2
2
* ARM Versatile/PB PCI host controller
4
* Copyright (c) 2006 CodeSourcery.
4
* Copyright (c) 2006-2009 CodeSourcery.
5
5
* Written by Paul Brook
7
* This code is licenced under the LGPL.
7
* This code is licensed under the LGPL.
12
#include "primecell.h"
13
#include "exec-memory.h"
19
MemoryRegion mem_config;
20
MemoryRegion mem_config2;
14
24
static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
16
26
return addr & 0xffffff;
19
static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr,
22
pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1);
25
static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr,
28
#ifdef TARGET_WORDS_BIGENDIAN
31
pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2);
34
static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr,
37
#ifdef TARGET_WORDS_BIGENDIAN
40
pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4);
43
static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr)
46
val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1);
50
static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr)
53
val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2);
54
#ifdef TARGET_WORDS_BIGENDIAN
60
static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr)
63
val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4);
64
#ifdef TARGET_WORDS_BIGENDIAN
70
static CPUWriteMemoryFunc *pci_vpb_config_write[] = {
71
&pci_vpb_config_writeb,
72
&pci_vpb_config_writew,
73
&pci_vpb_config_writel,
76
static CPUReadMemoryFunc *pci_vpb_config_read[] = {
77
&pci_vpb_config_readb,
78
&pci_vpb_config_readw,
79
&pci_vpb_config_readl,
82
static int pci_vpb_irq;
29
static void pci_vpb_config_write(void *opaque, target_phys_addr_t addr,
30
uint64_t val, unsigned size)
32
pci_data_write(opaque, vpb_pci_config_addr(addr), val, size);
35
static uint64_t pci_vpb_config_read(void *opaque, target_phys_addr_t addr,
39
val = pci_data_read(opaque, vpb_pci_config_addr(addr), size);
43
static const MemoryRegionOps pci_vpb_config_ops = {
44
.read = pci_vpb_config_read,
45
.write = pci_vpb_config_write,
46
.endianness = DEVICE_NATIVE_ENDIAN,
84
49
static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
89
static void pci_vpb_set_irq(qemu_irq *pic, int irq_num, int level)
54
static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
91
qemu_set_irq(pic[pci_vpb_irq + irq_num], level);
56
qemu_irq *pic = opaque;
58
qemu_set_irq(pic[irq_num], level);
94
PCIBus *pci_vpb_init(qemu_irq *pic, int irq, int realview)
61
static int pci_vpb_init(SysBusDevice *dev)
63
PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
105
name = "RealView EB PCI Controller";
108
name = "Versatile/PB PCI Controller";
67
for (i = 0; i < 4; i++) {
68
sysbus_init_irq(dev, &s->irq[i]);
110
s = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, pic, 11 << 3, 4);
70
bus = pci_register_bus(&dev->qdev, "pci",
71
pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
72
get_system_memory(), get_system_io(),
111
75
/* ??? Register memory space. */
113
mem_config = cpu_register_io_memory(0, pci_vpb_config_read,
114
pci_vpb_config_write, s);
115
/* Selfconfig area. */
116
cpu_register_physical_memory(base + 0x01000000, 0x1000000, mem_config);
117
/* Normal config area. */
118
cpu_register_physical_memory(base + 0x02000000, 0x1000000, mem_config);
120
d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL);
123
/* IO memory area. */
124
isa_mmio_init(base + 0x03000000, 0x00100000);
77
/* Our memory regions are:
78
* 0 : PCI self config window
79
* 1 : PCI config window
80
* 2 : PCI IO window (realview_pci only)
82
memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
83
"pci-vpb-selfconfig", 0x1000000);
84
sysbus_init_mmio(dev, &s->mem_config);
85
memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
86
"pci-vpb-config", 0x1000000);
87
sysbus_init_mmio(dev, &s->mem_config2);
89
isa_mmio_setup(&s->isa, 0x0100000);
90
sysbus_init_mmio(dev, &s->isa);
127
pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX);
128
/* Both boards have the same device ID. Oh well. */
129
pci_config_set_device_id(d->config, 0x0300); // device_id
130
d->config[0x04] = 0x00;
131
d->config[0x05] = 0x00;
132
d->config[0x06] = 0x20;
133
d->config[0x07] = 0x02;
134
d->config[0x08] = 0x00; // revision
135
d->config[0x09] = 0x00; // programming i/f
136
pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO);
137
d->config[0x0D] = 0x10; // latency_timer
93
pci_create_simple(bus, -1, "versatile_pci_host");
97
static int pci_realview_init(SysBusDevice *dev)
99
PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
101
return pci_vpb_init(dev);
104
static int versatile_pci_host_init(PCIDevice *d)
106
pci_set_word(d->config + PCI_STATUS,
107
PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
108
pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10);
112
static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
114
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
116
k->init = versatile_pci_host_init;
117
k->vendor_id = PCI_VENDOR_ID_XILINX;
118
k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
119
k->class_id = PCI_CLASS_PROCESSOR_CO;
122
static TypeInfo versatile_pci_host_info = {
123
.name = "versatile_pci_host",
124
.parent = TYPE_PCI_DEVICE,
125
.instance_size = sizeof(PCIDevice),
126
.class_init = versatile_pci_host_class_init,
129
static void pci_vpb_class_init(ObjectClass *klass, void *data)
131
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
133
sdc->init = pci_vpb_init;
136
static TypeInfo pci_vpb_info = {
137
.name = "versatile_pci",
138
.parent = TYPE_SYS_BUS_DEVICE,
139
.instance_size = sizeof(PCIVPBState),
140
.class_init = pci_vpb_class_init,
143
static void pci_realview_class_init(ObjectClass *klass, void *data)
145
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
147
sdc->init = pci_realview_init;
150
static TypeInfo pci_realview_info = {
151
.name = "realview_pci",
152
.parent = TYPE_SYS_BUS_DEVICE,
153
.instance_size = sizeof(PCIVPBState),
154
.class_init = pci_realview_class_init,
157
static void versatile_pci_register_types(void)
159
type_register_static(&pci_vpb_info);
160
type_register_static(&pci_realview_info);
161
type_register_static(&versatile_pci_host_info);
164
type_init(versatile_pci_register_types)