1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29: #include "hw.h"
30: #include "pci.h"
31: typedef target_phys_addr_t pci_addr_t;
32: #include "pci_host.h"
33:
34: typedef PCIHostState APBState;
35:
36: static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
37: uint32_t val)
38: {
39: APBState *s = opaque;
40: int i;
41:
42: for (i = 11; i < 32; i++) {
43: if ((val & (1 << i)) != 0)
44: break;
45: }
46: s->config_reg = (1 << 16) | (val & 0x7FC) | (i << 11);
47: }
48:
49: static uint32_t pci_apb_config_readl (void *opaque,
50: target_phys_addr_t addr)
51: {
52: APBState *s = opaque;
53: uint32_t val;
54: int devfn;
55:
56: devfn = (s->config_reg >> 8) & 0xFF;
57: val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
58: return val;
59: }
60:
61: static CPUWriteMemoryFunc *pci_apb_config_write[] = {
62: &pci_apb_config_writel,
63: &pci_apb_config_writel,
64: &pci_apb_config_writel,
65: };
66:
67: static CPUReadMemoryFunc *pci_apb_config_read[] = {
68: &pci_apb_config_readl,
69: &pci_apb_config_readl,
70: &pci_apb_config_readl,
71: };
72:
73: static void apb_config_writel (void *opaque, target_phys_addr_t addr,
74: uint32_t val)
75: {
76:
77:
78: switch (addr & 0x3f) {
79: case 0x00:
80: case 0x10:
81: case 0x18:
82: case 0x20:
83: case 0x28:
84:
85: default:
86: break;
87: }
88: }
89:
90: static uint32_t apb_config_readl (void *opaque,
91: target_phys_addr_t addr)
92: {
93:
94: uint32_t val;
95:
96: switch (addr & 0x3f) {
97: case 0x00:
98: case 0x10:
99: case 0x18:
100: case 0x20:
101: case 0x28:
102:
103: default:
104: val = 0;
105: break;
106: }
107: return val;
108: }
109:
110: static CPUWriteMemoryFunc *apb_config_write[] = {
111: &apb_config_writel,
112: &apb_config_writel,
113: &apb_config_writel,
114: };
115:
116: static CPUReadMemoryFunc *apb_config_read[] = {
117: &apb_config_readl,
118: &apb_config_readl,
119: &apb_config_readl,
120: };
121:
122: static CPUWriteMemoryFunc *pci_apb_write[] = {
123: &pci_host_data_writeb,
124: &pci_host_data_writew,
125: &pci_host_data_writel,
126: };
127:
128: static CPUReadMemoryFunc *pci_apb_read[] = {
129: &pci_host_data_readb,
130: &pci_host_data_readw,
131: &pci_host_data_readl,
132: };
133:
134: static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
135: uint32_t val)
136: {
137: cpu_outb(NULL, addr & 0xffff, val);
138: }
139:
140: static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
141: uint32_t val)
142: {
143: cpu_outw(NULL, addr & 0xffff, val);
144: }
145:
146: static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
147: uint32_t val)
148: {
149: cpu_outl(NULL, addr & 0xffff, val);
150: }
151:
152: static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
153: {
154: uint32_t val;
155:
156: val = cpu_inb(NULL, addr & 0xffff);
157: return val;
158: }
159:
160: static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
161: {
162: uint32_t val;
163:
164: val = cpu_inw(NULL, addr & 0xffff);
165: return val;
166: }
167:
168: static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
169: {
170: uint32_t val;
171:
172: val = cpu_inl(NULL, addr & 0xffff);
173: return val;
174: }
175:
176: static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
177: &pci_apb_iowriteb,
178: &pci_apb_iowritew,
179: &pci_apb_iowritel,
180: };
181:
182: static CPUReadMemoryFunc *pci_apb_ioread[] = {
183: &pci_apb_ioreadb,
184: &pci_apb_ioreadw,
185: &pci_apb_ioreadl,
186: };
187:
188:
189: static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
190: {
191: return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
192: }
193:
194: static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
195: {
196: int bus_offset;
197: if (pci_dev->devfn & 1)
198: bus_offset = 16;
199: else
200: bus_offset = 0;
201: return bus_offset + irq_num;
202: }
203:
204: static void pci_apb_set_irq(qemu_irq *pic, int irq_num, int level)
205: {
206:
207: qemu_set_irq(pic[irq_num], level);
208: }
209:
210: PCIBus *pci_apb_init(target_phys_addr_t special_base,
211: target_phys_addr_t mem_base,
212: qemu_irq *pic)
213: {
214: APBState *s;
215: PCIDevice *d;
216: int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
217: PCIBus *secondary;
218:
219: s = qemu_mallocz(sizeof(APBState));
220:
221: s->bus = pci_register_bus(pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32);
222:
223: pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
224: pci_apb_config_write, s);
225: apb_config = cpu_register_io_memory(0, apb_config_read,
226: apb_config_write, s);
227: pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
228: pci_apb_write, s);
229: pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
230: pci_apb_iowrite, s);
231:
232: cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
233: cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
234: cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
235: cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data);
236:
237: d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
238: 0, NULL, NULL);
239: d->config[0x00] = 0x8e;
240: d->config[0x01] = 0x10;
241: d->config[0x02] = 0x00;
242: d->config[0x03] = 0xa0;
243: d->config[0x04] = 0x06;
244: d->config[0x05] = 0x00;
245: d->config[0x06] = 0xa0;
246: d->config[0x07] = 0x03;
247: d->config[0x08] = 0x00;
248: d->config[0x09] = 0x00;
249: d->config[0x0A] = 0x00;
250: d->config[0x0B] = 0x06;
251: d->config[0x0D] = 0x10;
252: d->config[0x0E] = 0x00;
253:
254:
255: secondary = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 1");
256: pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 2");
257: return secondary;
258: }
259:
260: