]> Git Repo - qemu.git/blobdiff - hw/pci.c
vga: remove unused vga_common_save/load
[qemu.git] / hw / pci.c
index 3182116563c5dc31963191712ee262d67db500a5..ef134f7e5c506074256ac82df2b685f34af3ed55 100644 (file)
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -40,10 +40,9 @@ struct PCIBus {
     int devfn_min;
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
+    pci_hotplug_fn hotplug;
     uint32_t config_reg; /* XXX: suppress */
-    /* low level pic */
-    SetIRQFunc *low_set_irq;
-    qemu_irq *irq_opaque;
+    void *irq_opaque;
     PCIDevice *devices[256];
     PCIDevice *parent_dev;
     PCIBus *next;
@@ -59,6 +58,10 @@ static struct BusInfo pci_bus_info = {
     .name       = "PCI",
     .size       = sizeof(PCIBus),
     .print_dev  = pcibus_dev_print,
+    .props      = (Property[]) {
+        DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
+        DEFINE_PROP_END_OF_LIST()
+    }
 };
 
 static void pci_update_mappings(PCIDevice *d);
@@ -69,83 +72,116 @@ static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
 static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
 static PCIBus *first_bus;
 
-static void pcibus_save(QEMUFile *f, void *opaque)
-{
-    PCIBus *bus = (PCIBus *)opaque;
-    int i;
+static const VMStateDescription vmstate_pcibus = {
+    .name = "PCIBUS",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 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()
+    }
+};
 
-    qemu_put_be32(f, bus->nirq);
-    for (i = 0; i < bus->nirq; i++)
-        qemu_put_be32(f, bus->irq_count[i]);
+static inline int pci_bar(int reg)
+{
+    return reg == PCI_ROM_SLOT ? PCI_ROM_ADDRESS : PCI_BASE_ADDRESS_0 + reg * 4;
 }
 
-static int  pcibus_load(QEMUFile *f, void *opaque, int version_id)
+static void pci_device_reset(PCIDevice *dev)
 {
-    PCIBus *bus = (PCIBus *)opaque;
-    int i, nirq;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    nirq = qemu_get_be32(f);
-    if (bus->nirq != nirq) {
-        fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n",
-                nirq, bus->nirq);
-        return -EINVAL;
+    int r;
+
+    memset(dev->irq_state, 0, sizeof dev->irq_state);
+    dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+                                  PCI_COMMAND_MASTER);
+    dev->config[PCI_CACHE_LINE_SIZE] = 0x0;
+    dev->config[PCI_INTERRUPT_LINE] = 0x0;
+    for (r = 0; r < PCI_NUM_REGIONS; ++r) {
+        if (!dev->io_regions[r].size) {
+            continue;
+        }
+        pci_set_long(dev->config + pci_bar(r), dev->io_regions[r].type);
     }
-
-    for (i = 0; i < nirq; i++)
-        bus->irq_count[i] = qemu_get_be32(f);
-
-    return 0;
+    pci_update_mappings(dev);
 }
 
 static void pci_bus_reset(void *opaque)
 {
-    PCIBus *bus = (PCIBus *)opaque;
+    PCIBus *bus = opaque;
     int i;
 
     for (i = 0; i < bus->nirq; i++) {
         bus->irq_count[i] = 0;
     }
-    for (i = 0; i < 256; i++) {
-        if (bus->devices[i])
-            memset(bus->devices[i]->irq_state, 0,
-                   sizeof(bus->devices[i]->irq_state));
+    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
+        if (bus->devices[i]) {
+            pci_device_reset(bus->devices[i]);
+        }
     }
 }
 
