1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qapi/error.h"
12#include <libfdt.h>
13#include "hw/hw.h"
14#include "hw/arm/arm.h"
15#include "hw/arm/linux-boot-if.h"
16#include "sysemu/kvm.h"
17#include "sysemu/sysemu.h"
18#include "sysemu/numa.h"
19#include "hw/boards.h"
20#include "hw/loader.h"
21#include "elf.h"
22#include "sysemu/device_tree.h"
23#include "qemu/config-file.h"
24#include "exec/address-spaces.h"
25
26#include <libfdt.h>
27
28
29
30
31
32#define KERNEL_ARGS_ADDR 0x100
33#define KERNEL_LOAD_ADDR 0x00010000
34#define KERNEL64_LOAD_ADDR 0x00080000
35
36#define ARM64_TEXT_OFFSET_OFFSET 8
37#define ARM64_MAGIC_OFFSET 56
38
39typedef enum {
40 FIXUP_NONE = 0,
41 FIXUP_TERMINATOR,
42 FIXUP_BOARDID,
43 FIXUP_BOARD_SETUP,
44 FIXUP_ARGPTR,
45 FIXUP_ENTRYPOINT,
46 FIXUP_GIC_CPU_IF,
47 FIXUP_BOOTREG,
48 FIXUP_DSB,
49 FIXUP_MAX,
50} FixupType;
51
52typedef struct ARMInsnFixup {
53 uint32_t insn;
54 FixupType fixup;
55} ARMInsnFixup;
56
57static const ARMInsnFixup bootloader_aarch64[] = {
58 { 0x580000c0 },
59 { 0xaa1f03e1 },
60 { 0xaa1f03e2 },
61 { 0xaa1f03e3 },
62 { 0x58000084 },
63 { 0xd61f0080 },
64 { 0, FIXUP_ARGPTR },
65 { 0 },
66 { 0, FIXUP_ENTRYPOINT },
67 { 0 },
68 { 0, FIXUP_TERMINATOR }
69};
70
71
72
73
74
75
76
77static const ARMInsnFixup bootloader[] = {
78 { 0xe28fe004 },
79 { 0xe51ff004 },
80 { 0, FIXUP_BOARD_SETUP },
81#define BOOTLOADER_NO_BOARD_SETUP_OFFSET 3
82 { 0xe3a00000 },
83 { 0xe59f1004 },
84 { 0xe59f2004 },
85 { 0xe59ff004 },
86 { 0, FIXUP_BOARDID },
87 { 0, FIXUP_ARGPTR },
88 { 0, FIXUP_ENTRYPOINT },
89 { 0, FIXUP_TERMINATOR }
90};
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106#define DSB_INSN 0xf57ff04f
107#define CP15_DSB_INSN 0xee070f9a
108
109static const ARMInsnFixup smpboot[] = {
110 { 0xe59f2028 },
111 { 0xe59f0028 },
112 { 0xe3a01001 },
113 { 0xe5821000 },
114 { 0xe3a010ff },
115 { 0xe5821004 },
116 { 0, FIXUP_DSB },
117 { 0xe320f003 },
118 { 0xe5901000 },
119 { 0xe1110001 },
120 { 0x0afffffb },
121 { 0xe12fff11 },
122 { 0, FIXUP_GIC_CPU_IF },
123 { 0, FIXUP_BOOTREG },
124 { 0, FIXUP_TERMINATOR }
125};
126
127static void write_bootloader(const char *name, hwaddr addr,
128 const ARMInsnFixup *insns, uint32_t *fixupcontext)
129{
130
131
132
133
134
135 int i, len;
136 uint32_t *code;
137
138 len = 0;
139 while (insns[len].fixup != FIXUP_TERMINATOR) {
140 len++;
141 }
142
143 code = g_new0(uint32_t, len);
144
145 for (i = 0; i < len; i++) {
146 uint32_t insn = insns[i].insn;
147 FixupType fixup = insns[i].fixup;
148
149 switch (fixup) {
150 case FIXUP_NONE:
151 break;
152 case FIXUP_BOARDID:
153 case FIXUP_BOARD_SETUP:
154 case FIXUP_ARGPTR:
155 case FIXUP_ENTRYPOINT:
156 case FIXUP_GIC_CPU_IF:
157 case FIXUP_BOOTREG:
158 case FIXUP_DSB:
159 insn = fixupcontext[fixup];
160 break;
161 default:
162 abort();
163 }
164 code[i] = tswap32(insn);
165 }
166
167 rom_add_blob_fixed(name, code, len * sizeof(uint32_t), addr);
168
169 g_free(code);
170}
171
172static void default_write_secondary(ARMCPU *cpu,
173 const struct arm_boot_info *info)
174{
175 uint32_t fixupcontext[FIXUP_MAX];
176
177 fixupcontext[FIXUP_GIC_CPU_IF] = info->gic_cpu_if_addr;
178 fixupcontext[FIXUP_BOOTREG] = info->smp_bootreg_addr;
179 if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
180 fixupcontext[FIXUP_DSB] = DSB_INSN;
181 } else {
182 fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
183 }
184
185 write_bootloader("smpboot", info->smp_loader_start,
186 smpboot, fixupcontext);
187}
188
189void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
190 const struct arm_boot_info *info,
191 hwaddr mvbar_addr)
192{
193 int n;
194 uint32_t mvbar_blob[] = {
195
196
197
198
199 0xeafffffe,
200 0xeafffffe,
201 0xe1b0f00e,
202 0xeafffffe,
203 0xeafffffe,
204 0xeafffffe,
205 0xeafffffe,
206 0xeafffffe,
207 };
208 uint32_t board_setup_blob[] = {
209
210 0xe3a00e00 + (mvbar_addr >> 4),
211 0xee0c0f30,
212 0xee110f11,
213 0xe3800031,
214 0xee010f11,
215 0xe1a0100e,
216 0xe1600070,
217 0xe1a0f001,
218 };
219
220
221 assert((mvbar_addr & 0x1f) == 0 && (mvbar_addr >> 4) < 0x100);
222
223
224 assert((mvbar_addr + sizeof(mvbar_blob) <= info->board_setup_addr)
225 || (info->board_setup_addr + sizeof(board_setup_blob) <= mvbar_addr));
226
227 for (n = 0; n < ARRAY_SIZE(mvbar_blob); n++) {
228 mvbar_blob[n] = tswap32(mvbar_blob[n]);
229 }
230 rom_add_blob_fixed("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob),
231 mvbar_addr);
232
233 for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
234 board_setup_blob[n] = tswap32(board_setup_blob[n]);
235 }
236 rom_add_blob_fixed("board-setup", board_setup_blob,
237 sizeof(board_setup_blob), info->board_setup_addr);
238}
239
240static void default_reset_secondary(ARMCPU *cpu,
241 const struct arm_boot_info *info)
242{
243 CPUState *cs = CPU(cpu);
244
245 address_space_stl_notdirty(&address_space_memory, info->smp_bootreg_addr,
246 0, MEMTXATTRS_UNSPECIFIED, NULL);
247 cpu_set_pc(cs, info->smp_loader_start);
248}
249
250static inline bool have_dtb(const struct arm_boot_info *info)
251{
252 return info->dtb_filename || info->get_dtb;
253}
254
255#define WRITE_WORD(p, value) do { \
256 address_space_stl_notdirty(&address_space_memory, p, value, \
257 MEMTXATTRS_UNSPECIFIED, NULL); \
258 p += 4; \
259} while (0)
260
261static void set_kernel_args(const struct arm_boot_info *info)
262{
263 int initrd_size = info->initrd_size;
264 hwaddr base = info->loader_start;
265 hwaddr p;
266
267 p = base + KERNEL_ARGS_ADDR;
268
269 WRITE_WORD(p, 5);
270 WRITE_WORD(p, 0x54410001);
271 WRITE_WORD(p, 1);
272 WRITE_WORD(p, 0x1000);
273 WRITE_WORD(p, 0);
274
275
276 WRITE_WORD(p, 4);
277 WRITE_WORD(p, 0x54410002);
278 WRITE_WORD(p, info->ram_size);
279 WRITE_WORD(p, info->loader_start);
280 if (initrd_size) {
281
282 WRITE_WORD(p, 4);
283 WRITE_WORD(p, 0x54420005);
284 WRITE_WORD(p, info->initrd_start);
285 WRITE_WORD(p, initrd_size);
286 }
287 if (info->kernel_cmdline && *info->kernel_cmdline) {
288
289 int cmdline_size;
290
291 cmdline_size = strlen(info->kernel_cmdline);
292 cpu_physical_memory_write(p + 8, info->kernel_cmdline,
293 cmdline_size + 1);
294 cmdline_size = (cmdline_size >> 2) + 1;
295 WRITE_WORD(p, cmdline_size + 2);
296 WRITE_WORD(p, 0x54410009);
297 p += cmdline_size * 4;
298 }
299 if (info->atag_board) {
300
301 int atag_board_len;
302 uint8_t atag_board_buf[0x1000];
303
304 atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3;
305 WRITE_WORD(p, (atag_board_len + 8) >> 2);
306 WRITE_WORD(p, 0x414f4d50);
307 cpu_physical_memory_write(p, atag_board_buf, atag_board_len);
308 p += atag_board_len;
309 }
310
311 WRITE_WORD(p, 0);
312 WRITE_WORD(p, 0);
313}
314
315static void set_kernel_args_old(const struct arm_boot_info *info)
316{
317 hwaddr p;
318 const char *s;
319 int initrd_size = info->initrd_size;
320 hwaddr base = info->loader_start;
321
322
323 p = base + KERNEL_ARGS_ADDR;
324
325 WRITE_WORD(p, 4096);
326
327 WRITE_WORD(p, info->ram_size / 4096);
328
329 WRITE_WORD(p, 0);
330#define FLAG_READONLY 1
331#define FLAG_RDLOAD 4
332#define FLAG_RDPROMPT 8
333
334 WRITE_WORD(p, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT);
335
336 WRITE_WORD(p, (31 << 8) | 0);
337
338 WRITE_WORD(p, 0);
339
340 WRITE_WORD(p, 0);
341
342 WRITE_WORD(p, 0);
343
344 WRITE_WORD(p, 0);
345
346 WRITE_WORD(p, 0);
347
348
349
350
351 WRITE_WORD(p, 0);
352
353 WRITE_WORD(p, 0);
354 WRITE_WORD(p, 0);
355 WRITE_WORD(p, 0);
356 WRITE_WORD(p, 0);
357
358 WRITE_WORD(p, 0);
359
360 if (initrd_size) {
361 WRITE_WORD(p, info->initrd_start);
362 } else {
363 WRITE_WORD(p, 0);
364 }
365
366 WRITE_WORD(p, initrd_size);
367
368 WRITE_WORD(p, 0);
369
370 WRITE_WORD(p, 0);
371
372 WRITE_WORD(p, 0);
373
374 WRITE_WORD(p, 0);
375
376 WRITE_WORD(p, 0);
377
378 while (p < base + KERNEL_ARGS_ADDR + 256 + 1024) {
379 WRITE_WORD(p, 0);
380 }
381 s = info->kernel_cmdline;
382 if (s) {
383 cpu_physical_memory_write(p, s, strlen(s) + 1);
384 } else {
385 WRITE_WORD(p, 0);
386 }
387}
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
410 hwaddr addr_limit)
411{
412 void *fdt = NULL;
413 int size, rc;
414 uint32_t acells, scells;
415 char *nodename;
416 unsigned int i;
417 hwaddr mem_base, mem_len;
418
419 if (binfo->dtb_filename) {
420 char *filename;
421 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
422 if (!filename) {
423 fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
424 goto fail;
425 }
426
427 fdt = load_device_tree(filename, &size);
428 if (!fdt) {
429 fprintf(stderr, "Couldn't open dtb file %s\n", filename);
430 g_free(filename);
431 goto fail;
432 }
433 g_free(filename);
434 } else {
435 fdt = binfo->get_dtb(binfo, &size);
436 if (!fdt) {
437 fprintf(stderr, "Board was unable to create a dtb blob\n");
438 goto fail;
439 }
440 }
441
442 if (addr_limit > addr && size > (addr_limit - addr)) {
443
444
445
446
447 g_free(fdt);
448 return 0;
449 }
450
451 acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", 0,
452 false, &error_abort);
453 scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", 0,
454 false, &error_abort);
455 if (acells == 0 || scells == 0) {
456 fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
457 goto fail;
458 }
459
460 if (scells < 2 && binfo->ram_size >= (1ULL << 32)) {
461
462
463
464 fprintf(stderr, "qemu: dtb file not compatible with "
465 "RAM size > 4GB\n");
466 goto fail;
467 }
468
469 if (nb_numa_nodes > 0) {
470
471
472
473
474 qemu_fdt_nop_node(fdt, "/memory");
475 mem_base = binfo->loader_start;
476 for (i = 0; i < nb_numa_nodes; i++) {
477 mem_len = numa_info[i].node_mem;
478 nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
479 qemu_fdt_add_subnode(fdt, nodename);
480 qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
481 rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
482 acells, mem_base,
483 scells, mem_len);
484 if (rc < 0) {
485 fprintf(stderr, "couldn't set %s/reg for node %d\n", nodename,
486 i);
487 goto fail;
488 }
489
490 qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", i);
491 mem_base += mem_len;
492 g_free(nodename);
493 }
494 } else {
495 Error *err = NULL;
496
497 rc = fdt_path_offset(fdt, "/memory");
498 if (rc < 0) {
499 qemu_fdt_add_subnode(fdt, "/memory");
500 }
501
502 if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, false,
503 &err)) {
504 qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
505 }
506
507 rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
508 acells, binfo->loader_start,
509 scells, binfo->ram_size);
510 if (rc < 0) {
511 fprintf(stderr, "couldn't set /memory/reg\n");
512 goto fail;
513 }
514 }
515
516 rc = fdt_path_offset(fdt, "/chosen");
517 if (rc < 0) {
518 qemu_fdt_add_subnode(fdt, "/chosen");
519 }
520
521 if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
522 rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
523 binfo->kernel_cmdline);
524 if (rc < 0) {
525 fprintf(stderr, "couldn't set /chosen/bootargs\n");
526 goto fail;
527 }
528 }
529
530 if (binfo->initrd_size) {
531 rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
532 binfo->initrd_start);
533 if (rc < 0) {
534 fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
535 goto fail;
536 }
537
538 rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
539 binfo->initrd_start + binfo->initrd_size);
540 if (rc < 0) {
541 fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
542 goto fail;
543 }
544 }
545
546 if (binfo->modify_dtb) {
547 binfo->modify_dtb(binfo, fdt);
548 }
549
550 qemu_fdt_dumpdtb(fdt, size);
551
552
553
554
555 rom_add_blob_fixed("dtb", fdt, size, addr);
556
557 g_free(fdt);
558
559 return size;
560
561fail:
562 g_free(fdt);
563 return -1;
564}
565
566static void do_cpu_reset(void *opaque)
567{
568 ARMCPU *cpu = opaque;
569 CPUState *cs = CPU(cpu);
570 CPUARMState *env = &cpu->env;
571 const struct arm_boot_info *info = env->boot_info;
572
573 cpu_reset(cs);
574 if (info) {
575 if (!info->is_linux) {
576 int i;
577
578 uint64_t entry = info->entry;
579
580 switch (info->endianness) {
581 case ARM_ENDIANNESS_LE:
582 env->cp15.sctlr_el[1] &= ~SCTLR_E0E;
583 for (i = 1; i < 4; ++i) {
584 env->cp15.sctlr_el[i] &= ~SCTLR_EE;
585 }
586 env->uncached_cpsr &= ~CPSR_E;
587 break;
588 case ARM_ENDIANNESS_BE8:
589 env->cp15.sctlr_el[1] |= SCTLR_E0E;
590 for (i = 1; i < 4; ++i) {
591 env->cp15.sctlr_el[i] |= SCTLR_EE;
592 }
593 env->uncached_cpsr |= CPSR_E;
594 break;
595 case ARM_ENDIANNESS_BE32:
596 env->cp15.sctlr_el[1] |= SCTLR_B;
597 break;
598 case ARM_ENDIANNESS_UNKNOWN:
599 break;
600 default:
601 g_assert_not_reached();
602 }
603
604 if (!env->aarch64) {
605 env->thumb = info->entry & 1;
606 entry &= 0xfffffffe;
607 }
608 cpu_set_pc(cs, entry);
609 } else {
610
611
612
613
614
615
616 if (arm_feature(env, ARM_FEATURE_EL3)) {
617
618
619
620
621
622
623 if (env->aarch64) {
624 env->cp15.scr_el3 |= SCR_RW;
625 if (arm_feature(env, ARM_FEATURE_EL2)) {
626 env->cp15.hcr_el2 |= HCR_RW;
627 env->pstate = PSTATE_MODE_EL2h;
628 } else {
629 env->pstate = PSTATE_MODE_EL1h;
630 }
631 }
632
633 if (arm_feature(env, ARM_FEATURE_EL2)) {
634
635 env->cp15.scr_el3 |= SCR_HCE;
636 }
637
638
639 if (!info->secure_boot &&
640 (cs != first_cpu || !info->secure_board_setup)) {
641
642 env->cp15.scr_el3 |= SCR_NS;
643 }
644 }
645
646 if (cs == first_cpu) {
647 cpu_set_pc(cs, info->loader_start);
648 cs->halt_pin = false;
649 cpu_reset_interrupt(cs, CPU_INTERRUPT_HALT);
650
651 if (!have_dtb(info)) {
652 if (old_param) {
653 set_kernel_args_old(info);
654 } else {
655 set_kernel_args(info);
656 }
657 }
658 } else {
659 info->secondary_cpu_reset_hook(cpu, info);
660 }
661 }
662 }
663}
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
683 uint16_t data_key, const char *image_name,
684 bool try_decompress)
685{
686 size_t size = -1;
687 uint8_t *data;
688
689 if (image_name == NULL) {
690 return;
691 }
692
693 if (try_decompress) {
694 size = load_image_gzipped_buffer(image_name,
695 LOAD_IMAGE_MAX_GUNZIP_BYTES, &data);
696 }
697
698 if (size == (size_t)-1) {
699 gchar *contents;
700 gsize length;
701
702 if (!g_file_get_contents(image_name, &contents, &length, NULL)) {
703 fprintf(stderr, "failed to load \"%s\"\n", image_name);
704 exit(1);
705 }
706 size = length;
707 data = (uint8_t *)contents;
708 }
709
710 fw_cfg_add_i32(fw_cfg, size_key, size);
711 fw_cfg_add_bytes(fw_cfg, data_key, data, size);
712}
713
714static int do_arm_linux_init(Object *obj, void *opaque)
715{
716 if (object_dynamic_cast(obj, TYPE_ARM_LINUX_BOOT_IF)) {
717 ARMLinuxBootIf *albif = ARM_LINUX_BOOT_IF(obj);
718 ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_GET_CLASS(obj);
719 struct arm_boot_info *info = opaque;
720
721 if (albifc->arm_linux_init) {
722 albifc->arm_linux_init(albif, info->secure_boot);
723 }
724 }
725 return 0;
726}
727
728static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
729 uint64_t *lowaddr, uint64_t *highaddr,
730 int elf_machine)
731{
732 bool elf_is64;
733 union {
734 Elf32_Ehdr h32;
735 Elf64_Ehdr h64;
736 } elf_header;
737 int data_swab = 0;
738 bool big_endian;
739 uint64_t ret = -1;
740 Error *err = NULL;
741
742
743 load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
744 if (err) {
745 return ret;
746 }
747
748 if (elf_is64) {
749 big_endian = elf_header.h64.e_ident[EI_DATA] == ELFDATA2MSB;
750 info->endianness = big_endian ? ARM_ENDIANNESS_BE8
751 : ARM_ENDIANNESS_LE;
752 } else {
753 big_endian = elf_header.h32.e_ident[EI_DATA] == ELFDATA2MSB;
754 if (big_endian) {
755 if (bswap32(elf_header.h32.e_flags) & EF_ARM_BE8) {
756 info->endianness = ARM_ENDIANNESS_BE8;
757 } else {
758 info->endianness = ARM_ENDIANNESS_BE32;
759
760
761
762
763
764
765
766 data_swab = 2;
767 }
768 } else {
769 info->endianness = ARM_ENDIANNESS_LE;
770 }
771 }
772
773 ret = load_elf(info->kernel_filename, NULL, NULL,
774 pentry, lowaddr, highaddr, big_endian, elf_machine,
775 1, data_swab);
776 if (ret <= 0) {
777
778 exit(1);
779 }
780
781 return ret;
782}
783
784static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
785 hwaddr *entry)
786{
787 hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
788 uint8_t *buffer;
789 int size;
790
791
792 size = load_image_gzipped_buffer(filename, LOAD_IMAGE_MAX_GUNZIP_BYTES,
793 &buffer);
794
795 if (size < 0) {
796 gsize len;
797
798
799 if (!g_file_get_contents(filename, (char **)&buffer, &len, NULL)) {
800 return -1;
801 }
802 size = len;
803 }
804
805
806 if (memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
807 uint64_t hdrvals[2];
808
809
810
811
812
813 memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
814 if (hdrvals[1] != 0) {
815 kernel_load_offset = le64_to_cpu(hdrvals[0]);
816 }
817 }
818
819 *entry = mem_base + kernel_load_offset;
820 rom_add_blob_fixed(filename, buffer, size, *entry);
821
822 g_free(buffer);
823
824 return size;
825}
826
827static void arm_load_kernel_notify(Notifier *notifier, void *data)
828{
829 CPUState *cs;
830 int kernel_size;
831 int initrd_size;
832 int is_linux = 0;
833 uint64_t elf_entry, elf_low_addr, elf_high_addr;
834 int elf_machine;
835 hwaddr entry;
836 static const ARMInsnFixup *primary_loader;
837 ArmLoadKernelNotifier *n = DO_UPCAST(ArmLoadKernelNotifier,
838 notifier, notifier);
839 ARMCPU *cpu = n->cpu;
840 struct arm_boot_info *info =
841 container_of(n, struct arm_boot_info, load_kernel_notifier);
842
843
844
845
846
847 assert(!(info->secure_board_setup && kvm_enabled()));
848
849 info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
850
851
852 if (!info->kernel_filename || info->firmware_loaded) {
853
854 if (have_dtb(info)) {
855
856
857
858
859 if (load_dtb(info->loader_start, info, 0) < 0) {
860 exit(1);
861 }
862 }
863
864 if (info->kernel_filename) {
865 FWCfgState *fw_cfg;
866 bool try_decompressing_kernel;
867
868 fw_cfg = fw_cfg_find();
869 try_decompressing_kernel = arm_feature(&cpu->env,
870 ARM_FEATURE_AARCH64);
871
872
873
874
875
876 load_image_to_fw_cfg(fw_cfg,
877 FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
878 info->kernel_filename,
879 try_decompressing_kernel);
880 load_image_to_fw_cfg(fw_cfg,
881 FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
882 info->initrd_filename, false);
883
884 if (info->kernel_cmdline) {
885 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
886 strlen(info->kernel_cmdline) + 1);
887 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
888 info->kernel_cmdline);
889 }
890 }
891
892
893
894
895 return;
896 }
897
898 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
899 primary_loader = bootloader_aarch64;
900 elf_machine = EM_AARCH64;
901 } else {
902 primary_loader = bootloader;
903 if (!info->write_board_setup) {
904 primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
905 }
906 elf_machine = EM_ARM;
907 }
908
909 info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
910 is_linux = object_property_get_bool(OBJECT(qdev_get_machine()),
911 "linux", NULL);
912
913 if (!info->secondary_cpu_reset_hook) {
914 info->secondary_cpu_reset_hook = default_reset_secondary;
915 }
916 if (!info->write_secondary_boot) {
917 info->write_secondary_boot = default_write_secondary;
918 }
919
920 if (info->nb_cpus == 0)
921 info->nb_cpus = 1;
922
923
924
925
926
927
928
929
930
931
932
933 info->initrd_start = info->loader_start +
934 MIN(info->ram_size / 2, 128 * 1024 * 1024);
935
936
937
938
939
940 kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
941 &elf_high_addr, 0);
942 if (kernel_size > 0 && have_dtb(info)) {
943
944
945
946 if (elf_low_addr > info->loader_start
947 || elf_high_addr < info->loader_start) {
948
949
950
951 if (elf_low_addr < info->loader_start) {
952 elf_low_addr = 0;
953 }
954 if (load_dtb(info->loader_start, info, elf_low_addr) < 0) {
955 exit(1);
956 }
957 }
958 }
959 entry = elf_entry;
960 if (kernel_size < 0) {
961 kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
962 &is_linux, NULL, NULL);
963 }
964 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
965 kernel_size = load_aarch64_image(info->kernel_filename,
966 info->loader_start, &entry);
967 is_linux = 1;
968 } else if (kernel_size < 0) {
969
970 entry = info->loader_start + KERNEL_LOAD_ADDR;
971 kernel_size = load_image_targphys(info->kernel_filename, entry,
972 info->ram_size - KERNEL_LOAD_ADDR);
973 is_linux = 1;
974 }
975 if (kernel_size < 0) {
976 fprintf(stderr, "qemu: could not load kernel '%s'\n",
977 info->kernel_filename);
978 exit(1);
979 }
980 info->entry = entry;
981 if (is_linux) {
982 uint32_t fixupcontext[FIXUP_MAX];
983
984 if (info->initrd_filename) {
985 initrd_size = load_ramdisk(info->initrd_filename,
986 info->initrd_start,
987 info->ram_size -
988 info->initrd_start);
989 if (initrd_size < 0) {
990 initrd_size = load_image_targphys(info->initrd_filename,
991 info->initrd_start,
992 info->ram_size -
993 info->initrd_start);
994 }
995 if (initrd_size < 0) {
996 fprintf(stderr, "qemu: could not load initrd '%s'\n",
997 info->initrd_filename);
998 exit(1);
999 }
1000 } else {
1001 initrd_size = 0;
1002 }
1003 info->initrd_size = initrd_size;
1004
1005 fixupcontext[FIXUP_BOARDID] = info->board_id;
1006 fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
1007
1008 if (info->fdt && fdt_path_offset(info->fdt, "/psci") > 0) {
1009
1010
1011
1012
1013 char *method = NULL;
1014
1015 method = qemu_fdt_getprop_string(info->fdt, "/psci", "method",
1016 0, false, NULL);
1017
1018 for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
1019 if (!strcmp(method, "smc")) {
1020 cpu->psci_conduit = QEMU_PSCI_CONDUIT_SMC;
1021 } else if (!strcmp(method, "hvc")) {
1022 cpu->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
1023 }
1024 }
1025
1026 g_free(method);
1027 }
1028
1029
1030
1031
1032 if (have_dtb(info)) {
1033 hwaddr align;
1034 hwaddr dtb_start;
1035
1036 if (elf_machine == EM_AARCH64) {
1037
1038
1039
1040
1041
1042
1043
1044 align = 2 * 1024 * 1024;
1045 } else {
1046
1047
1048
1049
1050 align = 4096;
1051 }
1052
1053
1054 dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align);
1055 if (load_dtb(dtb_start, info, 0) < 0) {
1056 exit(1);
1057 }
1058 fixupcontext[FIXUP_ARGPTR] = dtb_start;
1059 } else {
1060 fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR;
1061 if (info->ram_size >= (1ULL << 32)) {
1062 fprintf(stderr, "qemu: RAM size must be less than 4GB to boot"
1063 " Linux kernel using ATAGS (try passing a device tree"
1064 " using -dtb)\n");
1065 exit(1);
1066 }
1067 }
1068 fixupcontext[FIXUP_ENTRYPOINT] = entry;
1069
1070 write_bootloader("bootloader", info->loader_start,
1071 primary_loader, fixupcontext);
1072
1073 if (info->nb_cpus > 1) {
1074 info->write_secondary_boot(cpu, info);
1075 }
1076 if (info->write_board_setup) {
1077 info->write_board_setup(cpu, info);
1078 }
1079
1080
1081
1082
1083 object_child_foreach_recursive(object_get_root(),
1084 do_arm_linux_init, info);
1085 }
1086 info->is_linux = is_linux;
1087
1088 for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
1089 ARM_CPU(cs)->env.boot_info = info;
1090 }
1091}
1092
1093void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
1094{
1095 CPUState *cs;
1096
1097 info->load_kernel_notifier.cpu = cpu;
1098 info->load_kernel_notifier.notifier.notify = arm_load_kernel_notify;
1099 qemu_add_machine_init_done_notifier(&info->load_kernel_notifier.notifier);
1100
1101
1102
1103
1104
1105
1106 for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
1107 qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
1108 }
1109}
1110
1111static const TypeInfo arm_linux_boot_if_info = {
1112 .name = TYPE_ARM_LINUX_BOOT_IF,
1113 .parent = TYPE_INTERFACE,
1114 .class_size = sizeof(ARMLinuxBootIfClass),
1115};
1116
1117static void arm_linux_boot_register_types(void)
1118{
1119 type_register_static(&arm_linux_boot_if_info);
1120}
1121
1122type_init(arm_linux_boot_register_types)
1123