All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library
@ 2010-07-13  4:01 Isaku Yamahata
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 1/4] pci/bridge: split out pci bridge code into pci_bridge.c from pci.c Isaku Yamahata
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-07-13  4:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, yamahata, mst

Changes v2 -> v1:
- dropped first patch as it is merdged.
- rebased to mst's pci branch.
- eliminated pci_brdige_qdev_register(), pci_brdige_create(),
  pci_brdige_create_simple() by exporting PCIBus and PCIBridge.

Patch description:
Now pci.c has grown. So split bridge related code into dedicated file
for further extension to pci bridge. Further clean up and pcie port emulator. 
This make patch conflict less possible in future.

Clean up of pci host bus ans piix pci as discussed with v1
will be addressed after this patch set is accepted.

changes v1 -> v2:
- introduce pci_internals.h to accomodate pci internal strcutures to
  share between pci.c and pci_bridge.c
- don't make PCIBridge::bus pointer as suggested by
  Michael S. Tsirkin <mst@redhat.com>
- rename PCIBridge::bus -> PCIBridge::sec_bus
- eliminate pci_reguster_secondary_bus()/pci_unregister_secondary_bus()
- document pci bridge library functions.
- introduced pci bridge library.

Isaku Yamahata (4):
  pci/bridge: split out pci bridge code into pci_bridge.c from pci.c
  pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus.
  pci_bridge: clean up: remove pci_{register,
    unregister}_secondary_bus()
  pci_bridge: introduce pci bridge library.

 Makefile.objs      |    2 +-
 hw/apb_pci.c       |   56 +++++++++++---
 hw/dec_pci.c       |   46 +++++++++--
 hw/pci.c           |  177 +-------------------------------------------
 hw/pci.h           |    5 +-
 hw/pci_bridge.c    |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/pci_bridge.h    |   62 +++++++++++++++
 hw/pci_internals.h |   17 +++-
 qemu-common.h      |    1 +
 9 files changed, 369 insertions(+), 207 deletions(-)
 create mode 100644 hw/pci_bridge.c
 create mode 100644 hw/pci_bridge.h

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 1/4] pci/bridge: split out pci bridge code into pci_bridge.c from pci.c
  2010-07-13  4:01 [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
@ 2010-07-13  4:01 ` Isaku Yamahata
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 2/4] pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus Isaku Yamahata
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-07-13  4:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, yamahata, mst

Move pci bridge related code into pci_bridge.c from pci.c
for further enhancement. pci.c is big enough now, so split it out.
No code change but exporting some accesser functions.

In fact, few pci bridge functions stays in pci.c.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 Makefile.objs   |    2 +-
 hw/apb_pci.c    |    1 +
 hw/dec_pci.c    |    1 +
 hw/pci.c        |  177 +----------------------------------------------
 hw/pci.h        |    5 +-
 hw/pci_bridge.c |  208 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/pci_bridge.h |   48 +++++++++++++
 7 files changed, 262 insertions(+), 180 deletions(-)
 create mode 100644 hw/pci_bridge.c
 create mode 100644 hw/pci_bridge.h

diff --git a/Makefile.objs b/Makefile.objs
index 67f1b21..594894b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -139,7 +139,7 @@ user-obj-y += cutils.o cache-utils.o
 hw-obj-y =
 hw-obj-y += vl.o loader.o
 hw-obj-y += virtio.o virtio-console.o
-hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o
+hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o pci_bridge.o
 hw-obj-y += watchdog.o
 hw-obj-$(CONFIG_ISA_MMIO) += isa_mmio.o
 hw-obj-$(CONFIG_ECC) += ecc.o
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 0ecac55..88ee4a9 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -29,6 +29,7 @@
 #include "sysbus.h"
 #include "pci.h"
 #include "pci_host.h"
+#include "pci_bridge.h"
 #include "rwhandler.h"
 #include "apb_pci.h"
 #include "sysemu.h"
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index ee49d5a..f7a9cdc 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -27,6 +27,7 @@
 #include "sysbus.h"
 #include "pci.h"
 #include "pci_host.h"
+#include "pci_bridge.h"
 
 /* debug DEC */
 //#define DEBUG_DEC
diff --git a/hw/pci.c b/hw/pci.c
index 9c83d74..2dc1577 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -23,6 +23,7 @@
  */
 #include "hw.h"
 #include "pci.h"
+#include "pci_bridge.h"
 #include "pci_internals.h"
 #include "monitor.h"
 #include "net.h"
@@ -272,26 +273,6 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
     return bus;
 }
 
-static void pci_register_secondary_bus(PCIBus *parent,
-                                       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;
-
-    QLIST_INIT(&bus->child);
-    QLIST_INSERT_HEAD(&parent->child, bus, sibling);
-}
-
-static void pci_unregister_secondary_bus(PCIBus *bus)
-{
-    assert(QLIST_EMPTY(&bus->child));
-    QLIST_REMOVE(bus, sibling);
-}
-
 int pci_bus_num(PCIBus *s)
 {
     if (!s->parent_dev)
@@ -799,75 +780,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     }
 }
 
-static uint32_t pci_config_get_io_base(PCIDevice *d,
-                                       uint32_t base, uint32_t base_upper16)
-{
-    uint32_t val;
-
-    val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
-    if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
-        val |= (uint32_t)pci_get_word(d->config + base_upper16) << 16;
-    }
-    return val;
-}
-
-static pcibus_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
-{
-    return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
-        << 16;
-}
-
-static pcibus_t pci_config_get_pref_base(PCIDevice *d,
-                                         uint32_t base, uint32_t upper)
-{
-    pcibus_t tmp;
-    pcibus_t val;
-
-    tmp = (pcibus_t)pci_get_word(d->config + base);
-    val = (tmp & PCI_PREF_RANGE_MASK) << 16;
-    if (tmp & PCI_PREF_RANGE_TYPE_64) {
-        val |= (pcibus_t)pci_get_long(d->config + upper) << 32;
-    }
-    return val;
-}
-
-static pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type)
-{
-    pcibus_t base;
-    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
-        base = pci_config_get_io_base(bridge,
-                                      PCI_IO_BASE, PCI_IO_BASE_UPPER16);
-    } else {
-        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-            base = pci_config_get_pref_base(
-                bridge, PCI_PREF_MEMORY_BASE, PCI_PREF_BASE_UPPER32);
-        } else {
-            base = pci_config_get_memory_base(bridge, PCI_MEMORY_BASE);
-        }
-    }
-
-    return base;
-}
-
-static pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type)
-{
-    pcibus_t limit;
-    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
-        limit = pci_config_get_io_base(bridge,
-                                      PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16);
-        limit |= 0xfff;         /* PCI bridge spec 3.2.5.6. */
-    } else {
-        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-            limit = pci_config_get_pref_base(
-                bridge, PCI_PREF_MEMORY_LIMIT, PCI_PREF_LIMIT_UPPER32);
-        } else {
-            limit = pci_config_get_memory_base(bridge, PCI_MEMORY_LIMIT);
-        }
-        limit |= 0xfffff;       /* PCI bridge spec 3.2.5.{1, 8}. */
-    }
-    return limit;
-}
-
 static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
                               uint8_t type)
 {
@@ -1518,7 +1430,7 @@ static void pci_bridge_update_mappings_fn(PCIBus *b, PCIDevice *d)
     pci_update_mappings(d);
 }
 
-static void pci_bridge_update_mappings(PCIBus *b)
+void pci_bridge_update_mappings(PCIBus *b)
 {
     PCIBus *child;
 
@@ -1529,23 +1441,6 @@ static void pci_bridge_update_mappings(PCIBus *b)
     }
 }
 
-static void pci_bridge_write_config(PCIDevice *d,
-                             uint32_t address, uint32_t val, int len)
-{
-    pci_default_write_config(d, address, val, len);
-
-    if (/* io base/limit */
-        ranges_overlap(address, len, PCI_IO_BASE, 2) ||
-
-        /* memory base/limit, prefetchable base/limit and
-           io base/limit upper 16 */
-        ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
-        PCIBridge *s = container_of(d, PCIBridge, dev);
-        PCIBus *secondary_bus = &s->bus;
-        pci_bridge_update_mappings(secondary_bus);
-    }
-}
-
 PCIBus *pci_find_bus(PCIBus *bus, int bus_num)
 {
     PCIBus *sec;
@@ -1589,54 +1484,6 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function)
     return bus->devices[PCI_DEVFN(slot, function)];
 }
 
-static int pci_bridge_initfn(PCIDevice *dev)
-{
-    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
-
-    pci_config_set_vendor_id(s->dev.config, s->vid);
-    pci_config_set_device_id(s->dev.config, s->did);
-
-    pci_set_word(dev->config + PCI_STATUS,
-                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
-    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);
-    dev->config[PCI_HEADER_TYPE] =
-        (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
-        PCI_HEADER_TYPE_BRIDGE;
-    pci_set_word(dev->config + PCI_SEC_STATUS,
-                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
-    return 0;
-}
-
-static int pci_bridge_exitfn(PCIDevice *pci_dev)
-{
-    PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
-    PCIBus *bus = &s->bus;
-    pci_unregister_secondary_bus(bus);
-    return 0;
-}
-
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
-                        uint16_t vid, uint16_t did,
-                        pci_map_irq_fn map_irq, const char *name)
-{
-    PCIDevice *dev;
-    PCIBridge *s;
-
-    dev = pci_create_multifunction(bus, devfn, multifunction, "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(bus, &s->bus, &s->dev, map_irq, name);
-    return &s->bus;
-}
-
-PCIDevice *pci_bridge_get_device(PCIBus *bus)
-{
-    return bus->parent_dev;
-}
-
 static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
     PCIDevice *pci_dev = (PCIDevice *)qdev;
@@ -1942,23 +1789,3 @@ static char *pcibus_get_dev_path(DeviceState *dev)
     return strdup(path);
 }
 
-static PCIDeviceInfo bridge_info = {
-    .qdev.name    = "pci-bridge",
-    .qdev.size    = sizeof(PCIBridge),
-    .init         = pci_bridge_initfn,
-    .exit         = pci_bridge_exitfn,
-    .config_write = pci_bridge_write_config,
-    .is_bridge    = 1,
-    .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)
diff --git a/hw/pci.h b/hw/pci.h
index 1eab7e7..c551f96 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -233,10 +233,7 @@ int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
 
 void do_pci_info_print(Monitor *mon, const QObject *data);
 void do_pci_info(Monitor *mon, QObject **ret_data);
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
-                        uint16_t vid, uint16_t did,
-                        pci_map_irq_fn map_irq, const char *name);
-PCIDevice *pci_bridge_get_device(PCIBus *bus);
+void pci_bridge_update_mappings(PCIBus *b);
 
 static inline void
 pci_set_byte(uint8_t *config, uint8_t val)
diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
new file mode 100644
index 0000000..7f27870
--- /dev/null
+++ b/hw/pci_bridge.c
@@ -0,0 +1,208 @@
+/*
+ * QEMU PCI bus manager
+ *
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to dea
+
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
+
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*
+ * split out from pci.c
+ * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ */
+
+#include "pci_bridge.h"
+#include "pci_internals.h"
+
+PCIDevice *pci_bridge_get_device(PCIBus *bus)
+{
+    return bus->parent_dev;
+}
+
+static void pci_register_secondary_bus(PCIBus *parent,
+                                       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;
+
+    QLIST_INIT(&bus->child);
+    QLIST_INSERT_HEAD(&parent->child, bus, sibling);
+}
+
+static void pci_unregister_secondary_bus(PCIBus *bus)
+{
+    assert(QLIST_EMPTY(&bus->child));
+    QLIST_REMOVE(bus, sibling);
+}
+
+static uint32_t pci_config_get_io_base(PCIDevice *d,
+                                       uint32_t base, uint32_t base_upper16)
+{
+    uint32_t val;
+
+    val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
+    if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
+        val |= (uint32_t)pci_get_word(d->config + base_upper16) << 16;
+    }
+    return val;
+}
+
+static pcibus_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
+{
+    return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
+        << 16;
+}
+
+static pcibus_t pci_config_get_pref_base(PCIDevice *d,
+                                         uint32_t base, uint32_t upper)
+{
+    pcibus_t tmp;
+    pcibus_t val;
+
+    tmp = (pcibus_t)pci_get_word(d->config + base);
+    val = (tmp & PCI_PREF_RANGE_MASK) << 16;
+    if (tmp & PCI_PREF_RANGE_TYPE_64) {
+        val |= (pcibus_t)pci_get_long(d->config + upper) << 32;
+    }
+    return val;
+}
+
+pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type)
+{
+    pcibus_t base;
+    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
+        base = pci_config_get_io_base(bridge,
+                                      PCI_IO_BASE, PCI_IO_BASE_UPPER16);
+    } else {
+        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+            base = pci_config_get_pref_base(
+                bridge, PCI_PREF_MEMORY_BASE, PCI_PREF_BASE_UPPER32);
+        } else {
+            base = pci_config_get_memory_base(bridge, PCI_MEMORY_BASE);
+        }
+    }
+
+    return base;
+}
+
+pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type)
+{
+    pcibus_t limit;
+    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
+        limit = pci_config_get_io_base(bridge,
+                                      PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16);
+        limit |= 0xfff;         /* PCI bridge spec 3.2.5.6. */
+    } else {
+        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+            limit = pci_config_get_pref_base(
+                bridge, PCI_PREF_MEMORY_LIMIT, PCI_PREF_LIMIT_UPPER32);
+        } else {
+            limit = pci_config_get_memory_base(bridge, PCI_MEMORY_LIMIT);
+        }
+        limit |= 0xfffff;       /* PCI bridge spec 3.2.5.{1, 8}. */
+    }
+    return limit;
+}
+
+static void pci_bridge_write_config(PCIDevice *d,
+                             uint32_t address, uint32_t val, int len)
+{
+    pci_default_write_config(d, address, val, len);
+
+    if (/* io base/limit */
+        ranges_overlap(address, len, PCI_IO_BASE, 2) ||
+
+        /* memory base/limit, prefetchable base/limit and
+           io base/limit upper 16 */
+        ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
+        PCIBridge *s = container_of(d, PCIBridge, dev);
+        PCIBus *secondary_bus = &s->bus;
+        pci_bridge_update_mappings(secondary_bus);
+    }
+}
+
+static int pci_bridge_initfn(PCIDevice *dev)
+{
+    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
+
+    pci_config_set_vendor_id(s->dev.config, s->vid);
+    pci_config_set_device_id(s->dev.config, s->did);
+
+    pci_set_word(dev->config + PCI_STATUS,
+                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
+    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);
+    dev->config[PCI_HEADER_TYPE] =
+        (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
+        PCI_HEADER_TYPE_BRIDGE;
+    pci_set_word(dev->config + PCI_SEC_STATUS,
+                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
+    return 0;
+}
+
+static int pci_bridge_exitfn(PCIDevice *pci_dev)
+{
+    PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
+    PCIBus *bus = &s->bus;
+    pci_unregister_secondary_bus(bus);
+    return 0;
+}
+
+PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
+                        uint16_t vid, uint16_t did,
+                        pci_map_irq_fn map_irq, const char *name)
+{
+    PCIDevice *dev;
+    PCIBridge *s;
+
+    dev = pci_create_multifunction(bus, devfn, multifunction, "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(bus, &s->bus, &s->dev, map_irq, name);
+    return &s->bus;
+}
+
+static PCIDeviceInfo bridge_info = {
+    .qdev.name    = "pci-bridge",
+    .qdev.size    = sizeof(PCIBridge),
+    .init         = pci_bridge_initfn,
+    .exit         = pci_bridge_exitfn,
+    .config_write = pci_bridge_write_config,
+    .is_bridge    = 1,
+    .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)
diff --git a/hw/pci_bridge.h b/hw/pci_bridge.h
new file mode 100644
index 0000000..ddb2c82
--- /dev/null
+++ b/hw/pci_bridge.h
@@ -0,0 +1,48 @@
+/*
+ * QEMU PCI bridge
+ *
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * split out pci bus specific stuff from pci.[hc] to pci_bridge.[hc]
+ * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ */
+
+#ifndef QEMU_PCI_BRIDGE_H
+#define QEMU_PCI_BRIDGE_H
+
+#include "pci.h"
+
+PCIDevice *pci_bridge_get_device(PCIBus *bus);
+
+pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type);
+pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type);
+
+PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
+                        uint16_t vid, uint16_t did,
+                        pci_map_irq_fn map_irq, const char *name);
+
+#endif  /* QEMU_PCI_BRIDGE_H */
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ *  indent-tab-mode: nil
+ * End:
+ */
-- 
1.7.1.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 2/4] pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus.
  2010-07-13  4:01 [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 1/4] pci/bridge: split out pci bridge code into pci_bridge.c from pci.c Isaku Yamahata
@ 2010-07-13  4:01 ` Isaku Yamahata
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 3/4] pci_bridge: clean up: remove pci_{register, unregister}_secondary_bus() Isaku Yamahata
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-07-13  4:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, yamahata, mst

