aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh3
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-09-01 04:38:32 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-09-01 04:38:32 -0400
commit1e1030dccb1084c8a38976d3656aab1d50d762da (patch)
tree18c62bd2a12dbb8e8aae56d771f0561784af186b /arch/sh/kernel/cpu/sh3
parentac6a0cf6716bb46813d0161024c66c2af66e53d1 (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.S26
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S4
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 aebd33d18ff7..d1142d365925 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -532,7 +532,33 @@ ENTRY(handle_interrupt)
532 mov.l 2f, r4 532 mov.l 2f, r4
533 mov.l 3f, r9 533 mov.l 3f, r9
534 mov.l @r4, r4 ! pass INTEVT vector as arg0 534 mov.l @r4, r4 ! pass INTEVT vector as arg0
535
536 shlr2 r4
537 shlr r4
538 mov r4, r0 ! save vector->jmp table offset for later
539
540 shlr2 r4 ! vector to IRQ# conversion
541 add #-0x10, r4
542
543 cmp/pz r4 ! is it a valid IRQ?
544 bt 10f
545
546 /*
547 * We got here as a result of taking the INTEVT path for something
548 * that isn't a valid hard IRQ, therefore we bypass the do_IRQ()
549 * path and special case the event dispatch instead. This is the
550 * expected path for the NMI (and any other brilliantly implemented
551 * exception), which effectively wants regular exception dispatch
552 * but is unfortunately reported through INTEVT rather than
553 * EXPEVT. Grr.
554 */
555 mov.l 6f, r9
556 mov.l @(r0, r9), r9
535 jmp @r9 557 jmp @r9
558 mov r15, r8 ! trap handlers take saved regs in r8
559
56010:
561 jmp @r9 ! Off to do_IRQ() we go.
536 mov r15, r5 ! pass saved registers as arg1 562 mov r15, r5 ! pass saved registers as arg1
537 563
538ENTRY(exception_none) 564ENTRY(exception_none)
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index e5a0de39a2db..46610c35c232 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)
48 .long system_call ! Unconditional Trap /* 160 */ 48 .long system_call ! Unconditional Trap /* 160 */
49 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ 49 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
50 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ 50 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
51ENTRY(nmi_slot) 51 .long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger
52 .long kgdb_handle_exception /* 1C0 */ ! Allow trap to debugger
53ENTRY(user_break_point_trap)
54 .long break_point_trap /* 1E0 */ 52 .long break_point_trap /* 1E0 */
55 53
56 /* 54 /*