1
2
3
4
5
6
7
8
9#include <linux/bug.h>
10#include <linux/uaccess.h>
11#include <linux/module.h>
12#include <linux/sched/signal.h>
13#include <linux/sched/debug.h>
14#include <asm/traps.h>
15#include <asm/cplb.h>
16#include <asm/blackfin.h>
17#include <asm/irq_handler.h>
18#include <linux/irq.h>
19#include <asm/trace.h>
20#include <asm/fixed_code.h>
21#include <asm/pseudo_instructions.h>
22#include <asm/pda.h>
23#include <asm/asm-offsets.h>
24
25#ifdef CONFIG_KGDB
26# include <linux/kgdb.h>
27
28# define CHK_DEBUGGER_TRAP() \
29 do { \
30 kgdb_handle_exception(trapnr, sig, info.si_code, fp); \
31 } while (0)
32# define CHK_DEBUGGER_TRAP_MAYBE() \
33 do { \
34 if (kgdb_connected) \
35 CHK_DEBUGGER_TRAP(); \
36 } while (0)
37#else
38# define CHK_DEBUGGER_TRAP() do { } while (0)
39# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0)
40#endif
41
42
43#ifdef CONFIG_DEBUG_VERBOSE
44#define verbose_printk(fmt, arg...) \
45 printk(fmt, ##arg)
46#else
47#define verbose_printk(fmt, arg...) \
48 ({ if (0) printk(fmt, ##arg); 0; })
49#endif
50
51#if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE)
52u32 last_seqstat;
53#ifdef CONFIG_DEBUG_MMRS_MODULE
54EXPORT_SYMBOL(last_seqstat);
55#endif
56#endif
57
58
59void __init trap_init(void)
60{
61 CSYNC();
62 bfin_write_EVT3(trap);
63 CSYNC();
64}
65
66static int kernel_mode_regs(struct pt_regs *regs)
67{
68 return regs->ipend & 0xffc0;
69}
70
71asmlinkage notrace void trap_c(struct pt_regs *fp)
72{
73#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
74 int j;
75#endif
76#ifdef CONFIG_BFIN_PSEUDODBG_INSNS
77 int opcode;
78#endif
79 unsigned int cpu = raw_smp_processor_id();
80 const char *strerror = NULL;
81 int sig = 0;
82 siginfo_t info;
83 unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
84
85 trace_buffer_save(j);
86#if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE)
87 last_seqstat = (u32)fp->seqstat;
88#endif
89
90
91
92
93
94
95
96
97
98 fp->orig_pc = fp->retx;
99
100
101
102
103 switch (trapnr) {
104
105
106
107
108
109
110
111
112
113
114
115 case VEC_EXCPT01:
116 info.si_code = TRAP_ILLTRAP;
117 sig = SIGTRAP;
118 CHK_DEBUGGER_TRAP_MAYBE();
119
120 if (kernel_mode_regs(fp))
121 goto traps_done;
122 else
123 break;
124
125 case VEC_EXCPT03:
126 info.si_code = SEGV_STACKFLOW;
127 sig = SIGSEGV;
128 strerror = KERN_NOTICE EXC_0x03(KERN_NOTICE);
129 CHK_DEBUGGER_TRAP_MAYBE();
130 break;
131
132 case VEC_EXCPT02:
133#ifdef CONFIG_KGDB
134 info.si_code = TRAP_ILLTRAP;
135 sig = SIGTRAP;
136 CHK_DEBUGGER_TRAP();
137 goto traps_done;
138#endif
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 case VEC_EXCPT04 ... VEC_EXCPT15:
155 info.si_code = ILL_ILLPARAOP;
156 sig = SIGILL;
157 strerror = KERN_NOTICE EXC_0x04(KERN_NOTICE);
158 CHK_DEBUGGER_TRAP_MAYBE();
159 break;
160
161 case VEC_STEP:
162 info.si_code = TRAP_STEP;
163 sig = SIGTRAP;
164 CHK_DEBUGGER_TRAP_MAYBE();
165
166 if (kernel_mode_regs(fp))
167 goto traps_done;
168 else
169 break;
170
171 case VEC_OVFLOW:
172 info.si_code = TRAP_TRACEFLOW;
173 sig = SIGTRAP;
174 strerror = KERN_NOTICE EXC_0x11(KERN_NOTICE);
175 CHK_DEBUGGER_TRAP_MAYBE();
176 break;
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 case VEC_UNDEF_I:
194#ifdef CONFIG_BUG
195 if (kernel_mode_regs(fp)) {
196 switch (report_bug(fp->pc, fp)) {
197 case BUG_TRAP_TYPE_NONE:
198 break;
199 case BUG_TRAP_TYPE_WARN:
200 dump_bfin_trace_buffer();
201 fp->pc += 2;
202 goto traps_done;
203 case BUG_TRAP_TYPE_BUG:
204
205
206
207 panic("BUG()");
208 }
209 }
210#endif
211#ifdef CONFIG_BFIN_PSEUDODBG_INSNS
212
213
214
215
216
217 if (!kernel_mode_regs(fp) && get_instruction(&opcode, (unsigned short *)fp->pc)) {
218 if (execute_pseudodbg_assert(fp, opcode))
219 goto traps_done;
220 if (execute_pseudodbg(fp, opcode))
221 goto traps_done;
222 }
223#endif
224 info.si_code = ILL_ILLOPC;
225 sig = SIGILL;
226 strerror = KERN_NOTICE EXC_0x21(KERN_NOTICE);
227 CHK_DEBUGGER_TRAP_MAYBE();
228 break;
229
230 case VEC_ILGAL_I:
231 info.si_code = ILL_ILLPARAOP;
232 sig = SIGILL;
233 strerror = KERN_NOTICE EXC_0x22(KERN_NOTICE);
234 CHK_DEBUGGER_TRAP_MAYBE();
235 break;
236
237 case VEC_CPLB_VL:
238 info.si_code = ILL_CPLB_VI;
239 sig = SIGSEGV;
240 strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE);
241 CHK_DEBUGGER_TRAP_MAYBE();
242 break;
243
244 case VEC_MISALI_D:
245 info.si_code = BUS_ADRALN;
246 sig = SIGBUS;
247 strerror = KERN_NOTICE EXC_0x24(KERN_NOTICE);
248 CHK_DEBUGGER_TRAP_MAYBE();
249 break;
250
251 case VEC_UNCOV:
252 info.si_code = ILL_ILLEXCPT;
253 sig = SIGILL;
254 strerror = KERN_NOTICE EXC_0x25(KERN_NOTICE);
255 CHK_DEBUGGER_TRAP_MAYBE();
256 break;
257
258
259 case VEC_CPLB_M:
260 info.si_code = BUS_ADRALN;
261 sig = SIGBUS;
262 strerror = KERN_NOTICE EXC_0x26(KERN_NOTICE);
263 break;
264
265 case VEC_CPLB_MHIT:
266 info.si_code = ILL_CPLB_MULHIT;
267 sig = SIGSEGV;
268#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
269 if (cpu_pda[cpu].dcplb_fault_addr < FIXED_CODE_START)
270 strerror = KERN_NOTICE "NULL pointer access\n";
271 else
272#endif
273 strerror = KERN_NOTICE EXC_0x27(KERN_NOTICE);
274 CHK_DEBUGGER_TRAP_MAYBE();
275 break;
276
277 case VEC_WATCH:
278 info.si_code = TRAP_WATCHPT;
279 sig = SIGTRAP;
280 pr_debug(EXC_0x28(KERN_DEBUG));
281 CHK_DEBUGGER_TRAP_MAYBE();
282
283 if (kernel_mode_regs(fp))
284 goto traps_done;
285 else
286 break;
287#ifdef CONFIG_BF535
288
289 case VEC_ISTRU_VL:
290 info.si_code = BUS_OPFETCH;
291 sig = SIGBUS;
292 strerror = KERN_NOTICE "BF535: VEC_ISTRU_VL\n";
293 CHK_DEBUGGER_TRAP_MAYBE();
294 break;
295#else
296
297#endif
298
299 case VEC_MISALI_I:
300 info.si_code = BUS_ADRALN;
301 sig = SIGBUS;
302 strerror = KERN_NOTICE EXC_0x2A(KERN_NOTICE);
303 CHK_DEBUGGER_TRAP_MAYBE();
304 break;
305
306 case VEC_CPLB_I_VL:
307 info.si_code = ILL_CPLB_VI;
308 sig = SIGBUS;
309 strerror = KERN_NOTICE EXC_0x2B(KERN_NOTICE);
310 CHK_DEBUGGER_TRAP_MAYBE();
311 break;
312
313 case VEC_CPLB_I_M:
314 info.si_code = ILL_CPLB_MISS;
315 sig = SIGBUS;
316 strerror = KERN_NOTICE EXC_0x2C(KERN_NOTICE);
317 break;
318
319 case VEC_CPLB_I_MHIT:
320 info.si_code = ILL_CPLB_MULHIT;
321 sig = SIGSEGV;
322#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
323 if (cpu_pda[cpu].icplb_fault_addr < FIXED_CODE_START)
324 strerror = KERN_NOTICE "Jump to NULL address\n";
325 else
326#endif
327 strerror = KERN_NOTICE EXC_0x2D(KERN_NOTICE);
328 CHK_DEBUGGER_TRAP_MAYBE();
329 break;
330
331 case VEC_ILL_RES:
332 info.si_code = ILL_PRVOPC;
333 sig = SIGILL;
334 strerror = KERN_NOTICE EXC_0x2E(KERN_NOTICE);
335 CHK_DEBUGGER_TRAP_MAYBE();
336 break;
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 case VEC_HWERR:
355 info.si_code = BUS_ADRALN;
356 sig = SIGBUS;
357 switch (fp->seqstat & SEQSTAT_HWERRCAUSE) {
358
359 case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR):
360 info.si_code = BUS_ADRALN;
361 sig = SIGBUS;
362 strerror = KERN_NOTICE HWC_x2(KERN_NOTICE);
363 break;
364
365 case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):
366 if (ANOMALY_05000310) {
367 static unsigned long anomaly_rets;
368
369 if ((fp->pc >= (L1_CODE_START + L1_CODE_LENGTH - 512)) &&
370 (fp->pc < (L1_CODE_START + L1_CODE_LENGTH))) {
371
372
373
374
375 anomaly_rets = fp->rets;
376 goto traps_done;
377 } else if (fp->rets == anomaly_rets) {
378
379
380
381
382
383 goto traps_done;
384 } else if ((fp->rets >= (L1_CODE_START + L1_CODE_LENGTH - 512)) &&
385 (fp->rets < (L1_CODE_START + L1_CODE_LENGTH))) {
386
387
388
389
390
391 goto traps_done;
392 } else
393 anomaly_rets = 0;
394 }
395
396 info.si_code = BUS_ADRERR;
397 sig = SIGBUS;
398 strerror = KERN_NOTICE HWC_x3(KERN_NOTICE);
399 break;
400
401 case (SEQSTAT_HWERRCAUSE_PERF_FLOW):
402 strerror = KERN_NOTICE HWC_x12(KERN_NOTICE);
403 break;
404
405 case (SEQSTAT_HWERRCAUSE_RAISE_5):
406 printk(KERN_NOTICE HWC_x18(KERN_NOTICE));
407 break;
408 default:
409 printk(KERN_NOTICE HWC_default(KERN_NOTICE));
410 break;
411 }
412 CHK_DEBUGGER_TRAP_MAYBE();
413 break;
414
415
416
417
418 default:
419 info.si_code = ILL_ILLPARAOP;
420 sig = SIGILL;
421 verbose_printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
422 (fp->seqstat & SEQSTAT_EXCAUSE));
423 CHK_DEBUGGER_TRAP_MAYBE();
424 break;
425 }
426
427 BUG_ON(sig == 0);
428
429
430
431
432 if (kernel_mode_regs(fp) || (current && !current->mm)) {
433 console_verbose();
434 oops_in_progress = 1;
435 }
436
437 if (sig != SIGTRAP) {
438 if (strerror)
439 verbose_printk(strerror);
440
441 dump_bfin_process(fp);
442 dump_bfin_mem(fp);
443 show_regs(fp);
444
445
446#ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
447 if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M)
448 verbose_printk(KERN_NOTICE "No trace since you do not have "
449 "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n\n");
450 else
451#endif
452 dump_bfin_trace_buffer();
453
454 if (oops_in_progress) {
455
456 verbose_printk(KERN_NOTICE "Kernel Stack\n");
457 show_stack(current, NULL);
458 print_modules();
459#ifndef CONFIG_ACCESS_CHECK
460 verbose_printk(KERN_EMERG "Please turn on "
461 "CONFIG_ACCESS_CHECK\n");
462#endif
463 panic("Kernel exception");
464 } else {
465#ifdef CONFIG_DEBUG_VERBOSE
466 unsigned long *stack;
467
468 stack = (unsigned long *)rdusp();
469 verbose_printk(KERN_NOTICE "Userspace Stack\n");
470 show_stack(NULL, stack);
471#endif
472 }
473 }
474
475#ifdef CONFIG_IPIPE
476 if (!ipipe_trap_notify(fp->seqstat & 0x3f, fp))
477#endif
478 {
479 info.si_signo = sig;
480 info.si_errno = 0;
481 switch (trapnr) {
482 case VEC_CPLB_VL:
483 case VEC_MISALI_D:
484 case VEC_CPLB_M:
485 case VEC_CPLB_MHIT:
486 info.si_addr = (void __user *)cpu_pda[cpu].dcplb_fault_addr;
487 break;
488 default:
489 info.si_addr = (void __user *)fp->pc;
490 break;
491 }
492 force_sig_info(sig, &info, current);
493 }
494
495 if ((ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) ||
496 (ANOMALY_05000281 && trapnr == VEC_HWERR) ||
497 (ANOMALY_05000189 && (trapnr == VEC_CPLB_I_VL || trapnr == VEC_CPLB_VL)))
498 fp->pc = SAFE_USER_INSTRUCTION;
499
500 traps_done:
501 trace_buffer_restore(j);
502}
503
504asmlinkage void double_fault_c(struct pt_regs *fp)
505{
506#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
507 int j;
508 trace_buffer_save(j);
509#endif
510
511 console_verbose();
512 oops_in_progress = 1;
513#ifdef CONFIG_DEBUG_VERBOSE
514 printk(KERN_EMERG "Double Fault\n");
515#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
516 if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) {
517 unsigned int cpu = raw_smp_processor_id();
518 char buf[150];
519 decode_address(buf, cpu_pda[cpu].retx_doublefault);
520 printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n",
521 (unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf);
522 decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr);
523 printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf);
524 decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr);
525 printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf);
526
527 decode_address(buf, fp->retx);
528 printk(KERN_NOTICE "The instruction at %s caused a double exception\n", buf);
529 } else
530#endif
531 {
532 dump_bfin_process(fp);
533 dump_bfin_mem(fp);
534 show_regs(fp);
535 dump_bfin_trace_buffer();
536 }
537#endif
538 panic("Double Fault - unrecoverable event");
539
540}
541
542
543void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
544{
545 switch (cplb_panic) {
546 case CPLB_NO_UNLOCKED:
547 printk(KERN_EMERG "All CPLBs are locked\n");
548 break;
549 case CPLB_PROT_VIOL:
550 return;
551 case CPLB_NO_ADDR_MATCH:
552 return;
553 case CPLB_UNKNOWN_ERR:
554 printk(KERN_EMERG "Unknown CPLB Exception\n");
555 break;
556 }
557
558 oops_in_progress = 1;
559
560 dump_bfin_process(fp);
561 dump_bfin_mem(fp);
562 show_regs(fp);
563 dump_stack();
564 panic("Unrecoverable event");
565}
566
567#ifdef CONFIG_BUG
568int is_valid_bugaddr(unsigned long addr)
569{
570 unsigned int opcode;
571
572 if (!get_instruction(&opcode, (unsigned short *)addr))
573 return 0;
574
575 return opcode == BFIN_BUG_OPCODE;
576}
577#endif
578
579
580#ifndef CONFIG_DEBUG_VERBOSE
581void show_regs(struct pt_regs *fp)
582{
583
584}
585#endif
586