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 qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
687 rom_ptr_for_as(as, addr, size));
688
689 g_free(fdt);
690
691 return size;
692
693fail:
694 g_free(fdt);
695 return -1;
696}
697
698static void do_cpu_reset(void *opaque)
699{
700 ARMCPU *cpu = opaque;
701 CPUState *cs = CPU(cpu);
702 CPUARMState *env = &cpu->env;
703 const struct arm_boot_info *info = env->boot_info;
704
705 cpu_reset(cs);
706 if (info) {
707 if (!info->is_linux) {
708 int i;
709
710 uint64_t entry = info->entry;
711
712 switch (info->endianness) {
713 case ARM_ENDIANNESS_LE:
714 env->cp15.sctlr_el[1] &= ~SCTLR_E0E;
715 for (i = 1; i < 4; ++i) {
716 env->cp15.sctlr_el[i] &= ~SCTLR_EE;
717 }
718 env->uncached_cpsr &= ~CPSR_E;
719 break;
720 case ARM_ENDIANNESS_BE8:
721 env->cp15.sctlr_el[1] |= SCTLR_E0E;
722 for (i = 1; i < 4; ++i) {
723 env->cp15.sctlr_el[i] |= SCTLR_EE;
724 }
725 env->uncached_cpsr |= CPSR_E;
726 break;
727 case ARM_ENDIANNESS_BE32:
728 env->cp15.sctlr_el[1] |= SCTLR_B;
729 break;
730 case ARM_ENDIANNESS_UNKNOWN:
731 break;
732 default:
733 g_assert_not_reached();
734 }
735
736 cpu_set_pc(cs, entry);
737 } else {
738
739
740
741
742
743
744 if (arm_feature(env, ARM_FEATURE_EL3)) {
745
746
747
748
749
750
751 if (env->aarch64) {
752 env->cp15.scr_el3 |= SCR_RW;
753 if (arm_feature(env, ARM_FEATURE_EL2)) {
754 env->cp15.hcr_el2 |= HCR_RW;
755 env->pstate = PSTATE_MODE_EL2h;
756 } else {
757 env->pstate = PSTATE_MODE_EL1h;
758 }
759 if (cpu_isar_feature(aa64_pauth, cpu)) {
760 env->cp15.scr_el3 |= SCR_API | SCR_APK;
761 }
762 if (cpu_isar_feature(aa64_mte, cpu)) {
763 env->cp15.scr_el3 |= SCR_ATA;
764 }
765 if (cpu_isar_feature(aa64_sve, cpu)) {
766 env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
767 env->vfp.zcr_el[3] = 0xf;
768 }
769 if (cpu_isar_feature(aa64_sme, cpu)) {
770 env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
771 env->cp15.scr_el3 |= SCR_ENTP2;
772 env->vfp.smcr_el[3] = 0xf;
773 }
774 if (cpu_isar_feature(aa64_hcx, cpu)) {
775 env->cp15.scr_el3 |= SCR_HXEN;
776 }
777
778 assert(!info->secure_boot);
779
780
781
782
783 assert(!info->secure_board_setup);
784 }
785
786 if (arm_feature(env, ARM_FEATURE_EL2)) {
787
788 env->cp15.scr_el3 |= SCR_HCE;
789 }
790
791
792 if (!info->secure_boot &&
793 (cs != first_cpu || !info->secure_board_setup)) {
794
795 env->cp15.scr_el3 |= SCR_NS;
796
797 env->cp15.nsacr |= 3 << 10;
798 }
799 }
800
801 if (!env->aarch64 && !info->secure_boot &&
802 arm_feature(env, ARM_FEATURE_EL2)) {
803
804
805
806
807
808
809 cpsr_write(env, ARM_CPU_MODE_HYP, CPSR_M, CPSRWriteRaw);
810 }
811
812 if (cs == first_cpu) {
813 AddressSpace *as = arm_boot_address_space(cpu, info);
814
815 cpu_set_pc(cs, info->loader_start);
816
817 if (!have_dtb(info)) {
818 if (old_param) {
819 set_kernel_args_old(info, as);
820 } else {
821 set_kernel_args(info, as);
822 }
823 }
824 } else if (info->secondary_cpu_reset_hook) {
825 info->secondary_cpu_reset_hook(cpu, info);
826 }
827 }
828 arm_rebuild_hflags(env);
829 }
830}
831
832static int do_arm_linux_init(Object *obj, void *opaque)
833{
834 if (object_dynamic_cast(obj, TYPE_ARM_LINUX_BOOT_IF)) {
835 ARMLinuxBootIf *albif = ARM_LINUX_BOOT_IF(obj);
836 ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_GET_CLASS(obj);
837 struct arm_boot_info *info = opaque;
838
839 if (albifc->arm_linux_init) {
840 albifc->arm_linux_init(albif, info->secure_boot);
841 }
842 }
843 return 0;
844}
845
846static ssize_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
847 uint64_t *lowaddr, uint64_t *highaddr,
848 int elf_machine, AddressSpace *as)
849{
850 bool elf_is64;
851 union {
852 Elf32_Ehdr h32;
853 Elf64_Ehdr h64;
854 } elf_header;
855 int data_swab = 0;
856 bool big_endian;
857 ssize_t ret = -1;
858 Error *err = NULL;
859
860
861 load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
862 if (err) {
863 error_free(err);
864 return ret;
865 }
866
867 if (elf_is64) {
868 big_endian = elf_header.h64.e_ident[EI_DATA] == ELFDATA2MSB;
869 info->endianness = big_endian ? ARM_ENDIANNESS_BE8
870 : ARM_ENDIANNESS_LE;
871 } else {
872 big_endian = elf_header.h32.e_ident[EI_DATA] == ELFDATA2MSB;
873 if (big_endian) {
874 if (bswap32(elf_header.h32.e_flags) & EF_ARM_BE8) {
875 info->endianness = ARM_ENDIANNESS_BE8;
876 } else {
877 info->endianness = ARM_ENDIANNESS_BE32;
878
879
880
881
882
883
884
885 data_swab = 2;
886 }
887 } else {
888 info->endianness = ARM_ENDIANNESS_LE;
889 }
890 }
891
892 ret = load_elf_as(info->kernel_filename, NULL, NULL, NULL,
893 pentry, lowaddr, highaddr, NULL, big_endian, elf_machine,
894 1, data_swab, as);
895 if (ret <= 0) {
896
897 exit(1);
898 }
899
900 return ret;
901}
902
903static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
904 hwaddr *entry, AddressSpace *as)
905{
906 hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
907 uint64_t kernel_size = 0;
908 uint8_t *buffer;
909 int size;
910
911
912 size = load_image_gzipped_buffer(filename, LOAD_IMAGE_MAX_GUNZIP_BYTES,
913 &buffer);
914
915 if (size < 0) {
916 gsize len;
917
918
919 if (!g_file_get_contents(filename, (char **)&buffer, &len, NULL)) {
920 return -1;
921 }
922 size = len;
923 }
924
925
926 if (size > ARM64_MAGIC_OFFSET + 4 &&
927 memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
928 uint64_t hdrvals[2];
929
930
931
932
933
934 memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
935
936 kernel_size = le64_to_cpu(hdrvals[1]);
937
938 if (kernel_size != 0) {
939 kernel_load_offset = le64_to_cpu(hdrvals[0]);
940
941
942
943
944
945
946
947
948
949
950 if (kernel_load_offset < BOOTLOADER_MAX_SIZE) {
951 kernel_load_offset += 2 * MiB;
952 }
953 }
954 }
955
956
957
958
959
960
961 if (kernel_size == 0) {
962 kernel_size = size;
963 }
964
965 *entry = mem_base + kernel_load_offset;
966 rom_add_blob_fixed_as(filename, buffer, size, *entry, as);
967
968 g_free(buffer);
969
970 return kernel_size;
971}
972
973static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
974 struct arm_boot_info *info)
975{
976
977 CPUState *cs;
978 AddressSpace *as = arm_boot_address_space(cpu, info);
979 ssize_t kernel_size;
980 int initrd_size;
981 int is_linux = 0;
982 uint64_t elf_entry;
983
984 uint64_t image_low_addr = 0, image_high_addr = 0;
985 int elf_machine;
986 hwaddr entry;
987 static const ARMInsnFixup *primary_loader;
988 uint64_t ram_end = info->loader_start + info->ram_size;
989
990 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
991 primary_loader = bootloader_aarch64;
992 elf_machine = EM_AARCH64;
993 } else {
994 primary_loader = bootloader;
995 if (!info->write_board_setup) {
996 primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
997 }
998 elf_machine = EM_ARM;
999 }
1000
1001
1002 kernel_size = arm_load_elf(info, &elf_entry, &image_low_addr,
1003 &image_high_addr, elf_machine, as);
1004 if (kernel_size > 0 && have_dtb(info)) {
1005
1006
1007
1008
1009 if (image_low_addr > info->loader_start
1010 || image_high_addr < info->loader_start) {
1011
1012
1013
1014
1015 if (image_low_addr < info->loader_start) {
1016 image_low_addr = 0;
1017 }
1018 info->dtb_start = info->loader_start;
1019 info->dtb_limit = image_low_addr;
1020 }
1021 }
1022 entry = elf_entry;
1023 if (kernel_size < 0) {
1024 uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
1025 kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
1026 &is_linux, NULL, NULL, as);
1027 if (kernel_size >= 0) {
1028 image_low_addr = loadaddr;
1029 image_high_addr = image_low_addr + kernel_size;
1030 }
1031 }
1032 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
1033 kernel_size = load_aarch64_image(info->kernel_filename,
1034 info->loader_start, &entry, as);
1035 is_linux = 1;
1036 if (kernel_size >= 0) {
1037 image_low_addr = entry;
1038 image_high_addr = image_low_addr + kernel_size;
1039 }
1040 } else if (kernel_size < 0) {
1041
1042 entry = info->loader_start + KERNEL_LOAD_ADDR;
1043 kernel_size = load_image_targphys_as(info->kernel_filename, entry,
1044 ram_end - KERNEL_LOAD_ADDR, as);
1045 is_linux = 1;
1046 if (kernel_size >= 0) {
1047 image_low_addr = entry;
1048 image_high_addr = image_low_addr + kernel_size;
1049 }
1050 }
1051 if (kernel_size < 0) {
1052 error_report("could not load kernel '%s'", info->kernel_filename);
1053 exit(1);
1054 }
1055
1056 if (kernel_size > info->ram_size) {
1057 error_report("kernel '%s' is too large to fit in RAM "
1058 "(kernel size %zd, RAM size %" PRId64 ")",
1059 info->kernel_filename, kernel_size, info->ram_size);
1060 exit(1);
1061 }
1062
1063 info->entry = entry;
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080 info->initrd_start = info->loader_start +
1081 MIN(info->ram_size / 2, 128 * MiB);
1082 if (image_high_addr) {
1083 info->initrd_start = MAX(info->initrd_start, image_high_addr);
1084 }
1085 info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
1086
1087 if (is_linux) {
1088 uint32_t fixupcontext[FIXUP_MAX];
1089
1090 if (info->initrd_filename) {
1091
1092 if (info->initrd_start >= ram_end) {
1093 error_report("not enough space after kernel to load initrd");
1094 exit(1);
1095 }
1096
1097 initrd_size = load_ramdisk_as(info->initrd_filename,
1098 info->initrd_start,
1099 ram_end - info->initrd_start, as);
1100 if (initrd_size < 0) {
1101 initrd_size = load_image_targphys_as(info->initrd_filename,
1102 info->initrd_start,
1103 ram_end -
1104 info->initrd_start,
1105 as);
1106 }
1107 if (initrd_size < 0) {
1108 error_report("could not load initrd '%s'",
1109 info->initrd_filename);
1110 exit(1);
1111 }
1112 if (info->initrd_start + initrd_size > ram_end) {
1113 error_report("could not load initrd '%s': "
1114 "too big to fit into RAM after the kernel",
1115 info->initrd_filename);
1116 exit(1);
1117 }
1118 } else {
1119 initrd_size = 0;
1120 }
1121 info->initrd_size = initrd_size;
1122
1123 fixupcontext[FIXUP_BOARDID] = info->board_id;
1124 fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
1125
1126
1127
1128
1129
1130 if (have_dtb(info)) {
1131 hwaddr align;
1132
1133 if (elf_machine == EM_AARCH64) {
1134
1135
1136
1137
1138
1139
1140
1141 align = 2 * MiB;
1142 } else {
1143
1144
1145
1146
1147 align = 4 * KiB;
1148 }
1149
1150
1151 info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
1152 align);
1153 if (info->dtb_start >= ram_end) {
1154 error_report("Not enough space for DTB after kernel/initrd");
1155 exit(1);
1156 }
1157 fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
1158 fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
1159 } else {
1160 fixupcontext[FIXUP_ARGPTR_LO] =
1161 info->loader_start + KERNEL_ARGS_ADDR;
1162 fixupcontext[FIXUP_ARGPTR_HI] =
1163 (info->loader_start + KERNEL_ARGS_ADDR) >> 32;
1164 if (info->ram_size >= 4 * GiB) {
1165 error_report("RAM size must be less than 4GB to boot"
1166 " Linux kernel using ATAGS (try passing a device tree"
1167 " using -dtb)");
1168 exit(1);
1169 }
1170 }
1171 fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
1172 fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
1173
1174 write_bootloader("bootloader", info->loader_start,
1175 primary_loader, fixupcontext, as);
1176
1177 if (info->write_board_setup) {
1178 info->write_board_setup(cpu, info);
1179 }
1180
1181
1182
1183
1184
1185 object_child_foreach_recursive(object_get_root(),
1186 do_arm_linux_init, info);
1187 }
1188 info->is_linux = is_linux;
1189
1190 for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
1191 ARM_CPU(cs)->env.boot_info = info;
1192 }
1193}
1194
1195static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info)
1196{
1197
1198
1199 if (have_dtb(info)) {
1200
1201
1202
1203
1204
1205 info->dtb_start = info->loader_start;
1206 }
1207
1208 if (info->kernel_filename) {
1209 FWCfgState *fw_cfg;
1210 bool try_decompressing_kernel;
1211
1212 fw_cfg = fw_cfg_find();
1213
1214 if (!fw_cfg) {
1215 error_report("This machine type does not support loading both "
1216 "a guest firmware/BIOS image and a guest kernel at "
1217 "the same time. You should change your QEMU command "
1218 "line to specify one or the other, but not both.");
1219 exit(1);
1220 }
1221
1222 try_decompressing_kernel = arm_feature(&cpu->env,
1223 ARM_FEATURE_AARCH64);
1224
1225
1226
1227
1228
1229
1230 load_image_to_fw_cfg(fw_cfg,
1231 FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
1232 info->kernel_filename,
1233 try_decompressing_kernel);
1234 load_image_to_fw_cfg(fw_cfg,
1235 FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
1236 info->initrd_filename, false);
1237
1238 if (info->kernel_cmdline) {
1239 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
1240 strlen(info->kernel_cmdline) + 1);
1241 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
1242 info->kernel_cmdline);
1243 }
1244 }
1245
1246
1247
1248
1249
1250
1251}
1252
1253void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info)
1254{
1255 CPUState *cs;
1256 AddressSpace *as = arm_boot_address_space(cpu, info);
1257 int boot_el;
1258 CPUARMState *env = &cpu->env;
1259 int nb_cpus = 0;
1260
1261
1262
1263
1264
1265
1266
1267 for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
1268 qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
1269 nb_cpus++;
1270 }
1271
1272
1273
1274
1275
1276
1277 assert(!(info->secure_board_setup && kvm_enabled()));
1278 info->kernel_filename = ms->kernel_filename;
1279 info->kernel_cmdline = ms->kernel_cmdline;
1280 info->initrd_filename = ms->initrd_filename;
1281 info->dtb_filename = ms->dtb;
1282 info->dtb_limit = 0;
1283
1284
1285 if (!info->kernel_filename || info->firmware_loaded) {
1286 arm_setup_firmware_boot(cpu, info);
1287 } else {
1288 arm_setup_direct_kernel_boot(cpu, info);
1289 }
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306 assert(info->psci_conduit == QEMU_PSCI_CONDUIT_DISABLED ||
1307 !info->secure_board_setup);
1308
1309
1310 if (arm_feature(env, ARM_FEATURE_EL3)) {
1311 boot_el = 3;
1312 } else if (arm_feature(env, ARM_FEATURE_EL2)) {
1313 boot_el = 2;
1314 } else {
1315 boot_el = 1;
1316 }
1317
1318 if (info->is_linux && !info->secure_boot) {
1319 boot_el = arm_feature(env, ARM_FEATURE_EL2) ? 2 : 1;
1320 }
1321
1322 if ((info->psci_conduit == QEMU_PSCI_CONDUIT_HVC && boot_el >= 2) ||
1323 (info->psci_conduit == QEMU_PSCI_CONDUIT_SMC && boot_el == 3)) {
1324 info->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
1325 }
1326
1327 if (info->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
1328 for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
1329 Object *cpuobj = OBJECT(cs);
1330
1331 object_property_set_int(cpuobj, "psci-conduit", info->psci_conduit,
1332 &error_abort);
1333
1334
1335
1336
1337
1338 if (cs != first_cpu) {
1339 object_property_set_bool(cpuobj, "start-powered-off", true,
1340 &error_abort);
1341 }
1342 }
1343 }
1344
1345 if (info->psci_conduit == QEMU_PSCI_CONDUIT_DISABLED &&
1346 info->is_linux && nb_cpus > 1) {
1347
1348
1349
1350
1351
1352 if (!info->secondary_cpu_reset_hook) {
1353 info->secondary_cpu_reset_hook = default_reset_secondary;
1354 }
1355 if (!info->write_secondary_boot) {
1356 info->write_secondary_boot = default_write_secondary;
1357 }
1358 info->write_secondary_boot(cpu, info);
1359 } else {
1360
1361
1362
1363
1364 info->write_secondary_boot = NULL;
1365 info->secondary_cpu_reset_hook = NULL;
1366 }
1367
1368
1369
1370
1371
1372 if (!info->skip_dtb_autoload && have_dtb(info)) {
1373 if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) {
1374 exit(1);
1375 }
1376 }
1377}
1378
1379static const TypeInfo arm_linux_boot_if_info = {
1380 .name = TYPE_ARM_LINUX_BOOT_IF,
1381 .parent = TYPE_INTERFACE,
1382 .class_size = sizeof(ARMLinuxBootIfClass),
1383};
1384
1385static void arm_linux_boot_register_types(void)
1386{
1387 type_register_static(&arm_linux_boot_if_info);
1388}
1389
1390type_init(arm_linux_boot_register_types)
1391