qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board
@ 2025-05-28 20:01 Daniel Henrique Barboza
  2025-05-28 20:01 ` [PATCH v3 1/4] target/riscv/cpu.c: remove 'bare' condition for .profile Daniel Henrique Barboza
                   ` (4 more replies)
  0 siblings, 5 replies; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-05-28 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu, palmer,
	ajones, Daniel Henrique Barboza

Hi,

This is my attempt to ressurect the Server SoC Platform reference work
that has been buried for an year. The last posting was made an year ago
[1]. 

Most of the changes were made due to upstream differences from one year
ago. Patch 1 is an example of that.

In patch 2 (former 1), the main difference is the new CPU is rva23s64
compliant. This wasn't possible in May 2024 because we didn't have this
support back then.

Patch 3 consists mostly of code base changes rather than functional
changes. There was a discussion about whether we should supply fdts in
this machine back in the v2 review [2]. The answer is yes: machine mode
requires fdt to work, and we want to be flexible enough to generate our
own fdt instead of relying on EDK2 to supply them. Note that we can also
supply an EDK2-generated fdt via command line, bypassing the fdt created
by QEMU, if desired.

Patch 4 adds a riscv-iommu-sys device to the board. This wasn't possible
back then because we didn't have the required upstream support for it.

Patches based on alistair/riscv-to-apply.next.


Changes from v2:
- patch 1 (new):
  - allow CPUs other than 'bare' to assign profiles
- patch 2 (former 1):
  - added RVA23 profile support in the rvsp-ref CPU
- patch 3 (former 2):
  - hw/riscv/Kconfig changes:
    * added 'default y' in hw/riscv/Kconfig to build the board by default
    * added 'depends on RISCV64' to prevent the board to be built for qemu-system-riscv32

  - HMP qtest fixes:
    * added rvsp_aclint_allowed(). Use it instead of (!tcg_enabled()) when checking aclint support

  - changes in rvsp_ref_machine_done():
    * added 'RISCVBootInfo boot_info' struct
    * changed riscv_find_and_load_firmware(), riscv_calc_kernel_start_addr(),
      riscv_load_kernel() and riscv_compute_fdt_addr() to use boot_info

  - added "hw/char/serial-mm.h" include
  - changed 'addr' mem variables to 'hwaddr'
  - use HWADDR_PRIx format with 'addr' variables
  - changed GPEX_NUM_IRQS to PCI_NUM_PINS

- patch 4 (new):
  - add riscv-iommu-sys platform device
- v2 link: https://lore.kernel.org/qemu-riscv/20240312135222.3187945-1-fei2.wu@intel.com/


[1] https://lore.kernel.org/qemu-riscv/20240312135222.3187945-1-fei2.wu@intel.com/
[2] https://lore.kernel.org/qemu-riscv/CAHBxVyG186Zo7nAm7o8=vhBtzU+x8ry4_mWwHxuaZ8BasnDyPg@mail.gmail.com/

Daniel Henrique Barboza (2):
  target/riscv/cpu.c: remove 'bare' condition for .profile
  hw/riscv/server_platform_ref.c: add riscv-iommu-sys

Fei Wu (2):
  target/riscv: Add server platform reference cpu
  hw/riscv: Add server platform reference machine

 configs/devices/riscv64-softmmu/default.mak |    1 +
 hw/riscv/Kconfig                            |   15 +
 hw/riscv/meson.build                        |    1 +
 hw/riscv/server_platform_ref.c              | 1346 +++++++++++++++++++
 target/riscv/cpu-qom.h                      |    1 +
 target/riscv/cpu.c                          |   12 +-
 6 files changed, 1375 insertions(+), 1 deletion(-)
 create mode 100644 hw/riscv/server_platform_ref.c

-- 
2.49.0



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

* [PATCH v3 1/4] target/riscv/cpu.c: remove 'bare' condition for .profile
  2025-05-28 20:01 [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Daniel Henrique Barboza
@ 2025-05-28 20:01 ` Daniel Henrique Barboza
  2025-05-29 11:56   ` Andrew Jones
  2025-05-28 20:01 ` [PATCH v3 2/4] target/riscv: Add server platform reference cpu Daniel Henrique Barboza
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-05-28 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu, palmer,
	ajones, Daniel Henrique Barboza

We want to configure other CPU types to use profiles as an alternative
to adding every profile extension explicitly, i.e. a profile is nothing
more than an extension bundle.

This means that a vendor CPU can set .profile=rva23s64 while having the
same handling as any other vendor CPU. Same thing with all other CPU
types.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index fe21e0fb44..4a30cf8444 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2713,7 +2713,6 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
         mcc->def->bare |= def->bare;
         if (def->profile) {
             assert(profile_extends(def->profile, mcc->def->profile));
-            assert(mcc->def->bare);
             mcc->def->profile = def->profile;
         }
         if (def->misa_mxl_max) {
-- 
2.49.0



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

* [PATCH v3 2/4] target/riscv: Add server platform reference cpu
  2025-05-28 20:01 [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Daniel Henrique Barboza
  2025-05-28 20:01 ` [PATCH v3 1/4] target/riscv/cpu.c: remove 'bare' condition for .profile Daniel Henrique Barboza
@ 2025-05-28 20:01 ` Daniel Henrique Barboza
  2025-05-29 11:56   ` Andrew Jones
  2025-10-30 15:01   ` Chao Liu
  2025-05-28 20:01 ` [PATCH v3 3/4] hw/riscv: Add server platform reference machine Daniel Henrique Barboza
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-05-28 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu, palmer,
	ajones, Fei Wu, Daniel Henrique Barboza

From: Fei Wu <wu.fei9@sanechips.com.cn>

The harts requirements of RISC-V server platform [1] require RVA23 ISA
profile support, plus Sv48, Svadu, H, Sscofmpf etc. This patch provides
a virt CPU type (rvsp-ref) as compliant as possible.

[1] https://github.com/riscv-non-isa/riscv-server-platform/blob/main/server_platform_requirements.adoc

Signed-off-by: Fei Wu <fei2.wu@intel.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 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..70978fd53c 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -55,6 +55,7 @@
 #define TYPE_RISCV_CPU_VEYRON_V1        RISCV_CPU_TYPE_NAME("veyron-v1")
 #define TYPE_RISCV_CPU_TT_ASCALON       RISCV_CPU_TYPE_NAME("tt-ascalon")
 #define TYPE_RISCV_CPU_XIANGSHAN_NANHU  RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
+#define TYPE_RISCV_CPU_RVSP_REF         RISCV_CPU_TYPE_NAME("rvsp-ref")
 #define TYPE_RISCV_CPU_HOST             RISCV_CPU_TYPE_NAME("host")
 
 OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4a30cf8444..ec2fbc0e78 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3166,6 +3166,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .cfg.max_satp_mode = VM_1_10_SV39,
     ),
 
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RVSP_REF, TYPE_RISCV_VENDOR_CPU,
+        .misa_mxl_max = MXL_RV64,
+        .profile = &RVA23S64,
+
+        /* ISA extensions */
+        .cfg.ext_zkr = true,
+        .cfg.ext_svadu = true,
+
+        .cfg.max_satp_mode = VM_1_10_SV57,
+    ),
+
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE128, TYPE_RISCV_DYNAMIC_CPU,
         .cfg.max_satp_mode = VM_1_10_SV57,
-- 
2.49.0



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

