qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* Add initial CVA6 implementaiton
@ 2025-05-27 11:24 Ben Dooks
  2025-05-27 11:24 ` [PATCH v2 1/3] hw/riscv: add CVA6 machine Ben Dooks
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Ben Dooks @ 2025-05-27 11:24 UTC (permalink / raw)
  To: nazar.kazakov, joseph.baker, fran.redondo, lawrence.hunter,
	liwei1518, dbarboza, zhiwei_liu, qemu-riscv
  Cc: ben.dooks, qemu-devel

This implements the CVA6 (the corev_apu from the fpga) model.

v2:
- fixed whitespace and rebased patches




^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/3] hw/riscv: add CVA6 machine
  2025-05-27 11:24 Add initial CVA6 implementaiton Ben Dooks
@ 2025-05-27 11:24 ` Ben Dooks
  2025-06-09 11:24   ` Daniel Henrique Barboza
  2025-05-27 11:24 ` [PATCH v2 2/3] target/riscv: add cva6 core type Ben Dooks
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Ben Dooks @ 2025-05-27 11:24 UTC (permalink / raw)
  To: nazar.kazakov, joseph.baker, fran.redondo, lawrence.hunter,
	liwei1518, dbarboza, zhiwei_liu, qemu-riscv
  Cc: ben.dooks, qemu-devel

Add a (currently Genesy2 based) CVA6 machine.

Has SPI and UART, the GPIO and Ethernet are currently black-holed
as there is no hardware model for them (lowRISC ethernet and Xilinx
GPIO)

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
v2:
- whitespace fixes
- use g_autofree on plic
v1:
- squashed in fixes for sd-card and new qemu init
- move to spdx for cva6 machine
- code cleanups missed in first review
---
 hw/riscv/Kconfig        |  10 ++
 hw/riscv/cva6.c         | 229 ++++++++++++++++++++++++++++++++++++++++
 hw/riscv/meson.build    |   1 +
 include/hw/riscv/cva6.h |  85 +++++++++++++++
 4 files changed, 325 insertions(+)
 create mode 100644 hw/riscv/cva6.c
 create mode 100644 include/hw/riscv/cva6.h

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index e6a0ac1fa1..b96f6fa014 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -9,6 +9,16 @@ config IBEX
 
 # RISC-V machines in alphabetical order
 
+config CVA6
+    bool
+    default y
+    depends on RISCV32 || RISCV64
+    select DEVICE_TREE
+    select SIFIVE_PLIC
+    select XILINX_SPI
+    select RISCV_ACLINT
+    select UNIMP
+
 config MICROCHIP_PFSOC
     bool
     default y
diff --git a/hw/riscv/cva6.c b/hw/riscv/cva6.c
new file mode 100644
index 0000000000..3adfa8b5cc
--- /dev/null
+++ b/hw/riscv/cva6.c
@@ -0,0 +1,229 @@
+/*
+ * QEMU RISC-V Board for OpenHW CVA6 SoC
+ *
+ * Copyright (c) 2025 Codethink Ltd
+ * Ben Dooks <ben.dooks@codethink.co.uk>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "hw/boards.h"
+#include "hw/irq.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+#include "hw/misc/unimp.h"
+
+#include "hw/sd/sd.h"
+#include "hw/ssi/ssi.h"
+
+#include "hw/riscv/cva6.h"
+#include "hw/riscv/boot.h"
+#include "hw/intc/riscv_aclint.h"
+
+#include "system/system.h"
+
+#include <libfdt.h>
+
+#define CVA6_ROM_BASE  0x10000
+
+static const MemMapEntry cva6_memmap[] = {
+    [CVA6_DEBUG] =              {  0x0000000,  0x1000 },
+    [CVA6_ROM] =                { CVA6_ROM_BASE, 0x10000 },
+    [CVA6_CLINT] =              {  0x2000000, 0xC0000 },
+    [CVA6_PLIC] =               {  0xC000000, 0x4000000 },
+    [CVA6_UART] =               { 0x10000000, 0x1000 },
+    [CVA6_TIMER] =              { 0x18000000, 0x10000 },
+    [CVA6_SPI] =                { 0x20000000, 0x800000 },
+    [CVA6_ETHERNET] =           { 0x30000000, 0x10000 },
+    [CVA6_GPIO] =               { 0x40000000, 0x1000 },
+    [CVA6_DRAM] =               { 0x80000000, 0x40000000 },
+};
+
+static void cva6_machine_init(MachineState *machine)
+{
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
+    MemoryRegion *sys_mem = get_system_memory();
+    hwaddr dram_addr = cva6_memmap[CVA6_DRAM].base;
+    CVA6State *s = CVA6_MACHINE(machine);
+    RISCVBootInfo boot_info;
+
+    object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_CVA6);
+    qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
+
+    if (machine->ram_size > mc->default_ram_size) {
+        error_report("RAM size is too big for DRAM area");
+        exit(EXIT_FAILURE);
+    }
+
+    memory_region_add_subregion(sys_mem, dram_addr, machine->ram);
+    riscv_boot_info_init(&boot_info, &s->soc.cpus);
+
+    if (machine->firmware) {
+         hwaddr firmware_load_addr = cva6_memmap[CVA6_ROM].base;
+         riscv_load_firmware(machine->firmware, &firmware_load_addr, NULL);
+    }
+
+     if (machine->kernel_filename) {
+         /* note - we've not tested just loading the kernel w/o uboot */
+         riscv_load_kernel(machine, &boot_info, dram_addr, false, NULL);
+    }
+
+}
+
+static void cva6_machine_class_init(ObjectClass *oc, const void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "RISC-V board for CVA6";
+    mc->init = cva6_machine_init;
+    mc->max_cpus = 1;
+    mc->default_ram_id = "cva6.ram";
+    /* start with "max" cpu type until we sort out CVA6 type */
+    mc->default_cpu_type = TYPE_RISCV_CPU_MAX;
+    mc->default_ram_size = cva6_memmap[CVA6_DRAM].size;
+};
+
+static void cva6_soc_init(Object *obj)
+{
+    CVA6SoCState *s = RISCV_CVA6(obj);
+
+    object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
+}
+
+static void cva6_add_spi(CVA6SoCState *s, const MemMapEntry *map)
+{
+    DriveInfo *dinfo;
+    BlockBackend *blk;
+    DeviceState *card_dev;
+    qemu_irq sd_cs;
+    DeviceState *sddev;
+    SysBusDevice *busdev;
+    DeviceState *spi_dev;
+    SSIBus *spi;
+
+    spi_dev = qdev_new("xlnx.xps-spi");
+    qdev_prop_set_uint8(spi_dev, "num-ss-bits", 1);
+    qdev_prop_set_string(spi_dev, "endianness", "little");
+
+    busdev = SYS_BUS_DEVICE(spi_dev);
+    sysbus_realize_and_unref(busdev, &error_fatal);
+    sysbus_mmio_map(busdev, 0, map->base);
+    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(s->plic), CVA6_SPI_IRQ));
+
+    spi = (SSIBus *)qdev_get_child_bus(spi_dev, "spi");
+
+    sddev = ssi_create_peripheral(spi, "ssi-sd");
+    sd_cs = qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0);
+    sysbus_connect_irq(busdev, 1, sd_cs);
+
+    dinfo = drive_get(IF_SD, 0, 0);
+    blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
+    card_dev = qdev_new(TYPE_SD_CARD_SPI);
+    qdev_prop_set_drive_err(card_dev, "drive", blk, &error_fatal);
+
+    qdev_realize_and_unref(card_dev, qdev_get_child_bus(sddev, "sd-bus"), &error_fatal);
+}
+
+static void not_implemented(const char *name, const MemMapEntry *map)
+{
+    create_unimplemented_device(name, map->base, map->size);
+}
+
+static void cva6_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+    MemoryRegion *system_memory = get_system_memory();
+    MachineState *ms = MACHINE(qdev_get_machine());
+    CVA6SoCState *s = RISCV_CVA6(dev_soc);
+    const MemMapEntry *memmap = cva6_memmap;
+    MemoryRegion *rom = g_new(MemoryRegion, 1);
+    g_autofree char *plic_hart_config;
+
+    object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
+                            &error_abort);
+    object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
+                            &error_abort);
+    object_property_set_int(OBJECT(&s->cpus), "resetvec", CVA6_ROM_BASE,
+                            &error_abort);
+    sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
+
+    /* boot rom */
+    memory_region_init_rom(rom, OBJECT(dev_soc), "riscv.cva6.bootrom",
+                           memmap[CVA6_ROM].size, &error_fatal);
+    memory_region_add_subregion(system_memory, memmap[CVA6_ROM].base,
+                                rom);
+
+    /* create PLIC hart topology configuration string */
+    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
+
+    /* MMIO */
+    s->plic = sifive_plic_create(memmap[CVA6_PLIC].base,
+        plic_hart_config, ms->smp.cpus, 0,
+        CVA6_PLIC_NUM_SOURCES,
+        CVA6_PLIC_NUM_PRIORITIES,
+        CVA6_PLIC_PRIORITY_BASE,
+        CVA6_PLIC_PENDING_BASE,
+        CVA6_PLIC_ENABLE_BASE,
+        CVA6_PLIC_ENABLE_STRIDE,
+        CVA6_PLIC_CONTEXT_BASE,
+        CVA6_PLIC_CONTEXT_STRIDE,
+        memmap[CVA6_PLIC].size);
+
+    riscv_aclint_swi_create(memmap[CVA6_CLINT].base, 0,
+                            ms->smp.cpus, false);
+
+    riscv_aclint_mtimer_create(
+        memmap[CVA6_CLINT].base + RISCV_ACLINT_SWI_SIZE,
+        RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
+        RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
+        CLINT_TIMEBASE_FREQ, true);
+
+    /* something in cva6-sdk uboot seems to prod the debug
+     * unit by accident, so make it not implemented */
+    not_implemented("debug", &memmap[CVA6_DEBUG]);
+
+    /* 16550 uart, one 32bit register per 32bit word */
+
+    serial_mm_init(system_memory, memmap[CVA6_UART].base, 2,
+                   qdev_get_gpio_in(DEVICE(s->plic), CVA6_UART_IRQ),
+                   50*1000*10000,
+                   serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+    /* just unimplement the timers, network and gpio here for now.
+     * no-one seems to be using the apb timer block anyway*/
+    not_implemented("net", &memmap[CVA6_ETHERNET]);
+    not_implemented("gpio", &memmap[CVA6_GPIO]);
+    not_implemented("timer", &memmap[CVA6_TIMER]);
+
+    /* connect xilinx spi block here */
+    cva6_add_spi(s, &memmap[CVA6_SPI]);
+}
+
+static void cva6_soc_class_init(ObjectClass *oc, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = cva6_soc_realize;
+    dc->user_creatable = false;
+};
+
+static const TypeInfo cva6_types[] = {
+    {
+        .name           = TYPE_RISCV_CVA6,
+        .parent         = TYPE_DEVICE,
+        .instance_size  = sizeof(CVA6SoCState),
+        .instance_init  = cva6_soc_init,
+        .class_init     = cva6_soc_class_init,
+    }, {
+        .name           = TYPE_CVA6_MACHINE,
+        .parent         = TYPE_MACHINE,
+        .instance_size  = sizeof(CVA6State),
+        .class_init     = cva6_machine_class_init,
+    }
+};
+
+DEFINE_TYPES(cva6_types)
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index c22f3a7216..a32fffab63 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -2,6 +2,7 @@ riscv_ss = ss.source_set()
 riscv_ss.add(files('boot.c'))
 riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c'))
 riscv_ss.add(files('riscv_hart.c'))
