From a6507838a569762ec92493bfcb422e7dbc2cfae9 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 30 Apr 2018 19:01:44 +0300 Subject: [PATCH] handling spurious interrupts correctly --- src/intr.c | 8 ++++++++ src/intr_asm.S | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/intr.c b/src/intr.c index 5f49b87..a9bd5f1 100644 --- a/src/intr.c +++ b/src/intr.c @@ -60,6 +60,8 @@ static void gate_desc(desc_t *desc, uint16_t sel, uint32_t addr, int dpl, int ty /* defined in intr_asm.S */ void set_idt(uint32_t addr, uint16_t limit); void intr_entry_default(void); +void irq7_entry_check_spurious(void); +void irq15_entry_check_spurious(void); /* the IDT (interrupt descriptor table) */ static desc_t idt[256] __attribute__((aligned(8))); @@ -90,6 +92,12 @@ void init_intr(void) */ #include "intrtab.h" + /* change irq7 and irq15 to special entry points which first + * make sure we didn't get a spurious interrupt before proceeding + */ + set_intr_entry(IRQ_TO_INTR(7), irq7_entry_check_spurious); + set_intr_entry(IRQ_TO_INTR(15), irq15_entry_check_spurious); + /* initialize the programmable interrupt controller * setting up the maping of IRQs [0, 15] to interrupts [32, 47] */ diff --git a/src/intr_asm.S b/src/intr_asm.S index dcbef63..8434a8f 100644 --- a/src/intr_asm.S +++ b/src/intr_asm.S @@ -104,7 +104,42 @@ intr_entry_fast_timer: out %al, $0x20 pop %eax iret - + +/* special case for IRQ 7 and IRQ 15, to catch spurious interrupts */ + .set PIC1_CMD, 0x20 + .set PIC2_CMD, 0xa0 + .set OCW2_EOI, 0x20 + .set OCW3_ISR, 0x0b + + .extern intr_entry_irq7 + .global irq7_entry_check_spurious +irq7_entry_check_spurious: + push %eax + mov $OCW3_ISR, %al + out %al, $PIC1_CMD + in $PIC1_CMD, %al + and $0x80, %al + pop %eax + jnz intr_entry_irq7 + iret + + .extern intr_entry_irq15 + .global irq15_entry_check_spurious +irq15_entry_check_spurious: + push %eax + mov $OCW3_ISR, %al + out %al, $PIC2_CMD + in $PIC2_CMD, %al + and $0x80, %al + jnz 0f + # it was spurious, send EOI to master PIC and iret + mov $OCW2_EOI, %al + out %al, $PIC1_CMD + pop %eax + iret +0: pop %eax + jmp intr_entry_irq15 + /* XXX not necessary for now, just leaving it in in case it's useful * down the road. -- 1.7.10.4