]> git.proxmox.com Git - qemu.git/blame - hw/arm_gic.c
hw/arm_gic: Expose PPI inputs as gpio inputs
[qemu.git] / hw / arm_gic.c
CommitLineData
5fafdf24 1/*
9ee6e8bb 2 * ARM Generic/Distributed Interrupt Controller
e69954b9 3 *
9ee6e8bb 4 * Copyright (c) 2006-2007 CodeSourcery.
e69954b9
PB
5 * Written by Paul Brook
6 *
8e31bf38 7 * This code is licensed under the GPL.
e69954b9
PB
8 */
9
9ee6e8bb
PB
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. */
e69954b9 13
a32134aa
ML
14/* Maximum number of possible interrupts, determined by the GIC architecture */
15#define GIC_MAXIRQ 1020
69253800
RR
16/* First 32 are private to each CPU (SGIs and PPIs). */
17#define GIC_INTERNAL 32
386e2955
PM
18/* Maximum number of possible CPU interfaces, determined by GIC architecture */
19#ifdef NVIC
20#define NCPU 1
21#else
22#define NCPU 8
23#endif
24
e69954b9
PB
25//#define DEBUG_GIC
26
27#ifdef DEBUG_GIC
001faf32
BS
28#define DPRINTF(fmt, ...) \
29do { printf("arm_gic: " fmt , ## __VA_ARGS__); } while (0)
e69954b9 30#else
001faf32 31#define DPRINTF(fmt, ...) do {} while(0)
e69954b9
PB
32#endif
33
9ee6e8bb
PB
34#ifdef NVIC
35static const uint8_t gic_id[] =
36{ 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 };
9ee6e8bb
PB
37/* The NVIC has 16 internal vectors. However these are not exposed
38 through the normal GIC interface. */
39#define GIC_BASE_IRQ 32
40#else
e69954b9
PB
41static const uint8_t gic_id[] =
42{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
9ee6e8bb
PB
43#define GIC_BASE_IRQ 0
44#endif
e69954b9 45
fe7e8758
PB
46#define FROM_SYSBUSGIC(type, dev) \
47 DO_UPCAST(type, gic, FROM_SYSBUS(gic_state, dev))
48
e69954b9
PB
49typedef struct gic_irq_state
50{
41bf234d
RV
51 /* The enable bits are only banked for per-cpu interrupts. */
52 unsigned enabled:NCPU;
9ee6e8bb
PB
53 unsigned pending:NCPU;
54 unsigned active:NCPU;
a45db6c6 55 unsigned level:NCPU;
9ee6e8bb 56 unsigned model:1; /* 0 = N:N, 1 = 1:N */
e69954b9
PB
57 unsigned trigger:1; /* nonzero = edge triggered. */
58} gic_irq_state;
59
386e2955 60#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
c988bfad
PB
61#if NCPU > 1
62#define NUM_CPU(s) ((s)->num_cpu)
63#else
64#define NUM_CPU(s) 1
65#endif
9ee6e8bb 66
41bf234d
RV
67#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm)
68#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm)
69#define GIC_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm)) != 0)
9ee6e8bb
PB
70#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
71#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
72#define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
73#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
74#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
75#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
e69954b9
PB
76#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
77#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
78#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
9ee6e8bb
PB
79#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
80#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
57d69a91 81#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
e69954b9
PB
82#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
83#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
84#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
69253800
RR
85#define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ? \
86 s->priority1[irq][cpu] : \
87 s->priority2[(irq) - GIC_INTERNAL])
9ee6e8bb
PB
88#ifdef NVIC
89#define GIC_TARGET(irq) 1
90#else
91#define GIC_TARGET(irq) s->irq_target[irq]
92#endif
e69954b9
PB
93
94typedef struct gic_state
95{
fe7e8758 96 SysBusDevice busdev;
9ee6e8bb 97 qemu_irq parent_irq[NCPU];
e69954b9 98 int enabled;
9ee6e8bb 99 int cpu_enabled[NCPU];
e69954b9 100
a32134aa 101 gic_irq_state irq_state[GIC_MAXIRQ];
9ee6e8bb 102#ifndef NVIC
a32134aa 103 int irq_target[GIC_MAXIRQ];
9ee6e8bb 104#endif
69253800
RR
105 int priority1[GIC_INTERNAL][NCPU];
106 int priority2[GIC_MAXIRQ - GIC_INTERNAL];
a32134aa 107 int last_active[GIC_MAXIRQ][NCPU];
9ee6e8bb
PB
108
109 int priority_mask[NCPU];
110 int running_irq[NCPU];
111 int running_priority[NCPU];
112 int current_pending[NCPU];
113
c988bfad
PB
114#if NCPU > 1
115 int num_cpu;
116#endif
117
e2c56465
PM
118 MemoryRegion iomem; /* Distributor */
119#ifndef NVIC
120 /* This is just so we can have an opaque pointer which identifies
121 * both this GIC and which CPU interface we should be accessing.
122 */
123 struct gic_state *backref[NCPU];
124 MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
125#endif
a32134aa 126 uint32_t num_irq;
e69954b9
PB
127} gic_state;
128
926c4aff
PM
129static inline int gic_get_current_cpu(gic_state *s)
130{
131#if NCPU > 1
132 if (s->num_cpu > 1) {
133 return cpu_single_env->cpu_index;
134 }
135#endif
136 return 0;
137}
138
e69954b9
PB
139/* TODO: Many places that call this routine could be optimized. */
140/* Update interrupt status after enabled or pending bits have been changed. */
141static void gic_update(gic_state *s)
142{
143 int best_irq;
144 int best_prio;
145 int irq;
9ee6e8bb
PB
146 int level;
147 int cpu;
148 int cm;
149
c988bfad 150 for (cpu = 0; cpu < NUM_CPU(s); cpu++) {
9ee6e8bb
PB
151 cm = 1 << cpu;
152 s->current_pending[cpu] = 1023;
153 if (!s->enabled || !s->cpu_enabled[cpu]) {
154 qemu_irq_lower(s->parent_irq[cpu]);
155 return;
156 }
157 best_prio = 0x100;
158 best_irq = 1023;
a32134aa 159 for (irq = 0; irq < s->num_irq; irq++) {
41bf234d 160 if (GIC_TEST_ENABLED(irq, cm) && GIC_TEST_PENDING(irq, cm)) {
9ee6e8bb
PB
161 if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
162 best_prio = GIC_GET_PRIORITY(irq, cpu);
163 best_irq = irq;
164 }
e69954b9
PB
165 }
166 }
9ee6e8bb
PB
167 level = 0;
168 if (best_prio <= s->priority_mask[cpu]) {
169 s->current_pending[cpu] = best_irq;
170 if (best_prio < s->running_priority[cpu]) {
171 DPRINTF("Raised pending IRQ %d\n", best_irq);
172 level = 1;
173 }
e69954b9 174 }
9ee6e8bb 175 qemu_set_irq(s->parent_irq[cpu], level);
e69954b9
PB
176 }
177}
178
9ee6e8bb
PB
179static void __attribute__((unused))
180gic_set_pending_private(gic_state *s, int cpu, int irq)
181{
182 int cm = 1 << cpu;
183
184 if (GIC_TEST_PENDING(irq, cm))
185 return;
186
187 DPRINTF("Set %d pending cpu %d\n", irq, cpu);
188 GIC_SET_PENDING(irq, cm);
189 gic_update(s);
190}
191
192/* Process a change in an external IRQ input. */
e69954b9
PB
193static void gic_set_irq(void *opaque, int irq, int level)
194{
544d1afa
PM
195 /* Meaning of the 'irq' parameter:
196 * [0..N-1] : external interrupts
197 * [N..N+31] : PPI (internal) interrupts for CPU 0
198 * [N+32..N+63] : PPI (internal interrupts for CPU 1
199 * ...
200 */
e69954b9 201 gic_state *s = (gic_state *)opaque;
544d1afa
PM
202 int cm, target;
203 if (irq < (s->num_irq - GIC_INTERNAL)) {
204 /* The first external input line is internal interrupt 32. */
205 cm = ALL_CPU_MASK;
206 irq += GIC_INTERNAL;
207 target = GIC_TARGET(irq);
208 } else {
209 int cpu;
210 irq -= (s->num_irq - GIC_INTERNAL);
211 cpu = irq / GIC_INTERNAL;
212 irq %= GIC_INTERNAL;
213 cm = 1 << cpu;
214 target = cm;
215 }
216
217 if (level == GIC_TEST_LEVEL(irq, cm)) {
e69954b9 218 return;
544d1afa 219 }
e69954b9
PB
220
221 if (level) {
544d1afa
PM
222 GIC_SET_LEVEL(irq, cm);
223 if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) {
224 DPRINTF("Set %d pending mask %x\n", irq, target);
225 GIC_SET_PENDING(irq, target);
e69954b9
PB
226 }
227 } else {
544d1afa 228 GIC_CLEAR_LEVEL(irq, cm);
e69954b9
PB
229 }
230 gic_update(s);
231}
232
9ee6e8bb 233static void gic_set_running_irq(gic_state *s, int cpu, int irq)
e69954b9 234{
9ee6e8bb
PB
235 s->running_irq[cpu] = irq;
236 if (irq == 1023) {
237 s->running_priority[cpu] = 0x100;
238 } else {
239 s->running_priority[cpu] = GIC_GET_PRIORITY(irq, cpu);
240 }
e69954b9
PB
241 gic_update(s);
242}
243
9ee6e8bb 244static uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
e69954b9
PB
245{
246 int new_irq;
9ee6e8bb
PB
247 int cm = 1 << cpu;
248 new_irq = s->current_pending[cpu];
249 if (new_irq == 1023
250 || GIC_GET_PRIORITY(new_irq, cpu) >= s->running_priority[cpu]) {
e69954b9
PB
251 DPRINTF("ACK no pending IRQ\n");
252 return 1023;
253 }
9ee6e8bb
PB
254 s->last_active[new_irq][cpu] = s->running_irq[cpu];
255 /* Clear pending flags for both level and edge triggered interrupts.
256 Level triggered IRQs will be reasserted once they become inactive. */
257 GIC_CLEAR_PENDING(new_irq, GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm);
258 gic_set_running_irq(s, cpu, new_irq);
e69954b9
PB
259 DPRINTF("ACK %d\n", new_irq);
260 return new_irq;
261}
262
9ee6e8bb 263static void gic_complete_irq(gic_state * s, int cpu, int irq)
e69954b9
PB
264{
265 int update = 0;
9ee6e8bb 266 int cm = 1 << cpu;
df628ff1 267 DPRINTF("EOI %d\n", irq);
a32134aa 268 if (irq >= s->num_irq) {
217bfb44
PM
269 /* This handles two cases:
270 * 1. If software writes the ID of a spurious interrupt [ie 1023]
271 * to the GICC_EOIR, the GIC ignores that write.
272 * 2. If software writes the number of a non-existent interrupt
273 * this must be a subcase of "value written does not match the last
274 * valid interrupt value read from the Interrupt Acknowledge
275 * register" and so this is UNPREDICTABLE. We choose to ignore it.
276 */
277 return;
278 }
9ee6e8bb 279 if (s->running_irq[cpu] == 1023)
e69954b9 280 return; /* No active IRQ. */
217bfb44
PM
281 /* Mark level triggered interrupts as pending if they are still
282 raised. */
283 if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq, cm)
284 && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) != 0) {
285 DPRINTF("Set %d pending mask %x\n", irq, cm);
286 GIC_SET_PENDING(irq, cm);
287 update = 1;
e69954b9 288 }
9ee6e8bb 289 if (irq != s->running_irq[cpu]) {
e69954b9 290 /* Complete an IRQ that is not currently running. */
9ee6e8bb
PB
291 int tmp = s->running_irq[cpu];
292 while (s->last_active[tmp][cpu] != 1023) {
293 if (s->last_active[tmp][cpu] == irq) {
294 s->last_active[tmp][cpu] = s->last_active[irq][cpu];
e69954b9
PB
295 break;
296 }
9ee6e8bb 297 tmp = s->last_active[tmp][cpu];
e69954b9
PB
298 }
299 if (update) {
300 gic_update(s);
301 }
302 } else {
303 /* Complete the current running IRQ. */
9ee6e8bb 304 gic_set_running_irq(s, cpu, s->last_active[s->running_irq[cpu]][cpu]);
e69954b9
PB
305 }
306}
307
c227f099 308static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
e69954b9
PB
309{
310 gic_state *s = (gic_state *)opaque;
311 uint32_t res;
312 int irq;
313 int i;
9ee6e8bb
PB
314 int cpu;
315 int cm;
316 int mask;
e69954b9 317
926c4aff 318 cpu = gic_get_current_cpu(s);
9ee6e8bb 319 cm = 1 << cpu;
e69954b9 320 if (offset < 0x100) {
9ee6e8bb 321#ifndef NVIC
e69954b9
PB
322 if (offset == 0)
323 return s->enabled;
324 if (offset == 4)
a32134aa 325 return ((s->num_irq / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
e69954b9
PB
326 if (offset < 0x08)
327 return 0;
b79f2265
RH
328 if (offset >= 0x80) {
329 /* Interrupt Security , RAZ/WI */
330 return 0;
331 }
9ee6e8bb 332#endif
e69954b9
PB
333 goto bad_reg;
334 } else if (offset < 0x200) {
335 /* Interrupt Set/Clear Enable. */
336 if (offset < 0x180)
337 irq = (offset - 0x100) * 8;
338 else
339 irq = (offset - 0x180) * 8;
9ee6e8bb 340 irq += GIC_BASE_IRQ;
a32134aa 341 if (irq >= s->num_irq)
e69954b9
PB
342 goto bad_reg;
343 res = 0;
344 for (i = 0; i < 8; i++) {
41bf234d 345 if (GIC_TEST_ENABLED(irq + i, cm)) {
e69954b9
PB
346 res |= (1 << i);
347 }
348 }
349 } else if (offset < 0x300) {
350 /* Interrupt Set/Clear Pending. */
351 if (offset < 0x280)
352 irq = (offset - 0x200) * 8;
353 else
354 irq = (offset - 0x280) * 8;
9ee6e8bb 355 irq += GIC_BASE_IRQ;
a32134aa 356 if (irq >= s->num_irq)
e69954b9
PB
357 goto bad_reg;
358 res = 0;
69253800 359 mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK;
e69954b9 360 for (i = 0; i < 8; i++) {
9ee6e8bb 361 if (GIC_TEST_PENDING(irq + i, mask)) {
e69954b9
PB
362 res |= (1 << i);
363 }
364 }
365 } else if (offset < 0x400) {
366 /* Interrupt Active. */
9ee6e8bb 367 irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
a32134aa 368 if (irq >= s->num_irq)
e69954b9
PB
369 goto bad_reg;
370 res = 0;
69253800 371 mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK;
e69954b9 372 for (i = 0; i < 8; i++) {
9ee6e8bb 373 if (GIC_TEST_ACTIVE(irq + i, mask)) {
e69954b9
PB
374 res |= (1 << i);
375 }
376 }
377 } else if (offset < 0x800) {
378 /* Interrupt Priority. */
9ee6e8bb 379 irq = (offset - 0x400) + GIC_BASE_IRQ;
a32134aa 380 if (irq >= s->num_irq)
e69954b9 381 goto bad_reg;
9ee6e8bb
PB
382 res = GIC_GET_PRIORITY(irq, cpu);
383#ifndef NVIC
e69954b9
PB
384 } else if (offset < 0xc00) {
385 /* Interrupt CPU Target. */
9ee6e8bb 386 irq = (offset - 0x800) + GIC_BASE_IRQ;
a32134aa 387 if (irq >= s->num_irq)
e69954b9 388 goto bad_reg;
9ee6e8bb
PB
389 if (irq >= 29 && irq <= 31) {
390 res = cm;
391 } else {
392 res = GIC_TARGET(irq);
393 }
e69954b9
PB
394 } else if (offset < 0xf00) {
395 /* Interrupt Configuration. */
9ee6e8bb 396 irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
a32134aa 397 if (irq >= s->num_irq)
e69954b9
PB
398 goto bad_reg;
399 res = 0;
400 for (i = 0; i < 4; i++) {
401 if (GIC_TEST_MODEL(irq + i))
402 res |= (1 << (i * 2));
403 if (GIC_TEST_TRIGGER(irq + i))
404 res |= (2 << (i * 2));
405 }
9ee6e8bb 406#endif
e69954b9
PB
407 } else if (offset < 0xfe0) {
408 goto bad_reg;
409 } else /* offset >= 0xfe0 */ {
410 if (offset & 3) {
411 res = 0;
412 } else {
413 res = gic_id[(offset - 0xfe0) >> 2];
414 }
415 }
416 return res;
417bad_reg:
2ac71179 418 hw_error("gic_dist_readb: Bad offset %x\n", (int)offset);
e69954b9
PB
419 return 0;
420}
421
c227f099 422static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
e69954b9
PB
423{
424 uint32_t val;
425 val = gic_dist_readb(opaque, offset);
426 val |= gic_dist_readb(opaque, offset + 1) << 8;
427 return val;
428}
429
c227f099 430static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
e69954b9
PB
431{
432 uint32_t val;
9ee6e8bb
PB
433#ifdef NVIC
434 gic_state *s = (gic_state *)opaque;
435 uint32_t addr;
8da3ff18 436 addr = offset;
9ee6e8bb 437 if (addr < 0x100 || addr > 0xd00)
fe7e8758 438 return nvic_readl(s, addr);
9ee6e8bb 439#endif
e69954b9
PB
440 val = gic_dist_readw(opaque, offset);
441 val |= gic_dist_readw(opaque, offset + 2) << 16;
442 return val;
443}
444
c227f099 445static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
e69954b9
PB
446 uint32_t value)
447{
448 gic_state *s = (gic_state *)opaque;
449 int irq;
450 int i;
9ee6e8bb 451 int cpu;
e69954b9 452
926c4aff 453 cpu = gic_get_current_cpu(s);
e69954b9 454 if (offset < 0x100) {
9ee6e8bb
PB
455#ifdef NVIC
456 goto bad_reg;
457#else
e69954b9
PB
458 if (offset == 0) {
459 s->enabled = (value & 1);
460 DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
461 } else if (offset < 4) {
462 /* ignored. */
b79f2265
RH
463 } else if (offset >= 0x80) {
464 /* Interrupt Security Registers, RAZ/WI */
e69954b9
PB
465 } else {
466 goto bad_reg;
467 }
9ee6e8bb 468#endif
e69954b9
PB
469 } else if (offset < 0x180) {
470 /* Interrupt Set Enable. */
9ee6e8bb 471 irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
a32134aa 472 if (irq >= s->num_irq)
e69954b9 473 goto bad_reg;
9ee6e8bb
PB
474 if (irq < 16)
475 value = 0xff;
e69954b9
PB
476 for (i = 0; i < 8; i++) {
477 if (value & (1 << i)) {
69253800
RR
478 int mask = (irq < GIC_INTERNAL) ? (1 << cpu) : GIC_TARGET(irq);
479 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
41bf234d
RV
480
481 if (!GIC_TEST_ENABLED(irq + i, cm)) {
e69954b9 482 DPRINTF("Enabled IRQ %d\n", irq + i);
41bf234d
RV
483 }
484 GIC_SET_ENABLED(irq + i, cm);
e69954b9
PB
485 /* If a raised level triggered IRQ enabled then mark
486 is as pending. */
9ee6e8bb
PB
487 if (GIC_TEST_LEVEL(irq + i, mask)
488 && !GIC_TEST_TRIGGER(irq + i)) {
489 DPRINTF("Set %d pending mask %x\n", irq + i, mask);
490 GIC_SET_PENDING(irq + i, mask);
491 }
e69954b9
PB
492 }
493 }
494 } else if (offset < 0x200) {
495 /* Interrupt Clear Enable. */
9ee6e8bb 496 irq = (offset - 0x180) * 8 + GIC_BASE_IRQ;
a32134aa 497 if (irq >= s->num_irq)
e69954b9 498 goto bad_reg;
9ee6e8bb
PB
499 if (irq < 16)
500 value = 0;
e69954b9
PB
501 for (i = 0; i < 8; i++) {
502 if (value & (1 << i)) {
69253800 503 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
41bf234d
RV
504
505 if (GIC_TEST_ENABLED(irq + i, cm)) {
e69954b9 506 DPRINTF("Disabled IRQ %d\n", irq + i);
41bf234d
RV
507 }
508 GIC_CLEAR_ENABLED(irq + i, cm);
e69954b9
PB
509 }
510 }
511 } else if (offset < 0x280) {
512 /* Interrupt Set Pending. */
9ee6e8bb 513 irq = (offset - 0x200) * 8 + GIC_BASE_IRQ;
a32134aa 514 if (irq >= s->num_irq)
e69954b9 515 goto bad_reg;
9ee6e8bb
PB
516 if (irq < 16)
517 irq = 0;
518
e69954b9
PB
519 for (i = 0; i < 8; i++) {
520 if (value & (1 << i)) {
9ee6e8bb 521 GIC_SET_PENDING(irq + i, GIC_TARGET(irq));
e69954b9
PB
522 }
523 }
524 } else if (offset < 0x300) {
525 /* Interrupt Clear Pending. */
9ee6e8bb 526 irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
a32134aa 527 if (irq >= s->num_irq)
e69954b9
PB
528 goto bad_reg;
529 for (i = 0; i < 8; i++) {
9ee6e8bb
PB
530 /* ??? This currently clears the pending bit for all CPUs, even
531 for per-CPU interrupts. It's unclear whether this is the
532 corect behavior. */
e69954b9 533 if (value & (1 << i)) {
9ee6e8bb 534 GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK);
e69954b9
PB
535 }
536 }
537 } else if (offset < 0x400) {
538 /* Interrupt Active. */
539 goto bad_reg;
540 } else if (offset < 0x800) {
541 /* Interrupt Priority. */
9ee6e8bb 542 irq = (offset - 0x400) + GIC_BASE_IRQ;
a32134aa 543 if (irq >= s->num_irq)
e69954b9 544 goto bad_reg;
69253800 545 if (irq < GIC_INTERNAL) {
9ee6e8bb
PB
546 s->priority1[irq][cpu] = value;
547 } else {
69253800 548 s->priority2[irq - GIC_INTERNAL] = value;
9ee6e8bb
PB
549 }
550#ifndef NVIC
e69954b9
PB
551 } else if (offset < 0xc00) {
552 /* Interrupt CPU Target. */
9ee6e8bb 553 irq = (offset - 0x800) + GIC_BASE_IRQ;
a32134aa 554 if (irq >= s->num_irq)
e69954b9 555 goto bad_reg;
9ee6e8bb
PB
556 if (irq < 29)
557 value = 0;
69253800 558 else if (irq < GIC_INTERNAL)
9ee6e8bb
PB
559 value = ALL_CPU_MASK;
560 s->irq_target[irq] = value & ALL_CPU_MASK;
e69954b9
PB
561 } else if (offset < 0xf00) {
562 /* Interrupt Configuration. */
9ee6e8bb 563 irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
a32134aa 564 if (irq >= s->num_irq)
e69954b9 565 goto bad_reg;
69253800 566 if (irq < GIC_INTERNAL)
9ee6e8bb 567 value |= 0xaa;
e69954b9
PB
568 for (i = 0; i < 4; i++) {
569 if (value & (1 << (i * 2))) {
570 GIC_SET_MODEL(irq + i);
571 } else {
572 GIC_CLEAR_MODEL(irq + i);
573 }
574 if (value & (2 << (i * 2))) {
575 GIC_SET_TRIGGER(irq + i);
576 } else {
577 GIC_CLEAR_TRIGGER(irq + i);
578 }
579 }
9ee6e8bb 580#endif
e69954b9 581 } else {
9ee6e8bb 582 /* 0xf00 is only handled for 32-bit writes. */
e69954b9
PB
583 goto bad_reg;
584 }
585 gic_update(s);
586 return;
587bad_reg:
2ac71179 588 hw_error("gic_dist_writeb: Bad offset %x\n", (int)offset);
e69954b9
PB
589}
590
c227f099 591static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
e69954b9
PB
592 uint32_t value)
593{
e69954b9
PB
594 gic_dist_writeb(opaque, offset, value & 0xff);
595 gic_dist_writeb(opaque, offset + 1, value >> 8);
596}
597
c227f099 598static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
e69954b9
PB
599 uint32_t value)
600{
9ee6e8bb
PB
601 gic_state *s = (gic_state *)opaque;
602#ifdef NVIC
603 uint32_t addr;
8da3ff18 604 addr = offset;
9ee6e8bb 605 if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
fe7e8758 606 nvic_writel(s, addr, value);
9ee6e8bb
PB
607 return;
608 }
609#endif
8da3ff18 610 if (offset == 0xf00) {
9ee6e8bb
PB
611 int cpu;
612 int irq;
613 int mask;
614
926c4aff 615 cpu = gic_get_current_cpu(s);
9ee6e8bb
PB
616 irq = value & 0x3ff;
617 switch ((value >> 24) & 3) {
618 case 0:
619 mask = (value >> 16) & ALL_CPU_MASK;
620 break;
621 case 1:
fa250144 622 mask = ALL_CPU_MASK ^ (1 << cpu);
9ee6e8bb
PB
623 break;
624 case 2:
fa250144 625 mask = 1 << cpu;
9ee6e8bb
PB
626 break;
627 default:
628 DPRINTF("Bad Soft Int target filter\n");
629 mask = ALL_CPU_MASK;
630 break;
631 }
632 GIC_SET_PENDING(irq, mask);
633 gic_update(s);
634 return;
635 }
e69954b9
PB
636 gic_dist_writew(opaque, offset, value & 0xffff);
637 gic_dist_writew(opaque, offset + 2, value >> 16);
638}
639
755c0802
AK
640static const MemoryRegionOps gic_dist_ops = {
641 .old_mmio = {
642 .read = { gic_dist_readb, gic_dist_readw, gic_dist_readl, },
643 .write = { gic_dist_writeb, gic_dist_writew, gic_dist_writel, },
644 },
645 .endianness = DEVICE_NATIVE_ENDIAN,
e69954b9
PB
646};
647
9ee6e8bb
PB
648#ifndef NVIC
649static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
e69954b9 650{
e69954b9
PB
651 switch (offset) {
652 case 0x00: /* Control */
9ee6e8bb 653 return s->cpu_enabled[cpu];
e69954b9 654 case 0x04: /* Priority mask */
9ee6e8bb 655 return s->priority_mask[cpu];
e69954b9
PB
656 case 0x08: /* Binary Point */
657 /* ??? Not implemented. */
658 return 0;
659 case 0x0c: /* Acknowledge */
9ee6e8bb 660 return gic_acknowledge_irq(s, cpu);
66a0a2cb 661 case 0x14: /* Running Priority */
9ee6e8bb 662 return s->running_priority[cpu];
e69954b9 663 case 0x18: /* Highest Pending Interrupt */
9ee6e8bb 664 return s->current_pending[cpu];
e69954b9 665 default:
2ac71179 666 hw_error("gic_cpu_read: Bad offset %x\n", (int)offset);
e69954b9
PB
667 return 0;
668 }
669}
670
9ee6e8bb 671static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
e69954b9 672{
e69954b9
PB
673 switch (offset) {
674 case 0x00: /* Control */
9ee6e8bb 675 s->cpu_enabled[cpu] = (value & 1);
f7c70325 676 DPRINTF("CPU %d %sabled\n", cpu, s->cpu_enabled ? "En" : "Dis");
e69954b9
PB
677 break;
678 case 0x04: /* Priority mask */
9ee6e8bb 679 s->priority_mask[cpu] = (value & 0xff);
e69954b9
PB
680 break;
681 case 0x08: /* Binary Point */
682 /* ??? Not implemented. */
683 break;
684 case 0x10: /* End Of Interrupt */
9ee6e8bb 685 return gic_complete_irq(s, cpu, value & 0x3ff);
e69954b9 686 default:
2ac71179 687 hw_error("gic_cpu_write: Bad offset %x\n", (int)offset);
e69954b9
PB
688 return;
689 }
690 gic_update(s);
691}
e2c56465
PM
692
693/* Wrappers to read/write the GIC CPU interface for the current CPU */
694static uint64_t gic_thiscpu_read(void *opaque, target_phys_addr_t addr,
695 unsigned size)
696{
697 gic_state *s = (gic_state *)opaque;
926c4aff 698 return gic_cpu_read(s, gic_get_current_cpu(s), addr);
e2c56465
PM
699}
700
701static void gic_thiscpu_write(void *opaque, target_phys_addr_t addr,
702 uint64_t value, unsigned size)
703{
704 gic_state *s = (gic_state *)opaque;
926c4aff 705 gic_cpu_write(s, gic_get_current_cpu(s), addr, value);
e2c56465
PM
706}
707
708/* Wrappers to read/write the GIC CPU interface for a specific CPU.
709 * These just decode the opaque pointer into gic_state* + cpu id.
710 */
711static uint64_t gic_do_cpu_read(void *opaque, target_phys_addr_t addr,
712 unsigned size)
713{
714 gic_state **backref = (gic_state **)opaque;
715 gic_state *s = *backref;
716 int id = (backref - s->backref);
0e4a398a 717 return gic_cpu_read(s, id, addr);
e2c56465
PM
718}
719
720static void gic_do_cpu_write(void *opaque, target_phys_addr_t addr,
721 uint64_t value, unsigned size)
722{
723 gic_state **backref = (gic_state **)opaque;
724 gic_state *s = *backref;
725 int id = (backref - s->backref);
0e4a398a 726 gic_cpu_write(s, id, addr, value);
e2c56465
PM
727}
728
729static const MemoryRegionOps gic_thiscpu_ops = {
730 .read = gic_thiscpu_read,
731 .write = gic_thiscpu_write,
732 .endianness = DEVICE_NATIVE_ENDIAN,
733};
734
735static const MemoryRegionOps gic_cpu_ops = {
736 .read = gic_do_cpu_read,
737 .write = gic_do_cpu_write,
738 .endianness = DEVICE_NATIVE_ENDIAN,
739};
9ee6e8bb 740#endif
e69954b9
PB
741
742static void gic_reset(gic_state *s)
743{
744 int i;
a32134aa 745 memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
c988bfad 746 for (i = 0 ; i < NUM_CPU(s); i++) {
9ee6e8bb
PB
747 s->priority_mask[i] = 0xf0;
748 s->current_pending[i] = 1023;
749 s->running_irq[i] = 1023;
750 s->running_priority[i] = 0x100;
751#ifdef NVIC
752 /* The NVIC doesn't have per-cpu interfaces, so enable by default. */
753 s->cpu_enabled[i] = 1;
754#else
755 s->cpu_enabled[i] = 0;
756#endif
757 }
e57ec016 758 for (i = 0; i < 16; i++) {
41bf234d 759 GIC_SET_ENABLED(i, ALL_CPU_MASK);
e69954b9
PB
760 GIC_SET_TRIGGER(i);
761 }
9ee6e8bb
PB
762#ifdef NVIC
763 /* The NVIC is always enabled. */
764 s->enabled = 1;
765#else
e69954b9 766 s->enabled = 0;
9ee6e8bb 767#endif
e69954b9
PB
768}
769
23e39294
PB
770static void gic_save(QEMUFile *f, void *opaque)
771{
772 gic_state *s = (gic_state *)opaque;
773 int i;
774 int j;
775
776 qemu_put_be32(f, s->enabled);
c988bfad 777 for (i = 0; i < NUM_CPU(s); i++) {
23e39294 778 qemu_put_be32(f, s->cpu_enabled[i]);
69253800 779 for (j = 0; j < GIC_INTERNAL; j++)
23e39294 780 qemu_put_be32(f, s->priority1[j][i]);
a32134aa 781 for (j = 0; j < s->num_irq; j++)
23e39294
PB
782 qemu_put_be32(f, s->last_active[j][i]);
783 qemu_put_be32(f, s->priority_mask[i]);
784 qemu_put_be32(f, s->running_irq[i]);
785 qemu_put_be32(f, s->running_priority[i]);
786 qemu_put_be32(f, s->current_pending[i]);
787 }
69253800 788 for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
23e39294
PB
789 qemu_put_be32(f, s->priority2[i]);
790 }
a32134aa 791 for (i = 0; i < s->num_irq; i++) {
c2e2343e
DK
792#ifndef NVIC
793 qemu_put_be32(f, s->irq_target[i]);
794#endif
23e39294
PB
795 qemu_put_byte(f, s->irq_state[i].enabled);
796 qemu_put_byte(f, s->irq_state[i].pending);
797 qemu_put_byte(f, s->irq_state[i].active);
798 qemu_put_byte(f, s->irq_state[i].level);
799 qemu_put_byte(f, s->irq_state[i].model);
800 qemu_put_byte(f, s->irq_state[i].trigger);
801 }
802}
803
804static int gic_load(QEMUFile *f, void *opaque, int version_id)
805{
806 gic_state *s = (gic_state *)opaque;
807 int i;
808 int j;
809
c2e2343e 810 if (version_id != 2)
23e39294
PB
811 return -EINVAL;
812
813 s->enabled = qemu_get_be32(f);
c988bfad 814 for (i = 0; i < NUM_CPU(s); i++) {
23e39294 815 s->cpu_enabled[i] = qemu_get_be32(f);
69253800 816 for (j = 0; j < GIC_INTERNAL; j++)
23e39294 817 s->priority1[j][i] = qemu_get_be32(f);
a32134aa 818 for (j = 0; j < s->num_irq; j++)
23e39294
PB
819 s->last_active[j][i] = qemu_get_be32(f);
820 s->priority_mask[i] = qemu_get_be32(f);
821 s->running_irq[i] = qemu_get_be32(f);
822 s->running_priority[i] = qemu_get_be32(f);
823 s->current_pending[i] = qemu_get_be32(f);
824 }
69253800 825 for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
23e39294
PB
826 s->priority2[i] = qemu_get_be32(f);
827 }
a32134aa 828 for (i = 0; i < s->num_irq; i++) {
c2e2343e
DK
829#ifndef NVIC
830 s->irq_target[i] = qemu_get_be32(f);
831#endif
23e39294
PB
832 s->irq_state[i].enabled = qemu_get_byte(f);
833 s->irq_state[i].pending = qemu_get_byte(f);
834 s->irq_state[i].active = qemu_get_byte(f);
835 s->irq_state[i].level = qemu_get_byte(f);
836 s->irq_state[i].model = qemu_get_byte(f);
837 s->irq_state[i].trigger = qemu_get_byte(f);
838 }
839
840 return 0;
841}
842
c988bfad 843#if NCPU > 1
a32134aa 844static void gic_init(gic_state *s, int num_cpu, int num_irq)
c988bfad 845#else
a32134aa 846static void gic_init(gic_state *s, int num_irq)
c988bfad 847#endif
e69954b9 848{
9ee6e8bb 849 int i;
e69954b9 850
c988bfad
PB
851#if NCPU > 1
852 s->num_cpu = num_cpu;
386e2955
PM
853 if (s->num_cpu > NCPU) {
854 hw_error("requested %u CPUs exceeds GIC maximum %d\n",
855 num_cpu, NCPU);
856 }
c988bfad 857#endif
a32134aa
ML
858 s->num_irq = num_irq + GIC_BASE_IRQ;
859 if (s->num_irq > GIC_MAXIRQ) {
860 hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
861 num_irq, GIC_MAXIRQ);
862 }
41c1e2f5
RR
863 /* ITLinesNumber is represented as (N / 32) - 1 (see
864 * gic_dist_readb) so this is an implementation imposed
865 * restriction, not an architectural one:
866 */
867 if (s->num_irq < 32 || (s->num_irq % 32)) {
868 hw_error("%d interrupt lines unsupported: not divisible by 32\n",
869 num_irq);
870 }
871
544d1afa
PM
872 i = s->num_irq - GIC_INTERNAL;
873#ifndef NVIC
874 /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
875 * GPIO array layout is thus:
876 * [0..N-1] SPIs
877 * [N..N+31] PPIs for CPU 0
878 * [N+32..N+63] PPIs for CPU 1
879 * ...
880 */
881 i += (GIC_INTERNAL * num_cpu);
882#endif
883 qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i);
c988bfad 884 for (i = 0; i < NUM_CPU(s); i++) {
fe7e8758 885 sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
e69954b9 886 }
755c0802 887 memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
e2c56465
PM
888#ifndef NVIC
889 /* Memory regions for the CPU interfaces (NVIC doesn't have these):
890 * a region for "CPU interface for this core", then a region for
891 * "CPU interface for core 0", "for core 1", ...
892 * NB that the memory region size of 0x100 applies for the 11MPCore
893 * and also cores following the GIC v1 spec (ie A9).
894 * GIC v2 defines a larger memory region (0x1000) so this will need
895 * to be extended when we implement A15.
896 */
897 memory_region_init_io(&s->cpuiomem[0], &gic_thiscpu_ops, s,
898 "gic_cpu", 0x100);
899 for (i = 0; i < NUM_CPU(s); i++) {
900 s->backref[i] = s;
901 memory_region_init_io(&s->cpuiomem[i+1], &gic_cpu_ops, &s->backref[i],
902 "gic_cpu", 0x100);
903 }
904#endif
905
e69954b9 906 gic_reset(s);
c2e2343e 907 register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
e69954b9 908}