+riscv_ss.add(when: 'CONFIG_CVA6', if_true: files('cva6.c'))
 riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
 riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c'))
 riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c'))
diff --git a/include/hw/riscv/cva6.h b/include/hw/riscv/cva6.h
new file mode 100644
index 0000000000..8f6172e8b8
--- /dev/null
+++ b/include/hw/riscv/cva6.h
@@ -0,0 +1,85 @@
+/*
+ * QEMU RISC-V Board for OpenHW CVA6 SoC
+ * https://github.com/openhwgroup/cva6/tree/master/corev_apu
+ *
+ * Copyright (c) 2025 Codethink Ltd
+ * Ben Dooks <ben.dooks@codethink.co.uk>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_CVA6_H
+#define HW_CVA6_H
+
+#include "hw/riscv/riscv_hart.h"
+#include "hw/intc/sifive_plic.h"
+#include "hw/char/serial-mm.h"
+
+#include "hw/boards.h"
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_RISCV_CVA6 "riscv.cva6.soc"
+OBJECT_DECLARE_SIMPLE_TYPE(CVA6SoCState, RISCV_CVA6)
+
+typedef struct CVA6SoCState {
+    /*< private >*/
+    DeviceState parent_obj;
+
+    /*< public >*/
+    RISCVHartArrayState cpus;
+    DeviceState *plic;
+    MemoryRegion rom;
+
+    uint32_t resetvec;
+} CVA6SoCState;
+
+#define TYPE_CVA6_MACHINE MACHINE_TYPE_NAME("cva6")
+OBJECT_DECLARE_SIMPLE_TYPE(CVA6State, CVA6_MACHINE)
+
+typedef struct CVA6State {
+    /*< private >*/
+    MachineState parent_obj;
+
+    /*< public >*/
+    CVA6SoCState soc;
+}
+CVA6State;
+
+enum {
+    CVA6_DEBUG,
+    CVA6_ROM,
+    CVA6_CLINT,
+    CVA6_PLIC,
+    CVA6_UART,
+    CVA6_TIMER,
+    CVA6_SPI,
+    CVA6_ETHERNET,
+    CVA6_GPIO,
+    CVA6_DRAM,
+};
+
+enum {
+    CVA6_UART_IRQ       = 1,
+    CVA6_SPI_IRQ        = 2,
+    CVA6_ETH_IRQ        = 3,
+    CVA6_TIMER0_OVF_IRQ = 4,
+    CVA6_TIMER0_CMP_IRQ = 5,
+    CVA6_TIMER1_OVF_IRQ = 6,
+    CVA6_TIMER1_CMP_IRQ = 7,
+};
+
+#define CLINT_TIMEBASE_FREQ 25000000
+
+/* plic register interface in corev_apu/rv_plic/rtl/plic_regmap.sv */
+
+#define CVA6_PLIC_NUM_SOURCES           32
+#define CVA6_PLIC_NUM_PRIORITIES        7
+#define CVA6_PLIC_PRIORITY_BASE         0x0000
+#define CVA6_PLIC_PENDING_BASE          0x1000
+#define CVA6_PLIC_ENABLE_BASE           0x2000
+#define CVA6_PLIC_ENABLE_STRIDE         0x80
+#define CVA6_PLIC_CONTEXT_BASE          0x200000
+#define CVA6_PLIC_CONTEXT_STRIDE        0x1000
+
+#endif /* HW_CVA6_H */
-- 
2.37.2.352.g3c44437643



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-05-27 11:24 Add initial CVA6 implementaiton Ben Dooks
  2025-05-27 11:24 ` [PATCH v2 1/3] hw/riscv: add CVA6 machine Ben Dooks
@ 2025-05-27 11:24 ` Ben Dooks
  2025-06-07 20:17   ` Daniel Henrique Barboza
  2025-05-27 11:24 ` [PATCH v2 3/3] hw/riscv: set cva6 to use TYPE_RISCV_CPU_CVA6 Ben Dooks
  2025-06-07 20:22 ` Add initial CVA6 implementaiton Daniel Henrique Barboza
  3 siblings, 1 reply; 15+ messages in thread
From: Ben Dooks @ 2025-05-27 11:24 UTC (permalink / raw)
  To: nazar.kazakov, joseph.baker, fran.redondo, lawrence.hunter,
	liwei1518, dbarboza, zhiwei_liu, qemu-riscv
  Cc: ben.dooks, qemu-devel

Add TYPE_RISCV_CPU_CVA6 for the CVA6 core

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 target/riscv/cpu-qom.h |  1 +
 target/riscv/cpu.c     | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 1ee05eb393..3daf75568c 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -34,6 +34,7 @@
 #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
 #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
 #define TYPE_RISCV_CPU_BASE128          RISCV_CPU_TYPE_NAME("x-rv128")
+#define TYPE_RISCV_CPU_CVA6             RISCV_CPU_TYPE_NAME("cva6")
 #define TYPE_RISCV_CPU_RV32I            RISCV_CPU_TYPE_NAME("rv32i")
 #define TYPE_RISCV_CPU_RV32E            RISCV_CPU_TYPE_NAME("rv32e")
 #define TYPE_RISCV_CPU_RV64I            RISCV_CPU_TYPE_NAME("rv64i")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 629ac37501..fca45dc9d9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3009,6 +3009,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .misa_mxl_max = MXL_RV64,
     ),
 
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_CVA6, TYPE_RISCV_VENDOR_CPU,
+        .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVS | RVU,
+        .misa_mxl_max = MXL_RV64,
+        .cfg.max_satp_mode = VM_1_10_SV39,
+        .priv_spec = PRIV_VERSION_1_12_0,
+        .cfg.pmp = true,
+        .cfg.mmu = true,
+        .cfg.ext_zifencei = true,
+        .cfg.ext_zicsr = true,
+    ),
+
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E51, TYPE_RISCV_CPU_SIFIVE_E,
         .misa_mxl_max = MXL_RV64
     ),
-- 
2.37.2.352.g3c44437643



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 3/3] hw/riscv: set cva6 to use TYPE_RISCV_CPU_CVA6
  2025-05-27 11:24 Add initial CVA6 implementaiton Ben Dooks
  2025-05-27 11:24 ` [PATCH v2 1/3] hw/riscv: add CVA6 machine Ben Dooks
  2025-05-27 11:24 ` [PATCH v2 2/3] target/riscv: add cva6 core type Ben Dooks
@ 2025-05-27 11:24 ` Ben Dooks
  2025-06-07 20:22 ` Add initial CVA6 implementaiton Daniel Henrique Barboza
  3 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2025-05-27 11:24 UTC (permalink / raw)
  To: nazar.kazakov, joseph.baker, fran.redondo, lawrence.hunter,
	liwei1518, dbarboza, zhiwei_liu, qemu-riscv
  Cc: ben.dooks, qemu-devel

Change to using TYPE_RISCV_CPU_CVA6 once this is merged.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 hw/riscv/cva6.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/riscv/cva6.c b/hw/riscv/cva6.c
index 3adfa8b5cc..e6fd0ebafc 100644
--- a/hw/riscv/cva6.c
+++ b/hw/riscv/cva6.c
@@ -83,8 +83,7 @@ static void cva6_machine_class_init(ObjectClass *oc, const void *data)
     mc->init = cva6_machine_init;
     mc->max_cpus = 1;
     mc->default_ram_id = "cva6.ram";
-    /* start with "max" cpu type until we sort out CVA6 type */
-    mc->default_cpu_type = TYPE_RISCV_CPU_MAX;
+    mc->default_cpu_type = TYPE_RISCV_CPU_CVA6;
     mc->default_ram_size = cva6_memmap[CVA6_DRAM].size;
 };
 
-- 
2.37.2.352.g3c44437643



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-05-27 11:24 ` [PATCH v2 2/3] target/riscv: add cva6 core type Ben Dooks
@ 2025-06-07 20:17   ` Daniel Henrique Barboza
  2025-06-09 10:40     ` Ben Dooks
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Henrique Barboza @ 2025-06-07 20:17 UTC (permalink / raw)
  To: Ben Dooks, nazar.kazakov, joseph.baker, fran.redondo,
	lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel



