xref: /openbmc/qemu/hw/intc/arm_gic.c (revision b8bcf811)
1 /*
2  * ARM Generic/Distributed Interrupt Controller
3  *
4  * Copyright (c) 2006-2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the GPL.
8  */
9 
10 /* This file contains implementation code for the RealView EB interrupt
11  * controller, MPCore distributed interrupt controller and ARMv7-M
12  * Nested Vectored Interrupt Controller.
13  * It is compiled in two ways:
14  *  (1) as a standalone file to produce a sysbus device which is a GIC
15  *  that can be used on the realview board and as one of the builtin
16  *  private peripherals for the ARM MP CPUs (11MPCore, A9, etc)
17  *  (2) by being directly #included into armv7m_nvic.c to produce the
18  *  armv7m_nvic device.
19  */
20 
21 #include "hw/sysbus.h"
22 #include "gic_internal.h"
23 #include "qom/cpu.h"
24 
25 //#define DEBUG_GIC
26 
27 #ifdef DEBUG_GIC
28 #define DPRINTF(fmt, ...) \
29 do { fprintf(stderr, "arm_gic: " fmt , ## __VA_ARGS__); } while (0)
30 #else
31 #define DPRINTF(fmt, ...) do {} while(0)
32 #endif
33 
34 static const uint8_t gic_id[] = {
35     0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
36 };
37 
38 #define NUM_CPU(s) ((s)->num_cpu)
39 
40 static inline int gic_get_current_cpu(GICState *s)
41 {
42     if (s->num_cpu > 1) {
43         return current_cpu->cpu_index;
44     }
45     return 0;
46 }
47 
48 /* TODO: Many places that call this routine could be optimized.  */
49 /* Update interrupt status after enabled or pending bits have been changed.  */
50 void gic_update(GICState *s)
51 {
52     int best_irq;
53     int best_prio;
54     int irq;
55     int level;
56     int cpu;
57     int cm;
58 
59     for (cpu = 0; cpu < NUM_CPU(s); cpu++) {
60         cm = 1 << cpu;
61         s->current_pending[cpu] = 1023;
62         if (!s->enabled || !s->cpu_enabled[cpu]) {
63             qemu_irq_lower(s->parent_irq[cpu]);
64             return;
65         }
66         best_prio = 0x100;
67         best_irq = 1023;
68         for (irq = 0; irq < s->num_irq; irq++) {
69             if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm)) {
70                 if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
71                     best_prio = GIC_GET_PRIORITY(irq, cpu);
72                     best_irq = irq;
73                 }
74             }
75         }
76         level = 0;
77         if (best_prio < s->priority_mask[cpu]) {
78             s->current_pending[cpu] = best_irq;
79             if (best_prio < s->running_priority[cpu]) {
80                 DPRINTF("Raised pending IRQ %d (cpu %d)\n", best_irq, cpu);
81                 level = 1;
82             }
83         }
84         qemu_set_irq(s->parent_irq[cpu], level);
85     }
86 }
87 
88 void gic_set_pending_private(GICState *s, int cpu, int irq)
89 {
90     int cm = 1 << cpu;
91 
92     if (gic_test_pending(s, irq, cm)) {
93         return;
94     }
95 
96     DPRINTF("Set %d pending cpu %d\n", irq, cpu);
97     GIC_SET_PENDING(irq, cm);
98     gic_update(s);
99 }
100 
101 static void gic_set_irq_11mpcore(GICState *s, int irq, int level,
102                                  int cm, int target)
103 {
104     if (level) {
105         GIC_SET_LEVEL(irq, cm);
106         if (GIC_TEST_EDGE_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) {
107             DPRINTF("Set %d pending mask %x\n", irq, target);
108             GIC_SET_PENDING(irq, target);
109         }
110     } else {
111         GIC_CLEAR_LEVEL(irq, cm);
112     }
113 }
114 
115 static void gic_set_irq_generic(GICState *s, int irq, int level,
116                                 int cm, int target)
117 {
118     if (level) {
119         GIC_SET_LEVEL(irq, cm);
120         DPRINTF("Set %d pending mask %x\n", irq, target);
121         if (GIC_TEST_EDGE_TRIGGER(irq)) {
122             GIC_SET_PENDING(irq, target);
123         }
124     } else {
125         GIC_CLEAR_LEVEL(irq, cm);
126     }
127 }
128 
129 /* Process a change in an external IRQ input.  */
130 static void gic_set_irq(void *opaque, int irq, int level)
131 {
132     /* Meaning of the 'irq' parameter:
133      *  [0..N-1] : external interrupts
134      *  [N..N+31] : PPI (internal) interrupts for CPU 0
135      *  [N+32..N+63] : PPI (internal interrupts for CPU 1
136      *  ...
137      */
138     GICState *s = (GICState *)opaque;
139     int cm, target;
140     if (irq < (s->num_irq - GIC_INTERNAL)) {
141         /* The first external input line is internal interrupt 32.  */
142         cm = ALL_CPU_MASK;
143         irq += GIC_INTERNAL;
144         target = GIC_TARGET(irq);
145     } else {
146         int cpu;
147         irq -= (s->num_irq - GIC_INTERNAL);
148         cpu = irq / GIC_INTERNAL;
149         irq %= GIC_INTERNAL;
150         cm = 1 << cpu;
151         target = cm;
152     }
153 
154     assert(irq >= GIC_NR_SGIS);
155 
156     if (level == GIC_TEST_LEVEL(irq, cm)) {
157         return;
158     }
159 
160     if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
161         gic_set_irq_11mpcore(s, irq, level, cm, target);
162     } else {
163         gic_set_irq_generic(s, irq, level, cm, target);
164     }
165 
166     gic_update(s);
167 }
168 
169 static void gic_set_running_irq(GICState *s, int cpu, int irq)
170 {
171     s->running_irq[cpu] = irq;
172     if (irq == 1023) {
173         s->running_priority[cpu] = 0x100;
174     } else {
175         s->running_priority[cpu] = GIC_GET_PRIORITY(irq, cpu);
176     }
177     gic_update(s);
178 }
179 
180 uint32_t gic_acknowledge_irq(GICState *s, int cpu)
181 {
182     int ret, irq, src;
183     int cm = 1 << cpu;
184     irq = s->current_pending[cpu];
185     if (irq == 1023
186             || GIC_GET_PRIORITY(irq, cpu) >= s->running_priority[cpu]) {
187         DPRINTF("ACK no pending IRQ\n");
188         return 1023;
189     }
190     s->last_active[irq][cpu] = s->running_irq[cpu];
191 
192     if (s->revision == REV_11MPCORE) {
193         /* Clear pending flags for both level and edge triggered interrupts.
194          * Level triggered IRQs will be reasserted once they become inactive.
195          */
196         GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm);
197         ret = irq;
198     } else {
199         if (irq < GIC_NR_SGIS) {
200             /* Lookup the source CPU for the SGI and clear this in the
201              * sgi_pending map.  Return the src and clear the overall pending
202              * state on this CPU if the SGI is not pending from any CPUs.
203              */
204             assert(s->sgi_pending[irq][cpu] != 0);
205             src = ctz32(s->sgi_pending[irq][cpu]);
206             s->sgi_pending[irq][cpu] &= ~(1 << src);
207             if (s->sgi_pending[irq][cpu] == 0) {
208                 GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm);
209             }
210             ret = irq | ((src & 0x7) << 10);
211         } else {
212             /* Clear pending state for both level and edge triggered
213              * interrupts. (level triggered interrupts with an active line
214              * remain pending, see gic_test_pending)
215              */
216             GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm);
217             ret = irq;
218         }
219     }
220 
221     gic_set_running_irq(s, cpu, irq);
222     DPRINTF("ACK %d\n", irq);
223     return ret;
224 }
225 
226 void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val)
227 {
228     if (irq < GIC_INTERNAL) {
229         s->priority1[irq][cpu] = val;
230     } else {
231         s->priority2[(irq) - GIC_INTERNAL] = val;
232     }
233 }
234 
235 void gic_complete_irq(GICState *s, int cpu, int irq)
236 {
237     int update = 0;
238     int cm = 1 << cpu;
239     DPRINTF("EOI %d\n", irq);
240     if (irq >= s->num_irq) {
241         /* This handles two cases:
242          * 1. If software writes the ID of a spurious interrupt [ie 1023]
243          * to the GICC_EOIR, the GIC ignores that write.
244          * 2. If software writes the number of a non-existent interrupt
245          * this must be a subcase of "value written does not match the last
246          * valid interrupt value read from the Interrupt Acknowledge
247          * register" and so this is UNPREDICTABLE. We choose to ignore it.
248          */
249         return;
250     }
251     if (s->running_irq[cpu] == 1023)
252         return; /* No active IRQ.  */
253 
254     if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
255         /* Mark level triggered interrupts as pending if they are still
256            raised.  */
257         if (!GIC_TEST_EDGE_TRIGGER(irq) && GIC_TEST_ENABLED(irq, cm)
258             && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) != 0) {
259             DPRINTF("Set %d pending mask %x\n", irq, cm);
260             GIC_SET_PENDING(irq, cm);
261             update = 1;
262         }
263     }
264 
265     if (irq != s->running_irq[cpu]) {
266         /* Complete an IRQ that is not currently running.  */
267         int tmp = s->running_irq[cpu];
268         while (s->last_active[tmp][cpu] != 1023) {
269             if (s->last_active[tmp][cpu] == irq) {
270                 s->last_active[tmp][cpu] = s->last_active[irq][cpu];
271                 break;
272             }
273             tmp = s->last_active[tmp][cpu];
274         }
275         if (update) {
276             gic_update(s);
277         }
278     } else {
279         /* Complete the current running IRQ.  */
280         gic_set_running_irq(s, cpu, s->last_active[s->running_irq[cpu]][cpu]);
281     }
282 }
283 
284 static uint32_t gic_dist_readb(void *opaque, hwaddr offset)
285 {
286     GICState *s = (GICState *)opaque;
287     uint32_t res;
288     int irq;
289     int i;
290     int cpu;
291     int cm;
292     int mask;
293 
294     cpu = gic_get_current_cpu(s);
295     cm = 1 << cpu;
296     if (offset < 0x100) {
297         if (offset == 0)
298             return s->enabled;
299         if (offset == 4)
300             return ((s->num_irq / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
301         if (offset < 0x08)
302             return 0;
303         if (offset >= 0x80) {
304             /* Interrupt Security , RAZ/WI */
305             return 0;
306         }
307         goto bad_reg;
308     } else if (offset < 0x200) {
309         /* Interrupt Set/Clear Enable.  */
310         if (offset < 0x180)
311             irq = (offset - 0x100) * 8;
312         else
313             irq = (offset - 0x180) * 8;
314         irq += GIC_BASE_IRQ;
315         if (irq >= s->num_irq)
316             goto bad_reg;
317         res = 0;
318         for (i = 0; i < 8; i++) {
319             if (GIC_TEST_ENABLED(irq + i, cm)) {
320                 res |= (1 << i);
321             }
322         }
323     } else if (offset < 0x300) {
324         /* Interrupt Set/Clear Pending.  */
325         if (offset < 0x280)
326             irq = (offset - 0x200) * 8;
327         else
328             irq = (offset - 0x280) * 8;
329         irq += GIC_BASE_IRQ;
330         if (irq >= s->num_irq)
331             goto bad_reg;
332         res = 0;
333         mask = (irq < GIC_INTERNAL) ?  cm : ALL_CPU_MASK;
334         for (i = 0; i < 8; i++) {
335             if (gic_test_pending(s, irq + i, mask)) {
336                 res |= (1 << i);
337             }
338         }
339     } else if (offset < 0x400) {
340         /* Interrupt Active.  */
341         irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
342         if (irq >= s->num_irq)
343             goto bad_reg;
344         res = 0;
345         mask = (irq < GIC_INTERNAL) ?  cm : ALL_CPU_MASK;
346         for (i = 0; i < 8; i++) {
347             if (GIC_TEST_ACTIVE(irq + i, mask)) {
348                 res |= (1 << i);
349             }
350         }
351     } else if (offset < 0x800) {
352         /* Interrupt Priority.  */
353         irq = (offset - 0x400) + GIC_BASE_IRQ;
354         if (irq >= s->num_irq)
355             goto bad_reg;
356         res = GIC_GET_PRIORITY(irq, cpu);
357     } else if (offset < 0xc00) {
358         /* Interrupt CPU Target.  */
359         if (s->num_cpu == 1 && s->revision != REV_11MPCORE) {
360             /* For uniprocessor GICs these RAZ/WI */
361             res = 0;
362         } else {
363             irq = (offset - 0x800) + GIC_BASE_IRQ;
364             if (irq >= s->num_irq) {
365                 goto bad_reg;
366             }
367             if (irq >= 29 && irq <= 31) {
368                 res = cm;
369             } else {
370                 res = GIC_TARGET(irq);
371             }
372         }
373     } else if (offset < 0xf00) {
374         /* Interrupt Configuration.  */
375         irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
376         if (irq >= s->num_irq)
377             goto bad_reg;
378         res = 0;
379         for (i = 0; i < 4; i++) {
380             if (GIC_TEST_MODEL(irq + i))
381                 res |= (1 << (i * 2));
382             if (GIC_TEST_EDGE_TRIGGER(irq + i))
383                 res |= (2 << (i * 2));
384         }
385     } else if (offset < 0xf10) {
386         goto bad_reg;
387     } else if (offset < 0xf30) {
388         if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
389             goto bad_reg;
390         }
391 
392         if (offset < 0xf20) {
393             /* GICD_CPENDSGIRn */
394             irq = (offset - 0xf10);
395         } else {
396             irq = (offset - 0xf20);
397             /* GICD_SPENDSGIRn */
398         }
399 
400         res = s->sgi_pending[irq][cpu];
401     } else if (offset < 0xfe0) {
402         goto bad_reg;
403     } else /* offset >= 0xfe0 */ {
404         if (offset & 3) {
405             res = 0;
406         } else {
407             res = gic_id[(offset - 0xfe0) >> 2];
408         }
409     }
410     return res;
411 bad_reg:
412     qemu_log_mask(LOG_GUEST_ERROR,
413                   "gic_dist_readb: Bad offset %x\n", (int)offset);
414     return 0;
415 }
416 
417 static uint32_t gic_dist_readw(void *opaque, hwaddr offset)
418 {
419     uint32_t val;
420     val = gic_dist_readb(opaque, offset);
421     val |= gic_dist_readb(opaque, offset + 1) << 8;
422     return val;
423 }
424 
425 static uint32_t gic_dist_readl(void *opaque, hwaddr offset)
426 {
427     uint32_t val;
428     val = gic_dist_readw(opaque, offset);
429     val |= gic_dist_readw(opaque, offset + 2) << 16;
430     return val;
431 }
432 
433 static void gic_dist_writeb(void *opaque, hwaddr offset,
434                             uint32_t value)
435 {
436     GICState *s = (GICState *)opaque;
437     int irq;
438     int i;
439     int cpu;
440 
441     cpu = gic_get_current_cpu(s);
442     if (offset < 0x100) {
443         if (offset == 0) {
444             s->enabled = (value & 1);
445             DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
446         } else if (offset < 4) {
447             /* ignored.  */
448         } else if (offset >= 0x80) {
449             /* Interrupt Security Registers, RAZ/WI */
450         } else {
451             goto bad_reg;
452         }
453     } else if (offset < 0x180) {
454         /* Interrupt Set Enable.  */
455         irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
456         if (irq >= s->num_irq)
457             goto bad_reg;
458         if (irq < GIC_NR_SGIS) {
459             value = 0xff;
460         }
461 
462         for (i = 0; i < 8; i++) {
463             if (value & (1 << i)) {
464                 int mask =
465                     (irq < GIC_INTERNAL) ? (1 << cpu) : GIC_TARGET(irq + i);
466                 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
467 
468                 if (!GIC_TEST_ENABLED(irq + i, cm)) {
469                     DPRINTF("Enabled IRQ %d\n", irq + i);
470                 }
471                 GIC_SET_ENABLED(irq + i, cm);
472                 /* If a raised level triggered IRQ enabled then mark
473                    is as pending.  */
474                 if (GIC_TEST_LEVEL(irq + i, mask)
475                         && !GIC_TEST_EDGE_TRIGGER(irq + i)) {
476                     DPRINTF("Set %d pending mask %x\n", irq + i, mask);
477                     GIC_SET_PENDING(irq + i, mask);
478                 }
479             }
480         }
481     } else if (offset < 0x200) {
482         /* Interrupt Clear Enable.  */
483         irq = (offset - 0x180) * 8 + GIC_BASE_IRQ;
484         if (irq >= s->num_irq)
485             goto bad_reg;
486         if (irq < GIC_NR_SGIS) {
487             value = 0;
488         }
489 
490         for (i = 0; i < 8; i++) {
491             if (value & (1 << i)) {
492                 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
493 
494                 if (GIC_TEST_ENABLED(irq + i, cm)) {
495                     DPRINTF("Disabled IRQ %d\n", irq + i);
496                 }
497                 GIC_CLEAR_ENABLED(irq + i, cm);
498             }
499         }
500     } else if (offset < 0x280) {
501         /* Interrupt Set Pending.  */
502         irq = (offset - 0x200) * 8 + GIC_BASE_IRQ;
503         if (irq >= s->num_irq)
504             goto bad_reg;
505         if (irq < GIC_NR_SGIS) {
506             value = 0;
507         }
508 
509         for (i = 0; i < 8; i++) {
510             if (value & (1 << i)) {
511                 GIC_SET_PENDING(irq + i, GIC_TARGET(irq + i));
512             }
513         }
514     } else if (offset < 0x300) {
515         /* Interrupt Clear Pending.  */
516         irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
517         if (irq >= s->num_irq)
518             goto bad_reg;
519         if (irq < GIC_NR_SGIS) {
520             value = 0;
521         }
522 
523         for (i = 0; i < 8; i++) {
524             /* ??? This currently clears the pending bit for all CPUs, even
525                for per-CPU interrupts.  It's unclear whether this is the
526                corect behavior.  */
527             if (value & (1 << i)) {
528                 GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK);
529             }
530         }
531     } else if (offset < 0x400) {
532         /* Interrupt Active.  */
533         goto bad_reg;
534     } else if (offset < 0x800) {
535         /* Interrupt Priority.  */
536         irq = (offset - 0x400) + GIC_BASE_IRQ;
537         if (irq >= s->num_irq)
538             goto bad_reg;
539         gic_set_priority(s, cpu, irq, value);
540     } else if (offset < 0xc00) {
541         /* Interrupt CPU Target. RAZ/WI on uniprocessor GICs, with the
542          * annoying exception of the 11MPCore's GIC.
543          */
544         if (s->num_cpu != 1 || s->revision == REV_11MPCORE) {
545             irq = (offset - 0x800) + GIC_BASE_IRQ;
546             if (irq >= s->num_irq) {
547                 goto bad_reg;
548             }
549             if (irq < 29) {
550                 value = 0;
551             } else if (irq < GIC_INTERNAL) {
552                 value = ALL_CPU_MASK;
553             }
554             s->irq_target[irq] = value & ALL_CPU_MASK;
555         }
556     } else if (offset < 0xf00) {
557         /* Interrupt Configuration.  */
558         irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
559         if (irq >= s->num_irq)
560             goto bad_reg;
561         if (irq < GIC_INTERNAL)
562             value |= 0xaa;
563         for (i = 0; i < 4; i++) {
564             if (value & (1 << (i * 2))) {
565                 GIC_SET_MODEL(irq + i);
566             } else {
567                 GIC_CLEAR_MODEL(irq + i);
568             }
569             if (value & (2 << (i * 2))) {
570                 GIC_SET_EDGE_TRIGGER(irq + i);
571             } else {
572                 GIC_CLEAR_EDGE_TRIGGER(irq + i);
573             }
574         }
575     } else if (offset < 0xf10) {
576         /* 0xf00 is only handled for 32-bit writes.  */
577         goto bad_reg;
578     } else if (offset < 0xf20) {
579         /* GICD_CPENDSGIRn */
580         if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
581             goto bad_reg;
582         }
583         irq = (offset - 0xf10);
584 
585         s->sgi_pending[irq][cpu] &= ~value;
586         if (s->sgi_pending[irq][cpu] == 0) {
587             GIC_CLEAR_PENDING(irq, 1 << cpu);
588         }
589     } else if (offset < 0xf30) {
590         /* GICD_SPENDSGIRn */
591         if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
592             goto bad_reg;
593         }
594         irq = (offset - 0xf20);
595 
596         GIC_SET_PENDING(irq, 1 << cpu);
597         s->sgi_pending[irq][cpu] |= value;
598     } else {
599         goto bad_reg;
600     }
601     gic_update(s);
602     return;
603 bad_reg:
604     qemu_log_mask(LOG_GUEST_ERROR,
605                   "gic_dist_writeb: Bad offset %x\n", (int)offset);
606 }
607 
608 static void gic_dist_writew(void *opaque, hwaddr offset,
609                             uint32_t value)
610 {
611     gic_dist_writeb(opaque, offset, value & 0xff);
612     gic_dist_writeb(opaque, offset + 1, value >> 8);
613 }
614 
615 static void gic_dist_writel(void *opaque, hwaddr offset,
616                             uint32_t value)
617 {
618     GICState *s = (GICState *)opaque;
619     if (offset == 0xf00) {
620         int cpu;
621         int irq;
622         int mask;
623         int target_cpu;
624 
625         cpu = gic_get_current_cpu(s);
626         irq = value & 0x3ff;
627         switch ((value >> 24) & 3) {
628         case 0:
629             mask = (value >> 16) & ALL_CPU_MASK;
630             break;
631         case 1:
632             mask = ALL_CPU_MASK ^ (1 << cpu);
633             break;
634         case 2:
635             mask = 1 << cpu;
636             break;
637         default:
638             DPRINTF("Bad Soft Int target filter\n");
639             mask = ALL_CPU_MASK;
640             break;
641         }
642         GIC_SET_PENDING(irq, mask);
643         target_cpu = ctz32(mask);
644         while (target_cpu < GIC_NCPU) {
645             s->sgi_pending[irq][target_cpu] |= (1 << cpu);
646             mask &= ~(1 << target_cpu);
647             target_cpu = ctz32(mask);
648         }
649         gic_update(s);
650         return;
651     }
652     gic_dist_writew(opaque, offset, value & 0xffff);
653     gic_dist_writew(opaque, offset + 2, value >> 16);
654 }
655 
656 static const MemoryRegionOps gic_dist_ops = {
657     .old_mmio = {
658         .read = { gic_dist_readb, gic_dist_readw, gic_dist_readl, },
659         .write = { gic_dist_writeb, gic_dist_writew, gic_dist_writel, },
660     },
661     .endianness = DEVICE_NATIVE_ENDIAN,
662 };
663 
664 static uint32_t gic_cpu_read(GICState *s, int cpu, int offset)
665 {
666     switch (offset) {
667     case 0x00: /* Control */
668         return s->cpu_enabled[cpu];
669     case 0x04: /* Priority mask */
670         return s->priority_mask[cpu];
671     case 0x08: /* Binary Point */
672         return s->bpr[cpu];
673     case 0x0c: /* Acknowledge */
674         return gic_acknowledge_irq(s, cpu);
675     case 0x14: /* Running Priority */
676         return s->running_priority[cpu];
677     case 0x18: /* Highest Pending Interrupt */
678         return s->current_pending[cpu];
679     case 0x1c: /* Aliased Binary Point */
680         return s->abpr[cpu];
681     case 0xd0: case 0xd4: case 0xd8: case 0xdc:
682         return s->apr[(offset - 0xd0) / 4][cpu];
683     default:
684         qemu_log_mask(LOG_GUEST_ERROR,
685                       "gic_cpu_read: Bad offset %x\n", (int)offset);
686         return 0;
687     }
688 }
689 
690 static void gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value)
691 {
692     switch (offset) {
693     case 0x00: /* Control */
694         s->cpu_enabled[cpu] = (value & 1);
695         DPRINTF("CPU %d %sabled\n", cpu, s->cpu_enabled[cpu] ? "En" : "Dis");
696         break;
697     case 0x04: /* Priority mask */
698         s->priority_mask[cpu] = (value & 0xff);
699         break;
700     case 0x08: /* Binary Point */
701         s->bpr[cpu] = (value & 0x7);
702         break;
703     case 0x10: /* End Of Interrupt */
704         return gic_complete_irq(s, cpu, value & 0x3ff);
705     case 0x1c: /* Aliased Binary Point */
706         if (s->revision >= 2) {
707             s->abpr[cpu] = (value & 0x7);
708         }
709         break;
710     case 0xd0: case 0xd4: case 0xd8: case 0xdc:
711         qemu_log_mask(LOG_UNIMP, "Writing APR not implemented\n");
712         break;
713     default:
714         qemu_log_mask(LOG_GUEST_ERROR,
715                       "gic_cpu_write: Bad offset %x\n", (int)offset);
716         return;
717     }
718     gic_update(s);
719 }
720 
721 /* Wrappers to read/write the GIC CPU interface for the current CPU */
722 static uint64_t gic_thiscpu_read(void *opaque, hwaddr addr,
723                                  unsigned size)
724 {
725     GICState *s = (GICState *)opaque;
726     return gic_cpu_read(s, gic_get_current_cpu(s), addr);
727 }
728 
729 static void gic_thiscpu_write(void *opaque, hwaddr addr,
730                               uint64_t value, unsigned size)
731 {
732     GICState *s = (GICState *)opaque;
733     gic_cpu_write(s, gic_get_current_cpu(s), addr, value);
734 }
735 
736 /* Wrappers to read/write the GIC CPU interface for a specific CPU.
737  * These just decode the opaque pointer into GICState* + cpu id.
738  */
739 static uint64_t gic_do_cpu_read(void *opaque, hwaddr addr,
740                                 unsigned size)
741 {
742     GICState **backref = (GICState **)opaque;
743     GICState *s = *backref;
744     int id = (backref - s->backref);
745     return gic_cpu_read(s, id, addr);
746 }
747 
748 static void gic_do_cpu_write(void *opaque, hwaddr addr,
749                              uint64_t value, unsigned size)
750 {
751     GICState **backref = (GICState **)opaque;
752     GICState *s = *backref;
753     int id = (backref - s->backref);
754     gic_cpu_write(s, id, addr, value);
755 }
756 
757 static const MemoryRegionOps gic_thiscpu_ops = {
758     .read = gic_thiscpu_read,
759     .write = gic_thiscpu_write,
760     .endianness = DEVICE_NATIVE_ENDIAN,
761 };
762 
763 static const MemoryRegionOps gic_cpu_ops = {
764     .read = gic_do_cpu_read,
765     .write = gic_do_cpu_write,
766     .endianness = DEVICE_NATIVE_ENDIAN,
767 };
768 
769 void gic_init_irqs_and_distributor(GICState *s, int num_irq)
770 {
771     SysBusDevice *sbd = SYS_BUS_DEVICE(s);
772     int i;
773 
774     i = s->num_irq - GIC_INTERNAL;
775     /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
776      * GPIO array layout is thus:
777      *  [0..N-1] SPIs
778      *  [N..N+31] PPIs for CPU 0
779      *  [N+32..N+63] PPIs for CPU 1
780      *   ...
781      */
782     if (s->revision != REV_NVIC) {
783         i += (GIC_INTERNAL * s->num_cpu);
784     }
785     qdev_init_gpio_in(DEVICE(s), gic_set_irq, i);
786     for (i = 0; i < NUM_CPU(s); i++) {
787         sysbus_init_irq(sbd, &s->parent_irq[i]);
788     }
789     memory_region_init_io(&s->iomem, OBJECT(s), &gic_dist_ops, s,
790                           "gic_dist", 0x1000);
791 }
792 
793 static void arm_gic_realize(DeviceState *dev, Error **errp)
794 {
795     /* Device instance realize function for the GIC sysbus device */
796     int i;
797     GICState *s = ARM_GIC(dev);
798     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
799     ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
800 
801     agc->parent_realize(dev, errp);
802     if (error_is_set(errp)) {
803         return;
804     }
805 
806     gic_init_irqs_and_distributor(s, s->num_irq);
807 
808     /* Memory regions for the CPU interfaces (NVIC doesn't have these):
809      * a region for "CPU interface for this core", then a region for
810      * "CPU interface for core 0", "for core 1", ...
811      * NB that the memory region size of 0x100 applies for the 11MPCore
812      * and also cores following the GIC v1 spec (ie A9).
813      * GIC v2 defines a larger memory region (0x1000) so this will need
814      * to be extended when we implement A15.
815      */
816     memory_region_init_io(&s->cpuiomem[0], OBJECT(s), &gic_thiscpu_ops, s,
817                           "gic_cpu", 0x100);
818     for (i = 0; i < NUM_CPU(s); i++) {
819         s->backref[i] = s;
820         memory_region_init_io(&s->cpuiomem[i+1], OBJECT(s), &gic_cpu_ops,
821                               &s->backref[i], "gic_cpu", 0x100);
822     }
823     /* Distributor */
824     sysbus_init_mmio(sbd, &s->iomem);
825     /* cpu interfaces (one for "current cpu" plus one per cpu) */
826     for (i = 0; i <= NUM_CPU(s); i++) {
827         sysbus_init_mmio(sbd, &s->cpuiomem[i]);
828     }
829 }
830 
831 static void arm_gic_class_init(ObjectClass *klass, void *data)
832 {
833     DeviceClass *dc = DEVICE_CLASS(klass);
834     ARMGICClass *agc = ARM_GIC_CLASS(klass);
835 
836     agc->parent_realize = dc->realize;
837     dc->realize = arm_gic_realize;
838 }
839 
840 static const TypeInfo arm_gic_info = {
841     .name = TYPE_ARM_GIC,
842     .parent = TYPE_ARM_GIC_COMMON,
843     .instance_size = sizeof(GICState),
844     .class_init = arm_gic_class_init,
845     .class_size = sizeof(ARMGICClass),
846 };
847 
848 static void arm_gic_register_types(void)
849 {
850     type_register_static(&arm_gic_info);
851 }
852 
853 type_init(arm_gic_register_types)
854