[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC v3 4/6] pci_expander_bridge: Add config_read callback
From: |
Zihan Yang |
Subject: |
[Qemu-devel] [RFC v3 4/6] pci_expander_bridge: Add config_read callback |
Date: |
Thu, 2 Aug 2018 10:42:21 +0800 |
This allows SeaBIOS to retrieve MCFG base and size when it initializes
pxb host bridges.
A backlink to PXBPCIEHost is added in PXBDev to achieve above goal
Signed-off-by: Zihan Yang <address@hidden>
---
hw/pci-bridge/pci_expander_bridge.c | 55 +++++++++++++++++++++++++++++
include/hw/pci-bridge/pci_expander_bridge.h | 1 +
2 files changed, 56 insertions(+)
diff --git a/hw/pci-bridge/pci_expander_bridge.c
b/hw/pci-bridge/pci_expander_bridge.c
index f50938f..cdfdb90 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -49,11 +49,18 @@ typedef struct PXBBus {
#define PROP_PXB_PCIE_MAX_BUS "max_bus"
#define PROP_PXB_NUMA_NODE "numa_node"
+typedef struct PXBPCIEHost PXBPCIEHost;
+typedef struct PXBDev PXBDev;
+
typedef struct PXBDev {
/*< private >*/
PCIDevice parent_obj;
/*< public >*/
+ /* backlink to PXBPCIEHost, this makes it easier to get
+ * mcfg properties in pxb-pcie-host bridge */
+ PXBPCIEHost *pxbhost;
+
uint32_t domain_nr; /* PCI domain number, non-zero means separate domain */
uint8_t max_bus; /* max bus number to use(including this one) */
uint8_t bus_nr;
@@ -342,9 +349,15 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool
pcie, Error **errp)
if (pcie) {
g_assert (pxb->max_bus >= pxb->bus_nr);
ds = qdev_create(NULL, TYPE_PXB_PCIE_HOST);
+ /* attach it under /machine, so that we can resolve a valid path in
+ * object_property_set_link below */
+ object_property_add_child(qdev_get_machine(), "pxb-pcie-host[*]",
OBJECT(ds), NULL);
+ /* set link and backlink between PXBPCIEHost and PXBDev */
object_property_set_link(OBJECT(ds), OBJECT(pxb),
PROP_PXB_PCIE_DEV, errp);
+ object_property_set_link(OBJECT(pxb), OBJECT(ds),
+ PROP_PXB_PCIE_HOST, errp);
/* will be overwritten by firmware, but kept for readability */
qdev_prop_set_uint64(ds, PCIE_HOST_MCFG_BASE,
@@ -413,6 +426,36 @@ static void pxb_dev_exitfn(PCIDevice *pci_dev)
pxb_dev_list = g_list_remove(pxb_dev_list, pxb);
}
+static uint32_t pxb_pcie_config_read(PCIDevice *d, uint32_t address, int len)
+{
+ PXBDev *pxb = convert_to_pxb(d);
+ uint32_t val;
+ Object *host;
+
+ switch (address) {
+ case MCH_HOST_BRIDGE_PCIEXBAR:
+ host = object_property_get_link(OBJECT(pxb), PROP_PXB_PCIE_HOST, NULL);
+ assert(host);
+ val = object_property_get_uint(host, PCIE_HOST_MCFG_BASE, NULL) &
0xFFFFFFFF;
+ break;
+ case MCH_HOST_BRIDGE_PCIEXBAR + 4:
+ host = object_property_get_link(OBJECT(pxb), PROP_PXB_PCIE_HOST, NULL);
+ assert(host);
+ val = (object_property_get_uint(host, PCIE_HOST_MCFG_BASE, NULL) >>
32) & 0xFFFFFFFF;
+ break;
+ case MCH_HOST_BRIDGE_PCIEXBAR + 8: // Fix me!
+ host = object_property_get_link(OBJECT(pxb), PROP_PXB_PCIE_HOST, NULL);
+ assert(host);
+ val = object_property_get_uint(host, PCIE_HOST_MCFG_SIZE, NULL) &
0xFFFFFFFF;
+ break;
+ default:
+ val = pci_default_read_config(d, address, len);
+ break;
+ }
+
+ return val;
+}
+
static Property pxb_dev_properties[] = {
/* Note: 0 is not a legal PXB bus number. */
DEFINE_PROP_UINT8(PROP_PXB_BUS_NR, PXBDev, bus_nr, 0),
@@ -447,6 +490,16 @@ static void pxb_dev_class_init(ObjectClass *klass, void
*data)
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
+static void pxb_pcie_dev_initfn(Object *obj)
+{
+ PXBDev *pxb = PXB_PCIE_DEV(obj);
+
+ /* Add backlink to pxb-pcie-host */
+ object_property_add_link(obj, PROP_PXB_PCIE_HOST, TYPE_PXB_PCIE_HOST,
+ (Object **)&pxb->pxbhost,
+ qdev_prop_allow_set_link_before_realize, 0, NULL);
+}
+
static const TypeInfo pxb_dev_info = {
.name = TYPE_PXB_DEVICE,
.parent = TYPE_PCI_DEVICE,
@@ -478,6 +531,7 @@ static void pxb_pcie_dev_class_init(ObjectClass *klass,
void *data)
k->realize = pxb_pcie_dev_realize;
k->exit = pxb_dev_exitfn;
+ k->config_read = pxb_pcie_config_read;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_PXB_PCIE;
k->class_id = PCI_CLASS_BRIDGE_HOST;
@@ -492,6 +546,7 @@ static const TypeInfo pxb_pcie_dev_info = {
.name = TYPE_PXB_PCIE_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PXBDev),
+ .instance_init = pxb_pcie_dev_initfn,
.class_init = pxb_pcie_dev_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
diff --git a/include/hw/pci-bridge/pci_expander_bridge.h
b/include/hw/pci-bridge/pci_expander_bridge.h
index 870c4cd..1119210 100644
--- a/include/hw/pci-bridge/pci_expander_bridge.h
+++ b/include/hw/pci-bridge/pci_expander_bridge.h
@@ -2,6 +2,7 @@
#define HW_PCI_EXPANDER_H
#define PROP_PXB_PCIE_DEV "pxbdev"
+#define PROP_PXB_PCIE_HOST "x-pxb-host"
#define PROP_PXB_PCIE_DOMAIN_NR "domain_nr"
#define PROP_PXB_BUS_NR "bus_nr"
--
2.7.4
- [Qemu-devel] [RFC v3 0/6] pci_expander_brdige: Put pxb-pcie host bridge into separate pci domain, Zihan Yang, 2018/08/01
- [Qemu-devel] [RFC v3 1/6] pci_expander_bridge: add type TYPE_PXB_PCIE_HOST, Zihan Yang, 2018/08/01
- [Qemu-devel] [RFC v3 2/6] acpi-build: allocate mcfg for pxb-pcie host bridges, Zihan Yang, 2018/08/01
- [Qemu-devel] [RFC v3 3/6] i386/acpi-build: describe new pci domain in AML, Zihan Yang, 2018/08/01
- [Qemu-devel] [RFC v3 4/6] pci_expander_bridge: Add config_read callback,
Zihan Yang <=
- [Qemu-devel] [RFC v3 5/6] pci_expander_bridge: Add ioport for pxb host bus, Zihan Yang, 2018/08/01
- [Qemu-devel] [RFC v3 6/6] pci_expander_bridge: add start_bus property, Zihan Yang, 2018/08/01
- Re: [Qemu-devel] [RFC v3 0/6] pci_expander_brdige: Put pxb-pcie host bridge into separate pci domain, no-reply, 2018/08/01
- Re: [Qemu-devel] [RFC v3 0/6] pci_expander_brdige: Put pxb-pcie host bridge into separate pci domain, no-reply, 2018/08/01