diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-11-20 04:08:06 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-01-27 23:18:50 -0500 |
commit | 5a4f7c66be981c6b5f44a4d66a14ea6ac9b7b6b0 (patch) | |
tree | a605424a32ce11d189a1aa1385c3fc22f972449f | |
parent | 811d50cb43eb730cc325df0c6913556e25739797 (diff) |
sh: Share bug/debug traps across _32 and _64.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/kernel/Makefile_32 | 2 | ||||
-rw-r--r-- | arch/sh/kernel/Makefile_64 | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2/entry.S | 2 | ||||
-rw-r--r-- | arch/sh/kernel/process_32.c | 46 | ||||
-rw-r--r-- | arch/sh/kernel/process_64.c | 15 | ||||
-rw-r--r-- | arch/sh/kernel/traps.c | 66 | ||||
-rw-r--r-- | arch/sh/kernel/traps_32.c | 25 | ||||
-rw-r--r-- | include/asm-sh/ptrace.h | 2 | ||||
-rw-r--r-- | include/asm-sh/system.h | 25 | ||||
-rw-r--r-- | include/asm-sh/types.h | 6 |
10 files changed, 102 insertions, 89 deletions
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index 34e8fa0d40cc..990ba74db0d6 100644 --- a/arch/sh/kernel/Makefile_32 +++ b/arch/sh/kernel/Makefile_32 | |||
@@ -6,7 +6,7 @@ extra-y := head_32.o init_task.o vmlinux.lds | |||
6 | 6 | ||
7 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ | 7 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ |
8 | ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \ | 8 | ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \ |
9 | syscalls_32.o time.o topology.o traps_32.o | 9 | syscalls_32.o time.o topology.o traps.o traps_32.o |
10 | 10 | ||
11 | obj-y += cpu/ timers/ | 11 | obj-y += cpu/ timers/ |
12 | obj-$(CONFIG_VSYSCALL) += vsyscall/ | 12 | obj-$(CONFIG_VSYSCALL) += vsyscall/ |
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64 index aeac4006df7b..10e3ae1c64b8 100644 --- a/arch/sh/kernel/Makefile_64 +++ b/arch/sh/kernel/Makefile_64 | |||
@@ -2,7 +2,7 @@ extra-y := head_64.o init_task.o vmlinux.lds | |||
2 | 2 | ||
3 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ | 3 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ |
4 | ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \ | 4 | ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \ |
5 | syscalls_64.o time.o topology.o traps_64.o | 5 | syscalls_64.o time.o topology.o traps.o traps_64.o |
6 | 6 | ||
7 | obj-y += cpu/ timers/ | 7 | obj-y += cpu/ timers/ |
8 | obj-$(CONFIG_VSYSCALL) += vsyscall/ | 8 | obj-$(CONFIG_VSYSCALL) += vsyscall/ |
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index ee8f1fe84b08..4ff2334b4a38 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S | |||
@@ -250,7 +250,7 @@ ENTRY(sh_bios_handler) | |||
250 | 1: .long gdb_vbr_vector | 250 | 1: .long gdb_vbr_vector |
251 | #endif /* CONFIG_SH_STANDARD_BIOS */ | 251 | #endif /* CONFIG_SH_STANDARD_BIOS */ |
252 | 252 | ||
253 | ENTRY(address_error_handler) | 253 | ENTRY(address_error_trap_handler) |
254 | mov r15,r4 ! regs | 254 | mov r15,r4 ! regs |
255 | add #4,r4 | 255 | add #4,r4 |
256 | mov #OFF_PC,r0 | 256 | mov #OFF_PC,r0 |
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index c9291f462311..b48324867eee 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c | |||
@@ -482,49 +482,3 @@ asmlinkage void break_point_trap(void) | |||
482 | 482 | ||
483 | force_sig(SIGTRAP, current); | 483 | force_sig(SIGTRAP, current); |
484 | } | 484 | } |
485 | |||
486 | /* | ||
487 | * Generic trap handler. | ||
488 | */ | ||
489 | asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, | ||
490 | unsigned long r6, unsigned long r7, | ||
491 | struct pt_regs __regs) | ||
492 | { | ||
493 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
494 | |||
495 | /* Rewind */ | ||
496 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); | ||
497 | |||
498 | if (notify_die(DIE_TRAP, "debug trap", regs, 0, regs->tra & 0xff, | ||
499 | SIGTRAP) == NOTIFY_STOP) | ||
500 | return; | ||
501 | |||
502 | force_sig(SIGTRAP, current); | ||
503 | } | ||
504 | |||
505 | /* | ||
506 | * Special handler for BUG() traps. | ||
507 | */ | ||
508 | asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, | ||
509 | unsigned long r6, unsigned long r7, | ||
510 | struct pt_regs __regs) | ||
511 | { | ||
512 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
513 | |||
514 | /* Rewind */ | ||
515 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); | ||
516 | |||
517 | if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, | ||
518 | SIGTRAP) == NOTIFY_STOP) | ||
519 | return; | ||
520 | |||
521 | #ifdef CONFIG_BUG | ||
522 | if (__kernel_text_address(instruction_pointer(regs))) { | ||
523 | u16 insn = *(u16 *)instruction_pointer(regs); | ||
524 | if (insn == TRAPA_BUG_OPCODE) | ||
525 | handle_BUG(regs); | ||
526 | } | ||
527 | #endif | ||
528 | |||
529 | force_sig(SIGTRAP, current); | ||
530 | } | ||
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 47415671da0c..92d01465eb87 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c | |||
@@ -1,12 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public | 2 | * arch/sh/kernel/process_64.c |
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | 3 | * |
6 | * arch/sh64/kernel/process.c | 4 | * This file handles the architecture-dependent parts of process handling.. |
7 | * | 5 | * |
8 | * Copyright (C) 2000, 2001 Paolo Alberelli | 6 | * Copyright (C) 2000, 2001 Paolo Alberelli |
9 | * Copyright (C) 2003 Paul Mundt | 7 | * Copyright (C) 2003 - 2007 Paul Mundt |
10 | * Copyright (C) 2003, 2004 Richard Curnow | 8 | * Copyright (C) 2003, 2004 Richard Curnow |
11 | * | 9 | * |
12 | * Started from SH3/4 version: | 10 | * Started from SH3/4 version: |
@@ -15,10 +13,9 @@ | |||
15 | * In turn started from i386 version: | 13 | * In turn started from i386 version: |
16 | * Copyright (C) 1995 Linus Torvalds | 14 | * Copyright (C) 1995 Linus Torvalds |
17 | * | 15 | * |
18 | */ | 16 | * This file is subject to the terms and conditions of the GNU General Public |
19 | 17 | * License. See the file "COPYING" in the main directory of this archive | |
20 | /* | 18 | * for more details. |
21 | * This file handles the architecture-dependent parts of process handling.. | ||
22 | */ | 19 | */ |
23 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
24 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c new file mode 100644 index 000000000000..bf70827b17cc --- /dev/null +++ b/arch/sh/kernel/traps.c | |||
@@ -0,0 +1,66 @@ | |||
1 | #include <linux/bug.h> | ||
2 | #include <linux/io.h> | ||
3 | #include <linux/types.h> | ||
4 | #include <linux/kdebug.h> | ||
5 | #include <asm/system.h> | ||
6 | |||
7 | #ifdef CONFIG_BUG | ||
8 | static void handle_BUG(struct pt_regs *regs) | ||
9 | { | ||
10 | enum bug_trap_type tt; | ||
11 | tt = report_bug(regs->pc, regs); | ||
12 | if (tt == BUG_TRAP_TYPE_WARN) { | ||
13 | regs->pc += instruction_size(regs->pc); | ||
14 | return; | ||
15 | } | ||
16 | |||
17 | die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); | ||
18 | } | ||
19 | |||
20 | int is_valid_bugaddr(unsigned long addr) | ||
21 | { | ||
22 | return addr >= PAGE_OFFSET; | ||
23 | } | ||
24 | #endif | ||
25 | |||
26 | /* | ||
27 | * Generic trap handler. | ||
28 | */ | ||
29 | BUILD_TRAP_HANDLER(debug) | ||
30 | { | ||
31 | TRAP_HANDLER_DECL; | ||
32 | |||
33 | /* Rewind */ | ||
34 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); | ||
35 | |||
36 | if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff, | ||
37 | SIGTRAP) == NOTIFY_STOP) | ||
38 | return; | ||
39 | |||
40 | force_sig(SIGTRAP, current); | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * Special handler for BUG() traps. | ||
45 | */ | ||
46 | BUILD_TRAP_HANDLER(bug) | ||
47 | { | ||
48 | TRAP_HANDLER_DECL; | ||
49 | |||
50 | /* Rewind */ | ||
51 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); | ||
52 | |||
53 | if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, | ||
54 | SIGTRAP) == NOTIFY_STOP) | ||
55 | return; | ||
56 | |||
57 | #ifdef CONFIG_BUG | ||
58 | if (__kernel_text_address(instruction_pointer(regs))) { | ||
59 | opcode_t insn = *(opcode_t *)instruction_pointer(regs); | ||
60 | if (insn == TRAPA_BUG_OPCODE) | ||
61 | handle_BUG(regs); | ||
62 | } | ||
63 | #endif | ||
64 | |||
65 | force_sig(SIGTRAP, current); | ||
66 | } | ||
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index cf99111cb33f..0d05fb3c48e3 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c | |||
@@ -837,10 +837,6 @@ void *set_exception_table_vec(unsigned int vec, void *handler) | |||
837 | return old_handler; | 837 | return old_handler; |
838 | } | 838 | } |
839 | 839 | ||
840 | extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5, | ||
841 | unsigned long r6, unsigned long r7, | ||
842 | struct pt_regs __regs); | ||
843 | |||
844 | void __init trap_init(void) | 840 | void __init trap_init(void) |
845 | { | 841 | { |
846 | set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); | 842 | set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); |
@@ -866,7 +862,7 @@ void __init trap_init(void) | |||
866 | #endif | 862 | #endif |
867 | 863 | ||
868 | #ifdef CONFIG_CPU_SH2 | 864 | #ifdef CONFIG_CPU_SH2 |
869 | set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler); | 865 | set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler); |
870 | #endif | 866 | #endif |
871 | #ifdef CONFIG_CPU_SH2A | 867 | #ifdef CONFIG_CPU_SH2A |
872 | set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); | 868 | set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); |
@@ -877,25 +873,6 @@ void __init trap_init(void) | |||
877 | per_cpu_trap_init(); | 873 | per_cpu_trap_init(); |
878 | } | 874 | } |
879 | 875 | ||
880 | #ifdef CONFIG_BUG | ||
881 | void handle_BUG(struct pt_regs *regs) | ||
882 | { | ||
883 | enum bug_trap_type tt; | ||
884 | tt = report_bug(regs->pc, regs); | ||
885 | if (tt == BUG_TRAP_TYPE_WARN) { | ||
886 | regs->pc += 2; | ||
887 | return; | ||
888 | } | ||
889 | |||
890 | die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); | ||
891 | } | ||
892 | |||
893 | int is_valid_bugaddr(unsigned long addr) | ||
894 | { | ||
895 | return addr >= PAGE_OFFSET; | ||
896 | } | ||
897 | #endif | ||
898 | |||
899 | void show_trace(struct task_struct *tsk, unsigned long *sp, | 876 | void show_trace(struct task_struct *tsk, unsigned long *sp, |
900 | struct pt_regs *regs) | 877 | struct pt_regs *regs) |
901 | { | 878 | { |
diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h index a83a7b45ba6f..8d6c92b3e770 100644 --- a/include/asm-sh/ptrace.h +++ b/include/asm-sh/ptrace.h | |||
@@ -95,7 +95,7 @@ struct pt_dspregs { | |||
95 | #include <asm/addrspace.h> | 95 | #include <asm/addrspace.h> |
96 | 96 | ||
97 | #define user_mode(regs) (((regs)->sr & 0x40000000)==0) | 97 | #define user_mode(regs) (((regs)->sr & 0x40000000)==0) |
98 | #define instruction_pointer(regs) ((regs)->pc) | 98 | #define instruction_pointer(regs) ((unsigned long)(regs)->pc) |
99 | 99 | ||
100 | extern void show_regs(struct pt_regs *); | 100 | extern void show_regs(struct pt_regs *); |
101 | 101 | ||
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 0cfa96aa5844..6b02dfd587ea 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h | |||
@@ -185,12 +185,25 @@ void default_idle(void); | |||
185 | void per_cpu_trap_init(void); | 185 | void per_cpu_trap_init(void); |
186 | 186 | ||
187 | asmlinkage void break_point_trap(void); | 187 | asmlinkage void break_point_trap(void); |
188 | asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, | 188 | |
189 | unsigned long r6, unsigned long r7, | 189 | #ifdef CONFIG_SUPERH32 |
190 | struct pt_regs __regs); | 190 | #define BUILD_TRAP_HANDLER(name) \ |
191 | asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, | 191 | asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ |
192 | unsigned long r6, unsigned long r7, | 192 | unsigned long r6, unsigned long r7, \ |
193 | struct pt_regs __regs); | 193 | struct pt_regs __regs) |
194 | |||
195 | #define TRAP_HANDLER_DECL \ | ||
196 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); \ | ||
197 | unsigned int vec = regs->tra; | ||
198 | #else | ||
199 | #define BUILD_TRAP_HANDLER(name) \ | ||
200 | asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs) | ||
201 | #define TRAP_HANDLER_DECL | ||
202 | #endif | ||
203 | |||
204 | BUILD_TRAP_HANDLER(address_error); | ||
205 | BUILD_TRAP_HANDLER(debug); | ||
206 | BUILD_TRAP_HANDLER(bug); | ||
194 | 207 | ||
195 | #define arch_align_stack(x) (x) | 208 | #define arch_align_stack(x) (x) |
196 | 209 | ||
diff --git a/include/asm-sh/types.h b/include/asm-sh/types.h index 7ba69d9707ef..a6e1d4126e67 100644 --- a/include/asm-sh/types.h +++ b/include/asm-sh/types.h | |||
@@ -52,6 +52,12 @@ typedef unsigned long long u64; | |||
52 | 52 | ||
53 | typedef u32 dma_addr_t; | 53 | typedef u32 dma_addr_t; |
54 | 54 | ||
55 | #ifdef CONFIG_SUPERH32 | ||
56 | typedef u16 opcode_t; | ||
57 | #else | ||
58 | typedef u32 opcode_t; | ||
59 | #endif | ||
60 | |||
55 | #endif /* __ASSEMBLY__ */ | 61 | #endif /* __ASSEMBLY__ */ |
56 | 62 | ||
57 | #endif /* __KERNEL__ */ | 63 | #endif /* __KERNEL__ */ |