[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [Qemu-devel] [PATCH RFC 06/17] hw/pci: move pci bus related c
From: |
Marcel Apfelbaum |
Subject: |
[Qemu-ppc] [Qemu-devel] [PATCH RFC 06/17] hw/pci: move pci bus related code to separate files |
Date: |
Thu, 22 Jan 2015 21:52:32 +0200 |
From: Marcel Apfelbaum <address@hidden>
This refactoring moves all the code needed (recursively)
to register TYPE_PCI_BUS type to a new file hw/pci/pci_bus.c .
This allows to properly add new functionality to the pci bus class.
Signed-off-by: Marcel Apfelbaum <address@hidden>
---
arch_init.c | 1 +
hw/alpha/typhoon.c | 1 +
hw/mips/gt64xxx_pci.c | 1 +
hw/pci-host/bonito.c | 1 +
hw/pci-host/grackle.c | 1 +
hw/pci-host/piix.c | 1 +
hw/pci-host/ppce500.c | 1 +
hw/pci-host/q35.c | 1 +
hw/pci-host/uninorth.c | 1 +
hw/pci/Makefile.objs | 2 +-
hw/pci/pci.c | 472 +--------------------------------------------
hw/pci/pci_bus.c | 491 +++++++++++++++++++++++++++++++++++++++++++++++
hw/ppc/ppc4xx_pci.c | 1 +
hw/sh4/r2d.c | 1 +
hw/sh4/sh_pci.c | 1 +
include/hw/pci/pci.h | 3 +-
include/hw/pci/pci_bus.h | 8 +
17 files changed, 514 insertions(+), 474 deletions(-)
create mode 100644 hw/pci/pci_bus.c
diff --git a/arch_init.c b/arch_init.c
index 89c8fa4..f2f7452 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -37,6 +37,7 @@
#include "audio/audio.h"
#include "hw/i386/pc.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/audio/audio.h"
#include "sysemu/kvm.h"
#include "migration/migration.h"
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 5310006..c8be8a6 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -8,6 +8,7 @@
#include "cpu.h"
#include "hw/hw.h"
+#include "hw/pci/pci_bus.h"
#include "hw/devices.h"
#include "sysemu/sysemu.h"
#include "alpha_sys.h"
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 1f2fe5f..6856bb0 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -25,6 +25,7 @@
#include "hw/hw.h"
#include "hw/mips/mips.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
#include "hw/i386/pc.h"
#include "exec/address-spaces.h"
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 56292ad..72d6e12 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -41,6 +41,7 @@
#include "hw/hw.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/i386/pc.h"
#include "hw/mips/mips.h"
#include "hw/pci/pci_host.h"
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 6c7cfdb..7ee6417 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -26,6 +26,7 @@
#include "hw/pci/pci_host.h"
#include "hw/ppc/mac.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
/* debug Grackle */
//#define DEBUG_GRACKLE
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 1530038..f7cfbc8 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -25,6 +25,7 @@
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
#include "hw/isa/isa.h"
#include "hw/sysbus.h"
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 574f8b2..a6aef6a 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -17,6 +17,7 @@
#include "hw/hw.h"
#include "hw/ppc/e500-ccsr.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
#include "qemu/bswap.h"
#include "hw/pci-host/ppce500.h"
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index b20bad8..c36fefa 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -28,6 +28,7 @@
* THE SOFTWARE.
*/
#include "hw/hw.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci-host/q35.h"
#include "qapi/visitor.h"
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index 21f805f..c9cc570 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -24,6 +24,7 @@
#include "hw/hw.h"
#include "hw/ppc/mac.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
/* debug UniNorth */
diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index 80f8aa6..63aa4c5 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-$(CONFIG_PCI) += pci.o pci_bridge.o
+common-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bus.o
common-obj-$(CONFIG_PCI) += msix.o msi.o
common-obj-$(CONFIG_PCI) += shpc.o
common-obj-$(CONFIG_PCI) += slotid_cap.o
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 371699c..933ef65 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -44,11 +44,6 @@
# define PCI_DPRINTF(format, ...) do { } while (0)
#endif
-static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
-static char *pcibus_get_dev_path(DeviceState *dev);
-static char *pcibus_get_fw_dev_path(DeviceState *dev);
-static void pcibus_reset(BusState *qbus);
-
static Property pci_props[] = {
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
@@ -60,58 +55,11 @@ static Property pci_props[] = {
DEFINE_PROP_END_OF_LIST()
};
-static const VMStateDescription vmstate_pcibus = {
- .name = "PCIBUS",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_EQUAL(nirq, PCIBus),
- VMSTATE_VARRAY_INT32(irq_count, PCIBus,
- nirq, 0, vmstate_info_int32,
- int32_t),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void pci_bus_realize(BusState *qbus, Error **errp)
-{
- PCIBus *bus = PCI_BUS(qbus);
-
- vmstate_register(NULL, -1, &vmstate_pcibus, bus);
-}
-
-static void pci_bus_unrealize(BusState *qbus, Error **errp)
-{
- PCIBus *bus = PCI_BUS(qbus);
-
- vmstate_unregister(NULL, &vmstate_pcibus, bus);
-}
-
-static void pci_bus_class_init(ObjectClass *klass, void *data)
-{
- BusClass *k = BUS_CLASS(klass);
-
- k->print_dev = pcibus_dev_print;
- k->get_dev_path = pcibus_get_dev_path;
- k->get_fw_dev_path = pcibus_get_fw_dev_path;
- k->realize = pci_bus_realize;
- k->unrealize = pci_bus_unrealize;
- k->reset = pcibus_reset;
-}
-
-static const TypeInfo pci_bus_info = {
- .name = TYPE_PCI_BUS,
- .parent = TYPE_BUS,
- .instance_size = sizeof(PCIBus),
- .class_init = pci_bus_class_init,
-};
-
static const TypeInfo pcie_bus_info = {
.name = TYPE_PCIE_BUS,
.parent = TYPE_PCI_BUS,
};
-static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
static void pci_update_mappings(PCIDevice *d);
static void pci_irq_handler(void *opaque, int irq_num, int level);
static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom);
@@ -184,7 +132,7 @@ void pci_device_deassert_intx(PCIDevice *dev)
}
}
-static void pci_do_device_reset(PCIDevice *dev)
+void pci_do_device_reset(PCIDevice *dev)
{
int r;
@@ -229,27 +177,6 @@ void pci_device_reset(PCIDevice *dev)
pci_do_device_reset(dev);
}
-/*
- * Trigger pci bus reset under a given bus.
- * Called via qbus_reset_all on RST# assert, after the devices
- * have been reset qdev_reset_all-ed already.
- */
-static void pcibus_reset(BusState *qbus)
-{
- PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
- if (bus->devices[i]) {
- pci_do_device_reset(bus->devices[i]);
- }
- }
-
- for (i = 0; i < bus->nirq; i++) {
- assert(bus->irq_count[i] == 0);
- }
-}
-
static void pci_host_bus_register(PCIBus *bus, DeviceState *parent)
{
PCIHostState *host_bridge = PCI_HOST_BRIDGE(parent);
@@ -1286,74 +1213,6 @@ int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin)
return (pin + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
}
-/***********************************************************/
-/* monitor info on PCI */
-
-typedef struct {
- uint16_t class;
- const char *desc;
- const char *fw_name;
- uint16_t fw_ign_bits;
-} pci_class_desc;
-
-static const pci_class_desc pci_class_descriptions[] =
-{
- { 0x0001, "VGA controller", "display"},
- { 0x0100, "SCSI controller", "scsi"},
- { 0x0101, "IDE controller", "ide"},
- { 0x0102, "Floppy controller", "fdc"},
- { 0x0103, "IPI controller", "ipi"},
- { 0x0104, "RAID controller", "raid"},
- { 0x0106, "SATA controller"},
- { 0x0107, "SAS controller"},
- { 0x0180, "Storage controller"},
- { 0x0200, "Ethernet controller", "ethernet"},
- { 0x0201, "Token Ring controller", "token-ring"},
- { 0x0202, "FDDI controller", "fddi"},
- { 0x0203, "ATM controller", "atm"},
- { 0x0280, "Network controller"},
- { 0x0300, "VGA controller", "display", 0x00ff},
- { 0x0301, "XGA controller"},
- { 0x0302, "3D controller"},
- { 0x0380, "Display controller"},
- { 0x0400, "Video controller", "video"},
- { 0x0401, "Audio controller", "sound"},
- { 0x0402, "Phone"},
- { 0x0403, "Audio controller", "sound"},
- { 0x0480, "Multimedia controller"},
- { 0x0500, "RAM controller", "memory"},
- { 0x0501, "Flash controller", "flash"},
- { 0x0580, "Memory controller"},
- { 0x0600, "Host bridge", "host"},
- { 0x0601, "ISA bridge", "isa"},
- { 0x0602, "EISA bridge", "eisa"},
- { 0x0603, "MC bridge", "mca"},
- { 0x0604, "PCI bridge", "pci-bridge"},
- { 0x0605, "PCMCIA bridge", "pcmcia"},
- { 0x0606, "NUBUS bridge", "nubus"},
- { 0x0607, "CARDBUS bridge", "cardbus"},
- { 0x0608, "RACEWAY bridge"},
- { 0x0680, "Bridge"},
- { 0x0700, "Serial port", "serial"},
- { 0x0701, "Parallel port", "parallel"},
- { 0x0800, "Interrupt controller", "interrupt-controller"},
- { 0x0801, "DMA controller", "dma-controller"},
- { 0x0802, "Timer", "timer"},
- { 0x0803, "RTC", "rtc"},
- { 0x0900, "Keyboard", "keyboard"},
- { 0x0901, "Pen", "pen"},
- { 0x0902, "Mouse", "mouse"},
- { 0x0A00, "Dock station", "dock", 0x00ff},
- { 0x0B00, "i386 cpu", "cpu", 0x00ff},
- { 0x0c00, "Fireware contorller", "fireware"},
- { 0x0c01, "Access bus controller", "access-bus"},
- { 0x0c02, "SSA controller", "ssa"},
- { 0x0c03, "USB controller", "usb"},
- { 0x0c04, "Fibre channel controller", "fibre-channel"},
- { 0x0c05, "SMBus"},
- { 0, NULL}
-};
-
static void pci_for_each_device_under_bus(PCIBus *bus,
void (*fn)(PCIBus *b, PCIDevice *d,
void *opaque),
@@ -1381,161 +1240,6 @@ void pci_for_each_device(PCIBus *bus, int bus_num,
}
}
-static const pci_class_desc *get_class_desc(int class)
-{
- const pci_class_desc *desc;
-
- desc = pci_class_descriptions;
- while (desc->desc && class != desc->class) {
- desc++;
- }
-
- return desc;
-}
-
-static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
-
-static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
-{
- PciMemoryRegionList *head = NULL, *cur_item = NULL;
- int i;
-
- for (i = 0; i < PCI_NUM_REGIONS; i++) {
- const PCIIORegion *r = &dev->io_regions[i];
- PciMemoryRegionList *region;
-
- if (!r->size) {
- continue;
- }
-
- region = g_malloc0(sizeof(*region));
- region->value = g_malloc0(sizeof(*region->value));
-
- if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
- region->value->type = g_strdup("io");
- } else {
- region->value->type = g_strdup("memory");
- region->value->has_prefetch = true;
- region->value->prefetch = !!(r->type &
PCI_BASE_ADDRESS_MEM_PREFETCH);
- region->value->has_mem_type_64 = true;
- region->value->mem_type_64 = !!(r->type &
PCI_BASE_ADDRESS_MEM_TYPE_64);
- }
-
- region->value->bar = i;
- region->value->address = r->addr;
- region->value->size = r->size;
-
- /* XXX: waiting for the qapi to support GSList */
- if (!cur_item) {
- head = cur_item = region;
- } else {
- cur_item->next = region;
- cur_item = region;
- }
- }
-
- return head;
-}
-
-static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
- int bus_num)
-{
- PciBridgeInfo *info;
-
- info = g_malloc0(sizeof(*info));
-
- info->bus.number = dev->config[PCI_PRIMARY_BUS];
- info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
- info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
-
- info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
- info->bus.io_range->base = pci_bridge_get_base(dev,
PCI_BASE_ADDRESS_SPACE_IO);
- info->bus.io_range->limit = pci_bridge_get_limit(dev,
PCI_BASE_ADDRESS_SPACE_IO);
-
- info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
- info->bus.memory_range->base = pci_bridge_get_base(dev,
PCI_BASE_ADDRESS_SPACE_MEMORY);
- info->bus.memory_range->limit = pci_bridge_get_limit(dev,
PCI_BASE_ADDRESS_SPACE_MEMORY);
-
- info->bus.prefetchable_range =
g_malloc0(sizeof(*info->bus.prefetchable_range));
- info->bus.prefetchable_range->base = pci_bridge_get_base(dev,
PCI_BASE_ADDRESS_MEM_PREFETCH);
- info->bus.prefetchable_range->limit = pci_bridge_get_limit(dev,
PCI_BASE_ADDRESS_MEM_PREFETCH);
-
- if (dev->config[PCI_SECONDARY_BUS] != 0) {
- PCIBus *child_bus = pci_find_bus_nr(bus,
dev->config[PCI_SECONDARY_BUS]);
- if (child_bus) {
- info->has_devices = true;
- info->devices = qmp_query_pci_devices(child_bus,
dev->config[PCI_SECONDARY_BUS]);
- }
- }
-
- return info;
-}
-
-static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
- int bus_num)
-{
- const pci_class_desc *desc;
- PciDeviceInfo *info;
- uint8_t type;
- int class;
-
- info = g_malloc0(sizeof(*info));
- info->bus = bus_num;
- info->slot = PCI_SLOT(dev->devfn);
- info->function = PCI_FUNC(dev->devfn);
-
- class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
- info->class_info.q_class = class;
- desc = get_class_desc(class);
- if (desc->desc) {
- info->class_info.has_desc = true;
- info->class_info.desc = g_strdup(desc->desc);
- }
-
- info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
- info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
- info->regions = qmp_query_pci_regions(dev);
- info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
-
- if (dev->config[PCI_INTERRUPT_PIN] != 0) {
- info->has_irq = true;
- info->irq = dev->config[PCI_INTERRUPT_LINE];
- }
-
- type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
- if (type == PCI_HEADER_TYPE_BRIDGE) {
- info->has_pci_bridge = true;
- info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
- }
-
- return info;
-}
-
-static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
-{
- PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
- PCIDevice *dev;
- int devfn;
-
- for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
- dev = bus->devices[devfn];
- if (dev) {
- info = g_malloc0(sizeof(*info));
- info->value = qmp_query_pci_device(dev, bus, bus_num);
-
- /* XXX: waiting for the qapi to support GSList */
- if (!cur_item) {
- head = cur_item = info;
- } else {
- cur_item->next = info;
- cur_item = info;
- }
- }
- }
-
- return head;
-}
-
static PciInfo *qmp_query_pci_bus(PCIBus *bus, int bus_num)
{
PciInfo *info = NULL;
@@ -1660,50 +1364,6 @@ PCIDevice *pci_vga_init(PCIBus *bus)
}
}
-/* Whether a given bus number is in range of the secondary
- * bus of the given bridge device. */
-static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
-{
- return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
- PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */
&&
- dev->config[PCI_SECONDARY_BUS] < bus_num &&
- bus_num <= dev->config[PCI_SUBORDINATE_BUS];
-}
-
-static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
-{
- PCIBus *sec;
-
- if (!bus) {
- return NULL;
- }
-
- if (pci_bus_num(bus) == bus_num) {
- return bus;
- }
-
- /* Consider all bus numbers in range for the host pci bridge. */
- if (!pci_bus_is_root(bus) &&
- !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
- return NULL;
- }
-
- /* try child bus */
- for (; bus; bus = sec) {
- QLIST_FOREACH(sec, &bus->child, sibling) {
- assert(!pci_bus_is_root(sec));
- if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
- return sec;
- }
- if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
- break;
- }
- }
- }
-
- return NULL;
-}
-
void pci_for_each_bus_depth_first(PCIBus *bus,
void *(*begin)(PCIBus *bus, void
*parent_state),
void (*end)(PCIBus *bus, void *state),
@@ -2106,135 +1766,6 @@ uint8_t pci_find_capability(PCIDevice *pdev, uint8_t
cap_id)
return pci_find_capability_list(pdev, cap_id, NULL);
}
-static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
-{
- PCIDevice *d = (PCIDevice *)dev;
- const pci_class_desc *desc;
- char ctxt[64];
- PCIIORegion *r;
- int i, class;
-
- class = pci_get_word(d->config + PCI_CLASS_DEVICE);
- desc = pci_class_descriptions;
- while (desc->desc && class != desc->class)
- desc++;
- if (desc->desc) {
- snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
- } else {
- snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
- }
-
- monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
- "pci id %04x:%04x (sub %04x:%04x)\n",
- indent, "", ctxt, pci_bus_num(d->bus),
- PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
- pci_get_word(d->config + PCI_VENDOR_ID),
- pci_get_word(d->config + PCI_DEVICE_ID),
- pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
- pci_get_word(d->config + PCI_SUBSYSTEM_ID));
- for (i = 0; i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (!r->size)
- continue;
- monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
- " [0x%"FMT_PCIBUS"]\n",
- indent, "",
- i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
- r->addr, r->addr + r->size - 1);
- }
-}
-
-static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
-{
- PCIDevice *d = (PCIDevice *)dev;
- const char *name = NULL;
- const pci_class_desc *desc = pci_class_descriptions;
- int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
-
- while (desc->desc &&
- (class & ~desc->fw_ign_bits) !=
- (desc->class & ~desc->fw_ign_bits)) {
- desc++;
- }
-
- if (desc->desc) {
- name = desc->fw_name;
- }
-
- if (name) {
- pstrcpy(buf, len, name);
- } else {
- snprintf(buf, len, "pci%04x,%04x",
- pci_get_word(d->config + PCI_VENDOR_ID),
- pci_get_word(d->config + PCI_DEVICE_ID));
- }
-
- return buf;
-}
-
-static char *pcibus_get_fw_dev_path(DeviceState *dev)
-{
- PCIDevice *d = (PCIDevice *)dev;
- char path[50], name[33];
- int off;
-
- off = snprintf(path, sizeof(path), "address@hidden",
- pci_dev_fw_name(dev, name, sizeof name),
- PCI_SLOT(d->devfn));
- if (PCI_FUNC(d->devfn))
- snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
- return g_strdup(path);
-}
-
-static char *pcibus_get_dev_path(DeviceState *dev)
-{
- PCIDevice *d = container_of(dev, PCIDevice, qdev);
- PCIDevice *t;
- int slot_depth;
- /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
- * 00 is added here to make this format compatible with
- * domain:Bus:Slot.Func for systems without nested PCI bridges.
- * Slot.Function list specifies the slot and function numbers for all
- * devices on the path from root to the specific device. */
- const char *root_bus_path;
- int root_bus_len;
- char slot[] = ":SS.F";
- int slot_len = sizeof slot - 1 /* For '\0' */;
- int path_len;
- char *path, *p;
- int s;
-
- root_bus_path = pci_root_bus_path(d);
- root_bus_len = strlen(root_bus_path);
-
- /* Calculate # of slots on path between device and root. */;
- slot_depth = 0;
- for (t = d; t; t = t->bus->parent_dev) {
- ++slot_depth;
- }
-
- path_len = root_bus_len + slot_len * slot_depth;
-
- /* Allocate memory, fill in the terminating null byte. */
- path = g_malloc(path_len + 1 /* For '\0' */);
- path[path_len] = '\0';
-
- memcpy(path, root_bus_path, root_bus_len);
-
- /* 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) {
- p -= slot_len;
- s = snprintf(slot, sizeof slot, ":%02x.%x",
- PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
- assert(s == slot_len);
- memcpy(p, slot, slot_len);
- }
-
- return path;
-}
-
static int pci_qdev_find_recursive(PCIBus *bus,
const char *id, PCIDevice **pdev)
{
@@ -2377,7 +1908,6 @@ static const TypeInfo pci_device_type_info = {
static void pci_register_types(void)
{
- type_register_static(&pci_bus_info);
type_register_static(&pcie_bus_info);
type_register_static(&pci_device_type_info);
}
diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
new file mode 100644
index 0000000..d156194
--- /dev/null
+++ b/hw/pci/pci_bus.c
@@ -0,0 +1,491 @@
+/*
+ * PCI Bus
+ *
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * Authors:
+ * Marcel Apfelbaum <address@hidden> (split out from pci.c)
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_bridge.h"
+#include "monitor/monitor.h"
+
+typedef struct {
+ uint16_t class;
+ const char *desc;
+ const char *fw_name;
+ uint16_t fw_ign_bits;
+} pci_class_desc;
+
+static const pci_class_desc pci_class_descriptions[] = {
+ { 0x0001, "VGA controller", "display"},
+ { 0x0100, "SCSI controller", "scsi"},
+ { 0x0101, "IDE controller", "ide"},
+ { 0x0102, "Floppy controller", "fdc"},
+ { 0x0103, "IPI controller", "ipi"},
+ { 0x0104, "RAID controller", "raid"},
+ { 0x0106, "SATA controller"},
+ { 0x0107, "SAS controller"},
+ { 0x0180, "Storage controller"},
+ { 0x0200, "Ethernet controller", "ethernet"},
+ { 0x0201, "Token Ring controller", "token-ring"},
+ { 0x0202, "FDDI controller", "fddi"},
+ { 0x0203, "ATM controller", "atm"},
+ { 0x0280, "Network controller"},
+ { 0x0300, "VGA controller", "display", 0x00ff},
+ { 0x0301, "XGA controller"},
+ { 0x0302, "3D controller"},
+ { 0x0380, "Display controller"},
+ { 0x0400, "Video controller", "video"},
+ { 0x0401, "Audio controller", "sound"},
+ { 0x0402, "Phone"},
+ { 0x0403, "Audio controller", "sound"},
+ { 0x0480, "Multimedia controller"},
+ { 0x0500, "RAM controller", "memory"},
+ { 0x0501, "Flash controller", "flash"},
+ { 0x0580, "Memory controller"},
+ { 0x0600, "Host bridge", "host"},
+ { 0x0601, "ISA bridge", "isa"},
+ { 0x0602, "EISA bridge", "eisa"},
+ { 0x0603, "MC bridge", "mca"},
+ { 0x0604, "PCI bridge", "pci-bridge"},
+ { 0x0605, "PCMCIA bridge", "pcmcia"},
+ { 0x0606, "NUBUS bridge", "nubus"},
+ { 0x0607, "CARDBUS bridge", "cardbus"},
+ { 0x0608, "RACEWAY bridge"},
+ { 0x0680, "Bridge"},
+ { 0x0700, "Serial port", "serial"},
+ { 0x0701, "Parallel port", "parallel"},
+ { 0x0800, "Interrupt controller", "interrupt-controller"},
+ { 0x0801, "DMA controller", "dma-controller"},
+ { 0x0802, "Timer", "timer"},
+ { 0x0803, "RTC", "rtc"},
+ { 0x0900, "Keyboard", "keyboard"},
+ { 0x0901, "Pen", "pen"},
+ { 0x0902, "Mouse", "mouse"},
+ { 0x0A00, "Dock station", "dock", 0x00ff},
+ { 0x0B00, "i386 cpu", "cpu", 0x00ff},
+ { 0x0c00, "Fireware contorller", "fireware"},
+ { 0x0c01, "Access bus controller", "access-bus"},
+ { 0x0c02, "SSA controller", "ssa"},
+ { 0x0c03, "USB controller", "usb"},
+ { 0x0c04, "Fibre channel controller", "fibre-channel"},
+ { 0x0c05, "SMBus"},
+ { 0, NULL}
+};
+
+/* Whether a given bus number is in range of the secondary
+ * bus of the given bridge device. */
+static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
+{
+ return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
+ PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */
&&
+ dev->config[PCI_SECONDARY_BUS] < bus_num &&
+ bus_num <= dev->config[PCI_SUBORDINATE_BUS];
+}
+
+PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
+{
+ PCIBus *sec;
+
+ if (!bus) {
+ return NULL;
+ }
+
+ if (pci_bus_num(bus) == bus_num) {
+ return bus;
+ }
+
+ /* Consider all bus numbers in range for the host pci bridge. */
+ if (!pci_bus_is_root(bus) &&
+ !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
+ return NULL;
+ }
+
+ /* try child bus */
+ for (; bus; bus = sec) {
+ QLIST_FOREACH(sec, &bus->child, sibling) {
+ assert(!pci_bus_is_root(sec));
+ if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
+ return sec;
+ }
+ if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
+ break;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static const pci_class_desc *get_class_desc(int class)
+{
+ const pci_class_desc *desc;
+
+ desc = pci_class_descriptions;
+ while (desc->desc && class != desc->class) {
+ desc++;
+ }
+
+ return desc;
+}
+
+static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
+{
+ PciMemoryRegionList *head = NULL, *cur_item = NULL;
+ int i;
+
+ for (i = 0; i < PCI_NUM_REGIONS; i++) {
+ const PCIIORegion *r = &dev->io_regions[i];
+ PciMemoryRegionList *region;
+
+ if (!r->size) {
+ continue;
+ }
+
+ region = g_malloc0(sizeof(*region));
+ region->value = g_malloc0(sizeof(*region->value));
+
+ if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
+ region->value->type = g_strdup("io");
+ } else {
+ region->value->type = g_strdup("memory");
+ region->value->has_prefetch = true;
+ region->value->prefetch = !!(r->type &
PCI_BASE_ADDRESS_MEM_PREFETCH);
+ region->value->has_mem_type_64 = true;
+ region->value->mem_type_64 = !!(r->type &
PCI_BASE_ADDRESS_MEM_TYPE_64);
+ }
+
+ region->value->bar = i;
+ region->value->address = r->addr;
+ region->value->size = r->size;
+
+ /* XXX: waiting for the qapi to support GSList */
+ if (!cur_item) {
+ head = cur_item = region;
+ } else {
+ cur_item->next = region;
+ cur_item = region;
+ }
+ }
+
+ return head;
+}
+
+static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
+ int bus_num)
+{
+ PciBridgeInfo *info;
+
+ info = g_malloc0(sizeof(*info));
+
+ info->bus.number = dev->config[PCI_PRIMARY_BUS];
+ info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
+ info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
+
+ info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
+ info->bus.io_range->base = pci_bridge_get_base(dev,
+ PCI_BASE_ADDRESS_SPACE_IO);
+ info->bus.io_range->limit =
+ pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
+
+ info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
+ info->bus.memory_range->base =
+ pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
+ info->bus.memory_range->limit =
+ pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
+
+ info->bus.prefetchable_range =
+ g_malloc0(sizeof(*info->bus.prefetchable_range));
+ info->bus.prefetchable_range->base =
+ pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+ info->bus.prefetchable_range->limit =
+ pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+
+ if (dev->config[PCI_SECONDARY_BUS] != 0) {
+ PCIBus *child_bus = pci_find_bus_nr(bus,
dev->config[PCI_SECONDARY_BUS]);
+ if (child_bus) {
+ info->has_devices = true;
+ info->devices = qmp_query_pci_devices(child_bus,
+
dev->config[PCI_SECONDARY_BUS]);
+ }
+ }
+
+ return info;
+}
+
+static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
+ int bus_num)
+{
+ const pci_class_desc *desc;
+ PciDeviceInfo *info;
+ uint8_t type;
+ int class;
+
+ info = g_malloc0(sizeof(*info));
+ info->bus = bus_num;
+ info->slot = PCI_SLOT(dev->devfn);
+ info->function = PCI_FUNC(dev->devfn);
+
+ class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
+ info->class_info.q_class = class;
+ desc = get_class_desc(class);
+ if (desc->desc) {
+ info->class_info.has_desc = true;
+ info->class_info.desc = g_strdup(desc->desc);
+ }
+
+ info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
+ info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
+ info->regions = qmp_query_pci_regions(dev);
+ info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
+
+ if (dev->config[PCI_INTERRUPT_PIN] != 0) {
+ info->has_irq = true;
+ info->irq = dev->config[PCI_INTERRUPT_LINE];
+ }
+
+ type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
+ if (type == PCI_HEADER_TYPE_BRIDGE) {
+ info->has_pci_bridge = true;
+ info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
+ }
+
+ return info;
+}
+
+PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
+{
+ PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
+ PCIDevice *dev;
+ int devfn;
+
+ for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+ dev = bus->devices[devfn];
+ if (dev) {
+ info = g_malloc0(sizeof(*info));
+ info->value = qmp_query_pci_device(dev, bus, bus_num);
+
+ /* XXX: waiting for the qapi to support GSList */
+ if (!cur_item) {
+ head = cur_item = info;
+ } else {
+ cur_item->next = info;
+ cur_item = info;
+ }
+ }
+ }
+
+ return head;
+}
+
+
+static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
+{
+ PCIDevice *d = (PCIDevice *)dev;
+ const pci_class_desc *desc;
+ char ctxt[64];
+ PCIIORegion *r;
+ int i, class;
+
+ class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+ desc = pci_class_descriptions;
+ while (desc->desc && class != desc->class) {
+ desc++;
+ }
+ if (desc->desc) {
+ snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
+ } else {
+ snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
+ }
+
+ monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
+ "pci id %04x:%04x (sub %04x:%04x)\n",
+ indent, "", ctxt, pci_bus_num(d->bus),
+ PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
+ pci_get_word(d->config + PCI_VENDOR_ID),
+ pci_get_word(d->config + PCI_DEVICE_ID),
+ pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
+ pci_get_word(d->config + PCI_SUBSYSTEM_ID));
+ for (i = 0; i < PCI_NUM_REGIONS; i++) {
+ r = &d->io_regions[i];
+ if (!r->size) {
+ continue;
+ }
+ monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
+ " [0x%"FMT_PCIBUS"]\n",
+ indent, "",
+ i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
+ r->addr, r->addr + r->size - 1);
+ }
+}
+
+static char *pcibus_get_dev_path(DeviceState *dev)
+{
+ PCIDevice *d = container_of(dev, PCIDevice, qdev);
+ PCIDevice *t;
+ int slot_depth;
+ /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
+ * 00 is added here to make this format compatible with
+ * domain:Bus:Slot.Func for systems without nested PCI bridges.
+ * Slot.Function list specifies the slot and function numbers for all
+ * devices on the path from root to the specific device. */
+ const char *root_bus_path;
+ int root_bus_len;
+ char slot[] = ":SS.F";
+ int slot_len = sizeof slot - 1 /* For '\0' */;
+ int path_len;
+ char *path, *p;
+ int s;
+
+ root_bus_path = pci_root_bus_path(d);
+ root_bus_len = strlen(root_bus_path);
+
+ /* Calculate # of slots on path between device and root. */;
+ slot_depth = 0;
+ for (t = d; t; t = t->bus->parent_dev) {
+ ++slot_depth;
+ }
+
+ path_len = root_bus_len + slot_len * slot_depth;
+
+ /* Allocate memory, fill in the terminating null byte. */
+ path = g_malloc(path_len + 1 /* For '\0' */);
+ path[path_len] = '\0';
+
+ memcpy(path, root_bus_path, root_bus_len);
+
+ /* 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) {
+ p -= slot_len;
+ s = snprintf(slot, sizeof slot, ":%02x.%x",
+ PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
+ assert(s == slot_len);
+ memcpy(p, slot, slot_len);
+ }
+
+ return path;
+}
+
+static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
+{
+ PCIDevice *d = (PCIDevice *)dev;
+ const char *name = NULL;
+ const pci_class_desc *desc = pci_class_descriptions;
+ int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+
+ while (desc->desc &&
+ (class & ~desc->fw_ign_bits) !=
+ (desc->class & ~desc->fw_ign_bits)) {
+ desc++;
+ }
+
+ if (desc->desc) {
+ name = desc->fw_name;
+ }
+
+ if (name) {
+ pstrcpy(buf, len, name);
+ } else {
+ snprintf(buf, len, "pci%04x,%04x",
+ pci_get_word(d->config + PCI_VENDOR_ID),
+ pci_get_word(d->config + PCI_DEVICE_ID));
+ }
+
+ return buf;
+}
+
+static char *pcibus_get_fw_dev_path(DeviceState *dev)
+{
+ PCIDevice *d = (PCIDevice *)dev;
+ char path[50], name[33];
+ int off;
+
+ off = snprintf(path, sizeof(path), "address@hidden",
+ pci_dev_fw_name(dev, name, sizeof name),
+ PCI_SLOT(d->devfn));
+ if (PCI_FUNC(d->devfn)) {
+ snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
+ }
+ return g_strdup(path);
+}
+
+static const VMStateDescription vmstate_pcibus = {
+ .name = "PCIBUS",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32_EQUAL(nirq, PCIBus),
+ VMSTATE_VARRAY_INT32(irq_count, PCIBus,
+ nirq, 0, vmstate_info_int32,
+ int32_t),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void pci_bus_realize(BusState *qbus, Error **errp)
+{
+ PCIBus *bus = PCI_BUS(qbus);
+
+ vmstate_register(NULL, -1, &vmstate_pcibus, bus);
+}
+
+static void pci_bus_unrealize(BusState *qbus, Error **errp)
+{
+ PCIBus *bus = PCI_BUS(qbus);
+
+ vmstate_unregister(NULL, &vmstate_pcibus, bus);
+}
+
+/*
+ * Trigger pci bus reset under a given bus.
+ * Called via qbus_reset_all on RST# assert, after the devices
+ * have been reset qdev_reset_all-ed already.
+ */
+static void pcibus_reset(BusState *qbus)
+{
+ PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
+ if (bus->devices[i]) {
+ pci_do_device_reset(bus->devices[i]);
+ }
+ }
+
+ for (i = 0; i < bus->nirq; i++) {
+ assert(bus->irq_count[i] == 0);
+ }
+}
+
+static void pci_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->print_dev = pcibus_dev_print;
+ k->get_dev_path = pcibus_get_dev_path;
+ k->get_fw_dev_path = pcibus_get_fw_dev_path;
+ k->realize = pci_bus_realize;
+ k->unrealize = pci_bus_unrealize;
+ k->reset = pcibus_reset;
+}
+
+static const TypeInfo pci_bus_info = {
+ .name = TYPE_PCI_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(PCIBus),
+ .class_init = pci_bus_class_init,
+};
+
+static void pci_bus_register_types(void)
+{
+ type_register_static(&pci_bus_info);
+}
+
+type_init(pci_bus_register_types)
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 0bb3cdb..f5847bc 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -23,6 +23,7 @@
#include "hw/ppc/ppc.h"
#include "hw/ppc/ppc4xx.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
#include "exec/address-spaces.h"
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 12f44d2..80d3c43 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -30,6 +30,7 @@
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "net/net.h"
#include "sh7750_regs.h"
#include "hw/ide.h"
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index a2f6d9e..f02e998 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -24,6 +24,7 @@
#include "hw/sysbus.h"
#include "hw/sh4/sh.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
#include "qemu/bswap.h"
#include "exec/address-spaces.h"
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 97a83d3..966e9cd 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -335,8 +335,6 @@ typedef void (*pci_set_irq_fn)(void *opaque, int irq_num,
int level);
typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
-#define TYPE_PCI_BUS "PCI"
-#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
#define TYPE_PCIE_BUS "PCIE"
bool pci_bus_is_express(PCIBus *bus);
@@ -368,6 +366,7 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
void pci_device_set_intx_routing_notifier(PCIDevice *dev,
PCIINTxRoutingNotifier notifier);
void pci_device_reset(PCIDevice *dev);
+void pci_do_device_reset(PCIDevice *dev);
PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus,
const char *default_model,
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index fabaeee..ea427a3 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -1,6 +1,8 @@
#ifndef QEMU_PCI_BUS_H
#define QEMU_PCI_BUS_H
+#include "hw/pci/pci.h"
+
/*
* PCI Bus and Bridge datastructures.
*
@@ -8,6 +10,12 @@
* use accessor functions in pci.h, pci_bridge.h
*/
+PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
+PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
+
+#define TYPE_PCI_BUS "PCI"
+#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
+
struct PCIBus {
BusState qbus;
PCIIOMMUFunc iommu_fn;
--
2.1.0
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 00/17] implement multiple primary busses for pc machines, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 02/17] hw/acpi: add support for multiple root busses, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 01/17] acpi: added needed acpi constructs, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 03/17] hw/apci: add _PRT method for extra root busses, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 04/17] hw/acpi: add _CRS method for extra root busses, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 05/17] hw/acpi: remove from root bus 0 the crs resources used by other busses., Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 07/17] hw/pci: made pci_bus_is_root a PCIBusClass method, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 09/17] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 10/17] hw/pci: removed 'rootbus nr is 0' assumption from qmp_pci_query, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 08/17] hw/pci: made pci_bus_num a PCIBusClass method, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 06/17] hw/pci: move pci bus related code to separate files,
Marcel Apfelbaum <=
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 11/17] hw/pci: implement iteration over multiple host bridges, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 12/17] hw/pci: introduce PCI Expander Bridge (PXB), Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 13/17] hw/pci: inform bios if the system has more than one pci bridge, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 15/17] hw/pxb: add map_irq func, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 14/17] hw/pci: piix - suport multiple host bridges, Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 16/17] hw/pci-bridge: hack - disable shpc bar (will be removed from the series), Marcel Apfelbaum, 2015/01/22
- [Qemu-ppc] [Qemu-devel] [PATCH RFC 17/17] hw/acpi: hack - generate dummy region ranges for first acpi-build (will be removed from the series), Marcel Apfelbaum, 2015/01/22