From a2a8479cbef6c47591fa1ae5907c9b6d47e7ba3e Mon Sep 17 00:00:00 2001 From: tsutsui Date: Fri, 14 Mar 2008 16:47:08 +0000 Subject: [PATCH] Fix spl(9) botch in cpu_intr() on ews4800mips: Don't enable unhandled interrupts before all interrupts are processed. --- sys/arch/ews4800mips/ews4800mips/tr2_intr.c | 25 ++++++++--------- sys/arch/ews4800mips/ews4800mips/tr2a_intr.c | 28 ++++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/sys/arch/ews4800mips/ews4800mips/tr2_intr.c b/sys/arch/ews4800mips/ews4800mips/tr2_intr.c index c2157922540f..fd3731ada382 100644 --- a/sys/arch/ews4800mips/ews4800mips/tr2_intr.c +++ b/sys/arch/ews4800mips/ews4800mips/tr2_intr.c @@ -1,4 +1,4 @@ -/* $NetBSD: tr2_intr.c,v 1.8 2008/01/04 22:15:09 ad Exp $ */ +/* $NetBSD: tr2_intr.c,v 1.9 2008/03/14 16:47:08 tsutsui Exp $ */ /*- * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tr2_intr.c,v 1.8 2008/01/04 22:15:09 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tr2_intr.c,v 1.9 2008/03/14 16:47:08 tsutsui Exp $"); #include #include @@ -150,9 +150,9 @@ tr2_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) { struct tr2_intr_handler *ih; struct clockframe cf; - uint32_t r, cause0; + uint32_t r, handled; - cause0 = cause; + handled = 0; if (ipending & MIPS_INT_MASK_5) { /* CLOCK */ cf.pc = pc; @@ -163,9 +163,9 @@ tr2_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) hardclock(&cf); timer_tr2_ev.ev_count++; - cause &= ~MIPS_INT_MASK_5; + handled |= MIPS_INT_MASK_5; } - _splset((status & MIPS_INT_MASK_5) | MIPS_SR_INT_IE); + _splset((status & handled) | MIPS_SR_INT_IE); if (ipending & MIPS_INT_MASK_4) { /* KBD, MOUSE, SERIAL */ r = *PICNIC_INT4_STATUS_REG; @@ -191,9 +191,9 @@ tr2_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) r &= ~PICNIC_INT_SERIAL; } - cause &= ~MIPS_INT_MASK_4; + handled |= MIPS_INT_MASK_4; } - _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + _splset((status & handled) | MIPS_SR_INT_IE); if (ipending & MIPS_INT_MASK_3) { /* VME */ printf("VME interrupt\n"); @@ -230,7 +230,7 @@ tr2_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) } if ((r & PICNIC_INT_FDDLPT) && - ((cause0 & status) & MIPS_INT_MASK_5)) { + ((cause & status) & MIPS_INT_MASK_5)) { #ifdef DEBUG printf("FDD LPT interrupt\n"); #endif @@ -242,9 +242,9 @@ tr2_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) r &= ~PICNIC_INT_FDDLPT; } - cause &= ~MIPS_INT_MASK_2; + handled |= MIPS_INT_MASK_2; } - _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + _splset((status & handled) | MIPS_SR_INT_IE); if (ipending & MIPS_INT_MASK_1) panic("unknown interrupt INT1\n"); @@ -257,8 +257,9 @@ tr2_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) } else { printf("unknown interrupt INT0\n"); } - cause &= ~MIPS_INT_MASK_0; + handled |= MIPS_INT_MASK_0; } + cause &= ~handled; _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); } diff --git a/sys/arch/ews4800mips/ews4800mips/tr2a_intr.c b/sys/arch/ews4800mips/ews4800mips/tr2a_intr.c index 5ea14bb51e8e..69ba7ac351fd 100644 --- a/sys/arch/ews4800mips/ews4800mips/tr2a_intr.c +++ b/sys/arch/ews4800mips/ews4800mips/tr2a_intr.c @@ -1,4 +1,4 @@ -/* $NetBSD: tr2a_intr.c,v 1.10 2008/01/04 22:15:09 ad Exp $ */ +/* $NetBSD: tr2a_intr.c,v 1.11 2008/03/14 16:47:08 tsutsui Exp $ */ /*- * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tr2a_intr.c,v 1.10 2008/01/04 22:15:09 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tr2a_intr.c,v 1.11 2008/03/14 16:47:08 tsutsui Exp $"); #include #include @@ -189,8 +189,9 @@ tr2a_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) { struct tr2a_intr_handler *ih; struct clockframe cf; - uint32_t r, intc_cause; + uint32_t r, intc_cause, handled; + handled = 0; intc_cause = *INTC_STATUS_REG & *INTC_MASK_REG; if ((ipending & MIPS_INT_MASK_5) && (intc_cause & INTC_INT5)) { @@ -202,9 +203,9 @@ tr2a_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) hardclock(&cf); timer_tr2a_ev.ev_count++; - cause &= ~MIPS_INT_MASK_5; + handled |= MIPS_INT_MASK_5; } - _splset((status & MIPS_INT_MASK_5) | MIPS_SR_INT_IE); + _splset((status & handled) | MIPS_SR_INT_IE); if ((ipending & MIPS_INT_MASK_4) && (intc_cause & INTC_INT4)) { @@ -237,9 +238,9 @@ tr2a_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) *INTC_CLEAR_REG = 0x68; *INTC_STATUS_REG; - cause &= ~MIPS_INT_MASK_4; + handled |= MIPS_INT_MASK_4; } - _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + _splset((status & handled) | MIPS_SR_INT_IE); if ((ipending & MIPS_INT_MASK_3) && (intc_cause & INTC_INT3)) { /* APbus HI */ @@ -247,9 +248,8 @@ tr2a_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) tr2a_wbflush(); *INTC_CLEAR_REG = 0x54; *INTC_STATUS_REG; - cause &= ~MIPS_INT_MASK_3; + handled |= MIPS_INT_MASK_3; } - _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); if ((ipending & MIPS_INT_MASK_2) && (intc_cause & INTC_INT2)) { /* SCSI, ETHER */ @@ -280,9 +280,9 @@ tr2a_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) tr2a_wbflush(); *INTC_CLEAR_REG = 0x40; *INTC_STATUS_REG; - cause &= ~MIPS_INT_MASK_2; + handled |= MIPS_INT_MASK_2; } - _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); + _splset((status & handled) | MIPS_SR_INT_IE); if ((ipending & MIPS_INT_MASK_1) && (intc_cause & INTC_INT1)) { /* APbus LO */ @@ -290,9 +290,8 @@ tr2a_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) tr2a_wbflush(); *INTC_CLEAR_REG = 0x2c; *INTC_STATUS_REG; - cause &= ~MIPS_INT_MASK_1; + handled |= MIPS_INT_MASK_1; } - _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); if ((ipending & MIPS_INT_MASK_0) && (intc_cause & INTC_INT0)) { /* NMI etc. */ @@ -310,8 +309,9 @@ tr2a_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending) tr2a_wbflush(); *INTC_CLEAR_REG = 0x14; *INTC_STATUS_REG; - cause &= ~MIPS_INT_MASK_0; + handled |= MIPS_INT_MASK_0; } + cause &= ~handled; _splset(((status & ~cause) & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); }