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