diff options
author | Ley Foon Tan <lftan@altera.com> | 2015-04-16 03:19:01 -0400 |
---|---|---|
committer | Ley Foon Tan <lftan@altera.com> | 2015-04-19 23:11:14 -0400 |
commit | baa54ab93c2e1ced7e54f9c021fe102c0d39c090 (patch) | |
tree | d7e6dc664ef3c36d3b93f865dc1e245f2870805f /arch/nios2/kernel | |
parent | 170c381f6bcd9ad3235654988aabddb612b34a39 (diff) |
nios2: rework trap handler
Redefine trap handler as below:
0 N/A reserved for system calls
1 SIGUSR1 user-defined signal 1
2 SIGUSR2 user-defined signal 2
3 SIGILL illegal instruction
4..29 reserved (but implemented to raise SIGILL instead of being undefined)
30 SIGTRAP KGDB
31 SIGTRAP trace/breakpoint trap
Signed-off-by: Ley Foon Tan <lftan@altera.com>
Diffstat (limited to 'arch/nios2/kernel')
-rw-r--r-- | arch/nios2/kernel/entry.S | 71 | ||||
-rw-r--r-- | arch/nios2/kernel/traps.c | 34 |
2 files changed, 69 insertions, 36 deletions
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S index 27b006c52e12..1e515ccd698e 100644 --- a/arch/nios2/kernel/entry.S +++ b/arch/nios2/kernel/entry.S | |||
@@ -92,35 +92,35 @@ exception_table: | |||
92 | 92 | ||
93 | trap_table: | 93 | trap_table: |
94 | .word handle_system_call /* 0 */ | 94 | .word handle_system_call /* 0 */ |
95 | .word instruction_trap /* 1 */ | 95 | .word handle_trap_1 /* 1 */ |
96 | .word instruction_trap /* 2 */ | 96 | .word handle_trap_2 /* 2 */ |
97 | .word instruction_trap /* 3 */ | 97 | .word handle_trap_3 /* 3 */ |
98 | .word instruction_trap /* 4 */ | 98 | .word handle_trap_reserved /* 4 */ |
99 | .word instruction_trap /* 5 */ | 99 | .word handle_trap_reserved /* 5 */ |
100 | .word instruction_trap /* 6 */ | 100 | .word handle_trap_reserved /* 6 */ |
101 | .word instruction_trap /* 7 */ | 101 | .word handle_trap_reserved /* 7 */ |
102 | .word instruction_trap /* 8 */ | 102 | .word handle_trap_reserved /* 8 */ |
103 | .word instruction_trap /* 9 */ | 103 | .word handle_trap_reserved /* 9 */ |
104 | .word instruction_trap /* 10 */ | 104 | .word handle_trap_reserved /* 10 */ |
105 | .word instruction_trap /* 11 */ | 105 | .word handle_trap_reserved /* 11 */ |
106 | .word instruction_trap /* 12 */ | 106 | .word handle_trap_reserved /* 12 */ |
107 | .word instruction_trap /* 13 */ | 107 | .word handle_trap_reserved /* 13 */ |
108 | .word instruction_trap /* 14 */ | 108 | .word handle_trap_reserved /* 14 */ |
109 | .word instruction_trap /* 15 */ | 109 | .word handle_trap_reserved /* 15 */ |
110 | .word instruction_trap /* 16 */ | 110 | .word handle_trap_reserved /* 16 */ |
111 | .word instruction_trap /* 17 */ | 111 | .word handle_trap_reserved /* 17 */ |
112 | .word instruction_trap /* 18 */ | 112 | .word handle_trap_reserved /* 18 */ |
113 | .word instruction_trap /* 19 */ | 113 | .word handle_trap_reserved /* 19 */ |
114 | .word instruction_trap /* 20 */ | 114 | .word handle_trap_reserved /* 20 */ |
115 | .word instruction_trap /* 21 */ | 115 | .word handle_trap_reserved /* 21 */ |
116 | .word instruction_trap /* 22 */ | 116 | .word handle_trap_reserved /* 22 */ |
117 | .word instruction_trap /* 23 */ | 117 | .word handle_trap_reserved /* 23 */ |
118 | .word instruction_trap /* 24 */ | 118 | .word handle_trap_reserved /* 24 */ |
119 | .word instruction_trap /* 25 */ | 119 | .word handle_trap_reserved /* 25 */ |
120 | .word instruction_trap /* 26 */ | 120 | .word handle_trap_reserved /* 26 */ |
121 | .word instruction_trap /* 27 */ | 121 | .word handle_trap_reserved /* 27 */ |
122 | .word instruction_trap /* 28 */ | 122 | .word handle_trap_reserved /* 28 */ |
123 | .word instruction_trap /* 29 */ | 123 | .word handle_trap_reserved /* 29 */ |
124 | #ifdef CONFIG_KGDB | 124 | #ifdef CONFIG_KGDB |
125 | .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */ | 125 | .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */ |
126 | #else | 126 | #else |
@@ -455,6 +455,19 @@ handle_kgdb_breakpoint: | |||
455 | br ret_from_exception | 455 | br ret_from_exception |
456 | #endif | 456 | #endif |
457 | 457 | ||
458 | handle_trap_1: | ||
459 | call handle_trap_1_c | ||
460 | br ret_from_exception | ||
461 | |||
462 | handle_trap_2: | ||
463 | call handle_trap_2_c | ||
464 | br ret_from_exception | ||
465 | |||
466 | handle_trap_3: | ||
467 | handle_trap_reserved: | ||
468 | call handle_trap_3_c | ||
469 | br ret_from_exception | ||
470 | |||
458 | /* | 471 | /* |
459 | * Beware - when entering resume, prev (the current task) is | 472 | * Beware - when entering resume, prev (the current task) is |
460 | * in r4, next (the new task) is in r5, don't change these | 473 | * in r4, next (the new task) is in r5, don't change these |
diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c index b7b97641a9a6..81f7da7b1d55 100644 --- a/arch/nios2/kernel/traps.c +++ b/arch/nios2/kernel/traps.c | |||
@@ -23,6 +23,17 @@ | |||
23 | 23 | ||
24 | static DEFINE_SPINLOCK(die_lock); | 24 | static DEFINE_SPINLOCK(die_lock); |
25 | 25 | ||
26 | static void _send_sig(int signo, int code, unsigned long addr) | ||
27 | { | ||
28 | siginfo_t info; | ||
29 | |||
30 | info.si_signo = signo; | ||
31 | info.si_errno = 0; | ||
32 | info.si_code = code; | ||
33 | info.si_addr = (void __user *) addr; | ||
34 | force_sig_info(signo, &info, current); | ||
35 | } | ||
36 | |||
26 | void die(const char *str, struct pt_regs *regs, long err) | 37 | void die(const char *str, struct pt_regs *regs, long err) |
27 | { | 38 | { |
28 | console_verbose(); | 39 | console_verbose(); |
@@ -39,16 +50,10 @@ void die(const char *str, struct pt_regs *regs, long err) | |||
39 | 50 | ||
40 | void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr) | 51 | void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr) |
41 | { | 52 | { |
42 | siginfo_t info; | ||
43 | |||
44 | if (!user_mode(regs)) | 53 | if (!user_mode(regs)) |
45 | die("Exception in kernel mode", regs, signo); | 54 | die("Exception in kernel mode", regs, signo); |
46 | 55 | ||
47 | info.si_signo = signo; | 56 | _send_sig(signo, code, addr); |
48 | info.si_errno = 0; | ||
49 | info.si_code = code; | ||
50 | info.si_addr = (void __user *) addr; | ||
51 | force_sig_info(signo, &info, current); | ||
52 | } | 57 | } |
53 | 58 | ||
54 | /* | 59 | /* |
@@ -183,3 +188,18 @@ asmlinkage void unhandled_exception(struct pt_regs *regs, int cause) | |||
183 | 188 | ||
184 | pr_emerg("opcode: 0x%08lx\n", *(unsigned long *)(regs->ea)); | 189 | pr_emerg("opcode: 0x%08lx\n", *(unsigned long *)(regs->ea)); |
185 | } | 190 | } |
191 | |||
192 | asmlinkage void handle_trap_1_c(struct pt_regs *fp) | ||
193 | { | ||
194 | _send_sig(SIGUSR1, 0, fp->ea); | ||
195 | } | ||
196 | |||
197 | asmlinkage void handle_trap_2_c(struct pt_regs *fp) | ||
198 | { | ||
199 | _send_sig(SIGUSR2, 0, fp->ea); | ||
200 | } | ||
201 | |||
202 | asmlinkage void handle_trap_3_c(struct pt_regs *fp) | ||
203 | { | ||
204 | _send_sig(SIGILL, ILL_ILLTRP, fp->ea); | ||
205 | } | ||