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).
This commit is contained in:
parent
73fa5bcac3
commit
4fada584a6
|
@ -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 @@ cpu_configure(void)
|
|||
/*
|
||||
* 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 */
|
||||
|
|
|
@ -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 @@ void to_monitor(int) __attribute__((__noreturn__));
|
|||
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 @@ mach_init(int x_boothowto, int x_bootdev, int x_bootname, int x_maxmem)
|
|||
* Initialize locore-function vector.
|
||||
* Clear out the I and D caches.
|
||||
*/
|
||||
ipl_sr_map = newsmips_ipl_sr_map;
|
||||
mips_vector_init(NULL, false);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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>
|
||||
|
@ -58,6 +58,27 @@ static volatile int badaddr_flag;
|
|||
|
||||
#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.
|
||||
*/
|
||||
|
@ -179,10 +200,16 @@ news3400_level1_intr(void)
|
|||
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 @@ news3400_badaddr(void *addr, u_int size)
|
|||
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 @@ news3400_disable_intr(void)
|
|||
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 @@ void
|
|||
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;
|
||||
|
|
|
@ -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>
|
||||
|
@ -52,6 +52,27 @@ static void news5000_readidrom(uint8_t *);
|
|||
static void news5000_tc_init(void);
|
||||
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.
|
||||
*/
|
||||
|
@ -259,6 +280,8 @@ void
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue