qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [PATCH] e500-pci: Factor into distinct mpc8540 and p4080 PCI


From: Ben Collins
Subject: [Qemu-ppc] [PATCH] e500-pci: Factor into distinct mpc8540 and p4080 PCI Hosts
Date: Wed, 30 May 2012 19:25:19 -0400

In order to provide a closer virtualization, factor out e500-pci into seperate
PCI hosts, namely fsl,mpc8540-pci and fsl,p4080-pcie (to match the device-tree
node naming).

Make use of the mpc8540 variant (basically a NOP) for ppce500_mpc8544 machine
type. The p4080-pcie variant can be used later for a P4080DS specific machine
description.

The major differences between the two are the host-bridge PCI device ID and the
difference in starting slot number. Eventually I'd like to get the p4080 variant
to support any valid slot number, and actually move the bus behind the host
bridge as is done in the physical hardware.

Signed-off-by: Ben Collins <address@hidden>
---
 hw/pci_ids.h           |    1 +
 hw/ppce500_mpc8544ds.c |    2 +-
 hw/ppce500_pci.c       |  131 +++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 116 insertions(+), 18 deletions(-)

diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index e8235a7..a85ad63 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -96,6 +96,7 @@
 
 #define PCI_VENDOR_ID_FREESCALE          0x1957
 #define PCI_DEVICE_ID_MPC8533E           0x0030
+#define PCI_DEVICE_ID_P4080E             0x0400
 
 #define PCI_VENDOR_ID_INTEL              0x8086
 #define PCI_DEVICE_ID_INTEL_82378        0x0484
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index f1dfbe1..475f8dd 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -321,7 +321,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
     sysbus_create_simple("mpc8544-guts", MPC8544_UTIL_BASE, NULL);
 
     /* PCI */
-    dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE,
+    dev = sysbus_create_varargs("fsl,mpc8540-pci", MPC8544_PCI_REGS_BASE,
                                 mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]],
                                 mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]],
                                 NULL);
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 0f60b24..30a43e0 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -227,7 +227,7 @@ static const MemoryRegionOps e500_pci_reg_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
+static int mpc8540_pci_map_irq(PCIDevice *pci_dev, int irq_num)
 {
     int devno = pci_dev->devfn >> 3, ret = 0;
 
@@ -247,7 +247,29 @@ static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int 
irq_num)
     return ret;
 }
 
-static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level)
+static int p4080_pci_map_irq(PCIDevice *pci_dev, int irq_num)
+{
+    int devno = pci_dev->devfn >> 3, ret = 0;
+
+    switch (devno) {
+        /* Four PCI slots */
+        case 0x02:
+        case 0x03:
+        case 0x04:
+        case 0x05:
+            ret = (irq_num + devno - 0x01) & 3;
+            break;
+        default:
+            printf("Error:%s:unknown dev number\n", __func__);
+    }
+
+    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
+           pci_dev->devfn, irq_num, ret, devno);
+
+    return ret;
+}
+
+static void e500_pci_set_irq(void *opaque, int irq_num, int level)
 {
     qemu_irq *pic = opaque;
 
@@ -301,7 +323,7 @@ static const VMStateDescription vmstate_ppce500_pci = {
 
 #include "exec-memory.h"
 
-static int e500_pcihost_initfn(SysBusDevice *dev)
+static int mpc8540_pcihost_initfn(SysBusDevice *dev)
 {
     PCIHostState *h;
     PPCE500PCIState *s;
@@ -317,12 +339,12 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
         sysbus_init_irq(dev, &s->irq[i]);
     }
 
-    b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
-                         mpc85xx_pci_map_irq, s->irq, address_space_mem,
+    b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, e500_pci_set_irq,
+                         mpc8540_pci_map_irq, s->irq, address_space_mem,
                          address_space_io, PCI_DEVFN(0x11, 0), 4);
     s->pci_state.bus = b;
 
-    pci_create_simple(b, 0, "e500-host-bridge");
+    pci_create_simple(b, 0, "mpc8540-host-bridge");
 
     memory_region_init(&s->container, "pci-container", PCIE500_ALL_SIZE);
     memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h,
@@ -339,7 +361,45 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
+static int p4080_pcihost_initfn(SysBusDevice *dev)
+{
+    PCIHostState *h;
+    PPCE500PCIState *s;
+    PCIBus *b;
+    int i;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *address_space_io = get_system_io();
+
+    h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
+    s = DO_UPCAST(PPCE500PCIState, pci_state, h);
+
+    for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
+        sysbus_init_irq(dev, &s->irq[i]);
+    }
+
+    b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, e500_pci_set_irq,
+                         p4080_pci_map_irq, s->irq, address_space_mem,
+                         address_space_io, PCI_DEVFN(0x02, 0), 4);
+    s->pci_state.bus = b;
+
+    pci_create_simple(b, 0, "p4080-host-bridge");
+
+    memory_region_init(&s->container, "pci-container", PCIE500_ALL_SIZE);
+    memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h,
+                          "pci-conf-idx", 4);
+    memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h,
+                          "pci-conf-data", 4);
+    memory_region_init_io(&s->iomem, &e500_pci_reg_ops, s,
+                          "pci.reg", PCIE500_REG_SIZE);
+    memory_region_add_subregion(&s->container, PCIE500_CFGADDR, &h->conf_mem);
+    memory_region_add_subregion(&s->container, PCIE500_CFGDATA, &h->data_mem);
+    memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem);
+    sysbus_init_mmio(dev, &s->container);
+
+    return 0;
+}
+
+static void mpc8540_host_bridge_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -350,33 +410,70 @@ static void e500_host_bridge_class_init(ObjectClass 
*klass, void *data)
     dc->desc = "Host bridge";
 }
 