To avoid confusion of primary bus with secondary bus,
rename PCIBridge::bus to PCIBridge::sec_bus.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 hw/pci_bridge.c    |   10 ++++------
 hw/pci_internals.h |    2 +-
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 7f27870..63052fe 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -138,8 +138,7 @@ static void pci_bridge_write_config(PCIDevice *d,
            io base/limit upper 16 */
         ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
         PCIBridge *s = container_of(d, PCIBridge, dev);
-        PCIBus *secondary_bus = &s->bus;
-        pci_bridge_update_mappings(secondary_bus);
+        pci_bridge_update_mappings(&s->sec_bus);
     }
 }
 
@@ -164,8 +163,7 @@ static int pci_bridge_initfn(PCIDevice *dev)
 static int pci_bridge_exitfn(PCIDevice *pci_dev)
 {
     PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
-    PCIBus *bus = &s->bus;
-    pci_unregister_secondary_bus(bus);
+    pci_unregister_secondary_bus(&s->sec_bus);
     return 0;
 }
 
@@ -182,8 +180,8 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
     qdev_init_nofail(&dev->qdev);
 
     s = DO_UPCAST(PCIBridge, dev, dev);
-    pci_register_secondary_bus(bus, &s->bus, &s->dev, map_irq, name);
-    return &s->bus;
+    pci_register_secondary_bus(bus, &s->sec_bus, &s->dev, map_irq, name);
+    return &s->sec_bus;
 }
 
 static PCIDeviceInfo bridge_info = {
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index 8a3026b..fa844ab 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -32,7 +32,7 @@ struct PCIBus {
 
 typedef struct {
     PCIDevice dev;
-    PCIBus bus;
+    PCIBus sec_bus;
     uint32_t vid;
     uint32_t did;
 } PCIBridge;
-- 
1.7.1.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 3/4] pci_bridge: clean up: remove pci_{register, unregister}_secondary_bus()
  2010-07-13  4:01 [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 1/4] pci/bridge: split out pci bridge code into pci_bridge.c from pci.c Isaku Yamahata
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 2/4] pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus Isaku Yamahata
@ 2010-07-13  4:01 ` Isaku Yamahata
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 4/4] pci_bridge: introduce pci bridge library Isaku Yamahata
  2010-07-22  2:33 ` [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
  4 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-07-13  4:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, yamahata, mst

Remove pci_{register, unregister}_secondary_bus() by open code.
They are old stype API and aren't used any more by others. So eliminate it.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 hw/pci_bridge.c |   32 ++++++++++----------------------
 1 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 63052fe..2f13c7d 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -37,26 +37,6 @@ PCIDevice *pci_bridge_get_device(PCIBus *bus)
     return bus->parent_dev;
 }
 
