mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 01:03:55 -06:00
hw/riscv: Respect firmware ELF entry point
When riscv_load_firmware() loads an ELF, the ELF segment addresses are used, not the passed-in firmware_load_addr. The machine models assume the firmware entry point is what they provided for firmware_load_addr, and use that address to generate the boot ROM, so if the ELF is linked at any other address, the boot ROM will jump to empty memory. Pass back the ELF entry point to use when generating the boot ROM, so the boot ROM can jump to firmware loaded anywhere in RAM. For example, on the virt machine, this allows using an OpenSBI fw_dynamic.elf built with FW_TEXT_START values other than 0x80000000. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20240817002651.3209701-1-samuel.holland@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
6ffe9b6669
commit
55c136599f
8 changed files with 24 additions and 22 deletions
|
@ -128,11 +128,11 @@ char *riscv_find_firmware(const char *firmware_filename,
|
|||
|
||||
target_ulong riscv_find_and_load_firmware(MachineState *machine,
|
||||
const char *default_machine_firmware,
|
||||
hwaddr firmware_load_addr,
|
||||
hwaddr *firmware_load_addr,
|
||||
symbol_fn_t sym_cb)
|
||||
{
|
||||
char *firmware_filename;
|
||||
target_ulong firmware_end_addr = firmware_load_addr;
|
||||
target_ulong firmware_end_addr = *firmware_load_addr;
|
||||
|
||||
firmware_filename = riscv_find_firmware(machine->firmware,
|
||||
default_machine_firmware);
|
||||
|
@ -148,7 +148,7 @@ target_ulong riscv_find_and_load_firmware(MachineState *machine,
|
|||
}
|
||||
|
||||
target_ulong riscv_load_firmware(const char *firmware_filename,
|
||||
hwaddr firmware_load_addr,
|
||||
hwaddr *firmware_load_addr,
|
||||
symbol_fn_t sym_cb)
|
||||
{
|
||||
uint64_t firmware_entry, firmware_end;
|
||||
|
@ -159,15 +159,16 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
|
|||
if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
|
||||
&firmware_entry, NULL, &firmware_end, NULL,
|
||||
0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
|
||||
*firmware_load_addr = firmware_entry;
|
||||
return firmware_end;
|
||||
}
|
||||
|
||||
firmware_size = load_image_targphys_as(firmware_filename,
|
||||
firmware_load_addr,
|
||||
*firmware_load_addr,
|
||||
current_machine->ram_size, NULL);
|
||||
|
||||
if (firmware_size > 0) {
|
||||
return firmware_load_addr + firmware_size;
|
||||
return *firmware_load_addr + firmware_size;
|
||||
}
|
||||
|
||||
error_report("could not load firmware '%s'", firmware_filename);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue