aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/traps_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/traps_32.c')
-rw-r--r--arch/sh/kernel/traps_32.c36
1 files changed, 12 insertions, 24 deletions
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 1e5c74efbacc..88807a2aacc3 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -28,17 +28,6 @@
28#include <asm/fpu.h> 28#include <asm/fpu.h>
29#include <asm/kprobes.h> 29#include <asm/kprobes.h>
30 30
31#ifdef CONFIG_SH_KGDB
32#include <asm/kgdb.h>
33#define CHK_REMOTE_DEBUG(regs) \
34{ \
35 if (kgdb_debug_hook && !user_mode(regs))\
36 (*kgdb_debug_hook)(regs); \
37}
38#else
39#define CHK_REMOTE_DEBUG(regs)
40#endif
41
42#ifdef CONFIG_CPU_SH2 31#ifdef CONFIG_CPU_SH2
43# define TRAP_RESERVED_INST 4 32# define TRAP_RESERVED_INST 4
44# define TRAP_ILLEGAL_SLOT_INST 6 33# define TRAP_ILLEGAL_SLOT_INST 6
@@ -94,7 +83,6 @@ void die(const char * str, struct pt_regs * regs, long err)
94 83
95 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 84 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
96 85
97 CHK_REMOTE_DEBUG(regs);
98 print_modules(); 86 print_modules();
99 show_regs(regs); 87 show_regs(regs);
100 88
@@ -683,13 +671,12 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
683 error_code = lookup_exception_vector(); 671 error_code = lookup_exception_vector();
684 672
685 local_irq_enable(); 673 local_irq_enable();
686 CHK_REMOTE_DEBUG(regs);
687 force_sig(SIGILL, tsk); 674 force_sig(SIGILL, tsk);
688 die_if_no_fixup("reserved instruction", regs, error_code); 675 die_if_no_fixup("reserved instruction", regs, error_code);
689} 676}
690 677
691#ifdef CONFIG_SH_FPU_EMU 678#ifdef CONFIG_SH_FPU_EMU
692static int emulate_branch(unsigned short inst, struct pt_regs* regs) 679static int emulate_branch(unsigned short inst, struct pt_regs *regs)
693{ 680{
694 /* 681 /*
695 * bfs: 8fxx: PC+=d*2+4; 682 * bfs: 8fxx: PC+=d*2+4;
@@ -702,27 +689,32 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
702 * jsr: 4x0b: PC=Rn after PR=PC+4; 689 * jsr: 4x0b: PC=Rn after PR=PC+4;
703 * rts: 000b: PC=PR; 690 * rts: 000b: PC=PR;
704 */ 691 */
705 if ((inst & 0xfd00) == 0x8d00) { 692 if (((inst & 0xf000) == 0xb000) || /* bsr */
693 ((inst & 0xf0ff) == 0x0003) || /* bsrf */
694 ((inst & 0xf0ff) == 0x400b)) /* jsr */
695 regs->pr = regs->pc + 4;
696
697 if ((inst & 0xfd00) == 0x8d00) { /* bfs, bts */
706 regs->pc += SH_PC_8BIT_OFFSET(inst); 698 regs->pc += SH_PC_8BIT_OFFSET(inst);
707 return 0; 699 return 0;
708 } 700 }
709 701
710 if ((inst & 0xe000) == 0xa000) { 702 if ((inst & 0xe000) == 0xa000) { /* bra, bsr */
711 regs->pc += SH_PC_12BIT_OFFSET(inst); 703 regs->pc += SH_PC_12BIT_OFFSET(inst);
712 return 0; 704 return 0;
713 } 705 }
714 706
715 if ((inst & 0xf0df) == 0x0003) { 707 if ((inst & 0xf0df) == 0x0003) { /* braf, bsrf */
716 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; 708 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
717 return 0; 709 return 0;
718 } 710 }
719 711
720 if ((inst & 0xf0df) == 0x400b) { 712 if ((inst & 0xf0df) == 0x400b) { /* jmp, jsr */
721 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; 713 regs->pc = regs->regs[(inst & 0x0f00) >> 8];
722 return 0; 714 return 0;
723 } 715 }
724 716
725 if ((inst & 0xffff) == 0x000b) { 717 if ((inst & 0xffff) == 0x000b) { /* rts */
726 regs->pc = regs->pr; 718 regs->pc = regs->pr;
727 return 0; 719 return 0;
728 } 720 }
@@ -756,7 +748,6 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
756 inst = lookup_exception_vector(); 748 inst = lookup_exception_vector();
757 749
758 local_irq_enable(); 750 local_irq_enable();
759 CHK_REMOTE_DEBUG(regs);
760 force_sig(SIGILL, tsk); 751 force_sig(SIGILL, tsk);
761 die_if_no_fixup("illegal slot instruction", regs, inst); 752 die_if_no_fixup("illegal slot instruction", regs, inst);
762} 753}
@@ -868,10 +859,7 @@ void show_trace(struct task_struct *tsk, unsigned long *sp,
868 if (regs && user_mode(regs)) 859 if (regs && user_mode(regs))
869 return; 860 return;
870 861
871 printk("\nCall trace: "); 862 printk("\nCall trace:\n");
872#ifdef CONFIG_KALLSYMS
873 printk("\n");
874#endif
875 863
876 while (!kstack_end(sp)) { 864 while (!kstack_end(sp)) {
877 addr = *sp++; 865 addr = *sp++;