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 Carsten Langgaard wrote: > 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 -- _ _ ____ ___ 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 10 Dec 2002 13:29:55 -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/mips/kernel/traps.c =================================================================== RCS file: /home/cvs/linux/arch/mips/kernel/traps.c,v retrieving revision 1.99.2.35 diff -u -r1.99.2.35 traps.c --- arch/mips/kernel/traps.c 4 Dec 2002 23:50:23 -0000 1.99.2.35 +++ arch/mips/kernel/traps.c 10 Dec 2002 13:29:55 -0000 @@ -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 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 10 Dec 2002 13:29:57 -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.38 diff -u -r1.30.2.38 traps.c --- arch/mips64/kernel/traps.c 5 Dec 2002 15:01:17 -0000 1.30.2.38 +++ arch/mips64/kernel/traps.c 10 Dec 2002 13:29:59 -0000 @@ -608,6 +608,13 @@ asmlinkage void do_mcheck(struct pt_regs *regs) { + switch(mips_cpu.cputype) { + 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(); /* @@ -638,6 +645,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 +749,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 +765,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