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
30#include "qemu/osdep.h"
31#include "hw/sysbus.h"
32#include "hw/pci/pci.h"
33#include "hw/pci/pci_host.h"
34#include "hw/pci/pci_bridge.h"
35#include "hw/pci/pci_bus.h"
36#include "hw/pci-host/apb.h"
37#include "sysemu/sysemu.h"
38#include "exec/address-spaces.h"
39
40
41
42
43#ifdef DEBUG_APB
44#define APB_DPRINTF(fmt, ...) \
45do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
46#else
47#define APB_DPRINTF(fmt, ...)
48#endif
49
50
51
52
53#ifdef DEBUG_IOMMU
54#define IOMMU_DPRINTF(fmt, ...) \
55do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
56#else
57#define IOMMU_DPRINTF(fmt, ...)
58#endif
59
60
61
62
63
64
65
66
67
68
69#define PBM_PCI_IMR_MASK 0x7fffffff
70#define PBM_PCI_IMR_ENABLED 0x80000000
71
72#define POR (1U << 31)
73#define SOFT_POR (1U << 30)
74#define SOFT_XIR (1U << 29)
75#define BTN_POR (1U << 28)
76#define BTN_XIR (1U << 27)
77#define RESET_MASK 0xf8000000
78#define RESET_WCMASK 0x98000000
79#define RESET_WMASK 0x60000000
80
81#define MAX_IVEC 0x40
82#define NO_IRQ_REQUEST (MAX_IVEC + 1)
83
84#define IOMMU_PAGE_SIZE_8K (1ULL << 13)
85#define IOMMU_PAGE_MASK_8K (~(IOMMU_PAGE_SIZE_8K - 1))
86#define IOMMU_PAGE_SIZE_64K (1ULL << 16)
87#define IOMMU_PAGE_MASK_64K (~(IOMMU_PAGE_SIZE_64K - 1))
88
89#define IOMMU_NREGS 3
90
91#define IOMMU_CTRL 0x0
92#define IOMMU_CTRL_TBW_SIZE (1ULL << 2)
93#define IOMMU_CTRL_MMU_EN (1ULL)
94
95#define IOMMU_CTRL_TSB_SHIFT 16
96
97#define IOMMU_BASE 0x8
98#define IOMMU_FLUSH 0x10
99
100#define IOMMU_TTE_DATA_V (1ULL << 63)
101#define IOMMU_TTE_DATA_SIZE (1ULL << 61)
102#define IOMMU_TTE_DATA_W (1ULL << 1)
103
104#define IOMMU_TTE_PHYS_MASK_8K 0x1ffffffe000ULL
105#define IOMMU_TTE_PHYS_MASK_64K 0x1ffffff8000ULL
106
107#define IOMMU_TSB_8K_OFFSET_MASK_8M 0x00000000007fe000ULL
108#define IOMMU_TSB_8K_OFFSET_MASK_16M 0x0000000000ffe000ULL
109#define IOMMU_TSB_8K_OFFSET_MASK_32M 0x0000000001ffe000ULL
110#define IOMMU_TSB_8K_OFFSET_MASK_64M 0x0000000003ffe000ULL
111#define IOMMU_TSB_8K_OFFSET_MASK_128M 0x0000000007ffe000ULL
112#define IOMMU_TSB_8K_OFFSET_MASK_256M 0x000000000fffe000ULL
113#define IOMMU_TSB_8K_OFFSET_MASK_512M 0x000000001fffe000ULL
114#define IOMMU_TSB_8K_OFFSET_MASK_1G 0x000000003fffe000ULL
115
116#define IOMMU_TSB_64K_OFFSET_MASK_64M 0x0000000003ff0000ULL
117#define IOMMU_TSB_64K_OFFSET_MASK_128M 0x0000000007ff0000ULL
118#define IOMMU_TSB_64K_OFFSET_MASK_256M 0x000000000fff0000ULL
119#define IOMMU_TSB_64K_OFFSET_MASK_512M 0x000000001fff0000ULL
120#define IOMMU_TSB_64K_OFFSET_MASK_1G 0x000000003fff0000ULL
121#define IOMMU_TSB_64K_OFFSET_MASK_2G 0x000000007fff0000ULL
122
123typedef struct IOMMUState {
124 AddressSpace iommu_as;
125 MemoryRegion iommu;
126
127 uint64_t regs[IOMMU_NREGS];
128} IOMMUState;
129
130#define TYPE_APB "pbm"
131
132#define APB_DEVICE(obj) \
133 OBJECT_CHECK(APBState, (obj), TYPE_APB)
134
135typedef struct APBState {
136 PCIHostState parent_obj;
137
138 MemoryRegion apb_config;
139 MemoryRegion pci_config;
140 MemoryRegion pci_mmio;
141 MemoryRegion pci_ioport;
142 uint64_t pci_irq_in;
143 IOMMUState iommu;
144 uint32_t pci_control[16];
145 uint32_t pci_irq_map[8];
146 uint32_t pci_err_irq_map[4];
147 uint32_t obio_irq_map[32];
148 qemu_irq *pbm_irqs;
149 qemu_irq *ivec_irqs;
150 unsigned int irq_request;
151 uint32_t reset_control;
152 unsigned int nr_resets;
153} APBState;
154
155static inline void pbm_set_request(APBState *s, unsigned int irq_num)
156{
157 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
158
159 s->irq_request = irq_num;
160 qemu_set_irq(s->ivec_irqs[irq_num], 1);
161}
162
163static inline void pbm_check_irqs(APBState *s)
164{
165
166 unsigned int i;
167
168
169 if (s->irq_request != NO_IRQ_REQUEST) {
170 pbm_set_request(s, s->irq_request);
171 return;
172 }
173
174 if (s->pci_irq_in == 0ULL) {
175 return;
176 }
177 for (i = 0; i < 32; i++) {
178 if (s->pci_irq_in & (1ULL << i)) {
179 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
180 pbm_set_request(s, i);
181 return;
182 }
183 }
184 }
185 for (i = 32; i < 64; i++) {
186 if (s->pci_irq_in & (1ULL << i)) {
187 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
188 pbm_set_request(s, i);
189 break;
190 }
191 }
192 }
193}
194
195static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
196{
197 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
198 qemu_set_irq(s->ivec_irqs[irq_num], 0);
199 s->irq_request = NO_IRQ_REQUEST;
200}
201
202static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
203{
204 IOMMUState *is = opaque;
205
206 return &is->iommu_as;
207}
208
209
210static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr,
211 bool is_write)
212{
213 IOMMUState *is = container_of(iommu, IOMMUState, iommu);
214 hwaddr baseaddr, offset;
215 uint64_t tte;
216 uint32_t tsbsize;
217 IOMMUTLBEntry ret = {
218 .target_as = &address_space_memory,
219 .iova = 0,
220 .translated_addr = 0,
221 .addr_mask = ~(hwaddr)0,
222 .perm = IOMMU_NONE,
223 };
224
225 if (!(is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_MMU_EN)) {
226
227 ret.iova = addr & IOMMU_PAGE_MASK_8K;
228 ret.translated_addr = addr;
229 ret.addr_mask = IOMMU_PAGE_MASK_8K;
230 ret.perm = IOMMU_RW;
231
232 return ret;
233 }
234
235 baseaddr = is->regs[IOMMU_BASE >> 3];
236 tsbsize = (is->regs[IOMMU_CTRL >> 3] >> IOMMU_CTRL_TSB_SHIFT) & 0x7;
237
238 if (is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_TBW_SIZE) {
239
240 switch (tsbsize) {
241 case 0:
242 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_64M) >> 13;
243 break;
244 case 1:
245 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_128M) >> 13;
246 break;
247 case 2:
248 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_256M) >> 13;
249 break;
250 case 3:
251 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_512M) >> 13;
252 break;
253 case 4:
254 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_1G) >> 13;
255 break;
256 case 5:
257 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_2G) >> 13;
258 break;
259 default:
260
261 return ret;
262 }
263 } else {
264
265 switch (tsbsize) {
266 case 0:
267 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_8M) >> 10;
268 break;
269 case 1:
270 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_16M) >> 10;
271 break;
272 case 2:
273 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_32M) >> 10;
274 break;
275 case 3:
276 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_64M) >> 10;
277 break;
278 case 4:
279 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_128M) >> 10;
280 break;
281 case 5:
282 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_256M) >> 10;
283 break;
284 case 6:
285 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_512M) >> 10;
286 break;
287 case 7:
288 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_1G) >> 10;
289 break;
290 }
291 }
292
293 tte = address_space_ldq_be(&address_space_memory, baseaddr + offset,
294 MEMTXATTRS_UNSPECIFIED, NULL);
295
296 if (!(tte & IOMMU_TTE_DATA_V)) {
297
298 return ret;
299 }
300
301 if (tte & IOMMU_TTE_DATA_W) {
302
303 ret.perm = IOMMU_RW;
304 } else {
305 ret.perm = IOMMU_RO;
306 }
307
308
309 if (tte & IOMMU_TTE_DATA_SIZE) {
310
311 ret.iova = addr & IOMMU_PAGE_MASK_64K;
312 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_64K;
313 ret.addr_mask = (IOMMU_PAGE_SIZE_64K - 1);
314 } else {
315
316 ret.iova = addr & IOMMU_PAGE_MASK_8K;
317 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_8K;
318 ret.addr_mask = (IOMMU_PAGE_SIZE_8K - 1);
319 }
320
321 return ret;
322}
323
324static MemoryRegionIOMMUOps pbm_iommu_ops = {
325 .translate = pbm_translate_iommu,
326};
327
328static void iommu_config_write(void *opaque, hwaddr addr,
329 uint64_t val, unsigned size)
330{
331 IOMMUState *is = opaque;
332
333 IOMMU_DPRINTF("IOMMU config write: 0x%" HWADDR_PRIx " val: %" PRIx64
334 " size: %d\n", addr, val, size);
335
336 switch (addr) {
337 case IOMMU_CTRL:
338 if (size == 4) {
339 is->regs[IOMMU_CTRL >> 3] &= 0xffffffffULL;
340 is->regs[IOMMU_CTRL >> 3] |= val << 32;
341 } else {
342 is->regs[IOMMU_CTRL >> 3] = val;
343 }
344 break;
345 case IOMMU_CTRL + 0x4:
346 is->regs[IOMMU_CTRL >> 3] &= 0xffffffff00000000ULL;
347 is->regs[IOMMU_CTRL >> 3] |= val & 0xffffffffULL;
348 break;
349 case IOMMU_BASE:
350 if (size == 4) {
351 is->regs[IOMMU_BASE >> 3] &= 0xffffffffULL;
352 is->regs[IOMMU_BASE >> 3] |= val << 32;
353 } else {
354 is->regs[IOMMU_BASE >> 3] = val;
355 }
356 break;
357 case IOMMU_BASE + 0x4:
358 is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
359 is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
360 break;
361 case IOMMU_FLUSH:
362 case IOMMU_FLUSH + 0x4:
363 break;
364 default:
365 qemu_log_mask(LOG_UNIMP,
366 "apb iommu: Unimplemented register write "
367 "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
368 addr, size, val);
369 break;
370 }
371}
372
373static uint64_t iommu_config_read(void *opaque, hwaddr addr, unsigned size)
374{
375 IOMMUState *is = opaque;
376 uint64_t val;
377
378 switch (addr) {
379 case IOMMU_CTRL:
380 if (size == 4) {
381 val = is->regs[IOMMU_CTRL >> 3] >> 32;
382 } else {
383 val = is->regs[IOMMU_CTRL >> 3];
384 }
385 break;
386 case IOMMU_CTRL + 0x4:
387 val = is->regs[IOMMU_CTRL >> 3] & 0xffffffffULL;
388 break;
389 case IOMMU_BASE:
390 if (size == 4) {
391 val = is->regs[IOMMU_BASE >> 3] >> 32;
392 } else {
393 val = is->regs[IOMMU_BASE >> 3];
394 }
395 break;
396 case IOMMU_BASE + 0x4:
397 val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
398 break;
399 case IOMMU_FLUSH:
400 case IOMMU_FLUSH + 0x4:
401 val = 0;
402 break;
403 default:
404 qemu_log_mask(LOG_UNIMP,
405 "apb iommu: Unimplemented register read "
406 "reg 0x%" HWADDR_PRIx " size 0x%x\n",
407 addr, size);
408 val = 0;
409 break;
410 }
411
412 IOMMU_DPRINTF("IOMMU config read: 0x%" HWADDR_PRIx " val: %" PRIx64
413 " size: %d\n", addr, val, size);
414
415 return val;
416}
417
418static void apb_config_writel (void *opaque, hwaddr addr,
419 uint64_t val, unsigned size)
420{
421 APBState *s = opaque;
422 IOMMUState *is = &s->iommu;
423
424 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
425
426 switch (addr & 0xffff) {
427 case 0x30 ... 0x4f:
428
429 break;
430 case 0x200 ... 0x217:
431 iommu_config_write(is, (addr & 0x1f), val, size);
432 break;
433 case 0xc00 ... 0xc3f:
434 if (addr & 4) {
435 unsigned int ino = (addr & 0x3f) >> 3;
436 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
437 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
438 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
439 pbm_clear_request(s, ino);
440 }
441 pbm_check_irqs(s);
442 }
443 break;
444 case 0x1000 ... 0x107f:
445 if (addr & 4) {
446 unsigned int ino = ((addr & 0xff) >> 3);
447 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
448 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
449 if ((s->irq_request == (ino | 0x20))
450 && !(val & ~PBM_PCI_IMR_MASK)) {
451 pbm_clear_request(s, ino | 0x20);
452 }
453 pbm_check_irqs(s);
454 }
455 break;
456 case 0x1400 ... 0x14ff:
457 if (addr & 4) {
458 unsigned int ino = (addr & 0xff) >> 5;
459 if ((s->irq_request / 4) == ino) {
460 pbm_clear_request(s, s->irq_request);
461 pbm_check_irqs(s);
462 }
463 }
464 break;
465 case 0x1800 ... 0x1860:
466 if (addr & 4) {
467 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
468 if (s->irq_request == ino) {
469 pbm_clear_request(s, ino);
470 pbm_check_irqs(s);
471 }
472 }
473 break;
474 case 0x2000 ... 0x202f:
475 s->pci_control[(addr & 0x3f) >> 2] = val;
476 break;
477 case 0xf020 ... 0xf027:
478 if (addr & 4) {
479 val &= RESET_MASK;
480 s->reset_control &= ~(val & RESET_WCMASK);
481 s->reset_control |= val & RESET_WMASK;
482 if (val & SOFT_POR) {
483 s->nr_resets = 0;
484 qemu_system_reset_request();
485 } else if (val & SOFT_XIR) {
486 qemu_system_reset_request();
487 }
488 }
489 break;
490 case 0x5000 ... 0x51cf:
491 case 0xa400 ... 0xa67f:
492 case 0xa800 ... 0xa80f:
493 case 0xf000 ... 0xf01f:
494
495 default:
496 break;
497 }
498}
499
500static uint64_t apb_config_readl (void *opaque,
501 hwaddr addr, unsigned size)
502{
503 APBState *s = opaque;
504 IOMMUState *is = &s->iommu;
505 uint32_t val;
506
507 switch (addr & 0xffff) {
508 case 0x30 ... 0x4f:
509 val = 0;
510
511 break;
512 case 0x200 ... 0x217:
513 val = iommu_config_read(is, (addr & 0x1f), size);
514 break;
515 case 0xc00 ... 0xc3f:
516 if (addr & 4) {
517 val = s->pci_irq_map[(addr & 0x3f) >> 3];
518 } else {
519 val = 0;
520 }
521 break;
522 case 0x1000 ... 0x107f:
523 if (addr & 4) {
524 val = s->obio_irq_map[(addr & 0xff) >> 3];
525 } else {
526 val = 0;
527 }
528 break;
529 case 0x1080 ... 0x108f:
530 if (addr & 4) {
531 val = s->pci_err_irq_map[(addr & 0xf) >> 3];
532 } else {
533 val = 0;
534 }
535 break;
536 case 0x2000 ... 0x202f:
537 val = s->pci_control[(addr & 0x3f) >> 2];
538 break;
539 case 0xf020 ... 0xf027:
540 if (addr & 4) {
541 val = s->reset_control;
542 } else {
543 val = 0;
544 }
545 break;
546 case 0x5000 ... 0x51cf:
547 case 0xa400 ... 0xa67f:
548 case 0xa800 ... 0xa80f:
549 case 0xf000 ... 0xf01f:
550
551 default:
552 val = 0;
553 break;
554 }
555 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
556
557 return val;
558}
559
560static const MemoryRegionOps apb_config_ops = {
561 .read = apb_config_readl,
562 .write = apb_config_writel,
563 .endianness = DEVICE_NATIVE_ENDIAN,
564};
565
566static void apb_pci_config_write(void *opaque, hwaddr addr,
567 uint64_t val, unsigned size)
568{
569 APBState *s = opaque;
570 PCIHostState *phb = PCI_HOST_BRIDGE(s);
571
572 val = qemu_bswap_len(val, size);
573 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
574 pci_data_write(phb->bus, addr, val, size);
575}
576
577static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
578 unsigned size)
579{
580 uint32_t ret;
581 APBState *s = opaque;
582 PCIHostState *phb = PCI_HOST_BRIDGE(s);
583
584 ret = pci_data_read(phb->bus, addr, size);
585 ret = qemu_bswap_len(ret, size);
586 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
587 return ret;
588}
589
590
591static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
592{
593 return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
594}
595
596static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
597{
598 int bus_offset;
599 if (pci_dev->devfn & 1)
600 bus_offset = 16;
601 else
602 bus_offset = 0;
603 return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
604}
605
606static void pci_apb_set_irq(void *opaque, int irq_num, int level)
607{
608 APBState *s = opaque;
609
610 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
611
612 if (irq_num < 32) {
613 if (level) {
614 s->pci_irq_in |= 1ULL << irq_num;
615 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
616 pbm_set_request(s, irq_num);
617 }
618 } else {
619 s->pci_irq_in &= ~(1ULL << irq_num);
620 }
621 } else {
622
623 if (level) {
624 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
625 s->pci_irq_in |= 1ULL << irq_num;
626 if ((s->irq_request == NO_IRQ_REQUEST)
627 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
628 pbm_set_request(s, irq_num);
629 }
630 } else {
631 s->pci_irq_in &= ~(1ULL << irq_num);
632 }
633 }
634}
635
636static int apb_pci_bridge_initfn(PCIDevice *dev)
637{
638 pci_bridge_initfn(dev, TYPE_PCI_BUS);
639
640
641
642
643
644
645
646
647
648
649 pci_set_word(dev->config + PCI_COMMAND,
650 PCI_COMMAND_MEMORY);
651 pci_set_word(dev->config + PCI_STATUS,
652 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
653 PCI_STATUS_DEVSEL_MEDIUM);
654 return 0;
655}
656
657PCIBus *pci_apb_init(hwaddr special_base,
658 hwaddr mem_base,
659 qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
660 qemu_irq **pbm_irqs)
661{
662 DeviceState *dev;
663 SysBusDevice *s;
664 PCIHostState *phb;
665 APBState *d;
666 IOMMUState *is;
667 PCIDevice *pci_dev;
668 PCIBridge *br;
669
670
671 dev = qdev_create(NULL, TYPE_APB);
672 qdev_init_nofail(dev);
673 s = SYS_BUS_DEVICE(dev);
674
675 sysbus_mmio_map(s, 0, special_base);
676
677 sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
678
679 sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
680 d = APB_DEVICE(dev);
681
682 memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
683 memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
684
685 phb = PCI_HOST_BRIDGE(dev);
686 phb->bus = pci_register_bus(DEVICE(phb), "pci",
687 pci_apb_set_irq, pci_pbm_map_irq, d,
688 &d->pci_mmio,
689 get_system_io(),
690 0, 32, TYPE_PCI_BUS);
691
692 *pbm_irqs = d->pbm_irqs;
693 d->ivec_irqs = ivec_irqs;
694
695 pci_create_simple(phb->bus, 0, "pbm-pci");
696
697
698 is = &d->iommu;
699 memset(is, 0, sizeof(IOMMUState));
700
701 memory_region_init_iommu(&is->iommu, OBJECT(dev), &pbm_iommu_ops,
702 "iommu-apb", UINT64_MAX);
703 address_space_init(&is->iommu_as, &is->iommu, "pbm-as");
704 pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, is);
705
706
707 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
708 "pbm-bridge");
709 br = PCI_BRIDGE(pci_dev);
710 pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
711 pci_apb_map_irq);
712 qdev_init_nofail(&pci_dev->qdev);
713 *bus2 = pci_bridge_get_sec_bus(br);
714
715 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
716 "pbm-bridge");
717 br = PCI_BRIDGE(pci_dev);
718 pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
719 pci_apb_map_irq);
720 qdev_init_nofail(&pci_dev->qdev);
721 *bus3 = pci_bridge_get_sec_bus(br);
722
723 return phb->bus;
724}
725
726static void pci_pbm_reset(DeviceState *d)
727{
728 unsigned int i;
729 APBState *s = APB_DEVICE(d);
730
731 for (i = 0; i < 8; i++) {
732 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
733 }
734 for (i = 0; i < 32; i++) {
735 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
736 }
737
738 s->irq_request = NO_IRQ_REQUEST;
739 s->pci_irq_in = 0ULL;
740
741 if (s->nr_resets++ == 0) {
742
743 s->reset_control = POR;
744 }
745}
746
747static const MemoryRegionOps pci_config_ops = {
748 .read = apb_pci_config_read,
749 .write = apb_pci_config_write,
750 .endianness = DEVICE_NATIVE_ENDIAN,
751};
752
753static int pci_pbm_init_device(SysBusDevice *dev)
754{
755 APBState *s;
756 unsigned int i;
757
758 s = APB_DEVICE(dev);
759 for (i = 0; i < 8; i++) {
760 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
761 }
762 for (i = 0; i < 2; i++) {
763 s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
764 }
765 for (i = 0; i < 32; i++) {
766 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
767 }
768 s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
769 s->irq_request = NO_IRQ_REQUEST;
770 s->pci_irq_in = 0ULL;
771
772
773 memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
774 "apb-config", 0x10000);
775
776 sysbus_init_mmio(dev, &s->apb_config);
777
778 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
779 "apb-pci-config", 0x1000000);
780
781 sysbus_init_mmio(dev, &s->pci_config);
782
783
784 memory_region_init_alias(&s->pci_ioport, OBJECT(s), "apb-pci-ioport",
785 get_system_io(), 0, 0x10000);
786
787 sysbus_init_mmio(dev, &s->pci_ioport);
788
789 return 0;
790}
791
792static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
793{
794 pci_set_word(d->config + PCI_COMMAND,
795 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
796 pci_set_word(d->config + PCI_STATUS,
797 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
798 PCI_STATUS_DEVSEL_MEDIUM);
799}
800
801static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
802{
803 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
804 DeviceClass *dc = DEVICE_CLASS(klass);
805
806 k->realize = pbm_pci_host_realize;
807 k->vendor_id = PCI_VENDOR_ID_SUN;
808 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
809 k->class_id = PCI_CLASS_BRIDGE_HOST;
810
811
812
813
814 dc->cannot_instantiate_with_device_add_yet = true;
815}
816
817static const TypeInfo pbm_pci_host_info = {
818 .name = "pbm-pci",
819 .parent = TYPE_PCI_DEVICE,
820 .instance_size = sizeof(PCIDevice),
821 .class_init = pbm_pci_host_class_init,
822};
823
824static void pbm_host_class_init(ObjectClass *klass, void *data)
825{
826 DeviceClass *dc = DEVICE_CLASS(klass);
827 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
828
829 k->init = pci_pbm_init_device;
830 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
831 dc->reset = pci_pbm_reset;
832}
833
834static const TypeInfo pbm_host_info = {
835 .name = TYPE_APB,
836 .parent = TYPE_PCI_HOST_BRIDGE,
837 .instance_size = sizeof(APBState),
838 .class_init = pbm_host_class_init,
839};
840
841static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
842{
843 DeviceClass *dc = DEVICE_CLASS(klass);
844 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
845
846 k->init = apb_pci_bridge_initfn;
847 k->exit = pci_bridge_exitfn;
848 k->vendor_id = PCI_VENDOR_ID_SUN;
849 k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
850 k->revision = 0x11;
851 k->config_write = pci_bridge_write_config;
852 k->is_bridge = 1;
853 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
854 dc->reset = pci_bridge_reset;
855 dc->vmsd = &vmstate_pci_device;
856}
857
858static const TypeInfo pbm_pci_bridge_info = {
859 .name = "pbm-bridge",
860 .parent = TYPE_PCI_BRIDGE,
861 .class_init = pbm_pci_bridge_class_init,
862};
863
864static void pbm_register_types(void)
865{
866 type_register_static(&pbm_host_info);
867 type_register_static(&pbm_pci_host_info);
868 type_register_static(&pbm_pci_bridge_info);
869}
870
871type_init(pbm_register_types)
872