diff options
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 90 |
1 files changed, 54 insertions, 36 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index ad922ab91543..9a9d5083acfd 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -567,7 +567,7 @@ bool get_instruction(unsigned short *val, unsigned short *address) | |||
567 | * we don't read something in the async space that can hang forever | 567 | * we don't read something in the async space that can hang forever |
568 | */ | 568 | */ |
569 | if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || | 569 | if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || |
570 | #ifdef L2_START | 570 | #if L2_LENGTH != 0 |
571 | (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || | 571 | (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || |
572 | #endif | 572 | #endif |
573 | (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || | 573 | (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || |
@@ -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; |