aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorYoshinori Sato <ysato@users.sourceforge.jp>2008-07-09 12:20:03 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-07-28 05:10:34 -0400
commit6e80f5e8c4c685eb7bc34c3916e3d986b03f9981 (patch)
tree3c8768bdb748ba6b1bc923d798b1a8e3b91df4eb /arch/sh
parentcafd63b0076b78bc8f114abbeb724c7e5f5bfe5d (diff)
sh2(A) exception handler update
This patch is By sh2 - Remove duplicate code - Reduce stack usage - Cleanup and little optimize By sh2a - Add missing handler(256 to 511) - Use sh2a instructions handler Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S133
-rw-r--r--arch/sh/kernel/cpu/sh2/ex.S15
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh2a/entry.S249
-rw-r--r--arch/sh/kernel/cpu/sh2a/ex.S72
-rw-r--r--arch/sh/kernel/traps_32.c4
6 files changed, 385 insertions, 90 deletions
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index 0fc89069d8c7..ee894e5a45e7 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -3,7 +3,7 @@
3 * 3 *
4 * The SH-2 exception entry 4 * The SH-2 exception entry
5 * 5 *
6 * Copyright (C) 2005,2006 Yoshinori Sato 6 * Copyright (C) 2005-2008 Yoshinori Sato
7 * Copyright (C) 2005 AXE,Inc. 7 * Copyright (C) 2005 AXE,Inc.
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
@@ -36,43 +36,41 @@ OFF_TRA = (16*4+6*4)
36#include <asm/entry-macros.S> 36#include <asm/entry-macros.S>
37 37
38ENTRY(exception_handler) 38ENTRY(exception_handler)
39 ! already saved r0/r1 39 ! stack
40 ! r0 <- point sp
41 ! r1
42 ! pc
43 ! sr
44 ! r0 = temporary
45 ! r1 = vector (pseudo EXPEVT / INTEVT / TRA)
40 mov.l r2,@-sp 46 mov.l r2,@-sp
41 mov.l r3,@-sp 47 mov.l r3,@-sp
42 mov r0,r1
43 cli 48 cli
44 mov.l $cpu_mode,r2 49 mov.l $cpu_mode,r2
45 mov.l @r2,r0 50 mov.l @r2,r0
46 mov.l @(5*4,r15),r3 ! previous SR 51 mov.l @(5*4,r15),r3 ! previous SR
47 shll2 r3 ! set "S" flag 52 or r0,r3 ! set MD
48 rotl r0 ! T <- "S" flag 53 tst r0,r0
49 rotl r0 ! "S" flag is LSB 54 bf/s 1f ! previous mode check
50 rotcr r3 ! T -> r3:b30 55 mov.l r3,@(5*4,r15) ! update SR
51 shlr r3
52 shlr r0
53 bt/s 1f
54 mov.l r3,@(5*4,r15) ! copy cpu mode to SR
55 ! switch to kernel mode 56 ! switch to kernel mode
56 mov #1,r0 57 mov.l __md_bit,r0
57 rotr r0
58 rotr r0
59 mov.l r0,@r2 ! enter kernel mode 58 mov.l r0,@r2 ! enter kernel mode
60 mov.l $current_thread_info,r2 59 mov.l $current_thread_info,r2
61 mov.l @r2,r2 60 mov.l @r2,r2
62 mov #0x20,r0 61 mov #(THREAD_SIZE >> 8),r0
63 shll8 r0 62 shll8 r0
64 add r2,r0 63 add r2,r0
65 mov r15,r2 ! r2 = user stack top 64 mov r15,r2 ! r2 = user stack top
66 mov r0,r15 ! switch kernel stack 65 mov r0,r15 ! switch kernel stack
67 add #-4,r15 ! dummy
68 mov.l r1,@-r15 ! TRA 66 mov.l r1,@-r15 ! TRA
69 sts.l macl, @-r15 67 sts.l macl, @-r15
70 sts.l mach, @-r15 68 sts.l mach, @-r15
71 stc.l gbr, @-r15 69 stc.l gbr, @-r15
72 mov.l @(4*4,r2),r0 70 mov.l @(5*4,r2),r0
73 mov.l @(5*4,r2),r1 71 mov.l r0,@-r15 ! original SR
74 mov.l r1,@-r15 ! original SR
75 sts.l pr,@-r15 72 sts.l pr,@-r15
73 mov.l @(4*4,r2),r0
76 mov.l r0,@-r15 ! original PC 74 mov.l r0,@-r15 ! original PC
77 mov r2,r3 75 mov r2,r3
78 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame 76 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame
@@ -88,14 +86,15 @@ ENTRY(exception_handler)
88 mov.l r6,@-r15 86 mov.l r6,@-r15
89 mov.l r5,@-r15 87 mov.l r5,@-r15
90 mov.l r4,@-r15 88 mov.l r4,@-r15
89 mov r1,r9 ! save TRA
91 mov r2,r8 ! copy user -> kernel stack 90 mov r2,r8 ! copy user -> kernel stack
92 mov.l @r8+,r3 91 mov.l @(0,r8),r3
93 mov.l r3,@-r15 92 mov.l r3,@-r15
94 mov.l @r8+,r2 93 mov.l @(4,r8),r2
95 mov.l r2,@-r15 94 mov.l r2,@-r15
96 mov.l @r8+,r1 95 mov.l @(12,r8),r1
97 mov.l r1,@-r15 96 mov.l r1,@-r15
98 mov.l @r8+,r0 97 mov.l @(8,r8),r0
99 bra 2f 98 bra 2f
100 mov.l r0,@-r15 99 mov.l r0,@-r15
1011: 1001:
@@ -107,10 +106,11 @@ ENTRY(exception_handler)
107 mov.l r0,@-r15 106 mov.l r0,@-r15
108 mov.l @r2+,r0 ! old R2 107 mov.l @r2+,r0 ! old R2
109 mov.l r0,@-r15 108 mov.l r0,@-r15
110 mov.l @r2+,r0 ! old R1 109 mov.l @(4,r2),r0 ! old R1
111 mov.l r0,@-r15
112 mov.l @r2+,r0 ! old R0
113 mov.l r0,@-r15 110 mov.l r0,@-r15
111 mov.l @r2,r0 ! old R0
112 mov.l r0,@-r15
113 add #8,r2
114 mov.l @r2+,r3 ! old PC 114 mov.l @r2+,r3 ! old PC
115 mov.l @r2+,r0 ! old SR 115 mov.l @r2+,r0 ! old SR
116 add #-4,r2 ! exception frame stub (sr) 116 add #-4,r2 ! exception frame stub (sr)
@@ -135,14 +135,12 @@ ENTRY(exception_handler)
135 mov.l r6,@-r2 135 mov.l r6,@-r2
136 mov.l r5,@-r2 136 mov.l r5,@-r2
137 mov.l r4,@-r2 137 mov.l r4,@-r2
138 mov r1,r9
138 mov.l @(OFF_R0,r15),r0 139 mov.l @(OFF_R0,r15),r0
139 mov.l @(OFF_R1,r15),r1 140 mov.l @(OFF_R1,r15),r1
140 mov.l @(OFF_R2,r15),r2 141 mov.l @(OFF_R2,r15),r2
141 mov.l @(OFF_R3,r15),r3 142 mov.l @(OFF_R3,r15),r3
1422: 1432:
143 mov #OFF_TRA,r8
144 add r15,r8
145 mov.l @r8,r9
146 mov #64,r8 144 mov #64,r8
147 cmp/hs r8,r9 145 cmp/hs r8,r9
148 bt interrupt_entry ! vec >= 64 is interrupt 146 bt interrupt_entry ! vec >= 64 is interrupt
@@ -150,26 +148,14 @@ ENTRY(exception_handler)
150 cmp/hs r8,r9 148 cmp/hs r8,r9
151 bt trap_entry ! 64 > vec >= 32 is trap 149 bt trap_entry ! 64 > vec >= 32 is trap
152 150
153#if defined(CONFIG_SH_FPU)
154 mov #13,r8
155 cmp/eq r8,r9
156 bt 10f ! fpu
157 nop
158#endif
159
160 mov.l 4f,r8 151 mov.l 4f,r8
161 mov r9,r4 152 mov r9,r4
162 shll2 r9 153 shll2 r9
163 add r9,r8 154 add r9,r8
164 mov.l @r8,r8 155 mov.l @r8,r8 ! exception handler address
165 mov #0,r9 156 tst r8,r8
166 cmp/eq r9,r8
167 bf 3f 157 bf 3f
168 mov.l 8f,r8 ! unhandled exception 158 mov.l 8f,r8 ! unhandled exception
169#if defined(CONFIG_SH_FPU)
17010:
171 mov.l 9f, r8 ! unhandled exception
172#endif
1733: 1593:
174 mov.l 5f,r10 160 mov.l 5f,r10
175 jmp @r8 161 jmp @r8
@@ -188,10 +174,7 @@ interrupt_entry:
1885: .long ret_from_exception 1745: .long ret_from_exception
1896: .long ret_from_irq 1756: .long ret_from_irq
1907: .long do_IRQ 1767: .long do_IRQ
1918: .long do_exception_error 1778: .long exception_error
192#ifdef CONFIG_SH_FPU
1939: .long fpu_error_trap_handler
194#endif
195 178
196trap_entry: 179trap_entry:
197 mov #0x30,r8 180 mov #0x30,r8
@@ -200,24 +183,9 @@ trap_entry:
200 add #-0x10,r9 ! convert SH2 to SH3/4 ABI 183 add #-0x10,r9 ! convert SH2 to SH3/4 ABI
2011: 1841:
202 shll2 r9 ! TRA 185 shll2 r9 ! TRA
203 mov #OFF_TRA,r8 186 bra system_call ! jump common systemcall entry
204 add r15,r8 187 mov r9,r8
205 mov.l r9,@r8
206 mov r9,r8
207#ifdef CONFIG_TRACE_IRQFLAGS
208 mov.l 2f, r9
209 jsr @r9
210 nop
211#endif
212 sti
213 bra system_call
214 nop
215 188
216 .align 2
217#ifdef CONFIG_TRACE_IRQFLAGS
2182: .long trace_hardirqs_on
219#endif
220
221#if defined(CONFIG_SH_STANDARD_BIOS) 189#if defined(CONFIG_SH_STANDARD_BIOS)
222 /* Unwind the stack and jmp to the debug entry */ 190 /* Unwind the stack and jmp to the debug entry */
223ENTRY(sh_bios_handler) 191ENTRY(sh_bios_handler)
@@ -240,7 +208,7 @@ ENTRY(sh_bios_handler)
240 mov.l @r2,r2 208 mov.l @r2,r2
241 stc sr,r3 209 stc sr,r3
242 mov.l r2,@r0 210 mov.l r2,@r0
243 mov.l r3,@r0 211 mov.l r3,@(4,r0)
244 mov.l r1,@(8,r0) 212 mov.l r1,@(8,r0)
245 mov.l @r15+, r0 213 mov.l @r15+, r0
246 mov.l @r15+, r1 214 mov.l @r15+, r1
@@ -272,22 +240,30 @@ ENTRY(address_error_trap_handler)
272 mov.l 1f,r0 240 mov.l 1f,r0
273 jmp @r0 241 jmp @r0
274 mov #0,r5 ! writeaccess is unknown 242 mov #0,r5 ! writeaccess is unknown
275 .align 2
276 243
244 .align 2
2771: .long do_address_error 2451: .long do_address_error
278 246
279restore_all: 247restore_all:
280 cli 248 stc sr,r0
281#ifdef CONFIG_TRACE_IRQFLAGS 249 or #0xf0,r0
282 mov.l 1f, r0 250 ldc r0,sr ! all interrupt block (same BL = 1)
283 jsr @r0 251 ! restore special register
284 nop 252 ! overlap exception frame
285#endif 253 mov r15,r0
254 add #17*4,r0
255 lds.l @r0+,pr
256 add #4,r0
257 ldc.l @r0+,gbr
258 lds.l @r0+,mach
259 lds.l @r0+,macl
286 mov r15,r0 260 mov r15,r0
287 mov.l $cpu_mode,r2 261 mov.l $cpu_mode,r2
288 mov #OFF_SR,r3 262 mov #OFF_SR,r3
289 mov.l @(r0,r3),r1 263 mov.l @(r0,r3),r1
290 mov.l r1,@r2 264 mov.l __md_bit,r3
265 and r1,r3 ! copy MD bit
266 mov.l r3,@r2
291 shll2 r1 ! clear MD bit 267 shll2 r1 ! clear MD bit
292 shlr2 r1 268 shlr2 r1
293 mov.l @(OFF_SP,r0),r2 269 mov.l @(OFF_SP,r0),r2
@@ -297,12 +273,6 @@ restore_all:
297 mov #OFF_PC,r3 273 mov #OFF_PC,r3
298 mov.l @(r0,r3),r1 274 mov.l @(r0,r3),r1
299 mov.l r1,@r2 ! set pc 275 mov.l r1,@r2 ! set pc
300 add #4*16+4,r0
301 lds.l @r0+,pr
302 add #4,r0 ! skip sr
303 ldc.l @r0+,gbr
304 lds.l @r0+,mach
305 lds.l @r0+,macl
306 get_current_thread_info r0, r1 276 get_current_thread_info r0, r1
307 mov.l $current_thread_info,r1 277 mov.l $current_thread_info,r1
308 mov.l r0,@r1 278 mov.l r0,@r1
@@ -326,9 +296,8 @@ restore_all:
326 nop 296 nop
327 297
328 .align 2 298 .align 2
329#ifdef CONFIG_TRACE_IRQFLAGS 299__md_bit:
3301: .long trace_hardirqs_off 300 .long 0x40000000
331#endif
332$current_thread_info: 301$current_thread_info:
333 .long __current_thread_info 302 .long __current_thread_info
334$cpu_mode: 303$cpu_mode:
diff --git a/arch/sh/kernel/cpu/sh2/ex.S b/arch/sh/kernel/cpu/sh2/ex.S
index 6d285af7846c..85b0bf81fc1d 100644
--- a/arch/sh/kernel/cpu/sh2/ex.S
+++ b/arch/sh/kernel/cpu/sh2/ex.S
@@ -18,16 +18,17 @@
18exception_entry: 18exception_entry:
19no = 0 19no = 0
20 .rept 256 20 .rept 256
21 mov.l r0,@-sp 21 mov.l r1,@-sp
22 mov #no,r0
23 bra exception_trampoline 22 bra exception_trampoline
24 and #0xff,r0 23 mov #no,r1
25no = no + 1 24no = no + 1
26 .endr 25 .endr
27exception_trampoline: 26exception_trampoline:
28 mov.l r1,@-sp 27 mov.l r0,@-sp
29 mov.l $exception_handler,r1 28 mov.l $exception_handler,r0
30 jmp @r1 29 extu.b r1,r1
30 jmp @r0
31 extu.w r1,r1
31 32
32 .align 2 33 .align 2
33$exception_entry: 34$exception_entry:
@@ -41,6 +42,6 @@ $exception_handler:
41ENTRY(vbr_base) 42ENTRY(vbr_base)
42vector = 0 43vector = 0
43 .rept 256 44 .rept 256
44 .long exception_entry + vector * 8 45 .long exception_entry + vector * 6
45vector = vector + 1 46vector = vector + 1
46 .endr 47 .endr
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index 7e2b90cfa7bf..1ab1ecf4c768 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-y := common.o probe.o opcode_helper.o 5obj-y := common.o probe.o opcode_helper.o
6 6
7common-y += $(addprefix ../sh2/, ex.o entry.o) 7common-y += ex.o entry.o
8 8
9obj-$(CONFIG_SH_FPU) += fpu.o 9obj-$(CONFIG_SH_FPU) += fpu.o
10 10
diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S
new file mode 100644
index 000000000000..47096dc3d206
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/entry.S
@@ -0,0 +1,249 @@
1/*
2 * arch/sh/kernel/cpu/sh2a/entry.S
3 *
4 * The SH-2A exception entry
5 *
6 * Copyright (C) 2008 Yoshinori Sato
7 * Based on arch/sh/kernel/cpu/sh2/entry.S
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/linkage.h>
15#include <asm/asm-offsets.h>
16#include <asm/thread_info.h>
17#include <asm/cpu/mmu_context.h>
18#include <asm/unistd.h>
19#include <asm/errno.h>
20#include <asm/page.h>
21
22/* Offsets to the stack */
23OFF_R0 = 0 /* Return value. New ABI also arg4 */
24OFF_R1 = 4 /* New ABI: arg5 */
25OFF_R2 = 8 /* New ABI: arg6 */
26OFF_R3 = 12 /* New ABI: syscall_nr */
27OFF_R4 = 16 /* New ABI: arg0 */
28OFF_R5 = 20 /* New ABI: arg1 */
29OFF_R6 = 24 /* New ABI: arg2 */
30OFF_R7 = 28 /* New ABI: arg3 */
31OFF_SP = (15*4)
32OFF_PC = (16*4)
33OFF_SR = (16*4+2*4)
34OFF_TRA = (16*4+6*4)
35
36#include <asm/entry-macros.S>
37
38ENTRY(exception_handler)
39 ! stack
40 ! r0 <- point sp
41 ! r1
42 ! pc
43 ! sr
44 ! r0 = temporary
45 ! r1 = vector (pseudo EXPEVT / INTEVT / TRA)
46 mov.l r2,@-sp
47 cli
48 mov.l $cpu_mode,r2
49 bld.b #6,@(0,r2) !previus SR.MD
50 bst.b #6,@(4*4,r15) !set cpu mode to SR.MD
51 bt 1f
52 ! switch to kernel mode
53 bset.b #6,@(0,r2) !set SR.MD
54 mov.l $current_thread_info,r2
55 mov.l @r2,r2
56 mov #(THREAD_SIZE >> 8),r0
57 shll8 r0
58 add r2,r0 ! r0 = kernel stack tail
59 mov r15,r2 ! r2 = user stack top
60 mov r0,r15 ! switch kernel stack
61 mov.l r1,@-r15 ! TRA
62 sts.l macl, @-r15
63 sts.l mach, @-r15
64 stc.l gbr, @-r15
65 mov.l @(4*4,r2),r0
66 mov.l r0,@-r15 ! original SR
67 sts.l pr,@-r15
68 mov.l @(3*4,r2),r0
69 mov.l r0,@-r15 ! original PC
70 mov r2,r0
71 add #(3+2)*4,r0 ! rewind r0 - r3 + exception frame
72 lds r0,pr ! pr = original SP
73 movmu.l r3,@-r15 ! save regs
74 mov r2,r8 ! r8 = previus stack top
75 mov r1,r9 ! r9 = interrupt vector
76 ! restore previous stack
77 mov.l @r8+,r2
78 mov.l @r8+,r0
79 mov.l @r8+,r1
80 bra 2f
81 movml.l r2,@-r15
821:
83 ! in kernel exception
84 mov r15,r2
85 add #-((OFF_TRA + 4) - OFF_PC) + 5*4,r15
86 movmu.l r3,@-r15
87 mov r2,r8 ! r8 = previous stack top
88 mov r1,r9 ! r9 = interrupt vector
89 ! restore exception frame & regs
90 mov.l @r8+,r2 ! old R2
91 mov.l @r8+,r0 ! old R0
92 mov.l @r8+,r1 ! old R1
93 mov.l @r8+,r10 ! old PC
94 mov.l @r8+,r11 ! old SR
95 movml.l r2,@-r15
96 mov.l r10,@(OFF_PC,r15)
97 mov.l r11,@(OFF_SR,r15)
98 mov.l r8,@(OFF_SP,r15) ! save old sp
99 mov r15,r8
100 add #OFF_TRA + 4,r8
101 mov.l r9,@-r8
102 sts.l macl,@-r8
103 sts.l mach,@-r8
104 stc.l gbr,@-r8
105 add #-4,r8
106 sts.l pr,@-r8
1072:
108 ! dispatch exception / interrupt
109 mov #64,r8
110 cmp/hs r8,r9
111 bt interrupt_entry ! vec >= 64 is interrupt
112 mov #32,r8
113 cmp/hs r8,r9
114 bt trap_entry ! 64 > vec >= 32 is trap
115
116 mov.l 4f,r8
117 mov r9,r4
118 shll2 r9
119 add r9,r8
120 mov.l @r8,r8 ! exception handler address
121 tst r8,r8
122 bf 3f
123 mov.l 8f,r8 ! unhandled exception
1243:
125 mov.l 5f,r10
126 jmp @r8
127 lds r10,pr
128
129interrupt_entry:
130 mov r9,r4
131 mov r15,r5
132 mov.l 7f,r8
133 mov.l 6f,r9
134 jmp @r8
135 lds r9,pr
136
137 .align 2
1384: .long exception_handling_table
1395: .long ret_from_exception
1406: .long ret_from_irq
1417: .long do_IRQ
1428: .long exception_error
143
144trap_entry:
145 mov #0x30,r8
146 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
147 bt 1f
148 add #-0x10,r9 ! convert SH2 to SH3/4 ABI
1491:
150 shll2 r9 ! TRA
151 bra system_call ! jump common systemcall entry
152 mov r9,r8
153
154#if defined(CONFIG_SH_STANDARD_BIOS)
155 /* Unwind the stack and jmp to the debug entry */
156ENTRY(sh_bios_handler)
157 mov r15,r0
158 add #(22-4)*4-4,r0
159 ldc.l @r0+,gbr
160 lds.l @r0+,mach
161 lds.l @r0+,macl
162 mov r15,r0
163 mov.l @(OFF_SP,r0),r1
164 mov.l @(OFF_SR,r2),r3
165 mov.l r3,@-r1
166 mov.l @(OFF_SP,r2),r3
167 mov.l r3,@-r1
168 mov r15,r0
169 add #(22-4)*4-8,r0
170 mov.l 1f,r2
171 mov.l @r2,r2
172 stc sr,r3
173 mov.l r2,@r0
174 mov.l r3,@(4,r0)
175 mov.l r1,@(8,r0)
176 movml.l @r15+,r14
177 add #8,r15
178 lds.l @r15+, pr
179 rte
180 mov.l @r15+,r15
181 .align 2
1821: .long gdb_vbr_vector
183#endif /* CONFIG_SH_STANDARD_BIOS */
184
185ENTRY(address_error_trap_handler)
186 mov r15,r4 ! regs
187 mov.l @(OFF_PC,r15),r6 ! pc
188 mov.l 1f,r0
189 jmp @r0
190 mov #0,r5 ! writeaccess is unknown
191
192 .align 2
1931: .long do_address_error
194
195restore_all:
196 stc sr,r0
197 or #0xf0,r0
198 ldc r0,sr ! all interrupt block (same BL = 1)
199 ! restore special register
200 ! overlap exception frame
201 mov r15,r0
202 add #17*4,r0
203 lds.l @r0+,pr
204 add #4,r0
205 ldc.l @r0+,gbr
206 lds.l @r0+,mach
207 lds.l @r0+,macl
208 mov r15,r0
209 mov.l $cpu_mode,r2
210 bld.b #6,@(OFF_SR,r15)
211 bst.b #6,@(0,r2) ! save CPU mode
212 mov.l @(OFF_SR,r0),r1
213 shll2 r1
214 shlr2 r1 ! clear MD bit
215 mov.l @(OFF_SP,r0),r2
216 add #-8,r2
217 mov.l r2,@(OFF_SP,r0) ! point exception frame top
218 mov.l r1,@(4,r2) ! set sr
219 mov.l @(OFF_PC,r0),r1
220 mov.l r1,@r2 ! set pc
221 get_current_thread_info r0, r1
222 mov.l $current_thread_info,r1
223 mov.l r0,@r1
224 movml.l @r15+,r14
225 mov.l @r15,r15
226 rte
227 nop
228
229 .align 2
230$current_thread_info:
231 .long __current_thread_info
232$cpu_mode:
233 .long __cpu_mode
234
235! common exception handler
236#include "../../entry-common.S"
237
238 .data
239! cpu operation mode
240! bit30 = MD (compatible SH3/4)
241__cpu_mode:
242 .long 0x40000000
243
244 .section .bss
245__current_thread_info:
246 .long 0
247
248ENTRY(exception_handling_table)
249 .space 4*32
diff --git a/arch/sh/kernel/cpu/sh2a/ex.S b/arch/sh/kernel/cpu/sh2a/ex.S
new file mode 100644
index 000000000000..3ead9e63965a
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/ex.S
@@ -0,0 +1,72 @@
1/*
2 * arch/sh/kernel/cpu/sh2a/ex.S
3 *
4 * The SH-2A exception vector table
5 *
6 * Copyright (C) 2008 Yoshinori Sato
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/linkage.h>
14
15!
16! convert Exception Vector to Exception Number
17!
18
19! exception no 0 to 255
20exception_entry0:
21no = 0
22 .rept 256
23 mov.l r1,@-sp
24 bra exception_trampoline0
25 mov #no,r1
26no = no + 1
27 .endr
28exception_trampoline0:
29 mov.l r0,@-sp
30 mov.l 1f,r0
31 extu.b r1,r1
32 jmp @r0
33 extu.w r1,r1
34
35 .align 2
361: .long exception_handler
37
38! exception no 256 to 511
39exception_entry1:
40no = 0
41 .rept 256
42 mov.l r1,@-sp
43 bra exception_trampoline1
44 mov #no,r1
45no = no + 1
46 .endr
47exception_trampoline1:
48 mov.l r0,@-sp
49 extu.b r1,r1
50 movi20 #0x100,r0
51 add r0,r1
52 mov.l 1f,r0
53 jmp @r0
54 extu.w r1,r1
55
56 .align 2
571: .long exception_handler
58
59 !
60! Exception Vector Base
61!
62 .align 2
63ENTRY(vbr_base)
64vector = 0
65 .rept 256
66 .long exception_entry0 + vector * 6
67vector = vector + 1
68 .endr
69 .rept 256
70 .long exception_entry1 + vector * 6
71vector = vector + 1
72 .endr
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index e08b3bfeb656..511a9426cec5 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -43,6 +43,7 @@
43# define TRAP_ILLEGAL_SLOT_INST 6 43# define TRAP_ILLEGAL_SLOT_INST 6
44# define TRAP_ADDRESS_ERROR 9 44# define TRAP_ADDRESS_ERROR 9
45# ifdef CONFIG_CPU_SH2A 45# ifdef CONFIG_CPU_SH2A
46# define TRAP_FPU_ERROR 13
46# define TRAP_DIVZERO_ERROR 17 47# define TRAP_DIVZERO_ERROR 17
47# define TRAP_DIVOVF_ERROR 18 48# define TRAP_DIVOVF_ERROR 18
48# endif 49# endif
@@ -851,6 +852,9 @@ void __init trap_init(void)
851#ifdef CONFIG_CPU_SH2A 852#ifdef CONFIG_CPU_SH2A
852 set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); 853 set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error);
853 set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error); 854 set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error);
855#ifdef CONFIG_SH_FPU
856 set_exception_table_vec(TRAP_FPU_ERROR, fpu_error_trap_handler);
857#endif
854#endif 858#endif
855 859
856 /* Setup VBR for boot cpu */ 860 /* Setup VBR for boot cpu */