-static void pci_register_secondary_bus(PCIBus *parent,
-                                       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;
-
-    QLIST_INIT(&bus->child);
-    QLIST_INSERT_HEAD(&parent->child, bus, sibling);
-}
-
-static void pci_unregister_secondary_bus(PCIBus *bus)
-{
-    assert(QLIST_EMPTY(&bus->child));
-    QLIST_REMOVE(bus, sibling);
-}
-
 static uint32_t pci_config_get_io_base(PCIDevice *d,
                                        uint32_t base, uint32_t base_upper16)
 {
@@ -163,7 +143,8 @@ static int pci_bridge_initfn(PCIDevice *dev)
 static int pci_bridge_exitfn(PCIDevice *pci_dev)
 {
     PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
-    pci_unregister_secondary_bus(&s->sec_bus);
+    assert(QLIST_EMPTY(&s->sec_bus.child));
+    QLIST_REMOVE(&s->sec_bus, sibling);
     return 0;
 }
 
@@ -173,6 +154,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
 {
     PCIDevice *dev;
     PCIBridge *s;
+    PCIBus *sec_bus;
 
     dev = pci_create_multifunction(bus, devfn, multifunction, "pci-bridge");
     qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
@@ -180,7 +162,13 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
     qdev_init_nofail(&dev->qdev);
 
     s = DO_UPCAST(PCIBridge, dev, dev);
-    pci_register_secondary_bus(bus, &s->sec_bus, &s->dev, map_irq, name);
+    sec_bus = &s->sec_bus;
+    qbus_create_inplace(&sec_bus->qbus, &pci_bus_info, &dev->qdev, name);
+    sec_bus->parent_dev = dev;
+    sec_bus->map_irq = map_irq;
+
+    QLIST_INIT(&sec_bus->child);
+    QLIST_INSERT_HEAD(&bus->child, sec_bus, sibling);
     return &s->sec_bus;
 }
 
-- 
1.7.1.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 4/4] pci_bridge: introduce pci bridge library.
  2010-07-13  4:01 [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
                   ` (2 preceding siblings ...)
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 3/4] pci_bridge: clean up: remove pci_{register, unregister}_secondary_bus() Isaku Yamahata
@ 2010-07-13  4:01 ` Isaku Yamahata
  2010-07-22  2:33 ` [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
  4 siblings, 0 replies; 9+ messages in thread
From: Isaku Yamahata @ 2010-07-13  4:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, yamahata, mst

introduce pci bridge library.
convert apb bridge and dec p2p bridge to use new pci bridge library.
save/restore is supported as a side effect.
This is also preparation for pci express root/upstream/downstream port.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>

---
changes v2 -> v3:
eliminate pci_bridge_qdev_register(), pci_bridge_create(),
pci_bridge_create_simple() by exporting PCIBus, PCIBridge.
---
 hw/apb_pci.c       |   55 ++++++++++++++++++------
 hw/dec_pci.c       |   45 +++++++++++++++----
 hw/pci_bridge.c    |  122 +++++++++++++++++++++++++++++----------------------
 hw/pci_bridge.h    |   24 ++++++++--
 hw/pci_internals.h |   15 +++++--
 qemu-common.h      |    1 +
 6 files changed, 178 insertions(+), 84 deletions(-)

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 88ee4a9..10a5baa 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -30,6 +30,7 @@
 #include "pci.h"
 #include "pci_host.h"
 #include "pci_bridge.h"
+#include "pci_internals.h"
 #include "rwhandler.h"
 #include "apb_pci.h"
 #include "sysemu.h"
@@ -294,9 +295,17 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level)
     }
 }
 
-static void apb_pci_bridge_init(PCIBus *b)
+static int apb_pci_bridge_initfn(PCIDevice *dev)
 {
-    PCIDevice *dev = pci_bridge_get_device(b);
+    int rc;
+
+    rc = pci_bridge_initfn(dev);
+    if (rc < 0) {
+        return rc;
+    }
+
+    pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_SUN);
+    pci_config_set_device_id(dev->config, PCI_DEVICE_ID_SUN_SIMBA);
 
     /*
      * command register:
@@ -313,6 +322,7 @@ static void apb_pci_bridge_init(PCIBus *b)
                  PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
                  PCI_STATUS_DEVSEL_MEDIUM);
     pci_set_byte(dev->config + PCI_REVISION_ID, 0x11);
+    return 0;
 }
 
 PCIBus *pci_apb_init(target_phys_addr_t special_base,
@@ -323,6 +333,8 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
     SysBusDevice *s;
     APBState *d;
     unsigned int i;
+    PCIDevice *pci_dev;
+    PCIBridge *br;
 
     /* Ultrasparc PBM main bus */
     dev = qdev_create(NULL, "pbm");
@@ -348,17 +360,21 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
     pci_create_simple(d->bus, 0, "pbm");
 
     /* APB secondary busses */
-    *bus2 = pci_bridge_init(d->bus, PCI_DEVFN(1, 0), true,
-                            PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA,
-                            pci_apb_map_irq,
-                            "Advanced PCI Bus secondary bridge 1");
-    apb_pci_bridge_init(*bus2);
-
-    *bus3 = pci_bridge_init(d->bus, PCI_DEVFN(1, 1), true,
-                            PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA,
-                            pci_apb_map_irq,
-                            "Advanced PCI Bus secondary bridge 2");
-    apb_pci_bridge_init(*bus3);
+    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
+                                   "pbm-bridge");
+    br = DO_UPCAST(PCIBridge, dev, dev);
+    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
+                       pci_apb_map_irq);
+    qdev_init_nofail(&pci_dev->qdev);
+    *bus2 = pci_bridge_get_sec_bus(br);
+
+    pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 1), true,
+                                   "pbm-bridge");
+    br = DO_UPCAST(PCIBridge, dev, dev);
+    pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
+                       pci_apb_map_irq);
+    qdev_init_nofail(&pci_dev->qdev);
+    *bus3 = pci_bridge_get_sec_bus(br);
 
     return d->bus;
 }
@@ -441,10 +457,23 @@ static SysBusDeviceInfo pbm_host_info = {
     .qdev.reset = pci_pbm_reset,
     .init = pci_pbm_init_device,
 };
+
+static PCIDeviceInfo pbm_pci_bridge_info = {
+    .qdev.name = "pbm-bridge",
+    .qdev.size = sizeof(PCIBridge),
+    .qdev.vmsd = &vmstate_pci_device,
+    .qdev.reset = pci_brdige_reset,
+    .init = apb_pci_bridge_initfn,
+    .exit = pci_bridge_exitfn,
+    .config_write = pci_bridge_write_config,
+    .is_bridge = 1,
+};
+
 static void pbm_register_devices(void)
 {
     sysbus_register_withprop(&pbm_host_info);
     pci_qdev_register(&pbm_pci_host_info);
+    pci_qdev_register(&pbm_pci_bridge_info);
 }
 
 device_init(pbm_register_devices)
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index f7a9cdc..aa07ab7 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -28,6 +28,7 @@
 #include "pci.h"
 #include "pci_host.h"
 #include "pci_bridge.h"
+#include "pci_internals.h"
 
 /* debug DEC */
 //#define DEBUG_DEC
@@ -49,18 +50,43 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
     return irq_num;
 }
 
-PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
+static int dec_21154_initfn(PCIDevice *dev)
 {
-    DeviceState *dev;
-    PCIBus *ret;
+    int rc;
+
+    rc = pci_bridge_initfn(dev);
+    if (rc < 0) {
+        return rc;
+    }
+
+    pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_DEC);
+    pci_config_set_device_id(dev->config, PCI_DEVICE_ID_DEC_21154);
+    return 0;
+}
 
-    dev = qdev_create(NULL, "dec-21154");
-    qdev_init_nofail(dev);
-    ret = pci_bridge_init(parent_bus, devfn, false,
-                          PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21154,
-                          dec_map_irq, "DEC 21154 PCI-PCI bridge");
+static PCIDeviceInfo dec_21154_pci_bridge_info = {
+    .qdev.name = "dec-21154-p2p-bridge",
+    .qdev.desc = "DEC 21154 PCI-PCI bridge",
+    .qdev.size = sizeof(PCIBridge),
+    .qdev.vmsd = &vmstate_pci_device,
+    .qdev.reset = pci_bridge_reset,
+    .init = dec_21154_initfn,
+    .exit = pci_bridge_exitfn,
+    .config_write = pci_bridge_write_config,
+    .is_bridge = 1,
+};
+
+PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
+{
+    PCIDevice *dev;
+    PCIBridge *br;
 
-    return ret;
+    dev = pci_create_multifunction(parent_bus, devfn, false,
+                                   "dec-21154-p2p-bridge");
+    br = DO_UPCAST(PCIBridge, dev, dev);
+    pci_bridge_map_irq(br, "DEC 21154 PCI-PCI bridge", dec_map_irq);
+    qdev_init_nofail(&dev->qdev);
+    return pci_bridge_get_sec_bus(br);
 }
 
 static int pci_dec_21154_init_device(SysBusDevice *dev)
@@ -99,6 +125,7 @@ static void dec_register_devices(void)
     sysbus_register_dev("dec-21154", sizeof(DECState),
                         pci_dec_21154_init_device);
     pci_qdev_register(&dec_21154_pci_host_info);
+    pci_qdev_register(&dec_21154_pci_bridge_info);
 }
 
 device_init(dec_register_devices)
diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 2f13c7d..198c3c7 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -32,12 +32,19 @@
 #include "pci_bridge.h"
 #include "pci_internals.h"
 
+/* Accessor function to get parent bridge device from pci bus. */
 PCIDevice *pci_bridge_get_device(PCIBus *bus)
 {
     return bus->parent_dev;
 }
 
-static uint32_t pci_config_get_io_base(PCIDevice *d,
+/* Accessor function to get secondary bus from pci-to-pci bridge device */
+PCIBus *pci_bridge_get_sec_bus(PCIBridge *br)
+{
+    return &br->sec_bus;
+}
+
+static uint32_t pci_config_get_io_base(const PCIDevice *d,
                                        uint32_t base, uint32_t base_upper16)
 {
     uint32_t val;
@@ -49,13 +56,13 @@ static uint32_t pci_config_get_io_base(PCIDevice *d,
     return val;
 }
 
-static pcibus_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
+static pcibus_t pci_config_get_memory_base(const PCIDevice *d, uint32_t base)
 {
     return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
         << 16;
 }
 
-static pcibus_t pci_config_get_pref_base(PCIDevice *d,
+static pcibus_t pci_config_get_pref_base(const PCIDevice *d,
                                          uint32_t base, uint32_t upper)
 {
     pcibus_t tmp;
@@ -69,7 +76,8 @@ static pcibus_t pci_config_get_pref_base(PCIDevice *d,
     return val;
 }
 
-pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type)
+/* accessor function to get bridge filtering base address */
+pcibus_t pci_bridge_get_base(const PCIDevice *bridge, uint8_t type)
 {
     pcibus_t base;
     if (type & PCI_BASE_ADDRESS_SPACE_IO) {
@@ -87,7 +95,8 @@ pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type)
     return base;
 }
 
-pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type)
+/* accessor funciton to get bridge filtering limit */
+pcibus_t pci_bridge_get_limit(const PCIDevice *bridge, uint8_t type)
 {
     pcibus_t limit;
     if (type & PCI_BASE_ADDRESS_SPACE_IO) {
@@ -106,7 +115,8 @@ pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type)
     return limit;
 }
 
-static void pci_bridge_write_config(PCIDevice *d,
+/* default write_config function for PCI-to-PCI bridge */
+void pci_bridge_write_config(PCIDevice *d,
                              uint32_t address, uint32_t val, int len)
 {
     pci_default_write_config(d, address, val, len);
@@ -122,12 +132,41 @@ static void pci_bridge_write_config(PCIDevice *d,
     }
 }
 
-static int pci_bridge_initfn(PCIDevice *dev)
+/* reset bridge specific configuration registers */
+void pci_bridge_reset_reg(PCIDevice *dev)
+{
+    uint8_t *conf = dev->config;
+
+    conf[PCI_PRIMARY_BUS] = 0;
+    conf[PCI_SECONDARY_BUS] = 0;
+    conf[PCI_SUBORDINATE_BUS] = 0;
+    conf[PCI_SEC_LATENCY_TIMER] = 0;
+
+    conf[PCI_IO_BASE] = 0;
+    conf[PCI_IO_LIMIT] = 0;
+    pci_set_word(conf + PCI_MEMORY_BASE, 0);
+    pci_set_word(conf + PCI_MEMORY_LIMIT, 0);
+    pci_set_word(conf + PCI_PREF_MEMORY_BASE, 0);
+    pci_set_word(conf + PCI_PREF_MEMORY_LIMIT, 0);
+    pci_set_word(conf + PCI_PREF_BASE_UPPER32, 0);
+    pci_set_word(conf + PCI_PREF_LIMIT_UPPER32, 0);
+
+    pci_set_word(conf + PCI_BRIDGE_CONTROL, 0);
+}
+
+/* default reset function for PCI-to-PCI bridge */
+void pci_bridge_reset(DeviceState *qdev)
 {
-    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
+    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
+    pci_bridge_reset_reg(dev);
+}
 
-    pci_config_set_vendor_id(s->dev.config, s->vid);
-    pci_config_set_device_id(s->dev.config, s->did);
+/* default qdev initialization function for PCI-to-PCI bridge */
+int pci_bridge_initfn(PCIDevice *dev)
+{
+    PCIBus *parent = dev->bus;
+    PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
+    PCIBus *sec_bus = &br->sec_bus;
 
     pci_set_word(dev->config + PCI_STATUS,
                  PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
@@ -137,58 +176,35 @@ static int pci_bridge_initfn(PCIDevice *dev)
         PCI_HEADER_TYPE_BRIDGE;
     pci_set_word(dev->config + PCI_SEC_STATUS,
                  PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
+
+    qbus_create_inplace(&sec_bus->qbus, &pci_bus_info, &dev->qdev,
+                        br->bus_name);
+    sec_bus->parent_dev = dev;
+    sec_bus->map_irq = br->map_irq;
+
+    QLIST_INIT(&sec_bus->child);
+    QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling);
     return 0;
 }
 
-static int pci_bridge_exitfn(PCIDevice *pci_dev)
+/* default qdev clean up function for PCI-to-PCI bridge */
+int pci_bridge_exitfn(PCIDevice *pci_dev)
 {
     PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
     assert(QLIST_EMPTY(&s->sec_bus.child));
     QLIST_REMOVE(&s->sec_bus, sibling);
+    /* qbus_free() is called automatically by qdev_free() */
     return 0;
 }
 
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
-                        uint16_t vid, uint16_t did,
-                        pci_map_irq_fn map_irq, const char *name)
-{
-    PCIDevice *dev;
-    PCIBridge *s;
-    PCIBus *sec_bus;
-
-    dev = pci_create_multifunction(bus, devfn, multifunction, "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);
-    sec_bus = &s->sec_bus;
-    qbus_create_inplace(&sec_bus->qbus, &pci_bus_info, &dev->qdev, name);
-    sec_bus->parent_dev = dev;
-    sec_bus->map_irq = map_irq;
-
-    QLIST_INIT(&sec_bus->child);
-    QLIST_INSERT_HEAD(&bus->child, sec_bus, sibling);
-    return &s->sec_bus;
-}
-
-static PCIDeviceInfo bridge_info = {
-    .qdev.name    = "pci-bridge",
-    .qdev.size    = sizeof(PCIBridge),
-    .init         = pci_bridge_initfn,
-    .exit         = pci_bridge_exitfn,
-    .config_write = pci_bridge_write_config,
-    .is_bridge    = 1,
-    .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)
+/*
+ * before qdev initialization(qdev_init()), this function sets bus_name and
+ * map_irq callback which are necessry for pci_bridge_initfn() to
+ * initialize bus.
+ */
+void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
+                        pci_map_irq_fn map_irq)
 {
-    pci_qdev_register(&bridge_info);
+    br->map_irq = map_irq;
+    br->bus_name = bus_name;
 }
-
-device_init(pci_register_devices)
diff --git a/hw/pci_bridge.h b/hw/pci_bridge.h
index ddb2c82..63ada19 100644
--- a/hw/pci_bridge.h
+++ b/hw/pci_bridge.h
@@ -29,13 +29,27 @@
 #include "pci.h"
 
 PCIDevice *pci_bridge_get_device(PCIBus *bus);
+PCIBus *pci_bridge_get_sec_bus(PCIBridge *br);
 
-pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type);
-pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type);
+pcibus_t pci_bridge_get_base(const PCIDevice *bridge, uint8_t type);
+pcibus_t pci_bridge_get_limit(const PCIDevice *bridge, uint8_t type);
 
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
-                        uint16_t vid, uint16_t did,
-                        pci_map_irq_fn map_irq, const char *name);
+void pci_bridge_write_config(PCIDevice *d,
+                             uint32_t address, uint32_t val, int len);
+void pci_bridge_reset_reg(PCIDevice *dev);
+void pci_bridge_reset(DeviceState *qdev);
+
+int pci_bridge_initfn(PCIDevice *pci_dev);
+int pci_bridge_exitfn(PCIDevice *pci_dev);
+
+
+/*
+ * before qdev initialization(qdev_init()), this function sets bus_name and
+ * map_irq callback which are necessry for pci_bridge_initfn() to
+ * initialize bus.
+ */
+void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
+                        pci_map_irq_fn map_irq);
 
 #endif  /* QEMU_PCI_BRIDGE_H */
 /*
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index fa844ab..e3c93a3 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -5,6 +5,11 @@
  * This header files is private to pci.c and pci_bridge.c
  * So following structures are opaque to others and shouldn't be
  * accessed.
+ *
+ * For pci-to-pci bridge needs to include this header file to embed
+ * PCIBridge in its structure or to get sizeof(PCIBridge),
+ * However, they shouldn't access those following members directly.
+ * Use accessor function in pci.h, pci_bridge.h
  */
 
 extern struct BusInfo pci_bus_info;
@@ -30,11 +35,13 @@ struct PCIBus {
     int *irq_count;
 };
 
-typedef struct {
+struct PCIBridge {
     PCIDevice dev;
+
+    /* private member */
     PCIBus sec_bus;
-    uint32_t vid;
-    uint32_t did;
-} PCIBridge;
+    pci_map_irq_fn map_irq;
+    const char *bus_name;
+};
 
 #endif /* QEMU_PCI_INTERNALS_H */
diff --git a/qemu-common.h b/qemu-common.h
index 3fb2f0b..d735235 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -219,6 +219,7 @@ typedef struct PCIHostState PCIHostState;
 typedef struct PCIExpressHost PCIExpressHost;
 typedef struct PCIBus PCIBus;
 typedef struct PCIDevice PCIDevice;
+typedef struct PCIBridge PCIBridge;
 typedef struct SerialState SerialState;
 typedef struct IRQState *qemu_irq;
 typedef struct PCMCIACardState PCMCIACardState;
-- 
1.7.1.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library
  2010-07-13  4:01 [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
                   ` (3 preceding siblings ...)
  2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 4/4] pci_bridge: introduce pci bridge library Isaku Yamahata
