summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-02-08 21:40:59 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-02-08 21:40:59 +0000
commit25431b25fbe3b25002c7ace44412fe3805186b0e (patch)
tree763d1e0b76b7b638fcddab573e894f1eebb7d40f /sys
parent11f6e365339fb77ee766be771dcdfa5e0a461e17 (diff)
On 88110 processors, use a separate stack to handle NMI; these can occur
while we are switching pcbs and all sort of bad things could happen.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/m88k/include/cpu.h6
-rw-r--r--sys/arch/m88k/m88k/eh_common.S98
-rw-r--r--sys/arch/m88k/m88k/genassym.cf5
-rw-r--r--sys/arch/mvme88k/mvme88k/locore.S7
-rw-r--r--sys/arch/mvme88k/mvme88k/m197_machdep.c5
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c23
6 files changed, 103 insertions, 41 deletions
diff --git a/sys/arch/m88k/include/cpu.h b/sys/arch/m88k/include/cpu.h
index 7dae95065b7..96bd7a101e2 100644
--- a/sys/arch/m88k/include/cpu.h
+++ b/sys/arch/m88k/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.39 2008/12/21 21:43:51 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.40 2009/02/08 21:40:56 miod Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* Copyright (c) 1992, 1993
@@ -110,7 +110,9 @@ struct cpu_info {
#define CI_DDB_PAUSE 3
int ci_softintr; /* pending soft interrupts */
- u_int32_t ci_randseed;
+ u_int32_t ci_randseed; /* per-cpu random seed */
+
+ vaddr_t ci_nmi_stack; /* NMI stack (88110) */
#ifdef MULTIPROCESSOR
diff --git a/sys/arch/m88k/m88k/eh_common.S b/sys/arch/m88k/m88k/eh_common.S
index 84e27554050..011c60056f0 100644
--- a/sys/arch/m88k/m88k/eh_common.S
+++ b/sys/arch/m88k/m88k/eh_common.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: eh_common.S,v 1.46 2008/07/28 17:49:38 miod Exp $ */
+/* $OpenBSD: eh_common.S,v 1.47 2009/02/08 21:40:58 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -222,10 +222,13 @@
* cause other exceptions to happen, and the whole system is
* in a rather precarious state and so special cautions must
* be taken.
+ * The bit FLAG_NMI_STACK, on 88110, indicates that this exception
+ * should be handled on the NMI stack.
*/
#define FLAG_IGNORE_DATA_EXCEPTION 0
#define FLAG_ENABLING_FPU 1
#define FLAG_FROM_KERNEL 2
+#define FLAG_NMI_STACK 3
/* GENeral REGister OFFset into the E.F. (exception frame) */
#define GENREG_OFF(num) (EF_R0 + (num) * 4)
@@ -356,6 +359,8 @@
#define M88110_Data_Precheck \
bb1.n FLAG_IGNORE_DATA_EXCEPTION, FLAGS, \
_ASM_LABEL(m88110_ignore_data_exception);
+#define M88110_NMI_Precheck \
+ set FLAGS, FLAGS, 1<FLAG_NMI_STACK>
#ifdef M88100
/*
@@ -1598,9 +1603,9 @@ GLOBAL(m88110_fpu_handler)
or r3, r0, r30
XCALL(_C_LABEL(m88110_trap), _ASM_LABEL(check_ast))
-/* MVME197 non-maskable interrupt handler (ABORT button) */
+/* non-maskable interrupt handler (IPIs, ABORT button) */
GLOBAL(m88110_nonmaskable)
- PREP88110("NMI", 11,)
+ PREP88110("NMI", 11, M88110_NMI_Precheck)
or r2, r0, T_NON_MASK
or r3, r0, r30
XCALL(_C_LABEL(interrupt), _ASM_LABEL(check_ast))
@@ -1813,7 +1818,7 @@ ASLOCAL(m88110_setup_phase_one)
/*
* SR1: saved copy of exception-time register now holding FLAGS
* SR2: saved copy of exception-time r1
- * SR3: must be preserved .. may be the exception-time stack
+ * SR3: free
* r1: return address to calling exception handler
* FLAGS: CPU status flags
*
@@ -1828,33 +1833,17 @@ ASLOCAL(m88110_setup_phase_one)
NOP
NOP
- /* are we coming in from user mode? If so, pick up process pcb */
- bb0 FLAG_FROM_KERNEL, FLAGS, _ASM_LABEL(m88110_pickup_stack)
-
- /* Interrupt in kernel mode */
/*
- * SR1: saved copy of exception-time register now holding FLAGS
- * SR2: return address to the calling exception handler
- * SR3: must be preserved; may be important for other exceptions
- * FLAGS: CPU status flags
- *
- * immediate goal:
- * We're already on the kernel stack, but not having
- * needed to use SR3. We can just make room on the
- * stack (r31) for our exception frame.
+ * If we were in the kernel when the exception occured, we have
+ * a valid stack. Keep using it.
*/
- subu r31, r31, TRAPFRAME_SIZEOF /* r31 now our E.F. */
- st FLAGS,r31, EF_FLAGS /* save flags */
- st r1, r31, GENREG_OFF(1) /* save prev. r1 (now free) */
+ bb1 FLAG_FROM_KERNEL, FLAGS, _ASM_LABEL(m88110_kernel_stack)
- ldcr r1, SR3 /* save previous SR3 */
- st r1, r31, EF_SR3
-
- addu r1, r31, TRAPFRAME_SIZEOF /* save previous r31 */
- st r1, r31, GENREG_OFF(31)
- br _ASM_LABEL(m88110_have_pcb)
+ /* is this an NMI? If so, pick the NMI stack */
+ bb1 FLAG_NMI_STACK, FLAGS, _ASM_LABEL(m88110_nmi_stack)
ASLOCAL(m88110_pickup_stack)
+ /* Non-NMI exception in user mode */
/*
* SR1: saved copy of exception-time register now holding FLAGS
* SR2: return address to the calling exception handler
@@ -1862,9 +1851,7 @@ ASLOCAL(m88110_pickup_stack)
* FLAGS: CPU status flags
*
* immediate goal:
- * Since we're servicing an exception from user mode, we
- * know that SR3 is free. We use it to free up a temporary
- * register to be used in getting the process pcb.
+ * Pick the process PCB and point our stack to it.
*/
stcr r31, SR3 /* save previous r31 */
@@ -1883,6 +1870,50 @@ ASLOCAL(m88110_pickup_stack)
st r1, r31, GENREG_OFF(1) /* save prev. r1 (now free)*/
ldcr r1, SR3 /* save previous r31 */
st r1, r31, GENREG_OFF(31)
+ br _ASM_LABEL(m88110_have_pcb)
+
+ASLOCAL(m88110_nmi_stack)
+ /* NMI exception in user mode */
+ /*
+ * SR1: saved copy of exception-time register now holding FLAGS
+ * SR2: return address to the calling exception handler
+ * SR3: free
+ * FLAGS: CPU status flags
+ *
+ * immediate goal:
+ * Pick the cpu NMI stack.
+ */
+ stcr r31, SR3 /* save previous r31 */
+
+ /* switch to the NMI stack */
+ ldcr r31, CPU
+ ld r31, r31, CI_NMI_STACK
+ addu r31, r31, USPACE
+
+ subu r31, r31, TRAPFRAME_SIZEOF /* r31 now our E.F. */
+ st FLAGS,r31, EF_FLAGS /* save flags */
+ st r1, r31, GENREG_OFF(1) /* save prev. r1 (now free) */
+ ldcr r1, SR3 /* save previous r31 */
+ st r1, r31, GENREG_OFF(31)
+ br _ASM_LABEL(m88110_have_pcb)
+
+ASLOCAL(m88110_kernel_stack)
+ /* Exception in kernel mode */
+ /*
+ * SR1: saved copy of exception-time register now holding FLAGS
+ * SR2: return address to the calling exception handler
+ * SR3: free
+ * FLAGS: CPU status flags
+ *
+ * immediate goal:
+ * We're already on the kernel stack. We can just make room on the
+ * stack (r31) for our exception frame.
+ */
+ subu r31, r31, TRAPFRAME_SIZEOF /* r31 now our E.F. */
+ st FLAGS,r31, EF_FLAGS /* save flags */
+ st r1, r31, GENREG_OFF(1) /* save prev. r1 (now free) */
+ addu r1, r31, TRAPFRAME_SIZEOF /* save previous r31 */
+ st r1, r31, GENREG_OFF(31)
/* FALLTHROUGH */
ASLOCAL(m88110_have_pcb)
@@ -1897,6 +1928,10 @@ ASLOCAL(m88110_have_pcb)
* Exception-time r1, r31, FLAGS.
* Exception SR3, if appropriate.
*/
+
+ /* make sure that the FLAG_NMI_STACK bit is off */
+ clr FLAGS, FLAGS, 1<FLAG_NMI_STACK>
+
stcr TMP, SR3 /* free up TMP, TMP2, TMP3 */
SAVE_TMP2
SAVE_TMP3
@@ -1960,7 +1995,6 @@ ASLOCAL(m88110_setup_phase_two)
* Exception-time TMP2, TMP3.
* Exception-time espr, enip, exip.
* Exception number (EF_VECTOR).
- * Exception SR3, if appropriate.
*
* immediate goal:
* restore the system to the exception-time state (except SR3 will
@@ -2016,7 +2050,6 @@ ASLOCAL(m88110_shadow_enable)
st r30, TMP, GENREG_OFF(30) /* save previous r30, r31 */
st r31, TMP, GENREG_OFF(31) /* save previous r30, r31 */
or r31, TMP, r0 /* transfer E.F. pointer */
- ld TMP, r31, EF_SR3 /* get previous SR3 */
xcr TMP, TMP, SR3 /* replace TMP, SR3 */
/* now save all regs to the exception frame. */
@@ -2054,7 +2087,7 @@ ASLOCAL(m88110_shadow_enable)
/*
* SR1: free
* SR2: free
- * SR3: previous exception-time SR3
+ * SR3: free
* r1: return address to the calling exception handler
* r2 through r30: free
* r31: our exception frame
@@ -2065,7 +2098,6 @@ ASLOCAL(m88110_shadow_enable)
* Exception-time espr, enip, exip.
* Exception number (EF_VECTOR).
* DSR/ISR
- * Exception SR3, if appropriate.
*
* immediate goal:
* Put a copy of the exception frame pointer into r30
diff --git a/sys/arch/m88k/m88k/genassym.cf b/sys/arch/m88k/m88k/genassym.cf
index da3351166c0..05563cb829e 100644
--- a/sys/arch/m88k/m88k/genassym.cf
+++ b/sys/arch/m88k/m88k/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.17 2007/12/22 17:14:39 miod Exp $
+# $OpenBSD: genassym.cf,v 1.18 2009/02/08 21:40:58 miod Exp $
#
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -28,7 +28,7 @@
# SUCH DAMAGE.
#
# @(#)genassym.c 7.8 (Berkeley) 5/7/91
-# $Id: genassym.cf,v 1.17 2007/12/22 17:14:39 miod Exp $
+# $Id: genassym.cf,v 1.18 2009/02/08 21:40:58 miod Exp $
#
include <sys/param.h>
@@ -69,6 +69,7 @@ member ci_pfsr_d0
member ci_pfsr_d1
member ci_want_resched
member ci_softintr
+member ci_nmi_stack
# pcb fields
struct pcb
diff --git a/sys/arch/mvme88k/mvme88k/locore.S b/sys/arch/mvme88k/mvme88k/locore.S
index f7dc045a29a..291fee7edc5 100644
--- a/sys/arch/mvme88k/mvme88k/locore.S
+++ b/sys/arch/mvme88k/mvme88k/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.62 2008/10/30 22:06:59 miod Exp $ */
+/* $OpenBSD: locore.S,v 1.63 2009/02/08 21:40:58 miod Exp $ */
/*
* Copyright (c) 2005, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -328,6 +328,11 @@ ASGLOBAL(initstack)
space USPACE
ASGLOBAL(initstack_end)
+#ifdef M88110
+GLOBAL(nmi_stack) /* NMI stack for the boot processor */
+ space USPACE
+#endif
+
#ifdef MULTIPROCESSOR
space PAGE_SIZE /* 4K, small, interim stack */
ASLOCAL(slavestack_end)
diff --git a/sys/arch/mvme88k/mvme88k/m197_machdep.c b/sys/arch/mvme88k/mvme88k/m197_machdep.c
index e7cf6b7d774..f329cdeee56 100644
--- a/sys/arch/mvme88k/mvme88k/m197_machdep.c
+++ b/sys/arch/mvme88k/mvme88k/m197_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m197_machdep.c,v 1.27 2008/09/19 20:18:03 miod Exp $ */
+/* $OpenBSD: m197_machdep.c,v 1.28 2009/02/08 21:40:58 miod Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -201,8 +201,9 @@ m197_ext_int(u_int v, struct trapframe *eframe)
abort = *(u_int8_t *)(BS_BASE + BS_ABORT);
if (abort & BS_ABORT_INT) {
*(u_int8_t *)(BS_BASE + BS_ABORT) =
- abort | BS_ABORT_ICLR;
+ (abort & ~BS_ABORT_IEN) | BS_ABORT_ICLR;
nmihand(eframe);
+ *(u_int8_t *)(BS_BASE + BS_ABORT) |= BS_ABORT_IEN;
}
#ifdef MULTIPROCESSOR
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index b0350332c51..b67950eef54 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.215 2009/02/01 00:51:32 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.216 2009/02/08 21:40:58 miod Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -710,6 +710,20 @@ secondary_pre_main()
for (;;) ;
}
+ /*
+ * On 88110 processors, allocate UPAGES contiguous pages for
+ * the NMI handling stack.
+ */
+ if (CPU_IS88110) {
+ ci->ci_nmi_stack = uvm_km_zalloc(kernel_map, USPACE);
+ if (ci->ci_nmi_stack == (vaddr_t)NULL) {
+ printf("cpu%d: unable to allocate NMI stack\n",
+ ci->ci_cpuid);
+ __cpu_simple_unlock(&cpu_boot_mutex);
+ for (;;) ;
+ }
+ }
+
return (init_stack);
}
@@ -990,6 +1004,13 @@ mvme_bootstrap()
set_cpu_number(master_cpu);
SET(curcpu()->ci_flags, CIF_ALIVE | CIF_PRIMARY);
+#ifdef M88110
+ if (CPU_IS88110) {
+ extern vaddr_t nmi_stack;
+ curcpu()->ci_nmi_stack = nmi_stack;
+ }
+#endif
+
#ifdef M88100
if (CPU_IS88100) {
m88100_apply_patches();