Statistics
| Branch: | Revision:

root / hw / versatile_pci.c @ c09015dd

History | View | Annotate | Download (3.5 kB)

1 5fafdf24 ths
/*
2 502a5395 pbrook
 * ARM Versatile/PB PCI host controller
3 502a5395 pbrook
 *
4 0027b06d Paul Brook
 * Copyright (c) 2006-2009 CodeSourcery.
5 502a5395 pbrook
 * Written by Paul Brook
6 502a5395 pbrook
 *
7 8e31bf38 Matthew Fernandez
 * This code is licensed under the LGPL.
8 502a5395 pbrook
 */
9 502a5395 pbrook
10 0027b06d Paul Brook
#include "sysbus.h"
11 87ecb68b pbrook
#include "pci.h"
12 b6243d99 Isaku Yamahata
#include "pci_host.h"
13 1e39101c Avi Kivity
#include "exec-memory.h"
14 0027b06d Paul Brook
15 0027b06d Paul Brook
typedef struct {
16 0027b06d Paul Brook
    SysBusDevice busdev;
17 0027b06d Paul Brook
    qemu_irq irq[4];
18 0027b06d Paul Brook
    int realview;
19 45de094e Avi Kivity
    MemoryRegion mem_config;
20 45de094e Avi Kivity
    MemoryRegion mem_config2;
21 45de094e Avi Kivity
    MemoryRegion isa;
22 0027b06d Paul Brook
} PCIVPBState;
23 502a5395 pbrook
24 c227f099 Anthony Liguori
static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
25 502a5395 pbrook
{
26 80b3ada7 pbrook
    return addr & 0xffffff;
27 502a5395 pbrook
}
28 502a5395 pbrook
29 45de094e Avi Kivity
static void pci_vpb_config_write(void *opaque, target_phys_addr_t addr,
30 45de094e Avi Kivity
                                 uint64_t val, unsigned size)
31 502a5395 pbrook
{
32 45de094e Avi Kivity
    pci_data_write(opaque, vpb_pci_config_addr(addr), val, size);
33 502a5395 pbrook
}
34 502a5395 pbrook
35 45de094e Avi Kivity
static uint64_t pci_vpb_config_read(void *opaque, target_phys_addr_t addr,
36 45de094e Avi Kivity
                                    unsigned size)
37 502a5395 pbrook
{
38 502a5395 pbrook
    uint32_t val;
39 45de094e Avi Kivity
    val = pci_data_read(opaque, vpb_pci_config_addr(addr), size);
40 502a5395 pbrook
    return val;
41 502a5395 pbrook
}
42 502a5395 pbrook
43 45de094e Avi Kivity
static const MemoryRegionOps pci_vpb_config_ops = {
44 45de094e Avi Kivity
    .read = pci_vpb_config_read,
45 45de094e Avi Kivity
    .write = pci_vpb_config_write,
46 45de094e Avi Kivity
    .endianness = DEVICE_NATIVE_ENDIAN,
47 502a5395 pbrook
};
48 502a5395 pbrook
49 d2b59317 pbrook
static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
50 d2b59317 pbrook
{
51 d2b59317 pbrook
    return irq_num;
52 d2b59317 pbrook
}
53 d2b59317 pbrook
54 5d4e84c8 Juan Quintela
static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
55 502a5395 pbrook
{
56 5d4e84c8 Juan Quintela
    qemu_irq *pic = opaque;
57 5d4e84c8 Juan Quintela
58 97aff481 Paul Brook
    qemu_set_irq(pic[irq_num], level);
59 502a5395 pbrook
}
60 502a5395 pbrook
61 81a322d4 Gerd Hoffmann
static int pci_vpb_init(SysBusDevice *dev)
62 0027b06d Paul Brook
{
63 0027b06d Paul Brook
    PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
64 0027b06d Paul Brook
    PCIBus *bus;
65 97aff481 Paul Brook
    int i;
66 e69954b9 pbrook
67 97aff481 Paul Brook
    for (i = 0; i < 4; i++) {
68 0027b06d Paul Brook
        sysbus_init_irq(dev, &s->irq[i]);
69 e69954b9 pbrook
    }
70 02e2da45 Paul Brook
    bus = pci_register_bus(&dev->qdev, "pci",
71 02e2da45 Paul Brook
                           pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
72 aee97b84 Avi Kivity
                           get_system_memory(), get_system_io(),
73 520128bd Isaku Yamahata
                           PCI_DEVFN(11, 0), 4);
74 0027b06d Paul Brook
75 502a5395 pbrook
    /* ??? Register memory space.  */
76 502a5395 pbrook
77 7d6e771f Peter Maydell
    /* Our memory regions are:
78 7d6e771f Peter Maydell
     * 0 : PCI self config window
79 7d6e771f Peter Maydell
     * 1 : PCI config window
80 7d6e771f Peter Maydell
     * 2 : PCI IO window (realview_pci only)
81 7d6e771f Peter Maydell
     */
82 45de094e Avi Kivity
    memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
83 45de094e Avi Kivity
                          "pci-vpb-selfconfig", 0x1000000);