@ 2010-07-22  2:33 ` Isaku Yamahata
  2010-07-22  8:28   ` Michael S. Tsirkin
  4 siblings, 1 reply; 9+ messages in thread
From: Isaku Yamahata @ 2010-07-22  2:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, mst

Ping?

On Tue, Jul 13, 2010 at 01:01:38PM +0900, Isaku Yamahata wrote:
> Changes v2 -> v1:
                v3
> - dropped first patch as it is merdged.
> - rebased to mst's pci branch.
> - eliminated pci_brdige_qdev_register(), pci_brdige_create(),
>   pci_brdige_create_simple() by exporting PCIBus and PCIBridge.
> 
> Patch description:
> Now pci.c has grown. So split bridge related code into dedicated file
> for further extension to pci bridge. Further clean up and pcie port emulator. 
> This make patch conflict less possible in future.
> 
> Clean up of pci host bus ans piix pci as discussed with v1
> will be addressed after this patch set is accepted.
> 
> changes v1 -> v2:
> - introduce pci_internals.h to accomodate pci internal strcutures to
>   share between pci.c and pci_bridge.c
> - don't make PCIBridge::bus pointer as suggested by
>   Michael S. Tsirkin <mst@redhat.com>
> - rename PCIBridge::bus -> PCIBridge::sec_bus
> - eliminate pci_reguster_secondary_bus()/pci_unregister_secondary_bus()
> - document pci bridge library functions.
> - introduced pci bridge library.
> 
> Isaku Yamahata (4):
>   pci/bridge: split out pci bridge code into pci_bridge.c from pci.c
>   pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus.
>   pci_bridge: clean up: remove pci_{register,
>     unregister}_secondary_bus()
>   pci_bridge: introduce pci bridge library.
> 
>  Makefile.objs      |    2 +-
>  hw/apb_pci.c       |   56 +++++++++++---
>  hw/dec_pci.c       |   46 +++++++++--
>  hw/pci.c           |  177 +-------------------------------------------
>  hw/pci.h           |    5 +-
>  hw/pci_bridge.c    |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/pci_bridge.h    |   62 +++++++++++++++
>  hw/pci_internals.h |   17 +++-
>  qemu-common.h      |    1 +
>  9 files changed, 369 insertions(+), 207 deletions(-)
>  create mode 100644 hw/pci_bridge.c
>  create mode 100644 hw/pci_bridge.h
> 
> 

