@@ -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)