root / hw / versatile_pci.c @ c5d6edc3
History | View | Annotate | Download (3.1 kB)
1 |
/*
|
---|---|
2 |
* ARM Versatile/PB PCI host controller
|
3 |
*
|
4 |
* Copyright (c) 2006 CodeSourcery.
|
5 |
* Written by Paul Brook
|
6 |
*
|
7 |
* This code is licenced under the LGPL.
|
8 |
*/
|
9 |
|
10 |
#include "vl.h" |
11 |
|
12 |
static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr) |
13 |
{ |
14 |
return addr & 0xf8ff; |
15 |
} |
16 |
|
17 |
static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr, |
18 |
uint32_t val) |
19 |
{ |
20 |
pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1);
|
21 |
} |
22 |
|
23 |
static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr, |
24 |
uint32_t val) |
25 |
{ |
26 |
#ifdef TARGET_WORDS_BIGENDIAN
|
27 |
val = bswap16(val); |
28 |
#endif
|
29 |
pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2);
|
30 |
} |
31 |
|
32 |
static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr, |
33 |
uint32_t val) |
34 |
{ |
35 |
#ifdef TARGET_WORDS_BIGENDIAN
|
36 |
val = bswap32(val); |
37 |
#endif
|
38 |
pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4);
|
39 |
} |
40 |
|
41 |
static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr) |
42 |
{ |
43 |
uint32_t val; |
44 |
val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1);
|
45 |
return val;
|
46 |
} |
47 |
|
48 |
static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr) |
49 |
{ |
50 |
uint32_t val; |
51 |
val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2);
|
52 |
#ifdef TARGET_WORDS_BIGENDIAN
|
53 |
val = bswap16(val); |
54 |
#endif
|
55 |
return val;
|
56 |
} |
57 |
|
58 |
static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr) |
59 |
{ |
60 |
uint32_t val; |
61 |
val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4);
|
62 |
#ifdef TARGET_WORDS_BIGENDIAN
|
63 |
val = bswap32(val); |
64 |
#endif
|
65 |
return val;
|
66 |
} |
67 |
|
68 |
static CPUWriteMemoryFunc *pci_vpb_config_write[] = {
|
69 |
&pci_vpb_config_writeb, |
70 |
&pci_vpb_config_writew, |
71 |
&pci_vpb_config_writel, |
72 |
}; |
73 |
|
74 |
static CPUReadMemoryFunc *pci_vpb_config_read[] = {
|
75 |
&pci_vpb_config_readb, |
76 |
&pci_vpb_config_readw, |
77 |
&pci_vpb_config_readl, |
78 |
}; |
79 |
|
80 |
static void pci_vpb_set_irq(PCIDevice *d, void *pic, int irq_num, int level) |
81 |
{ |
82 |
pic_set_irq_new(pic, 27 + irq_num, level);
|
83 |
} |
84 |
|
85 |
PCIBus *pci_vpb_init(void *pic)
|
86 |
{ |
87 |
PCIBus *s; |
88 |
PCIDevice *d; |
89 |
int mem_config;
|
90 |
|
91 |
s = pci_register_bus(pci_vpb_set_irq, pic, 11 << 3); |
92 |
/* ??? Register memory space. */
|
93 |
|
94 |
mem_config = cpu_register_io_memory(0, pci_vpb_config_read,
|
95 |
pci_vpb_config_write, s); |
96 |
/* Selfconfig area. */
|
97 |
cpu_register_physical_memory(0x41000000, 0x10000, mem_config); |
98 |
/* Normal config area. */
|
99 |
cpu_register_physical_memory(0x42000000, 0x10000, mem_config); |
100 |
|
101 |
d = pci_register_device(s, "Versatile/PB PCI Controller",
|
102 |
sizeof(PCIDevice), -1, NULL, NULL); |
103 |
d->config[0x00] = 0xee; // vendor_id |
104 |
d->config[0x01] = 0x10; |
105 |
d->config[0x02] = 0x00; // device_id |
106 |
d->config[0x03] = 0x03; |
107 |
d->config[0x04] = 0x00; |
108 |
d->config[0x05] = 0x00; |
109 |
d->config[0x06] = 0x20; |
110 |
d->config[0x07] = 0x02; |
111 |
d->config[0x08] = 0x00; // revision |
112 |
d->config[0x09] = 0x00; // programming i/f |
113 |
d->config[0x0A] = 0x40; // class_sub = pci host |
114 |
d->config[0x0B] = 0x0b; // class_base = PCI_bridge |
115 |
d->config[0x0D] = 0x10; // latency_timer |
116 |
|
117 |
return s;
|
118 |
} |
119 |
|