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