aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r--arch/blackfin/kernel/traps.c198
1 files changed, 109 insertions, 89 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 5ab87b0b92dd..3909f5b35536 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -27,15 +27,15 @@
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 28 */
29 29
30#include <asm/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/interrupt.h>
32#include <linux/module.h>
33#include <linux/kallsyms.h>
31#include <asm/traps.h> 34#include <asm/traps.h>
32#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
33#include <asm/blackfin.h> 36#include <asm/blackfin.h>
34#include <asm/uaccess.h>
35#include <asm/irq_handler.h> 37#include <asm/irq_handler.h>
36#include <linux/interrupt.h> 38#include <asm/trace.h>
37#include <linux/module.h>
38#include <linux/kallsyms.h>
39 39
40#ifdef CONFIG_KGDB 40#ifdef CONFIG_KGDB
41# include <linux/debugger.h> 41# include <linux/debugger.h>
@@ -76,7 +76,7 @@ static int printk_address(unsigned long address)
76 if (!modname) 76 if (!modname)
77 modname = delim = ""; 77 modname = delim = "";
78 return printk("<0x%p> { %s%s%s%s + 0x%lx }", 78 return printk("<0x%p> { %s%s%s%s + 0x%lx }",
79 (void*)address, delim, modname, delim, symname, 79 (void *)address, delim, modname, delim, symname,
80 (unsigned long)offset); 80 (unsigned long)offset);
81 81
82 } 82 }
@@ -119,7 +119,7 @@ static int printk_address(unsigned long address)
119 119
120 write_unlock_irq(&tasklist_lock); 120 write_unlock_irq(&tasklist_lock);
121 return printk("<0x%p> [ %s + 0x%lx ]", 121 return printk("<0x%p> [ %s + 0x%lx ]",
122 (void*)address, name, offset); 122 (void *)address, name, offset);
123 } 123 }
124 124
125 vml = vml->next; 125 vml = vml->next;
@@ -128,19 +128,9 @@ static int printk_address(unsigned long address)
128 write_unlock_irq(&tasklist_lock); 128 write_unlock_irq(&tasklist_lock);
129 129
130 /* we were unable to find this address anywhere */ 130 /* we were unable to find this address anywhere */
131 return printk("[<0x%p>]", (void*)address); 131 return printk("[<0x%p>]", (void *)address);
132} 132}
133 133
134#define trace_buffer_save(x) \
135 do { \
136 (x) = bfin_read_TBUFCTL(); \
137 bfin_write_TBUFCTL((x) & ~TBUFEN); \
138 } while (0)
139#define trace_buffer_restore(x) \
140 do { \
141 bfin_write_TBUFCTL((x)); \
142 } while (0)
143
144asmlinkage void trap_c(struct pt_regs *fp) 134asmlinkage void trap_c(struct pt_regs *fp)
145{ 135{
146 int j, sig = 0; 136 int j, sig = 0;
@@ -148,8 +138,15 @@ asmlinkage void trap_c(struct pt_regs *fp)
148 unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; 138 unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
149 139
150#ifdef CONFIG_KGDB 140#ifdef CONFIG_KGDB
151# define CHK_DEBUGGER_TRAP() do { CHK_DEBUGGER(trapnr, sig, info.si_code, fp,); } while (0) 141# define CHK_DEBUGGER_TRAP() \
152# define CHK_DEBUGGER_TRAP_MAYBE() do { if (kgdb_connected) CHK_DEBUGGER_TRAP(); } while (0) 142 do { \
143 CHK_DEBUGGER(trapnr, sig, info.si_code, fp); \
144 } while (0)
145# define CHK_DEBUGGER_TRAP_MAYBE() \
146 do { \
147 if (kgdb_connected) \
148 CHK_DEBUGGER_TRAP(); \
149 } while (0)
153#else 150#else
154# define CHK_DEBUGGER_TRAP() do { } while (0) 151# define CHK_DEBUGGER_TRAP() do { } while (0)
155# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) 152# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0)
@@ -196,15 +193,14 @@ asmlinkage void trap_c(struct pt_regs *fp)
196#else 193#else
197 /* 0x02 - User Defined, Caught by default */ 194 /* 0x02 - User Defined, Caught by default */
198#endif 195#endif
199 /* 0x03 - Atomic test and set */ 196 /* 0x03 - User Defined, userspace stack overflow */
200 case VEC_EXCPT03: 197 case VEC_EXCPT03:
201 info.si_code = SEGV_STACKFLOW; 198 info.si_code = SEGV_STACKFLOW;
202 sig = SIGSEGV; 199 sig = SIGSEGV;
203 printk(KERN_EMERG EXC_0x03); 200 printk(KERN_EMERG EXC_0x03);
204 CHK_DEBUGGER_TRAP(); 201 CHK_DEBUGGER_TRAP();
205 break; 202 break;
206 /* 0x04 - spinlock - handled by _ex_spinlock, 203 /* 0x04 - User Defined, Caught by default */
207 getting here is an error */
208 /* 0x05 - User Defined, Caught by default */ 204 /* 0x05 - User Defined, Caught by default */
209 /* 0x06 - User Defined, Caught by default */ 205 /* 0x06 - User Defined, Caught by default */
210 /* 0x07 - User Defined, Caught by default */ 206 /* 0x07 - User Defined, Caught by default */
@@ -297,7 +293,8 @@ asmlinkage void trap_c(struct pt_regs *fp)
297 info.si_code = ILL_CPLB_MULHIT; 293 info.si_code = ILL_CPLB_MULHIT;
298#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 294#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
299 sig = SIGSEGV; 295 sig = SIGSEGV;
300 printk(KERN_EMERG "\n\nNULL pointer access (probably)\n"); 296 printk(KERN_EMERG "\n"
297 KERN_EMERG "NULL pointer access (probably)\n");
301#else 298#else
302 sig = SIGILL; 299 sig = SIGILL;
303 printk(KERN_EMERG EXC_0x27); 300 printk(KERN_EMERG EXC_0x27);
@@ -418,7 +415,9 @@ asmlinkage void trap_c(struct pt_regs *fp)
418 if (current->mm) { 415 if (current->mm) {
419 fp->pc = current->mm->start_code; 416 fp->pc = current->mm->start_code;
420 } else { 417 } else {
421 printk(KERN_EMERG "I can't return to memory that doesn't exist - bad things happen\n"); 418 printk(KERN_EMERG
419 "I can't return to memory that doesn't exist"
420 " - bad things happen\n");
422 panic("Help - I've fallen and can't get up\n"); 421 panic("Help - I've fallen and can't get up\n");
423 } 422 }
424 } 423 }
@@ -522,38 +521,47 @@ EXPORT_SYMBOL(dump_stack);
522void dump_bfin_regs(struct pt_regs *fp, void *retaddr) 521void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
523{ 522{
524 if (current->pid) { 523 if (current->pid) {
525 printk("\nCURRENT PROCESS:\n\n"); 524 printk(KERN_EMERG "\n" KERN_EMERG "CURRENT PROCESS:\n"
526 printk("COMM=%s PID=%d\n", current->comm, current->pid); 525 KERN_EMERG "\n");
526 printk(KERN_EMERG "COMM=%s PID=%d\n",
527 current->comm, current->pid);
527 } else { 528 } else {
528 printk 529 printk
529 ("\nNo Valid pid - Either things are really messed up, or you are in the kernel\n"); 530 (KERN_EMERG "\n" KERN_EMERG
531 "No Valid pid - Either things are really messed up,"
532 " or you are in the kernel\n");
530 } 533 }
531 534
532 if (current->mm) { 535 if (current->mm) {
533 printk("TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" 536 printk(KERN_EMERG "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n"
534 "BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", 537 KERN_EMERG "BSS = 0x%p-0x%p USER-STACK = 0x%p\n"
535 (void*)current->mm->start_code, 538 KERN_EMERG "\n",
536 (void*)current->mm->end_code, 539 (void *)current->mm->start_code,
537 (void*)current->mm->start_data, 540 (void *)current->mm->end_code,
538 (void*)current->mm->end_data, 541 (void *)current->mm->start_data,
539 (void*)current->mm->end_data, 542 (void *)current->mm->end_data,
540 (void*)current->mm->brk, 543 (void *)current->mm->end_data,
541 (void*)current->mm->start_stack); 544 (void *)current->mm->brk,
545 (void *)current->mm->start_stack);
542 } 546 }
543 547
544 printk("return address: 0x%p; contents of [PC-16...PC+8]:\n", retaddr); 548 printk(KERN_EMERG "return address: [0x%p]; contents of:", retaddr);
545 if (retaddr != 0 && retaddr <= (void*)physical_mem_end 549 if (retaddr != 0 && retaddr <= (void *)physical_mem_end
546#if L1_CODE_LENGTH != 0 550#if L1_CODE_LENGTH != 0
547 /* FIXME: Copy the code out of L1 Instruction SRAM through dma 551 /* FIXME: Copy the code out of L1 Instruction SRAM through dma
548 memcpy. */ 552 memcpy. */
549 && !(retaddr >= (void*)L1_CODE_START 553 && !(retaddr >= (void *)L1_CODE_START
550 && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH)) 554 && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
551#endif 555#endif
552 ) { 556 ) {
553 int i = 0; 557 int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32;
554 unsigned short x = 0; 558 unsigned short x = 0;
555 for (i = -16; i < 8; i++) { 559 for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
556 if (get_user(x, (unsigned short *)retaddr + i)) 560 if (!(i & 0xF))
561 printk(KERN_EMERG "\n" KERN_EMERG
562 "0x%08x: ", i);
563
564 if (get_user(x, (unsigned short *)i))
557 break; 565 break;
558#ifndef CONFIG_DEBUG_HWERR 566#ifndef CONFIG_DEBUG_HWERR
559 /* If one of the last few instructions was a STI 567 /* If one of the last few instructions was a STI
@@ -561,53 +569,65 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
561 * and we just noticed 569 * and we just noticed
562 */ 570 */
563 if (x >= 0x0040 && x <= 0x0047 && i <= 0) 571 if (x >= 0x0040 && x <= 0x0047 && i <= 0)
564 panic("\n\nWARNING : You should reconfigure the kernel to turn on\n" 572 panic("\n\nWARNING : You should reconfigure"
565 " 'Hardware error interrupt debugging'\n" 573 " the kernel to turn on\n"
566 " The rest of this error is meanless\n"); 574 " 'Hardware error interrupt"
575 " debugging'\n"
576 " The rest of this error"
577 " is meanless\n");
567#endif 578#endif
568 579 if (i == (unsigned int)retaddr)
569 if (i == -8) 580 printk("[%04x]", x);
570 printk("\n"); 581 else
571 if (i == 0) 582 printk(" %04x ", x);
572 printk("X\n");
573 printk("%04x ", x);
574 } 583 }
584 printk("\n" KERN_EMERG "\n");
575 } else 585 } else
576 printk("Cannot look at the [PC] for it is in unreadable L1 SRAM - sorry\n"); 586 printk(KERN_EMERG
577 587 "Cannot look at the [PC] for it is"
578 printk("\n\n"); 588 "in unreadable L1 SRAM - sorry\n");
579 589
580 printk("RETE: %08lx RETN: %08lx RETX: %08lx RETS: %08lx\n", 590
581 fp->rete, fp->retn, fp->retx, fp->rets); 591 printk(KERN_EMERG
582 printk("IPEND: %04lx SYSCFG: %04lx\n", fp->ipend, fp->syscfg); 592 "RETE: %08lx RETN: %08lx RETX: %08lx RETS: %08lx\n",
583 printk("SEQSTAT: %08lx SP: %08lx\n", (long)fp->seqstat, (long)fp); 593 fp->rete, fp->retn, fp->retx, fp->rets);
584 printk("R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n", 594 printk(KERN_EMERG "IPEND: %04lx SYSCFG: %04lx\n",
585 fp->r0, fp->r1, fp->r2, fp->r3); 595 fp->ipend, fp->syscfg);
586 printk("R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n", 596 printk(KERN_EMERG "SEQSTAT: %08lx SP: %08lx\n",
587 fp->r4, fp->r5, fp->r6, fp->r7); 597 (long)fp->seqstat, (long)fp);
588 printk("P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n", 598 printk(KERN_EMERG "R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n",
589 fp->p0, fp->p1, fp->p2, fp->p3); 599 fp->r0, fp->r1, fp->r2, fp->r3);
590 printk("P4: %08lx P5: %08lx FP: %08lx\n", fp->p4, fp->p5, fp->fp); 600 printk(KERN_EMERG "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
591 printk("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", 601 fp->r4, fp->r5, fp->r6, fp->r7);
592 fp->a0w, fp->a0x, fp->a1w, fp->a1x); 602 printk(KERN_EMERG "P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n",
593 603 fp->p0, fp->p1, fp->p2, fp->p3);
594 printk("LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, 604 printk(KERN_EMERG
595 fp->lc0); 605 "P4: %08lx P5: %08lx FP: %08lx\n",
596 printk("LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1, 606 fp->p4, fp->p5, fp->fp);
597 fp->lc1); 607 printk(KERN_EMERG
598 printk("B0: %08lx L0: %08lx M0: %08lx I0: %08lx\n", fp->b0, fp->l0, 608 "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n",
599 fp->m0, fp->i0); 609 fp->a0w, fp->a0x, fp->a1w, fp->a1x);
600 printk("B1: %08lx L1: %08lx M1: %08lx I1: %08lx\n", fp->b1, fp->l1, 610
601 fp->m1, fp->i1); 611 printk(KERN_EMERG "LB0: %08lx LT0: %08lx LC0: %08lx\n",
602 printk("B2: %08lx L2: %08lx M2: %08lx I2: %08lx\n", fp->b2, fp->l2, 612 fp->lb0, fp->lt0, fp->lc0);
603 fp->m2, fp->i2); 613 printk(KERN_EMERG "LB1: %08lx LT1: %08lx LC1: %08lx\n",
604 printk("B3: %08lx L3: %08lx M3: %08lx I3: %08lx\n", fp->b3, fp->l3, 614 fp->lb1, fp->lt1, fp->lc1);
605 fp->m3, fp->i3); 615 printk(KERN_EMERG "B0: %08lx L0: %08lx M0: %08lx I0: %08lx\n",
606 616 fp->b0, fp->l0, fp->m0, fp->i0);
607 printk("\nUSP: %08lx ASTAT: %08lx\n", rdusp(), fp->astat); 617 printk(KERN_EMERG "B1: %08lx L1: %08lx M1: %08lx I1: %08lx\n",
618 fp->b1, fp->l1, fp->m1, fp->i1);
619 printk(KERN_EMERG "B2: %08lx L2: %08lx M2: %08lx I2: %08lx\n",
620 fp->b2, fp->l2, fp->m2, fp->i2);
621 printk(KERN_EMERG "B3: %08lx L3: %08lx M3: %08lx I3: %08lx\n",
622 fp->b3, fp->l3, fp->m3, fp->i3);
623
624 printk(KERN_EMERG "\n" KERN_EMERG "USP: %08lx ASTAT: %08lx\n",
625 rdusp(), fp->astat);
608 if ((long)fp->seqstat & SEQSTAT_EXCAUSE) { 626 if ((long)fp->seqstat & SEQSTAT_EXCAUSE) {
609 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR()); 627 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n",
610 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR()); 628 (void *)bfin_read_DCPLB_FAULT_ADDR());
629 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n",
630 (void *)bfin_read_ICPLB_FAULT_ADDR());
611 } 631 }
612 632
613 printk("\n\n"); 633 printk("\n\n");
@@ -649,8 +669,8 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
649 break; 669 break;
650 } 670 }
651 671
652 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR()); 672 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
653 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR()); 673 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
654 dump_bfin_regs(fp, (void *)fp->retx); 674 dump_bfin_regs(fp, (void *)fp->retx);
655 dump_stack(); 675 dump_stack();
656 panic("Unrecoverable event\n"); 676 panic("Unrecoverable event\n");