Statistics
| Branch: | Revision:

root / hw / versatile_pci.c @ 1de7afc9

History | View | Annotate | Download (4.2 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 a2cb15b0 Michael S. Tsirkin
#include "pci/pci.h"
12 a2cb15b0 Michael S. Tsirkin
#include "pci/pci_host.h"
13 022c62cb Paolo Bonzini
#include "exec/address-spaces.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 a8170e5e Avi Kivity
static inline uint32_t vpb_pci_config_addr(hwaddr addr)
25 502a5395 pbrook
{
26 80b3ada7 pbrook
    return addr & 0xffffff;
27 502a5395 pbrook
}
28 502a5395 pbrook
29 a8170e5e Avi Kivity
static void pci_vpb_config_write(void *opaque, hwaddr 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 a8170e5e Avi Kivity
static uint64_t pci_vpb_config_read(void *opaque, hwaddr 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 40021f08 Anthony Liguori
static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
113 40021f08 Anthony Liguori
{
114 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
115 40021f08 Anthony Liguori
116 40021f08 Anthony Liguori
    k->init = versatile_pci_host_init;
117 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_XILINX;
118 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
119 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_PROCESSOR_CO;
120 40021f08 Anthony Liguori
}
121 40021f08 Anthony Liguori
122 39bffca2 Anthony Liguori
static TypeInfo versatile_pci_host_info = {
123 39bffca2 Anthony Liguori
    .name          = "versatile_pci_host",
124 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
125 39bffca2 Anthony Liguori
    .instance_size = sizeof(PCIDevice),
126 39bffca2 Anthony Liguori
    .class_init    = versatile_pci_host_class_init,
127 0aab0d3a Gerd Hoffmann
};
128 0aab0d3a Gerd Hoffmann
129 999e12bb Anthony Liguori
static void pci_vpb_class_init(ObjectClass *klass, void *data)
130 999e12bb Anthony Liguori
{
131 999e12bb Anthony Liguori
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
132 999e12bb Anthony Liguori
133 999e12bb Anthony Liguori
    sdc->init = pci_vpb_init;
134 999e12bb Anthony Liguori
}
135 999e12bb Anthony Liguori
136 39bffca2 Anthony Liguori
static TypeInfo pci_vpb_info = {
137 39bffca2 Anthony Liguori
    .name          = "versatile_pci",
138 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
139 39bffca2 Anthony Liguori
    .instance_size = sizeof(PCIVPBState),
140 39bffca2 Anthony Liguori
    .class_init    = pci_vpb_class_init,
141 999e12bb Anthony Liguori
};
142 999e12bb Anthony Liguori
143 999e12bb Anthony Liguori
static void pci_realview_class_init(ObjectClass *klass, void *data)
144 999e12bb Anthony Liguori
{
145 999e12bb Anthony Liguori
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
146 999e12bb Anthony Liguori
147 999e12bb Anthony Liguori
    sdc->init = pci_realview_init;
148 999e12bb Anthony Liguori
}
149 999e12bb Anthony Liguori
150 39bffca2 Anthony Liguori
static TypeInfo pci_realview_info = {
151 39bffca2 Anthony Liguori
    .name          = "realview_pci",
152 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
153 39bffca2 Anthony Liguori
    .instance_size = sizeof(PCIVPBState),
154 39bffca2 Anthony Liguori
    .class_init    = pci_realview_class_init,
155 999e12bb Anthony Liguori
};
156 999e12bb Anthony Liguori
157 83f7d43a Andreas Färber
static void versatile_pci_register_types(void)
158 0027b06d Paul Brook
{
159 39bffca2 Anthony Liguori
    type_register_static(&pci_vpb_info);
160 39bffca2 Anthony Liguori
    type_register_static(&pci_realview_info);
161 39bffca2 Anthony Liguori
    type_register_static(&versatile_pci_host_info);
162 502a5395 pbrook
}
163 0027b06d Paul Brook
164 83f7d43a Andreas Färber
type_init(versatile_pci_register_types)