-PCIBus *pci_register_bus(DeviceState *parent, const char *name,
-                         pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         qemu_irq *pic, int devfn_min, int nirq)
+void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+                         const char *name, int devfn_min)
 {
-    PCIBus *bus;
     static int nbus = 0;
 
-    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;
+    qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
     bus->devfn_min = devfn_min;
-    bus->nirq = nirq;
-    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
     bus->next = first_bus;
     first_bus = bus;
-    register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
+    vmstate_register(nbus++, &vmstate_pcibus, bus);
     qemu_register_reset(pci_bus_reset, bus);
+}
+
+PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
+{
+    PCIBus *bus;
+
+    bus = qemu_mallocz(sizeof(*bus));
+    bus->qbus.qdev_allocated = 1;
+    pci_bus_new_inplace(bus, parent, name, devfn_min);
     return bus;
 }
 
-static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
+void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+                  void *irq_opaque, int nirq)
+{
+    bus->set_irq = set_irq;
+    bus->map_irq = map_irq;
+    bus->irq_opaque = irq_opaque;
+    bus->nirq = nirq;
+    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
+}
+
+void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug)
+{
+    bus->qbus.allow_hotplug = 1;
+    bus->hotplug = hotplug;
+}
+
+PCIBus *pci_register_bus(DeviceState *parent, const char *name,
+                         pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+                         void *irq_opaque, int devfn_min, int nirq)
 {
     PCIBus *bus;
 
-    bus = qemu_mallocz(sizeof(PCIBus));
+    bus = pci_bus_new(parent, name, devfn_min);
+    pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
+    return bus;
+}
+
+static void pci_register_secondary_bus(PCIBus *bus,
+                                       PCIDevice *dev,
+                                       pci_map_irq_fn map_irq,
+                                       const char *name)
+{
+    qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name);
     bus->map_irq = map_irq;
     bus->parent_dev = dev;
     bus->next = dev->bus->next;
     dev->bus->next = bus;
-    return bus;
 }
 
 int pci_bus_num(PCIBus *s)
@@ -153,25 +189,13 @@ int pci_bus_num(PCIBus *s)
     return s->bus_num;
 }
 
-void pci_device_save(PCIDevice *s, QEMUFile *f)
-{
-    int i;
-
-    qemu_put_be32(f, 2); /* PCI device version */
-    qemu_put_buffer(f, s->config, 256);
-    for (i = 0; i < 4; i++)
-        qemu_put_be32(f, s->irq_state[i]);
-}
-
-int pci_device_load(PCIDevice *s, QEMUFile *f)
+static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
 {
+    PCIDevice *s = container_of(pv, PCIDevice, config);
     uint8_t config[PCI_CONFIG_SPACE_SIZE];
-    uint32_t version_id;
     int i;
 
-    version_id = qemu_get_be32(f);
-    if (version_id > 2)
-        return -EINVAL;
+    assert(size == sizeof config);
     qemu_get_buffer(f, config, sizeof config);
     for (i = 0; i < sizeof config; ++i)
         if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i])
@@ -180,12 +204,46 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
 
     pci_update_mappings(s);
 
-    if (version_id >= 2)
-        for (i = 0; i < 4; i ++)
-            s->irq_state[i] = qemu_get_be32(f);
     return 0;
 }
 
+/* just put buffer */
+static void put_pci_config_device(QEMUFile *f, void *pv, size_t size)
+{
+    const uint8_t *v = pv;
+    qemu_put_buffer(f, v, size);
+}
+
+static VMStateInfo vmstate_info_pci_config = {
+    .name = "pci config",
+    .get  = get_pci_config_device,
+    .put  = put_pci_config_device,
+};
+
+const VMStateDescription vmstate_pci_device = {
+    .name = "PCIDevice",
+    .version_id = 2,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_INT32_LE(version_id, PCIDevice),
+        VMSTATE_SINGLE(config, PCIDevice, 0, vmstate_info_pci_config,
+                       typeof_field(PCIDevice,config)),
+        VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, 4, 2),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+void pci_device_save(PCIDevice *s, QEMUFile *f)
+{
+    vmstate_save_state(f, &vmstate_pci_device, s);
+}
+
+int pci_device_load(PCIDevice *s, QEMUFile *f)
+{
+    return vmstate_load_state(f, &vmstate_pci_device, s, s->version_id);
+}
+
 static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
 {
     uint16_t *id;
@@ -259,7 +317,7 @@ int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
     return 0;
 }
 
