diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/primecell.h | 3 | ||||
-rw-r--r-- | hw/realview.c | 5 | ||||
-rw-r--r-- | hw/versatile_pci.c | 86 | ||||
-rw-r--r-- | hw/versatilepb.c | 5 |
4 files changed, 62 insertions, 37 deletions
diff --git a/hw/primecell.h b/hw/primecell.h index 477c2cbb64..7d8aa04f4f 100644 --- a/hw/primecell.h +++ b/hw/primecell.h @@ -26,7 +26,4 @@ extern qemu_irq *mpcore_irq_init(qemu_irq *cpu_irq); /* arm_sysctl.c */ void arm_sysctl_init(uint32_t base, uint32_t sys_id); -/* versatile_pci.c */ -PCIBus *pci_vpb_init(qemu_irq *pic, int realview); - #endif diff --git a/hw/realview.c b/hw/realview.c index a482487de2..5d7073a946 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -32,6 +32,7 @@ static void realview_init(ram_addr_t ram_size, CPUState *env; ram_addr_t ram_offset; qemu_irq *pic; + DeviceState *dev; PCIBus *pci_bus; NICInfo *nd; int n; @@ -100,7 +101,9 @@ static void realview_init(ram_addr_t ram_size, sysbus_create_simple("pl031", 0x10017000, pic[10]); - pci_bus = pci_vpb_init(pic + 48, 1); + dev = sysbus_create_varargs("realview_pci", 0x60000000, + pic[48], pic[49], pic[50], pic[51], NULL); + pci_bus = qdev_get_child_bus(dev, "pci"); if (usb_enabled) { usb_ohci_init_pci(pci_bus, 3, -1); } 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) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 13a8e19401..ecbd3bf2e3 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -199,7 +199,10 @@ static void versatile_init(ram_addr_t ram_size, sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]); sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]); - pci_bus = pci_vpb_init(sic + 27, 0); + dev = sysbus_create_varargs("versatile_pci", 0x40000000, + sic[27], sic[28], sic[29], sic[30], NULL); + pci_bus = qdev_get_child_bus(dev, "pci"); + /* The Versatile PCI bridge does not provide access to PCI IO space, so many of the qemu PCI devices are not useable. */ for(n = 0; n < nb_nics; n++) { |