]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
hw/pci-host/aspeed_pcie: Update ASPEED PCIe Root Port capabilities and enable MSI...
authorJamin Lin <jamin_lin@aspeedtech.com>
Fri, 21 Nov 2025 05:01:08 +0000 (13:01 +0800)
committerCédric Le Goater <clg@redhat.com>
Mon, 24 Nov 2025 06:52:42 +0000 (07:52 +0100)
This patch updates the ASPEED PCIe Root Port capability layout and interrupt
handling to match the hardware-defined capability structure as documented in
the PCI Express Controller (PCIE) chapter of the ASPEED SoC datasheet.

The following capability offsets and fields are now aligned with the actual
hardware implementation (validated using EVB config-space dumps via
'lspci -s <bdf> -vvv'):

- Added MSI capability at offset 0x50 and enabled 1-vector MSI support
- Added PCI Express Capability structure at offset 0x80
- Added Secondary Subsystem Vendor ID (SSVID) at offset 0xC0
- Added AER capability at offset 0x100
- Implemented aer_vector() callback and MSI init/uninit hooks
- Updated Root Port SSID to 0x1150 to reflect the platform default

Enabling MSI is required for proper PCIe Hotplug event signaling. This change
improves correctness and ensures QEMU Root Port behavior matches the behavior
of ASPEED hardware and downstream kernel expectations.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Fixes: 2af56518fa91 ("hw/pci-host/aspeed: Add AST2600 PCIe Root Port and make address configurable")
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Nabih Estefan <nabihestefan@google.com>
Tested-by: Nabih Estefan <nabihestefan@google.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20251121050108.3407445-2-jamin_lin@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
hw/pci-host/aspeed_pcie.c

index f7593444fc42f9eaf1d570899470ce3ec58b9d52..1fc2c617727d35c0ea939b677481a00c4a87bbe5 100644 (file)
@@ -68,6 +68,38 @@ static const TypeInfo aspeed_pcie_root_device_info = {
  * PCIe Root Port
  */
 
+#define ASPEED_PCIE_ROOT_PORT_MSI_OFFSET        0x50
+#define ASPEED_PCIE_ROOT_PORT_MSI_NR_VECTOR     1
+#define ASPEED_PCIE_ROOT_PORT_SSVID_OFFSET      0xC0
+#define ASPEED_PCIE_ROOT_PORT_EXP_OFFSET        0x80
+#define ASPEED_PCIE_ROOT_PORT_AER_OFFSET        0x100
+
+static uint8_t aspeed_pcie_root_port_aer_vector(const PCIDevice *d)
+{
+    return 0;
+}
+
+static int aspeed_pcie_root_port_interrupts_init(PCIDevice *d, Error **errp)
+{
+    int rc;
+
+    rc = msi_init(d, ASPEED_PCIE_ROOT_PORT_MSI_OFFSET,
+                  ASPEED_PCIE_ROOT_PORT_MSI_NR_VECTOR,
+                  PCI_MSI_FLAGS_MASKBIT & PCI_MSI_FLAGS_64BIT,
+                  PCI_MSI_FLAGS_MASKBIT & PCI_MSI_FLAGS_MASKBIT,
+                  errp);
+    if (rc < 0) {
+        assert(rc == -ENOTSUP);
+    }
+
+    return rc;
+}
+
+static void aspeed_pcie_root_port_interrupts_uninit(PCIDevice *d)
+{
+    msi_uninit(d);
+}
+
 static void aspeed_pcie_root_port_class_init(ObjectClass *klass,
                                              const void *data)
 {
@@ -80,7 +112,13 @@ static void aspeed_pcie_root_port_class_init(ObjectClass *klass,
     k->device_id = 0x1150;
     dc->user_creatable = true;
 
-    rpc->aer_offset = 0x100;
+    rpc->aer_vector = aspeed_pcie_root_port_aer_vector;
+    rpc->interrupts_init = aspeed_pcie_root_port_interrupts_init;
+    rpc->interrupts_uninit = aspeed_pcie_root_port_interrupts_uninit;
+    rpc->exp_offset = ASPEED_PCIE_ROOT_PORT_EXP_OFFSET;
+    rpc->aer_offset = ASPEED_PCIE_ROOT_PORT_AER_OFFSET;
+    rpc->ssvid_offset = ASPEED_PCIE_ROOT_PORT_SSVID_OFFSET;
+    rpc->ssid = 0x1150;
 }
 
 static const TypeInfo aspeed_pcie_root_port_info = {