-static PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
+PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
 {
     int dom, bus;
     unsigned slot;
@@ -332,6 +390,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     pci_dev->config_write = config_write;
     bus->devices[devfn] = pci_dev;
     pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
+    pci_dev->version_id = 2; /* Current pci device vmstate version */
     return pci_dev;
 }
 
@@ -371,12 +430,14 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
     }
 }
 
-int pci_unregister_device(PCIDevice *pci_dev)
+static int pci_unregister_device(DeviceState *dev)
 {
+    PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
+    PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->info);
     int ret = 0;
 
-    if (pci_dev->unregister)
-        ret = pci_dev->unregister(pci_dev);
+    if (info->exit)
+        ret = info->exit(pci_dev);
     if (ret)
         return ret;
 
@@ -384,7 +445,6 @@ int pci_unregister_device(PCIDevice *pci_dev)
 
     qemu_free_irqs(pci_dev->irq);
     pci_dev->bus->devices[pci_dev->devfn] = NULL;
-    qdev_free(&pci_dev->qdev);
     return 0;
 }
 
@@ -412,12 +472,10 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     r->map_func = map_func;
 
     wmask = ~(size - 1);
+    addr = pci_bar(region_num);
     if (region_num == PCI_ROM_SLOT) {
-        addr = 0x30;
         /* ROM enable bit is writeable */
-        wmask |= 1;
-    } else {
-        addr = 0x10 + region_num * 4;
+        wmask |= PCI_ROM_ADDRESS_ENABLE;
     }
     *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
     *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask);
@@ -428,21 +486,15 @@ static void pci_update_mappings(PCIDevice *d)
 {
     PCIIORegion *r;
     int cmd, i;
-    uint32_t last_addr, new_addr, config_ofs;
+    uint32_t last_addr, new_addr;
 
     cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
     for(i = 0; i < PCI_NUM_REGIONS; i++) {
         r = &d->io_regions[i];
-        if (i == PCI_ROM_SLOT) {
-            config_ofs = 0x30;
-        } else {
-            config_ofs = 0x10 + i * 4;
-        }
         if (r->size != 0) {
             if (r->type & PCI_ADDRESS_SPACE_IO) {
                 if (cmd & PCI_COMMAND_IO) {
-                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
-                                                         config_ofs));
+                    new_addr = pci_get_long(d->config + pci_bar(i));
                     new_addr = new_addr & ~(r->size - 1);
                     last_addr = new_addr + r->size - 1;
                     /* NOTE: we have only 64K ioports on PC */
@@ -455,10 +507,9 @@ static void pci_update_mappings(PCIDevice *d)
                 }
             } else {
                 if (cmd & PCI_COMMAND_MEMORY) {
-                    new_addr = le32_to_cpu(*(uint32_t *)(d->config +
-                                                         config_ofs));
+                    new_addr = pci_get_long(d->config + pci_bar(i));
                     /* the ROM slot has a specific enable bit */
-                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
+                    if (i == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE))
                         goto no_mem_map;
                     new_addr = new_addr & ~(r->size - 1);
                     last_addr = new_addr + r->size - 1;
@@ -482,7 +533,7 @@ static void pci_update_mappings(PCIDevice *d)
                         int class;
                         /* NOTE: specific hack for IDE in PC case:
                            only one byte must be mapped. */
-                        class = d->config[0x0a] | (d->config[0x0b] << 8);
+                        class = pci_get_word(d->config + PCI_CLASS_DEVICE);
                         if (class == 0x0101 && r->size == 4) {
                             isa_unassign_ioport(r->addr + 2, 1);
                         } else {
@@ -618,7 +669,7 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
 /* 0 <= irq_num <= 3. level must be 0 or 1 */
 static void pci_set_irq(void *opaque, int irq_num, int level)
 {
-    PCIDevice *pci_dev = (PCIDevice *)opaque;
+    PCIDevice *pci_dev = opaque;
     PCIBus *bus;
     int change;
 
@@ -729,6 +780,7 @@ static void pci_info_device(PCIDevice *d)
             }
         }
     }
+    monitor_printf(mon, "      id \"%s\"\n", d->qdev.id ? d->qdev.id : "");
     if (class == 0x0604 && d->config[0x19] != 0) {
         pci_for_each_device(d->config[0x19], pci_info_device);
     }
@@ -756,24 +808,6 @@ void pci_info(Monitor *mon)
     pci_for_each_device(0, pci_info_device);
 }
 
