diff options
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 85 |
1 files changed, 54 insertions, 31 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 910cdd43fe60..21a55ef19cbd 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -169,7 +169,9 @@ asmlinkage void double_fault_c(struct pt_regs *fp) | |||
169 | console_verbose(); | 169 | console_verbose(); |
170 | oops_in_progress = 1; | 170 | oops_in_progress = 1; |
171 | printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); | 171 | printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); |
172 | dump_bfin_regs(fp, (void *)fp->retx); | 172 | dump_bfin_process(fp); |
173 | dump_bfin_mem((void *)fp->retx); | ||
174 | show_regs(fp); | ||
173 | panic("Double Fault - unrecoverable event\n"); | 175 | panic("Double Fault - unrecoverable event\n"); |
174 | 176 | ||
175 | } | 177 | } |
@@ -444,7 +446,9 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
444 | 446 | ||
445 | if (sig != SIGTRAP) { | 447 | if (sig != SIGTRAP) { |
446 | unsigned long stack; | 448 | unsigned long stack; |
447 | dump_bfin_regs(fp, (void *)fp->retx); | 449 | dump_bfin_process(fp); |
450 | dump_bfin_mem((void *)fp->retx); | ||
451 | show_regs(fp); | ||
448 | 452 | ||
449 | /* Print out the trace buffer if it makes sense */ | 453 | /* Print out the trace buffer if it makes sense */ |
450 | #ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE | 454 | #ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE |
@@ -601,38 +605,48 @@ void dump_stack(void) | |||
601 | show_stack(current, &stack); | 605 | show_stack(current, &stack); |
602 | trace_buffer_restore(tflags); | 606 | trace_buffer_restore(tflags); |
603 | } | 607 | } |
604 | |||
605 | EXPORT_SYMBOL(dump_stack); | 608 | EXPORT_SYMBOL(dump_stack); |
606 | 609 | ||
607 | void dump_bfin_regs(struct pt_regs *fp, void *retaddr) | 610 | void dump_bfin_process(struct pt_regs *fp) |
608 | { | 611 | { |
609 | char buf [150]; | 612 | /* We should be able to look at fp->ipend, but we don't push it on the |
613 | * stack all the time, so do this until we fix that */ | ||
614 | unsigned int context = bfin_read_IPEND(); | ||
615 | |||
616 | if (oops_in_progress) | ||
617 | printk(KERN_EMERG "Kernel OOPS in progress\n"); | ||
618 | |||
619 | if (context & 0x0020) | ||
620 | printk(KERN_NOTICE "Deferred excecption or HW Error context\n"); | ||
621 | else if (context & 0x3FC0) | ||
622 | printk(KERN_NOTICE "Interrupt context\n"); | ||
623 | else if (context & 0x4000) | ||
624 | printk(KERN_NOTICE "Deferred Interrupt context\n"); | ||
625 | else if (context & 0x8000) | ||
626 | printk(KERN_NOTICE "Kernel process context\n"); | ||
627 | |||
628 | if (current->pid && current->mm) { | ||
629 | printk(KERN_NOTICE "CURRENT PROCESS:\n"); | ||
630 | printk(KERN_NOTICE "COMM=%s PID=%d\n", | ||
631 | current->comm, current->pid); | ||
632 | |||
633 | printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" | ||
634 | KERN_NOTICE "BSS = 0x%p-0x%p USER-STACK = 0x%p\n" | ||
635 | KERN_NOTICE "\n", | ||
636 | (void *)current->mm->start_code, | ||
637 | (void *)current->mm->end_code, | ||
638 | (void *)current->mm->start_data, | ||
639 | (void *)current->mm->end_data, | ||
640 | (void *)current->mm->end_data, | ||
641 | (void *)current->mm->brk, | ||
642 | (void *)current->mm->start_stack); | ||
643 | } else | ||
644 | printk(KERN_NOTICE "\n" KERN_NOTICE | ||
645 | "No Valid process in current context\n"); | ||
646 | } | ||
610 | 647 | ||
611 | if (!oops_in_progress) { | 648 | void dump_bfin_mem(void *retaddr) |
612 | if (current->pid && current->mm) { | 649 | { |
613 | printk(KERN_NOTICE "\n" KERN_NOTICE "CURRENT PROCESS:\n"); | ||
614 | printk(KERN_NOTICE "COMM=%s PID=%d\n", | ||
615 | current->comm, current->pid); | ||
616 | |||
617 | printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" | ||
618 | KERN_NOTICE "BSS = 0x%p-0x%p USER-STACK = 0x%p\n" | ||
619 | KERN_NOTICE "\n", | ||
620 | (void *)current->mm->start_code, | ||
621 | (void *)current->mm->end_code, | ||
622 | (void *)current->mm->start_data, | ||
623 | (void *)current->mm->end_data, | ||
624 | (void *)current->mm->end_data, | ||
625 | (void *)current->mm->brk, | ||
626 | (void *)current->mm->start_stack); | ||
627 | } else { | ||
628 | printk (KERN_NOTICE "\n" KERN_NOTICE | ||
629 | "No Valid pid - Either things are really messed up," | ||
630 | " or you are in the kernel\n"); | ||
631 | } | ||
632 | } else { | ||
633 | printk(KERN_NOTICE "Kernel or interrupt exception\n"); | ||
634 | print_modules(); | ||
635 | } | ||
636 | 650 | ||
637 | if (retaddr >= (void *)FIXED_CODE_START && retaddr < (void *)physical_mem_end | 651 | if (retaddr >= (void *)FIXED_CODE_START && retaddr < (void *)physical_mem_end |
638 | #if L1_CODE_LENGTH != 0 | 652 | #if L1_CODE_LENGTH != 0 |
@@ -675,6 +689,11 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr) | |||
675 | printk("\n" KERN_NOTICE | 689 | printk("\n" KERN_NOTICE |
676 | "Cannot look at the [PC] <%p> for it is" | 690 | "Cannot look at the [PC] <%p> for it is" |
677 | " in unreadable memory - sorry\n", retaddr); | 691 | " in unreadable memory - sorry\n", retaddr); |
692 | } | ||
693 | |||
694 | void show_regs(struct pt_regs *fp) | ||
695 | { | ||
696 | char buf [150]; | ||
678 | 697 | ||
679 | printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n"); | 698 | printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n"); |
680 | printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 699 | printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", |
@@ -688,6 +707,8 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr) | |||
688 | printk(KERN_NOTICE " RETX: %s\n", buf); | 707 | printk(KERN_NOTICE " RETX: %s\n", buf); |
689 | decode_address(buf, fp->rets); | 708 | decode_address(buf, fp->rets); |
690 | printk(KERN_NOTICE " RETS: %s\n", buf); | 709 | printk(KERN_NOTICE " RETS: %s\n", buf); |
710 | decode_address(buf, fp->pc); | ||
711 | printk(KERN_NOTICE " PC: %s\n", buf); | ||
691 | 712 | ||
692 | if ((long)fp->seqstat & SEQSTAT_EXCAUSE) { | 713 | if ((long)fp->seqstat & SEQSTAT_EXCAUSE) { |
693 | decode_address(buf, bfin_read_DCPLB_FAULT_ADDR()); | 714 | decode_address(buf, bfin_read_DCPLB_FAULT_ADDR()); |
@@ -802,7 +823,9 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) | |||
802 | 823 | ||
803 | printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR()); | 824 | printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR()); |
804 | printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR()); | 825 | printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR()); |
805 | dump_bfin_regs(fp, (void *)fp->retx); | 826 | dump_bfin_process(fp); |
827 | dump_bfin_mem((void *)fp->retx); | ||
828 | show_regs(fp); | ||
806 | dump_stack(); | 829 | dump_stack(); |
807 | panic("Unrecoverable event\n"); | 830 | panic("Unrecoverable event\n"); |
808 | } | 831 | } |