On Fri, 2026-08-07 at 14:26 +0300, lists wrote: > Ping. > > Do you have a different solution to emulate memory layouts of actual > boards?
The ideal answer is to model the board > > For me this is necessary for the Plan 9 porting work: a Banana Pi F3 > has a different base address than one of the K3 boards, and both > different than the QEMU default. The Banana Pi F3 and the K3 will also have different hardware blocks at different addresses. The starting address of memory isn't the only or even the main difference. I don't see how just changing the memory address fixes an issue for you. > > > On Jul 30, 2026, at 12:42, Shawn Rutledge <[email protected]> wrote: > > > > The 'virt' RISC-V machine hardcodes its DRAM base to 0x80000000. > > Real-world RISC-V SoCs put DRAM elsewhere (SpacemiT K1 at > > 0x40000000, > > SpacemiT K3 at 0x100000000, etc.), which forces ports that target > > those boards to build separate kernels for QEMU testing. RISC-V SoCs can locate their DRAM at any address, that is true. But I don't see how just changing the virt machine address allows you to suddenly test a K3 kernel on the virt board. The rest of the hardware is still different > > > > Add a 'dram-base' string property that lets users move VIRT_DRAM up > > without rebuilding QEMU. Values must be 2 MiB-aligned and at or > > above the default 0x80000000 to avoid colliding with statically- > > placed MMIO regions (PCIE_MMIO ends at 0x80000000). Lower bases > > would also require moving PCIE_MMIO/IMSIC/etc. and are rejected > > with > > an explicit error pointing at the cause. Am I miscounting a 0? 0x4000_0000 is less then 0x8000_0000 so this doesn't help for half of your examples. Alistair > > > > Example: > > qemu-system-riscv64 -machine virt,dram-base=0x100000000 -m 6G ... > > runs OpenSBI at firmware base 0x100000000, matching K3 memory > > layout. > > > > Signed-off-by: Shawn Rutledge <[email protected]> > > --- > > hw/riscv/virt.c | 59 > > ++++++++++++++++++++++++++++++++++++++++- > > include/hw/riscv/virt.h | 2 ++ > > 2 files changed, 60 insertions(+), 1 deletion(-) > > > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c > > index 51bac47a91..6ccc98842f 100644 > > --- a/hw/riscv/virt.c > > +++ b/hw/riscv/virt.c > > @@ -20,6 +20,7 @@ > > > > #include "qemu/osdep.h" > > #include "qemu/units.h" > > +#include "qemu/cutils.h" > > #include "qemu/error-report.h" > > #include "qemu/guest-random.h" > > #include "qapi/error.h" > > @@ -1307,7 +1308,13 @@ static void virt_machine_init(MachineState > > *machine) > > int i, base_hartid, hart_count; > > int socket_count = riscv_socket_count(machine); > > > > - s->memmap = virt_memmap; > > + if (s->dram_base) { > > + s->memmap_storage = g_memdup2(virt_memmap, > > sizeof(virt_memmap)); > > + s->memmap_storage[VIRT_DRAM].base = s->dram_base; > > + s->memmap = s->memmap_storage; > > + } else { > > + s->memmap = virt_memmap; > > + } > > > > /* Check socket count limit */ > > if (VIRT_SOCKETS_MAX < socket_count) { > > @@ -1545,6 +1552,7 @@ static void > > virt_machine_instance_finalize(Object *obj) > > } > > g_free(s->oem_id); > > g_free(s->oem_table_id); > > + g_free(s->memmap_storage); > > } > > > > static void virt_machine_instance_init(Object *obj) > > @@ -1616,6 +1624,46 @@ static void virt_set_aia(Object *obj, const > > char *val, Error **errp) > > } > > } > > > > +static char *virt_get_dram_base(Object *obj, Error **errp) > > +{ > > + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); > > + uint64_t val = s->dram_base ? s->dram_base : > > virt_memmap[VIRT_DRAM].base; > > + > > + return g_strdup_printf("0x%" PRIx64, val); > > +} > > + > > +static void virt_set_dram_base(Object *obj, const char *val, Error > > **errp) > > +{ > > + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); > > + const char *endptr; > > + uint64_t base; > > + > > + if (qemu_strtou64(val, &endptr, 0, &base) < 0 || *endptr != > > '\0') { > > + error_setg(errp, "Invalid dram-base value '%s'", val); > > + return; > > + } > > + /* > > + * DRAM must clear all statically-placed MMIO regions in > > virt_memmap[] > > + * (PCIE_MMIO ends at 0x80000000) and be 2 MiB-aligned so a > > standard > > + * OpenSBI + kernel layout (firmware at base, kernel at > > base+0x200000) > > + * fits. Values below the default base would collide with on- > > board > > + * MMIO and are rejected. > > + */ > > + if (base < virt_memmap[VIRT_DRAM].base) { > > + error_setg(errp, > > + "dram-base 0x%" PRIx64 " is below default 0x%" > > PRIx64 > > + "; would collide with static MMIO regions", > > + base, (uint64_t)virt_memmap[VIRT_DRAM].base); > > + return; > > + } > > + if (base & (2 * MiB - 1)) { > > + error_setg(errp, "dram-base 0x%" PRIx64 " must be 2 MiB- > > aligned", > > + base); > > + return; > > + } > > + s->dram_base = base; > > +} > > + > > static bool virt_get_aclint(Object *obj, Error **errp) > > { > > RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); > > @@ -1744,6 +1792,15 @@ static void > > virt_machine_class_init(ObjectClass *oc, const void *data) > > machine_class_allow_dynamic_sysbus_dev(mc, > > TYPE_TPM_TIS_SYSBUS); > > #endif > > > > + object_class_property_add_str(oc, "dram-base", > > virt_get_dram_base, > > + virt_set_dram_base); > > + object_class_property_set_description(oc, "dram-base", > > + "Base physical address > > of DRAM " > > + "(default 0x80000000). > > Must be " > > + "2 MiB-aligned and at or > > above " > > + "the default to avoid > > colliding " > > + "with statically-placed > > MMIO."); > > + > > object_class_property_add_bool(oc, "aclint", virt_get_aclint, > > virt_set_aclint); > > object_class_property_set_description(oc, "aclint", > > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h > > index 36a2def410..be8a4ac049 100644 > > --- a/include/hw/riscv/virt.h > > +++ b/include/hw/riscv/virt.h > > @@ -61,6 +61,8 @@ struct RISCVVirtState { > > char *oem_table_id; > > OnOffAuto acpi; > > const MemMapEntry *memmap; > > + MemMapEntry *memmap_storage; /* g_malloc'd copy when dram-base > > override is set */ > > + uint64_t dram_base; /* 0 = use compiled-in default > > (0x80000000) */ > > struct GPEXHost *gpex_host; > > OnOffAuto iommu_sys; > > uint16_t pci_iommu_bdf; > > -- > > 2.55.0 > >
