[PATCH] hw/riscv: Add basic fw_cfg support to virt

Asherah Connor posted 1 patch 4 years, 8 months ago
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20210225101343.40301-1-ashe@kivikakk.ee
Maintainers: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>, Alistair Francis <Alistair.Francis@wdc.com>, Palmer Dabbelt <palmer@dabbelt.com>, Sagar Karandikar <sagark@eecs.berkeley.edu>
hw/riscv/virt.c         | 25 +++++++++++++++++++++++++
include/hw/riscv/virt.h |  4 +++-
2 files changed, 28 insertions(+), 1 deletion(-)
[PATCH] hw/riscv: Add basic fw_cfg support to virt
Posted by Asherah Connor 4 years, 8 months ago
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)


Re: [PATCH] hw/riscv: Add basic fw_cfg support to virt
Posted by Philippe Mathieu-Daudé 4 years, 8 months ago
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 {
> 


Re: [PATCH] hw/riscv: Add basic fw_cfg support to virt
Posted by Asherah Connor 4 years, 8 months ago
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