apb: move the two secondary PCI bridges objects into APBState
[qemu/ar7.git] / hw / pci-host / apb.c
blob823661a8a675725e65808143a156bbd52371401b
1 /*
2 * QEMU Ultrasparc APB PCI host
4 * Copyright (c) 2006 Fabrice Bellard
5 * Copyright (c) 2012,2013 Artyom Tarasenko
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
26 /* XXX This file and most of its contents are somewhat misnamed. The
27 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
28 the secondary PCI bridge. */
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"
41 /* debug APB */
42 //#define DEBUG_APB
44 #ifdef DEBUG_APB
45 #define APB_DPRINTF(fmt, ...) \
46 do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
47 #else
48 #define APB_DPRINTF(fmt, ...)
49 #endif
51 /* debug IOMMU */
52 //#define DEBUG_IOMMU
54 #ifdef DEBUG_IOMMU
55 #define IOMMU_DPRINTF(fmt, ...) \
56 do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
57 #else
58 #define IOMMU_DPRINTF(fmt, ...)
59 #endif
62 * Chipset docs:
63 * PBM: "UltraSPARC IIi User's Manual",
64 * http://www.sun.com/processors/manuals/805-0087.pdf
66 * APB: "Advanced PCI Bridge (APB) User's Manual",
67 * http://www.sun.com/processors/manuals/805-1251.pdf
70 #define PBM_PCI_IMR_MASK 0x7fffffff
71 #define PBM_PCI_IMR_ENABLED 0x80000000
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
82 #define NO_IRQ_REQUEST (MAX_IVEC + 1)
84 static inline void pbm_set_request(APBState *s, unsigned int irq_num)
86 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
88 s->irq_request = irq_num;
89 qemu_set_irq(s->ivec_irqs[irq_num], 1);
92 static inline void pbm_check_irqs(APBState *s)
95 unsigned int i;
97 /* Previous request is not acknowledged, resubmit */
98 if (s->irq_request != NO_IRQ_REQUEST) {
99 pbm_set_request(s, s->irq_request);
100 return;
102 /* no request pending */
103 if (s->pci_irq_in == 0ULL) {
104 return;
106 for (i = 0; i < 32; i++) {
107 if (s->pci_irq_in & (1ULL << i)) {
108 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
109 pbm_set_request(s, i);
110 return;
114 for (i = 32; i < 64; i++) {
115 if (s->pci_irq_in & (1ULL << i)) {
116 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
117 pbm_set_request(s, i);
118 break;
124 static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
126 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
127 qemu_set_irq(s->ivec_irqs[irq_num], 0);
128 s->irq_request = NO_IRQ_REQUEST;
131 static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
133 IOMMUState *is = opaque;
135 return &is->iommu_as;
138 /* Called from RCU critical section */
139 static IOMMUTLBEntry pbm_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr,
140 IOMMUAccessFlags flag)
142 IOMMUState *is = container_of(iommu, IOMMUState, iommu);
143 hwaddr baseaddr, offset;
144 uint64_t tte;
145 uint32_t tsbsize;
146 IOMMUTLBEntry ret = {
147 .target_as = &address_space_memory,
148 .iova = 0,
149 .translated_addr = 0,
150 .addr_mask = ~(hwaddr)0,
151 .perm = IOMMU_NONE,
154 if (!(is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_MMU_EN)) {
155 /* IOMMU disabled, passthrough using standard 8K page */
156 ret.iova = addr & IOMMU_PAGE_MASK_8K;
157 ret.translated_addr = addr;
158 ret.addr_mask = IOMMU_PAGE_MASK_8K;
159 ret.perm = IOMMU_RW;
161 return ret;
164 baseaddr = is->regs[IOMMU_BASE >> 3];
165 tsbsize = (is->regs[IOMMU_CTRL >> 3] >> IOMMU_CTRL_TSB_SHIFT) & 0x7;
167 if (is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_TBW_SIZE) {
168 /* 64K */
169 switch (tsbsize) {
170 case 0:
171 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_64M) >> 13;
172 break;
173 case 1:
174 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_128M) >> 13;
175 break;
176 case 2:
177 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_256M) >> 13;
178 break;
179 case 3:
180 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_512M) >> 13;
181 break;
182 case 4:
183 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_1G) >> 13;
184 break;
185 case 5:
186 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_2G) >> 13;
187 break;
188 default:
189 /* Not implemented, error */
190 return ret;
192 } else {
193 /* 8K */
194 switch (tsbsize) {
195 case 0:
196 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_8M) >> 10;
197 break;
198 case 1:
199 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_16M) >> 10;
200 break;
201 case 2:
202 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_32M) >> 10;
203 break;
204 case 3:
205 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_64M) >> 10;
206 break;
207 case 4:
208 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_128M) >> 10;
209 break;
210 case 5:
211 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_256M) >> 10;
212 break;
213 case 6:
214 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_512M) >> 10;
215 break;
216 case 7:
217 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_1G) >> 10;
218 break;
222 tte = address_space_ldq_be(&address_space_memory, baseaddr + offset,
223 MEMTXATTRS_UNSPECIFIED, NULL);
225 if (!(tte & IOMMU_TTE_DATA_V)) {
226 /* Invalid mapping */
227 return ret;
230 if (tte & IOMMU_TTE_DATA_W) {
231 /* Writeable */
232 ret.perm = IOMMU_RW;
233 } else {
234 ret.perm = IOMMU_RO;
237 /* Extract phys */
238 if (tte & IOMMU_TTE_DATA_SIZE) {
239 /* 64K */
240 ret.iova = addr & IOMMU_PAGE_MASK_64K;
241 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_64K;
242 ret.addr_mask = (IOMMU_PAGE_SIZE_64K - 1);
243 } else {
244 /* 8K */
245 ret.iova = addr & IOMMU_PAGE_MASK_8K;
246 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_8K;
247 ret.addr_mask = (IOMMU_PAGE_SIZE_8K - 1);
250 return ret;
253 static void iommu_config_write(void *opaque, hwaddr addr,
254 uint64_t val, unsigned size)
256 IOMMUState *is = opaque;
258 IOMMU_DPRINTF("IOMMU config write: 0x%" HWADDR_PRIx " val: %" PRIx64
259 " size: %d\n", addr, val, size);
261 switch (addr) {
262 case IOMMU_CTRL:
263 if (size == 4) {
264 is->regs[IOMMU_CTRL >> 3] &= 0xffffffffULL;
265 is->regs[IOMMU_CTRL >> 3] |= val << 32;
266 } else {
267 is->regs[IOMMU_CTRL >> 3] = val;
269 break;
270 case IOMMU_CTRL + 0x4:
271 is->regs[IOMMU_CTRL >> 3] &= 0xffffffff00000000ULL;
272 is->regs[IOMMU_CTRL >> 3] |= val & 0xffffffffULL;
273 break;
274 case IOMMU_BASE:
275 if (size == 4) {
276 is->regs[IOMMU_BASE >> 3] &= 0xffffffffULL;
277 is->regs[IOMMU_BASE >> 3] |= val << 32;
278 } else {
279 is->regs[IOMMU_BASE >> 3] = val;
281 break;
282 case IOMMU_BASE + 0x4:
283 is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
284 is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
285 break;
286 case IOMMU_FLUSH:
287 case IOMMU_FLUSH + 0x4:
288 break;
289 default:
290 qemu_log_mask(LOG_UNIMP,
291 "apb iommu: Unimplemented register write "
292 "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
293 addr, size, val);
294 break;
298 static uint64_t iommu_config_read(void *opaque, hwaddr addr, unsigned size)
300 IOMMUState *is = opaque;
301 uint64_t val;
303 switch (addr) {
304 case IOMMU_CTRL:
305 if (size == 4) {
306 val = is->regs[IOMMU_CTRL >> 3] >> 32;
307 } else {
308 val = is->regs[IOMMU_CTRL >> 3];
310 break;
311 case IOMMU_CTRL + 0x4:
312 val = is->regs[IOMMU_CTRL >> 3] & 0xffffffffULL;
313 break;
314 case IOMMU_BASE:
315 if (size == 4) {
316 val = is->regs[IOMMU_BASE >> 3] >> 32;
317 } else {
318 val = is->regs[IOMMU_BASE >> 3];
320 break;
321 case IOMMU_BASE + 0x4:
322 val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
323 break;
324 case IOMMU_FLUSH:
325 case IOMMU_FLUSH + 0x4:
326 val = 0;
327 break;
328 default:
329 qemu_log_mask(LOG_UNIMP,
330 "apb iommu: Unimplemented register read "
331 "reg 0x%" HWADDR_PRIx " size 0x%x\n",
332 addr, size);
333 val = 0;
334 break;
337 IOMMU_DPRINTF("IOMMU config read: 0x%" HWADDR_PRIx " val: %" PRIx64
338 " size: %d\n", addr, val, size);
340 return val;
343 static void apb_config_writel (void *opaque, hwaddr addr,
344 uint64_t val, unsigned size)
346 APBState *s = opaque;
347 IOMMUState *is = &s->iommu;
349 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
351 switch (addr & 0xffff) {
352 case 0x30 ... 0x4f: /* DMA error registers */
353 /* XXX: not implemented yet */
354 break;
355 case 0x200 ... 0x217: /* IOMMU */
356 iommu_config_write(is, (addr & 0x1f), val, size);
357 break;
358 case 0xc00 ... 0xc3f: /* PCI interrupt control */
359 if (addr & 4) {
360 unsigned int ino = (addr & 0x3f) >> 3;
361 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
362 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
363 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
364 pbm_clear_request(s, ino);
366 pbm_check_irqs(s);
368 break;
369 case 0x1000 ... 0x107f: /* OBIO interrupt control */
370 if (addr & 4) {
371 unsigned int ino = ((addr & 0xff) >> 3);
372 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
373 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
374 if ((s->irq_request == (ino | 0x20))
375 && !(val & ~PBM_PCI_IMR_MASK)) {
376 pbm_clear_request(s, ino | 0x20);
378 pbm_check_irqs(s);
380 break;
381 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
382 if (addr & 4) {
383 unsigned int ino = (addr & 0xff) >> 5;
384 if ((s->irq_request / 4) == ino) {
385 pbm_clear_request(s, s->irq_request);
386 pbm_check_irqs(s);
389 break;
390 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
391 if (addr & 4) {
392 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
393 if (s->irq_request == ino) {
394 pbm_clear_request(s, ino);
395 pbm_check_irqs(s);
398 break;
399 case 0x2000 ... 0x202f: /* PCI control */
400 s->pci_control[(addr & 0x3f) >> 2] = val;
401 break;
402 case 0xf020 ... 0xf027: /* Reset control */
403 if (addr & 4) {
404 val &= RESET_MASK;
405 s->reset_control &= ~(val & RESET_WCMASK);
406 s->reset_control |= val & RESET_WMASK;
407 if (val & SOFT_POR) {
408 s->nr_resets = 0;
409 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
410 } else if (val & SOFT_XIR) {
411 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
414 break;
415 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
416 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
417 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
418 case 0xf000 ... 0xf01f: /* FFB config, memory control */
419 /* we don't care */
420 default:
421 break;
425 static uint64_t apb_config_readl (void *opaque,
426 hwaddr addr, unsigned size)
428 APBState *s = opaque;
429 IOMMUState *is = &s->iommu;
430 uint32_t val;
432 switch (addr & 0xffff) {
433 case 0x30 ... 0x4f: /* DMA error registers */
434 val = 0;
435 /* XXX: not implemented yet */
436 break;
437 case 0x200 ... 0x217: /* IOMMU */
438 val = iommu_config_read(is, (addr & 0x1f), size);
439 break;
440 case 0xc00 ... 0xc3f: /* PCI interrupt control */
441 if (addr & 4) {
442 val = s->pci_irq_map[(addr & 0x3f) >> 3];
443 } else {
444 val = 0;
446 break;
447 case 0x1000 ... 0x107f: /* OBIO interrupt control */
448 if (addr & 4) {
449 val = s->obio_irq_map[(addr & 0xff) >> 3];
450 } else {
451 val = 0;
453 break;
454 case 0x1080 ... 0x108f: /* PCI bus error */
455 if (addr & 4) {
456 val = s->pci_err_irq_map[(addr & 0xf) >> 3];
457 } else {
458 val = 0;
460 break;
461 case 0x2000 ... 0x202f: /* PCI control */
462 val = s->pci_control[(addr & 0x3f) >> 2];
463 break;
464 case 0xf020 ... 0xf027: /* Reset control */
465 if (addr & 4) {
466 val = s->reset_control;
467 } else {
468 val = 0;
470 break;
471 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
472 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
473 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
474 case 0xf000 ... 0xf01f: /* FFB config, memory control */
475 /* we don't care */
476 default:
477 val = 0;
478 break;
480 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
482 return val;
485 static const MemoryRegionOps apb_config_ops = {
486 .read = apb_config_readl,
487 .write = apb_config_writel,
488 .endianness = DEVICE_BIG_ENDIAN,
491 static void apb_pci_config_write(void *opaque, hwaddr addr,
492 uint64_t val, unsigned size)
494 APBState *s = opaque;
495 PCIHostState *phb = PCI_HOST_BRIDGE(s);
497 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
498 pci_data_write(phb->bus, addr, val, size);
501 static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
502 unsigned size)
504 uint32_t ret;
505 APBState *s = opaque;
506 PCIHostState *phb = PCI_HOST_BRIDGE(s);
508 ret = pci_data_read(phb->bus, addr, size);
509 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
510 return ret;
513 /* The APB host has an IRQ line for each IRQ line of each slot. */
514 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
516 /* Return the irq as swizzled by the PBM */
517 return irq_num;
520 static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
522 PBMPCIBridge *br = PBM_PCI_BRIDGE(pci_bridge_get_device(
523 PCI_BUS(qdev_get_parent_bus(DEVICE(pci_dev)))));
525 int bus_offset;
526 if (br->busA) {
527 bus_offset = 0x0;
529 /* The on-board devices have fixed (legacy) OBIO intnos */
530 switch (PCI_SLOT(pci_dev->devfn)) {
531 case 1:
532 /* Onboard NIC */
533 return 0x21;
534 case 3:
535 /* Onboard IDE */
536 return 0x20;
538 default:
539 /* Normal intno, fall through */
540 break;
542 } else {
543 bus_offset = 0x10;
545 return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
548 static void pci_apb_set_irq(void *opaque, int irq_num, int level)
550 APBState *s = opaque;
552 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
553 /* PCI IRQ map onto the first 32 INO. */
554 if (irq_num < 32) {
555 if (level) {
556 s->pci_irq_in |= 1ULL << irq_num;
557 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
558 pbm_set_request(s, irq_num);
560 } else {
561 s->pci_irq_in &= ~(1ULL << irq_num);
563 } else {
564 /* OBIO IRQ map onto the next 32 INO. */
565 if (level) {
566 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
567 s->pci_irq_in |= 1ULL << irq_num;
568 if ((s->irq_request == NO_IRQ_REQUEST)
569 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
570 pbm_set_request(s, irq_num);
572 } else {
573 s->pci_irq_in &= ~(1ULL << irq_num);
578 static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
581 * command register:
582 * According to PCI bridge spec, after reset
583 * bus master bit is off
584 * memory space enable bit is off
585 * According to manual (805-1251.pdf).
586 * the reset value should be zero unless the boot pin is tied high
587 * (which is true) and thus it should be PCI_COMMAND_MEMORY.
589 uint16_t cmd = PCI_COMMAND_MEMORY;
590 PBMPCIBridge *br = PBM_PCI_BRIDGE(dev);
592 pci_bridge_initfn(dev, TYPE_PCI_BUS);
594 /* If initialising busA, ensure that we allow IO transactions so that
595 we get the early serial console until OpenBIOS configures the bridge */
596 if (br->busA) {
597 cmd |= PCI_COMMAND_IO;
600 pci_set_word(dev->config + PCI_COMMAND, cmd);
601 pci_set_word(dev->config + PCI_STATUS,
602 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
603 PCI_STATUS_DEVSEL_MEDIUM);
605 /* Allow 32-bit IO addresses */
606 pci_set_word(dev->config + PCI_IO_BASE, PCI_IO_RANGE_TYPE_32);
607 pci_set_word(dev->config + PCI_IO_LIMIT, PCI_IO_RANGE_TYPE_32);
608 pci_set_word(dev->wmask + PCI_IO_BASE_UPPER16, 0xffff);
609 pci_set_word(dev->wmask + PCI_IO_LIMIT_UPPER16, 0xffff);
611 pci_bridge_update_mappings(PCI_BRIDGE(br));
614 APBState *pci_apb_init(hwaddr special_base,
615 hwaddr mem_base)
617 DeviceState *dev;
618 SysBusDevice *s;
619 PCIHostState *phb;
620 APBState *d;
621 IOMMUState *is;
622 PCIDevice *pci_dev;
624 /* Ultrasparc PBM main bus */
625 dev = qdev_create(NULL, TYPE_APB);
626 d = APB_DEVICE(dev);
627 phb = PCI_HOST_BRIDGE(dev);
628 phb->bus = pci_register_bus(DEVICE(phb), "pci",
629 pci_apb_set_irq, pci_apb_map_irq, d,
630 &d->pci_mmio,
631 &d->pci_ioport,
632 0, 32, TYPE_PCI_BUS);
633 qdev_init_nofail(dev);
634 s = SYS_BUS_DEVICE(dev);
635 /* apb_config */
636 sysbus_mmio_map(s, 0, special_base);
637 /* PCI configuration space */
638 sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
639 /* pci_ioport */
640 sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
642 memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
643 memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
645 pci_create_simple(phb->bus, 0, "pbm-pci");
647 /* APB IOMMU */
648 is = &d->iommu;
649 memset(is, 0, sizeof(IOMMUState));
651 memory_region_init_iommu(&is->iommu, sizeof(is->iommu),
652 TYPE_APB_IOMMU_MEMORY_REGION, OBJECT(dev),
653 "iommu-apb", UINT64_MAX);
654 address_space_init(&is->iommu_as, MEMORY_REGION(&is->iommu), "pbm-as");
655 pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, is);
657 /* APB secondary busses */
658 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
659 TYPE_PBM_PCI_BRIDGE);
660 d->bridgeB = PCI_BRIDGE(pci_dev);
661 pci_bridge_map_irq(d->bridgeB, "pciB", pci_pbm_map_irq);
662 qdev_init_nofail(&pci_dev->qdev);
664 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
665 TYPE_PBM_PCI_BRIDGE);
666 d->bridgeA = PCI_BRIDGE(pci_dev);
667 pci_bridge_map_irq(d->bridgeA, "pciA", pci_pbm_map_irq);
668 qdev_prop_set_bit(DEVICE(pci_dev), "busA", true);
669 qdev_init_nofail(&pci_dev->qdev);
671 return d;
674 static void pci_pbm_reset(DeviceState *d)
676 unsigned int i;
677 APBState *s = APB_DEVICE(d);
679 for (i = 0; i < 8; i++) {
680 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
682 for (i = 0; i < 32; i++) {
683 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
686 s->irq_request = NO_IRQ_REQUEST;
687 s->pci_irq_in = 0ULL;
689 if (s->nr_resets++ == 0) {
690 /* Power on reset */
691 s->reset_control = POR;
695 static const MemoryRegionOps pci_config_ops = {
696 .read = apb_pci_config_read,
697 .write = apb_pci_config_write,
698 .endianness = DEVICE_LITTLE_ENDIAN,
701 static int pci_pbm_init_device(DeviceState *dev)
703 APBState *s = APB_DEVICE(dev);
704 SysBusDevice *sbd = SYS_BUS_DEVICE(s);
705 unsigned int i;
707 for (i = 0; i < 8; i++) {
708 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
710 for (i = 0; i < 2; i++) {
711 s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
713 for (i = 0; i < 32; i++) {
714 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
716 s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
717 qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
718 s->irq_request = NO_IRQ_REQUEST;
719 s->pci_irq_in = 0ULL;
721 /* apb_config */
722 memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
723 "apb-config", 0x10000);
724 /* at region 0 */
725 sysbus_init_mmio(sbd, &s->apb_config);
727 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
728 "apb-pci-config", 0x1000000);
729 /* at region 1 */
730 sysbus_init_mmio(sbd, &s->pci_config);
732 /* pci_ioport */
733 memory_region_init(&s->pci_ioport, OBJECT(s), "apb-pci-ioport", 0x1000000);
735 /* at region 2 */
736 sysbus_init_mmio(sbd, &s->pci_ioport);
738 return 0;
741 static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
743 pci_set_word(d->config + PCI_COMMAND,
744 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
745 pci_set_word(d->config + PCI_STATUS,
746 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
747 PCI_STATUS_DEVSEL_MEDIUM);
750 static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
752 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
753 DeviceClass *dc = DEVICE_CLASS(klass);
755 k->realize = pbm_pci_host_realize;
756 k->vendor_id = PCI_VENDOR_ID_SUN;
757 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
758 k->class_id = PCI_CLASS_BRIDGE_HOST;
760 * PCI-facing part of the host bridge, not usable without the
761 * host-facing part, which can't be device_add'ed, yet.
763 dc->user_creatable = false;
766 static const TypeInfo pbm_pci_host_info = {
767 .name = "pbm-pci",
768 .parent = TYPE_PCI_DEVICE,
769 .instance_size = sizeof(PCIDevice),
770 .class_init = pbm_pci_host_class_init,
771 .interfaces = (InterfaceInfo[]) {
772 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
773 { },
777 static void pbm_host_class_init(ObjectClass *klass, void *data)
779 DeviceClass *dc = DEVICE_CLASS(klass);
781 dc->init = pci_pbm_init_device;
782 dc->reset = pci_pbm_reset;
783 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
786 static const TypeInfo pbm_host_info = {
787 .name = TYPE_APB,
788 .parent = TYPE_PCI_HOST_BRIDGE,
789 .instance_size = sizeof(APBState),
790 .class_init = pbm_host_class_init,
793 static Property pbm_pci_properties[] = {
794 DEFINE_PROP_BOOL("busA", PBMPCIBridge, busA, false),
795 DEFINE_PROP_END_OF_LIST(),
798 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
800 DeviceClass *dc = DEVICE_CLASS(klass);
801 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
803 k->realize = apb_pci_bridge_realize;
804 k->exit = pci_bridge_exitfn;
805 k->vendor_id = PCI_VENDOR_ID_SUN;
806 k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
807 k->revision = 0x11;
808 k->config_write = pci_bridge_write_config;
809 k->is_bridge = 1;
810 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
811 dc->reset = pci_bridge_reset;
812 dc->vmsd = &vmstate_pci_device;
813 dc->props = pbm_pci_properties;
816 static const TypeInfo pbm_pci_bridge_info = {
817 .name = TYPE_PBM_PCI_BRIDGE,
818 .parent = TYPE_PCI_BRIDGE,
819 .class_init = pbm_pci_bridge_class_init,
820 .instance_size = sizeof(PBMPCIBridge),
821 .interfaces = (InterfaceInfo[]) {
822 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
823 { },
827 static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)
829 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
831 imrc->translate = pbm_translate_iommu;
834 static const TypeInfo pbm_iommu_memory_region_info = {
835 .parent = TYPE_IOMMU_MEMORY_REGION,
836 .name = TYPE_APB_IOMMU_MEMORY_REGION,
837 .class_init = pbm_iommu_memory_region_class_init,
840 static void pbm_register_types(void)
842 type_register_static(&pbm_host_info);
843 type_register_static(&pbm_pci_host_info);
844 type_register_static(&pbm_pci_bridge_info);
845 type_register_static(&pbm_iommu_memory_region_info);
848 type_init(pbm_register_types)