On 5/27/25 8:24 AM, Ben Dooks wrote:
> Add TYPE_RISCV_CPU_CVA6 for the CVA6 core
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>   target/riscv/cpu-qom.h |  1 +
>   target/riscv/cpu.c     | 11 +++++++++++
>   2 files changed, 12 insertions(+)
> 
> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
> index 1ee05eb393..3daf75568c 100644
> --- a/target/riscv/cpu-qom.h
> +++ b/target/riscv/cpu-qom.h
> @@ -34,6 +34,7 @@
>   #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
>   #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
>   #define TYPE_RISCV_CPU_BASE128          RISCV_CPU_TYPE_NAME("x-rv128")
> +#define TYPE_RISCV_CPU_CVA6             RISCV_CPU_TYPE_NAME("cva6")
>   #define TYPE_RISCV_CPU_RV32I            RISCV_CPU_TYPE_NAME("rv32i")
>   #define TYPE_RISCV_CPU_RV32E            RISCV_CPU_TYPE_NAME("rv32e")
>   #define TYPE_RISCV_CPU_RV64I            RISCV_CPU_TYPE_NAME("rv64i")
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 629ac37501..fca45dc9d9 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -3009,6 +3009,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>           .misa_mxl_max = MXL_RV64,
>       ),
>   
> +    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_CVA6, TYPE_RISCV_VENDOR_CPU,
> +        .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVS | RVU,
> +        .misa_mxl_max = MXL_RV64,
> +        .cfg.max_satp_mode = VM_1_10_SV39,
> +        .priv_spec = PRIV_VERSION_1_12_0,
> +        .cfg.pmp = true,
> +        .cfg.mmu = true,
> +        .cfg.ext_zifencei = true,
> +        .cfg.ext_zicsr = true,
> +    ),
> +

The CPU is being added inside a "#if defined(TARGET_RISCV64)" block, meaning
that it's a 64-bit CPU only. But the CVA6 board added in patch 1 is being
added for both 32 and 64 bit emulations in hw/riscv/Kconfig:

config CVA6
     bool
     default y
     depends on RISCV32 || RISCV64  <------------------

This setup (after patch 3 is added) triggered a test failure in 'check-qtest',
when polling all available boards in qemu-system-riscv32, because it didn't find
a default 32 bit CPU for the cva6 board:

# starting QEMU: exec ./qemu-system-riscv32 -qtest unix:/tmp/qtest-1683816.sock -qtest-log /dev/null -chardev socket,path=/tmp/qtest-1683816.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine cva6 -accel qtest
----------------------------------- stderr -----------------------------------
qemu-system-riscv32: ../hw/core/machine.c:1574: is_cpu_type_supported: Assertion `cc != NULL' failed.
Broken pipe
../tests/qtest/libqtest.c:208: kill_qemu() detected QEMU death from signal 6 (Aborted) (core dumped)



We have 2 options here:

- if the CVA6 board is supposed to run in RISCV32 and RISCV64, then its default
CPU must be 32 bit compliant too. The CPU declaration in this patch must be moved
outside the "#if defined(TARGET_RISCV64)" block (e.g right after
TYPE_RISCV_CPU_SIFIVE_U);

- if the board is 64 bit only then the CPU declaration is fine, and we need to
change the board hw/riscv/Kconfig entry to "depends on RISCV64".


Thanks,

Daniel


>       DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E51, TYPE_RISCV_CPU_SIFIVE_E,
>           .misa_mxl_max = MXL_RV64
>       ),



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Add initial CVA6 implementaiton
  2025-05-27 11:24 Add initial CVA6 implementaiton Ben Dooks
                   ` (2 preceding siblings ...)
  2025-05-27 11:24 ` [PATCH v2 3/3] hw/riscv: set cva6 to use TYPE_RISCV_CPU_CVA6 Ben Dooks
@ 2025-06-07 20:22 ` Daniel Henrique Barboza
  3 siblings, 0 replies; 15+ messages in thread
From: Daniel Henrique Barboza @ 2025-06-07 20:22 UTC (permalink / raw)
  To: Ben Dooks, nazar.kazakov, joseph.baker, fran.redondo,
	lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel, Alistair Francis

Hi,

(added Alistair in CC)

I suggest adding the RISC-V maintainer, Alistair, in the CC for the next
posting. It helps in the series visibility.

It would also be nice to add a RISC-V reference in the subject, e.g.
"RISCV: Add initial CVA6 implementation", to help ppl from the common
qemu-devel ML to quickly identify what the series is about.



Thanks,

Daniel

