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 "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"
45 #define APB_DPRINTF(fmt, ...) \
46 do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
48 #define APB_DPRINTF(fmt, ...)
55 #define IOMMU_DPRINTF(fmt, ...) \
56 do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
58 #define IOMMU_DPRINTF(fmt, ...)
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
)
97 /* Previous request is not acknowledged, resubmit */
98 if (s
->irq_request
!= NO_IRQ_REQUEST
) {
99 pbm_set_request(s
, s
->irq_request
);
102 /* no request pending */
103 if (s
->pci_irq_in
== 0ULL) {
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
);
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
);
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
;
146 IOMMUTLBEntry ret
= {
147 .target_as
= &address_space_memory
,
149 .translated_addr
= 0,
150 .addr_mask
= ~(hwaddr
)0,
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
;
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
) {
171 offset
= (addr
& IOMMU_TSB_64K_OFFSET_MASK_64M
) >> 13;
174 offset
= (addr
& IOMMU_TSB_64K_OFFSET_MASK_128M
) >> 13;
177 offset
= (addr
& IOMMU_TSB_64K_OFFSET_MASK_256M
) >> 13;
180 offset
= (addr
& IOMMU_TSB_64K_OFFSET_MASK_512M
) >> 13;
183 offset
= (addr
& IOMMU_TSB_64K_OFFSET_MASK_1G
) >> 13;
186 offset
= (addr
& IOMMU_TSB_64K_OFFSET_MASK_2G
) >> 13;
189 /* Not implemented, error */
196 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_8M
) >> 10;
199 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_16M
) >> 10;
202 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_32M
) >> 10;
205 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_64M
) >> 10;
208 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_128M
) >> 10;
211 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_256M
) >> 10;
214 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_512M
) >> 10;
217 offset
= (addr
& IOMMU_TSB_8K_OFFSET_MASK_1G
) >> 10;
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 */
230 if (tte
& IOMMU_TTE_DATA_W
) {
238 if (tte
& IOMMU_TTE_DATA_SIZE
) {
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);
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);
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
);
264 is
->regs
[IOMMU_CTRL
>> 3] &= 0xffffffffULL
;
265 is
->regs
[IOMMU_CTRL
>> 3] |= val
<< 32;
267 is
->regs
[IOMMU_CTRL
>> 3] = val
;
270 case IOMMU_CTRL
+ 0x4:
271 is
->regs
[IOMMU_CTRL
>> 3] &= 0xffffffff00000000ULL
;
272 is
->regs
[IOMMU_CTRL
>> 3] |= val
& 0xffffffffULL
;
276 is
->regs
[IOMMU_BASE
>> 3] &= 0xffffffffULL
;
277 is
->regs
[IOMMU_BASE
>> 3] |= val
<< 32;
279 is
->regs
[IOMMU_BASE
>> 3] = val
;
282 case IOMMU_BASE
+ 0x4:
283 is
->regs
[IOMMU_BASE
>> 3] &= 0xffffffff00000000ULL
;
284 is
->regs
[IOMMU_BASE
>> 3] |= val
& 0xffffffffULL
;
287 case IOMMU_FLUSH
+ 0x4:
290 qemu_log_mask(LOG_UNIMP
,
291 "apb iommu: Unimplemented register write "
292 "reg 0x%" HWADDR_PRIx
" size 0x%x value 0x%" PRIx64
"\n",
298 static uint64_t iommu_config_read(void *opaque
, hwaddr addr
, unsigned size
)
300 IOMMUState
*is
= opaque
;
306 val
= is
->regs
[IOMMU_CTRL
>> 3] >> 32;
308 val
= is
->regs
[IOMMU_CTRL
>> 3];
311 case IOMMU_CTRL
+ 0x4:
312 val
= is
->regs
[IOMMU_CTRL
>> 3] & 0xffffffffULL
;
316 val
= is
->regs
[IOMMU_BASE
>> 3] >> 32;
318 val
= is
->regs
[IOMMU_BASE
>> 3];
321 case IOMMU_BASE
+ 0x4:
322 val
= is
->regs
[IOMMU_BASE
>> 3] & 0xffffffffULL
;
325 case IOMMU_FLUSH
+ 0x4:
329 qemu_log_mask(LOG_UNIMP
,
330 "apb iommu: Unimplemented register read "
331 "reg 0x%" HWADDR_PRIx
" size 0x%x\n",
337 IOMMU_DPRINTF("IOMMU config read: 0x%" HWADDR_PRIx
" val: %" PRIx64
338 " size: %d\n", addr
, val
, size
);
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 */
355 case 0x200 ... 0x217: /* IOMMU */
356 iommu_config_write(is
, (addr
& 0x1f), val
, size
);
358 case 0xc00 ... 0xc3f: /* PCI interrupt control */
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
);
369 case 0x1000 ... 0x107f: /* OBIO interrupt control */
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);
381 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
383 unsigned int ino
= (addr
& 0xff) >> 5;
384 if ((s
->irq_request
/ 4) == ino
) {
385 pbm_clear_request(s
, s
->irq_request
);
390 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
392 unsigned int ino
= ((addr
& 0xff) >> 3) | 0x20;
393 if (s
->irq_request
== ino
) {
394 pbm_clear_request(s
, ino
);
399 case 0x2000 ... 0x202f: /* PCI control */
400 s
->pci_control
[(addr
& 0x3f) >> 2] = val
;
402 case 0xf020 ... 0xf027: /* Reset control */
405 s
->reset_control
&= ~(val
& RESET_WCMASK
);
406 s
->reset_control
|= val
& RESET_WMASK
;
407 if (val
& SOFT_POR
) {
409 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET
);
410 } else if (val
& SOFT_XIR
) {
411 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET
);
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 */
425 static uint64_t apb_config_readl (void *opaque
,
426 hwaddr addr
, unsigned size
)
428 APBState
*s
= opaque
;
429 IOMMUState
*is
= &s
->iommu
;
432 switch (addr
& 0xffff) {
433 case 0x30 ... 0x4f: /* DMA error registers */
435 /* XXX: not implemented yet */
437 case 0x200 ... 0x217: /* IOMMU */
438 val
= iommu_config_read(is
, (addr
& 0x1f), size
);
440 case 0xc00 ... 0xc3f: /* PCI interrupt control */
442 val
= s
->pci_irq_map
[(addr
& 0x3f) >> 3];
447 case 0x1000 ... 0x107f: /* OBIO interrupt control */
449 val
= s
->obio_irq_map
[(addr
& 0xff) >> 3];
454 case 0x1080 ... 0x108f: /* PCI bus error */
456 val
= s
->pci_err_irq_map
[(addr
& 0xf) >> 3];
461 case 0x2000 ... 0x202f: /* PCI control */
462 val
= s
->pci_control
[(addr
& 0x3f) >> 2];
464 case 0xf020 ... 0xf027: /* Reset control */
466 val
= s
->reset_control
;
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 */
480 APB_DPRINTF("%s: addr " TARGET_FMT_plx
" -> %x\n", __func__
, addr
, 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
,
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
);
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 */
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
)))));
529 /* The on-board devices have fixed (legacy) OBIO intnos */
530 switch (PCI_SLOT(pci_dev
->devfn
)) {
539 /* Normal intno, fall through */
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. */
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
);
561 s
->pci_irq_in
&= ~(1ULL << irq_num
);
564 /* OBIO IRQ map onto the next 32 INO. */
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
);
573 s
->pci_irq_in
&= ~(1ULL << irq_num
);
578 static void apb_pci_bridge_realize(PCIDevice
*dev
, Error
**errp
)
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 */
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 static void pci_pbm_reset(DeviceState
*d
)
617 APBState
*s
= APB_DEVICE(d
);
619 for (i
= 0; i
< 8; i
++) {
620 s
->pci_irq_map
[i
] &= PBM_PCI_IMR_MASK
;
622 for (i
= 0; i
< 32; i
++) {
623 s
->obio_irq_map
[i
] &= PBM_PCI_IMR_MASK
;
626 s
->irq_request
= NO_IRQ_REQUEST
;
627 s
->pci_irq_in
= 0ULL;
629 if (s
->nr_resets
++ == 0) {
631 s
->reset_control
= POR
;
635 static const MemoryRegionOps pci_config_ops
= {
636 .read
= apb_pci_config_read
,
637 .write
= apb_pci_config_write
,
638 .endianness
= DEVICE_LITTLE_ENDIAN
,
641 static void pci_pbm_realize(DeviceState
*dev
, Error
**errp
)
643 APBState
*s
= APB_DEVICE(dev
);
644 PCIHostState
*phb
= PCI_HOST_BRIDGE(dev
);
645 SysBusDevice
*sbd
= SYS_BUS_DEVICE(s
);
650 sysbus_mmio_map(sbd
, 0, s
->special_base
);
651 /* PCI configuration space */
652 sysbus_mmio_map(sbd
, 1, s
->special_base
+ 0x1000000ULL
);
654 sysbus_mmio_map(sbd
, 2, s
->special_base
+ 0x2000000ULL
);
656 memory_region_init(&s
->pci_mmio
, OBJECT(s
), "pci-mmio", 0x100000000ULL
);
657 memory_region_add_subregion(get_system_memory(), s
->mem_base
,
660 phb
->bus
= pci_register_bus(dev
, "pci",
661 pci_apb_set_irq
, pci_apb_map_irq
, s
,
664 0, 32, TYPE_PCI_BUS
);
666 pci_create_simple(phb
->bus
, 0, "pbm-pci");
670 memset(is
, 0, sizeof(IOMMUState
));
672 memory_region_init_iommu(&is
->iommu
, sizeof(is
->iommu
),
673 TYPE_APB_IOMMU_MEMORY_REGION
, OBJECT(dev
),
674 "iommu-apb", UINT64_MAX
);
675 address_space_init(&is
->iommu_as
, MEMORY_REGION(&is
->iommu
), "pbm-as");
676 pci_setup_iommu(phb
->bus
, pbm_pci_dma_iommu
, is
);
678 /* APB secondary busses */
679 pci_dev
= pci_create_multifunction(phb
->bus
, PCI_DEVFN(1, 0), true,
680 TYPE_PBM_PCI_BRIDGE
);
681 s
->bridgeB
= PCI_BRIDGE(pci_dev
);
682 pci_bridge_map_irq(s
->bridgeB
, "pciB", pci_pbm_map_irq
);
683 qdev_init_nofail(&pci_dev
->qdev
);
685 pci_dev
= pci_create_multifunction(phb
->bus
, PCI_DEVFN(1, 1), true,
686 TYPE_PBM_PCI_BRIDGE
);
687 s
->bridgeA
= PCI_BRIDGE(pci_dev
);
688 pci_bridge_map_irq(s
->bridgeA
, "pciA", pci_pbm_map_irq
);
689 qdev_prop_set_bit(DEVICE(pci_dev
), "busA", true);
690 qdev_init_nofail(&pci_dev
->qdev
);
693 static void pci_pbm_init(Object
*obj
)
695 APBState
*s
= APB_DEVICE(obj
);
696 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
699 for (i
= 0; i
< 8; i
++) {
700 s
->pci_irq_map
[i
] = (0x1f << 6) | (i
<< 2);
702 for (i
= 0; i
< 2; i
++) {
703 s
->pci_err_irq_map
[i
] = (0x1f << 6) | 0x30;
705 for (i
= 0; i
< 32; i
++) {
706 s
->obio_irq_map
[i
] = ((0x1f << 6) | 0x20) + i
;
708 s
->pbm_irqs
= qemu_allocate_irqs(pci_apb_set_irq
, s
, MAX_IVEC
);
709 qdev_init_gpio_out_named(DEVICE(s
), s
->ivec_irqs
, "ivec-irq", MAX_IVEC
);
710 s
->irq_request
= NO_IRQ_REQUEST
;
711 s
->pci_irq_in
= 0ULL;
714 memory_region_init_io(&s
->apb_config
, OBJECT(s
), &apb_config_ops
, s
,
715 "apb-config", 0x10000);
717 sysbus_init_mmio(sbd
, &s
->apb_config
);
719 memory_region_init_io(&s
->pci_config
, OBJECT(s
), &pci_config_ops
, s
,
720 "apb-pci-config", 0x1000000);
722 sysbus_init_mmio(sbd
, &s
->pci_config
);
725 memory_region_init(&s
->pci_ioport
, OBJECT(s
), "apb-pci-ioport", 0x1000000);
728 sysbus_init_mmio(sbd
, &s
->pci_ioport
);
731 static void pbm_pci_host_realize(PCIDevice
*d
, Error
**errp
)
733 pci_set_word(d
->config
+ PCI_COMMAND
,
734 PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER
);
735 pci_set_word(d
->config
+ PCI_STATUS
,
736 PCI_STATUS_FAST_BACK
| PCI_STATUS_66MHZ
|
737 PCI_STATUS_DEVSEL_MEDIUM
);
740 static void pbm_pci_host_class_init(ObjectClass
*klass
, void *data
)
742 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
743 DeviceClass
*dc
= DEVICE_CLASS(klass
);
745 k
->realize
= pbm_pci_host_realize
;
746 k
->vendor_id
= PCI_VENDOR_ID_SUN
;
747 k
->device_id
= PCI_DEVICE_ID_SUN_SABRE
;
748 k
->class_id
= PCI_CLASS_BRIDGE_HOST
;
750 * PCI-facing part of the host bridge, not usable without the
751 * host-facing part, which can't be device_add'ed, yet.
753 dc
->user_creatable
= false;
756 static const TypeInfo pbm_pci_host_info
= {
758 .parent
= TYPE_PCI_DEVICE
,
759 .instance_size
= sizeof(PCIDevice
),
760 .class_init
= pbm_pci_host_class_init
,
761 .interfaces
= (InterfaceInfo
[]) {
762 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
767 static Property pbm_pci_host_properties
[] = {
768 DEFINE_PROP_UINT64("special-base", APBState
, special_base
, 0),
769 DEFINE_PROP_UINT64("mem-base", APBState
, mem_base
, 0),
770 DEFINE_PROP_END_OF_LIST(),
773 static void pbm_host_class_init(ObjectClass
*klass
, void *data
)
775 DeviceClass
*dc
= DEVICE_CLASS(klass
);
777 dc
->realize
= pci_pbm_realize
;
778 dc
->reset
= pci_pbm_reset
;
779 dc
->props
= pbm_pci_host_properties
;
780 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
783 static const TypeInfo pbm_host_info
= {
785 .parent
= TYPE_PCI_HOST_BRIDGE
,
786 .instance_size
= sizeof(APBState
),
787 .instance_init
= pci_pbm_init
,
788 .class_init
= pbm_host_class_init
,
791 static Property pbm_pci_properties
[] = {
792 DEFINE_PROP_BOOL("busA", PBMPCIBridge
, busA
, false),
793 DEFINE_PROP_END_OF_LIST(),
796 static void pbm_pci_bridge_class_init(ObjectClass
*klass
, void *data
)
798 DeviceClass
*dc
= DEVICE_CLASS(klass
);
799 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
801 k
->realize
= apb_pci_bridge_realize
;
802 k
->exit
= pci_bridge_exitfn
;
803 k
->vendor_id
= PCI_VENDOR_ID_SUN
;
804 k
->device_id
= PCI_DEVICE_ID_SUN_SIMBA
;
806 k
->config_write
= pci_bridge_write_config
;
808 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
809 dc
->reset
= pci_bridge_reset
;
810 dc
->vmsd
= &vmstate_pci_device
;
811 dc
->props
= pbm_pci_properties
;
814 static const TypeInfo pbm_pci_bridge_info
= {
815 .name
= TYPE_PBM_PCI_BRIDGE
,
816 .parent
= TYPE_PCI_BRIDGE
,
817 .class_init
= pbm_pci_bridge_class_init
,
818 .instance_size
= sizeof(PBMPCIBridge
),
819 .interfaces
= (InterfaceInfo
[]) {
820 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
825 static void pbm_iommu_memory_region_class_init(ObjectClass
*klass
, void *data
)
827 IOMMUMemoryRegionClass
*imrc
= IOMMU_MEMORY_REGION_CLASS(klass
);
829 imrc
->translate
= pbm_translate_iommu
;
832 static const TypeInfo pbm_iommu_memory_region_info
= {
833 .parent
= TYPE_IOMMU_MEMORY_REGION
,
834 .name
= TYPE_APB_IOMMU_MEMORY_REGION
,
835 .class_init
= pbm_iommu_memory_region_class_init
,
838 static void pbm_register_types(void)
840 type_register_static(&pbm_host_info
);
841 type_register_static(&pbm_pci_host_info
);
842 type_register_static(&pbm_pci_bridge_info
);
843 type_register_static(&pbm_iommu_memory_region_info
);
846 type_init(pbm_register_types
)