diff options
author | Robin Getz <rgetz@blackfin.uclinux.org> | 2008-08-06 05:49:27 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-08-06 05:49:27 -0400 |
commit | d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3 (patch) | |
tree | 6e6b1b4702bd38f294a4962e182606d2062451cd /arch/blackfin | |
parent | 56f5f59052bb662a77d5ffd6cbe5861a2ef2407c (diff) |
Blackfin arch: Fix bug - when expanding the trace buffer, it does not print out the decoded instruction.
as pointed out by Michael McTernan in the forums, when expanding
the trace buffer, it does not print out the decoded instruction.
Signed-off-by: Robin Getz <rgetz@blackfin.uclinux.org>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 88 |
1 files changed, 53 insertions, 35 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 62a47d67d876..9a9d5083acfd 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -601,12 +601,55 @@ bool get_instruction(unsigned short *val, unsigned short *address) | |||
601 | return false; | 601 | return false; |
602 | } | 602 | } |
603 | 603 | ||
604 | /* | ||
605 | * decode the instruction if we are printing out the trace, as it | ||
606 | * makes things easier to follow, without running it through objdump | ||
607 | * These are the normal instructions which cause change of flow, which | ||
608 | * would be at the source of the trace buffer | ||
609 | */ | ||
610 | void decode_instruction(unsigned short *address) | ||
611 | { | ||
612 | unsigned short opcode; | ||
613 | |||
614 | if (get_instruction(&opcode, address)) { | ||
615 | if (opcode == 0x0010) | ||
616 | printk("RTS"); | ||
617 | else if (opcode == 0x0011) | ||
618 | printk("RTI"); | ||
619 | else if (opcode == 0x0012) | ||
620 | printk("RTX"); | ||
621 | else if (opcode >= 0x0050 && opcode <= 0x0057) | ||
622 | printk("JUMP (P%i)", opcode & 7); | ||
623 | else if (opcode >= 0x0060 && opcode <= 0x0067) | ||
624 | printk("CALL (P%i)", opcode & 7); | ||
625 | else if (opcode >= 0x0070 && opcode <= 0x0077) | ||
626 | printk("CALL (PC+P%i)", opcode & 7); | ||
627 | else if (opcode >= 0x0080 && opcode <= 0x0087) | ||
628 | printk("JUMP (PC+P%i)", opcode & 7); | ||
629 | else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) | ||
630 | printk("IF !CC JUMP"); | ||
631 | else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) | ||
632 | printk("IF CC JUMP"); | ||
633 | else if (opcode >= 0x2000 && opcode <= 0x2fff) | ||
634 | printk("JUMP.S"); | ||
635 | else if (opcode >= 0xe080 && opcode <= 0xe0ff) | ||
636 | printk("LSETUP"); | ||
637 | else if (opcode >= 0xe200 && opcode <= 0xe2ff) | ||
638 | printk("JUMP.L"); | ||
639 | else if (opcode >= 0xe300 && opcode <= 0xe3ff) | ||
640 | printk("CALL pcrel"); | ||
641 | else | ||
642 | printk("0x%04x", opcode); | ||
643 | } | ||
644 | |||
645 | } | ||
646 | |||
604 | void dump_bfin_trace_buffer(void) | 647 | void dump_bfin_trace_buffer(void) |
605 | { | 648 | { |
606 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | 649 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
607 | int tflags, i = 0; | 650 | int tflags, i = 0; |
608 | char buf[150]; | 651 | char buf[150]; |
609 | unsigned short val = 0, *addr; | 652 | unsigned short *addr; |
610 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND | 653 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND |
611 | int j, index; | 654 | int j, index; |
612 | #endif | 655 | #endif |
@@ -615,6 +658,10 @@ void dump_bfin_trace_buffer(void) | |||
615 | 658 | ||
616 | printk(KERN_NOTICE "Hardware Trace:\n"); | 659 | printk(KERN_NOTICE "Hardware Trace:\n"); |
617 | 660 | ||
661 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND | ||
662 | printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); | ||
663 | #endif | ||
664 | |||
618 | if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { | 665 | if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { |
619 | for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { | 666 | for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { |
620 | decode_address(buf, (unsigned long)bfin_read_TBUF()); | 667 | decode_address(buf, (unsigned long)bfin_read_TBUF()); |
@@ -622,45 +669,14 @@ void dump_bfin_trace_buffer(void) | |||
622 | addr = (unsigned short *)bfin_read_TBUF(); | 669 | addr = (unsigned short *)bfin_read_TBUF(); |
623 | decode_address(buf, (unsigned long)addr); | 670 | decode_address(buf, (unsigned long)addr); |
624 | printk(KERN_NOTICE " Source : %s ", buf); | 671 | printk(KERN_NOTICE " Source : %s ", buf); |
625 | if (get_instruction(&val, addr)) { | 672 | decode_instruction(addr); |
626 | if (val == 0x0010) | ||
627 | printk("RTS"); | ||
628 | else if (val == 0x0011) | ||
629 | printk("RTI"); | ||
630 | else if (val == 0x0012) | ||
631 | printk("RTX"); | ||
632 | else if (val >= 0x0050 && val <= 0x0057) | ||
633 | printk("JUMP (P%i)", val & 7); | ||
634 | else if (val >= 0x0060 && val <= 0x0067) | ||
635 | printk("CALL (P%i)", val & 7); | ||
636 | else if (val >= 0x0070 && val <= 0x0077) | ||
637 | printk("CALL (PC+P%i)", val & 7); | ||
638 | else if (val >= 0x0080 && val <= 0x0087) | ||
639 | printk("JUMP (PC+P%i)", val & 7); | ||
640 | else if ((val >= 0x1000 && val <= 0x13FF) || | ||
641 | (val >= 0x1800 && val <= 0x1BFF)) | ||
642 | printk("IF !CC JUMP"); | ||
643 | else if ((val >= 0x1400 && val <= 0x17ff) || | ||
644 | (val >= 0x1c00 && val <= 0x1fff)) | ||
645 | printk("IF CC JUMP"); | ||
646 | else if (val >= 0x2000 && val <= 0x2fff) | ||
647 | printk("JUMP.S"); | ||
648 | else if (val >= 0xe080 && val <= 0xe0ff) | ||
649 | printk("LSETUP"); | ||
650 | else if (val >= 0xe200 && val <= 0xe2ff) | ||
651 | printk("JUMP.L"); | ||
652 | else if (val >= 0xe300 && val <= 0xe3ff) | ||
653 | printk("CALL pcrel"); | ||
654 | else | ||
655 | printk("0x%04x", val); | ||
656 | } | ||
657 | printk("\n"); | 673 | printk("\n"); |
658 | } | 674 | } |
659 | } | 675 | } |
660 | 676 | ||
661 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND | 677 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND |
662 | if (trace_buff_offset) | 678 | if (trace_buff_offset) |
663 | index = trace_buff_offset/4 - 1; | 679 | index = trace_buff_offset / 4; |
664 | else | 680 | else |
665 | index = EXPAND_LEN; | 681 | index = EXPAND_LEN; |
666 | 682 | ||
@@ -672,7 +688,9 @@ void dump_bfin_trace_buffer(void) | |||
672 | if (index < 0 ) | 688 | if (index < 0 ) |
673 | index = EXPAND_LEN; | 689 | index = EXPAND_LEN; |
674 | decode_address(buf, software_trace_buff[index]); | 690 | decode_address(buf, software_trace_buff[index]); |
675 | printk(KERN_NOTICE " Source : %s\n", buf); | 691 | printk(KERN_NOTICE " Source : %s ", buf); |
692 | decode_instruction((unsigned short *)software_trace_buff[index]); | ||
693 | printk("\n"); | ||
676 | index -= 1; | 694 | index -= 1; |
677 | if (index < 0) | 695 | if (index < 0) |
678 | index = EXPAND_LEN; | 696 | index = EXPAND_LEN; |