Module Name:    src
Committed By:   tsutsui
Date:           Wed Mar  9 13:21:36 UTC 2011

Modified Files:
        src/sys/arch/newsmips/newsmips: autoconf.c machdep.c news3400.c
            news5000.c

Log Message:
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).


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/newsmips/newsmips/autoconf.c
cvs rdiff -u -r1.112 -r1.113 src/sys/arch/newsmips/newsmips/machdep.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/newsmips/newsmips/news3400.c
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/newsmips/newsmips/news5000.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/newsmips/newsmips/autoconf.c
diff -u src/sys/arch/newsmips/newsmips/autoconf.c:1.34 src/sys/arch/newsmips/newsmips/autoconf.c:1.35
--- src/sys/arch/newsmips/newsmips/autoconf.c:1.34	Sun Feb 20 07:56:31 2011
+++ src/sys/arch/newsmips/newsmips/autoconf.c	Wed Mar  9 13:21:36 2011
@@ -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 */

Index: src/sys/arch/newsmips/newsmips/machdep.c
diff -u src/sys/arch/newsmips/newsmips/machdep.c:1.112 src/sys/arch/newsmips/newsmips/machdep.c:1.113
--- src/sys/arch/newsmips/newsmips/machdep.c:1.112	Sun Feb 20 07:56:31 2011
+++ src/sys/arch/newsmips/newsmips/machdep.c	Wed Mar  9 13:21:36 2011
@@ -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);
 
 	/*

Index: src/sys/arch/newsmips/newsmips/news3400.c
diff -u src/sys/arch/newsmips/newsmips/news3400.c:1.20 src/sys/arch/newsmips/newsmips/news3400.c:1.21
--- src/sys/arch/newsmips/newsmips/news3400.c:1.20	Sun Feb 20 07:56:31 2011
+++ src/sys/arch/newsmips/newsmips/news3400.c	Wed Mar  9 13:21:36 2011
@@ -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;

Index: src/sys/arch/newsmips/newsmips/news5000.c
diff -u src/sys/arch/newsmips/newsmips/news5000.c:1.18 src/sys/arch/newsmips/newsmips/news5000.c:1.19
--- src/sys/arch/newsmips/newsmips/news5000.c:1.18	Sun Feb 20 07:56:32 2011
+++ src/sys/arch/newsmips/newsmips/news5000.c	Wed Mar  9 13:21:36 2011
@@ -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;

Reply via email to