-PCIDevice *pci_create(const char *name, const char *devaddr)
-{
-    PCIBus *bus;
-    int devfn;
-    DeviceState *dev;
-
-    bus = pci_get_bus_devfn(&devfn, devaddr);
-    if (!bus) {
-        fprintf(stderr, "Invalid PCI device address %s for device %s\n",
-                devaddr, name);
-        exit(1);
-    }
-
-    dev = qdev_create(&bus->qbus, name);
-    qdev_set_prop_int(dev, "devfn", devfn);
-    return (PCIDevice *)dev;
-}
-
 static const char * const pci_nic_models[] = {
     "ne2k_pci",
     "i82551",
@@ -799,33 +833,57 @@ static const char * const pci_nic_names[] = {
 };
 
 /* Initialize a PCI NIC.  */
+/* FIXME callers should check for failure, but don't */
 PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
                         const char *default_devaddr)
 {
     const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
+    PCIBus *bus;
+    int devfn;
     PCIDevice *pci_dev;
     DeviceState *dev;
     int i;
 
-    qemu_check_nic_model_list(nd, pci_nic_models, default_model);
+    i = qemu_find_nic_model(nd, pci_nic_models, default_model);
+    if (i < 0)
+        return NULL;
 
-    for (i = 0; pci_nic_models[i]; i++) {
-        if (strcmp(nd->model, pci_nic_models[i]) == 0) {
-            pci_dev = pci_create(pci_nic_names[i], devaddr);
-            dev = &pci_dev->qdev;
-            qdev_set_netdev(dev, nd);
-            qdev_init(dev);
-            nd->private = dev;
-            return pci_dev;
-        }
+    bus = pci_get_bus_devfn(&devfn, devaddr);
+    if (!bus) {
+        qemu_error("Invalid PCI device address %s for device %s\n",
+                   devaddr, pci_nic_names[i]);
+        return NULL;
     }
 
-    return NULL;
+    pci_dev = pci_create(bus, devfn, pci_nic_names[i]);
+    dev = &pci_dev->qdev;
+    if (nd->name)
+        dev->id = qemu_strdup(nd->name);
+    qdev_set_nic_properties(dev, nd);
+    if (qdev_init(dev) < 0)
+        return NULL;
+    return pci_dev;
+}
+
+PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
+                               const char *default_devaddr)
+{
+    PCIDevice *res;
+
+    if (qemu_show_nic_models(nd->model, pci_nic_models))
+        exit(0);
+
+    res = pci_nic_init(nd, default_model, default_devaddr);
+    if (!res)
+        exit(1);
+    return res;
 }
 
 typedef struct {
     PCIDevice dev;
-    PCIBus *bus;
+    PCIBus bus;
+    uint32_t vid;
+    uint32_t did;
 } PCIBridge;
 
 static void pci_bridge_write_config(PCIDevice *d,
@@ -834,7 +892,7 @@ static void pci_bridge_write_config(PCIDevice *d,
     PCIBridge *s = (PCIBridge *)d;
 
     pci_default_write_config(d, address, val, len);
-    s->bus->bus_num = d->config[PCI_SECONDARY_BUS];
+    s->bus.bus_num = d->config[PCI_SECONDARY_BUS];
 }
 
 PCIBus *pci_find_bus(int bus_num)
@@ -857,15 +915,12 @@ PCIDevice *pci_find_device(int bus_num, int slot, int function)
     return bus->devices[PCI_DEVFN(slot, function)];
 }
 
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
-                        pci_map_irq_fn map_irq, const char *name)
+static int pci_bridge_initfn(PCIDevice *dev)
 {
-    PCIBridge *s;
-    s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
-                                         devfn, NULL, pci_bridge_write_config);
+    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
 