On 5/27/25 8:24 AM, Ben Dooks wrote:
> This implements the CVA6 (the corev_apu from the fpga) model.
> 
> v2:
> - fixed whitespace and rebased patches
> 
> 



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-06-07 20:17   ` Daniel Henrique Barboza
@ 2025-06-09 10:40     ` Ben Dooks
  2025-06-09 11:30       ` Daniel Henrique Barboza
  0 siblings, 1 reply; 15+ messages in thread
From: Ben Dooks @ 2025-06-09 10:40 UTC (permalink / raw)
  To: Daniel Henrique Barboza, nazar.kazakov, joseph.baker,
	fran.redondo, lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel

On 07/06/2025 21:17, Daniel Henrique Barboza wrote:
> 
> 
> On 5/27/25 8:24 AM, Ben Dooks wrote:
>> Add TYPE_RISCV_CPU_CVA6 for the CVA6 core
>>
>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>> ---
>>   target/riscv/cpu-qom.h |  1 +
>>   target/riscv/cpu.c     | 11 +++++++++++
>>   2 files changed, 12 insertions(+)
>>
>> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
>> index 1ee05eb393..3daf75568c 100644
>> --- a/target/riscv/cpu-qom.h
>> +++ b/target/riscv/cpu-qom.h
>> @@ -34,6 +34,7 @@
>>   #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
>>   #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
>>   #define TYPE_RISCV_CPU_BASE128          RISCV_CPU_TYPE_NAME("x-rv128")
>> +#define TYPE_RISCV_CPU_CVA6             RISCV_CPU_TYPE_NAME("cva6")
>>   #define TYPE_RISCV_CPU_RV32I            RISCV_CPU_TYPE_NAME("rv32i")
>>   #define TYPE_RISCV_CPU_RV32E            RISCV_CPU_TYPE_NAME("rv32e")
>>   #define TYPE_RISCV_CPU_RV64I            RISCV_CPU_TYPE_NAME("rv64i")
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 629ac37501..fca45dc9d9 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -3009,6 +3009,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>>           .misa_mxl_max = MXL_RV64,
>>       ),
>> +    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_CVA6, TYPE_RISCV_VENDOR_CPU,
>> +        .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVS | RVU,
>> +        .misa_mxl_max = MXL_RV64,
>> +        .cfg.max_satp_mode = VM_1_10_SV39,
>> +        .priv_spec = PRIV_VERSION_1_12_0,
>> +        .cfg.pmp = true,
>> +        .cfg.mmu = true,
>> +        .cfg.ext_zifencei = true,
>> +        .cfg.ext_zicsr = true,
>> +    ),
>> +
> 
> The CPU is being added inside a "#if defined(TARGET_RISCV64)" block, 
> meaning
> that it's a 64-bit CPU only. But the CVA6 board added in patch 1 is being
> added for both 32 and 64 bit emulations in hw/riscv/Kconfig:

Ah yes, it is possible to make a cva6 32bit, is it ok just to ove this
into a different place or is there anything else needed to allow 32 or 
64bit?

I've only been building a 64bit userland to test so didn't notice the
lack of 32bit was an issue.

> config CVA6
>      bool
>      default y
>      depends on RISCV32 || RISCV64  <------------------
> 
> This setup (after patch 3 is added) triggered a test failure in 'check- 
> qtest',
> when polling all available boards in qemu-system-riscv32, because it 
> didn't find
> a default 32 bit CPU for the cva6 board:
> 
> # starting QEMU: exec ./qemu-system-riscv32 -qtest unix:/tmp/ 
> qtest-1683816.sock -qtest-log /dev/null -chardev socket,path=/tmp/ 
> qtest-1683816.qmp,id=char0 -mon chardev=char0,mode=control -display none 
> -audio none -machine cva6 -accel qtest
> ----------------------------------- stderr 
> -----------------------------------
> qemu-system-riscv32: ../hw/core/machine.c:1574: is_cpu_type_supported: 
> Assertion `cc != NULL' failed.
> Broken pipe
> ../tests/qtest/libqtest.c:208: kill_qemu() detected QEMU death from 
> signal 6 (Aborted) (core dumped)
> 
> 
> 
> We have 2 options here:
> 
> - if the CVA6 board is supposed to run in RISCV32 and RISCV64, then its 
> default
> CPU must be 32 bit compliant too. The CPU declaration in this patch must 
> be moved
> outside the "#if defined(TARGET_RISCV64)" block (e.g right after
> TYPE_RISCV_CPU_SIFIVE_U);
> 
> - if the board is 64 bit only then the CPU declaration is fine, and we 
> need to
> change the board hw/riscv/Kconfig entry to "depends on RISCV64".
> 

As long as it is just the #ifdef block I will move it.

Should I just re-send this change?

> Thanks,
> 
> Daniel
> 
> 
>>       DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E51, 
>> TYPE_RISCV_CPU_SIFIVE_E,
>>           .misa_mxl_max = MXL_RV64
>>       ),
> 
> 