84 750ecd44 Avi Kivity
    sysbus_init_mmio(dev, &s->mem_config);
85 45de094e Avi Kivity
    memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
86 45de094e Avi Kivity
                          "pci-vpb-config", 0x1000000);
87 750ecd44 Avi Kivity
    sysbus_init_mmio(dev, &s->mem_config2);
88 45de094e Avi Kivity
    if (s->realview) {
89 45de094e Avi Kivity
        isa_mmio_setup(&s->isa, 0x0100000);
90 750ecd44 Avi Kivity
        sysbus_init_mmio(dev, &s->isa);
91 45de094e Avi Kivity
    }
92 45de094e Avi Kivity
93 0027b06d Paul Brook
    pci_create_simple(bus, -1, "versatile_pci_host");
94 81a322d4 Gerd Hoffmann
    return 0;
95 0027b06d Paul Brook
}
96 e69954b9 pbrook
97 81a322d4 Gerd Hoffmann
static int pci_realview_init(SysBusDevice *dev)
98 0027b06d Paul Brook
{
99 0027b06d Paul Brook
    PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
100 0027b06d Paul Brook
    s->realview = 1;
101 81a322d4 Gerd Hoffmann
    return pci_vpb_init(dev);
102 0027b06d Paul Brook
}
103 502a5395 pbrook
104 81a322d4 Gerd Hoffmann
static int versatile_pci_host_init(PCIDevice *d)
105 0027b06d Paul Brook
{
106 a408b1de Michael S. Tsirkin
    pci_set_word(d->config + PCI_STATUS,
107 a408b1de Michael S. Tsirkin
                 PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
108 01764fe0 Michael S. Tsirkin
    pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10);
109 81a322d4 Gerd Hoffmann
    return 0;
110 0027b06d Paul Brook
}
111 502a5395 pbrook
112 0aab0d3a Gerd Hoffmann
static PCIDeviceInfo versatile_pci_host_info = {
113 0aab0d3a Gerd Hoffmann
    .qdev.name = "versatile_pci_host",
114 0aab0d3a Gerd Hoffmann
    .qdev.size = sizeof(PCIDevice),
115 0aab0d3a Gerd Hoffmann
    .init      = versatile_pci_host_init,
116 56fe6408 Isaku Yamahata
    .vendor_id = PCI_VENDOR_ID_XILINX,
117 56fe6408 Isaku Yamahata
    /* Both boards have the same device ID.  Oh well.  */
118 56fe6408 Isaku Yamahata
    .device_id = PCI_DEVICE_ID_XILINX_XC2VP30,
119 56fe6408 Isaku Yamahata
    .class_id  = PCI_CLASS_PROCESSOR_CO,
120 0aab0d3a Gerd Hoffmann
};
121 0aab0d3a Gerd Hoffmann
122 0027b06d Paul Brook
static void versatile_pci_register_devices(void)
123 0027b06d Paul Brook
{
124 0027b06d Paul Brook
    sysbus_register_dev("versatile_pci", sizeof(PCIVPBState), pci_vpb_init);
125 0027b06d Paul Brook
    sysbus_register_dev("realview_pci", sizeof(PCIVPBState),
126 0027b06d Paul Brook
                        pci_realview_init);
127 0aab0d3a Gerd Hoffmann
    pci_qdev_register(&versatile_pci_host_info);
128 502a5395 pbrook
}
129 0027b06d Paul Brook
130 0027b06d Paul Brook
device_init(versatile_pci_register_devices)