-- 
yamahata

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library
  2010-07-22  2:33 ` [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
@ 2010-07-22  8:28   ` Michael S. Tsirkin
  2010-07-22  8:51     ` Isaku Yamahata
  0 siblings, 1 reply; 9+ messages in thread
From: Michael S. Tsirkin @ 2010-07-22  8:28 UTC (permalink / raw)
  To: Isaku Yamahata; +Cc: blauwirbel, qemu-devel

On Thu, Jul 22, 2010 at 11:33:32AM +0900, Isaku Yamahata wrote:
> Ping?

You said you will rebase and repost?

> On Tue, Jul 13, 2010 at 01:01:38PM +0900, Isaku Yamahata wrote:
> > Changes v2 -> v1:
>                 v3
> > - dropped first patch as it is merdged.
> > - rebased to mst's pci branch.
> > - eliminated pci_brdige_qdev_register(), pci_brdige_create(),
> >   pci_brdige_create_simple() by exporting PCIBus and PCIBridge.
> > 
> > Patch description:
> > Now pci.c has grown. So split bridge related code into dedicated file
> > for further extension to pci bridge. Further clean up and pcie port emulator. 
> > This make patch conflict less possible in future.
> > 
> > Clean up of pci host bus ans piix pci as discussed with v1
> > will be addressed after this patch set is accepted.
> > 
> > changes v1 -> v2:
> > - introduce pci_internals.h to accomodate pci internal strcutures to
> >   share between pci.c and pci_bridge.c
> > - don't make PCIBridge::bus pointer as suggested by
> >   Michael S. Tsirkin <mst@redhat.com>
> > - rename PCIBridge::bus -> PCIBridge::sec_bus
> > - eliminate pci_reguster_secondary_bus()/pci_unregister_secondary_bus()
> > - document pci bridge library functions.
> > - introduced pci bridge library.
> > 
> > Isaku Yamahata (4):
> >   pci/bridge: split out pci bridge code into pci_bridge.c from pci.c
> >   pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus.
> >   pci_bridge: clean up: remove pci_{register,
> >     unregister}_secondary_bus()
> >   pci_bridge: introduce pci bridge library.
> > 
> >  Makefile.objs      |    2 +-
> >  hw/apb_pci.c       |   56 +++++++++++---
> >  hw/dec_pci.c       |   46 +++++++++--
> >  hw/pci.c           |  177 +-------------------------------------------
> >  hw/pci.h           |    5 +-
> >  hw/pci_bridge.c    |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  hw/pci_bridge.h    |   62 +++++++++++++++
> >  hw/pci_internals.h |   17 +++-
> >  qemu-common.h      |    1 +
> >  9 files changed, 369 insertions(+), 207 deletions(-)
> >  create mode 100644 hw/pci_bridge.c
> >  create mode 100644 hw/pci_bridge.h
> > 
> > 
> 
> -- 
> yamahata

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library
  2010-07-22  8:28   ` Michael S. Tsirkin
