EJTAG and NMI handler broken

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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:carstenl@mips.com
|\  /|||___)(___   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
--- arch/mips/kernel/head.S	5 Aug 2002 23:53:33 -0000	1.29.2.14
+++ arch/mips/kernel/head.S	5 Dec 2002 13:32:24 -0000
@@ -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
--- arch/mips64/kernel/r4k_genex.S	2 Oct 2002 14:45:46 -0000	1.7.2.8
+++ arch/mips64/kernel/r4k_genex.S	5 Dec 2002 13:32:25 -0000
@@ -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
--- arch/mips64/kernel/traps.c	2 Dec 2002 00:24:52 -0000	1.30.2.37
+++ arch/mips64/kernel/traps.c	5 Dec 2002 13:32:25 -0000
@@ -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)
+		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 of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux