hw/elf_ops: Fix a typo
[qemu/ar7.git] / hw / alpha / typhoon.c
bloba42b31981216964c2634bcb93cd42e4cc18b8b72
1 /*
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.
7 */
9 #include "qemu/osdep.h"
10 #include "qemu/module.h"
11 #include "qemu/units.h"
12 #include "qapi/error.h"
13 #include "cpu.h"
14 #include "hw/boards.h"
15 #include "hw/irq.h"
16 #include "alpha_sys.h"
17 #include "exec/address-spaces.h"
18 #include "qom/object.h"
21 #define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
22 #define TYPE_TYPHOON_IOMMU_MEMORY_REGION "typhoon-iommu-memory-region"
24 typedef struct TyphoonCchip {
25 MemoryRegion region;
26 uint64_t misc;
27 uint64_t drir;
28 uint64_t dim[4];
29 uint32_t iic[4];
30 AlphaCPU *cpu[4];
31 } TyphoonCchip;
33 typedef struct TyphoonWindow {
34 uint64_t wba;
35 uint64_t wsm;
36 uint64_t tba;
37 } TyphoonWindow;
39 typedef struct TyphoonPchip {
40 MemoryRegion region;
41 MemoryRegion reg_iack;
42 MemoryRegion reg_mem;
43 MemoryRegion reg_io;
44 MemoryRegion reg_conf;
46 AddressSpace iommu_as;
47 IOMMUMemoryRegion iommu;
49 uint64_t ctl;
50 TyphoonWindow win[4];
51 } TyphoonPchip;
53 OBJECT_DECLARE_SIMPLE_TYPE(TyphoonState, TYPHOON_PCI_HOST_BRIDGE)
55 struct TyphoonState {
56 PCIHostState parent_obj;
58 TyphoonCchip cchip;
59 TyphoonPchip pchip;
60 MemoryRegion dchip_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. */
67 if (cpu != NULL) {
68 CPUState *cs = CPU(cpu);
69 if (req) {
70 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
71 } else {
72 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
77 static MemTxResult cchip_read(void *opaque, hwaddr addr,
78 uint64_t *data, unsigned size,
79 MemTxAttrs attrs)
81 CPUState *cpu = current_cpu;
82 TyphoonState *s = opaque;
83 uint64_t ret = 0;
85 switch (addr) {
86 case 0x0000:
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. */
90 break;
92 case 0x0040:
93 /* MTR: Memory Timing Register. */
94 /* All sorts of stuff related to real DRAM. */
95 break;
97 case 0x0080:
98 /* MISC: Miscellaneous Register. */
99 ret = s->cchip.misc | (cpu->cpu_index & 3);
100 break;
102 case 0x00c0:
103 /* MPD: Memory Presence Detect Register. */
104 break;
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. */
112 break;
114 case 0x0200:
115 /* DIM0: Device Interrupt Mask Register, CPU0. */
116 ret = s->cchip.dim[0];
117 break;
118 case 0x0240:
119 /* DIM1: Device Interrupt Mask Register, CPU1. */
120 ret = s->cchip.dim[1];
121 break;
122 case 0x0280:
123 /* DIR0: Device Interrupt Request Register, CPU0. */
124 ret = s->cchip.dim[0] & s->cchip.drir;
125 break;
126 case 0x02c0:
127 /* DIR1: Device Interrupt Request Register, CPU1. */
128 ret = s->cchip.dim[1] & s->cchip.drir;
129 break;
130 case 0x0300:
131 /* DRIR: Device Raw Interrupt Request Register. */
132 ret = s->cchip.drir;
133 break;
135 case 0x0340:
136 /* PRBEN: Probe Enable Register. */
137 break;
139 case 0x0380:
140 /* IIC0: Interval Ignore Count Register, CPU0. */
141 ret = s->cchip.iic[0];
142 break;
143 case 0x03c0:
144 /* IIC1: Interval Ignore Count Register, CPU1. */
145 ret = s->cchip.iic[1];
146 break;
148 case 0x0400: /* MPR0 */
149 case 0x0440: /* MPR1 */
150 case 0x0480: /* MPR2 */
151 case 0x04c0: /* MPR3 */
152 /* MPR: Memory Programming Register. */
153 break;
155 case 0x0580:
156 /* TTR: TIGbus Timing Register. */
157 /* All sorts of stuff related to interrupt delivery timings. */
158 break;
159 case 0x05c0:
160 /* TDR: TIGbug Device Timing Register. */
161 break;
163 case 0x0600:
164 /* DIM2: Device Interrupt Mask Register, CPU2. */
165 ret = s->cchip.dim[2];
166 break;
167 case 0x0640:
168 /* DIM3: Device Interrupt Mask Register, CPU3. */
169 ret = s->cchip.dim[3];
170 break;
171 case 0x0680:
172 /* DIR2: Device Interrupt Request Register, CPU2. */
173 ret = s->cchip.dim[2] & s->cchip.drir;
174 break;
175 case 0x06c0:
176 /* DIR3: Device Interrupt Request Register, CPU3. */
177 ret = s->cchip.dim[3] & s->cchip.drir;
178 break;
180 case 0x0700:
181 /* IIC2: Interval Ignore Count Register, CPU2. */
182 ret = s->cchip.iic[2];
183 break;
184 case 0x0740:
185 /* IIC3: Interval Ignore Count Register, CPU3. */
186 ret = s->cchip.iic[3];
187 break;
189 case 0x0780:
190 /* PWR: Power Management Control. */
191 break;
193 case 0x0c00: /* CMONCTLA */
194 case 0x0c40: /* CMONCTLB */
195 case 0x0c80: /* CMONCNT01 */
196 case 0x0cc0: /* CMONCNT23 */
197 break;
199 default:
200 return MEMTX_ERROR;
203 *data = ret;
204 return MEMTX_OK;
207 static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
209 /* Skip this. It's all related to DRAM timing and setup. */
210 return 0;
213 static MemTxResult pchip_read(void *opaque, hwaddr addr, uint64_t *data,
214 unsigned size, MemTxAttrs attrs)
216 TyphoonState *s = opaque;
217 uint64_t ret = 0;
219 switch (addr) {
220 case 0x0000:
221 /* WSBA0: Window Space Base Address Register. */
222 ret = s->pchip.win[0].wba;
223 break;
224 case 0x0040:
225 /* WSBA1 */
226 ret = s->pchip.win[1].wba;
227 break;
228 case 0x0080:
229 /* WSBA2 */
230 ret = s->pchip.win[2].wba;
231 break;
232 case 0x00c0:
233 /* WSBA3 */
234 ret = s->pchip.win[3].wba;
235 break;
237 case 0x0100:
238 /* WSM0: Window Space Mask Register. */
239 ret = s->pchip.win[0].wsm;
240 break;
241 case 0x0140:
242 /* WSM1 */
243 ret = s->pchip.win[1].wsm;
244 break;
245 case 0x0180:
246 /* WSM2 */
247 ret = s->pchip.win[2].wsm;
248 break;
249 case 0x01c0:
250 /* WSM3 */
251 ret = s->pchip.win[3].wsm;
252 break;
254 case 0x0200:
255 /* TBA0: Translated Base Address Register. */
256 ret = s->pchip.win[0].tba;
257 break;
258 case 0x0240:
259 /* TBA1 */
260 ret = s->pchip.win[1].tba;
261 break;
262 case 0x0280:
263 /* TBA2 */
264 ret = s->pchip.win[2].tba;
265 break;
266 case 0x02c0:
267 /* TBA3 */
268 ret = s->pchip.win[3].tba;
269 break;
271 case 0x0300:
272 /* PCTL: Pchip Control Register. */
273 ret = s->pchip.ctl;
274 break;
275 case 0x0340:
276 /* PLAT: Pchip Master Latency Register. */
277 break;
278 case 0x03c0:
279 /* PERROR: Pchip Error Register. */
280 break;
281 case 0x0400:
282 /* PERRMASK: Pchip Error Mask Register. */
283 break;
284 case 0x0440:
285 /* PERRSET: Pchip Error Set Register. */
286 break;
287 case 0x0480:
288 /* TLBIV: Translation Buffer Invalidate Virtual Register (WO). */
289 break;
290 case 0x04c0:
291 /* TLBIA: Translation Buffer Invalidate All Register (WO). */
292 break;
293 case 0x0500: /* PMONCTL */
294 case 0x0540: /* PMONCNT */
295 case 0x0800: /* SPRST */
296 break;
298 default:
299 return MEMTX_ERROR;
302 *data = ret;
303 return MEMTX_OK;
306 static MemTxResult cchip_write(void *opaque, hwaddr addr,
307 uint64_t val, unsigned size,
308 MemTxAttrs attrs)
310 TyphoonState *s = opaque;
311 uint64_t oldval, newval;
313 switch (addr) {
314 case 0x0000:
315 /* CSC: Cchip System Configuration Register. */
316 /* All sorts of data here; nothing relevant RW. */
317 break;
319 case 0x0040:
320 /* MTR: Memory Timing Register. */
321 /* All sorts of stuff related to real DRAM. */
322 break;
324 case 0x0080:
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 */
330 } else {
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) {
344 int i;
345 for (i = 0; i < 4; ++i) {
346 AlphaCPU *cpu = s->cchip.cpu[i];
347 if (cpu != NULL) {
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);
352 } else {
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);
363 break;
365 case 0x00c0:
366 /* MPD: Memory Presence Detect Register. */
367 break;
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. */
375 break;
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);
381 break;
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);
386 break;
388 case 0x0280: /* DIR0 (RO) */
389 case 0x02c0: /* DIR1 (RO) */
390 case 0x0300: /* DRIR (RO) */
391 break;
393 case 0x0340:
394 /* PRBEN: Probe Enable Register. */
395 break;
397 case 0x0380: /* IIC0 */
398 s->cchip.iic[0] = val & 0xffffff;
399 break;
400 case 0x03c0: /* IIC1 */
401 s->cchip.iic[1] = val & 0xffffff;
402 break;
404 case 0x0400: /* MPR0 */
405 case 0x0440: /* MPR1 */
406 case 0x0480: /* MPR2 */
407 case 0x04c0: /* MPR3 */
408 /* MPR: Memory Programming Register. */
409 break;
411 case 0x0580:
412 /* TTR: TIGbus Timing Register. */
413 /* All sorts of stuff related to interrupt delivery timings. */
414 break;
415 case 0x05c0:
416 /* TDR: TIGbug Device Timing Register. */
417 break;
419 case 0x0600:
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);
423 break;
424 case 0x0640:
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);
428 break;
430 case 0x0680: /* DIR2 (RO) */
431 case 0x06c0: /* DIR3 (RO) */
432 break;
434 case 0x0700: /* IIC2 */
435 s->cchip.iic[2] = val & 0xffffff;
436 break;
437 case 0x0740: /* IIC3 */
438 s->cchip.iic[3] = val & 0xffffff;
439 break;
441 case 0x0780:
442 /* PWR: Power Management Control. */
443 break;
445 case 0x0c00: /* CMONCTLA */
446 case 0x0c40: /* CMONCTLB */
447 case 0x0c80: /* CMONCNT01 */
448 case 0x0cc0: /* CMONCNT23 */
449 break;
451 default:
452 return MEMTX_ERROR;
455 return MEMTX_OK;
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,
466 MemTxAttrs attrs)
468 TyphoonState *s = opaque;
469 uint64_t oldval;
471 switch (addr) {
472 case 0x0000:
473 /* WSBA0: Window Space Base Address Register. */
474 s->pchip.win[0].wba = val & 0xfff00003u;
475 break;
476 case 0x0040:
477 /* WSBA1 */
478 s->pchip.win[1].wba = val & 0xfff00003u;
479 break;
480 case 0x0080:
481 /* WSBA2 */
482 s->pchip.win[2].wba = val & 0xfff00003u;
483 break;
484 case 0x00c0:
485 /* WSBA3 */
486 s->pchip.win[3].wba = (val & 0x80fff00001ull) | 2;
487 break;
489 case 0x0100:
490 /* WSM0: Window Space Mask Register. */
491 s->pchip.win[0].wsm = val & 0xfff00000u;
492 break;
493 case 0x0140:
494 /* WSM1 */
495 s->pchip.win[1].wsm = val & 0xfff00000u;
496 break;
497 case 0x0180:
498 /* WSM2 */
499 s->pchip.win[2].wsm = val & 0xfff00000u;
500 break;
501 case 0x01c0:
502 /* WSM3 */
503 s->pchip.win[3].wsm = val & 0xfff00000u;
504 break;
506 case 0x0200:
507 /* TBA0: Translated Base Address Register. */
508 s->pchip.win[0].tba = val & 0x7fffffc00ull;
509 break;
510 case 0x0240:
511 /* TBA1 */
512 s->pchip.win[1].tba = val & 0x7fffffc00ull;
513 break;
514 case 0x0280:
515 /* TBA2 */
516 s->pchip.win[2].tba = val & 0x7fffffc00ull;
517 break;
518 case 0x02c0:
519 /* TBA3 */
520 s->pchip.win[3].tba = val & 0x7fffffc00ull;
521 break;
523 case 0x0300:
524 /* PCTL: Pchip Control Register. */
525 oldval = s->pchip.ctl;
526 oldval &= ~0x00001cff0fc7ffull; /* RW fields */
527 oldval |= val & 0x00001cff0fc7ffull;
528 s->pchip.ctl = oldval;
529 break;
531 case 0x0340:
532 /* PLAT: Pchip Master Latency Register. */
533 break;
534 case 0x03c0:
535 /* PERROR: Pchip Error Register. */
536 break;
537 case 0x0400:
538 /* PERRMASK: Pchip Error Mask Register. */
539 break;
540 case 0x0440:
541 /* PERRSET: Pchip Error Set Register. */
542 break;
544 case 0x0480:
545 /* TLBIV: Translation Buffer Invalidate Virtual Register. */
546 break;
548 case 0x04c0:
549 /* TLBIA: Translation Buffer Invalidate All Register (WO). */
550 break;
552 case 0x0500:
553 /* PMONCTL */
554 case 0x0540:
555 /* PMONCNT */
556 case 0x0800:
557 /* SPRST */
558 break;
560 default:
561 return MEMTX_ERROR;
564 return MEMTX_OK;
567 static const MemoryRegionOps cchip_ops = {
568 .read_with_attrs = cchip_read,
569 .write_with_attrs = cchip_write,
570 .endianness = DEVICE_LITTLE_ENDIAN,
571 .valid = {
572 .min_access_size = 8,
573 .max_access_size = 8,
575 .impl = {
576 .min_access_size = 8,
577 .max_access_size = 8,
581 static const MemoryRegionOps dchip_ops = {
582 .read = dchip_read,
583 .write = dchip_write,
584 .endianness = DEVICE_LITTLE_ENDIAN,
585 .valid = {
586 .min_access_size = 8,
587 .max_access_size = 8,
589 .impl = {
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,
599 .valid = {
600 .min_access_size = 8,
601 .max_access_size = 8,
603 .impl = {
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,
616 .addr_mask = mask,
617 .perm = IOMMU_RW,
619 return true;
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) {
631 return false;
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,
640 IOMMUTLBEntry *ret)
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) {
649 return false;
652 /* Check for window hit. */
653 if ((addr & ~wsm_ext) != (wba & 0xfff00000u)) {
654 return false;
657 if (wba & 2) {
658 /* Scatter-gather translation. */
659 hwaddr pte_addr;
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);
665 } else {
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,
675 hwaddr addr,
676 IOMMUAccessFlags flag,
677 int iommu_idx)
679 TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
680 IOMMUTLBEntry ret;
681 int i;
683 if (addr <= 0xffffffffu) {
684 /* Single-address cycle. */
686 /* Check for the Window Hole, inhibiting matching. */
687 if ((pchip->ctl & 0x20)
688 && addr >= 0x80000
689 && addr <= 0xfffff) {
690 goto failure;
693 /* Check the first three windows. */
694 for (i = 0; i < 3; ++i) {
695 if (window_translate(&pchip->win[i], addr, &ret)) {
696 goto success;
700 /* Check the fourth window for DAC disable. */
701 if ((pchip->win[3].wba & 0x80000000000ull) == 0
702 && window_translate(&pchip->win[3], addr, &ret)) {
703 goto success;
705 } else {
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);
713 goto success;
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) {
720 uint64_t pte_addr;
722 pte_addr = pchip->win[3].tba & 0x7ffc00000ull;
723 pte_addr |= (addr & 0xffffe000u) >> 10;
724 if (pte_translate(pte_addr, &ret)) {
725 goto success;
731 failure:
732 ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
733 success:
734 return ret;
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;
746 uint64_t drir;
747 int i;
749 /* Set/Reset the bit in CCHIP.DRIR based on IRQ+LEVEL. */
750 drir = s->cchip.drir;
751 if (level) {
752 drir |= 1ull << irq;
753 } else {
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;
771 int i;
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. */
777 if (level == 0) {
778 return;
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];
784 if (cpu != NULL) {
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(MemoryRegion *ram, ISABus **isa_bus, qemu_irq *p_rtc_irq,
820 AlphaCPU *cpus[4], pci_map_irq_fn sys_map_irq)
822 MemoryRegion *addr_space = get_system_memory();
823 DeviceState *dev;
824 TyphoonState *s;
825 PCIHostState *phb;
826 PCIBus *b;
827 int i;
829 dev = qdev_new(TYPE_TYPHOON_PCI_HOST_BRIDGE);
831 s = TYPHOON_PCI_HOST_BRIDGE(dev);
832 phb = PCI_HOST_BRIDGE(dev);
834 s->cchip.misc = 0x800000000ull; /* Revision: Typhoon. */
835 s->pchip.win[3].wba = 2; /* Window 3 SG always enabled. */
837 /* Remember the CPUs so that we can deliver interrupts to them. */
838 for (i = 0; i < 4; i++) {
839 AlphaCPU *cpu = cpus[i];
840 s->cchip.cpu[i] = cpu;
841 if (cpu != NULL) {
842 cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
843 typhoon_alarm_timer,
844 (void *)((uintptr_t)s + i));
848 *p_rtc_irq = qemu_allocate_irq(typhoon_set_timer_irq, s, 0);
850 /* Main memory region, 0x00.0000.0000. Real hardware supports 32GB,
851 but the address space hole reserved at this point is 8TB. */
852 memory_region_add_subregion(addr_space, 0, ram);
854 /* TIGbus, 0x801.0000.0000, 1GB. */
855 /* ??? The TIGbus is used for delivering interrupts, and access to
856 the flash ROM. I'm not sure that we need to implement it at all. */
858 /* Pchip0 CSRs, 0x801.8000.0000, 256MB. */
859 memory_region_init_io(&s->pchip.region, OBJECT(s), &pchip_ops, s, "pchip0",
860 256 * MiB);
861 memory_region_add_subregion(addr_space, 0x80180000000ULL,
862 &s->pchip.region);
864 /* Cchip CSRs, 0x801.A000.0000, 256MB. */
865 memory_region_init_io(&s->cchip.region, OBJECT(s), &cchip_ops, s, "cchip0",
866 256 * MiB);
867 memory_region_add_subregion(addr_space, 0x801a0000000ULL,
868 &s->cchip.region);
870 /* Dchip CSRs, 0x801.B000.0000, 256MB. */
871 memory_region_init_io(&s->dchip_region, OBJECT(s), &dchip_ops, s, "dchip0",
872 256 * MiB);
873 memory_region_add_subregion(addr_space, 0x801b0000000ULL,
874 &s->dchip_region);
876 /* Pchip0 PCI memory, 0x800.0000.0000, 4GB. */
877 memory_region_init(&s->pchip.reg_mem, OBJECT(s), "pci0-mem", 4 * GiB);
878 memory_region_add_subregion(addr_space, 0x80000000000ULL,
879 &s->pchip.reg_mem);
881 /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB. */
882 memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops,
883 NULL, "pci0-io", 32 * MiB);
884 memory_region_add_subregion(addr_space, 0x801fc000000ULL,
885 &s->pchip.reg_io);
887 b = pci_register_root_bus(dev, "pci",
888 typhoon_set_irq, sys_map_irq, s,
889 &s->pchip.reg_mem, &s->pchip.reg_io,
890 0, 64, TYPE_PCI_BUS);
891 phb->bus = b;
892 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
894 /* Host memory as seen from the PCI side, via the IOMMU. */
895 memory_region_init_iommu(&s->pchip.iommu, sizeof(s->pchip.iommu),
896 TYPE_TYPHOON_IOMMU_MEMORY_REGION, OBJECT(s),
897 "iommu-typhoon", UINT64_MAX);
898 address_space_init(&s->pchip.iommu_as, MEMORY_REGION(&s->pchip.iommu),
899 "pchip0-pci");
900 pci_setup_iommu(b, typhoon_pci_dma_iommu, s);
902 /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
903 memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
904 b, "pci0-iack", 64 * MiB);
905 memory_region_add_subregion(addr_space, 0x801f8000000ULL,
906 &s->pchip.reg_iack);
908 /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB. */
909 memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops,
910 b, "pci0-conf", 16 * MiB);
911 memory_region_add_subregion(addr_space, 0x801fe000000ULL,
912 &s->pchip.reg_conf);
914 /* For the record, these are the mappings for the second PCI bus.
915 We can get away with not implementing them because we indicate
916 via the Cchip.CSC<PIP> bit that Pchip1 is not present. */
917 /* Pchip1 PCI memory, 0x802.0000.0000, 4GB. */
918 /* Pchip1 CSRs, 0x802.8000.0000, 256MB. */
919 /* Pchip1 PCI special/interrupt acknowledge, 0x802.F800.0000, 64MB. */
920 /* Pchip1 PCI I/O, 0x802.FC00.0000, 32MB. */
921 /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB. */
923 /* Init the ISA bus. */
924 /* ??? Technically there should be a cy82c693ub pci-isa bridge. */
926 qemu_irq *isa_irqs;
928 *isa_bus = isa_bus_new(NULL, get_system_memory(), &s->pchip.reg_io,
929 &error_abort);
930 isa_irqs = i8259_init(*isa_bus,
931 qemu_allocate_irq(typhoon_set_isa_irq, s, 0));
932 isa_bus_irqs(*isa_bus, isa_irqs);
935 return b;
938 static const TypeInfo typhoon_pcihost_info = {
939 .name = TYPE_TYPHOON_PCI_HOST_BRIDGE,
940 .parent = TYPE_PCI_HOST_BRIDGE,
941 .instance_size = sizeof(TyphoonState),
944 static void typhoon_iommu_memory_region_class_init(ObjectClass *klass,
945 void *data)
947 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
949 imrc->translate = typhoon_translate_iommu;
952 static const TypeInfo typhoon_iommu_memory_region_info = {
953 .parent = TYPE_IOMMU_MEMORY_REGION,
954 .name = TYPE_TYPHOON_IOMMU_MEMORY_REGION,
955 .class_init = typhoon_iommu_memory_region_class_init,
958 static void typhoon_register_types(void)
960 type_register_static(&typhoon_pcihost_info);
961 type_register_static(&typhoon_iommu_memory_region_info);
964 type_init(typhoon_register_types)