diff options
Diffstat (limited to 'hw/versatile_pci.c')
-rw-r--r-- | hw/versatile_pci.c | 86 |
1 files changed, 54 insertions, 32 deletions
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 95ccbdfc97..720742c0e0 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -1,15 +1,21 @@ /* * ARM Versatile/PB PCI host controller * - * Copyright (c) 2006 CodeSourcery. + * Copyright (c) 2006-2009 CodeSourcery. * Written by Paul Brook * * This code is licenced under the LGPL. */ -#include "hw.h" +#include "sysbus.h" #include "pci.h" -#include "primecell.h" + +typedef struct { + SysBusDevice busdev; + qemu_irq irq[4]; + int realview; + int mem_config; +} PCIVPBState; static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr) { @@ -89,44 +95,51 @@ static void pci_vpb_set_irq(qemu_irq *pic, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } -PCIBus *pci_vpb_init(qemu_irq *pic, int realview) +static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base) { - PCIBus *s; - PCIDevice *d; - int mem_config; - uint32_t base; - const char * name; - qemu_irq *irqs; + PCIVPBState *s = (PCIVPBState *)dev; + /* Selfconfig area. */ + cpu_register_physical_memory(base + 0x01000000, 0x1000000, s->mem_config); + /* Normal config area. */ + cpu_register_physical_memory(base + 0x02000000, 0x1000000, s->mem_config); + + if (s->realview) { + /* IO memory area. */ + isa_mmio_init(base + 0x03000000, 0x00100000); + } +} + +static void pci_vpb_init(SysBusDevice *dev) +{ + PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); + PCIBus *bus; int i; - irqs = qemu_mallocz(sizeof(qemu_irq) * 4); for (i = 0; i < 4; i++) { - irqs[i] = pic[i]; - } - if (realview) { - base = 0x60000000; - name = "RealView EB PCI Controller"; - } else { - base = 0x40000000; - name = "Versatile/PB PCI Controller"; + sysbus_init_irq(dev, &s->irq[i]); } - s = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, irqs, 11 << 3, 4); + bus = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, s->irq, + 11 << 3, 4); + qdev_attach_child_bus(&dev->qdev, "pci", bus); + /* ??? Register memory space. */ - mem_config = cpu_register_io_memory(0, pci_vpb_config_read, - pci_vpb_config_write, s); - /* Selfconfig area. */ - cpu_register_physical_memory(base + 0x01000000, 0x1000000, mem_config); - /* Normal config area. */ - cpu_register_physical_memory(base + 0x02000000, 0x1000000, mem_config); + s->mem_config = cpu_register_io_memory(0, pci_vpb_config_read, + pci_vpb_config_write, bus); + sysbus_init_mmio_cb(dev, 0x04000000, pci_vpb_map); - d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL); + pci_create_simple(bus, -1, "versatile_pci_host"); +} - if (realview) { - /* IO memory area. */ - isa_mmio_init(base + 0x03000000, 0x00100000); - } +static void pci_realview_init(SysBusDevice *dev) +{ + PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); + s->realview = 1; + pci_vpb_init(dev); +} +static void versatile_pci_host_init(PCIDevice *d) +{ pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX); /* Both boards have the same device ID. Oh well. */ pci_config_set_device_id(d->config, PCI_DEVICE_ID_XILINX_XC2VP30); @@ -138,6 +151,15 @@ PCIBus *pci_vpb_init(qemu_irq *pic, int realview) d->config[0x09] = 0x00; // programming i/f pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO); d->config[0x0D] = 0x10; // latency_timer +} - return s; +static void versatile_pci_register_devices(void) +{ + sysbus_register_dev("versatile_pci", sizeof(PCIVPBState), pci_vpb_init); + sysbus_register_dev("realview_pci", sizeof(PCIVPBState), + pci_realview_init); + pci_qdev_register("versatile_pci_host", sizeof(PCIDevice), + versatile_pci_host_init); } + +device_init(versatile_pci_register_devices) |