Remove most uses of phys_ram_base (initial patch by Ian Jackson)
[qemu] / hw / arm_gic.c
1 /*
2  * ARM Generic/Distributed Interrupt Controller
3  *
4  * Copyright (c) 2006-2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licenced 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
14 //#define DEBUG_GIC
15
16 #ifdef DEBUG_GIC
17 #define DPRINTF(fmt, args...) \
18 do { printf("arm_gic: " fmt , ##args); } while (0)
19 #else
20 #define DPRINTF(fmt, args...) do {} while(0)
21 #endif
22
23 #ifdef NVIC
24 static const uint8_t gic_id[] =
25 { 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 };
26 #define GIC_DIST_OFFSET 0
27 /* The NVIC has 16 internal vectors.  However these are not exposed
28    through the normal GIC interface.  */
29 #define GIC_BASE_IRQ    32
30 #else
31 static const uint8_t gic_id[] =
32 { 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
33 #define GIC_DIST_OFFSET 0x1000
34 #define GIC_BASE_IRQ    0
35 #endif
36
37 typedef struct gic_irq_state
38 {
39     /* ??? The documentation seems to imply the enable bits are global, even
40        for per-cpu interrupts.  This seems strange.  */
41     unsigned enabled:1;
42     unsigned pending:NCPU;
43     unsigned active:NCPU;
44     unsigned level:1;
45     unsigned model:1; /* 0 = N:N, 1 = 1:N */
46     unsigned trigger:1; /* nonzero = edge triggered.  */
47 } gic_irq_state;
48
49 #define ALL_CPU_MASK ((1 << NCPU) - 1)
50
51 #define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1
52 #define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0
53 #define GIC_TEST_ENABLED(irq) s->irq_state[irq].enabled
54 #define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
55 #define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
56 #define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
57 #define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
58 #define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
59 #define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
60 #define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
61 #define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
62 #define GIC_TEST_MODEL(irq) s->irq_state[irq].model
63 #define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
64 #define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
65 #define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
66 #define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
67 #define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
68 #define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
69 #define GIC_GET_PRIORITY(irq, cpu) \
70   (((irq) < 32) ? s->priority1[irq][cpu] : s->priority2[(irq) - 32])
71 #ifdef NVIC
72 #define GIC_TARGET(irq) 1
73 #else
74 #define GIC_TARGET(irq) s->irq_target[irq]
75 #endif
76
77 typedef struct gic_state
78 {
79     uint32_t base;
80     qemu_irq parent_irq[NCPU];
81     int enabled;
82     int cpu_enabled[NCPU];
83
84     gic_irq_state irq_state[GIC_NIRQ];
85 #ifndef NVIC
86     int irq_target[GIC_NIRQ];
87 #endif
88     int priority1[32][NCPU];
89     int priority2[GIC_NIRQ - 32];
90     int last_active[GIC_NIRQ][NCPU];
91
92     int priority_mask[NCPU];
93     int running_irq[NCPU];
94     int running_priority[NCPU];
95     int current_pending[NCPU];
96
97     qemu_irq *in;
98 #ifdef NVIC
99     void *nvic;
100 #endif
101 } gic_state;
102
103 /* TODO: Many places that call this routine could be optimized.  */
104 /* Update interrupt status after enabled or pending bits have been changed.  */
105 static void gic_update(gic_state *s)
106 {
107     int best_irq;
108     int best_prio;
109     int irq;
110     int level;
111     int cpu;
112     int cm;
113
114     for (cpu = 0; cpu < NCPU; cpu++) {
115         cm = 1 << cpu;
116         s->current_pending[cpu] = 1023;
117         if (!s->enabled || !s->cpu_enabled[cpu]) {
118             qemu_irq_lower(s->parent_irq[cpu]);
119             return;
120         }
121         best_prio = 0x100;
122         best_irq = 1023;
123         for (irq = 0; irq < GIC_NIRQ; irq++) {
124             if (GIC_TEST_ENABLED(irq) && GIC_TEST_PENDING(irq, cm)) {
125                 if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
126                     best_prio = GIC_GET_PRIORITY(irq, cpu);
127                     best_irq = irq;
128                 }
129             }
130         }
131         level = 0;
132         if (best_prio <= s->priority_mask[cpu]) {
133             s->current_pending[cpu] = best_irq;
134             if (best_prio < s->running_priority[cpu]) {
135                 DPRINTF("Raised pending IRQ %d\n", best_irq);
136                 level = 1;
137             }
138         }
139         qemu_set_irq(s->parent_irq[cpu], level);
140     }
141 }
142
143 static void __attribute__((unused))
144 gic_set_pending_private(gic_state *s, int cpu, int irq)
145 {
146     int cm = 1 << cpu;
147
148     if (GIC_TEST_PENDING(irq, cm))
149         return;
150
151     DPRINTF("Set %d pending cpu %d\n", irq, cpu);
152     GIC_SET_PENDING(irq, cm);
153     gic_update(s);
154 }
155
156 /* Process a change in an external IRQ input.  */
157 static void gic_set_irq(void *opaque, int irq, int level)
158 {
159     gic_state *s = (gic_state *)opaque;
160     /* The first external input line is internal interrupt 32.  */
161     irq += 32;
162     if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK))
163         return;
164
165     if (level) {
166         GIC_SET_LEVEL(irq, ALL_CPU_MASK);
167         if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq)) {
168             DPRINTF("Set %d pending mask %x\n", irq, GIC_TARGET(irq));
169             GIC_SET_PENDING(irq, GIC_TARGET(irq));
170         }
171     } else {
172         GIC_CLEAR_LEVEL(irq, ALL_CPU_MASK);
173     }
174     gic_update(s);
175 }
176
177 static void gic_set_running_irq(gic_state *s, int cpu, int irq)
178 {
179     s->running_irq[cpu] = irq;
180     if (irq == 1023) {
181         s->running_priority[cpu] = 0x100;
182     } else {
183         s->running_priority[cpu] = GIC_GET_PRIORITY(irq, cpu);
184     }
185     gic_update(s);
186 }
187
188 static uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
189 {
190     int new_irq;
191     int cm = 1 << cpu;
192     new_irq = s->current_pending[cpu];
193     if (new_irq == 1023
194             || GIC_GET_PRIORITY(new_irq, cpu) >= s->running_priority[cpu]) {
195         DPRINTF("ACK no pending IRQ\n");
196         return 1023;
197     }
198     s->last_active[new_irq][cpu] = s->running_irq[cpu];
199     /* Clear pending flags for both level and edge triggered interrupts.
200        Level triggered IRQs will be reasserted once they become inactive.  */
201     GIC_CLEAR_PENDING(new_irq, GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm);
202     gic_set_running_irq(s, cpu, new_irq);
203     DPRINTF("ACK %d\n", new_irq);
204     return new_irq;
205 }
206
207 static void gic_complete_irq(gic_state * s, int cpu, int irq)
208 {
209     int update = 0;
210     int cm = 1 << cpu;
211     DPRINTF("EOI %d\n", irq);
212     if (s->running_irq[cpu] == 1023)
213         return; /* No active IRQ.  */
214     if (irq != 1023) {
215         /* Mark level triggered interrupts as pending if they are still
216            raised.  */
217         if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq)
218                 && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) != 0) {
219             DPRINTF("Set %d pending mask %x\n", irq, cm);
220             GIC_SET_PENDING(irq, cm);
221             update = 1;
222         }
223     }
224     if (irq != s->running_irq[cpu]) {
225         /* Complete an IRQ that is not currently running.  */
226         int tmp = s->running_irq[cpu];
227         while (s->last_active[tmp][cpu] != 1023) {
228             if (s->last_active[tmp][cpu] == irq) {
229                 s->last_active[tmp][cpu] = s->last_active[irq][cpu];
230                 break;
231             }
232             tmp = s->last_active[tmp][cpu];
233         }
234         if (update) {
235             gic_update(s);
236         }
237     } else {
238         /* Complete the current running IRQ.  */
239         gic_set_running_irq(s, cpu, s->last_active[s->running_irq[cpu]][cpu]);
240     }
241 }
242
243 static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
244 {
245     gic_state *s = (gic_state *)opaque;
246     uint32_t res;
247     int irq;
248     int i;
249     int cpu;
250     int cm;
251     int mask;
252
253     cpu = gic_get_current_cpu();
254     cm = 1 << cpu;
255     offset -= s->base + GIC_DIST_OFFSET;
256     if (offset < 0x100) {
257 #ifndef NVIC
258         if (offset == 0)
259             return s->enabled;
260         if (offset == 4)
261             return ((GIC_NIRQ / 32) - 1) | ((NCPU - 1) << 5);
262         if (offset < 0x08)
263             return 0;
264 #endif
265         goto bad_reg;
266     } else if (offset < 0x200) {
267         /* Interrupt Set/Clear Enable.  */
268         if (offset < 0x180)
269             irq = (offset - 0x100) * 8;
270         else
271             irq = (offset - 0x180) * 8;
272         irq += GIC_BASE_IRQ;
273         if (irq >= GIC_NIRQ)
274             goto bad_reg;
275         res = 0;
276         for (i = 0; i < 8; i++) {
277             if (GIC_TEST_ENABLED(irq + i)) {
278                 res |= (1 << i);
279             }
280         }
281     } else if (offset < 0x300) {
282         /* Interrupt Set/Clear Pending.  */
283         if (offset < 0x280)
284             irq = (offset - 0x200) * 8;
285         else
286             irq = (offset - 0x280) * 8;
287         irq += GIC_BASE_IRQ;
288         if (irq >= GIC_NIRQ)
289             goto bad_reg;
290         res = 0;
291         mask = (irq < 32) ?  cm : ALL_CPU_MASK;
292         for (i = 0; i < 8; i++) {
293             if (GIC_TEST_PENDING(irq + i, mask)) {
294                 res |= (1 << i);
295             }
296         }
297     } else if (offset < 0x400) {
298         /* Interrupt Active.  */
299         irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
300         if (irq >= GIC_NIRQ)
301             goto bad_reg;
302         res = 0;
303         mask = (irq < 32) ?  cm : ALL_CPU_MASK;
304         for (i = 0; i < 8; i++) {
305             if (GIC_TEST_ACTIVE(irq + i, mask)) {
306                 res |= (1 << i);
307             }
308         }
309     } else if (offset < 0x800) {
310         /* Interrupt Priority.  */
311         irq = (offset - 0x400) + GIC_BASE_IRQ;
312         if (irq >= GIC_NIRQ)
313             goto bad_reg;
314         res = GIC_GET_PRIORITY(irq, cpu);
315 #ifndef NVIC
316     } else if (offset < 0xc00) {
317         /* Interrupt CPU Target.  */
318         irq = (offset - 0x800) + GIC_BASE_IRQ;
319         if (irq >= GIC_NIRQ)
320             goto bad_reg;
321         if (irq >= 29 && irq <= 31) {
322             res = cm;
323         } else {
324             res = GIC_TARGET(irq);
325         }
326     } else if (offset < 0xf00) {
327         /* Interrupt Configuration.  */
328         irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
329         if (irq >= GIC_NIRQ)
330             goto bad_reg;
331         res = 0;
332         for (i = 0; i < 4; i++) {
333             if (GIC_TEST_MODEL(irq + i))
334                 res |= (1 << (i * 2));
335             if (GIC_TEST_TRIGGER(irq + i))
336                 res |= (2 << (i * 2));
337         }
338 #endif
339     } else if (offset < 0xfe0) {
340         goto bad_reg;
341     } else /* offset >= 0xfe0 */ {
342         if (offset & 3) {
343             res = 0;
344         } else {
345             res = gic_id[(offset - 0xfe0) >> 2];
346         }
347     }
348     return res;
349 bad_reg:
350     cpu_abort(cpu_single_env, "gic_dist_readb: Bad offset %x\n", (int)offset);
351     return 0;
352 }
353
354 static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
355 {
356     uint32_t val;
357     val = gic_dist_readb(opaque, offset);
358     val |= gic_dist_readb(opaque, offset + 1) << 8;
359     return val;
360 }
361
362 static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
363 {
364     uint32_t val;
365 #ifdef NVIC
366     gic_state *s = (gic_state *)opaque;
367     uint32_t addr;
368     addr = offset - s->base;
369     if (addr < 0x100 || addr > 0xd00)
370         return nvic_readl(s->nvic, addr);
371 #endif
372     val = gic_dist_readw(opaque, offset);
373     val |= gic_dist_readw(opaque, offset + 2) << 16;
374     return val;
375 }
376
377 static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
378                             uint32_t value)
379 {
380     gic_state *s = (gic_state *)opaque;
381     int irq;
382     int i;
383     int cpu;
384
385     cpu = gic_get_current_cpu();
386     offset -= s->base + GIC_DIST_OFFSET;
387     if (offset < 0x100) {
388 #ifdef NVIC
389         goto bad_reg;
390 #else
391         if (offset == 0) {
392             s->enabled = (value & 1);
393             DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
394         } else if (offset < 4) {
395             /* ignored.  */
396         } else {
397             goto bad_reg;
398         }
399 #endif
400     } else if (offset < 0x180) {
401         /* Interrupt Set Enable.  */
402         irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
403         if (irq >= GIC_NIRQ)
404             goto bad_reg;
405         if (irq < 16)
406           value = 0xff;
407         for (i = 0; i < 8; i++) {
408             if (value & (1 << i)) {
409                 int mask = (irq < 32) ? (1 << cpu) : GIC_TARGET(irq);
410                 if (!GIC_TEST_ENABLED(irq + i))
411                     DPRINTF("Enabled IRQ %d\n", irq + i);
412                 GIC_SET_ENABLED(irq + i);
413                 /* If a raised level triggered IRQ enabled then mark
414                    is as pending.  */
415                 if (GIC_TEST_LEVEL(irq + i, mask)
416                         && !GIC_TEST_TRIGGER(irq + i)) {
417                     DPRINTF("Set %d pending mask %x\n", irq + i, mask);
418                     GIC_SET_PENDING(irq + i, mask);
419                 }
420             }
421         }
422     } else if (offset < 0x200) {
423         /* Interrupt Clear Enable.  */
424         irq = (offset - 0x180) * 8 + GIC_BASE_IRQ;
425         if (irq >= GIC_NIRQ)
426             goto bad_reg;
427         if (irq < 16)
428           value = 0;
429         for (i = 0; i < 8; i++) {
430             if (value & (1 << i)) {
431                 if (GIC_TEST_ENABLED(irq + i))
432                     DPRINTF("Disabled IRQ %d\n", irq + i);
433                 GIC_CLEAR_ENABLED(irq + i);
434             }
435         }
436     } else if (offset < 0x280) {
437         /* Interrupt Set Pending.  */
438         irq = (offset - 0x200) * 8 + GIC_BASE_IRQ;
439         if (irq >= GIC_NIRQ)
440             goto bad_reg;
441         if (irq < 16)
442           irq = 0;
443
444         for (i = 0; i < 8; i++) {
445             if (value & (1 << i)) {
446                 GIC_SET_PENDING(irq + i, GIC_TARGET(irq));
447             }
448         }
449     } else if (offset < 0x300) {
450         /* Interrupt Clear Pending.  */
451         irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
452         if (irq >= GIC_NIRQ)
453             goto bad_reg;
454         for (i = 0; i < 8; i++) {
455             /* ??? This currently clears the pending bit for all CPUs, even
456                for per-CPU interrupts.  It's unclear whether this is the
457                corect behavior.  */
458             if (value & (1 << i)) {
459                 GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK);
460             }
461         }
462     } else if (offset < 0x400) {
463         /* Interrupt Active.  */
464         goto bad_reg;
465     } else if (offset < 0x800) {
466         /* Interrupt Priority.  */
467         irq = (offset - 0x400) + GIC_BASE_IRQ;
468         if (irq >= GIC_NIRQ)
469             goto bad_reg;
470         if (irq < 32) {
471             s->priority1[irq][cpu] = value;
472         } else {
473             s->priority2[irq - 32] = value;
474         }
475 #ifndef NVIC
476     } else if (offset < 0xc00) {
477         /* Interrupt CPU Target.  */
478         irq = (offset - 0x800) + GIC_BASE_IRQ;
479         if (irq >= GIC_NIRQ)
480             goto bad_reg;
481         if (irq < 29)
482             value = 0;
483         else if (irq < 32)
484             value = ALL_CPU_MASK;
485         s->irq_target[irq] = value & ALL_CPU_MASK;
486     } else if (offset < 0xf00) {
487         /* Interrupt Configuration.  */
488         irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
489         if (irq >= GIC_NIRQ)
490             goto bad_reg;
491         if (irq < 32)
492             value |= 0xaa;
493         for (i = 0; i < 4; i++) {
494             if (value & (1 << (i * 2))) {
495                 GIC_SET_MODEL(irq + i);
496             } else {
497                 GIC_CLEAR_MODEL(irq + i);
498             }
499             if (value & (2 << (i * 2))) {
500                 GIC_SET_TRIGGER(irq + i);
501             } else {
502                 GIC_CLEAR_TRIGGER(irq + i);
503             }
504         }
505 #endif
506     } else {
507         /* 0xf00 is only handled for 32-bit writes.  */
508         goto bad_reg;
509     }
510     gic_update(s);
511     return;
512 bad_reg:
513     cpu_abort(cpu_single_env, "gic_dist_writeb: Bad offset %x\n", (int)offset);
514 }
515
516 static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
517                             uint32_t value)
518 {
519     gic_dist_writeb(opaque, offset, value & 0xff);
520     gic_dist_writeb(opaque, offset + 1, value >> 8);
521 }
522
523 static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
524                             uint32_t value)
525 {
526     gic_state *s = (gic_state *)opaque;
527 #ifdef NVIC
528     uint32_t addr;
529     addr = offset - s->base;
530     if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
531         nvic_writel(s->nvic, addr, value);
532         return;
533     }
534 #endif
535     if (offset - s->base == GIC_DIST_OFFSET + 0xf00) {
536         int cpu;
537         int irq;
538         int mask;
539
540         cpu = gic_get_current_cpu();
541         irq = value & 0x3ff;
542         switch ((value >> 24) & 3) {
543         case 0:
544             mask = (value >> 16) & ALL_CPU_MASK;
545             break;
546         case 1:
547             mask = 1 << cpu;
548             break;
549         case 2:
550             mask = ALL_CPU_MASK ^ (1 << cpu);
551             break;
552         default:
553             DPRINTF("Bad Soft Int target filter\n");
554             mask = ALL_CPU_MASK;
555             break;
556         }
557         GIC_SET_PENDING(irq, mask);
558         gic_update(s);
559         return;
560     }
561     gic_dist_writew(opaque, offset, value & 0xffff);
562     gic_dist_writew(opaque, offset + 2, value >> 16);
563 }
564
565 static CPUReadMemoryFunc *gic_dist_readfn[] = {
566    gic_dist_readb,
567    gic_dist_readw,
568    gic_dist_readl
569 };
570
571 static CPUWriteMemoryFunc *gic_dist_writefn[] = {
572    gic_dist_writeb,
573    gic_dist_writew,
574    gic_dist_writel
575 };
576
577 #ifndef NVIC
578 static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
579 {
580     switch (offset) {
581     case 0x00: /* Control */
582         return s->cpu_enabled[cpu];
583     case 0x04: /* Priority mask */
584         return s->priority_mask[cpu];
585     case 0x08: /* Binary Point */
586         /* ??? Not implemented.  */
587         return 0;
588     case 0x0c: /* Acknowledge */
589         return gic_acknowledge_irq(s, cpu);
590     case 0x14: /* Runing Priority */
591         return s->running_priority[cpu];
592     case 0x18: /* Highest Pending Interrupt */
593         return s->current_pending[cpu];
594     default:
595         cpu_abort(cpu_single_env, "gic_cpu_read: Bad offset %x\n",
596                   (int)offset);
597         return 0;
598     }
599 }
600
601 static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
602 {
603     switch (offset) {
604     case 0x00: /* Control */
605         s->cpu_enabled[cpu] = (value & 1);
606         DPRINTF("CPU %sabled\n", s->cpu_enabled ? "En" : "Dis");
607         break;
608     case 0x04: /* Priority mask */
609         s->priority_mask[cpu] = (value & 0xff);
610         break;
611     case 0x08: /* Binary Point */
612         /* ??? Not implemented.  */
613         break;
614     case 0x10: /* End Of Interrupt */
615         return gic_complete_irq(s, cpu, value & 0x3ff);
616     default:
617         cpu_abort(cpu_single_env, "gic_cpu_write: Bad offset %x\n",
618                   (int)offset);
619         return;
620     }
621     gic_update(s);
622 }
623 #endif
624
625 static void gic_reset(gic_state *s)
626 {
627     int i;
628     memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
629     for (i = 0 ; i < NCPU; i++) {
630         s->priority_mask[i] = 0xf0;
631         s->current_pending[i] = 1023;
632         s->running_irq[i] = 1023;
633         s->running_priority[i] = 0x100;
634 #ifdef NVIC
635         /* The NVIC doesn't have per-cpu interfaces, so enable by default.  */
636         s->cpu_enabled[i] = 1;
637 #else
638         s->cpu_enabled[i] = 0;
639 #endif
640     }
641     for (i = 0; i < 16; i++) {
642         GIC_SET_ENABLED(i);
643         GIC_SET_TRIGGER(i);
644     }
645 #ifdef NVIC
646     /* The NVIC is always enabled.  */
647     s->enabled = 1;
648 #else
649     s->enabled = 0;
650 #endif
651 }
652
653 static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq)
654 {
655     gic_state *s;
656     int iomemtype;
657     int i;
658
659     s = (gic_state *)qemu_mallocz(sizeof(gic_state));
660     if (!s)
661         return NULL;
662     s->in = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
663     for (i = 0; i < NCPU; i++) {
664         s->parent_irq[i] = parent_irq[i];
665     }
666     iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
667                                        gic_dist_writefn, s);
668     cpu_register_physical_memory(base + GIC_DIST_OFFSET, 0x00001000,
669                                  iomemtype);
670     s->base = base;
671     gic_reset(s);
672     return s;
673 }