hw/riscv/virt.c | 25 +++++++++++++++++++++++++ include/hw/riscv/virt.h | 4 +++- 2 files changed, 28 insertions(+), 1 deletion(-)
Provides a minimal fw_cfg for the virt machine on riscv. I've
arbitrarily selected an MMIO base for it. This is very rudimentary, so
no DMA interface is exposed. Tested as working!
(First patch to qemu, so whatever patience you can afford would be
appreciated.)
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
---
hw/riscv/virt.c | 25 +++++++++++++++++++++++++
include/hw/riscv/virt.h | 4 +++-
2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2299b3a6be..4981ca004b 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -56,6 +56,7 @@ static const struct MemmapEntry {
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
[VIRT_UART0] = { 0x10000000, 0x100 },
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
+ [VIRT_FW_CFG] = { 0x10100000, 0x10 },
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
@@ -488,6 +489,26 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
return dev;
}
+static FWCfgState *create_fw_cfg(const RISCVVirtState *s)
+{
+ hwaddr base = virt_memmap[VIRT_FW_CFG].base;
+ hwaddr size = virt_memmap[VIRT_FW_CFG].size;
+ FWCfgState *fw_cfg;
+ char *nodename;
+
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, 0, NULL);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)MACHINE(s)->smp.cpus);
+
+ nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
+ qemu_fdt_add_subnode(s->fdt, nodename);
+ qemu_fdt_setprop_string(s->fdt, nodename,
+ "compatible", "qemu,fw-cfg-mmio");
+ qemu_fdt_setprop_sized_cells(s->fdt, nodename, "reg",
+ 2, base, 2, size);
+ g_free(nodename);
+ return fw_cfg;
+}
+
static void virt_machine_init(MachineState *machine)
{
const struct MemmapEntry *memmap = virt_memmap;
@@ -652,6 +673,10 @@ static void virt_machine_init(MachineState *machine)
start_addr = virt_memmap[VIRT_FLASH].base;
}
+ /* init fw_cfg */
+ s->fw_cfg = create_fw_cfg(s);
+ rom_set_fw(s->fw_cfg);
+
/* Compute the fdt load address in dram */
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
machine->ram_size, s->fdt);
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 84b7a3848f..3b81a2e3f6 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -40,6 +40,7 @@ struct RISCVVirtState {
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
DeviceState *plic[VIRT_SOCKETS_MAX];
PFlashCFI01 *flash[2];
+ FWCfgState *fw_cfg;
void *fdt;
int fdt_size;
@@ -58,7 +59,8 @@ enum {
VIRT_DRAM,
VIRT_PCIE_MMIO,
VIRT_PCIE_PIO,
- VIRT_PCIE_ECAM
+ VIRT_PCIE_ECAM,
+ VIRT_FW_CFG
};
enum {
--
2.24.3 (Apple Git-128)
Hi Asherah,
You forgot to Cc the maintainers (doing it now):
./scripts/get_maintainer.pl -f hw/riscv/virt.c
Palmer Dabbelt <palmer@dabbelt.com>
Alistair Francis <Alistair.Francis@wdc.com>
Sagar Karandikar <sagark@eecs.berkeley.edu>
Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
qemu-riscv@nongnu.org
qemu-devel@nongnu.org
On 2/25/21 11:13 AM, Asherah Connor wrote:
> Provides a minimal fw_cfg for the virt machine on riscv. I've
> arbitrarily selected an MMIO base for it. This is very rudimentary, so
> no DMA interface is exposed. Tested as working!
>
> (First patch to qemu, so whatever patience you can afford would be
> appreciated.)
What is missing here is why do you need this, what problem
does this patch solve.
>
> Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
> ---
> hw/riscv/virt.c | 25 +++++++++++++++++++++++++
> include/hw/riscv/virt.h | 4 +++-
> 2 files changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 2299b3a6be..4981ca004b 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -56,6 +56,7 @@ static const struct MemmapEntry {
> [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
> [VIRT_UART0] = { 0x10000000, 0x100 },
> [VIRT_VIRTIO] = { 0x10001000, 0x1000 },
> + [VIRT_FW_CFG] = { 0x10100000, 0x10 },
> [VIRT_FLASH] = { 0x20000000, 0x4000000 },
> [VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
> [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
> @@ -488,6 +489,26 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
> return dev;
> }
>
> +static FWCfgState *create_fw_cfg(const RISCVVirtState *s)
> +{
> + hwaddr base = virt_memmap[VIRT_FW_CFG].base;
> + hwaddr size = virt_memmap[VIRT_FW_CFG].size;
> + FWCfgState *fw_cfg;
> + char *nodename;
> +
> + fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, 0, NULL);
> + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)MACHINE(s)->smp.cpus);
> +
> + nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
> + qemu_fdt_add_subnode(s->fdt, nodename);
> + qemu_fdt_setprop_string(s->fdt, nodename,
> + "compatible", "qemu,fw-cfg-mmio");
> + qemu_fdt_setprop_sized_cells(s->fdt, nodename, "reg",
> + 2, base, 2, size);
> + g_free(nodename);
> + return fw_cfg;
> +}
> +
> static void virt_machine_init(MachineState *machine)
> {
> const struct MemmapEntry *memmap = virt_memmap;
> @@ -652,6 +673,10 @@ static void virt_machine_init(MachineState *machine)
> start_addr = virt_memmap[VIRT_FLASH].base;
> }
>
> + /* init fw_cfg */
> + s->fw_cfg = create_fw_cfg(s);
> + rom_set_fw(s->fw_cfg);
> +
> /* Compute the fdt load address in dram */
> fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
> machine->ram_size, s->fdt);
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 84b7a3848f..3b81a2e3f6 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -40,6 +40,7 @@ struct RISCVVirtState {
> RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
> DeviceState *plic[VIRT_SOCKETS_MAX];
> PFlashCFI01 *flash[2];
> + FWCfgState *fw_cfg;
>
> void *fdt;
> int fdt_size;
> @@ -58,7 +59,8 @@ enum {
> VIRT_DRAM,
> VIRT_PCIE_MMIO,
> VIRT_PCIE_PIO,
> - VIRT_PCIE_ECAM
> + VIRT_PCIE_ECAM,
> + VIRT_FW_CFG
> };
>
> enum {
>
Hi Philippe, On 21/02/25 12:02:p, Philippe Mathieu-Daudé wrote: > Hi Asherah, > > You forgot to Cc the maintainers (doing it now): Ah, my bad. Thank you! > What is missing here is why do you need this, what problem > does this patch solve. I would eventually like to use qemu ramfb on RISC-V (through UEFI) -- this is the first step in that direction. I have continued on my side to add the ramfb device to the machine, and it's another +7 -2 diff to a working ramfb on riscv :) There may be more after cleaning up, but all in all it seems a fairly low-impact change with useful result for developers. Best, Asherah
© 2016 - 2025 Red Hat, Inc.