diff options
Diffstat (limited to 'hw/intc/arm_gic.c')
-rw-r--r-- | hw/intc/arm_gic.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 1532ef9..db9110c 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -66,7 +66,8 @@ void gic_update(GICState *s) best_prio = 0x100; best_irq = 1023; for (irq = 0; irq < s->num_irq; irq++) { - if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm)) { + if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) && + (irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) { if (GIC_GET_PRIORITY(irq, cpu) < best_prio) { best_prio = GIC_GET_PRIORITY(irq, cpu); best_irq = irq; @@ -372,7 +373,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset) } } else if (offset < 0xf00) { /* Interrupt Configuration. */ - irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ; + irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ; if (irq >= s->num_irq) goto bad_reg; res = 0; @@ -558,13 +559,15 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ; if (irq >= s->num_irq) goto bad_reg; - if (irq < GIC_INTERNAL) + if (irq < GIC_NR_SGIS) value |= 0xaa; for (i = 0; i < 4; i++) { - if (value & (1 << (i * 2))) { - GIC_SET_MODEL(irq + i); - } else { - GIC_CLEAR_MODEL(irq + i); + if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) { + if (value & (1 << (i * 2))) { + GIC_SET_MODEL(irq + i); + } else { + GIC_CLEAR_MODEL(irq + i); + } } if (value & (2 << (i * 2))) { GIC_SET_EDGE_TRIGGER(irq + i); |