1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qemu/datadir.h"
12#include "qemu/error-report.h"
13#include "qapi/error.h"
14#include <libfdt.h>
15#include "hw/arm/boot.h"
16#include "hw/arm/linux-boot-if.h"
17#include "sysemu/kvm.h"
18#include "sysemu/sysemu.h"
19#include "sysemu/numa.h"
20#include "hw/boards.h"
21#include "sysemu/reset.h"
22#include "hw/loader.h"
23#include "elf.h"
24#include "sysemu/device_tree.h"
25#include "qemu/config-file.h"
26#include "qemu/option.h"
27#include "qemu/units.h"
28
29
30
31
32
33#define KERNEL_ARGS_ADDR 0x100
34#define KERNEL_NOLOAD_ADDR 0x02000000
35#define KERNEL_LOAD_ADDR 0x00010000
36#define KERNEL64_LOAD_ADDR 0x00080000
37
38#define ARM64_TEXT_OFFSET_OFFSET 8
39#define ARM64_MAGIC_OFFSET 56
40
41#define BOOTLOADER_MAX_SIZE (4 * KiB)
42
43AddressSpace *arm_boot_address_space(ARMCPU *cpu,
44 const struct arm_boot_info *info)
45{
46
47
48
49
50 int asidx;
51 CPUState *cs = CPU(cpu);
52
53 if (arm_feature(&cpu->env, ARM_FEATURE_EL3) && info->secure_boot) {
54 asidx = ARMASIdx_S;
55 } else {
56 asidx = ARMASIdx_NS;
57 }
58
59 return cpu_get_address_space(cs, asidx);
60}
61
62typedef enum {
63 FIXUP_NONE = 0,
64 FIXUP_TERMINATOR,
65 FIXUP_BOARDID,
66 FIXUP_BOARD_SETUP,
67 FIXUP_ARGPTR_LO,
68 FIXUP_ARGPTR_HI,
69 FIXUP_ENTRYPOINT_LO,
70 FIXUP_ENTRYPOINT_HI,
71 FIXUP_GIC_CPU_IF,
72 FIXUP_BOOTREG,
73 FIXUP_DSB,
74 FIXUP_MAX,
75} FixupType;
76
77typedef struct ARMInsnFixup {
78 uint32_t insn;
79 FixupType fixup;
80} ARMInsnFixup;
81
82static const ARMInsnFixup bootloader_aarch64[] = {
83 { 0x580000c0 },
84 { 0xaa1f03e1 },
85 { 0xaa1f03e2 },
86 { 0xaa1f03e3 },
87 { 0x58000084 },
88 { 0xd61f0080 },
89 { 0, FIXUP_ARGPTR_LO },
90 { 0, FIXUP_ARGPTR_HI},
91 { 0, FIXUP_ENTRYPOINT_LO },
92 { 0, FIXUP_ENTRYPOINT_HI },
93 { 0, FIXUP_TERMINATOR }
94};
95
96
97
98
99
100
101
102static const ARMInsnFixup bootloader[] = {
103 { 0xe28fe004 },
104 { 0xe51ff004 },
105 { 0, FIXUP_BOARD_SETUP },
106#define BOOTLOADER_NO_BOARD_SETUP_OFFSET 3
107 { 0xe3a00000 },
108 { 0xe59f1004 },
109 { 0xe59f2004 },
110 { 0xe59ff004 },
111 { 0, FIXUP_BOARDID },
112 { 0, FIXUP_ARGPTR_LO },
113 { 0, FIXUP_ENTRYPOINT_LO },
114 { 0, FIXUP_TERMINATOR }
115};
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131#define DSB_INSN 0xf57ff04f
132#define CP15_DSB_INSN 0xee070f9a
133
134static const ARMInsnFixup smpboot[] = {
135 { 0xe59f2028 },
136 { 0xe59f0028 },
137 { 0xe3a01001 },
138 { 0xe5821000 },
139 { 0xe3a010ff },
140 { 0xe5821004 },
141 { 0, FIXUP_DSB },
142 { 0xe320f003 },
143 { 0xe5901000 },
144 { 0xe1110001 },
145 { 0x0afffffb },
146 { 0xe12fff11 },
147 { 0, FIXUP_GIC_CPU_IF },
148 { 0, FIXUP_BOOTREG },
149 { 0, FIXUP_TERMINATOR }
150};
151
152static void write_bootloader(const char *name, hwaddr addr,
153 const ARMInsnFixup *insns, uint32_t *fixupcontext,
154 AddressSpace *as)
155{
156
157
158
159
160
161 int i, len;
162 uint32_t *code;
163
164 len = 0;
165 while (insns[len].fixup != FIXUP_TERMINATOR) {
166 len++;
167 }
168
169 code = g_new0(uint32_t, len);
170
171 for (i = 0; i < len; i++) {
172 uint32_t insn = insns[i].insn;
173 FixupType fixup = insns[i].fixup;
174
175 switch (fixup) {
176 case FIXUP_NONE:
177 break;
178 case FIXUP_BOARDID:
179 case FIXUP_BOARD_SETUP:
180 case FIXUP_ARGPTR_LO:
181 case FIXUP_ARGPTR_HI:
182 case FIXUP_ENTRYPOINT_LO:
183 case FIXUP_ENTRYPOINT_HI:
184 case FIXUP_GIC_CPU_IF:
185 case FIXUP_BOOTREG:
186 case FIXUP_DSB:
187 insn = fixupcontext[fixup];
188 break;
189 default:
190 abort();
191 }
192 code[i] = tswap32(insn);
193 }
194
195 assert((len * sizeof(uint32_t)) < BOOTLOADER_MAX_SIZE);
196
197 rom_add_blob_fixed_as(name, code, len * sizeof(uint32_t), addr, as);
198
199 g_free(code);
200}
201
202static void default_write_secondary(ARMCPU *cpu,
203 const struct arm_boot_info *info)
204{
205 uint32_t fixupcontext[FIXUP_MAX];
206 AddressSpace *as = arm_boot_address_space(cpu, info);
207
208 fixupcontext[FIXUP_GIC_CPU_IF] = info->gic_cpu_if_addr;
209 fixupcontext[FIXUP_BOOTREG] = info->smp_bootreg_addr;
210 if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
211 fixupcontext[FIXUP_DSB] = DSB_INSN;
212 } else {
213 fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
214 }
215
216 write_bootloader("smpboot", info->smp_loader_start,
217 smpboot, fixupcontext, as);
218}
219
220void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
221 const struct arm_boot_info *info,
222 hwaddr mvbar_addr)
223{
224 AddressSpace *as = arm_boot_address_space(cpu, info);
225 int n;
226 uint32_t mvbar_blob[] = {
227
228
229
230
231 0xeafffffe,
232 0xeafffffe,
233 0xe1b0f00e,
234 0xeafffffe,
235 0xeafffffe,
236 0xeafffffe,
237 0xeafffffe,
238 0xeafffffe,
239 };
240 uint32_t board_setup_blob[] = {
241
242 0xee110f51,
243 0xe3800b03,
244 0xee010f51,
245 0xe3a00e00 + (mvbar_addr >> 4),
246 0xee0c0f30,
247 0xee110f11,
248 0xe3800031,
249 0xee010f11,
250 0xe1a0100e,
251 0xe1600070,
252 0xe1a0f001,
253 };
254
255
256 assert((mvbar_addr & 0x1f) == 0 && (mvbar_addr >> 4) < 0x100);
257
258
259 assert((mvbar_addr + sizeof(mvbar_blob) <= info->board_setup_addr)
260 || (info->board_setup_addr + sizeof(board_setup_blob) <= mvbar_addr));
261
262 for (n = 0; n < ARRAY_SIZE(mvbar_blob); n++) {
263 mvbar_blob[n] = tswap32(mvbar_blob[n]);
264 }
265 rom_add_blob_fixed_as("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob),
266 mvbar_addr, as);
267
268 for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
269 board_setup_blob[n] = tswap32(board_setup_blob[n]);
270 }
271 rom_add_blob_fixed_as("board-setup", board_setup_blob,
272 sizeof(board_setup_blob), info->board_setup_addr, as);
273}
274
275static void default_reset_secondary(ARMCPU *cpu,
276 const struct arm_boot_info *info)
277{
278 AddressSpace *as = arm_boot_address_space(cpu, info);
279 CPUState *cs = CPU(cpu);
280
281 address_space_stl_notdirty(as, info->smp_bootreg_addr,
282 0, MEMTXATTRS_UNSPECIFIED, NULL);
283 cpu_set_pc(cs, info->smp_loader_start);
284}
285
286static inline bool have_dtb(const struct arm_boot_info *info)
287{
288 return info->dtb_filename || info->get_dtb;
289}
290
291#define WRITE_WORD(p, value) do { \
292 address_space_stl_notdirty(as, p, value, \
293 MEMTXATTRS_UNSPECIFIED, NULL); \
294 p += 4; \
295} while (0)
296
297static void set_kernel_args(const struct arm_boot_info *info, AddressSpace *as)
298{
299 int initrd_size = info->initrd_size;
300 hwaddr base = info->loader_start;
301 hwaddr p;
302
303 p = base + KERNEL_ARGS_ADDR;
304
305 WRITE_WORD(p, 5);
306 WRITE_WORD(p, 0x54410001);
307 WRITE_WORD(p, 1);
308 WRITE_WORD(p, 0x1000);
309 WRITE_WORD(p, 0);
310
311
312 WRITE_WORD(p, 4);
313 WRITE_WORD(p, 0x54410002);
314 WRITE_WORD(p, info->ram_size);
315 WRITE_WORD(p, info->loader_start);
316 if (initrd_size) {
317
318 WRITE_WORD(p, 4);
319 WRITE_WORD(p, 0x54420005);
320 WRITE_WORD(p, info->initrd_start);
321 WRITE_WORD(p, initrd_size);
322 }
323 if (info->kernel_cmdline && *info->kernel_cmdline) {
324
325 int cmdline_size;
326
327 cmdline_size = strlen(info->kernel_cmdline);
328 address_space_write(as, p + 8, MEMTXATTRS_UNSPECIFIED,
329 info->kernel_cmdline, cmdline_size + 1);
330 cmdline_size = (cmdline_size >> 2) + 1;
331 WRITE_WORD(p, cmdline_size + 2);
332 WRITE_WORD(p, 0x54410009);
333 p += cmdline_size * 4;
334 }
335 if (info->atag_board) {
336
337 int atag_board_len;
338 uint8_t atag_board_buf[0x1000];
339
340 atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3;
341 WRITE_WORD(p, (atag_board_len + 8) >> 2);
342 WRITE_WORD(p, 0x414f4d50);
343 address_space_write(as, p, MEMTXATTRS_UNSPECIFIED,
344 atag_board_buf, atag_board_len);
345 p += atag_board_len;
346 }
347
348 WRITE_WORD(p, 0);
349 WRITE_WORD(p, 0);
350}
351
352static void set_kernel_args_old(const struct arm_boot_info *info,
353 AddressSpace *as)
354{
355 hwaddr p;
356 const char *s;
357 int initrd_size = info->initrd_size;
358 hwaddr base = info->loader_start;
359
360
361 p = base + KERNEL_ARGS_ADDR;
362
363 WRITE_WORD(p, 4096);
364
365 WRITE_WORD(p, info->ram_size / 4096);
366
367 WRITE_WORD(p, 0);
368#define FLAG_READONLY 1
369#define FLAG_RDLOAD 4
370#define FLAG_RDPROMPT 8
371
372 WRITE_WORD(p, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT);
373
374 WRITE_WORD(p, (31 << 8) | 0);
375
376 WRITE_WORD(p, 0);
377
378 WRITE_WORD(p, 0);
379
380 WRITE_WORD(p, 0);
381
382 WRITE_WORD(p, 0);
383
384 WRITE_WORD(p, 0);
385
386
387
388
389 WRITE_WORD(p, 0);
390
391 WRITE_WORD(p, 0);
392 WRITE_WORD(p, 0);
393 WRITE_WORD(p, 0);
394 WRITE_WORD(p, 0);
395
396 WRITE_WORD(p, 0);
397
398 if (initrd_size) {
399 WRITE_WORD(p, info->initrd_start);
400 } else {
401 WRITE_WORD(p, 0);
402 }
403
404 WRITE_WORD(p, initrd_size);
405
406 WRITE_WORD(p, 0);
407
408 WRITE_WORD(p, 0);
409
410 WRITE_WORD(p, 0);
411
412 WRITE_WORD(p, 0);
413
414 WRITE_WORD(p, 0);
415
416 while (p < base + KERNEL_ARGS_ADDR + 256 + 1024) {
417 WRITE_WORD(p, 0);
418 }
419 s = info->kernel_cmdline;
420 if (s) {
421 address_space_write(as, p, MEMTXATTRS_UNSPECIFIED, s, strlen(s) + 1);
422 } else {
423 WRITE_WORD(p, 0);
424 }
425}
426
427static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
428 uint32_t scells, hwaddr mem_len,
429 int numa_node_id)
430{
431 char *nodename;
432 int ret;
433
434 nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
435 qemu_fdt_add_subnode(fdt, nodename);
436 qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
437 ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", acells, mem_base,
438 scells, mem_len);
439 if (ret < 0) {
440 goto out;
441 }
442
443
444 if (numa_node_id >= 0) {
445 ret = qemu_fdt_setprop_cell(fdt, nodename,
446 "numa-node-id", numa_node_id);
447 }
448out:
449 g_free(nodename);
450 return ret;
451}
452
453static void fdt_add_psci_node(void *fdt)
454{
455 uint32_t cpu_suspend_fn;
456 uint32_t cpu_off_fn;
457 uint32_t cpu_on_fn;
458 uint32_t migrate_fn;
459 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
460 const char *psci_method;
461 int64_t psci_conduit;
462 int rc;
463
464 psci_conduit = object_property_get_int(OBJECT(armcpu),
465 "psci-conduit",
466 &error_abort);
467 switch (psci_conduit) {
468 case QEMU_PSCI_CONDUIT_DISABLED:
469 return;
470 case QEMU_PSCI_CONDUIT_HVC:
471 psci_method = "hvc";
472 break;
473 case QEMU_PSCI_CONDUIT_SMC:
474 psci_method = "smc";
475 break;
476 default:
477 g_assert_not_reached();
478 }
479
480
481
482
483
484
485 rc = fdt_path_offset(fdt, "/psci");
486 if (rc >= 0) {
487 qemu_fdt_nop_node(fdt, "/psci");
488 }
489
490 qemu_fdt_add_subnode(fdt, "/psci");
491 if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
492 if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
493 const char comp[] = "arm,psci-0.2\0arm,psci";
494 qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
495 } else {
496 const char comp[] = "arm,psci-1.0\0arm,psci-0.2\0arm,psci";
497 qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
498 }
499
500 cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
501 if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
502 cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
503 cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
504 migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
505 } else {
506 cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
507 cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
508 migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
509 }
510 } else {
511 qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
512
513 cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
514 cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
515 cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
516 migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
517 }
518
519
520
521
522
523
524 qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
525
526 qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
527 qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
528 qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
529 qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
530}
531
532int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
533 hwaddr addr_limit, AddressSpace *as, MachineState *ms)
534{
535 void *fdt = NULL;
536 int size, rc, n = 0;
537 uint32_t acells, scells;
538 unsigned int i;
539 hwaddr mem_base, mem_len;
540 char **node_path;
541 Error *err = NULL;
542
543 if (binfo->dtb_filename) {
544 char *filename;
545 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
546 if (!filename) {
547 fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
548 goto fail;
549 }
550
551 fdt = load_device_tree(filename, &size);
552 if (!fdt) {
553 fprintf(stderr, "Couldn't open dtb file %s\n", filename);
554 g_free(filename);
555 goto fail;
556 }
557 g_free(filename);
558 } else {
559 fdt = binfo->get_dtb(binfo, &size);
560 if (!fdt) {
561 fprintf(stderr, "Board was unable to create a dtb blob\n");
562 goto fail;
563 }
564 }
565
566 if (addr_limit > addr && size > (addr_limit - addr)) {
567
568
569
570
571 g_free(fdt);
572 return 0;
573 }
574
575 acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells",
576 NULL, &error_fatal);
577 scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells",
578 NULL, &error_fatal);
579 if (acells == 0 || scells == 0) {
580 fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
581 goto fail;
582 }
583
584 if (scells < 2 && binfo->ram_size >= 4 * GiB) {
585
586
587
588 fprintf(stderr, "qemu: dtb file not compatible with "
589 "RAM size > 4GB\n");
590 goto fail;
591 }
592
593
594 node_path = qemu_fdt_node_unit_path(fdt, "memory", &err);
595 if (err) {
596 error_report_err(err);
597 goto fail;
598 }
599 while (node_path[n]) {
600 if (g_str_has_prefix(node_path[n], "/memory")) {
601 qemu_fdt_nop_node(fdt, node_path[n]);
602 }
603 n++;
604 }
605 g_strfreev(node_path);
606
607
608
609
610
611
612
613
614
615
616 if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) {
617 mem_base = binfo->loader_start;
618 for (i = 0; i < ms->numa_state->num_nodes; i++) {
619 mem_len = ms->numa_state->nodes[i].node_mem;
620 if (!mem_len) {
621 continue;
622 }
623
624 rc = fdt_add_memory_node(fdt, acells, mem_base,
625 scells, mem_len, i);
626 if (rc < 0) {
627 fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
628 mem_base);
629 goto fail;
630 }
631
632 mem_base += mem_len;
633 }
634 } else {
635 rc = fdt_add_memory_node(fdt, acells, binfo->loader_start,
636 scells, binfo->ram_size, -1);
637 if (rc < 0) {
638 fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
639 binfo->loader_start);
640 goto fail;
641 }
642 }
643
644 rc = fdt_path_offset(fdt, "/chosen");
645 if (rc < 0) {
646 qemu_fdt_add_subnode(fdt, "/chosen");
647 }
648
649 if (ms->kernel_cmdline && *ms->kernel_cmdline) {
650 rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
651 ms->kernel_cmdline);
652 if (rc < 0) {
653 fprintf(stderr, "couldn't set /chosen/bootargs\n");
654 goto fail;
655 }
656 }
657
658 if (binfo->initrd_size) {
659 rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
660 binfo->initrd_start);
661 if (rc < 0) {
662 fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
663 goto fail;
664 }
665
666 rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
667 binfo->initrd_start + binfo->initrd_size);
668 if (rc < 0) {
669 fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
670 goto fail;
671 }
672 }
673
674 fdt_add_psci_node(fdt);
675
676 if (binfo->modify_dtb) {
677 binfo->modify_dtb(binfo, fdt);
678 }
679
680 qemu_fdt_dumpdtb(fdt, size);
681
682
683
684
685 rom_add_blob_fixed_as("dtb", fdt, size, addr, as);
686
687 g_free(fdt);
688
689 return size;
690
691fail:
692 g_free(fdt);
693 return -1;
694}
695
696static void do_cpu_reset(void *opaque)
697{
698 ARMCPU *cpu = opaque;
699 CPUState *cs = CPU(cpu);
700 CPUARMState *env = &cpu->env;
701 const struct arm_boot_info *info = env->boot_info;
702
703 cpu_reset(cs);
704 if (info) {
705 if (!info->is_linux) {
706 int i;
707
708 uint64_t entry = info->entry;
709
710 switch (info->endianness) {
711 case ARM_ENDIANNESS_LE:
712 env->cp15.sctlr_el[1] &= ~SCTLR_E0E;
713 for (i = 1; i < 4; ++i) {
714 env->cp15.sctlr_el[i] &= ~SCTLR_EE;
715 }
716 env->uncached_cpsr &= ~CPSR_E;
717 break;
718 case ARM_ENDIANNESS_BE8:
719 env->cp15.sctlr_el[1] |= SCTLR_E0E;
720 for (i = 1; i < 4; ++i) {
721 env->cp15.sctlr_el[i] |= SCTLR_EE;
722 }
723 env->uncached_cpsr |= CPSR_E;
724 break;
725 case ARM_ENDIANNESS_BE32:
726 env->cp15.sctlr_el[1] |= SCTLR_B;
727 break;
728 case ARM_ENDIANNESS_UNKNOWN:
729 break;
730 default:
731 g_assert_not_reached();
732 }
733
734 cpu_set_pc(cs, entry);
735 } else {
736
737
738
739
740
741
742 if (arm_feature(env, ARM_FEATURE_EL3)) {
743
744
745
746
747
748
749 if (env->aarch64) {
750 env->cp15.scr_el3 |= SCR_RW;
751 if (arm_feature(env, ARM_FEATURE_EL2)) {
752 env->cp15.hcr_el2 |= HCR_RW;
753 env->pstate = PSTATE_MODE_EL2h;
754 } else {
755 env->pstate = PSTATE_MODE_EL1h;
756 }
757 if (cpu_isar_feature(aa64_pauth, cpu)) {
758 env->cp15.scr_el3 |= SCR_API | SCR_APK;
759 }
760 if (cpu_isar_feature(aa64_mte, cpu)) {
761 env->cp15.scr_el3 |= SCR_ATA;
762 }
763 if (cpu_isar_feature(aa64_sve, cpu)) {
764 env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
765 }
766
767 assert(!info->secure_boot);
768
769
770
771
772 assert(!info->secure_board_setup);
773 }
774
775 if (arm_feature(env, ARM_FEATURE_EL2)) {
776
777 env->cp15.scr_el3 |= SCR_HCE;
778 }
779
780
781 if (!info->secure_boot &&
782 (cs != first_cpu || !info->secure_board_setup)) {
783
784 env->cp15.scr_el3 |= SCR_NS;
785
786 env->cp15.nsacr |= 3 << 10;
787 }
788 }
789
790 if (!env->aarch64 && !info->secure_boot &&
791 arm_feature(env, ARM_FEATURE_EL2)) {
792
793
794
795
796
797
798 cpsr_write(env, ARM_CPU_MODE_HYP, CPSR_M, CPSRWriteRaw);
799 }
800
801 if (cs == first_cpu) {
802 AddressSpace *as = arm_boot_address_space(cpu, info);
803
804 cpu_set_pc(cs, info->loader_start);
805
806 if (!have_dtb(info)) {
807 if (old_param) {
808 set_kernel_args_old(info, as);
809 } else {
810 set_kernel_args(info, as);
811 }
812 }
813 } else if (info->secondary_cpu_reset_hook) {
814 info->secondary_cpu_reset_hook(cpu, info);
815 }
816 }
817 arm_rebuild_hflags(env);
818 }
819}
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
839 uint16_t data_key, const char *image_name,
840 bool try_decompress)
841{
842 size_t size = -1;
843 uint8_t *data;
844
845 if (image_name == NULL) {
846 return;
847 }
848
849 if (try_decompress) {
850 size = load_image_gzipped_buffer(image_name,
851 LOAD_IMAGE_MAX_GUNZIP_BYTES, &data);
852 }
853
854 if (size == (size_t)-1) {
855 gchar *contents;
856 gsize length;
857
858 if (!g_file_get_contents(image_name, &contents, &length, NULL)) {
859 error_report("failed to load \"%s\"", image_name);
860 exit(1);
861 }
862 size = length;
863 data = (uint8_t *)contents;
864 }
865
866 fw_cfg_add_i32(fw_cfg, size_key, size);
867 fw_cfg_add_bytes(fw_cfg, data_key, data, size);
868}
869
870static int do_arm_linux_init(Object *obj, void *opaque)
871{
872 if (object_dynamic_cast(obj, TYPE_ARM_LINUX_BOOT_IF)) {
873 ARMLinuxBootIf *albif = ARM_LINUX_BOOT_IF(obj);
874 ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_GET_CLASS(obj);
875 struct arm_boot_info *info = opaque;
876
877 if (albifc->arm_linux_init) {
878 albifc->arm_linux_init(albif, info->secure_boot);
879 }
880 }
881 return 0;
882}
883
884static ssize_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
885 uint64_t *lowaddr, uint64_t *highaddr,
886 int elf_machine, AddressSpace *as)
887{
888 bool elf_is64;
889 union {
890 Elf32_Ehdr h32;
891 Elf64_Ehdr h64;
892 } elf_header;
893 int data_swab = 0;
894 bool big_endian;
895 ssize_t ret = -1;
896 Error *err = NULL;
897
898
899 load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
900 if (err) {
901 error_free(err);
902 return ret;
903 }
904
905 if (elf_is64) {
906 big_endian = elf_header.h64.e_ident[EI_DATA] == ELFDATA2MSB;
907 info->endianness = big_endian ? ARM_ENDIANNESS_BE8
908 : ARM_ENDIANNESS_LE;
909 } else {
910 big_endian = elf_header.h32.e_ident[EI_DATA] == ELFDATA2MSB;
911 if (big_endian) {
912 if (bswap32(elf_header.h32.e_flags) & EF_ARM_BE8) {
913 info->endianness = ARM_ENDIANNESS_BE8;
914 } else {
915 info->endianness = ARM_ENDIANNESS_BE32;
916
917
918
919
920
921
922
923 data_swab = 2;
924 }
925 } else {
926 info->endianness = ARM_ENDIANNESS_LE;
927 }
928 }
929
930 ret = load_elf_as(info->kernel_filename, NULL, NULL, NULL,
931 pentry, lowaddr, highaddr, NULL, big_endian, elf_machine,
932 1, data_swab, as);
933 if (ret <= 0) {
934
935 exit(1);
936 }
937
938 return ret;
939}
940
941static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
942 hwaddr *entry, AddressSpace *as)
943{
944 hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
945 uint64_t kernel_size = 0;
946 uint8_t *buffer;
947 int size;
948
949
950 size = load_image_gzipped_buffer(filename, LOAD_IMAGE_MAX_GUNZIP_BYTES,
951 &buffer);
952
953 if (size < 0) {
954 gsize len;
955
956
957 if (!g_file_get_contents(filename, (char **)&buffer, &len, NULL)) {
958 return -1;
959 }
960 size = len;
961 }
962
963
964 if (size > ARM64_MAGIC_OFFSET + 4 &&
965 memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
966 uint64_t hdrvals[2];
967
968
969
970
971
972 memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
973
974 kernel_size = le64_to_cpu(hdrvals[1]);
975
976 if (kernel_size != 0) {
977 kernel_load_offset = le64_to_cpu(hdrvals[0]);
978
979
980
981
982
983
984
985
986
987
988 if (kernel_load_offset < BOOTLOADER_MAX_SIZE) {
989 kernel_load_offset += 2 * MiB;
990 }
991 }
992 }
993
994
995
996
997
998
999 if (kernel_size == 0) {
1000 kernel_size = size;
1001 }
1002
1003 *entry = mem_base + kernel_load_offset;
1004 rom_add_blob_fixed_as(filename, buffer, size, *entry, as);
1005
1006 g_free(buffer);
1007
1008 return kernel_size;
1009}
1010
1011static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
1012 struct arm_boot_info *info)
1013{
1014
1015 CPUState *cs;
1016 AddressSpace *as = arm_boot_address_space(cpu, info);
1017 ssize_t kernel_size;
1018 int initrd_size;
1019 int is_linux = 0;
1020 uint64_t elf_entry;
1021
1022 uint64_t image_low_addr = 0, image_high_addr = 0;
1023 int elf_machine;
1024 hwaddr entry;
1025 static const ARMInsnFixup *primary_loader;
1026 uint64_t ram_end = info->loader_start + info->ram_size;
1027
1028 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
1029 primary_loader = bootloader_aarch64;
1030 elf_machine = EM_AARCH64;
1031 } else {
1032 primary_loader = bootloader;
1033 if (!info->write_board_setup) {
1034 primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
1035 }
1036 elf_machine = EM_ARM;
1037 }
1038
1039
1040 kernel_size = arm_load_elf(info, &elf_entry, &image_low_addr,
1041 &image_high_addr, elf_machine, as);
1042 if (kernel_size > 0 && have_dtb(info)) {
1043
1044
1045
1046
1047 if (image_low_addr > info->loader_start
1048 || image_high_addr < info->loader_start) {
1049
1050
1051
1052
1053 if (image_low_addr < info->loader_start) {
1054 image_low_addr = 0;
1055 }
1056 info->dtb_start = info->loader_start;
1057 info->dtb_limit = image_low_addr;
1058 }
1059 }
1060 entry = elf_entry;
1061 if (kernel_size < 0) {
1062 uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
1063 kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
1064 &is_linux, NULL, NULL, as);
1065 if (kernel_size >= 0) {
1066 image_low_addr = loadaddr;
1067 image_high_addr = image_low_addr + kernel_size;
1068 }
1069 }
1070 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
1071 kernel_size = load_aarch64_image(info->kernel_filename,
1072 info->loader_start, &entry, as);
1073 is_linux = 1;
1074 if (kernel_size >= 0) {
1075 image_low_addr = entry;
1076 image_high_addr = image_low_addr + kernel_size;
1077 }
1078 } else if (kernel_size < 0) {
1079
1080 entry = info->loader_start + KERNEL_LOAD_ADDR;
1081 kernel_size = load_image_targphys_as(info->kernel_filename, entry,
1082 ram_end - KERNEL_LOAD_ADDR, as);
1083 is_linux = 1;
1084 if (kernel_size >= 0) {
1085 image_low_addr = entry;
1086 image_high_addr = image_low_addr + kernel_size;
1087 }
1088 }
1089 if (kernel_size < 0) {
1090 error_report("could not load kernel '%s'", info->kernel_filename);
1091 exit(1);
1092 }
1093
1094 if (kernel_size > info->ram_size) {
1095 error_report("kernel '%s' is too large to fit in RAM "
1096 "(kernel size %zd, RAM size %" PRId64 ")",
1097 info->kernel_filename, kernel_size, info->ram_size);
1098 exit(1);
1099 }
1100
1101 info->entry = entry;
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118 info->initrd_start = info->loader_start +
1119 MIN(info->ram_size / 2, 128 * MiB);
1120 if (image_high_addr) {
1121 info->initrd_start = MAX(info->initrd_start, image_high_addr);
1122 }
1123 info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
1124
1125 if (is_linux) {
1126 uint32_t fixupcontext[FIXUP_MAX];
1127
1128 if (info->initrd_filename) {
1129
1130 if (info->initrd_start >= ram_end) {
1131 error_report("not enough space after kernel to load initrd");
1132 exit(1);
1133 }
1134
1135 initrd_size = load_ramdisk_as(info->initrd_filename,
1136 info->initrd_start,
1137 ram_end - info->initrd_start, as);
1138 if (initrd_size < 0) {
1139 initrd_size = load_image_targphys_as(info->initrd_filename,
1140 info->initrd_start,
1141 ram_end -
1142 info->initrd_start,
1143 as);
1144 }
1145 if (initrd_size < 0) {
1146 error_report("could not load initrd '%s'",
1147 info->initrd_filename);
1148 exit(1);
1149 }
1150 if (info->initrd_start + initrd_size > ram_end) {
1151 error_report("could not load initrd '%s': "
1152 "too big to fit into RAM after the kernel",
1153 info->initrd_filename);
1154 exit(1);
1155 }
1156 } else {
1157 initrd_size = 0;
1158 }
1159 info->initrd_size = initrd_size;
1160
1161 fixupcontext[FIXUP_BOARDID] = info->board_id;
1162 fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
1163
1164
1165
1166
1167
1168 if (have_dtb(info)) {
1169 hwaddr align;
1170
1171 if (elf_machine == EM_AARCH64) {
1172
1173
1174
1175
1176
1177
1178
1179 align = 2 * MiB;
1180 } else {
1181
1182
1183
1184
1185 align = 4 * KiB;
1186 }
1187
1188
1189 info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
1190 align);
1191 if (info->dtb_start >= ram_end) {
1192 error_report("Not enough space for DTB after kernel/initrd");
1193 exit(1);
1194 }
1195 fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
1196 fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
1197 } else {
1198 fixupcontext[FIXUP_ARGPTR_LO] =
1199 info->loader_start + KERNEL_ARGS_ADDR;
1200 fixupcontext[FIXUP_ARGPTR_HI] =
1201 (info->loader_start + KERNEL_ARGS_ADDR) >> 32;
1202 if (info->ram_size >= 4 * GiB) {
1203 error_report("RAM size must be less than 4GB to boot"
1204 " Linux kernel using ATAGS (try passing a device tree"
1205 " using -dtb)");
1206 exit(1);
1207 }
1208 }
1209 fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
1210 fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
1211
1212 write_bootloader("bootloader", info->loader_start,
1213 primary_loader, fixupcontext, as);
1214
1215 if (info->write_board_setup) {
1216 info->write_board_setup(cpu, info);
1217 }
1218
1219
1220
1221
1222
1223 object_child_foreach_recursive(object_get_root(),
1224 do_arm_linux_init, info);
1225 }
1226 info->is_linux = is_linux;
1227
1228 for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
1229 ARM_CPU(cs)->env.boot_info = info;
1230 }
1231}
1232
1233static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info)
1234{
1235
1236
1237 if (have_dtb(info)) {
1238
1239
1240
1241
1242
1243 info->dtb_start = info->loader_start;
1244 }
1245
1246 if (info->kernel_filename) {
1247 FWCfgState *fw_cfg;
1248 bool try_decompressing_kernel;
1249
1250 fw_cfg = fw_cfg_find();
1251
1252 if (!fw_cfg) {
1253 error_report("This machine type does not support loading both "
1254 "a guest firmware/BIOS image and a guest kernel at "
1255 "the same time. You should change your QEMU command "
1256 "line to specify one or the other, but not both.");
1257 exit(1);
1258 }
1259
1260 try_decompressing_kernel = arm_feature(&cpu->env,
1261 ARM_FEATURE_AARCH64);
1262
1263
1264
1265
1266
1267
1268 load_image_to_fw_cfg(fw_cfg,
1269 FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
1270 info->kernel_filename,
1271 try_decompressing_kernel);
1272 load_image_to_fw_cfg(fw_cfg,
1273 FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
1274 info->initrd_filename, false);
1275
1276 if (info->kernel_cmdline) {
1277 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
1278 strlen(info->kernel_cmdline) + 1);
1279 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
1280 info->kernel_cmdline);
1281 }
1282 }
1283
1284
1285
1286
1287
1288
1289}
1290
1291void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info)
1292{
1293 CPUState *cs;
1294 AddressSpace *as = arm_boot_address_space(cpu, info);
1295 int boot_el;
1296 CPUARMState *env = &cpu->env;
1297 int nb_cpus = 0;
1298
1299
1300
1301
1302
1303
1304
1305 for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
1306 qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
1307 nb_cpus++;
1308 }
1309
1310
1311
1312
1313
1314
1315 assert(!(info->secure_board_setup && kvm_enabled()));
1316 info->kernel_filename = ms->kernel_filename;
1317 info->kernel_cmdline = ms->kernel_cmdline;
1318 info->initrd_filename = ms->initrd_filename;
1319 info->dtb_filename = ms->dtb;
1320 info->dtb_limit = 0;
1321
1322
1323 if (!info->kernel_filename || info->firmware_loaded) {
1324 arm_setup_firmware_boot(cpu, info);
1325 } else {
1326 arm_setup_direct_kernel_boot(cpu, info);
1327 }
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344 assert(info->psci_conduit == QEMU_PSCI_CONDUIT_DISABLED ||
1345 !info->secure_board_setup);
1346
1347
1348 if (arm_feature(env, ARM_FEATURE_EL3)) {
1349 boot_el = 3;
1350 } else if (arm_feature(env, ARM_FEATURE_EL2)) {
1351 boot_el = 2;
1352 } else {
1353 boot_el = 1;
1354 }
1355
1356 if (info->is_linux && !info->secure_boot) {
1357 boot_el = arm_feature(env, ARM_FEATURE_EL2) ? 2 : 1;
1358 }
1359
1360 if ((info->psci_conduit == QEMU_PSCI_CONDUIT_HVC && boot_el >= 2) ||
1361 (info->psci_conduit == QEMU_PSCI_CONDUIT_SMC && boot_el == 3)) {
1362 info->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
1363 }
1364
1365 if (info->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
1366 for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
1367 Object *cpuobj = OBJECT(cs);
1368
1369 object_property_set_int(cpuobj, "psci-conduit", info->psci_conduit,
1370 &error_abort);
1371
1372
1373
1374
1375
1376 if (cs != first_cpu) {
1377 object_property_set_bool(cpuobj, "start-powered-off", true,
1378 &error_abort);
1379 }
1380 }
1381 }
1382
1383 if (info->psci_conduit == QEMU_PSCI_CONDUIT_DISABLED &&
1384 info->is_linux && nb_cpus > 1) {
1385
1386
1387
1388
1389
1390 if (!info->secondary_cpu_reset_hook) {
1391 info->secondary_cpu_reset_hook = default_reset_secondary;
1392 }
1393 if (!info->write_secondary_boot) {
1394 info->write_secondary_boot = default_write_secondary;
1395 }
1396 info->write_secondary_boot(cpu, info);
1397 } else {
1398
1399
1400
1401
1402 info->write_secondary_boot = NULL;
1403 info->secondary_cpu_reset_hook = NULL;
1404 }
1405
1406
1407
1408
1409
1410 if (!info->skip_dtb_autoload && have_dtb(info)) {
1411 if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) {
1412 exit(1);
1413 }
1414 }
1415}
1416
1417static const TypeInfo arm_linux_boot_if_info = {
1418 .name = TYPE_ARM_LINUX_BOOT_IF,
1419 .parent = TYPE_INTERFACE,
1420 .class_size = sizeof(ARMLinuxBootIfClass),
1421};
1422
1423static void arm_linux_boot_register_types(void)
1424{
1425 type_register_static(&arm_linux_boot_if_info);
1426}
1427
1428type_init(arm_linux_boot_register_types)
1429