-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] hw/riscv: add CVA6 machine
  2025-05-27 11:24 ` [PATCH v2 1/3] hw/riscv: add CVA6 machine Ben Dooks
@ 2025-06-09 11:24   ` Daniel Henrique Barboza
  2025-06-09 11:32     ` Ben Dooks
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Henrique Barboza @ 2025-06-09 11:24 UTC (permalink / raw)
  To: Ben Dooks, nazar.kazakov, joseph.baker, fran.redondo,
	lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel



On 5/27/25 8:24 AM, Ben Dooks wrote:
> Add a (currently Genesy2 based) CVA6 machine.
> 
> Has SPI and UART, the GPIO and Ethernet are currently black-holed
> as there is no hardware model for them (lowRISC ethernet and Xilinx
> GPIO)
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> v2:
> - whitespace fixes
> - use g_autofree on plic
> v1:
> - squashed in fixes for sd-card and new qemu init
> - move to spdx for cva6 machine
> - code cleanups missed in first review
> ---
>   hw/riscv/Kconfig        |  10 ++
>   hw/riscv/cva6.c         | 229 ++++++++++++++++++++++++++++++++++++++++
>   hw/riscv/meson.build    |   1 +
>   include/hw/riscv/cva6.h |  85 +++++++++++++++
>   4 files changed, 325 insertions(+)
>   create mode 100644 hw/riscv/cva6.c
>   create mode 100644 include/hw/riscv/cva6.h
> 
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index e6a0ac1fa1..b96f6fa014 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -9,6 +9,16 @@ config IBEX
>   
>   # RISC-V machines in alphabetical order
>   
> +config CVA6
> +    bool
> +    default y
> +    depends on RISCV32 || RISCV64
> +    select DEVICE_TREE
> +    select SIFIVE_PLIC
> +    select XILINX_SPI
> +    select RISCV_ACLINT
> +    select UNIMP
> +
>   config MICROCHIP_PFSOC
>       bool
>       default y
> diff --git a/hw/riscv/cva6.c b/hw/riscv/cva6.c
> new file mode 100644
> index 0000000000..3adfa8b5cc
> --- /dev/null
> +++ b/hw/riscv/cva6.c
> @@ -0,0 +1,229 @@
> +/*
> + * QEMU RISC-V Board for OpenHW CVA6 SoC
> + *
> + * Copyright (c) 2025 Codethink Ltd
> + * Ben Dooks <ben.dooks@codethink.co.uk>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "qapi/visitor.h"
> +#include "hw/boards.h"
> +#include "hw/irq.h"
> +#include "hw/loader.h"
> +#include "hw/sysbus.h"
> +#include "hw/misc/unimp.h"
> +
> +#include "hw/sd/sd.h"
> +#include "hw/ssi/ssi.h"
> +
> +#include "hw/riscv/cva6.h"
> +#include "hw/riscv/boot.h"
> +#include "hw/intc/riscv_aclint.h"
> +
> +#include "system/system.h"
> +
> +#include <libfdt.h>
> +
> +#define CVA6_ROM_BASE  0x10000
> +
> +static const MemMapEntry cva6_memmap[] = {
> +    [CVA6_DEBUG] =              {  0x0000000,  0x1000 },
> +    [CVA6_ROM] =                { CVA6_ROM_BASE, 0x10000 },
> +    [CVA6_CLINT] =              {  0x2000000, 0xC0000 },
> +    [CVA6_PLIC] =               {  0xC000000, 0x4000000 },
> +    [CVA6_UART] =               { 0x10000000, 0x1000 },
> +    [CVA6_TIMER] =              { 0x18000000, 0x10000 },
> +    [CVA6_SPI] =                { 0x20000000, 0x800000 },
> +    [CVA6_ETHERNET] =           { 0x30000000, 0x10000 },
> +    [CVA6_GPIO] =               { 0x40000000, 0x1000 },
> +    [CVA6_DRAM] =               { 0x80000000, 0x40000000 },
> +};
> +
> +static void cva6_machine_init(MachineState *machine)
> +{
> +    MachineClass *mc = MACHINE_GET_CLASS(machine);
> +    MemoryRegion *sys_mem = get_system_memory();
> +    hwaddr dram_addr = cva6_memmap[CVA6_DRAM].base;
> +    CVA6State *s = CVA6_MACHINE(machine);
> +    RISCVBootInfo boot_info;
> +
> +    object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_CVA6);
> +    qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
> +
> +    if (machine->ram_size > mc->default_ram_size) {
> +        error_report("RAM size is too big for DRAM area");
> +        exit(EXIT_FAILURE);
> +    }
> +
> +    memory_region_add_subregion(sys_mem, dram_addr, machine->ram);
> +    riscv_boot_info_init(&boot_info, &s->soc.cpus);
> +
> +    if (machine->firmware) {
> +         hwaddr firmware_load_addr = cva6_memmap[CVA6_ROM].base;
> +         riscv_load_firmware(machine->firmware, &firmware_load_addr, NULL);
> +    }
> +
> +     if (machine->kernel_filename) {
> +         /* note - we've not tested just loading the kernel w/o uboot */
> +         riscv_load_kernel(machine, &boot_info, dram_addr, false, NULL);
> +    }
> +
> +}
> +
> +static void cva6_machine_class_init(ObjectClass *oc, const void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +
> +    mc->desc = "RISC-V board for CVA6";
> +    mc->init = cva6_machine_init;
> +    mc->max_cpus = 1;
> +    mc->default_ram_id = "cva6.ram";
> +    /* start with "max" cpu type until we sort out CVA6 type */
> +    mc->default_cpu_type = TYPE_RISCV_CPU_MAX;
> +    mc->default_ram_size = cva6_memmap[CVA6_DRAM].size;
> +};
> +
> +static void cva6_soc_init(Object *obj)
> +{
> +    CVA6SoCState *s = RISCV_CVA6(obj);
> +
> +    object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
> +}
> +
> +static void cva6_add_spi(CVA6SoCState *s, const MemMapEntry *map)
> +{
> +    DriveInfo *dinfo;
> +    BlockBackend *blk;
> +    DeviceState *card_dev;
> +    qemu_irq sd_cs;
> +    DeviceState *sddev;
> +    SysBusDevice *busdev;
> +    DeviceState *spi_dev;
> +    SSIBus *spi;
> +
> +    spi_dev = qdev_new("xlnx.xps-spi");
> +    qdev_prop_set_uint8(spi_dev, "num-ss-bits", 1);
> +    qdev_prop_set_string(spi_dev, "endianness", "little");
> +
> +    busdev = SYS_BUS_DEVICE(spi_dev);
> +    sysbus_realize_and_unref(busdev, &error_fatal);
> +    sysbus_mmio_map(busdev, 0, map->base);
> +    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(s->plic), CVA6_SPI_IRQ));
> +
> +    spi = (SSIBus *)qdev_get_child_bus(spi_dev, "spi");
> +
> +    sddev = ssi_create_peripheral(spi, "ssi-sd");
> +    sd_cs = qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0);
> +    sysbus_connect_irq(busdev, 1, sd_cs);
> +
> +    dinfo = drive_get(IF_SD, 0, 0);
> +    blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
> +    card_dev = qdev_new(TYPE_SD_CARD_SPI);
> +    qdev_prop_set_drive_err(card_dev, "drive", blk, &error_fatal);
> +
> +    qdev_realize_and_unref(card_dev, qdev_get_child_bus(sddev, "sd-bus"), &error_fatal);
> +}
> +
> +static void not_implemented(const char *name, const MemMapEntry *map)
> +{
> +    create_unimplemented_device(name, map->base, map->size);
> +}
> +
> +static void cva6_soc_realize(DeviceState *dev_soc, Error **errp)
> +{
> +    MemoryRegion *system_memory = get_system_memory();
> +    MachineState *ms = MACHINE(qdev_get_machine());
> +    CVA6SoCState *s = RISCV_CVA6(dev_soc);
> +    const MemMapEntry *memmap = cva6_memmap;
> +    MemoryRegion *rom = g_new(MemoryRegion, 1);
> +    g_autofree char *plic_hart_config;
> +
> +    object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
> +                            &error_abort);
> +    object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
> +                            &error_abort);
> +    object_property_set_int(OBJECT(&s->cpus), "resetvec", CVA6_ROM_BASE,
> +                            &error_abort);
> +    sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
> +
> +    /* boot rom */
> +    memory_region_init_rom(rom, OBJECT(dev_soc), "riscv.cva6.bootrom",
> +                           memmap[CVA6_ROM].size, &error_fatal);
> +    memory_region_add_subregion(system_memory, memmap[CVA6_ROM].base,
> +                                rom);
> +
> +    /* create PLIC hart topology configuration string */
> +    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
> +
> +    /* MMIO */
> +    s->plic = sifive_plic_create(memmap[CVA6_PLIC].base,
> +        plic_hart_config, ms->smp.cpus, 0,
> +        CVA6_PLIC_NUM_SOURCES,
> +        CVA6_PLIC_NUM_PRIORITIES,
> +        CVA6_PLIC_PRIORITY_BASE,
> +        CVA6_PLIC_PENDING_BASE,
> +        CVA6_PLIC_ENABLE_BASE,
> +        CVA6_PLIC_ENABLE_STRIDE,
> +        CVA6_PLIC_CONTEXT_BASE,
> +        CVA6_PLIC_CONTEXT_STRIDE,
> +        memmap[CVA6_PLIC].size);
> +
> +    riscv_aclint_swi_create(memmap[CVA6_CLINT].base, 0,
> +                            ms->smp.cpus, false);
> +
> +    riscv_aclint_mtimer_create(
> +        memmap[CVA6_CLINT].base + RISCV_ACLINT_SWI_SIZE,
> +        RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
> +        RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
> +        CLINT_TIMEBASE_FREQ, true);
> +
> +    /* something in cva6-sdk uboot seems to prod the debug
> +     * unit by accident, so make it not implemented */
> +    not_implemented("debug", &memmap[CVA6_DEBUG]);
> +
> +    /* 16550 uart, one 32bit register per 32bit word */
> +
> +    serial_mm_init(system_memory, memmap[CVA6_UART].base, 2,
> +                   qdev_get_gpio_in(DEVICE(s->plic), CVA6_UART_IRQ),
> +                   50*1000*10000,
> +                   serial_hd(0), DEVICE_LITTLE_ENDIAN);
> +
> +    /* just unimplement the timers, network and gpio here for now.
> +     * no-one seems to be using the apb timer block anyway*/
> +    not_implemented("net", &memmap[CVA6_ETHERNET]);
> +    not_implemented("gpio", &memmap[CVA6_GPIO]);
> +    not_implemented("timer", &memmap[CVA6_TIMER]);
> +
> +    /* connect xilinx spi block here */
> +    cva6_add_spi(s, &memmap[CVA6_SPI]);
> +}
> +
> +static void cva6_soc_class_init(ObjectClass *oc, const void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = cva6_soc_realize;
> +    dc->user_creatable = false;
> +};
> +
> +static const TypeInfo cva6_types[] = {
> +    {
> +        .name           = TYPE_RISCV_CVA6,
> +        .parent         = TYPE_DEVICE,
> +        .instance_size  = sizeof(CVA6SoCState),
> +        .instance_init  = cva6_soc_init,
> +        .class_init     = cva6_soc_class_init,
> +    }, {
> +        .name           = TYPE_CVA6_MACHINE,
> +        .parent         = TYPE_MACHINE,
> +        .instance_size  = sizeof(CVA6State),
> +        .class_init     = cva6_machine_class_init,
> +    }
> +};
> +
> +DEFINE_TYPES(cva6_types)
> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> index c22f3a7216..a32fffab63 100644
> --- a/hw/riscv/meson.build
> +++ b/hw/riscv/meson.build
> @@ -2,6 +2,7 @@ riscv_ss = ss.source_set()
>   riscv_ss.add(files('boot.c'))
>   riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c'))
>   riscv_ss.add(files('riscv_hart.c'))
> +riscv_ss.add(when: 'CONFIG_CVA6', if_true: files('cva6.c'))
>   riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
>   riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c'))
>   riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c'))
> diff --git a/include/hw/riscv/cva6.h b/include/hw/riscv/cva6.h
> new file mode 100644
> index 0000000000..8f6172e8b8
> --- /dev/null
> +++ b/include/hw/riscv/cva6.h
> @@ -0,0 +1,85 @@
> +/*
> + * QEMU RISC-V Board for OpenHW CVA6 SoC
> + * https://github.com/openhwgroup/cva6/tree/master/corev_apu
> + *
> + * Copyright (c) 2025 Codethink Ltd
> + * Ben Dooks <ben.dooks@codethink.co.uk>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef HW_CVA6_H
> +#define HW_CVA6_H
> +
> +#include "hw/riscv/riscv_hart.h"
> +#include "hw/intc/sifive_plic.h"
> +#include "hw/char/serial-mm.h"
> +
> +#include "hw/boards.h"
> +#include "hw/sysbus.h"
> +#include "qom/object.h"
> +
> +#define TYPE_RISCV_CVA6 "riscv.cva6.soc"
> +OBJECT_DECLARE_SIMPLE_TYPE(CVA6SoCState, RISCV_CVA6)
> +
> +typedef struct CVA6SoCState {
> +    /*< private >*/
> +    DeviceState parent_obj;
> +
> +    /*< public >*/
> +    RISCVHartArrayState cpus;
> +    DeviceState *plic;
> +    MemoryRegion rom;
> +
> +    uint32_t resetvec;
> +} CVA6SoCState;
> +
> +#define TYPE_CVA6_MACHINE MACHINE_TYPE_NAME("cva6")
> +OBJECT_DECLARE_SIMPLE_TYPE(CVA6State, CVA6_MACHINE)
> +
> +typedef struct CVA6State {
> +    /*< private >*/
> +    MachineState parent_obj;
> +
> +    /*< public >*/
> +    CVA6SoCState soc;
> +}
> +CVA6State;
> +
> +enum {
> +    CVA6_DEBUG,
> +    CVA6_ROM,
> +    CVA6_CLINT,
> +    CVA6_PLIC,
> +    CVA6_UART,
> +    CVA6_TIMER,
> +    CVA6_SPI,
> +    CVA6_ETHERNET,
> +    CVA6_GPIO,
> +    CVA6_DRAM,
> +};
> +
> +enum {
> +    CVA6_UART_IRQ       = 1,
> +    CVA6_SPI_IRQ        = 2,
> +    CVA6_ETH_IRQ        = 3,
> +    CVA6_TIMER0_OVF_IRQ = 4,
> +    CVA6_TIMER0_CMP_IRQ = 5,
> +    CVA6_TIMER1_OVF_IRQ = 6,
> +    CVA6_TIMER1_CMP_IRQ = 7,
> +};
> +
> +#define CLINT_TIMEBASE_FREQ 25000000
> +
> +/* plic register interface in corev_apu/rv_plic/rtl/plic_regmap.sv */
> +

I believe you've missed my comment in v1:

"Where is this file? It's not on QEMU or Linux.

I'm assuming that you're referring to plic_regmap.sv from this repo:

https://github.com/openhwgroup/cva6/tree/master/corev_apu

If that's the case we need to point to this repo in the comment. The commit
msg also works."



Please add the github link in the comment. Thanks,


Daniel






> +#define CVA6_PLIC_NUM_SOURCES           32
> +#define CVA6_PLIC_NUM_PRIORITIES        7
> +#define CVA6_PLIC_PRIORITY_BASE         0x0000
> +#define CVA6_PLIC_PENDING_BASE          0x1000
> +#define CVA6_PLIC_ENABLE_BASE           0x2000
> +#define CVA6_PLIC_ENABLE_STRIDE         0x80
> +#define CVA6_PLIC_CONTEXT_BASE          0x200000
> +#define CVA6_PLIC_CONTEXT_STRIDE        0x1000
> +
> +#endif /* HW_CVA6_H */



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-06-09 10:40     ` Ben Dooks
@ 2025-06-09 11:30       ` Daniel Henrique Barboza
  2025-06-09 11:47         ` Ben Dooks
  2025-06-09 11:59         ` Ben Dooks
  0 siblings, 2 replies; 15+ messages in thread
From: Daniel Henrique Barboza @ 2025-06-09 11:30 UTC (permalink / raw)
  To: Ben Dooks, nazar.kazakov, joseph.baker, fran.redondo,
	lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel



On 6/9/25 7:40 AM, Ben Dooks wrote:
> On 07/06/2025 21:17, Daniel Henrique Barboza wrote:
>>
>>
>> On 5/27/25 8:24 AM, Ben Dooks wrote:
>>> Add TYPE_RISCV_CPU_CVA6 for the CVA6 core
>>>
>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>> ---
>>>   target/riscv/cpu-qom.h |  1 +
>>>   target/riscv/cpu.c     | 11 +++++++++++
>>>   2 files changed, 12 insertions(+)
>>>
>>> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
>>> index 1ee05eb393..3daf75568c 100644
>>> --- a/target/riscv/cpu-qom.h
>>> +++ b/target/riscv/cpu-qom.h
>>> @@ -34,6 +34,7 @@
>>>   #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
>>>   #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
>>>   #define TYPE_RISCV_CPU_BASE128          RISCV_CPU_TYPE_NAME("x-rv128")
>>> +#define TYPE_RISCV_CPU_CVA6             RISCV_CPU_TYPE_NAME("cva6")
>>>   #define TYPE_RISCV_CPU_RV32I            RISCV_CPU_TYPE_NAME("rv32i")
>>>   #define TYPE_RISCV_CPU_RV32E            RISCV_CPU_TYPE_NAME("rv32e")
>>>   #define TYPE_RISCV_CPU_RV64I            RISCV_CPU_TYPE_NAME("rv64i")
>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>> index 629ac37501..fca45dc9d9 100644
>>> --- a/target/riscv/cpu.c
>>> +++ b/target/riscv/cpu.c
>>> @@ -3009,6 +3009,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>>>           .misa_mxl_max = MXL_RV64,
>>>       ),
>>> +    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_CVA6, TYPE_RISCV_VENDOR_CPU,
>>> +        .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVS | RVU,
>>> +        .misa_mxl_max = MXL_RV64,
>>> +        .cfg.max_satp_mode = VM_1_10_SV39,
>>> +        .priv_spec = PRIV_VERSION_1_12_0,
>>> +        .cfg.pmp = true,
>>> +        .cfg.mmu = true,
>>> +        .cfg.ext_zifencei = true,
>>> +        .cfg.ext_zicsr = true,
>>> +    ),
>>> +
>>
>> The CPU is being added inside a "#if defined(TARGET_RISCV64)" block, meaning
>> that it's a 64-bit CPU only. But the CVA6 board added in patch 1 is being
>> added for both 32 and 64 bit emulations in hw/riscv/Kconfig:
> 
> Ah yes, it is possible to make a cva6 32bit, is it ok just to ove this
> into a different place or is there anything else needed to allow 32 or 64bit?
> 
> I've only been building a 64bit userland to test so didn't notice the
> lack of 32bit was an issue.
> 
>> config CVA6
>>      bool
>>      default y
>>      depends on RISCV32 || RISCV64  <------------------
>>
>> This setup (after patch 3 is added) triggered a test failure in 'check- qtest',
>> when polling all available boards in qemu-system-riscv32, because it didn't find
>> a default 32 bit CPU for the cva6 board:
>>
>> # starting QEMU: exec ./qemu-system-riscv32 -qtest unix:/tmp/ qtest-1683816.sock -qtest-log /dev/null -chardev socket,path=/tmp/ qtest-1683816.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine cva6 -accel qtest
>> ----------------------------------- stderr -----------------------------------
>> qemu-system-riscv32: ../hw/core/machine.c:1574: is_cpu_type_supported: Assertion `cc != NULL' failed.
>> Broken pipe
>> ../tests/qtest/libqtest.c:208: kill_qemu() detected QEMU death from signal 6 (Aborted) (core dumped)
>>
>>
>>
>> We have 2 options here:
>>
>> - if the CVA6 board is supposed to run in RISCV32 and RISCV64, then its default
>> CPU must be 32 bit compliant too. The CPU declaration in this patch must be moved
>> outside the "#if defined(TARGET_RISCV64)" block (e.g right after
>> TYPE_RISCV_CPU_SIFIVE_U);
>>
>> - if the board is 64 bit only then the CPU declaration is fine, and we need to
>> change the board hw/riscv/Kconfig entry to "depends on RISCV64".
>>
> 
> As long as it is just the #ifdef block I will move it.

