summaryrefslogtreecommitdiff
path: root/i386/i386at/interrupt.S
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2011-02-27 05:37:57 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2011-02-27 05:37:57 +0100
commit5da1aea7ab3cf8634e1ef061a8c6a9873fed4f4e (patch)
treee1a1e654b89cc65e5883463c6b2ad4f81d8ca0c7 /i386/i386at/interrupt.S
parentaa0c4071694a19b0f7de5fcaca8b1f9918e06fc8 (diff)
Acknoledge interrupt after handler call
This fixes interrupt overflows when software interrupts processing gets slower than hardware. * i386/i386at/interrupt.S (interrupt): Issue EOI to PICs after having called the interrupt handler and disabled interrupts through cli.
Diffstat (limited to 'i386/i386at/interrupt.S')
-rw-r--r--i386/i386at/interrupt.S19
1 files changed, 11 insertions, 8 deletions
diff --git a/i386/i386at/interrupt.S b/i386/i386at/interrupt.S
index 4916903..e238ea4 100644
--- a/i386/i386at/interrupt.S
+++ b/i386/i386at/interrupt.S
@@ -27,13 +27,8 @@
* On entry, %eax contains the irq number.
*/
ENTRY(interrupt)
- movl %eax,%ecx /* save irq number */
- movb $(NON_SPEC_EOI),%al /* non-specific EOI */
- outb %al,$(PIC_MASTER_ICW) /* ack interrupt to master */
- cmpl $8,%ecx /* do we need to ack slave? */
- jl 1f /* no, skip it */
- outb %al,$(PIC_SLAVE_ICW)
-1:
+ pushl %eax /* save irq number */
+ movl %eax,%ecx /* copy irq number */
shll $2,%ecx /* irq * 4 */
movl EXT(intpri)(%ecx),%edx /* get new ipl */
call spl /* set ipl */
@@ -43,6 +38,14 @@ ENTRY(interrupt)
call *EXT(ivect)(%ecx) /* call interrupt handler */
addl $4,%esp /* pop unit number */
call splx_cli /* restore previous ipl */
- cli /* XXX no more nested interrupts */
addl $4,%esp /* pop previous ipl */
+ cli /* XXX no more nested interrupts */
+ popl %eax /* restore irq number */
+ movl %eax,%ecx /* copy irq number */
+ movb $(NON_SPEC_EOI),%al /* non-specific EOI */
+ outb %al,$(PIC_MASTER_ICW) /* ack interrupt to master */
+ cmpl $8,%ecx /* do we need to ack slave? */
+ jl 1f /* no, skip it */
+ outb %al,$(PIC_SLAVE_ICW)
+1:
ret /* return */