On Tue, 11 Nov 2025 15:29:42 -0300, Daniel Henrique Barboza wrote:
>From: Fei Wu <[email protected]>
>
>The RISC-V Server Platform specification [1] defines a standardized set
>of hardware and software capabilities, that portable system software,
>such as OS and hypervisors can rely on being present in a RISC-V server
>platform.
>
>We do not have all the required extensions in QEMU: we're missing
>'sdext'. In theory we shouldn't go ahead with this work, but the
>emulation as is now is proving to be useful for development and testing
>of other parts of the SW stack (firmware, kernel) and we would like to
>make it broadly available to everyone. We're contributing it as
>'experimental', hopefully making it clear that the board does NOT
>complies 100% with [1].
>
>The main features included in this emulation are:
>
> - Based on riscv virt machine type
> - A new memory map as close as virt machine as possible
> - A new virt CPU type rvsp-ref-cpu for server platform compliance
> - AIA
> - PCIe AHCI
> - PCIe NIC
> - No virtio device
> - No fw_cfg device
> - No ACPI table provided
> - Only minimal device tree nodes
>
>[1] https://github.com/riscv-non-isa/riscv-server-platform
>
>Signed-off-by: Fei Wu <[email protected]>
>Signed-off-by: Daniel Henrique Barboza <[email protected]>
>---
> configs/devices/riscv64-softmmu/default.mak |    1 +
> hw/riscv/Kconfig                            |   14 +
> hw/riscv/meson.build                        |    1 +
> hw/riscv/server_platform_ref.c              | 1276 +++++++++++++++++++
> 4 files changed, 1292 insertions(+)
> create mode 100644 hw/riscv/server_platform_ref.c
>
>diff --git a/configs/devices/riscv64-softmmu/default.mak
b/configs/devices/riscv64-softmmu/default.mak
>index e485bbd1a3..e6075a7113 100644
>--- a/configs/devices/riscv64-softmmu/default.mak
>+++ b/configs/devices/riscv64-softmmu/default.mak
>@@ -9,6 +9,7 @@
> # CONFIG_SIFIVE_E=n
> # CONFIG_SIFIVE_U=n
> # CONFIG_RISCV_VIRT=n
>+# CONFIG_SERVER_PLATFORM_REF=n
> # CONFIG_MICROCHIP_PFSOC=n
> # CONFIG_SHAKTI_C=n
> # CONFIG_XIANGSHAN_KUNMINGHU=n
>diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
>index fc9c35bd98..6a5085c7a5 100644
>--- a/hw/riscv/Kconfig
>+++ b/hw/riscv/Kconfig
>@@ -69,6 +69,20 @@ config RISCV_VIRT
>     select ACPI
>     select ACPI_PCI
>
>+config SERVER_PLATFORM_REF
>+    bool
>+    default y
>+    depends on RISCV64
>+    select RISCV_NUMA
>+    select GOLDFISH_RTC
>+    select PCI
>+    select PCI_EXPRESS_GENERIC_BRIDGE
>+    select PFLASH_CFI01
>+    select SERIAL
>+    select RISCV_ACLINT
>+    select RISCV_APLIC
>+    select RISCV_IMSIC
>+
> config SHAKTI_C
>     bool
>     default y
>diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
>index 2a8d5b136c..0daf77e887 100644
>--- a/hw/riscv/meson.build
>+++ b/hw/riscv/meson.build
>@@ -4,6 +4,7 @@ riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: 
>files('numa.c'))
> riscv_ss.add(files('riscv_hart.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_SERVER_PLATFORM_REF', if_true:
files('server_platform_ref.c'))
> riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c'))
> riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sifive_e.c'))
> riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c'))
>diff --git a/hw/riscv/server_platform_ref.c b/hw/riscv/server_platform_ref.c
>new file mode 100644
>index 0000000000..ef2891a9d7
>--- /dev/null
>+++ b/hw/riscv/server_platform_ref.c
>@@ -0,0 +1,1276 @@
>+/*
>+ * QEMU RISC-V Server Platform (RVSP) Reference Board
>+ *
>+ * Copyright (c) 2024 Intel, Inc.
>+ * Copyright (c) 2025 Ventana Micro Systems Inc.
>+ *
>+ * This board is compliant RISC-V Server platform specification and leveraging
>+ * a lot of riscv virt code.
>+ *
>+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
>+ * See the COPYING file in the top-level directory.
>+ */
>+
>+#include "qemu/osdep.h"
>+#include "qemu/units.h"
>+#include "qemu/error-report.h"
>+#include "qemu/guest-random.h"
>+#include "qapi/error.h"
>+#include "qapi/qapi-visit-common.h"
>+#include "hw/boards.h"
>+#include "hw/loader.h"
>+#include "hw/sysbus.h"
>+#include "hw/qdev-properties.h"
>+#include "hw/char/serial.h"
>+#include "hw/block/flash.h"
>+#include "hw/ide/pci.h"
>+#include "hw/ide/ahci-pci.h"
>+#include "hw/pci/pci.h"
>+#include "hw/pci-host/gpex.h"
>+#include "hw/core/sysbus-fdt.h"
>+#include "hw/riscv/riscv_hart.h"
>+#include "hw/riscv/boot.h"
>+#include "hw/riscv/numa.h"
>+#include "hw/intc/riscv_aclint.h"
>+#include "hw/intc/riscv_aplic.h"
>+#include "hw/intc/riscv_imsic.h"
>+#include "chardev/char.h"
>+#include "hw/char/serial-mm.h"
>+#include "system/device_tree.h"
>+#include "system/runstate.h"
>+#include "system/system.h"
>+#include "system/tcg.h"
>+#include "system/qtest.h"
>+#include "target/riscv/cpu.h"
>+#include "target/riscv/pmu.h"
>+#include "net/net.h"
>+
>+#define RVSP_CPUS_MAX_BITS             9
>+#define RVSP_CPUS_MAX                  (1 << RVSP_CPUS_MAX_BITS)
>+#define RVSP_SOCKETS_MAX_BITS          2
>+#define RVSP_SOCKETS_MAX               (1 << RVSP_SOCKETS_MAX_BITS)
>+
>+#define RVSP_IRQCHIP_NUM_MSIS 255
>+#define RVSP_IRQCHIP_NUM_SOURCES 96
>+#define RVSP_IRQCHIP_NUM_PRIO_BITS 3
>+#define RVSP_IRQCHIP_MAX_GUESTS_BITS 3
>+#define RVSP_IRQCHIP_MAX_GUESTS ((1U << RVSP_IRQCHIP_MAX_GUESTS_BITS) - 1U)
>+
>+#define FDT_PCI_ADDR_CELLS    3
>+#define FDT_PCI_INT_CELLS     1
>+#define FDT_APLIC_INT_CELLS   2
>+#define FDT_IMSIC_INT_CELLS   0
>+#define FDT_MAX_INT_CELLS     2
>+#define FDT_MAX_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \
>+                                 1 + FDT_MAX_INT_CELLS)
>+#define FDT_APLIC_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \
>+                                 1 + FDT_APLIC_INT_CELLS)
>+
>+#define NUM_SATA_PORTS  6
>+
>+#define SYSCON_RESET     0x1
>+#define SYSCON_POWEROFF  0x2
>+
>+#define TYPE_RVSP_REF_MACHINE MACHINE_TYPE_NAME("rvsp-ref")
>+OBJECT_DECLARE_SIMPLE_TYPE(RVSPMachineState, RVSP_REF_MACHINE)
>+
>+struct RVSPMachineState {
>+    /*< private >*/
>+    MachineState parent;
>+
>+    /*< public >*/
>+    Notifier machine_done;
>+    RISCVHartArrayState soc[RVSP_SOCKETS_MAX];
>+    DeviceState *irqchip[RVSP_SOCKETS_MAX];
>+    PFlashCFI01 *flash[2];
>+
>+    int fdt_size;
>+    int aia_guests;
>+    const MemMapEntry *memmap;
>+};
>+
>+enum {
>+    RVSP_DEBUG,
>+    RVSP_MROM,
>+    RVSP_RESET_SYSCON,
>+    RVSP_RTC,
>+    RVSP_ACLINT,
>+    RVSP_APLIC_M,
>+    RVSP_APLIC_S,
>+    RVSP_UART0,
>+    RVSP_IMSIC_M,
>+    RVSP_IMSIC_S,
>+    RVSP_FLASH,
>+    RVSP_DRAM,
>+    RVSP_PCIE_MMIO,
>+    RVSP_PCIE_PIO,
>+    RVSP_PCIE_ECAM,
>+    RVSP_PCIE_MMIO_HIGH
>+};
>+
>+enum {
>+    RVSP_UART0_IRQ = 10,
>+    RVSP_RTC_IRQ = 11,
>+    RVSP_PCIE_IRQ = 0x20, /* 32 to 35 */
>+};
>+
>+/*
>+ * The server soc reference machine physical address space used by some of the
>+ * devices namely ACLINT, APLIC and IMSIC depend on number of Sockets, number
>+ * of CPUs, and number of IMSIC guest files.
>+ *
>+ * Various limits defined by RVSP_SOCKETS_MAX_BITS, RVSP_CPUS_MAX_BITS, and
>+ * RVSP_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization of server 
>soc
>+ * reference machine physical address space.
>+ */
>+
>+#define RVSP_IMSIC_GROUP_MAX_SIZE      (1U << IMSIC_MMIO_GROUP_MIN_SHIFT)
>+#if RVSP_IMSIC_GROUP_MAX_SIZE < \
>+    IMSIC_GROUP_SIZE(RVSP_CPUS_MAX_BITS, RVSP_IRQCHIP_MAX_GUESTS_BITS)
>+#error "Can't accomodate single IMSIC group in address space"
>+#endif
>+
>+#define RVSP_IMSIC_MAX_SIZE            (RVSP_SOCKETS_MAX * \
>+                                        RVSP_IMSIC_GROUP_MAX_SIZE)
>+#if 0x4000000 < RVSP_IMSIC_MAX_SIZE
>+#error "Can't accomodate all IMSIC groups in address space"
>+#endif
>+
>+static const MemMapEntry rvsp_ref_memmap[] = {
>+    [RVSP_DEBUG] =          {        0x0,         0x100 },
>+    [RVSP_MROM] =           {     0x1000,        0xf000 },
>+    [RVSP_RESET_SYSCON] =   {   0x100000,        0x1000 },
>+    [RVSP_RTC] =            {   0x101000,        0x1000 },
>+    [RVSP_ACLINT] =         {  0x2000000,       0x10000 },
>+    [RVSP_PCIE_PIO] =       {  0x3000000,       0x10000 },
>+    [RVSP_APLIC_M] =        {  0xc000000, APLIC_SIZE(RVSP_CPUS_MAX) },
>+    [RVSP_APLIC_S] =        {  0xd000000, APLIC_SIZE(RVSP_CPUS_MAX) },
>+    [RVSP_UART0] =          { 0x10000000,         0x100 },
>+    [RVSP_FLASH] =          { 0x20000000,     0x4000000 },
>+    [RVSP_IMSIC_M] =        { 0x24000000, RVSP_IMSIC_MAX_SIZE },
>+    [RVSP_IMSIC_S] =        { 0x28000000, RVSP_IMSIC_MAX_SIZE },
>+    [RVSP_PCIE_ECAM] =      { 0x30000000,    0x10000000 },
>+    [RVSP_PCIE_MMIO] =      { 0x40000000,    0x40000000 },
>+    [RVSP_DRAM] =           { 0x80000000, 0xff80000000ull },
>+    [RVSP_PCIE_MMIO_HIGH] = { 0x10000000000ull, 0x10000000000ull },
The base address of RVSP_PCIE_MMIO_HIGH exceeds the 39-bit address space, while
the satp mode of the rvsp-ref-cpu is SV39 (based on the RVA23S64).

static RISCVCPUProfile RVA23S64 = {
    .u_parent = &RVA23U64,
    .s_parent = &RVA22S64,
    .name = "rva23s64",
    .misa_ext = RVS,
    .priv_spec = PRIV_VERSION_1_13_0,
    .satp_mode = VM_1_10_SV39, /* there */
    ...
}

This will cause an error when EDKII processes the address mapping of PCI MMIO,
but I am not yet sure whose issue this is.

I suggest setting the default value of satp_mode for rvsp-ref-cpu to SV48.

Thanks,
Chao


Reply via email to