* [PATCH v3 3/4] hw/riscv: Add server platform reference machine
  2025-05-28 20:01 [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Daniel Henrique Barboza
  2025-05-28 20:01 ` [PATCH v3 1/4] target/riscv/cpu.c: remove 'bare' condition for .profile Daniel Henrique Barboza
  2025-05-28 20:01 ` [PATCH v3 2/4] target/riscv: Add server platform reference cpu Daniel Henrique Barboza
@ 2025-05-28 20:01 ` Daniel Henrique Barboza
  2025-05-29 12:31   ` Andrew Jones
  2025-10-30 22:27   ` Philippe Mathieu-Daudé
  2025-05-28 20:01 ` [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys Daniel Henrique Barboza
  2025-10-30 11:48 ` [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Chao Liu
  4 siblings, 2 replies; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-05-28 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu, palmer,
	ajones, Fei Wu, Daniel Henrique Barboza

From: Fei Wu <wu.fei9@sanechips.com.cn>

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.

A corresponding Qemu RISC-V server platform reference (rvsp-ref for
short) machine type is added to provide a environment for firmware/OS
development and testing. The main features included in rvsp-ref 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 <fei2.wu@intel.com>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 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 39ed3a0061..0c4893b708 100644
--- a/configs/devices/riscv64-softmmu/default.mak
+++ b/configs/devices/riscv64-softmmu/default.mak
@@ -9,5 +9,6 @@
 # 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
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index e6a0ac1fa1..f626774c52 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 c22f3a7216..7a663fac64 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..5102286103
--- /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 },
+};
+
+#define RVSP_FLASH_SECTOR_SIZE (256 * KiB)
+
+static PFlashCFI01 *rvsp_flash_create(RVSPMachineState *s,
+                                      const char *name,
+                                      const char *alias_prop_name)
+{
+    /*
+     * Create a single flash device.  We use the same parameters as
+     * the flash devices on the ARM virt board.
+     */
+    DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01);
+
+    qdev_prop_set_uint64(dev, "sector-length", RVSP_FLASH_SECTOR_SIZE);
+    qdev_prop_set_uint8(dev, "width", 4);
+    qdev_prop_set_uint8(dev, "device-width", 2);
+    qdev_prop_set_bit(dev, "big-endian", false);
+    qdev_prop_set_uint16(dev, "id0", 0x89);
+    qdev_prop_set_uint16(dev, "id1", 0x18);
+    qdev_prop_set_uint16(dev, "id2", 0x00);
+    qdev_prop_set_uint16(dev, "id3", 0x00);
+    qdev_prop_set_string(dev, "name", name);
+
+    object_property_add_child(OBJECT(s), name, OBJECT(dev));
+    object_property_add_alias(OBJECT(s), alias_prop_name,
+                              OBJECT(dev), "drive");
+
+    return PFLASH_CFI01(dev);
+}
+
+static void rvsp_flash_map(PFlashCFI01 *flash,
+                           hwaddr base, hwaddr size,
+                           MemoryRegion *sysmem)
+{
+    DeviceState *dev = DEVICE(flash);
+
+    assert(QEMU_IS_ALIGNED(size, RVSP_FLASH_SECTOR_SIZE));
+    assert(size / RVSP_FLASH_SECTOR_SIZE <= UINT32_MAX);
+    qdev_prop_set_uint32(dev, "num-blocks", size / RVSP_FLASH_SECTOR_SIZE);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+    memory_region_add_subregion(sysmem, base,
+                                sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
+                                                       0));
+}
+
+static void rvsp_flash_maps(RVSPMachineState *s,
+                            MemoryRegion *sysmem)
+{
+    hwaddr flashsize = rvsp_ref_memmap[RVSP_FLASH].size / 2;
+    hwaddr flashbase = rvsp_ref_memmap[RVSP_FLASH].base;
+
+    rvsp_flash_map(s->flash[0], flashbase, flashsize, sysmem);
+    rvsp_flash_map(s->flash[1], flashbase + flashsize, flashsize, sysmem);
+}
+
+static void create_pcie_irq_map(RVSPMachineState *s, void *fdt, char *nodename,
+                                uint32_t irqchip_phandle)
+{
+    int pin, dev;
+    uint32_t irq_map_stride = 0;
+    uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS *
+                          FDT_MAX_INT_MAP_WIDTH] = {};
+    uint32_t *irq_map = full_irq_map;
+
+    /*
+     * This code creates a standard swizzle of interrupts such that
+     * each device's first interrupt is based on it's PCI_SLOT number.
+     * (See pci_swizzle_map_irq_fn())
+     *
+     * We only need one entry per interrupt in the table (not one per
+     * possible slot) seeing the interrupt-map-mask will allow the table
+     * to wrap to any number of devices.
+     */
+    for (dev = 0; dev < PCI_NUM_PINS; dev++) {
+        int devfn = dev * 0x8;
+
+        for (pin = 0; pin < PCI_NUM_PINS; pin++) {
+            int irq_nr = RVSP_PCIE_IRQ +
+                         ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS);
+            int i = 0;
+
+            /* Fill PCI address cells */
+            irq_map[i] = cpu_to_be32(devfn << 8);
+            i += FDT_PCI_ADDR_CELLS;
+
+            /* Fill PCI Interrupt cells */
+            irq_map[i] = cpu_to_be32(pin + 1);
+            i += FDT_PCI_INT_CELLS;
+
+            /* Fill interrupt controller phandle and cells */
+            irq_map[i++] = cpu_to_be32(irqchip_phandle);
+            irq_map[i++] = cpu_to_be32(irq_nr);
+            irq_map[i++] = cpu_to_be32(0x4);
+
+            if (!irq_map_stride) {
+                irq_map_stride = i;
+            }
+            irq_map += irq_map_stride;
+        }
+    }
+
+    qemu_fdt_setprop(fdt, nodename, "interrupt-map", full_irq_map,
+                     PCI_NUM_PINS * PCI_NUM_PINS *
+                     irq_map_stride * sizeof(uint32_t));
+
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
+                           0x1800, 0, 0, 0x7);
+}
+
+static void create_fdt_socket_cpus(RVSPMachineState *s, int socket,
+                                   char *clust_name, uint32_t *phandle,
+                                   uint32_t *intc_phandles)
+{
+    int cpu;
+    uint32_t cpu_phandle;
+    MachineState *ms = MACHINE(s);
+    bool is_32_bit = riscv_is_32bit(&s->soc[0]);
+    int8_t satp_mode_max;
+
+    for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
+        RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
+        satp_mode_max = cpu_ptr->cfg.max_satp_mode;
+        g_autofree char *cpu_name = NULL;
+        g_autofree char *core_name = NULL;
+        g_autofree char *intc_name = NULL;
+        g_autofree char *sv_name = NULL;
+
+        cpu_phandle = (*phandle)++;
+
+        cpu_name = g_strdup_printf("/cpus/cpu@%d",
+            s->soc[socket].hartid_base + cpu);
+        qemu_fdt_add_subnode(ms->fdt, cpu_name);
+
+        if (satp_mode_max != -1) {
+            sv_name = g_strdup_printf("riscv,%s",
+                                      satp_mode_str(satp_mode_max, is_32_bit));
+            qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);
+        }
+
+        riscv_isa_write_fdt(cpu_ptr, ms->fdt, cpu_name);
+
+        if (cpu_ptr->cfg.ext_zicbom) {
+            qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cbom-block-size",
+                                  cpu_ptr->cfg.cbom_blocksize);
+        }
+
+        if (cpu_ptr->cfg.ext_zicboz) {
+            qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cboz-block-size",
+                                  cpu_ptr->cfg.cboz_blocksize);
+        }
+
+        if (cpu_ptr->cfg.ext_zicbop) {
+            qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cbop-block-size",
+                                  cpu_ptr->cfg.cbop_blocksize);
+        }
+
+        qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
+        qemu_fdt_setprop_string(ms->fdt, cpu_name, "status", "okay");
+        qemu_fdt_setprop_cell(ms->fdt, cpu_name, "reg",
+            s->soc[socket].hartid_base + cpu);
+        qemu_fdt_setprop_string(ms->fdt, cpu_name, "device_type", "cpu");
+        riscv_socket_fdt_write_id(ms, cpu_name, socket);
+        qemu_fdt_setprop_cell(ms->fdt, cpu_name, "phandle", cpu_phandle);
+
+        intc_phandles[cpu] = (*phandle)++;
+
+        intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
+        qemu_fdt_add_subnode(ms->fdt, intc_name);
+        qemu_fdt_setprop_cell(ms->fdt, intc_name, "phandle",
+            intc_phandles[cpu]);
+        qemu_fdt_setprop_string(ms->fdt, intc_name, "compatible",
+            "riscv,cpu-intc");
+        qemu_fdt_setprop(ms->fdt, intc_name, "interrupt-controller", NULL, 0);
+        qemu_fdt_setprop_cell(ms->fdt, intc_name, "#interrupt-cells", 1);
+
+        core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
+        qemu_fdt_add_subnode(ms->fdt, core_name);
+        qemu_fdt_setprop_cell(ms->fdt, core_name, "cpu", cpu_phandle);
+    }
+}
+
+static void create_fdt_socket_memory(RVSPMachineState *s,
+                                     const MemMapEntry *memmap, int socket)
+{
+    g_autofree char *mem_name = NULL;
+    hwaddr addr, size;
+    MachineState *ms = MACHINE(s);
+
+    addr = memmap[RVSP_DRAM].base + riscv_socket_mem_offset(ms, socket);
+    size = riscv_socket_mem_size(ms, socket);
+    mem_name = g_strdup_printf("/memory@%"HWADDR_PRIx, addr);
+    qemu_fdt_add_subnode(ms->fdt, mem_name);
+    qemu_fdt_setprop_cells(ms->fdt, mem_name, "reg",
+        addr >> 32, addr, size >> 32, size);
+    qemu_fdt_setprop_string(ms->fdt, mem_name, "device_type", "memory");
+    riscv_socket_fdt_write_id(ms, mem_name, socket);
+}
+
+static void create_fdt_socket_aclint(RVSPMachineState *s,
+                                     const MemMapEntry *memmap, int socket,
+                                     uint32_t *intc_phandles)
+{
+    int cpu;
+    g_autofree char *name = NULL;
+    hwaddr addr, size;
+    uint32_t aclint_cells_size;
+    g_autofree uint32_t *aclint_mtimer_cells = NULL;
+    MachineState *ms = MACHINE(s);
+
+    aclint_mtimer_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
+
+    for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
+        aclint_mtimer_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
+        aclint_mtimer_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_TIMER);
+    }
+    aclint_cells_size = s->soc[socket].num_harts * sizeof(uint32_t) * 2;
+
+    addr = memmap[RVSP_ACLINT].base + RISCV_ACLINT_DEFAULT_MTIMER_SIZE * socket;
+    size = RISCV_ACLINT_DEFAULT_MTIMER_SIZE;
+
+    name = g_strdup_printf("/soc/mtimer@%"HWADDR_PRIx, addr);
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible",
+        "riscv,aclint-mtimer");
+    qemu_fdt_setprop_cells(ms->fdt, name, "reg",
+        0x0, addr + RISCV_ACLINT_DEFAULT_MTIME,
+        0x0, size - RISCV_ACLINT_DEFAULT_MTIME,
+        0x0, addr + RISCV_ACLINT_DEFAULT_MTIMECMP,
+        0x0, RISCV_ACLINT_DEFAULT_MTIME);
+    qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
+        aclint_mtimer_cells, aclint_cells_size);
+    riscv_socket_fdt_write_id(ms, name, socket);
+}
+
+static uint32_t imsic_num_bits(uint32_t count)
+{
+    uint32_t ret = 0;
+
+    while (BIT(ret) < count) {
+        ret++;
+    }
+
+    return ret;
+}
+
+static void create_fdt_one_imsic(RVSPMachineState *s, hwaddr base_addr,
+                                 uint32_t *intc_phandles, uint32_t msi_phandle,
+                                 bool m_mode, uint32_t imsic_guest_bits)
+{
+    int cpu, socket;
+    g_autofree char *imsic_name = NULL;
+    MachineState *ms = MACHINE(s);
+    int socket_count = riscv_socket_count(ms);
+    uint32_t imsic_max_hart_per_socket, imsic_addr, imsic_size;
+    g_autofree uint32_t *imsic_cells = NULL;
+    g_autofree uint32_t *imsic_regs = NULL;
+
+    imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
+    imsic_regs = g_new0(uint32_t, socket_count * 4);
+
+    for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+        imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
+        imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
+    }
+
+    imsic_max_hart_per_socket = 0;
+    for (socket = 0; socket < socket_count; socket++) {
+        imsic_addr = base_addr + socket * RVSP_IMSIC_GROUP_MAX_SIZE;
+        imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
+                     s->soc[socket].num_harts;
+        imsic_regs[socket * 4 + 0] = 0;
+        imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
+        imsic_regs[socket * 4 + 2] = 0;
+        imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
+        if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
+            imsic_max_hart_per_socket = s->soc[socket].num_harts;
+        }
+    }
+
+    imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
+    qemu_fdt_add_subnode(ms->fdt, imsic_name);
+    qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
+    qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
+                          FDT_IMSIC_INT_CELLS);
+    qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0);
+    qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0);
+    qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
+                     imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
+    qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
+                     socket_count * sizeof(uint32_t) * 4);
+    qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
+                     RVSP_IRQCHIP_NUM_MSIS);
+
+    if (imsic_guest_bits) {
+        qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
+                              imsic_guest_bits);
+    }
+
+    if (socket_count > 1) {
+        qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
+                              imsic_num_bits(imsic_max_hart_per_socket));
+        qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
+                              imsic_num_bits(socket_count));
+        qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
+                              IMSIC_MMIO_GROUP_MIN_SHIFT);
+    }
+    qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle);
+}
+
+static void create_fdt_imsic(RVSPMachineState *s, const MemMapEntry *memmap,
+                             uint32_t *phandle, uint32_t *intc_phandles,
+                             uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
+{
+    *msi_m_phandle = (*phandle)++;
+    *msi_s_phandle = (*phandle)++;
+
+    /* M-level IMSIC node */
+    create_fdt_one_imsic(s, memmap[RVSP_IMSIC_M].base, intc_phandles,
+                         *msi_m_phandle, true, 0);
+
+    /* S-level IMSIC node */
+    create_fdt_one_imsic(s, memmap[RVSP_IMSIC_S].base, intc_phandles,
+                         *msi_s_phandle, false,
+                         imsic_num_bits(s->aia_guests + 1));
+
+}
+
+static void create_fdt_one_aplic(RVSPMachineState *s, int socket,
+                                 unsigned long aplic_addr, uint32_t aplic_size,
+                                 uint32_t msi_phandle,
+                                 uint32_t *intc_phandles,
+                                 uint32_t aplic_phandle,
+                                 uint32_t aplic_child_phandle,
+                                 bool m_mode, int num_harts)
+{
+    int cpu;
+    g_autofree char *aplic_name = NULL;
+    g_autofree uint32_t *aplic_cells = g_new0(uint32_t, num_harts * 2);
+    MachineState *ms = MACHINE(s);
+
+    aplic_cells = g_new0(uint32_t, num_harts * 2);
+
+    for (cpu = 0; cpu < num_harts; cpu++) {
+        aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
+        aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
+    }
+
+    aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
+    qemu_fdt_add_subnode(ms->fdt, aplic_name);
+    qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
+    qemu_fdt_setprop_cell(ms->fdt, aplic_name,
+                          "#interrupt-cells", FDT_APLIC_INT_CELLS);
+    qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
+
+    qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
+
+    qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
+                           0x0, aplic_addr, 0x0, aplic_size);
+    qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
+                          RVSP_IRQCHIP_NUM_SOURCES);
+
+    if (aplic_child_phandle) {
+        qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
+                              aplic_child_phandle);
+        qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
+                               aplic_child_phandle, 0x1,
+                               RVSP_IRQCHIP_NUM_SOURCES);
+    }
+
+    riscv_socket_fdt_write_id(ms, aplic_name, socket);
+    qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle);
+}
+
+static void create_fdt_socket_aplic(RVSPMachineState *s,
+                                    const MemMapEntry *memmap, int socket,
+                                    uint32_t msi_m_phandle,
+                                    uint32_t msi_s_phandle,
+                                    uint32_t *phandle,
+                                    uint32_t *intc_phandles,
+                                    uint32_t *aplic_phandles,
+                                    int num_harts)
+{
+    unsigned long aplic_addr;
+    uint32_t aplic_m_phandle, aplic_s_phandle;
+
+    aplic_m_phandle = (*phandle)++;
+    aplic_s_phandle = (*phandle)++;
+
+    /* M-level APLIC node */
+    aplic_addr = memmap[RVSP_APLIC_M].base + memmap[RVSP_APLIC_M].size * socket;
+    create_fdt_one_aplic(s, socket, aplic_addr, memmap[RVSP_APLIC_M].size,
+                         msi_m_phandle, intc_phandles,
+                         aplic_m_phandle, aplic_s_phandle,
+                         true, num_harts);
+
+    /* S-level APLIC node */
+    aplic_addr = memmap[RVSP_APLIC_S].base + memmap[RVSP_APLIC_S].size * socket;
+    create_fdt_one_aplic(s, socket, aplic_addr, memmap[RVSP_APLIC_S].size,
+                         msi_s_phandle, intc_phandles,
+                         aplic_s_phandle, 0,
+                         false, num_harts);
+
+    aplic_phandles[socket] = aplic_s_phandle;
+}
+
+static void create_fdt_pmu(RVSPMachineState *s)
+{
+    g_autofree char *pmu_name = g_strdup_printf("/pmu");
+    MachineState *ms = MACHINE(s);
+    RISCVCPU hart = s->soc[0].harts[0];
+
+    qemu_fdt_add_subnode(ms->fdt, pmu_name);
+    qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
+    riscv_pmu_generate_fdt_node(ms->fdt, hart.pmu_avail_ctrs, pmu_name);
+}
+
+static void create_fdt_sockets(RVSPMachineState *s, const MemMapEntry *memmap,
+                               uint32_t *phandle,
+                               uint32_t *irq_mmio_phandle,
+                               uint32_t *irq_pcie_phandle,
+                               uint32_t *msi_pcie_phandle)
+{
+    int socket, phandle_pos;
+    MachineState *ms = MACHINE(s);
+    uint32_t msi_m_phandle = 0, msi_s_phandle = 0;
+    uint32_t xplic_phandles[MAX_NODES];
+    g_autofree uint32_t *intc_phandles = NULL;
+    int socket_count = riscv_socket_count(ms);
+
+    qemu_fdt_add_subnode(ms->fdt, "/cpus");
+    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
+                          RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
+    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
+    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
+    qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
+
+    intc_phandles = g_new0(uint32_t, ms->smp.cpus);
+
+    phandle_pos = ms->smp.cpus;
+    for (socket = (socket_count - 1); socket >= 0; socket--) {
+        g_autofree char *clust_name = NULL;
+        phandle_pos -= s->soc[socket].num_harts;
+
+        clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
+        qemu_fdt_add_subnode(ms->fdt, clust_name);
+
+        create_fdt_socket_cpus(s, socket, clust_name, phandle,
+                               &intc_phandles[phandle_pos]);
+
+        create_fdt_socket_memory(s, memmap, socket);
+
+        create_fdt_socket_aclint(s, memmap, socket,
+            &intc_phandles[phandle_pos]);
+    }
+
+    create_fdt_imsic(s, memmap, phandle, intc_phandles,
+        &msi_m_phandle, &msi_s_phandle);
+    *msi_pcie_phandle = msi_s_phandle;
+
+    phandle_pos = ms->smp.cpus;
+    for (socket = (socket_count - 1); socket >= 0; socket--) {
+        phandle_pos -= s->soc[socket].num_harts;
+
+        create_fdt_socket_aplic(s, memmap, socket,
+                                msi_m_phandle, msi_s_phandle, phandle,
+                                &intc_phandles[phandle_pos],
+                                xplic_phandles,
+                                s->soc[socket].num_harts);
+    }
+
+    for (socket = 0; socket < socket_count; socket++) {
+        if (socket == 0) {
+            *irq_mmio_phandle = xplic_phandles[socket];
+            *irq_pcie_phandle = xplic_phandles[socket];
+        }
+        if (socket == 1) {
+            *irq_pcie_phandle = xplic_phandles[socket];
+        }
+    }
+
+    riscv_socket_fdt_write_distance_matrix(ms);
+}
+
+static void create_fdt_pcie(RVSPMachineState *s, const MemMapEntry *memmap,
+                            uint32_t irq_pcie_phandle,
+                            uint32_t msi_pcie_phandle)
+{
+    g_autofree char *name = NULL;
+    MachineState *ms = MACHINE(s);
+
+    name = g_strdup_printf("/soc/pci@%"HWADDR_PRIx,
+                           memmap[RVSP_PCIE_ECAM].base);
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_cell(ms->fdt, name, "#address-cells",
+        FDT_PCI_ADDR_CELLS);
+    qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells",
+        FDT_PCI_INT_CELLS);
+    qemu_fdt_setprop_cell(ms->fdt, name, "#size-cells", 0x2);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible",
+        "pci-host-ecam-generic");
+    qemu_fdt_setprop_string(ms->fdt, name, "device_type", "pci");
+    qemu_fdt_setprop_cell(ms->fdt, name, "linux,pci-domain", 0);
+    qemu_fdt_setprop_cells(ms->fdt, name, "bus-range", 0,
+        memmap[RVSP_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1);
+    qemu_fdt_setprop(ms->fdt, name, "dma-coherent", NULL, 0);
+    qemu_fdt_setprop_cell(ms->fdt, name, "msi-parent", msi_pcie_phandle);
+    qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0,
+        memmap[RVSP_PCIE_ECAM].base, 0, memmap[RVSP_PCIE_ECAM].size);
+    qemu_fdt_setprop_sized_cells(ms->fdt, name, "ranges",
+        1, FDT_PCI_RANGE_IOPORT, 2, 0,
+        2, memmap[RVSP_PCIE_PIO].base, 2, memmap[RVSP_PCIE_PIO].size,
+        1, FDT_PCI_RANGE_MMIO,
+        2, memmap[RVSP_PCIE_MMIO].base,
+        2, memmap[RVSP_PCIE_MMIO].base, 2, memmap[RVSP_PCIE_MMIO].size,
+        1, FDT_PCI_RANGE_MMIO_64BIT,
+        2, memmap[RVSP_PCIE_MMIO_HIGH].base,
+        2, memmap[RVSP_PCIE_MMIO_HIGH].base, 2,
+           memmap[RVSP_PCIE_MMIO_HIGH].size);
+
+    create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle);
+}
+
+static void create_fdt_reset(RVSPMachineState *s, const MemMapEntry *memmap,
+                             uint32_t *phandle)
+{
+    char *name;
+    uint32_t test_phandle;
+    MachineState *ms = MACHINE(s);
+
+    test_phandle = (*phandle)++;
+    name = g_strdup_printf("/soc/reset_syscon@%"HWADDR_PRIx,
+                           memmap[RVSP_RESET_SYSCON].base);
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon");
+    qemu_fdt_setprop_cells(ms->fdt, name, "reg",
+        0x0, memmap[RVSP_RESET_SYSCON].base,
+        0x0, memmap[RVSP_RESET_SYSCON].size);
+    qemu_fdt_setprop_cell(ms->fdt, name, "phandle", test_phandle);
+    test_phandle = qemu_fdt_get_phandle(ms->fdt, name);
+    g_free(name);
+
+    name = g_strdup_printf("/soc/reboot");
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot");
+    qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle);
+    qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0);
+    qemu_fdt_setprop_cell(ms->fdt, name, "value", SYSCON_RESET);
+    g_free(name);
+
+    name = g_strdup_printf("/soc/poweroff");
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-poweroff");
+    qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle);
+    qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0);
+    qemu_fdt_setprop_cell(ms->fdt, name, "value", SYSCON_POWEROFF);
+    g_free(name);
+}
+
+static void create_fdt_uart(RVSPMachineState *s, const MemMapEntry *memmap,
+                            uint32_t irq_mmio_phandle)
+{
+    g_autofree char *name = NULL;
+    MachineState *ms = MACHINE(s);
+
+    name = g_strdup_printf("/soc/serial@%"HWADDR_PRIx,
+                           memmap[RVSP_UART0].base);
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible", "ns16550a");
+    qemu_fdt_setprop_cells(ms->fdt, name, "reg",
+        0x0, memmap[RVSP_UART0].base,
+        0x0, memmap[RVSP_UART0].size);
+    qemu_fdt_setprop_cell(ms->fdt, name, "clock-frequency", 3686400);
+    qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_mmio_phandle);
+    qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", RVSP_UART0_IRQ, 0x4);
+
+    qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", name);
+}
+
+static void create_fdt_rtc(RVSPMachineState *s, const MemMapEntry *memmap,
+                           uint32_t irq_mmio_phandle)
+{
+    g_autofree char *name = NULL;
+    MachineState *ms = MACHINE(s);
+
+    name = g_strdup_printf("/soc/rtc@%"HWADDR_PRIx, memmap[RVSP_RTC].base);
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible",
+        "google,goldfish-rtc");
+    qemu_fdt_setprop_cells(ms->fdt, name, "reg",
+        0x0, memmap[RVSP_RTC].base, 0x0, memmap[RVSP_RTC].size);
+    qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent",
+        irq_mmio_phandle);
+    qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", RVSP_RTC_IRQ, 0x4);
+}
+
+static void create_fdt_flash(RVSPMachineState *s, const MemMapEntry *memmap)
+{
+    MachineState *ms = MACHINE(s);
+    hwaddr flashsize = rvsp_ref_memmap[RVSP_FLASH].size / 2;
+    hwaddr flashbase = rvsp_ref_memmap[RVSP_FLASH].base;
+    g_autofree char *name = g_strdup_printf("/flash@%"HWADDR_PRIx, flashbase);
+
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible", "cfi-flash");
+    qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
+                                 2, flashbase, 2, flashsize,
+                                 2, flashbase + flashsize, 2, flashsize);
+    qemu_fdt_setprop_cell(ms->fdt, name, "bank-width", 4);
+}
+
+static void finalize_fdt(RVSPMachineState *s)
+{
+    uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
+    uint32_t irq_pcie_phandle = 1;
+
+    create_fdt_sockets(s, rvsp_ref_memmap, &phandle, &irq_mmio_phandle,
+                       &irq_pcie_phandle, &msi_pcie_phandle);
+
+    create_fdt_pcie(s, rvsp_ref_memmap, irq_pcie_phandle, msi_pcie_phandle);
+
+    create_fdt_reset(s, rvsp_ref_memmap, &phandle);
+
+    create_fdt_uart(s, rvsp_ref_memmap, irq_mmio_phandle);
+
+    create_fdt_rtc(s, rvsp_ref_memmap, irq_mmio_phandle);
+}
+
+static void create_fdt(RVSPMachineState *s, const MemMapEntry *memmap)
+{
+    MachineState *ms = MACHINE(s);
+    uint8_t rng_seed[32];
+
+    ms->fdt = create_device_tree(&s->fdt_size);
+    if (!ms->fdt) {
+        error_report("create_device_tree() failed");
+        exit(1);
+    }
+
+    qemu_fdt_setprop_string(ms->fdt, "/", "model", "riscv-rvsp-ref,qemu");
+    qemu_fdt_setprop_string(ms->fdt, "/", "compatible", "riscv-rvsp-ref");
+    qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
+    qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
+
+    /*
+     * This versioning scheme is for informing platform fw only. It is neither:
+     * - A QEMU versioned machine type; a given version of QEMU will emulate
+     *   a given version of the platform.
+     * - A reflection of level of server platform support provided.
+     *
+     * machine-version-major: updated when changes breaking fw compatibility
+     *                        are introduced.
+     * machine-version-minor: updated when features are added that don't break
+     *                        fw compatibility.
+     *
+     * It's the same as the scheme in arm sbsa-ref.
+     */
+    qemu_fdt_setprop_cell(ms->fdt, "/", "machine-version-major", 0);
+    qemu_fdt_setprop_cell(ms->fdt, "/", "machine-version-minor", 0);
+
+    qemu_fdt_add_subnode(ms->fdt, "/soc");
+    qemu_fdt_setprop(ms->fdt, "/soc", "ranges", NULL, 0);
+    qemu_fdt_setprop_string(ms->fdt, "/soc", "compatible", "simple-bus");
+    qemu_fdt_setprop_cell(ms->fdt, "/soc", "#size-cells", 0x2);
+    qemu_fdt_setprop_cell(ms->fdt, "/soc", "#address-cells", 0x2);
+
+    qemu_fdt_add_subnode(ms->fdt, "/chosen");
+
+    /* Pass seed to RNG */
+    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
+    qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed",
+                     rng_seed, sizeof(rng_seed));
+
+    create_fdt_flash(s, memmap);
+    create_fdt_pmu(s);
+
+}
+
+static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
+                                          DeviceState *irqchip,
+                                          RVSPMachineState *s)
+{
+    DeviceState *dev;
+    PCIHostState *pci;
+    PCIDevice *pdev_ahci;
+    AHCIPCIState *ich9;
+    DriveInfo *hd[NUM_SATA_PORTS];
+    MemoryRegion *ecam_alias, *ecam_reg;
+    MemoryRegion *mmio_alias, *high_mmio_alias, *mmio_reg;
+    hwaddr ecam_base = rvsp_ref_memmap[RVSP_PCIE_ECAM].base;
+    hwaddr ecam_size = rvsp_ref_memmap[RVSP_PCIE_ECAM].size;
+    hwaddr mmio_base = rvsp_ref_memmap[RVSP_PCIE_MMIO].base;
+    hwaddr mmio_size = rvsp_ref_memmap[RVSP_PCIE_MMIO].size;
+    hwaddr high_mmio_base = rvsp_ref_memmap[RVSP_PCIE_MMIO_HIGH].base;
+    hwaddr high_mmio_size = rvsp_ref_memmap[RVSP_PCIE_MMIO_HIGH].size;
+    hwaddr pio_base = rvsp_ref_memmap[RVSP_PCIE_PIO].base;
+    hwaddr pio_size = rvsp_ref_memmap[RVSP_PCIE_PIO].size;
+    MachineClass *mc = MACHINE_GET_CLASS(s);
+    qemu_irq irq;
+    int i;
+
+    dev = qdev_new(TYPE_GPEX_HOST);
+
+    /* Set GPEX object properties for the rvsp ref machine */
+    object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_BASE,
+                            ecam_base, NULL);
+    object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_SIZE,
+                            ecam_size, NULL);
+    object_property_set_uint(OBJECT(GPEX_HOST(dev)),
+                             PCI_HOST_BELOW_4G_MMIO_BASE,
+                             mmio_base, NULL);
+    object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_BELOW_4G_MMIO_SIZE,
+                            mmio_size, NULL);
+    object_property_set_uint(OBJECT(GPEX_HOST(dev)),
+                             PCI_HOST_ABOVE_4G_MMIO_BASE,
+                             high_mmio_base, NULL);
+    object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ABOVE_4G_MMIO_SIZE,
+                            high_mmio_size, NULL);
+    object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_BASE,
+                            pio_base, NULL);
+    object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_SIZE,
+                            pio_size, NULL);
+
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+    ecam_alias = g_new0(MemoryRegion, 1);
+    ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+    memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
+                             ecam_reg, 0, ecam_size);
+    memory_region_add_subregion(get_system_memory(), ecam_base, ecam_alias);
+
+    mmio_alias = g_new0(MemoryRegion, 1);
+    mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+    memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
+                             mmio_reg, mmio_base, mmio_size);
+    memory_region_add_subregion(get_system_memory(), mmio_base, mmio_alias);
+
+    /* Map high MMIO space */
+    high_mmio_alias = g_new0(MemoryRegion, 1);
+    memory_region_init_alias(high_mmio_alias, OBJECT(dev), "pcie-mmio-high",
+                             mmio_reg, high_mmio_base, high_mmio_size);
+    memory_region_add_subregion(get_system_memory(), high_mmio_base,
+                                high_mmio_alias);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base);
+
+    for (i = 0; i < PCI_NUM_PINS; i++) {
+        irq = qdev_get_gpio_in(irqchip, RVSP_PCIE_IRQ + i);
+
+        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
+        gpex_set_irq_num(GPEX_HOST(dev), i, RVSP_PCIE_IRQ + i);
+    }
+
+    pci = PCI_HOST_BRIDGE(dev);
+    pci_init_nic_devices(pci->bus, mc->default_nic);
+    /* IDE disk setup.  */
+    pdev_ahci = pci_create_simple(pci->bus, -1, TYPE_ICH9_AHCI);
+    ich9 = ICH9_AHCI(pdev_ahci);
+    g_assert(ARRAY_SIZE(hd) == ich9->ahci.ports);
+    ide_drive_get(hd, ich9->ahci.ports);
+    ahci_ide_create_devs(&ich9->ahci, hd);
+
+    GPEX_HOST(dev)->gpex_cfg.bus = PCI_HOST_BRIDGE(GPEX_HOST(dev))->bus;
+    return dev;
+}
+
+static DeviceState *rvsp_ref_create_aia(int aia_guests,
+                                        const MemMapEntry *memmap, int socket,
+                                        int base_hartid, int hart_count)
+{
+    int i;
+    hwaddr addr;
+    uint32_t guest_bits;
+    DeviceState *aplic_s = NULL;
+    DeviceState *aplic_m = NULL;
+    bool msimode = true;
+
+    /* Per-socket M-level IMSICs */
+    addr = memmap[RVSP_IMSIC_M].base +
+           socket * RVSP_IMSIC_GROUP_MAX_SIZE;
+    for (i = 0; i < hart_count; i++) {
+        riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
+                           base_hartid + i, true, 1,
+                           RVSP_IRQCHIP_NUM_MSIS);
+    }
+
+    /* Per-socket S-level IMSICs */
+    guest_bits = imsic_num_bits(aia_guests + 1);
+    addr = memmap[RVSP_IMSIC_S].base + socket * RVSP_IMSIC_GROUP_MAX_SIZE;
+    for (i = 0; i < hart_count; i++) {
+        riscv_imsic_create(addr + i * IMSIC_HART_SIZE(guest_bits),
+                           base_hartid + i, false, 1 + aia_guests,
+                           RVSP_IRQCHIP_NUM_MSIS);
+    }
+
+    /* Per-socket M-level APLIC */
+    aplic_m = riscv_aplic_create(memmap[RVSP_APLIC_M].base +
+                                 socket * memmap[RVSP_APLIC_M].size,
+                                 memmap[RVSP_APLIC_M].size,
+                                 (msimode) ? 0 : base_hartid,
+                                 (msimode) ? 0 : hart_count,
+                                 RVSP_IRQCHIP_NUM_SOURCES,
+                                 RVSP_IRQCHIP_NUM_PRIO_BITS,
+                                 msimode, true, NULL);
+
+    /* Per-socket S-level APLIC */
+    aplic_s = riscv_aplic_create(memmap[RVSP_APLIC_S].base +
+                                 socket * memmap[RVSP_APLIC_S].size,
+                                 memmap[RVSP_APLIC_S].size,
+                                 (msimode) ? 0 : base_hartid,
+                                 (msimode) ? 0 : hart_count,
+                                 RVSP_IRQCHIP_NUM_SOURCES,
+                                 RVSP_IRQCHIP_NUM_PRIO_BITS,
+                                 msimode, false, aplic_m);
+
+    (void)aplic_s;
+    return aplic_m;
+}
+
+static uint64_t rvsp_reset_syscon_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
+static void rvsp_reset_syscon_write(void *opaque, hwaddr addr,
+                                    uint64_t val64, unsigned int size)
+{
+    switch (val64) {
+    case SYSCON_POWEROFF:
+        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+        return;
+    case SYSCON_RESET:
+        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+        return;
+    default:
+        break;
+    }
+}
+
+static const MemoryRegionOps rvsp_reset_syscon_ops = {
+    .read = rvsp_reset_syscon_read,
+    .write = rvsp_reset_syscon_write,
+    .endianness = DEVICE_NATIVE_ENDIAN
+};
+
+static void rvsp_ref_machine_done(Notifier *notifier, void *data)
+{
+    RVSPMachineState *s = container_of(notifier, RVSPMachineState,
+                                       machine_done);
+    const MemMapEntry *memmap = rvsp_ref_memmap;
+    MachineState *machine = MACHINE(s);
+    hwaddr start_addr = memmap[RVSP_DRAM].base;
+    target_ulong firmware_end_addr, kernel_start_addr;
+    const char *firmware_name = riscv_default_firmware_name(&s->soc[0]);
+    uint64_t fdt_load_addr;
+    uint64_t kernel_entry = 0;
+    BlockBackend *pflash_blk0;
+    RISCVBootInfo boot_info;
+
+    /*
+     * An user provided dtb must include everything, including
+     * dynamic sysbus devices. Our FDT needs to be finalized.
+     */
+    if (machine->dtb == NULL) {
+        finalize_fdt(s);
+    }
+
+    firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
+                                                     &start_addr, NULL);
+
+    pflash_blk0 = pflash_cfi01_get_blk(s->flash[0]);
+    if (pflash_blk0) {
+        if (machine->firmware && !strcmp(machine->firmware, "none")) {
+            /*
+             * Pflash was supplied but bios is none and not KVM guest,
+             * let's overwrite the address we jump to after reset to
+             * the base of the flash.
+             */
+            start_addr = rvsp_ref_memmap[RVSP_FLASH].base;
+        } else {
+            /*
+             * Pflash was supplied but either KVM guest or bios is not none.
+             * In this case, base of the flash would contain S-mode payload.
+             */
+            riscv_setup_firmware_boot(machine);
+            kernel_entry = rvsp_ref_memmap[RVSP_FLASH].base;
+        }
+    }
+
+    riscv_boot_info_init(&boot_info, &s->soc[0]);
+
+    if (machine->kernel_filename && !kernel_entry) {
+        kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,
+                                                         firmware_end_addr);
+        riscv_load_kernel(machine, &boot_info, kernel_start_addr, true, NULL);
+        kernel_entry = boot_info.image_low_addr;
+    }
+
+    fdt_load_addr = riscv_compute_fdt_addr(memmap[RVSP_DRAM].base,
+                                           memmap[RVSP_DRAM].size,
+                                           machine, &boot_info);
+
+    riscv_load_fdt(fdt_load_addr, machine->fdt);
+
+    /* load the reset vector */
+    riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
+                              rvsp_ref_memmap[RVSP_MROM].base,
+                              rvsp_ref_memmap[RVSP_MROM].size, kernel_entry,
+                              fdt_load_addr);
+
+}
+
+static bool rvsp_aclint_allowed(void)
+{
+    return tcg_enabled() || qtest_enabled();
+}
+
+static void rvsp_ref_machine_init(MachineState *machine)
+{
+    const MemMapEntry *memmap = rvsp_ref_memmap;
+    RVSPMachineState *s = RVSP_REF_MACHINE(machine);
+    MemoryRegion *system_memory = get_system_memory();
+    MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
+    MemoryRegion *reset_syscon_io = g_new(MemoryRegion, 1);
+    DeviceState *mmio_irqchip, *pcie_irqchip;
+    int i, base_hartid, hart_count;
+    int socket_count = riscv_socket_count(machine);
+
+    /* Check socket count limit */
+    if (RVSP_SOCKETS_MAX < socket_count) {
+        error_report("number of sockets/nodes should be less than %d",
+            RVSP_SOCKETS_MAX);
+        exit(1);
+    }
+
+    if (!rvsp_aclint_allowed()) {
+        error_report("'aclint' is only available with TCG acceleration");
+        exit(1);
+    }
+
+    /* Initialize sockets */
+    mmio_irqchip = pcie_irqchip = NULL;
+    for (i = 0; i < socket_count; i++) {
+        g_autofree char *soc_name = g_strdup_printf("soc%d", i);
+
+        if (!riscv_socket_check_hartids(machine, i)) {
+            error_report("discontinuous hartids in socket%d", i);
+            exit(1);
+        }
+
+        base_hartid = riscv_socket_first_hartid(machine, i);
+        if (base_hartid < 0) {
+            error_report("can't find hartid base for socket%d", i);
+            exit(1);
+        }
+
+        hart_count = riscv_socket_hart_count(machine, i);
+        if (hart_count < 0) {
+            error_report("can't find hart count for socket%d", i);
+            exit(1);
+        }
+
+        object_initialize_child(OBJECT(machine), soc_name, &s->soc[i],
+                                TYPE_RISCV_HART_ARRAY);
+        object_property_set_str(OBJECT(&s->soc[i]), "cpu-type",
+                                machine->cpu_type, &error_abort);
+        object_property_set_int(OBJECT(&s->soc[i]), "hartid-base",
+                                base_hartid, &error_abort);
+        object_property_set_int(OBJECT(&s->soc[i]), "num-harts",
+                                hart_count, &error_abort);
+        sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_fatal);
+
+        /* Per-socket ACLINT MTIMER */
+        riscv_aclint_mtimer_create(memmap[RVSP_ACLINT].base +
+                i * RISCV_ACLINT_DEFAULT_MTIMER_SIZE,
+            RISCV_ACLINT_DEFAULT_MTIMER_SIZE,
+            base_hartid, hart_count,
+            RISCV_ACLINT_DEFAULT_MTIMECMP,
+            RISCV_ACLINT_DEFAULT_MTIME,
+            RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true);
+
+        /* Per-socket interrupt controller */
+        s->irqchip[i] = rvsp_ref_create_aia(s->aia_guests,
+                                            memmap, i, base_hartid,
+                                            hart_count);
+
+        /* Try to use different IRQCHIP instance based device type */
+        if (i == 0) {
+            mmio_irqchip = s->irqchip[i];
+            pcie_irqchip = s->irqchip[i];
+        }
+        if (i == 1) {
+            pcie_irqchip = s->irqchip[i];
+        }
+    }
+
+    s->memmap = rvsp_ref_memmap;
+
+    /* register system main memory (actual RAM) */
+    memory_region_add_subregion(system_memory, memmap[RVSP_DRAM].base,
+        machine->ram);
+
+    /* boot rom */
+    memory_region_init_rom(mask_rom, NULL, "riscv_rvsp_ref_board.mrom",
+                           memmap[RVSP_MROM].size, &error_fatal);
+    memory_region_add_subregion(system_memory, memmap[RVSP_MROM].base,
+                                mask_rom);
+
+    memory_region_init_io(reset_syscon_io, NULL, &rvsp_reset_syscon_ops,
+                          NULL, "reset_syscon_io",
+                          memmap[RVSP_RESET_SYSCON].size);
+    memory_region_add_subregion(system_memory,
+                                memmap[RVSP_RESET_SYSCON].base,
+                                reset_syscon_io);
+
+    gpex_pcie_init(system_memory, pcie_irqchip, s);
+
+    serial_mm_init(system_memory, memmap[RVSP_UART0].base,
+        0, qdev_get_gpio_in(mmio_irqchip, RVSP_UART0_IRQ), 399193,
+        serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+    sysbus_create_simple("goldfish_rtc", memmap[RVSP_RTC].base,
+        qdev_get_gpio_in(mmio_irqchip, RVSP_RTC_IRQ));
+
+    for (i = 0; i < ARRAY_SIZE(s->flash); i++) {
+        /* Map legacy -drive if=pflash to machine properties */
+        pflash_cfi01_legacy_drive(s->flash[i],
+                                  drive_get(IF_PFLASH, 0, i));
+    }
+    rvsp_flash_maps(s, system_memory);
+
+    /* load/create device tree */
+    if (machine->dtb) {
+        machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
+        if (!machine->fdt) {
+            error_report("load_device_tree() failed");
+            exit(1);
+        }
+    } else {
+        create_fdt(s, memmap);
+    }
+
+    s->machine_done.notify = rvsp_ref_machine_done;
+    qemu_add_machine_init_done_notifier(&s->machine_done);
+}
+
+static void rvsp_ref_machine_instance_init(Object *obj)
+{
+    RVSPMachineState *s = RVSP_REF_MACHINE(obj);
+
+    s->flash[0] = rvsp_flash_create(s, "rvsp.flash0", "pflash0");
+    s->flash[1] = rvsp_flash_create(s, "rvsp.flash1", "pflash1");
+}
+
+static char *rvsp_ref_get_aia_guests(Object *obj, Error **errp)
+{
+    RVSPMachineState *s = RVSP_REF_MACHINE(obj);
+    char val[32];
+
+    sprintf(val, "%d", s->aia_guests);
+    return g_strdup(val);
+}
+
+static void rvsp_ref_set_aia_guests(Object *obj, const char *val, Error **errp)
+{
+    RVSPMachineState *s = RVSP_REF_MACHINE(obj);
+
+    s->aia_guests = atoi(val);
+    if (s->aia_guests < 0 || s->aia_guests > RVSP_IRQCHIP_MAX_GUESTS) {
+        error_setg(errp, "Invalid number of AIA IMSIC guests");
+        error_append_hint(errp, "Valid values be between 0 and %d.\n",
+                          RVSP_IRQCHIP_MAX_GUESTS);
+    }
+}
+
+static void rvsp_ref_machine_class_init(ObjectClass *oc, const void *data)
+{
+    char str[128];
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static const char * const valid_cpu_types[] = {
+        TYPE_RISCV_CPU_RVSP_REF,
+    };
+
+    mc->desc = "RISC-V Server SoC Reference board";
+    mc->init = rvsp_ref_machine_init;
+    mc->max_cpus = RVSP_CPUS_MAX;
+    mc->default_cpu_type = TYPE_RISCV_CPU_RVSP_REF;
+    mc->valid_cpu_types = valid_cpu_types;
+    mc->pci_allow_0_address = true;
+    mc->default_nic = "e1000e";
+    mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
+    mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
+    mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
+    mc->numa_mem_supported = true;
+    /* platform instead of architectural choice */
+    mc->cpu_cluster_has_numa_boundary = true;
+    mc->default_ram_id = "riscv_rvsp_ref_board.ram";
+
+    object_class_property_add_str(oc, "aia-guests",
+                                  rvsp_ref_get_aia_guests,
+                                  rvsp_ref_set_aia_guests);
+    sprintf(str, "Set number of guest MMIO pages for AIA IMSIC. Valid value "
+                 "should be between 0 and %d.", RVSP_IRQCHIP_MAX_GUESTS);
+    object_class_property_set_description(oc, "aia-guests", str);
+}
+
+static const TypeInfo rvsp_ref_typeinfo = {
+    .name       = TYPE_RVSP_REF_MACHINE,
+    .parent     = TYPE_MACHINE,
+    .class_init = rvsp_ref_machine_class_init,
+    .instance_init = rvsp_ref_machine_instance_init,
+    .instance_size = sizeof(RVSPMachineState),
+};
+
+static void rvsp_ref_init_register_types(void)
+{
+    type_register_static(&rvsp_ref_typeinfo);
+}
+
+type_init(rvsp_ref_init_register_types)
-- 
2.49.0



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

* [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys
  2025-05-28 20:01 [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Daniel Henrique Barboza
                   ` (2 preceding siblings ...)
  2025-05-28 20:01 ` [PATCH v3 3/4] hw/riscv: Add server platform reference machine Daniel Henrique Barboza
@ 2025-05-28 20:01 ` Daniel Henrique Barboza
  2025-05-29 12:33   ` Andrew Jones
  2025-10-30 11:40   ` Chao Liu
  2025-10-30 11:48 ` [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Chao Liu
  4 siblings, 2 replies; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-05-28 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu, palmer,
	ajones, Daniel Henrique Barboza

Add an always present IOMMU platform device for the rvsp-ref board.

The IRQs being used are similar to what the 'virt' board is using: IRQs
36 to 39, one IRQ for queue.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 hw/riscv/Kconfig               |  1 +
 hw/riscv/server_platform_ref.c | 78 ++++++++++++++++++++++++++++++++--
 2 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index f626774c52..cd70095687 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -82,6 +82,7 @@ config SERVER_PLATFORM_REF
     select RISCV_ACLINT
     select RISCV_APLIC
     select RISCV_IMSIC
+    select RISCV_IOMMU
 
 config SHAKTI_C
     bool
diff --git a/hw/riscv/server_platform_ref.c b/hw/riscv/server_platform_ref.c
index 5102286103..9740b395f6 100644
--- a/hw/riscv/server_platform_ref.c
+++ b/hw/riscv/server_platform_ref.c
@@ -31,6 +31,8 @@
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/boot.h"
 #include "hw/riscv/numa.h"
+#include "hw/riscv/iommu.h"
+#include "hw/riscv/riscv-iommu-bits.h"
 #include "hw/intc/riscv_aclint.h"
 #include "hw/intc/riscv_aplic.h"
 #include "hw/intc/riscv_imsic.h"
@@ -94,6 +96,7 @@ enum {
     RVSP_MROM,
     RVSP_RESET_SYSCON,
     RVSP_RTC,
+    RVSP_IOMMU_SYS,
     RVSP_ACLINT,
     RVSP_APLIC_M,
     RVSP_APLIC_S,
@@ -112,6 +115,7 @@ enum {
     RVSP_UART0_IRQ = 10,
     RVSP_RTC_IRQ = 11,
     RVSP_PCIE_IRQ = 0x20, /* 32 to 35 */
+    IOMMU_SYS_IRQ = 0x24 /* 36 to 39 */
 };
 
 /*
@@ -141,6 +145,7 @@ static const MemMapEntry rvsp_ref_memmap[] = {
     [RVSP_MROM] =           {     0x1000,        0xf000 },
     [RVSP_RESET_SYSCON] =   {   0x100000,        0x1000 },
     [RVSP_RTC] =            {   0x101000,        0x1000 },
+    [RVSP_IOMMU_SYS] =      {    0102000,        0x1000 },
     [RVSP_ACLINT] =         {  0x2000000,       0x10000 },
     [RVSP_PCIE_PIO] =       {  0x3000000,       0x10000 },
     [RVSP_APLIC_M] =        {  0xc000000, APLIC_SIZE(RVSP_CPUS_MAX) },
@@ -638,9 +643,51 @@ static void create_fdt_sockets(RVSPMachineState *s, const MemMapEntry *memmap,
     riscv_socket_fdt_write_distance_matrix(ms);
 }
 
+static void create_fdt_iommu_sys(RVSPMachineState *s, uint32_t irq_chip,
+                                 uint32_t msi_phandle,
+                                 uint32_t *iommu_sys_phandle)
+{
+    const char comp[] = "riscv,iommu";
+    void *fdt = MACHINE(s)->fdt;
+    uint32_t iommu_phandle;
+    g_autofree char *iommu_node = NULL;
+    hwaddr addr = s->memmap[RVSP_IOMMU_SYS].base;
+    hwaddr size = s->memmap[RVSP_IOMMU_SYS].size;
+    uint32_t iommu_irq_map[RISCV_IOMMU_INTR_COUNT] = {
+        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_CQ,
+        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_FQ,
+        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_PM,
+        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_PQ,
+    };
+
+    iommu_node = g_strdup_printf("/soc/iommu@%"HWADDR_PRIx,
+                                 s->memmap[RVSP_IOMMU_SYS].base);
+    iommu_phandle = qemu_fdt_alloc_phandle(fdt);
+    qemu_fdt_add_subnode(fdt, iommu_node);
+
+    qemu_fdt_setprop(fdt, iommu_node, "compatible", comp, sizeof(comp));
+    qemu_fdt_setprop_cell(fdt, iommu_node, "#iommu-cells", 1);
+    qemu_fdt_setprop_cell(fdt, iommu_node, "phandle", iommu_phandle);
+
+    qemu_fdt_setprop_cells(fdt, iommu_node, "reg",
+                           addr >> 32, addr, size >> 32, size);
+    qemu_fdt_setprop_cell(fdt, iommu_node, "interrupt-parent", irq_chip);
+
+    qemu_fdt_setprop_cells(fdt, iommu_node, "interrupts",
+        iommu_irq_map[0], FDT_IRQ_TYPE_EDGE_LOW,
+        iommu_irq_map[1], FDT_IRQ_TYPE_EDGE_LOW,
+        iommu_irq_map[2], FDT_IRQ_TYPE_EDGE_LOW,
+        iommu_irq_map[3], FDT_IRQ_TYPE_EDGE_LOW);
+
+    qemu_fdt_setprop_cell(fdt, iommu_node, "msi-parent", msi_phandle);
+
+    *iommu_sys_phandle = iommu_phandle;
+}
+
 static void create_fdt_pcie(RVSPMachineState *s, const MemMapEntry *memmap,
                             uint32_t irq_pcie_phandle,
-                            uint32_t msi_pcie_phandle)
+                            uint32_t msi_pcie_phandle,
+                            uint32_t iommu_sys_phandle)
 {
     g_autofree char *name = NULL;
     MachineState *ms = MACHINE(s);
@@ -675,6 +722,10 @@ static void create_fdt_pcie(RVSPMachineState *s, const MemMapEntry *memmap,
            memmap[RVSP_PCIE_MMIO_HIGH].size);
 
     create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle);
+
+    qemu_fdt_setprop_cells(ms->fdt, name, "iommu-map",
+                           0, iommu_sys_phandle, 0, 0, 0,
+                           iommu_sys_phandle, 0, 0xffff);
 }
 
 static void create_fdt_reset(RVSPMachineState *s, const MemMapEntry *memmap,
@@ -768,12 +819,16 @@ static void create_fdt_flash(RVSPMachineState *s, const MemMapEntry *memmap)
 static void finalize_fdt(RVSPMachineState *s)
 {
     uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
-    uint32_t irq_pcie_phandle = 1;
+    uint32_t irq_pcie_phandle = 1, iommu_sys_phandle;
 
     create_fdt_sockets(s, rvsp_ref_memmap, &phandle, &irq_mmio_phandle,
                        &irq_pcie_phandle, &msi_pcie_phandle);
 
-    create_fdt_pcie(s, rvsp_ref_memmap, irq_pcie_phandle, msi_pcie_phandle);
+    create_fdt_iommu_sys(s, irq_mmio_phandle, msi_pcie_phandle,
+                         &iommu_sys_phandle);
+
+    create_fdt_pcie(s, rvsp_ref_memmap, irq_pcie_phandle,
+                    msi_pcie_phandle, iommu_sys_phandle);
 
     create_fdt_reset(s, rvsp_ref_memmap, &phandle);
 
@@ -1078,7 +1133,7 @@ static void rvsp_ref_machine_init(MachineState *machine)
     MemoryRegion *system_memory = get_system_memory();
     MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
     MemoryRegion *reset_syscon_io = g_new(MemoryRegion, 1);
-    DeviceState *mmio_irqchip, *pcie_irqchip;
+    DeviceState *mmio_irqchip, *pcie_irqchip, *iommu_sys;
     int i, base_hartid, hart_count;
     int socket_count = riscv_socket_count(machine);
 
@@ -1196,6 +1251,21 @@ static void rvsp_ref_machine_init(MachineState *machine)
         create_fdt(s, memmap);
     }
 
+    iommu_sys = qdev_new(TYPE_RISCV_IOMMU_SYS);
+    object_property_set_uint(OBJECT(iommu_sys), "addr",
+                             s->memmap[RVSP_IOMMU_SYS].base,
+                             &error_fatal);
+
+    object_property_set_uint(OBJECT(iommu_sys), "base-irq",
+                             IOMMU_SYS_IRQ,
+                             &error_fatal);
+
+    object_property_set_link(OBJECT(iommu_sys), "irqchip",
+                             OBJECT(mmio_irqchip),
+                             &error_fatal);
+
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
+
     s->machine_done.notify = rvsp_ref_machine_done;
     qemu_add_machine_init_done_notifier(&s->machine_done);
 }
-- 
2.49.0



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

* Re: [PATCH v3 2/4] target/riscv: Add server platform reference cpu
  2025-05-28 20:01 ` [PATCH v3 2/4] target/riscv: Add server platform reference cpu Daniel Henrique Barboza
@ 2025-05-29 11:56   ` Andrew Jones
  2025-10-30 15:01   ` Chao Liu
  1 sibling, 0 replies; 20+ messages in thread
From: Andrew Jones @ 2025-05-29 11:56 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
	palmer, Fei Wu

On Wed, May 28, 2025 at 05:01:27PM -0300, Daniel Henrique Barboza wrote:
> From: Fei Wu <wu.fei9@sanechips.com.cn>
> 
> The harts requirements of RISC-V server platform [1] require RVA23 ISA
> profile support, plus Sv48, Svadu, H, Sscofmpf etc. This patch provides
> a virt CPU type (rvsp-ref) as compliant as possible.
> 
> [1] https://github.com/riscv-non-isa/riscv-server-platform/blob/main/server_platform_requirements.adoc
> 
> Signed-off-by: Fei Wu <fei2.wu@intel.com>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>  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..70978fd53c 100644
> --- a/target/riscv/cpu-qom.h
> +++ b/target/riscv/cpu-qom.h
> @@ -55,6 +55,7 @@
>  #define TYPE_RISCV_CPU_VEYRON_V1        RISCV_CPU_TYPE_NAME("veyron-v1")
>  #define TYPE_RISCV_CPU_TT_ASCALON       RISCV_CPU_TYPE_NAME("tt-ascalon")
>  #define TYPE_RISCV_CPU_XIANGSHAN_NANHU  RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
> +#define TYPE_RISCV_CPU_RVSP_REF         RISCV_CPU_TYPE_NAME("rvsp-ref")
>  #define TYPE_RISCV_CPU_HOST             RISCV_CPU_TYPE_NAME("host")
>  
>  OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 4a30cf8444..ec2fbc0e78 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -3166,6 +3166,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>          .cfg.max_satp_mode = VM_1_10_SV39,
>      ),
>  
> +    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RVSP_REF, TYPE_RISCV_VENDOR_CPU,
> +        .misa_mxl_max = MXL_RV64,
> +        .profile = &RVA23S64,
> +
> +        /* ISA extensions */
> +        .cfg.ext_zkr = true,
> +        .cfg.ext_svadu = true,
> +
> +        .cfg.max_satp_mode = VM_1_10_SV57,

This is still missing several extensions required by the platform spec.

Sdtrig
Sdext
Ssccfg
Ssstrict
Ssaia

Thanks,
drew

> +    ),
> +
>  #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
>      DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE128, TYPE_RISCV_DYNAMIC_CPU,
>          .cfg.max_satp_mode = VM_1_10_SV57,
> -- 
> 2.49.0
> 


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

