From 5a4f7c66be981c6b5f44a4d66a14ea6ac9b7b6b0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 20 Nov 2007 18:08:06 +0900 Subject: [PATCH] sh: Share bug/debug traps across _32 and _64. Signed-off-by: Paul Mundt --- arch/sh/kernel/Makefile_32 | 2 +- arch/sh/kernel/Makefile_64 | 2 +- arch/sh/kernel/cpu/sh2/entry.S | 2 +- arch/sh/kernel/process_32.c | 46 ----------------------------- arch/sh/kernel/process_64.c | 15 ++++------ arch/sh/kernel/traps.c | 66 ++++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/traps_32.c | 25 +--------------- include/asm-sh/ptrace.h | 2 +- include/asm-sh/system.h | 25 ++++++++++++---- include/asm-sh/types.h | 6 ++++ 10 files changed, 102 insertions(+), 89 deletions(-) create mode 100644 arch/sh/kernel/traps.c diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index 34e8fa0..990ba74 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 obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \ - syscalls_32.o time.o topology.o traps_32.o + syscalls_32.o time.o topology.o traps.o traps_32.o obj-y += cpu/ timers/ obj-$(CONFIG_VSYSCALL) += vsyscall/ diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64 index aeac400..10e3ae1 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 obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \ - syscalls_64.o time.o topology.o traps_64.o + syscalls_64.o time.o topology.o traps.o traps_64.o obj-y += cpu/ timers/ obj-$(CONFIG_VSYSCALL) += vsyscall/ diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index ee8f1fe..4ff2334 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) 1: .long gdb_vbr_vector #endif /* CONFIG_SH_STANDARD_BIOS */ -ENTRY(address_error_handler) +ENTRY(address_error_trap_handler) mov r15,r4 ! regs add #4,r4 mov #OFF_PC,r0 diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index c9291f4..b483248 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) force_sig(SIGTRAP, current); } - -/* - * Generic trap handler. - */ -asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) -{ - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - - /* Rewind */ - regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); - - if (notify_die(DIE_TRAP, "debug trap", regs, 0, regs->tra & 0xff, - SIGTRAP) == NOTIFY_STOP) - return; - - force_sig(SIGTRAP, current); -} - -/* - * Special handler for BUG() traps. - */ -asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) -{ - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - - /* Rewind */ - regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); - - if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, - SIGTRAP) == NOTIFY_STOP) - return; - -#ifdef CONFIG_BUG - if (__kernel_text_address(instruction_pointer(regs))) { - u16 insn = *(u16 *)instruction_pointer(regs); - if (insn == TRAPA_BUG_OPCODE) - handle_BUG(regs); - } -#endif - - force_sig(SIGTRAP, current); -} diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 4741567..92d0146 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -1,12 +1,10 @@ /* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * arch/sh/kernel/process_64.c * - * arch/sh64/kernel/process.c + * This file handles the architecture-dependent parts of process handling.. * * Copyright (C) 2000, 2001 Paolo Alberelli - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2007 Paul Mundt * Copyright (C) 2003, 2004 Richard Curnow * * Started from SH3/4 version: @@ -15,10 +13,9 @@ * In turn started from i386 version: * Copyright (C) 1995 Linus Torvalds * - */ - -/* - * This file handles the architecture-dependent parts of process handling.. + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ #include #include diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c new file mode 100644 index 0000000..bf70827 --- /dev/null +++ b/arch/sh/kernel/traps.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +#ifdef CONFIG_BUG +static void handle_BUG(struct pt_regs *regs) +{ + enum bug_trap_type tt; + tt = report_bug(regs->pc, regs); + if (tt == BUG_TRAP_TYPE_WARN) { + regs->pc += instruction_size(regs->pc); + return; + } + + die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); +} + +int is_valid_bugaddr(unsigned long addr) +{ + return addr >= PAGE_OFFSET; +} +#endif + +/* + * Generic trap handler. + */ +BUILD_TRAP_HANDLER(debug) +{ + TRAP_HANDLER_DECL; + + /* Rewind */ + regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + + if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; + + force_sig(SIGTRAP, current); +} + +/* + * Special handler for BUG() traps. + */ +BUILD_TRAP_HANDLER(bug) +{ + TRAP_HANDLER_DECL; + + /* Rewind */ + regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + + if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, + SIGTRAP) == NOTIFY_STOP) + return; + +#ifdef CONFIG_BUG + if (__kernel_text_address(instruction_pointer(regs))) { + opcode_t insn = *(opcode_t *)instruction_pointer(regs); + if (insn == TRAPA_BUG_OPCODE) + handle_BUG(regs); + } +#endif + + force_sig(SIGTRAP, current); +} diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index cf99111c..0d05fb3 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) return old_handler; } -extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); - void __init trap_init(void) { set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); @@ -866,7 +862,7 @@ void __init trap_init(void) #endif #ifdef CONFIG_CPU_SH2 - set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler); + set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler); #endif #ifdef CONFIG_CPU_SH2A set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); @@ -877,25 +873,6 @@ void __init trap_init(void) per_cpu_trap_init(); } -#ifdef CONFIG_BUG -void handle_BUG(struct pt_regs *regs) -{ - enum bug_trap_type tt; - tt = report_bug(regs->pc, regs); - if (tt == BUG_TRAP_TYPE_WARN) { - regs->pc += 2; - return; - } - - die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); -} - -int is_valid_bugaddr(unsigned long addr) -{ - return addr >= PAGE_OFFSET; -} -#endif - void show_trace(struct task_struct *tsk, unsigned long *sp, struct pt_regs *regs) { diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h index a83a7b4..8d6c92b 100644 --- a/include/asm-sh/ptrace.h +++ b/include/asm-sh/ptrace.h @@ -95,7 +95,7 @@ struct pt_dspregs { #include #define user_mode(regs) (((regs)->sr & 0x40000000)==0) -#define instruction_pointer(regs) ((regs)->pc) +#define instruction_pointer(regs) ((unsigned long)(regs)->pc) extern void show_regs(struct pt_regs *); diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 0cfa96a..6b02dfd 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -185,12 +185,25 @@ void default_idle(void); void per_cpu_trap_init(void); asmlinkage void break_point_trap(void); -asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); + +#ifdef CONFIG_SUPERH32 +#define BUILD_TRAP_HANDLER(name) \ +asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ + unsigned long r6, unsigned long r7, \ + struct pt_regs __regs) + +#define TRAP_HANDLER_DECL \ + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); \ + unsigned int vec = regs->tra; +#else +#define BUILD_TRAP_HANDLER(name) \ +asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs) +#define TRAP_HANDLER_DECL +#endif + +BUILD_TRAP_HANDLER(address_error); +BUILD_TRAP_HANDLER(debug); +BUILD_TRAP_HANDLER(bug); #define arch_align_stack(x) (x) diff --git a/include/asm-sh/types.h b/include/asm-sh/types.h index 7ba69d9..a6e1d41 100644 --- a/include/asm-sh/types.h +++ b/include/asm-sh/types.h @@ -52,6 +52,12 @@ typedef unsigned long long u64; typedef u32 dma_addr_t; +#ifdef CONFIG_SUPERH32 +typedef u16 opcode_t; +#else +typedef u32 opcode_t; +#endif + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -- 2.7.4