Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/newsmips/newsmips Fix newsmips interrupt handling f...



details:   https://anonhg.NetBSD.org/src/rev/92bb227cdeaf
branches:  trunk
changeset: 763057:92bb227cdeaf
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Wed Mar 09 13:21:36 2011 +0000

description:
Fix newsmips interrupt handling for new mips interrupt/spl framework:
 - make news3400_badaddr() work even if interrupts are disabled
   (in the old world bus error interrupt is enabled even during splhigh())
 - make ipl_sr_map values model dependent

Now GENERIC kernel boots to single user properly on R3000 NWS-3470D,
though sh(1) still gets floating point exceptions during /etc/rc scripts.
news5000 is untested (yet).

diffstat:

 sys/arch/newsmips/newsmips/autoconf.c |  15 +++-------
 sys/arch/newsmips/newsmips/machdep.c  |  26 +------------------
 sys/arch/newsmips/newsmips/news3400.c |  45 ++++++++++++++++++++++++++++++++--
 sys/arch/newsmips/newsmips/news5000.c |  27 +++++++++++++++++++-
 4 files changed, 74 insertions(+), 39 deletions(-)

diffs (248 lines):

diff -r a544af4995e0 -r 92bb227cdeaf sys/arch/newsmips/newsmips/autoconf.c
--- a/sys/arch/newsmips/newsmips/autoconf.c     Wed Mar 09 12:56:08 2011 +0000
+++ b/sys/arch/newsmips/newsmips/autoconf.c     Wed Mar 09 13:21:36 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.c,v 1.34 2011/02/20 07:56:31 matt Exp $       */
+/*     $NetBSD: autoconf.c,v 1.35 2011/03/09 13:21:36 tsutsui Exp $    */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -49,7 +49,7 @@
 #define __INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.34 2011/02/20 07:56:31 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.35 2011/03/09 13:21:36 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -94,19 +94,14 @@
        /*
         * Kick off autoconfiguration
         */
-       spl0();         /* enable all interrupts */
-       splhigh();      /* ...then disable device interrupts */
-
-       if (systype == NEWS3400) {
-               *(char *)INTEN0 = INTEN0_BERR;  /* only buserr occurs */
-               *(char *)INTEN1 = 0;
-       }
+       (*disable_intr)();
+       (void)splhigh();
 
        if (config_rootfound("mainbus", NULL) == NULL)
                panic("no mainbus found");
 
        /* Enable hardware interrupt registers. */
-       enable_intr();
+       (*enable_intr)();
 
        /* Configuration is finished, turn on interrupts. */
        spl0();         /* enable all source forcing SOFT_INTs cleared */
diff -r a544af4995e0 -r 92bb227cdeaf sys/arch/newsmips/newsmips/machdep.c
--- a/sys/arch/newsmips/newsmips/machdep.c      Wed Mar 09 12:56:08 2011 +0000
+++ b/sys/arch/newsmips/newsmips/machdep.c      Wed Mar 09 13:21:36 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.112 2011/02/20 07:56:31 matt Exp $       */
+/*     $NetBSD: machdep.c,v 1.113 2011/03/09 13:21:36 tsutsui Exp $    */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.112 2011/02/20 07:56:31 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.113 2011/03/09 13:21:36 tsutsui Exp $");
 
 /* from: Utah Hdr: machdep.c 1.63 91/04/24 */
 
@@ -138,27 +138,6 @@
 extern void stacktrace(void); /*XXX*/
 #endif
 
-/*
- * This is a mask of bits to clear in the SR when we go to a
- * given interrupt priority level.
- */
-const struct ipl_sr_map newsmips_ipl_sr_map = {
-    .sr_bits = {
-       [IPL_NONE] =            0,
-       [IPL_SOFTCLOCK] =       MIPS_SOFT_INT_MASK_0,
-       [IPL_SOFTNET] =         MIPS_SOFT_INT_MASK,
-       [IPL_VM] =              MIPS_SOFT_INT_MASK
-                               | MIPS_INT_MASK_0
-                               | MIPS_INT_MASK_1,
-       [IPL_SCHED] =           MIPS_SOFT_INT_MASK
-                               | MIPS_INT_MASK_0
-                               | MIPS_INT_MASK_1
-                               | MIPS_INT_MASK_2,
-       [IPL_DDB] =             MIPS_INT_MASK,
-       [IPL_HIGH] =            MIPS_INT_MASK,
-    },
-};
-
 extern u_long bootdev;
 extern char edata[], end[];
 
@@ -284,7 +263,6 @@
         * Initialize locore-function vector.
         * Clear out the I and D caches.
         */
