diff options
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index ffe7fb53eccb..aa76dfb0226e 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -68,6 +68,13 @@ | |||
68 | ({ if (0) printk(fmt, ##arg); 0; }) | 68 | ({ if (0) printk(fmt, ##arg); 0; }) |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | #if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) | ||
72 | u32 last_seqstat; | ||
73 | #ifdef CONFIG_DEBUG_MMRS_MODULE | ||
74 | EXPORT_SYMBOL(last_seqstat); | ||
75 | #endif | ||
76 | #endif | ||
77 | |||
71 | /* Initiate the event table handler */ | 78 | /* Initiate the event table handler */ |
72 | void __init trap_init(void) | 79 | void __init trap_init(void) |
73 | { | 80 | { |
@@ -79,7 +86,6 @@ void __init trap_init(void) | |||
79 | static void decode_address(char *buf, unsigned long address) | 86 | static void decode_address(char *buf, unsigned long address) |
80 | { | 87 | { |
81 | #ifdef CONFIG_DEBUG_VERBOSE | 88 | #ifdef CONFIG_DEBUG_VERBOSE |
82 | struct vm_list_struct *vml; | ||
83 | struct task_struct *p; | 89 | struct task_struct *p; |
84 | struct mm_struct *mm; | 90 | struct mm_struct *mm; |
85 | unsigned long flags, offset; | 91 | unsigned long flags, offset; |
@@ -196,6 +202,11 @@ done: | |||
196 | 202 | ||
197 | asmlinkage void double_fault_c(struct pt_regs *fp) | 203 | asmlinkage void double_fault_c(struct pt_regs *fp) |
198 | { | 204 | { |
205 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | ||
206 | int j; | ||
207 | trace_buffer_save(j); | ||
208 | #endif | ||
209 | |||
199 | console_verbose(); | 210 | console_verbose(); |
200 | oops_in_progress = 1; | 211 | oops_in_progress = 1; |
201 | #ifdef CONFIG_DEBUG_VERBOSE | 212 | #ifdef CONFIG_DEBUG_VERBOSE |
@@ -220,9 +231,10 @@ asmlinkage void double_fault_c(struct pt_regs *fp) | |||
220 | dump_bfin_process(fp); | 231 | dump_bfin_process(fp); |
221 | dump_bfin_mem(fp); | 232 | dump_bfin_mem(fp); |
222 | show_regs(fp); | 233 | show_regs(fp); |
234 | dump_bfin_trace_buffer(); | ||
223 | } | 235 | } |
224 | #endif | 236 | #endif |
225 | panic("Double Fault - unrecoverable event\n"); | 237 | panic("Double Fault - unrecoverable event"); |
226 | 238 | ||
227 | } | 239 | } |
228 | 240 | ||
@@ -239,6 +251,9 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
239 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; | 251 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; |
240 | 252 | ||
241 | trace_buffer_save(j); | 253 | trace_buffer_save(j); |
254 | #if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) | ||
255 | last_seqstat = (u32)fp->seqstat; | ||
256 | #endif | ||
242 | 257 | ||
243 | /* Important - be very careful dereferncing pointers - will lead to | 258 | /* Important - be very careful dereferncing pointers - will lead to |
244 | * double faults if the stack has become corrupt | 259 | * double faults if the stack has become corrupt |
@@ -588,6 +603,9 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
588 | force_sig_info(sig, &info, current); | 603 | force_sig_info(sig, &info, current); |
589 | } | 604 | } |
590 | 605 | ||
606 | if (ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) | ||
607 | fp->pc = SAFE_USER_INSTRUCTION; | ||
608 | |||
591 | trace_buffer_restore(j); | 609 | trace_buffer_restore(j); |
592 | return; | 610 | return; |
593 | } | 611 | } |
@@ -832,6 +850,11 @@ void show_stack(struct task_struct *task, unsigned long *stack) | |||
832 | decode_address(buf, (unsigned int)stack); | 850 | decode_address(buf, (unsigned int)stack); |
833 | printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); | 851 | printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); |
834 | 852 | ||
853 | if (!access_ok(VERIFY_READ, stack, (unsigned int)endstack - (unsigned int)stack)) { | ||
854 | printk(KERN_NOTICE "Invalid stack pointer\n"); | ||
855 | return; | ||
856 | } | ||
857 | |||
835 | /* First thing is to look for a frame pointer */ | 858 | /* First thing is to look for a frame pointer */ |
836 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { | 859 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { |
837 | if (*addr & 0x1) | 860 | if (*addr & 0x1) |
@@ -1066,6 +1089,29 @@ void show_regs(struct pt_regs *fp) | |||
1066 | unsigned int cpu = smp_processor_id(); | 1089 | unsigned int cpu = smp_processor_id(); |
1067 | unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); | 1090 | unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); |
1068 | 1091 | ||
1092 | verbose_printk(KERN_NOTICE "\n"); | ||
1093 | if (CPUID != bfin_cpuid()) | ||
1094 | verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " | ||
1095 | "but running on:0x%04x (Rev %d)\n", | ||
1096 | CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); | ||
1097 | |||
1098 | verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", | ||
1099 | CPU, bfin_compiled_revid()); | ||
1100 | |||
1101 | if (bfin_compiled_revid() != bfin_revid()) | ||
1102 | verbose_printk("(Detected 0.%d)", bfin_revid()); | ||
1103 | |||
1104 | verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", | ||
1105 | get_cclk()/1000000, get_sclk()/1000000, | ||
1106 | #ifdef CONFIG_MPU | ||
1107 | "mpu on" | ||
1108 | #else | ||
1109 | "mpu off" | ||
1110 | #endif | ||
1111 | ); | ||
1112 | |||
1113 | verbose_printk(KERN_NOTICE "%s", linux_banner); | ||
1114 | |||
1069 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); | 1115 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); |
1070 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 1116 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", |
1071 | (long)fp->seqstat, fp->ipend, fp->syscfg); | 1117 | (long)fp->seqstat, fp->ipend, fp->syscfg); |
@@ -1246,5 +1292,5 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) | |||
1246 | dump_bfin_mem(fp); | 1292 | dump_bfin_mem(fp); |
1247 | show_regs(fp); | 1293 | show_regs(fp); |
1248 | dump_stack(); | 1294 | dump_stack(); |
1249 | panic("Unrecoverable event\n"); | 1295 | panic("Unrecoverable event"); |
1250 | } | 1296 | } |