-    pci_config_set_vendor_id(s->dev.config, vid);
-    pci_config_set_device_id(s->dev.config, did);
+    pci_config_set_vendor_id(s->dev.config, s->vid);
+    pci_config_set_device_id(s->dev.config, s->did);
 
     s->dev.config[0x04] = 0x06; // command = bus master, pci mem
     s->dev.config[0x05] = 0x00;
@@ -878,29 +933,58 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
     s->dev.config[PCI_HEADER_TYPE] =
         PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
     s->dev.config[0x1E] = 0xa0; // secondary status
+    return 0;
+}
+
+PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
+                        pci_map_irq_fn map_irq, const char *name)
+{
+    PCIDevice *dev;
+    PCIBridge *s;
 
-    s->bus = pci_register_secondary_bus(&s->dev, map_irq);
-    return s->bus;
+    dev = pci_create(bus, devfn, "pci-bridge");
+    qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
+    qdev_prop_set_uint32(&dev->qdev, "deviceid", did);
+    qdev_init_nofail(&dev->qdev);
+
+    s = DO_UPCAST(PCIBridge, dev, dev);
+    pci_register_secondary_bus(&s->bus, &s->dev, map_irq, name);
+    return &s->bus;
 }
 
-static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
     PCIDevice *pci_dev = (PCIDevice *)qdev;
     PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
     PCIBus *bus;
-    int devfn;
+    int devfn, rc;
 
     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
-    devfn = qdev_get_prop_int(qdev, "devfn", -1);
+    devfn = pci_dev->devfn;
     pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
                                      info->config_read, info->config_write);
     assert(pci_dev);
-    info->init(pci_dev);
+    rc = info->init(pci_dev);
+    if (rc != 0)
+        return rc;
+    if (qdev->hotplugged)
+        bus->hotplug(pci_dev, 1);
+    return 0;
+}
+
+static int pci_unplug_device(DeviceState *qdev)
+{
+    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
+
+    dev->bus->hotplug(dev, 0);
+    return 0;
 }
 
 void pci_qdev_register(PCIDeviceInfo *info)
 {
     info->qdev.init = pci_qdev_init;
+    info->qdev.unplug = pci_unplug_device;
+    info->qdev.exit = pci_unregister_device;
     info->qdev.bus_info = &pci_bus_info;
     qdev_register(&info->qdev);
 }
@@ -913,15 +997,20 @@ void pci_qdev_register_many(PCIDeviceInfo *info)
     }
 }
 
-PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
+PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name)
 {
     DeviceState *dev;
 
     dev = qdev_create(&bus->qbus, name);
-    qdev_set_prop_int(dev, "devfn", devfn);
-    qdev_init(dev);
+    qdev_prop_set_uint32(dev, "addr", devfn);
+    return DO_UPCAST(PCIDevice, qdev, dev);
+}
 
-    return (PCIDevice *)dev;
+PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
+{
+    PCIDevice *dev = pci_create(bus, devfn, name);
+    qdev_init_nofail(&dev->qdev);
+    return dev;
 }
 
 static int pci_find_space(PCIDevice *pdev, uint8_t size)
@@ -1036,3 +1125,22 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
                        r->addr, r->addr + r->size - 1);
     }
 }
+
+static PCIDeviceInfo bridge_info = {
+    .qdev.name    = "pci-bridge",
+    .qdev.size    = sizeof(PCIBridge),
+    .init         = pci_bridge_initfn,
+    .config_write = pci_bridge_write_config,
+    .qdev.props   = (Property[]) {
+        DEFINE_PROP_HEX32("vendorid", PCIBridge, vid, 0),
+        DEFINE_PROP_HEX32("deviceid", PCIBridge, did, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void pci_register_devices(void)
+{
+    pci_qdev_register(&bridge_info);
+}
+
+device_init(pci_register_devices)
This page took 0.041771 seconds and 4 git commands to generate.