]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/sh/kernel/traps.c
sh: Share bug/debug traps across _32 and _64.
[mv-sheeva.git] / arch / sh / kernel / traps.c
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 }