Commit 3bc4b52c authored by Marcin Krzeminski's avatar Marcin Krzeminski Committed by Peter Maydell
Browse files

nvic: set pending status for not active interrupts



According to ARM DUI 0552A 4.2.10. NVIC set pending status
also for disabled interrupts. Correct the logic for
when interrupts are marked pending both on input level
transition and when interrupts are dismissed, to match
the NVIC behaviour rather than the 11MPCore GIC.

Signed-off-by: default avatarMarcin Krzeminski <marcin.krzeminski@nokia.com>
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 6e29651c
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -156,6 +156,17 @@ static void gic_set_irq_11mpcore(GICState *s, int irq, int level,
    }
}

static void gic_set_irq_nvic(GICState *s, int irq, int level,
                                 int cm, int target)
{
    if (level) {
        GIC_SET_LEVEL(irq, cm);
        GIC_SET_PENDING(irq, target);
    } else {
        GIC_CLEAR_LEVEL(irq, cm);
    }
}

static void gic_set_irq_generic(GICState *s, int irq, int level,
                                int cm, int target)
{
@@ -201,8 +212,10 @@ static void gic_set_irq(void *opaque, int irq, int level)
        return;
    }

    if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
    if (s->revision == REV_11MPCORE) {
        gic_set_irq_11mpcore(s, irq, level, cm, target);
    } else if (s->revision == REV_NVIC) {
        gic_set_irq_nvic(s, irq, level, cm, target);
    } else {
        gic_set_irq_generic(s, irq, level, cm, target);
    }
@@ -568,7 +581,7 @@ void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
        return; /* No active IRQ.  */
    }

    if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
    if (s->revision == REV_11MPCORE) {
        /* Mark level triggered interrupts as pending if they are still
           raised.  */
        if (!GIC_TEST_EDGE_TRIGGER(irq) && GIC_TEST_ENABLED(irq, cm)
@@ -576,6 +589,11 @@ void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
            DPRINTF("Set %d pending mask %x\n", irq, cm);
            GIC_SET_PENDING(irq, cm);
        }
    } else if (s->revision == REV_NVIC) {
        if (GIC_TEST_LEVEL(irq, cm)) {
            DPRINTF("Set nvic %d pending mask %x\n", irq, cm);
            GIC_SET_PENDING(irq, cm);
        }
    }

    group = gic_has_groups(s) && GIC_TEST_GROUP(irq, cm);