X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=hw%2Fversatile_pci.c;h=5eb26251a39891ebca54b331fbffe515cb3defbf;hb=1452411b25fb207e7f442e5a5128f34b4939d31c;hp=1f4c1f30ff7b9865bbd6dd5fde4b0dee40079d0d;hpb=1d6198c3b01619151f3227c6461b3d53eeb711e5;p=qemu.git diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 1f4c1f30f..5eb26251a 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) { @@ -79,8 +85,6 @@ static CPUReadMemoryFunc *pci_vpb_config_read[] = { &pci_vpb_config_readl, }; -static int pci_vpb_irq; - static int pci_vpb_map_irq(PCIDevice *d, int irq_num) { return irq_num; @@ -88,56 +92,79 @@ static int pci_vpb_map_irq(PCIDevice *d, int irq_num) static void pci_vpb_set_irq(qemu_irq *pic, int irq_num, int level) { - qemu_set_irq(pic[pci_vpb_irq + irq_num], level); + qemu_set_irq(pic[irq_num], level); } -PCIBus *pci_vpb_init(qemu_irq *pic, int irq, 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; - - pci_vpb_irq = irq; - if (realview) { - base = 0x60000000; - name = "RealView EB PCI Controller"; - } else { - base = 0x40000000; - name = "Versatile/PB PCI Controller"; - } - s = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, pic, 11 << 3, 4); - /* ??? Register memory space. */ - - mem_config = cpu_register_io_memory(0, pci_vpb_config_read, - pci_vpb_config_write, s); + PCIVPBState *s = (PCIVPBState *)dev; /* Selfconfig area. */ - cpu_register_physical_memory(base + 0x01000000, 0x1000000, mem_config); + cpu_register_physical_memory(base + 0x01000000, 0x1000000, s->mem_config); /* Normal config area. */ - cpu_register_physical_memory(base + 0x02000000, 0x1000000, mem_config); + cpu_register_physical_memory(base + 0x02000000, 0x1000000, s->mem_config); - d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL); - - if (realview) { + 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; - d->config[0x00] = 0xee; // vendor_id - d->config[0x01] = 0x10; + for (i = 0; i < 4; i++) { + sysbus_init_irq(dev, &s->irq[i]); + } + bus = pci_register_bus(&dev->qdev, "pci", + pci_vpb_set_irq, pci_vpb_map_irq, s->irq, + 11 << 3, 4); + + /* ??? Register memory space. */ + + s->mem_config = cpu_register_io_memory(pci_vpb_config_read, + pci_vpb_config_write, bus); + sysbus_init_mmio_cb(dev, 0x04000000, pci_vpb_map); + + pci_create_simple(bus, -1, "versatile_pci_host"); +} + +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. */ - d->config[0x02] = 0x00; // device_id - d->config[0x03] = 0x03; + pci_config_set_device_id(d->config, PCI_DEVICE_ID_XILINX_XC2VP30); d->config[0x04] = 0x00; d->config[0x05] = 0x00; d->config[0x06] = 0x20; d->config[0x07] = 0x02; d->config[0x08] = 0x00; // revision d->config[0x09] = 0x00; // programming i/f - d->config[0x0A] = 0x40; // class_sub = pci host - d->config[0x0B] = 0x0b; // class_base = PCI_bridge + pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO); d->config[0x0D] = 0x10; // latency_timer +} + +static PCIDeviceInfo versatile_pci_host_info = { + .qdev.name = "versatile_pci_host", + .qdev.size = sizeof(PCIDevice), + .init = versatile_pci_host_init, +}; - 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_info); } + +device_init(versatile_pci_register_devices)