diff options
author | marcel <marcel@FreeBSD.org> | 2011-07-16 20:16:49 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2011-07-16 20:16:49 +0000 |
commit | 87a4ad12f030ac678b2f894a8a168c4b219e3eeb (patch) | |
tree | 34b390d20c53cc78182274efbe2fa8340a773b2c /sys/ia64 | |
parent | 21706948a50344e60f249fb0738da4912bd4ba3e (diff) | |
download | FreeBSD-src-87a4ad12f030ac678b2f894a8a168c4b219e3eeb.zip FreeBSD-src-87a4ad12f030ac678b2f894a8a168c4b219e3eeb.tar.gz |
Don't send EOI to the CPU before we handled the interrupt. This could
potentially trigger multiple pending interrupts for level-sensitive
interrupts. However, the event timer interrupt does need EOI before
being handled to avoid missing clock events.
These conflicting requirements are handled by having the XIV handler
inform the dispatch code whether or not it send EOI to the CPU. If not,
the dispatch code will do it. This allows handlers to send EOI before
doing potentially long-running activities, while still have a sensible
default behaviour.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/clock.c | 4 | ||||
-rw-r--r-- | sys/ia64/ia64/interrupt.c | 7 |
2 files changed, 7 insertions, 4 deletions
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index 96d07c4..24623c5 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -91,12 +91,14 @@ ia64_ih_clock(struct thread *td, u_int xiv, struct trapframe *tf) ia64_set_itm(itc + load); } else ia64_set_itv((1 << 16) | xiv); + + ia64_set_eoi(0); ia64_srlz_d(); et = &ia64_clock_et; if (et->et_active) et->et_event_cb(et, et->et_arg); - return (0); + return (1); } /* diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index 27d5e60..c2372b2 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -320,11 +320,12 @@ ia64_handle_intr(struct trapframe *tf) td->td_intr_frame = tf; do { - ia64_set_eoi(0); - ia64_srlz_d(); CTR2(KTR_INTR, "INTR: ITC=%u, XIV=%u", (u_int)tf->tf_special.ifa, xiv); - (ia64_handler[xiv])(td, xiv, tf); + if (!(ia64_handler[xiv])(td, xiv, tf)) { + ia64_set_eoi(0); + ia64_srlz_d(); + } xiv = ia64_get_ivr(); ia64_srlz_d(); } while (xiv != 15); |