@ 2010-07-22  8:51     ` Isaku Yamahata
  2010-07-22  9:23       ` Michael S. Tsirkin
  0 siblings, 1 reply; 9+ messages in thread
From: Isaku Yamahata @ 2010-07-22  8:51 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: blauwirbel, qemu-devel

On Thu, Jul 22, 2010 at 11:28:27AM +0300, Michael S. Tsirkin wrote:
> On Thu, Jul 22, 2010 at 11:33:32AM +0900, Isaku Yamahata wrote:
> > Ping?
> 
> You said you will rebase and repost?

This is it. Probably there was a race between them

> 
> > On Tue, Jul 13, 2010 at 01:01:38PM +0900, Isaku Yamahata wrote:
> > > Changes v2 -> v1:
> >                 v3
> > > - dropped first patch as it is merdged.
> > > - rebased to mst's pci branch.
> > > - eliminated pci_brdige_qdev_register(), pci_brdige_create(),
> > >   pci_brdige_create_simple() by exporting PCIBus and PCIBridge.
> > > 
> > > Patch description:
> > > Now pci.c has grown. So split bridge related code into dedicated file
> > > for further extension to pci bridge. Further clean up and pcie port emulator. 
> > > This make patch conflict less possible in future.
> > > 
> > > Clean up of pci host bus ans piix pci as discussed with v1
> > > will be addressed after this patch set is accepted.
> > > 
> > > changes v1 -> v2:
> > > - introduce pci_internals.h to accomodate pci internal strcutures to
> > >   share between pci.c and pci_bridge.c
> > > - don't make PCIBridge::bus pointer as suggested by
> > >   Michael S. Tsirkin <mst@redhat.com>
> > > - rename PCIBridge::bus -> PCIBridge::sec_bus
> > > - eliminate pci_reguster_secondary_bus()/pci_unregister_secondary_bus()
> > > - document pci bridge library functions.
> > > - introduced pci bridge library.
> > > 
> > > Isaku Yamahata (4):
> > >   pci/bridge: split out pci bridge code into pci_bridge.c from pci.c
> > >   pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus.
> > >   pci_bridge: clean up: remove pci_{register,
> > >     unregister}_secondary_bus()
> > >   pci_bridge: introduce pci bridge library.
> > > 
> > >  Makefile.objs      |    2 +-
> > >  hw/apb_pci.c       |   56 +++++++++++---
> > >  hw/dec_pci.c       |   46 +++++++++--
> > >  hw/pci.c           |  177 +-------------------------------------------
> > >  hw/pci.h           |    5 +-
> > >  hw/pci_bridge.c    |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  hw/pci_bridge.h    |   62 +++++++++++++++
> > >  hw/pci_internals.h |   17 +++-
> > >  qemu-common.h      |    1 +
> > >  9 files changed, 369 insertions(+), 207 deletions(-)
> > >  create mode 100644 hw/pci_bridge.c
> > >  create mode 100644 hw/pci_bridge.h
> > > 
> > > 
> > 
> > -- 
> > yamahata
> 

-- 
yamahata

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library
  2010-07-22  8:51     ` Isaku Yamahata
@ 2010-07-22  9:23       ` Michael S. Tsirkin
  0 siblings, 0 replies; 9+ messages in thread
From: Michael S. Tsirkin @ 2010-07-22  9:23 UTC (permalink / raw)
  To: Isaku Yamahata; +Cc: blauwirbel, qemu-devel

On Thu, Jul 22, 2010 at 05:51:21PM +0900, Isaku Yamahata wrote:
> On Thu, Jul 22, 2010 at 11:28:27AM +0300, Michael S. Tsirkin wrote:
> > On Thu, Jul 22, 2010 at 11:33:32AM +0900, Isaku Yamahata wrote:
> > > Ping?
> > 
> > You said you will rebase and repost?
> 
> This is it. Probably there was a race between them

Applied, thanks!

> > 
> > > On Tue, Jul 13, 2010 at 01:01:38PM +0900, Isaku Yamahata wrote:
> > > > Changes v2 -> v1:
> > >                 v3
> > > > - dropped first patch as it is merdged.
> > > > - rebased to mst's pci branch.
> > > > - eliminated pci_brdige_qdev_register(), pci_brdige_create(),
> > > >   pci_brdige_create_simple() by exporting PCIBus and PCIBridge.
> > > > 
> > > > Patch description:
> > > > Now pci.c has grown. So split bridge related code into dedicated file
> > > > for further extension to pci bridge. Further clean up and pcie port emulator. 
> > > > This make patch conflict less possible in future.
> > > > 
> > > > Clean up of pci host bus ans piix pci as discussed with v1
> > > > will be addressed after this patch set is accepted.
> > > > 
> > > > changes v1 -> v2:
> > > > - introduce pci_internals.h to accomodate pci internal strcutures to
> > > >   share between pci.c and pci_bridge.c
> > > > - don't make PCIBridge::bus pointer as suggested by
> > > >   Michael S. Tsirkin <mst@redhat.com>
> > > > - rename PCIBridge::bus -> PCIBridge::sec_bus
> > > > - eliminate pci_reguster_secondary_bus()/pci_unregister_secondary_bus()
> > > > - document pci bridge library functions.
> > > > - introduced pci bridge library.
> > > > 
> > > > Isaku Yamahata (4):
> > > >   pci/bridge: split out pci bridge code into pci_bridge.c from pci.c
> > > >   pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus.
> > > >   pci_bridge: clean up: remove pci_{register,
> > > >     unregister}_secondary_bus()
> > > >   pci_bridge: introduce pci bridge library.
> > > > 
> > > >  Makefile.objs      |    2 +-
> > > >  hw/apb_pci.c       |   56 +++++++++++---
> > > >  hw/dec_pci.c       |   46 +++++++++--
> > > >  hw/pci.c           |  177 +-------------------------------------------
> > > >  hw/pci.h           |    5 +-
> > > >  hw/pci_bridge.c    |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  hw/pci_bridge.h    |   62 +++++++++++++++
> > > >  hw/pci_internals.h |   17 +++-
> > > >  qemu-common.h      |    1 +
> > > >  9 files changed, 369 insertions(+), 207 deletions(-)
> > > >  create mode 100644 hw/pci_bridge.c
> > > >  create mode 100644 hw/pci_bridge.h
> > > > 
> > > > 
> > > 
> > > -- 
> > > yamahata
> > 
> 
> -- 
> yamahata

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-07-22  9:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-13  4:01 [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 1/4] pci/bridge: split out pci bridge code into pci_bridge.c from pci.c Isaku Yamahata
2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 2/4] pci_bridge: rename PCIBridge::bus -> PCIBridge::sec_bus Isaku Yamahata
2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 3/4] pci_bridge: clean up: remove pci_{register, unregister}_secondary_bus() Isaku Yamahata
2010-07-13  4:01 ` [Qemu-devel] [PATCH v3 4/4] pci_bridge: introduce pci bridge library Isaku Yamahata
2010-07-22  2:33 ` [Qemu-devel] [PATCH v3 0/4] pci: split out bridge code into pci_bridge and make it library Isaku Yamahata
2010-07-22  8:28   ` Michael S. Tsirkin
2010-07-22  8:51     ` Isaku Yamahata
2010-07-22  9:23       ` Michael S. Tsirkin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.