@@ -174,6 +174,7 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
}
target_ulong riscv_load_kernel(MachineState *machine,
+ RISCVHartArrayState *harts,
target_ulong kernel_start_addr,
symbol_fn_t sym_cb)
{
@@ -192,21 +193,34 @@ target_ulong riscv_load_kernel(MachineState *machine,
if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
NULL, &kernel_load_base, NULL, NULL, 0,
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
- return kernel_load_base;
+ kernel_entry = kernel_load_base;
+ goto out;
}
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
NULL, NULL, NULL) > 0) {
- return kernel_entry;
+ goto out;
}
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
current_machine->ram_size, NULL) > 0) {
- return kernel_start_addr;
+ kernel_entry = kernel_start_addr;
+ goto out;
}
error_report("could not load kernel '%s'", kernel_filename);
exit(1);
+
+out:
+ /*
+ * For 32 bit CPUs 'kernel_entry' can be sign-extended by
+ * load_elf_ram_sym().
+ */
+ if (riscv_is_32bit(harts)) {
+ kernel_entry = extract64(kernel_entry, 0, 32);
+ }
+
+ return kernel_entry;
}
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
@@ -629,7 +629,8 @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
firmware_end_addr);
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
+ kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
+ kernel_start_addr, NULL);
if (machine->initrd_filename) {
riscv_load_initrd(machine, kernel_entry);
@@ -101,7 +101,8 @@ static void opentitan_board_init(MachineState *machine)
}
if (machine->kernel_filename) {
- riscv_load_kernel(machine, memmap[IBEX_DEV_RAM].base, NULL);
+ riscv_load_kernel(machine, &s->soc.cpus,
+ memmap[IBEX_DEV_RAM].base, NULL);
}
}
@@ -114,7 +114,8 @@ static void sifive_e_machine_init(MachineState *machine)
memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
if (machine->kernel_filename) {
- riscv_load_kernel(machine, memmap[SIFIVE_E_DEV_DTIM].base, NULL);
+ riscv_load_kernel(machine, &s->soc.cpus,
+ memmap[SIFIVE_E_DEV_DTIM].base, NULL);
}
}
@@ -598,7 +598,8 @@ static void sifive_u_machine_init(MachineState *machine)
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
firmware_end_addr);
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
+ kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
+ kernel_start_addr, NULL);
if (machine->initrd_filename) {
riscv_load_initrd(machine, kernel_entry);
@@ -305,7 +305,8 @@ static void spike_board_init(MachineState *machine)
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
firmware_end_addr);
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr,
+ kernel_entry = riscv_load_kernel(machine, &s->soc[0],
+ kernel_start_addr,
htif_symbol_callback);
if (machine->initrd_filename) {
@@ -1277,7 +1277,8 @@ static void virt_machine_done(Notifier *notifier, void *data)
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
firmware_end_addr);
- kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
+ kernel_entry = riscv_load_kernel(machine, &s->soc[0],
+ kernel_start_addr, NULL);
if (machine->initrd_filename) {
riscv_load_initrd(machine, kernel_entry);
@@ -44,6 +44,7 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
hwaddr firmware_load_addr,
symbol_fn_t sym_cb);
target_ulong riscv_load_kernel(MachineState *machine,
+ RISCVHartArrayState *harts,
target_ulong firmware_end_addr,
symbol_fn_t sym_cb);
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);