diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2008-07-29 16:58:53 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-07-30 16:54:42 -0400 |
commit | 8854700115ecf8aa6f087aa915b7b6cf18090d39 (patch) | |
tree | 3338d7aed80d715e0576783e0fecf30cc507a9a7 /arch/mips/kernel/traps.c | |
parent | 8d60a903d986ffa26c41f0092320a3b9da20bfaf (diff) |
[MIPS] kgdb: add arch support for the kernel's kgdb core
The new kgdb architecture specific handler registers and unregisters
dynamically for exceptions depending on when you configure a kgdb I/O
driver.
Aside from initializing the exceptions earlier in the boot process,
kgdb should have no impact on a device when it is compiled in so long
as an I/O module is not configured for use.
There have been quite a number of contributors during the existence of
this patch (see arch/mips/kernel/kgdb.c). Most recently Jason
re-wrote the mips kgdb logic to use the die notification handlers.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b8ea4e9d0d87..426cced1e9dc 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
26 | #include <linux/kgdb.h> | ||
27 | #include <linux/kdebug.h> | ||
26 | 28 | ||
27 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
28 | #include <asm/branch.h> | 30 | #include <asm/branch.h> |
@@ -425,6 +427,10 @@ asmlinkage void do_be(struct pt_regs *regs) | |||
425 | printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", | 427 | printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", |
426 | data ? "Data" : "Instruction", | 428 | data ? "Data" : "Instruction", |
427 | field, regs->cp0_epc, field, regs->regs[31]); | 429 | field, regs->cp0_epc, field, regs->regs[31]); |
430 | if (notify_die(DIE_OOPS, "bus error", regs, SIGBUS, 0, 0) | ||
431 | == NOTIFY_STOP) | ||
432 | return; | ||
433 | |||
428 | die_if_kernel("Oops", regs); | 434 | die_if_kernel("Oops", regs); |
429 | force_sig(SIGBUS, current); | 435 | force_sig(SIGBUS, current); |
430 | } | 436 | } |
@@ -623,6 +629,9 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
623 | { | 629 | { |
624 | siginfo_t info; | 630 | siginfo_t info; |
625 | 631 | ||
632 | if (notify_die(DIE_FP, "FP exception", regs, SIGFPE, 0, 0) | ||
633 | == NOTIFY_STOP) | ||
634 | return; | ||
626 | die_if_kernel("FP exception in kernel code", regs); | 635 | die_if_kernel("FP exception in kernel code", regs); |
627 | 636 | ||
628 | if (fcr31 & FPU_CSR_UNI_X) { | 637 | if (fcr31 & FPU_CSR_UNI_X) { |
@@ -682,6 +691,9 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | |||
682 | siginfo_t info; | 691 | siginfo_t info; |
683 | char b[40]; | 692 | char b[40]; |
684 | 693 | ||
694 | if (notify_die(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) | ||
695 | return; | ||
696 | |||
685 | /* | 697 | /* |
686 | * A short test says that IRIX 5.3 sends SIGTRAP for all trap | 698 | * A short test says that IRIX 5.3 sends SIGTRAP for all trap |
687 | * insns, even for trap and break codes that indicate arithmetic | 699 | * insns, even for trap and break codes that indicate arithmetic |
@@ -762,6 +774,10 @@ asmlinkage void do_ri(struct pt_regs *regs) | |||
762 | unsigned int opcode = 0; | 774 | unsigned int opcode = 0; |
763 | int status = -1; | 775 | int status = -1; |
764 | 776 | ||
777 | if (notify_die(DIE_RI, "RI Fault", regs, SIGSEGV, 0, 0) | ||
778 | == NOTIFY_STOP) | ||
779 | return; | ||
780 | |||
765 | die_if_kernel("Reserved instruction in kernel code", regs); | 781 | die_if_kernel("Reserved instruction in kernel code", regs); |
766 | 782 | ||
767 | if (unlikely(compute_return_epc(regs) < 0)) | 783 | if (unlikely(compute_return_epc(regs) < 0)) |
@@ -1537,6 +1553,11 @@ void __init trap_init(void) | |||
1537 | extern char except_vec4; | 1553 | extern char except_vec4; |
1538 | unsigned long i; | 1554 | unsigned long i; |
1539 | 1555 | ||
1556 | #if defined(CONFIG_KGDB) | ||
1557 | if (kgdb_early_setup) | ||
1558 | return; /* Already done */ | ||
1559 | #endif | ||
1560 | |||
1540 | if (cpu_has_veic || cpu_has_vint) | 1561 | if (cpu_has_veic || cpu_has_vint) |
1541 | ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64); | 1562 | ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64); |
1542 | else | 1563 | else |