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
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 "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"
43 #define APB_DPRINTF(fmt, ...) \
44 do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
46 #define APB_DPRINTF(fmt, ...)
53 #define IOMMU_DPRINTF(fmt, ...) \
54 do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
56 #define IOMMU_DPRINTF(fmt, ...)
61 * PBM: "UltraSPARC IIi User's Manual",
62 * http://www.sun.com/processors/manuals/805-0087.pdf
64 * APB: "Advanced PCI Bridge (APB) User's Manual",
65 * http://www.sun.com/processors/manuals/805-1251.pdf
68 #define PBM_PCI_IMR_MASK 0x7fffffff
69 #define PBM_PCI_IMR_ENABLED 0x80000000
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
81 #define NO_IRQ_REQUEST (MAX_IVEC + 1)
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))
90 #define IOMMU_CTRL 0x0
91 #define IOMMU_CTRL_TBW_SIZE (1ULL << 2)
92 #define IOMMU_CTRL_MMU_EN (1ULL)
94 #define IOMMU_CTRL_TSB_SHIFT 16
96 #define IOMMU_BASE 0x8
97 #define IOMMU_FLUSH 0x10
99 #define IOMMU_TTE_DATA_V (1ULL << 63)
100 #define IOMMU_TTE_DATA_SIZE (1ULL << 61)
101 #define IOMMU_TTE_DATA_W (1ULL << 1)
103 #define IOMMU_TTE_PHYS_MASK_8K 0x1ffffffe000ULL
104 #define IOMMU_TTE_PHYS_MASK_64K 0x1ffffff8000ULL
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
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
122 typedef struct IOMMUState {
123 AddressSpace iommu_as;
126 uint64_t regs[IOMMU_NREGS];
129 #define TYPE_APB "pbm"
131 #define APB_DEVICE(obj) \
132 OBJECT_CHECK(APBState, (obj), TYPE_APB)
134 typedef struct APBState {
135 PCIHostState parent_obj;
137 MemoryRegion apb_config;
138 MemoryRegion pci_config;
139 MemoryRegion pci_mmio;
140 MemoryRegion pci_ioport;
143 uint32_t pci_control[16];
144 uint32_t pci_irq_map[8];
145 uint32_t obio_irq_map[32];
148 unsigned int irq_request;
149 uint32_t reset_control;
150 unsigned int nr_resets;
153 static inline void pbm_set_request(APBState *s, unsigned int irq_num)
155 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
157 s->irq_request = irq_num;
158 qemu_set_irq(s->ivec_irqs[irq_num], 1);
161 static inline void pbm_check_irqs(APBState *s)
166 /* Previous request is not acknowledged, resubmit */
167 if (s->irq_request != NO_IRQ_REQUEST) {
168 pbm_set_request(s, s->irq_request);
171 /* no request pending */
172 if (s->pci_irq_in == 0ULL) {
175 for (i = 0; i < 32; i++) {
176 if (s->pci_irq_in & (1ULL << i)) {
177 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
178 pbm_set_request(s, i);
183 for (i = 32; i < 64; i++) {
184 if (s->pci_irq_in & (1ULL << i)) {
185 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
186 pbm_set_request(s, i);
193 static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
195 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
196 qemu_set_irq(s->ivec_irqs[irq_num], 0);
197 s->irq_request = NO_IRQ_REQUEST;
200 static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
202 IOMMUState *is = opaque;
204 return &is->iommu_as;
207 static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr,
210 IOMMUState *is = container_of(iommu, IOMMUState, iommu);
211 hwaddr baseaddr, offset;
214 IOMMUTLBEntry ret = {
215 .target_as = &address_space_memory,
217 .translated_addr = 0,
218 .addr_mask = ~(hwaddr)0,
222 if (!(is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_MMU_EN)) {
223 /* IOMMU disabled, passthrough using standard 8K page */
224 ret.iova = addr & IOMMU_PAGE_MASK_8K;
225 ret.translated_addr = addr;
226 ret.addr_mask = IOMMU_PAGE_MASK_8K;
232 baseaddr = is->regs[IOMMU_BASE >> 3];
233 tsbsize = (is->regs[IOMMU_CTRL >> 3] >> IOMMU_CTRL_TSB_SHIFT) & 0x7;
235 if (is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_TBW_SIZE) {
239 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_64M) >> 13;
242 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_128M) >> 13;
245 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_256M) >> 13;
248 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_512M) >> 13;
251 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_1G) >> 13;
254 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_2G) >> 13;
257 /* Not implemented, error */
264 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_8M) >> 10;
267 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_16M) >> 10;
270 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_32M) >> 10;
273 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_64M) >> 10;
276 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_128M) >> 10;
279 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_256M) >> 10;
282 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_512M) >> 10;
285 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_1G) >> 10;
290 tte = ldq_be_phys(&address_space_memory, baseaddr + offset);
292 if (!(tte & IOMMU_TTE_DATA_V)) {
293 /* Invalid mapping */
297 if (tte & IOMMU_TTE_DATA_W) {
305 if (tte & IOMMU_TTE_DATA_SIZE) {
307 ret.iova = addr & IOMMU_PAGE_MASK_64K;
308 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_64K;
309 ret.addr_mask = (IOMMU_PAGE_SIZE_64K - 1);
312 ret.iova = addr & IOMMU_PAGE_MASK_8K;
313 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_8K;
314 ret.addr_mask = (IOMMU_PAGE_SIZE_8K - 1);
320 static MemoryRegionIOMMUOps pbm_iommu_ops = {
321 .translate = pbm_translate_iommu,
324 static void iommu_config_write(void *opaque, hwaddr addr,
325 uint64_t val, unsigned size)
327 IOMMUState *is = opaque;
329 IOMMU_DPRINTF("IOMMU config write: 0x%" HWADDR_PRIx " val: %" PRIx64
330 " size: %d\n", addr, val, size);
335 is->regs[IOMMU_CTRL >> 3] &= 0xffffffffULL;
336 is->regs[IOMMU_CTRL >> 3] |= val << 32;
338 is->regs[IOMMU_CTRL >> 3] = val;
341 case IOMMU_CTRL + 0x4:
342 is->regs[IOMMU_CTRL >> 3] &= 0xffffffff00000000ULL;
343 is->regs[IOMMU_CTRL >> 3] |= val & 0xffffffffULL;
347 is->regs[IOMMU_BASE >> 3] &= 0xffffffffULL;
348 is->regs[IOMMU_BASE >> 3] |= val << 32;
350 is->regs[IOMMU_BASE >> 3] = val;
353 case IOMMU_BASE + 0x4:
354 is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
355 is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
358 case IOMMU_FLUSH + 0x4:
361 qemu_log_mask(LOG_UNIMP,
362 "apb iommu: Unimplemented register write "
363 "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
369 static uint64_t iommu_config_read(void *opaque, hwaddr addr, unsigned size)
371 IOMMUState *is = opaque;
377 val = is->regs[IOMMU_CTRL >> 3] >> 32;
379 val = is->regs[IOMMU_CTRL >> 3];
382 case IOMMU_CTRL + 0x4:
383 val = is->regs[IOMMU_CTRL >> 3] & 0xffffffffULL;
387 val = is->regs[IOMMU_BASE >> 3] >> 32;
389 val = is->regs[IOMMU_BASE >> 3];
392 case IOMMU_BASE + 0x4:
393 val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
396 case IOMMU_FLUSH + 0x4:
400 qemu_log_mask(LOG_UNIMP,
401 "apb iommu: Unimplemented register read "
402 "reg 0x%" HWADDR_PRIx " size 0x%x\n",
408 IOMMU_DPRINTF("IOMMU config read: 0x%" HWADDR_PRIx " val: %" PRIx64
409 " size: %d\n", addr, val, size);
414 static void apb_config_writel (void *opaque, hwaddr addr,
415 uint64_t val, unsigned size)
417 APBState *s = opaque;
418 IOMMUState *is = &s->iommu;
420 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
422 switch (addr & 0xffff) {
423 case 0x30 ... 0x4f: /* DMA error registers */
424 /* XXX: not implemented yet */
426 case 0x200 ... 0x217: /* IOMMU */
427 iommu_config_write(is, (addr & 0x1f), val, size);
429 case 0xc00 ... 0xc3f: /* PCI interrupt control */
431 unsigned int ino = (addr & 0x3f) >> 3;
432 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
433 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
434 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
435 pbm_clear_request(s, ino);
440 case 0x1000 ... 0x1080: /* OBIO interrupt control */
442 unsigned int ino = ((addr & 0xff) >> 3);
443 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
444 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
445 if ((s->irq_request == (ino | 0x20))
446 && !(val & ~PBM_PCI_IMR_MASK)) {
447 pbm_clear_request(s, ino | 0x20);
452 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
454 unsigned int ino = (addr & 0xff) >> 5;
455 if ((s->irq_request / 4) == ino) {
456 pbm_clear_request(s, s->irq_request);
461 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
463 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
464 if (s->irq_request == ino) {
465 pbm_clear_request(s, ino);
470 case 0x2000 ... 0x202f: /* PCI control */
471 s->pci_control[(addr & 0x3f) >> 2] = val;
473 case 0xf020 ... 0xf027: /* Reset control */
476 s->reset_control &= ~(val & RESET_WCMASK);
477 s->reset_control |= val & RESET_WMASK;
478 if (val & SOFT_POR) {
480 qemu_system_reset_request();
481 } else if (val & SOFT_XIR) {
482 qemu_system_reset_request();
486 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
487 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
488 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
489 case 0xf000 ... 0xf01f: /* FFB config, memory control */
496 static uint64_t apb_config_readl (void *opaque,
497 hwaddr addr, unsigned size)
499 APBState *s = opaque;
500 IOMMUState *is = &s->iommu;
503 switch (addr & 0xffff) {
504 case 0x30 ... 0x4f: /* DMA error registers */
506 /* XXX: not implemented yet */
508 case 0x200 ... 0x217: /* IOMMU */
509 val = iommu_config_read(is, (addr & 0x1f), size);
511 case 0xc00 ... 0xc3f: /* PCI interrupt control */
513 val = s->pci_irq_map[(addr & 0x3f) >> 3];
518 case 0x1000 ... 0x1080: /* OBIO interrupt control */
520 val = s->obio_irq_map[(addr & 0xff) >> 3];
525 case 0x2000 ... 0x202f: /* PCI control */
526 val = s->pci_control[(addr & 0x3f) >> 2];
528 case 0xf020 ... 0xf027: /* Reset control */
530 val = s->reset_control;
535 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
536 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
537 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
538 case 0xf000 ... 0xf01f: /* FFB config, memory control */
544 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
549 static const MemoryRegionOps apb_config_ops = {
550 .read = apb_config_readl,
551 .write = apb_config_writel,
552 .endianness = DEVICE_NATIVE_ENDIAN,
555 static void apb_pci_config_write(void *opaque, hwaddr addr,
556 uint64_t val, unsigned size)
558 APBState *s = opaque;
559 PCIHostState *phb = PCI_HOST_BRIDGE(s);
561 val = qemu_bswap_len(val, size);
562 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
563 pci_data_write(phb->bus, addr, val, size);
566 static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
570 APBState *s = opaque;
571 PCIHostState *phb = PCI_HOST_BRIDGE(s);
573 ret = pci_data_read(phb->bus, addr, size);
574 ret = qemu_bswap_len(ret, size);
575 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
579 /* The APB host has an IRQ line for each IRQ line of each slot. */
580 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
582 return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
585 static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
588 if (pci_dev->devfn & 1)
592 return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
595 static void pci_apb_set_irq(void *opaque, int irq_num, int level)
597 APBState *s = opaque;
599 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
600 /* PCI IRQ map onto the first 32 INO. */
603 s->pci_irq_in |= 1ULL << irq_num;
604 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
605 pbm_set_request(s, irq_num);
608 s->pci_irq_in &= ~(1ULL << irq_num);
611 /* OBIO IRQ map onto the next 32 INO. */
613 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
614 s->pci_irq_in |= 1ULL << irq_num;
615 if ((s->irq_request == NO_IRQ_REQUEST)
616 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
617 pbm_set_request(s, irq_num);
620 s->pci_irq_in &= ~(1ULL << irq_num);
625 static int apb_pci_bridge_initfn(PCIDevice *dev)
629 rc = pci_bridge_initfn(dev, TYPE_PCI_BUS);
636 * According to PCI bridge spec, after reset
637 * bus master bit is off
638 * memory space enable bit is off
639 * According to manual (805-1251.pdf).
640 * the reset value should be zero unless the boot pin is tied high
641 * (which is true) and thus it should be PCI_COMMAND_MEMORY.
643 pci_set_word(dev->config + PCI_COMMAND,
645 pci_set_word(dev->config + PCI_STATUS,
646 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
647 PCI_STATUS_DEVSEL_MEDIUM);
651 PCIBus *pci_apb_init(hwaddr special_base,
653 qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
664 /* Ultrasparc PBM main bus */
665 dev = qdev_create(NULL, TYPE_APB);
666 qdev_init_nofail(dev);
667 s = SYS_BUS_DEVICE(dev);
669 sysbus_mmio_map(s, 0, special_base);
670 /* PCI configuration space */
671 sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
673 sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
676 memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
677 memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
679 phb = PCI_HOST_BRIDGE(dev);
680 phb->bus = pci_register_bus(DEVICE(phb), "pci",
681 pci_apb_set_irq, pci_pbm_map_irq, d,
684 0, 32, TYPE_PCI_BUS);
686 *pbm_irqs = d->pbm_irqs;
687 d->ivec_irqs = ivec_irqs;
689 pci_create_simple(phb->bus, 0, "pbm-pci");
693 memset(is, 0, sizeof(IOMMUState));
695 memory_region_init_iommu(&is->iommu, OBJECT(dev), &pbm_iommu_ops,
696 "iommu-apb", UINT64_MAX);
697 address_space_init(&is->iommu_as, &is->iommu, "pbm-as");
698 pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, is);
700 /* APB secondary busses */
701 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
703 br = PCI_BRIDGE(pci_dev);
704 pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
706 qdev_init_nofail(&pci_dev->qdev);
707 *bus2 = pci_bridge_get_sec_bus(br);
709 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
711 br = PCI_BRIDGE(pci_dev);
712 pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
714 qdev_init_nofail(&pci_dev->qdev);
715 *bus3 = pci_bridge_get_sec_bus(br);
720 static void pci_pbm_reset(DeviceState *d)
723 APBState *s = APB_DEVICE(d);
725 for (i = 0; i < 8; i++) {
726 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
728 for (i = 0; i < 32; i++) {
729 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
732 s->irq_request = NO_IRQ_REQUEST;
733 s->pci_irq_in = 0ULL;
735 if (s->nr_resets++ == 0) {
737 s->reset_control = POR;
741 static const MemoryRegionOps pci_config_ops = {
742 .read = apb_pci_config_read,
743 .write = apb_pci_config_write,
744 .endianness = DEVICE_NATIVE_ENDIAN,
747 static int pci_pbm_init_device(SysBusDevice *dev)
753 for (i = 0; i < 8; i++) {
754 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
756 for (i = 0; i < 32; i++) {
757 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
759 s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
760 s->irq_request = NO_IRQ_REQUEST;
761 s->pci_irq_in = 0ULL;
764 memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
765 "apb-config", 0x10000);
767 sysbus_init_mmio(dev, &s->apb_config);
769 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
770 "apb-pci-config", 0x1000000);
772 sysbus_init_mmio(dev, &s->pci_config);
775 memory_region_init_alias(&s->pci_ioport, OBJECT(s), "apb-pci-ioport",
776 get_system_io(), 0, 0x10000);
778 sysbus_init_mmio(dev, &s->pci_ioport);
783 static int pbm_pci_host_init(PCIDevice *d)
785 pci_set_word(d->config + PCI_COMMAND,
786 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
787 pci_set_word(d->config + PCI_STATUS,
788 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
789 PCI_STATUS_DEVSEL_MEDIUM);
793 static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
795 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
796 DeviceClass *dc = DEVICE_CLASS(klass);
798 k->init = pbm_pci_host_init;
799 k->vendor_id = PCI_VENDOR_ID_SUN;
800 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
801 k->class_id = PCI_CLASS_BRIDGE_HOST;
803 * PCI-facing part of the host bridge, not usable without the
804 * host-facing part, which can't be device_add'ed, yet.
806 dc->cannot_instantiate_with_device_add_yet = true;
809 static const TypeInfo pbm_pci_host_info = {
811 .parent = TYPE_PCI_DEVICE,
812 .instance_size = sizeof(PCIDevice),
813 .class_init = pbm_pci_host_class_init,
816 static void pbm_host_class_init(ObjectClass *klass, void *data)
818 DeviceClass *dc = DEVICE_CLASS(klass);
819 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
821 k->init = pci_pbm_init_device;
822 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
823 dc->reset = pci_pbm_reset;
826 static const TypeInfo pbm_host_info = {
828 .parent = TYPE_PCI_HOST_BRIDGE,
829 .instance_size = sizeof(APBState),
830 .class_init = pbm_host_class_init,
833 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
835 DeviceClass *dc = DEVICE_CLASS(klass);
836 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
838 k->init = apb_pci_bridge_initfn;
839 k->exit = pci_bridge_exitfn;
840 k->vendor_id = PCI_VENDOR_ID_SUN;
841 k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
843 k->config_write = pci_bridge_write_config;
845 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
846 dc->reset = pci_bridge_reset;
847 dc->vmsd = &vmstate_pci_device;
850 static const TypeInfo pbm_pci_bridge_info = {
851 .name = "pbm-bridge",
852 .parent = TYPE_PCI_BRIDGE,
853 .class_init = pbm_pci_bridge_class_init,
856 static void pbm_register_types(void)
858 type_register_static(&pbm_host_info);
859 type_register_static(&pbm_pci_host_info);
860 type_register_static(&pbm_pci_bridge_info);
863 type_init(pbm_register_types)