On Wed, Jun 3, 2026 at 4:59 PM Joel Stanley <[email protected]> wrote: > > From: Nicholas Piggin <[email protected]> > > This loads firmware into the first (low) memory range, > accounting for machines having discontiguous memory regions. > > Reviewed-by: Daniel Henrique Barboza <[email protected]> > Signed-off-by: Nicholas Piggin <[email protected]> > Signed-off-by: Joel Stanley <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > include/hw/riscv/boot.h | 5 ++++- > hw/riscv/boot.c | 18 ++++++++++++------ > hw/riscv/microchip_pfsoc.c | 8 ++++++-- > hw/riscv/opentitan.c | 6 ++++-- > hw/riscv/shakti_c.c | 6 +++++- > hw/riscv/sifive_u.c | 6 ++++-- > hw/riscv/spike.c | 6 ++++-- > hw/riscv/virt.c | 7 ++++--- > hw/riscv/xiangshan_kmh.c | 6 +++++- > 9 files changed, 48 insertions(+), 20 deletions(-) > > diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h > index 69c99a149613..4e7bd9a225ef 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, > + const 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 b1a020b58aed..b0a2e384b1ae 100644 > --- a/hw/riscv/boot.c > +++ b/hw/riscv/boot.c > @@ -150,6 +150,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) > @@ -162,7 +163,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); > } > @@ -170,10 +172,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, > + const 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; > > @@ -202,7 +207,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) { > @@ -217,7 +222,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; > @@ -263,6 +268,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; > @@ -294,7 +300,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; > @@ -390,7 +396,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 5e48a2970838..4017129c8304 100644 > --- a/hw/riscv/microchip_pfsoc.c > +++ b/hw/riscv/microchip_pfsoc.c > @@ -619,18 +619,22 @@ static void > microchip_icicle_kit_machine_init(MachineState *machine) > firmware_load_addr = RESET_VECTOR; > } > > + riscv_boot_info_init_discontig_mem(&boot_info, &s->soc.u_cpus, > + memmap[MICROCHIP_PFSOC_DRAM_LO].base, > + mem_low_size); > + > /* 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 c8b2f028f237..5b2f33d5acac 100644 > --- a/hw/riscv/opentitan.c > +++ b/hw/riscv/opentitan.c > @@ -100,12 +100,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 b1823a312508..835b1f879b7f 100644 > --- a/hw/riscv/shakti_c.c > +++ b/hw/riscv/shakti_c.c > @@ -46,6 +46,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 */ > @@ -58,8 +59,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 6a637e3b86c4..3b2763de1684 100644 > --- a/hw/riscv/sifive_u.c > +++ b/hw/riscv/sifive_u.c > @@ -590,11 +590,13 @@ static void sifive_u_machine_init(MachineState *machine) > break; > } > > + riscv_boot_info_init(&boot_info, &s->soc.u_cpus); > + > 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); > if (machine->kernel_filename) { > kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info, > firmware_end_addr); > diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c > index f9d00e0d5c48..8d68b4e235dd 100644 > --- a/hw/riscv/spike.c > +++ b/hw/riscv/spike.c > @@ -282,9 +282,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); > @@ -294,7 +297,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 ce64eaaef7d9..febf49d5f149 100644 > --- a/hw/riscv/virt.c > +++ b/hw/riscv/virt.c > @@ -1458,7 +1458,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]); > @@ -1481,8 +1484,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 76417ba7aba1..384624d69ad5 100644 > --- a/hw/riscv/xiangshan_kmh.c > +++ b/hw/riscv/xiangshan_kmh.c > @@ -167,6 +167,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, > @@ -178,13 +179,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 > >
