diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-03-01 17:43:26 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-03-01 17:43:26 +0000 |
commit | cec7dc19b3324cb403321874029d652f4a378a2d (patch) | |
tree | 9fcc9b89a72891f2ee5dddd9e3e6a75dfff77e81 | |
parent | 8f54fb6926d4725e4d6342aa5abe1e249a028cf8 (diff) |
Files forgotten during last commit:
Rework nmi handling to handle ``complex'' NMI faster, and return as fast as
possible from the exception, without doing the AST and softintr dance.
This should avoid too much stack usage under load.
ok deraadt@
-rw-r--r-- | sys/arch/m88k/include/trap.h | 7 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/eh_common.S | 122 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/trap.c | 15 |
3 files changed, 117 insertions, 27 deletions
diff --git a/sys/arch/m88k/include/trap.h b/sys/arch/m88k/include/trap.h index 6c65ba34f4a..642b447d1b6 100644 --- a/sys/arch/m88k/include/trap.h +++ b/sys/arch/m88k/include/trap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.h,v 1.8 2009/02/16 22:55:03 miod Exp $ */ +/* $OpenBSD: trap.h,v 1.9 2009/03/01 17:43:23 miod Exp $ */ /* * Mach Operating System * Copyright (c) 1992 Carnegie Mellon University @@ -57,10 +57,11 @@ #ifndef _LOCORE -void cache_flush(struct trapframe *); void ast(struct trapframe *); -void nmi(struct trapframe *); +void cache_flush(struct trapframe *); void interrupt(struct trapframe *); +int nmi(struct trapframe *); +void nmi_wrapup(struct trapframe *); void m88100_syscall(register_t, struct trapframe *); void m88100_trap(u_int, struct trapframe *); diff --git a/sys/arch/m88k/m88k/eh_common.S b/sys/arch/m88k/m88k/eh_common.S index 1b48c14b9a8..b122fa25c96 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.52 2009/02/21 18:35:22 miod Exp $ */ +/* $OpenBSD: eh_common.S,v 1.53 2009/03/01 17:43:25 miod Exp $ */ /* * Mach Operating System * Copyright (c) 1993-1991 Carnegie Mellon University @@ -1601,7 +1601,7 @@ GLOBAL(m88110_fpu_handler) GLOBAL(m88110_nonmaskable) PREP88110("NMI", 11,) or r2, r0, r30 - XCALL(_C_LABEL(nmi), _ASM_LABEL(check_ast)) + XCALL(_C_LABEL(nmi), _ASM_LABEL(nmi_return)) /* software walk data MMU read miss handler */ GLOBAL(m88110_data_read_miss) @@ -2213,17 +2213,15 @@ ASGLOBAL(ast_done) bsr.n _C_LABEL(setipl) ld r2, FPTR, EF_MASK /* get pre-exception ipl */ - /* - * Disable shadowing. This used to be done after all the registers - * from the E.F. have been restored, but on 88110 we may receive - * an NMI anytime, unless shadowing is frozen, and we rely on r31 - * being valid. - */ - ldcr r1, PSR - set r1, r1, 1<PSR_SHADOW_FREEZE_BIT> - stcr r1, PSR - FLUSH_PIPELINE +#if defined(M88100) && defined(M88110) + ldcr r2, PID + extu r3, r2, 8<8> + bcnd ne0, r3, _ASM_LABEL(m88110_user_rte) + /* FALLTHROUGH */ +#endif +#ifdef M88100 +ASGLOBAL(m88100_user_rte) /* * Transfer the frame pointer to r31, since we no longer need a stack. * No page faults here, and interrupts are disabled. @@ -2260,16 +2258,13 @@ ASGLOBAL(ast_done) ld r29, r31, GENREG_OFF(29) /* restore r1, r30, r31 later */ - /* reload the control regs*/ -#if defined(M88100) && defined(M88110) - ldcr r1, PID - extu r30, r1, 8<8> - bcnd ne0, r30, _ASM_LABEL(m88110_user_rte) - /* FALLTHROUGH */ -#endif + /* disable shadowing */ + ldcr r1, PSR + set r1, r1, 1<PSR_SHADOW_FREEZE_BIT> + stcr r1, PSR + FLUSH_PIPELINE -#ifdef M88100 -ASGLOBAL(m88100_user_rte) + /* reload the control regs*/ /* * RTE will cause execution to continue first with the * instruction pointed to by the NIP and then the FIP; @@ -2294,6 +2289,55 @@ ASGLOBAL(m88100_user_rte) #ifdef M88110 ASGLOBAL(m88110_user_rte) + /* + * Disable shadowing. This used to be done after all the registers + * from the E.F. have been restored, but on 88110 we may receive + * an NMI anytime, unless shadowing is frozen, and we rely on r31 + * being valid. + */ + ldcr r1, PSR + set r1, r1, 1<PSR_SHADOW_FREEZE_BIT> + stcr r1, PSR + FLUSH_PIPELINE + +ASLOCAL(m88110_restore) + /* + * Transfer the frame pointer to r31, since we no longer need a stack. + * No page faults here, and interrupts are disabled. + */ + or r31, r0, FPTR + /* restore r1 later */ + ld r2 , r31, GENREG_OFF(2) + ld r3 , r31, GENREG_OFF(3) + ld r4 , r31, GENREG_OFF(4) + ld r5 , r31, GENREG_OFF(5) + ld r6 , r31, GENREG_OFF(6) + ld r7 , r31, GENREG_OFF(7) + ld r8 , r31, GENREG_OFF(8) + ld r9 , r31, GENREG_OFF(9) + ld r10, r31, GENREG_OFF(10) + ld r11, r31, GENREG_OFF(11) + ld r12, r31, GENREG_OFF(12) + ld r13, r31, GENREG_OFF(13) + ld r14, r31, GENREG_OFF(14) + ld r15, r31, GENREG_OFF(15) + ld r16, r31, GENREG_OFF(16) + ld r17, r31, GENREG_OFF(17) + ld r18, r31, GENREG_OFF(18) + ld r19, r31, GENREG_OFF(19) + ld r20, r31, GENREG_OFF(20) + ld r21, r31, GENREG_OFF(21) + ld r22, r31, GENREG_OFF(22) + ld r23, r31, GENREG_OFF(23) + ld r24, r31, GENREG_OFF(24) + ld r25, r31, GENREG_OFF(25) + ld r26, r31, GENREG_OFF(26) + ld r27, r31, GENREG_OFF(27) + ld r28, r31, GENREG_OFF(28) + ld r29, r31, GENREG_OFF(29) + /* restore r1, r30, r31 later */ + + /* reload the control regs*/ ld r30, r31, EF_ENIP ld r1, r31, EF_EXIP stcr r30, ENIP @@ -2324,4 +2368,40 @@ ASGLOBAL(m88110_user_rte) 1: NOP RTE + + /* + * NMI return here after processing. + * We then decide whether to check for AST and soft interrupts, + * or not. + */ +ASLOCAL(nmi_return) + bcnd ne0, r2, _ASM_LABEL(check_ast) + + ld FPTR, r31, 0 /* grab exception frame pointer */ + + /* + * Disable interrupts and shadowing. The latter used to be done + * after all the registers from the E.F. have been restored, but + * on 88110 we may receive an NMI anytime, unless shadowing is frozen, + * and we rely on r31 being valid. + */ + ldcr r1, PSR + set r1, r1, 1<PSR_INTERRUPT_DISABLE_BIT> + set r1, r1, 1<PSR_SHADOW_FREEZE_BIT> + stcr r1, PSR + FLUSH_PIPELINE + + /* now ready to return....*/ + bsr.n _C_LABEL(setipl) + ld r2, FPTR, EF_MASK /* get pre-exception ipl */ + +#ifdef MULTIPROCESSOR + /* + * Reenable NMIs if necessary. + */ + or r2, FPTR, r0 + bsr _C_LABEL(nmi_wrapup) +#endif + + br _ASM_LABEL(m88110_restore) #endif diff --git a/sys/arch/m88k/m88k/trap.c b/sys/arch/m88k/m88k/trap.c index cbaacef4d26..50539debcb5 100644 --- a/sys/arch/m88k/m88k/trap.c +++ b/sys/arch/m88k/m88k/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.68 2009/02/16 22:55:03 miod Exp $ */ +/* $OpenBSD: trap.c,v 1.69 2009/03/01 17:43:25 miod Exp $ */ /* * Copyright (c) 2004, Miodrag Vallat. * Copyright (c) 1998 Steve Murphree, Jr. @@ -191,10 +191,19 @@ interrupt(struct trapframe *frame) /* * Handle non-maskable interrupts. */ -void +int nmi(struct trapframe *frame) { - md_nmi_func(frame); + return md_nmi_func(frame); +} + +/* + * Reenable non-maskable interrupts. + */ +void +nmi_wrapup(struct trapframe *frame) +{ + md_nmi_wrapup_func(frame); } #endif |