From: Nicholas Piggin <[email protected]> This loads firmware into the first (low) memory range, accounting for machines having discontiguous memory regions.
Signed-off-by: Nicholas Piggin <[email protected]> Signed-off-by: Joel Stanley <[email protected]> --- include/hw/riscv/boot.h | 5 ++++- hw/riscv/boot.c | 18 ++++++++++++------ hw/riscv/microchip_pfsoc.c | 6 ++++-- hw/riscv/opentitan.c | 6 ++++-- hw/riscv/shakti_c.c | 6 +++++- hw/riscv/sifive_u.c | 3 ++- hw/riscv/spike.c | 6 ++++-- hw/riscv/virt.c | 7 ++++--- hw/riscv/xiangshan_kmh.c | 6 +++++- 9 files changed, 44 insertions(+), 19 deletions(-) diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 115e3222174f..fb90bf12399e 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -53,13 +53,16 @@ void riscv_boot_info_init_discontig_mem(RISCVBootInfo *info, vaddr riscv_calc_kernel_start_addr(RISCVBootInfo *info, hwaddr firmware_end_addr); hwaddr riscv_find_and_load_firmware(MachineState *machine, + RISCVBootInfo *info, const char *default_machine_firmware, hwaddr *firmware_load_addr, symbol_fn_t sym_cb); const char *riscv_default_firmware_name(RISCVHartArrayState *harts); char *riscv_find_firmware(const char *firmware_filename, const char *default_machine_firmware); -hwaddr riscv_load_firmware(const char *firmware_filename, +hwaddr riscv_load_firmware(MachineState *machine, + RISCVBootInfo *info, + const char *firmware_filename, hwaddr *firmware_load_addr, symbol_fn_t sym_cb); void riscv_load_kernel(MachineState *machine, diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 9babb85b0458..f3857e984240 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -145,6 +145,7 @@ char *riscv_find_firmware(const char *firmware_filename, } hwaddr riscv_find_and_load_firmware(MachineState *machine, + RISCVBootInfo *info, const char *default_machine_firmware, hwaddr *firmware_load_addr, symbol_fn_t sym_cb) @@ -157,7 +158,8 @@ hwaddr riscv_find_and_load_firmware(MachineState *machine, if (firmware_filename) { /* If not "none" load the firmware */ - firmware_end_addr = riscv_load_firmware(firmware_filename, + firmware_end_addr = riscv_load_firmware(machine, info, + firmware_filename, firmware_load_addr, sym_cb); g_free(firmware_filename); } @@ -165,10 +167,13 @@ hwaddr riscv_find_and_load_firmware(MachineState *machine, return firmware_end_addr; } -hwaddr riscv_load_firmware(const char *firmware_filename, +hwaddr riscv_load_firmware(MachineState *machine, + RISCVBootInfo *info, + const char *firmware_filename, hwaddr *firmware_load_addr, symbol_fn_t sym_cb) { + uint64_t mem_size = info->ram_low_size ?: machine->ram_size; uint64_t firmware_entry, firmware_end; ssize_t firmware_size; @@ -183,7 +188,7 @@ hwaddr riscv_load_firmware(const char *firmware_filename, firmware_size = load_image_targphys_as(firmware_filename, *firmware_load_addr, - current_machine->ram_size, NULL, + mem_size, NULL, NULL); if (firmware_size > 0) { @@ -197,7 +202,7 @@ hwaddr riscv_load_firmware(const char *firmware_filename, static void riscv_load_initrd(MachineState *machine, RISCVBootInfo *info) { const char *filename = machine->initrd_filename; - uint64_t mem_size = machine->ram_size; + uint64_t mem_size = info->ram_low_size ?: machine->ram_size; void *fdt = machine->fdt; hwaddr start, end; ssize_t size; @@ -243,6 +248,7 @@ void riscv_load_kernel(MachineState *machine, bool load_initrd, symbol_fn_t sym_cb) { + uint64_t mem_size = info->ram_low_size ?: machine->ram_size; const char *kernel_filename = machine->kernel_filename; ssize_t kernel_size; void *fdt = machine->fdt; @@ -274,7 +280,7 @@ void riscv_load_kernel(MachineState *machine, } kernel_size = load_image_targphys_as(kernel_filename, kernel_start_addr, - current_machine->ram_size, NULL, NULL); + mem_size, NULL, NULL); if (kernel_size > 0) { info->kernel_size = kernel_size; info->image_low_addr = kernel_start_addr; @@ -370,7 +376,7 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size, dtb_start = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); if (dtb_start_limit && (dtb_start < dtb_start_limit)) { - error_report("No enough memory to place DTB after kernel/initrd"); + error_report("Not enough memory to place DTB after kernel/initrd"); exit(1); } diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 4ff83e494034..8905ed0ba190 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -615,18 +615,20 @@ static void microchip_icicle_kit_machine_init(MachineState *machine) firmware_load_addr = RESET_VECTOR; } + riscv_boot_info_init(&boot_info, &s->soc.u_cpus); + /* Load the firmware if necessary */ firmware_end_addr = firmware_load_addr; if (firmware_name) { char *filename = riscv_find_firmware(firmware_name, NULL); if (filename) { - firmware_end_addr = riscv_load_firmware(filename, + firmware_end_addr = riscv_load_firmware(machine, &boot_info, + filename, &firmware_load_addr, NULL); g_free(filename); } } - riscv_boot_info_init(&boot_info, &s->soc.u_cpus); if (machine->kernel_filename) { kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr); diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c index 309125e854bc..8cd660dd4154 100644 --- a/hw/riscv/opentitan.c +++ b/hw/riscv/opentitan.c @@ -99,12 +99,14 @@ static void opentitan_machine_init(MachineState *machine) memory_region_add_subregion(sys_mem, memmap[IBEX_DEV_RAM].base, machine->ram); + riscv_boot_info_init(&boot_info, &s->soc.cpus); + if (machine->firmware) { hwaddr firmware_load_addr = memmap[IBEX_DEV_RAM].base; - riscv_load_firmware(machine->firmware, &firmware_load_addr, NULL); + riscv_load_firmware(machine, &boot_info, machine->firmware, + &firmware_load_addr, NULL); } - riscv_boot_info_init(&boot_info, &s->soc.cpus); if (machine->kernel_filename) { riscv_load_kernel(machine, &boot_info, memmap[IBEX_DEV_RAM].base, diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c index 49a39b30212d..eb720d9cdf5d 100644 --- a/hw/riscv/shakti_c.c +++ b/hw/riscv/shakti_c.c @@ -45,6 +45,7 @@ static void shakti_c_machine_state_init(MachineState *mstate) { ShaktiCMachineState *sms = RISCV_SHAKTI_MACHINE(mstate); MemoryRegion *system_memory = get_system_memory(); + RISCVBootInfo boot_info; hwaddr firmware_load_addr = shakti_c_memmap[SHAKTI_C_RAM].base; /* Initialize SoC */ @@ -57,8 +58,11 @@ static void shakti_c_machine_state_init(MachineState *mstate) shakti_c_memmap[SHAKTI_C_RAM].base, mstate->ram); + riscv_boot_info_init(&boot_info, &sms->soc.cpus); + if (mstate->firmware) { - riscv_load_firmware(mstate->firmware, &firmware_load_addr, NULL); + riscv_load_firmware(mstate, &boot_info, mstate->firmware, + &firmware_load_addr, NULL); } /* ROM reset vector */ diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 7ec67b256514..4c526f73edf6 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -590,7 +590,8 @@ static void sifive_u_machine_init(MachineState *machine) } firmware_name = riscv_default_firmware_name(&s->soc.u_cpus); - firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name, + firmware_end_addr = riscv_find_and_load_firmware(machine, &boot_info, + firmware_name, &start_addr, NULL); riscv_boot_info_init(&boot_info, &s->soc.u_cpus); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 1493b928dad3..86b06a173565 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -289,9 +289,12 @@ static void spike_board_init(MachineState *machine) } } + riscv_boot_info_init(&boot_info, &s->soc[0]); + /* Load firmware */ if (firmware_name) { - firmware_end_addr = riscv_load_firmware(firmware_name, + firmware_end_addr = riscv_load_firmware(machine, &boot_info, + firmware_name, &firmware_load_addr, htif_symbol_callback); g_free(firmware_name); @@ -301,7 +304,6 @@ static void spike_board_init(MachineState *machine) create_fdt(s, memmap, riscv_is_32bit(&s->soc[0]), htif_custom_base); /* Load kernel */ - riscv_boot_info_init(&boot_info, &s->soc[0]); if (machine->kernel_filename) { kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index bd8608ea5bfd..a907ca359e09 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1466,7 +1466,10 @@ static void virt_machine_done(Notifier *notifier, void *data) } } - firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name, + riscv_boot_info_init(&boot_info, &s->soc[0]); + + firmware_end_addr = riscv_find_and_load_firmware(machine, &boot_info, + firmware_name, &start_addr, NULL); pflash_blk0 = pflash_cfi01_get_blk(s->flash[0]); @@ -1489,8 +1492,6 @@ static void virt_machine_done(Notifier *notifier, void *data) } } - riscv_boot_info_init(&boot_info, &s->soc[0]); - if (machine->kernel_filename && !kernel_entry) { kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr); diff --git a/hw/riscv/xiangshan_kmh.c b/hw/riscv/xiangshan_kmh.c index 436e51c1c593..247a0b5d1f21 100644 --- a/hw/riscv/xiangshan_kmh.c +++ b/hw/riscv/xiangshan_kmh.c @@ -166,6 +166,7 @@ static void xiangshan_kmh_machine_init(MachineState *machine) const MemMapEntry *memmap = xiangshan_kmh_memmap; MemoryRegion *system_memory = get_system_memory(); hwaddr start_addr = memmap[XIANGSHAN_KMH_DRAM].base; + RISCVBootInfo boot_info; /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, @@ -177,13 +178,16 @@ static void xiangshan_kmh_machine_init(MachineState *machine) memmap[XIANGSHAN_KMH_DRAM].base, machine->ram); + riscv_boot_info_init(&boot_info, &s->soc.cpus); + /* ROM reset vector */ riscv_setup_rom_reset_vec(machine, &s->soc.cpus, start_addr, memmap[XIANGSHAN_KMH_ROM].base, memmap[XIANGSHAN_KMH_ROM].size, 0, 0); if (machine->firmware) { - riscv_load_firmware(machine->firmware, &start_addr, NULL); + riscv_load_firmware(machine, &boot_info, machine->firmware, + &start_addr, NULL); } /* Note: dtb has been integrated into firmware(OpenSBI) when compiling */ -- 2.47.3
