1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "hw/sysbus.h"
23#include "gic_internal.h"
24#include "qapi/error.h"
25#include "qom/cpu.h"
26#include "qemu/log.h"
27#include "trace.h"
28
29#include "hw/fdt_generic_util.h"
30
31#include "hw/guest/linux.h"
32
33
34
35#ifdef DEBUG_GIC
36#define DPRINTF(fmt, ...) \
37do { fprintf(stderr, "arm_gic: " fmt , ## __VA_ARGS__); } while (0)
38#else
39#define DPRINTF(fmt, ...) do {} while(0)
40#endif
41
42#define IDLE_PRIORITY 0xff
43
44static const uint8_t gic_id_11mpcore[] = {
45 0x00, 0x00, 0x00, 0x00, 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
46};
47
48static const uint8_t gic_id_gicv1[] = {
49 0x04, 0x00, 0x00, 0x00, 0x90, 0xb3, 0x1b, 0x00, 0x0d, 0xf0, 0x05, 0xb1
50};
51
52static const uint8_t gic_id_gicv2[] = {
53 0x04, 0x00, 0x00, 0x00, 0x90, 0xb4, 0x2b, 0x00, 0x0d, 0xf0, 0x05, 0xb1
54};
55
56#define NUM_CPU(s) ((s)->num_cpu)
57
58#define GICH_LRN_STATE_INVALID 0
59#define GICH_LRN_STATE_PENDING 1
60#define GICH_LRN_STATE_ACTIVE 2
61
62static inline int gic_get_current_cpu(GICState *s)
63{
64 if (s->num_cpu > 1) {
65 return current_cpu->cpu_index % 4;
66 }
67 return 0;
68}
69
70#define GICH_LRN_STATE_INVALID 0
71#define GICH_LRN_STATE_PENDING 1
72#define GICH_LRN_STATE_ACTIVE 2
73static void gicv_update_cpu(GICState *s, int vcpu)
74{
75 int cpu = vcpu + GIC_N_REALCPU;
76 unsigned int i;
77 unsigned int best_prio = 0x100;
78 unsigned int best_irq = 1023;
79 unsigned int best_lrn = 0;
80 unsigned int allstate = 0;
81 int level = 0;
82 bool maint_irq;
83
84 s->current_pending[cpu] = 1023;
85 s->gich.pending_prio[vcpu] = 0x100;
86 s->gich.misr[vcpu] = 0;
87 s->gich.eisr[vcpu] = 0;
88 s->gich.elrsr[vcpu] = 0;
89
90 for (i = 0; i < ARRAY_SIZE(s->gich.lr[vcpu]); i++) {
91 unsigned int state;
92 unsigned int prio;
93 unsigned int vid;
94 unsigned int hw;
95 unsigned int eoi;
96
97 state = extract32(s->gich.lr[vcpu][i], 28, 2);
98 vid = extract32(s->gich.lr[vcpu][i], 0, 10);
99 prio = extract32(s->gich.lr[vcpu][i], 23, 6);
100 hw = extract32(s->gich.lr[vcpu][i], 31, 1);
101 eoi = extract32(s->gich.lr[vcpu][i], 19, 1);
102
103 if (state == 0 && hw == 0 && eoi) {
104 s->gich.eisr[vcpu] |= 1ULL << i;
105 }
106
107 if (state == 0 && (hw || !eoi)) {
108 s->gich.elrsr[vcpu] |= 1ULL << i;
109 }
110
111 allstate |= state;
112
113 if (!(state & GICH_LRN_STATE_PENDING)) {
114 continue;
115 }
116
117 if (prio < best_prio) {
118 best_prio = prio;
119 best_irq = vid;
120 best_lrn = i;
121 }
122 }
123
124 if (best_prio < s->priority_mask[cpu]) {
125
126 s->current_pending[cpu] = best_irq;
127 s->gich.pending_lrn[vcpu] = best_lrn;
128 s->gich.pending_prio[vcpu] = best_prio;
129 if (best_prio < s->running_priority[cpu]) {
130 level = 1;
131 }
132 }
133
134 s->gich.misr[vcpu] |= s->gich.eisr[vcpu] != 0;
135 s->gich.misr[vcpu] |= (allstate ? 0 : 1 << 1) & s->gich.hcr[vcpu];
136 s->gich.misr[vcpu] |= ((allstate & 1) << 3) & s->gich.hcr[vcpu];
137
138 level &= s->gich.hcr[vcpu] & 1;
139 assert(!(level && !(s->gicc_ctrl[cpu].enable_grp[1])));
140 qemu_set_irq(s->parent_irq[cpu], level);
141
142
143 maint_irq = s->gich.misr[vcpu] && (s->gich.hcr[vcpu] & 1);
144 if (maint_irq) {
145 qemu_log("gic maint-irq: VCPU=%d MISR=%x\n", vcpu, s->gich.misr[vcpu]);
146 }
147#if 0
148 qemu_set_irq(s->maint[vcpu], maint_irq);
149#endif
150}
151
152static void gicv_update(GICState *s)
153{
154 unsigned int i;
155
156 for (i = 0; i < s->num_cpu; i++) {
157 gicv_update_cpu(s, i);
158 }
159}
160
161
162
163void gic_update(GICState *s)
164{
165 int best_irq;
166 int best_prio;
167 int irq;
168 int level;
169 int cpu;
170 int cm;
171
172 for (cpu = 0; cpu < NUM_CPU(s); cpu++) {
173 bool cpu_irq = false;
174 bool cpu_fiq = false;
175 bool next_grp0;
176
177 cm = 1 << cpu;
178 s->current_pending[cpu] = 1023;
179 best_prio = 0x100;
180 best_irq = 1023;
181 for (irq = 0; irq < s->num_irq; irq++) {
182 if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
183 (irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
184 if (GIC_GET_PRIORITY(irq, cpu) < best_prio &&
185 !s->eoir[cpu][irq]) {
186 best_prio = GIC_GET_PRIORITY(irq, cpu);
187 best_irq = irq;
188 }
189 }
190 }
191 level = 0;
192 if (best_prio < s->priority_mask[cpu]) {
193 s->current_pending[cpu] = best_irq;
194 if (best_prio < s->running_priority[cpu]) {
195 DPRINTF("Raised pending IRQ %d (cpu %d)\n", best_irq, cpu);
196 level = 1;
197 }
198 }
199
200 next_grp0 = GIC_GROUP(best_irq) == 0;
201 if (level) {
202 if (next_grp0 && s->gicc_ctrl[cpu].fiq_en) {
203 if (s->gicc_ctrl[cpu].enable_grp[0]) {
204 cpu_fiq = true;
205 }
206 } else {
207 if ((next_grp0 && s->gicc_ctrl[cpu].enable_grp[0])
208 || (!next_grp0 && s->gicc_ctrl[cpu].enable_grp[1])) {
209 cpu_irq = true;
210 }
211 }
212 }
213 qemu_set_irq(s->parent_fiq[cpu], cpu_fiq);
214 qemu_set_irq(s->parent_irq[cpu], cpu_irq);
215 }
216 gicv_update(s);
217}
218
219void gic_set_pending_private(GICState *s, int cpu, int irq)
220{
221 int cm = 1 << cpu;
222
223 if (gic_test_pending(s, irq, cm)) {
224 return;
225 }
226
227 DPRINTF("Set %d pending cpu %d\n", irq, cpu);
228 GIC_SET_PENDING(irq, cm);
229 gic_update(s);
230}
231
232static void gic_set_irq_11mpcore(GICState *s, int irq, int level,
233 int cm, int target)
234{
235 if (level) {
236 GIC_SET_LEVEL(irq, cm);
237 if (GIC_TEST_EDGE_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) {
238 DPRINTF("Set %d pending mask %x\n", irq, target);
239 GIC_SET_PENDING(irq, target);
240 }
241 } else {
242 GIC_CLEAR_LEVEL(irq, cm);
243 }
244}
245
246static void gic_set_irq_generic(GICState *s, int irq, int level,
247 int cm, int target)
248{
249 if (level) {
250 GIC_SET_LEVEL(irq, cm);
251 DPRINTF("Set %d pending mask %x\n", irq, target);
252 if (GIC_TEST_EDGE_TRIGGER(irq)) {
253 GIC_SET_PENDING(irq, target);
254 }
255 } else {
256 GIC_CLEAR_LEVEL(irq, cm);
257 }
258}
259
260
261static void gic_set_irq(void *opaque, int irq, int level)
262{
263
264
265
266
267
268
269 GICState *s = (GICState *)opaque;
270 int cm, target;
271 if (irq < (s->num_irq - GIC_INTERNAL)) {
272
273 cm = ALL_CPU_MASK;
274 irq += GIC_INTERNAL;
275 target = GIC_TARGET(irq);
276 } else {
277 int cpu;
278 irq -= (s->num_irq - GIC_INTERNAL);
279 cpu = irq / GIC_INTERNAL;
280 irq %= GIC_INTERNAL;
281 cm = 1 << cpu;
282 target = cm;
283 }
284
285 assert(irq >= GIC_NR_SGIS);
286
287 if (level == GIC_TEST_LEVEL(irq, cm)) {
288 return;
289 }
290
291 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
292 gic_set_irq_11mpcore(s, irq, level, cm, target);
293 } else {
294 gic_set_irq_generic(s, irq, level, cm, target);
295 }
296
297 gic_update(s);
298}
299
300static void gic_set_irq_cb(void *opaque, int irq, int level)
301{
302 ARMGICClass *agc = ARM_GIC_GET_CLASS((Object *)opaque);
303
304 agc->irq_handler(opaque, irq, level);
305}
306
307static void gic_set_running_irq(GICState *s, int cpu, int irq)
308{
309 s->running_irq[cpu] = irq;
310 if (irq == 1023) {
311 s->running_priority[cpu] = 0x100;
312 } else {
313 s->running_priority[cpu] = GIC_GET_PRIORITY(irq, cpu);
314 }
315 gic_update(s);
316}
317
318static uint32_t gic_acknowledge_virq(GICState *s, int cpu)
319{
320 uint32_t t, cpuid;
321 int vcpu = cpu - GIC_N_REALCPU;
322
323 if (s->gich.pending_prio[vcpu] == 0x100) {
324 return 1023;
325 }
326 s->running_priority[cpu] = s->gich.pending_prio[vcpu];
327 s->running_irq[cpu] = s->current_pending[cpu];
328
329 t = s->gich.lr[vcpu][s->gich.pending_lrn[vcpu]];
330 s->gich.lr[vcpu][s->gich.pending_lrn[vcpu]] = deposit32(t, 28, 2, 2);
331 cpuid = extract32(t, 10, 3);
332
333 gicv_update(s);
334
335 s->gich.apr[vcpu] |= 1 << s->running_priority[cpu];
336 return s->running_irq[cpu] | (cpuid << 10);
337}
338
339uint32_t gic_acknowledge_irq(GICState *s, int cpu, bool secure)
340{
341 int ret, irq, src;
342 int cm = 1 << cpu;
343 bool is_grp0;
344
345 irq = s->current_pending[cpu];
346 is_grp0 = GIC_GROUP(irq) == 0;
347
348 if (irq == 1023
349 || GIC_GET_PRIORITY(irq, cpu) >= s->running_priority[cpu]) {
350 DPRINTF("ACK no pending IRQ\n");
351 return 1023;
352 }
353
354 if ((is_grp0 && !s->gicc_ctrl[cpu].enable_grp[0])
355 || (!is_grp0 && !s->gicc_ctrl[cpu].enable_grp[1])
356 || (is_grp0 && !secure)) {
357 return 1023;
358 }
359
360 if (!is_grp0 && secure && !s->gicc_ctrl[cpu].ack_ctl) {
361 return 1022;
362 }
363
364 s->last_active[irq][cpu] = s->running_irq[cpu];
365
366 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
367
368
369
370 GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm);
371 ret = irq;
372 } else {
373 if (irq < GIC_NR_SGIS) {
374
375
376
377
378 assert(s->sgi_pending[irq][cpu] != 0);
379 src = ctz32(s->sgi_pending[irq][cpu]);
380 s->sgi_pending[irq][cpu] &= ~(1 << src);
381 if (s->sgi_pending[irq][cpu] == 0) {
382 GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm);
383 }
384 ret = irq | ((src & 0x7) << 10);
385 } else {
386
387
388
389
390 GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm);
391 ret = irq;
392 }
393 }
394
395 gic_set_running_irq(s, cpu, irq);
396 DPRINTF("ACK %d\n", irq);
397 return ret;
398}
399
400void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val)
401{
402 if (irq < GIC_INTERNAL) {
403 s->priority1[irq][cpu] = val;
404 } else {
405 s->priority2[(irq) - GIC_INTERNAL] = val;
406 }
407}
408
409static void gic_complete_irq_force(GICState *s, int cpu, int irq, bool force, bool sec)
410{
411 int update = 0;
412 int cm = 1 << cpu;
413 bool eoirmode = s->gicc_ctrl[cpu].eoirmode_ns;
414
415 if (sec) {
416 eoirmode = s->gicc_ctrl[cpu].eoirmode;
417 }
418
419 if (force) {
420 s->eoir[cpu][irq] = false;
421 eoirmode = false;
422 }
423
424 if (irq >= s->num_irq) {
425
426
427
428
429
430
431
432
433 return;
434 }
435 if (s->running_irq[cpu] == 1023)
436 return;
437
438 if (eoirmode) {
439 s->eoir[cpu][irq] = true;
440 gic_set_running_irq(s, cpu, 1023);
441 gic_update(s);
442 return;
443 }
444
445 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
446
447
448 if (!GIC_TEST_EDGE_TRIGGER(irq) && GIC_TEST_ENABLED(irq, cm)
449 && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) != 0) {
450 DPRINTF("Set %d pending mask %x\n", irq, cm);
451 GIC_SET_PENDING(irq, cm);
452 update = 1;
453 }
454 }
455
456 if (irq != s->running_irq[cpu]) {
457
458 int tmp = s->running_irq[cpu];
459 while (s->last_active[tmp][cpu] != 1023) {
460 if (s->last_active[tmp][cpu] == irq) {
461 s->last_active[tmp][cpu] = s->last_active[irq][cpu];
462 break;
463 }
464 tmp = s->last_active[tmp][cpu];
465 }
466 if (update) {
467 gic_update(s);
468 }
469 } else {
470
471 gic_set_running_irq(s, cpu, s->last_active[s->running_irq[cpu]][cpu]);
472 }
473}
474
475void gic_complete_irq(GICState *s, int cpu, int irq, bool secure)
476{
477 gic_complete_irq_force(s, cpu, irq, false, secure);
478}
479
480static void gic_complete_virq(GICState *s, int cpu, int irq)
481{
482 int vcpu = cpu - GIC_N_REALCPU;
483 bool eoirmode = s->gicc_ctrl[cpu].eoirmode_ns;
484 unsigned int i;
485 unsigned int state;
486 unsigned int vid;
487 unsigned int pid;
488 unsigned int hw;
489
490 for (i = 0; i < ARRAY_SIZE(s->gich.lr[vcpu]); i++) {
491 state = extract32(s->gich.lr[vcpu][i], 28, 2);
492 if (state == GICH_LRN_STATE_INVALID) {
493 continue;
494 }
495
496 vid = extract32(s->gich.lr[vcpu][i], 0, 10);
497 pid = extract32(s->gich.lr[vcpu][i], 10, 10);
498 hw = extract32(s->gich.lr[vcpu][i], 31, 1);
499 if (vid == irq) {
500 break;
501 }
502 }
503
504 if (i == ARRAY_SIZE(s->gich.lr[vcpu])) {
505 s->running_priority[cpu] = 0x100;
506 s->running_irq[cpu] = 1023;
507 return;
508 }
509
510 if (eoirmode == 0) {
511
512 s->gich.lr[vcpu][i] = deposit32(s->gich.lr[vcpu][i], 29, 1, 0);
513 if (hw) {
514
515 gic_complete_irq_force(s, vcpu, pid, true, false);
516 }
517 } else {
518 qemu_log_mask(LOG_UNIMP, "gic: unimplemted CTLR.EOIRMODE = 1\n");
519 }
520 s->gich.apr[vcpu] &= ~(1 << s->running_priority[cpu]);
521 s->running_priority[cpu] = 0x100;
522 s->running_irq[cpu] = 1023;
523}
524
525static uint32_t gic_dist_readb(void *opaque, hwaddr offset, bool secure)
526{
527 GICState *s = (GICState *)opaque;
528 uint32_t res;
529 int irq;
530 int i;
531 int cpu;
532 int cm;
533 int mask;
534
535 cpu = gic_get_current_cpu(s);
536 cm = 1 << cpu;
537 if (offset < 0x100) {
538 if (offset == 0) {
539 if (secure) {
540 return (s->enabled << 1) | s->enabled_grp0;
541 } else {
542 return s->enabled;
543 }
544 }
545 if (offset == 4)
546 return ((s->num_irq / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
547 if (offset < 0x08)
548 return 0;
549 if (offset >= 0x80) {
550 if (secure && s->revision >= 2) {
551 unsigned int irq = (offset - 0x80) * 8;
552 res = 0;
553 for (i = 0; i < 8; i++) {
554 res |= s->irq_state[irq + i].group << i;
555 }
556 return res;
557 }
558
559 return 0;
560 }
561 goto bad_reg;
562 } else if (offset < 0x200) {
563
564 if (offset < 0x180)
565 irq = (offset - 0x100) * 8;
566 else
567 irq = (offset - 0x180) * 8;
568 irq += GIC_BASE_IRQ;
569 if (irq >= s->num_irq)
570 goto bad_reg;
571 res = 0;
572 for (i = 0; i < 8; i++) {
573 if (GIC_TEST_ENABLED(irq + i, cm)) {
574 res |= (1 << i);
575 }
576 }
577 } else if (offset < 0x300) {
578
579 if (offset < 0x280)
580 irq = (offset - 0x200) * 8;
581 else
582 irq = (offset - 0x280) * 8;
583 irq += GIC_BASE_IRQ;
584 if (irq >= s->num_irq)
585 goto bad_reg;
586 res = 0;
587 mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK;
588 for (i = 0; i < 8; i++) {
589 if (gic_test_pending(s, irq + i, mask)) {
590 res |= (1 << i);
591 }
592 }
593 } else if (offset < 0x400) {
594
595 irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
596 if (irq >= s->num_irq)
597 goto bad_reg;
598 res = 0;
599 mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK;
600 for (i = 0; i < 8; i++) {
601 if (GIC_TEST_ACTIVE(irq + i, mask)) {
602 res |= (1 << i);
603 }
604 }
605 } else if (offset < 0x800) {
606
607 irq = (offset - 0x400) + GIC_BASE_IRQ;
608 if (irq >= s->num_irq)
609 goto bad_reg;
610 res = GIC_GET_PRIORITY(irq, cpu);
611 } else if (offset < 0xc00) {
612
613 if (s->num_cpu == 1 && s->revision != REV_11MPCORE) {
614
615 res = 0;
616 } else {
617 irq = (offset - 0x800) + GIC_BASE_IRQ;
618 if (irq >= s->num_irq) {
619 goto bad_reg;
620 }
621 if (irq < GIC_INTERNAL) {
622 res = cm;
623 } else {
624 res = GIC_TARGET(irq);
625 }
626 }
627 } else if (offset < 0xf00) {
628
629 irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
630 if (irq >= s->num_irq)
631 goto bad_reg;
632 res = 0;
633 for (i = 0; i < 4; i++) {
634 if (GIC_TEST_MODEL(irq + i))
635 res |= (1 << (i * 2));
636 if (GIC_TEST_EDGE_TRIGGER(irq + i))
637 res |= (2 << (i * 2));
638 }
639 } else if (offset < 0xf10) {
640 goto bad_reg;
641 } else if (offset < 0xf30) {
642 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
643 goto bad_reg;
644 }
645
646 if (offset < 0xf20) {
647
648 irq = (offset - 0xf10);
649 } else {
650 irq = (offset - 0xf20);
651
652 }
653
654 res = s->sgi_pending[irq][cpu];
655 } else if (offset < 0xfd0) {
656 goto bad_reg;
657 } else if (offset < 0x1000) {
658 if (offset & 3) {
659 res = 0;
660 } else {
661 switch (s->revision) {
662 case REV_11MPCORE:
663 res = gic_id_11mpcore[(offset - 0xfd0) >> 2];
664 break;
665 case 1:
666 res = gic_id_gicv1[(offset - 0xfd0) >> 2];
667 break;
668 case 2:
669 res = gic_id_gicv2[(offset - 0xfd0) >> 2];
670 break;
671 case REV_NVIC:
672
673 abort();
674 default:
675 res = 0;
676 }
677 }
678 } else {
679 g_assert_not_reached();
680 }
681 return res;
682bad_reg:
683 qemu_log_mask(LOG_GUEST_ERROR,
684 "gic_dist_readb: Bad offset %x\n", (int)offset);
685 return 0;
686}
687
688static uint32_t gic_dist_readw(void *opaque, hwaddr offset, bool secure)
689{
690 uint32_t val;
691 val = gic_dist_readb(opaque, offset, secure);
692 val |= gic_dist_readb(opaque, offset + 1, secure) << 8;
693 return val;
694}
695
696static uint32_t gic_dist_readl(void *opaque, hwaddr offset, bool secure)
697{
698 uint32_t val;
699 val = gic_dist_readw(opaque, offset, secure);
700 val |= gic_dist_readw(opaque, offset + 2, secure) << 16;
701 return val;
702}
703
704static void gic_dist_writeb(void *opaque, hwaddr offset,
705 uint32_t value, bool secure)
706{
707 GICState *s = (GICState *)opaque;
708 int irq;
709 int i;
710 int cpu;
711
712 cpu = gic_get_current_cpu(s);
713 if (offset < 0x100) {
714 if (offset == 0) {
715 if (!secure) {
716 s->enabled = (value & 1);
717 } else {
718 s->enabled = (value & 2);
719 s->enabled_grp0 = (value & 1);
720 }
721 DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
722 } else if (offset < 4) {
723
724 } else if (offset >= 0x80) {
725 if (secure && s->revision >= 2) {
726 unsigned int irq = (offset - 0x80) * 8;
727 for (i = 0; i < 8; i++) {
728 s->irq_state[irq + i].group = value & (1 << i);
729 }
730 }
731 } else {
732 goto bad_reg;
733 }
734 } else if (offset < 0x180) {
735
736 irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
737 if (irq >= s->num_irq)
738 goto bad_reg;
739 if (irq < GIC_NR_SGIS) {
740 value = 0xff;
741 }
742
743 for (i = 0; i < 8; i++) {
744 if (value & (1 << i)) {
745 int mask =
746 (irq < GIC_INTERNAL) ? (1 << cpu) : GIC_TARGET(irq + i);
747 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
748
749 if (!s->irq_state[irq + i].group && !secure) {
750 continue;
751 }
752
753 if (!GIC_TEST_ENABLED(irq + i, cm)) {
754 DPRINTF("Enabled IRQ %d\n", irq + i);
755 }
756 GIC_SET_ENABLED(irq + i, cm);
757
758
759 if (GIC_TEST_LEVEL(irq + i, mask)
760 && !GIC_TEST_EDGE_TRIGGER(irq + i)) {
761 DPRINTF("Set %d pending mask %x\n", irq + i, mask);
762 GIC_SET_PENDING(irq + i, mask);
763 }
764 }
765 }
766 } else if (offset < 0x200) {
767
768 irq = (offset - 0x180) * 8 + GIC_BASE_IRQ;
769 if (irq >= s->num_irq)
770 goto bad_reg;
771 if (irq < GIC_NR_SGIS) {
772 value = 0;
773 }
774
775 for (i = 0; i < 8; i++) {
776 if (value & (1 << i)) {
777 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
778
779 if (!s->irq_state[irq + i].group && !secure) {
780 continue;
781 }
782
783 if (GIC_TEST_ENABLED(irq + i, cm)) {
784 DPRINTF("Disabled IRQ %d\n", irq + i);
785 }
786 GIC_CLEAR_ENABLED(irq + i, cm);
787 }
788 }
789 } else if (offset < 0x280) {
790
791 irq = (offset - 0x200) * 8 + GIC_BASE_IRQ;
792 qemu_log("pend irq=%d\n", irq);
793 if (irq >= s->num_irq)
794 goto bad_reg;
795 if (irq < GIC_NR_SGIS) {
796 value = 0;
797 }
798
799 for (i = 0; i < 8; i++) {
800 if (value & (1 << i)) {
801 GIC_SET_PENDING(irq + i, GIC_TARGET(irq + i));
802 }
803 }
804 } else if (offset < 0x300) {
805
806 irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
807 if (irq >= s->num_irq)
808 goto bad_reg;
809 if (irq < GIC_NR_SGIS) {
810 value = 0;
811 }
812
813 for (i = 0; i < 8; i++) {
814
815
816
817 if (value & (1 << i)) {
818 GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK);
819 }
820 }
821 } else if (offset < 0x400) {
822
823 goto bad_reg;
824 } else if (offset < 0x800) {
825
826 irq = (offset - 0x400) + GIC_BASE_IRQ;
827 if (irq >= s->num_irq)
828 goto bad_reg;
829 if (s->irq_state[irq].group || secure) {
830 gic_set_priority(s, cpu, irq, value);
831 }
832 } else if (offset < 0xc00) {
833
834
835
836 if (s->num_cpu != 1 || s->revision == REV_11MPCORE) {
837 irq = (offset - 0x800) + GIC_BASE_IRQ;
838 if (irq >= s->num_irq) {
839 goto bad_reg;
840 }
841 if (irq < 29) {
842 value = 0;
843 } else if (irq < GIC_INTERNAL) {
844 value = ALL_CPU_MASK;
845 }
846 if (s->irq_state[irq].group || secure) {
847 s->irq_target[irq] = value & ALL_CPU_MASK;
848 }
849 }
850 } else if (offset < 0xf00) {
851
852 irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
853 if (irq >= s->num_irq)
854 goto bad_reg;
855 if (irq < GIC_NR_SGIS)
856 value |= 0xaa;
857 for (i = 0; i < 4; i++) {
858 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
859 if (value & (1 << (i * 2))) {
860 GIC_SET_MODEL(irq + i);
861 } else {
862 GIC_CLEAR_MODEL(irq + i);
863 }
864 }
865 if (value & (2 << (i * 2))) {
866 GIC_SET_EDGE_TRIGGER(irq + i);
867 } else {
868 GIC_CLEAR_EDGE_TRIGGER(irq + i);
869 }
870 }
871 } else if (offset < 0xf10) {
872
873 goto bad_reg;
874 } else if (offset < 0xf20) {
875
876 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
877 goto bad_reg;
878 }
879 irq = (offset - 0xf10);
880
881 s->sgi_pending[irq][cpu] &= ~value;
882 if (s->sgi_pending[irq][cpu] == 0) {
883 GIC_CLEAR_PENDING(irq, 1 << cpu);
884 }
885 } else if (offset < 0xf30) {
886
887 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
888 goto bad_reg;
889 }
890 irq = (offset - 0xf20);
891
892 GIC_SET_PENDING(irq, 1 << cpu);
893 s->sgi_pending[irq][cpu] |= value;
894 } else {
895 goto bad_reg;
896 }
897 gic_update(s);
898 return;
899bad_reg:
900 qemu_log_mask(LOG_GUEST_ERROR,
901 "gic_dist_writeb: Bad offset %x\n", (int)offset);
902}
903
904static void gic_dist_writew(void *opaque, hwaddr offset,
905 uint32_t value, bool secure)
906{
907 gic_dist_writeb(opaque, offset, value & 0xff, secure);
908 gic_dist_writeb(opaque, offset + 1, value >> 8, secure);
909}
910
911static void gic_dist_writel(void *opaque, hwaddr offset,
912 uint32_t value, bool secure)
913{
914 GICState *s = (GICState *)opaque;
915 if (offset == 0xf00) {
916 int cpu;
917 int irq;
918 int mask;
919 int target_cpu;
920
921 cpu = gic_get_current_cpu(s);
922 irq = value & 0x3ff;
923 switch ((value >> 24) & 3) {
924 case 0:
925 mask = (value >> 16) & ALL_CPU_MASK;
926 break;
927 case 1:
928 mask = ALL_CPU_MASK ^ (1 << cpu);
929 break;
930 case 2:
931 mask = 1 << cpu;
932 break;
933 default:
934 DPRINTF("Bad Soft Int target filter\n");
935 mask = ALL_CPU_MASK;
936 break;
937 }
938 GIC_SET_PENDING(irq, mask);
939 target_cpu = ctz32(mask);
940 while (target_cpu < GIC_N_REALCPU) {
941 s->sgi_pending[irq][target_cpu] |= (1 << cpu);
942 mask &= ~(1 << target_cpu);
943 target_cpu = ctz32(mask);
944 }
945 gic_update(s);
946 return;
947 }
948 gic_dist_writew(opaque, offset, value & 0xffff, secure);
949 gic_dist_writew(opaque, offset + 2, value >> 16, secure);
950}
951
952static void gic_dist_access(MemoryTransaction *tr)
953{
954 bool sec = tr->attr.secure;
955 if (tr->rw) {
956 switch (tr->size) {
957 case 1:
958 gic_dist_writeb(tr->opaque, tr->addr, tr->data.u8, sec);
959 break;
960 case 2:
961 gic_dist_writew(tr->opaque, tr->addr, tr->data.u16, sec);
962 break;
963 case 4:
964 gic_dist_writel(tr->opaque, tr->addr, tr->data.u32, sec);
965 break;
966 }
967 } else {
968 switch (tr->size) {
969 case 1:
970 tr->data.u8 = gic_dist_readb(tr->opaque, tr->addr, sec);
971 break;
972 case 2:
973 tr->data.u16 = gic_dist_readw(tr->opaque, tr->addr, sec);
974 break;
975 case 4:
976 tr->data.u32 = gic_dist_readl(tr->opaque, tr->addr, sec);
977 break;
978 }
979 }
980#if 0
981 qemu_log("GIC sz=%d rw=%d addr=%lx data32=%x secure=%d\n",
982 tr->size, tr->rw, tr->addr, tr->data.u32, sec);
983#endif
984}
985
986static const MemoryRegionOps gic_dist_ops = {
987#if 1
988 .access = gic_dist_access,
989#else
990 .old_mmio = {
991 .read = { gic_dist_readb, gic_dist_readw, gic_dist_readl, },
992 .write = { gic_dist_writeb, gic_dist_writew, gic_dist_writel, },
993 },
994#endif
995 .endianness = DEVICE_NATIVE_ENDIAN,
996};
997
998#define GICC_ACK_CTL (1 << 2)
999#define GICC_FIQ_EN (1 << 3)
1000#define GICC_EOIRMODE (1 << 9)
1001#define GICC_EOIRMODE_NS (1 << 10)
1002static uint32_t gicc_encode_ctrl(GICState *s, int cpu, bool secure)
1003{
1004 uint32_t r;
1005
1006 if (secure) {
1007 r = s->gicc_ctrl[cpu].enable_grp[0];
1008 r |= s->gicc_ctrl[cpu].enable_grp[1] << 1;
1009 r |= s->gicc_ctrl[cpu].ack_ctl << 2;
1010 r |= s->gicc_ctrl[cpu].fiq_en << 3;
1011 r |= s->gicc_ctrl[cpu].eoirmode << 9;
1012 r |= s->gicc_ctrl[cpu].eoirmode_ns << 10;
1013 } else {
1014 r = s->gicc_ctrl[cpu].enable_grp[1];
1015 r |= s->gicc_ctrl[cpu].eoirmode_ns << 9;
1016 }
1017 return r;
1018}
1019
1020static void gicc_decode_ctrl(GICState *s, int cpu, bool secure, uint32_t v)
1021{
1022 if (secure) {
1023 s->gicc_ctrl[cpu].enable_grp[0] = v & 1;
1024 s->gicc_ctrl[cpu].enable_grp[1] = v & 2;
1025 s->gicc_ctrl[cpu].ack_ctl = v & GICC_ACK_CTL;
1026 s->gicc_ctrl[cpu].fiq_en = v & GICC_FIQ_EN;
1027 s->gicc_ctrl[cpu].eoirmode = v & GICC_EOIRMODE;
1028 s->gicc_ctrl[cpu].eoirmode_ns = v & GICC_EOIRMODE_NS;
1029 } else {
1030 s->gicc_ctrl[cpu].enable_grp[1] = v & 1;
1031 s->gicc_ctrl[cpu].eoirmode_ns = v & GICC_EOIRMODE;
1032 }
1033}
1034
1035static uint32_t gic_cpu_read(GICState *s, int cpu, int offset, bool secure)
1036{
1037 bool virt = cpu >= GIC_N_REALCPU;
1038
1039 switch (offset) {
1040 case 0x00:
1041 return gicc_encode_ctrl(s, cpu, secure);
1042 case 0x04:
1043 return s->priority_mask[cpu];
1044 case 0x08:
1045 return s->bpr[cpu];
1046 case 0x0c:
1047 if (virt) {
1048 return gic_acknowledge_virq(s, cpu);
1049 } else {
1050 return gic_acknowledge_irq(s, cpu, secure);
1051 }
1052 case 0x14:
1053 return s->running_priority[cpu] == 0x100 ?
1054 IDLE_PRIORITY : s->running_priority[cpu];
1055 case 0x18:
1056 return s->current_pending[cpu];
1057 case 0x1c:
1058 return s->abpr[cpu];
1059 case 0x20:
1060 hw_error("unsupported AIAR\n");
1061 break;
1062 case 0xd0: case 0xd4: case 0xd8: case 0xdc:
1063 return s->apr[(offset - 0xd0) / 4][cpu];
1064 case 0xFC:
1065 return s->c_iidr;
1066 default:
1067 qemu_log_mask(LOG_GUEST_ERROR,
1068 "gic_cpu_read: Bad offset %x\n", (int)offset);
1069 return 0;
1070 }
1071}
1072
1073static void gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value, bool secure)
1074{
1075 bool virt = cpu >= GIC_N_REALCPU;
1076
1077 switch (offset) {
1078 case 0x00:
1079 gicc_decode_ctrl(s, cpu, secure, value);
1080 s->ctrl[cpu] = gicc_encode_ctrl(s, cpu, true);
1081 break;
1082 case 0x04:
1083 s->priority_mask[cpu] = (value & 0xff);
1084 break;
1085 case 0x08:
1086 s->bpr[cpu] = (value & 0x7);
1087 break;
1088 case 0x10:
1089 if (virt) {
1090 gic_complete_virq(s, cpu, value & 0x3ff);
1091 } else {
1092 return gic_complete_irq(s, cpu, value & 0x3ff, secure);
1093 }
1094 break;
1095 case 0x1c:
1096 if (s->revision >= 2) {
1097 s->abpr[cpu] = (value & 0x7);
1098 }
1099 break;
1100 case 0xd0: case 0xd4: case 0xd8: case 0xdc:
1101 qemu_log_mask(LOG_UNIMP, "Writing APR not implemented\n");
1102 break;
1103 case 0x1000:
1104 case 0x10000:
1105 if (offset != s->map_stride) {
1106 qemu_log("Bad write to GIC 0x%x: Wrong GIC map stride?\n", offset);
1107 }
1108 if (virt) {
1109 qemu_log_mask(LOG_UNIMP, "Writing GICV_DIR not implemented\n");
1110 } else {
1111 return gic_complete_irq_force(s, cpu, value & 0x3ff, true, secure);
1112 }
1113 break;
1114 default:
1115 qemu_log_mask(LOG_GUEST_ERROR,
1116 "gic_cpu_write: Bad offset %x\n", (int)offset);
1117 return;
1118 }
1119 gic_update(s);
1120}
1121
1122static void thiscpu_access(MemoryTransaction *tr)
1123{
1124 GICState *s = (GICState *) tr->opaque;
1125 bool sec = tr->attr.secure;
1126
1127 if (tr->rw) {
1128 gic_cpu_write(s, gic_get_current_cpu(s), tr->addr, tr->data.u32, sec);
1129 } else {
1130 tr->data.u32 = gic_cpu_read(s, gic_get_current_cpu(s), tr->addr, sec);
1131 }
1132#ifdef DEBUG_GIC
1133 dump_memory_transaction(tr, stderr, __FILE__ ":");
1134#endif
1135}
1136
1137static void cpu_access(MemoryTransaction *tr)
1138{
1139 GICState **backref = (GICState **) tr->opaque;
1140 GICState *s = *backref;
1141 int id = (backref - s->backref);
1142 bool sec = tr->attr.secure;
1143
1144 if (tr->rw) {
1145 gic_cpu_write(s, id, tr->addr, tr->data.u32, sec);
1146 } else {
1147 tr->data.u32 = gic_cpu_read(s, id, tr->addr, sec);
1148 }
1149#ifdef DEBUG_GIC
1150 dump_memory_transaction(tr, stderr, __FILE__ ":");
1151#endif
1152}
1153
1154static uint32_t gic_hyp_vmcr_read(GICState *s, int vcpu)
1155{
1156 int cpu = vcpu + GIC_N_REALCPU;
1157 uint32_t r;
1158 uint32_t ctrl;
1159
1160 r = extract32(s->priority_mask[cpu], 3, 5) << 27;
1161 r |= extract32(s->bpr[cpu], 0, 3) << 21;
1162 r |= extract32(s->abpr[cpu], 0, 3) << 18;
1163
1164 ctrl = gicc_encode_ctrl(s, cpu, false);
1165 r |= extract32(ctrl, 0, 10);
1166 return r;
1167}
1168
1169static void gic_hyp_vmcr_write(GICState *s, int vcpu, uint32_t value)
1170{
1171 int cpu = vcpu + GIC_N_REALCPU;
1172 uint32_t primask = extract32(value, 27, 5);
1173 uint32_t bpr = extract32(value, 21, 3);
1174 uint32_t abpr = extract32(value, 18, 3);
1175 uint32_t ctrl = extract32(value, 0, 10);
1176
1177 s->priority_mask[cpu] = primask << 3;
1178 s->bpr[cpu] = bpr;
1179 s->abpr[cpu] = abpr;
1180 gicc_decode_ctrl(s, cpu, false, ctrl);
1181}
1182
1183static uint32_t gic_hyp_read(GICState *s, int vcpu, int offset)
1184{
1185 uint32_t r = 0;
1186
1187 switch (offset) {
1188 case 0x00:
1189 r = s->gich.hcr[vcpu];
1190 break;
1191 case 0x04:
1192
1193 r = 5 << 29 | 5 << 26 | (GICV_NR_LR - 1);
1194 break;
1195 case 0x08:
1196 r = gic_hyp_vmcr_read(s, vcpu);
1197 break;
1198 case 0x10:
1199 r = s->gich.misr[vcpu];
1200 break;
1201 case 0x20:
1202 r = s->gich.eisr[vcpu] & 0xffffffff;
1203 break;
1204 case 0x24:
1205 r = s->gich.eisr[vcpu] >> 32;
1206 break;
1207 case 0x30:
1208 r = s->gich.elrsr[vcpu] & 0xffffffff;
1209 break;
1210 case 0x34:
1211 r = s->gich.elrsr[vcpu] >> 32;
1212 break;
1213 case 0xf0:
1214 r = s->gich.apr[vcpu];
1215 break;
1216 case 0x100 ... 0x1fc:
1217 r = s->gich.lr[vcpu][(offset - 0x100) / 4];
1218 break;
1219 default:
1220 qemu_log_mask(LOG_GUEST_ERROR,
1221 "%s: Bad offset %x\n", __func__, offset);
1222 }
1223 return r;
1224}
1225
1226static void gic_hyp_write(GICState *s, int vcpu, int offset, uint32_t value)
1227{
1228 switch (offset) {
1229 case 0x00:
1230 s->gich.hcr[vcpu] = value;
1231 gicv_update(s);
1232 break;
1233 case 0x08:
1234 gic_hyp_vmcr_write(s, vcpu, value);
1235 gicv_update(s);
1236 break;
1237 case 0xf0:
1238 s->gich.apr[vcpu] = value;
1239 break;
1240 case 0x100 ... 0x1fc:
1241 if (s->gich.lr[vcpu][(offset - 0x100) / 4] != value) {
1242 s->gich.lr[vcpu][(offset - 0x100) / 4] = value;
1243 gicv_update(s);
1244 }
1245 break;
1246 default:
1247 qemu_log_mask(LOG_GUEST_ERROR,
1248 "%s: Bad offset %x\n", __func__, offset);
1249 return;
1250 }
1251}
1252
1253static uint64_t gic_do_hyp_read(void *opaque, hwaddr addr,
1254 unsigned size)
1255{
1256 GICState **backref = (GICState **)opaque;
1257 GICState *s = *backref;
1258 int id = backref - s->backref;
1259 uint64_t r;
1260
1261 r = gic_hyp_read(s, id, addr);
1262 return r;
1263}
1264
1265static void gic_do_hyp_write(void *opaque, hwaddr addr,
1266 uint64_t value, unsigned size)
1267{
1268 GICState **backref = (GICState **)opaque;
1269 GICState *s = *backref;
1270 int id = backref - s->backref;
1271
1272 gic_hyp_write(s, id, addr, value);
1273}
1274
1275static uint64_t gic_thishyp_read(void *opaque, hwaddr addr,
1276 unsigned size)
1277{
1278 GICState *s = (GICState *)opaque;
1279 int id = gic_get_current_cpu(s);
1280 uint64_t r;
1281
1282 r = gic_hyp_read(s, id, addr);
1283 return r;
1284}
1285
1286static void gic_thishyp_write(void *opaque, hwaddr addr,
1287 uint64_t value, unsigned size)
1288{
1289 GICState *s = (GICState *)opaque;
1290 int id = gic_get_current_cpu(s);
1291
1292 gic_hyp_write(s, id, addr, value);
1293}
1294
1295
1296static uint64_t gic_thisvcpu_read(void *opaque, hwaddr addr,
1297 unsigned size)
1298{
1299 GICState *s = (GICState *)opaque;
1300 int id = GIC_N_REALCPU + gic_get_current_cpu(s);
1301 uint64_t r;
1302
1303 r = gic_cpu_read(s, id, addr, false);
1304 return r;
1305}
1306
1307static void gic_thisvcpu_write(void *opaque, hwaddr addr,
1308 uint64_t value, unsigned size)
1309{
1310 GICState *s = (GICState *)opaque;
1311 int id = GIC_N_REALCPU + gic_get_current_cpu(s);
1312
1313 gic_cpu_write(s, id, addr, value, false);
1314}
1315
1316static const MemoryRegionOps gic_thiscpu_ops = {
1317#if 1
1318 .access = thiscpu_access,
1319#else
1320 .read = gic_thiscpu_read,
1321 .write = gic_thiscpu_write,
1322 .endianness = DEVICE_NATIVE_ENDIAN,
1323#endif
1324};
1325
1326static const MemoryRegionOps gic_cpu_ops = {
1327#if 1
1328 .access = cpu_access,
1329#else
1330 .read = gic_do_cpu_read,
1331 .write = gic_do_cpu_write,
1332 .endianness = DEVICE_NATIVE_ENDIAN,
1333#endif
1334};
1335
1336static const MemoryRegionOps gic_thishyp_ops = {
1337 .read = gic_thishyp_read,
1338 .write = gic_thishyp_write,
1339 .endianness = DEVICE_NATIVE_ENDIAN,
1340};
1341
1342static const MemoryRegionOps gic_hyp_ops = {
1343 .read = gic_do_hyp_read,
1344 .write = gic_do_hyp_write,
1345 .endianness = DEVICE_NATIVE_ENDIAN,
1346};
1347
1348static const MemoryRegionOps gic_thisvcpu_ops = {
1349 .read = gic_thisvcpu_read,
1350 .write = gic_thisvcpu_write,
1351 .endianness = DEVICE_NATIVE_ENDIAN,
1352};
1353
1354void gic_init_irqs_and_distributor(GICState *s)
1355{
1356 SysBusDevice *sbd = SYS_BUS_DEVICE(s);
1357 int i;
1358
1359 i = s->num_irq - GIC_INTERNAL;
1360
1361
1362
1363
1364
1365
1366
1367 if (s->revision != REV_NVIC) {
1368 i += (GIC_INTERNAL * s->num_cpu);
1369 }
1370 qdev_init_gpio_in(DEVICE(s), gic_set_irq_cb, i);
1371 for (i = 0; i < GIC_N_REALCPU; i++) {
1372 sysbus_init_irq(sbd, &s->parent_irq[i]);
1373 }
1374 for (i = 0; i < GIC_N_REALCPU; i++) {
1375 sysbus_init_irq(sbd, &s->parent_irq[GIC_N_REALCPU + i]);
1376 }
1377 for (i = 0; i < GIC_N_REALCPU; i++) {
1378 sysbus_init_irq(sbd, &s->parent_fiq[i]);
1379 }
1380 for (i = 0; i < GIC_N_REALCPU; i++) {
1381 sysbus_init_irq(sbd, &s->parent_fiq[GIC_N_REALCPU + i]);
1382 }
1383 for (i = 0; i < NUM_CPU(s); i++) {
1384 sysbus_init_irq(sbd, &s->maint[i]);
1385 }
1386 qdev_init_gpio_out_named(DEVICE(s), s->parent_irq, "irq", GIC_N_REALCPU * 2);
1387 qdev_init_gpio_out_named(DEVICE(s), s->parent_fiq, "fiq", GIC_N_REALCPU * 2);
1388 qdev_init_gpio_out_named(DEVICE(s), s->maint, "maint", NUM_CPU(s));
1389 memory_region_init_io(&s->iomem, OBJECT(s), &gic_dist_ops, s,
1390 "gic_dist", 0x1000);
1391}
1392
1393static void arm_gic_realize(DeviceState *dev, Error **errp)
1394{
1395
1396 int i;
1397 GICState *s = ARM_GIC(dev);
1398 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1399 ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
1400 Error *local_err = NULL;
1401
1402 agc->parent_realize(dev, &local_err);
1403 if (local_err) {
1404 error_propagate(errp, local_err);
1405 return;
1406 }
1407
1408 gic_init_irqs_and_distributor(s);
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418 memory_region_init_io(&s->cpuiomem[0], OBJECT(s), &gic_thiscpu_ops, s,
1419 "gic_cpu", s->revision >= 2 ? s->map_stride * 2 : 0x100);
1420#if 0
1421 for (i = 0; i < NUM_CPU(s); i++) {
1422 char *region_name = g_strdup_printf("gic_cpu-%d", i);
1423 s->backref[i] = s;
1424 memory_region_init_io(&s->cpuiomem[i+1], OBJECT(s), &gic_cpu_ops,
1425 &s->backref[i], region_name, 0x100);
1426 g_free(region_name);
1427 }
1428#endif
1429 memory_region_init_io(&s->hypiomem[0], OBJECT(s), &gic_thishyp_ops, s,
1430 "gic_thishyp_cpu", 0x200);
1431 memory_region_init_io(&s->vcpuiomem, OBJECT(s), &gic_thisvcpu_ops, s,
1432 "gic_thisvcpu",
1433 s->revision >= 2 ? s->map_stride * 2 : 0x2000);
1434 for (i = 0; i < NUM_CPU(s); i++) {
1435 char *region_name = g_strdup_printf("gic_hyp_cpu-%d", i);
1436 s->backref[GIC_N_REALCPU + i] = s;
1437 memory_region_init_io(&s->hypiomem[i+1], OBJECT(s), &gic_hyp_ops,
1438 &s->backref[i], region_name, 0x200);
1439 g_free(region_name);
1440 }
1441
1442 sysbus_init_mmio(sbd, &s->iomem);
1443
1444 sysbus_init_mmio(sbd, &s->cpuiomem[0]);
1445#if 0
1446 for (i = 1; i <= NUM_CPU(s); i++) {
1447 sysbus_init_mmio(sbd, &s->cpuiomem[i]);
1448 }
1449#endif
1450 sysbus_init_mmio(sbd, &s->hypiomem[0]);
1451 sysbus_init_mmio(sbd, &s->vcpuiomem);
1452#if 0
1453
1454
1455
1456 for (i = 0; i <= NUM_CPU(s); i++) {
1457 sysbus_init_mmio(sbd, &s->hypiomem[i]);
1458 }
1459#endif
1460}
1461
1462static void arm_gic_fdt_auto_parent(FDTGenericIntc *obj, Error **errp)
1463{
1464 GICState *s = ARM_GIC(obj);
1465 CPUState *cs;
1466 int i = 0;
1467
1468 for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
1469 if (i >= s->num_cpu) {
1470 break;
1471 }
1472 qdev_connect_gpio_out_named(DEVICE(obj), "irq", i,
1473 qdev_get_gpio_in(DEVICE(cs), 0));
1474 i++;
1475 }
1476
1477
1478}
1479
1480static const FDTGenericGPIOSet arm_gic_client_gpios [] = {
1481 {
1482 .names = &fdt_generic_gpio_name_set_interrupts,
1483 .gpios = (FDTGenericGPIOConnection []) {
1484 { .name = "irq", .range = 16 },
1485 { .name = "fiq", .range = 16, .fdt_index = 16 },
1486 { .name = "maint", .range = 4, .fdt_index = 32 },
1487 { },
1488 },
1489 },
1490 {
1491 .names = &fdt_generic_gpio_name_set_gpio,
1492 .gpios = (FDTGenericGPIOConnection []) {
1493 { .name = "pwr_cntrl", .range = 1, .fdt_index = 0 },
1494 { .name = "rst_cntrl", .range = 1, .fdt_index = 1 },
1495 { },
1496 },
1497 },
1498 { },
1499};
1500
1501static void arm_gic_linux_init(LinuxDevice *obj)
1502{
1503 GICState *s = ARM_GIC(obj);
1504 int i;
1505
1506 if (s->disable_linux_gic_init) {
1507 return;
1508 }
1509
1510 for (i = 0 ; i < s->num_irq; ++i) {
1511 s->irq_state[i].group = 1;
1512 }
1513}
1514
1515static void arm_gic_class_init(ObjectClass *klass, void *data)
1516{
1517 DeviceClass *dc = DEVICE_CLASS(klass);
1518 ARMGICClass *agc = ARM_GIC_CLASS(klass);
1519 FDTGenericIntcClass *fgic = FDT_GENERIC_INTC_CLASS(klass);
1520 FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
1521 LinuxDeviceClass *ldc = LINUX_DEVICE_CLASS(klass);
1522
1523 agc->irq_handler = gic_set_irq;
1524 agc->parent_realize = dc->realize;
1525 dc->realize = arm_gic_realize;
1526 fgic->auto_parent = arm_gic_fdt_auto_parent;
1527 fggc->client_gpios = arm_gic_client_gpios;
1528 ldc->linux_init = arm_gic_linux_init;
1529}
1530
1531static const TypeInfo arm_gic_info = {
1532 .name = TYPE_ARM_GIC,
1533 .parent = TYPE_ARM_GIC_COMMON,
1534 .instance_size = sizeof(GICState),
1535 .class_init = arm_gic_class_init,
1536 .class_size = sizeof(ARMGICClass),
1537 .interfaces = (InterfaceInfo []) {
1538 { TYPE_LINUX_DEVICE },
1539 { },
1540 }
1541};
1542
1543static void arm_gic_register_types(void)
1544{
1545 type_register_static(&arm_gic_info);
1546}
1547
1548type_init(arm_gic_register_types)
1549