summary refs log tree commit diff stats
path: root/hw/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/pci.c')
-rw-r--r--hw/pci.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/hw/pci.c b/hw/pci.c
index e82965ff12..f4c749483e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -45,7 +45,15 @@ struct PCIBus {
     /* The bus IRQ state is the logical OR of the connected devices.
        Keep a count of the number of devices with raised IRQs.  */
     int nirq;
-    int irq_count[];
+    int *irq_count;
+};
+
+static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+
+static struct BusInfo pci_bus_info = {
+    .name       = "PCI",
+    .size       = sizeof(PCIBus),
+    .print_dev  = pcibus_dev_print,
 };
 
 static void pci_update_mappings(PCIDevice *d);
@@ -109,14 +117,13 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
     PCIBus *bus;
     static int nbus = 0;
 
-    bus = FROM_QBUS(PCIBus, qbus_create(BUS_TYPE_PCI,
-                                        sizeof(PCIBus) + (nirq * sizeof(int)),
-                                        parent, name));
+    bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, parent, name));
     bus->set_irq = set_irq;
     bus->map_irq = map_irq;
     bus->irq_opaque = pic;
     bus->devfn_min = devfn_min;
     bus->nirq = nirq;
+    bus->irq_count = qemu_malloc(nirq * sizeof(bus->irq_count[0]));
     bus->next = first_bus;
     first_bus = bus;
     register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
@@ -892,7 +899,7 @@ static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 void pci_qdev_register(PCIDeviceInfo *info)
 {
     info->qdev.init = pci_qdev_init;
-    info->qdev.bus_type = BUS_TYPE_PCI;
+    info->qdev.bus_info = &pci_bus_info;
     qdev_register(&info->qdev);
 }
 
@@ -991,3 +998,39 @@ 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 = le16_to_cpu(*((uint16_t *)(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,
+                   d->bus->bus_num, d->devfn >> 3, d->devfn & 7,
+                   le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
+                   le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))),
+                   le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_VENDOR_ID))),
+                   le16_to_cpu(*((uint16_t *)(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%x [0x%x]\n", indent, "",
+                       i, r->type & PCI_ADDRESS_SPACE_IO ? "i/o" : "mem",
+                       r->addr, r->addr + r->size - 1);
+    }
+}