-       ipl_sr_map = newsmips_ipl_sr_map;
        mips_vector_init(NULL, false);
 
        /*
diff -r a544af4995e0 -r 92bb227cdeaf sys/arch/newsmips/newsmips/news3400.c
--- a/sys/arch/newsmips/newsmips/news3400.c     Wed Mar 09 12:56:08 2011 +0000
+++ b/sys/arch/newsmips/newsmips/news3400.c     Wed Mar 09 13:21:36 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: news3400.c,v 1.20 2011/02/20 07:56:31 matt Exp $       */
+/*     $NetBSD: news3400.c,v 1.21 2011/03/09 13:21:36 tsutsui Exp $    */
 
 /*-
  * Copyright (C) 1999 Tsubai Masanari.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: news3400.c,v 1.20 2011/02/20 07:56:31 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: news3400.c,v 1.21 2011/03/09 13:21:36 tsutsui Exp $");
 
 #define __INTR_PRIVATE
 #include <sys/param.h>
@@ -59,6 +59,27 @@
 #define INT_MASK_FPU MIPS_INT_MASK_3
 
 /*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+static const struct ipl_sr_map news3400_ipl_sr_map = {
+    .sr_bits = {
+       [IPL_NONE] =            0,
+       [IPL_SOFTCLOCK] =       MIPS_SOFT_INT_MASK_0,
+       [IPL_SOFTNET] =         MIPS_SOFT_INT_MASK,
+       [IPL_VM] =              MIPS_SOFT_INT_MASK
+                               | MIPS_INT_MASK_0
+                               | MIPS_INT_MASK_1,
+       [IPL_SCHED] =           MIPS_SOFT_INT_MASK
+                               | MIPS_INT_MASK_0
+                               | MIPS_INT_MASK_1
+                               | MIPS_INT_MASK_2,
+       [IPL_DDB] =             MIPS_INT_MASK,
+       [IPL_HIGH] =            MIPS_INT_MASK,
+    },
+};
+
+/*
  * Handle news3400 interrupts.
  */
 void
@@ -179,10 +200,16 @@
 int
 news3400_badaddr(void *addr, u_int size)
 {
+       uint32_t cause;
        volatile u_int x;
+       volatile uint8_t *intclr0 = (void *)INTCLR0;
 
        badaddr_flag = 0;
 
+       /* clear bus error interrupt */
+       *intclr0 = INTCLR0_BERR;
+
+       /* bus error will cause INT4 */
        switch (size) {
        case 1:
                x = *(volatile uint8_t *)addr;
@@ -195,6 +222,15 @@
                break;
        }
 
+       /* also check CPU INT4 here for bus errors during splhigh() */
+       if (badaddr_flag == 0) {
+               cause = mips_cp0_cause_read();
+               if ((cause & MIPS_INT_MASK_4) != 0) {
+                       badaddr_flag = 1;
+                       *intclr0 = INTCLR0_BERR;
+               }
+       }
+
        return badaddr_flag;
 }
 
@@ -233,7 +269,8 @@
        volatile uint8_t *inten0 = (void *)INTEN0;
        volatile uint8_t *inten1 = (void *)INTEN1;
 
-       *inten0 = 0;
+       /* always enable bus error check so that news3400_badaddr() works */
+       *inten0 = INTEN0_BERR;
        *inten1 = 0;
 }
 
@@ -264,6 +301,8 @@
 news3400_init(void)
 {
 
+       ipl_sr_map = news3400_ipl_sr_map;
+
        enable_intr = news3400_enable_intr;
        disable_intr = news3400_disable_intr;
        enable_timer = news3400_enable_timer;
diff -r a544af4995e0 -r 92bb227cdeaf sys/arch/newsmips/newsmips/news5000.c
--- a/sys/arch/newsmips/newsmips/news5000.c     Wed Mar 09 12:56:08 2011 +0000
+++ b/sys/arch/newsmips/newsmips/news5000.c     Wed Mar 09 13:21:36 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: news5000.c,v 1.18 2011/02/20 07:56:32 matt Exp $       */
+/*     $NetBSD: news5000.c,v 1.19 2011/03/09 13:21:36 tsutsui Exp $    */
 
 /*-
  * Copyright (C) 1999 SHIMIZU Ryo.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: news5000.c,v 1.18 2011/02/20 07:56:32 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: news5000.c,v 1.19 2011/03/09 13:21:36 tsutsui Exp $");
 
 #define __INTR_PRIVATE
 #include <sys/param.h>
@@ -53,6 +53,27 @@
 static uint32_t news5000_getfreerun(struct timecounter *);
 
 /*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+static const struct ipl_sr_map news5000_ipl_sr_map = {
+    .sr_bits = {
+       [IPL_NONE] =            0,
+       [IPL_SOFTCLOCK] =       MIPS_SOFT_INT_MASK_0,
+       [IPL_SOFTNET] =         MIPS_SOFT_INT_MASK,
+       [IPL_VM] =              MIPS_SOFT_INT_MASK
+                               | MIPS_INT_MASK_0
+                               | MIPS_INT_MASK_1,
+       [IPL_SCHED] =           MIPS_SOFT_INT_MASK
+                               | MIPS_INT_MASK_0
+                               | MIPS_INT_MASK_1
+                               | MIPS_INT_MASK_2,
+       [IPL_DDB] =             MIPS_INT_MASK,
+       [IPL_HIGH] =            MIPS_INT_MASK,
+    },
+};
+
+/*
  * Handle news5000 interrupts.
  */
 void
@@ -259,6 +280,8 @@
 news5000_init(void)
 {
 
+       ipl_sr_map = news5000_ipl_sr_map;
+
        enable_intr = news5000_enable_intr;
        disable_intr = news5000_disable_intr;
        enable_timer = news5000_enable_timer;



Home | Main Index | Thread Index | Old Index