From: Nicholas Piggin <npiggin@gmail.com>
This loads firmware into the first (low) memory range,
accounting for machines having discontiguous memory regions.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
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 f53531fc0bd5..e025162a77b1 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,
hwaddr 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 e3292e75ed80..ef9751730ee1 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 a17f62cd082d..3aa9d0e25a1c 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -614,18 +614,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 d369a8a7dcd1..968c7dcb2969 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 3e7f4411727d..d0398f4fd0ec 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 a7492aa27a46..cc1105665859 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -589,7 +589,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 b0bab3fe0081..9a8bce07d9f6 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 17909206c7ef..7615b7cde9ac 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1465,7 +1465,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]);
@@ -1488,8 +1491,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 a95fd6174fdc..431fe21b762e 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
© 2016 - 2026 Red Hat, Inc.