I just read the CV6 documentation at:

https://github.com/openhwgroup/cva6/


The README states right at the start:


"CVA6 is a 6-stage, single-issue, in-order CPU which implements the 64-bit RISC-V instruction set."


So this means that CVA6 is a 64-bit CPU only. This means that we want the second
option: the CPU declaration is fine, but the CVA6 board must be built only for 64
bits. In patch 1, this line:


>> config CVA6
>>      bool
>>      default y
>>      depends on RISCV32 || RISCV64  <------------------


Should be "depends on RISCV64".


Thanks,

Daniel

> 
> Should I just re-send this change?
> 
>> Thanks,
>>
>> Daniel
>>
>>
>>>       DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E51, TYPE_RISCV_CPU_SIFIVE_E,
>>>           .misa_mxl_max = MXL_RV64
>>>       ),
>>
>>
> 
> 



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] hw/riscv: add CVA6 machine
  2025-06-09 11:24   ` Daniel Henrique Barboza
@ 2025-06-09 11:32     ` Ben Dooks
  2025-06-09 12:03       ` Daniel Henrique Barboza
  0 siblings, 1 reply; 15+ messages in thread
From: Ben Dooks @ 2025-06-09 11:32 UTC (permalink / raw)
  To: Daniel Henrique Barboza, nazar.kazakov, joseph.baker,
	fran.redondo, lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel

On 09/06/2025 12:24, Daniel Henrique Barboza wrote:
> 
> 
> On 5/27/25 8:24 AM, Ben Dooks wrote:
>> Add a (currently Genesy2 based) CVA6 machine.
>>
>> Has SPI and UART, the GPIO and Ethernet are currently black-holed
>> as there is no hardware model for them (lowRISC ethernet and Xilinx
>> GPIO)
>>
>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>> ---
>> v2:

Apologie,s looks like it this got rebased out of the release

>> +/* plic register interface in corev_apu/rv_plic/rtl/plic_regmap.sv */
>> +
> 
> I believe you've missed my comment in v1:
> 

would this be ok

/*
* plic register interface in corev_apu/rv_plic/rtl/plic_regmap.sv
* https://github.com/pulp-platform/rv_plic/blob/master/rtl/plic_regmap.sv
*/

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-06-09 11:30       ` Daniel Henrique Barboza
@ 2025-06-09 11:47         ` Ben Dooks
  2025-06-09 12:28           ` Daniel Henrique Barboza
  2025-06-09 11:59         ` Ben Dooks
  1 sibling, 1 reply; 15+ messages in thread
From: Ben Dooks @ 2025-06-09 11:47 UTC (permalink / raw)
  To: Daniel Henrique Barboza, nazar.kazakov, joseph.baker,
	fran.redondo, lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel

On 09/06/2025 12:30, Daniel Henrique Barboza wrote:
> 
> 
> On 6/9/25 7:40 AM, Ben Dooks wrote:
>> On 07/06/2025 21:17, Daniel Henrique Barboza wrote:
>>>
>>>
>>> On 5/27/25 8:24 AM, Ben Dooks wrote:
>>>> Add TYPE_RISCV_CPU_CVA6 for the CVA6 core
>>>>
>>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>>> ---
>>>>   target/riscv/cpu-qom.h |  1 +
>>>>   target/riscv/cpu.c     | 11 +++++++++++
>>>>   2 files changed, 12 insertions(+)
>>>>
>>>> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
>>>> index 1ee05eb393..3daf75568c 100644
>>>> --- a/target/riscv/cpu-qom.h
>>>> +++ b/target/riscv/cpu-qom.h
>>>> @@ -34,6 +34,7 @@
>>>>   #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
>>>>   #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
>>>>   #define TYPE_RISCV_CPU_BASE128          RISCV_CPU_TYPE_NAME("x- 
>>>> rv128")
>>>> +#define TYPE_RISCV_CPU_CVA6             RISCV_CPU_TYPE_NAME("cva6")
>>>>   #define TYPE_RISCV_CPU_RV32I            RISCV_CPU_TYPE_NAME("rv32i")
>>>>   #define TYPE_RISCV_CPU_RV32E            RISCV_CPU_TYPE_NAME("rv32e")
>>>>   #define TYPE_RISCV_CPU_RV64I            RISCV_CPU_TYPE_NAME("rv64i")
>>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>>> index 629ac37501..fca45dc9d9 100644
>>>> --- a/target/riscv/cpu.c
>>>> +++ b/target/riscv/cpu.c
>>>> @@ -3009,6 +3009,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>>>>           .misa_mxl_max = MXL_RV64,
>>>>       ),
>>>> +    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_CVA6, TYPE_RISCV_VENDOR_CPU,
>>>> +        .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVS | 
>>>> RVU,
>>>> +        .misa_mxl_max = MXL_RV64,
>>>> +        .cfg.max_satp_mode = VM_1_10_SV39,
>>>> +        .priv_spec = PRIV_VERSION_1_12_0,
>>>> +        .cfg.pmp = true,
>>>> +        .cfg.mmu = true,
>>>> +        .cfg.ext_zifencei = true,
>>>> +        .cfg.ext_zicsr = true,
>>>> +    ),
>>>> +
>>>
>>> The CPU is being added inside a "#if defined(TARGET_RISCV64)" block, 
>>> meaning
>>> that it's a 64-bit CPU only. But the CVA6 board added in patch 1 is 
>>> being
>>> added for both 32 and 64 bit emulations in hw/riscv/Kconfig:
>>
>> Ah yes, it is possible to make a cva6 32bit, is it ok just to ove this
>> into a different place or is there anything else needed to allow 32 or 
>> 64bit?
>>
>> I've only been building a 64bit userland to test so didn't notice the
>> lack of 32bit was an issue.
>>
>>> config CVA6
>>>      bool
>>>      default y
>>>      depends on RISCV32 || RISCV64  <------------------
>>>
>>> This setup (after patch 3 is added) triggered a test failure in 
>>> 'check- qtest',
>>> when polling all available boards in qemu-system-riscv32, because it 
>>> didn't find
>>> a default 32 bit CPU for the cva6 board:
>>>
>>> # starting QEMU: exec ./qemu-system-riscv32 -qtest unix:/tmp/ 
>>> qtest-1683816.sock -qtest-log /dev/null -chardev socket,path=/tmp/ 
>>> qtest-1683816.qmp,id=char0 -mon chardev=char0,mode=control -display 
>>> none -audio none -machine cva6 -accel qtest
>>> ----------------------------------- stderr 
>>> -----------------------------------
>>> qemu-system-riscv32: ../hw/core/machine.c:1574: 
>>> is_cpu_type_supported: Assertion `cc != NULL' failed.
>>> Broken pipe
>>> ../tests/qtest/libqtest.c:208: kill_qemu() detected QEMU death from 
>>> signal 6 (Aborted) (core dumped)
>>>
>>>
>>>
>>> We have 2 options here:
>>>
>>> - if the CVA6 board is supposed to run in RISCV32 and RISCV64, then 
>>> its default
>>> CPU must be 32 bit compliant too. The CPU declaration in this patch 
>>> must be moved
>>> outside the "#if defined(TARGET_RISCV64)" block (e.g right after
>>> TYPE_RISCV_CPU_SIFIVE_U);
>>>
>>> - if the board is 64 bit only then the CPU declaration is fine, and 
>>> we need to
>>> change the board hw/riscv/Kconfig entry to "depends on RISCV64".
>>>
>>
>> As long as it is just the #ifdef block I will move it.
> 
> I just read the CV6 documentation at:
> 
> https://github.com/openhwgroup/cva6/
> 
> 
> The README states right at the start:
> 
> 
> "CVA6 is a 6-stage, single-issue, in-order CPU which implements the 64- 
> bit RISC-V instruction set."
> 
> 
> So this means that CVA6 is a 64-bit CPU only. This means that we want 
> the second
> option: the CPU declaration is fine, but the CVA6 board must be built 
> only for 64
> bits. In patch 1, this line:


