On Wed, Sep 09, 2026 at 06:07:53PM -0300, Daniel Henrique Barboza wrote:
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index d06ac26648..da59eb2155 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -69,6 +69,22 @@ config RISCV_VIRT
> select ACPI
> select ACPI_PCI
>
> +config RISCV_SERVER_PLATFORM_REF
> + bool
> + default y
> + depends on RISCV64
> + imply TPM_TIS_SYSBUS
> + select RISCV_NUMA
> + select GOLDFISH_RTC
> + select PCI
> + select PCI_EXPRESS_GENERIC_BRIDGE
> + select PFLASH_CFI01
> + select SERIAL
This needs to select SERIAL_MM rather than SERIAL, since the machine calls
serial_mm_init(). It also directly uses the platform bus, so it needs
select PLATFORM_BUS
The machine also creates an ICH9 AHCI controller, so keeping it would require
selecting AHCI_ICH9.
However, SATA is optional for Server Platform v1.0, so I suggest dropping the
default ICH9 AHCI controller instead. That would also remove the IDE/AHCI
includes, NUM_SATA_PORTS, the AHCI-specific state, and its initialization.
The base machine would then have no default storage controller, and users
could add NVMe explicitly when needed.
Likewise, networking hardware is optional, so I suggest dropping the e1000e
default NIC. pci_init_nic_devices() may remain for explicit -nic requests.
To make suitable optional devices such as NVMe available, I suggest
imply PCIE_DEVICES
rather than the broader PCI_DEVICES set.
> +#include "system/kvm.h"
> +#include "system/qtest.h"
> +#include "system/tcg.h"
> +#include "kvm/kvm_riscv.h"
> +#include "system/tpm.h"
> +#include "system/qtest.h"
Duplicate system/qtest.h include.
> +#define RVSERVER_IRQCHIP_NUM_MSIS 255
> +#define RVSERVER_IRQCHIP_NUM_SOURCES 96
> +#define RVSERVER_IRQCHIP_NUM_PRIO_BITS 3
> +#define RVSERVER_IRQCHIP_MAX_GUESTS_BITS 3
> +#define RVSERVER_IRQCHIP_MAX_GUESTS \
> + ((1U << RVSERVER_IRQCHIP_MAX_GUESTS_BITS) - 1U)
> +#define RVSERVER_IRQCHIP_DEFAULT_AIA_GUESTS 5
nit: Please align these definitions with the related definitions above.
Also, the two nearby #error strings have "accomodate" rather than
"accommodate".
> +enum {
> + RVSERVER_UART0_IRQ = 10,
> + RVSERVER_RTC_IRQ = 11,
> + RVSERVER_PCIE_IRQ = 32, /* 32 to 35 */
> + IOMMU_SYS_IRQ = 36, /* 36 to 39 */
> + RVSERVER_PLATFORM_BUS_IRQ = 40, /* 40 to 48 */
> +};
RVSERVER_PLATFORM_BUS_NUM_IRQS is 8, so this should say 40 to 47. Please
also align the assignments.
> +static const MemMapEntry rvserver_ref_memmap[] = {
> + [RVSERVER_DEBUG] = { 0x0, 0x100 },
RVSERVER_DEBUG does not appear to be used.
> + riscv_aclint_mtimer_create(memmap[RVSERVER_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);
Server SoC v1.0 CTI_010 requires the time CSR to count in units of 1 ns,
so we should define a machine-specific 1 GHz timebase rather than using
the 10 MHz virt default, for example
#define RVSERVER_ACLINT_TIMEBASE_FREQ 1000000000
and use RVSERVER_ACLINT_TIMEBASE_FREQ in this call. The CPU FDT
timebase-frequency property should use
kvm_enabled() ? kvm_riscv_get_timebase_frequency(&s->soc->harts[0]) :
RVSERVER_ACLINT_TIMEBASE_FREQ
> + if (!rvserver_aclint_allowed()) {
> + error_report("'aclint' is only available with TCG acceleration");
> + exit(1);
> + }
This makes the machine TCG/qtest only. We can follow virt's support of KVM
to enable it. The documentation can state that a conformant guest requires
a conformant host, while allowing nonconformant hosts to be used for
functional KVM testing.
> +static void rvserver_ref_machine_instance_init(Object *obj)
> +{
> + RISCVServerRefMachineState *s = RISCV_SERVER_REF_MACHINE(obj);
> +
> + s->flash[0] = riscv_flash_create(OBJECT(s),
> + "riscv-server-ref.flash0",
> + "pflash0",
> + RVSERVER_FLASH_SECTOR_SIZE);
> + s->flash[1] = riscv_flash_create(OBJECT(s),
> + "riscv-server-ref.flash1",
> + "pflash1",
> + RVSERVER_FLASH_SECTOR_SIZE);
virt has an instance finalizer which unreferences either flash device when
initialization fails before realization. This machine should have the same
cleanup and set instance_finalize in its TypeInfo.
> + static const char * const valid_cpu_types[] = {
> + TYPE_RISCV_CPU_RVSERVER_REF,
> + };
This needs a NULL terminator. MachineClass.valid_cpu_types is walked until
NULL. For example, testing this with "-cpu max" printed:
The valid models are: riscv-server-ref, (null), (null)
KVM also needs TYPE_RISCV_CPU_HOST in the valid CPU types.
Thanks,
drew