diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-09-01 17:38:32 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-09-01 17:38:32 +0900 |
commit | 1e1030dccb1084c8a38976d3656aab1d50d762da (patch) | |
tree | 18c62bd2a12dbb8e8aae56d771f0561784af186b /arch/sh/kernel/cpu/sh3 | |
parent | ac6a0cf6716bb46813d0161024c66c2af66e53d1 (diff) |
sh: nmi_debug support.
This implements support for NMI debugging that was shamelessly copied
from the avr32 port. A bit of special magic is needed in the interrupt
exception path given that the NMI exception handler is stubbed in to the
regular exception handling table despite being reported in INTEVT. So we
mangle the lookup and kick off an EXPEVT-style exception dispatch from
the INTEVT path for exceptions that do_IRQ() has no chance of handling.
As a result, we also drop the evt2irq() conversion from the do_IRQ() path
and just do it in assembly.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/sh3')
-rw-r--r-- | arch/sh/kernel/cpu/sh3/entry.S | 26 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/ex.S | 4 |
2 files changed, 27 insertions, 3 deletions
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index aebd33d18ff..d1142d36592 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -532,7 +532,33 @@ ENTRY(handle_interrupt) mov.l 2f, r4 mov.l 3f, r9 mov.l @r4, r4 ! pass INTEVT vector as arg0 + + shlr2 r4 + shlr r4 + mov r4, r0 ! save vector->jmp table offset for later + + shlr2 r4 ! vector to IRQ# conversion + add #-0x10, r4 + + cmp/pz r4 ! is it a valid IRQ? + bt 10f + + /* + * We got here as a result of taking the INTEVT path for something + * that isn't a valid hard IRQ, therefore we bypass the do_IRQ() + * path and special case the event dispatch instead. This is the + * expected path for the NMI (and any other brilliantly implemented + * exception), which effectively wants regular exception dispatch + * but is unfortunately reported through INTEVT rather than + * EXPEVT. Grr. + */ + mov.l 6f, r9 + mov.l @(r0, r9), r9 jmp @r9 + mov r15, r8 ! trap handlers take saved regs in r8 + +10: + jmp @r9 ! Off to do_IRQ() we go. mov r15, r5 ! pass saved registers as arg1 ENTRY(exception_none) diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index e5a0de39a2d..46610c35c23 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S @@ -48,9 +48,7 @@ ENTRY(exception_handling_table) .long system_call ! Unconditional Trap /* 160 */ .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ -ENTRY(nmi_slot) - .long kgdb_handle_exception /* 1C0 */ ! Allow trap to debugger -ENTRY(user_break_point_trap) + .long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger .long break_point_trap /* 1E0 */ /* |