There do seem to be some build variants for cva32a6 deep in the docs
and the cva6-sdk has builds for both xlen==32 and xlen==64 so I am a
bit confused here.


-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-06-09 11:30       ` Daniel Henrique Barboza
  2025-06-09 11:47         ` Ben Dooks
@ 2025-06-09 11:59         ` Ben Dooks
  2025-06-09 12:30           ` Daniel Henrique Barboza
  1 sibling, 1 reply; 15+ messages in thread
From: Ben Dooks @ 2025-06-09 11:59 UTC (permalink / raw)
  To: Daniel Henrique Barboza, nazar.kazakov, joseph.baker,
	fran.redondo, lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel

On 09/06/2025 12:30, Daniel Henrique Barboza wrote:
> 
> 
> On 6/9/25 7:40 AM, Ben Dooks wrote:
>> On 07/06/2025 21:17, Daniel Henrique Barboza wrote:
>>>
>>>
>>> On 5/27/25 8:24 AM, Ben Dooks wrote:
>>>> Add TYPE_RISCV_CPU_CVA6 for the CVA6 core
>>>>
>>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>>> ---

> The README states right at the start:
> 
> 
> "CVA6 is a 6-stage, single-issue, in-order CPU which implements the 64- 
> bit RISC-V instruction set."
> 
> 
> So this means that CVA6 is a 64-bit CPU only. This means that we want 
> the second
> option: the CPU declaration is fine, but the CVA6 board must be built 
> only for 64
> bits. In patch 1, this line:
> 
> 
>>> config CVA6
>>>      bool
>>>      default y
>>>      depends on RISCV32 || RISCV64  <------------------
> 
> 
> Should be "depends on RISCV64".


I think given the confusion, let's go with the RISCV64 for now and if
it turns out there is an 32-bit build option we can always add it in
later and change anything else around.


-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] hw/riscv: add CVA6 machine
  2025-06-09 11:32     ` Ben Dooks
@ 2025-06-09 12:03       ` Daniel Henrique Barboza
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Henrique Barboza @ 2025-06-09 12:03 UTC (permalink / raw)
  To: Ben Dooks, nazar.kazakov, joseph.baker, fran.redondo,
	lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel



On 6/9/25 8:32 AM, Ben Dooks wrote:
> On 09/06/2025 12:24, Daniel Henrique Barboza wrote:
>>
>>
>> On 5/27/25 8:24 AM, Ben Dooks wrote:
>>> Add a (currently Genesy2 based) CVA6 machine.
>>>
>>> Has SPI and UART, the GPIO and Ethernet are currently black-holed
>>> as there is no hardware model for them (lowRISC ethernet and Xilinx
>>> GPIO)
>>>
>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>> ---
>>> v2:
> 
> Apologie,s looks like it this got rebased out of the release
> 
>>> +/* plic register interface in corev_apu/rv_plic/rtl/plic_regmap.sv */
>>> +
>>
>> I believe you've missed my comment in v1:
>>
> 
> would this be ok
> 
> /*
> * plic register interface in corev_apu/rv_plic/rtl/plic_regmap.sv
> * https://github.com/pulp-platform/rv_plic/blob/master/rtl/plic_regmap.sv
> */

LGTM.


Thanks,

Daniel

> 



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-06-09 11:47         ` Ben Dooks
@ 2025-06-09 12:28           ` Daniel Henrique Barboza
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Henrique Barboza @ 2025-06-09 12:28 UTC (permalink / raw)
  To: Ben Dooks, nazar.kazakov, joseph.baker, fran.redondo,
	lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel



