From 425a5c79006c9254abb20ccaaf938d01813c307a Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 31 Oct 2013 03:23:25 +0000 Subject: [PATCH] Do not EOI an interrupt until the point after the filter handlers / before threaded handlers. It's not easy to see from the diffs of this change exactly how it accomplishes the above. The arm_mask_irq() and arm_unmask_irq() functions are, respectively, the pre_thread and post_thread hooks. Not seen in these diffs, the arm_post_filter() routine also EOIs. The post_filter routine runs after filter handlers if there will be no threaded handlers, so it just EOIs. The pre_thread routine masks the interrupt (at the controller, not the source) and EOIs. So one way or another, the EOI happens at the point where filter handlers are done. --- sys/arm/arm/gic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index a73011f177fd..d11c600afb74 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -271,7 +271,6 @@ arm_get_next_irq(int last_irq) printf("Spurious interrupt detected [0x%08x]\n", active_irq); return -1; } - gic_c_write_4(GICC_EOIR, active_irq); return active_irq; } @@ -279,14 +278,15 @@ arm_get_next_irq(int last_irq) void arm_mask_irq(uintptr_t nb) { + gic_d_write_4(GICD_ICENABLER(nb >> 5), (1UL << (nb & 0x1F))); + gic_c_write_4(GICC_EOIR, nb); } void arm_unmask_irq(uintptr_t nb) { - gic_c_write_4(GICC_EOIR, nb); gic_d_write_4(GICD_ISENABLER(nb >> 5), (1UL << (nb & 0x1F))); }