hw/pci-host/aspeed: Add AST2600 PCIe Root Port and make address configurable
Introduce an ASPEED PCIe Root Port and wire it under the RC. The root port is modeled as TYPE_ASPEED_PCIE_ROOT_PORT (subclass of TYPE_PCIE_ROOT_PORT). Key changes: - Add TYPE_ASPEED_PCIE_ROOT_PORT (PCIESlot-based) with vendor/device IDs and AER capability offset. - Extend AspeedPCIERcState to embed a root_port instance and a configurable rp_addr. - Add "rp-addr" property to the RC to place the root port at a specific devfn on the root bus. - Set the root port's "chassis" property to ensure a unique chassis per RC. - Extend AspeedPCIECfgClass with rc_rp_addr defaulting to PCI_DEVFN(8,0). Rationale: - AST2600 places the root port at 80:08.0 (bus 0x80, dev 8, fn 0). - AST2700 must place the root port at 00:00.0, and it supports three RCs. Each root port must therefore be uniquely identifiable; uses the PCIe "chassis" ID for that. - Providing a configurable "rp-addr" lets platforms select the correct devfn per SoC family, while the "chassis" property ensures uniqueness across multiple RC instances on AST2700. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250919093017.338309-6-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
cac2f08293
commit
2af56518fa
2 changed files with 61 additions and 0 deletions
|
|
@ -21,6 +21,7 @@
|
|||
#include "hw/registerfields.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/pci/pci_host.h"
|
||||
#include "hw/pci/pcie_port.h"
|
||||
#include "hw/pci-host/aspeed_pcie.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "trace.h"
|
||||
|
|
@ -63,6 +64,32 @@ static const TypeInfo aspeed_pcie_root_device_info = {
|
|||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* PCIe Root Port
|
||||
*/
|
||||
|
||||
static void aspeed_pcie_root_port_class_init(ObjectClass *klass,
|
||||
const void *data)
|
||||
{
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED PCIe Root Port";
|
||||
k->vendor_id = PCI_VENDOR_ID_ASPEED;
|
||||
k->device_id = 0x1150;
|
||||
dc->user_creatable = true;
|
||||
|
||||
rpc->aer_offset = 0x100;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_pcie_root_port_info = {
|
||||
.name = TYPE_ASPEED_PCIE_ROOT_PORT,
|
||||
.parent = TYPE_PCIE_ROOT_PORT,
|
||||
.instance_size = sizeof(AspeedPCIERootPortState),
|
||||
.class_init = aspeed_pcie_root_port_class_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* PCIe Root Complex (RC)
|
||||
*/
|
||||
|
|
@ -144,6 +171,13 @@ static void aspeed_pcie_rc_realize(DeviceState *dev, Error **errp)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup root port */
|
||||
qdev_prop_set_int32(DEVICE(&rc->root_port), "addr", rc->rp_addr);
|
||||
qdev_prop_set_uint16(DEVICE(&rc->root_port), "chassis", cfg->id);
|
||||
if (!qdev_realize(DEVICE(&rc->root_port), BUS(pci->bus), errp)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *aspeed_pcie_rc_root_bus_path(PCIHostState *host_bridge,
|
||||
|
|
@ -158,9 +192,19 @@ static const char *aspeed_pcie_rc_root_bus_path(PCIHostState *host_bridge,
|
|||
return rc->name;
|
||||
}
|
||||
|
||||
static void aspeed_pcie_rc_instance_init(Object *obj)
|
||||
{
|
||||
AspeedPCIERcState *rc = ASPEED_PCIE_RC(obj);
|
||||
AspeedPCIERootPortState *root_port = &rc->root_port;
|
||||
|
||||
object_initialize_child(obj, "root_port", root_port,
|
||||
TYPE_ASPEED_PCIE_ROOT_PORT);
|
||||
}
|
||||
|
||||
static const Property aspeed_pcie_rc_props[] = {
|
||||
DEFINE_PROP_UINT32("bus-nr", AspeedPCIERcState, bus_nr, 0),
|
||||
DEFINE_PROP_BOOL("has-rd", AspeedPCIERcState, has_rd, 0),
|
||||
DEFINE_PROP_UINT32("rp-addr", AspeedPCIERcState, rp_addr, 0),
|
||||
};
|
||||
|
||||
static void aspeed_pcie_rc_class_init(ObjectClass *klass, const void *data)
|
||||
|
|
@ -183,6 +227,7 @@ static const TypeInfo aspeed_pcie_rc_info = {
|
|||
.name = TYPE_ASPEED_PCIE_RC,
|
||||
.parent = TYPE_PCIE_HOST_BRIDGE,
|
||||
.instance_size = sizeof(AspeedPCIERcState),
|
||||
.instance_init = aspeed_pcie_rc_instance_init,
|
||||
.class_init = aspeed_pcie_rc_class_init,
|
||||
};
|
||||
|
||||
|
|
@ -455,6 +500,9 @@ static void aspeed_pcie_cfg_realize(DeviceState *dev, Error **errp)
|
|||
object_property_set_bool(OBJECT(&s->rc), "has-rd",
|
||||
apc->rc_has_rd,
|
||||
&error_abort);
|
||||
object_property_set_int(OBJECT(&s->rc), "rp-addr",
|
||||
apc->rc_rp_addr,
|
||||
&error_abort);
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->rc), errp)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -488,6 +536,7 @@ static void aspeed_pcie_cfg_class_init(ObjectClass *klass, const void *data)
|
|||
apc->nr_regs = 0x100 >> 2;
|
||||
apc->rc_bus_nr = 0x80;
|
||||
apc->rc_has_rd = true;
|
||||
apc->rc_rp_addr = PCI_DEVFN(8, 0);
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_pcie_cfg_info = {
|
||||
|
|
@ -626,6 +675,7 @@ static void aspeed_pcie_register_types(void)
|
|||
{
|
||||
type_register_static(&aspeed_pcie_rc_info);
|
||||
type_register_static(&aspeed_pcie_root_device_info);
|
||||
type_register_static(&aspeed_pcie_root_port_info);
|
||||
type_register_static(&aspeed_pcie_cfg_info);
|
||||
type_register_static(&aspeed_pcie_phy_info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#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 {
|
||||
|
|
@ -40,6 +41,13 @@ 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);
|
||||
|
||||
|
|
@ -58,12 +66,14 @@ struct AspeedPCIERcState {
|
|||
MemoryRegion mmio;
|
||||
MemoryRegion io;
|
||||
|
||||
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. */
|
||||
|
|
@ -87,6 +97,7 @@ struct AspeedPCIECfgClass {
|
|||
const AspeedPCIERegMap *reg_map;
|
||||
const MemoryRegionOps *reg_ops;
|
||||
|
||||
uint32_t rc_rp_addr;
|
||||
uint64_t rc_bus_nr;
|
||||
uint64_t nr_regs;
|
||||
bool rc_has_rd;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue