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