-static TypeInfo e500_host_bridge_info = {
-    .name          = "e500-host-bridge",
+static TypeInfo mpc8540_host_bridge_info = {
+    .name          = "mpc8540-host-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = mpc8540_host_bridge_class_init,
+};
+
+static void mpc8540_pcihost_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mpc8540_pcihost_initfn;
+    dc->vmsd = &vmstate_ppce500_pci;
+}
+
+static TypeInfo mpc8540_pcihost_info = {
+    .name          = "fsl,mpc8540-pci",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PPCE500PCIState),
+    .class_init    = mpc8540_pcihost_class_init,
+};
+
+static void p4080_host_bridge_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->vendor_id = PCI_VENDOR_ID_FREESCALE;
+    k->device_id = PCI_DEVICE_ID_P4080E;
+    k->class_id = PCI_CLASS_PROCESSOR_POWERPC;
+    dc->desc = "Host bridge";
+}
+
+static TypeInfo p4080_host_bridge_info = {
+    .name          = "p4080-host-bridge",
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(PCIDevice),
-    .class_init    = e500_host_bridge_class_init,
+    .class_init    = p4080_host_bridge_class_init,
 };
 
-static void e500_pcihost_class_init(ObjectClass *klass, void *data)
+static void p4080_pcihost_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = e500_pcihost_initfn;
+    k->init = p4080_pcihost_initfn;
     dc->vmsd = &vmstate_ppce500_pci;
 }
 
-static TypeInfo e500_pcihost_info = {
-    .name          = "e500-pcihost",
+static TypeInfo p4080_pcihost_info = {
+    .name          = "fsl,p4080-pcie",
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(PPCE500PCIState),
-    .class_init    = e500_pcihost_class_init,
+    .class_init    = p4080_pcihost_class_init,
 };
 
 static void e500_pci_register_types(void)
 {
-    type_register_static(&e500_pcihost_info);
-    type_register_static(&e500_host_bridge_info);
+    type_register_static(&mpc8540_pcihost_info);
+    type_register_static(&mpc8540_host_bridge_info);
+
+    type_register_static(&p4080_pcihost_info);
+    type_register_static(&p4080_host_bridge_info);
 }
 
 type_init(e500_pci_register_types)
-- 
1.7.9.5


--
Bluecherry: http://www.bluecherrydvr.com/
SwissDisk : http://www.swissdisk.com/
Ubuntu    : http://www.ubuntu.com/
My Blog   : http://ben-collins.blogspot.com/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]