diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-08 21:40:59 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-08 21:40:59 +0000 |
commit | 25431b25fbe3b25002c7ace44412fe3805186b0e (patch) | |
tree | 763d1e0b76b7b638fcddab573e894f1eebb7d40f /sys | |
parent | 11f6e365339fb77ee766be771dcdfa5e0a461e17 (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.h | 6 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/eh_common.S | 98 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/genassym.cf | 5 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/locore.S | 7 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/m197_machdep.c | 5 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/machdep.c | 23 |
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(); |