Skip to contentSkip to conversation

EJTAG and NMI handler broken

PATCH Carsten Langgaard 1 participant 2 messages Dec 5, 2002 – Dec 10, 2002 MIPS

lore
Share & tools
lore
#0 lore raw

The EJTAG and NMI handler are broken in the 32-bit kernel, because they are laying in the __INIT section, which is removed after boot. The handlers are missing in the 64-bit kernel.
The attached patch will fix that.

/Carsten

--

_    _ ____  ___   Carsten Langgaard   Mailto:[email protected]
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com

Index: arch/mips/kernel/head.S
===================================================================
RCS file: /home/cvs/linux/arch/mips/kernel/head.S,v retrieving revision 1.29.2.14

mips/kernel/head.S +42 -41
diff -u -r1.29.2.14 head.S
@@ -92,34 +92,6 @@
 		END(except_vec_ejtag_debug)
 
 		/*
-		 * EJTAG debug exception handler.
-		 */
-		NESTED(ejtag_debug_handler, PT_SIZE, sp)
-		.set	noat
-		.set	noreorder
-		mtc0	k0, CP0_DESAVE
-		mfc0	k0, CP0_DEBUG
-
-		sll	k0, k0, 30	# Check for SDBBP.
-		bgez	k0, ejtag_return
-
-		la	k0, ejtag_debug_buffer
-		sw	k1, 0(k0)
-		SAVE_ALL
-		jal	ejtag_exception_handler
-		 move	a0, sp
-		RESTORE_ALL
-		la	k0, ejtag_debug_buffer
-		lw	k1, 0(k0)
-
-ejtag_return:
-		mfc0	k0, CP0_DESAVE
-		.word	0x4200001f     # DERET, return from EJTAG debug exception.
-		 nop
-		.set	at
-		END(ejtag_debug_handler)
-
-		/*
 		* NMI debug exception handler for MIPS reference boards.
 		* The NMI debug exception entry point is 0xbfc00000, which
 		* normally is in the boot PROM, so the boot PROM must do a
@@ -130,19 +102,6 @@
 		 nop
 		END(except_vec_nmi)
 
-		NESTED(nmi_handler, PT_SIZE, sp)
-		.set    noat
-		.set    noreorder
-		.set    mips3
-		SAVE_ALL
-		jal     nmi_exception_handler
-		 move   a0, sp
-		RESTORE_ALL
-		eret
-		.set    at
-		.set    mips0
-		END(nmi_handler)
-
 		/*
 		 * Kernel entry point
 		 */
@@ -199,10 +158,52 @@
 		__FINIT
 
 		/*
+		 * EJTAG debug exception handler.
+		 */
+		NESTED(ejtag_debug_handler, PT_SIZE, sp)
+		.set	noat
+		.set	noreorder
+		mtc0	k0, CP0_DESAVE
+		mfc0	k0, CP0_DEBUG
+
+		sll	k0, k0, 30	# Check for SDBBP.
+		bgez	k0, ejtag_return
+
+		la	k0, ejtag_debug_buffer
+		sw	k1, 0(k0)
+		SAVE_ALL
+		jal	ejtag_exception_handler
+		 move	a0, sp
+		RESTORE_ALL
+		la	k0, ejtag_debug_buffer
+		lw	k1, 0(k0)
+
+ejtag_return:
+		mfc0	k0, CP0_DESAVE
+		.word	0x4200001f     # DERET, return from EJTAG debug exception.
+		 nop
+		.set	at
+		END(ejtag_debug_handler)
+
+		NESTED(nmi_handler, PT_SIZE, sp)
+		.set    noat
+		.set    noreorder
+		.set    mips3
+		SAVE_ALL
+		jal     nmi_exception_handler
+		 move   a0, sp
+		RESTORE_ALL
+		eret
+		.set    at
+		.set    mips0
+		END(nmi_handler)
+		
+		/*
 		 * This buffer is reserved for the use of the EJTAG debug
 		 * handler.
 		 */
 		.data
+		.align 2
 		EXPORT(ejtag_debug_buffer)
 		.fill	4
 

