]> git.proxmox.com Git - mirror_qemu.git/blame - hw/alpha/typhoon.c
memory: add owner argument to initialization functions
[mirror_qemu.git] / hw / alpha / typhoon.c
CommitLineData
80bb2ff7
RH
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 "cpu.h"
83c9f4ca 10#include "hw/hw.h"
bd2be150 11#include "hw/devices.h"
9c17d615 12#include "sysemu/sysemu.h"
47b43a1f 13#include "alpha_sys.h"
022c62cb 14#include "exec/address-spaces.h"
80bb2ff7
RH
15
16
94dd91d6
AF
17#define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
18
80bb2ff7
RH
19typedef struct TyphoonCchip {
20 MemoryRegion region;
21 uint64_t misc;
22 uint64_t drir;
23 uint64_t dim[4];
24 uint32_t iic[4];
ad601177 25 AlphaCPU *cpu[4];
80bb2ff7
RH
26} TyphoonCchip;
27
28typedef struct TyphoonWindow {
29 uint32_t base_addr;
30 uint32_t mask;
31 uint32_t translated_base_pfn;
32} TyphoonWindow;
33
34typedef struct TyphoonPchip {
35 MemoryRegion region;
36 MemoryRegion reg_iack;
37 MemoryRegion reg_mem;
38 MemoryRegion reg_io;
39 MemoryRegion reg_conf;
40 uint64_t ctl;
41 TyphoonWindow win[4];
42} TyphoonPchip;
43
94dd91d6
AF
44#define TYPHOON_PCI_HOST_BRIDGE(obj) \
45 OBJECT_CHECK(TyphoonState, (obj), TYPE_TYPHOON_PCI_HOST_BRIDGE)
46
80bb2ff7 47typedef struct TyphoonState {
67c332fd 48 PCIHostState parent_obj;
94dd91d6 49
80bb2ff7
RH
50 TyphoonCchip cchip;
51 TyphoonPchip pchip;
52 MemoryRegion dchip_region;
53 MemoryRegion ram_region;
54
55 /* QEMU emulation state. */
56 uint32_t latch_tmp;
57} TyphoonState;
58
59/* Called when one of DRIR or DIM changes. */
ad601177 60static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
80bb2ff7
RH
61{
62 /* If there are any non-masked interrupts, tell the cpu. */
ad601177 63 if (cpu != NULL) {
d8ed887b 64 CPUState *cs = CPU(cpu);
80bb2ff7 65 if (req) {
c3affe56 66 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
80bb2ff7 67 } else {
d8ed887b 68 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
80bb2ff7
RH
69 }
70 }
71}
72
a8170e5e 73static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
80bb2ff7 74{
8b2aee29 75 CPUAlphaState *env = cpu_single_env;
80bb2ff7 76 TyphoonState *s = opaque;
55e5c285 77 CPUState *cpu;
80bb2ff7
RH
78 uint64_t ret = 0;
79
80 if (addr & 4) {
81 return s->latch_tmp;
82 }
83
84 switch (addr) {
85 case 0x0000:
86 /* CSC: Cchip System Configuration Register. */
87 /* All sorts of data here; probably the only thing relevant is
88 PIP<14> Pchip 1 Present = 0. */
89 break;
90
91 case 0x0040:
92 /* MTR: Memory Timing Register. */
93 /* All sorts of stuff related to real DRAM. */
94 break;
95
96 case 0x0080:
97 /* MISC: Miscellaneous Register. */
55e5c285
AF
98 cpu = ENV_GET_CPU(env);
99 ret = s->cchip.misc | (cpu->cpu_index & 3);
80bb2ff7
RH
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:
c658b94f
AF
200 cpu = CPU(alpha_env_get_cpu(cpu_single_env));
201 cpu_unassigned_access(cpu, addr, false, false, 0, size);
80bb2ff7
RH
202 return -1;
203 }
204
205 s->latch_tmp = ret >> 32;
206 return ret;
207}
208
a8170e5e 209static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
80bb2ff7
RH
210{
211 /* Skip this. It's all related to DRAM timing and setup. */
212 return 0;
213}
214
a8170e5e 215static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
80bb2ff7
RH
216{
217 TyphoonState *s = opaque;
c658b94f 218 CPUState *cs;
80bb2ff7
RH
219 uint64_t ret = 0;
220
221 if (addr & 4) {
222 return s->latch_tmp;
223 }
224
225 switch (addr) {
226 case 0x0000:
227 /* WSBA0: Window Space Base Address Register. */
228 ret = s->pchip.win[0].base_addr;
229 break;
230 case 0x0040:
231 /* WSBA1 */
232 ret = s->pchip.win[1].base_addr;
233 break;
234 case 0x0080:
235 /* WSBA2 */
236 ret = s->pchip.win[2].base_addr;
237 break;
238 case 0x00c0:
239 /* WSBA3 */
240 ret = s->pchip.win[3].base_addr;
241 break;
242
243 case 0x0100:
244 /* WSM0: Window Space Mask Register. */
245 ret = s->pchip.win[0].mask;
246 break;
247 case 0x0140:
248 /* WSM1 */
249 ret = s->pchip.win[1].mask;
250 break;
251 case 0x0180:
252 /* WSM2 */
253 ret = s->pchip.win[2].mask;
254 break;
255 case 0x01c0:
256 /* WSM3 */
257 ret = s->pchip.win[3].mask;
258 break;
259
260 case 0x0200:
261 /* TBA0: Translated Base Address Register. */
262 ret = (uint64_t)s->pchip.win[0].translated_base_pfn << 10;
263 break;
264 case 0x0240:
265 /* TBA1 */
266 ret = (uint64_t)s->pchip.win[1].translated_base_pfn << 10;
267 break;
268 case 0x0280:
269 /* TBA2 */
270 ret = (uint64_t)s->pchip.win[2].translated_base_pfn << 10;
271 break;
272 case 0x02c0:
273 /* TBA3 */
274 ret = (uint64_t)s->pchip.win[3].translated_base_pfn << 10;
275 break;
276
277 case 0x0300:
278 /* PCTL: Pchip Control Register. */
279 ret = s->pchip.ctl;
280 break;
281 case 0x0340:
282 /* PLAT: Pchip Master Latency Register. */
283 break;
284 case 0x03c0:
285 /* PERROR: Pchip Error Register. */
286 break;
287 case 0x0400:
288 /* PERRMASK: Pchip Error Mask Register. */
289 break;
290 case 0x0440:
291 /* PERRSET: Pchip Error Set Register. */
292 break;
293 case 0x0480:
294 /* TLBIV: Translation Buffer Invalidate Virtual Register (WO). */
295 break;
296 case 0x04c0:
297 /* TLBIA: Translation Buffer Invalidate All Register (WO). */
298 break;
299 case 0x0500: /* PMONCTL */
300 case 0x0540: /* PMONCNT */
301 case 0x0800: /* SPRST */
302 break;
303
304 default:
c658b94f
AF
305 cs = CPU(alpha_env_get_cpu(cpu_single_env));
306 cpu_unassigned_access(cs, addr, false, false, 0, size);
80bb2ff7
RH
307 return -1;
308 }
309
310 s->latch_tmp = ret >> 32;
311 return ret;
312}
313
a8170e5e 314static void cchip_write(void *opaque, hwaddr addr,
80bb2ff7
RH
315 uint64_t v32, unsigned size)
316{
317 TyphoonState *s = opaque;
c658b94f 318 CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
80bb2ff7
RH
319 uint64_t val, oldval, newval;
320
321 if (addr & 4) {
322 val = v32 << 32 | s->latch_tmp;
323 addr ^= 4;
324 } else {
325 s->latch_tmp = v32;
326 return;
327 }
328
329 switch (addr) {
330 case 0x0000:
331 /* CSC: Cchip System Configuration Register. */
332 /* All sorts of data here; nothing relevant RW. */
333 break;
334
335 case 0x0040:
336 /* MTR: Memory Timing Register. */
337 /* All sorts of stuff related to real DRAM. */
338 break;
339
340 case 0x0080:
341 /* MISC: Miscellaneous Register. */
342 newval = oldval = s->cchip.misc;
343 newval &= ~(val & 0x10000ff0); /* W1C fields */
344 if (val & 0x100000) {
345 newval &= ~0xff0000ull; /* ACL clears ABT and ABW */
346 } else {
347 newval |= val & 0x00f00000; /* ABT field is W1S */
348 if ((newval & 0xf0000) == 0) {
349 newval |= val & 0xf0000; /* ABW field is W1S iff zero */
350 }
351 }
352 newval |= (val & 0xf000) >> 4; /* IPREQ field sets IPINTR. */
353
354 newval &= ~0xf0000000000ull; /* WO and RW fields */
355 newval |= val & 0xf0000000000ull;
356 s->cchip.misc = newval;
357
358 /* Pass on changes to IPI and ITI state. */
359 if ((newval ^ oldval) & 0xff0) {
360 int i;
361 for (i = 0; i < 4; ++i) {
ad601177
AF
362 AlphaCPU *cpu = s->cchip.cpu[i];
363 if (cpu != NULL) {
d8ed887b 364 CPUState *cs = CPU(cpu);
80bb2ff7
RH
365 /* IPI can be either cleared or set by the write. */
366 if (newval & (1 << (i + 8))) {
c3affe56 367 cpu_interrupt(cs, CPU_INTERRUPT_SMP);
80bb2ff7 368 } else {
d8ed887b 369 cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP);
80bb2ff7
RH
370 }
371
372 /* ITI can only be cleared by the write. */
373 if ((newval & (1 << (i + 4))) == 0) {
d8ed887b 374 cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER);
80bb2ff7
RH
375 }
376 }
377 }
378 }
379 break;
380
381 case 0x00c0:
382 /* MPD: Memory Presence Detect Register. */
383 break;
384
385 case 0x0100: /* AAR0 */
386 case 0x0140: /* AAR1 */
387 case 0x0180: /* AAR2 */
388 case 0x01c0: /* AAR3 */
389 /* AAR: Array Address Register. */
390 /* All sorts of information about DRAM. */
391 break;
392
393 case 0x0200: /* DIM0 */
394 /* DIM: Device Interrupt Mask Register, CPU0. */
395 s->cchip.dim[0] = val;
396 cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir);
397 break;
398 case 0x0240: /* DIM1 */
399 /* DIM: Device Interrupt Mask Register, CPU1. */
400 s->cchip.dim[0] = val;
401 cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir);
402 break;
403
404 case 0x0280: /* DIR0 (RO) */
405 case 0x02c0: /* DIR1 (RO) */
406 case 0x0300: /* DRIR (RO) */
407 break;
408
409 case 0x0340:
410 /* PRBEN: Probe Enable Register. */
411 break;
412
413 case 0x0380: /* IIC0 */
414 s->cchip.iic[0] = val & 0xffffff;
415 break;
416 case 0x03c0: /* IIC1 */
417 s->cchip.iic[1] = val & 0xffffff;
418 break;
419
420 case 0x0400: /* MPR0 */
421 case 0x0440: /* MPR1 */
422 case 0x0480: /* MPR2 */
423 case 0x04c0: /* MPR3 */
424 /* MPR: Memory Programming Register. */
425 break;
426
427 case 0x0580:
428 /* TTR: TIGbus Timing Register. */
429 /* All sorts of stuff related to interrupt delivery timings. */
430 break;
431 case 0x05c0:
432 /* TDR: TIGbug Device Timing Register. */
433 break;
434
435 case 0x0600:
436 /* DIM2: Device Interrupt Mask Register, CPU2. */
437 s->cchip.dim[2] = val;
438 cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir);
439 break;
440 case 0x0640:
441 /* DIM3: Device Interrupt Mask Register, CPU3. */
442 s->cchip.dim[3] = val;
443 cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir);
444 break;
445
446 case 0x0680: /* DIR2 (RO) */
447 case 0x06c0: /* DIR3 (RO) */
448 break;
449
450 case 0x0700: /* IIC2 */
451 s->cchip.iic[2] = val & 0xffffff;
452 break;
453 case 0x0740: /* IIC3 */
454 s->cchip.iic[3] = val & 0xffffff;
455 break;
456
457 case 0x0780:
458 /* PWR: Power Management Control. */
459 break;
460
461 case 0x0c00: /* CMONCTLA */
462 case 0x0c40: /* CMONCTLB */
463 case 0x0c80: /* CMONCNT01 */
464 case 0x0cc0: /* CMONCNT23 */
465 break;
466
467 default:
c658b94f 468 cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
80bb2ff7
RH
469 return;
470 }
471}
472
a8170e5e 473static void dchip_write(void *opaque, hwaddr addr,
80bb2ff7
RH
474 uint64_t val, unsigned size)
475{
476 /* Skip this. It's all related to DRAM timing and setup. */
477}
478
a8170e5e 479static void pchip_write(void *opaque, hwaddr addr,
80bb2ff7
RH
480 uint64_t v32, unsigned size)
481{
482 TyphoonState *s = opaque;
c658b94f 483 CPUState *cs;
80bb2ff7
RH
484 uint64_t val, oldval;
485
486 if (addr & 4) {
487 val = v32 << 32 | s->latch_tmp;
488 addr ^= 4;
489 } else {
490 s->latch_tmp = v32;
491 return;
492 }
493
494 switch (addr) {
495 case 0x0000:
496 /* WSBA0: Window Space Base Address Register. */
497 s->pchip.win[0].base_addr = val;
498 break;
499 case 0x0040:
500 /* WSBA1 */
501 s->pchip.win[1].base_addr = val;
502 break;
503 case 0x0080:
504 /* WSBA2 */
505 s->pchip.win[2].base_addr = val;
506 break;
507 case 0x00c0:
508 /* WSBA3 */
509 s->pchip.win[3].base_addr = val;
510 break;
511
512 case 0x0100:
513 /* WSM0: Window Space Mask Register. */
514 s->pchip.win[0].mask = val;
515 break;
516 case 0x0140:
517 /* WSM1 */
518 s->pchip.win[1].mask = val;
519 break;
520 case 0x0180:
521 /* WSM2 */
522 s->pchip.win[2].mask = val;
523 break;
524 case 0x01c0:
525 /* WSM3 */
526 s->pchip.win[3].mask = val;
527 break;
528
529 case 0x0200:
530 /* TBA0: Translated Base Address Register. */
531 s->pchip.win[0].translated_base_pfn = val >> 10;
532 break;
533 case 0x0240:
534 /* TBA1 */
535 s->pchip.win[1].translated_base_pfn = val >> 10;
536 break;
537 case 0x0280:
538 /* TBA2 */
539 s->pchip.win[2].translated_base_pfn = val >> 10;
540 break;
541 case 0x02c0:
542 /* TBA3 */
543 s->pchip.win[3].translated_base_pfn = val >> 10;
544 break;
545
546 case 0x0300:
547 /* PCTL: Pchip Control Register. */
548 oldval = s->pchip.ctl;
549 oldval &= ~0x00001cff0fc7ffull; /* RW fields */
550 oldval |= val & 0x00001cff0fc7ffull;
551
552 s->pchip.ctl = oldval;
553 break;
554
555 case 0x0340:
556 /* PLAT: Pchip Master Latency Register. */
557 break;
558 case 0x03c0:
559 /* PERROR: Pchip Error Register. */
560 break;
561 case 0x0400:
562 /* PERRMASK: Pchip Error Mask Register. */
563 break;
564 case 0x0440:
565 /* PERRSET: Pchip Error Set Register. */
566 break;
567
568 case 0x0480:
569 /* TLBIV: Translation Buffer Invalidate Virtual Register. */
570 break;
571
572 case 0x04c0:
573 /* TLBIA: Translation Buffer Invalidate All Register (WO). */
574 break;
575
576 case 0x0500:
577 /* PMONCTL */
578 case 0x0540:
579 /* PMONCNT */
580 case 0x0800:
581 /* SPRST */
582 break;
583
584 default:
c658b94f
AF
585 cs = CPU(alpha_env_get_cpu(cpu_single_env));
586 cpu_unassigned_access(cs, addr, true, false, 0, size);
80bb2ff7
RH
587 return;
588 }
589}
590
591static const MemoryRegionOps cchip_ops = {
592 .read = cchip_read,
593 .write = cchip_write,
594 .endianness = DEVICE_LITTLE_ENDIAN,
595 .valid = {
596 .min_access_size = 4, /* ??? Should be 8. */
597 .max_access_size = 8,
598 },
599 .impl = {
600 .min_access_size = 4,
601 .max_access_size = 4,
602 },
603};
604
605static const MemoryRegionOps dchip_ops = {
606 .read = dchip_read,
607 .write = dchip_write,
608 .endianness = DEVICE_LITTLE_ENDIAN,
609 .valid = {
610 .min_access_size = 4, /* ??? Should be 8. */
611 .max_access_size = 8,
612 },
613 .impl = {
614 .min_access_size = 4,
615 .max_access_size = 8,
616 },
617};
618
619static const MemoryRegionOps pchip_ops = {
620 .read = pchip_read,
621 .write = pchip_write,
622 .endianness = DEVICE_LITTLE_ENDIAN,
623 .valid = {
624 .min_access_size = 4, /* ??? Should be 8. */
625 .max_access_size = 8,
626 },
627 .impl = {
628 .min_access_size = 4,
629 .max_access_size = 4,
630 },
631};
632
633static void typhoon_set_irq(void *opaque, int irq, int level)
634{
635 TyphoonState *s = opaque;
636 uint64_t drir;
637 int i;
638
639 /* Set/Reset the bit in CCHIP.DRIR based on IRQ+LEVEL. */
640 drir = s->cchip.drir;
641 if (level) {
642 drir |= 1ull << irq;
643 } else {
644 drir &= ~(1ull << irq);
645 }
646 s->cchip.drir = drir;
647
648 for (i = 0; i < 4; ++i) {
649 cpu_irq_change(s->cchip.cpu[i], s->cchip.dim[i] & drir);
650 }
651}
652
653static void typhoon_set_isa_irq(void *opaque, int irq, int level)
654{
655 typhoon_set_irq(opaque, 55, level);
656}
657
658static void typhoon_set_timer_irq(void *opaque, int irq, int level)
659{
660 TyphoonState *s = opaque;
661 int i;
662
663 /* Thankfully, the mc146818rtc code doesn't track the IRQ state,
664 and so we don't have to worry about missing interrupts just
665 because we never actually ACK the interrupt. Just ignore any
666 case of the interrupt level going low. */
667 if (level == 0) {
668 return;
669 }
670
671 /* Deliver the interrupt to each CPU, considering each CPU's IIC. */
672 for (i = 0; i < 4; ++i) {
ad601177
AF
673 AlphaCPU *cpu = s->cchip.cpu[i];
674 if (cpu != NULL) {
80bb2ff7
RH
675 uint32_t iic = s->cchip.iic[i];
676
677 /* ??? The verbage in Section 10.2.2.10 isn't 100% clear.
678 Bit 24 is the OverFlow bit, RO, and set when the count
679 decrements past 0. When is OF cleared? My guess is that
680 OF is actually cleared when the IIC is written, and that
681 the ICNT field always decrements. At least, that's an
682 interpretation that makes sense, and "allows the CPU to
683 determine exactly how mant interval timer ticks were
684 skipped". At least within the next 4M ticks... */
685
686 iic = ((iic - 1) & 0x1ffffff) | (iic & 0x1000000);
687 s->cchip.iic[i] = iic;
688
689 if (iic & 0x1000000) {
690 /* Set the ITI bit for this cpu. */
691 s->cchip.misc |= 1 << (i + 4);
692 /* And signal the interrupt. */
c3affe56 693 cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TIMER);
80bb2ff7
RH
694 }
695 }
696 }
697}
698
c781cf96
RH
699static void typhoon_alarm_timer(void *opaque)
700{
701 TyphoonState *s = (TyphoonState *)((uintptr_t)opaque & ~3);
702 int cpu = (uintptr_t)opaque & 3;
703
704 /* Set the ITI bit for this cpu. */
705 s->cchip.misc |= 1 << (cpu + 4);
c3affe56 706 cpu_interrupt(CPU(s->cchip.cpu[cpu]), CPU_INTERRUPT_TIMER);
c781cf96
RH
707}
708
71baa303
HP
709PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
710 qemu_irq *p_rtc_irq,
ad601177 711 AlphaCPU *cpus[4], pci_map_irq_fn sys_map_irq)
80bb2ff7
RH
712{
713 const uint64_t MB = 1024 * 1024;
714 const uint64_t GB = 1024 * MB;
715 MemoryRegion *addr_space = get_system_memory();
716 MemoryRegion *addr_space_io = get_system_io();
717 DeviceState *dev;
80bb2ff7 718 TyphoonState *s;
94dd91d6 719 PCIHostState *phb;
80bb2ff7 720 PCIBus *b;
c781cf96 721 int i;
80bb2ff7 722
94dd91d6 723 dev = qdev_create(NULL, TYPE_TYPHOON_PCI_HOST_BRIDGE);
80bb2ff7
RH
724 qdev_init_nofail(dev);
725
94dd91d6 726 s = TYPHOON_PCI_HOST_BRIDGE(dev);
8558d942 727 phb = PCI_HOST_BRIDGE(dev);
80bb2ff7
RH
728
729 /* Remember the CPUs so that we can deliver interrupts to them. */
c781cf96 730 for (i = 0; i < 4; i++) {
ad601177
AF
731 AlphaCPU *cpu = cpus[i];
732 s->cchip.cpu[i] = cpu;
733 if (cpu != NULL) {
c9245853 734 cpu->alarm_timer = qemu_new_timer_ns(rtc_clock,
c781cf96
RH
735 typhoon_alarm_timer,
736 (void *)((uintptr_t)s + i));
737 }
738 }
80bb2ff7
RH
739
740 *p_rtc_irq = *qemu_allocate_irqs(typhoon_set_timer_irq, s, 1);
741
742 /* Main memory region, 0x00.0000.0000. Real hardware supports 32GB,
743 but the address space hole reserved at this point is 8TB. */
2c9b15ca 744 memory_region_init_ram(&s->ram_region, NULL, "ram", ram_size);
c5705a77 745 vmstate_register_ram_global(&s->ram_region);
80bb2ff7
RH
746 memory_region_add_subregion(addr_space, 0, &s->ram_region);
747
748 /* TIGbus, 0x801.0000.0000, 1GB. */
749 /* ??? The TIGbus is used for delivering interrupts, and access to
750 the flash ROM. I'm not sure that we need to implement it at all. */
751
752 /* Pchip0 CSRs, 0x801.8000.0000, 256MB. */
2c9b15ca 753 memory_region_init_io(&s->pchip.region, NULL, &pchip_ops, s, "pchip0", 256*MB);
02d6516c
SW
754 memory_region_add_subregion(addr_space, 0x80180000000ULL,
755 &s->pchip.region);
80bb2ff7
RH
756
757 /* Cchip CSRs, 0x801.A000.0000, 256MB. */
2c9b15ca 758 memory_region_init_io(&s->cchip.region, NULL, &cchip_ops, s, "cchip0", 256*MB);
02d6516c
SW
759 memory_region_add_subregion(addr_space, 0x801a0000000ULL,
760 &s->cchip.region);
80bb2ff7
RH
761
762 /* Dchip CSRs, 0x801.B000.0000, 256MB. */
2c9b15ca 763 memory_region_init_io(&s->dchip_region, NULL, &dchip_ops, s, "dchip0", 256*MB);
02d6516c
SW
764 memory_region_add_subregion(addr_space, 0x801b0000000ULL,
765 &s->dchip_region);
80bb2ff7
RH
766
767 /* Pchip0 PCI memory, 0x800.0000.0000, 4GB. */
2c9b15ca 768 memory_region_init(&s->pchip.reg_mem, NULL, "pci0-mem", 4*GB);
02d6516c
SW
769 memory_region_add_subregion(addr_space, 0x80000000000ULL,
770 &s->pchip.reg_mem);
80bb2ff7
RH
771
772 /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB. */
773 /* ??? Ideally we drop the "system" i/o space on the floor and give the
774 PCI subsystem the full address space reserved by the chipset.
775 We can't do that until the MEM and IO paths in memory.c are unified. */
2c9b15ca 776 memory_region_init_io(&s->pchip.reg_io, NULL, &alpha_pci_bw_io_ops, NULL,
80bb2ff7 777 "pci0-io", 32*MB);
02d6516c
SW
778 memory_region_add_subregion(addr_space, 0x801fc000000ULL,
779 &s->pchip.reg_io);
80bb2ff7 780
94dd91d6 781 b = pci_register_bus(dev, "pci",
80bb2ff7 782 typhoon_set_irq, sys_map_irq, s,
60a0e443 783 &s->pchip.reg_mem, addr_space_io, 0, 64, TYPE_PCI_BUS);
94dd91d6 784 phb->bus = b;
80bb2ff7
RH
785
786 /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
2c9b15ca 787 memory_region_init_io(&s->pchip.reg_iack, NULL, &alpha_pci_iack_ops, b,
80bb2ff7 788 "pci0-iack", 64*MB);
02d6516c
SW
789 memory_region_add_subregion(addr_space, 0x801f8000000ULL,
790 &s->pchip.reg_iack);
80bb2ff7
RH
791
792 /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB. */
2c9b15ca 793 memory_region_init_io(&s->pchip.reg_conf, NULL, &alpha_pci_conf1_ops, b,
80bb2ff7 794 "pci0-conf", 16*MB);
02d6516c
SW
795 memory_region_add_subregion(addr_space, 0x801fe000000ULL,
796 &s->pchip.reg_conf);
80bb2ff7
RH
797
798 /* For the record, these are the mappings for the second PCI bus.
799 We can get away with not implementing them because we indicate
800 via the Cchip.CSC<PIP> bit that Pchip1 is not present. */
801 /* Pchip1 PCI memory, 0x802.0000.0000, 4GB. */
802 /* Pchip1 CSRs, 0x802.8000.0000, 256MB. */
803 /* Pchip1 PCI special/interrupt acknowledge, 0x802.F800.0000, 64MB. */
804 /* Pchip1 PCI I/O, 0x802.FC00.0000, 32MB. */
805 /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB. */
806
807 /* Init the ISA bus. */
808 /* ??? Technically there should be a cy82c693ub pci-isa bridge. */
809 {
810 qemu_irq isa_pci_irq, *isa_irqs;
811
71baa303 812 *isa_bus = isa_bus_new(NULL, addr_space_io);
80bb2ff7 813 isa_pci_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1);
71baa303
HP
814 isa_irqs = i8259_init(*isa_bus, isa_pci_irq);
815 isa_bus_irqs(*isa_bus, isa_irqs);
80bb2ff7
RH
816 }
817
818 return b;
819}
820
821static int typhoon_pcihost_init(SysBusDevice *dev)
822{
823 return 0;
824}
825
999e12bb
AL
826static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
827{
39bffca2 828 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb
AL
829 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
830
831 k->init = typhoon_pcihost_init;
39bffca2 832 dc->no_user = 1;
999e12bb
AL
833}
834
4240abff 835static const TypeInfo typhoon_pcihost_info = {
94dd91d6 836 .name = TYPE_TYPHOON_PCI_HOST_BRIDGE,
8558d942 837 .parent = TYPE_PCI_HOST_BRIDGE,
39bffca2
AL
838 .instance_size = sizeof(TyphoonState),
839 .class_init = typhoon_pcihost_class_init,
80bb2ff7
RH
840};
841
83f7d43a 842static void typhoon_register_types(void)
80bb2ff7 843{
39bffca2 844 type_register_static(&typhoon_pcihost_info);
80bb2ff7 845}
83f7d43a
AF
846
847type_init(typhoon_register_types)