On Mon, Oct 14, 2013 at 05:33:38PM +0100, Peter Maydell wrote: > On 14 October 2013 16:36, Peter Maydell <peter.maydell@xxxxxxxxxx> wrote: [...] > > Tangentially, I notice that we don't correctly handle > the PENDING bit for level triggered interrupts, since > we do: > > /* Clear pending flags for both level and edge triggered interrupts. > Level triggered IRQs will be reasserted once they become inactive. */ > gic_clear_pending(s, new_irq, GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm, > GIC_SGI_SRC(new_irq, cpu)); > > in gic_acknowledge_irq(). This is wrong, because section > 3.2.4 is clear for a level triggered interrupt that if the > interrupt signal remains asserted (which it usually will be) > then we go from Pending to Active+Pending (whereas our > current implementation goes from Pending to Active and > then resets Pending later in gic_complete_irq()). > Yes, I will send this patch to address this as part of the revised series: diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index bf1eb02..fce66c6 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -175,10 +180,15 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu) return 1023; } s->last_active[new_irq][cpu] = s->running_irq[cpu]; - /* Clear pending flags for both level and edge triggered interrupts. - Level triggered IRQs will be reasserted once they become inactive. */ - gic_clear_pending(s, new_irq, GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm, - GIC_SGI_SRC(new_irq, cpu)); + /* Clear pending flags for edge-triggered and non-asserted level-triggered + * interrupts. + */ + cm = GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm; + if (GIC_TEST_TRIGGER(new_irq) || !GIC_TEST_LEVEL(new_irq, cm)) { + gic_clear_pending(s, new_irq, cm, GIC_SGI_SRC(new_irq, cpu)); + } + gic_set_running_irq(s, cpu, new_irq); DPRINTF("ACK %d\n", new_irq); return new_irq; -- Christoffer _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm