From: Bin Meng <bin.m...@windriver.com> The reset vector codes are subject to change, e.g.: with recent fw_dynamic type image support, it breaks oreboot again.
Add a subregion in the MROM, with the size of machine RAM stored, so that we can provide a reliable way for bootloader to detect whether it is running in QEMU. Signed-off-by: Bin Meng <bin.m...@windriver.com> --- hw/riscv/sifive_u.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 3413369..6d714a2 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -88,6 +88,7 @@ static const struct MemmapEntry { #define OTP_SERIAL 1 #define GEM_REVISION 0x10070109 +#define MROM_RAMSIZE_OFFSET 0xf8 static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap, uint64_t mem_size, const char *cmdline) @@ -382,6 +383,7 @@ static void sifive_u_machine_init(MachineState *machine) int i; uint32_t fdt_load_addr; uint64_t kernel_entry; + ram_addr_t ram_size = machine->ram_size; /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC); @@ -391,7 +393,7 @@ static void sifive_u_machine_init(MachineState *machine) /* register RAM */ memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram", - machine->ram_size, &error_fatal); + ram_size, &error_fatal); memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DRAM].base, main_mem); @@ -406,7 +408,7 @@ static void sifive_u_machine_init(MachineState *machine) qemu_allocate_irq(sifive_u_machine_reset, NULL, 0)); /* create device tree */ - create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); + create_fdt(s, memmap, ram_size, machine->kernel_cmdline); if (s->start_in_flash) { /* @@ -443,7 +445,7 @@ static void sifive_u_machine_init(MachineState *machine) if (machine->initrd_filename) { hwaddr start; hwaddr end = riscv_load_initrd(machine->initrd_filename, - machine->ram_size, kernel_entry, + ram_size, kernel_entry, &start); qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-start", start); @@ -460,7 +462,7 @@ static void sifive_u_machine_init(MachineState *machine) /* Compute the fdt load address in dram */ fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DRAM].base, - machine->ram_size, s->fdt); + ram_size, s->fdt); #if defined(TARGET_RISCV64) start_addr_hi32 = start_addr >> 32; #endif @@ -496,6 +498,17 @@ static void sifive_u_machine_init(MachineState *machine) riscv_rom_copy_firmware_info(memmap[SIFIVE_U_MROM].base, memmap[SIFIVE_U_MROM].size, sizeof(reset_vec), kernel_entry); + + /* + * Tell guest the machine ram size at MROM_RAMSIZE_OFFSET. + * On real hardware, the 64-bit value from MROM_RAMSIZE_OFFSET is zero. + * QEMU aware bootloader (e.g.: oreboot, U-Boot) can check value stored + * here to determine whether it is running in QEMU. + */ + ram_size = cpu_to_le32(ram_size); + rom_add_blob_fixed_as("mrom.ram_size", &ram_size, sizeof(ram_size), + memmap[SIFIVE_U_MROM].base + MROM_RAMSIZE_OFFSET, + &address_space_memory); } static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp) -- 2.7.4