diff options
author | peter <peter@FreeBSD.org> | 2003-11-21 02:58:26 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2003-11-21 02:58:26 +0000 |
commit | cccfc8f4107b77dd1e4fe79c4b7875f08232998f (patch) | |
tree | 165db0032cd6c5bef84d72d1efbba143d2fe7e3a /sys/amd64 | |
parent | 72c8222cf4342f70e7f7203c17f9c7475f012359 (diff) | |
download | FreeBSD-src-cccfc8f4107b77dd1e4fe79c4b7875f08232998f.zip FreeBSD-src-cccfc8f4107b77dd1e4fe79c4b7875f08232998f.tar.gz |
MFi386: pre-register idt slots for atpic so we catch any strays without
blowing up.
Approved by: re (scottl)
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/isa/atpic.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/sys/amd64/isa/atpic.c b/sys/amd64/isa/atpic.c index 64fa45e3..2a64e1c 100644 --- a/sys/amd64/isa/atpic.c +++ b/sys/amd64/isa/atpic.c @@ -107,6 +107,8 @@ struct atpic_intsrc { struct intsrc at_intsrc; int at_irq; /* Relative to PIC base. */ inthand_t *at_intr; + u_long at_count; + u_long at_straycount; }; static void atpic_enable_source(struct intsrc *isrc); @@ -277,28 +279,37 @@ i8259_init(struct atpic *pic, int slave) void atpic_startup(void) { + struct atpic_intsrc *ai; + int i; /* Start off with all interrupts disabled. */ imen = 0xffff; i8259_init(&atpics[MASTER], 0); i8259_init(&atpics[SLAVE], 1); atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]); + + /* Install low-level interrupt handlers for all of our IRQs. */ + for (i = 0; i < sizeof(atintrs) / sizeof(struct atpic_intsrc); i++) { + if (i == ICU_SLAVEID) + continue; + ai = &atintrs[i]; + ai->at_intsrc.is_count = &ai->at_count; + ai->at_intsrc.is_straycount = &ai->at_straycount; + setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase + + ai->at_irq, ai->at_intr, SDT_SYSIGT, SEL_KPL, 0); + } } static void atpic_init(void *dummy __unused) { - struct atpic_intsrc *ai; int i; /* Loop through all interrupt sources and add them. */ for (i = 0; i < sizeof(atintrs) / sizeof(struct atpic_intsrc); i++) { if (i == ICU_SLAVEID) continue; - ai = &atintrs[i]; - setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase + - ai->at_irq, ai->at_intr, SDT_SYSIGT, SEL_KPL, 0); - intr_register_source(&ai->at_intsrc); + intr_register_source(&atintrs[i].at_intsrc); } } SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL) @@ -311,7 +322,12 @@ atpic_handle_intr(void *cookie, struct intrframe iframe) KASSERT(vec < ICU_LEN, ("unknown int %d\n", vec)); isrc = &atintrs[vec].at_intsrc; - if (vec == 7 || vec == 15) { + + /* + * If we don't have an ithread, see if this is a spurious + * interrupt. + */ + if (isrc->is_ithread == NULL && (vec == 7 || vec == 15)) { int port, isr; /* |