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