aboutsummaryrefslogtreecommitdiff
path: root/hw/pci
diff options
context:
space:
mode:
Diffstat (limited to 'hw/pci')
-rw-r--r--hw/pci/pci.c141
-rw-r--r--hw/pci/pci_bridge.c6
-rw-r--r--hw/pci/pcie.c5
-rw-r--r--hw/pci/pcie_aer.c4
4 files changed, 74 insertions, 82 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index b2d139bd9a..e8f9fc1c27 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -222,7 +222,7 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
{
PCIBus *bus;
for (;;) {
- bus = pci_dev->bus;
+ bus = pci_get_bus(pci_dev);
irq_num = bus->map_irq(pci_dev, irq_num);
if (bus->set_irq)
break;
@@ -331,31 +331,15 @@ static void pci_host_bus_register(DeviceState *host)
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
}
-PCIBus *pci_find_primary_bus(void)
-{
- PCIBus *primary_bus = NULL;
- PCIHostState *host;
-
- QLIST_FOREACH(host, &pci_host_bridges, next) {
- if (primary_bus) {
- /* We have multiple root buses, refuse to select a primary */
- return NULL;
- }
- primary_bus = host->bus;
- }
-
- return primary_bus;
-}
-
PCIBus *pci_device_root_bus(const PCIDevice *d)
{
- PCIBus *bus = d->bus;
+ PCIBus *bus = pci_get_bus(d);
while (!pci_bus_is_root(bus)) {
d = bus->parent_dev;
assert(d != NULL);
- bus = d->bus;
+ bus = pci_get_bus(d);
}
return bus;
@@ -376,10 +360,10 @@ const char *pci_root_bus_path(PCIDevice *dev)
return rootbus->qbus.name;
}
-static void pci_bus_init(PCIBus *bus, DeviceState *parent,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min)
+static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min)
{
assert(PCI_FUNC(devfn_min) == 0);
bus->devfn_min = devfn_min;
@@ -403,25 +387,27 @@ bool pci_bus_is_root(PCIBus *bus)
return PCI_BUS_GET_CLASS(bus)->is_root(bus);
}
-void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
- const char *name,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, const char *typename)
+void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
+ const char *name,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, const char *typename)
{
qbus_create_inplace(bus, bus_size, typename, parent, name);
- pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
+ pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
+ devfn_min);
}
-PCIBus *pci_bus_new(DeviceState *parent, const char *name,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, const char *typename)
+PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, const char *typename)
{
PCIBus *bus;
bus = PCI_BUS(qbus_create(typename, parent, name));
- pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
+ pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
+ devfn_min);
return bus;
}
@@ -435,17 +421,18 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
}
-PCIBus *pci_register_bus(DeviceState *parent, const char *name,
- pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *irq_opaque,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, int nirq, const char *typename)
+PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
+ pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ void *irq_opaque,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, int nirq,
+ const char *typename)
{
PCIBus *bus;
- bus = pci_bus_new(parent, name, address_space_mem,
- address_space_io, devfn_min, typename);
+ bus = pci_root_bus_new(parent, name, address_space_mem,
+ address_space_io, devfn_min, typename);
pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
return bus;
}
@@ -879,7 +866,7 @@ static void pci_config_free(PCIDevice *pci_dev)
static void do_pci_unregister_device(PCIDevice *pci_dev)
{
- pci_dev->bus->devices[pci_dev->devfn] = NULL;
+ pci_get_bus(pci_dev)->devices[pci_dev->devfn] = NULL;
pci_config_free(pci_dev);
if (memory_region_is_mapped(&pci_dev->bus_master_enable_region)) {
@@ -900,7 +887,7 @@ static uint16_t pci_req_id_cache_extract(PCIReqIDCache *cache)
result = pci_get_bdf(cache->dev);
break;
case PCI_REQ_ID_SECONDARY_BUS:
- bus_n = pci_bus_num(cache->dev->bus);
+ bus_n = pci_dev_bus_num(cache->dev);
result = PCI_BUILD_BDF(bus_n, 0);
break;
default:
@@ -930,9 +917,9 @@ static PCIReqIDCache pci_req_id_cache_get(PCIDevice *dev)
.type = PCI_REQ_ID_BDF,
};
- while (!pci_bus_is_root(dev->bus)) {
+ while (!pci_bus_is_root(pci_get_bus(dev))) {
/* We are under PCI/PCIe bridges */
- parent = dev->bus->parent_dev;
+ parent = pci_get_bus(dev)->parent_dev;
if (pci_is_express(parent)) {
if (pcie_cap_get_type(parent) == PCI_EXP_TYPE_PCI_BRIDGE) {
/* When we pass through PCIe-to-PCI/PCIX bridges, we
@@ -975,7 +962,7 @@ static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
}
/* -1 for devfn means auto assign */
-static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
+static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
const char *name, int devfn,
Error **errp)
{
@@ -984,8 +971,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
PCIConfigWriteFunc *config_write = pc->config_write;
Error *local_err = NULL;
DeviceState *dev = DEVICE(pci_dev);
+ PCIBus *bus = pci_get_bus(pci_dev);
- pci_dev->bus = bus;
/* Only pci bridges can be attached to extra PCI root buses */
if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {
error_setg(errp,
@@ -1139,8 +1126,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
r->type = type;
r->memory = memory;
r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
- ? pci_dev->bus->address_space_io
- : pci_dev->bus->address_space_mem;
+ ? pci_get_bus(pci_dev)->address_space_io
+ : pci_get_bus(pci_dev)->address_space_mem;
wmask = ~(size - 1);
if (region_num == PCI_ROM_SLOT) {
@@ -1182,21 +1169,23 @@ static void pci_update_vga(PCIDevice *pci_dev)
void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
MemoryRegion *io_lo, MemoryRegion *io_hi)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
assert(!pci_dev->has_vga);
assert(memory_region_size(mem) == QEMU_PCI_VGA_MEM_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_MEM] = mem;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_mem,
+ memory_region_add_subregion_overlap(bus->address_space_mem,
QEMU_PCI_VGA_MEM_BASE, mem, 1);
assert(memory_region_size(io_lo) == QEMU_PCI_VGA_IO_LO_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO] = io_lo;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
+ memory_region_add_subregion_overlap(bus->address_space_io,
QEMU_PCI_VGA_IO_LO_BASE, io_lo, 1);
assert(memory_region_size(io_hi) == QEMU_PCI_VGA_IO_HI_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI] = io_hi;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
+ memory_region_add_subregion_overlap(bus->address_space_io,
QEMU_PCI_VGA_IO_HI_BASE, io_hi, 1);
pci_dev->has_vga = true;
@@ -1205,15 +1194,17 @@ void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
void pci_unregister_vga(PCIDevice *pci_dev)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
if (!pci_dev->has_vga) {
return;
}
- memory_region_del_subregion(pci_dev->bus->address_space_mem,
+ memory_region_del_subregion(bus->address_space_mem,
pci_dev->vga_regions[QEMU_PCI_VGA_MEM]);
- memory_region_del_subregion(pci_dev->bus->address_space_io,
+ memory_region_del_subregion(bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO]);
- memory_region_del_subregion(pci_dev->bus->address_space_io,
+ memory_region_del_subregion(bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI]);
pci_dev->has_vga = false;
}
@@ -1316,7 +1307,7 @@ static void pci_update_mappings(PCIDevice *d)
/* now do the real mapping */
if (r->addr != PCI_BAR_UNMAPPED) {
- trace_pci_update_mappings_del(d, pci_bus_num(d->bus),
+ trace_pci_update_mappings_del(d, pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
PCI_FUNC(d->devfn),
i, r->addr, r->size);
@@ -1324,7 +1315,7 @@ static void pci_update_mappings(PCIDevice *d)
}
r->addr = new_addr;
if (r->addr != PCI_BAR_UNMAPPED) {
- trace_pci_update_mappings_add(d, pci_bus_num(d->bus),
+ trace_pci_update_mappings_add(d, pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
PCI_FUNC(d->devfn),
i, r->addr, r->size);
@@ -1443,9 +1434,9 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
PCIBus *bus;
do {
- bus = dev->bus;
- pin = bus->map_irq(dev, pin);
- dev = bus->parent_dev;
+ bus = pci_get_bus(dev);
+ pin = bus->map_irq(dev, pin);
+ dev = bus->parent_dev;
} while (dev);
if (!bus->route_intx_to_irq) {
@@ -2015,7 +2006,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
PCIDevice *pci_dev = (PCIDevice *)qdev;
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
Error *local_err = NULL;
- PCIBus *bus;
bool is_default_rom;
/* initialize cap_present for pci_is_express() and pci_config_size() */
@@ -2023,8 +2013,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
}
- bus = PCI_BUS(qdev_get_parent_bus(qdev));
- pci_dev = do_pci_register_device(pci_dev, bus,
+ pci_dev = do_pci_register_device(pci_dev,
object_get_typename(OBJECT(qdev)),
pci_dev->devfn, errp);
if (pci_dev == NULL)
@@ -2317,7 +2306,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
error_setg(errp, "%s:%02x:%02x.%x "
"Attempt to add PCI capability %x at offset "
"%x overlaps existing capability %x at offset %x",
- pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
+ pci_root_bus_path(pdev), pci_dev_bus_num(pdev),
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
cap_id, offset, overlapping_cap, i);
return -EINVAL;
@@ -2381,7 +2370,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
"pci id %04x:%04x (sub %04x:%04x)\n",
- indent, "", ctxt, pci_bus_num(d->bus),
+ indent, "", ctxt, pci_dev_bus_num(d),
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
pci_get_word(d->config + PCI_VENDOR_ID),
pci_get_word(d->config + PCI_DEVICE_ID),
@@ -2464,7 +2453,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
/* Calculate # of slots on path between device and root. */;
slot_depth = 0;
- for (t = d; t; t = t->bus->parent_dev) {
+ for (t = d; t; t = pci_get_bus(t)->parent_dev) {
++slot_depth;
}
@@ -2479,7 +2468,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
/* Fill in slot numbers. We walk up from device to root, so need to print
* them in the reverse order, last to first. */
p = path + path_len;
- for (t = d; t; t = t->bus->parent_dev) {
+ for (t = d; t; t = pci_get_bus(t)->parent_dev) {
p -= slot_len;
s = snprintf(slot, sizeof slot, ":%02x.%x",
PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
@@ -2527,12 +2516,12 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev)
MemoryRegion *pci_address_space(PCIDevice *dev)
{
- return dev->bus->address_space_mem;
+ return pci_get_bus(dev)->address_space_mem;
}
MemoryRegion *pci_address_space_io(PCIDevice *dev)
{
- return dev->bus->address_space_io;
+ return pci_get_bus(dev)->address_space_io;
}
static void pci_device_class_init(ObjectClass *klass, void *data)
@@ -2560,11 +2549,11 @@ static void pci_device_class_base_init(ObjectClass *klass, void *data)
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
{
- PCIBus *bus = PCI_BUS(dev->bus);
+ PCIBus *bus = pci_get_bus(dev);
PCIBus *iommu_bus = bus;
while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) {
- iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus);
+ iommu_bus = pci_get_bus(iommu_bus->parent_dev);
}
if (iommu_bus && iommu_bus->iommu_fn) {
return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn);
@@ -2635,7 +2624,7 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range)
static bool pcie_has_upstream_port(PCIDevice *dev)
{
- PCIDevice *parent_dev = pci_bridge_get_device(dev->bus);
+ PCIDevice *parent_dev = pci_bridge_get_device(pci_get_bus(dev));
/* Device associated with an upstream port.
* As there are several types of these, it's easier to check the
@@ -2651,12 +2640,14 @@ static bool pcie_has_upstream_port(PCIDevice *dev)
PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
if(pcie_has_upstream_port(pci_dev)) {
/* With an upstream PCIe port, we only support 1 device at slot 0 */
- return pci_dev->bus->devices[0];
+ return bus->devices[0];
} else {
/* Other bus types might support multiple devices at slots 0-31 */
- return pci_dev->bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
+ return bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
}
}
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index a47d257149..b2e50c36a0 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -183,7 +183,7 @@ static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
{
PCIDevice *pd = PCI_DEVICE(br);
- PCIBus *parent = pd->bus;
+ PCIBus *parent = pci_get_bus(pd);
PCIBridgeWindows *w = g_new(PCIBridgeWindows, 1);
uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
@@ -214,7 +214,7 @@ static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
{
PCIDevice *pd = PCI_DEVICE(br);
- PCIBus *parent = pd->bus;
+ PCIBus *parent = pci_get_bus(pd);
memory_region_del_subregion(parent->address_space_io, &w->alias_io);
memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
@@ -339,7 +339,7 @@ void pci_bridge_reset(DeviceState *qdev)
/* default qdev initialization function for PCI-to-PCI bridge */
void pci_bridge_initfn(PCIDevice *dev, const char *typename)
{
- PCIBus *parent = dev->bus;
+ PCIBus *parent = pci_get_bus(dev);
PCIBridge *br = PCI_BRIDGE(dev);
PCIBus *sec_bus = &br->sec_bus;
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 32191f2a55..6c91bd44a0 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -155,7 +155,8 @@ pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
* a regular Endpoint type is exposed on a root complex. These
* should instead be Root Complex Integrated Endpoints.
*/
- if (pci_bus_is_express(dev->bus) && pci_bus_is_root(dev->bus)) {
+ if (pci_bus_is_express(pci_get_bus(dev))
+ && pci_bus_is_root(pci_get_bus(dev))) {
type = PCI_EXP_TYPE_RC_END;
}
@@ -369,7 +370,7 @@ void pcie_cap_slot_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
{
uint8_t *exp_cap;
PCIDevice *pci_dev = PCI_DEVICE(dev);
- PCIBus *bus = pci_dev->bus;
+ PCIBus *bus = pci_get_bus(pci_dev);
pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 97200742b4..b009be7f17 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -409,7 +409,7 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
*/
return;
}
- dev = pci_bridge_get_device(dev->bus);
+ dev = pci_bridge_get_device(pci_get_bus(dev));
}
}
@@ -1025,7 +1025,7 @@ static int do_pcie_aer_inject_error(Monitor *mon,
}
details->id = id;
details->root_bus = pci_root_bus_path(dev);
- details->bus = pci_bus_num(dev->bus);
+ details->bus = pci_dev_bus_num(dev);
details->devfn = dev->devfn;
return 0;