* Re: [PATCH v3 1/4] target/riscv/cpu.c: remove 'bare' condition for .profile
  2025-05-28 20:01 ` [PATCH v3 1/4] target/riscv/cpu.c: remove 'bare' condition for .profile Daniel Henrique Barboza
@ 2025-05-29 11:56   ` Andrew Jones
  0 siblings, 0 replies; 20+ messages in thread
From: Andrew Jones @ 2025-05-29 11:56 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
	palmer

On Wed, May 28, 2025 at 05:01:26PM -0300, Daniel Henrique Barboza wrote:
> We want to configure other CPU types to use profiles as an alternative
> to adding every profile extension explicitly, i.e. a profile is nothing
> more than an extension bundle.
> 
> This means that a vendor CPU can set .profile=rva23s64 while having the
> same handling as any other vendor CPU. Same thing with all other CPU
> types.
> 
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>  target/riscv/cpu.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index fe21e0fb44..4a30cf8444 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -2713,7 +2713,6 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
>          mcc->def->bare |= def->bare;
>          if (def->profile) {
>              assert(profile_extends(def->profile, mcc->def->profile));
> -            assert(mcc->def->bare);
>              mcc->def->profile = def->profile;
>          }
>          if (def->misa_mxl_max) {
> -- 
> 2.49.0
>

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>


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

* Re: [PATCH v3 3/4] hw/riscv: Add server platform reference machine
  2025-05-28 20:01 ` [PATCH v3 3/4] hw/riscv: Add server platform reference machine Daniel Henrique Barboza
@ 2025-05-29 12:31   ` Andrew Jones
  2025-10-30 22:27   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 20+ messages in thread
From: Andrew Jones @ 2025-05-29 12:31 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
	palmer, Fei Wu

On Wed, May 28, 2025 at 05:01:28PM -0300, Daniel Henrique Barboza wrote:
> From: Fei Wu <wu.fei9@sanechips.com.cn>
> 
> 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.
> 
> A corresponding Qemu RISC-V server platform reference (rvsp-ref for
> short) machine type is added to provide a environment for firmware/OS
> development and testing. The main features included in rvsp-ref 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

The server platform spec requires BRS-I (see FIRM_010). BRS-I requires
ACPI, and even some specific ACPI tables, e.g. PPTT (see Chapter 6 of
the BRS spec). However, I think the idea is we're suppose to generate
a DT here and then leave it to edk2 to generate ACPI tables from that
DT.

> 
> [1] https://github.com/riscv-non-isa/riscv-server-platform
> 
> Signed-off-by: Fei Wu <fei2.wu@intel.com>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>  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 39ed3a0061..0c4893b708 100644
> --- a/configs/devices/riscv64-softmmu/default.mak
> +++ b/configs/devices/riscv64-softmmu/default.mak
> @@ -9,5 +9,6 @@
>  # 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
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index e6a0ac1fa1..f626774c52 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

We shouldn't need 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 c22f3a7216..7a663fac64 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..5102286103
> --- /dev/null
> +++ b/hw/riscv/server_platform_ref.c
> @@ -0,0 +1,1276 @@

Missing SPDX

> +/*
> + * 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 board provides a reference implementation of the RISC-V Server
Platform specification. 

> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.

Can be dropped, since we want SPDX instead.

> + */
> +
> +#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

nit: should align all the above defines

> +
> +#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;

This can be hard coded to 5, as required by the server-soc spec.

Thanks,
drew


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

* Re: [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys
  2025-05-28 20:01 ` [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys Daniel Henrique Barboza
@ 2025-05-29 12:33   ` Andrew Jones
  2025-10-30 11:40   ` Chao Liu
  1 sibling, 0 replies; 20+ messages in thread
From: Andrew Jones @ 2025-05-29 12:33 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
	palmer

On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
> Add an always present IOMMU platform device for the rvsp-ref board.
> 
> The IRQs being used are similar to what the 'virt' board is using: IRQs
> 36 to 39, one IRQ for queue.
> 
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>  hw/riscv/Kconfig               |  1 +
>  hw/riscv/server_platform_ref.c | 78 ++++++++++++++++++++++++++++++++--
>  2 files changed, 75 insertions(+), 4 deletions(-)
>

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>


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

* Re: [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys
  2025-05-28 20:01 ` [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys Daniel Henrique Barboza
  2025-05-29 12:33   ` Andrew Jones
@ 2025-10-30 11:40   ` Chao Liu
  2025-10-30 13:23     ` Daniel Henrique Barboza
  1 sibling, 1 reply; 20+ messages in thread
From: Chao Liu @ 2025-10-30 11:40 UTC (permalink / raw)
  To: dbarboza
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, zhiwei_liu

On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>Add an always present IOMMU platform device for the rvsp-ref board.
>
>The IRQs being used are similar to what the 'virt' board is using: IRQs
>36 to 39, one IRQ for queue.
>
>Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>---
> hw/riscv/Kconfig               |  1 +
> hw/riscv/server_platform_ref.c | 78 ++++++++++++++++++++++++++++++++--
> 2 files changed, 75 insertions(+), 4 deletions(-)
>
>diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
>index f626774c52..cd70095687 100644
>--- a/hw/riscv/Kconfig
>+++ b/hw/riscv/Kconfig
>@@ -82,6 +82,7 @@ config SERVER_PLATFORM_REF
>     select RISCV_ACLINT
>     select RISCV_APLIC
>     select RISCV_IMSIC
>+    select RISCV_IOMMU
> 
> config SHAKTI_C
>     bool
>diff --git a/hw/riscv/server_platform_ref.c b/hw/riscv/server_platform_ref.c
>index 5102286103..9740b395f6 100644
>--- a/hw/riscv/server_platform_ref.c
>+++ b/hw/riscv/server_platform_ref.c
>@@ -31,6 +31,8 @@
> #include "hw/riscv/riscv_hart.h"
> #include "hw/riscv/boot.h"
> #include "hw/riscv/numa.h"
>+#include "hw/riscv/iommu.h"
>+#include "hw/riscv/riscv-iommu-bits.h"
> #include "hw/intc/riscv_aclint.h"
> #include "hw/intc/riscv_aplic.h"
> #include "hw/intc/riscv_imsic.h"
>@@ -94,6 +96,7 @@ enum {
>     RVSP_MROM,
>     RVSP_RESET_SYSCON,
>     RVSP_RTC,
>+    RVSP_IOMMU_SYS,
>     RVSP_ACLINT,
>     RVSP_APLIC_M,
>     RVSP_APLIC_S,
>@@ -112,6 +115,7 @@ enum {
>     RVSP_UART0_IRQ = 10,
>     RVSP_RTC_IRQ = 11,
>     RVSP_PCIE_IRQ = 0x20, /* 32 to 35 */
>+    IOMMU_SYS_IRQ = 0x24 /* 36 to 39 */
> };
> 
> /*
>@@ -141,6 +145,7 @@ static const MemMapEntry rvsp_ref_memmap[] = {
>     [RVSP_MROM] =           {     0x1000,        0xf000 },
>     [RVSP_RESET_SYSCON] =   {   0x100000,        0x1000 },
>     [RVSP_RTC] =            {   0x101000,        0x1000 },
>+    [RVSP_IOMMU_SYS] =      {    0102000,        0x1000 },
This might be a typo:
      0102000 -> 0x102000

Thanks,
Chao



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

* Re: [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board
  2025-05-28 20:01 [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Daniel Henrique Barboza
                   ` (3 preceding siblings ...)
  2025-05-28 20:01 ` [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys Daniel Henrique Barboza
@ 2025-10-30 11:48 ` Chao Liu
  2025-10-30 13:33   ` Daniel Henrique Barboza
  4 siblings, 1 reply; 20+ messages in thread
From: Chao Liu @ 2025-10-30 11:48 UTC (permalink / raw)
  To: dbarboza
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, zhiwei_liu

On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>Hi,
>
>This is my attempt to ressurect the Server SoC Platform reference work
>that has been buried for an year. The last posting was made an year ago
>[1]. 
>
>Most of the changes were made due to upstream differences from one year
>ago. Patch 1 is an example of that.
>
>In patch 2 (former 1), the main difference is the new CPU is rva23s64
>compliant. This wasn't possible in May 2024 because we didn't have this
>support back then.
>
>Patch 3 consists mostly of code base changes rather than functional
>changes. There was a discussion about whether we should supply fdts in
>this machine back in the v2 review [2]. The answer is yes: machine mode
>requires fdt to work, and we want to be flexible enough to generate our
>own fdt instead of relying on EDK2 to supply them. Note that we can also
>supply an EDK2-generated fdt via command line, bypassing the fdt created
>by QEMU, if desired.
>
>Patch 4 adds a riscv-iommu-sys device to the board. This wasn't possible
>back then because we didn't have the required upstream support for it.
>

Hi, Daniel.

Do we have any plans to support virt-io on the rvsp-ref machine in the future?

Recently, I have been using the RISC-V reference platform built on this set of
patches to support running the OpenEuler RISC-V operating system.

I will actively feed back any test results to the upstream.

Thanks,
Chao


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

* Re: [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys
  2025-10-30 11:40   ` Chao Liu
@ 2025-10-30 13:23     ` Daniel Henrique Barboza
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-30 13:23 UTC (permalink / raw)
  To: Chao Liu
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, zhiwei_liu



On 10/30/25 8:40 AM, Chao Liu wrote:
> On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>> Add an always present IOMMU platform device for the rvsp-ref board.
>>
>> The IRQs being used are similar to what the 'virt' board is using: IRQs
>> 36 to 39, one IRQ for queue.
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>> hw/riscv/Kconfig               |  1 +
>> hw/riscv/server_platform_ref.c | 78 ++++++++++++++++++++++++++++++++--
>> 2 files changed, 75 insertions(+), 4 deletions(-)
>>
>> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
>> index f626774c52..cd70095687 100644
>> --- a/hw/riscv/Kconfig
>> +++ b/hw/riscv/Kconfig
>> @@ -82,6 +82,7 @@ config SERVER_PLATFORM_REF
>>     select RISCV_ACLINT
>>     select RISCV_APLIC
>>     select RISCV_IMSIC
>> +    select RISCV_IOMMU
>>
>> config SHAKTI_C
>>     bool
>> diff --git a/hw/riscv/server_platform_ref.c b/hw/riscv/server_platform_ref.c
>> index 5102286103..9740b395f6 100644
>> --- a/hw/riscv/server_platform_ref.c
>> +++ b/hw/riscv/server_platform_ref.c
>> @@ -31,6 +31,8 @@
>> #include "hw/riscv/riscv_hart.h"
>> #include "hw/riscv/boot.h"
>> #include "hw/riscv/numa.h"
>> +#include "hw/riscv/iommu.h"
>> +#include "hw/riscv/riscv-iommu-bits.h"
>> #include "hw/intc/riscv_aclint.h"
>> #include "hw/intc/riscv_aplic.h"
>> #include "hw/intc/riscv_imsic.h"
>> @@ -94,6 +96,7 @@ enum {
>>     RVSP_MROM,
>>     RVSP_RESET_SYSCON,
>>     RVSP_RTC,
>> +    RVSP_IOMMU_SYS,
>>     RVSP_ACLINT,
>>     RVSP_APLIC_M,
>>     RVSP_APLIC_S,
>> @@ -112,6 +115,7 @@ enum {
>>     RVSP_UART0_IRQ = 10,
>>     RVSP_RTC_IRQ = 11,
>>     RVSP_PCIE_IRQ = 0x20, /* 32 to 35 */
>> +    IOMMU_SYS_IRQ = 0x24 /* 36 to 39 */
>> };
>>
>> /*
>> @@ -141,6 +145,7 @@ static const MemMapEntry rvsp_ref_memmap[] = {
>>     [RVSP_MROM] =           {     0x1000,        0xf000 },
>>     [RVSP_RESET_SYSCON] =   {   0x100000,        0x1000 },
>>     [RVSP_RTC] =            {   0x101000,        0x1000 },
>> +    [RVSP_IOMMU_SYS] =      {    0102000,        0x1000 },
> This might be a typo:
>       0102000 -> 0x102000

Good call. I'll fix it in v4. Thanks,


Daniel

> 
> Thanks,
> Chao
> 



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

* Re: [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board
  2025-10-30 11:48 ` [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Chao Liu
@ 2025-10-30 13:33   ` Daniel Henrique Barboza
  2025-10-30 15:23     ` Chao Liu
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-30 13:33 UTC (permalink / raw)
  To: Chao Liu
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, zhiwei_liu



On 10/30/25 8:48 AM, Chao Liu wrote:
> On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>> Hi,
>>
>> This is my attempt to ressurect the Server SoC Platform reference work
>> that has been buried for an year. The last posting was made an year ago
>> [1].
>> Most of the changes were made due to upstream differences from one year
>> ago. Patch 1 is an example of that.
>>
>> In patch 2 (former 1), the main difference is the new CPU is rva23s64
>> compliant. This wasn't possible in May 2024 because we didn't have this
>> support back then.
>>
>> Patch 3 consists mostly of code base changes rather than functional
>> changes. There was a discussion about whether we should supply fdts in
>> this machine back in the v2 review [2]. The answer is yes: machine mode
>> requires fdt to work, and we want to be flexible enough to generate our
>> own fdt instead of relying on EDK2 to supply them. Note that we can also
>> supply an EDK2-generated fdt via command line, bypassing the fdt created
>> by QEMU, if desired.
>>
>> Patch 4 adds a riscv-iommu-sys device to the board. This wasn't possible
>> back then because we didn't have the required upstream support for it.
>>
> 
> Hi, Daniel.
> 
> Do we have any plans to support virt-io on the rvsp-ref machine in the future?

Hmmm good question. In theory we're interested only in implementing the rvsp-ref
spec but adding virt-io support doesn't hurt the spec implementation in any
way ... I think. Drew, any comments?


> 
> Recently, I have been using the RISC-V reference platform built on this set of
> patches to support running the OpenEuler RISC-V operating system.
> 
> I will actively feed back any test results to the upstream.


This series has been stale because, as you might've read in the thread, it turns
out we're missing a mandatory extension (sdext).

I get emails from time to time from people asking about the status of this work
so I'm considering pushing the patches as is, without sdext, and add documentation
saying that this isn't a 100% rsvp-ref compliant board. The absence of sdext
seems tolerable for the current uses ppl have for the board ATM, so upstreaming
it as is can be beneficial for everyone. We can add sdext support later and
then update the docs claiming 100% compliance.

At very least I'll have to send a v4 now that you pointed out a wrong memory
address in the memmap, so I'll start with that.


Thanks,

Daniel


> 
> Thanks,
> Chao



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

* Re: [PATCH v3 2/4] target/riscv: Add server platform reference cpu
  2025-05-28 20:01 ` [PATCH v3 2/4] target/riscv: Add server platform reference cpu Daniel Henrique Barboza
  2025-05-29 11:56   ` Andrew Jones
@ 2025-10-30 15:01   ` Chao Liu
  2025-10-30 15:14     ` Daniel Henrique Barboza
  1 sibling, 1 reply; 20+ messages in thread
From: Chao Liu @ 2025-10-30 15:01 UTC (permalink / raw)
  To: dbarboza
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, wu.fei9, zhiwei_liu

On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>rom: Fei Wu <wu.fei9@sanechips.com.cn>
>
>he harts requirements of RISC-V server platform [1] require RVA23 ISA
>rofile support, plus Sv48, Svadu, H, Sscofmpf etc. This patch provides
> virt CPU type (rvsp-ref) as compliant as possible.
>
>1] https://github.com/riscv-non-isa/riscv-server-platform/blob/main/server_platform_requirements.adoc
>
>igned-off-by: Fei Wu <fei2.wu@intel.com>
>igned-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>--
>target/riscv/cpu-qom.h |  1 +
>target/riscv/cpu.c     | 11 +++++++++++
>2 files changed, 12 insertions(+)
>
>iff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
>ndex 1ee05eb393..70978fd53c 100644
>-- a/target/riscv/cpu-qom.h
>++ b/target/riscv/cpu-qom.h
>@ -55,6 +55,7 @@
>#define TYPE_RISCV_CPU_VEYRON_V1        RISCV_CPU_TYPE_NAME("veyron-v1")
>#define TYPE_RISCV_CPU_TT_ASCALON       RISCV_CPU_TYPE_NAME("tt-ascalon")
>#define TYPE_RISCV_CPU_XIANGSHAN_NANHU  RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
>#define TYPE_RISCV_CPU_RVSP_REF         RISCV_CPU_TYPE_NAME("rvsp-ref")
>#define TYPE_RISCV_CPU_HOST             RISCV_CPU_TYPE_NAME("host")
>
>OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
>iff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>ndex 4a30cf8444..ec2fbc0e78 100644
>-- a/target/riscv/cpu.c
>++ b/target/riscv/cpu.c
>@ -3166,6 +3166,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>        .cfg.max_satp_mode = VM_1_10_SV39,
>    ),
>
>    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RVSP_REF, TYPE_RISCV_VENDOR_CPU,

I'm not sure the parent type TYPE_RISCV_VENDOR_CPU is right here.

To be on the safe side, I tested this CPU type using an openEuler image that
can boot on a virtual machine. This image supports rva23s64, and my command is
as follows:

cmd="$QEMU_SYSTEM_RISCV64 \
   -nographic -machine virt,pflash0=pflash0,pflash1=pflash1,acpi=off \
   -cpu rvsp-ref \
   -smp "$vcpu" -m "$memory"G \
   -blockdev node-name=pflash0,driver=file,read-only=on,filename="$fw1" \
   -blockdev node-name=pflash1,driver=file,filename="$fw2" \
   -drive file="$drive",format=qcow2,id=hd0,if=none \
   -object rng-random,filename=/dev/urandom,id=rng0 \
   -device virtio-vga \
   -device virtio-rng-device,rng=rng0 \
   -device virtio-blk-device,drive=hd0 \
   -device virtio-net-device,netdev=usernet \
   -netdev user,id=usernet,hostfwd=tcp::"$ssh_port"-:22 \
   -device qemu-xhci -usb -device usb-kbd -device usb-tablet"

This process gets stuck at the initialization stage:

```
     Loading Linux 6.6.0-102.0.0.5.oe2509.riscv64 ...
     Loading initial ramdisk ...
```

If I use the parameter `-cpu rva23s64`, the system can boot normally.

I tried changing TYPE_RISCV_VENDOR_CPU to TYPE_RISCV_BARE_CPU and found that
the system then boots normally.

However, I haven’t conducted an in-depth analysis yet, so the issue might be
with my system image.

Thanks,
Chao

>        .misa_mxl_max = MXL_RV64,
>        .profile = &RVA23S64,
>
>        /* ISA extensions */
>        .cfg.ext_zkr = true,
>        .cfg.ext_svadu = true,
>
>        .cfg.max_satp_mode = VM_1_10_SV57,
>    ),
>



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

* Re: [PATCH v3 2/4] target/riscv: Add server platform reference cpu
  2025-10-30 15:01   ` Chao Liu
@ 2025-10-30 15:14     ` Daniel Henrique Barboza
  2025-10-30 16:45       ` Chao Liu
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-30 15:14 UTC (permalink / raw)
  To: Chao Liu
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, wu.fei9, zhiwei_liu



On 10/30/25 12:01 PM, Chao Liu wrote:
> On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>> rom: Fei Wu <wu.fei9@sanechips.com.cn>
>>
>> he harts requirements of RISC-V server platform [1] require RVA23 ISA
>> rofile support, plus Sv48, Svadu, H, Sscofmpf etc. This patch provides
>> virt CPU type (rvsp-ref) as compliant as possible.
>>
>> 1] https://github.com/riscv-non-isa/riscv-server-platform/blob/main/server_platform_requirements.adoc
>>
>> igned-off-by: Fei Wu <fei2.wu@intel.com>
>> igned-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> -- 
>> target/riscv/cpu-qom.h |  1 +
>> target/riscv/cpu.c     | 11 +++++++++++
>> 2 files changed, 12 insertions(+)
>>
>> iff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
>> ndex 1ee05eb393..70978fd53c 100644
>> -- a/target/riscv/cpu-qom.h
>> ++ b/target/riscv/cpu-qom.h
>> @ -55,6 +55,7 @@
>> #define TYPE_RISCV_CPU_VEYRON_V1        RISCV_CPU_TYPE_NAME("veyron-v1")
>> #define TYPE_RISCV_CPU_TT_ASCALON       RISCV_CPU_TYPE_NAME("tt-ascalon")
>> #define TYPE_RISCV_CPU_XIANGSHAN_NANHU  RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
>> #define TYPE_RISCV_CPU_RVSP_REF         RISCV_CPU_TYPE_NAME("rvsp-ref")
>> #define TYPE_RISCV_CPU_HOST             RISCV_CPU_TYPE_NAME("host")
>>
>> OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
>> iff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> ndex 4a30cf8444..ec2fbc0e78 100644
>> -- a/target/riscv/cpu.c
>> ++ b/target/riscv/cpu.c
>> @ -3166,6 +3166,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>>        .cfg.max_satp_mode = VM_1_10_SV39,
>>    ),
>>
>>    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RVSP_REF, TYPE_RISCV_VENDOR_CPU,
> 
> I'm not sure the parent type TYPE_RISCV_VENDOR_CPU is right here.
> 
> To be on the safe side, I tested this CPU type using an openEuler image that
> can boot on a virtual machine. This image supports rva23s64, and my command is
> as follows:
> 
> cmd="$QEMU_SYSTEM_RISCV64 \
>    -nographic -machine virt,pflash0=pflash0,pflash1=pflash1,acpi=off \
>    -cpu rvsp-ref \
>    -smp "$vcpu" -m "$memory"G \
>    -blockdev node-name=pflash0,driver=file,read-only=on,filename="$fw1" \
>    -blockdev node-name=pflash1,driver=file,filename="$fw2" \
>    -drive file="$drive",format=qcow2,id=hd0,if=none \
>    -object rng-random,filename=/dev/urandom,id=rng0 \
>    -device virtio-vga \
>    -device virtio-rng-device,rng=rng0 \
>    -device virtio-blk-device,drive=hd0 \
>    -device virtio-net-device,netdev=usernet \
>    -netdev user,id=usernet,hostfwd=tcp::"$ssh_port"-:22 \
>    -device qemu-xhci -usb -device usb-kbd -device usb-tablet"
> 
> This process gets stuck at the initialization stage:
> 
> ```
>      Loading Linux 6.6.0-102.0.0.5.oe2509.riscv64 ...
>      Loading initial ramdisk ...
> ```
> 
> If I use the parameter `-cpu rva23s64`, the system can boot normally.
> 
> I tried changing TYPE_RISCV_VENDOR_CPU to TYPE_RISCV_BARE_CPU and found that
> the system then boots normally.

There is a chance that we're mishandling the .profile property with VENDOR
type CPUs. Maybe worth taking a look.

There's nothing stopping us from declaring the CPU as BARE though. It's
probably a good idea - it gives us a clean CPU without any enabled default
extensions to work on. I believe we can change that for v4.


Thanks,

Daniel

> 
> However, I haven’t conducted an in-depth analysis yet, so the issue might be
> with my system image.
> 
> Thanks,
> Chao
> 
>>        .misa_mxl_max = MXL_RV64,
>>        .profile = &RVA23S64,
>>
>>        /* ISA extensions */
>>        .cfg.ext_zkr = true,
>>        .cfg.ext_svadu = true,
>>
>>        .cfg.max_satp_mode = VM_1_10_SV57,
>>    ),
>>
> 



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

* Re: [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board
  2025-10-30 13:33   ` Daniel Henrique Barboza
@ 2025-10-30 15:23     ` Chao Liu
  2025-10-30 15:37       ` Daniel Henrique Barboza
  0 siblings, 1 reply; 20+ messages in thread
From: Chao Liu @ 2025-10-30 15:23 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, zhiwei_liu

On 10/30/2025 9:33 PM, Daniel Henrique Barboza wrote:
> 
> 
> On 10/30/25 8:48 AM, Chao Liu wrote:
>> On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>>> Hi,
>>>
>>> This is my attempt to ressurect the Server SoC Platform reference work
>>> that has been buried for an year. The last posting was made an year ago
>>> [1].
>>> Most of the changes were made due to upstream differences from one year
>>> ago. Patch 1 is an example of that.
>>>
>>> In patch 2 (former 1), the main difference is the new CPU is rva23s64
>>> compliant. This wasn't possible in May 2024 because we didn't have this
>>> support back then.
>>>
>>> Patch 3 consists mostly of code base changes rather than functional
>>> changes. There was a discussion about whether we should supply fdts in
>>> this machine back in the v2 review [2]. The answer is yes: machine mode
>>> requires fdt to work, and we want to be flexible enough to generate our
>>> own fdt instead of relying on EDK2 to supply them. Note that we can also
>>> supply an EDK2-generated fdt via command line, bypassing the fdt created
>>> by QEMU, if desired.
>>>
>>> Patch 4 adds a riscv-iommu-sys device to the board. This wasn't possible
>>> back then because we didn't have the required upstream support for it.
>>>
>>
>> Hi, Daniel.
>>
>> Do we have any plans to support virt-io on the rvsp-ref machine in the future?
> 
> Hmmm good question. In theory we're interested only in implementing the rvsp-ref
> spec but adding virt-io support doesn't hurt the spec implementation in any
> way ... I think. Drew, any comments?
> 
> 
>>
>> Recently, I have been using the RISC-V reference platform built on this set of
>> patches to support running the OpenEuler RISC-V operating system.
>>
>> I will actively feed back any test results to the upstream.
> 
> 
> This series has been stale because, as you might've read in the thread, it turns
> out we're missing a mandatory extension (sdext).
> 

I have a basic version of the sdext extension ready. I’ll improve it later and
share it with the upstream community to discuss.

Thank,
Chao

> I get emails from time to time from people asking about the status of this work
> so I'm considering pushing the patches as is, without sdext, and add documentation
> saying that this isn't a 100% rsvp-ref compliant board. The absence of sdext
> seems tolerable for the current uses ppl have for the board ATM, so upstreaming
> it as is can be beneficial for everyone. We can add sdext support later and
> then update the docs claiming 100% compliance.
> 
> At very least I'll have to send a v4 now that you pointed out a wrong memory
> address in the memmap, so I'll start with that.
> 
> 
> Thanks,
> 
> Daniel
> 
> 
>>
>> Thanks,
>> Chao



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

* Re: [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board
  2025-10-30 15:23     ` Chao Liu
@ 2025-10-30 15:37       ` Daniel Henrique Barboza
  2025-10-30 20:53         ` Andrew Jones
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Henrique Barboza @ 2025-10-30 15:37 UTC (permalink / raw)
  To: Chao Liu
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, zhiwei_liu



On 10/30/25 12:23 PM, Chao Liu wrote:
> On 10/30/2025 9:33 PM, Daniel Henrique Barboza wrote:
>>
>>
>> On 10/30/25 8:48 AM, Chao Liu wrote:
>>> On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>>>> Hi,
>>>>
>>>> This is my attempt to ressurect the Server SoC Platform reference work
>>>> that has been buried for an year. The last posting was made an year ago
>>>> [1].
>>>> Most of the changes were made due to upstream differences from one year
>>>> ago. Patch 1 is an example of that.
>>>>
>>>> In patch 2 (former 1), the main difference is the new CPU is rva23s64
>>>> compliant. This wasn't possible in May 2024 because we didn't have this
>>>> support back then.
>>>>
>>>> Patch 3 consists mostly of code base changes rather than functional
>>>> changes. There was a discussion about whether we should supply fdts in
>>>> this machine back in the v2 review [2]. The answer is yes: machine mode
>>>> requires fdt to work, and we want to be flexible enough to generate our
>>>> own fdt instead of relying on EDK2 to supply them. Note that we can also
>>>> supply an EDK2-generated fdt via command line, bypassing the fdt created
>>>> by QEMU, if desired.
>>>>
>>>> Patch 4 adds a riscv-iommu-sys device to the board. This wasn't possible
>>>> back then because we didn't have the required upstream support for it.
>>>>
>>>
>>> Hi, Daniel.
>>>
>>> Do we have any plans to support virt-io on the rvsp-ref machine in the future?
>>
>> Hmmm good question. In theory we're interested only in implementing the rvsp-ref
>> spec but adding virt-io support doesn't hurt the spec implementation in any
>> way ... I think. Drew, any comments?
>>
>>
>>>
>>> Recently, I have been using the RISC-V reference platform built on this set of
>>> patches to support running the OpenEuler RISC-V operating system.
>>>
>>> I will actively feed back any test results to the upstream.
>>
>>
>> This series has been stale because, as you might've read in the thread, it turns
>> out we're missing a mandatory extension (sdext).
>>
> 
> I have a basic version of the sdext extension ready. I’ll improve it later and
> share it with the upstream community to discuss.


That's awesome! Guess we'll be able to upstream a 100% compliant server platform
emulation sooner than I've expected.


Thanks,

Daniel

> 
> Thank,
> Chao
> 
>> I get emails from time to time from people asking about the status of this work
>> so I'm considering pushing the patches as is, without sdext, and add documentation
>> saying that this isn't a 100% rsvp-ref compliant board. The absence of sdext
>> seems tolerable for the current uses ppl have for the board ATM, so upstreaming
>> it as is can be beneficial for everyone. We can add sdext support later and
>> then update the docs claiming 100% compliance.
>>
>> At very least I'll have to send a v4 now that you pointed out a wrong memory
>> address in the memmap, so I'll start with that.
>>
>>
>> Thanks,
>>
>> Daniel
>>
>>
>>>
>>> Thanks,
>>> Chao
> 



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

* Re: [PATCH v3 2/4] target/riscv: Add server platform reference cpu
  2025-10-30 15:14     ` Daniel Henrique Barboza
@ 2025-10-30 16:45       ` Chao Liu
  0 siblings, 0 replies; 20+ messages in thread
From: Chao Liu @ 2025-10-30 16:45 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: ajones, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, wu.fei9, zhiwei_liu



On 10/30/2025 11:14 PM, Daniel Henrique Barboza wrote:
> 
> 
> On 10/30/25 12:01 PM, Chao Liu wrote:
>> On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>>> rom: Fei Wu <wu.fei9@sanechips.com.cn>
>>>
>>> he harts requirements of RISC-V server platform [1] require RVA23 ISA
>>> rofile support, plus Sv48, Svadu, H, Sscofmpf etc. This patch provides
>>> virt CPU type (rvsp-ref) as compliant as possible.
>>>
>>> 1] https://github.com/riscv-non-isa/riscv-server-platform/blob/main/server_platform_requirements.adoc
>>>
>>> igned-off-by: Fei Wu <fei2.wu@intel.com>
>>> igned-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>>> -- 
>>> target/riscv/cpu-qom.h |  1 +
>>> target/riscv/cpu.c     | 11 +++++++++++
>>> 2 files changed, 12 insertions(+)
>>>
>>> iff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
>>> ndex 1ee05eb393..70978fd53c 100644
>>> -- a/target/riscv/cpu-qom.h
>>> ++ b/target/riscv/cpu-qom.h
>>> @ -55,6 +55,7 @@
>>> #define TYPE_RISCV_CPU_VEYRON_V1        RISCV_CPU_TYPE_NAME("veyron-v1")
>>> #define TYPE_RISCV_CPU_TT_ASCALON       RISCV_CPU_TYPE_NAME("tt-ascalon")
>>> #define TYPE_RISCV_CPU_XIANGSHAN_NANHU  RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
>>> #define TYPE_RISCV_CPU_RVSP_REF         RISCV_CPU_TYPE_NAME("rvsp-ref")
>>> #define TYPE_RISCV_CPU_HOST             RISCV_CPU_TYPE_NAME("host")
>>>
>>> OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
>>> iff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>> ndex 4a30cf8444..ec2fbc0e78 100644
>>> -- a/target/riscv/cpu.c
>>> ++ b/target/riscv/cpu.c
>>> @ -3166,6 +3166,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>>>        .cfg.max_satp_mode = VM_1_10_SV39,
>>>    ),
>>>
>>>    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RVSP_REF, TYPE_RISCV_VENDOR_CPU,
>>
>> I'm not sure the parent type TYPE_RISCV_VENDOR_CPU is right here.
>>
>> To be on the safe side, I tested this CPU type using an openEuler image that
>> can boot on a virtual machine. This image supports rva23s64, and my command is
>> as follows:
>>
>> cmd="$QEMU_SYSTEM_RISCV64 \
>>    -nographic -machine virt,pflash0=pflash0,pflash1=pflash1,acpi=off \
>>    -cpu rvsp-ref \
>>    -smp "$vcpu" -m "$memory"G \
>>    -blockdev node-name=pflash0,driver=file,read-only=on,filename="$fw1" \
>>    -blockdev node-name=pflash1,driver=file,filename="$fw2" \
>>    -drive file="$drive",format=qcow2,id=hd0,if=none \
>>    -object rng-random,filename=/dev/urandom,id=rng0 \
>>    -device virtio-vga \
>>    -device virtio-rng-device,rng=rng0 \
>>    -device virtio-blk-device,drive=hd0 \
>>    -device virtio-net-device,netdev=usernet \
>>    -netdev user,id=usernet,hostfwd=tcp::"$ssh_port"-:22 \
>>    -device qemu-xhci -usb -device usb-kbd -device usb-tablet"
>>
>> This process gets stuck at the initialization stage:
>>
>> ```
>>      Loading Linux 6.6.0-102.0.0.5.oe2509.riscv64 ...
>>      Loading initial ramdisk ...
>> ```
>>
>> If I use the parameter `-cpu rva23s64`, the system can boot normally.
>>
>> I tried changing TYPE_RISCV_VENDOR_CPU to TYPE_RISCV_BARE_CPU and found that
>> the system then boots normally.
> 
> There is a chance that we're mishandling the .profile property with VENDOR
> type CPUs. Maybe worth taking a look.
> 
> There's nothing stopping us from declaring the CPU as BARE though. It's
> probably a good idea - it gives us a clean CPU without any enabled default
> extensions to work on. I believe we can change that for v4.
> 

I have done more tests. TYPE_RISCV_BARE_CPU works well in the virt machine,
but it can’t start EDKII normally in the rvsp-ref machine.

I think it’s really worth finding out the exact reason first before
we decide whether to make the change.

If I get any progress on my part, I will reply to this email quickly :).

Thanks,
Chao



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

* Re: [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board
  2025-10-30 15:37       ` Daniel Henrique Barboza
@ 2025-10-30 20:53         ` Andrew Jones
  0 siblings, 0 replies; 20+ messages in thread
From: Andrew Jones @ 2025-10-30 20:53 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: Chao Liu, alistair.francis, liwei1518, palmer, qemu-devel,
	qemu-riscv, zhiwei_liu

On Thu, Oct 30, 2025 at 12:37:00PM -0300, Daniel Henrique Barboza wrote:
> 
> 
> On 10/30/25 12:23 PM, Chao Liu wrote:
> > On 10/30/2025 9:33 PM, Daniel Henrique Barboza wrote:
> > > 
> > > 
> > > On 10/30/25 8:48 AM, Chao Liu wrote:
> > > > On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
> > > > > Hi,
> > > > > 
> > > > > This is my attempt to ressurect the Server SoC Platform reference work
> > > > > that has been buried for an year. The last posting was made an year ago
> > > > > [1].
> > > > > Most of the changes were made due to upstream differences from one year
> > > > > ago. Patch 1 is an example of that.
> > > > > 
> > > > > In patch 2 (former 1), the main difference is the new CPU is rva23s64
> > > > > compliant. This wasn't possible in May 2024 because we didn't have this
> > > > > support back then.
> > > > > 
> > > > > Patch 3 consists mostly of code base changes rather than functional
> > > > > changes. There was a discussion about whether we should supply fdts in
> > > > > this machine back in the v2 review [2]. The answer is yes: machine mode
> > > > > requires fdt to work, and we want to be flexible enough to generate our
> > > > > own fdt instead of relying on EDK2 to supply them. Note that we can also
> > > > > supply an EDK2-generated fdt via command line, bypassing the fdt created
> > > > > by QEMU, if desired.
> > > > > 
> > > > > Patch 4 adds a riscv-iommu-sys device to the board. This wasn't possible
> > > > > back then because we didn't have the required upstream support for it.
> > > > > 
> > > > 
> > > > Hi, Daniel.
> > > > 
> > > > Do we have any plans to support virt-io on the rvsp-ref machine in the future?
> > > 
> > > Hmmm good question. In theory we're interested only in implementing the rvsp-ref
> > > spec but adding virt-io support doesn't hurt the spec implementation in any
> > > way ... I think. Drew, any comments?

Allowing virtio devices should be fine. I think other reference models
have shied away from supporting virtio devices since they want to strictly
represent real hardware. Of course there can be real hardware which
implements the virtio spec, though, so I don't see a problem of allowing
them even when being strict.

> > > 
> > > 
> > > > 
> > > > Recently, I have been using the RISC-V reference platform built on this set of
> > > > patches to support running the OpenEuler RISC-V operating system.
> > > > 
> > > > I will actively feed back any test results to the upstream.
> > > 
> > > 
> > > This series has been stale because, as you might've read in the thread, it turns
> > > out we're missing a mandatory extension (sdext).
> > > 
> > 
> > I have a basic version of the sdext extension ready. I’ll improve it later and
> > share it with the upstream community to discuss.
> 
> 
> That's awesome! Guess we'll be able to upstream a 100% compliant server platform
> emulation sooner than I've expected.

And I would prefer we wait until the reference model is complete before
merging it, unless it gets merged with a temporary "experimental" type
name.

Thanks,
drew


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

* Re: [PATCH v3 3/4] hw/riscv: Add server platform reference machine
  2025-05-28 20:01 ` [PATCH v3 3/4] hw/riscv: Add server platform reference machine Daniel Henrique Barboza
  2025-05-29 12:31   ` Andrew Jones
@ 2025-10-30 22:27   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-10-30 22:27 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu, palmer,
	ajones, Fei Wu

On 28/5/25 22:01, Daniel Henrique Barboza wrote:
> From: Fei Wu <wu.fei9@sanechips.com.cn>
> 
> 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.
> 
> A corresponding Qemu RISC-V server platform reference (rvsp-ref for
> short) machine type is added to provide a environment for firmware/OS
> development and testing. The main features included in rvsp-ref 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 <fei2.wu@intel.com>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   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 39ed3a0061..0c4893b708 100644
> --- a/configs/devices/riscv64-softmmu/default.mak
> +++ b/configs/devices/riscv64-softmmu/default.mak
> @@ -9,5 +9,6 @@
>   # 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
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index e6a0ac1fa1..f626774c52 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

PCI is already selected by PCI_EXPRESS_GENERIC_BRIDGE.

> +    select PCI_EXPRESS_GENERIC_BRIDGE
> +    select PFLASH_CFI01
> +    select SERIAL
> +    select RISCV_ACLINT
> +    select RISCV_APLIC
> +    select RISCV_IMSIC


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

end of thread, other threads:[~2025-10-30 22:30 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-28 20:01 [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Daniel Henrique Barboza
2025-05-28 20:01 ` [PATCH v3 1/4] target/riscv/cpu.c: remove 'bare' condition for .profile Daniel Henrique Barboza
2025-05-29 11:56   ` Andrew Jones
2025-05-28 20:01 ` [PATCH v3 2/4] target/riscv: Add server platform reference cpu Daniel Henrique Barboza
2025-05-29 11:56   ` Andrew Jones
2025-10-30 15:01   ` Chao Liu
2025-10-30 15:14     ` Daniel Henrique Barboza
2025-10-30 16:45       ` Chao Liu
2025-05-28 20:01 ` [PATCH v3 3/4] hw/riscv: Add server platform reference machine Daniel Henrique Barboza
2025-05-29 12:31   ` Andrew Jones
2025-10-30 22:27   ` Philippe Mathieu-Daudé
2025-05-28 20:01 ` [PATCH v3 4/4] hw/riscv/server_platform_ref.c: add riscv-iommu-sys Daniel Henrique Barboza
2025-05-29 12:33   ` Andrew Jones
2025-10-30 11:40   ` Chao Liu
2025-10-30 13:23     ` Daniel Henrique Barboza
2025-10-30 11:48 ` [PATCH v3 0/4] hw/riscv: Add Server Platform Reference Board Chao Liu
2025-10-30 13:33   ` Daniel Henrique Barboza
2025-10-30 15:23     ` Chao Liu
2025-10-30 15:37       ` Daniel Henrique Barboza
2025-10-30 20:53         ` Andrew Jones

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).