On 6/9/25 8:47 AM, Ben Dooks wrote:
> On 09/06/2025 12:30, Daniel Henrique Barboza wrote:
>>
>>
>> On 6/9/25 7:40 AM, Ben Dooks wrote:
>>> On 07/06/2025 21:17, Daniel Henrique Barboza wrote:
>>>>
>>>>
>>>> On 5/27/25 8:24 AM, Ben Dooks wrote:
>>>>> Add TYPE_RISCV_CPU_CVA6 for the CVA6 core
>>>>>
>>>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>>>> ---
>>>>>   target/riscv/cpu-qom.h |  1 +
>>>>>   target/riscv/cpu.c     | 11 +++++++++++
>>>>>   2 files changed, 12 insertions(+)
>>>>>
>>>>> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
>>>>> index 1ee05eb393..3daf75568c 100644
>>>>> --- a/target/riscv/cpu-qom.h
>>>>> +++ b/target/riscv/cpu-qom.h
>>>>> @@ -34,6 +34,7 @@
>>>>>   #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
>>>>>   #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
>>>>>   #define TYPE_RISCV_CPU_BASE128          RISCV_CPU_TYPE_NAME("x- rv128")
>>>>> +#define TYPE_RISCV_CPU_CVA6             RISCV_CPU_TYPE_NAME("cva6")
>>>>>   #define TYPE_RISCV_CPU_RV32I            RISCV_CPU_TYPE_NAME("rv32i")
>>>>>   #define TYPE_RISCV_CPU_RV32E            RISCV_CPU_TYPE_NAME("rv32e")
>>>>>   #define TYPE_RISCV_CPU_RV64I            RISCV_CPU_TYPE_NAME("rv64i")
>>>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>>>> index 629ac37501..fca45dc9d9 100644
>>>>> --- a/target/riscv/cpu.c
>>>>> +++ b/target/riscv/cpu.c
>>>>> @@ -3009,6 +3009,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>>>>>           .misa_mxl_max = MXL_RV64,
>>>>>       ),
>>>>> +    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_CVA6, TYPE_RISCV_VENDOR_CPU,
>>>>> +        .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVS | RVU,
>>>>> +        .misa_mxl_max = MXL_RV64,
>>>>> +        .cfg.max_satp_mode = VM_1_10_SV39,
>>>>> +        .priv_spec = PRIV_VERSION_1_12_0,
>>>>> +        .cfg.pmp = true,
>>>>> +        .cfg.mmu = true,
>>>>> +        .cfg.ext_zifencei = true,
>>>>> +        .cfg.ext_zicsr = true,
>>>>> +    ),
>>>>> +
>>>>
>>>> The CPU is being added inside a "#if defined(TARGET_RISCV64)" block, meaning
>>>> that it's a 64-bit CPU only. But the CVA6 board added in patch 1 is being
>>>> added for both 32 and 64 bit emulations in hw/riscv/Kconfig:
>>>
>>> Ah yes, it is possible to make a cva6 32bit, is it ok just to ove this
>>> into a different place or is there anything else needed to allow 32 or 64bit?
>>>
>>> I've only been building a 64bit userland to test so didn't notice the
>>> lack of 32bit was an issue.
>>>
>>>> config CVA6
>>>>      bool
>>>>      default y
>>>>      depends on RISCV32 || RISCV64  <------------------
>>>>
>>>> This setup (after patch 3 is added) triggered a test failure in 'check- qtest',
>>>> when polling all available boards in qemu-system-riscv32, because it didn't find
>>>> a default 32 bit CPU for the cva6 board:
>>>>
>>>> # starting QEMU: exec ./qemu-system-riscv32 -qtest unix:/tmp/ qtest-1683816.sock -qtest-log /dev/null -chardev socket,path=/tmp/ qtest-1683816.qmp,id=char0 -mon chardev=char0,mode=control -display none -audio none -machine cva6 -accel qtest
>>>> ----------------------------------- stderr -----------------------------------
>>>> qemu-system-riscv32: ../hw/core/machine.c:1574: is_cpu_type_supported: Assertion `cc != NULL' failed.
>>>> Broken pipe
>>>> ../tests/qtest/libqtest.c:208: kill_qemu() detected QEMU death from signal 6 (Aborted) (core dumped)
>>>>
>>>>
>>>>
>>>> We have 2 options here:
>>>>
>>>> - if the CVA6 board is supposed to run in RISCV32 and RISCV64, then its default
>>>> CPU must be 32 bit compliant too. The CPU declaration in this patch must be moved
>>>> outside the "#if defined(TARGET_RISCV64)" block (e.g right after
>>>> TYPE_RISCV_CPU_SIFIVE_U);
>>>>
>>>> - if the board is 64 bit only then the CPU declaration is fine, and we need to
>>>> change the board hw/riscv/Kconfig entry to "depends on RISCV64".
>>>>
>>>
>>> As long as it is just the #ifdef block I will move it.
>>
>> I just read the CV6 documentation at:
>>
>> https://github.com/openhwgroup/cva6/
>>
>>
>> The README states right at the start:
>>
>>
>> "CVA6 is a 6-stage, single-issue, in-order CPU which implements the 64- bit RISC-V instruction set."
>>
>>
>> So this means that CVA6 is a 64-bit CPU only. This means that we want the second
>> option: the CPU declaration is fine, but the CVA6 board must be built only for 64
>> bits. In patch 1, this line:
> 
> 
> There do seem to be some build variants for cva32a6 deep in the docs
> and the cva6-sdk has builds for both xlen==32 and xlen==64 so I am a
> bit confused here.

It looks like that the 32 bit version (which I assume to be this cva32a65x target)
is not the same CPU as you're adding here. At least in a quick read at the docs.

Even if we move the CPU declaration as I've suggested, making this cva6 work 32 bit
compliant too, that doesn't mean that it'll have the intended purpose as per its
own spec.

My suggestion is to get a clarification with the cva6 folks (or any other interested
party) about whether this is supposed to be a 64 bit only board/cpu or not. If
unsure, I suggest to contribute this as a 64 bit only CPU/board for now and then
revisit this later in case there's a 32 bit variant too.


Thanks,

Daniel



> 
> 



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] target/riscv: add cva6 core type
  2025-06-09 11:59         ` Ben Dooks
@ 2025-06-09 12:30           ` Daniel Henrique Barboza
  0 siblings, 0 replies; 15+ messages in thread
From: Daniel Henrique Barboza @ 2025-06-09 12:30 UTC (permalink / raw)
  To: Ben Dooks, nazar.kazakov, joseph.baker, fran.redondo,
	lawrence.hunter, liwei1518, zhiwei_liu, qemu-riscv
  Cc: qemu-devel



On 6/9/25 8:59 AM, Ben Dooks wrote:
> On 09/06/2025 12:30, Daniel Henrique Barboza wrote:
>>
>>
>> On 6/9/25 7:40 AM, Ben Dooks wrote:
>>> On 07/06/2025 21:17, Daniel Henrique Barboza wrote:
>>>>
>>>>
>>>> On 5/27/25 8:24 AM, Ben Dooks wrote:
>>>>> Add TYPE_RISCV_CPU_CVA6 for the CVA6 core
>>>>>
>>>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>>>> ---
> 
>> The README states right at the start:
>>
>>
>> "CVA6 is a 6-stage, single-issue, in-order CPU which implements the 64- bit RISC-V instruction set."
>>
>>
>> So this means that CVA6 is a 64-bit CPU only. This means that we want the second
>> option: the CPU declaration is fine, but the CVA6 board must be built only for 64
>> bits. In patch 1, this line:
>>
>>
>>>> config CVA6
>>>>      bool
>>>>      default y
>>>>      depends on RISCV32 || RISCV64  <------------------
>>
>>
>> Should be "depends on RISCV64".
> 
> 
> I think given the confusion, let's go with the RISCV64 for now and if
> it turns out there is an 32-bit build option we can always add it in
> later and change anything else around.

Just sent a reply making this same suggestion. I agree.


Daniel

> 
> 



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2025-06-09 12:32 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-27 11:24 Add initial CVA6 implementaiton Ben Dooks
2025-05-27 11:24 ` [PATCH v2 1/3] hw/riscv: add CVA6 machine Ben Dooks
2025-06-09 11:24   ` Daniel Henrique Barboza
2025-06-09 11:32     ` Ben Dooks
2025-06-09 12:03       ` Daniel Henrique Barboza
2025-05-27 11:24 ` [PATCH v2 2/3] target/riscv: add cva6 core type Ben Dooks
2025-06-07 20:17   ` Daniel Henrique Barboza
2025-06-09 10:40     ` Ben Dooks
2025-06-09 11:30       ` Daniel Henrique Barboza
2025-06-09 11:47         ` Ben Dooks
2025-06-09 12:28           ` Daniel Henrique Barboza
2025-06-09 11:59         ` Ben Dooks
2025-06-09 12:30           ` Daniel Henrique Barboza
2025-05-27 11:24 ` [PATCH v2 3/3] hw/riscv: set cva6 to use TYPE_RISCV_CPU_CVA6 Ben Dooks
2025-06-07 20:22 ` Add initial CVA6 implementaiton Daniel Henrique Barboza

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).