Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/mips/mips Add mipsX_nonmaskable_intr if DDB is defi...
details: https://anonhg.NetBSD.org/src/rev/9a8773a82b34
branches: trunk
changeset: 338757:9a8773a82b34
user: matt <matt%NetBSD.org@localhost>
date: Sat Jun 06 21:48:45 2015 +0000
description:
Add mipsX_nonmaskable_intr if DDB is defined.
Add missing */ at end of comment.
Use trap instructon on mipsNN in paranoia sections instead of endless loop.
diffstat:
sys/arch/mips/mips/mipsX_subr.S | 157 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 152 insertions(+), 5 deletions(-)
diffs (223 lines):
diff -r 6e77e725132e -r 9a8773a82b34 sys/arch/mips/mips/mipsX_subr.S
--- a/sys/arch/mips/mips/mipsX_subr.S Sat Jun 06 21:46:17 2015 +0000
+++ b/sys/arch/mips/mips/mipsX_subr.S Sat Jun 06 21:48:45 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mipsX_subr.S,v 1.58 2015/06/04 02:27:25 matt Exp $ */
+/* $NetBSD: mipsX_subr.S,v 1.59 2015/06/06 21:48:45 matt Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -622,7 +622,7 @@
NESTED_NOPROFILE(MIPSX(kern_gen_exception), KERNFRAME_SIZ, ra)
.set noat
.mask 0x80000000, -4
-#ifdef PARANOIA
+#if defined(PARANOIA)
PTR_L k0, L_PCB(MIPS_CURLWP)
slt k0, k0, sp # k0 = L_PCB(MIPS_CURLWP) < sp
1: beqz k0, 1b # loop forever if false
@@ -632,7 +632,7 @@
slt k0, sp, k0 # k0 = sp < L_PCB(MIPS_CURLWP) + USPACE
2: beqz k0, 2b # loop forever if false
nop
-#endif /* PARANOIA
+#endif /* PARANOIA */
/*
* Save the relevant kernel registers onto the stack.
* We don't need to save s0 - s8, sp and gp because
@@ -700,7 +700,7 @@
INT_S t1, TF_BASE+TF_PPL(sp) # save priority level
#endif /* PARANOIA */
-#if defined(DDB) || defined(DEBUG) || defined(KGDB)
+#if defined(__mips_o32) && (defined(DDB) || defined(DEBUG) || defined(KGDB))
PTR_ADDU v0, sp, KERNFRAME_SIZ
REG_S v0, KERNFRAME_SP(sp)
#endif
@@ -726,9 +726,11 @@
xor v0, a0, v1 # generate new status
mtc0 v0, MIPS_COP_0_STATUS # update.
COP0_SYNC
+#ifdef MIPS3
nop
nop
nop
+#endif
/*
* Call the trap handler.
*/
@@ -740,9 +742,11 @@
*/
RESET_EXCEPTION_LEVEL_DISABLE_INTERRUPTS(v0)
COP0_SYNC
+#ifdef MIPS3
nop # 3 nop delay
nop
nop
+#endif
REG_L a0, TF_BASE+TF_REG_SR(sp) # get SR with EXL set
mtc0 a0, MIPS_COP_0_STATUS # restore the SR, disable intrs
COP0_SYNC
@@ -821,6 +825,145 @@
.set at
END(MIPSX(kern_gen_exception))
+#ifdef DDB
+/*
+ * mipsN_kern_nonmaskable_intr
+ *
+ * Handle a NMI during kernel mode.
+ * Build trapframe on stack to hold interrupted kernel context, then
+ * call trap() to process the condition.
+ *
+ * trapframe is pointed to by the 5th arg and a dummy sixth argument is used
+ * to avoid alignment problems
+ * {
+ * register_t cf_args[4 + 1];
+ * register_t cf_pad; (for 8 word alignment)
+ * register_t cf_sp;
+ * register_t cf_ra;
+ * struct reg cf_tf;
+ * };
+ */
+NESTED_NOPROFILE(MIPSX(kern_nonmaskable_intr), KERNFRAME_SIZ, ra)
+ .set noat
+ .mask 0x80000000, -4
+#if defined(PARANOIA)
+ PTR_L k0, L_PCB(MIPS_CURLWP)
+ slt k0, k0, sp # k0 = L_PCB(MIPS_CURLWP) < sp
+1: beqz k0, 1b # loop forever if false
+ nop
+
+ PTR_L k0, L_PCB(MIPS_CURLWP)
+ PTR_ADDU k0, USPACE
+ slt k0, sp, k0 # k0 = sp < L_PCB(MIPS_CURLWP) + USPACE
+2: beqz k0, 2b # loop forever if false
+ nop
+#endif /* PARANOIA */
+
+/*
+ * Save the relevant kernel registers onto the NMI stack.
+ * We save s0 - s8, sp and gp so DDB can see them.
+ */
+ move k1, sp # save for later
+ PTR_L sp, CPU_INFO_NMI_STACK(k0) # get NMI stack
+ REG_S k1, TF_BASE+TF_REG_SP(sp)
+ REG_S AT, TF_BASE+TF_REG_AST(sp)
+ REG_S v0, TF_BASE+TF_REG_V0(sp)
+ REG_S v1, TF_BASE+TF_REG_V1(sp)
+ mflo v0
+ mfhi v1
+
+ REG_S a0, TF_BASE+TF_REG_A0(sp)
+ REG_S a1, TF_BASE+TF_REG_A1(sp)
+ REG_S a2, TF_BASE+TF_REG_A2(sp)
+ REG_S a3, TF_BASE+TF_REG_A3(sp)
+ mfc0 a0, MIPS_COP_0_STATUS # 1st arg is STATUS
+ REG_S t0, TF_BASE+TF_REG_T0(sp)
+ REG_S t1, TF_BASE+TF_REG_T1(sp)
+ REG_S t2, TF_BASE+TF_REG_T2(sp)
+ REG_S t3, TF_BASE+TF_REG_T3(sp)
+ mfc0 a1, MIPS_COP_0_CAUSE # 2nd arg is CAUSE
+ REG_S ta0, TF_BASE+TF_REG_TA0(sp)
+ REG_S ta1, TF_BASE+TF_REG_TA1(sp)
+ REG_S ta2, TF_BASE+TF_REG_TA2(sp)
+ REG_S ta3, TF_BASE+TF_REG_TA3(sp)
+ _MFC0 a2, MIPS_COP_0_BAD_VADDR # 3rd arg is fault address
+ REG_S t8, TF_BASE+TF_REG_T8(sp) # is MIPS_CURLWP
+ REG_S t9, TF_BASE+TF_REG_T9(sp)
+ REG_S ra, TF_BASE+TF_REG_RA(sp)
+ REG_S a0, TF_BASE+TF_REG_SR(sp)
+ _MFC0 a3, MIPS_COP_0_ERROR_PC # 4th arg is exception PC
+ REG_S v0, TF_BASE+TF_REG_MULLO(sp)
+ REG_S v1, TF_BASE+TF_REG_MULHI(sp)
+ REG_S a3, TF_BASE+TF_REG_EPC(sp)
+ REG_S a1, TF_BASE+TF_REG_CAUSE(sp)
+ REG_S s0, TF_BASE+TF_REG_S0(sp)
+ REG_S s1, TF_BASE+TF_REG_S1(sp)
+ REG_S s2, TF_BASE+TF_REG_S2(sp)
+ REG_S s3, TF_BASE+TF_REG_S3(sp)
+ REG_S s4, TF_BASE+TF_REG_S4(sp)
+ REG_S s5, TF_BASE+TF_REG_S5(sp)
+ REG_S s6, TF_BASE+TF_REG_S6(sp)
+ REG_S s7, TF_BASE+TF_REG_S7(sp)
+ //PTR_ADDU v0, sp, KERNFRAME_SIZ
+ REG_S s8, TF_BASE+TF_REG_S8(sp)
+ REG_S gp, TF_BASE+TF_REG_GP(sp)
+ PTR_L t8, CPU_INFO_CURLWP(k0)
+#if defined(__mips_o32) || defined(__mips_o64)
+ PTR_ADDU v0, sp, TF_BASE
+ REG_S v0, KERNFRAME_ARG5(sp) # 5th arg is p. to trapframe
+#endif
+#if defined(__mips_n32) || defined(__mips_n64)
+ PTR_ADDU a4, sp, TF_BASE # 5th arg is p. to trapframe
+#endif
+
+ /*
+ * save PPL in trapframe
+ */
+ PTR_L t0, L_CPU(MIPS_CURLWP)
+ INT_L t1, CPU_INFO_CPL(t0) # get current priority level
+ INT_S t1, TF_BASE+TF_PPL(sp) # save priority level
+
+#if defined(__mips_o32) && (defined(DDB) || defined(DEBUG) || defined(KGDB))
+ PTR_ADDU v0, sp, KERNFRAME_SIZ
+ REG_S v0, KERNFRAME_SP(sp)
+#endif
+
+#if defined(PARANOIA_SPL)
+ /*
+ * Verify our existing interrupt level.
+ */
+ jal _C_LABEL(splcheck)
+ nop
+#endif /* PARANOIA_SPL */
+
+ /*
+ * Clear exception level.
+ */
+ xor v0, a0, MIPS_SR_EXL # xor out the EXL bit
+ mtc0 v0, MIPS_COP_0_STATUS # update.
+ COP0_SYNC
+#ifdef MIPS3
+ nop
+ nop
+ nop
+#endif
+
+ /*
+ * Call the trap handler.
+ */
+ jal _C_LABEL(trap)
+ REG_S a3, KERNFRAME_RA(sp) # for debugging
+
+ /*
+ * Wait for a reset
+ */
+1: wait
+ b 1b
+ nop
+ .set at
+END(MIPSX(kern_nonmaskable_intr))
+#endif /* DDB */
+
/*
* mipsN_kern_intr
*
@@ -955,11 +1098,15 @@
and t1, s0, 0xff # get previous interrupt depth
INT_S t1, CPU_INFO_IDEPTH(s2) # to it previous value
-#ifdef PARANOIA
+#if defined(PARANOIA)
mfc0 t0, MIPS_COP_0_STATUS # verify INT_IE is still set
and t0, MIPS_SR_INT_IE
+#if defined(MIPS32) || defined(MIPS32R2) || defined(MIPS64) || defined(MIPS64R2)
+ teqi t0, 0
+#else
3: beqz t0, 3b
nop
+#endif
#endif /* PARANOIA */
#ifdef __HAVE_FAST_SOFTINTS
Home |
Main Index |
Thread Index |
Old Index