Index: arch/mips64/kernel/r4k_genex.S
===================================================================
RCS file: /home/cvs/linux/arch/mips64/kernel/r4k_genex.S,v retrieving revision 1.7.2.8

mips64/kernel/r4k_genex.S +68 -0

73 lines not on this page · raw message

Index: arch/mips64/kernel/traps.c
===================================================================
RCS file: /home/cvs/linux/arch/mips64/kernel/traps.c,v retrieving revision 1.30.2.37

mips64/kernel/traps.c +55 -0

73 lines not on this page · raw message

#1 lore raw

Ralf, did you ever take a look on my previous mail (patch). I have added few extra things, used by MIPS32/MIPS64 compliant CPUs. Please take a look at the attached patch.

/Carsten

Quoted 284 lines · Carsten Langgaard

The EJTAG and NMI handler are broken in the 32-bit kernel, because they are laying in the __INIT section, which is removed after boot. The handlers are missing in the 64-bit kernel.
The attached patch will fix that.

/Carsten

--

_    _ ____  ___   Carsten Langgaard  Mailto:[email protected]
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556

Denmark http://www.mips.com

------------------------------------------------------------------------
Index: arch/mips/kernel/head.S
===================================================================
RCS file: /home/cvs/linux/arch/mips/kernel/head.S,v retrieving revision 1.29.2.14
diff -u -r1.29.2.14 head.S

mips/kernel/head.S 5 Dec 2002 13:32:24 -0000 renamed from mips/kernel/head.S 5 Aug 2002 23:53:33 -0000 1.29.2.14 +42 -41
@@ -92,34 +92,6 @@
                END(except_vec_ejtag_debug)
 
                /*
-                * EJTAG debug exception handler.
-                */
-               NESTED(ejtag_debug_handler, PT_SIZE, sp)
-               .set    noat
-               .set    noreorder
-               mtc0    k0, CP0_DESAVE
-               mfc0    k0, CP0_DEBUG
-
-               sll     k0, k0, 30      # Check for SDBBP.
-               bgez    k0, ejtag_return
-
-               la      k0, ejtag_debug_buffer
-               sw      k1, 0(k0)
-               SAVE_ALL
-               jal     ejtag_exception_handler
-                move   a0, sp
-               RESTORE_ALL
-               la      k0, ejtag_debug_buffer
-               lw      k1, 0(k0)
-
-ejtag_return:
-               mfc0    k0, CP0_DESAVE
-               .word   0x4200001f     # DERET, return from EJTAG debug exception.
-                nop
-               .set    at
-               END(ejtag_debug_handler)
-
-               /*
                * NMI debug exception handler for MIPS reference boards.
                * The NMI debug exception entry point is 0xbfc00000, which
                * normally is in the boot PROM, so the boot PROM must do a
@@ -130,19 +102,6 @@
                 nop
                END(except_vec_nmi)
 
-               NESTED(nmi_handler, PT_SIZE, sp)
-               .set    noat
-               .set    noreorder
-               .set    mips3
-               SAVE_ALL
-               jal     nmi_exception_handler
-                move   a0, sp
-               RESTORE_ALL
-               eret
-               .set    at
-               .set    mips0
-               END(nmi_handler)
-
                /*
                 * Kernel entry point
                 */
@@ -199,10 +158,52 @@
                __FINIT
 
                /*
+                * EJTAG debug exception handler.
+                */
+               NESTED(ejtag_debug_handler, PT_SIZE, sp)
+               .set    noat
+               .set    noreorder
+               mtc0    k0, CP0_DESAVE
+               mfc0    k0, CP0_DEBUG
+
+               sll     k0, k0, 30      # Check for SDBBP.
+               bgez    k0, ejtag_return
+
+               la      k0, ejtag_debug_buffer
+               sw      k1, 0(k0)
+               SAVE_ALL
+               jal     ejtag_exception_handler
+                move   a0, sp
+               RESTORE_ALL
+               la      k0, ejtag_debug_buffer
+               lw      k1, 0(k0)
+
+ejtag_return:
+               mfc0    k0, CP0_DESAVE
+               .word   0x4200001f     # DERET, return from EJTAG debug exception.
+                nop
+               .set    at
+               END(ejtag_debug_handler)
+
+               NESTED(nmi_handler, PT_SIZE, sp)
+               .set    noat
+               .set    noreorder
+               .set    mips3
+               SAVE_ALL
+               jal     nmi_exception_handler
+                move   a0, sp
+               RESTORE_ALL
+               eret
+               .set    at
+               .set    mips0
+               END(nmi_handler)
+
+               /*
                 * This buffer is reserved for the use of the EJTAG debug
                 * handler.
                 */
                .data
