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