2 * DEC 21272 (TSUNAMI/TYPHOON) chipset emulation.
4 * Written by Richard Henderson.
6 * This work is licensed under the GNU GPL license version 2 or later.
9 #include "qemu/osdep.h"
10 #include "qemu/units.h"
11 #include "qapi/error.h"
14 #include "sysemu/sysemu.h"
15 #include "alpha_sys.h"
16 #include "exec/address-spaces.h"
19 #define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
20 #define TYPE_TYPHOON_IOMMU_MEMORY_REGION "typhoon-iommu-memory-region"
22 typedef struct TyphoonCchip
{
31 typedef struct TyphoonWindow
{
37 typedef struct TyphoonPchip
{
39 MemoryRegion reg_iack
;
42 MemoryRegion reg_conf
;
44 AddressSpace iommu_as
;
45 IOMMUMemoryRegion iommu
;
51 #define TYPHOON_PCI_HOST_BRIDGE(obj) \
52 OBJECT_CHECK(TyphoonState, (obj), TYPE_TYPHOON_PCI_HOST_BRIDGE)
54 typedef struct TyphoonState
{
55 PCIHostState parent_obj
;
59 MemoryRegion dchip_region
;
60 MemoryRegion ram_region
;
63 /* Called when one of DRIR or DIM changes. */
64 static void cpu_irq_change(AlphaCPU
*cpu
, uint64_t req
)
66 /* If there are any non-masked interrupts, tell the cpu. */
68 CPUState
*cs
= CPU(cpu
);
70 cpu_interrupt(cs
, CPU_INTERRUPT_HARD
);
72 cpu_reset_interrupt(cs
, CPU_INTERRUPT_HARD
);
77 static MemTxResult
cchip_read(void *opaque
, hwaddr addr
,
78 uint64_t *data
, unsigned size
,
81 CPUState
*cpu
= current_cpu
;
82 TyphoonState
*s
= opaque
;
87 /* CSC: Cchip System Configuration Register. */
88 /* All sorts of data here; probably the only thing relevant is
89 PIP<14> Pchip 1 Present = 0. */
93 /* MTR: Memory Timing Register. */
94 /* All sorts of stuff related to real DRAM. */
98 /* MISC: Miscellaneous Register. */
99 ret
= s
->cchip
.misc
| (cpu
->cpu_index
& 3);
103 /* MPD: Memory Presence Detect Register. */
106 case 0x0100: /* AAR0 */
107 case 0x0140: /* AAR1 */
108 case 0x0180: /* AAR2 */
109 case 0x01c0: /* AAR3 */
110 /* AAR: Array Address Register. */
111 /* All sorts of information about DRAM. */
115 /* DIM0: Device Interrupt Mask Register, CPU0. */
116 ret
= s
->cchip
.dim
[0];
119 /* DIM1: Device Interrupt Mask Register, CPU1. */
120 ret
= s
->cchip
.dim
[1];
123 /* DIR0: Device Interrupt Request Register, CPU0. */
124 ret
= s
->cchip
.dim
[0] & s
->cchip
.drir
;
127 /* DIR1: Device Interrupt Request Register, CPU1. */
128 ret
= s
->cchip
.dim
[1] & s
->cchip
.drir
;
131 /* DRIR: Device Raw Interrupt Request Register. */
136 /* PRBEN: Probe Enable Register. */
140 /* IIC0: Interval Ignore Count Register, CPU0. */
141 ret
= s
->cchip
.iic
[0];
144 /* IIC1: Interval Ignore Count Register, CPU1. */
145 ret
= s
->cchip
.iic
[1];
148 case 0x0400: /* MPR0 */
149 case 0x0440: /* MPR1 */
150 case 0x0480: /* MPR2 */
151 case 0x04c0: /* MPR3 */
152 /* MPR: Memory Programming Register. */
156 /* TTR: TIGbus Timing Register. */
157 /* All sorts of stuff related to interrupt delivery timings. */
160 /* TDR: TIGbug Device Timing Register. */
164 /* DIM2: Device Interrupt Mask Register, CPU2. */
165 ret
= s
->cchip
.dim
[2];
168 /* DIM3: Device Interrupt Mask Register, CPU3. */
169 ret
= s
->cchip
.dim
[3];
172 /* DIR2: Device Interrupt Request Register, CPU2. */
173 ret
= s
->cchip
.dim
[2] & s
->cchip
.drir
;
176 /* DIR3: Device Interrupt Request Register, CPU3. */
177 ret
= s
->cchip
.dim
[3] & s
->cchip
.drir
;
181 /* IIC2: Interval Ignore Count Register, CPU2. */
182 ret
= s
->cchip
.iic
[2];
185 /* IIC3: Interval Ignore Count Register, CPU3. */
186 ret
= s
->cchip
.iic
[3];
190 /* PWR: Power Management Control. */
193 case 0x0c00: /* CMONCTLA */
194 case 0x0c40: /* CMONCTLB */
195 case 0x0c80: /* CMONCNT01 */
196 case 0x0cc0: /* CMONCNT23 */
207 static uint64_t dchip_read(void *opaque
, hwaddr addr
, unsigned size
)
209 /* Skip this. It's all related to DRAM timing and setup. */
213 static MemTxResult
pchip_read(void *opaque
, hwaddr addr
, uint64_t *data
,
214 unsigned size
, MemTxAttrs attrs
)
216 TyphoonState
*s
= opaque
;
221 /* WSBA0: Window Space Base Address Register. */
222 ret
= s
->pchip
.win
[0].wba
;
226 ret
= s
->pchip
.win
[1].wba
;
230 ret
= s
->pchip
.win
[2].wba
;
234 ret
= s
->pchip
.win
[3].wba
;
238 /* WSM0: Window Space Mask Register. */
239 ret
= s
->pchip
.win
[0].wsm
;
243 ret
= s
->pchip
.win
[1].wsm
;
247 ret
= s
->pchip
.win
[2].wsm
;
251 ret
= s
->pchip
.win
[3].wsm
;
255 /* TBA0: Translated Base Address Register. */
256 ret
= s
->pchip
.win
[0].tba
;
260 ret
= s
->pchip
.win
[1].tba
;
264 ret
= s
->pchip
.win
[2].tba
;
268 ret
= s
->pchip
.win
[3].tba
;
272 /* PCTL: Pchip Control Register. */
276 /* PLAT: Pchip Master Latency Register. */
279 /* PERROR: Pchip Error Register. */
282 /* PERRMASK: Pchip Error Mask Register. */
285 /* PERRSET: Pchip Error Set Register. */
288 /* TLBIV: Translation Buffer Invalidate Virtual Register (WO). */
291 /* TLBIA: Translation Buffer Invalidate All Register (WO). */
293 case 0x0500: /* PMONCTL */
294 case 0x0540: /* PMONCNT */
295 case 0x0800: /* SPRST */
306 static MemTxResult
cchip_write(void *opaque
, hwaddr addr
,
307 uint64_t val
, unsigned size
,
310 TyphoonState
*s
= opaque
;
311 uint64_t oldval
, newval
;
315 /* CSC: Cchip System Configuration Register. */
316 /* All sorts of data here; nothing relevant RW. */
320 /* MTR: Memory Timing Register. */
321 /* All sorts of stuff related to real DRAM. */
325 /* MISC: Miscellaneous Register. */
326 newval
= oldval
= s
->cchip
.misc
;
327 newval
&= ~(val
& 0x10000ff0); /* W1C fields */
328 if (val
& 0x100000) {
329 newval
&= ~0xff0000ull
; /* ACL clears ABT and ABW */
331 newval
|= val
& 0x00f00000; /* ABT field is W1S */
332 if ((newval
& 0xf0000) == 0) {
333 newval
|= val
& 0xf0000; /* ABW field is W1S iff zero */
336 newval
|= (val
& 0xf000) >> 4; /* IPREQ field sets IPINTR. */
338 newval
&= ~0xf0000000000ull
; /* WO and RW fields */
339 newval
|= val
& 0xf0000000000ull
;
340 s
->cchip
.misc
= newval
;
342 /* Pass on changes to IPI and ITI state. */
343 if ((newval
^ oldval
) & 0xff0) {
345 for (i
= 0; i
< 4; ++i
) {
346 AlphaCPU
*cpu
= s
->cchip
.cpu
[i
];
348 CPUState
*cs
= CPU(cpu
);
349 /* IPI can be either cleared or set by the write. */
350 if (newval
& (1 << (i
+ 8))) {
351 cpu_interrupt(cs
, CPU_INTERRUPT_SMP
);
353 cpu_reset_interrupt(cs
, CPU_INTERRUPT_SMP
);
356 /* ITI can only be cleared by the write. */
357 if ((newval
& (1 << (i
+ 4))) == 0) {
358 cpu_reset_interrupt(cs
, CPU_INTERRUPT_TIMER
);
366 /* MPD: Memory Presence Detect Register. */
369 case 0x0100: /* AAR0 */
370 case 0x0140: /* AAR1 */
371 case 0x0180: /* AAR2 */
372 case 0x01c0: /* AAR3 */
373 /* AAR: Array Address Register. */
374 /* All sorts of information about DRAM. */
377 case 0x0200: /* DIM0 */
378 /* DIM: Device Interrupt Mask Register, CPU0. */
379 s
->cchip
.dim
[0] = val
;
380 cpu_irq_change(s
->cchip
.cpu
[0], val
& s
->cchip
.drir
);
382 case 0x0240: /* DIM1 */
383 /* DIM: Device Interrupt Mask Register, CPU1. */
384 s
->cchip
.dim
[1] = val
;
385 cpu_irq_change(s
->cchip
.cpu
[1], val
& s
->cchip
.drir
);
388 case 0x0280: /* DIR0 (RO) */
389 case 0x02c0: /* DIR1 (RO) */
390 case 0x0300: /* DRIR (RO) */
394 /* PRBEN: Probe Enable Register. */
397 case 0x0380: /* IIC0 */
398 s
->cchip
.iic
[0] = val
& 0xffffff;
400 case 0x03c0: /* IIC1 */
401 s
->cchip
.iic
[1] = val
& 0xffffff;
404 case 0x0400: /* MPR0 */
405 case 0x0440: /* MPR1 */
406 case 0x0480: /* MPR2 */
407 case 0x04c0: /* MPR3 */
408 /* MPR: Memory Programming Register. */
412 /* TTR: TIGbus Timing Register. */
413 /* All sorts of stuff related to interrupt delivery timings. */
416 /* TDR: TIGbug Device Timing Register. */
420 /* DIM2: Device Interrupt Mask Register, CPU2. */
421 s
->cchip
.dim
[2] = val
;
422 cpu_irq_change(s
->cchip
.cpu
[2], val
& s
->cchip
.drir
);
425 /* DIM3: Device Interrupt Mask Register, CPU3. */
426 s
->cchip
.dim
[3] = val
;
427 cpu_irq_change(s
->cchip
.cpu
[3], val
& s
->cchip
.drir
);
430 case 0x0680: /* DIR2 (RO) */
431 case 0x06c0: /* DIR3 (RO) */
434 case 0x0700: /* IIC2 */
435 s
->cchip
.iic
[2] = val
& 0xffffff;
437 case 0x0740: /* IIC3 */
438 s
->cchip
.iic
[3] = val
& 0xffffff;
442 /* PWR: Power Management Control. */
445 case 0x0c00: /* CMONCTLA */
446 case 0x0c40: /* CMONCTLB */
447 case 0x0c80: /* CMONCNT01 */
448 case 0x0cc0: /* CMONCNT23 */
458 static void dchip_write(void *opaque
, hwaddr addr
,
459 uint64_t val
, unsigned size
)
461 /* Skip this. It's all related to DRAM timing and setup. */
464 static MemTxResult
pchip_write(void *opaque
, hwaddr addr
,
465 uint64_t val
, unsigned size
,
468 TyphoonState
*s
= opaque
;
473 /* WSBA0: Window Space Base Address Register. */
474 s
->pchip
.win
[0].wba
= val
& 0xfff00003u
;
478 s
->pchip
.win
[1].wba
= val
& 0xfff00003u
;
482 s
->pchip
.win
[2].wba
= val
& 0xfff00003u
;
486 s
->pchip
.win
[3].wba
= (val
& 0x80fff00001ull
) | 2;
490 /* WSM0: Window Space Mask Register. */
491 s
->pchip
.win
[0].wsm
= val
& 0xfff00000u
;
495 s
->pchip
.win
[1].wsm
= val
& 0xfff00000u
;
499 s
->pchip
.win
[2].wsm
= val
& 0xfff00000u
;
503 s
->pchip
.win
[3].wsm
= val
& 0xfff00000u
;
507 /* TBA0: Translated Base Address Register. */
508 s
->pchip
.win
[0].tba
= val
& 0x7fffffc00ull
;
512 s
->pchip
.win
[1].tba
= val
& 0x7fffffc00ull
;
516 s
->pchip
.win
[2].tba
= val
& 0x7fffffc00ull
;
520 s
->pchip
.win
[3].tba
= val
& 0x7fffffc00ull
;
524 /* PCTL: Pchip Control Register. */
525 oldval
= s
->pchip
.ctl
;
526 oldval
&= ~0x00001cff0fc7ffull
; /* RW fields */
527 oldval
|= val
& 0x00001cff0fc7ffull
;
528 s
->pchip
.ctl
= oldval
;
532 /* PLAT: Pchip Master Latency Register. */
535 /* PERROR: Pchip Error Register. */
538 /* PERRMASK: Pchip Error Mask Register. */
541 /* PERRSET: Pchip Error Set Register. */
545 /* TLBIV: Translation Buffer Invalidate Virtual Register. */
549 /* TLBIA: Translation Buffer Invalidate All Register (WO). */
567 static const MemoryRegionOps cchip_ops
= {
568 .read_with_attrs
= cchip_read
,
569 .write_with_attrs
= cchip_write
,
570 .endianness
= DEVICE_LITTLE_ENDIAN
,
572 .min_access_size
= 8,
573 .max_access_size
= 8,
576 .min_access_size
= 8,
577 .max_access_size
= 8,
581 static const MemoryRegionOps dchip_ops
= {
583 .write
= dchip_write
,
584 .endianness
= DEVICE_LITTLE_ENDIAN
,
586 .min_access_size
= 8,
587 .max_access_size
= 8,
590 .min_access_size
= 8,
591 .max_access_size
= 8,
595 static const MemoryRegionOps pchip_ops
= {
596 .read_with_attrs
= pchip_read
,
597 .write_with_attrs
= pchip_write
,
598 .endianness
= DEVICE_LITTLE_ENDIAN
,
600 .min_access_size
= 8,
601 .max_access_size
= 8,
604 .min_access_size
= 8,
605 .max_access_size
= 8,
609 /* A subroutine of typhoon_translate_iommu that builds an IOMMUTLBEntry
610 using the given translated address and mask. */
611 static bool make_iommu_tlbe(hwaddr taddr
, hwaddr mask
, IOMMUTLBEntry
*ret
)
613 *ret
= (IOMMUTLBEntry
) {
614 .target_as
= &address_space_memory
,
615 .translated_addr
= taddr
,
622 /* A subroutine of typhoon_translate_iommu that handles scatter-gather
623 translation, given the address of the PTE. */
624 static bool pte_translate(hwaddr pte_addr
, IOMMUTLBEntry
*ret
)
626 uint64_t pte
= address_space_ldq(&address_space_memory
, pte_addr
,
627 MEMTXATTRS_UNSPECIFIED
, NULL
);
629 /* Check valid bit. */
630 if ((pte
& 1) == 0) {
634 return make_iommu_tlbe((pte
& 0x3ffffe) << 12, 0x1fff, ret
);
637 /* A subroutine of typhoon_translate_iommu that handles one of the
638 four single-address-cycle translation windows. */
639 static bool window_translate(TyphoonWindow
*win
, hwaddr addr
,
642 uint32_t wba
= win
->wba
;
643 uint64_t wsm
= win
->wsm
;
644 uint64_t tba
= win
->tba
;
645 uint64_t wsm_ext
= wsm
| 0xfffff;
647 /* Check for window disabled. */
648 if ((wba
& 1) == 0) {
652 /* Check for window hit. */
653 if ((addr
& ~wsm_ext
) != (wba
& 0xfff00000u
)) {
658 /* Scatter-gather translation. */
661 /* See table 10-6, Generating PTE address for PCI DMA Address. */
662 pte_addr
= tba
& ~(wsm
>> 10);
663 pte_addr
|= (addr
& (wsm
| 0xfe000)) >> 10;
664 return pte_translate(pte_addr
, ret
);
666 /* Direct-mapped translation. */
667 return make_iommu_tlbe(tba
& ~wsm_ext
, wsm_ext
, ret
);
671 /* Handle PCI-to-system address translation. */
672 /* TODO: A translation failure here ought to set PCI error codes on the
673 Pchip and generate a machine check interrupt. */
674 static IOMMUTLBEntry
typhoon_translate_iommu(IOMMUMemoryRegion
*iommu
,
676 IOMMUAccessFlags flag
,
679 TyphoonPchip
*pchip
= container_of(iommu
, TyphoonPchip
, iommu
);
683 if (addr
<= 0xffffffffu
) {
684 /* Single-address cycle. */
686 /* Check for the Window Hole, inhibiting matching. */
687 if ((pchip
->ctl
& 0x20)
689 && addr
<= 0xfffff) {
693 /* Check the first three windows. */
694 for (i
= 0; i
< 3; ++i
) {
695 if (window_translate(&pchip
->win
[i
], addr
, &ret
)) {
700 /* Check the fourth window for DAC disable. */
701 if ((pchip
->win
[3].wba
& 0x80000000000ull
) == 0
702 && window_translate(&pchip
->win
[3], addr
, &ret
)) {
706 /* Double-address cycle. */
708 if (addr
>= 0x10000000000ull
&& addr
< 0x20000000000ull
) {
709 /* Check for the DMA monster window. */
710 if (pchip
->ctl
& 0x40) {
711 /* See 10.1.4.4; in particular <39:35> is ignored. */
712 make_iommu_tlbe(0, 0x007ffffffffull
, &ret
);
717 if (addr
>= 0x80000000000ull
&& addr
<= 0xfffffffffffull
) {
718 /* Check the fourth window for DAC enable and window enable. */
719 if ((pchip
->win
[3].wba
& 0x80000000001ull
) == 0x80000000001ull
) {
722 pte_addr
= pchip
->win
[3].tba
& 0x7ffc00000ull
;
723 pte_addr
|= (addr
& 0xffffe000u
) >> 10;
724 if (pte_translate(pte_addr
, &ret
)) {
732 ret
= (IOMMUTLBEntry
) { .perm
= IOMMU_NONE
};
737 static AddressSpace
*typhoon_pci_dma_iommu(PCIBus
*bus
, void *opaque
, int devfn
)
739 TyphoonState
*s
= opaque
;
740 return &s
->pchip
.iommu_as
;
743 static void typhoon_set_irq(void *opaque
, int irq
, int level
)
745 TyphoonState
*s
= opaque
;
749 /* Set/Reset the bit in CCHIP.DRIR based on IRQ+LEVEL. */
750 drir
= s
->cchip
.drir
;
754 drir
&= ~(1ull << irq
);
756 s
->cchip
.drir
= drir
;
758 for (i
= 0; i
< 4; ++i
) {
759 cpu_irq_change(s
->cchip
.cpu
[i
], s
->cchip
.dim
[i
] & drir
);
763 static void typhoon_set_isa_irq(void *opaque
, int irq
, int level
)
765 typhoon_set_irq(opaque
, 55, level
);
768 static void typhoon_set_timer_irq(void *opaque
, int irq
, int level
)
770 TyphoonState
*s
= opaque
;
773 /* Thankfully, the mc146818rtc code doesn't track the IRQ state,
774 and so we don't have to worry about missing interrupts just
775 because we never actually ACK the interrupt. Just ignore any
776 case of the interrupt level going low. */
781 /* Deliver the interrupt to each CPU, considering each CPU's IIC. */
782 for (i
= 0; i
< 4; ++i
) {
783 AlphaCPU
*cpu
= s
->cchip
.cpu
[i
];
785 uint32_t iic
= s
->cchip
.iic
[i
];
787 /* ??? The verbage in Section 10.2.2.10 isn't 100% clear.
788 Bit 24 is the OverFlow bit, RO, and set when the count
789 decrements past 0. When is OF cleared? My guess is that
790 OF is actually cleared when the IIC is written, and that
791 the ICNT field always decrements. At least, that's an
792 interpretation that makes sense, and "allows the CPU to
793 determine exactly how mant interval timer ticks were
794 skipped". At least within the next 4M ticks... */
796 iic
= ((iic
- 1) & 0x1ffffff) | (iic
& 0x1000000);
797 s
->cchip
.iic
[i
] = iic
;
799 if (iic
& 0x1000000) {
800 /* Set the ITI bit for this cpu. */
801 s
->cchip
.misc
|= 1 << (i
+ 4);
802 /* And signal the interrupt. */
803 cpu_interrupt(CPU(cpu
), CPU_INTERRUPT_TIMER
);
809 static void typhoon_alarm_timer(void *opaque
)
811 TyphoonState
*s
= (TyphoonState
*)((uintptr_t)opaque
& ~3);
812 int cpu
= (uintptr_t)opaque
& 3;
814 /* Set the ITI bit for this cpu. */
815 s
->cchip
.misc
|= 1 << (cpu
+ 4);
816 cpu_interrupt(CPU(s
->cchip
.cpu
[cpu
]), CPU_INTERRUPT_TIMER
);
819 PCIBus
*typhoon_init(ram_addr_t ram_size
, ISABus
**isa_bus
,
821 AlphaCPU
*cpus
[4], pci_map_irq_fn sys_map_irq
)
823 MemoryRegion
*addr_space
= get_system_memory();
830 dev
= qdev_create(NULL
, TYPE_TYPHOON_PCI_HOST_BRIDGE
);
832 s
= TYPHOON_PCI_HOST_BRIDGE(dev
);
833 phb
= PCI_HOST_BRIDGE(dev
);
835 s
->cchip
.misc
= 0x800000000ull
; /* Revision: Typhoon. */
836 s
->pchip
.win
[3].wba
= 2; /* Window 3 SG always enabled. */
838 /* Remember the CPUs so that we can deliver interrupts to them. */
839 for (i
= 0; i
< 4; i
++) {
840 AlphaCPU
*cpu
= cpus
[i
];
841 s
->cchip
.cpu
[i
] = cpu
;
843 cpu
->alarm_timer
= timer_new_ns(QEMU_CLOCK_VIRTUAL
,
845 (void *)((uintptr_t)s
+ i
));
849 *p_rtc_irq
= qemu_allocate_irq(typhoon_set_timer_irq
, s
, 0);
851 /* Main memory region, 0x00.0000.0000. Real hardware supports 32GB,
852 but the address space hole reserved at this point is 8TB. */
853 memory_region_allocate_system_memory(&s
->ram_region
, OBJECT(s
), "ram",
855 memory_region_add_subregion(addr_space
, 0, &s
->ram_region
);
857 /* TIGbus, 0x801.0000.0000, 1GB. */
858 /* ??? The TIGbus is used for delivering interrupts, and access to
859 the flash ROM. I'm not sure that we need to implement it at all. */
861 /* Pchip0 CSRs, 0x801.8000.0000, 256MB. */
862 memory_region_init_io(&s
->pchip
.region
, OBJECT(s
), &pchip_ops
, s
, "pchip0",
864 memory_region_add_subregion(addr_space
, 0x80180000000ULL
,
867 /* Cchip CSRs, 0x801.A000.0000, 256MB. */
868 memory_region_init_io(&s
->cchip
.region
, OBJECT(s
), &cchip_ops
, s
, "cchip0",
870 memory_region_add_subregion(addr_space
, 0x801a0000000ULL
,
873 /* Dchip CSRs, 0x801.B000.0000, 256MB. */
874 memory_region_init_io(&s
->dchip_region
, OBJECT(s
), &dchip_ops
, s
, "dchip0",
876 memory_region_add_subregion(addr_space
, 0x801b0000000ULL
,
879 /* Pchip0 PCI memory, 0x800.0000.0000, 4GB. */
880 memory_region_init(&s
->pchip
.reg_mem
, OBJECT(s
), "pci0-mem", 4 * GiB
);
881 memory_region_add_subregion(addr_space
, 0x80000000000ULL
,
884 /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB. */
885 memory_region_init_io(&s
->pchip
.reg_io
, OBJECT(s
), &alpha_pci_ignore_ops
,
886 NULL
, "pci0-io", 32 * MiB
);
887 memory_region_add_subregion(addr_space
, 0x801fc000000ULL
,
890 b
= pci_register_root_bus(dev
, "pci",
891 typhoon_set_irq
, sys_map_irq
, s
,
892 &s
->pchip
.reg_mem
, &s
->pchip
.reg_io
,
893 0, 64, TYPE_PCI_BUS
);
895 qdev_init_nofail(dev
);
897 /* Host memory as seen from the PCI side, via the IOMMU. */
898 memory_region_init_iommu(&s
->pchip
.iommu
, sizeof(s
->pchip
.iommu
),
899 TYPE_TYPHOON_IOMMU_MEMORY_REGION
, OBJECT(s
),
900 "iommu-typhoon", UINT64_MAX
);
901 address_space_init(&s
->pchip
.iommu_as
, MEMORY_REGION(&s
->pchip
.iommu
),
903 pci_setup_iommu(b
, typhoon_pci_dma_iommu
, s
);
905 /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
906 memory_region_init_io(&s
->pchip
.reg_iack
, OBJECT(s
), &alpha_pci_iack_ops
,
907 b
, "pci0-iack", 64 * MiB
);
908 memory_region_add_subregion(addr_space
, 0x801f8000000ULL
,
911 /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB. */
912 memory_region_init_io(&s
->pchip
.reg_conf
, OBJECT(s
), &alpha_pci_conf1_ops
,
913 b
, "pci0-conf", 16 * MiB
);
914 memory_region_add_subregion(addr_space
, 0x801fe000000ULL
,
917 /* For the record, these are the mappings for the second PCI bus.
918 We can get away with not implementing them because we indicate
919 via the Cchip.CSC<PIP> bit that Pchip1 is not present. */
920 /* Pchip1 PCI memory, 0x802.0000.0000, 4GB. */
921 /* Pchip1 CSRs, 0x802.8000.0000, 256MB. */
922 /* Pchip1 PCI special/interrupt acknowledge, 0x802.F800.0000, 64MB. */
923 /* Pchip1 PCI I/O, 0x802.FC00.0000, 32MB. */
924 /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB. */
926 /* Init the ISA bus. */
927 /* ??? Technically there should be a cy82c693ub pci-isa bridge. */
931 *isa_bus
= isa_bus_new(NULL
, get_system_memory(), &s
->pchip
.reg_io
,
933 isa_irqs
= i8259_init(*isa_bus
,
934 qemu_allocate_irq(typhoon_set_isa_irq
, s
, 0));
935 isa_bus_irqs(*isa_bus
, isa_irqs
);
941 static const TypeInfo typhoon_pcihost_info
= {
942 .name
= TYPE_TYPHOON_PCI_HOST_BRIDGE
,
943 .parent
= TYPE_PCI_HOST_BRIDGE
,
944 .instance_size
= sizeof(TyphoonState
),
947 static void typhoon_iommu_memory_region_class_init(ObjectClass
*klass
,
950 IOMMUMemoryRegionClass
*imrc
= IOMMU_MEMORY_REGION_CLASS(klass
);
952 imrc
->translate
= typhoon_translate_iommu
;
955 static const TypeInfo typhoon_iommu_memory_region_info
= {
956 .parent
= TYPE_IOMMU_MEMORY_REGION
,
957 .name
= TYPE_TYPHOON_IOMMU_MEMORY_REGION
,
958 .class_init
= typhoon_iommu_memory_region_class_init
,
961 static void typhoon_register_types(void)
963 type_register_static(&typhoon_pcihost_info
);
964 type_register_static(&typhoon_iommu_memory_region_info
);
967 type_init(typhoon_register_types
)