Commit e9a8b04dbb for qemu.org

commit e9a8b04dbb98fba7942b23b3ac5c35f2f0b9c4a0
Author: Jamin Lin <jamin_lin@aspeedtech.com>
Date:   Fri Nov 21 13:01:08 2025 +0800

    hw/pci-host/aspeed_pcie: Update ASPEED PCIe Root Port capabilities and enable MSI to support hotplug

    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>

diff --git a/hw/pci-host/aspeed_pcie.c b/hw/pci-host/aspeed_pcie.c
index f7593444fc..1fc2c61772 100644
--- a/hw/pci-host/aspeed_pcie.c
+++ b/hw/pci-host/aspeed_pcie.c
@@ -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 = {