+               .align 2
                EXPORT(ejtag_debug_buffer)
                .fill   4
 

Index: arch/mips64/kernel/r4k_genex.S
===================================================================
RCS file: /home/cvs/linux/arch/mips64/kernel/r4k_genex.S,v retrieving revision 1.7.2.8
diff -u -r1.7.2.8 r4k_genex.S

mips64/kernel/r4k_genex.S 5 Dec 2002 13:32:25 -0000 renamed from mips64/kernel/r4k_genex.S 2 Oct 2002 14:45:46 -0000 1.7.2.8 +68 -0
@@ -121,4 +121,72 @@
 1:     j       1b                      /* Dummy, will be replaced */
 END(except_vec4)
 
+/*
+ * EJTAG debug exception handler.
+ * The EJTAG debug exception entry point is 0xbfc00480, which
+ * normally is in the boot PROM, so the boot PROM must do a
+ * unconditional jump to this vector.
+ */
+NESTED(except_vec_ejtag_debug, 0, sp)
+       j       ejtag_debug_handler
+        nop
+END(except_vec_ejtag_debug)
+
+/*
+ * NMI debug exception handler for MIPS reference boards.
+ * The NMI debug exception entry point is 0xbfc00000, which
+ * normally is in the boot PROM, so the boot PROM must do a
+ * unconditional jump to this vector.
+ */
+NESTED(except_vec_nmi, 0, sp)
+       j       nmi_handler
+        nop
+END(except_vec_nmi)
+
        __FINIT
+
+/*
+ * EJTAG debug exception handler.
+ */
+NESTED(ejtag_debug_handler, PT_SIZE, sp)
+       .set    noat
+       .set    noreorder
+       dmtc0   k0, CP0_DESAVE
+       mfc0    k0, CP0_DEBUG
+
+       sll     k0, k0, 30      # Check for SDBBP.
+       bgez    k0, ejtag_return
+
+       dla     k0, ejtag_debug_buffer
+       sd      k1, 0(k0)
+       SAVE_ALL
+       jal     ejtag_exception_handler
+        move   a0, sp
+       RESTORE_ALL
+       dla     k0, ejtag_debug_buffer
+       ld      k1, 0(k0)
+
+ejtag_return:
+       mfc0    k0, CP0_DESAVE
+       .word   0x4200001f     # DERET, return from EJTAG debug exception.
+        nop
+       .set    at
+END(ejtag_debug_handler)
+
+NESTED(nmi_handler, PT_SIZE, sp)
+       .set    noat
+       .set    noreorder
+       SAVE_ALL
+       jal     nmi_exception_handler
+        move   a0, sp
+       .set    at
+END(nmi_handler)
+
+/*
+ * This buffer is reserved for the use of the EJTAG debug
+ * handler.
+ */
+       .data
+       .align 3
+       EXPORT(ejtag_debug_buffer)
+       .fill   8
\ No newline at end of file

Index: arch/mips64/kernel/traps.c
===================================================================
RCS file: /home/cvs/linux/arch/mips64/kernel/traps.c,v retrieving revision 1.30.2.37
diff -u -r1.30.2.37 traps.c

mips64/kernel/traps.c 5 Dec 2002 13:32:25 -0000 renamed from mips64/kernel/traps.c 2 Dec 2002 00:24:52 -0000 1.30.2.37 +48 -0
@@ -638,6 +638,46 @@
        }
 }
 
