]> Git Repo - qemu.git/blob - hw/alpha/typhoon.c
trace-events: Shorten file names in comments
[qemu.git] / hw / alpha / typhoon.c
1 /*
2  * DEC 21272 (TSUNAMI/TYPHOON) chipset emulation.
3  *
4  * Written by Richard Henderson.
5  *
6  * This work is licensed under the GNU GPL license version 2 or later.
7  */
8
9 #include "qemu/osdep.h"
10 #include "qemu/units.h"
11 #include "qapi/error.h"
12 #include "cpu.h"
13 #include "hw/hw.h"
14 #include "sysemu/sysemu.h"
15 #include "alpha_sys.h"
16 #include "exec/address-spaces.h"
17
18
19 #define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
20 #define TYPE_TYPHOON_IOMMU_MEMORY_REGION "typhoon-iommu-memory-region"
21
22 typedef struct TyphoonCchip {
23     MemoryRegion region;
24     uint64_t misc;
25     uint64_t drir;
26     uint64_t dim[4];
27     uint32_t iic[4];
28     AlphaCPU *cpu[4];
29 } TyphoonCchip;
30
31 typedef struct TyphoonWindow {
32     uint64_t wba;
33     uint64_t wsm;
34     uint64_t tba;
35 } TyphoonWindow;
36  
37 typedef struct TyphoonPchip {
38     MemoryRegion region;
39     MemoryRegion reg_iack;
40     MemoryRegion reg_mem;
41     MemoryRegion reg_io;
42     MemoryRegion reg_conf;
43
44     AddressSpace iommu_as;
45     IOMMUMemoryRegion iommu;
46
47     uint64_t ctl;
48     TyphoonWindow win[4];
49 } TyphoonPchip;
50
51 #define TYPHOON_PCI_HOST_BRIDGE(obj) \
52     OBJECT_CHECK(TyphoonState, (obj), TYPE_TYPHOON_PCI_HOST_BRIDGE)
53
54 typedef struct TyphoonState {
55     PCIHostState parent_obj;
56
57     TyphoonCchip cchip;
58     TyphoonPchip pchip;
59     MemoryRegion dchip_region;
60     MemoryRegion ram_region;
61 } TyphoonState;
62
63 /* Called when one of DRIR or DIM changes.  */
64 static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
65 {
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);
73         }
74     }
75 }
76
77 static MemTxResult cchip_read(void *opaque, hwaddr addr,
78                               uint64_t *data, unsigned size,
79                               MemTxAttrs attrs)
80 {
81     CPUState *cpu = current_cpu;
82     TyphoonState *s = opaque;
83     uint64_t ret = 0;
84
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;
91
92     case 0x0040:
93         /* MTR: Memory Timing Register.  */
94         /* All sorts of stuff related to real DRAM.  */
95         break;
96
97     case 0x0080:
98         /* MISC: Miscellaneous Register.  */
99         ret = s->cchip.misc | (cpu->cpu_index & 3);
100         break;
101
102     case 0x00c0:
103         /* MPD: Memory Presence Detect Register.  */
104         break;
105
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;
113
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;
134
135     case 0x0340:
136         /* PRBEN: Probe Enable Register.  */
137         break;
138
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;
147
148     case 0x0400: /* MPR0 */
149     case 0x0440: /* MPR1 */
150     case 0x0480: /* MPR2 */
151     case 0x04c0: /* MPR3 */
152         /* MPR: Memory Programming Register.  */
153         break;
154
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;
162
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;
179
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;
188
189     case 0x0780:
190         /* PWR: Power Management Control.   */
191         break;
192     
193     case 0x0c00: /* CMONCTLA */
194     case 0x0c40: /* CMONCTLB */
195     case 0x0c80: /* CMONCNT01 */
196     case 0x0cc0: /* CMONCNT23 */
197         break;
198
199     default:
200         return MEMTX_ERROR;
201     }
202
203     *data = ret;
204     return MEMTX_OK;
205 }
206
207 static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
208 {
209     /* Skip this.  It's all related to DRAM timing and setup.  */
210     return 0;
211 }
212
213 static MemTxResult pchip_read(void *opaque, hwaddr addr, uint64_t *data,
214                               unsigned size, MemTxAttrs attrs)
215 {
216     TyphoonState *s = opaque;
217     uint64_t ret = 0;
218
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;
236
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;
253
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;
270
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;
297
298     default:
299         return MEMTX_ERROR;
300     }
301
302     *data = ret;
303     return MEMTX_OK;
304 }
305
306 static MemTxResult cchip_write(void *opaque, hwaddr addr,
307                                uint64_t val, unsigned size,
308                                MemTxAttrs attrs)
309 {
310     TyphoonState *s = opaque;
311     uint64_t oldval, newval;
312
313     switch (addr) {
314     case 0x0000:
315         /* CSC: Cchip System Configuration Register.  */
316         /* All sorts of data here; nothing relevant RW.  */
317         break;
318
319     case 0x0040:
320         /* MTR: Memory Timing Register.  */
321         /* All sorts of stuff related to real DRAM.  */
322         break;
323
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 */
334             }
335         }
336         newval |= (val & 0xf000) >> 4;     /* IPREQ field sets IPINTR.  */
337
338         newval &= ~0xf0000000000ull;       /* WO and RW fields */
339         newval |= val & 0xf0000000000ull;
340         s->cchip.misc = newval;
341
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);
354                     }
355
356                     /* ITI can only be cleared by the write.  */
357                     if ((newval & (1 << (i + 4))) == 0) {
358                         cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER);
359                     }
360                 }
361             }
362         }
363         break;
364
365     case 0x00c0:
366         /* MPD: Memory Presence Detect Register.  */
367         break;
368
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;
376
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;
387
388     case 0x0280: /* DIR0 (RO) */
389     case 0x02c0: /* DIR1 (RO) */
390     case 0x0300: /* DRIR (RO) */
391         break;
392
393     case 0x0340:
394         /* PRBEN: Probe Enable Register.  */
395         break;
396
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;
403
404     case 0x0400: /* MPR0 */
405     case 0x0440: /* MPR1 */
406     case 0x0480: /* MPR2 */
407     case 0x04c0: /* MPR3 */
408         /* MPR: Memory Programming Register.  */
409         break;
410
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;
418
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;
429
430     case 0x0680: /* DIR2 (RO) */
431     case 0x06c0: /* DIR3 (RO) */
432         break;
433
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;
440
441     case 0x0780:
442         /* PWR: Power Management Control.   */
443         break;
444     
445     case 0x0c00: /* CMONCTLA */
446     case 0x0c40: /* CMONCTLB */
447     case 0x0c80: /* CMONCNT01 */
448     case 0x0cc0: /* CMONCNT23 */
449         break;
450
451     default:
452         return MEMTX_ERROR;
453     }
454
455     return MEMTX_OK;
456 }
457
458 static void dchip_write(void *opaque, hwaddr addr,
459                         uint64_t val, unsigned size)
460 {
461     /* Skip this.  It's all related to DRAM timing and setup.  */
462 }
463
464 static MemTxResult pchip_write(void *opaque, hwaddr addr,
465                                uint64_t val, unsigned size,
466                                MemTxAttrs attrs)
467 {
468     TyphoonState *s = opaque;
469     uint64_t oldval;
470
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;
488
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;
505
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;
522
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;
530
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;
543
544     case 0x0480:
545         /* TLBIV: Translation Buffer Invalidate Virtual Register.  */
546         break;
547
548     case 0x04c0:
549         /* TLBIA: Translation Buffer Invalidate All Register (WO).  */
550         break;
551
552     case 0x0500:
553         /* PMONCTL */
554     case 0x0540:
555         /* PMONCNT */
556     case 0x0800:
557         /* SPRST */
558         break;
559
560     default:
561         return MEMTX_ERROR;
562     }
563
564     return MEMTX_OK;
565 }
566
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,
574     },
575     .impl = {
576         .min_access_size = 8,
577         .max_access_size = 8,
578     },
579 };
580
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,
588     },
589     .impl = {
590         .min_access_size = 8,
591         .max_access_size = 8,
592     },
593 };
594
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,
602     },
603     .impl = {
604         .min_access_size = 8,
605         .max_access_size = 8,
606     },
607 };
608
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)
612 {
613     *ret = (IOMMUTLBEntry) {
614         .target_as = &address_space_memory,
615         .translated_addr = taddr,
616         .addr_mask = mask,
617         .perm = IOMMU_RW,
618     };
619     return true;
620 }
621
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)
625 {
626     uint64_t pte = address_space_ldq(&address_space_memory, pte_addr,
627                                      MEMTXATTRS_UNSPECIFIED, NULL);
628
629     /* Check valid bit.  */
630     if ((pte & 1) == 0) {
631         return false;
632     }
633
634     return make_iommu_tlbe((pte & 0x3ffffe) << 12, 0x1fff, ret);
635 }
636
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)
641 {
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;
646
647     /* Check for window disabled.  */
648     if ((wba & 1) == 0) {
649         return false;
650     }
651
652     /* Check for window hit.  */
653     if ((addr & ~wsm_ext) != (wba & 0xfff00000u)) {
654         return false;
655     }
656
657     if (wba & 2) {
658         /* Scatter-gather translation.  */
659         hwaddr pte_addr;
660
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);
668     }
669 }
670
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)
678 {
679     TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
680     IOMMUTLBEntry ret;
681     int i;
682
683     if (addr <= 0xffffffffu) {
684         /* Single-address cycle.  */
685
686         /* Check for the Window Hole, inhibiting matching.  */
687         if ((pchip->ctl & 0x20)
688             && addr >= 0x80000
689             && addr <= 0xfffff) {
690             goto failure;
691         }
692
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;
697             }
698         }
699
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;
704         }
705     } else {
706         /* Double-address cycle.  */
707
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;
714             }
715         }
716
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;
721
722                 pte_addr  = pchip->win[3].tba & 0x7ffc00000ull;
723                 pte_addr |= (addr & 0xffffe000u) >> 10;
724                 if (pte_translate(pte_addr, &ret)) {
725                         goto success;
726                 }
727             }
728         }
729     }
730
731  failure:
732     ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
733  success:
734     return ret;
735 }
736
737 static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
738 {
739     TyphoonState *s = opaque;
740     return &s->pchip.iommu_as;
741 }
742
743 static void typhoon_set_irq(void *opaque, int irq, int level)
744 {
745     TyphoonState *s = opaque;
746     uint64_t drir;
747     int i;
748
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);
755     }
756     s->cchip.drir = drir;
757
758     for (i = 0; i < 4; ++i) {
759         cpu_irq_change(s->cchip.cpu[i], s->cchip.dim[i] & drir);
760     }
761 }
762
763 static void typhoon_set_isa_irq(void *opaque, int irq, int level)
764 {
765     typhoon_set_irq(opaque, 55, level);
766 }
767
768 static void typhoon_set_timer_irq(void *opaque, int irq, int level)
769 {
770     TyphoonState *s = opaque;
771     int i;
772
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;
779     }
780
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];
786
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...  */
795
796             iic = ((iic - 1) & 0x1ffffff) | (iic & 0x1000000);
797             s->cchip.iic[i] = iic;
798
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);
804             }
805         }
806     }
807 }
808
809 static void typhoon_alarm_timer(void *opaque)
810 {
811     TyphoonState *s = (TyphoonState *)((uintptr_t)opaque & ~3);
812     int cpu = (uintptr_t)opaque & 3;
813
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);
817 }
818
819 PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
820                      qemu_irq *p_rtc_irq,
821                      AlphaCPU *cpus[4], pci_map_irq_fn sys_map_irq)
822 {
823     MemoryRegion *addr_space = get_system_memory();
824     DeviceState *dev;
825     TyphoonState *s;
826     PCIHostState *phb;
827     PCIBus *b;
828     int i;
829
830     dev = qdev_create(NULL, TYPE_TYPHOON_PCI_HOST_BRIDGE);
831
832     s = TYPHOON_PCI_HOST_BRIDGE(dev);
833     phb = PCI_HOST_BRIDGE(dev);
834
835     s->cchip.misc = 0x800000000ull; /* Revision: Typhoon.  */
836     s->pchip.win[3].wba = 2;        /* Window 3 SG always enabled. */
837
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;
842         if (cpu != NULL) {
843             cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
844                                                  typhoon_alarm_timer,
845                                                  (void *)((uintptr_t)s + i));
846         }
847     }
848
849     *p_rtc_irq = qemu_allocate_irq(typhoon_set_timer_irq, s, 0);
850
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",
854                                          ram_size);
855     memory_region_add_subregion(addr_space, 0, &s->ram_region);
856
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.  */
860
861     /* Pchip0 CSRs, 0x801.8000.0000, 256MB.  */
862     memory_region_init_io(&s->pchip.region, OBJECT(s), &pchip_ops, s, "pchip0",
863                           256 * MiB);
864     memory_region_add_subregion(addr_space, 0x80180000000ULL,
865                                 &s->pchip.region);
866
867     /* Cchip CSRs, 0x801.A000.0000, 256MB.  */
868     memory_region_init_io(&s->cchip.region, OBJECT(s), &cchip_ops, s, "cchip0",
869                           256 * MiB);
870     memory_region_add_subregion(addr_space, 0x801a0000000ULL,
871                                 &s->cchip.region);
872
873     /* Dchip CSRs, 0x801.B000.0000, 256MB.  */
874     memory_region_init_io(&s->dchip_region, OBJECT(s), &dchip_ops, s, "dchip0",
875                           256 * MiB);
876     memory_region_add_subregion(addr_space, 0x801b0000000ULL,
877                                 &s->dchip_region);
878
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,
882                                 &s->pchip.reg_mem);
883
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,
888                                 &s->pchip.reg_io);
889
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);
894     phb->bus = b;
895     qdev_init_nofail(dev);
896
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),
902                        "pchip0-pci");
903     pci_setup_iommu(b, typhoon_pci_dma_iommu, s);
904
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,
909                                 &s->pchip.reg_iack);
910
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,
915                                 &s->pchip.reg_conf);
916
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.  */
925
926     /* Init the ISA bus.  */
927     /* ??? Technically there should be a cy82c693ub pci-isa bridge.  */
928     {
929         qemu_irq *isa_irqs;
930
931         *isa_bus = isa_bus_new(NULL, get_system_memory(), &s->pchip.reg_io,
932                                &error_abort);
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);
936     }
937
938     return b;
939 }
940
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),
945 };
946
947 static void typhoon_iommu_memory_region_class_init(ObjectClass *klass,
948                                                    void *data)
949 {
950     IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
951
952     imrc->translate = typhoon_translate_iommu;
953 }
954
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,
959 };
960
961 static void typhoon_register_types(void)
962 {
963     type_register_static(&typhoon_pcihost_info);
964     type_register_static(&typhoon_iommu_memory_region_info);
965 }
966
967 type_init(typhoon_register_types)
This page took 0.077793 seconds and 4 git commands to generate.