diff options
author | Robin Getz <robin.getz@analog.com> | 2007-07-24 23:03:28 -0400 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-07-24 23:03:28 -0400 |
commit | 518039bc24cbb9ce34665814fe120eac50bedd9a (patch) | |
tree | 6b089a05025ae224d6636b6dc9d95e7c9e4677eb /arch/blackfin/kernel/traps.c | |
parent | f16295e7e7f2a2a15876f570f10d6dc8f1f36ab8 (diff) |
Blackfin arch: Add ability to expend the hardware trace buffer
Add ability to expend the hardware trace buffer via a configurable
software buffer - so you can have lots of history when a crash occurs.
The interesting way we do printk in the traps.c confusese the checking
script
Signed-off-by: Robin Getz <robin.getz@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 792a8416fe10..0ec02fe663e9 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -55,6 +55,7 @@ asmlinkage void trap_c(struct pt_regs *fp); | |||
55 | 55 | ||
56 | int kstack_depth_to_print = 48; | 56 | int kstack_depth_to_print = 48; |
57 | 57 | ||
58 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | ||
58 | static int printk_address(unsigned long address) | 59 | static int printk_address(unsigned long address) |
59 | { | 60 | { |
60 | struct vm_list_struct *vml; | 61 | struct vm_list_struct *vml; |
@@ -131,10 +132,14 @@ static int printk_address(unsigned long address) | |||
131 | /* we were unable to find this address anywhere */ | 132 | /* we were unable to find this address anywhere */ |
132 | return printk("[<0x%p>]", (void *)address); | 133 | return printk("[<0x%p>]", (void *)address); |
133 | } | 134 | } |
135 | #endif | ||
134 | 136 | ||
135 | asmlinkage void trap_c(struct pt_regs *fp) | 137 | asmlinkage void trap_c(struct pt_regs *fp) |
136 | { | 138 | { |
137 | int j, sig = 0; | 139 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
140 | int j; | ||
141 | #endif | ||
142 | int sig = 0; | ||
138 | siginfo_t info; | 143 | siginfo_t info; |
139 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; | 144 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; |
140 | 145 | ||
@@ -429,24 +434,56 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
429 | 434 | ||
430 | /* Typical exception handling routines */ | 435 | /* Typical exception handling routines */ |
431 | 436 | ||
437 | #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) | ||
438 | |||
432 | void dump_bfin_trace_buffer(void) | 439 | void dump_bfin_trace_buffer(void) |
433 | { | 440 | { |
434 | int tflags; | 441 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
442 | int tflags, i = 0; | ||
443 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND | ||
444 | int j, index; | ||
445 | #endif | ||
446 | |||
435 | trace_buffer_save(tflags); | 447 | trace_buffer_save(tflags); |
436 | 448 | ||
449 | printk(KERN_EMERG "Hardware Trace:\n"); | ||
450 | |||
437 | if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { | 451 | if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { |
438 | int i; | 452 | for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { |
439 | printk(KERN_EMERG "Hardware Trace:\n"); | 453 | printk(KERN_EMERG "%4i Target : ", i); |
440 | for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) { | ||
441 | printk(KERN_EMERG "%2i Target : ", i); | ||
442 | printk_address((unsigned long)bfin_read_TBUF()); | 454 | printk_address((unsigned long)bfin_read_TBUF()); |
443 | printk("\n" KERN_EMERG " Source : "); | 455 | printk("\n" KERN_EMERG " Source : "); |
444 | printk_address((unsigned long)bfin_read_TBUF()); | 456 | printk_address((unsigned long)bfin_read_TBUF()); |
445 | printk("\n"); | 457 | printk("\n"); |
446 | } | 458 | } |
447 | } | 459 | } |
448 | 460 | ||
461 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND | ||
462 | if (trace_buff_offset) | ||
463 | index = trace_buff_offset/4 - 1; | ||
464 | else | ||
465 | index = EXPAND_LEN; | ||
466 | |||
467 | j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; | ||
468 | while (j) { | ||
469 | printk(KERN_EMERG "%4i Target : ", i); | ||
470 | printk_address(software_trace_buff[index]); | ||
471 | index -= 1; | ||
472 | if (index < 0 ) | ||
473 | index = EXPAND_LEN; | ||
474 | printk("\n" KERN_EMERG " Source : "); | ||
475 | printk_address(software_trace_buff[index]); | ||
476 | index -= 1; | ||
477 | if (index < 0) | ||
478 | index = EXPAND_LEN; | ||
479 | printk("\n"); | ||
480 | j--; | ||
481 | i++; | ||
482 | } | ||
483 | #endif | ||
484 | |||
449 | trace_buffer_restore(tflags); | 485 | trace_buffer_restore(tflags); |
486 | #endif | ||
450 | } | 487 | } |
451 | EXPORT_SYMBOL(dump_bfin_trace_buffer); | 488 | EXPORT_SYMBOL(dump_bfin_trace_buffer); |
452 | 489 | ||
@@ -510,7 +547,9 @@ void show_stack(struct task_struct *task, unsigned long *stack) | |||
510 | void dump_stack(void) | 547 | void dump_stack(void) |
511 | { | 548 | { |
512 | unsigned long stack; | 549 | unsigned long stack; |
550 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | ||
513 | int tflags; | 551 | int tflags; |
552 | #endif | ||
514 | trace_buffer_save(tflags); | 553 | trace_buffer_save(tflags); |
515 | dump_bfin_trace_buffer(); | 554 | dump_bfin_trace_buffer(); |
516 | show_stack(current, &stack); | 555 | show_stack(current, &stack); |