sh: Share bug/debug traps across _32 and _64.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
Paul Mundt 2007-11-20 18:08:06 +09:00
parent 811d50cb43
commit 5a4f7c66be
10 changed files with 102 additions and 89 deletions

View File

@ -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/

View File

@ -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/

View File

@ -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

View File

@ -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);
}

View File

@ -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 <linux/mm.h>
#include <linux/fs.h>

66
arch/sh/kernel/traps.c Normal file
View File

@ -0,0 +1,66 @@
#include <linux/bug.h>
#include <linux/io.h>
#include <linux/types.h>
#include <linux/kdebug.h>
#include <asm/system.h>
#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);
}

View File

@ -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)
{

View File

@ -95,7 +95,7 @@ struct pt_dspregs {
#include <asm/addrspace.h>
#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 *);

View File

@ -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)

View File

@ -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__ */