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