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;