1 | /* |
2 | * bonito north bridge support |
3 | * |
4 | * Copyright (c) 2008 yajin (yajin@vm-kernel.org) |
5 | * Copyright (c) 2010 Huacai Chen (zltjiangshi@gmail.com) |
6 | * |
7 | * This code is licensed under the GNU GPL v2. |
8 | * |
9 | * Contributions after 2012-01-13 are licensed under the terms of the |
10 | * GNU GPL, version 2 or (at your option) any later version. |
11 | */ |
12 | |
13 | /* |
14 | * fulong 2e mini pc has a bonito north bridge. |
15 | */ |
16 | |
17 | /* what is the meaning of devfn in qemu and IDSEL in bonito northbridge? |
18 | * |
19 | * devfn pci_slot<<3 + funno |
20 | * one pci bus can have 32 devices and each device can have 8 functions. |
21 | * |
22 | * In bonito north bridge, pci slot = IDSEL bit - 12. |
23 | * For example, PCI_IDSEL_VIA686B = 17, |
24 | * pci slot = 17-12=5 |
25 | * |
26 | * so |
27 | * VT686B_FUN0's devfn = (5<<3)+0 |
28 | * VT686B_FUN1's devfn = (5<<3)+1 |
29 | * |
30 | * qemu also uses pci address for north bridge to access pci config register. |
31 | * bus_no [23:16] |
32 | * dev_no [15:11] |
33 | * fun_no [10:8] |
34 | * reg_no [7:2] |
35 | * |
36 | * so function bonito_sbridge_pciaddr for the translation from |
37 | * north bridge address to pci address. |
38 | */ |
39 | |
40 | #include "qemu/osdep.h" |
41 | #include "qemu/error-report.h" |
42 | #include "hw/pci/pci.h" |
43 | #include "hw/i386/pc.h" |
44 | #include "hw/irq.h" |
45 | #include "hw/mips/mips.h" |
46 | #include "hw/pci/pci_host.h" |
47 | #include "migration/vmstate.h" |
48 | #include "sysemu/reset.h" |
49 | #include "sysemu/runstate.h" |
50 | #include "exec/address-spaces.h" |
51 | |
52 | //#define DEBUG_BONITO |
53 | |
54 | #ifdef DEBUG_BONITO |
55 | #define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) |
56 | #else |
57 | #define DPRINTF(fmt, ...) |
58 | #endif |
59 | |
60 | /* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/ |
61 | #define BONITO_BOOT_BASE 0x1fc00000 |
62 | #define BONITO_BOOT_SIZE 0x00100000 |
63 | #define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1) |
64 | #define BONITO_FLASH_BASE 0x1c000000 |
65 | #define BONITO_FLASH_SIZE 0x03000000 |
66 | #define BONITO_FLASH_TOP (BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1) |
67 | #define BONITO_SOCKET_BASE 0x1f800000 |
68 | #define BONITO_SOCKET_SIZE 0x00400000 |
69 | #define BONITO_SOCKET_TOP (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1) |
70 | #define BONITO_REG_BASE 0x1fe00000 |
71 | #define BONITO_REG_SIZE 0x00040000 |
72 | #define BONITO_REG_TOP (BONITO_REG_BASE+BONITO_REG_SIZE-1) |
73 | #define BONITO_DEV_BASE 0x1ff00000 |
74 | #define BONITO_DEV_SIZE 0x00100000 |
75 | #define BONITO_DEV_TOP (BONITO_DEV_BASE+BONITO_DEV_SIZE-1) |
76 | #define BONITO_PCILO_BASE 0x10000000 |
77 | #define BONITO_PCILO_BASE_VA 0xb0000000 |
78 | #define BONITO_PCILO_SIZE 0x0c000000 |
79 | #define BONITO_PCILO_TOP (BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1) |
80 | #define BONITO_PCILO0_BASE 0x10000000 |
81 | #define BONITO_PCILO1_BASE 0x14000000 |
82 | #define BONITO_PCILO2_BASE 0x18000000 |
83 | #define BONITO_PCIHI_BASE 0x20000000 |
84 | #define BONITO_PCIHI_SIZE 0x20000000 |
85 | #define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1) |
86 | #define BONITO_PCIIO_BASE 0x1fd00000 |
87 | #define BONITO_PCIIO_BASE_VA 0xbfd00000 |
88 | #define BONITO_PCIIO_SIZE 0x00010000 |
89 | #define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1) |
90 | #define BONITO_PCICFG_BASE 0x1fe80000 |
91 | #define BONITO_PCICFG_SIZE 0x00080000 |
92 | #define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1) |
93 | |
94 | |
95 | #define BONITO_PCICONFIGBASE 0x00 |
96 | #define BONITO_REGBASE 0x100 |
97 | |
98 | #define BONITO_PCICONFIG_BASE (BONITO_PCICONFIGBASE+BONITO_REG_BASE) |
99 | #define BONITO_PCICONFIG_SIZE (0x100) |
100 | |
101 | #define BONITO_INTERNAL_REG_BASE (BONITO_REGBASE+BONITO_REG_BASE) |
102 | #define BONITO_INTERNAL_REG_SIZE (0x70) |
103 | |
104 | #define BONITO_SPCICONFIG_BASE (BONITO_PCICFG_BASE) |
105 | #define BONITO_SPCICONFIG_SIZE (BONITO_PCICFG_SIZE) |
106 | |
107 | |
108 | |
109 | /* 1. Bonito h/w Configuration */ |
110 | /* Power on register */ |
111 | |
112 | #define BONITO_BONPONCFG (0x00 >> 2) /* 0x100 */ |
113 | #define BONITO_BONGENCFG_OFFSET 0x4 |
114 | #define BONITO_BONGENCFG (BONITO_BONGENCFG_OFFSET>>2) /*0x104 */ |
115 | |
116 | /* 2. IO & IDE configuration */ |
117 | #define BONITO_IODEVCFG (0x08 >> 2) /* 0x108 */ |
118 | |
119 | /* 3. IO & IDE configuration */ |
120 | #define BONITO_SDCFG (0x0c >> 2) /* 0x10c */ |
121 | |
122 | /* 4. PCI address map control */ |
123 | #define BONITO_PCIMAP (0x10 >> 2) /* 0x110 */ |
124 | #define BONITO_PCIMEMBASECFG (0x14 >> 2) /* 0x114 */ |
125 | #define BONITO_PCIMAP_CFG (0x18 >> 2) /* 0x118 */ |
126 | |
127 | /* 5. ICU & GPIO regs */ |
128 | /* GPIO Regs - r/w */ |
129 | #define BONITO_GPIODATA_OFFSET 0x1c |
130 | #define BONITO_GPIODATA (BONITO_GPIODATA_OFFSET >> 2) /* 0x11c */ |
131 | #define BONITO_GPIOIE (0x20 >> 2) /* 0x120 */ |
132 | |
133 | /* ICU Configuration Regs - r/w */ |
134 | #define BONITO_INTEDGE (0x24 >> 2) /* 0x124 */ |
135 | #define BONITO_INTSTEER (0x28 >> 2) /* 0x128 */ |
136 | #define BONITO_INTPOL (0x2c >> 2) /* 0x12c */ |
137 | |
138 | /* ICU Enable Regs - IntEn & IntISR are r/o. */ |
139 | #define BONITO_INTENSET (0x30 >> 2) /* 0x130 */ |
140 | #define BONITO_INTENCLR (0x34 >> 2) /* 0x134 */ |
141 | #define BONITO_INTEN (0x38 >> 2) /* 0x138 */ |
142 | #define BONITO_INTISR (0x3c >> 2) /* 0x13c */ |
143 | |
144 | /* PCI mail boxes */ |
145 | #define BONITO_PCIMAIL0_OFFSET 0x40 |
146 | #define BONITO_PCIMAIL1_OFFSET 0x44 |
147 | #define BONITO_PCIMAIL2_OFFSET 0x48 |
148 | #define BONITO_PCIMAIL3_OFFSET 0x4c |
149 | #define BONITO_PCIMAIL0 (0x40 >> 2) /* 0x140 */ |
150 | #define BONITO_PCIMAIL1 (0x44 >> 2) /* 0x144 */ |
151 | #define BONITO_PCIMAIL2 (0x48 >> 2) /* 0x148 */ |
152 | #define BONITO_PCIMAIL3 (0x4c >> 2) /* 0x14c */ |
153 | |
154 | /* 6. PCI cache */ |
155 | #define BONITO_PCICACHECTRL (0x50 >> 2) /* 0x150 */ |
156 | #define BONITO_PCICACHETAG (0x54 >> 2) /* 0x154 */ |
157 | #define BONITO_PCIBADADDR (0x58 >> 2) /* 0x158 */ |
158 | #define BONITO_PCIMSTAT (0x5c >> 2) /* 0x15c */ |
159 | |
160 | /* 7. other*/ |
161 | #define BONITO_TIMECFG (0x60 >> 2) /* 0x160 */ |
162 | #define BONITO_CPUCFG (0x64 >> 2) /* 0x164 */ |
163 | #define BONITO_DQCFG (0x68 >> 2) /* 0x168 */ |
164 | #define BONITO_MEMSIZE (0x6C >> 2) /* 0x16c */ |
165 | |
166 | #define BONITO_REGS (0x70 >> 2) |
167 | |
168 | /* PCI config for south bridge. type 0 */ |
169 | #define BONITO_PCICONF_IDSEL_MASK 0xfffff800 /* [31:11] */ |
170 | #define BONITO_PCICONF_IDSEL_OFFSET 11 |
171 | #define BONITO_PCICONF_FUN_MASK 0x700 /* [10:8] */ |
172 | #define BONITO_PCICONF_FUN_OFFSET 8 |
173 | #define BONITO_PCICONF_REG_MASK 0xFC |
174 | #define BONITO_PCICONF_REG_OFFSET 0 |
175 | |
176 | |
177 | /* idsel BIT = pci slot number +12 */ |
178 | #define PCI_SLOT_BASE 12 |
179 | #define PCI_IDSEL_VIA686B_BIT (17) |
180 | #define PCI_IDSEL_VIA686B (1<<PCI_IDSEL_VIA686B_BIT) |
181 | |
182 | #define PCI_ADDR(busno,devno,funno,regno) \ |
183 | ((((busno)<<16)&0xff0000) + (((devno)<<11)&0xf800) + (((funno)<<8)&0x700) + (regno)) |
184 | |
185 | typedef struct BonitoState BonitoState; |
186 | |
187 | typedef struct PCIBonitoState |
188 | { |
189 | PCIDevice dev; |
190 | |
191 | BonitoState *pcihost; |
192 | uint32_t regs[BONITO_REGS]; |
193 | |
194 | struct bonldma { |
195 | uint32_t ldmactrl; |
196 | uint32_t ldmastat; |
197 | uint32_t ldmaaddr; |
198 | uint32_t ldmago; |
199 | } bonldma; |
200 | |
201 | /* Based at 1fe00300, bonito Copier */ |
202 | struct boncop { |
203 | uint32_t copctrl; |
204 | uint32_t copstat; |
205 | uint32_t coppaddr; |
206 | uint32_t copgo; |
207 | } boncop; |
208 | |
209 | /* Bonito registers */ |
210 | MemoryRegion iomem; |
211 | MemoryRegion iomem_ldma; |
212 | MemoryRegion iomem_cop; |
213 | MemoryRegion bonito_pciio; |
214 | MemoryRegion bonito_localio; |
215 | |
216 | } PCIBonitoState; |
217 | |
218 | struct BonitoState { |
219 | PCIHostState parent_obj; |
220 | qemu_irq *pic; |
221 | PCIBonitoState *pci_dev; |
222 | MemoryRegion pci_mem; |
223 | }; |
224 | |
225 | #define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost" |
226 | #define BONITO_PCI_HOST_BRIDGE(obj) \ |
227 | OBJECT_CHECK(BonitoState, (obj), TYPE_BONITO_PCI_HOST_BRIDGE) |
228 | |
229 | #define TYPE_PCI_BONITO "Bonito" |
230 | #define PCI_BONITO(obj) \ |
231 | OBJECT_CHECK(PCIBonitoState, (obj), TYPE_PCI_BONITO) |
232 | |
233 | static void bonito_writel(void *opaque, hwaddr addr, |
234 | uint64_t val, unsigned size) |
235 | { |
236 | PCIBonitoState *s = opaque; |
237 | uint32_t saddr; |
238 | int reset = 0; |
239 | |
240 | saddr = addr >> 2; |
241 | |
242 | DPRINTF("bonito_writel " TARGET_FMT_plx" val %x saddr %x\n" , addr, val, saddr); |
243 | switch (saddr) { |
244 | case BONITO_BONPONCFG: |
245 | case BONITO_IODEVCFG: |
246 | case BONITO_SDCFG: |
247 | case BONITO_PCIMAP: |
248 | case BONITO_PCIMEMBASECFG: |
249 | case BONITO_PCIMAP_CFG: |
250 | case BONITO_GPIODATA: |
251 | case BONITO_GPIOIE: |
252 | case BONITO_INTEDGE: |
253 | case BONITO_INTSTEER: |
254 | case BONITO_INTPOL: |
255 | case BONITO_PCIMAIL0: |
256 | case BONITO_PCIMAIL1: |
257 | case BONITO_PCIMAIL2: |
258 | case BONITO_PCIMAIL3: |
259 | case BONITO_PCICACHECTRL: |
260 | case BONITO_PCICACHETAG: |
261 | case BONITO_PCIBADADDR: |
262 | case BONITO_PCIMSTAT: |
263 | case BONITO_TIMECFG: |
264 | case BONITO_CPUCFG: |
265 | case BONITO_DQCFG: |
266 | case BONITO_MEMSIZE: |
267 | s->regs[saddr] = val; |
268 | break; |
269 | case BONITO_BONGENCFG: |
270 | if (!(s->regs[saddr] & 0x04) && (val & 0x04)) { |
271 | reset = 1; /* bit 2 jump from 0 to 1 cause reset */ |
272 | } |
273 | s->regs[saddr] = val; |
274 | if (reset) { |
275 | qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); |
276 | } |
277 | break; |
278 | case BONITO_INTENSET: |
279 | s->regs[BONITO_INTENSET] = val; |
280 | s->regs[BONITO_INTEN] |= val; |
281 | break; |
282 | case BONITO_INTENCLR: |
283 | s->regs[BONITO_INTENCLR] = val; |
284 | s->regs[BONITO_INTEN] &= ~val; |
285 | break; |
286 | case BONITO_INTEN: |
287 | case BONITO_INTISR: |
288 | DPRINTF("write to readonly bonito register %x\n" , saddr); |
289 | break; |
290 | default: |
291 | DPRINTF("write to unknown bonito register %x\n" , saddr); |
292 | break; |
293 | } |
294 | } |
295 | |
296 | static uint64_t bonito_readl(void *opaque, hwaddr addr, |
297 | unsigned size) |
298 | { |
299 | PCIBonitoState *s = opaque; |
300 | uint32_t saddr; |
301 | |
302 | saddr = addr >> 2; |
303 | |
304 | DPRINTF("bonito_readl " TARGET_FMT_plx"\n" , addr); |
305 | switch (saddr) { |
306 | case BONITO_INTISR: |
307 | return s->regs[saddr]; |
308 | default: |
309 | return s->regs[saddr]; |
310 | } |
311 | } |
312 | |
313 | static const MemoryRegionOps bonito_ops = { |
314 | .read = bonito_readl, |
315 | .write = bonito_writel, |
316 | .endianness = DEVICE_NATIVE_ENDIAN, |
317 | .valid = { |
318 | .min_access_size = 4, |
319 | .max_access_size = 4, |
320 | }, |
321 | }; |
322 | |
323 | static void bonito_pciconf_writel(void *opaque, hwaddr addr, |
324 | uint64_t val, unsigned size) |
325 | { |
326 | PCIBonitoState *s = opaque; |
327 | PCIDevice *d = PCI_DEVICE(s); |
328 | |
329 | DPRINTF("bonito_pciconf_writel " TARGET_FMT_plx" val %x\n" , addr, val); |
330 | d->config_write(d, addr, val, 4); |
331 | } |
332 | |
333 | static uint64_t bonito_pciconf_readl(void *opaque, hwaddr addr, |
334 | unsigned size) |
335 | { |
336 | |
337 | PCIBonitoState *s = opaque; |
338 | PCIDevice *d = PCI_DEVICE(s); |
339 | |
340 | DPRINTF("bonito_pciconf_readl " TARGET_FMT_plx"\n" , addr); |
341 | return d->config_read(d, addr, 4); |
342 | } |
343 | |
344 | /* north bridge PCI configure space. 0x1fe0 0000 - 0x1fe0 00ff */ |
345 | |
346 | static const MemoryRegionOps bonito_pciconf_ops = { |
347 | .read = bonito_pciconf_readl, |
348 | .write = bonito_pciconf_writel, |
349 | .endianness = DEVICE_NATIVE_ENDIAN, |
350 | .valid = { |
351 | .min_access_size = 4, |
352 | .max_access_size = 4, |
353 | }, |
354 | }; |
355 | |
356 | static uint64_t bonito_ldma_readl(void *opaque, hwaddr addr, |
357 | unsigned size) |
358 | { |
359 | uint32_t val; |
360 | PCIBonitoState *s = opaque; |
361 | |
362 | if (addr >= sizeof(s->bonldma)) { |
363 | return 0; |
364 | } |
365 | |
366 | val = ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)]; |
367 | |
368 | return val; |
369 | } |
370 | |
371 | static void bonito_ldma_writel(void *opaque, hwaddr addr, |
372 | uint64_t val, unsigned size) |
373 | { |
374 | PCIBonitoState *s = opaque; |
375 | |
376 | if (addr >= sizeof(s->bonldma)) { |
377 | return; |
378 | } |
379 | |
380 | ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)] = val & 0xffffffff; |
381 | } |
382 | |
383 | static const MemoryRegionOps bonito_ldma_ops = { |
384 | .read = bonito_ldma_readl, |
385 | .write = bonito_ldma_writel, |
386 | .endianness = DEVICE_NATIVE_ENDIAN, |
387 | .valid = { |
388 | .min_access_size = 4, |
389 | .max_access_size = 4, |
390 | }, |
391 | }; |
392 | |
393 | static uint64_t bonito_cop_readl(void *opaque, hwaddr addr, |
394 | unsigned size) |
395 | { |
396 | uint32_t val; |
397 | PCIBonitoState *s = opaque; |
398 | |
399 | if (addr >= sizeof(s->boncop)) { |
400 | return 0; |
401 | } |
402 | |
403 | val = ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)]; |
404 | |
405 | return val; |
406 | } |
407 | |
408 | static void bonito_cop_writel(void *opaque, hwaddr addr, |
409 | uint64_t val, unsigned size) |
410 | { |
411 | PCIBonitoState *s = opaque; |
412 | |
413 | if (addr >= sizeof(s->boncop)) { |
414 | return; |
415 | } |
416 | |
417 | ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)] = val & 0xffffffff; |
418 | } |
419 | |
420 | static const MemoryRegionOps bonito_cop_ops = { |
421 | .read = bonito_cop_readl, |
422 | .write = bonito_cop_writel, |
423 | .endianness = DEVICE_NATIVE_ENDIAN, |
424 | .valid = { |
425 | .min_access_size = 4, |
426 | .max_access_size = 4, |
427 | }, |
428 | }; |
429 | |
430 | static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr) |
431 | { |
432 | PCIBonitoState *s = opaque; |
433 | PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); |
434 | uint32_t cfgaddr; |
435 | uint32_t idsel; |
436 | uint32_t devno; |
437 | uint32_t funno; |
438 | uint32_t regno; |
439 | uint32_t pciaddr; |
440 | |
441 | /* support type0 pci config */ |
442 | if ((s->regs[BONITO_PCIMAP_CFG] & 0x10000) != 0x0) { |
443 | return 0xffffffff; |
444 | } |
445 | |
446 | cfgaddr = addr & 0xffff; |
447 | cfgaddr |= (s->regs[BONITO_PCIMAP_CFG] & 0xffff) << 16; |
448 | |
449 | idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> BONITO_PCICONF_IDSEL_OFFSET; |
450 | devno = ctz32(idsel); |
451 | funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET; |
452 | regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET; |
453 | |
454 | if (idsel == 0) { |
455 | error_report("error in bonito pci config address " TARGET_FMT_plx |
456 | ",pcimap_cfg=%x" , addr, s->regs[BONITO_PCIMAP_CFG]); |
457 | exit(1); |
458 | } |
459 | pciaddr = PCI_ADDR(pci_bus_num(phb->bus), devno, funno, regno); |
460 | DPRINTF("cfgaddr %x pciaddr %x busno %x devno %d funno %d regno %d\n" , |
461 | cfgaddr, pciaddr, pci_bus_num(phb->bus), devno, funno, regno); |
462 | |
463 | return pciaddr; |
464 | } |
465 | |
466 | static void bonito_spciconf_write(void *opaque, hwaddr addr, uint64_t val, |
467 | unsigned size) |
468 | { |
469 | PCIBonitoState *s = opaque; |
470 | PCIDevice *d = PCI_DEVICE(s); |
471 | PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); |
472 | uint32_t pciaddr; |
473 | uint16_t status; |
474 | |
475 | DPRINTF("bonito_spciconf_write " TARGET_FMT_plx" size %d val %x\n" , |
476 | addr, size, val); |
477 | |
478 | pciaddr = bonito_sbridge_pciaddr(s, addr); |
479 | |
480 | if (pciaddr == 0xffffffff) { |
481 | return; |
482 | } |
483 | |
484 | /* set the pci address in s->config_reg */ |
485 | phb->config_reg = (pciaddr) | (1u << 31); |
486 | pci_data_write(phb->bus, phb->config_reg, val, size); |
487 | |
488 | /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */ |
489 | status = pci_get_word(d->config + PCI_STATUS); |
490 | status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT); |
491 | pci_set_word(d->config + PCI_STATUS, status); |
492 | } |
493 | |
494 | static uint64_t bonito_spciconf_read(void *opaque, hwaddr addr, unsigned size) |
495 | { |
496 | PCIBonitoState *s = opaque; |
497 | PCIDevice *d = PCI_DEVICE(s); |
498 | PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); |
499 | uint32_t pciaddr; |
500 | uint16_t status; |
501 | |
502 | DPRINTF("bonito_spciconf_read " TARGET_FMT_plx" size %d\n" , addr, size); |
503 | |
504 | pciaddr = bonito_sbridge_pciaddr(s, addr); |
505 | |
506 | if (pciaddr == 0xffffffff) { |
507 | return MAKE_64BIT_MASK(0, size * 8); |
508 | } |
509 | |
510 | /* set the pci address in s->config_reg */ |
511 | phb->config_reg = (pciaddr) | (1u << 31); |
512 | |
513 | /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */ |
514 | status = pci_get_word(d->config + PCI_STATUS); |
515 | status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT); |
516 | pci_set_word(d->config + PCI_STATUS, status); |
517 | |
518 | return pci_data_read(phb->bus, phb->config_reg, size); |
519 | } |
520 | |
521 | /* south bridge PCI configure space. 0x1fe8 0000 - 0x1fef ffff */ |
522 | static const MemoryRegionOps bonito_spciconf_ops = { |
523 | .read = bonito_spciconf_read, |
524 | .write = bonito_spciconf_write, |
525 | .valid.min_access_size = 1, |
526 | .valid.max_access_size = 4, |
527 | .impl.min_access_size = 1, |
528 | .impl.max_access_size = 4, |
529 | .endianness = DEVICE_NATIVE_ENDIAN, |
530 | }; |
531 | |
532 | #define BONITO_IRQ_BASE 32 |
533 | |
534 | static void pci_bonito_set_irq(void *opaque, int irq_num, int level) |
535 | { |
536 | BonitoState *s = opaque; |
537 | qemu_irq *pic = s->pic; |
538 | PCIBonitoState *bonito_state = s->pci_dev; |
539 | int internal_irq = irq_num - BONITO_IRQ_BASE; |
540 | |
541 | if (bonito_state->regs[BONITO_INTEDGE] & (1 << internal_irq)) { |
542 | qemu_irq_pulse(*pic); |
543 | } else { /* level triggered */ |
544 | if (bonito_state->regs[BONITO_INTPOL] & (1 << internal_irq)) { |
545 | qemu_irq_raise(*pic); |
546 | } else { |
547 | qemu_irq_lower(*pic); |
548 | } |
549 | } |
550 | } |
551 | |
552 | /* map the original irq (0~3) to bonito irq (16~47, but 16~31 are unused) */ |
553 | static int pci_bonito_map_irq(PCIDevice * pci_dev, int irq_num) |
554 | { |
555 | int slot; |
556 | |
557 | slot = (pci_dev->devfn >> 3); |
558 | |
559 | switch (slot) { |
560 | case 5: /* FULONG2E_VIA_SLOT, SouthBridge, IDE, USB, ACPI, AC97, MC97 */ |
561 | return irq_num % 4 + BONITO_IRQ_BASE; |
562 | case 6: /* FULONG2E_ATI_SLOT, VGA */ |
563 | return 4 + BONITO_IRQ_BASE; |
564 | case 7: /* FULONG2E_RTL_SLOT, RTL8139 */ |
565 | return 5 + BONITO_IRQ_BASE; |
566 | case 8 ... 12: /* PCI slot 1 to 4 */ |
567 | return (slot - 8 + irq_num) + 6 + BONITO_IRQ_BASE; |
568 | default: /* Unknown device, don't do any translation */ |
569 | return irq_num; |
570 | } |
571 | } |
572 | |
573 | static void bonito_reset(void *opaque) |
574 | { |
575 | PCIBonitoState *s = opaque; |
576 | |
577 | /* set the default value of north bridge registers */ |
578 | |
579 | s->regs[BONITO_BONPONCFG] = 0xc40; |
580 | s->regs[BONITO_BONGENCFG] = 0x1384; |
581 | s->regs[BONITO_IODEVCFG] = 0x2bff8010; |
582 | s->regs[BONITO_SDCFG] = 0x255e0091; |
583 | |
584 | s->regs[BONITO_GPIODATA] = 0x1ff; |
585 | s->regs[BONITO_GPIOIE] = 0x1ff; |
586 | s->regs[BONITO_DQCFG] = 0x8; |
587 | s->regs[BONITO_MEMSIZE] = 0x10000000; |
588 | s->regs[BONITO_PCIMAP] = 0x6140; |
589 | } |
590 | |
591 | static const VMStateDescription vmstate_bonito = { |
592 | .name = "Bonito" , |
593 | .version_id = 1, |
594 | .minimum_version_id = 1, |
595 | .fields = (VMStateField[]) { |
596 | VMSTATE_PCI_DEVICE(dev, PCIBonitoState), |
597 | VMSTATE_END_OF_LIST() |
598 | } |
599 | }; |
600 | |
601 | static void bonito_pcihost_realize(DeviceState *dev, Error **errp) |
602 | { |
603 | PCIHostState *phb = PCI_HOST_BRIDGE(dev); |
604 | BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev); |
605 | |
606 | memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem" , BONITO_PCILO_SIZE); |
607 | phb->bus = pci_register_root_bus(DEVICE(dev), "pci" , |
608 | pci_bonito_set_irq, pci_bonito_map_irq, |
609 | dev, &bs->pci_mem, get_system_io(), |
610 | 0x28, 32, TYPE_PCI_BUS); |
611 | memory_region_add_subregion(get_system_memory(), BONITO_PCILO_BASE, |
612 | &bs->pci_mem); |
613 | } |
614 | |
615 | static void bonito_realize(PCIDevice *dev, Error **errp) |
616 | { |
617 | PCIBonitoState *s = PCI_BONITO(dev); |
618 | SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost); |
619 | PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); |
620 | |
621 | /* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */ |
622 | pci_config_set_prog_interface(dev->config, 0x00); |
623 | |
624 | /* set the north bridge register mapping */ |
625 | memory_region_init_io(&s->iomem, OBJECT(s), &bonito_ops, s, |
626 | "north-bridge-register" , BONITO_INTERNAL_REG_SIZE); |
627 | sysbus_init_mmio(sysbus, &s->iomem); |
628 | sysbus_mmio_map(sysbus, 0, BONITO_INTERNAL_REG_BASE); |
629 | |
630 | /* set the north bridge pci configure mapping */ |
631 | memory_region_init_io(&phb->conf_mem, OBJECT(s), &bonito_pciconf_ops, s, |
632 | "north-bridge-pci-config" , BONITO_PCICONFIG_SIZE); |
633 | sysbus_init_mmio(sysbus, &phb->conf_mem); |
634 | sysbus_mmio_map(sysbus, 1, BONITO_PCICONFIG_BASE); |
635 | |
636 | /* set the south bridge pci configure mapping */ |
637 | memory_region_init_io(&phb->data_mem, OBJECT(s), &bonito_spciconf_ops, s, |
638 | "south-bridge-pci-config" , BONITO_SPCICONFIG_SIZE); |
639 | sysbus_init_mmio(sysbus, &phb->data_mem); |
640 | sysbus_mmio_map(sysbus, 2, BONITO_SPCICONFIG_BASE); |
641 | |
642 | memory_region_init_io(&s->iomem_ldma, OBJECT(s), &bonito_ldma_ops, s, |
643 | "ldma" , 0x100); |
644 | sysbus_init_mmio(sysbus, &s->iomem_ldma); |
645 | sysbus_mmio_map(sysbus, 3, 0xbfe00200); |
646 | |
647 | memory_region_init_io(&s->iomem_cop, OBJECT(s), &bonito_cop_ops, s, |
648 | "cop" , 0x100); |
649 | sysbus_init_mmio(sysbus, &s->iomem_cop); |
650 | sysbus_mmio_map(sysbus, 4, 0xbfe00300); |
651 | |
652 | /* Map PCI IO Space 0x1fd0 0000 - 0x1fd1 0000 */ |
653 | memory_region_init_alias(&s->bonito_pciio, OBJECT(s), "isa_mmio" , |
654 | get_system_io(), 0, BONITO_PCIIO_SIZE); |
655 | sysbus_init_mmio(sysbus, &s->bonito_pciio); |
656 | sysbus_mmio_map(sysbus, 5, BONITO_PCIIO_BASE); |
657 | |
658 | /* add pci local io mapping */ |
659 | memory_region_init_alias(&s->bonito_localio, OBJECT(s), "isa_mmio" , |
660 | get_system_io(), 0, BONITO_DEV_SIZE); |
661 | sysbus_init_mmio(sysbus, &s->bonito_localio); |
662 | sysbus_mmio_map(sysbus, 6, BONITO_DEV_BASE); |
663 | |
664 | /* set the default value of north bridge pci config */ |
665 | pci_set_word(dev->config + PCI_COMMAND, 0x0000); |
666 | pci_set_word(dev->config + PCI_STATUS, 0x0000); |
667 | pci_set_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID, 0x0000); |
668 | pci_set_word(dev->config + PCI_SUBSYSTEM_ID, 0x0000); |
669 | |
670 | pci_set_byte(dev->config + PCI_INTERRUPT_LINE, 0x00); |
671 | pci_set_byte(dev->config + PCI_INTERRUPT_PIN, 0x01); |
672 | pci_set_byte(dev->config + PCI_MIN_GNT, 0x3c); |
673 | pci_set_byte(dev->config + PCI_MAX_LAT, 0x00); |
674 | |
675 | qemu_register_reset(bonito_reset, s); |
676 | } |
677 | |
678 | PCIBus *bonito_init(qemu_irq *pic) |
679 | { |
680 | DeviceState *dev; |
681 | BonitoState *pcihost; |
682 | PCIHostState *phb; |
683 | PCIBonitoState *s; |
684 | PCIDevice *d; |
685 | |
686 | dev = qdev_create(NULL, TYPE_BONITO_PCI_HOST_BRIDGE); |
687 | phb = PCI_HOST_BRIDGE(dev); |
688 | pcihost = BONITO_PCI_HOST_BRIDGE(dev); |
689 | pcihost->pic = pic; |
690 | qdev_init_nofail(dev); |
691 | |
692 | d = pci_create(phb->bus, PCI_DEVFN(0, 0), TYPE_PCI_BONITO); |
693 | s = PCI_BONITO(d); |
694 | s->pcihost = pcihost; |
695 | pcihost->pci_dev = s; |
696 | qdev_init_nofail(DEVICE(d)); |
697 | |
698 | return phb->bus; |
699 | } |
700 | |
701 | static void bonito_class_init(ObjectClass *klass, void *data) |
702 | { |
703 | DeviceClass *dc = DEVICE_CLASS(klass); |
704 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); |
705 | |
706 | k->realize = bonito_realize; |
707 | k->vendor_id = 0xdf53; |
708 | k->device_id = 0x00d5; |
709 | k->revision = 0x01; |
710 | k->class_id = PCI_CLASS_BRIDGE_HOST; |
711 | dc->desc = "Host bridge" ; |
712 | dc->vmsd = &vmstate_bonito; |
713 | /* |
714 | * PCI-facing part of the host bridge, not usable without the |
715 | * host-facing part, which can't be device_add'ed, yet. |
716 | */ |
717 | dc->user_creatable = false; |
718 | } |
719 | |
720 | static const TypeInfo bonito_info = { |
721 | .name = TYPE_PCI_BONITO, |
722 | .parent = TYPE_PCI_DEVICE, |
723 | .instance_size = sizeof(PCIBonitoState), |
724 | .class_init = bonito_class_init, |
725 | .interfaces = (InterfaceInfo[]) { |
726 | { INTERFACE_CONVENTIONAL_PCI_DEVICE }, |
727 | { }, |
728 | }, |
729 | }; |
730 | |
731 | static void bonito_pcihost_class_init(ObjectClass *klass, void *data) |
732 | { |
733 | DeviceClass *dc = DEVICE_CLASS(klass); |
734 | |
735 | dc->realize = bonito_pcihost_realize; |
736 | } |
737 | |
738 | static const TypeInfo bonito_pcihost_info = { |
739 | .name = TYPE_BONITO_PCI_HOST_BRIDGE, |
740 | .parent = TYPE_PCI_HOST_BRIDGE, |
741 | .instance_size = sizeof(BonitoState), |
742 | .class_init = bonito_pcihost_class_init, |
743 | }; |
744 | |
745 | static void bonito_register_types(void) |
746 | { |
747 | type_register_static(&bonito_pcihost_info); |
748 | type_register_static(&bonito_info); |
749 | } |
750 | |
751 | type_init(bonito_register_types) |
752 | |