Patchwork pci: move apb specific stuff to apb_pci.c

login
register
mail settings
Submitter Michael S. Tsirkin
Date Nov. 11, 2009, 12:33 p.m.
Message ID <20091111123354.GA23033@redhat.com>
Download mbox | patch
Permalink /patch/38133/
State New
Headers show

Comments

Michael S. Tsirkin - Nov. 11, 2009, 12:33 p.m.
pci code had a TODO to move apb specific
pci bridge initialization to apb_pci.
Implement this and remove the TODO.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/apb_pci.c |   22 ++++++++++++++++++++++
 hw/pci.c     |   26 ++++++--------------------
 hw/pci.h     |    1 +
 3 files changed, 29 insertions(+), 20 deletions(-)

Patch

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 3999879..8fc8f21 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -181,6 +181,25 @@  static void pci_apb_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[irq_num], level);
 }
 
+static void apb_pci_bridge_init(PCIBus *b)
+{
+    PCIDevice *dev = pci_bridge_get_device(b);
+
+    /*
+     * command register:
+     * According to PCI bridge spec, after reset
+     *   bus master bit is off
+     *   memory space enable bit is off
+     * According to manual (805-1251.pdf).
+     *   the reset value should be zero unless the boot pin is tied high
+     *   (which is true) and thus it should be PCI_COMMAND_MEMORY.
+     */
+    pci_set_word(dev->config + PCI_COMMAND,
+                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+    dev->config[PCI_LATENCY_TIMER] = 0x10;
+    dev->config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;
+}
+
 PCIBus *pci_apb_init(target_phys_addr_t special_base,
                      target_phys_addr_t mem_base,
                      qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
@@ -211,10 +230,13 @@  PCIBus *pci_apb_init(target_phys_addr_t special_base,
                             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->host_state.bus, PCI_DEVFN(1, 1),
                             PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA,
                             pci_apb_map_irq,
                             "Advanced PCI Bus secondary bridge 2");
+    apb_pci_bridge_init(*bus3);
 
     return d->host_state.bus;
 }
diff --git a/hw/pci.c b/hw/pci.c
index 2ab1117..3eb4784 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1204,29 +1204,10 @@  static int pci_bridge_initfn(PCIDevice *dev)
     pci_config_set_vendor_id(s->dev.config, s->vid);
     pci_config_set_device_id(s->dev.config, s->did);
 
-    /* TODO: intial value
-     * command register:
-     * According to PCI bridge spec, after reset
-     *   bus master bit is off
-     *   memory space enable bit is off
-     * According to manual (805-1251.pdf).(See abp_pbi.c for its links.)
-     *   the reset value should be zero unless the boot pin is tied high
-     *   (which is tru) and thus it should be PCI_COMMAND_MEMORY.
-     *
-     * For now, don't touch the value.
-     * Later command register will be set to zero and apb_pci.c will
-     * override the value.
-     * Same for latency timer, and multi function bit of header type.
-     */
-    pci_set_word(dev->config + PCI_COMMAND,
-                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-
     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_LATENCY_TIMER] = 0x10;
-    dev->config[PCI_HEADER_TYPE] =
-        PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE;
+    dev->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_BRIDGE;
     pci_set_word(dev->config + PCI_SEC_STATUS,
                  PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
     return 0;
@@ -1256,6 +1237,11 @@  PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
     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;
diff --git a/hw/pci.h b/hw/pci.h
index 9a56d0d..39ee0f7 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -308,6 +308,7 @@  int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
 void pci_info(Monitor *mon);
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
                         pci_map_irq_fn map_irq, const char *name);
+PCIDevice *pci_bridge_get_device(PCIBus *bus);
 
 static inline void
 pci_set_byte(uint8_t *config, uint8_t val)