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 = {