diff options
author | Richard Braun <rbraun@sceen.net> | 2017-05-28 15:48:35 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-05-28 15:49:38 +0200 |
commit | dcf8889c5cf22450936b58cecff1273a19e558a3 (patch) | |
tree | d6fdb22f86a9eadb12de19506d75ad315d99231a | |
parent | 779696077e4b9eb47cc1fff7f7d022eb8b1fcb89 (diff) |
x86/pic: handle spurious interrupts
Support was lost during the trap module rework.
-rw-r--r-- | arch/x86/machine/pic.c | 67 | ||||
-rw-r--r-- | arch/x86/machine/pic.h | 7 |
2 files changed, 42 insertions, 32 deletions
diff --git a/arch/x86/machine/pic.c b/arch/x86/machine/pic.c index fed8c97a..9084abce 100644 --- a/arch/x86/machine/pic.c +++ b/arch/x86/machine/pic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Richard Braun. + * Copyright (c) 2012-2017 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include <stdint.h> #include <kern/assert.h> +#include <kern/error.h> #include <kern/init.h> #include <kern/intr.h> #include <kern/panic.h> @@ -57,6 +58,9 @@ static unsigned int pic_nr_slave_intrs; static uint8_t pic_master_mask; static uint8_t pic_slave_mask; +static uint8_t pic_master_spurious_intr; +static uint8_t pic_slave_spurious_intr; + static bool pic_is_slave_intr(unsigned int intr) { @@ -168,9 +172,37 @@ pic_register(void) } } +static int +pic_spurious_intr(void *arg) +{ + uint8_t intr, isr; + + intr = *(const uint8_t *)arg; + + if (arg == &pic_master_spurious_intr) { + isr = pic_read_isr(PIC_MASTER_CMD); + + if (isr & (1 << PIC_SPURIOUS_INTR)) { + panic("pic: real interrupt %hhu", intr); + } + } else { + isr = pic_read_isr(PIC_SLAVE_CMD); + + if (isr & (1 << PIC_SPURIOUS_INTR)) { + panic("pic: real interrupt %hhu", intr); + } + + pic_eoi(PIC_SLAVE_INTR); + } + + return 0; +} + void __init pic_setup(void) { + int error; + pic_nr_slave_intrs = 0; pic_master_mask = 0xff; pic_slave_mask = 0xff; @@ -198,31 +230,14 @@ pic_setup(void) if (lapic_unused()) { pic_register(); } -} - -void -pic_spurious_intr(struct trap_frame *frame) -{ - unsigned long intr; - uint8_t isr; - intr = frame->vector - TRAP_INTR_FIRST; - assert((intr == PIC_SPURIOUS_INTR) - || (intr == (PIC_NR_INTRS + PIC_SPURIOUS_INTR))); + pic_master_spurious_intr = PIC_SPURIOUS_INTR; + error = intr_register(pic_master_spurious_intr, pic_spurious_intr, + &pic_master_spurious_intr); + error_check(error, __func__); - if (intr == PIC_SPURIOUS_INTR) { - isr = pic_read_isr(PIC_MASTER_CMD); - - if (isr & (1 << PIC_SPURIOUS_INTR)) { - panic("pic: real interrupt %lu", intr); - } - } else { - isr = pic_read_isr(PIC_SLAVE_CMD); - - if (isr & (1 << PIC_SPURIOUS_INTR)) { - panic("pic: real interrupt %lu", intr); - } - - pic_eoi(PIC_SLAVE_INTR); - } + pic_slave_spurious_intr = PIC_NR_INTRS + PIC_SPURIOUS_INTR; + error = intr_register(pic_slave_spurious_intr, pic_spurious_intr, + &pic_slave_spurious_intr); + error_check(error, __func__); } diff --git a/arch/x86/machine/pic.h b/arch/x86/machine/pic.h index 3dc13d4e..9da75b74 100644 --- a/arch/x86/machine/pic.h +++ b/arch/x86/machine/pic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Richard Braun. + * Copyright (c) 2012-2017 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,9 +25,4 @@ */ void pic_setup(void); -/* - * Interrupt handlers. - */ -void pic_spurious_intr(struct trap_frame *frame); - #endif /* _X86_PIC_H */ |