+/*
+ * SDBBP EJTAG debug exception handler.
+ * We skip the instruction and return to the next instruction.
+ */
+void ejtag_exception_handler(struct pt_regs *regs)
+{
+        unsigned long depc, old_epc;
+       unsigned int debug;
+
+        printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
+       depc = read_c0_depc();
+        debug = read_c0_debug();
+        printk("DEPC = %p, DEBUG = %08x\n", depc, debug);
+        if (debug & 0x80000000) {
+                /*
+                 * In branch delay slot.
+                 * We cheat a little bit here and use EPC to calculate the
+                 * debug return address (DEPC). EPC is restored after the
+                 * calculation.
+                 */
+                old_epc = regs->cp0_epc;
+                regs->cp0_epc = depc;
+                __compute_return_epc(regs);
+                depc = regs->cp0_epc;
+                regs->cp0_epc = old_epc;
+        } else
+                depc += 4;
+       write_c0_depc(depc);
+}
+
+/*
+ * NMI exception handler.
+ */
+void nmi_exception_handler(struct pt_regs *regs)
+{
+       printk("NMI taken: ERROREPC = %p\n", read_c0_errorepc());
+        die("NMI", regs);
+        while(1) ;  /* We die here. */
+}
+
 unsigned long exception_handlers[32];
 
 /*
@@ -702,6 +742,8 @@
        extern char except_vec0_generic, except_vec2_generic;
        extern char except_vec3_generic, except_vec3_r4000;
        extern char except_vec4;
+       extern char except_vec_ejtag_debug;
+       extern char except_vec_nmi;
        unsigned long i;
 
        per_cpu_trap_init();
@@ -716,6 +758,19 @@
         */
        for (i = 0; i <= 31; i++)
                set_except_vector(i, handle_reserved);
+
+       /*
+        * Copy the EJTAG debug exception vector handler code to it's final
+        * destination.
+        */
+       if (mips_cpu.options & MIPS_CPU_EJTAG)

mips64/kernel/traps.c 5 Dec 2002 13:32:25 -0000 line 776

Quoted 10 lines
mips64/kernel/traps.c 5 Dec 2002 13:32:25 -0000 renamed from mips64/kernel/traps.c 2 Dec 2002 00:24:52 -0000 1.30.2.37 +7 -0
+               memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
+
+       /*
+         * Copy the NMI exception vector handler code to it's final
+         * destination.
+         */
+        memcpy((void *)(KSEG0 + 0x380), &except_vec_nmi, 0x80);
 
        /*
         * Only some CPUs have the watch exceptions or a dedicated

--

_    _ ____  ___   Carsten Langgaard   Mailto:[email protected]
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com

Index: arch/mips/kernel/head.S
===================================================================
RCS file: /home/cvs/linux/arch/mips/kernel/head.S,v retrieving revision 1.29.2.14

mips/kernel/head.S +42 -41
diff -u -r1.29.2.14 head.S
@@ -92,34 +92,6 @@
 		END(except_vec_ejtag_debug)
 
 		/*
-		 * EJTAG debug exception handler.
-		 */
-		NESTED(ejtag_debug_handler, PT_SIZE, sp)
-		.set	noat
-		.set	noreorder
-		mtc0	k0, CP0_DESAVE
-		mfc0	k0, CP0_DEBUG
-
-		sll	k0, k0, 30	# Check for SDBBP.
-		bgez	k0, ejtag_return
-
-		la	k0, ejtag_debug_buffer
-		sw	k1, 0(k0)
-		SAVE_ALL
-		jal	ejtag_exception_handler
-		 move	a0, sp
-		RESTORE_ALL
-		la	k0, ejtag_debug_buffer
-		lw	k1, 0(k0)
-
-ejtag_return:
-		mfc0	k0, CP0_DESAVE
-		.word	0x4200001f     # DERET, return from EJTAG debug exception.
-		 nop
-		.set	at
-		END(ejtag_debug_handler)
-
-		/*
 		* NMI debug exception handler for MIPS reference boards.
 		* The NMI debug exception entry point is 0xbfc00000, which
 		* normally is in the boot PROM, so the boot PROM must do a
@@ -130,19 +102,6 @@
 		 nop
 		END(except_vec_nmi)
 
-		NESTED(nmi_handler, PT_SIZE, sp)
-		.set    noat
-		.set    noreorder
-		.set    mips3
-		SAVE_ALL
-		jal     nmi_exception_handler
-		 move   a0, sp
-		RESTORE_ALL
-		eret
-		.set    at
-		.set    mips0
-		END(nmi_handler)
-
 		/*
 		 * Kernel entry point
 		 */
