aboutsummaryrefslogtreecommitdiff
path: root/include/hw
diff options
context:
space:
mode:
Diffstat (limited to 'include/hw')
-rw-r--r--include/hw/acpi/acpi_dev_interface.h1
-rw-r--r--include/hw/acpi/aml-build.h2
-rw-r--r--include/hw/acpi/generic_event_device.h18
-rw-r--r--include/hw/acpi/ghes.h51
-rw-r--r--include/hw/acpi/pci.h5
-rw-r--r--include/hw/acpi/pcihp.h21
-rw-r--r--include/hw/arm/aspeed.h3
-rw-r--r--include/hw/arm/aspeed_coprocessor.h61
-rw-r--r--include/hw/arm/aspeed_soc.h61
-rw-r--r--include/hw/arm/boot.h3
-rw-r--r--include/hw/arm/max78000_soc.h50
-rw-r--r--include/hw/arm/npcm8xx.h7
-rw-r--r--include/hw/arm/omap.h536
-rw-r--r--include/hw/arm/sharpsl.h17
-rw-r--r--include/hw/arm/smmu-common.h1
-rw-r--r--include/hw/arm/soc_dma.h4
-rw-r--r--include/hw/arm/stm32f205_soc.h2
-rw-r--r--include/hw/arm/virt.h14
-rw-r--r--include/hw/arm/xen_arch_hvm.h9
-rw-r--r--include/hw/arm/xlnx-versal-version.h16
-rw-r--r--include/hw/arm/xlnx-versal.h342
-rw-r--r--include/hw/arm/xlnx-zynqmp.h5
-rw-r--r--include/hw/block/flash.h18
-rw-r--r--include/hw/boards.h71
-rw-r--r--include/hw/char/max78000_uart.h78
-rw-r--r--include/hw/core/cpu.h95
-rw-r--r--include/hw/core/resetcontainer.h2
-rw-r--r--include/hw/cxl/cxl.h6
-rw-r--r--include/hw/cxl/cxl_device.h54
-rw-r--r--include/hw/cxl/cxl_events.h15
-rw-r--r--include/hw/cxl/cxl_host.h5
-rw-r--r--include/hw/cxl/cxl_mailbox.h7
-rw-r--r--include/hw/display/bcm2835_fb.h1
-rw-r--r--include/hw/display/edid.h2
-rw-r--r--include/hw/display/ramfb.h2
-rw-r--r--include/hw/dma/xlnx_dpdma.h1
-rw-r--r--include/hw/firmware/smbios.h2
-rw-r--r--include/hw/gpio/aspeed_gpio.h2
-rw-r--r--include/hw/hyperv/hvgdk.h20
-rw-r--r--include/hw/hyperv/hvgdk_mini.h817
-rw-r--r--include/hw/hyperv/hvhdk.h249
-rw-r--r--include/hw/hyperv/hvhdk_mini.h102
-rw-r--r--include/hw/hyperv/hyperv.h3
-rw-r--r--include/hw/i2c/aspeed_i2c.h3
-rw-r--r--include/hw/i386/intel_iommu.h1
-rw-r--r--include/hw/i386/pc.h10
-rw-r--r--include/hw/i386/tdvf.h45
-rw-r--r--include/hw/i386/x86-iommu.h1
-rw-r--r--include/hw/i386/x86.h8
-rw-r--r--include/hw/i386/xen_arch_hvm.h11
-rw-r--r--include/hw/intc/arm_gic.h3
-rw-r--r--include/hw/intc/arm_gic_common.h2
-rw-r--r--include/hw/intc/arm_gicv3_common.h5
-rw-r--r--include/hw/intc/arm_gicv3_its_common.h2
-rw-r--r--include/hw/intc/aspeed_intc.h5
-rw-r--r--include/hw/intc/loongarch_dintc.h36
-rw-r--r--include/hw/intc/loongarch_extioi.h6
-rw-r--r--include/hw/intc/loongarch_extioi_common.h3
-rw-r--r--include/hw/intc/loongarch_ipi.h5
-rw-r--r--include/hw/intc/loongarch_pch_pic.h5
-rw-r--r--include/hw/intc/loongarch_pic_common.h60
-rw-r--r--include/hw/intc/loongson_ipi_common.h2
-rw-r--r--include/hw/intc/riscv_aclint.h4
-rw-r--r--include/hw/irq.h23
-rw-r--r--include/hw/loader.h2
-rw-r--r--include/hw/loongarch/boot.h5
-rw-r--r--include/hw/loongarch/virt.h87
-rw-r--r--include/hw/misc/aspeed_hace.h11
-rw-r--r--include/hw/misc/aspeed_sbc.h6
-rw-r--r--include/hw/misc/ivshmem-flat.h2
-rw-r--r--include/hw/misc/max78000_aes.h68
-rw-r--r--include/hw/misc/max78000_gcr.h131
-rw-r--r--include/hw/misc/max78000_icc.h33
-rw-r--r--include/hw/misc/max78000_trng.h35
-rw-r--r--include/hw/misc/xlnx-versal-crl.h366
-rw-r--r--include/hw/nvram/aspeed_otp.h33
-rw-r--r--include/hw/nvram/fw_cfg.h10
-rw-r--r--include/hw/pci-host/aspeed_pcie.h137
-rw-r--r--include/hw/pci-host/dino.h4
-rw-r--r--include/hw/pci-host/gpex.h1
-rw-r--r--include/hw/pci-host/ls7a.h37
-rw-r--r--include/hw/pci/msix.h1
-rw-r--r--include/hw/pci/pci.h329
-rw-r--r--include/hw/pci/pci_bridge.h5
-rw-r--r--include/hw/pci/pci_bus.h1
-rw-r--r--include/hw/pci/pci_device.h7
-rw-r--r--include/hw/pci/pci_host.h1
-rw-r--r--include/hw/pci/pci_ids.h2
-rw-r--r--include/hw/pci/pcie.h14
-rw-r--r--include/hw/pci/pcie_regs.h8
-rw-r--r--include/hw/pci/pcie_sriov.h23
-rw-r--r--include/hw/ppc/pnv.h38
-rw-r--r--include/hw/ppc/pnv_chip.h8
-rw-r--r--include/hw/ppc/pnv_chiptod.h2
-rw-r--r--include/hw/ppc/pnv_xscom.h49
-rw-r--r--include/hw/ppc/ppc.h1
-rw-r--r--include/hw/ppc/xive.h66
-rw-r--r--include/hw/ppc/xive2.h22
-rw-r--r--include/hw/ppc/xive2_regs.h22
-rw-r--r--include/hw/qdev-core.h1
-rw-r--r--include/hw/qdev-properties-system.h5
-rw-r--r--include/hw/qdev-properties.h18
-rw-r--r--include/hw/riscv/iommu.h6
-rw-r--r--include/hw/riscv/microchip_pfsoc.h1
-rw-r--r--include/hw/riscv/virt.h1
-rw-r--r--include/hw/riscv/xiangshan_kmh.h68
-rw-r--r--include/hw/s390x/ap-bridge.h39
-rw-r--r--include/hw/s390x/cpu-topology.h2
-rw-r--r--include/hw/s390x/event-facility.h17
-rw-r--r--include/hw/s390x/s390-pci-kvm.h7
-rw-r--r--include/hw/s390x/s390-virtio-ccw.h5
-rw-r--r--include/hw/scsi/esp.h15
-rw-r--r--include/hw/sd/sd.h24
-rw-r--r--include/hw/southbridge/ich9.h2
-rw-r--r--include/hw/ssi/ssi.h14
-rw-r--r--include/hw/sysbus.h1
-rw-r--r--include/hw/timer/aspeed_timer.h3
-rw-r--r--include/hw/vfio/vfio-amd-xgbe.h46
-rw-r--r--include/hw/vfio/vfio-calxeda-xgmac.h43
-rw-r--r--include/hw/vfio/vfio-container-base.h173
-rw-r--r--include/hw/vfio/vfio-container-legacy.h39
-rw-r--r--include/hw/vfio/vfio-container.h288
-rw-r--r--include/hw/vfio/vfio-cpr.h88
-rw-r--r--include/hw/vfio/vfio-device.h153
-rw-r--r--include/hw/vfio/vfio-platform.h78
-rw-r--r--include/hw/vfio/vfio-region.h47
-rw-r--r--include/hw/virtio/vhost-backend.h6
-rw-r--r--include/hw/virtio/vhost-scsi-common.h2
-rw-r--r--include/hw/virtio/vhost-user-base.h2
-rw-r--r--include/hw/virtio/vhost-user-blk.h2
-rw-r--r--include/hw/virtio/vhost-vdpa.h22
-rw-r--r--include/hw/virtio/vhost-vsock-common.h2
-rw-r--r--include/hw/virtio/vhost.h84
-rw-r--r--include/hw/virtio/virtio-features.h126
-rw-r--r--include/hw/virtio/virtio-gpu.h3
-rw-r--r--include/hw/virtio/virtio-mem.h2
-rw-r--r--include/hw/virtio/virtio-net.h8
-rw-r--r--include/hw/virtio/virtio-pci.h11
-rw-r--r--include/hw/virtio/virtio-pmem.h2
-rw-r--r--include/hw/virtio/virtio.h24
-rw-r--r--include/hw/xen/arch_hvm.h14
-rw-r--r--include/hw/xen/interface/io/blkif.h2
142 files changed, 4738 insertions, 1346 deletions
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index 68d9d15..8294f8f 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -13,6 +13,7 @@ typedef enum {
ACPI_NVDIMM_HOTPLUG_STATUS = 16,
ACPI_VMGENID_CHANGE_STATUS = 32,
ACPI_POWER_DOWN_STATUS = 64,
+ ACPI_GENERIC_ERROR = 128,
} AcpiEventStatusBits;
#define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index c18f681..f38e129 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -252,6 +252,7 @@ struct CrsRangeSet {
/* Consumer/Producer */
#define AML_SERIAL_BUS_FLAG_CONSUME_ONLY (1 << 1)
+#define ACPI_APEI_ERROR_DEVICE "GEDD"
/**
* init_aml_allocator:
*
@@ -382,6 +383,7 @@ Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
uint8_t channel);
Aml *aml_sleep(uint64_t msec);
Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source);
+Aml *aml_error_device(void);
/* Block AML object primitives */
Aml *aml_scope(const char *name_format, ...) G_GNUC_PRINTF(1, 2);
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index d2dac87..130c014 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -63,12 +63,13 @@
#include "hw/acpi/memory_hotplug.h"
#include "hw/acpi/ghes.h"
#include "hw/acpi/cpu.h"
+#include "hw/acpi/pcihp.h"
#include "qom/object.h"
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
#define TYPE_ACPI_GED "acpi-ged"
-OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
+OBJECT_DECLARE_TYPE(AcpiGedState, AcpiGedClass, ACPI_GED)
#define ACPI_GED_EVT_SEL_OFFSET 0x0
#define ACPI_GED_EVT_SEL_LEN 0x4
@@ -101,6 +102,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
#define ACPI_GED_PWR_DOWN_EVT 0x2
#define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
#define ACPI_GED_CPU_HOTPLUG_EVT 0x8
+#define ACPI_GED_PCI_HOTPLUG_EVT 0x10
+#define ACPI_GED_ERROR_EVT 0x20
typedef struct GEDState {
MemoryRegion evt;
@@ -108,18 +111,31 @@ typedef struct GEDState {
uint32_t sel;
} GEDState;
+#define ACPI_PCIHP_REGION_NAME "pcihp container"
+#define ACPI_MEMHP_REGION_NAME "memhp container"
+
struct AcpiGedState {
SysBusDevice parent_obj;
MemHotplugState memhp_state;
MemoryRegion container_memhp;
CPUHotplugState cpuhp_state;
MemoryRegion container_cpuhp;
+ AcpiPciHpState pcihp_state;
+ MemoryRegion container_pcihp;
GEDState ged_state;
uint32_t ged_event_bitmap;
qemu_irq irq;
AcpiGhesState ghes_state;
};
+typedef struct AcpiGedClass {
+ /* <private> */
+ SysBusDeviceClass parent_class;
+
+ /*< public >*/
+ ResettablePhases parent_phases;
+} AcpiGedClass;
+
void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base);
void acpi_dsdt_add_power_button(Aml *scope);
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
index 578a582..df2ecbf 100644
--- a/include/hw/acpi/ghes.h
+++ b/include/hw/acpi/ghes.h
@@ -24,6 +24,9 @@
#include "hw/acpi/bios-linker-loader.h"
#include "qapi/error.h"
+#include "qemu/notify.h"
+
+extern NotifierList acpi_generic_error_notifiers;
/*
* Values for Hardware Error Notification Type field
@@ -57,30 +60,54 @@ enum AcpiGhesNotifyType {
ACPI_GHES_NOTIFY_RESERVED = 12
};
-enum {
- ACPI_HEST_SRC_ID_SEA = 0,
- /* future ids go here */
-
- ACPI_GHES_ERROR_SOURCE_COUNT
+/*
+ * ID numbers used to fill HEST source ID field
+ */
+enum AcpiGhesSourceID {
+ ACPI_HEST_SRC_ID_SYNC,
+ ACPI_HEST_SRC_ID_QMP, /* Use it only for QMP injected errors */
};
+typedef struct AcpiNotificationSourceId {
+ enum AcpiGhesSourceID source_id;
+ enum AcpiGhesNotifyType notify;
+} AcpiNotificationSourceId;
+
+/*
+ * AcpiGhesState stores GPA values that will be used to fill HEST entries.
+ *
+ * When use_hest_addr is false, the GPA of the etc/hardware_errors firmware
+ * is stored at hw_error_le. This is the default on QEMU 9.x.
+ *
+ * When use_hest_addr is true, the GPA of the HEST table is stored at
+ * hest_addr_le. This is the default for QEMU 10.x and above.
+ *
+ * Whe both GPA values are equal to zero means that GHES is not present.
+ */
typedef struct AcpiGhesState {
+ uint64_t hest_addr_le;
uint64_t hw_error_le;
- bool present; /* True if GHES is present at all on this board */
+ bool use_hest_addr; /* True if HEST address is present */
} AcpiGhesState;
-void acpi_build_hest(GArray *table_data, GArray *hardware_errors,
+void acpi_build_hest(AcpiGhesState *ags, GArray *table_data,
+ GArray *hardware_errors,
BIOSLinker *linker,
+ const AcpiNotificationSourceId * const notif_source,
+ int num_sources,
const char *oem_id, const char *oem_table_id);
void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
GArray *hardware_errors);
-int acpi_ghes_memory_errors(uint16_t source_id, uint64_t error_physical_addr);
+int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
+ uint64_t error_physical_addr);
+void ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
+ uint16_t source_id, Error **errp);
/**
- * acpi_ghes_present: Report whether ACPI GHES table is present
+ * acpi_ghes_get_state: Get a pointer for ACPI ghes state
*
- * Returns: true if the system has an ACPI GHES table and it is
- * safe to call acpi_ghes_memory_errors() to record a memory error.
+ * Returns: a pointer to ghes state if the system has an ACPI GHES table,
+ * NULL, otherwise.
*/
-bool acpi_ghes_present(void);
+AcpiGhesState *acpi_ghes_get_state(void);
#endif
diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
index 6359d57..20b6725 100644
--- a/include/hw/acpi/pci.h
+++ b/include/hw/acpi/pci.h
@@ -36,11 +36,12 @@ typedef struct AcpiMcfgInfo {
void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
const char *oem_id, const char *oem_table_id);
-Aml *aml_pci_device_dsm(void);
-void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
void build_srat_generic_affinity_structures(GArray *table_data);
+Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug);
+Aml *build_pci_bridge_edsm(void);
+
#endif
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index ac21a95..ca6a258 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -3,7 +3,7 @@
*
* QEMU supports PCI hotplug via ACPI. This module
* implements the interface between QEMU and the ACPI BIOS.
- * Interface specification - see docs/specs/acpi_pci_hotplug.txt
+ * Interface specification - see docs/specs/acpi_pci_hotplug.rst
*
* Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
* Copyright (c) 2006 Fabrice Bellard
@@ -28,11 +28,18 @@
#define HW_ACPI_PCIHP_H
#include "hw/acpi/acpi.h"
+#include "hw/acpi/aml-build.h"
#include "hw/hotplug.h"
#define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
#define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len"
+/* PCI Hot-plug registers bases. See docs/specs/acpi_pci_hotplug.rst */
+#define ACPI_PCIHP_SEJ_BASE 0x8
+#define ACPI_PCIHP_BNMR_BASE 0x10
+
+#define ACPI_PCIHP_SIZE 0x0018
+
typedef struct AcpiPciHpPciStatus {
uint32_t up;
uint32_t down;
@@ -55,10 +62,10 @@ typedef struct AcpiPciHpState {
bool use_acpi_root_pci_hotplug;
} AcpiPciHpState;
-void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
+void acpi_pcihp_init(Object *owner, AcpiPciHpState *,
MemoryRegion *io, uint16_t io_base);
-bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus);
+bool acpi_pcihp_is_hotpluggable_bus(AcpiPciHpState *s, BusState *bus);
void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
@@ -69,6 +76,14 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
AcpiPciHpState *s, DeviceState *dev,
Error **errp);
+void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr);
+void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
+void build_append_pcihp_resources(Aml *table,
+ uint64_t io_addr, uint64_t io_len);
+bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
+
+void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
+
/* Called on reset */
void acpi_pcihp_reset(AcpiPciHpState *s);
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
index 9cae45a..6c36455 100644
--- a/include/hw/arm/aspeed.h
+++ b/include/hw/arm/aspeed.h
@@ -35,11 +35,14 @@ struct AspeedMachineClass {
uint32_t hw_strap2;
const char *fmc_model;
const char *spi_model;
+ const char *spi2_model;
uint32_t num_cs;
+ uint32_t num_cs2;
uint32_t macs_mask;
void (*i2c_init)(AspeedMachineState *bmc);
uint32_t uart_default;
bool sdhci_wp_inverted;
+ bool vbootrom;
};
diff --git a/include/hw/arm/aspeed_coprocessor.h b/include/hw/arm/aspeed_coprocessor.h
new file mode 100644
index 0000000..d77655d
--- /dev/null
+++ b/include/hw/arm/aspeed_coprocessor.h
@@ -0,0 +1,61 @@
+/*
+ * ASPEED Coprocessor
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_COPROCESSOR_H
+#define ASPEED_COPROCESSOR_H
+
+#include "qom/object.h"
+#include "hw/arm/aspeed_soc.h"
+
+struct AspeedCoprocessorState {
+ DeviceState parent;
+
+ MemoryRegion *memory;
+ MemoryRegion sram;
+ Clock *sysclk;
+
+ AspeedSCUState scu;
+ AspeedSCUState scuio;
+ AspeedTimerCtrlState timerctrl;
+ SerialMM uart[ASPEED_UARTS_NUM];
+};
+
+#define TYPE_ASPEED_COPROCESSOR "aspeed-coprocessor"
+OBJECT_DECLARE_TYPE(AspeedCoprocessorState, AspeedCoprocessorClass,
+ ASPEED_COPROCESSOR)
+
+struct AspeedCoprocessorClass {
+ DeviceClass parent_class;
+
+ /** valid_cpu_types: NULL terminated array of a single CPU type. */
+ const char * const *valid_cpu_types;
+ uint32_t silicon_rev;
+ const hwaddr *memmap;
+ const int *irqmap;
+ int uarts_base;
+ int uarts_num;
+};
+
+struct Aspeed27x0CoprocessorState {
+ AspeedCoprocessorState parent;
+ AspeedINTCState intc[2];
+ UnimplementedDeviceState ipc[2];
+ UnimplementedDeviceState scuio;
+
+ ARMv7MState armv7m;
+};
+
+#define TYPE_ASPEED27X0SSP_COPROCESSOR "aspeed27x0ssp-coprocessor"
+OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0CoprocessorState,
+ ASPEED27X0SSP_COPROCESSOR)
+
+#define TYPE_ASPEED27X0TSP_COPROCESSOR "aspeed27x0tsp-coprocessor"
+DECLARE_OBJ_CHECKERS(Aspeed27x0CoprocessorState, AspeedCoprocessorClass,
+ ASPEED27X0TSP_COPROCESSOR, TYPE_ASPEED27X0TSP_COPROCESSOR)
+
+#endif /* ASPEED_COPROCESSOR_H */
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index f069d17..4b8e599 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -37,18 +37,22 @@
#include "qom/object.h"
#include "hw/misc/aspeed_lpc.h"
#include "hw/misc/unimp.h"
+#include "hw/pci-host/aspeed_pcie.h"
#include "hw/misc/aspeed_peci.h"
#include "hw/fsi/aspeed_apb2opb.h"
#include "hw/char/serial-mm.h"
#include "hw/intc/arm_gicv3.h"
+#define VBOOTROM_FILE_NAME "ast27x0_bootrom.bin"
+
#define ASPEED_SPIS_NUM 3
-#define ASPEED_EHCIS_NUM 2
+#define ASPEED_EHCIS_NUM 4
#define ASPEED_WDTS_NUM 8
#define ASPEED_CPUS_NUM 4
#define ASPEED_MACS_NUM 4
#define ASPEED_UARTS_NUM 13
#define ASPEED_JTAG_NUM 2
+#define ASPEED_PCIE_NUM 3
struct AspeedSoCState {
DeviceState parent;
@@ -59,6 +63,8 @@ struct AspeedSoCState {
MemoryRegion sram;
MemoryRegion spi_boot_container;
MemoryRegion spi_boot;
+ MemoryRegion vbootrom;
+ MemoryRegion pcie_mmio_alias[ASPEED_PCIE_NUM];
AddressSpace dram_as;
AspeedRtcState rtc;
AspeedTimerCtrlState timerctrl;
@@ -86,10 +92,14 @@ struct AspeedSoCState {
AspeedSDHCIState sdhci;
AspeedSDHCIState emmc;
AspeedLPCState lpc;
+ AspeedPCIECfgState pcie[ASPEED_PCIE_NUM];
+ AspeedPCIEPhyState pcie_phy[ASPEED_PCIE_NUM];
AspeedPECIState peci;
SerialMM uart[ASPEED_UARTS_NUM];
Clock *sysclk;
UnimplementedDeviceState iomem;
+ UnimplementedDeviceState iomem0;
+ UnimplementedDeviceState iomem1;
UnimplementedDeviceState video;
UnimplementedDeviceState emmc_boot_controller;
UnimplementedDeviceState dpmcu;
@@ -97,6 +107,7 @@ struct AspeedSoCState {
UnimplementedDeviceState espi;
UnimplementedDeviceState udc;
UnimplementedDeviceState sgpiom;
+ UnimplementedDeviceState ltpi;
UnimplementedDeviceState jtag[ASPEED_JTAG_NUM];
AspeedAPB2OPBState fsi[2];
};
@@ -153,6 +164,7 @@ struct AspeedSoCClass {
uint32_t silicon_rev;
uint64_t sram_size;
uint64_t secsram_size;
+ int pcie_num;
int spis_num;
int ehcis_num;
int wdts_num;
@@ -162,15 +174,16 @@ struct AspeedSoCClass {
const int *irqmap;
const hwaddr *memmap;
uint32_t num_cpus;
- qemu_irq (*get_irq)(AspeedSoCState *s, int dev);
bool (*boot_from_emmc)(AspeedSoCState *s);
};
-const char *aspeed_soc_cpu_type(AspeedSoCClass *sc);
-
enum {
+ ASPEED_DEV_VBOOTROM,
ASPEED_DEV_SPI_BOOT,
ASPEED_DEV_IOMEM,
+ ASPEED_DEV_IOMEM0,
+ ASPEED_DEV_IOMEM1,
+ ASPEED_DEV_LTPI,
ASPEED_DEV_UART0,
ASPEED_DEV_UART1,
ASPEED_DEV_UART2,
@@ -192,6 +205,8 @@ enum {
ASPEED_DEV_SPI2,
ASPEED_DEV_EHCI1,
ASPEED_DEV_EHCI2,
+ ASPEED_DEV_EHCI3,
+ ASPEED_DEV_EHCI4,
ASPEED_DEV_VIC,
ASPEED_DEV_INTC,
ASPEED_DEV_INTCIO,
@@ -220,6 +235,15 @@ enum {
ASPEED_DEV_LPC,
ASPEED_DEV_IBT,
ASPEED_DEV_I2C,
+ ASPEED_DEV_PCIE0,
+ ASPEED_DEV_PCIE1,
+ ASPEED_DEV_PCIE2,
+ ASPEED_DEV_PCIE_PHY0,
+ ASPEED_DEV_PCIE_PHY1,
+ ASPEED_DEV_PCIE_PHY2,
+ ASPEED_DEV_PCIE_MMIO0,
+ ASPEED_DEV_PCIE_MMIO1,
+ ASPEED_DEV_PCIE_MMIO2,
ASPEED_DEV_PECI,
ASPEED_DEV_ETH1,
ASPEED_DEV_ETH2,
@@ -249,32 +273,43 @@ enum {
ASPEED_DEV_SLIIO,
ASPEED_GIC_DIST,
ASPEED_GIC_REDIST,
+ ASPEED_DEV_IPC0,
+ ASPEED_DEV_IPC1,
};
-qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
-bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp);
-void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr);
+const char *aspeed_soc_cpu_type(const char * const *valid_cpu_types);
+bool aspeed_soc_uart_realize(MemoryRegion *memory, SerialMM *smm,
+ const hwaddr addr, Error **errp);
+void aspeed_soc_uart_set_chr(SerialMM *uart, int dev, int uarts_base,
+ int uarts_num, Chardev *chr);
bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp);
-void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr);
-void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
+void aspeed_mmio_map(MemoryRegion *memory, SysBusDevice *dev, int n,
+ hwaddr addr);
+void aspeed_mmio_map_unimplemented(MemoryRegion *memory, SysBusDevice *dev,
const char *name, hwaddr addr,
uint64_t size);
void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
unsigned int count, int unit0);
+void aspeed_write_boot_rom(BlockBackend *blk, hwaddr addr, size_t rom_size,
+ Error **errp);
+void aspeed_install_boot_rom(AspeedSoCState *soc, BlockBackend *blk,
+ MemoryRegion *boot_rom, uint64_t rom_size);
+void aspeed_load_vbootrom(AspeedSoCState *soc, const char *bios_name,
+ Error **errp);
static inline int aspeed_uart_index(int uart_dev)
{
return uart_dev - ASPEED_DEV_UART0;
}
-static inline int aspeed_uart_first(AspeedSoCClass *sc)
+static inline int aspeed_uart_first(int uarts_base)
{
- return aspeed_uart_index(sc->uarts_base);
+ return aspeed_uart_index(uarts_base);
}
-static inline int aspeed_uart_last(AspeedSoCClass *sc)
+static inline int aspeed_uart_last(int uarts_base, int uarts_num)
{
- return aspeed_uart_first(sc) + sc->uarts_num - 1;
+ return aspeed_uart_first(uarts_base) + uarts_num - 1;
}
#endif /* ASPEED_SOC_H */
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index b12bf61..a2e22bd 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -132,6 +132,9 @@ struct arm_boot_info {
bool secure_board_setup;
arm_endianness endianness;
+
+ /* CPU having load the kernel and that should be the first to boot. */
+ ARMCPU *primary_cpu;
};
/**
diff --git a/include/hw/arm/max78000_soc.h b/include/hw/arm/max78000_soc.h
new file mode 100644
index 0000000..a203079
--- /dev/null
+++ b/include/hw/arm/max78000_soc.h
@@ -0,0 +1,50 @@
+/*
+ * MAX78000 SOC
+ *
+ * Copyright (c) 2025 Jackson Donaldson <jcksn@duck.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_ARM_MAX78000_SOC_H
+#define HW_ARM_MAX78000_SOC_H
+
+#include "hw/or-irq.h"
+#include "hw/arm/armv7m.h"
+#include "hw/misc/max78000_aes.h"
+#include "hw/misc/max78000_gcr.h"
+#include "hw/misc/max78000_icc.h"
+#include "hw/char/max78000_uart.h"
+#include "hw/misc/max78000_trng.h"
+#include "qom/object.h"
+
+#define TYPE_MAX78000_SOC "max78000-soc"
+OBJECT_DECLARE_SIMPLE_TYPE(MAX78000State, MAX78000_SOC)
+
+#define FLASH_BASE_ADDRESS 0x10000000
+#define FLASH_SIZE (512 * 1024)
+#define SRAM_BASE_ADDRESS 0x20000000
+#define SRAM_SIZE (128 * 1024)
+
+/* The MAX78k has 2 instruction caches; only icc0 matters, icc1 is for RISC */
+#define MAX78000_NUM_ICC 2
+#define MAX78000_NUM_UART 3
+
+struct MAX78000State {
+ SysBusDevice parent_obj;
+
+ ARMv7MState armv7m;
+
+ MemoryRegion sram;
+ MemoryRegion flash;
+
+ Max78000GcrState gcr;
+ Max78000IccState icc[MAX78000_NUM_ICC];
+ Max78000UartState uart[MAX78000_NUM_UART];
+ Max78000TrngState trng;
+ Max78000AesState aes;
+
+ Clock *sysclk;
+};
+
+#endif
diff --git a/include/hw/arm/npcm8xx.h b/include/hw/arm/npcm8xx.h
index 9812e6f..a8377db 100644
--- a/include/hw/arm/npcm8xx.h
+++ b/include/hw/arm/npcm8xx.h
@@ -28,7 +28,8 @@
#include "hw/misc/npcm7xx_mft.h"
#include "hw/misc/npcm7xx_pwm.h"
#include "hw/misc/npcm7xx_rng.h"
-#include "hw/net/npcm7xx_emc.h"
+#include "hw/net/npcm_gmac.h"
+#include "hw/net/npcm_pcs.h"
#include "hw/nvram/npcm7xx_otp.h"
#include "hw/sd/npcm7xx_sdhci.h"
#include "hw/timer/npcm7xx_timer.h"
@@ -36,6 +37,7 @@
#include "hw/usb/hcd-ehci.h"
#include "hw/usb/hcd-ohci.h"
#include "target/arm/cpu.h"
+#include "hw/ssi/npcm_pspi.h"
#define NPCM8XX_MAX_NUM_CPUS (4)
@@ -98,7 +100,10 @@ struct NPCM8xxState {
EHCISysBusState ehci[2];
OHCISysBusState ohci[2];
NPCM7xxFIUState fiu[3];
+ NPCMGMACState gmac[4];
+ NPCMPCSState pcs;
NPCM7xxSDHCIState mmc;
+ NPCMPSPIState pspi;
};
struct NPCM8xxClass {
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
index 6185507..bdb2e88 100644
--- a/include/hw/arm/omap.h
+++ b/include/hw/arm/omap.h
@@ -25,24 +25,24 @@
#include "qemu/log.h"
#include "qom/object.h"
-# define OMAP_EMIFS_BASE 0x00000000
-# define OMAP_CS0_BASE 0x00000000
-# define OMAP_CS1_BASE 0x04000000
-# define OMAP_CS2_BASE 0x08000000
-# define OMAP_CS3_BASE 0x0c000000
-# define OMAP_EMIFF_BASE 0x10000000
-# define OMAP_IMIF_BASE 0x20000000
-# define OMAP_LOCALBUS_BASE 0x30000000
-# define OMAP_MPUI_BASE 0xe1000000
-
-# define OMAP730_SRAM_SIZE 0x00032000
-# define OMAP15XX_SRAM_SIZE 0x00030000
-# define OMAP16XX_SRAM_SIZE 0x00004000
-# define OMAP1611_SRAM_SIZE 0x0003e800
-# define OMAP_CS0_SIZE 0x04000000
-# define OMAP_CS1_SIZE 0x04000000
-# define OMAP_CS2_SIZE 0x04000000
-# define OMAP_CS3_SIZE 0x04000000
+#define OMAP_EMIFS_BASE 0x00000000
+#define OMAP_CS0_BASE 0x00000000
+#define OMAP_CS1_BASE 0x04000000
+#define OMAP_CS2_BASE 0x08000000
+#define OMAP_CS3_BASE 0x0c000000
+#define OMAP_EMIFF_BASE 0x10000000
+#define OMAP_IMIF_BASE 0x20000000
+#define OMAP_LOCALBUS_BASE 0x30000000
+#define OMAP_MPUI_BASE 0xe1000000
+
+#define OMAP730_SRAM_SIZE 0x00032000
+#define OMAP15XX_SRAM_SIZE 0x00030000
+#define OMAP16XX_SRAM_SIZE 0x00004000
+#define OMAP1611_SRAM_SIZE 0x0003e800
+#define OMAP_CS0_SIZE 0x04000000
+#define OMAP_CS1_SIZE 0x04000000
+#define OMAP_CS2_SIZE 0x04000000
+#define OMAP_CS3_SIZE 0x04000000
/* omap_clk.c */
struct omap_mpu_state_s;
@@ -103,228 +103,228 @@ void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
* Common IRQ numbers for level 1 interrupt handler
* See /usr/include/asm-arm/arch-omap/irqs.h in Linux.
*/
-# define OMAP_INT_CAMERA 1
-# define OMAP_INT_FIQ 3
-# define OMAP_INT_RTDX 6
-# define OMAP_INT_DSP_MMU_ABORT 7
-# define OMAP_INT_HOST 8
-# define OMAP_INT_ABORT 9
-# define OMAP_INT_BRIDGE_PRIV 13
-# define OMAP_INT_GPIO_BANK1 14
-# define OMAP_INT_UART3 15
-# define OMAP_INT_TIMER3 16
-# define OMAP_INT_DMA_CH0_6 19
-# define OMAP_INT_DMA_CH1_7 20
-# define OMAP_INT_DMA_CH2_8 21
-# define OMAP_INT_DMA_CH3 22
-# define OMAP_INT_DMA_CH4 23
-# define OMAP_INT_DMA_CH5 24
-# define OMAP_INT_DMA_LCD 25
-# define OMAP_INT_TIMER1 26
-# define OMAP_INT_WD_TIMER 27
-# define OMAP_INT_BRIDGE_PUB 28
-# define OMAP_INT_TIMER2 30
-# define OMAP_INT_LCD_CTRL 31
+#define OMAP_INT_CAMERA 1
+#define OMAP_INT_FIQ 3
+#define OMAP_INT_RTDX 6
+#define OMAP_INT_DSP_MMU_ABORT 7
+#define OMAP_INT_HOST 8
+#define OMAP_INT_ABORT 9
+#define OMAP_INT_BRIDGE_PRIV 13
+#define OMAP_INT_GPIO_BANK1 14
+#define OMAP_INT_UART3 15
+#define OMAP_INT_TIMER3 16
+#define OMAP_INT_DMA_CH0_6 19
+#define OMAP_INT_DMA_CH1_7 20
+#define OMAP_INT_DMA_CH2_8 21
+#define OMAP_INT_DMA_CH3 22
+#define OMAP_INT_DMA_CH4 23
+#define OMAP_INT_DMA_CH5 24
+#define OMAP_INT_DMA_LCD 25
+#define OMAP_INT_TIMER1 26
+#define OMAP_INT_WD_TIMER 27
+#define OMAP_INT_BRIDGE_PUB 28
+#define OMAP_INT_TIMER2 30
+#define OMAP_INT_LCD_CTRL 31
/*
* Common OMAP-15xx IRQ numbers for level 1 interrupt handler
*/
-# define OMAP_INT_15XX_IH2_IRQ 0
-# define OMAP_INT_15XX_LB_MMU 17
-# define OMAP_INT_15XX_LOCAL_BUS 29
+#define OMAP_INT_15XX_IH2_IRQ 0
+#define OMAP_INT_15XX_LB_MMU 17
+#define OMAP_INT_15XX_LOCAL_BUS 29
/*
* OMAP-1510 specific IRQ numbers for level 1 interrupt handler
*/
-# define OMAP_INT_1510_SPI_TX 4
-# define OMAP_INT_1510_SPI_RX 5
-# define OMAP_INT_1510_DSP_MAILBOX1 10
-# define OMAP_INT_1510_DSP_MAILBOX2 11
+#define OMAP_INT_1510_SPI_TX 4
+#define OMAP_INT_1510_SPI_RX 5
+#define OMAP_INT_1510_DSP_MAILBOX1 10
+#define OMAP_INT_1510_DSP_MAILBOX2 11
/*
* OMAP-310 specific IRQ numbers for level 1 interrupt handler
*/
-# define OMAP_INT_310_McBSP2_TX 4
-# define OMAP_INT_310_McBSP2_RX 5
-# define OMAP_INT_310_HSB_MAILBOX1 12
-# define OMAP_INT_310_HSAB_MMU 18
+#define OMAP_INT_310_McBSP2_TX 4
+#define OMAP_INT_310_McBSP2_RX 5
+#define OMAP_INT_310_HSB_MAILBOX1 12
+#define OMAP_INT_310_HSAB_MMU 18
/*
* OMAP-1610 specific IRQ numbers for level 1 interrupt handler
*/
-# define OMAP_INT_1610_IH2_IRQ 0
-# define OMAP_INT_1610_IH2_FIQ 2
-# define OMAP_INT_1610_McBSP2_TX 4
-# define OMAP_INT_1610_McBSP2_RX 5
-# define OMAP_INT_1610_DSP_MAILBOX1 10
-# define OMAP_INT_1610_DSP_MAILBOX2 11
-# define OMAP_INT_1610_LCD_LINE 12
-# define OMAP_INT_1610_GPTIMER1 17
-# define OMAP_INT_1610_GPTIMER2 18
-# define OMAP_INT_1610_SSR_FIFO_0 29
+#define OMAP_INT_1610_IH2_IRQ 0
+#define OMAP_INT_1610_IH2_FIQ 2
+#define OMAP_INT_1610_McBSP2_TX 4
+#define OMAP_INT_1610_McBSP2_RX 5
+#define OMAP_INT_1610_DSP_MAILBOX1 10
+#define OMAP_INT_1610_DSP_MAILBOX2 11
+#define OMAP_INT_1610_LCD_LINE 12
+#define OMAP_INT_1610_GPTIMER1 17
+#define OMAP_INT_1610_GPTIMER2 18
+#define OMAP_INT_1610_SSR_FIFO_0 29
/*
* OMAP-730 specific IRQ numbers for level 1 interrupt handler
*/
-# define OMAP_INT_730_IH2_FIQ 0
-# define OMAP_INT_730_IH2_IRQ 1
-# define OMAP_INT_730_USB_NON_ISO 2
-# define OMAP_INT_730_USB_ISO 3
-# define OMAP_INT_730_ICR 4
-# define OMAP_INT_730_EAC 5
-# define OMAP_INT_730_GPIO_BANK1 6
-# define OMAP_INT_730_GPIO_BANK2 7
-# define OMAP_INT_730_GPIO_BANK3 8
-# define OMAP_INT_730_McBSP2TX 10
-# define OMAP_INT_730_McBSP2RX 11
-# define OMAP_INT_730_McBSP2RX_OVF 12
-# define OMAP_INT_730_LCD_LINE 14
-# define OMAP_INT_730_GSM_PROTECT 15
-# define OMAP_INT_730_TIMER3 16
-# define OMAP_INT_730_GPIO_BANK5 17
-# define OMAP_INT_730_GPIO_BANK6 18
-# define OMAP_INT_730_SPGIO_WR 29
+#define OMAP_INT_730_IH2_FIQ 0
+#define OMAP_INT_730_IH2_IRQ 1
+#define OMAP_INT_730_USB_NON_ISO 2
+#define OMAP_INT_730_USB_ISO 3
+#define OMAP_INT_730_ICR 4
+#define OMAP_INT_730_EAC 5
+#define OMAP_INT_730_GPIO_BANK1 6
+#define OMAP_INT_730_GPIO_BANK2 7
+#define OMAP_INT_730_GPIO_BANK3 8
+#define OMAP_INT_730_McBSP2TX 10
+#define OMAP_INT_730_McBSP2RX 11
+#define OMAP_INT_730_McBSP2RX_OVF 12
+#define OMAP_INT_730_LCD_LINE 14
+#define OMAP_INT_730_GSM_PROTECT 15
+#define OMAP_INT_730_TIMER3 16
+#define OMAP_INT_730_GPIO_BANK5 17
+#define OMAP_INT_730_GPIO_BANK6 18
+#define OMAP_INT_730_SPGIO_WR 29
/*
* Common IRQ numbers for level 2 interrupt handler
*/
-# define OMAP_INT_KEYBOARD 1
-# define OMAP_INT_uWireTX 2
-# define OMAP_INT_uWireRX 3
-# define OMAP_INT_I2C 4
-# define OMAP_INT_MPUIO 5
-# define OMAP_INT_USB_HHC_1 6
-# define OMAP_INT_McBSP3TX 10
-# define OMAP_INT_McBSP3RX 11
-# define OMAP_INT_McBSP1TX 12
-# define OMAP_INT_McBSP1RX 13
-# define OMAP_INT_UART1 14
-# define OMAP_INT_UART2 15
-# define OMAP_INT_USB_W2FC 20
-# define OMAP_INT_1WIRE 21
-# define OMAP_INT_OS_TIMER 22
-# define OMAP_INT_OQN 23
-# define OMAP_INT_GAUGE_32K 24
-# define OMAP_INT_RTC_TIMER 25
-# define OMAP_INT_RTC_ALARM 26
-# define OMAP_INT_DSP_MMU 28
+#define OMAP_INT_KEYBOARD 1
+#define OMAP_INT_uWireTX 2
+#define OMAP_INT_uWireRX 3
+#define OMAP_INT_I2C 4
+#define OMAP_INT_MPUIO 5
+#define OMAP_INT_USB_HHC_1 6
+#define OMAP_INT_McBSP3TX 10
+#define OMAP_INT_McBSP3RX 11
+#define OMAP_INT_McBSP1TX 12
+#define OMAP_INT_McBSP1RX 13
+#define OMAP_INT_UART1 14
+#define OMAP_INT_UART2 15
+#define OMAP_INT_USB_W2FC 20
+#define OMAP_INT_1WIRE 21
+#define OMAP_INT_OS_TIMER 22
+#define OMAP_INT_OQN 23
+#define OMAP_INT_GAUGE_32K 24
+#define OMAP_INT_RTC_TIMER 25
+#define OMAP_INT_RTC_ALARM 26
+#define OMAP_INT_DSP_MMU 28
/*
* OMAP-1510 specific IRQ numbers for level 2 interrupt handler
*/
-# define OMAP_INT_1510_BT_MCSI1TX 16
-# define OMAP_INT_1510_BT_MCSI1RX 17
-# define OMAP_INT_1510_SoSSI_MATCH 19
-# define OMAP_INT_1510_MEM_STICK 27
-# define OMAP_INT_1510_COM_SPI_RO 31
+#define OMAP_INT_1510_BT_MCSI1TX 16
+#define OMAP_INT_1510_BT_MCSI1RX 17
+#define OMAP_INT_1510_SoSSI_MATCH 19
+#define OMAP_INT_1510_MEM_STICK 27
+#define OMAP_INT_1510_COM_SPI_RO 31
/*
* OMAP-310 specific IRQ numbers for level 2 interrupt handler
*/
-# define OMAP_INT_310_FAC 0
-# define OMAP_INT_310_USB_HHC_2 7
-# define OMAP_INT_310_MCSI1_FE 16
-# define OMAP_INT_310_MCSI2_FE 17
-# define OMAP_INT_310_USB_W2FC_ISO 29
-# define OMAP_INT_310_USB_W2FC_NON_ISO 30
-# define OMAP_INT_310_McBSP2RX_OF 31
+#define OMAP_INT_310_FAC 0
+#define OMAP_INT_310_USB_HHC_2 7
+#define OMAP_INT_310_MCSI1_FE 16
+#define OMAP_INT_310_MCSI2_FE 17
+#define OMAP_INT_310_USB_W2FC_ISO 29
+#define OMAP_INT_310_USB_W2FC_NON_ISO 30
+#define OMAP_INT_310_McBSP2RX_OF 31
/*
* OMAP-1610 specific IRQ numbers for level 2 interrupt handler
*/
-# define OMAP_INT_1610_FAC 0
-# define OMAP_INT_1610_USB_HHC_2 7
-# define OMAP_INT_1610_USB_OTG 8
-# define OMAP_INT_1610_SoSSI 9
-# define OMAP_INT_1610_BT_MCSI1TX 16
-# define OMAP_INT_1610_BT_MCSI1RX 17
-# define OMAP_INT_1610_SoSSI_MATCH 19
-# define OMAP_INT_1610_MEM_STICK 27
-# define OMAP_INT_1610_McBSP2RX_OF 31
-# define OMAP_INT_1610_STI 32
-# define OMAP_INT_1610_STI_WAKEUP 33
-# define OMAP_INT_1610_GPTIMER3 34
-# define OMAP_INT_1610_GPTIMER4 35
-# define OMAP_INT_1610_GPTIMER5 36
-# define OMAP_INT_1610_GPTIMER6 37
-# define OMAP_INT_1610_GPTIMER7 38
-# define OMAP_INT_1610_GPTIMER8 39
-# define OMAP_INT_1610_GPIO_BANK2 40
-# define OMAP_INT_1610_GPIO_BANK3 41
-# define OMAP_INT_1610_MMC2 42
-# define OMAP_INT_1610_CF 43
-# define OMAP_INT_1610_WAKE_UP_REQ 46
-# define OMAP_INT_1610_GPIO_BANK4 48
-# define OMAP_INT_1610_SPI 49
-# define OMAP_INT_1610_DMA_CH6 53
-# define OMAP_INT_1610_DMA_CH7 54
-# define OMAP_INT_1610_DMA_CH8 55
-# define OMAP_INT_1610_DMA_CH9 56
-# define OMAP_INT_1610_DMA_CH10 57
-# define OMAP_INT_1610_DMA_CH11 58
-# define OMAP_INT_1610_DMA_CH12 59
-# define OMAP_INT_1610_DMA_CH13 60
-# define OMAP_INT_1610_DMA_CH14 61
-# define OMAP_INT_1610_DMA_CH15 62
-# define OMAP_INT_1610_NAND 63
+#define OMAP_INT_1610_FAC 0
+#define OMAP_INT_1610_USB_HHC_2 7
+#define OMAP_INT_1610_USB_OTG 8
+#define OMAP_INT_1610_SoSSI 9
+#define OMAP_INT_1610_BT_MCSI1TX 16
+#define OMAP_INT_1610_BT_MCSI1RX 17
+#define OMAP_INT_1610_SoSSI_MATCH 19
+#define OMAP_INT_1610_MEM_STICK 27
+#define OMAP_INT_1610_McBSP2RX_OF 31
+#define OMAP_INT_1610_STI 32
+#define OMAP_INT_1610_STI_WAKEUP 33
+#define OMAP_INT_1610_GPTIMER3 34
+#define OMAP_INT_1610_GPTIMER4 35
+#define OMAP_INT_1610_GPTIMER5 36
+#define OMAP_INT_1610_GPTIMER6 37
+#define OMAP_INT_1610_GPTIMER7 38
+#define OMAP_INT_1610_GPTIMER8 39
+#define OMAP_INT_1610_GPIO_BANK2 40
+#define OMAP_INT_1610_GPIO_BANK3 41
+#define OMAP_INT_1610_MMC2 42
+#define OMAP_INT_1610_CF 43
+#define OMAP_INT_1610_WAKE_UP_REQ 46
+#define OMAP_INT_1610_GPIO_BANK4 48
+#define OMAP_INT_1610_SPI 49
+#define OMAP_INT_1610_DMA_CH6 53
+#define OMAP_INT_1610_DMA_CH7 54
+#define OMAP_INT_1610_DMA_CH8 55
+#define OMAP_INT_1610_DMA_CH9 56
+#define OMAP_INT_1610_DMA_CH10 57
+#define OMAP_INT_1610_DMA_CH11 58
+#define OMAP_INT_1610_DMA_CH12 59
+#define OMAP_INT_1610_DMA_CH13 60
+#define OMAP_INT_1610_DMA_CH14 61
+#define OMAP_INT_1610_DMA_CH15 62
+#define OMAP_INT_1610_NAND 63
/*
* OMAP-730 specific IRQ numbers for level 2 interrupt handler
*/
-# define OMAP_INT_730_HW_ERRORS 0
-# define OMAP_INT_730_NFIQ_PWR_FAIL 1
-# define OMAP_INT_730_CFCD 2
-# define OMAP_INT_730_CFIREQ 3
-# define OMAP_INT_730_I2C 4
-# define OMAP_INT_730_PCC 5
-# define OMAP_INT_730_MPU_EXT_NIRQ 6
-# define OMAP_INT_730_SPI_100K_1 7
-# define OMAP_INT_730_SYREN_SPI 8
-# define OMAP_INT_730_VLYNQ 9
-# define OMAP_INT_730_GPIO_BANK4 10
-# define OMAP_INT_730_McBSP1TX 11
-# define OMAP_INT_730_McBSP1RX 12
-# define OMAP_INT_730_McBSP1RX_OF 13
-# define OMAP_INT_730_UART_MODEM_IRDA_2 14
-# define OMAP_INT_730_UART_MODEM_1 15
-# define OMAP_INT_730_MCSI 16
-# define OMAP_INT_730_uWireTX 17
-# define OMAP_INT_730_uWireRX 18
-# define OMAP_INT_730_SMC_CD 19
-# define OMAP_INT_730_SMC_IREQ 20
-# define OMAP_INT_730_HDQ_1WIRE 21
-# define OMAP_INT_730_TIMER32K 22
-# define OMAP_INT_730_MMC_SDIO 23
-# define OMAP_INT_730_UPLD 24
-# define OMAP_INT_730_USB_HHC_1 27
-# define OMAP_INT_730_USB_HHC_2 28
-# define OMAP_INT_730_USB_GENI 29
-# define OMAP_INT_730_USB_OTG 30
-# define OMAP_INT_730_CAMERA_IF 31
-# define OMAP_INT_730_RNG 32
-# define OMAP_INT_730_DUAL_MODE_TIMER 33
-# define OMAP_INT_730_DBB_RF_EN 34
-# define OMAP_INT_730_MPUIO_KEYPAD 35
-# define OMAP_INT_730_SHA1_MD5 36
-# define OMAP_INT_730_SPI_100K_2 37
-# define OMAP_INT_730_RNG_IDLE 38
-# define OMAP_INT_730_MPUIO 39
-# define OMAP_INT_730_LLPC_LCD_CTRL_OFF 40
-# define OMAP_INT_730_LLPC_OE_FALLING 41
-# define OMAP_INT_730_LLPC_OE_RISING 42
-# define OMAP_INT_730_LLPC_VSYNC 43
-# define OMAP_INT_730_WAKE_UP_REQ 46
-# define OMAP_INT_730_DMA_CH6 53
-# define OMAP_INT_730_DMA_CH7 54
-# define OMAP_INT_730_DMA_CH8 55
-# define OMAP_INT_730_DMA_CH9 56
-# define OMAP_INT_730_DMA_CH10 57
-# define OMAP_INT_730_DMA_CH11 58
-# define OMAP_INT_730_DMA_CH12 59
-# define OMAP_INT_730_DMA_CH13 60
-# define OMAP_INT_730_DMA_CH14 61
-# define OMAP_INT_730_DMA_CH15 62
-# define OMAP_INT_730_NAND 63
+#define OMAP_INT_730_HW_ERRORS 0
+#define OMAP_INT_730_NFIQ_PWR_FAIL 1
+#define OMAP_INT_730_CFCD 2
+#define OMAP_INT_730_CFIREQ 3
+#define OMAP_INT_730_I2C 4
+#define OMAP_INT_730_PCC 5
+#define OMAP_INT_730_MPU_EXT_NIRQ 6
+#define OMAP_INT_730_SPI_100K_1 7
+#define OMAP_INT_730_SYREN_SPI 8
+#define OMAP_INT_730_VLYNQ 9
+#define OMAP_INT_730_GPIO_BANK4 10
+#define OMAP_INT_730_McBSP1TX 11
+#define OMAP_INT_730_McBSP1RX 12
+#define OMAP_INT_730_McBSP1RX_OF 13
+#define OMAP_INT_730_UART_MODEM_IRDA_2 14
+#define OMAP_INT_730_UART_MODEM_1 15
+#define OMAP_INT_730_MCSI 16
+#define OMAP_INT_730_uWireTX 17
+#define OMAP_INT_730_uWireRX 18
+#define OMAP_INT_730_SMC_CD 19
+#define OMAP_INT_730_SMC_IREQ 20
+#define OMAP_INT_730_HDQ_1WIRE 21
+#define OMAP_INT_730_TIMER32K 22
+#define OMAP_INT_730_MMC_SDIO 23
+#define OMAP_INT_730_UPLD 24
+#define OMAP_INT_730_USB_HHC_1 27
+#define OMAP_INT_730_USB_HHC_2 28
+#define OMAP_INT_730_USB_GENI 29
+#define OMAP_INT_730_USB_OTG 30
+#define OMAP_INT_730_CAMERA_IF 31
+#define OMAP_INT_730_RNG 32
+#define OMAP_INT_730_DUAL_MODE_TIMER 33
+#define OMAP_INT_730_DBB_RF_EN 34
+#define OMAP_INT_730_MPUIO_KEYPAD 35
+#define OMAP_INT_730_SHA1_MD5 36
+#define OMAP_INT_730_SPI_100K_2 37
+#define OMAP_INT_730_RNG_IDLE 38
+#define OMAP_INT_730_MPUIO 39
+#define OMAP_INT_730_LLPC_LCD_CTRL_OFF 40
+#define OMAP_INT_730_LLPC_OE_FALLING 41
+#define OMAP_INT_730_LLPC_OE_RISING 42
+#define OMAP_INT_730_LLPC_VSYNC 43
+#define OMAP_INT_730_WAKE_UP_REQ 46
+#define OMAP_INT_730_DMA_CH6 53
+#define OMAP_INT_730_DMA_CH7 54
+#define OMAP_INT_730_DMA_CH8 55
+#define OMAP_INT_730_DMA_CH9 56
+#define OMAP_INT_730_DMA_CH10 57
+#define OMAP_INT_730_DMA_CH11 58
+#define OMAP_INT_730_DMA_CH12 59
+#define OMAP_INT_730_DMA_CH13 60
+#define OMAP_INT_730_DMA_CH14 61
+#define OMAP_INT_730_DMA_CH15 62
+#define OMAP_INT_730_NAND 63
/* omap_dma.c */
enum omap_dma_model {
@@ -353,9 +353,9 @@ struct dma_irq_map {
enum omap_dma_port {
emiff = 0,
emifs,
- imif, /* omap16xx: ocp_t1 */
+ imif, /* omap16xx: ocp_t1 */
tipb,
- local, /* omap16xx: ocp_t2 */
+ local, /* omap16xx: ocp_t2 */
tipb_mpui,
__omap_dma_port_last,
};
@@ -418,65 +418,65 @@ struct omap_dma_lcd_channel_s {
* DMA request numbers for OMAP1
* See /usr/include/asm-arm/arch-omap/dma.h in Linux.
*/
-# define OMAP_DMA_NO_DEVICE 0
-# define OMAP_DMA_MCSI1_TX 1
-# define OMAP_DMA_MCSI1_RX 2
-# define OMAP_DMA_I2C_RX 3
-# define OMAP_DMA_I2C_TX 4
-# define OMAP_DMA_EXT_NDMA_REQ0 5
-# define OMAP_DMA_EXT_NDMA_REQ1 6
-# define OMAP_DMA_UWIRE_TX 7
-# define OMAP_DMA_MCBSP1_TX 8
-# define OMAP_DMA_MCBSP1_RX 9
-# define OMAP_DMA_MCBSP3_TX 10
-# define OMAP_DMA_MCBSP3_RX 11
-# define OMAP_DMA_UART1_TX 12
-# define OMAP_DMA_UART1_RX 13
-# define OMAP_DMA_UART2_TX 14
-# define OMAP_DMA_UART2_RX 15
-# define OMAP_DMA_MCBSP2_TX 16
-# define OMAP_DMA_MCBSP2_RX 17
-# define OMAP_DMA_UART3_TX 18
-# define OMAP_DMA_UART3_RX 19
-# define OMAP_DMA_CAMERA_IF_RX 20
-# define OMAP_DMA_MMC_TX 21
-# define OMAP_DMA_MMC_RX 22
-# define OMAP_DMA_NAND 23 /* Not in OMAP310 */
-# define OMAP_DMA_IRQ_LCD_LINE 24 /* Not in OMAP310 */
-# define OMAP_DMA_MEMORY_STICK 25 /* Not in OMAP310 */
-# define OMAP_DMA_USB_W2FC_RX0 26
-# define OMAP_DMA_USB_W2FC_RX1 27
-# define OMAP_DMA_USB_W2FC_RX2 28
-# define OMAP_DMA_USB_W2FC_TX0 29
-# define OMAP_DMA_USB_W2FC_TX1 30
-# define OMAP_DMA_USB_W2FC_TX2 31
+#define OMAP_DMA_NO_DEVICE 0
+#define OMAP_DMA_MCSI1_TX 1
+#define OMAP_DMA_MCSI1_RX 2
+#define OMAP_DMA_I2C_RX 3
+#define OMAP_DMA_I2C_TX 4
+#define OMAP_DMA_EXT_NDMA_REQ0 5
+#define OMAP_DMA_EXT_NDMA_REQ1 6
+#define OMAP_DMA_UWIRE_TX 7
+#define OMAP_DMA_MCBSP1_TX 8
+#define OMAP_DMA_MCBSP1_RX 9
+#define OMAP_DMA_MCBSP3_TX 10
+#define OMAP_DMA_MCBSP3_RX 11
+#define OMAP_DMA_UART1_TX 12
+#define OMAP_DMA_UART1_RX 13
+#define OMAP_DMA_UART2_TX 14
+#define OMAP_DMA_UART2_RX 15
+#define OMAP_DMA_MCBSP2_TX 16
+#define OMAP_DMA_MCBSP2_RX 17
+#define OMAP_DMA_UART3_TX 18
+#define OMAP_DMA_UART3_RX 19
+#define OMAP_DMA_CAMERA_IF_RX 20
+#define OMAP_DMA_MMC_TX 21
+#define OMAP_DMA_MMC_RX 22
+#define OMAP_DMA_NAND 23 /* Not in OMAP310 */
+#define OMAP_DMA_IRQ_LCD_LINE 24 /* Not in OMAP310 */
+#define OMAP_DMA_MEMORY_STICK 25 /* Not in OMAP310 */
+#define OMAP_DMA_USB_W2FC_RX0 26
+#define OMAP_DMA_USB_W2FC_RX1 27
+#define OMAP_DMA_USB_W2FC_RX2 28
+#define OMAP_DMA_USB_W2FC_TX0 29
+#define OMAP_DMA_USB_W2FC_TX1 30
+#define OMAP_DMA_USB_W2FC_TX2 31
/* These are only for 1610 */
-# define OMAP_DMA_CRYPTO_DES_IN 32
-# define OMAP_DMA_SPI_TX 33
-# define OMAP_DMA_SPI_RX 34
-# define OMAP_DMA_CRYPTO_HASH 35
-# define OMAP_DMA_CCP_ATTN 36
-# define OMAP_DMA_CCP_FIFO_NOT_EMPTY 37
-# define OMAP_DMA_CMT_APE_TX_CHAN_0 38
-# define OMAP_DMA_CMT_APE_RV_CHAN_0 39
-# define OMAP_DMA_CMT_APE_TX_CHAN_1 40
-# define OMAP_DMA_CMT_APE_RV_CHAN_1 41
-# define OMAP_DMA_CMT_APE_TX_CHAN_2 42
-# define OMAP_DMA_CMT_APE_RV_CHAN_2 43
-# define OMAP_DMA_CMT_APE_TX_CHAN_3 44
-# define OMAP_DMA_CMT_APE_RV_CHAN_3 45
-# define OMAP_DMA_CMT_APE_TX_CHAN_4 46
-# define OMAP_DMA_CMT_APE_RV_CHAN_4 47
-# define OMAP_DMA_CMT_APE_TX_CHAN_5 48
-# define OMAP_DMA_CMT_APE_RV_CHAN_5 49
-# define OMAP_DMA_CMT_APE_TX_CHAN_6 50
-# define OMAP_DMA_CMT_APE_RV_CHAN_6 51
-# define OMAP_DMA_CMT_APE_TX_CHAN_7 52
-# define OMAP_DMA_CMT_APE_RV_CHAN_7 53
-# define OMAP_DMA_MMC2_TX 54
-# define OMAP_DMA_MMC2_RX 55
-# define OMAP_DMA_CRYPTO_DES_OUT 56
+#define OMAP_DMA_CRYPTO_DES_IN 32
+#define OMAP_DMA_SPI_TX 33
+#define OMAP_DMA_SPI_RX 34
+#define OMAP_DMA_CRYPTO_HASH 35
+#define OMAP_DMA_CCP_ATTN 36
+#define OMAP_DMA_CCP_FIFO_NOT_EMPTY 37
+#define OMAP_DMA_CMT_APE_TX_CHAN_0 38
+#define OMAP_DMA_CMT_APE_RV_CHAN_0 39
+#define OMAP_DMA_CMT_APE_TX_CHAN_1 40
+#define OMAP_DMA_CMT_APE_RV_CHAN_1 41
+#define OMAP_DMA_CMT_APE_TX_CHAN_2 42
+#define OMAP_DMA_CMT_APE_RV_CHAN_2 43
+#define OMAP_DMA_CMT_APE_TX_CHAN_3 44
+#define OMAP_DMA_CMT_APE_RV_CHAN_3 45
+#define OMAP_DMA_CMT_APE_TX_CHAN_4 46
+#define OMAP_DMA_CMT_APE_RV_CHAN_4 47
+#define OMAP_DMA_CMT_APE_TX_CHAN_5 48
+#define OMAP_DMA_CMT_APE_RV_CHAN_5 49
+#define OMAP_DMA_CMT_APE_TX_CHAN_6 50
+#define OMAP_DMA_CMT_APE_RV_CHAN_6 51
+#define OMAP_DMA_CMT_APE_TX_CHAN_7 52
+#define OMAP_DMA_CMT_APE_RV_CHAN_7 53
+#define OMAP_DMA_MMC2_TX 54
+#define OMAP_DMA_MMC2_RX 55
+#define OMAP_DMA_CRYPTO_DES_OUT 56
struct omap_uart_s;
struct omap_uart_s *omap_uart_init(hwaddr base,
@@ -542,14 +542,14 @@ void omap_mmc_set_clk(DeviceState *dev, omap_clk clk);
/* omap_i2c.c */
I2CBus *omap_i2c_bus(DeviceState *omap_i2c);
-# define cpu_is_omap310(cpu) (cpu->mpu_model == omap310)
-# define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510)
-# define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610)
-# define cpu_is_omap1710(cpu) (cpu->mpu_model == omap1710)
+#define cpu_is_omap310(cpu) (cpu->mpu_model == omap310)
+#define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510)
+#define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610)
+#define cpu_is_omap1710(cpu) (cpu->mpu_model == omap1710)
-# define cpu_is_omap15xx(cpu) \
+#define cpu_is_omap15xx(cpu) \
(cpu_is_omap310(cpu) || cpu_is_omap1510(cpu))
-# define cpu_is_omap16xx(cpu) \
+#define cpu_is_omap16xx(cpu) \
(cpu_is_omap1610(cpu) || cpu_is_omap1710(cpu))
struct omap_mpu_state_s {
@@ -685,14 +685,14 @@ void omap_badwidth_write32(void *opaque, hwaddr addr,
void omap_mpu_wakeup(void *opaque, int irq, int req);
-# define OMAP_BAD_REG(paddr) \
+#define OMAP_BAD_REG(paddr) \
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad register %#08"HWADDR_PRIx"\n", \
__func__, paddr)
-# define OMAP_RO_REG(paddr) \
+#define OMAP_RO_REG(paddr) \
qemu_log_mask(LOG_GUEST_ERROR, "%s: Read-only register %#08" \
HWADDR_PRIx "\n", \
__func__, paddr)
-# define OMAP_MPUI_REG_MASK 0x000007ff
+#define OMAP_MPUI_REG_MASK 0x000007ff
#endif
diff --git a/include/hw/arm/sharpsl.h b/include/hw/arm/sharpsl.h
deleted file mode 100644
index e986b28..0000000
--- a/include/hw/arm/sharpsl.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Common declarations for the Zaurii.
- *
- * This file is licensed under the GNU GPL.
- */
-
-#ifndef QEMU_SHARPSL_H
-#define QEMU_SHARPSL_H
-
-#include "exec/hwaddr.h"
-
-/* zaurus.c */
-
-#define SL_PXA_PARAM_BASE 0xa0000a00
-void sl_bootparam_write(hwaddr ptr);
-
-#endif
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
index e5e2d09..80d0fec 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -161,6 +161,7 @@ struct SMMUState {
QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
uint8_t bus_num;
PCIBus *primary_bus;
+ bool smmu_per_bus; /* SMMU is specific to the primary_bus */
};
struct SMMUBaseClass {
diff --git a/include/hw/arm/soc_dma.h b/include/hw/arm/soc_dma.h
index e93a749..bcdb914 100644
--- a/include/hw/arm/soc_dma.h
+++ b/include/hw/arm/soc_dma.h
@@ -54,7 +54,7 @@ struct soc_dma_ch_s {
int bytes;
/* Initialised by the DMA module, call soc_dma_ch_update after writing. */
enum soc_dma_access_type type[2];
- hwaddr vaddr[2]; /* Updated by .transfer_fn(). */
+ hwaddr vaddr[2]; /* Updated by .transfer_fn(). */
/* Private */
void *paddr[2];
soc_dma_io_t io_fn[2];
@@ -70,7 +70,7 @@ struct soc_dma_ch_s {
struct soc_dma_s {
/* Following fields are set by the SoC DMA module and can be used
* by anybody. */
- uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */
+ uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */
qemu_irq *drq;
void *opaque;
int64_t freq;
diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
index 4f4c8bb..46eda34 100644
--- a/include/hw/arm/stm32f205_soc.h
+++ b/include/hw/arm/stm32f205_soc.h
@@ -59,7 +59,7 @@ struct STM32F205State {
STM32F2XXADCState adc[STM_NUM_ADCS];
STM32F2XXSPIState spi[STM_NUM_SPIS];
- OrIRQState *adc_irqs;
+ OrIRQState adc_irqs;
MemoryRegion sram;
MemoryRegion flash;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index c8e94e6..04a09af 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -33,9 +33,11 @@
#include "exec/hwaddr.h"
#include "qemu/notify.h"
#include "hw/boards.h"
+#include "hw/acpi/ghes.h"
#include "hw/arm/boot.h"
#include "hw/arm/bsa.h"
#include "hw/block/flash.h"
+#include "hw/cxl/cxl.h"
#include "system/kvm.h"
#include "hw/intc/arm_gicv3_common.h"
#include "qom/object.h"
@@ -79,12 +81,14 @@ enum {
VIRT_ACPI_GED,
VIRT_NVDIMM_ACPI,
VIRT_PVTIME,
+ VIRT_ACPI_PCIHP,
VIRT_LOWMEMMAP_LAST,
};
/* indices of IO regions located after the RAM */
enum {
VIRT_HIGH_GIC_REDIST2 = VIRT_LOWMEMMAP_LAST,
+ VIRT_CXL_HOST,
VIRT_HIGH_PCIE_ECAM,
VIRT_HIGH_PCIE_MMIO,
};
@@ -117,14 +121,8 @@ typedef enum VirtGICType {
struct VirtMachineClass {
MachineClass parent;
- bool disallow_affinity_adjustment;
- bool no_its;
bool no_tcg_its;
- bool no_pmu;
- bool claim_edge_triggered_timers;
- bool smbios_old_sys_ver;
bool no_highmem_compact;
- bool no_highmem_ecam;
bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */
bool kvm_no_adjvtime;
bool no_kvm_steal_time;
@@ -146,6 +144,7 @@ struct VirtMachineState {
bool secure;
bool highmem;
bool highmem_compact;
+ bool highmem_cxl;
bool highmem_ecam;
bool highmem_mmio;
bool highmem_redists;
@@ -176,10 +175,13 @@ struct VirtMachineState {
DeviceState *gic;
DeviceState *acpi_dev;
Notifier powerdown_notifier;
+ Notifier generic_error_notifier;
PCIBus *bus;
char *oem_id;
char *oem_table_id;
bool ns_el2_virt_timer_irq;
+ CXLState cxl_devices_state;
+ bool legacy_smmuv3_present;
};
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
diff --git a/include/hw/arm/xen_arch_hvm.h b/include/hw/arm/xen_arch_hvm.h
deleted file mode 100644
index 8fd645e..0000000
--- a/include/hw/arm/xen_arch_hvm.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef HW_XEN_ARCH_ARM_HVM_H
-#define HW_XEN_ARCH_ARM_HVM_H
-
-#include <xen/hvm/ioreq.h>
-void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
-void arch_xen_set_memory(XenIOState *state,
- MemoryRegionSection *section,
- bool add);
-#endif
diff --git a/include/hw/arm/xlnx-versal-version.h b/include/hw/arm/xlnx-versal-version.h
new file mode 100644
index 0000000..5b6b6e5
--- /dev/null
+++ b/include/hw/arm/xlnx-versal-version.h
@@ -0,0 +1,16 @@
+/*
+ * AMD Versal versions
+ *
+ * Copyright (c) 2025 Advanced Micro Devices, Inc.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_ARM_XLNX_VERSAL_VERSION_H
+#define HW_ARM_XLNX_VERSAL_VERSION_H
+
+typedef enum VersalVersion {
+ VERSAL_VER_VERSAL,
+ VERSAL_VER_VERSAL2,
+} VersalVersion;
+
+#endif
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 05ed641..e1fb1f4 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -1,7 +1,8 @@
/*
- * Model of the Xilinx Versal
+ * AMD/Xilinx Versal family SoC model.
*
* Copyright (c) 2018 Xilinx Inc.
+ * Copyright (c) 2025 Advanced Micro Devices, Inc.
* Written by Edgar E. Iglesias
*
* This program is free software; you can redistribute it and/or modify
@@ -13,326 +14,77 @@
#define XLNX_VERSAL_H
#include "hw/sysbus.h"
-#include "hw/cpu/cluster.h"
-#include "hw/or-irq.h"
-#include "hw/sd/sdhci.h"
-#include "hw/intc/arm_gicv3.h"
-#include "hw/char/pl011.h"
-#include "hw/dma/xlnx-zdma.h"
-#include "hw/net/cadence_gem.h"
-#include "hw/rtc/xlnx-zynqmp-rtc.h"
#include "qom/object.h"
-#include "hw/usb/xlnx-usb-subsystem.h"
-#include "hw/misc/xlnx-versal-xramc.h"
-#include "hw/nvram/xlnx-bbram.h"
-#include "hw/nvram/xlnx-versal-efuse.h"
-#include "hw/ssi/xlnx-versal-ospi.h"
-#include "hw/dma/xlnx_csu_dma.h"
-#include "hw/misc/xlnx-versal-crl.h"
-#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
-#include "hw/misc/xlnx-versal-trng.h"
-#include "hw/net/xlnx-versal-canfd.h"
-#include "hw/misc/xlnx-versal-cfu.h"
-#include "hw/misc/xlnx-versal-cframe-reg.h"
-#include "target/arm/cpu.h"
+#include "net/can_emu.h"
+#include "hw/arm/xlnx-versal-version.h"
-#define TYPE_XLNX_VERSAL "xlnx-versal"
-OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
+#define TYPE_XLNX_VERSAL_BASE "xlnx-versal-base"
+OBJECT_DECLARE_TYPE(Versal, VersalClass, XLNX_VERSAL_BASE)
-#define XLNX_VERSAL_NR_ACPUS 2
-#define XLNX_VERSAL_NR_RCPUS 2
-#define XLNX_VERSAL_NR_UARTS 2
-#define XLNX_VERSAL_NR_GEMS 2
-#define XLNX_VERSAL_NR_ADMAS 8
-#define XLNX_VERSAL_NR_SDS 2
-#define XLNX_VERSAL_NR_XRAM 4
-#define XLNX_VERSAL_NR_IRQS 192
-#define XLNX_VERSAL_NR_CANFD 2
-#define XLNX_VERSAL_CANFD_REF_CLK (24 * 1000 * 1000)
-#define XLNX_VERSAL_NR_CFRAME 15
+#define TYPE_XLNX_VERSAL "xlnx-versal"
+#define TYPE_XLNX_VERSAL2 "xlnx-versal2"
struct Versal {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
- struct {
- struct {
- MemoryRegion mr;
- CPUClusterState cluster;
- ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
- GICv3State gic;
- } apu;
- } fpd;
-
+ GArray *intc;
MemoryRegion mr_ps;
struct {
- /* 4 ranges to access DDR. */
- MemoryRegion mr_ddr_ranges[4];
- } noc;
-
- struct {
- MemoryRegion mr_ocm;
-
- struct {
- PL011State uart[XLNX_VERSAL_NR_UARTS];
- CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
- OrIRQState gem_irq_orgate[XLNX_VERSAL_NR_GEMS];
- XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
- VersalUsb2 usb;
- CanBusState *canbus[XLNX_VERSAL_NR_CANFD];
- XlnxVersalCANFDState canfd[XLNX_VERSAL_NR_CANFD];
- } iou;
-
- /* Real-time Processing Unit. */
- struct {
- MemoryRegion mr;
- MemoryRegion mr_ps_alias;
-
- CPUClusterState cluster;
- ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
- } rpu;
-
- struct {
- OrIRQState irq_orgate;
- XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
- } xram;
-
- XlnxVersalCRL crl;
- } lpd;
-
- /* The Platform Management Controller subsystem. */
- struct {
- struct {
- SDHCIState sd[XLNX_VERSAL_NR_SDS];
- XlnxVersalPmcIouSlcr slcr;
-
- struct {
- XlnxVersalOspi ospi;
- XlnxCSUDMA dma_src;
- XlnxCSUDMA dma_dst;
- MemoryRegion linear_mr;
- OrIRQState irq_orgate;
- } ospi;
- } iou;
-
- XlnxZynqMPRTC rtc;
- XlnxVersalTRng trng;
- XlnxBBRam bbram;
- XlnxEFuse efuse;
- XlnxVersalEFuseCtrl efuse_ctrl;
- XlnxVersalEFuseCache efuse_cache;
- XlnxVersalCFUAPB cfu_apb;
- XlnxVersalCFUFDRO cfu_fdro;
- XlnxVersalCFUSFR cfu_sfr;
- XlnxVersalCFrameReg cframe[XLNX_VERSAL_NR_CFRAME];
- XlnxVersalCFrameBcastReg cframe_bcast;
-
- OrIRQState apb_irq_orgate;
- } pmc;
+ uint32_t clk_25mhz;
+ uint32_t clk_125mhz;
+ uint32_t gic;
+ } phandle;
struct {
MemoryRegion *mr_ddr;
+ CanBusState **canbus;
+ void *fdt;
} cfg;
};
-/* Memory-map and IRQ definitions. Copied a subset from
- * auto-generated files. */
-
-#define VERSAL_GIC_MAINT_IRQ 9
-#define VERSAL_TIMER_VIRT_IRQ 11
-#define VERSAL_TIMER_S_EL1_IRQ 13
-#define VERSAL_TIMER_NS_EL1_IRQ 14
-#define VERSAL_TIMER_NS_EL2_IRQ 10
-
-#define VERSAL_CRL_IRQ 10
-#define VERSAL_UART0_IRQ_0 18
-#define VERSAL_UART1_IRQ_0 19
-#define VERSAL_CANFD0_IRQ_0 20
-#define VERSAL_CANFD1_IRQ_0 21
-#define VERSAL_USB0_IRQ_0 22
-#define VERSAL_GEM0_IRQ_0 56
-#define VERSAL_GEM0_WAKE_IRQ_0 57
-#define VERSAL_GEM1_IRQ_0 58
-#define VERSAL_GEM1_WAKE_IRQ_0 59
-#define VERSAL_ADMA_IRQ_0 60
-#define VERSAL_XRAM_IRQ_0 79
-#define VERSAL_CFU_IRQ_0 120
-#define VERSAL_PMC_APB_IRQ 121
-#define VERSAL_OSPI_IRQ 124
-#define VERSAL_SD0_IRQ_0 126
-#define VERSAL_EFUSE_IRQ 139
-#define VERSAL_TRNG_IRQ 141
-#define VERSAL_RTC_ALARM_IRQ 142
-#define VERSAL_RTC_SECONDS_IRQ 143
-
-/* Architecturally reserved IRQs suitable for virtualization. */
-#define VERSAL_RSVD_IRQ_FIRST 111
-#define VERSAL_RSVD_IRQ_LAST 118
-
-#define MM_TOP_RSVD 0xa0000000U
-#define MM_TOP_RSVD_SIZE 0x4000000
-#define MM_GIC_APU_DIST_MAIN 0xf9000000U
-#define MM_GIC_APU_DIST_MAIN_SIZE 0x10000
-#define MM_GIC_APU_REDIST_0 0xf9080000U
-#define MM_GIC_APU_REDIST_0_SIZE 0x80000
-
-#define MM_UART0 0xff000000U
-#define MM_UART0_SIZE 0x10000
-#define MM_UART1 0xff010000U
-#define MM_UART1_SIZE 0x10000
-
-#define MM_CANFD0 0xff060000U
-#define MM_CANFD0_SIZE 0x10000
-#define MM_CANFD1 0xff070000U
-#define MM_CANFD1_SIZE 0x10000
-
-#define MM_GEM0 0xff0c0000U
-#define MM_GEM0_SIZE 0x10000
-#define MM_GEM1 0xff0d0000U
-#define MM_GEM1_SIZE 0x10000
+struct VersalClass {
+ SysBusDeviceClass parent;
-#define MM_ADMA_CH0 0xffa80000U
-#define MM_ADMA_CH0_SIZE 0x10000
-
-#define MM_OCM 0xfffc0000U
-#define MM_OCM_SIZE 0x40000
-
-#define MM_XRAM 0xfe800000
-#define MM_XRAMC 0xff8e0000
-#define MM_XRAMC_SIZE 0x10000
-
-#define MM_USB2_CTRL_REGS 0xFF9D0000
-#define MM_USB2_CTRL_REGS_SIZE 0x10000
-
-#define MM_USB_0 0xFE200000
-#define MM_USB_0_SIZE 0x10000
-
-#define MM_TOP_DDR 0x0
-#define MM_TOP_DDR_SIZE 0x80000000U
-#define MM_TOP_DDR_2 0x800000000ULL
-#define MM_TOP_DDR_2_SIZE 0x800000000ULL
-#define MM_TOP_DDR_3 0xc000000000ULL
-#define MM_TOP_DDR_3_SIZE 0x4000000000ULL
-#define MM_TOP_DDR_4 0x10000000000ULL
-#define MM_TOP_DDR_4_SIZE 0xb780000000ULL
-
-#define MM_PSM_START 0xffc80000U
-#define MM_PSM_END 0xffcf0000U
+ VersalVersion version;
+};
-#define MM_CRL 0xff5e0000U
-#define MM_CRL_SIZE 0x300000
-#define MM_IOU_SCNTR 0xff130000U
-#define MM_IOU_SCNTR_SIZE 0x10000
-#define MM_IOU_SCNTRS 0xff140000U
-#define MM_IOU_SCNTRS_SIZE 0x10000
-#define MM_FPD_CRF 0xfd1a0000U
-#define MM_FPD_CRF_SIZE 0x140000
-#define MM_FPD_FPD_APU 0xfd5c0000
-#define MM_FPD_FPD_APU_SIZE 0x100
+static inline void versal_set_fdt(Versal *s, void *fdt)
+{
+ g_assert(!qdev_is_realized(DEVICE(s)));
+ s->cfg.fdt = fdt;
+}
-#define MM_PMC_PMC_IOU_SLCR 0xf1060000
-#define MM_PMC_PMC_IOU_SLCR_SIZE 0x10000
+void versal_fdt_add_memory_nodes(Versal *s, uint64_t ram_size);
-#define MM_PMC_OSPI 0xf1010000
-#define MM_PMC_OSPI_SIZE 0x10000
+DeviceState *versal_get_boot_cpu(Versal *s);
+void versal_sdhci_plug_card(Versal *s, int sd_idx, BlockBackend *blk);
+void versal_efuse_attach_drive(Versal *s, BlockBackend *blk);
+void versal_bbram_attach_drive(Versal *s, BlockBackend *blk);
+void versal_ospi_create_flash(Versal *s, int flash_idx, const char *flash_mdl,
+ BlockBackend *blk);
-#define MM_PMC_OSPI_DAC 0xc0000000
-#define MM_PMC_OSPI_DAC_SIZE 0x20000000
+qemu_irq versal_get_reserved_irq(Versal *s, int idx, int *dtb_idx);
+hwaddr versal_get_reserved_mmio_addr(Versal *s);
-#define MM_PMC_OSPI_DMA_DST 0xf1011800
-#define MM_PMC_OSPI_DMA_SRC 0xf1011000
+int versal_get_num_cpu(VersalVersion version);
+int versal_get_num_can(VersalVersion version);
+int versal_get_num_sdhci(VersalVersion version);
-#define MM_PMC_SD0 0xf1040000U
-#define MM_PMC_SD0_SIZE 0x10000
-#define MM_PMC_BBRAM_CTRL 0xf11f0000
-#define MM_PMC_BBRAM_CTRL_SIZE 0x00050
-#define MM_PMC_EFUSE_CTRL 0xf1240000
-#define MM_PMC_EFUSE_CTRL_SIZE 0x00104
-#define MM_PMC_EFUSE_CACHE 0xf1250000
-#define MM_PMC_EFUSE_CACHE_SIZE 0x00C00
+static inline const char *versal_get_class(VersalVersion version)
+{
+ switch (version) {
+ case VERSAL_VER_VERSAL:
+ return TYPE_XLNX_VERSAL;
-#define MM_PMC_CFU_APB 0xf12b0000
-#define MM_PMC_CFU_APB_SIZE 0x10000
-#define MM_PMC_CFU_STREAM 0xf12c0000
-#define MM_PMC_CFU_STREAM_SIZE 0x1000
-#define MM_PMC_CFU_SFR 0xf12c1000
-#define MM_PMC_CFU_SFR_SIZE 0x1000
-#define MM_PMC_CFU_FDRO 0xf12c2000
-#define MM_PMC_CFU_FDRO_SIZE 0x1000
-#define MM_PMC_CFU_STREAM_2 0xf1f80000
-#define MM_PMC_CFU_STREAM_2_SIZE 0x40000
+ case VERSAL_VER_VERSAL2:
+ return TYPE_XLNX_VERSAL2;
-#define MM_PMC_CFRAME0_REG 0xf12d0000
-#define MM_PMC_CFRAME0_REG_SIZE 0x1000
-#define MM_PMC_CFRAME0_FDRI 0xf12d1000
-#define MM_PMC_CFRAME0_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME1_REG 0xf12d2000
-#define MM_PMC_CFRAME1_REG_SIZE 0x1000
-#define MM_PMC_CFRAME1_FDRI 0xf12d3000
-#define MM_PMC_CFRAME1_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME2_REG 0xf12d4000
-#define MM_PMC_CFRAME2_REG_SIZE 0x1000
-#define MM_PMC_CFRAME2_FDRI 0xf12d5000
-#define MM_PMC_CFRAME2_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME3_REG 0xf12d6000
-#define MM_PMC_CFRAME3_REG_SIZE 0x1000
-#define MM_PMC_CFRAME3_FDRI 0xf12d7000
-#define MM_PMC_CFRAME3_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME4_REG 0xf12d8000
-#define MM_PMC_CFRAME4_REG_SIZE 0x1000
-#define MM_PMC_CFRAME4_FDRI 0xf12d9000
-#define MM_PMC_CFRAME4_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME5_REG 0xf12da000
-#define MM_PMC_CFRAME5_REG_SIZE 0x1000
-#define MM_PMC_CFRAME5_FDRI 0xf12db000
-#define MM_PMC_CFRAME5_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME6_REG 0xf12dc000
-#define MM_PMC_CFRAME6_REG_SIZE 0x1000
-#define MM_PMC_CFRAME6_FDRI 0xf12dd000
-#define MM_PMC_CFRAME6_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME7_REG 0xf12de000
-#define MM_PMC_CFRAME7_REG_SIZE 0x1000
-#define MM_PMC_CFRAME7_FDRI 0xf12df000
-#define MM_PMC_CFRAME7_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME8_REG 0xf12e0000
-#define MM_PMC_CFRAME8_REG_SIZE 0x1000
-#define MM_PMC_CFRAME8_FDRI 0xf12e1000
-#define MM_PMC_CFRAME8_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME9_REG 0xf12e2000
-#define MM_PMC_CFRAME9_REG_SIZE 0x1000
-#define MM_PMC_CFRAME9_FDRI 0xf12e3000
-#define MM_PMC_CFRAME9_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME10_REG 0xf12e4000
-#define MM_PMC_CFRAME10_REG_SIZE 0x1000
-#define MM_PMC_CFRAME10_FDRI 0xf12e5000
-#define MM_PMC_CFRAME10_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME11_REG 0xf12e6000
-#define MM_PMC_CFRAME11_REG_SIZE 0x1000
-#define MM_PMC_CFRAME11_FDRI 0xf12e7000
-#define MM_PMC_CFRAME11_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME12_REG 0xf12e8000
-#define MM_PMC_CFRAME12_REG_SIZE 0x1000
-#define MM_PMC_CFRAME12_FDRI 0xf12e9000
-#define MM_PMC_CFRAME12_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME13_REG 0xf12ea000
-#define MM_PMC_CFRAME13_REG_SIZE 0x1000
-#define MM_PMC_CFRAME13_FDRI 0xf12eb000
-#define MM_PMC_CFRAME13_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME14_REG 0xf12ec000
-#define MM_PMC_CFRAME14_REG_SIZE 0x1000
-#define MM_PMC_CFRAME14_FDRI 0xf12ed000
-#define MM_PMC_CFRAME14_FDRI_SIZE 0x1000
-#define MM_PMC_CFRAME_BCAST_REG 0xf12ee000
-#define MM_PMC_CFRAME_BCAST_REG_SIZE 0x1000
-#define MM_PMC_CFRAME_BCAST_FDRI 0xf12ef000
-#define MM_PMC_CFRAME_BCAST_FDRI_SIZE 0x1000
+ default:
+ g_assert_not_reached();
+ }
+}
-#define MM_PMC_CRP 0xf1260000U
-#define MM_PMC_CRP_SIZE 0x10000
-#define MM_PMC_RTC 0xf12a0000
-#define MM_PMC_RTC_SIZE 0x10000
-#define MM_PMC_TRNG 0xf1230000
-#define MM_PMC_TRNG_SIZE 0x10000
#endif
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index c137ac5..a3117bd 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -42,6 +42,7 @@
#include "hw/misc/xlnx-zynqmp-crf.h"
#include "hw/timer/cadence_ttc.h"
#include "hw/usb/hcd-dwc3.h"
+#include "hw/core/split-irq.h"
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
@@ -67,6 +68,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
#define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000
#define XLNX_ZYNQMP_GIC_REGIONS 6
+#define XLNX_ZYNQMP_GIC_NUM_SPI_INTR 160
/*
* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets
@@ -105,6 +107,9 @@ struct XlnxZynqMPState {
GICState gic;
MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES];
+ GICState rpu_gic;
+ SplitIRQ splitter[XLNX_ZYNQMP_GIC_NUM_SPI_INTR];
+
MemoryRegion ocm_ram[XLNX_ZYNQMP_NUM_OCM_BANKS];
MemoryRegion *ddr_ram;
diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h
index 5fd67f5..3671f01 100644
--- a/include/hw/block/flash.h
+++ b/include/hw/block/flash.h
@@ -44,24 +44,6 @@ PFlashCFI02 *pflash_cfi02_register(hwaddr base,
uint16_t unlock_addr1,
int be);
-/* nand.c */
-DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id);
-void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale,
- uint8_t ce, uint8_t wp, uint8_t gnd);
-void nand_getpins(DeviceState *dev, int *rb);
-void nand_setio(DeviceState *dev, uint32_t value);
-uint32_t nand_getio(DeviceState *dev);
-uint32_t nand_getbuswidth(DeviceState *dev);
-
-#define NAND_MFR_TOSHIBA 0x98
-#define NAND_MFR_SAMSUNG 0xec
-#define NAND_MFR_FUJITSU 0x04
-#define NAND_MFR_NATIONAL 0x8f
-#define NAND_MFR_RENESAS 0x07
-#define NAND_MFR_STMICRO 0x20
-#define NAND_MFR_HYNIX 0xad
-#define NAND_MFR_MICRON 0x2c
-
/* m25p80.c */
#define TYPE_M25P80 "m25p80-generic"
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 765dc8d..665b620 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -286,8 +286,7 @@ struct MachineClass {
no_parallel:1,
no_floppy:1,
no_cdrom:1,
- pci_allow_0_address:1,
- legacy_fw_cfg_order:1;
+ pci_allow_0_address:1;
bool auto_create_sdcard;
bool is_default;
const char *default_machine_opts;
@@ -444,6 +443,7 @@ struct MachineState {
SmpCache smp_cache;
struct NVDIMMState *nvdimms_state;
struct NumaState *numa_state;
+ bool acpi_spcr_enabled;
};
/*
@@ -636,7 +636,11 @@ struct MachineState {
/*
* How many years/major releases for each phase
* of the life cycle. Assumes use of versioning
- * scheme where major is bumped each year
+ * scheme where major is bumped each year.
+ *
+ * These values must match the ver_machine_deprecation_version
+ * and ver_machine_deletion_version logic in docs/conf.py and
+ * the text in docs/about/deprecated.rst
*/
#define MACHINE_VER_DELETION_MAJOR 6
#define MACHINE_VER_DEPRECATION_MAJOR 3
@@ -650,11 +654,42 @@ struct MachineState {
" years old are subject to deletion after " \
stringify(MACHINE_VER_DELETION_MAJOR) " years"
-#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \
+#define _MACHINE_VER_IS_CURRENT_EXPIRED(cutoff, major, minor) \
(((QEMU_VERSION_MAJOR - major) > cutoff) || \
(((QEMU_VERSION_MAJOR - major) == cutoff) && \
(QEMU_VERSION_MINOR - minor) >= 0))
+#define _MACHINE_VER_IS_NEXT_MINOR_EXPIRED(cutoff, major, minor) \
+ (((QEMU_VERSION_MAJOR - major) > cutoff) || \
+ (((QEMU_VERSION_MAJOR - major) == cutoff) && \
+ ((QEMU_VERSION_MINOR + 1) - minor) >= 0))
+
+#define _MACHINE_VER_IS_NEXT_MAJOR_EXPIRED(cutoff, major, minor) \
+ ((((QEMU_VERSION_MAJOR + 1) - major) > cutoff) || \
+ ((((QEMU_VERSION_MAJOR + 1) - major) == cutoff) && \
+ (0 - minor) >= 0))
+
+/*
+ * - The first check applies to formal releases
+ * - The second check applies to dev snapshots / release candidates
+ * where the next major version is the same.
+ * e.g. 9.0.50, 9.1.50, 9.0.90, 9.1.90
+ * - The third check applies to dev snapshots / release candidates
+ * where the next major version will change.
+ * e.g. 9.2.50, 9.2.90
+ *
+ * NB: this assumes we do 3 minor releases per year, before bumping major,
+ * and dev snapshots / release candidates are numbered with micro >= 50
+ * If this ever changes the logic below will need modifying....
+ */
+#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \
+ ((QEMU_VERSION_MICRO < 50 && \
+ _MACHINE_VER_IS_CURRENT_EXPIRED(cutoff, major, minor)) || \
+ (QEMU_VERSION_MICRO >= 50 && QEMU_VERSION_MINOR < 2 && \
+ _MACHINE_VER_IS_NEXT_MINOR_EXPIRED(cutoff, major, minor)) || \
+ (QEMU_VERSION_MICRO >= 50 && QEMU_VERSION_MINOR == 2 && \
+ _MACHINE_VER_IS_NEXT_MAJOR_EXPIRED(cutoff, major, minor)))
+
#define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \
_MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
#define _MACHINE_VER_IS_EXPIRED3(cutoff, major, minor, micro) \
@@ -719,28 +754,11 @@ struct MachineState {
* suitable period of time has passed, it will cause
* execution of the method to return, avoiding registration
* of the machine
- *
- * The new deprecation and deletion policy for versioned
- * machine types was introduced in QEMU 9.1.0.
- *
- * Under the new policy a number of old machine types (any
- * prior to 2.12) would be liable for immediate deletion
- * which would be a violation of our historical deprecation
- * and removal policy
- *
- * Thus deletions are temporarily gated on existance of
- * the env variable "QEMU_DELETE_MACHINES" / QEMU version
- * number >= 10.1.0. This gate can be deleted in the 10.1.0
- * dev cycle
*/
#define MACHINE_VER_DELETION(...) \
do { \
if (MACHINE_VER_SHOULD_DELETE(__VA_ARGS__)) { \
- if (getenv("QEMU_DELETE_MACHINES") || \
- QEMU_VERSION_MAJOR > 10 || (QEMU_VERSION_MAJOR == 10 && \
- QEMU_VERSION_MINOR >= 1)) { \
- return; \
- } \
+ return; \
} \
} while (0)
@@ -761,6 +779,9 @@ struct MachineState {
} \
type_init(machine_initfn##_register_types)
+extern GlobalProperty hw_compat_10_1[];
+extern const size_t hw_compat_10_1_len;
+
extern GlobalProperty hw_compat_10_0[];
extern const size_t hw_compat_10_0_len;
@@ -845,10 +866,4 @@ extern const size_t hw_compat_2_7_len;
extern GlobalProperty hw_compat_2_6[];
extern const size_t hw_compat_2_6_len;
-extern GlobalProperty hw_compat_2_5[];
-extern const size_t hw_compat_2_5_len;
-
-extern GlobalProperty hw_compat_2_4[];
-extern const size_t hw_compat_2_4_len;
-
#endif
diff --git a/include/hw/char/max78000_uart.h b/include/hw/char/max78000_uart.h
new file mode 100644
index 0000000..cf90d51
--- /dev/null
+++ b/include/hw/char/max78000_uart.h
@@ -0,0 +1,78 @@
+/*
+ * MAX78000 UART
+ *
+ * Copyright (c) 2025 Jackson Donaldson <jcksn@duck.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MAX78000_UART_H
+#define HW_MAX78000_UART_H
+
+#include "hw/sysbus.h"
+#include "chardev/char-fe.h"
+#include "qemu/fifo8.h"
+#include "qom/object.h"
+
+#define UART_CTRL 0x0
+#define UART_STATUS 0x4
+#define UART_INT_EN 0x8
+#define UART_INT_FL 0xc
+#define UART_CLKDIV 0x10
+#define UART_OSR 0x14
+#define UART_TXPEEK 0x18
+#define UART_PNR 0x1c
+#define UART_FIFO 0x20
+#define UART_DMA 0x30
+#define UART_WKEN 0x34
+#define UART_WKFL 0x38
+
+/* CTRL */
+#define UART_CTF_DIS (1 << 7)
+#define UART_FLUSH_TX (1 << 8)
+#define UART_FLUSH_RX (1 << 9)
+#define UART_BCLKEN (1 << 15)
+#define UART_BCLKRDY (1 << 19)
+
+/* STATUS */
+#define UART_RX_LVL 8
+#define UART_TX_EM (1 << 6)
+#define UART_RX_FULL (1 << 5)
+#define UART_RX_EM (1 << 4)
+
+/* PNR (Pin Control Register) */
+#define UART_CTS 1
+#define UART_RTS (1 << 1)
+
+/* INT_EN / INT_FL */
+#define UART_RX_THD (1 << 4)
+#define UART_TX_HE (1 << 6)
+
+#define UART_RXBUFLEN 0x100
+#define TYPE_MAX78000_UART "max78000-uart"
+OBJECT_DECLARE_SIMPLE_TYPE(Max78000UartState, MAX78000_UART)
+
+struct Max78000UartState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+
+ uint32_t ctrl;
+ uint32_t status;
+ uint32_t int_en;
+ uint32_t int_fl;
+ uint32_t clkdiv;
+ uint32_t osr;
+ uint32_t txpeek;
+ uint32_t pnr;
+ uint32_t fifo;
+ uint32_t dma;
+ uint32_t wken;
+ uint32_t wkfl;
+
+ Fifo8 rx_fifo;
+
+ CharBackend chr;
+ qemu_irq irq;
+};
+#endif /* HW_STM32F2XX_USART_H */
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 12b2ff1..e79e8e0 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -169,7 +169,7 @@ struct CPUClass {
vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr);
const char *gdb_core_xml_file;
- const gchar * (*gdb_arch_name)(CPUState *cpu);
+ const char * (*gdb_arch_name)(CPUState *cpu);
const char * (*gdb_get_core_xml_file)(CPUState *cpu);
void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
@@ -198,10 +198,11 @@ struct CPUClass {
};
/*
- * Fix the number of mmu modes to 16, which is also the maximum
- * supported by the softmmu tlb api.
+ * Fix the number of mmu modes across all targets.
+ * Current maximum is target/arm/.
*/
-#define NB_MMU_MODES 16
+#define NB_MMU_MODES 22
+typedef uint32_t MMUIdxMap;
/* Use a fully associative victim tlb of 8 entries. */
#define CPU_VTLB_SIZE 8
@@ -306,7 +307,7 @@ typedef struct CPUTLBCommon {
* mmu_idx N since the last time that mmu_idx was flushed.
* Protected by tlb_c.lock.
*/
- uint16_t dirty;
+ MMUIdxMap dirty;
/*
* Statistics. These are not lock protected, but are read and
* written atomically. This allows the monitor to print a snapshot
@@ -368,6 +369,7 @@ typedef struct CPUNegativeOffsetState {
GArray *plugin_mem_cbs;
uint64_t plugin_mem_value_low;
uint64_t plugin_mem_value_high;
+ int32_t plugin_cb_flags;
#endif
IcountDecr icount_decr;
bool can_do_io;
@@ -421,7 +423,17 @@ struct qemu_work_item;
* valid under cpu_list_lock.
* @created: Indicates whether the CPU thread has been successfully created.
* @halt_cond: condition variable sleeping threads can wait on.
+ * @exit_request: Another thread requests the CPU to call qemu_process_cpu_events().
+ * Should be read only by CPU thread with load-acquire, to synchronize with
+ * other threads' store-release operation.
+ *
+ * In some cases, accelerator-specific code will write exit_request from
+ * within the same thread, to "bump" the effect of qemu_cpu_kick() to
+ * the one provided by cpu_exit(), especially when processing interrupt
+ * flags. In this case, the write and read happen in the same thread
+ * and the write therefore can use qemu_atomic_set().
* @interrupt_request: Indicates a pending interrupt request.
+ * Only used by system emulation.
* @halted: Nonzero if the CPU is in suspended state.
* @stop: Indicates a pending stop request.
* @stopped: Indicates the CPU has been artificially stopped.
@@ -441,6 +453,7 @@ struct qemu_work_item;
* @opaque: User data.
* @mem_io_pc: Host Program Counter at which the memory was accessed.
* @accel: Pointer to accelerator specific state.
+ * @vcpu_dirty: Hardware accelerator is not synchronized with QEMU state
* @kvm_fd: vCPU file descriptor for KVM.
* @work_mutex: Lock to prevent multiple access to @work_list.
* @work_list: List of pending asynchronous work.
@@ -492,7 +505,6 @@ struct CPUState {
bool exit_request;
int exclusive_context_count;
uint32_t cflags_next_tb;
- /* updates protected by BQL */
uint32_t interrupt_request;
int singlestep_enabled;
int64_t icount_budget;
@@ -504,7 +516,6 @@ struct CPUState {
QSIMPLEQ_HEAD(, qemu_work_item) work_list;
struct CPUAddressSpace *cpu_ases;
- int cpu_ases_count;
int num_ases;
AddressSpace *as;
MemoryRegion *memory;
@@ -537,7 +548,6 @@ struct CPUState {
uint32_t kvm_fetch_index;
uint64_t dirty_pages;
int kvm_vcpu_stats_fd;
- bool vcpu_dirty;
/* Use by accel-block: CPU is executing an ioctl() */
QemuLockCnt in_ioctl_lock;
@@ -553,6 +563,7 @@ struct CPUState {
uint32_t halted;
int32_t exception_index;
+ bool vcpu_dirty;
AccelCPUState *accel;
/* Used to keep track of an outstanding cpu throttle thread for migration
@@ -591,6 +602,22 @@ static inline CPUArchState *cpu_env(CPUState *cpu)
return (CPUArchState *)(cpu + 1);
}
+#ifdef CONFIG_TCG
+/*
+ * Invert the index order of the CPUTLBDescFast array so that lower
+ * mmu_idx have offsets from env with smaller magnitude.
+ */
+static inline int mmuidx_to_fast_index(int mmu_idx)
+{
+ return NB_MMU_MODES - 1 - mmu_idx;
+}
+
+static inline CPUTLBDescFast *cpu_tlb_fast(CPUState *cpu, int mmu_idx)
+{
+ return &cpu->neg.tlb.f[mmuidx_to_fast_index(mmu_idx)];
+}
+#endif
+
typedef QTAILQ_HEAD(CPUTailQ, CPUState) CPUTailQ;
extern CPUTailQ cpus_queue;
@@ -827,7 +854,8 @@ bool qemu_cpu_is_self(CPUState *cpu);
* qemu_cpu_kick:
* @cpu: The vCPU to kick.
*
- * Kicks @cpu's thread.
+ * Kicks @cpu's thread to exit the accelerator. For accelerators that
+ * can do that, the target vCPU thread will try not to take the BQL.
*/
void qemu_cpu_kick(CPUState *cpu);
@@ -941,6 +969,28 @@ CPUState *cpu_by_arch_id(int64_t id);
void cpu_interrupt(CPUState *cpu, int mask);
/**
+ * cpu_test_interrupt:
+ * @cpu: The CPU to check interrupt(s) on.
+ * @mask: The interrupts to check.
+ *
+ * Checks if any of interrupts in @mask are pending on @cpu.
+ */
+static inline bool cpu_test_interrupt(CPUState *cpu, int mask)
+{
+ return qatomic_load_acquire(&cpu->interrupt_request) & mask;
+}
+
+/**
+ * cpu_set_interrupt:
+ * @cpu: The CPU to set pending interrupt(s) on.
+ * @mask: The interrupts to set.
+ *
+ * Sets interrupts in @mask as pending on @cpu. Unlike @cpu_interrupt,
+ * this does not kick the vCPU.
+ */
+void cpu_set_interrupt(CPUState *cpu, int mask);
+
+/**
* cpu_set_pc:
* @cpu: The CPU to set the program counter for.
* @addr: Program counter value.
@@ -1111,6 +1161,15 @@ AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx);
G_NORETURN void cpu_abort(CPUState *cpu, const char *fmt, ...)
G_GNUC_PRINTF(2, 3);
+/**
+ * qemu_process_cpu_events:
+ * @cpu: CPU that left the execution loop
+ *
+ * Perform accelerator-independent work after the CPU has left
+ * the inner execution loop.
+ */
+void qemu_process_cpu_events(CPUState *cpu);
+
/* $(top_srcdir)/cpu.c */
void cpu_class_init_props(DeviceClass *dc);
void cpu_exec_class_post_init(CPUClass *cc);
@@ -1121,21 +1180,15 @@ bool cpu_exec_realizefn(CPUState *cpu, Error **errp);
void cpu_exec_unrealizefn(CPUState *cpu);
void cpu_exec_reset_hold(CPUState *cpu);
-#ifdef COMPILING_PER_TARGET
-
extern const VMStateDescription vmstate_cpu_common;
-#define VMSTATE_CPU() { \
- .name = "parent_obj", \
- .size = sizeof(CPUState), \
- .vmsd = &vmstate_cpu_common, \
- .flags = VMS_STRUCT, \
- .offset = 0, \
-}
-
-#endif /* COMPILING_PER_TARGET */
-
#define UNASSIGNED_CPU_INDEX -1
#define UNASSIGNED_CLUSTER_INDEX -1
+enum CacheType {
+ DATA_CACHE,
+ INSTRUCTION_CACHE,
+ UNIFIED_CACHE
+};
+
#endif
diff --git a/include/hw/core/resetcontainer.h b/include/hw/core/resetcontainer.h
index 23db0c7..daeb18c 100644
--- a/include/hw/core/resetcontainer.h
+++ b/include/hw/core/resetcontainer.h
@@ -20,7 +20,7 @@
#include "qom/object.h"
#define TYPE_RESETTABLE_CONTAINER "resettable-container"
-OBJECT_DECLARE_TYPE(ResettableContainer, ResettableContainerClass, RESETTABLE_CONTAINER)
+OBJECT_DECLARE_SIMPLE_TYPE(ResettableContainer, RESETTABLE_CONTAINER)
/**
* resettable_container_add: Add a resettable object to the container
diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
index 75e47b6..998f495 100644
--- a/include/hw/cxl/cxl.h
+++ b/include/hw/cxl/cxl.h
@@ -23,10 +23,13 @@
#define CXL_DEVICE_REG_BAR_IDX 2
#define CXL_WINDOW_MAX 10
+#define CXL_NUM_EXTENTS_SUPPORTED 512
typedef struct PXBCXLDev PXBCXLDev;
typedef struct CXLFixedWindow {
+ SysBusDevice parent_obj;
+ int index;
uint64_t size;
char **targets;
PXBCXLDev *target_hbs[16];
@@ -37,12 +40,13 @@ typedef struct CXLFixedWindow {
MemoryRegion mr;
hwaddr base;
} CXLFixedWindow;
+#define TYPE_CXL_FMW "cxl-fmw"
+OBJECT_DECLARE_SIMPLE_TYPE(CXLFixedWindow, CXL_FMW)
typedef struct CXLState {
bool is_enabled;
MemoryRegion host_mr;
unsigned int next_mr_idx;
- GList *fixed_windows;
CXLFixedMemoryWindowOptionsList *cfmw_list;
} CXLState;
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 3a0ee7e..89411c8 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -133,6 +133,15 @@ typedef enum {
CXL_MBOX_MAX = 0x20
} CXLRetCode;
+/* r3.2 Section 7.6.7.6.2: Table 7-66: DSMAS Flags Bits */
+typedef enum {
+ CXL_DSMAS_FLAGS_NONVOLATILE = 2,
+ CXL_DSMAS_FLAGS_SHARABLE = 3,
+ CXL_DSMAS_FLAGS_HW_MANAGED_COHERENCY = 4,
+ CXL_DSMAS_FLAGS_IC_SPECIFIC_DC_MANAGEMENT = 5,
+ CXL_DSMAS_FLAGS_RDONLY = 6,
+} CXLDSMASFlags;
+
typedef struct CXLCCI CXLCCI;
typedef struct cxl_device_state CXLDeviceState;
struct cxl_cmd;
@@ -176,10 +185,12 @@ typedef struct CXLCCI {
uint16_t opcode;
uint16_t complete_pct;
uint16_t ret_code; /* Current value of retcode */
+ bool aborted;
uint64_t starttime;
/* set by each bg cmd, cleared by the bg_timer when complete */
uint64_t runtime;
QEMUTimer *timer;
+ QemuMutex lock; /* serializes mbox abort vs timer cb */
} bg;
/* firmware update */
@@ -201,6 +212,7 @@ typedef struct CXLCCI {
DeviceState *d;
/* Pointer to the device hosting the protocol conversion */
DeviceState *intf;
+ bool initialized;
} CXLCCI;
typedef struct cxl_device_state {
@@ -316,6 +328,7 @@ void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf,
DeviceState *d, size_t payload_max);
void cxl_init_cci(CXLCCI *cci, size_t payload_max);
+void cxl_destroy_cci(CXLCCI *cci);
void cxl_add_cci_commands(CXLCCI *cci, const struct cxl_cmd (*cxl_cmd_set)[256],
size_t payload_max);
int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
@@ -526,6 +539,14 @@ typedef struct CXLDCRegion {
uint32_t dsmadhandle;
uint8_t flags;
unsigned long *blk_bitmap;
+ uint64_t supported_blk_size_bitmask;
+ QemuMutex bitmap_lock;
+ /* Following bools make up dsmas flags, as defined in the CDAT */
+ bool nonvolatile;
+ bool sharable;
+ bool hw_managed_coherency;
+ bool ic_specific_dc_management;
+ bool rdonly;
} CXLDCRegion;
typedef struct CXLSetFeatureInfo {
@@ -536,6 +557,21 @@ typedef struct CXLSetFeatureInfo {
size_t data_size;
} CXLSetFeatureInfo;
+struct CXLSanitizeInfo;
+
+typedef struct CXLAlertConfig {
+ uint8_t valid_alerts;
+ uint8_t enable_alerts;
+ uint8_t life_used_crit_alert_thresh;
+ uint8_t life_used_warn_thresh;
+ uint16_t over_temp_crit_alert_thresh;
+ uint16_t under_temp_crit_alert_thresh;
+ uint16_t over_temp_warn_thresh;
+ uint16_t under_temp_warn_thresh;
+ uint16_t cor_vmem_err_warn_thresh;
+ uint16_t cor_pmem_err_warn_thresh;
+} QEMU_PACKED CXLAlertConfig;
+
struct CXLType3Dev {
/* Private */
PCIDevice parent_obj;
@@ -557,6 +593,8 @@ struct CXLType3Dev {
CXLCCI vdm_fm_owned_ld_mctp_cci;
CXLCCI ld0_cci;
+ CXLAlertConfig alert_config;
+
/* PCIe link characteristics */
PCIExpLinkSpeed speed;
PCIExpLinkWidth width;
@@ -597,11 +635,14 @@ struct CXLType3Dev {
CXLDCExtentList extents;
CXLDCExtentGroupList extents_pending;
uint32_t total_extent_count;
+ uint32_t nr_extents_accepted;
uint32_t ext_list_gen_seq;
uint8_t num_regions; /* 0-8 regions */
CXLDCRegion regions[DCD_MAX_NUM_REGION];
} dc;
+
+ struct CXLSanitizeInfo *media_op_sanitize;
};
#define TYPE_CXL_TYPE3 "cxl-type3"
@@ -673,11 +714,22 @@ CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXLDCExtentGroup *group,
uint16_t shared_seq);
void cxl_extent_group_list_insert_tail(CXLDCExtentGroupList *list,
CXLDCExtentGroup *group);
-void cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list);
+uint32_t cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list);
void ct3_set_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
uint64_t len);
void ct3_clear_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
uint64_t len);
bool ct3_test_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
uint64_t len);
+void cxl_assign_event_header(CXLEventRecordHdr *hdr,
+ const QemuUUID *uuid, uint32_t flags,
+ uint8_t length, uint64_t timestamp);
+void cxl_create_dc_event_records_for_extents(CXLType3Dev *ct3d,
+ CXLDCEventType type,
+ CXLDCExtentRaw extents[],
+ uint32_t ext_count);
+bool cxl_extents_overlaps_dpa_range(CXLDCExtentList *list,
+ uint64_t dpa, uint64_t len);
+bool cxl_extent_groups_overlaps_dpa_range(CXLDCExtentGroupList *list,
+ uint64_t dpa, uint64_t len);
#endif
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 38cadaa..758b075 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -184,4 +184,19 @@ typedef struct CXLEventDynamicCapacity {
uint32_t tags_avail;
} QEMU_PACKED CXLEventDynamicCapacity;
+/* CXL r3.1 Table 8-50: Dynamic Capacity Event Record */
+static const QemuUUID dynamic_capacity_uuid = {
+ .data = UUID(0xca95afa7, 0xf183, 0x4018, 0x8c, 0x2f,
+ 0x95, 0x26, 0x8e, 0x10, 0x1a, 0x2a),
+};
+
+typedef enum CXLDCEventType {
+ DC_EVENT_ADD_CAPACITY = 0x0,
+ DC_EVENT_RELEASE_CAPACITY = 0x1,
+ DC_EVENT_FORCED_RELEASE_CAPACITY = 0x2,
+ DC_EVENT_REGION_CONFIG_UPDATED = 0x3,
+ DC_EVENT_ADD_CAPACITY_RSP = 0x4,
+ DC_EVENT_CAPACITY_RELEASED = 0x5,
+} CXLDCEventType;
+
#endif /* CXL_EVENTS_H */
diff --git a/include/hw/cxl/cxl_host.h b/include/hw/cxl/cxl_host.h
index c9bc9c7..cd3c368 100644
--- a/include/hw/cxl/cxl_host.h
+++ b/include/hw/cxl/cxl_host.h
@@ -14,8 +14,11 @@
#define CXL_HOST_H
void cxl_machine_init(Object *obj, CXLState *state);
-void cxl_fmws_link_targets(CXLState *stat, Error **errp);
+void cxl_fmws_link_targets(Error **errp);
void cxl_hook_up_pxb_registers(PCIBus *bus, CXLState *state, Error **errp);
+hwaddr cxl_fmws_set_memmap(hwaddr base, hwaddr max_addr);
+void cxl_fmws_update_mmio(void);
+GSList *cxl_fmws_get_all_sorted(void);
extern const MemoryRegionOps cfmws_ops;
diff --git a/include/hw/cxl/cxl_mailbox.h b/include/hw/cxl/cxl_mailbox.h
index beb0480..a05d7cb 100644
--- a/include/hw/cxl/cxl_mailbox.h
+++ b/include/hw/cxl/cxl_mailbox.h
@@ -8,11 +8,18 @@
#ifndef CXL_MAILBOX_H
#define CXL_MAILBOX_H
+#define CXL_MBOX_CONFIG_CHANGE_COLD_RESET (1)
#define CXL_MBOX_IMMEDIATE_CONFIG_CHANGE (1 << 1)
#define CXL_MBOX_IMMEDIATE_DATA_CHANGE (1 << 2)
#define CXL_MBOX_IMMEDIATE_POLICY_CHANGE (1 << 3)
#define CXL_MBOX_IMMEDIATE_LOG_CHANGE (1 << 4)
#define CXL_MBOX_SECURITY_STATE_CHANGE (1 << 5)
#define CXL_MBOX_BACKGROUND_OPERATION (1 << 6)
+#define CXL_MBOX_BACKGROUND_OPERATION_ABORT (1 << 7)
+#define CXL_MBOX_SECONDARY_MBOX_SUPPORTED (1 << 8)
+#define CXL_MBOX_REQUEST_ABORT_BACKGROUND_OP_SUPPORTED (1 << 9)
+#define CXL_MBOX_CEL_10_TO_11_VALID (1 << 10)
+#define CXL_MBOX_CONFIG_CHANGE_CONV_RESET (1 << 11)
+#define CXL_MBOX_CONFIG_CHANGE_CXL_RESET (1 << 12)
#endif
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
index 49541bf..acc9230 100644
--- a/include/hw/display/bcm2835_fb.h
+++ b/include/hw/display/bcm2835_fb.h
@@ -13,7 +13,6 @@
#define BCM2835_FB_H
#include "hw/sysbus.h"
-#include "ui/console.h"
#include "qom/object.h"
#define UPPER_RAM_BASE 0x40000000
diff --git a/include/hw/display/edid.h b/include/hw/display/edid.h
index 520f8ec..91c0a42 100644
--- a/include/hw/display/edid.h
+++ b/include/hw/display/edid.h
@@ -1,6 +1,8 @@
#ifndef EDID_H
#define EDID_H
+#define EDID_NAME_MAX_LENGTH 12
+
typedef struct qemu_edid_info {
const char *vendor; /* http://www.uefi.org/pnp_id_list */
const char *name;
diff --git a/include/hw/display/ramfb.h b/include/hw/display/ramfb.h
index a7e0019..172aa6d 100644
--- a/include/hw/display/ramfb.h
+++ b/include/hw/display/ramfb.h
@@ -6,7 +6,7 @@
/* ramfb.c */
typedef struct RAMFBState RAMFBState;
void ramfb_display_update(QemuConsole *con, RAMFBState *s);
-RAMFBState *ramfb_setup(Error **errp);
+RAMFBState *ramfb_setup(bool romfile, Error **errp);
extern const VMStateDescription ramfb_vmstate;
diff --git a/include/hw/dma/xlnx_dpdma.h b/include/hw/dma/xlnx_dpdma.h
index 1ec0d26..484b2e3 100644
--- a/include/hw/dma/xlnx_dpdma.h
+++ b/include/hw/dma/xlnx_dpdma.h
@@ -26,7 +26,6 @@
#define XLNX_DPDMA_H
#include "hw/sysbus.h"
-#include "ui/console.h"
#include "system/dma.h"
#include "qom/object.h"
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index f066ab7..3ea732f 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -22,7 +22,7 @@ extern GArray *usr_blobs_sizes;
typedef struct {
const char *vendor, *version, *date;
- bool have_major_minor, uefi;
+ bool have_major_minor, uefi, vm;
uint8_t major, minor;
} smbios_type0_t;
extern smbios_type0_t smbios_type0;
diff --git a/include/hw/gpio/aspeed_gpio.h b/include/hw/gpio/aspeed_gpio.h
index e1e6c54..e6b2fe7 100644
--- a/include/hw/gpio/aspeed_gpio.h
+++ b/include/hw/gpio/aspeed_gpio.h
@@ -70,7 +70,7 @@ typedef struct AspeedGPIOReg {
} AspeedGPIOReg;
struct AspeedGPIOClass {
- SysBusDevice parent_obj;
+ SysBusDeviceClass parent_class;
const GPIOSetProperties *props;
uint32_t nr_gpio_pins;
uint32_t nr_gpio_sets;
diff --git a/include/hw/hyperv/hvgdk.h b/include/hw/hyperv/hvgdk.h
new file mode 100644
index 0000000..71161f4
--- /dev/null
+++ b/include/hw/hyperv/hvgdk.h
@@ -0,0 +1,20 @@
+/*
+ * Type definitions for the mshv guest interface.
+ *
+ * Copyright Microsoft, Corp. 2025
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_HYPERV_HVGDK_H
+#define HW_HYPERV_HVGDK_H
+
+#define HVGDK_H_VERSION (25125)
+
+enum hv_unimplemented_msr_action {
+ HV_UNIMPLEMENTED_MSR_ACTION_FAULT = 0,
+ HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO = 1,
+ HV_UNIMPLEMENTED_MSR_ACTION_COUNT = 2,
+};
+
+#endif /* HW_HYPERV_HVGDK_H */
diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h
new file mode 100644
index 0000000..d89315f
--- /dev/null
+++ b/include/hw/hyperv/hvgdk_mini.h
@@ -0,0 +1,817 @@
+/*
+ * Userspace interfaces for /dev/mshv* devices and derived fds
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_HYPERV_HVGDK_MINI_H
+#define HW_HYPERV_HVGDK_MINI_H
+
+#define MSHV_IOCTL 0xB8
+
+typedef enum hv_register_name {
+ /* Pending Interruption Register */
+ HV_REGISTER_PENDING_INTERRUPTION = 0x00010002,
+
+ /* X64 User-Mode Registers */
+ HV_X64_REGISTER_RAX = 0x00020000,
+ HV_X64_REGISTER_RCX = 0x00020001,
+ HV_X64_REGISTER_RDX = 0x00020002,
+ HV_X64_REGISTER_RBX = 0x00020003,
+ HV_X64_REGISTER_RSP = 0x00020004,
+ HV_X64_REGISTER_RBP = 0x00020005,
+ HV_X64_REGISTER_RSI = 0x00020006,
+ HV_X64_REGISTER_RDI = 0x00020007,
+ HV_X64_REGISTER_R8 = 0x00020008,
+ HV_X64_REGISTER_R9 = 0x00020009,
+ HV_X64_REGISTER_R10 = 0x0002000A,
+ HV_X64_REGISTER_R11 = 0x0002000B,
+ HV_X64_REGISTER_R12 = 0x0002000C,
+ HV_X64_REGISTER_R13 = 0x0002000D,
+ HV_X64_REGISTER_R14 = 0x0002000E,
+ HV_X64_REGISTER_R15 = 0x0002000F,
+ HV_X64_REGISTER_RIP = 0x00020010,
+ HV_X64_REGISTER_RFLAGS = 0x00020011,
+
+ /* X64 Floating Point and Vector Registers */
+ HV_X64_REGISTER_XMM0 = 0x00030000,
+ HV_X64_REGISTER_XMM1 = 0x00030001,
+ HV_X64_REGISTER_XMM2 = 0x00030002,
+ HV_X64_REGISTER_XMM3 = 0x00030003,
+ HV_X64_REGISTER_XMM4 = 0x00030004,
+ HV_X64_REGISTER_XMM5 = 0x00030005,
+ HV_X64_REGISTER_XMM6 = 0x00030006,
+ HV_X64_REGISTER_XMM7 = 0x00030007,
+ HV_X64_REGISTER_XMM8 = 0x00030008,
+ HV_X64_REGISTER_XMM9 = 0x00030009,
+ HV_X64_REGISTER_XMM10 = 0x0003000A,
+ HV_X64_REGISTER_XMM11 = 0x0003000B,
+ HV_X64_REGISTER_XMM12 = 0x0003000C,
+ HV_X64_REGISTER_XMM13 = 0x0003000D,
+ HV_X64_REGISTER_XMM14 = 0x0003000E,
+ HV_X64_REGISTER_XMM15 = 0x0003000F,
+ HV_X64_REGISTER_FP_MMX0 = 0x00030010,
+ HV_X64_REGISTER_FP_MMX1 = 0x00030011,
+ HV_X64_REGISTER_FP_MMX2 = 0x00030012,
+ HV_X64_REGISTER_FP_MMX3 = 0x00030013,
+ HV_X64_REGISTER_FP_MMX4 = 0x00030014,
+ HV_X64_REGISTER_FP_MMX5 = 0x00030015,
+ HV_X64_REGISTER_FP_MMX6 = 0x00030016,
+ HV_X64_REGISTER_FP_MMX7 = 0x00030017,
+ HV_X64_REGISTER_FP_CONTROL_STATUS = 0x00030018,
+ HV_X64_REGISTER_XMM_CONTROL_STATUS = 0x00030019,
+
+ /* X64 Control Registers */
+ HV_X64_REGISTER_CR0 = 0x00040000,
+ HV_X64_REGISTER_CR2 = 0x00040001,
+ HV_X64_REGISTER_CR3 = 0x00040002,
+ HV_X64_REGISTER_CR4 = 0x00040003,
+ HV_X64_REGISTER_CR8 = 0x00040004,
+ HV_X64_REGISTER_XFEM = 0x00040005,
+
+ /* X64 Segment Registers */
+ HV_X64_REGISTER_ES = 0x00060000,
+ HV_X64_REGISTER_CS = 0x00060001,
+ HV_X64_REGISTER_SS = 0x00060002,
+ HV_X64_REGISTER_DS = 0x00060003,
+ HV_X64_REGISTER_FS = 0x00060004,
+ HV_X64_REGISTER_GS = 0x00060005,
+ HV_X64_REGISTER_LDTR = 0x00060006,
+ HV_X64_REGISTER_TR = 0x00060007,
+
+ /* X64 Table Registers */
+ HV_X64_REGISTER_IDTR = 0x00070000,
+ HV_X64_REGISTER_GDTR = 0x00070001,
+
+ /* X64 Virtualized MSRs */
+ HV_X64_REGISTER_TSC = 0x00080000,
+ HV_X64_REGISTER_EFER = 0x00080001,
+ HV_X64_REGISTER_KERNEL_GS_BASE = 0x00080002,
+ HV_X64_REGISTER_APIC_BASE = 0x00080003,
+ HV_X64_REGISTER_PAT = 0x00080004,
+ HV_X64_REGISTER_SYSENTER_CS = 0x00080005,
+ HV_X64_REGISTER_SYSENTER_EIP = 0x00080006,
+ HV_X64_REGISTER_SYSENTER_ESP = 0x00080007,
+ HV_X64_REGISTER_STAR = 0x00080008,
+ HV_X64_REGISTER_LSTAR = 0x00080009,
+ HV_X64_REGISTER_CSTAR = 0x0008000A,
+ HV_X64_REGISTER_SFMASK = 0x0008000B,
+ HV_X64_REGISTER_INITIAL_APIC_ID = 0x0008000C,
+
+ /* X64 Cache control MSRs */
+ HV_X64_REGISTER_MSR_MTRR_CAP = 0x0008000D,
+ HV_X64_REGISTER_MSR_MTRR_DEF_TYPE = 0x0008000E,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0 = 0x00080010,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1 = 0x00080011,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2 = 0x00080012,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3 = 0x00080013,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4 = 0x00080014,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5 = 0x00080015,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6 = 0x00080016,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7 = 0x00080017,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE8 = 0x00080018,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASE9 = 0x00080019,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASEA = 0x0008001A,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASEB = 0x0008001B,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASEC = 0x0008001C,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASED = 0x0008001D,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASEE = 0x0008001E,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_BASEF = 0x0008001F,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0 = 0x00080040,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1 = 0x00080041,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2 = 0x00080042,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3 = 0x00080043,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4 = 0x00080044,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5 = 0x00080045,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6 = 0x00080046,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7 = 0x00080047,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK8 = 0x00080048,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASK9 = 0x00080049,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASKA = 0x0008004A,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASKB = 0x0008004B,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASKC = 0x0008004C,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASKD = 0x0008004D,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASKE = 0x0008004E,
+ HV_X64_REGISTER_MSR_MTRR_PHYS_MASKF = 0x0008004F,
+ HV_X64_REGISTER_MSR_MTRR_FIX64K00000 = 0x00080070,
+ HV_X64_REGISTER_MSR_MTRR_FIX16K80000 = 0x00080071,
+ HV_X64_REGISTER_MSR_MTRR_FIX16KA0000 = 0x00080072,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KC0000 = 0x00080073,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KC8000 = 0x00080074,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KD0000 = 0x00080075,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KD8000 = 0x00080076,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KE0000 = 0x00080077,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KE8000 = 0x00080078,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KF0000 = 0x00080079,
+ HV_X64_REGISTER_MSR_MTRR_FIX4KF8000 = 0x0008007A,
+
+ HV_X64_REGISTER_TSC_AUX = 0x0008007B,
+ HV_X64_REGISTER_BNDCFGS = 0x0008007C,
+ HV_X64_REGISTER_DEBUG_CTL = 0x0008007D,
+
+ /* Available */
+
+ HV_X64_REGISTER_SPEC_CTRL = 0x00080084,
+ HV_X64_REGISTER_TSC_ADJUST = 0x00080096,
+
+ /* Other MSRs */
+ HV_X64_REGISTER_MSR_IA32_MISC_ENABLE = 0x000800A0,
+
+ /* Misc */
+ HV_REGISTER_GUEST_OS_ID = 0x00090002,
+ HV_REGISTER_REFERENCE_TSC = 0x00090017,
+
+ /* Hypervisor-defined Registers (Synic) */
+ HV_REGISTER_SINT0 = 0x000A0000,
+ HV_REGISTER_SINT1 = 0x000A0001,
+ HV_REGISTER_SINT2 = 0x000A0002,
+ HV_REGISTER_SINT3 = 0x000A0003,
+ HV_REGISTER_SINT4 = 0x000A0004,
+ HV_REGISTER_SINT5 = 0x000A0005,
+ HV_REGISTER_SINT6 = 0x000A0006,
+ HV_REGISTER_SINT7 = 0x000A0007,
+ HV_REGISTER_SINT8 = 0x000A0008,
+ HV_REGISTER_SINT9 = 0x000A0009,
+ HV_REGISTER_SINT10 = 0x000A000A,
+ HV_REGISTER_SINT11 = 0x000A000B,
+ HV_REGISTER_SINT12 = 0x000A000C,
+ HV_REGISTER_SINT13 = 0x000A000D,
+ HV_REGISTER_SINT14 = 0x000A000E,
+ HV_REGISTER_SINT15 = 0x000A000F,
+ HV_REGISTER_SCONTROL = 0x000A0010,
+ HV_REGISTER_SVERSION = 0x000A0011,
+ HV_REGISTER_SIEFP = 0x000A0012,
+ HV_REGISTER_SIMP = 0x000A0013,
+ HV_REGISTER_EOM = 0x000A0014,
+ HV_REGISTER_SIRBP = 0x000A0015,
+} hv_register_name;
+
+enum hv_intercept_type {
+ HV_INTERCEPT_TYPE_X64_IO_PORT = 0X00000000,
+ HV_INTERCEPT_TYPE_X64_MSR = 0X00000001,
+ HV_INTERCEPT_TYPE_X64_CPUID = 0X00000002,
+ HV_INTERCEPT_TYPE_EXCEPTION = 0X00000003,
+
+ /* Used to be HV_INTERCEPT_TYPE_REGISTER */
+ HV_INTERCEPT_TYPE_RESERVED0 = 0X00000004,
+ HV_INTERCEPT_TYPE_MMIO = 0X00000005,
+ HV_INTERCEPT_TYPE_X64_GLOBAL_CPUID = 0X00000006,
+ HV_INTERCEPT_TYPE_X64_APIC_SMI = 0X00000007,
+ HV_INTERCEPT_TYPE_HYPERCALL = 0X00000008,
+
+ HV_INTERCEPT_TYPE_X64_APIC_INIT_SIPI = 0X00000009,
+ HV_INTERCEPT_MC_UPDATE_PATCH_LEVEL_MSR_READ = 0X0000000A,
+
+ HV_INTERCEPT_TYPE_X64_APIC_WRITE = 0X0000000B,
+ HV_INTERCEPT_TYPE_X64_MSR_INDEX = 0X0000000C,
+ HV_INTERCEPT_TYPE_MAX,
+ HV_INTERCEPT_TYPE_INVALID = 0XFFFFFFFF,
+};
+
+struct hv_u128 {
+ uint64_t low_part;
+ uint64_t high_part;
+};
+
+union hv_x64_xmm_control_status_register {
+ struct hv_u128 as_uint128;
+ struct {
+ union {
+ /* long mode */
+ uint64_t last_fp_rdp;
+ /* 32 bit mode */
+ struct {
+ uint32_t last_fp_dp;
+ uint16_t last_fp_ds;
+ uint16_t padding;
+ };
+ };
+ uint32_t xmm_status_control;
+ uint32_t xmm_status_control_mask;
+ };
+};
+
+union hv_x64_fp_register {
+ struct hv_u128 as_uint128;
+ struct {
+ uint64_t mantissa;
+ uint64_t biased_exponent:15;
+ uint64_t sign:1;
+ uint64_t reserved:48;
+ };
+};
+
+union hv_x64_pending_exception_event {
+ uint64_t as_uint64[2];
+ struct {
+ uint32_t event_pending:1;
+ uint32_t event_type:3;
+ uint32_t reserved0:4;
+ uint32_t deliver_error_code:1;
+ uint32_t reserved1:7;
+ uint32_t vector:16;
+ uint32_t error_code;
+ uint64_t exception_parameter;
+ };
+};
+
+union hv_x64_pending_virtualization_fault_event {
+ uint64_t as_uint64[2];
+ struct {
+ uint32_t event_pending:1;
+ uint32_t event_type:3;
+ uint32_t reserved0:4;
+ uint32_t reserved1:8;
+ uint32_t parameter0:16;
+ uint32_t code;
+ uint64_t parameter1;
+ };
+};
+
+union hv_x64_pending_interruption_register {
+ uint64_t as_uint64;
+ struct {
+ uint32_t interruption_pending:1;
+ uint32_t interruption_type:3;
+ uint32_t deliver_error_code:1;
+ uint32_t instruction_length:4;
+ uint32_t nested_event:1;
+ uint32_t reserved:6;
+ uint32_t interruption_vector:16;
+ uint32_t error_code;
+ };
+};
+
+union hv_x64_register_sev_control {
+ uint64_t as_uint64;
+ struct {
+ uint64_t enable_encrypted_state:1;
+ uint64_t reserved_z:11;
+ uint64_t vmsa_gpa_page_number:52;
+ };
+};
+
+union hv_x64_msr_npiep_config_contents {
+ uint64_t as_uint64;
+ struct {
+ /*
+ * These bits enable instruction execution prevention for
+ * specific instructions.
+ */
+ uint64_t prevents_gdt:1;
+ uint64_t prevents_idt:1;
+ uint64_t prevents_ldt:1;
+ uint64_t prevents_tr:1;
+
+ /* The reserved bits must always be 0. */
+ uint64_t reserved:60;
+ };
+};
+
+typedef struct hv_x64_segment_register {
+ uint64_t base;
+ uint32_t limit;
+ uint16_t selector;
+ union {
+ struct {
+ uint16_t segment_type:4;
+ uint16_t non_system_segment:1;
+ uint16_t descriptor_privilege_level:2;
+ uint16_t present:1;
+ uint16_t reserved:4;
+ uint16_t available:1;
+ uint16_t _long:1;
+ uint16_t _default:1;
+ uint16_t granularity:1;
+ };
+ uint16_t attributes;
+ };
+} hv_x64_segment_register;
+
+typedef struct hv_x64_table_register {
+ uint16_t pad[3];
+ uint16_t limit;
+ uint64_t base;
+} hv_x64_table_register;
+
+union hv_x64_fp_control_status_register {
+ struct hv_u128 as_uint128;
+ struct {
+ uint16_t fp_control;
+ uint16_t fp_status;
+ uint8_t fp_tag;
+ uint8_t reserved;
+ uint16_t last_fp_op;
+ union {
+ /* long mode */
+ uint64_t last_fp_rip;
+ /* 32 bit mode */
+ struct {
+ uint32_t last_fp_eip;
+ uint16_t last_fp_cs;
+ uint16_t padding;
+ };
+ };
+ };
+};
+
+/* General Hypervisor Register Content Definitions */
+
+union hv_explicit_suspend_register {
+ uint64_t as_uint64;
+ struct {
+ uint64_t suspended:1;
+ uint64_t reserved:63;
+ };
+};
+
+union hv_internal_activity_register {
+ uint64_t as_uint64;
+
+ struct {
+ uint64_t startup_suspend:1;
+ uint64_t halt_suspend:1;
+ uint64_t idle_suspend:1;
+ uint64_t rsvd_z:61;
+ };
+};
+
+union hv_x64_interrupt_state_register {
+ uint64_t as_uint64;
+ struct {
+ uint64_t interrupt_shadow:1;
+ uint64_t nmi_masked:1;
+ uint64_t reserved:62;
+ };
+};
+
+union hv_intercept_suspend_register {
+ uint64_t as_uint64;
+ struct {
+ uint64_t suspended:1;
+ uint64_t reserved:63;
+ };
+};
+
+typedef union hv_register_value {
+ struct hv_u128 reg128;
+ uint64_t reg64;
+ uint32_t reg32;
+ uint16_t reg16;
+ uint8_t reg8;
+ union hv_x64_fp_register fp;
+ union hv_x64_fp_control_status_register fp_control_status;
+ union hv_x64_xmm_control_status_register xmm_control_status;
+ struct hv_x64_segment_register segment;
+ struct hv_x64_table_register table;
+ union hv_explicit_suspend_register explicit_suspend;
+ union hv_intercept_suspend_register intercept_suspend;
+ union hv_internal_activity_register internal_activity;
+ union hv_x64_interrupt_state_register interrupt_state;
+ union hv_x64_pending_interruption_register pending_interruption;
+ union hv_x64_msr_npiep_config_contents npiep_config;
+ union hv_x64_pending_exception_event pending_exception_event;
+ union hv_x64_pending_virtualization_fault_event
+ pending_virtualization_fault_event;
+ union hv_x64_register_sev_control sev_control;
+} hv_register_value;
+
+typedef struct hv_register_assoc {
+ uint32_t name; /* enum hv_register_name */
+ uint32_t reserved1;
+ uint64_t reserved2;
+ union hv_register_value value;
+} hv_register_assoc;
+
+union hv_input_vtl {
+ uint8_t as_uint8;
+ struct {
+ uint8_t target_vtl:4;
+ uint8_t use_target_vtl:1;
+ uint8_t reserved_z:3;
+ };
+};
+
+typedef struct hv_input_get_vp_registers {
+ uint64_t partition_id;
+ uint32_t vp_index;
+ union hv_input_vtl input_vtl;
+ uint8_t rsvd_z8;
+ uint16_t rsvd_z16;
+ uint32_t names[];
+} hv_input_get_vp_registers;
+
+typedef struct hv_input_set_vp_registers {
+ uint64_t partition_id;
+ uint32_t vp_index;
+ union hv_input_vtl input_vtl;
+ uint8_t rsvd_z8;
+ uint16_t rsvd_z16;
+ struct hv_register_assoc elements[];
+} hv_input_set_vp_registers;
+
+#define MSHV_VP_MAX_REGISTERS 128
+
+struct mshv_vp_registers {
+ int count; /* at most MSHV_VP_MAX_REGISTERS */
+ struct hv_register_assoc *regs;
+};
+
+union hv_interrupt_control {
+ uint64_t as_uint64;
+ struct {
+ uint32_t interrupt_type; /* enum hv_interrupt type */
+ uint32_t level_triggered:1;
+ uint32_t logical_dest_mode:1;
+ uint32_t rsvd:30;
+ };
+};
+
+struct hv_input_assert_virtual_interrupt {
+ uint64_t partition_id;
+ union hv_interrupt_control control;
+ uint64_t dest_addr; /* cpu's apic id */
+ uint32_t vector;
+ uint8_t target_vtl;
+ uint8_t rsvd_z0;
+ uint16_t rsvd_z1;
+};
+
+/* /dev/mshv */
+#define MSHV_CREATE_PARTITION _IOW(MSHV_IOCTL, 0x00, struct mshv_create_partition)
+#define MSHV_CREATE_VP _IOW(MSHV_IOCTL, 0x01, struct mshv_create_vp)
+
+/* Partition fds created with MSHV_CREATE_PARTITION */
+#define MSHV_INITIALIZE_PARTITION _IO(MSHV_IOCTL, 0x00)
+#define MSHV_SET_GUEST_MEMORY _IOW(MSHV_IOCTL, 0x02, struct mshv_user_mem_region)
+#define MSHV_IRQFD _IOW(MSHV_IOCTL, 0x03, struct mshv_user_irqfd)
+#define MSHV_IOEVENTFD _IOW(MSHV_IOCTL, 0x04, struct mshv_user_ioeventfd)
+#define MSHV_SET_MSI_ROUTING _IOW(MSHV_IOCTL, 0x05, struct mshv_user_irq_table)
+
+/*
+ ********************************
+ * VP APIs for child partitions *
+ ********************************
+ */
+
+struct hv_local_interrupt_controller_state {
+ /* HV_X64_INTERRUPT_CONTROLLER_STATE */
+ uint32_t apic_id;
+ uint32_t apic_version;
+ uint32_t apic_ldr;
+ uint32_t apic_dfr;
+ uint32_t apic_spurious;
+ uint32_t apic_isr[8];
+ uint32_t apic_tmr[8];
+ uint32_t apic_irr[8];
+ uint32_t apic_esr;
+ uint32_t apic_icr_high;
+ uint32_t apic_icr_low;
+ uint32_t apic_lvt_timer;
+ uint32_t apic_lvt_thermal;
+ uint32_t apic_lvt_perfmon;
+ uint32_t apic_lvt_lint0;
+ uint32_t apic_lvt_lint1;
+ uint32_t apic_lvt_error;
+ uint32_t apic_lvt_cmci;
+ uint32_t apic_error_status;
+ uint32_t apic_initial_count;
+ uint32_t apic_counter_value;
+ uint32_t apic_divide_configuration;
+ uint32_t apic_remote_read;
+};
+
+/* Generic hypercall */
+#define MSHV_ROOT_HVCALL _IOWR(MSHV_IOCTL, 0x07, struct mshv_root_hvcall)
+
+/* From hvgdk_mini.h */
+
+#define HV_X64_MSR_GUEST_OS_ID 0x40000000
+#define HV_X64_MSR_SINT0 0x40000090
+#define HV_X64_MSR_SINT1 0x40000091
+#define HV_X64_MSR_SINT2 0x40000092
+#define HV_X64_MSR_SINT3 0x40000093
+#define HV_X64_MSR_SINT4 0x40000094
+#define HV_X64_MSR_SINT5 0x40000095
+#define HV_X64_MSR_SINT6 0x40000096
+#define HV_X64_MSR_SINT7 0x40000097
+#define HV_X64_MSR_SINT8 0x40000098
+#define HV_X64_MSR_SINT9 0x40000099
+#define HV_X64_MSR_SINT10 0x4000009A
+#define HV_X64_MSR_SINT11 0x4000009B
+#define HV_X64_MSR_SINT12 0x4000009C
+#define HV_X64_MSR_SINT13 0x4000009D
+#define HV_X64_MSR_SINT14 0x4000009E
+#define HV_X64_MSR_SINT15 0x4000009F
+#define HV_X64_MSR_SCONTROL 0x40000080
+#define HV_X64_MSR_SIEFP 0x40000082
+#define HV_X64_MSR_SIMP 0x40000083
+#define HV_X64_MSR_REFERENCE_TSC 0x40000021
+#define HV_X64_MSR_EOM 0x40000084
+
+/* Define port identifier type. */
+union hv_port_id {
+ uint32_t asuint32_t;
+ struct {
+ uint32_t id:24;
+ uint32_t reserved:8;
+ };
+};
+
+#define HV_MESSAGE_SIZE (256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
+
+/* Define hypervisor message types. */
+enum hv_message_type {
+ HVMSG_NONE = 0x00000000,
+
+ /* Memory access messages. */
+ HVMSG_UNMAPPED_GPA = 0x80000000,
+ HVMSG_GPA_INTERCEPT = 0x80000001,
+ HVMSG_UNACCEPTED_GPA = 0x80000003,
+ HVMSG_GPA_ATTRIBUTE_INTERCEPT = 0x80000004,
+
+ /* Timer notification messages. */
+ HVMSG_TIMER_EXPIRED = 0x80000010,
+
+ /* Error messages. */
+ HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
+ HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
+ HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
+
+ /*
+ * Opaque intercept message. The original intercept message is only
+ * accessible from the mapped intercept message page.
+ */
+ HVMSG_OPAQUE_INTERCEPT = 0x8000003F,
+
+ /* Trace buffer complete messages. */
+ HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
+
+ /* Hypercall intercept */
+ HVMSG_HYPERCALL_INTERCEPT = 0x80000050,
+
+ /* SynIC intercepts */
+ HVMSG_SYNIC_EVENT_INTERCEPT = 0x80000060,
+ HVMSG_SYNIC_SINT_INTERCEPT = 0x80000061,
+ HVMSG_SYNIC_SINT_DELIVERABLE = 0x80000062,
+
+ /* Async call completion intercept */
+ HVMSG_ASYNC_CALL_COMPLETION = 0x80000070,
+
+ /* Root scheduler messages */
+ HVMSG_SCHEDULER_VP_SIGNAL_BITSE = 0x80000100,
+ HVMSG_SCHEDULER_VP_SIGNAL_PAIR = 0x80000101,
+
+ /* Platform-specific processor intercept messages. */
+ HVMSG_X64_IO_PORT_INTERCEPT = 0x80010000,
+ HVMSG_X64_MSR_INTERCEPT = 0x80010001,
+ HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
+ HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
+ HVMSG_X64_APIC_EOI = 0x80010004,
+ HVMSG_X64_LEGACY_FP_ERROR = 0x80010005,
+ HVMSG_X64_IOMMU_PRQ = 0x80010006,
+ HVMSG_X64_HALT = 0x80010007,
+ HVMSG_X64_INTERRUPTION_DELIVERABLE = 0x80010008,
+ HVMSG_X64_SIPI_INTERCEPT = 0x80010009,
+ HVMSG_X64_SEV_VMGEXIT_INTERCEPT = 0x80010013,
+};
+
+union hv_x64_vp_execution_state {
+ uint16_t as_uint16;
+ struct {
+ uint16_t cpl:2;
+ uint16_t cr0_pe:1;
+ uint16_t cr0_am:1;
+ uint16_t efer_lma:1;
+ uint16_t debug_active:1;
+ uint16_t interruption_pending:1;
+ uint16_t vtl:4;
+ uint16_t enclave_mode:1;
+ uint16_t interrupt_shadow:1;
+ uint16_t virtualization_fault_active:1;
+ uint16_t reserved:2;
+ };
+};
+
+/* From openvmm::hvdef */
+enum hv_x64_intercept_access_type {
+ HV_X64_INTERCEPT_ACCESS_TYPE_READ = 0,
+ HV_X64_INTERCEPT_ACCESS_TYPE_WRITE = 1,
+ HV_X64_INTERCEPT_ACCESS_TYPE_EXECUTE = 2,
+};
+
+struct hv_x64_intercept_message_header {
+ uint32_t vp_index;
+ uint8_t instruction_length:4;
+ uint8_t cr8:4; /* Only set for exo partitions */
+ uint8_t intercept_access_type;
+ union hv_x64_vp_execution_state execution_state;
+ struct hv_x64_segment_register cs_segment;
+ uint64_t rip;
+ uint64_t rflags;
+};
+
+union hv_x64_io_port_access_info {
+ uint8_t as_uint8;
+ struct {
+ uint8_t access_size:3;
+ uint8_t string_op:1;
+ uint8_t rep_prefix:1;
+ uint8_t reserved:3;
+ };
+};
+
+typedef struct hv_x64_io_port_intercept_message {
+ struct hv_x64_intercept_message_header header;
+ uint16_t port_number;
+ union hv_x64_io_port_access_info access_info;
+ uint8_t instruction_byte_count;
+ uint32_t reserved;
+ uint64_t rax;
+ uint8_t instruction_bytes[16];
+ struct hv_x64_segment_register ds_segment;
+ struct hv_x64_segment_register es_segment;
+ uint64_t rcx;
+ uint64_t rsi;
+ uint64_t rdi;
+} hv_x64_io_port_intercept_message;
+
+union hv_x64_memory_access_info {
+ uint8_t as_uint8;
+ struct {
+ uint8_t gva_valid:1;
+ uint8_t gva_gpa_valid:1;
+ uint8_t hypercall_output_pending:1;
+ uint8_t tlb_locked_no_overlay:1;
+ uint8_t reserved:4;
+ };
+};
+
+struct hv_x64_memory_intercept_message {
+ struct hv_x64_intercept_message_header header;
+ uint32_t cache_type; /* enum hv_cache_type */
+ uint8_t instruction_byte_count;
+ union hv_x64_memory_access_info memory_access_info;
+ uint8_t tpr_priority;
+ uint8_t reserved1;
+ uint64_t guest_virtual_address;
+ uint64_t guest_physical_address;
+ uint8_t instruction_bytes[16];
+};
+
+union hv_message_flags {
+ uint8_t asu8;
+ struct {
+ uint8_t msg_pending:1;
+ uint8_t reserved:7;
+ };
+};
+
+struct hv_message_header {
+ uint32_t message_type;
+ uint8_t payload_size;
+ union hv_message_flags message_flags;
+ uint8_t reserved[2];
+ union {
+ uint64_t sender;
+ union hv_port_id port;
+ };
+};
+
+struct hv_message {
+ struct hv_message_header header;
+ union {
+ uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+ } u;
+};
+
+/* From github.com/rust-vmm/mshv-bindings/src/x86_64/regs.rs */
+
+struct hv_cpuid_entry {
+ uint32_t function;
+ uint32_t index;
+ uint32_t flags;
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t padding[3];
+};
+
+struct hv_cpuid {
+ uint32_t nent;
+ uint32_t padding;
+ struct hv_cpuid_entry entries[0];
+};
+
+#define IA32_MSR_TSC 0x00000010
+#define IA32_MSR_EFER 0xC0000080
+#define IA32_MSR_KERNEL_GS_BASE 0xC0000102
+#define IA32_MSR_APIC_BASE 0x0000001B
+#define IA32_MSR_PAT 0x0277
+#define IA32_MSR_SYSENTER_CS 0x00000174
+#define IA32_MSR_SYSENTER_ESP 0x00000175
+#define IA32_MSR_SYSENTER_EIP 0x00000176
+#define IA32_MSR_STAR 0xC0000081
+#define IA32_MSR_LSTAR 0xC0000082
+#define IA32_MSR_CSTAR 0xC0000083
+#define IA32_MSR_SFMASK 0xC0000084
+
+#define IA32_MSR_MTRR_CAP 0x00FE
+#define IA32_MSR_MTRR_DEF_TYPE 0x02FF
+#define IA32_MSR_MTRR_PHYSBASE0 0x0200
+#define IA32_MSR_MTRR_PHYSMASK0 0x0201
+#define IA32_MSR_MTRR_PHYSBASE1 0x0202
+#define IA32_MSR_MTRR_PHYSMASK1 0x0203
+#define IA32_MSR_MTRR_PHYSBASE2 0x0204
+#define IA32_MSR_MTRR_PHYSMASK2 0x0205
+#define IA32_MSR_MTRR_PHYSBASE3 0x0206
+#define IA32_MSR_MTRR_PHYSMASK3 0x0207
+#define IA32_MSR_MTRR_PHYSBASE4 0x0208
+#define IA32_MSR_MTRR_PHYSMASK4 0x0209
+#define IA32_MSR_MTRR_PHYSBASE5 0x020A
+#define IA32_MSR_MTRR_PHYSMASK5 0x020B
+#define IA32_MSR_MTRR_PHYSBASE6 0x020C
+#define IA32_MSR_MTRR_PHYSMASK6 0x020D
+#define IA32_MSR_MTRR_PHYSBASE7 0x020E
+#define IA32_MSR_MTRR_PHYSMASK7 0x020F
+
+#define IA32_MSR_MTRR_FIX64K_00000 0x0250
+#define IA32_MSR_MTRR_FIX16K_80000 0x0258
+#define IA32_MSR_MTRR_FIX16K_A0000 0x0259
+#define IA32_MSR_MTRR_FIX4K_C0000 0x0268
+#define IA32_MSR_MTRR_FIX4K_C8000 0x0269
+#define IA32_MSR_MTRR_FIX4K_D0000 0x026A
+#define IA32_MSR_MTRR_FIX4K_D8000 0x026B
+#define IA32_MSR_MTRR_FIX4K_E0000 0x026C
+#define IA32_MSR_MTRR_FIX4K_E8000 0x026D
+#define IA32_MSR_MTRR_FIX4K_F0000 0x026E
+#define IA32_MSR_MTRR_FIX4K_F8000 0x026F
+
+#define IA32_MSR_TSC_AUX 0xC0000103
+#define IA32_MSR_BNDCFGS 0x00000d90
+#define IA32_MSR_DEBUG_CTL 0x1D9
+#define IA32_MSR_SPEC_CTRL 0x00000048
+#define IA32_MSR_TSC_ADJUST 0x0000003b
+
+#define IA32_MSR_MISC_ENABLE 0x000001a0
+
+#define HV_TRANSLATE_GVA_VALIDATE_READ (0x0001)
+#define HV_TRANSLATE_GVA_VALIDATE_WRITE (0x0002)
+#define HV_TRANSLATE_GVA_VALIDATE_EXECUTE (0x0004)
+
+#define HV_HYP_PAGE_SHIFT 12
+#define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT)
+#define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))
+
+#define HVCALL_GET_PARTITION_PROPERTY 0x0044
+#define HVCALL_SET_PARTITION_PROPERTY 0x0045
+#define HVCALL_GET_VP_REGISTERS 0x0050
+#define HVCALL_SET_VP_REGISTERS 0x0051
+#define HVCALL_TRANSLATE_VIRTUAL_ADDRESS 0x0052
+#define HVCALL_REGISTER_INTERCEPT_RESULT 0x0091
+#define HVCALL_ASSERT_VIRTUAL_INTERRUPT 0x0094
+
+#endif /* HW_HYPERV_HVGDK_MINI_H */
diff --git a/include/hw/hyperv/hvhdk.h b/include/hw/hyperv/hvhdk.h
new file mode 100644
index 0000000..866c821
--- /dev/null
+++ b/include/hw/hyperv/hvhdk.h
@@ -0,0 +1,249 @@
+/*
+ * Type definitions for the mshv host.
+ *
+ * Copyright Microsoft, Corp. 2025
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_HYPERV_HVHDK_H
+#define HW_HYPERV_HVHDK_H
+
+#define HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS 1
+
+struct hv_input_set_partition_property {
+ uint64_t partition_id;
+ uint32_t property_code; /* enum hv_partition_property_code */
+ uint32_t padding;
+ uint64_t property_value;
+};
+
+union hv_partition_synthetic_processor_features {
+ uint64_t as_uint64[HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS];
+
+ struct {
+ /*
+ * Report a hypervisor is present. CPUID leaves
+ * 0x40000000 and 0x40000001 are supported.
+ */
+ uint64_t hypervisor_present:1;
+
+ /*
+ * Features associated with HV#1:
+ */
+
+ /* Report support for Hv1 (CPUID leaves 0x40000000 - 0x40000006). */
+ uint64_t hv1:1;
+
+ /*
+ * Access to HV_X64_MSR_VP_RUNTIME.
+ * Corresponds to access_vp_run_time_reg privilege.
+ */
+ uint64_t access_vp_run_time_reg:1;
+
+ /*
+ * Access to HV_X64_MSR_TIME_REF_COUNT.
+ * Corresponds to access_partition_reference_counter privilege.
+ */
+ uint64_t access_partition_reference_counter:1;
+
+ /*
+ * Access to SINT-related registers (HV_X64_MSR_SCONTROL through
+ * HV_X64_MSR_EOM and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15).
+ * Corresponds to access_synic_regs privilege.
+ */
+ uint64_t access_synic_regs:1;
+
+ /*
+ * Access to synthetic timers and associated MSRs
+ * (HV_X64_MSR_STIMER0_CONFIG through HV_X64_MSR_STIMER3_COUNT).
+ * Corresponds to access_synthetic_timer_regs privilege.
+ */
+ uint64_t access_synthetic_timer_regs:1;
+
+ /*
+ * Access to APIC MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and
+ * HV_X64_MSR_TPR) as well as the VP assist page.
+ * Corresponds to access_intr_ctrl_regs privilege.
+ */
+ uint64_t access_intr_ctrl_regs:1;
+
+ /*
+ * Access to registers associated with hypercalls
+ * (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL).
+ * Corresponds to access_hypercall_msrs privilege.
+ */
+ uint64_t access_hypercall_regs:1;
+
+ /* VP index can be queried. corresponds to access_vp_index privilege. */
+ uint64_t access_vp_index:1;
+
+ /*
+ * Access to the reference TSC. Corresponds to
+ * access_partition_reference_tsc privilege.
+ */
+ uint64_t access_partition_reference_tsc:1;
+
+ /*
+ * Partition has access to the guest idle reg. Corresponds to
+ * access_guest_idle_reg privilege.
+ */
+ uint64_t access_guest_idle_reg:1;
+
+ /*
+ * Partition has access to frequency regs. corresponds to
+ * access_frequency_regs privilege.
+ */
+ uint64_t access_frequency_regs:1;
+
+ uint64_t reserved_z12:1; /* Reserved for access_reenlightenment_controls */
+ uint64_t reserved_z13:1; /* Reserved for access_root_scheduler_reg */
+ uint64_t reserved_z14:1; /* Reserved for access_tsc_invariant_controls */
+
+ /*
+ * Extended GVA ranges for HvCallFlushVirtualAddressList hypercall.
+ * Corresponds to privilege.
+ */
+ uint64_t enable_extended_gva_ranges_for_flush_virtual_address_list:1;
+
+ uint64_t reserved_z16:1; /* Reserved for access_vsm. */
+ uint64_t reserved_z17:1; /* Reserved for access_vp_registers. */
+
+ /* Use fast hypercall output. Corresponds to privilege. */
+ uint64_t fast_hypercall_output:1;
+
+ uint64_t reserved_z19:1; /* Reserved for enable_extended_hypercalls. */
+
+ /*
+ * HvStartVirtualProcessor can be used to start virtual processors.
+ * Corresponds to privilege.
+ */
+ uint64_t start_virtual_processor:1;
+
+ uint64_t reserved_z21:1; /* Reserved for Isolation. */
+
+ /* Synthetic timers in direct mode. */
+ uint64_t direct_synthetic_timers:1;
+
+ uint64_t reserved_z23:1; /* Reserved for synthetic time unhalted timer */
+
+ /* Use extended processor masks. */
+ uint64_t extended_processor_masks:1;
+
+ /*
+ * HvCallFlushVirtualAddressSpace / HvCallFlushVirtualAddressList are
+ * supported.
+ */
+ uint64_t tb_flush_hypercalls:1;
+
+ /* HvCallSendSyntheticClusterIpi is supported. */
+ uint64_t synthetic_cluster_ipi:1;
+
+ /* HvCallNotifyLongSpinWait is supported. */
+ uint64_t notify_long_spin_wait:1;
+
+ /* HvCallQueryNumaDistance is supported. */
+ uint64_t query_numa_distance:1;
+
+ /* HvCallSignalEvent is supported. Corresponds to privilege. */
+ uint64_t signal_events:1;
+
+ /* HvCallRetargetDeviceInterrupt is supported. */
+ uint64_t retarget_device_interrupt:1;
+
+ /* HvCallRestorePartitionTime is supported. */
+ uint64_t restore_time:1;
+
+ /* EnlightenedVmcs nested enlightenment is supported. */
+ uint64_t enlightened_vmcs:1;
+
+ uint64_t reserved:30;
+ };
+};
+
+enum hv_translate_gva_result_code {
+ HV_TRANSLATE_GVA_SUCCESS = 0,
+
+ /* Translation failures. */
+ HV_TRANSLATE_GVA_PAGE_NOT_PRESENT = 1,
+ HV_TRANSLATE_GVA_PRIVILEGE_VIOLATION = 2,
+ HV_TRANSLATE_GVA_INVALIDE_PAGE_TABLE_FLAGS = 3,
+
+ /* GPA access failures. */
+ HV_TRANSLATE_GVA_GPA_UNMAPPED = 4,
+ HV_TRANSLATE_GVA_GPA_NO_READ_ACCESS = 5,
+ HV_TRANSLATE_GVA_GPA_NO_WRITE_ACCESS = 6,
+ HV_TRANSLATE_GVA_GPA_ILLEGAL_OVERLAY_ACCESS = 7,
+
+ /*
+ * Intercept for memory access by either
+ * - a higher VTL
+ * - a nested hypervisor (due to a violation of the nested page table)
+ */
+ HV_TRANSLATE_GVA_INTERCEPT = 8,
+
+ HV_TRANSLATE_GVA_GPA_UNACCEPTED = 9,
+};
+
+union hv_translate_gva_result {
+ uint64_t as_uint64;
+ struct {
+ uint32_t result_code; /* enum hv_translate_hva_result_code */
+ uint32_t cache_type:8;
+ uint32_t overlay_page:1;
+ uint32_t reserved:23;
+ };
+};
+
+typedef struct hv_input_translate_virtual_address {
+ uint64_t partition_id;
+ uint32_t vp_index;
+ uint32_t padding;
+ uint64_t control_flags;
+ uint64_t gva_page;
+} hv_input_translate_virtual_address;
+
+typedef struct hv_output_translate_virtual_address {
+ union hv_translate_gva_result translation_result;
+ uint64_t gpa_page;
+} hv_output_translate_virtual_address;
+
+typedef struct hv_register_x64_cpuid_result_parameters {
+ struct {
+ uint32_t eax;
+ uint32_t ecx;
+ uint8_t subleaf_specific;
+ uint8_t always_override;
+ uint16_t padding;
+ } input;
+ struct {
+ uint32_t eax;
+ uint32_t eax_mask;
+ uint32_t ebx;
+ uint32_t ebx_mask;
+ uint32_t ecx;
+ uint32_t ecx_mask;
+ uint32_t edx;
+ uint32_t edx_mask;
+ } result;
+} hv_register_x64_cpuid_result_parameters;
+
+typedef struct hv_register_x64_msr_result_parameters {
+ uint32_t msr_index;
+ uint32_t access_type;
+ uint32_t action; /* enum hv_unimplemented_msr_action */
+} hv_register_x64_msr_result_parameters;
+
+union hv_register_intercept_result_parameters {
+ struct hv_register_x64_cpuid_result_parameters cpuid;
+ struct hv_register_x64_msr_result_parameters msr;
+};
+
+typedef struct hv_input_register_intercept_result {
+ uint64_t partition_id;
+ uint32_t vp_index;
+ uint32_t intercept_type; /* enum hv_intercept_type */
+ union hv_register_intercept_result_parameters parameters;
+} hv_input_register_intercept_result;
+
+#endif /* HW_HYPERV_HVHDK_H */
diff --git a/include/hw/hyperv/hvhdk_mini.h b/include/hw/hyperv/hvhdk_mini.h
new file mode 100644
index 0000000..9c2f3cf
--- /dev/null
+++ b/include/hw/hyperv/hvhdk_mini.h
@@ -0,0 +1,102 @@
+/*
+ * Type definitions for the mshv host interface.
+ *
+ * Copyright Microsoft, Corp. 2025
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_HYPERV_HVHDK_MINI_H
+#define HW_HYPERV_HVHDK_MINI_H
+
+#define HVHVK_MINI_VERSION (25294)
+
+/* Each generic set contains 64 elements */
+#define HV_GENERIC_SET_SHIFT (6)
+#define HV_GENERIC_SET_MASK (63)
+
+enum hv_generic_set_format {
+ HV_GENERIC_SET_SPARSE_4K,
+ HV_GENERIC_SET_ALL,
+};
+
+enum hv_partition_property_code {
+ /* Privilege properties */
+ HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS = 0x00010000,
+ HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES = 0x00010001,
+
+ /* Scheduling properties */
+ HV_PARTITION_PROPERTY_SUSPEND = 0x00020000,
+ HV_PARTITION_PROPERTY_CPU_RESERVE = 0x00020001,
+ HV_PARTITION_PROPERTY_CPU_CAP = 0x00020002,
+ HV_PARTITION_PROPERTY_CPU_WEIGHT = 0x00020003,
+ HV_PARTITION_PROPERTY_CPU_GROUP_ID = 0x00020004,
+
+ /* Time properties */
+ HV_PARTITION_PROPERTY_TIME_FREEZE = 0x00030003,
+ HV_PARTITION_PROPERTY_REFERENCE_TIME = 0x00030005,
+
+ /* Debugging properties */
+ HV_PARTITION_PROPERTY_DEBUG_CHANNEL_ID = 0x00040000,
+
+ /* Resource properties */
+ HV_PARTITION_PROPERTY_VIRTUAL_TLB_PAGE_COUNT = 0x00050000,
+ HV_PARTITION_PROPERTY_VSM_CONFIG = 0x00050001,
+ HV_PARTITION_PROPERTY_ZERO_MEMORY_ON_RESET = 0x00050002,
+ HV_PARTITION_PROPERTY_PROCESSORS_PER_SOCKET = 0x00050003,
+ HV_PARTITION_PROPERTY_NESTED_TLB_SIZE = 0x00050004,
+ HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING = 0x00050005,
+ HV_PARTITION_PROPERTY_VSM_PERMISSIONS_DIRTY_SINCE_LAST_QUERY = 0x00050006,
+ HV_PARTITION_PROPERTY_SGX_LAUNCH_CONTROL_CONFIG = 0x00050007,
+ HV_PARTITION_PROPERTY_DEFAULT_SGX_LAUNCH_CONTROL0 = 0x00050008,
+ HV_PARTITION_PROPERTY_DEFAULT_SGX_LAUNCH_CONTROL1 = 0x00050009,
+ HV_PARTITION_PROPERTY_DEFAULT_SGX_LAUNCH_CONTROL2 = 0x0005000a,
+ HV_PARTITION_PROPERTY_DEFAULT_SGX_LAUNCH_CONTROL3 = 0x0005000b,
+ HV_PARTITION_PROPERTY_ISOLATION_STATE = 0x0005000c,
+ HV_PARTITION_PROPERTY_ISOLATION_CONTROL = 0x0005000d,
+ HV_PARTITION_PROPERTY_ALLOCATION_ID = 0x0005000e,
+ HV_PARTITION_PROPERTY_MONITORING_ID = 0x0005000f,
+ HV_PARTITION_PROPERTY_IMPLEMENTED_PHYSICAL_ADDRESS_BITS = 0x00050010,
+ HV_PARTITION_PROPERTY_NON_ARCHITECTURAL_CORE_SHARING = 0x00050011,
+ HV_PARTITION_PROPERTY_HYPERCALL_DOORBELL_PAGE = 0x00050012,
+ HV_PARTITION_PROPERTY_ISOLATION_POLICY = 0x00050014,
+ HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION = 0x00050017,
+ HV_PARTITION_PROPERTY_SEV_VMGEXIT_OFFLOADS = 0x00050022,
+
+ /* Compatibility properties */
+ HV_PARTITION_PROPERTY_PROCESSOR_VENDOR = 0x00060000,
+ HV_PARTITION_PROPERTY_PROCESSOR_FEATURES_DEPRECATED = 0x00060001,
+ HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES = 0x00060002,
+ HV_PARTITION_PROPERTY_PROCESSOR_CL_FLUSH_SIZE = 0x00060003,
+ HV_PARTITION_PROPERTY_ENLIGHTENMENT_MODIFICATIONS = 0x00060004,
+ HV_PARTITION_PROPERTY_COMPATIBILITY_VERSION = 0x00060005,
+ HV_PARTITION_PROPERTY_PHYSICAL_ADDRESS_WIDTH = 0x00060006,
+ HV_PARTITION_PROPERTY_XSAVE_STATES = 0x00060007,
+ HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE = 0x00060008,
+ HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY = 0x00060009,
+ HV_PARTITION_PROPERTY_PROCESSOR_FEATURES0 = 0x0006000a,
+ HV_PARTITION_PROPERTY_PROCESSOR_FEATURES1 = 0x0006000b,
+
+ /* Guest software properties */
+ HV_PARTITION_PROPERTY_GUEST_OS_ID = 0x00070000,
+
+ /* Nested virtualization properties */
+ HV_PARTITION_PROPERTY_PROCESSOR_VIRTUALIZATION_FEATURES = 0x00080000,
+};
+
+/* HV Map GPA (Guest Physical Address) Flags */
+#define HV_MAP_GPA_PERMISSIONS_NONE 0x0
+#define HV_MAP_GPA_READABLE 0x1
+#define HV_MAP_GPA_WRITABLE 0x2
+#define HV_MAP_GPA_KERNEL_EXECUTABLE 0x4
+#define HV_MAP_GPA_USER_EXECUTABLE 0x8
+#define HV_MAP_GPA_EXECUTABLE 0xC
+#define HV_MAP_GPA_PERMISSIONS_MASK 0xF
+#define HV_MAP_GPA_ADJUSTABLE 0x8000
+#define HV_MAP_GPA_NO_ACCESS 0x10000
+#define HV_MAP_GPA_NOT_CACHED 0x200000
+#define HV_MAP_GPA_LARGE_PAGE 0x80000000
+
+#define HV_PFN_RNG_PAGEBITS 24 /* HV_SPA_PAGE_RANGE_ADDITIONAL_PAGES_BITS */
+
+#endif /* HW_HYPERV_HVHDK_MINI_H */
diff --git a/include/hw/hyperv/hyperv.h b/include/hw/hyperv/hyperv.h
index d717b4e..63a8b65 100644
--- a/include/hw/hyperv/hyperv.h
+++ b/include/hw/hyperv/hyperv.h
@@ -10,7 +10,8 @@
#ifndef HW_HYPERV_HYPERV_H
#define HW_HYPERV_HYPERV_H
-#include "cpu-qom.h"
+#include "exec/hwaddr.h"
+#include "hw/core/cpu.h"
#include "hw/hyperv/hyperv-proto.h"
typedef struct HvSintRoute HvSintRoute;
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
index 2c4c81b..2daacc1 100644
--- a/include/hw/i2c/aspeed_i2c.h
+++ b/include/hw/i2c/aspeed_i2c.h
@@ -14,8 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef ASPEED_I2C_H
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index e95477e..47730ac 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -110,6 +110,7 @@ struct VTDAddressSpace {
QLIST_ENTRY(VTDAddressSpace) next;
/* Superset of notifier flags that this address space has */
IOMMUNotifierFlag notifier_flags;
+ IOMMUPRINotifier *pri_notifier;
/*
* @iova_tree traces mapped IOVA ranges.
*
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9563674..e83157a 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -107,7 +107,6 @@ struct PCMachineClass {
/* RAM / address space compat: */
bool gigabyte_align;
bool has_reserved_memory;
- bool broken_reserved_end;
bool enforce_amd_1tb_hole;
bool isa_bios_alias;
@@ -215,6 +214,9 @@ void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size);
/* sgx.c */
void pc_machine_init_sgx_epc(PCMachineState *pcms);
+extern GlobalProperty pc_compat_10_1[];
+extern const size_t pc_compat_10_1_len;
+
extern GlobalProperty pc_compat_10_0[];
extern const size_t pc_compat_10_0_len;
@@ -299,12 +301,6 @@ extern const size_t pc_compat_2_7_len;
extern GlobalProperty pc_compat_2_6[];
extern const size_t pc_compat_2_6_len;
-extern GlobalProperty pc_compat_2_5[];
-extern const size_t pc_compat_2_5_len;
-
-extern GlobalProperty pc_compat_2_4[];
-extern const size_t pc_compat_2_4_len;
-
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
static void pc_machine_##suffix##_class_init(ObjectClass *oc, \
const void *data) \
diff --git a/include/hw/i386/tdvf.h b/include/hw/i386/tdvf.h
new file mode 100644
index 0000000..e75c8d1
--- /dev/null
+++ b/include/hw/i386/tdvf.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2025 Intel Corporation
+ * Author: Isaku Yamahata <isaku.yamahata at gmail.com>
+ * <isaku.yamahata at intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_I386_TDVF_H
+#define HW_I386_TDVF_H
+
+#include "qemu/osdep.h"
+
+#define TDVF_SECTION_TYPE_BFV 0
+#define TDVF_SECTION_TYPE_CFV 1
+#define TDVF_SECTION_TYPE_TD_HOB 2
+#define TDVF_SECTION_TYPE_TEMP_MEM 3
+
+#define TDVF_SECTION_ATTRIBUTES_MR_EXTEND (1U << 0)
+#define TDVF_SECTION_ATTRIBUTES_PAGE_AUG (1U << 1)
+
+typedef struct TdxFirmwareEntry {
+ uint32_t data_offset;
+ uint32_t data_len;
+ uint64_t address;
+ uint64_t size;
+ uint32_t type;
+ uint32_t attributes;
+
+ void *mem_ptr;
+} TdxFirmwareEntry;
+
+typedef struct TdxFirmware {
+ void *mem_ptr;
+
+ uint32_t nr_entries;
+ TdxFirmwareEntry *entries;
+} TdxFirmware;
+
+#define for_each_tdx_fw_entry(fw, e) \
+ for (e = (fw)->entries; e != (fw)->entries + (fw)->nr_entries; e++)
+
+int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size);
+
+#endif /* HW_I386_TDVF_H */
diff --git a/include/hw/i386/x86-iommu.h b/include/hw/i386/x86-iommu.h
index bfd2164..e89f55a 100644
--- a/include/hw/i386/x86-iommu.h
+++ b/include/hw/i386/x86-iommu.h
@@ -64,6 +64,7 @@ struct X86IOMMUState {
OnOffAuto intr_supported; /* Whether vIOMMU supports IR */
bool dt_supported; /* Whether vIOMMU supports DT */
bool pt_supported; /* Whether vIOMMU supports pass-through */
+ bool dma_translation; /* Whether vIOMMU supports DMA translation */
QLIST_HEAD(, IEC_Notifier) iec_notifiers; /* IEC notify list */
};
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 258b134..8755cad 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -25,15 +25,11 @@
#include "hw/intc/ioapic.h"
#include "hw/isa/isa.h"
#include "qom/object.h"
+#include "system/igvm-cfg.h"
struct X86MachineClass {
- /*< private >*/
MachineClass parent;
- /*< public >*/
-
- /* TSC rate migration: */
- bool save_tsc_khz;
/* use DMA capable linuxboot option rom */
bool fwcfg_dma_enabled;
/* CPU and apic information: */
@@ -97,6 +93,8 @@ struct X86MachineState {
* which means no limitation on the guest's bus locks.
*/
uint64_t bus_lock_ratelimit;
+
+ IgvmCfg *igvm;
};
#define X86_MACHINE_SMM "smm"
diff --git a/include/hw/i386/xen_arch_hvm.h b/include/hw/i386/xen_arch_hvm.h
deleted file mode 100644
index 1000f8f..0000000
--- a/include/hw/i386/xen_arch_hvm.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef HW_XEN_ARCH_I386_HVM_H
-#define HW_XEN_ARCH_I386_HVM_H
-
-#include <xen/hvm/ioreq.h>
-#include "hw/xen/xen-hvm-common.h"
-
-void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
-void arch_xen_set_memory(XenIOState *state,
- MemoryRegionSection *section,
- bool add);
-#endif
diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h
index 48f6a51..be923f7 100644
--- a/include/hw/intc/arm_gic.h
+++ b/include/hw/intc/arm_gic.h
@@ -27,6 +27,9 @@
* implement the security extensions
* + QOM property "has-virtualization-extensions": set true if the GIC should
* implement the virtualization extensions
+ * + QOM property "first-cpu-index": index of the first cpu attached to the
+ * GIC (default 0). The CPUs connected to the GIC are assumed to be
+ * first-cpu-index, first-cpu-index + 1, ... first-cpu-index + num-cpu - 1.
* + unnamed GPIO inputs: (where P is number of SPIs, i.e. num-irq - 32)
* [0..P-1] SPIs
* [P..P+31] PPIs for CPU 0
diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h
index 97fea41..93a3cc2 100644
--- a/include/hw/intc/arm_gic_common.h
+++ b/include/hw/intc/arm_gic_common.h
@@ -129,6 +129,8 @@ struct GICState {
uint32_t num_lrs;
uint32_t num_cpu;
+ /* cpu_index of the first CPU, attached to this GIC. */
+ uint32_t first_cpu_index;
MemoryRegion iomem; /* Distributor */
/* This is just so we can have an opaque pointer which identifies
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
index a3d6a0e..38aa196 100644
--- a/include/hw/intc/arm_gicv3_common.h
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -27,6 +27,7 @@
#include "hw/sysbus.h"
#include "hw/intc/arm_gic_common.h"
#include "qom/object.h"
+#include "qemu/notify.h"
/*
* Maximum number of possible interrupts, determined by the GIC architecture.
@@ -228,9 +229,11 @@ struct GICv3State {
uint32_t *redist_region_count; /* redistributor count within each region */
uint32_t nb_redist_regions; /* number of redist regions */
+ uint32_t first_cpu_idx;
uint32_t num_cpu;
uint32_t num_irq;
uint32_t revision;
+ uint32_t maint_irq;
bool lpi_enable;
bool nmi_support;
bool security_extn;
@@ -270,6 +273,8 @@ struct GICv3State {
GICv3CPUState *cpu;
/* List of all ITSes connected to this GIC */
GPtrArray *itslist;
+
+ NotifierWithReturn cpr_notifier;
};
#define GICV3_BITMAP_ACCESSORS(BMP) \
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
index 7dc712b..3c7b543 100644
--- a/include/hw/intc/arm_gicv3_its_common.h
+++ b/include/hw/intc/arm_gicv3_its_common.h
@@ -128,7 +128,7 @@ struct GICv3ITSCommonClass {
* Return the ITS class name to use depending on whether KVM acceleration
* and KVM CAP_SIGNAL_MSI are supported
*
- * Returns: class name to use or NULL
+ * Returns: class name to use
*/
const char *its_class_name(void);
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index 3727ba2..5128838 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -15,6 +15,11 @@
#define TYPE_ASPEED_INTC "aspeed.intc"
#define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700"
#define TYPE_ASPEED_2700_INTCIO TYPE_ASPEED_INTC "io-ast2700"
+#define TYPE_ASPEED_2700SSP_INTC TYPE_ASPEED_INTC "-ast2700ssp"
+#define TYPE_ASPEED_2700SSP_INTCIO TYPE_ASPEED_INTC "io-ast2700ssp"
+#define TYPE_ASPEED_2700TSP_INTC TYPE_ASPEED_INTC "-ast2700tsp"
+#define TYPE_ASPEED_2700TSP_INTCIO TYPE_ASPEED_INTC "io-ast2700tsp"
+
OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
#define ASPEED_INTC_MAX_INPINS 10
diff --git a/include/hw/intc/loongarch_dintc.h b/include/hw/intc/loongarch_dintc.h
new file mode 100644
index 0000000..0b0b534
--- /dev/null
+++ b/include/hw/intc/loongarch_dintc.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch direct interrupt controller definitions
+ *
+ * Copyright (C) 2025 Loongson Technology Corporation Limited
+ */
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "hw/loongarch/virt.h"
+
+
+#define NR_VECTORS 256
+
+#define TYPE_LOONGARCH_DINTC "loongarch_dintc"
+OBJECT_DECLARE_TYPE(LoongArchDINTCState, LoongArchDINTCClass, LOONGARCH_DINTC)
+
+typedef struct DINTCCore {
+ CPUState *cpu;
+ qemu_irq parent_irq;
+ uint64_t arch_id;
+} DINTCCore;
+
+struct LoongArchDINTCState {
+ SysBusDevice parent_obj;
+ MemoryRegion dintc_mmio;
+ DINTCCore *cpu;
+ uint32_t num_cpu;
+};
+
+struct LoongArchDINTCClass {
+ SysBusDeviceClass parent_class;
+
+ DeviceRealize parent_realize;
+ DeviceUnrealize parent_unrealize;
+};
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
index 4a6ae90..4795bdc 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -15,14 +15,18 @@ OBJECT_DECLARE_TYPE(LoongArchExtIOIState, LoongArchExtIOIClass, LOONGARCH_EXTIOI
struct LoongArchExtIOIState {
LoongArchExtIOICommonState parent_obj;
+ int dev_fd;
};
struct LoongArchExtIOIClass {
LoongArchExtIOICommonClass parent_class;
DeviceRealize parent_realize;
- DeviceUnrealize parent_unrealize;
ResettablePhases parent_phases;
};
+void kvm_extioi_realize(DeviceState *dev, Error **errp);
+int kvm_extioi_get(void *opaque);
+int kvm_extioi_put(void *opaque, int version_id);
+
#endif /* LOONGARCH_EXTIOI_H */
diff --git a/include/hw/intc/loongarch_extioi_common.h b/include/hw/intc/loongarch_extioi_common.h
index 735bfee..c021cce 100644
--- a/include/hw/intc/loongarch_extioi_common.h
+++ b/include/hw/intc/loongarch_extioi_common.h
@@ -35,7 +35,7 @@
#define EXTIOI_ISR_START (0x700 - APIC_OFFSET)
#define EXTIOI_ISR_END (0x720 - APIC_OFFSET)
#define EXTIOI_COREISR_START (0x800 - APIC_OFFSET)
-#define EXTIOI_COREISR_END (0xB20 - APIC_OFFSET)
+#define EXTIOI_COREISR_END (0x820 - APIC_OFFSET)
#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET)
#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET)
#define EXTIOI_SIZE 0x800
@@ -94,6 +94,7 @@ struct LoongArchExtIOICommonClass {
SysBusDeviceClass parent_class;
DeviceRealize parent_realize;
+ DeviceUnrealize parent_unrealize;
ResettablePhases parent_phases;
int (*pre_save)(void *s);
int (*post_load)(void *s, int version_id);
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
index a7c6bf8..5175a6b 100644
--- a/include/hw/intc/loongarch_ipi.h
+++ b/include/hw/intc/loongarch_ipi.h
@@ -16,6 +16,7 @@ OBJECT_DECLARE_TYPE(LoongarchIPIState, LoongarchIPIClass, LOONGARCH_IPI)
struct LoongarchIPIState {
LoongsonIPICommonState parent_obj;
+ int dev_fd;
};
struct LoongarchIPIClass {
@@ -24,4 +25,8 @@ struct LoongarchIPIClass {
ResettablePhases parent_phases;
};
+void kvm_ipi_realize(DeviceState *dev, Error **errp);
+int kvm_ipi_get(void *opaque);
+int kvm_ipi_put(void *opaque, int version_id);
+
#endif
diff --git a/include/hw/intc/loongarch_pch_pic.h b/include/hw/intc/loongarch_pch_pic.h
index 839a59a..a46b6f8 100644
--- a/include/hw/intc/loongarch_pch_pic.h
+++ b/include/hw/intc/loongarch_pch_pic.h
@@ -16,6 +16,7 @@ OBJECT_DECLARE_TYPE(LoongarchPICState, LoongarchPICClass, LOONGARCH_PIC)
struct LoongarchPICState {
LoongArchPICCommonState parent_obj;
+ int dev_fd;
};
struct LoongarchPICClass {
@@ -25,4 +26,8 @@ struct LoongarchPICClass {
ResettablePhases parent_phases;
};
+void kvm_pic_realize(DeviceState *dev, Error **errp);
+int kvm_pic_get(void *opaque);
+int kvm_pic_put(void *opaque, int version_id);
+
#endif /* HW_LOONGARCH_PCH_PIC_H */
diff --git a/include/hw/intc/loongarch_pic_common.h b/include/hw/intc/loongarch_pic_common.h
index d301377..675ba96 100644
--- a/include/hw/intc/loongarch_pic_common.h
+++ b/include/hw/intc/loongarch_pic_common.h
@@ -7,47 +7,47 @@
#ifndef HW_LOONGARCH_PIC_COMMON_H
#define HW_LOONGARCH_PIC_COMMON_H
-#include "hw/pci-host/ls7a.h"
+#include "hw/loongarch/virt.h"
#include "hw/sysbus.h"
-#define PCH_PIC_INT_ID_VAL 0x7000000UL
-#define PCH_PIC_INT_ID_VER 0x1UL
-#define PCH_PIC_INT_ID_LO 0x00
-#define PCH_PIC_INT_ID_HI 0x04
-#define PCH_PIC_INT_MASK_LO 0x20
-#define PCH_PIC_INT_MASK_HI 0x24
-#define PCH_PIC_HTMSI_EN_LO 0x40
-#define PCH_PIC_HTMSI_EN_HI 0x44
-#define PCH_PIC_INT_EDGE_LO 0x60
-#define PCH_PIC_INT_EDGE_HI 0x64
-#define PCH_PIC_INT_CLEAR_LO 0x80
-#define PCH_PIC_INT_CLEAR_HI 0x84
-#define PCH_PIC_AUTO_CTRL0_LO 0xc0
-#define PCH_PIC_AUTO_CTRL0_HI 0xc4
-#define PCH_PIC_AUTO_CTRL1_LO 0xe0
-#define PCH_PIC_AUTO_CTRL1_HI 0xe4
-#define PCH_PIC_ROUTE_ENTRY_OFFSET 0x100
+#define PCH_PIC_INT_ID 0x00
+#define PCH_PIC_INT_ID_VAL 0x7
+#define PCH_PIC_INT_ID_VER 0x1
+#define PCH_PIC_INT_MASK 0x20
+#define PCH_PIC_HTMSI_EN 0x40
+#define PCH_PIC_INT_EDGE 0x60
+#define PCH_PIC_INT_CLEAR 0x80
+#define PCH_PIC_AUTO_CTRL0 0xc0
+#define PCH_PIC_AUTO_CTRL1 0xe0
+#define PCH_PIC_ROUTE_ENTRY 0x100
#define PCH_PIC_ROUTE_ENTRY_END 0x13f
-#define PCH_PIC_HTMSI_VEC_OFFSET 0x200
+#define PCH_PIC_HTMSI_VEC 0x200
#define PCH_PIC_HTMSI_VEC_END 0x23f
-#define PCH_PIC_INT_STATUS_LO 0x3a0
-#define PCH_PIC_INT_STATUS_HI 0x3a4
-#define PCH_PIC_INT_POL_LO 0x3e0
-#define PCH_PIC_INT_POL_HI 0x3e4
-
-#define STATUS_LO_START 0
-#define STATUS_HI_START 0x4
-#define POL_LO_START 0x40
-#define POL_HI_START 0x44
+#define PCH_PIC_INT_REQUEST 0x380
+#define PCH_PIC_INT_STATUS 0x3a0
+#define PCH_PIC_INT_POL 0x3e0
#define TYPE_LOONGARCH_PIC_COMMON "loongarch_pic_common"
OBJECT_DECLARE_TYPE(LoongArchPICCommonState,
LoongArchPICCommonClass, LOONGARCH_PIC_COMMON)
+union LoongArchPIC_ID {
+ struct {
+ uint8_t _reserved_0[3];
+ uint8_t id;
+ uint8_t version;
+ uint8_t _reserved_1;
+ uint8_t irq_num;
+ uint8_t _reserved_2;
+ } QEMU_PACKED desc;
+ uint64_t data;
+};
+
struct LoongArchPICCommonState {
SysBusDevice parent_obj;
qemu_irq parent_irq[64];
+ union LoongArchPIC_ID id; /* 0x00 interrupt ID register */
uint64_t int_mask; /* 0x020 interrupt mask register */
uint64_t htmsi_en; /* 0x040 1=msi */
uint64_t intedge; /* 0x060 edge=1 level=0 */
@@ -66,9 +66,7 @@ struct LoongArchPICCommonState {
uint8_t route_entry[64]; /* 0x100 - 0x138 */
uint8_t htmsi_vector[64]; /* 0x200 - 0x238 */
- MemoryRegion iomem32_low;
- MemoryRegion iomem32_high;
- MemoryRegion iomem8;
+ MemoryRegion iomem;
unsigned int irq_num;
};
diff --git a/include/hw/intc/loongson_ipi_common.h b/include/hw/intc/loongson_ipi_common.h
index b587f9c..e58ce2a 100644
--- a/include/hw/intc/loongson_ipi_common.h
+++ b/include/hw/intc/loongson_ipi_common.h
@@ -48,6 +48,8 @@ struct LoongsonIPICommonClass {
AddressSpace *(*get_iocsr_as)(CPUState *cpu);
int (*cpu_by_arch_id)(LoongsonIPICommonState *lics, int64_t id,
int *index, CPUState **pcs);
+ int (*pre_save)(void *opaque);
+ int (*post_load)(void *opaque, int version_id);
};
MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr, uint64_t *data,
diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h
index 693415e..4b7406e 100644
--- a/include/hw/intc/riscv_aclint.h
+++ b/include/hw/intc/riscv_aclint.h
@@ -80,4 +80,8 @@ enum {
RISCV_ACLINT_SWI_SIZE = 0x4000
};
+#define VMSTATE_TIMER_PTR_VARRAY(_f, _s, _f_n) \
+VMSTATE_VARRAY_OF_POINTER_UINT32(_f, _s, _f_n, 0, vmstate_info_timer, \
+ QEMUTimer *)
+
#endif
diff --git a/include/hw/irq.h b/include/hw/irq.h
index b301223..291fdd6 100644
--- a/include/hw/irq.h
+++ b/include/hw/irq.h
@@ -36,12 +36,33 @@ static inline void qemu_irq_pulse(qemu_irq irq)
/*
* Init a single IRQ. The irq is assigned with a handler, an opaque data
- * and the interrupt number.
+ * and the interrupt number. The caller must free this with qemu_free_irq().
+ * If you are using this inside a device's init or realize method, then
+ * qemu_init_irq_child() is probably a better choice to avoid the need
+ * to manually clean up the IRQ.
*/
void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
int n);
/**
+ * qemu_init_irq_child: Initialize IRQ and make it a QOM child
+ * @parent: QOM object which owns this IRQ
+ * @propname: child property name
+ * @irq: pointer to IRQState to initialize
+ * @handler: handler function for incoming interrupts
+ * @opaque: opaque data to pass to @handler
+ * @n: interrupt number to pass to @handler
+ *
+ * Init a single IRQ and make the IRQ object a child of @parent with
+ * the child-property name @propname. The IRQ object will thus be
+ * automatically freed when @parent is destroyed.
+ */
+void qemu_init_irq_child(Object *parent, const char *propname,
+ IRQState *irq, qemu_irq_handler handler,
+ void *opaque, int n);
+
+
+/**
* qemu_init_irqs: Initialize an array of IRQs.
*
* @irq: Array of IRQs to initialize
diff --git a/include/hw/loader.h b/include/hw/loader.h
index d280dc3..c96b5e1 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -270,8 +270,6 @@ int rom_add_elf_program(const char *name, GMappedFile *mapped_file, void *data,
AddressSpace *as);
int rom_check_and_register_reset(void);
void rom_set_fw(FWCfgState *f);
-void rom_set_order_override(int order);
-void rom_reset_order_override(void);
/**
* rom_transaction_begin:
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index b3b870d..9819f7f 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -102,11 +102,10 @@ struct loongarch_boot_info {
const char *kernel_cmdline;
const char *initrd_filename;
uint64_t a0, a1, a2;
+ uint64_t initrd_addr;
+ uint64_t initrd_size;
};
-extern struct memmap_entry *memmap_table;
-extern unsigned memmap_entries;
-
struct memmap_entry {
uint64_t address;
uint64_t length;
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 2b7d199..27b1755 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -13,28 +13,84 @@
#include "hw/block/flash.h"
#include "hw/loongarch/boot.h"
+/* IOCSR region */
+#define VERSION_REG 0x0
+#define FEATURE_REG 0x8
+#define IOCSRF_TEMP 0
+#define IOCSRF_NODECNT 1
+#define IOCSRF_MSI 2
+#define IOCSRF_EXTIOI 3
+#define IOCSRF_CSRIPI 4
+#define IOCSRF_FREQCSR 5
+#define IOCSRF_FREQSCALE 6
+#define IOCSRF_DVFSV1 7
+#define IOCSRF_GMOD 9
+#define IOCSRF_VM 11
+#define IOCSRF_DMSI 15
+#define VENDOR_REG 0x10
+#define CPUNAME_REG 0x20
+#define MISC_FUNC_REG 0x420
+#define IOCSRM_EXTIOI_EN 48
+#define IOCSRM_EXTIOI_INT_ENCODE 49
+#define IOCSRM_DMSI_EN 51
+
#define LOONGARCH_MAX_CPUS 256
-#define VIRT_FWCFG_BASE 0x1e020000UL
+/* MMIO memory region */
+#define VIRT_PCH_REG_BASE 0x10000000UL
+#define VIRT_PCH_REG_SIZE 0x400
+#define VIRT_RTC_REG_BASE 0x100d0100UL
+#define VIRT_RTC_LEN 0x100
+#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000UL
+#define VIRT_PLATFORM_BUS_SIZE 0x02000000
+#define VIRT_PCI_IO_BASE 0x18004000UL
+#define VIRT_PCI_IO_OFFSET 0x4000
+#define VIRT_PCI_IO_SIZE 0xC000
#define VIRT_BIOS_BASE 0x1c000000UL
-#define VIRT_BIOS_SIZE (16 * MiB)
+#define VIRT_BIOS_SIZE 0x01000000UL
#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
#define VIRT_FLASH0_BASE VIRT_BIOS_BASE
#define VIRT_FLASH0_SIZE VIRT_BIOS_SIZE
#define VIRT_FLASH1_BASE 0x1d000000UL
-#define VIRT_FLASH1_SIZE (16 * MiB)
+#define VIRT_FLASH1_SIZE 0x01000000UL
+#define VIRT_FWCFG_BASE 0x1e020000UL
+#define VIRT_UART_BASE 0x1fe001e0UL
+#define VIRT_UART_SIZE 0x100
+#define VIRT_PCI_CFG_BASE 0x20000000UL
+#define VIRT_PCI_CFG_SIZE 0x08000000UL
+#define VIRT_DINTC_BASE 0x2FE00000UL
+#define VIRT_DINTC_SIZE 0x00100000UL
+#define VIRT_PCH_MSI_ADDR_LOW 0x2FF00000UL
+#define VIRT_PCH_MSI_SIZE 0x8
+#define VIRT_PCI_MEM_BASE 0x40000000UL
+#define VIRT_PCI_MEM_SIZE 0x40000000UL
#define VIRT_LOWMEM_BASE 0
#define VIRT_LOWMEM_SIZE 0x10000000
+#define FDT_BASE 0x100000
#define VIRT_HIGHMEM_BASE 0x80000000
#define VIRT_GED_EVT_ADDR 0x100e0000
-#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
-#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
-#define VIRT_GED_CPUHP_ADDR (VIRT_GED_REG_ADDR + ACPI_GED_REG_COUNT)
+#define VIRT_GED_MEM_ADDR QEMU_ALIGN_UP(VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN, 4)
+#define VIRT_GED_REG_ADDR QEMU_ALIGN_UP(VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN, 4)
+#define VIRT_GED_CPUHP_ADDR QEMU_ALIGN_UP(VIRT_GED_REG_ADDR + ACPI_GED_REG_COUNT, 4)
-#define COMMAND_LINE_SIZE 512
+/*
+ * GSI_BASE is hard-coded with 64 in linux kernel, else kernel fails to boot
+ * 0 - 15 GSI for ISA devices even if there is no ISA devices
+ * 16 - 63 GSI for CPU devices such as timers/perf monitor etc
+ * 64 - GSI for external devices
+ */
+#define VIRT_PCH_PIC_IRQ_NUM 32
+#define VIRT_GSI_BASE 64
+#define VIRT_DEVICE_IRQS 16
+#define VIRT_UART_IRQ (VIRT_GSI_BASE + 2)
+#define VIRT_UART_COUNT 4
+#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 6)
+#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 7)
+#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 8)
+#define VIRT_PLATFORM_BUS_NUM_IRQS 2
-#define FDT_BASE 0x100000
+#define COMMAND_LINE_SIZE 512
struct LoongArchVirtMachineState {
/*< private >*/
@@ -50,6 +106,7 @@ struct LoongArchVirtMachineState {
Notifier powerdown_notifier;
OnOffAuto acpi;
OnOffAuto veiointc;
+ OnOffAuto dmsi;
char *oem_id;
char *oem_table_id;
DeviceState *acpi_ged;
@@ -63,6 +120,11 @@ struct LoongArchVirtMachineState {
struct loongarch_boot_info bootinfo;
DeviceState *ipi;
DeviceState *extioi;
+ struct memmap_entry *memmap_table;
+ unsigned int memmap_entries;
+ uint64_t misc_feature;
+ uint64_t misc_status;
+ DeviceState *dintc;
};
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
@@ -70,6 +132,15 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
void virt_acpi_setup(LoongArchVirtMachineState *lvms);
void virt_fdt_setup(LoongArchVirtMachineState *lvms);
+static inline bool virt_has_dmsi(LoongArchVirtMachineState *lvms)
+{
+ if (!(lvms->misc_feature & BIT(IOCSRF_DMSI))) {
+ return false;
+ }
+
+ return true;
+}
+
static inline bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
{
if (lvms->veiointc == ON_OFF_AUTO_OFF) {
diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
index 5d4aa19..d5d07c6 100644
--- a/include/hw/misc/aspeed_hace.h
+++ b/include/hw/misc/aspeed_hace.h
@@ -22,7 +22,6 @@
OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE)
-#define ASPEED_HACE_NR_REGS (0x64 >> 2)
#define ASPEED_HACE_MAX_SG 256 /* max number of entries */
struct AspeedHACEState {
@@ -31,10 +30,8 @@ struct AspeedHACEState {
MemoryRegion iomem;
qemu_irq irq;
- struct iovec iov_cache[ASPEED_HACE_MAX_SG];
- uint32_t regs[ASPEED_HACE_NR_REGS];
+ uint32_t *regs;
uint32_t total_req_len;
- uint32_t iov_count;
MemoryRegion *dram_mr;
AddressSpace dram_as;
@@ -46,11 +43,17 @@ struct AspeedHACEState {
struct AspeedHACEClass {
SysBusDeviceClass parent_class;
+ const MemoryRegionOps *reg_ops;
uint32_t src_mask;
uint32_t dest_mask;
uint32_t key_mask;
uint32_t hash_mask;
+ uint64_t nr_regs;
bool raise_crypt_interrupt_workaround;
+ uint32_t src_hi_mask;
+ uint32_t dest_hi_mask;
+ uint32_t key_hi_mask;
+ bool has_dma64;
};
#endif /* ASPEED_HACE_H */
diff --git a/include/hw/misc/aspeed_sbc.h b/include/hw/misc/aspeed_sbc.h
index 405e678..7d640a0 100644
--- a/include/hw/misc/aspeed_sbc.h
+++ b/include/hw/misc/aspeed_sbc.h
@@ -10,9 +10,11 @@
#define ASPEED_SBC_H
#include "hw/sysbus.h"
+#include "hw/nvram/aspeed_otp.h"
#define TYPE_ASPEED_SBC "aspeed.sbc"
#define TYPE_ASPEED_AST2600_SBC TYPE_ASPEED_SBC "-ast2600"
+#define TYPE_ASPEED_AST10X0_SBC TYPE_ASPEED_SBC "-ast10x0"
OBJECT_DECLARE_TYPE(AspeedSBCState, AspeedSBCClass, ASPEED_SBC)
#define ASPEED_SBC_NR_REGS (0x93c >> 2)
@@ -36,10 +38,14 @@ struct AspeedSBCState {
MemoryRegion iomem;
uint32_t regs[ASPEED_SBC_NR_REGS];
+
+ AspeedOTPState otp;
};
struct AspeedSBCClass {
SysBusDeviceClass parent_class;
+
+ bool has_otp;
};
#endif /* ASPEED_SBC_H */
diff --git a/include/hw/misc/ivshmem-flat.h b/include/hw/misc/ivshmem-flat.h
index 09bc3ab..3eca990 100644
--- a/include/hw/misc/ivshmem-flat.h
+++ b/include/hw/misc/ivshmem-flat.h
@@ -36,7 +36,7 @@ typedef struct IvshmemFTState IvshmemFTState;
DECLARE_INSTANCE_CHECKER(IvshmemFTState, IVSHMEM_FLAT, TYPE_IVSHMEM_FLAT)
-/* Ivshmem registers. See ./docs/specs/ivshmem-spec.txt for details. */
+/* Ivshmem registers. See docs/specs/ivshmem-spec.rst for details. */
enum ivshmem_registers {
INTMASK = 0,
INTSTATUS = 4,
diff --git a/include/hw/misc/max78000_aes.h b/include/hw/misc/max78000_aes.h
new file mode 100644
index 0000000..407c45e
--- /dev/null
+++ b/include/hw/misc/max78000_aes.h
@@ -0,0 +1,68 @@
+/*
+ * MAX78000 AES
+ *
+ * Copyright (c) 2025 Jackson Donaldson <jcksn@duck.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_MAX78000_AES_H
+#define HW_MAX78000_AES_H
+
+#include "hw/sysbus.h"
+#include "crypto/aes.h"
+#include "qom/object.h"
+
+#define TYPE_MAX78000_AES "max78000-aes"
+OBJECT_DECLARE_SIMPLE_TYPE(Max78000AesState, MAX78000_AES)
+
+#define CTRL 0
+#define STATUS 4
+#define INTFL 8
+#define INTEN 0xc
+#define FIFO 0x10
+
+#define KEY_BASE 0x400
+#define KEY_END 0x420
+
+/* CTRL */
+#define TYPE (1 << 9 | 1 << 8)
+#define KEY_SIZE (1 << 7 | 1 << 6)
+#define OUTPUT_FLUSH (1 << 5)
+#define INPUT_FLUSH (1 << 4)
+#define START (1 << 3)
+
+#define AES_EN (1 << 0)
+
+/* STATUS */
+#define OUTPUT_FULL (1 << 4)
+#define OUTPUT_EMPTY (1 << 3)
+#define INPUT_FULL (1 << 2)
+#define INPUT_EMPTY (1 << 1)
+#define BUSY (1 << 0)
+
+/* INTFL*/
+#define DONE (1 << 0)
+
+struct Max78000AesState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+
+ uint32_t ctrl;
+ uint32_t status;
+ uint32_t intfl;
+ uint32_t inten;
+ uint32_t data_index;
+ uint8_t data[16];
+
+ uint8_t key[32];
+ AES_KEY internal_key;
+
+ uint32_t result_index;
+ uint8_t result[16];
+
+
+ qemu_irq irq;
+};
+
+#endif
diff --git a/include/hw/misc/max78000_gcr.h b/include/hw/misc/max78000_gcr.h
new file mode 100644
index 0000000..d5858a4
--- /dev/null
+++ b/include/hw/misc/max78000_gcr.h
@@ -0,0 +1,131 @@
+/*
+ * MAX78000 Global Control Register
+ *
+ * Copyright (c) 2025 Jackson Donaldson <jcksn@duck.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_MAX78000_GCR_H
+#define HW_MAX78000_GCR_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_MAX78000_GCR "max78000-gcr"
+OBJECT_DECLARE_SIMPLE_TYPE(Max78000GcrState, MAX78000_GCR)
+
+#define SYSCTRL 0x0
+#define RST0 0x4
+#define CLKCTRL 0x8
+#define PM 0xc
+#define PCLKDIV 0x18
+#define PCLKDIS0 0x24
+#define MEMCTRL 0x28
+#define MEMZ 0x2c
+#define SYSST 0x40
+#define RST1 0x44
+#define PCKDIS1 0x48
+#define EVENTEN 0x4c
+#define REVISION 0x50
+#define SYSIE 0x54
+#define ECCERR 0x64
+#define ECCED 0x68
+#define ECCIE 0x6c
+#define ECCADDR 0x70
+
+/* RST0 */
+#define SYSTEM_RESET (1 << 31)
+#define PERIPHERAL_RESET (1 << 30)
+#define SOFT_RESET (1 << 29)
+#define UART2_RESET (1 << 28)
+
+#define ADC_RESET (1 << 26)
+#define CNN_RESET (1 << 25)
+#define TRNG_RESET (1 << 24)
+
+#define RTC_RESET (1 << 17)
+#define I2C0_RESET (1 << 16)
+
+#define SPI1_RESET (1 << 13)
+#define UART1_RESET (1 << 12)
+#define UART0_RESET (1 << 11)
+
+#define TMR3_RESET (1 << 8)
+#define TMR2_RESET (1 << 7)
+#define TMR1_RESET (1 << 6)
+#define TMR0_RESET (1 << 5)
+
+#define GPIO1_RESET (1 << 3)
+#define GPIO0_RESET (1 << 2)
+#define WDT0_RESET (1 << 1)
+#define DMA_RESET (1 << 0)
+
+/* CLKCTRL */
+#define SYSCLK_RDY (1 << 13)
+
+/* MEMZ */
+#define ram0 (1 << 0)
+#define ram1 (1 << 1)
+#define ram2 (1 << 2)
+#define ram3 (1 << 3)
+
+/* RST1 */
+#define CPU1_RESET (1 << 31)
+
+#define SIMO_RESET (1 << 25)
+#define DVS_RESET (1 << 24)
+
+#define I2C2_RESET (1 << 20)
+#define I2S_RESET (1 << 19)
+
+#define SMPHR_RESET (1 << 16)
+
+#define SPI0_RESET (1 << 11)
+#define AES_RESET (1 << 10)
+#define CRC_RESET (1 << 9)
+
+#define PT_RESET (1 << 1)
+#define I2C1_RESET (1 << 0)
+
+
+#define SYSRAM0_START 0x20000000
+#define SYSRAM1_START 0x20008000
+#define SYSRAM2_START 0x20010000
+#define SYSRAM3_START 0x2001C000
+
+struct Max78000GcrState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+
+ uint32_t sysctrl;
+ uint32_t rst0;
+ uint32_t clkctrl;
+ uint32_t pm;
+ uint32_t pclkdiv;
+ uint32_t pclkdis0;
+ uint32_t memctrl;
+ uint32_t memz;
+ uint32_t sysst;
+ uint32_t rst1;
+ uint32_t pckdis1;
+ uint32_t eventen;
+ uint32_t revision;
+ uint32_t sysie;
+ uint32_t eccerr;
+ uint32_t ecced;
+ uint32_t eccie;
+ uint32_t eccaddr;
+
+ MemoryRegion *sram;
+ AddressSpace sram_as;
+
+ DeviceState *uart0;
+ DeviceState *uart1;
+ DeviceState *uart2;
+ DeviceState *trng;
+ DeviceState *aes;
+
+};
+
+#endif
diff --git a/include/hw/misc/max78000_icc.h b/include/hw/misc/max78000_icc.h
new file mode 100644
index 0000000..6fe2bb7
--- /dev/null
+++ b/include/hw/misc/max78000_icc.h
@@ -0,0 +1,33 @@
+/*
+ * MAX78000 Instruction Cache
+ *
+ * Copyright (c) 2025 Jackson Donaldson <jcksn@duck.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MAX78000_ICC_H
+#define HW_MAX78000_ICC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_MAX78000_ICC "max78000-icc"
+OBJECT_DECLARE_SIMPLE_TYPE(Max78000IccState, MAX78000_ICC)
+
+#define ICC_INFO 0x0
+#define ICC_SZ 0x4
+#define ICC_CTRL 0x100
+#define ICC_INVALIDATE 0x700
+
+struct Max78000IccState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+
+ uint32_t info;
+ uint32_t sz;
+ uint32_t ctrl;
+};
+
+#endif
diff --git a/include/hw/misc/max78000_trng.h b/include/hw/misc/max78000_trng.h
new file mode 100644
index 0000000..c5a8129
--- /dev/null
+++ b/include/hw/misc/max78000_trng.h
@@ -0,0 +1,35 @@
+/*
+ * MAX78000 True Random Number Generator
+ *
+ * Copyright (c) 2025 Jackson Donaldson <jcksn@duck.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_MAX78000_TRNG_H
+#define HW_MAX78000_TRNG_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_MAX78000_TRNG "max78000-trng"
+OBJECT_DECLARE_SIMPLE_TYPE(Max78000TrngState, MAX78000_TRNG)
+
+#define CTRL 0
+#define STATUS 4
+#define DATA 8
+
+#define RND_IE (1 << 1)
+
+struct Max78000TrngState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+
+ uint32_t ctrl;
+ uint32_t status;
+ uint32_t data;
+
+ qemu_irq irq;
+};
+
+#endif
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
index dba6d35..f6b8694 100644
--- a/include/hw/misc/xlnx-versal-crl.h
+++ b/include/hw/misc/xlnx-versal-crl.h
@@ -2,6 +2,7 @@
* QEMU model of the Clock-Reset-LPD (CRL).
*
* Copyright (c) 2022 Xilinx Inc.
+ * Copyright (c) 2025 Advanced Micro Devices, Inc.
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
@@ -12,9 +13,16 @@
#include "hw/sysbus.h"
#include "hw/register.h"
#include "target/arm/cpu-qom.h"
+#include "hw/arm/xlnx-versal-version.h"
+#define TYPE_XLNX_VERSAL_CRL_BASE "xlnx-versal-crl-base"
#define TYPE_XLNX_VERSAL_CRL "xlnx-versal-crl"
+#define TYPE_XLNX_VERSAL2_CRL "xlnx-versal2-crl"
+
+OBJECT_DECLARE_TYPE(XlnxVersalCRLBase, XlnxVersalCRLBaseClass,
+ XLNX_VERSAL_CRL_BASE)
OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersal2CRL, XLNX_VERSAL2_CRL)
REG32(ERR_CTRL, 0x0)
FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
@@ -214,22 +222,370 @@ REG32(PSM_RST_MODE, 0x370)
#define CRL_R_MAX (R_PSM_RST_MODE + 1)
-#define RPU_MAX_CPU 2
+REG32(VERSAL2_ERR_CTRL, 0x0)
+REG32(VERSAL2_WPROT, 0x1c)
+ FIELD(VERSAL2_WPROT, ACTIVE, 0, 1)
+REG32(VERSAL2_RPLL_CTRL, 0x40)
+ FIELD(VERSAL2_RPLL_CTRL, POST_SRC, 24, 3)
+ FIELD(VERSAL2_RPLL_CTRL, PRE_SRC, 20, 3)
+ FIELD(VERSAL2_RPLL_CTRL, CLKOUTDIV, 16, 2)
+ FIELD(VERSAL2_RPLL_CTRL, FBDIV, 8, 8)
+ FIELD(VERSAL2_RPLL_CTRL, BYPASS, 3, 1)
+ FIELD(VERSAL2_RPLL_CTRL, RESET, 0, 1)
+REG32(VERSAL2_RPLL_CFG, 0x44)
+ FIELD(VERSAL2_RPLL_CFG, LOCK_DLY, 25, 7)
+ FIELD(VERSAL2_RPLL_CFG, LOCK_CNT, 13, 10)
+ FIELD(VERSAL2_RPLL_CFG, LFHF, 10, 2)
+ FIELD(VERSAL2_RPLL_CFG, CP, 5, 4)
+ FIELD(VERSAL2_RPLL_CFG, RES, 0, 4)
+REG32(VERSAL2_FLXPLL_CTRL, 0x50)
+ FIELD(VERSAL2_FLXPLL_CTRL, POST_SRC, 24, 3)
+ FIELD(VERSAL2_FLXPLL_CTRL, PRE_SRC, 20, 3)
+ FIELD(VERSAL2_FLXPLL_CTRL, CLKOUTDIV, 16, 2)
+ FIELD(VERSAL2_FLXPLL_CTRL, FBDIV, 8, 8)
+ FIELD(VERSAL2_FLXPLL_CTRL, BYPASS, 3, 1)
+ FIELD(VERSAL2_FLXPLL_CTRL, RESET, 0, 1)
+REG32(VERSAL2_FLXPLL_CFG, 0x54)
+ FIELD(VERSAL2_FLXPLL_CFG, LOCK_DLY, 25, 7)
+ FIELD(VERSAL2_FLXPLL_CFG, LOCK_CNT, 13, 10)
+ FIELD(VERSAL2_FLXPLL_CFG, LFHF, 10, 2)
+ FIELD(VERSAL2_FLXPLL_CFG, CP, 5, 4)
+ FIELD(VERSAL2_FLXPLL_CFG, RES, 0, 4)
+REG32(VERSAL2_PLL_STATUS, 0x60)
+ FIELD(VERSAL2_PLL_STATUS, FLXPLL_STABLE, 3, 1)
+ FIELD(VERSAL2_PLL_STATUS, RPLL_STABLE, 2, 1)
+ FIELD(VERSAL2_PLL_STATUS, FLXPLL_LOCK, 1, 1)
+ FIELD(VERSAL2_PLL_STATUS, RPLL_LOCK, 0, 1)
+REG32(VERSAL2_RPLL_TO_XPD_CTRL, 0x100)
+ FIELD(VERSAL2_RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
+REG32(VERSAL2_LPX_TOP_SWITCH_CTRL, 0x104)
+ FIELD(VERSAL2_LPX_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
+ FIELD(VERSAL2_LPX_TOP_SWITCH_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_LPX_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_LPX_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_LPX_LSBUS_CLK_CTRL, 0x108)
+ FIELD(VERSAL2_LPX_LSBUS_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_LPX_LSBUS_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_LPX_LSBUS_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_RPU_CLK_CTRL, 0x10c)
+ FIELD(VERSAL2_RPU_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_RPU_CLK_CTRL, CLKACT_CLUSTERE, 24, 1)
+ FIELD(VERSAL2_RPU_CLK_CTRL, CLKACT_CLUSTERD, 23, 1)
+ FIELD(VERSAL2_RPU_CLK_CTRL, CLKACT_CLUSTERC, 22, 1)
+ FIELD(VERSAL2_RPU_CLK_CTRL, CLKACT_CLUSTERB, 21, 1)
+ FIELD(VERSAL2_RPU_CLK_CTRL, CLKACT_CLUSTERA, 20, 1)
+ FIELD(VERSAL2_RPU_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_RPU_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_OCM_CLK_CTRL, 0x120)
+ FIELD(VERSAL2_OCM_CLK_CTRL, CLKACT_OCM3, 24, 1)
+ FIELD(VERSAL2_OCM_CLK_CTRL, CLKACT_OCM2, 23, 1)
+ FIELD(VERSAL2_OCM_CLK_CTRL, CLKACT_OCM1, 22, 1)
+ FIELD(VERSAL2_OCM_CLK_CTRL, CLKACT_OCM0, 21, 1)
+REG32(VERSAL2_IOU_SWITCH_CLK_CTRL, 0x124)
+ FIELD(VERSAL2_IOU_SWITCH_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_IOU_SWITCH_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_IOU_SWITCH_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_GEM0_REF_CTRL, 0x128)
+ FIELD(VERSAL2_GEM0_REF_CTRL, CLKACT_RX, 27, 1)
+ FIELD(VERSAL2_GEM0_REF_CTRL, CLKACT_TX, 26, 1)
+ FIELD(VERSAL2_GEM0_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_GEM0_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_GEM0_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_GEM1_REF_CTRL, 0x12c)
+ FIELD(VERSAL2_GEM1_REF_CTRL, CLKACT_RX, 27, 1)
+ FIELD(VERSAL2_GEM1_REF_CTRL, CLKACT_TX, 26, 1)
+ FIELD(VERSAL2_GEM1_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_GEM1_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_GEM1_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_GEM_TSU_REF_CLK_CTRL, 0x130)
+ FIELD(VERSAL2_GEM_TSU_REF_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_GEM_TSU_REF_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_GEM_TSU_REF_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_USB0_BUS_REF_CLK_CTRL, 0x134)
+ FIELD(VERSAL2_USB0_BUS_REF_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_USB0_BUS_REF_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_USB0_BUS_REF_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_USB1_BUS_REF_CLK_CTRL, 0x138)
+ FIELD(VERSAL2_USB1_BUS_REF_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_USB1_BUS_REF_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_USB1_BUS_REF_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_UART0_REF_CLK_CTRL, 0x13c)
+ FIELD(VERSAL2_UART0_REF_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_UART0_REF_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_UART0_REF_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_UART1_REF_CLK_CTRL, 0x140)
+ FIELD(VERSAL2_UART1_REF_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_UART1_REF_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_UART1_REF_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_SPI0_REF_CLK_CTRL, 0x144)
+ FIELD(VERSAL2_SPI0_REF_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_SPI0_REF_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_SPI0_REF_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_SPI1_REF_CLK_CTRL, 0x148)
+ FIELD(VERSAL2_SPI1_REF_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_SPI1_REF_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_SPI1_REF_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_CAN0_REF_2X_CTRL, 0x14c)
+ FIELD(VERSAL2_CAN0_REF_2X_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_CAN0_REF_2X_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_CAN0_REF_2X_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_CAN1_REF_2X_CTRL, 0x150)
+ FIELD(VERSAL2_CAN1_REF_2X_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_CAN1_REF_2X_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_CAN1_REF_2X_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_CAN2_REF_2X_CTRL, 0x154)
+ FIELD(VERSAL2_CAN2_REF_2X_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_CAN2_REF_2X_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_CAN2_REF_2X_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_CAN3_REF_2X_CTRL, 0x158)
+ FIELD(VERSAL2_CAN3_REF_2X_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_CAN3_REF_2X_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_CAN3_REF_2X_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C0_REF_CTRL, 0x15c)
+ FIELD(VERSAL2_I3C0_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C0_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C0_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C1_REF_CTRL, 0x160)
+ FIELD(VERSAL2_I3C1_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C1_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C1_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C2_REF_CTRL, 0x164)
+ FIELD(VERSAL2_I3C2_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C2_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C2_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C3_REF_CTRL, 0x168)
+ FIELD(VERSAL2_I3C3_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C3_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C3_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C4_REF_CTRL, 0x16c)
+ FIELD(VERSAL2_I3C4_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C4_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C4_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C5_REF_CTRL, 0x170)
+ FIELD(VERSAL2_I3C5_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C5_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C5_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C6_REF_CTRL, 0x174)
+ FIELD(VERSAL2_I3C6_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C6_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C6_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_I3C7_REF_CTRL, 0x178)
+ FIELD(VERSAL2_I3C7_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_I3C7_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_I3C7_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_DBG_LPX_CTRL, 0x17c)
+ FIELD(VERSAL2_DBG_LPX_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_DBG_LPX_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_DBG_LPX_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_TIMESTAMP_REF_CTRL, 0x180)
+ FIELD(VERSAL2_TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_SAFETY_CHK, 0x184)
+REG32(VERSAL2_ASU_CLK_CTRL, 0x188)
+ FIELD(VERSAL2_ASU_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_ASU_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_DBG_TSTMP_CLK_CTRL, 0x18c)
+ FIELD(VERSAL2_DBG_TSTMP_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_DBG_TSTMP_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_DBG_TSTMP_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_MMI_TOPSW_CLK_CTRL, 0x190)
+ FIELD(VERSAL2_MMI_TOPSW_CLK_CTRL, CLKACT, 25, 1)
+ FIELD(VERSAL2_MMI_TOPSW_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_MMI_TOPSW_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_WWDT_PLL_CLK_CTRL, 0x194)
+ FIELD(VERSAL2_WWDT_PLL_CLK_CTRL, DIVISOR0, 8, 10)
+ FIELD(VERSAL2_WWDT_PLL_CLK_CTRL, SRCSEL, 0, 3)
+REG32(VERSAL2_RCLK_CTRL, 0x1a0)
+ FIELD(VERSAL2_RCLK_CTRL, CLKACT, 8, 6)
+ FIELD(VERSAL2_RCLK_CTRL, SELECT, 0, 6)
+REG32(VERSAL2_RST_RPU_A, 0x310)
+ FIELD(VERSAL2_RST_RPU_A, TOPRESET, 16, 1)
+ FIELD(VERSAL2_RST_RPU_A, CORE1_POR, 9, 1)
+ FIELD(VERSAL2_RST_RPU_A, CORE0_POR, 8, 1)
+ FIELD(VERSAL2_RST_RPU_A, CORE1_RESET, 1, 1)
+ FIELD(VERSAL2_RST_RPU_A, CORE0_RESET, 0, 1)
+REG32(VERSAL2_RST_RPU_B, 0x314)
+ FIELD(VERSAL2_RST_RPU_B, TOPRESET, 16, 1)
+ FIELD(VERSAL2_RST_RPU_B, CORE1_POR, 9, 1)
+ FIELD(VERSAL2_RST_RPU_B, CORE0_POR, 8, 1)
+ FIELD(VERSAL2_RST_RPU_B, CORE1_RESET, 1, 1)
+ FIELD(VERSAL2_RST_RPU_B, CORE0_RESET, 0, 1)
+REG32(VERSAL2_RST_RPU_C, 0x318)
+ FIELD(VERSAL2_RST_RPU_C, TOPRESET, 16, 1)
+ FIELD(VERSAL2_RST_RPU_C, CORE1_POR, 9, 1)
+ FIELD(VERSAL2_RST_RPU_C, CORE0_POR, 8, 1)
+ FIELD(VERSAL2_RST_RPU_C, CORE1_RESET, 1, 1)
+ FIELD(VERSAL2_RST_RPU_C, CORE0_RESET, 0, 1)
+REG32(VERSAL2_RST_RPU_D, 0x31c)
+ FIELD(VERSAL2_RST_RPU_D, TOPRESET, 16, 1)
+ FIELD(VERSAL2_RST_RPU_D, CORE1_POR, 9, 1)
+ FIELD(VERSAL2_RST_RPU_D, CORE0_POR, 8, 1)
+ FIELD(VERSAL2_RST_RPU_D, CORE1_RESET, 1, 1)
+ FIELD(VERSAL2_RST_RPU_D, CORE0_RESET, 0, 1)
+REG32(VERSAL2_RST_RPU_E, 0x320)
+ FIELD(VERSAL2_RST_RPU_E, TOPRESET, 16, 1)
+ FIELD(VERSAL2_RST_RPU_E, CORE1_POR, 9, 1)
+ FIELD(VERSAL2_RST_RPU_E, CORE0_POR, 8, 1)
+ FIELD(VERSAL2_RST_RPU_E, CORE1_RESET, 1, 1)
+ FIELD(VERSAL2_RST_RPU_E, CORE0_RESET, 0, 1)
+REG32(VERSAL2_RST_RPU_GD_0, 0x324)
+ FIELD(VERSAL2_RST_RPU_GD_0, RESET, 1, 1)
+ FIELD(VERSAL2_RST_RPU_GD_0, TOP_RESET, 0, 1)
+REG32(VERSAL2_RST_RPU_GD_1, 0x328)
+ FIELD(VERSAL2_RST_RPU_GD_1, RESET, 1, 1)
+ FIELD(VERSAL2_RST_RPU_GD_1, TOP_RESET, 0, 1)
+REG32(VERSAL2_RST_ASU_GD, 0x32c)
+ FIELD(VERSAL2_RST_ASU_GD, RESET, 1, 1)
+ FIELD(VERSAL2_RST_ASU_GD, TOP_RESET, 0, 1)
+REG32(VERSAL2_RST_ADMA, 0x334)
+ FIELD(VERSAL2_RST_ADMA, RESET, 0, 1)
+REG32(VERSAL2_RST_SDMA, 0x338)
+ FIELD(VERSAL2_RST_SDMA, RESET, 0, 1)
+REG32(VERSAL2_RST_GEM0, 0x33c)
+ FIELD(VERSAL2_RST_GEM0, RESET, 0, 1)
+REG32(VERSAL2_RST_GEM1, 0x340)
+ FIELD(VERSAL2_RST_GEM1, RESET, 0, 1)
+REG32(VERSAL2_RST_USB0, 0x348)
+ FIELD(VERSAL2_RST_USB0, RESET, 0, 1)
+REG32(VERSAL2_RST_USB1, 0x34c)
+ FIELD(VERSAL2_RST_USB1, RESET, 0, 1)
+REG32(VERSAL2_RST_UART0, 0x350)
+ FIELD(VERSAL2_RST_UART0, RESET, 0, 1)
+REG32(VERSAL2_RST_UART1, 0x354)
+ FIELD(VERSAL2_RST_UART1, RESET, 0, 1)
+REG32(VERSAL2_RST_SPI0, 0x358)
+ FIELD(VERSAL2_RST_SPI0, RESET, 0, 1)
+REG32(VERSAL2_RST_SPI1, 0x35c)
+ FIELD(VERSAL2_RST_SPI1, RESET, 0, 1)
+REG32(VERSAL2_RST_CAN0, 0x360)
+ FIELD(VERSAL2_RST_CAN0, RESET, 0, 1)
+REG32(VERSAL2_RST_CAN1, 0x364)
+ FIELD(VERSAL2_RST_CAN1, RESET, 0, 1)
+REG32(VERSAL2_RST_CAN2, 0x368)
+ FIELD(VERSAL2_RST_CAN2, RESET, 0, 1)
+REG32(VERSAL2_RST_CAN3, 0x36c)
+ FIELD(VERSAL2_RST_CAN3, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C0, 0x374)
+ FIELD(VERSAL2_RST_I3C0, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C1, 0x378)
+ FIELD(VERSAL2_RST_I3C1, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C2, 0x37c)
+ FIELD(VERSAL2_RST_I3C2, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C3, 0x380)
+ FIELD(VERSAL2_RST_I3C3, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C4, 0x384)
+ FIELD(VERSAL2_RST_I3C4, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C5, 0x388)
+ FIELD(VERSAL2_RST_I3C5, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C6, 0x38c)
+ FIELD(VERSAL2_RST_I3C6, RESET, 0, 1)
+REG32(VERSAL2_RST_I3C7, 0x390)
+ FIELD(VERSAL2_RST_I3C7, RESET, 0, 1)
+REG32(VERSAL2_RST_DBG_LPX, 0x398)
+ FIELD(VERSAL2_RST_DBG_LPX, RESET_HSDP, 1, 1)
+ FIELD(VERSAL2_RST_DBG_LPX, RESET, 0, 1)
+REG32(VERSAL2_RST_GPIO, 0x39c)
+ FIELD(VERSAL2_RST_GPIO, RESET, 0, 1)
+REG32(VERSAL2_RST_TTC, 0x3a0)
+ FIELD(VERSAL2_RST_TTC, TTC7_RESET, 7, 1)
+ FIELD(VERSAL2_RST_TTC, TTC6_RESET, 6, 1)
+ FIELD(VERSAL2_RST_TTC, TTC5_RESET, 5, 1)
+ FIELD(VERSAL2_RST_TTC, TTC4_RESET, 4, 1)
+ FIELD(VERSAL2_RST_TTC, TTC3_RESET, 3, 1)
+ FIELD(VERSAL2_RST_TTC, TTC2_RESET, 2, 1)
+ FIELD(VERSAL2_RST_TTC, TTC1_RESET, 1, 1)
+ FIELD(VERSAL2_RST_TTC, TTC0_RESET, 0, 1)
+REG32(VERSAL2_RST_TIMESTAMP, 0x3a4)
+ FIELD(VERSAL2_RST_TIMESTAMP, RESET, 0, 1)
+REG32(VERSAL2_RST_SWDT0, 0x3a8)
+ FIELD(VERSAL2_RST_SWDT0, RESET, 0, 1)
+REG32(VERSAL2_RST_SWDT1, 0x3ac)
+ FIELD(VERSAL2_RST_SWDT1, RESET, 0, 1)
+REG32(VERSAL2_RST_SWDT2, 0x3b0)
+ FIELD(VERSAL2_RST_SWDT2, RESET, 0, 1)
+REG32(VERSAL2_RST_SWDT3, 0x3b4)
+ FIELD(VERSAL2_RST_SWDT3, RESET, 0, 1)
+REG32(VERSAL2_RST_SWDT4, 0x3b8)
+ FIELD(VERSAL2_RST_SWDT4, RESET, 0, 1)
+REG32(VERSAL2_RST_IPI, 0x3bc)
+ FIELD(VERSAL2_RST_IPI, RESET, 0, 1)
+REG32(VERSAL2_RST_SYSMON, 0x3c0)
+ FIELD(VERSAL2_RST_SYSMON, CFG_RST, 0, 1)
+REG32(VERSAL2_ASU_MB_RST_MODE, 0x3c4)
+ FIELD(VERSAL2_ASU_MB_RST_MODE, WAKEUP, 2, 1)
+ FIELD(VERSAL2_ASU_MB_RST_MODE, RST_MODE, 0, 2)
+REG32(VERSAL2_FPX_TOPSW_MUX_CTRL, 0x3c8)
+ FIELD(VERSAL2_FPX_TOPSW_MUX_CTRL, SELECT, 0, 1)
+REG32(VERSAL2_RST_FPX, 0x3d0)
+ FIELD(VERSAL2_RST_FPX, SRST, 1, 1)
+ FIELD(VERSAL2_RST_FPX, POR, 0, 1)
+REG32(VERSAL2_RST_MMI, 0x3d4)
+ FIELD(VERSAL2_RST_MMI, POR, 0, 1)
+REG32(VERSAL2_RST_OCM, 0x3d8)
+ FIELD(VERSAL2_RST_OCM, RESET_OCM3, 3, 1)
+ FIELD(VERSAL2_RST_OCM, RESET_OCM2, 2, 1)
+ FIELD(VERSAL2_RST_OCM, RESET_OCM1, 1, 1)
+ FIELD(VERSAL2_RST_OCM, RESET_OCM0, 0, 1)
-struct XlnxVersalCRL {
+#define VERSAL2_CRL_R_MAX (R_VERSAL2_RST_OCM + 1)
+
+struct XlnxVersalCRLBase {
SysBusDevice parent_obj;
+
+ RegisterInfoArray *reg_array;
+ uint32_t *regs;
+};
+
+struct XlnxVersalCRLBaseClass {
+ SysBusDeviceClass parent_class;
+
+ DeviceState ** (*decode_periph_rst)(XlnxVersalCRLBase *s, hwaddr, size_t *);
+};
+
+struct XlnxVersalCRL {
+ XlnxVersalCRLBase parent_obj;
qemu_irq irq;
struct {
- ARMCPU *cpu_r5[RPU_MAX_CPU];
+ DeviceState *rpu[2];
DeviceState *adma[8];
DeviceState *uart[2];
DeviceState *gem[2];
- DeviceState *usb;
+ DeviceState *usb[1];
} cfg;
- RegisterInfoArray *reg_array;
uint32_t regs[CRL_R_MAX];
RegisterInfo regs_info[CRL_R_MAX];
};
+
+struct XlnxVersal2CRL {
+ XlnxVersalCRLBase parent_obj;
+
+ struct {
+ DeviceState *rpu[10];
+ DeviceState *adma[8];
+ DeviceState *sdma[8];
+ DeviceState *uart[2];
+ DeviceState *gem[2];
+ DeviceState *usb[2];
+ DeviceState *can[4];
+ } cfg;
+
+ RegisterInfo regs_info[VERSAL2_CRL_R_MAX];
+ uint32_t regs[VERSAL2_CRL_R_MAX];
+};
+
+static inline const char *xlnx_versal_crl_class_name(VersalVersion ver)
+{
+ switch (ver) {
+ case VERSAL_VER_VERSAL:
+ return TYPE_XLNX_VERSAL_CRL;
+ case VERSAL_VER_VERSAL2:
+ return TYPE_XLNX_VERSAL2_CRL;
+ default:
+ g_assert_not_reached();
+ }
+}
+
#endif
diff --git a/include/hw/nvram/aspeed_otp.h b/include/hw/nvram/aspeed_otp.h
new file mode 100644
index 0000000..3752353
--- /dev/null
+++ b/include/hw/nvram/aspeed_otp.h
@@ -0,0 +1,33 @@
+/*
+ * ASPEED OTP (One-Time Programmable) memory
+ *
+ * Copyright (C) 2025 Aspeed
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_OTP_H
+#define ASPEED_OTP_H
+
+#include "system/memory.h"
+#include "hw/block/block.h"
+#include "system/address-spaces.h"
+
+#define TYPE_ASPEED_OTP "aspeed-otp"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedOTPState, ASPEED_OTP)
+
+typedef struct AspeedOTPState {
+ DeviceState parent_obj;
+
+ BlockBackend *blk;
+
+ uint64_t size;
+
+ AddressSpace as;
+
+ MemoryRegion mmio;
+
+ uint8_t *storage;
+} AspeedOTPState;
+
+#endif /* ASPEED_OTP_H */
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 47578cc..d41b932 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -42,14 +42,6 @@ struct FWCfgDataGeneratorClass {
typedef struct fw_cfg_file FWCfgFile;
-#define FW_CFG_ORDER_OVERRIDE_VGA 70
-#define FW_CFG_ORDER_OVERRIDE_NIC 80
-#define FW_CFG_ORDER_OVERRIDE_USER 100
-#define FW_CFG_ORDER_OVERRIDE_DEVICE 110
-
-void fw_cfg_set_order_override(FWCfgState *fw_cfg, int order);
-void fw_cfg_reset_order_override(FWCfgState *fw_cfg);
-
typedef struct FWCfgFiles {
uint32_t count;
FWCfgFile f[];
@@ -75,8 +67,6 @@ struct FWCfgState {
uint32_t cur_offset;
Notifier machine_ready;
- int fw_cfg_order_override;
-
bool dma_enabled;
dma_addr_t dma_addr;
AddressSpace *dma_as;
diff --git a/include/hw/pci-host/aspeed_pcie.h b/include/hw/pci-host/aspeed_pcie.h
new file mode 100644
index 0000000..be53ea96
--- /dev/null
+++ b/include/hw/pci-host/aspeed_pcie.h
@@ -0,0 +1,137 @@
+/*
+ * ASPEED PCIe Host Controller
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ * Copyright (c) 2022 Cédric Le Goater <clg@kaod.org>
+ *
+ * Authors:
+ * Cédric Le Goater <clg@kaod.org>
+ * Jamin Lin <jamin_lin@aspeedtech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Based on previous work from Cédric Le Goater.
+ * Modifications extend support for the ASPEED AST2600 and AST2700 platforms.
+ */
+
+#ifndef ASPEED_PCIE_H
+#define ASPEED_PCIE_H
+
+#include "hw/sysbus.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pcie_port.h"
+#include "qom/object.h"
+
+typedef struct AspeedPCIECfgTxDesc {
+ uint32_t desc0;
+ uint32_t desc1;
+ uint32_t desc2;
+ uint32_t desc3;
+ uint32_t wdata;
+ uint32_t rdata_reg;
+} AspeedPCIECfgTxDesc;
+
+typedef struct AspeedPCIERcRegs {
+ uint32_t int_en_reg;
+ uint32_t int_sts_reg;
+ uint32_t msi_sts0_reg;
+ uint32_t msi_sts1_reg;
+} AspeedPCIERcRegs;
+
+typedef struct AspeedPCIERegMap {
+ AspeedPCIERcRegs rc;
+} AspeedPCIERegMap;
+
+#define TYPE_ASPEED_PCIE_ROOT_PORT "aspeed.pcie-root-port"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERootPortState, ASPEED_PCIE_ROOT_PORT)
+
+typedef struct AspeedPCIERootPortState {
+ PCIESlot parent_obj;
+} AspeedPCIERootPortState;
+
+#define TYPE_ASPEED_PCIE_ROOT_DEVICE "aspeed.pcie-root-device"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERootDeviceState, ASPEED_PCIE_ROOT_DEVICE);
+
+struct AspeedPCIERootDeviceState {
+ PCIBridge parent_obj;
+};
+
+#define TYPE_ASPEED_PCIE_RC "aspeed.pcie-rc"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERcState, ASPEED_PCIE_RC);
+
+struct AspeedPCIERcState {
+ PCIExpressHost parent_obj;
+
+ MemoryRegion iommu_root;
+ AddressSpace iommu_as;
+ MemoryRegion dram_alias;
+ MemoryRegion *dram_mr;
+ MemoryRegion mmio_window;
+ MemoryRegion msi_window;
+ MemoryRegion io_window;
+ MemoryRegion mmio;
+ MemoryRegion io;
+
+ uint64_t dram_base;
+ uint32_t msi_addr;
+ uint32_t rp_addr;
+ uint32_t bus_nr;
+ char name[16];
+ bool has_rd;
+ qemu_irq irq;
+
+ AspeedPCIERootDeviceState root_device;
+ AspeedPCIERootPortState root_port;
+};
+
+/* Bridge between AHB bus and PCIe RC. */
+#define TYPE_ASPEED_PCIE_CFG "aspeed.pcie-cfg"
+#define TYPE_ASPEED_2700_PCIE_CFG TYPE_ASPEED_PCIE_CFG "-ast2700"
+OBJECT_DECLARE_TYPE(AspeedPCIECfgState, AspeedPCIECfgClass, ASPEED_PCIE_CFG);
+
+struct AspeedPCIECfgState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t *regs;
+ uint32_t id;
+
+ const AspeedPCIERcRegs *rc_regs;
+ AspeedPCIERcState rc;
+ uint32_t tlpn_fifo[3];
+ uint32_t tlpn_idx;
+};
+
+struct AspeedPCIECfgClass {
+ SysBusDeviceClass parent_class;
+
+ const AspeedPCIERegMap *reg_map;
+ const MemoryRegionOps *reg_ops;
+
+ uint32_t rc_msi_addr;
+ uint32_t rc_rp_addr;
+ uint64_t rc_bus_nr;
+ uint64_t nr_regs;
+ bool rc_has_rd;
+};
+
+#define TYPE_ASPEED_PCIE_PHY "aspeed.pcie-phy"
+#define TYPE_ASPEED_2700_PCIE_PHY TYPE_ASPEED_PCIE_PHY "-ast2700"
+OBJECT_DECLARE_TYPE(AspeedPCIEPhyState, AspeedPCIEPhyClass, ASPEED_PCIE_PHY);
+
+struct AspeedPCIEPhyState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t *regs;
+ uint32_t id;
+};
+
+struct AspeedPCIEPhyClass {
+ SysBusDeviceClass parent_class;
+
+ uint64_t nr_regs;
+};
+
+#endif /* ASPEED_PCIE_H */
diff --git a/include/hw/pci-host/dino.h b/include/hw/pci-host/dino.h
index fd7975c..5dc8cdf 100644
--- a/include/hw/pci-host/dino.h
+++ b/include/hw/pci-host/dino.h
@@ -109,10 +109,6 @@ static const uint32_t reg800_keep_bits[DINO800_REGS] = {
struct DinoState {
PCIHostState parent_obj;
- /*
- * PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
- * so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops.
- */
uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
uint32_t iar0;
diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
index 8447153..feaf827 100644
--- a/include/hw/pci-host/gpex.h
+++ b/include/hw/pci-host/gpex.h
@@ -45,6 +45,7 @@ struct GPEXConfig {
MemMapEntry pio;
int irq;
PCIBus *bus;
+ bool pci_native_hotplug;
};
typedef struct GPEXIrq GPEXIrq;
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index 79d4ea8..33e7942 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -13,41 +13,4 @@
#include "qemu/range.h"
#include "qom/object.h"
-#define VIRT_PCI_MEM_BASE 0x40000000UL
-#define VIRT_PCI_MEM_SIZE 0x40000000UL
-#define VIRT_PCI_IO_OFFSET 0x4000
-#define VIRT_PCI_CFG_BASE 0x20000000
-#define VIRT_PCI_CFG_SIZE 0x08000000
-#define VIRT_PCI_IO_BASE 0x18004000UL
-#define VIRT_PCI_IO_SIZE 0xC000
-
-#define VIRT_PCH_REG_BASE 0x10000000UL
-#define VIRT_IOAPIC_REG_BASE (VIRT_PCH_REG_BASE)
-#define VIRT_PCH_MSI_ADDR_LOW 0x2FF00000UL
-#define VIRT_PCH_REG_SIZE 0x400
-#define VIRT_PCH_MSI_SIZE 0x8
-
-/*
- * GSI_BASE is hard-coded with 64 in linux kernel, else kernel fails to boot
- * 0 - 15 GSI for ISA devices even if there is no ISA devices
- * 16 - 63 GSI for CPU devices such as timers/perf monitor etc
- * 64 - GSI for external devices
- */
-#define VIRT_PCH_PIC_IRQ_NUM 32
-#define VIRT_GSI_BASE 64
-#define VIRT_DEVICE_IRQS 16
-#define VIRT_UART_COUNT 4
-#define VIRT_UART_IRQ (VIRT_GSI_BASE + 2)
-#define VIRT_UART_BASE 0x1fe001e0
-#define VIRT_UART_SIZE 0x100
-#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 6)
-#define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000)
-#define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100)
-#define VIRT_RTC_LEN 0x100
-#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 7)
-
-#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000
-#define VIRT_PLATFORM_BUS_SIZE 0x2000000
-#define VIRT_PLATFORM_BUS_NUM_IRQS 2
-#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 8)
#endif
diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h
index 0e6f257..11ef945 100644
--- a/include/hw/pci/msix.h
+++ b/include/hw/pci/msix.h
@@ -32,6 +32,7 @@ int msix_present(PCIDevice *dev);
bool msix_is_masked(PCIDevice *dev, unsigned vector);
void msix_set_pending(PCIDevice *dev, unsigned vector);
void msix_clr_pending(PCIDevice *dev, int vector);
+int msix_is_pending(PCIDevice *dev, unsigned vector);
void msix_vector_use(PCIDevice *dev, unsigned vector);
void msix_vector_unuse(PCIDevice *dev, unsigned vector);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c2fe6ca..6bccb25 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -134,6 +134,15 @@ struct PCIHostDeviceAddress {
unsigned int function;
};
+/*
+ * Represents the Address Type (AT) field in a PCI request,
+ * see MemTxAttrs.address_type
+ */
+typedef enum PCIAddressType {
+ PCI_AT_UNTRANSLATED = 0, /* Default when no attribute is set */
+ PCI_AT_TRANSLATED = 1,
+} PCIAddressType;
+
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
uint32_t address, uint32_t data, int len);
typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
@@ -222,6 +231,8 @@ enum {
QEMU_PCIE_EXT_TAG = (1 << QEMU_PCIE_EXT_TAG_BITNR),
#define QEMU_PCI_CAP_PM_BITNR 14
QEMU_PCI_CAP_PM = (1 << QEMU_PCI_CAP_PM_BITNR),
+#define QEMU_PCI_SKIP_RESET_ON_CPR_BITNR 15
+ QEMU_PCI_SKIP_RESET_ON_CPR = (1 << QEMU_PCI_SKIP_RESET_ON_CPR_BITNR),
};
typedef struct PCIINTxRoute {
@@ -375,6 +386,28 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range);
void pci_device_deassert_intx(PCIDevice *dev);
+/* Page Request Interface */
+typedef enum {
+ IOMMU_PRI_RESP_SUCCESS,
+ IOMMU_PRI_RESP_INVALID_REQUEST,
+ IOMMU_PRI_RESP_FAILURE,
+} IOMMUPRIResponseCode;
+
+typedef struct IOMMUPRIResponse {
+ IOMMUPRIResponseCode response_code;
+ uint16_t prgi;
+} IOMMUPRIResponse;
+
+struct IOMMUPRINotifier;
+
+typedef void (*IOMMUPRINotify)(struct IOMMUPRINotifier *notifier,
+ IOMMUPRIResponse *response);
+
+typedef struct IOMMUPRINotifier {
+ IOMMUPRINotify notify;
+} IOMMUPRINotifier;
+
+#define PCI_PRI_PRGI_MASK 0x1ffU
/**
* struct PCIIOMMUOps: callbacks structure for specific IOMMU handlers
@@ -429,6 +462,179 @@ typedef struct PCIIOMMUOps {
* @devfn: device and function number of the PCI device.
*/
void (*unset_iommu_device)(PCIBus *bus, void *opaque, int devfn);
+ /**
+ * @get_iotlb_info: get properties required to initialize a device IOTLB.
+ *
+ * Callback required if devices are allowed to cache translations.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @addr_width: the address width of the IOMMU (output parameter).
+ *
+ * @min_page_size: the page size of the IOMMU (output parameter).
+ */
+ void (*get_iotlb_info)(void *opaque, uint8_t *addr_width,
+ uint32_t *min_page_size);
+ /**
+ * @init_iotlb_notifier: initialize an IOMMU notifier.
+ *
+ * Optional callback.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @n: the notifier to be initialized.
+ *
+ * @fn: the callback to be installed.
+ *
+ * @user_opaque: a user pointer that can be used to track a state.
+ */
+ void (*init_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn,
+ IOMMUNotifier *n, IOMMUNotify fn,
+ void *user_opaque);
+ /**
+ * @register_iotlb_notifier: setup an IOTLB invalidation notifier.
+ *
+ * Callback required if devices are allowed to cache translations.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @pasid: the pasid of the address space to watch.
+ *
+ * @n: the notifier to register.
+ */
+ void (*register_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn,
+ uint32_t pasid, IOMMUNotifier *n);
+ /**
+ * @unregister_iotlb_notifier: remove an IOTLB invalidation notifier.
+ *
+ * Callback required if devices are allowed to cache translations.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @pasid: the pasid of the address space to stop watching.
+ *
+ * @n: the notifier to unregister.
+ */
+ void (*unregister_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn,
+ uint32_t pasid, IOMMUNotifier *n);
+ /**
+ * @ats_request_translation: issue an ATS request.
+ *
+ * Callback required if devices are allowed to use the address
+ * translation service.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @pasid: the pasid of the address space to use for the request.
+ *
+ * @priv_req: privileged mode bit (PASID TLP).
+ *
+ * @exec_req: execute request bit (PASID TLP).
+ *
+ * @addr: start address of the memory range to be translated.
+ *
+ * @length: length of the memory range in bytes.
+ *
+ * @no_write: request a read-only translation (if supported).
+ *
+ * @result: buffer in which the TLB entries will be stored.
+ *
+ * @result_length: result buffer length.
+ *
+ * @err_count: number of untranslated subregions.
+ *
+ * Returns: the number of translations stored in the result buffer, or
+ * -ENOMEM if the buffer is not large enough.
+ */
+ ssize_t (*ats_request_translation)(PCIBus *bus, void *opaque, int devfn,
+ uint32_t pasid, bool priv_req,
+ bool exec_req, hwaddr addr,
+ size_t length, bool no_write,
+ IOMMUTLBEntry *result,
+ size_t result_length,
+ uint32_t *err_count);
+ /**
+ * @pri_register_notifier: setup the PRI completion callback.
+ *
+ * Callback required if devices are allowed to use the page request
+ * interface.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @pasid: the pasid of the address space to track.
+ *
+ * @notifier: the notifier to register.
+ */
+ void (*pri_register_notifier)(PCIBus *bus, void *opaque, int devfn,
+ uint32_t pasid, IOMMUPRINotifier *notifier);
+ /**
+ * @pri_unregister_notifier: remove the PRI completion callback.
+ *
+ * Callback required if devices are allowed to use the page request
+ * interface.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @pasid: the pasid of the address space to stop tracking.
+ */
+ void (*pri_unregister_notifier)(PCIBus *bus, void *opaque, int devfn,
+ uint32_t pasid);
+ /**
+ * @pri_request_page: issue a PRI request.
+ *
+ * Callback required if devices are allowed to use the page request
+ * interface.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @pasid: the pasid of the address space to use for the request.
+ *
+ * @priv_req: privileged mode bit (PASID TLP).
+ *
+ * @exec_req: execute request bit (PASID TLP).
+ *
+ * @addr: untranslated address of the requested page.
+ *
+ * @lpig: last page in group.
+ *
+ * @prgi: page request group index.
+ *
+ * @is_read: request read access.
+ *
+ * @is_write: request write access.
+ */
+ int (*pri_request_page)(PCIBus *bus, void *opaque, int devfn,
+ uint32_t pasid, bool priv_req, bool exec_req,
+ hwaddr addr, bool lpig, uint16_t prgi, bool is_read,
+ bool is_write);
} PCIIOMMUOps;
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
@@ -437,6 +643,126 @@ bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
void pci_device_unset_iommu_device(PCIDevice *dev);
/**
+ * pci_iommu_get_iotlb_info: get properties required to initialize a
+ * device IOTLB.
+ *
+ * Returns 0 on success, or a negative errno otherwise.
+ *
+ * @dev: the device that wants to get the information.
+ * @addr_width: the address width of the IOMMU (output parameter).
+ * @min_page_size: the page size of the IOMMU (output parameter).
+ */
+int pci_iommu_get_iotlb_info(PCIDevice *dev, uint8_t *addr_width,
+ uint32_t *min_page_size);
+
+/**
+ * pci_iommu_init_iotlb_notifier: initialize an IOMMU notifier.
+ *
+ * This function is used by devices before registering an IOTLB notifier.
+ *
+ * @dev: the device.
+ * @n: the notifier to be initialized.
+ * @fn: the callback to be installed.
+ * @opaque: a user pointer that can be used to track a state.
+ */
+int pci_iommu_init_iotlb_notifier(PCIDevice *dev, IOMMUNotifier *n,
+ IOMMUNotify fn, void *opaque);
+
+/**
+ * pci_ats_request_translation: perform an ATS request.
+ *
+ * Returns the number of translations stored in @result in case of success,
+ * a negative error code otherwise.
+ * -ENOMEM is returned when the result buffer is not large enough to store
+ * all the translations.
+ *
+ * @dev: the ATS-capable PCI device.
+ * @pasid: the pasid of the address space in which the translation will be done.
+ * @priv_req: privileged mode bit (PASID TLP).
+ * @exec_req: execute request bit (PASID TLP).
+ * @addr: start address of the memory range to be translated.
+ * @length: length of the memory range in bytes.
+ * @no_write: request a read-only translation (if supported).
+ * @result: buffer in which the TLB entries will be stored.
+ * @result_length: result buffer length.
+ * @err_count: number of untranslated subregions.
+ */
+ssize_t pci_ats_request_translation(PCIDevice *dev, uint32_t pasid,
+ bool priv_req, bool exec_req,
+ hwaddr addr, size_t length,
+ bool no_write, IOMMUTLBEntry *result,
+ size_t result_length,
+ uint32_t *err_count);
+
+/**
+ * pci_pri_request_page: perform a PRI request.
+ *
+ * Returns 0 if the PRI request has been sent to the guest OS,
+ * an error code otherwise.
+ *
+ * @dev: the PRI-capable PCI device.
+ * @pasid: the pasid of the address space in which the translation will be done.
+ * @priv_req: privileged mode bit (PASID TLP).
+ * @exec_req: execute request bit (PASID TLP).
+ * @addr: untranslated address of the requested page.
+ * @lpig: last page in group.
+ * @prgi: page request group index.
+ * @is_read: request read access.
+ * @is_write: request write access.
+ */
+int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req,
+ bool exec_req, hwaddr addr, bool lpig,
+ uint16_t prgi, bool is_read, bool is_write);
+
+/**
+ * pci_pri_register_notifier: register the PRI callback for a given address
+ * space.
+ *
+ * Returns 0 on success, an error code otherwise.
+ *
+ * @dev: the PRI-capable PCI device.
+ * @pasid: the pasid of the address space to track.
+ * @notifier: the notifier to register.
+ */
+int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid,
+ IOMMUPRINotifier *notifier);
+
+/**
+ * pci_pri_unregister_notifier: remove the PRI callback from a given address
+ * space.
+ *
+ * @dev: the PRI-capable PCI device.
+ * @pasid: the pasid of the address space to stop tracking.
+ */
+void pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid);
+
+/**
+ * pci_iommu_register_iotlb_notifier: register a notifier for changes to
+ * IOMMU translation entries in a specific address space.
+ *
+ * Returns 0 on success, or a negative errno otherwise.
+ *
+ * @dev: the device that wants to get notified.
+ * @pasid: the pasid of the address space to track.
+ * @n: the notifier to register.
+ */
+int pci_iommu_register_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
+ IOMMUNotifier *n);
+
+/**
+ * pci_iommu_unregister_iotlb_notifier: unregister a notifier that has been
+ * registerd with pci_iommu_register_iotlb_notifier.
+ *
+ * Returns 0 on success, or a negative errno otherwise.
+ *
+ * @dev: the device that wants to stop notifications.
+ * @pasid: the pasid of the address space to stop tracking.
+ * @n: the notifier to unregister.
+ */
+int pci_iommu_unregister_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
+ IOMMUNotifier *n);
+
+/**
* pci_setup_iommu: Initialize specific IOMMU handlers for a PCIBus
*
* Let PCI host bridges define specific operations.
@@ -447,6 +773,8 @@ void pci_device_unset_iommu_device(PCIDevice *dev);
*/
void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque);
+void pci_setup_iommu_per_bus(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque);
+
pcibus_t pci_bar_address(PCIDevice *d,
int reg, uint8_t type, pcibus_t size);
@@ -668,6 +996,7 @@ void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev);
qemu_irq pci_allocate_irq(PCIDevice *pci_dev);
void pci_set_irq(PCIDevice *pci_dev, int level);
+int pci_irq_disabled(PCIDevice *d);
static inline void pci_irq_assert(PCIDevice *pci_dev)
{
diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
index b0f5204..a055fd8 100644
--- a/include/hw/pci/pci_bridge.h
+++ b/include/hw/pci/pci_bridge.h
@@ -14,8 +14,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program; if not, see
+ * <https://www.gnu.org/licenses/>.
*
* split out pci bus specific stuff from pci.[hc] to pci_bridge.[hc]
* Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
@@ -104,6 +104,7 @@ typedef struct PXBPCIEDev {
PXBDev parent_obj;
} PXBPCIEDev;
+#define TYPE_PXB_PCIE_BUS "pxb-pcie-bus"
#define TYPE_PXB_CXL_BUS "pxb-cxl-bus"
#define TYPE_PXB_DEV "pxb"
OBJECT_DECLARE_SIMPLE_TYPE(PXBDev, PXB_DEV)
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 2261312..c738446 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -35,6 +35,7 @@ struct PCIBus {
enum PCIBusFlags flags;
const PCIIOMMUOps *iommu_ops;
void *iommu_opaque;
+ bool iommu_per_bus;
uint8_t devfn_min;
uint32_t slot_reserved_mask;
pci_set_irq_fn set_irq;
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index 345b12e..eee0338 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -38,6 +38,8 @@ struct PCIDeviceClass {
uint16_t subsystem_id; /* only for header type = 0 */
const char *romfile; /* rom bar */
+
+ bool sriov_vf_user_creatable;
};
enum PCIReqIDType {
@@ -88,6 +90,7 @@ struct PCIDevice {
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
AddressSpace bus_master_as;
+ bool is_master;
MemoryRegion bus_master_container_region;
MemoryRegion bus_master_enable_region;
@@ -177,6 +180,8 @@ struct PCIDevice {
* realizing the device.
*/
uint32_t max_bounce_buffer_size;
+
+ char *sriov_pf;
};
static inline int pci_intx(PCIDevice *pci_dev)
@@ -209,7 +214,7 @@ static inline int pci_is_express_downstream_port(const PCIDevice *d)
static inline int pci_is_vf(const PCIDevice *d)
{
- return d->exp.sriov_vf.pf != NULL;
+ return d->sriov_pf || d->exp.sriov_vf.pf != NULL;
}
static inline uint32_t pci_config_size(const PCIDevice *d)
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index e52d8ec..954dd44 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -68,6 +68,5 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, unsigned len);
extern const MemoryRegionOps pci_host_conf_le_ops;
extern const MemoryRegionOps pci_host_conf_be_ops;
extern const MemoryRegionOps pci_host_data_le_ops;
-extern const MemoryRegionOps pci_host_data_be_ops;
#endif /* PCI_HOST_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 33e2898..16034aa 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -291,4 +291,6 @@
#define PCI_VENDOR_ID_NVIDIA 0x10de
+#define PCI_VENDOR_ID_ASPEED 0x1A03
+
#endif
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 70a5de0..42cebcd 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -70,8 +70,10 @@ struct PCIExpressDevice {
uint16_t aer_cap;
PCIEAERLog aer_log;
- /* Offset of ATS capability in config space */
+ /* Offset of ATS, PRI and PASID capabilities in config space */
uint16_t ats_cap;
+ uint16_t pasid_cap;
+ uint16_t pri_cap;
/* ACS */
uint16_t acs_cap;
@@ -150,4 +152,14 @@ void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp);
void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
+
+void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
+ bool exec_perm, bool priv_mod);
+void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
+ bool prg_response_pasid_req);
+
+uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev);
+bool pcie_pri_enabled(const PCIDevice *dev);
+bool pcie_pasid_enabled(const PCIDevice *dev);
+bool pcie_ats_enabled(const PCIDevice *dev);
#endif /* QEMU_PCIE_H */
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 9d3b686..33a2222 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -86,6 +86,14 @@ typedef enum PCIExpLinkWidth {
#define PCI_ARI_VER 1
#define PCI_ARI_SIZEOF 8
+/* PASID */
+#define PCI_PASID_VER 1
+#define PCI_EXT_CAP_PASID_MAX_WIDTH 20
+#define PCI_PASID_CAP_WIDTH_SHIFT 8
+
+/* PRI */
+#define PCI_PRI_VER 1
+
/* AER */
#define PCI_ERR_VER 2
#define PCI_ERR_SIZEOF 0x48
diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h
index c5d2d31..b0ea6a6 100644
--- a/include/hw/pci/pcie_sriov.h
+++ b/include/hw/pci/pcie_sriov.h
@@ -18,6 +18,7 @@
typedef struct PCIESriovPF {
uint8_t vf_bar_type[PCI_NUM_REGIONS]; /* Store type for each VF bar */
PCIDevice **vf; /* Pointer to an array of num_vfs VF devices */
+ bool vf_user_created; /* If VFs are created by user */
} PCIESriovPF;
typedef struct PCIESriovVF {
@@ -36,9 +37,25 @@ void pcie_sriov_pf_exit(PCIDevice *dev);
void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
uint8_t type, dma_addr_t size);
-/* Instantiate a bar for a VF */
-void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
- MemoryRegion *memory);
+/**
+ * pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
+ * VFs, adding ARI to PF
+ * @dev: A PCIe device being realized.
+ * @offset: The offset of the SR-IOV capability.
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Initializes a PF with user-created VFs, adding the ARI extended capability to
+ * the PF. The VFs should call pcie_ari_init() to form an ARI device.
+ *
+ * Return: The size of added capabilities. 0 if the user did not create VFs.
+ * -1 if failed.
+ */
+int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
+ uint16_t offset,
+ Error **errp);
+
+bool pcie_sriov_register_device(PCIDevice *dev, Error **errp);
+void pcie_sriov_unregister_device(PCIDevice *dev);
/*
* Default (minimal) page size support values
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index d8fca07..cbdddfc 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -33,6 +33,7 @@ typedef struct PnvChip PnvChip;
typedef struct Pnv8Chip Pnv8Chip;
typedef struct Pnv9Chip Pnv9Chip;
typedef struct Pnv10Chip Pnv10Chip;
+typedef struct Pnv10Chip Pnv11Chip;
#define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
#define PNV_CHIP_TYPE_NAME(cpu_model) cpu_model PNV_CHIP_TYPE_SUFFIX
@@ -57,6 +58,10 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER9,
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER10,
TYPE_PNV_CHIP_POWER10)
+#define TYPE_PNV_CHIP_POWER11 PNV_CHIP_TYPE_NAME("power11_v2.0")
+DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER11,
+ TYPE_PNV_CHIP_POWER11)
+
PnvCore *pnv_chip_find_core(PnvChip *chip, uint32_t core_id);
PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir);
@@ -252,4 +257,37 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
#define PNV10_HOMER_BASE(chip) \
(0x300ffd800000ll + ((uint64_t)(chip)->chip_id) * PNV_HOMER_SIZE)
+/* Power11 */
+#define PNV11_XSCOM_SIZE PNV10_XSCOM_SIZE
+#define PNV11_XSCOM_BASE(chip) PNV10_XSCOM_BASE(chip)
+
+#define PNV11_LPCM_SIZE PNV10_LPCM_SIZE
+#define PNV11_LPCM_BASE(chip) PNV10_LPCM_BASE(chip)
+
+#define PNV11_PSIHB_ESB_SIZE PNV10_PSIHB_ESB_SIZE
+#define PNV11_PSIHB_ESB_BASE(chip) PNV10_PSIHB_ESB_BASE(chip)
+
+#define PNV11_PSIHB_SIZE PNV10_PSIHB_SIZE
+#define PNV11_PSIHB_BASE(chip) PNV10_PSIHB_BASE(chip)
+
+#define PNV11_XIVE2_IC_SIZE PNV10_XIVE2_IC_SIZE
+#define PNV11_XIVE2_IC_BASE(chip) PNV10_XIVE2_IC_BASE(chip)
+
+#define PNV11_XIVE2_TM_SIZE PNV10_XIVE2_TM_SIZE
+#define PNV11_XIVE2_TM_BASE(chip) PNV10_XIVE2_TM_BASE(chip)
+
+#define PNV11_XIVE2_NVC_SIZE PNV10_XIVE2_NVC_SIZE
+#define PNV11_XIVE2_NVC_BASE(chip) PNV10_XIVE2_NVC_BASE(chip)
+
+#define PNV11_XIVE2_NVPG_SIZE PNV10_XIVE2_NVPG_SIZE
+#define PNV11_XIVE2_NVPG_BASE(chip) PNV10_XIVE2_NVPG_BASE(chip)
+
+#define PNV11_XIVE2_ESB_SIZE PNV10_XIVE2_ESB_SIZE
+#define PNV11_XIVE2_ESB_BASE(chip) PNV10_XIVE2_ESB_BASE(chip)
+
+#define PNV11_XIVE2_END_SIZE PNV10_XIVE2_END_SIZE
+#define PNV11_XIVE2_END_BASE(chip) PNV10_XIVE2_END_BASE(chip)
+
+#define PNV11_OCC_SENSOR_BASE(chip) PNV10_OCC_SENSOR_BASE(chip)
+
#endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 24ce37a..a5b8c49 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -141,6 +141,13 @@ struct Pnv10Chip {
#define PNV10_PIR2CHIP(pir) (((pir) >> 8) & 0x7f)
#define PNV10_PIR2THREAD(pir) (((pir) & 0x7f))
+#define TYPE_PNV11_CHIP "pnv11-chip"
+DECLARE_INSTANCE_CHECKER(Pnv11Chip, PNV11_CHIP,
+ TYPE_PNV11_CHIP)
+
+/* Power11 core is same as Power10 */
+typedef struct Pnv10Chip Pnv11Chip;
+
struct PnvChipClass {
/*< private >*/
SysBusDeviceClass parent_class;
@@ -163,6 +170,7 @@ struct PnvChipClass {
void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu);
void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu);
void (*intc_print_info)(PnvChip *chip, PowerPCCPU *cpu, GString *buf);
+ void* (*intc_get)(PnvChip *chip);
ISABus *(*isa_create)(PnvChip *chip, Error **errp);
void (*dt_populate)(PnvChip *chip, void *fdt);
void (*pic_print_info)(PnvChip *chip, GString *buf);
diff --git a/include/hw/ppc/pnv_chiptod.h b/include/hw/ppc/pnv_chiptod.h
index fde569b..466b065 100644
--- a/include/hw/ppc/pnv_chiptod.h
+++ b/include/hw/ppc/pnv_chiptod.h
@@ -17,6 +17,8 @@ OBJECT_DECLARE_TYPE(PnvChipTOD, PnvChipTODClass, PNV_CHIPTOD)
DECLARE_INSTANCE_CHECKER(PnvChipTOD, PNV9_CHIPTOD, TYPE_PNV9_CHIPTOD)
#define TYPE_PNV10_CHIPTOD TYPE_PNV_CHIPTOD "-POWER10"
DECLARE_INSTANCE_CHECKER(PnvChipTOD, PNV10_CHIPTOD, TYPE_PNV10_CHIPTOD)
+#define TYPE_PNV11_CHIPTOD TYPE_PNV_CHIPTOD "-POWER11"
+DECLARE_INSTANCE_CHECKER(PnvChipTOD, PNV11_CHIPTOD, TYPE_PNV11_CHIPTOD)
enum tod_state {
tod_error = 0,
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index b14549d..610b075 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -207,6 +207,55 @@ struct PnvXScomInterfaceClass {
#define PNV10_XSCOM_PIB_SPIC_BASE 0xc0000
#define PNV10_XSCOM_PIB_SPIC_SIZE 0x20
+/*
+ * Power11 core is same as Power10
+ */
+#define PNV11_XSCOM_EC_BASE(core) PNV10_XSCOM_EC_BASE(core)
+
+#define PNV11_XSCOM_ADU_BASE PNV10_XSCOM_ADU_BASE
+#define PNV11_XSCOM_ADU_SIZE PNV10_XSCOM_ADU_SIZE
+
+#define PNV11_XSCOM_QME_BASE(core) PNV10_XSCOM_QME_BASE(core)
+
+#define PNV11_XSCOM_EQ_BASE(core) PNV10_XSCOM_EQ_BASE(core)
+
+#define PNV11_XSCOM_PSIHB_BASE PNV10_XSCOM_PSIHB_BASE
+#define PNV11_XSCOM_PSIHB_SIZE PNV10_XSCOM_PSIHB_SIZE
+
+#define PNV11_XSCOM_I2CM_BASE PNV10_XSCOM_I2CM_BASE
+#define PNV11_XSCOM_I2CM_SIZE PNV10_XSCOM_I2CM_SIZE
+
+#define PNV11_XSCOM_CHIPTOD_BASE PNV10_XSCOM_CHIPTOD_BASE
+#define PNV11_XSCOM_CHIPTOD_SIZE PNV10_XSCOM_CHIPTOD_SIZE
+
+#define PNV11_XSCOM_OCC_BASE PNV10_XSCOM_OCC_BASE
+#define PNV11_XSCOM_OCC_SIZE PNV10_XSCOM_OCC_SIZE
+
+#define PNV11_XSCOM_SBE_CTRL_BASE PNV10_XSCOM_SBE_CTRL_BASE
+#define PNV11_XSCOM_SBE_CTRL_SIZE PNV10_XSCOM_SBE_CTRL_SIZE
+
+#define PNV11_XSCOM_SBE_MBOX_BASE PNV10_XSCOM_SBE_MBOX_BASE
+#define PNV11_XSCOM_SBE_MBOX_SIZE PNV10_XSCOM_SBE_MBOX_SIZE
+
+#define PNV11_XSCOM_PBA_BASE PNV10_XSCOM_PBA_BASE
+#define PNV11_XSCOM_PBA_SIZE PNV10_XSCOM_PBA_SIZE
+
+#define PNV11_XSCOM_XIVE2_BASE PNV10_XSCOM_XIVE2_BASE
+#define PNV11_XSCOM_XIVE2_SIZE PNV10_XSCOM_XIVE2_SIZE
+
+#define PNV11_XSCOM_N1_CHIPLET_CTRL_REGS_BASE \
+ PNV10_XSCOM_N1_CHIPLET_CTRL_REGS_BASE
+#define PNV11_XSCOM_CHIPLET_CTRL_REGS_SIZE PNV10_XSCOM_CHIPLET_CTRL_REGS_SIZE
+
+#define PNV11_XSCOM_N1_PB_SCOM_EQ_BASE PNV10_XSCOM_N1_PB_SCOM_EQ_BASE
+#define PNV11_XSCOM_N1_PB_SCOM_EQ_SIZE PNV10_XSCOM_N1_PB_SCOM_EQ_SIZE
+
+#define PNV11_XSCOM_N1_PB_SCOM_ES_BASE PNV10_XSCOM_N1_PB_SCOM_ES_BASE
+#define PNV11_XSCOM_N1_PB_SCOM_ES_SIZE PNV10_XSCOM_N1_PB_SCOM_ES_SIZE
+
+#define PNV11_XSCOM_PIB_SPIC_BASE PNV10_XSCOM_PIB_SPIC_BASE
+#define PNV11_XSCOM_PIB_SPIC_SIZE PNV10_XSCOM_PIB_SPIC_SIZE
+
void pnv_xscom_init(PnvChip *chip, uint64_t size, hwaddr addr);
int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
uint64_t xscom_base, uint64_t xscom_size,
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 8a14d62..cb51d70 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -52,6 +52,7 @@ struct ppc_tb_t {
#define PPC_DECR_UNDERFLOW_LEVEL (1 << 4) /* Decr interrupt active when
* the most significant bit is 1.
*/
+#define PPC_TIMER_PPE (1 << 5) /* Enable PPE support */
uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset);
void cpu_ppc_tb_init(CPUPPCState *env, uint32_t freq);
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 538f438..b7ca854 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -365,6 +365,11 @@ static inline uint32_t xive_tctx_word2(uint8_t *ring)
return *((uint32_t *) &ring[TM_WORD2]);
}
+bool xive_ring_valid(XiveTCTX *tctx, uint8_t ring);
+bool xive_nsr_indicates_exception(uint8_t ring, uint8_t nsr);
+bool xive_nsr_indicates_group_exception(uint8_t ring, uint8_t nsr);
+uint8_t xive_nsr_exception_ring(uint8_t ring, uint8_t nsr);
+
/*
* XIVE Router
*/
@@ -421,6 +426,7 @@ void xive_router_end_notify(XiveRouter *xrtr, XiveEAS *eas);
typedef struct XiveTCTXMatch {
XiveTCTX *tctx;
+ int count;
uint8_t ring;
bool precluded;
} XiveTCTXMatch;
@@ -436,10 +442,10 @@ DECLARE_CLASS_CHECKERS(XivePresenterClass, XIVE_PRESENTER,
struct XivePresenterClass {
InterfaceClass parent;
- int (*match_nvt)(XivePresenter *xptr, uint8_t format,
- uint8_t nvt_blk, uint32_t nvt_idx,
- bool crowd, bool cam_ignore, uint8_t priority,
- uint32_t logic_serv, XiveTCTXMatch *match);
+ bool (*match_nvt)(XivePresenter *xptr, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool crowd, bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match);
bool (*in_kernel)(const XivePresenter *xptr);
uint32_t (*get_config)(XivePresenter *xptr);
int (*broadcast)(XivePresenter *xptr,
@@ -451,12 +457,14 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
uint8_t format,
uint8_t nvt_blk, uint32_t nvt_idx,
bool cam_ignore, uint32_t logic_serv);
-bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
- uint8_t nvt_blk, uint32_t nvt_idx,
- bool crowd, bool cam_ignore, uint8_t priority,
- uint32_t logic_serv, bool *precluded);
+bool xive_presenter_match(XiveFabric *xfb, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool crowd, bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match);
uint32_t xive_get_vpgroup_size(uint32_t nvp_index);
+uint8_t xive_get_group_level(bool crowd, bool ignore,
+ uint32_t nvp_blk, uint32_t nvp_index);
/*
* XIVE Fabric (Interface between Interrupt Controller and Machine)
@@ -471,10 +479,10 @@ DECLARE_CLASS_CHECKERS(XiveFabricClass, XIVE_FABRIC,
struct XiveFabricClass {
InterfaceClass parent;
- int (*match_nvt)(XiveFabric *xfb, uint8_t format,
- uint8_t nvt_blk, uint32_t nvt_idx,
- bool crowd, bool cam_ignore, uint8_t priority,
- uint32_t logic_serv, XiveTCTXMatch *match);
+ bool (*match_nvt)(XiveFabric *xfb, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool crowd, bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match);
int (*broadcast)(XiveFabric *xfb, uint8_t nvt_blk, uint32_t nvt_idx,
bool crowd, bool cam_ignore, uint8_t priority);
};
@@ -532,7 +540,7 @@ static inline uint8_t xive_ipb_to_pipr(uint8_t ibp)
}
/*
- * XIVE Thread Interrupt Management Aera (TIMA)
+ * XIVE Thread Interrupt Management Area (TIMA)
*
* This region gives access to the registers of the thread interrupt
* management context. It is four page wide, each page providing a
@@ -544,6 +552,30 @@ static inline uint8_t xive_ipb_to_pipr(uint8_t ibp)
#define XIVE_TM_OS_PAGE 0x2
#define XIVE_TM_USER_PAGE 0x3
+/*
+ * The TCTX (TIMA) has 4 rings (phys, pool, os, user), but only signals
+ * (raises an interrupt on) the CPU from 3 of them. Phys and pool both
+ * cause a hypervisor privileged interrupt so interrupts presented on
+ * those rings signal using the phys ring. This helper returns the signal
+ * regs from the given ring.
+ */
+static inline uint8_t *xive_tctx_signal_regs(XiveTCTX *tctx, uint8_t ring)
+{
+ /*
+ * This is a good point to add invariants to ensure nothing has tried to
+ * signal using the POOL ring.
+ */
+ g_assert(tctx->regs[TM_QW2_HV_POOL + TM_NSR] == 0);
+ g_assert(tctx->regs[TM_QW2_HV_POOL + TM_PIPR] == 0);
+ g_assert(tctx->regs[TM_QW2_HV_POOL + TM_CPPR] == 0);
+
+ if (ring == TM_QW2_HV_POOL) {
+ /* POOL and PHYS rings share the signal regs (PIPR, NSR, CPPR) */
+ ring = TM_QW3_HV_PHYS;
+ }
+ return &tctx->regs[ring];
+}
+
void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
uint64_t value, unsigned size);
uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
@@ -553,10 +585,12 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, GString *buf);
Object *xive_tctx_create(Object *cpu, XivePresenter *xptr, Error **errp);
void xive_tctx_reset(XiveTCTX *tctx);
void xive_tctx_destroy(XiveTCTX *tctx);
-void xive_tctx_pipr_update(XiveTCTX *tctx, uint8_t ring, uint8_t priority,
- uint8_t group_level);
+void xive_tctx_pipr_set(XiveTCTX *tctx, uint8_t ring, uint8_t priority,
+ uint8_t group_level);
+void xive_tctx_pipr_present(XiveTCTX *tctx, uint8_t ring, uint8_t priority,
+ uint8_t group_level);
void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring);
-void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring, uint8_t group_level);
+uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring);
/*
* KVM XIVE device helpers
diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
index 8cdf819..f4437e2 100644
--- a/include/hw/ppc/xive2.h
+++ b/include/hw/ppc/xive2.h
@@ -29,9 +29,11 @@ OBJECT_DECLARE_TYPE(Xive2Router, Xive2RouterClass, XIVE2_ROUTER);
* Configuration flags
*/
-#define XIVE2_GEN1_TIMA_OS 0x00000001
-#define XIVE2_VP_SAVE_RESTORE 0x00000002
-#define XIVE2_THREADID_8BITS 0x00000004
+#define XIVE2_GEN1_TIMA_OS 0x00000001
+#define XIVE2_VP_SAVE_RESTORE 0x00000002
+#define XIVE2_THREADID_8BITS 0x00000004
+#define XIVE2_EN_VP_GRP_PRIORITY 0x00000008
+#define XIVE2_VP_INT_PRIO 0x00000030
typedef struct Xive2RouterClass {
SysBusDeviceClass parent;
@@ -80,6 +82,7 @@ int xive2_router_write_nvgc(Xive2Router *xrtr, bool crowd,
uint32_t xive2_router_get_config(Xive2Router *xrtr);
void xive2_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked);
+void xive2_notify(Xive2Router *xrtr, uint32_t lisn, bool pq_checked);
/*
* XIVE2 Presenter (POWER10)
@@ -127,6 +130,8 @@ void xive2_tm_set_hv_cppr(XivePresenter *xptr, XiveTCTX *tctx,
hwaddr offset, uint64_t value, unsigned size);
void xive2_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
hwaddr offset, uint64_t value, unsigned size);
+void xive2_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
+ hwaddr offset, uint64_t value, unsigned size);
void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
uint64_t value, unsigned size);
uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
@@ -137,7 +142,16 @@ bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority);
void xive2_tm_set_lsmfb(XiveTCTX *tctx, int ring, uint8_t priority);
void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx,
hwaddr offset, uint64_t value, unsigned size);
+void xive2_tm_push_pool_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+ hwaddr offset, uint64_t value, unsigned size);
+uint64_t xive2_tm_pull_pool_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+ hwaddr offset, unsigned size);
+void xive2_tm_push_phys_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+ hwaddr offset, uint64_t value, unsigned size);
+uint64_t xive2_tm_pull_phys_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+ hwaddr offset, unsigned size);
void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
hwaddr offset, uint64_t value, unsigned size);
-
+void xive2_tm_ack_os_el(XivePresenter *xptr, XiveTCTX *tctx,
+ hwaddr offset, uint64_t value, unsigned size);
#endif /* PPC_XIVE2_H */
diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
index b11395c..2a3e60a 100644
--- a/include/hw/ppc/xive2_regs.h
+++ b/include/hw/ppc/xive2_regs.h
@@ -39,15 +39,18 @@
typedef struct Xive2Eas {
uint64_t w;
-#define EAS2_VALID PPC_BIT(0)
-#define EAS2_END_BLOCK PPC_BITMASK(4, 7) /* Destination EQ block# */
-#define EAS2_END_INDEX PPC_BITMASK(8, 31) /* Destination EQ index */
-#define EAS2_MASKED PPC_BIT(32) /* Masked */
-#define EAS2_END_DATA PPC_BITMASK(33, 63) /* written to the EQ */
+#define EAS2_VALID PPC_BIT(0)
+#define EAS2_QOS PPC_BIT(1, 2) /* Quality of Service(unimp) */
+#define EAS2_RESUME PPC_BIT(3) /* END Resume(unimp) */
+#define EAS2_END_BLOCK PPC_BITMASK(4, 7) /* Destination EQ block# */
+#define EAS2_END_INDEX PPC_BITMASK(8, 31) /* Destination EQ index */
+#define EAS2_MASKED PPC_BIT(32) /* Masked */
+#define EAS2_END_DATA PPC_BITMASK(33, 63) /* written to the EQ */
} Xive2Eas;
#define xive2_eas_is_valid(eas) (be64_to_cpu((eas)->w) & EAS2_VALID)
#define xive2_eas_is_masked(eas) (be64_to_cpu((eas)->w) & EAS2_MASKED)
+#define xive2_eas_is_resume(eas) (be64_to_cpu((eas)->w) & EAS2_RESUME)
void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf);
@@ -87,6 +90,7 @@ typedef struct Xive2End {
#define END2_W2_EQ_ADDR_HI PPC_BITMASK32(8, 31)
uint32_t w3;
#define END2_W3_EQ_ADDR_LO PPC_BITMASK32(0, 24)
+#define END2_W3_CL PPC_BIT32(27)
#define END2_W3_QSIZE PPC_BITMASK32(28, 31)
uint32_t w4;
#define END2_W4_END_BLOCK PPC_BITMASK32(4, 7)
@@ -154,6 +158,7 @@ typedef struct Xive2Nvp {
#define NVP2_W0_L PPC_BIT32(8)
#define NVP2_W0_G PPC_BIT32(9)
#define NVP2_W0_T PPC_BIT32(10)
+#define NVP2_W0_P PPC_BIT32(11)
#define NVP2_W0_ESC_END PPC_BIT32(25) /* 'N' bit 0:ESB 1:END */
#define NVP2_W0_PGOFIRST PPC_BITMASK32(26, 31)
uint32_t w1;
@@ -205,9 +210,9 @@ static inline uint32_t xive2_nvp_idx(uint32_t cam_line)
return cam_line & ((1 << XIVE2_NVP_SHIFT) - 1);
}
-static inline uint32_t xive2_nvp_blk(uint32_t cam_line)
+static inline uint8_t xive2_nvp_blk(uint32_t cam_line)
{
- return (cam_line >> XIVE2_NVP_SHIFT) & 0xf;
+ return (uint8_t)((cam_line >> XIVE2_NVP_SHIFT) & 0xf);
}
void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf);
@@ -220,6 +225,9 @@ typedef struct Xive2Nvgc {
#define NVGC2_W0_VALID PPC_BIT32(0)
#define NVGC2_W0_PGONEXT PPC_BITMASK32(26, 31)
uint32_t w1;
+#define NVGC2_W1_PSIZE PPC_BITMASK32(0, 1)
+#define NVGC2_W1_END_BLK PPC_BITMASK32(4, 7)
+#define NVGC2_W1_END_IDX PPC_BITMASK32(8, 31)
uint32_t w2;
uint32_t w3;
uint32_t w4;
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 530f3da..a7bfb10 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -1064,6 +1064,7 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
extern bool qdev_hot_removed;
char *qdev_get_dev_path(DeviceState *dev);
+const char *qdev_get_printable_name(DeviceState *dev);
void qbus_set_hotplug_handler(BusState *bus, Object *handler);
void qbus_set_bus_hotplug_handler(BusState *bus);
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index b921392..9601a11 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -32,6 +32,7 @@ extern const PropertyInfo qdev_prop_cpus390entitlement;
extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
extern const PropertyInfo qdev_prop_endian_mode;
extern const PropertyInfo qdev_prop_vmapple_virtio_blk_variant;
+extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
@@ -110,4 +111,8 @@ extern const PropertyInfo qdev_prop_vmapple_virtio_blk_variant;
qdev_prop_vmapple_virtio_blk_variant, \
VMAppleVirtioBlkVariant)
+#define DEFINE_PROP_VIRTIO_GPU_OUTPUT_LIST(_name, _state, _field) \
+ DEFINE_PROP(_name, _state, _field, qdev_prop_virtio_gpu_output_list, \
+ VirtIOGPUOutputList *)
+
#endif
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 2c99856..0197aa4 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -43,11 +43,22 @@ struct PropertyInfo {
ObjectPropertyRelease *release;
};
+/**
+ * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements.
+ * @on_bits: Bitmap of elements with "on".
+ * @auto_bits: Bitmap of elements with "auto".
+ */
+typedef struct OnOffAutoBit64 {
+ uint64_t on_bits;
+ uint64_t auto_bits;
+} OnOffAutoBit64;
+
/*** qdev-properties.c ***/
extern const PropertyInfo qdev_prop_bit;
extern const PropertyInfo qdev_prop_bit64;
+extern const PropertyInfo qdev_prop_on_off_auto_bit64;
extern const PropertyInfo qdev_prop_bool;
extern const PropertyInfo qdev_prop_uint8;
extern const PropertyInfo qdev_prop_uint16;
@@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link;
.set_default = true, \
.defval.u = (bool)_defval)
+#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \
+ DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64, \
+ OnOffAutoBit64, \
+ .bitnr = (_bit), \
+ .set_default = true, \
+ .defval.i = (OnOffAuto)_defval)
+
#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \
DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
.set_default = true, \
diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h
index b03339d..8a8acfc 100644
--- a/include/hw/riscv/iommu.h
+++ b/include/hw/riscv/iommu.h
@@ -30,14 +30,12 @@ typedef struct RISCVIOMMUState RISCVIOMMUState;
typedef struct RISCVIOMMUSpace RISCVIOMMUSpace;
#define TYPE_RISCV_IOMMU_PCI "riscv-iommu-pci"
-OBJECT_DECLARE_TYPE(RISCVIOMMUStatePci, RISCVIOMMUPciClass, RISCV_IOMMU_PCI)
+OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI)
typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci;
-typedef struct RISCVIOMMUPciClass RISCVIOMMUPciClass;
#define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device"
-OBJECT_DECLARE_TYPE(RISCVIOMMUStateSys, RISCVIOMMUSysClass, RISCV_IOMMU_SYS)
+OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS)
typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys;
-typedef struct RISCVIOMMUSysClass RISCVIOMMUSysClass;
#define FDT_IRQ_TYPE_EDGE_LOW 1
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
index daef086..7ca9b97 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -67,6 +67,7 @@ typedef struct MicrochipIcicleKitState {
MachineState parent_obj;
/*< public >*/
+ uint32_t clint_timebase_freq;
MicrochipPFSoCState soc;
} MicrochipIcicleKitState;
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 48a14be..7b4c2c8 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -63,6 +63,7 @@ struct RISCVVirtState {
const MemMapEntry *memmap;
struct GPEXHost *gpex_host;
OnOffAuto iommu_sys;
+ uint16_t pci_iommu_bdf;
};
enum {
diff --git a/include/hw/riscv/xiangshan_kmh.h b/include/hw/riscv/xiangshan_kmh.h
new file mode 100644
index 0000000..c5dc6b1
--- /dev/null
+++ b/include/hw/riscv/xiangshan_kmh.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * QEMU RISC-V Board Compatible with the Xiangshan Kunminghu
+ * FPGA prototype platform
+ *
+ * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
+ *
+ */
+
+#ifndef HW_XIANGSHAN_KMH_H
+#define HW_XIANGSHAN_KMH_H
+
+#include "hw/boards.h"
+#include "hw/riscv/riscv_hart.h"
+
+#define XIANGSHAN_KMH_MAX_CPUS 16
+
+typedef struct XiangshanKmhSoCState {
+ /*< private >*/
+ DeviceState parent_obj;
+
+ /*< public >*/
+ RISCVHartArrayState cpus;
+ DeviceState *irqchip;
+ MemoryRegion rom;
+} XiangshanKmhSoCState;
+
+#define TYPE_XIANGSHAN_KMH_SOC "xiangshan.kunminghu.soc"
+DECLARE_INSTANCE_CHECKER(XiangshanKmhSoCState, XIANGSHAN_KMH_SOC,
+ TYPE_XIANGSHAN_KMH_SOC)
+
+typedef struct XiangshanKmhState {
+ /*< private >*/
+ MachineState parent_obj;
+
+ /*< public >*/
+ XiangshanKmhSoCState soc;
+} XiangshanKmhState;
+
+#define TYPE_XIANGSHAN_KMH_MACHINE MACHINE_TYPE_NAME("xiangshan-kunminghu")
+DECLARE_INSTANCE_CHECKER(XiangshanKmhState, XIANGSHAN_KMH_MACHINE,
+ TYPE_XIANGSHAN_KMH_MACHINE)
+
+enum {
+ XIANGSHAN_KMH_ROM,
+ XIANGSHAN_KMH_UART0,
+ XIANGSHAN_KMH_CLINT,
+ XIANGSHAN_KMH_APLIC_M,
+ XIANGSHAN_KMH_APLIC_S,
+ XIANGSHAN_KMH_IMSIC_M,
+ XIANGSHAN_KMH_IMSIC_S,
+ XIANGSHAN_KMH_DRAM,
+};
+
+enum {
+ XIANGSHAN_KMH_UART0_IRQ = 10,
+};
+
+/* Indicating Timebase-freq (1MHZ) */
+#define XIANGSHAN_KMH_CLINT_TIMEBASE_FREQ 1000000
+
+#define XIANGSHAN_KMH_IMSIC_NUM_IDS 255
+#define XIANGSHAN_KMH_IMSIC_NUM_GUESTS 7
+#define XIANGSHAN_KMH_IMSIC_GUEST_BITS 3
+
+#define XIANGSHAN_KMH_APLIC_NUM_SOURCES 96
+
+#endif
diff --git a/include/hw/s390x/ap-bridge.h b/include/hw/s390x/ap-bridge.h
index 470e439..7efc529 100644
--- a/include/hw/s390x/ap-bridge.h
+++ b/include/hw/s390x/ap-bridge.h
@@ -16,4 +16,43 @@
void s390_init_ap(void);
+typedef struct ChscSeiNt0Res {
+ uint16_t length;
+ uint16_t code;
+ uint8_t reserved1;
+ uint16_t reserved2;
+ uint8_t nt;
+#define PENDING_EVENT_INFO_BITMASK 0x80;
+ uint8_t flags;
+ uint8_t reserved3;
+ uint8_t rs;
+ uint8_t cc;
+} QEMU_PACKED ChscSeiNt0Res;
+
+#define NT0_RES_RESPONSE_CODE 1
+#define NT0_RES_NT_DEFAULT 0
+#define NT0_RES_RS_AP_CHANGE 5
+#define NT0_RES_CC_AP_CHANGE 3
+
+#define EVENT_INFORMATION_NOT_STORED 1
+#define EVENT_INFORMATION_STORED 0
+
+/**
+ * ap_chsc_sei_nt0_get_event - Retrieve the next pending AP config
+ * change event
+ * @res: Pointer to a ChscSeiNt0Res struct to be filled with event
+ * data
+ *
+ * This function checks for any pending AP config change events and,
+ * if present, populates the provided response structure with the
+ * appropriate SEI NT0 fields.
+ *
+ * Return:
+ * EVENT_INFORMATION_STORED - An event was available and written to @res
+ * EVENT_INFORMATION_NOT_STORED - No event was available
+ */
+int ap_chsc_sei_nt0_get_event(void *res);
+
+bool ap_chsc_sei_nt0_have_event(void);
+
#endif
diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
index 9283c94..d5e9aa4 100644
--- a/include/hw/s390x/cpu-topology.h
+++ b/include/hw/s390x/cpu-topology.h
@@ -13,7 +13,7 @@
#include "qemu/queue.h"
#include "hw/boards.h"
-#include "qapi/qapi-types-machine-target.h"
+#include "qapi/qapi-types-machine-s390x.h"
#define S390_TOPOLOGY_CPU_IFL 0x03
diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h
index ff874e7..eac7a51 100644
--- a/include/hw/s390x/event-facility.h
+++ b/include/hw/s390x/event-facility.h
@@ -25,6 +25,7 @@
#define SCLP_EVENT_MESSAGE 0x02
#define SCLP_EVENT_CONFIG_MGT_DATA 0x04
#define SCLP_EVENT_PMSGCMD 0x09
+#define SCLP_EVENT_CTRL_PGM_ID 0x0b
#define SCLP_EVENT_ASCII_CONSOLE_DATA 0x1a
#define SCLP_EVENT_SIGNAL_QUIESCE 0x1d
@@ -35,6 +36,7 @@
#define SCLP_EVENT_MASK_MSG SCLP_EVMASK(SCLP_EVENT_MESSAGE)
#define SCLP_EVENT_MASK_CONFIG_MGT_DATA SCLP_EVMASK(SCLP_EVENT_CONFIG_MGT_DATA)
#define SCLP_EVENT_MASK_PMSGCMD SCLP_EVMASK(SCLP_EVENT_PMSGCMD)
+#define SCLP_EVENT_MASK_CTRL_PGM_ID SCLP_EVMASK(SCLP_EVENT_CTRL_PGM_ID)
#define SCLP_EVENT_MASK_MSG_ASCII SCLP_EVMASK(SCLP_EVENT_ASCII_CONSOLE_DATA)
#define SCLP_EVENT_MASK_SIGNAL_QUIESCE SCLP_EVMASK(SCLP_EVENT_SIGNAL_QUIESCE)
@@ -191,6 +193,21 @@ struct SCLPEventClass {
bool (*can_handle_event)(uint8_t type);
};
+#define TYPE_SCLP_EVENT_CPI "sclpcpi"
+typedef struct SCLPEventCPIClass SCLPEventCPIClass;
+typedef struct SCLPEventCPI SCLPEventCPI;
+OBJECT_DECLARE_TYPE(SCLPEventCPI, SCLPEventCPIClass,
+ SCLP_EVENT_CPI)
+
+struct SCLPEventCPI {
+ SCLPEvent event;
+ uint8_t system_type[8];
+ uint8_t system_name[8];
+ uint64_t system_level;
+ uint8_t sysplex_name[8];
+ uint64_t timestamp;
+};
+
#define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility"
typedef struct SCLPEventFacility SCLPEventFacility;
typedef struct SCLPEventFacilityClass SCLPEventFacilityClass;
diff --git a/include/hw/s390x/s390-pci-kvm.h b/include/hw/s390x/s390-pci-kvm.h
index 933814a..c33f283 100644
--- a/include/hw/s390x/s390-pci-kvm.h
+++ b/include/hw/s390x/s390-pci-kvm.h
@@ -14,12 +14,19 @@
#include "hw/s390x/s390-pci-bus.h"
#include "hw/s390x/s390-pci-inst.h"
+#include "system/kvm.h"
#ifdef CONFIG_KVM
+static inline void s390_pcihost_kvm_realize(void)
+{
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
+}
+
bool s390_pci_kvm_interp_allowed(void);
int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist);
int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev);
#else
+static inline void s390_pcihost_kvm_realize(void) {}
static inline bool s390_pci_kvm_interp_allowed(void)
{
return false;
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
index 686d949..526078a 100644
--- a/include/hw/s390x/s390-virtio-ccw.h
+++ b/include/hw/s390x/s390-virtio-ccw.h
@@ -53,11 +53,8 @@ struct S390CcwMachineClass {
MachineClass parent_class;
/*< public >*/
- bool hpage_1m_allowed;
int max_threads;
+ bool use_cpi;
};
-/* 1M huge page mappings allowed by the machine */
-bool hpage_1m_allowed(void);
-
#endif
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index 533d856..3526bad 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -14,7 +14,11 @@ typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, uint8_t *buf, int len);
#define ESP_FIFO_SZ 16
#define ESP_CMDFIFO_SZ 32
-typedef struct ESPState ESPState;
+enum ESPASCMode {
+ ESP_ASC_MODE_DIS = 0, /* Disconnected */
+ ESP_ASC_MODE_INI = 1, /* Initiator */
+ ESP_ASC_MODE_TGT = 2 /* Target */
+};
#define TYPE_ESP "esp"
OBJECT_DECLARE_SIMPLE_TYPE(ESPState, ESP)
@@ -40,6 +44,7 @@ struct ESPState {
uint8_t cmdfifo_cdb_offset;
uint8_t lun;
uint32_t do_cmd;
+ uint8_t asc_mode;
bool data_ready;
int dma_enabled;
@@ -106,6 +111,13 @@ struct SysBusESPState {
#define CMD_DMA 0x80
#define CMD_CMD 0x7f
+#define CMD_GRP_MASK 0x70
+
+#define CMD_GRP_MISC 0x00
+#define CMD_GRP_INIT 0x01
+#define CMD_GRP_TRGT 0x02
+#define CMD_GRP_DISC 0x04
+
#define CMD_NOP 0x00
#define CMD_FLUSH 0x01
#define CMD_RESET 0x02
@@ -140,6 +152,7 @@ struct SysBusESPState {
#define INTR_FC 0x08
#define INTR_BS 0x10
#define INTR_DC 0x20
+#define INTR_IL 0x40
#define INTR_RST 0x80
#define SEQ_0 0x0
diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index d6bad17..91b5c40 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -56,7 +56,6 @@
#define AKE_SEQ_ERROR (1 << 3)
enum SDPhySpecificationVersion {
- SD_PHY_SPECv1_10_VERS = 1,
SD_PHY_SPECv2_00_VERS = 2,
SD_PHY_SPECv3_01_VERS = 3,
};
@@ -96,7 +95,17 @@ struct SDCardClass {
DeviceClass parent_class;
/*< public >*/
- int (*do_command)(SDState *sd, SDRequest *req, uint8_t *response);
+ /**
+ * Process a SD command request.
+ * @sd: card
+ * @req: command request
+ * @resp: buffer to receive the command response
+ * @respsz: size of @resp buffer
+ *
+ * Return: size of the response
+ */
+ size_t (*do_command)(SDState *sd, SDRequest *req,
+ uint8_t *resp, size_t respsz);
/**
* Write a byte to a SD card.
* @sd: card
@@ -153,7 +162,16 @@ struct SDBusClass {
void sdbus_set_voltage(SDBus *sdbus, uint16_t millivolts);
uint8_t sdbus_get_dat_lines(SDBus *sdbus);
bool sdbus_get_cmd_line(SDBus *sdbus);
-int sdbus_do_command(SDBus *sd, SDRequest *req, uint8_t *response);
+/**
+ * sdbus_do_command: Process a SD command request
+ * @sd: card
+ * @req: command request
+ * @resp: buffer to receive the command response
+ * @respsz: size of @resp buffer
+ *
+ * Return: size of the response
+ */
+size_t sdbus_do_command(SDBus *sd, SDRequest *req, uint8_t *resp, size_t respsz);
/**
* Write a byte to a SD bus.
* @sd: bus
diff --git a/include/hw/southbridge/ich9.h b/include/hw/southbridge/ich9.h
index 1e231e8..2c35dd0 100644
--- a/include/hw/southbridge/ich9.h
+++ b/include/hw/southbridge/ich9.h
@@ -95,7 +95,7 @@ struct ICH9LPCState {
#define ICH9_CC_OIC 0x31FF
#define ICH9_CC_OIC_AEN 0x1
#define ICH9_CC_GCS 0x3410
-#define ICH9_CC_GCS_DEFAULT 0x00000020
+#define ICH9_CC_GCS_DEFAULT 0x00000000
#define ICH9_CC_GCS_NO_REBOOT (1 << 5)
/* D28:F[0-5] */
diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h
index 3cdcbd5..2ad8033 100644
--- a/include/hw/ssi/ssi.h
+++ b/include/hw/ssi/ssi.h
@@ -38,6 +38,7 @@ struct SSIPeripheralClass {
/* if you have standard or no CS behaviour, just override transfer.
* This is called when the device cs is active (true by default).
+ * See ssi_transfer().
*/
uint32_t (*transfer)(SSIPeripheral *dev, uint32_t val);
/* called when the CS line changes. Optional, devices only need to implement
@@ -52,6 +53,7 @@ struct SSIPeripheralClass {
* of the CS behaviour at the device level. transfer, set_cs, and
* cs_polarity are unused if this is overwritten. Transfer_raw will
* always be called for the device for every txrx access to the parent bus
+ * See ssi_transfer().
*/
uint32_t (*transfer_raw)(SSIPeripheral *dev, uint32_t val);
};
@@ -110,6 +112,18 @@ bool ssi_realize_and_unref(DeviceState *dev, SSIBus *bus, Error **errp);
/* Master interface. */
SSIBus *ssi_create_bus(DeviceState *parent, const char *name);
+/**
+ * Transfer a word on a SSI bus
+ * @bus: SSI bus
+ * @val: word to transmit
+ *
+ * At the same time, read a word and write the @val one on the SSI bus.
+ *
+ * SSI words might vary between 8 and 32 bits. The same number of bits
+ * written is received.
+ *
+ * Return: word value received
+ */
uint32_t ssi_transfer(SSIBus *bus, uint32_t val);
DeviceState *ssi_get_cs(SSIBus *bus, uint8_t cs_index);
diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
index 7dc88aa..18fde8a 100644
--- a/include/hw/sysbus.h
+++ b/include/hw/sysbus.h
@@ -82,6 +82,7 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
bool sysbus_is_irq_connected(SysBusDevice *dev, int n);
qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n);
void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr);
+int sysbus_mmio_map_name(SysBusDevice *dev, const char*name, hwaddr addr);
void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
int priority);
diff --git a/include/hw/timer/aspeed_timer.h b/include/hw/timer/aspeed_timer.h
index 767cae4..a850625 100644
--- a/include/hw/timer/aspeed_timer.h
+++ b/include/hw/timer/aspeed_timer.h
@@ -16,8 +16,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef ASPEED_TIMER_H
#define ASPEED_TIMER_H
diff --git a/include/hw/vfio/vfio-amd-xgbe.h b/include/hw/vfio/vfio-amd-xgbe.h
deleted file mode 100644
index a894546..0000000
--- a/include/hw/vfio/vfio-amd-xgbe.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * VFIO AMD XGBE device
- *
- * Copyright Linaro Limited, 2015
- *
- * Authors:
- * Eric Auger <eric.auger@linaro.org>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef HW_VFIO_VFIO_AMD_XGBE_H
-#define HW_VFIO_VFIO_AMD_XGBE_H
-
-#include "hw/vfio/vfio-platform.h"
-#include "qom/object.h"
-
-#define TYPE_VFIO_AMD_XGBE "vfio-amd-xgbe"
-
-/**
- * This device exposes:
- * - 5 MMIO regions: MAC, PCS, SerDes Rx/Tx regs,
- SerDes Integration Registers 1/2 & 2/2
- * - 2 level sensitive IRQs and optional DMA channel IRQs
- */
-struct VFIOAmdXgbeDevice {
- VFIOPlatformDevice vdev;
-};
-
-typedef struct VFIOAmdXgbeDevice VFIOAmdXgbeDevice;
-
-struct VFIOAmdXgbeDeviceClass {
- /*< private >*/
- VFIOPlatformDeviceClass parent_class;
- /*< public >*/
- DeviceRealize parent_realize;
-};
-
-typedef struct VFIOAmdXgbeDeviceClass VFIOAmdXgbeDeviceClass;
-
-DECLARE_OBJ_CHECKERS(VFIOAmdXgbeDevice, VFIOAmdXgbeDeviceClass,
- VFIO_AMD_XGBE_DEVICE, TYPE_VFIO_AMD_XGBE)
-
-#endif
diff --git a/include/hw/vfio/vfio-calxeda-xgmac.h b/include/hw/vfio/vfio-calxeda-xgmac.h
deleted file mode 100644
index 8482f15..0000000
--- a/include/hw/vfio/vfio-calxeda-xgmac.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * VFIO calxeda xgmac device
- *
- * Copyright Linaro Limited, 2014
- *
- * Authors:
- * Eric Auger <eric.auger@linaro.org>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef HW_VFIO_VFIO_CALXEDA_XGMAC_H
-#define HW_VFIO_VFIO_CALXEDA_XGMAC_H
-
-#include "hw/vfio/vfio-platform.h"
-#include "qom/object.h"
-
-#define TYPE_VFIO_CALXEDA_XGMAC "vfio-calxeda-xgmac"
-
-/**
- * This device exposes:
- * - a single MMIO region corresponding to its register space
- * - 3 IRQS (main and 2 power related IRQs)
- */
-struct VFIOCalxedaXgmacDevice {
- VFIOPlatformDevice vdev;
-};
-typedef struct VFIOCalxedaXgmacDevice VFIOCalxedaXgmacDevice;
-
-struct VFIOCalxedaXgmacDeviceClass {
- /*< private >*/
- VFIOPlatformDeviceClass parent_class;
- /*< public >*/
- DeviceRealize parent_realize;
-};
-typedef struct VFIOCalxedaXgmacDeviceClass VFIOCalxedaXgmacDeviceClass;
-
-DECLARE_OBJ_CHECKERS(VFIOCalxedaXgmacDevice, VFIOCalxedaXgmacDeviceClass,
- VFIO_CALXEDA_XGMAC_DEVICE, TYPE_VFIO_CALXEDA_XGMAC)
-
-#endif
diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h
deleted file mode 100644
index 5527e02..0000000
--- a/include/hw/vfio/vfio-container-base.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * VFIO BASE CONTAINER
- *
- * Copyright (C) 2023 Intel Corporation.
- * Copyright Red Hat, Inc. 2023
- *
- * Authors: Yi Liu <yi.l.liu@intel.com>
- * Eric Auger <eric.auger@redhat.com>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef HW_VFIO_VFIO_CONTAINER_BASE_H
-#define HW_VFIO_VFIO_CONTAINER_BASE_H
-
-#include "system/memory.h"
-
-typedef struct VFIODevice VFIODevice;
-typedef struct VFIOIOMMUClass VFIOIOMMUClass;
-
-typedef struct {
- unsigned long *bitmap;
- hwaddr size;
- hwaddr pages;
-} VFIOBitmap;
-
-typedef struct VFIOAddressSpace {
- AddressSpace *as;
- QLIST_HEAD(, VFIOContainerBase) containers;
- QLIST_ENTRY(VFIOAddressSpace) list;
-} VFIOAddressSpace;
-
-/*
- * This is the base object for vfio container backends
- */
-typedef struct VFIOContainerBase {
- Object parent;
- VFIOAddressSpace *space;
- MemoryListener listener;
- Error *error;
- bool initialized;
- uint64_t dirty_pgsizes;
- uint64_t max_dirty_bitmap_size;
- unsigned long pgsizes;
- unsigned int dma_max_mappings;
- bool dirty_pages_supported;
- bool dirty_pages_started; /* Protected by BQL */
- QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
- QLIST_HEAD(, VFIORamDiscardListener) vrdl_list;
- QLIST_ENTRY(VFIOContainerBase) next;
- QLIST_HEAD(, VFIODevice) device_list;
- GList *iova_ranges;
- NotifierWithReturn cpr_reboot_notifier;
-} VFIOContainerBase;
-
-typedef struct VFIOGuestIOMMU {
- VFIOContainerBase *bcontainer;
- IOMMUMemoryRegion *iommu_mr;
- hwaddr iommu_offset;
- IOMMUNotifier n;
- QLIST_ENTRY(VFIOGuestIOMMU) giommu_next;
-} VFIOGuestIOMMU;
-
-typedef struct VFIORamDiscardListener {
- VFIOContainerBase *bcontainer;
- MemoryRegion *mr;
- hwaddr offset_within_address_space;
- hwaddr size;
- uint64_t granularity;
- RamDiscardListener listener;
- QLIST_ENTRY(VFIORamDiscardListener) next;
-} VFIORamDiscardListener;
-
-VFIOAddressSpace *vfio_address_space_get(AddressSpace *as);
-void vfio_address_space_put(VFIOAddressSpace *space);
-void vfio_address_space_insert(VFIOAddressSpace *space,
- VFIOContainerBase *bcontainer);
-
-int vfio_container_dma_map(VFIOContainerBase *bcontainer,
- hwaddr iova, ram_addr_t size,
- void *vaddr, bool readonly);
-int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
- hwaddr iova, ram_addr_t size,
- IOMMUTLBEntry *iotlb);
-bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
- MemoryRegionSection *section,
- Error **errp);
-void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
- MemoryRegionSection *section);
-int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
- bool start, Error **errp);
-bool vfio_container_dirty_tracking_is_started(
- const VFIOContainerBase *bcontainer);
-bool vfio_container_devices_dirty_tracking_is_supported(
- const VFIOContainerBase *bcontainer);
-int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
- uint64_t iova, uint64_t size, ram_addr_t ram_addr, Error **errp);
-
-GList *vfio_container_get_iova_ranges(const VFIOContainerBase *bcontainer);
-
-static inline uint64_t
-vfio_container_get_page_size_mask(const VFIOContainerBase *bcontainer)
-{
- assert(bcontainer);
- return bcontainer->pgsizes;
-}
-
-#define TYPE_VFIO_IOMMU "vfio-iommu"
-#define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy"
-#define TYPE_VFIO_IOMMU_SPAPR TYPE_VFIO_IOMMU "-spapr"
-#define TYPE_VFIO_IOMMU_IOMMUFD TYPE_VFIO_IOMMU "-iommufd"
-
-OBJECT_DECLARE_TYPE(VFIOContainerBase, VFIOIOMMUClass, VFIO_IOMMU)
-
-struct VFIOIOMMUClass {
- ObjectClass parent_class;
-
- /* basic feature */
- bool (*setup)(VFIOContainerBase *bcontainer, Error **errp);
- int (*dma_map)(const VFIOContainerBase *bcontainer,
- hwaddr iova, ram_addr_t size,
- void *vaddr, bool readonly);
- int (*dma_unmap)(const VFIOContainerBase *bcontainer,
- hwaddr iova, ram_addr_t size,
- IOMMUTLBEntry *iotlb);
- bool (*attach_device)(const char *name, VFIODevice *vbasedev,
- AddressSpace *as, Error **errp);
- void (*detach_device)(VFIODevice *vbasedev);
-
- /* migration feature */
-
- /**
- * @set_dirty_page_tracking
- *
- * Start or stop dirty pages tracking on VFIO container
- *
- * @bcontainer: #VFIOContainerBase on which to de/activate dirty
- * page tracking
- * @start: indicates whether to start or stop dirty pages tracking
- * @errp: pointer to Error*, to store an error if it happens.
- *
- * Returns zero to indicate success and negative for error
- */
- int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer,
- bool start, Error **errp);
- /**
- * @query_dirty_bitmap
- *
- * Get bitmap of dirty pages from container
- *
- * @bcontainer: #VFIOContainerBase from which to get dirty pages
- * @vbmap: #VFIOBitmap internal bitmap structure
- * @iova: iova base address
- * @size: size of iova range
- * @errp: pointer to Error*, to store an error if it happens.
- *
- * Returns zero to indicate success and negative for error
- */
- int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer,
- VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp);
- /* PCI specific */
- int (*pci_hot_reset)(VFIODevice *vbasedev, bool single);
-
- /* SPAPR specific */
- bool (*add_window)(VFIOContainerBase *bcontainer,
- MemoryRegionSection *section,
- Error **errp);
- void (*del_window)(VFIOContainerBase *bcontainer,
- MemoryRegionSection *section);
- void (*release)(VFIOContainerBase *bcontainer);
-};
-
-#endif /* HW_VFIO_VFIO_CONTAINER_BASE_H */
diff --git a/include/hw/vfio/vfio-container-legacy.h b/include/hw/vfio/vfio-container-legacy.h
new file mode 100644
index 0000000..74a72df
--- /dev/null
+++ b/include/hw/vfio/vfio-container-legacy.h
@@ -0,0 +1,39 @@
+/*
+ * VFIO container
+ *
+ * Copyright Red Hat, Inc. 2025
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_VFIO_CONTAINER_LEGACY_H
+#define HW_VFIO_CONTAINER_LEGACY_H
+
+#include "hw/vfio/vfio-container.h"
+#include "hw/vfio/vfio-cpr.h"
+
+typedef struct VFIOLegacyContainer VFIOLegacyContainer;
+typedef struct VFIODevice VFIODevice;
+
+typedef struct VFIOGroup {
+ int fd;
+ int groupid;
+ VFIOLegacyContainer *container;
+ QLIST_HEAD(, VFIODevice) device_list;
+ QLIST_ENTRY(VFIOGroup) next;
+ QLIST_ENTRY(VFIOGroup) container_next;
+ bool ram_block_discard_allowed;
+} VFIOGroup;
+
+struct VFIOLegacyContainer {
+ VFIOContainer parent_obj;
+
+ int fd; /* /dev/vfio/vfio, empowered by the attached groups */
+ unsigned iommu_type;
+ QLIST_HEAD(, VFIOGroup) group_list;
+ VFIOContainerCPR cpr;
+};
+
+OBJECT_DECLARE_SIMPLE_TYPE(VFIOLegacyContainer, VFIO_IOMMU_LEGACY);
+
+#endif /* HW_VFIO_CONTAINER_LEGACY_H */
diff --git a/include/hw/vfio/vfio-container.h b/include/hw/vfio/vfio-container.h
index afc498d..c4b58d6 100644
--- a/include/hw/vfio/vfio-container.h
+++ b/include/hw/vfio/vfio-container.h
@@ -1,36 +1,280 @@
/*
- * VFIO container
+ * VFIO BASE CONTAINER
*
- * Copyright Red Hat, Inc. 2025
+ * Copyright (C) 2023 Intel Corporation.
+ * Copyright Red Hat, Inc. 2023
+ *
+ * Authors: Yi Liu <yi.l.liu@intel.com>
+ * Eric Auger <eric.auger@redhat.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#ifndef HW_VFIO_CONTAINER_H
-#define HW_VFIO_CONTAINER_H
+#ifndef HW_VFIO_VFIO_CONTAINER_H
+#define HW_VFIO_VFIO_CONTAINER_H
-#include "hw/vfio/vfio-container-base.h"
+#include "system/memory.h"
-typedef struct VFIOContainer VFIOContainer;
typedef struct VFIODevice VFIODevice;
+typedef struct VFIOIOMMUClass VFIOIOMMUClass;
+
+typedef struct {
+ unsigned long *bitmap;
+ hwaddr size;
+ hwaddr pages;
+} VFIOBitmap;
-typedef struct VFIOGroup {
- int fd;
- int groupid;
- VFIOContainer *container;
+typedef struct VFIOAddressSpace {
+ AddressSpace *as;
+ QLIST_HEAD(, VFIOContainer) containers;
+ QLIST_ENTRY(VFIOAddressSpace) list;
+} VFIOAddressSpace;
+
+/*
+ * This is the base object for vfio container backends
+ */
+struct VFIOContainer {
+ Object parent_obj;
+
+ VFIOAddressSpace *space;
+ MemoryListener listener;
+ Error *error;
+ bool initialized;
+ uint64_t dirty_pgsizes;
+ uint64_t max_dirty_bitmap_size;
+ unsigned long pgsizes;
+ unsigned int dma_max_mappings;
+ bool dirty_pages_supported;
+ bool dirty_pages_started; /* Protected by BQL */
+ QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
+ QLIST_HEAD(, VFIORamDiscardListener) vrdl_list;
+ QLIST_ENTRY(VFIOContainer) next;
QLIST_HEAD(, VFIODevice) device_list;
- QLIST_ENTRY(VFIOGroup) next;
- QLIST_ENTRY(VFIOGroup) container_next;
- bool ram_block_discard_allowed;
-} VFIOGroup;
+ GList *iova_ranges;
+ NotifierWithReturn cpr_reboot_notifier;
+};
+
+#define TYPE_VFIO_IOMMU "vfio-iommu"
+OBJECT_DECLARE_TYPE(VFIOContainer, VFIOIOMMUClass, VFIO_IOMMU)
+
+typedef struct VFIOGuestIOMMU {
+ VFIOContainer *bcontainer;
+ IOMMUMemoryRegion *iommu_mr;
+ hwaddr iommu_offset;
+ IOMMUNotifier n;
+ QLIST_ENTRY(VFIOGuestIOMMU) giommu_next;
+} VFIOGuestIOMMU;
+
+typedef struct VFIORamDiscardListener {
+ VFIOContainer *bcontainer;
+ MemoryRegion *mr;
+ hwaddr offset_within_address_space;
+ hwaddr size;
+ uint64_t granularity;
+ RamDiscardListener listener;
+ QLIST_ENTRY(VFIORamDiscardListener) next;
+} VFIORamDiscardListener;
+
+VFIOAddressSpace *vfio_address_space_get(AddressSpace *as);
+void vfio_address_space_put(VFIOAddressSpace *space);
+void vfio_address_space_insert(VFIOAddressSpace *space,
+ VFIOContainer *bcontainer);
+
+int vfio_container_dma_map(VFIOContainer *bcontainer,
+ hwaddr iova, uint64_t size,
+ void *vaddr, bool readonly, MemoryRegion *mr);
+int vfio_container_dma_unmap(VFIOContainer *bcontainer,
+ hwaddr iova, uint64_t size,
+ IOMMUTLBEntry *iotlb, bool unmap_all);
+bool vfio_container_add_section_window(VFIOContainer *bcontainer,
+ MemoryRegionSection *section,
+ Error **errp);
+void vfio_container_del_section_window(VFIOContainer *bcontainer,
+ MemoryRegionSection *section);
+int vfio_container_set_dirty_page_tracking(VFIOContainer *bcontainer,
+ bool start, Error **errp);
+bool vfio_container_dirty_tracking_is_started(
+ const VFIOContainer *bcontainer);
+bool vfio_container_devices_dirty_tracking_is_supported(
+ const VFIOContainer *bcontainer);
+int vfio_container_query_dirty_bitmap(const VFIOContainer *bcontainer,
+ uint64_t iova, uint64_t size,
+ hwaddr translated_addr, Error **errp);
+
+GList *vfio_container_get_iova_ranges(const VFIOContainer *bcontainer);
+
+static inline uint64_t
+vfio_container_get_page_size_mask(const VFIOContainer *bcontainer)
+{
+ assert(bcontainer);
+ return bcontainer->pgsizes;
+}
+
+#define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy"
+#define TYPE_VFIO_IOMMU_SPAPR TYPE_VFIO_IOMMU "-spapr"
+#define TYPE_VFIO_IOMMU_IOMMUFD TYPE_VFIO_IOMMU "-iommufd"
+#define TYPE_VFIO_IOMMU_USER TYPE_VFIO_IOMMU "-user"
+
+struct VFIOIOMMUClass {
+ ObjectClass parent_class;
+
+ /**
+ * @setup
+ *
+ * Perform basic setup of the container, including configuring IOMMU
+ * capabilities, IOVA ranges, supported page sizes, etc.
+ *
+ * @bcontainer: #VFIOContainer
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns true to indicate success and false for error.
+ */
+ bool (*setup)(VFIOContainer *bcontainer, Error **errp);
+
+ /**
+ * @listener_begin
+ *
+ * Called at the beginning of an address space update transaction.
+ * See #MemoryListener.
+ *
+ * @bcontainer: #VFIOContainer
+ */
+ void (*listener_begin)(VFIOContainer *bcontainer);
+
+ /**
+ * @listener_commit
+ *
+ * Called at the end of an address space update transaction,
+ * See #MemoryListener.
+ *
+ * @bcontainer: #VFIOContainer
+ */
+ void (*listener_commit)(VFIOContainer *bcontainer);
+
+ /**
+ * @dma_map
+ *
+ * Map an address range into the container. Note that the memory region is
+ * referenced within an RCU read lock region across this call.
+ *
+ * @bcontainer: #VFIOContainer to use
+ * @iova: start address to map
+ * @size: size of the range to map
+ * @vaddr: process virtual address of mapping
+ * @readonly: true if mapping should be readonly
+ * @mr: the memory region for this mapping
+ *
+ * Returns 0 to indicate success and -errno otherwise.
+ */
+ int (*dma_map)(const VFIOContainer *bcontainer,
+ hwaddr iova, uint64_t size,
+ void *vaddr, bool readonly, MemoryRegion *mr);
+ /**
+ * @dma_map_file
+ *
+ * Map a file range for the container.
+ *
+ * @bcontainer: #VFIOContainer to use for map
+ * @iova: start address to map
+ * @size: size of the range to map
+ * @fd: descriptor of the file to map
+ * @start: starting file offset of the range to map
+ * @readonly: map read only if true
+ */
+ int (*dma_map_file)(const VFIOContainer *bcontainer,
+ hwaddr iova, uint64_t size,
+ int fd, unsigned long start, bool readonly);
+ /**
+ * @dma_unmap
+ *
+ * Unmap an address range from the container.
+ *
+ * @bcontainer: #VFIOContainer to use for unmap
+ * @iova: start address to unmap
+ * @size: size of the range to unmap
+ * @iotlb: The IOMMU TLB mapping entry (or NULL)
+ * @unmap_all: if set, unmap the entire address space
+ *
+ * Returns 0 to indicate success and -errno otherwise.
+ */
+ int (*dma_unmap)(const VFIOContainer *bcontainer,
+ hwaddr iova, uint64_t size,
+ IOMMUTLBEntry *iotlb, bool unmap_all);
+
+
+ /**
+ * @attach_device
+ *
+ * Associate the given device with a container and do some related
+ * initialization of the device context.
+ *
+ * @name: name of the device
+ * @vbasedev: the device
+ * @as: address space to use
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns true to indicate success and false for error.
+ */
+ bool (*attach_device)(const char *name, VFIODevice *vbasedev,
+ AddressSpace *as, Error **errp);
+
+ /*
+ * @detach_device
+ *
+ * Detach the given device from its container and clean up any necessary
+ * state.
+ *
+ * @vbasedev: the device to disassociate
+ */
+ void (*detach_device)(VFIODevice *vbasedev);
+
+ /* migration feature */
+
+ /**
+ * @set_dirty_page_tracking
+ *
+ * Start or stop dirty pages tracking on VFIO container
+ *
+ * @bcontainer: #VFIOContainer on which to de/activate dirty
+ * page tracking
+ * @start: indicates whether to start or stop dirty pages tracking
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error.
+ */
+ int (*set_dirty_page_tracking)(const VFIOContainer *bcontainer,
+ bool start, Error **errp);
+ /**
+ * @query_dirty_bitmap
+ *
+ * Get bitmap of dirty pages from container
+ *
+ * @bcontainer: #VFIOContainer from which to get dirty pages
+ * @vbmap: #VFIOBitmap internal bitmap structure
+ * @iova: iova base address
+ * @size: size of iova range
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error.
+ */
+ int (*query_dirty_bitmap)(const VFIOContainer *bcontainer,
+ VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp);
+ /* PCI specific */
+ int (*pci_hot_reset)(VFIODevice *vbasedev, bool single);
+
+ /* SPAPR specific */
+ bool (*add_window)(VFIOContainer *bcontainer,
+ MemoryRegionSection *section,
+ Error **errp);
+ void (*del_window)(VFIOContainer *bcontainer,
+ MemoryRegionSection *section);
+ void (*release)(VFIOContainer *bcontainer);
+};
-typedef struct VFIOContainer {
- VFIOContainerBase bcontainer;
- int fd; /* /dev/vfio/vfio, empowered by the attached groups */
- unsigned iommu_type;
- QLIST_HEAD(, VFIOGroup) group_list;
-} VFIOContainer;
+VFIORamDiscardListener *vfio_find_ram_discard_listener(
+ VFIOContainer *bcontainer, MemoryRegionSection *section);
-OBJECT_DECLARE_SIMPLE_TYPE(VFIOContainer, VFIO_IOMMU_LEGACY);
+void vfio_container_region_add(VFIOContainer *bcontainer,
+ MemoryRegionSection *section, bool cpr_remap);
-#endif /* HW_VFIO_CONTAINER_H */
+#endif /* HW_VFIO_VFIO_CONTAINER_H */
diff --git a/include/hw/vfio/vfio-cpr.h b/include/hw/vfio/vfio-cpr.h
new file mode 100644
index 0000000..81f4e24
--- /dev/null
+++ b/include/hw/vfio/vfio-cpr.h
@@ -0,0 +1,88 @@
+/*
+ * VFIO CPR
+ *
+ * Copyright (c) 2025 Oracle and/or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_VFIO_VFIO_CPR_H
+#define HW_VFIO_VFIO_CPR_H
+
+#include "migration/misc.h"
+#include "system/memory.h"
+
+struct VFIOLegacyContainer;
+struct VFIOContainer;
+struct VFIOGroup;
+struct VFIODevice;
+struct VFIOPCIDevice;
+struct VFIOIOMMUFDContainer;
+struct IOMMUFDBackend;
+
+typedef int (*dma_map_fn)(const struct VFIOContainer *bcontainer,
+ hwaddr iova, uint64_t size, void *vaddr,
+ bool readonly, MemoryRegion *mr);
+
+typedef struct VFIOContainerCPR {
+ Error *blocker;
+ bool vaddr_unmapped;
+ NotifierWithReturn transfer_notifier;
+ MemoryListener remap_listener;
+} VFIOContainerCPR;
+
+typedef struct VFIODeviceCPR {
+ Error *mdev_blocker;
+ Error *id_blocker;
+ uint32_t hwpt_id;
+ uint32_t ioas_id;
+} VFIODeviceCPR;
+
+typedef struct VFIOPCICPR {
+ NotifierWithReturn transfer_notifier;
+} VFIOPCICPR;
+
+bool vfio_legacy_cpr_register_container(struct VFIOLegacyContainer *container,
+ Error **errp);
+void vfio_legacy_cpr_unregister_container(
+ struct VFIOLegacyContainer *container);
+
+int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier, MigrationEvent *e,
+ Error **errp);
+
+bool vfio_iommufd_cpr_register_container(struct VFIOIOMMUFDContainer *container,
+ Error **errp);
+void vfio_iommufd_cpr_unregister_container(
+ struct VFIOIOMMUFDContainer *container);
+bool vfio_iommufd_cpr_register_iommufd(struct IOMMUFDBackend *be, Error **errp);
+void vfio_iommufd_cpr_unregister_iommufd(struct IOMMUFDBackend *be);
+void vfio_iommufd_cpr_register_device(struct VFIODevice *vbasedev);
+void vfio_iommufd_cpr_unregister_device(struct VFIODevice *vbasedev);
+void vfio_cpr_load_device(struct VFIODevice *vbasedev);
+
+int vfio_cpr_group_get_device_fd(int d, const char *name);
+
+bool vfio_cpr_container_match(struct VFIOLegacyContainer *container,
+ struct VFIOGroup *group, int fd);
+
+void vfio_cpr_giommu_remap(struct VFIOContainer *bcontainer,
+ MemoryRegionSection *section);
+
+bool vfio_cpr_ram_discard_register_listener(
+ struct VFIOContainer *bcontainer, MemoryRegionSection *section);
+
+void vfio_cpr_save_vector_fd(struct VFIOPCIDevice *vdev, const char *name,
+ int nr, int fd);
+int vfio_cpr_load_vector_fd(struct VFIOPCIDevice *vdev, const char *name,
+ int nr);
+void vfio_cpr_delete_vector_fd(struct VFIOPCIDevice *vdev, const char *name,
+ int nr);
+
+extern const VMStateDescription vfio_cpr_pci_vmstate;
+extern const VMStateDescription vmstate_cpr_vfio_devices;
+
+void vfio_cpr_add_kvm_notifier(void);
+void vfio_cpr_pci_register_device(struct VFIOPCIDevice *vdev);
+void vfio_cpr_pci_unregister_device(struct VFIOPCIDevice *vdev);
+
+#endif /* HW_VFIO_VFIO_CPR_H */
diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
index 81c95bb..7e9aed6 100644
--- a/include/hw/vfio/vfio-device.h
+++ b/include/hw/vfio/vfio-device.h
@@ -18,8 +18,8 @@
* Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com)
*/
-#ifndef HW_VFIO_VFIO_COMMON_H
-#define HW_VFIO_VFIO_COMMON_H
+#ifndef HW_VFIO_VFIO_DEVICE_H
+#define HW_VFIO_VFIO_DEVICE_H
#include "system/memory.h"
#include "qemu/queue.h"
@@ -27,7 +27,8 @@
#include <linux/vfio.h>
#endif
#include "system/system.h"
-#include "hw/vfio/vfio-container-base.h"
+#include "hw/vfio/vfio-container.h"
+#include "hw/vfio/vfio-cpr.h"
#include "system/host_iommu_device.h"
#include "system/iommufd.h"
@@ -35,23 +36,25 @@
enum {
VFIO_DEVICE_TYPE_PCI = 0,
- VFIO_DEVICE_TYPE_PLATFORM = 1,
+ VFIO_DEVICE_TYPE_UNUSED = 1,
VFIO_DEVICE_TYPE_CCW = 2,
VFIO_DEVICE_TYPE_AP = 3,
};
typedef struct VFIODeviceOps VFIODeviceOps;
+typedef struct VFIODeviceIOOps VFIODeviceIOOps;
typedef struct VFIOMigration VFIOMigration;
typedef struct IOMMUFDBackend IOMMUFDBackend;
typedef struct VFIOIOASHwpt VFIOIOASHwpt;
+typedef struct VFIOUserProxy VFIOUserProxy;
typedef struct VFIODevice {
QLIST_ENTRY(VFIODevice) next;
QLIST_ENTRY(VFIODevice) container_next;
QLIST_ENTRY(VFIODevice) global_next;
struct VFIOGroup *group;
- VFIOContainerBase *bcontainer;
+ VFIOContainer *bcontainer;
char *sysfsdev;
char *name;
DeviceState *dev;
@@ -64,8 +67,12 @@ typedef struct VFIODevice {
bool ram_block_discard_allowed;
OnOffAuto enable_migration;
OnOffAuto migration_multifd_transfer;
+ OnOffAuto migration_load_config_after_iter;
+ uint64_t migration_max_queued_buffers_size;
bool migration_events;
+ bool use_region_fds;
VFIODeviceOps *ops;
+ VFIODeviceIOOps *io_ops;
unsigned int num_irqs;
unsigned int num_regions;
unsigned int flags;
@@ -81,6 +88,10 @@ typedef struct VFIODevice {
IOMMUFDBackend *iommufd;
VFIOIOASHwpt *hwpt;
QLIST_ENTRY(VFIODevice) hwpt_next;
+ struct vfio_region_info **reginfo;
+ int *region_fds;
+ VFIODeviceCPR cpr;
+ VFIOUserProxy *proxy;
} VFIODevice;
struct VFIODeviceOps {
@@ -115,6 +126,20 @@ struct VFIODeviceOps {
int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f);
};
+/*
+ * Given a return value of either a short number of bytes read or -errno,
+ * construct a meaningful error message.
+ */
+#define strreaderror(ret) \
+ (ret < 0 ? strerror(-ret) : "short read")
+
+/*
+ * Given a return value of either a short number of bytes written or -errno,
+ * construct a meaningful error message.
+ */
+#define strwriteerror(ret) \
+ (ret < 0 ? strerror(-ret) : "short write")
+
void vfio_device_irq_disable(VFIODevice *vbasedev, int index);
void vfio_device_irq_unmask(VFIODevice *vbasedev, int index);
void vfio_device_irq_mask(VFIODevice *vbasedev, int index);
@@ -127,6 +152,9 @@ bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev,
const char *typename, Error **errp);
bool vfio_device_attach(char *name, VFIODevice *vbasedev,
AddressSpace *as, Error **errp);
+bool vfio_device_attach_by_iommu_type(const char *iommu_type, char *name,
+ VFIODevice *vbasedev, AddressSpace *as,
+ Error **errp);
void vfio_device_detach(VFIODevice *vbasedev);
VFIODevice *vfio_get_vfio_device(Object *obj);
@@ -134,17 +162,130 @@ typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList;
extern VFIODeviceList vfio_device_list;
#ifdef CONFIG_LINUX
+/*
+ * How devices communicate with the server. The default option is through
+ * ioctl() to the kernel VFIO driver, but vfio-user can use a socket to a remote
+ * process.
+ */
+struct VFIODeviceIOOps {
+ /**
+ * @device_feature
+ *
+ * Fill in feature info for the given device.
+ *
+ * @vdev: #VFIODevice to use
+ * @feat: feature information to fill in
+ *
+ * Returns 0 on success or -errno.
+ */
+ int (*device_feature)(VFIODevice *vdev, struct vfio_device_feature *feat);
+
+ /**
+ * @get_region_info
+ *
+ * Get the information for a given region on the device.
+ *
+ * @vdev: #VFIODevice to use
+ * @info: set @info->index to the region index to look up; the rest of the
+ * struct will be filled in on success
+ * @fd: pointer to the fd for the region; will be -1 if not found
+ *
+ * Returns 0 on success or -errno.
+ */
+ int (*get_region_info)(VFIODevice *vdev,
+ struct vfio_region_info *info, int *fd);
+
+ /**
+ * @get_irq_info
+ *
+ * @vdev: #VFIODevice to use
+ * @irq: set @irq->index to the IRQ index to look up; the rest of the struct
+ * will be filled in on success
+ *
+ * Returns 0 on success or -errno.
+ */
+ int (*get_irq_info)(VFIODevice *vdev, struct vfio_irq_info *irq);
+
+ /**
+ * @set_irqs
+ *
+ * Configure IRQs.
+ *
+ * @vdev: #VFIODevice to use
+ * @irqs: IRQ configuration as defined by VFIO docs.
+ *
+ * Returns 0 on success or -errno.
+ */
+ int (*set_irqs)(VFIODevice *vdev, struct vfio_irq_set *irqs);
+
+ /**
+ * @region_read
+ *
+ * Read part of a region.
+ *
+ * @vdev: #VFIODevice to use
+ * @nr: region index
+ * @off: offset within the region
+ * @size: size in bytes to read
+ * @data: buffer to read into
+ *
+ * Returns number of bytes read on success or -errno.
+ */
+ int (*region_read)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size,
+ void *data);
+
+ /**
+ * @region_write
+ *
+ * Write part of a region.
+ *
+ * @vdev: #VFIODevice to use
+ * @nr: region index
+ * @off: offset within the region
+ * @size: size in bytes to write
+ * @data: buffer to write from
+ * @post: true if this is a posted write
+ *
+ * Returns number of bytes write on success or -errno.
+ */
+ int (*region_write)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size,
+ void *data, bool post);
+};
+
+void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainer *bcontainer,
+ struct vfio_device_info *info);
+
+void vfio_device_unprepare(VFIODevice *vbasedev);
+
int vfio_device_get_region_info(VFIODevice *vbasedev, int index,
struct vfio_region_info **info);
int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type,
uint32_t subtype, struct vfio_region_info **info);
+
+/**
+ * Return the fd for mapping this region. This is either the device's fd (for
+ * e.g. kernel vfio), or a per-region fd (for vfio-user).
+ *
+ * @vbasedev: #VFIODevice to use
+ * @index: region index
+ *
+ * Returns the fd.
+ */
+int vfio_device_get_region_fd(VFIODevice *vbasedev, int index);
+
bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type);
+
+int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
+ struct vfio_irq_info *info);
#endif
/* Returns 0 on success, or a negative errno. */
bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp);
+void vfio_device_free_name(VFIODevice *vbasedev);
void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp);
void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops,
DeviceState *dev, bool ram_discard);
int vfio_device_get_aw_bits(VFIODevice *vdev);
-#endif /* HW_VFIO_VFIO_COMMON_H */
+
+void vfio_kvm_device_close(void);
+#endif /* HW_VFIO_VFIO_DEVICE_H */
diff --git a/include/hw/vfio/vfio-platform.h b/include/hw/vfio/vfio-platform.h
deleted file mode 100644
index 256d850..0000000
--- a/include/hw/vfio/vfio-platform.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * vfio based device assignment support - platform devices
- *
- * Copyright Linaro Limited, 2014
- *
- * Authors:
- * Kim Phillips <kim.phillips@linaro.org>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- * Based on vfio based PCI device assignment support:
- * Copyright Red Hat, Inc. 2012
- */
-
-#ifndef HW_VFIO_VFIO_PLATFORM_H
-#define HW_VFIO_VFIO_PLATFORM_H
-
-#include "hw/sysbus.h"
-#include "hw/vfio/vfio-device.h"
-#include "qemu/event_notifier.h"
-#include "qemu/queue.h"
-#include "qom/object.h"
-
-#define TYPE_VFIO_PLATFORM "vfio-platform"
-
-enum {
- VFIO_IRQ_INACTIVE = 0,
- VFIO_IRQ_PENDING = 1,
- VFIO_IRQ_ACTIVE = 2,
- /* VFIO_IRQ_ACTIVE_AND_PENDING cannot happen with VFIO */
-};
-
-typedef struct VFIOINTp {
- QLIST_ENTRY(VFIOINTp) next; /* entry for IRQ list */
- QSIMPLEQ_ENTRY(VFIOINTp) pqnext; /* entry for pending IRQ queue */
- EventNotifier *interrupt; /* eventfd triggered on interrupt */
- EventNotifier *unmask; /* eventfd for unmask on QEMU bypass */
- qemu_irq qemuirq;
- struct VFIOPlatformDevice *vdev; /* back pointer to device */
- int state; /* inactive, pending, active */
- uint8_t pin; /* index */
- uint32_t flags; /* IRQ info flags */
- bool kvm_accel; /* set when QEMU bypass through KVM enabled */
-} VFIOINTp;
-
-/* function type for user side eventfd handler */
-typedef void (*eventfd_user_side_handler_t)(VFIOINTp *intp);
-
-typedef struct VFIORegion VFIORegion;
-
-struct VFIOPlatformDevice {
- SysBusDevice sbdev;
- VFIODevice vbasedev; /* not a QOM object */
- VFIORegion **regions;
- QLIST_HEAD(, VFIOINTp) intp_list; /* list of IRQs */
- /* queue of pending IRQs */
- QSIMPLEQ_HEAD(, VFIOINTp) pending_intp_queue;
- char *compat; /* DT compatible values, separated by NUL */
- unsigned int num_compat; /* number of compatible values */
- uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
- QEMUTimer *mmap_timer; /* allows fast-path resume after IRQ hit */
- QemuMutex intp_mutex; /* protect the intp_list IRQ state */
- bool irqfd_allowed; /* debug option to force irqfd on/off */
-};
-typedef struct VFIOPlatformDevice VFIOPlatformDevice;
-
-struct VFIOPlatformDeviceClass {
- /*< private >*/
- SysBusDeviceClass parent_class;
- /*< public >*/
-};
-typedef struct VFIOPlatformDeviceClass VFIOPlatformDeviceClass;
-
-DECLARE_OBJ_CHECKERS(VFIOPlatformDevice, VFIOPlatformDeviceClass,
- VFIO_PLATFORM_DEVICE, TYPE_VFIO_PLATFORM)
-
-#endif /* HW_VFIO_VFIO_PLATFORM_H */
diff --git a/include/hw/vfio/vfio-region.h b/include/hw/vfio/vfio-region.h
deleted file mode 100644
index cbffb26..0000000
--- a/include/hw/vfio/vfio-region.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * VFIO region
- *
- * Copyright Red Hat, Inc. 2025
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef HW_VFIO_REGION_H
-#define HW_VFIO_REGION_H
-
-#include "system/memory.h"
-
-typedef struct VFIOMmap {
- MemoryRegion mem;
- void *mmap;
- off_t offset;
- size_t size;
-} VFIOMmap;
-
-typedef struct VFIODevice VFIODevice;
-
-typedef struct VFIORegion {
- struct VFIODevice *vbasedev;
- off_t fd_offset; /* offset of region within device fd */
- MemoryRegion *mem; /* slow, read/write access */
- size_t size;
- uint32_t flags; /* VFIO region flags (rd/wr/mmap) */
- uint32_t nr_mmaps;
- VFIOMmap *mmaps;
- uint8_t nr; /* cache the region number for debug */
-} VFIORegion;
-
-
-void vfio_region_write(void *opaque, hwaddr addr,
- uint64_t data, unsigned size);
-uint64_t vfio_region_read(void *opaque,
- hwaddr addr, unsigned size);
-int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
- int index, const char *name);
-int vfio_region_mmap(VFIORegion *region);
-void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled);
-void vfio_region_unmap(VFIORegion *region);
-void vfio_region_exit(VFIORegion *region);
-void vfio_region_finalize(VFIORegion *region);
-
-#endif /* HW_VFIO_REGION_H */
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index d6df209..ff94fa1 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -95,6 +95,10 @@ typedef int (*vhost_new_worker_op)(struct vhost_dev *dev,
struct vhost_worker_state *worker);
typedef int (*vhost_free_worker_op)(struct vhost_dev *dev,
struct vhost_worker_state *worker);
+typedef int (*vhost_set_features_ex_op)(struct vhost_dev *dev,
+ const uint64_t *features);
+typedef int (*vhost_get_features_ex_op)(struct vhost_dev *dev,
+ uint64_t *features);
typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
uint64_t features);
typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
@@ -186,6 +190,8 @@ typedef struct VhostOps {
vhost_free_worker_op vhost_free_worker;
vhost_get_vring_worker_op vhost_get_vring_worker;
vhost_attach_vring_worker_op vhost_attach_vring_worker;
+ vhost_set_features_ex_op vhost_set_features_ex;
+ vhost_get_features_ex_op vhost_get_features_ex;
vhost_set_features_op vhost_set_features;
vhost_get_features_op vhost_get_features;
vhost_set_backend_cap_op vhost_set_backend_cap;
diff --git a/include/hw/virtio/vhost-scsi-common.h b/include/hw/virtio/vhost-scsi-common.h
index c5d2c09..d54d9c9 100644
--- a/include/hw/virtio/vhost-scsi-common.h
+++ b/include/hw/virtio/vhost-scsi-common.h
@@ -40,7 +40,7 @@ struct VHostSCSICommon {
};
int vhost_scsi_common_start(VHostSCSICommon *vsc, Error **errp);
-void vhost_scsi_common_stop(VHostSCSICommon *vsc);
+int vhost_scsi_common_stop(VHostSCSICommon *vsc);
char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus,
DeviceState *dev);
void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config);
diff --git a/include/hw/virtio/vhost-user-base.h b/include/hw/virtio/vhost-user-base.h
index 51d0968..387e434 100644
--- a/include/hw/virtio/vhost-user-base.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -44,6 +44,6 @@ struct VHostUserBaseClass {
};
-#define TYPE_VHOST_USER_DEVICE "vhost-user-device"
+#define TYPE_VHOST_USER_TEST_DEVICE "vhost-user-test-device"
#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h
index ea085ee..a10f785 100644
--- a/include/hw/virtio/vhost-user-blk.h
+++ b/include/hw/virtio/vhost-user-blk.h
@@ -50,6 +50,8 @@ struct VHostUserBlk {
bool connected;
/* vhost_user_blk_start/vhost_user_blk_stop */
bool started_vu;
+
+ bool skip_get_vring_base_on_force_shutdown;
};
#endif
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 0a9575b..449bf5c 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -43,7 +43,21 @@ typedef struct vhost_vdpa_shared {
struct vhost_vdpa_iova_range iova_range;
QLIST_HEAD(, vdpa_iommu) iommu_list;
- /* IOVA mapping used by the Shadow Virtqueue */
+ /*
+ * IOVA mapping used by the Shadow Virtqueue
+ *
+ * It is shared among all ASID for simplicity, whether CVQ shares ASID with
+ * guest or not:
+ * - Memory listener need access to guest's memory addresses allocated in
+ * the IOVA tree.
+ * - There should be plenty of IOVA address space for both ASID not to
+ * worry about collisions between them. Guest's translations are still
+ * validated with virtio virtqueue_pop so there is no risk for the guest
+ * to access memory that it shouldn't.
+ *
+ * To allocate a iova tree per ASID is doable but it complicates the code
+ * and it is not worth it for the moment.
+ */
VhostIOVATree *iova_tree;
/* Copy of backend features */
@@ -51,6 +65,12 @@ typedef struct vhost_vdpa_shared {
bool iotlb_batch_begin_sent;
+ /*
+ * The memory listener has been registered, so DMA maps have been sent to
+ * the device.
+ */
+ bool listener_registered;
+
/* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */
bool shadow_data;
diff --git a/include/hw/virtio/vhost-vsock-common.h b/include/hw/virtio/vhost-vsock-common.h
index 75a74e8..01bf606 100644
--- a/include/hw/virtio/vhost-vsock-common.h
+++ b/include/hw/virtio/vhost-vsock-common.h
@@ -42,7 +42,7 @@ struct VHostVSockCommon {
};
int vhost_vsock_common_start(VirtIODevice *vdev);
-void vhost_vsock_common_stop(VirtIODevice *vdev);
+int vhost_vsock_common_stop(VirtIODevice *vdev);
int vhost_vsock_common_pre_save(void *opaque);
int vhost_vsock_common_post_load(void *opaque, int version_id);
void vhost_vsock_common_realize(VirtIODevice *vdev);
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index bb4b58e..08bbb4d 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -1,6 +1,7 @@
#ifndef VHOST_H
#define VHOST_H
+#include "net/vhost_net.h"
#include "hw/virtio/vhost-backend.h"
#include "hw/virtio/virtio.h"
#include "system/memory.h"
@@ -106,9 +107,9 @@ struct vhost_dev {
* future use should be discouraged and the variable retired as
* its easy to confuse with the VirtIO backend_features.
*/
- uint64_t features;
- uint64_t acked_features;
- uint64_t backend_features;
+ VIRTIO_DECLARE_FEATURES(features);
+ VIRTIO_DECLARE_FEATURES(acked_features);
+ VIRTIO_DECLARE_FEATURES(backend_features);
/**
* @protocol_features: is the vhost-user only feature set by
@@ -143,6 +144,10 @@ struct vhost_net {
struct vhost_dev dev;
struct vhost_virtqueue vqs[2];
int backend;
+ const int *feature_bits;
+ int max_tx_queue_size;
+ SaveAcketFeatures *save_acked_features;
+ bool is_vhost_user;
NetClientState *nc;
};
@@ -232,8 +237,25 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
* Stop the vhost device. After the device is stopped the notifiers
* can be disabled (@vhost_dev_disable_notifiers) and the device can
* be torn down (@vhost_dev_cleanup).
+ *
+ * Return: 0 on success, != 0 on error when stopping dev.
+ */
+int vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
+
+/**
+ * vhost_dev_force_stop() - force stop the vhost device
+ * @hdev: common vhost_dev structure
+ * @vdev: the VirtIODevice structure
+ * @vrings: true to have vrings disabled in this call
+ *
+ * Force stop the vhost device. After the device is stopped the notifiers
+ * can be disabled (@vhost_dev_disable_notifiers) and the device can
+ * be torn down (@vhost_dev_cleanup). Unlike @vhost_dev_stop, this doesn't
+ * attempt to flush in-flight backend requests by skipping GET_VRING_BASE
+ * entirely.
*/
-void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
+int vhost_dev_force_stop(struct vhost_dev *hdev, VirtIODevice *vdev,
+ bool vrings);
/**
* DOC: vhost device configuration handling
@@ -299,6 +321,20 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
bool mask);
/**
+ * vhost_get_features_ex() - sanitize the extended features set
+ * @hdev: common vhost_dev structure
+ * @feature_bits: pointer to terminated table of feature bits
+ * @features: original features set, filtered out on return
+ *
+ * This is the extended variant of vhost_get_features(), supporting the
+ * the extended features set. Filter it with the intersection of what is
+ * supported by the vhost backend (hdev->features) and the supported
+ * feature_bits.
+ */
+void vhost_get_features_ex(struct vhost_dev *hdev,
+ const int *feature_bits,
+ uint64_t *features);
+/**
* vhost_get_features() - return a sanitised set of feature bits
* @hdev: common vhost_dev structure
* @feature_bits: pointer to terminated table of feature bits
@@ -308,8 +344,28 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
* is supported by the vhost backend (hdev->features), the supported
* feature_bits and the requested feature set.
*/
-uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
- uint64_t features);
+static inline uint64_t vhost_get_features(struct vhost_dev *hdev,
+ const int *feature_bits,
+ uint64_t features)
+{
+ uint64_t features_ex[VIRTIO_FEATURES_NU64S];
+
+ virtio_features_from_u64(features_ex, features);
+ vhost_get_features_ex(hdev, feature_bits, features_ex);
+ return features_ex[0];
+}
+
+/**
+ * vhost_ack_features_ex() - set vhost full set of acked_features
+ * @hdev: common vhost_dev structure
+ * @feature_bits: pointer to terminated table of feature bits
+ * @features: requested feature set
+ *
+ * This sets the internal hdev->acked_features to the intersection of
+ * the backends advertised features and the supported feature_bits.
+ */
+void vhost_ack_features_ex(struct vhost_dev *hdev, const int *feature_bits,
+ const uint64_t *features);
/**
* vhost_ack_features() - set vhost acked_features
@@ -320,8 +376,16 @@ uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
* This sets the internal hdev->acked_features to the intersection of
* the backends advertised features and the supported feature_bits.
*/
-void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
- uint64_t features);
+static inline void vhost_ack_features(struct vhost_dev *hdev,
+ const int *feature_bits,
+ uint64_t features)
+{
+ uint64_t features_ex[VIRTIO_FEATURES_NU64S];
+
+ virtio_features_from_u64(features_ex, features);
+ vhost_ack_features_ex(hdev, feature_bits, features_ex);
+}
+
unsigned int vhost_get_max_memslots(void);
unsigned int vhost_get_free_memslots(void);
@@ -333,8 +397,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev,
struct vhost_virtqueue *vq, unsigned idx);
-void vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev,
- struct vhost_virtqueue *vq, unsigned idx);
+int vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev,
+ struct vhost_virtqueue *vq, unsigned idx);
void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
void vhost_dev_free_inflight(struct vhost_inflight *inflight);
diff --git a/include/hw/virtio/virtio-features.h b/include/hw/virtio/virtio-features.h
new file mode 100644
index 0000000..e29b7fe
--- /dev/null
+++ b/include/hw/virtio/virtio-features.h
@@ -0,0 +1,126 @@
+/*
+ * Virtio features helpers
+ *
+ * Copyright 2025 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VIRTIO_FEATURES_H
+#define QEMU_VIRTIO_FEATURES_H
+
+#include "qemu/bitops.h"
+
+#define VIRTIO_FEATURES_FMT "%016"PRIx64"%016"PRIx64
+#define VIRTIO_FEATURES_PR(f) (f)[1], (f)[0]
+
+#define VIRTIO_FEATURES_MAX 128
+#define VIRTIO_FEATURES_BIT(b) BIT_ULL((b) % 64)
+#define VIRTIO_FEATURES_U64(b) ((b) / 64)
+#define VIRTIO_FEATURES_NU32S (VIRTIO_FEATURES_MAX / 32)
+#define VIRTIO_FEATURES_NU64S (VIRTIO_FEATURES_MAX / 64)
+
+#define VIRTIO_DECLARE_FEATURES(name) \
+ union { \
+ uint64_t name; \
+ uint64_t name##_ex[VIRTIO_FEATURES_NU64S]; \
+ }
+
+#define VIRTIO_DEFINE_PROP_FEATURE(_name, _state, _field, _bit, _defval) \
+ DEFINE_PROP_BIT64(_name, _state, _field[VIRTIO_FEATURES_U64(_bit)], \
+ (_bit) % 64, _defval)
+
+static inline void virtio_features_clear(uint64_t *features)
+{
+ memset(features, 0, sizeof(features[0]) * VIRTIO_FEATURES_NU64S);
+}
+
+static inline void virtio_features_from_u64(uint64_t *features, uint64_t from)
+{
+ virtio_features_clear(features);
+ features[0] = from;
+}
+
+static inline bool virtio_has_feature_ex(const uint64_t *features,
+ unsigned int fbit)
+{
+ assert(fbit < VIRTIO_FEATURES_MAX);
+ return features[VIRTIO_FEATURES_U64(fbit)] & VIRTIO_FEATURES_BIT(fbit);
+}
+
+static inline void virtio_add_feature_ex(uint64_t *features,
+ unsigned int fbit)
+{
+ assert(fbit < VIRTIO_FEATURES_MAX);
+ features[VIRTIO_FEATURES_U64(fbit)] |= VIRTIO_FEATURES_BIT(fbit);
+}
+
+static inline void virtio_clear_feature_ex(uint64_t *features,
+ unsigned int fbit)
+{
+ assert(fbit < VIRTIO_FEATURES_MAX);
+ features[VIRTIO_FEATURES_U64(fbit)] &= ~VIRTIO_FEATURES_BIT(fbit);
+}
+
+static inline bool virtio_features_equal(const uint64_t *f1,
+ const uint64_t *f2)
+{
+ return !memcmp(f1, f2, sizeof(uint64_t) * VIRTIO_FEATURES_NU64S);
+}
+
+static inline bool virtio_features_use_ex(const uint64_t *features)
+{
+ int i;
+
+ for (i = 1; i < VIRTIO_FEATURES_NU64S; ++i) {
+ if (features[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static inline bool virtio_features_empty(const uint64_t *features)
+{
+ return !virtio_features_use_ex(features) && !features[0];
+}
+
+static inline void virtio_features_copy(uint64_t *to, const uint64_t *from)
+{
+ memcpy(to, from, sizeof(to[0]) * VIRTIO_FEATURES_NU64S);
+}
+
+static inline bool virtio_features_andnot(uint64_t *to, const uint64_t *f1,
+ const uint64_t *f2)
+{
+ uint64_t diff = 0;
+ int i;
+
+ for (i = 0; i < VIRTIO_FEATURES_NU64S; i++) {
+ to[i] = f1[i] & ~f2[i];
+ diff |= to[i];
+ }
+ return diff;
+}
+
+static inline void virtio_features_and(uint64_t *to, const uint64_t *f1,
+ const uint64_t *f2)
+{
+ int i;
+
+ for (i = 0; i < VIRTIO_FEATURES_NU64S; i++) {
+ to[i] = f1[i] & f2[i];
+ }
+}
+
+static inline void virtio_features_or(uint64_t *to, const uint64_t *f1,
+ const uint64_t *f2)
+{
+ int i;
+
+ for (i = 0; i < VIRTIO_FEATURES_NU64S; i++) {
+ to[i] = f1[i] | f2[i];
+ }
+}
+
+#endif
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index a42957c..9f16f89 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -20,6 +20,7 @@
#include "hw/virtio/virtio.h"
#include "qemu/log.h"
#include "system/vhost-user-backend.h"
+#include "qapi/qapi-types-virtio.h"
#include "standard-headers/linux/virtio_gpu.h"
#include "standard-headers/linux/virtio_ids.h"
@@ -128,6 +129,7 @@ struct virtio_gpu_base_conf {
uint32_t xres;
uint32_t yres;
uint64_t hostmem;
+ VirtIOGPUOutputList *outputs;
};
struct virtio_gpu_ctrl_command {
@@ -167,6 +169,7 @@ struct VirtIOGPUBaseClass {
#define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf) \
DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1), \
+ DEFINE_PROP_VIRTIO_GPU_OUTPUT_LIST("outputs", _state, _conf.outputs), \
DEFINE_PROP_BIT("edid", _state, _conf.flags, \
VIRTIO_GPU_FLAG_EDID_ENABLED, true), \
DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1280), \
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
index bc4f787..e0ab31b 100644
--- a/include/hw/virtio/virtio-mem.h
+++ b/include/hw/virtio/virtio-mem.h
@@ -134,7 +134,7 @@ struct VirtioMemSystemReset {
struct VirtIOMEMClass {
/* private */
- VirtIODevice parent;
+ VirtioDeviceClass parent_class;
/* public */
void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index b9ea9e8..5b8ab7b 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -144,7 +144,11 @@ typedef struct VirtioNetRssData {
bool enabled_software_rss;
bool redirect;
bool populate_hash;
- uint32_t hash_types;
+ bool peer_hash_available;
+ uint32_t runtime_hash_types;
+ uint32_t supported_hash_types;
+ uint32_t peer_hash_types;
+ OnOffAutoBit64 specified_hash_types;
uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE];
uint16_t indirections_len;
uint16_t *indirections_table;
@@ -178,7 +182,7 @@ struct VirtIONet {
uint32_t has_vnet_hdr;
size_t host_hdr_len;
size_t guest_hdr_len;
- uint64_t host_features;
+ VIRTIO_DECLARE_FEATURES(host_features);
uint32_t rsc_timeout;
uint8_t rsc4_enabled;
uint8_t rsc6_enabled;
diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
index 31ec144..6397529 100644
--- a/include/hw/virtio/virtio-pci.h
+++ b/include/hw/virtio/virtio-pci.h
@@ -32,9 +32,7 @@ DECLARE_OBJ_CHECKERS(VirtioPCIBusState, VirtioPCIBusClass,
enum {
VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT,
- VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
- VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT,
VIRTIO_PCI_FLAG_ATS_BIT,
VIRTIO_PCI_FLAG_INIT_DEVERR_BIT,
@@ -54,12 +52,6 @@ enum {
* vcpu thread using ioeventfd for some devices. */
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
-/* virtio version flags */
-#define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT)
-
-/* migrate extra state */
-#define VIRTIO_PCI_FLAG_MIGRATE_EXTRA (1 << VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT)
-
/* have pio notification for modern device ? */
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
(1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)
@@ -155,6 +147,7 @@ struct VirtIOPCIProxy {
uint32_t modern_io_bar_idx;
uint32_t modern_mem_bar_idx;
int config_cap;
+ uint16_t last_pcie_cap_offset;
uint32_t flags;
bool disable_modern;
bool ignore_backend_features;
@@ -165,7 +158,7 @@ struct VirtIOPCIProxy {
uint32_t nvectors;
uint32_t dfselect;
uint32_t gfselect;
- uint32_t guest_features[2];
+ uint32_t guest_features[VIRTIO_FEATURES_NU32S];
VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];
VirtIOIRQFD *vector_irqfd;
diff --git a/include/hw/virtio/virtio-pmem.h b/include/hw/virtio/virtio-pmem.h
index fc4fd1f..9cce600 100644
--- a/include/hw/virtio/virtio-pmem.h
+++ b/include/hw/virtio/virtio-pmem.h
@@ -36,7 +36,7 @@ struct VirtIOPMEM {
struct VirtIOPMEMClass {
/* private */
- VirtIODevice parent;
+ VirtioDeviceClass parent_class;
/* public */
void (*fill_device_info)(const VirtIOPMEM *pmem, VirtioPMEMDeviceInfo *vi);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 7e0c471..d97529c 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -16,6 +16,7 @@
#include "system/memory.h"
#include "hw/qdev-core.h"
+#include "hw/virtio/virtio-features.h"
#include "net/net.h"
#include "migration/vmstate.h"
#include "qemu/event_notifier.h"
@@ -121,9 +122,9 @@ struct VirtIODevice
* backend (e.g. vhost) and could potentially be a subset of the
* total feature set offered by QEMU.
*/
- uint64_t host_features;
- uint64_t guest_features;
- uint64_t backend_features;
+ VIRTIO_DECLARE_FEATURES(host_features);
+ VIRTIO_DECLARE_FEATURES(guest_features);
+ VIRTIO_DECLARE_FEATURES(backend_features);
size_t config_len;
void *config;
@@ -177,6 +178,9 @@ struct VirtioDeviceClass {
/* This is what a VirtioDevice must implement */
DeviceRealize realize;
DeviceUnrealize unrealize;
+ void (*get_features_ex)(VirtIODevice *vdev, uint64_t *requested_features,
+ Error **errp);
+ void (*set_features_ex)(VirtIODevice *vdev, const uint64_t *val);
uint64_t (*get_features)(VirtIODevice *vdev,
uint64_t requested_features,
Error **errp);
@@ -186,7 +190,7 @@ struct VirtioDeviceClass {
void (*get_config)(VirtIODevice *vdev, uint8_t *config);
void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
void (*reset)(VirtIODevice *vdev);
- void (*set_status)(VirtIODevice *vdev, uint8_t val);
+ int (*set_status)(VirtIODevice *vdev, uint8_t val);
/* Device must validate queue_index. */
void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index);
/* Device must validate queue_index. */
@@ -210,8 +214,14 @@ struct VirtioDeviceClass {
void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
int (*start_ioeventfd)(VirtIODevice *vdev);
void (*stop_ioeventfd)(VirtIODevice *vdev);
- /* Called before loading queues. Useful to add queues before loading. */
- int (*pre_load_queues)(VirtIODevice *vdev);
+ /*
+ * Called before loading queues.
+ * If the number of queues change at runtime, use @n to know the
+ * number and add or remove queues accordingly.
+ * Note that this function is called in the middle of loading vmsd;
+ * no assumption should be made on states being loaded from vmsd.
+ */
+ int (*pre_load_queues)(VirtIODevice *vdev, uint32_t n);
/* Saving and loading of a device; trying to deprecate save/load
* use vmsd for new devices.
*/
@@ -284,7 +294,6 @@ int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
unsigned int *out_bytes, unsigned max_in_bytes,
unsigned max_out_bytes);
-void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq);
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
int virtio_save(VirtIODevice *vdev, QEMUFile *f);
@@ -366,6 +375,7 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
void virtio_update_irq(VirtIODevice *vdev);
int virtio_set_features(VirtIODevice *vdev, uint64_t val);
+int virtio_set_features_ex(VirtIODevice *vdev, const uint64_t *val);
/* Base devices. */
typedef struct VirtIOBlkConf VirtIOBlkConf;
diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h
index df39c81..8bacaa4 100644
--- a/include/hw/xen/arch_hvm.h
+++ b/include/hw/xen/arch_hvm.h
@@ -1,5 +1,11 @@
-#if defined(TARGET_I386) || defined(TARGET_X86_64)
-#include "hw/i386/xen_arch_hvm.h"
-#elif defined(TARGET_ARM) || defined(TARGET_AARCH64)
-#include "hw/arm/xen_arch_hvm.h"
+#ifndef HW_XEN_ARCH_HVM_H
+#define HW_XEN_ARCH_HVM_H
+
+#include <xen/hvm/ioreq.h>
+#include "hw/xen/xen-hvm-common.h"
+
+void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
+void arch_xen_set_memory(XenIOState *state,
+ MemoryRegionSection *section,
+ bool add);
#endif
diff --git a/include/hw/xen/interface/io/blkif.h b/include/hw/xen/interface/io/blkif.h
index 22f1eef..c552799 100644
--- a/include/hw/xen/interface/io/blkif.h
+++ b/include/hw/xen/interface/io/blkif.h
@@ -324,7 +324,7 @@
* access (even when it should be read-only). If the frontend hits the
* maximum number of allowed persistently mapped grants, it can fallback
* to non persistent mode. This will cause a performance degradation,
- * since the the backend driver will still try to map those grants
+ * since the backend driver will still try to map those grants
* persistently. Since the persistent grants protocol is compatible with
* the previous protocol, a frontend driver can choose to work in
* persistent mode even when the backend doesn't support it.