@@ -199,10 +158,52 @@
 		__FINIT
 
 		/*
+		 * EJTAG debug exception handler.
+		 */
+		NESTED(ejtag_debug_handler, PT_SIZE, sp)
+		.set	noat
+		.set	noreorder
+		mtc0	k0, CP0_DESAVE
+		mfc0	k0, CP0_DEBUG
+
+		sll	k0, k0, 30	# Check for SDBBP.
+		bgez	k0, ejtag_return
+
+		la	k0, ejtag_debug_buffer
+		sw	k1, 0(k0)
+		SAVE_ALL
+		jal	ejtag_exception_handler
+		 move	a0, sp
+		RESTORE_ALL
+		la	k0, ejtag_debug_buffer
+		lw	k1, 0(k0)
+
+ejtag_return:
+		mfc0	k0, CP0_DESAVE
+		.word	0x4200001f     # DERET, return from EJTAG debug exception.
+		 nop
+		.set	at
+		END(ejtag_debug_handler)
+
+		NESTED(nmi_handler, PT_SIZE, sp)
+		.set    noat
+		.set    noreorder
+		.set    mips3
+		SAVE_ALL
+		jal     nmi_exception_handler
+		 move   a0, sp
+		RESTORE_ALL
+		eret
+		.set    at
+		.set    mips0
+		END(nmi_handler)
+		
+		/*
 		 * This buffer is reserved for the use of the EJTAG debug
 		 * handler.
 		 */
 		.data
+		.align 2
 		EXPORT(ejtag_debug_buffer)
 		.fill	4
 

Index: arch/mips/kernel/traps.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/kernel/traps.c,v retrieving revision 1.99.2.35

mips/kernel/traps.c +23 -1
diff -u -r1.99.2.35 traps.c
@@ -733,6 +733,16 @@
 
 asmlinkage void do_mcheck(struct pt_regs *regs)
 {
+	switch(mips_cpu.cputype) {
+	case CPU_4KC:
+	case CPU_4KEC:
+	case CPU_4KSC:
+	case CPU_5KC:
+	case CPU_20KC:
+		/* Clear the TS bit in the status register. */
+		clear_c0_status(0x00200000);
+		break;
+	}
 	show_regs(regs);
 	dump_tlb_all();
 	/*
@@ -777,6 +787,12 @@
 		       "MIPS 5KC CPUs.\n");
 		write_c0_ecc(read_c0_ecc() | 0x80000000);
 		break;
+	case CPU_20KC:
+		/* Clear the DE bit (bit 16) in the CP0_STATUS register. */
+		printk(KERN_INFO "Enable the cache parity detection for "
+		       "MIPS 20KC/25KF CPUs.\n");
+		clear_c0_status(0x0001000);
+		break;
 	default:
 		break;
 	}
@@ -857,7 +873,7 @@
  */
 void nmi_exception_handler(struct pt_regs *regs)
 {
-        printk("NMI taken!!!!\n");
+        printk("NMI taken: ERROREPC = %08x\n", read_c0_errorepc());
         die("NMI", regs);
         while(1) ;  /* We die here. */
 }
@@ -945,6 +961,12 @@
 	 */
 	if (mips_cpu.options & MIPS_CPU_EJTAG)
 		memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
+
+	/* 
+         * Copy the NMI exception vector handler code to it's final 
+         * destination.
+         */
+        memcpy((void *)(KSEG0 + 0x380), &except_vec_nmi, 0x80);
 
 	/*
 	 * Only some CPUs have the watch exceptions or a dedicated

Index: arch/mips64/kernel/r4k_genex.S
===================================================================
RCS file: /home/cvs/linux/arch/mips64/kernel/r4k_genex.S,v retrieving revision 1.7.2.8

mips64/kernel/r4k_genex.S +68 -0

73 lines not on this page · raw message

Index: arch/mips64/kernel/traps.c
===================================================================
RCS file: /home/cvs/linux/arch/mips64/kernel/traps.c,v retrieving revision 1.30.2.38

mips64/kernel/traps.c +62 -0

86 lines not on this page · raw message