34d51b3745eac80e35fccbb804f571b991595013
[deliverable/linux.git] / arch / sh / kernel / cpu / sh2 / entry.S
1 /*
2 * arch/sh/kernel/cpu/sh2/entry.S
3 *
4 * The SH-2 exception entry
5 *
6 * Copyright (C) 2005,2006 Yoshinori Sato
7 * Copyright (C) 2005 AXE,Inc.
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 */
23 OFF_R0 = 0 /* Return value. New ABI also arg4 */
24 OFF_R1 = 4 /* New ABI: arg5 */
25 OFF_R2 = 8 /* New ABI: arg6 */
26 OFF_R3 = 12 /* New ABI: syscall_nr */
27 OFF_R4 = 16 /* New ABI: arg0 */
28 OFF_R5 = 20 /* New ABI: arg1 */
29 OFF_R6 = 24 /* New ABI: arg2 */
30 OFF_R7 = 28 /* New ABI: arg3 */
31 OFF_SP = (15*4)
32 OFF_PC = (16*4)
33 OFF_SR = (16*4+2*4)
34 OFF_TRA = (16*4+6*4)
35
36 #include <asm/entry-macros.S>
37
38 ENTRY(exception_handler)
39 ! already saved r0/r1
40 mov.l r2,@-sp
41 mov.l r3,@-sp
42 mov r0,r1
43 cli
44 mov.l $cpu_mode,r2
45 mov.l @r2,r0
46 mov.l @(5*4,r15),r3 ! previous SR
47 shll2 r3 ! set "S" flag
48 rotl r0 ! T <- "S" flag
49 rotl r0 ! "S" flag is LSB
50 rotcr r3 ! T -> r3:b30
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 mov #1,r0
57 rotr r0
58 rotr r0
59 mov.l r0,@r2 ! enter kernel mode
60 mov.l $current_thread_info,r2
61 mov.l @r2,r2
62 mov #0x20,r0
63 shll8 r0
64 add r2,r0
65 mov r15,r2 ! r2 = user stack top
66 mov r0,r15 ! switch kernel stack
67 add #-4,r15 ! dummy
68 mov.l r1,@-r15 ! TRA
69 sts.l macl, @-r15
70 sts.l mach, @-r15
71 stc.l gbr, @-r15
72 mov.l @(4*4,r2),r0
73 mov.l @(5*4,r2),r1
74 mov.l r1,@-r15 ! original SR
75 sts.l pr,@-r15
76 mov.l r0,@-r15 ! original PC
77 mov r2,r3
78 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame
79 mov.l r3,@-r15 ! original SP
80 mov.l r14,@-r15
81 mov.l r13,@-r15
82 mov.l r12,@-r15
83 mov.l r11,@-r15
84 mov.l r10,@-r15
85 mov.l r9,@-r15
86 mov.l r8,@-r15
87 mov.l r7,@-r15
88 mov.l r6,@-r15
89 mov.l r5,@-r15
90 mov.l r4,@-r15
91 mov r2,r8 ! copy user -> kernel stack
92 mov.l @r8+,r3
93 mov.l r3,@-r15
94 mov.l @r8+,r2
95 mov.l r2,@-r15
96 mov.l @r8+,r1
97 mov.l r1,@-r15
98 mov.l @r8+,r0
99 bra 2f
100 mov.l r0,@-r15
101 1:
102 ! in kernel exception
103 mov #(22-4-4-1)*4+4,r0
104 mov r15,r2
105 sub r0,r15
106 mov.l @r2+,r0 ! old R3
107 mov.l r0,@-r15
108 mov.l @r2+,r0 ! old R2
109 mov.l r0,@-r15
110 mov.l @r2+,r0 ! old R1
111 mov.l r0,@-r15
112 mov.l @r2+,r0 ! old R0
113 mov.l r0,@-r15
114 mov.l @r2+,r3 ! old PC
115 mov.l @r2+,r0 ! old SR
116 add #-4,r2 ! exception frame stub (sr)
117 mov.l r1,@-r2 ! TRA
118 sts.l macl, @-r2
119 sts.l mach, @-r2
120 stc.l gbr, @-r2
121 mov.l r0,@-r2 ! save old SR
122 sts.l pr,@-r2
123 mov.l r3,@-r2 ! save old PC
124 mov r2,r0
125 add #8*4,r0
126 mov.l r0,@-r2 ! save old SP
127 mov.l r14,@-r2
128 mov.l r13,@-r2
129 mov.l r12,@-r2
130 mov.l r11,@-r2
131 mov.l r10,@-r2
132 mov.l r9,@-r2
133 mov.l r8,@-r2
134 mov.l r7,@-r2
135 mov.l r6,@-r2
136 mov.l r5,@-r2
137 mov.l r4,@-r2
138 mov.l @(OFF_R0,r15),r0
139 mov.l @(OFF_R1,r15),r1
140 mov.l @(OFF_R2,r15),r2
141 mov.l @(OFF_R3,r15),r3
142 2:
143 mov #OFF_TRA,r8
144 add r15,r8
145 mov.l @r8,r9
146 mov #64,r8
147 cmp/hs r8,r9
148 bt interrupt_entry ! vec >= 64 is interrupt
149 mov #32,r8
150 cmp/hs r8,r9
151 bt trap_entry ! 64 > vec >= 32 is trap
152 mov.l 4f,r8
153 mov r9,r4
154 shll2 r9
155 add r9,r8
156 mov.l @r8,r8
157 mov #0,r9
158 cmp/eq r9,r8
159 bf 3f
160 mov.l 8f,r8 ! unhandled exception
161 3:
162 mov.l 5f,r10
163 jmp @r8
164 lds r10,pr
165
166 interrupt_entry:
167 mov r9,r4
168 mov.l 6f,r9
169 mov.l 7f,r8
170 jmp @r8
171 lds r9,pr
172
173 .align 2
174 4: .long exception_handling_table
175 5: .long ret_from_exception
176 6: .long ret_from_irq
177 7: .long do_IRQ
178 8: .long do_exception_error
179
180 trap_entry:
181 add #-0x10,r9
182 shll2 r9 ! TRA
183 mov #OFF_TRA,r8
184 add r15,r8
185 mov.l r9,@r8
186 mov r9,r8
187 #ifdef CONFIG_TRACE_IRQFLAGS
188 mov.l 5f, r9
189 jsr @r9
190 nop
191 #endif
192 sti
193 bra system_call
194 nop
195
196 .align 2
197 1: .long syscall_exit
198 2: .long break_point_trap_software
199 3: .long NR_syscalls
200 4: .long sys_call_table
201 #ifdef CONFIG_TRACE_IRQFLAGS
202 5: .long trace_hardirqs_on
203 #endif
204
205 #if defined(CONFIG_SH_STANDARD_BIOS)
206 /* Unwind the stack and jmp to the debug entry */
207 debug_kernel_fw:
208 mov r15,r0
209 add #(22-4)*4-4,r0
210 ldc.l @r0+,gbr
211 lds.l @r0+,mach
212 lds.l @r0+,macl
213 mov r15,r0
214 mov.l @(OFF_SP,r0),r1
215 mov #OFF_SR,r2
216 mov.l @(r0,r2),r3
217 mov.l r3,@-r1
218 mov #OFF_SP,r2
219 mov.l @(r0,r2),r3
220 mov.l r3,@-r1
221 mov r15,r0
222 add #(22-4)*4-8,r0
223 mov.l 1f,r2
224 mov.l @r2,r2
225 stc sr,r3
226 mov.l r2,@r0
227 mov.l r3,@r0
228 mov.l r1,@(8,r0)
229 mov.l @r15+, r0
230 mov.l @r15+, r1
231 mov.l @r15+, r2
232 mov.l @r15+, r3
233 mov.l @r15+, r4
234 mov.l @r15+, r5
235 mov.l @r15+, r6
236 mov.l @r15+, r7
237 mov.l @r15+, r8
238 mov.l @r15+, r9
239 mov.l @r15+, r10
240 mov.l @r15+, r11
241 mov.l @r15+, r12
242 mov.l @r15+, r13
243 mov.l @r15+, r14
244 add #8,r15
245 lds.l @r15+, pr
246 rte
247 mov.l @r15+,r15
248 .align 2
249 1: .long gdb_vbr_vector
250 #endif /* CONFIG_SH_STANDARD_BIOS */
251
252 ENTRY(address_error_handler)
253 mov r15,r4 ! regs
254 add #4,r4
255 mov #OFF_PC,r0
256 mov.l @(r0,r15),r6 ! pc
257 mov.l 1f,r0
258 jmp @r0
259 mov #0,r5 ! writeaccess is unknown
260 .align 2
261
262 1: .long do_address_error
263
264 restore_all:
265 cli
266 #ifdef CONFIG_TRACE_IRQFLAGS
267 mov.l 3f, r0
268 jsr @r0
269 nop
270 #endif
271 mov r15,r0
272 mov.l $cpu_mode,r2
273 mov #OFF_SR,r3
274 mov.l @(r0,r3),r1
275 mov.l r1,@r2
276 shll2 r1 ! clear MD bit
277 shlr2 r1
278 mov.l @(OFF_SP,r0),r2
279 add #-8,r2
280 mov.l r2,@(OFF_SP,r0) ! point exception frame top
281 mov.l r1,@(4,r2) ! set sr
282 mov #OFF_PC,r3
283 mov.l @(r0,r3),r1
284 mov.l r1,@r2 ! set pc
285 add #4*16+4,r0
286 lds.l @r0+,pr
287 add #4,r0 ! skip sr
288 ldc.l @r0+,gbr
289 lds.l @r0+,mach
290 lds.l @r0+,macl
291 get_current_thread_info r0, r1
292 mov.l $current_thread_info,r1
293 mov.l r0,@r1
294 mov.l @r15+,r0
295 mov.l @r15+,r1
296 mov.l @r15+,r2
297 mov.l @r15+,r3
298 mov.l @r15+,r4
299 mov.l @r15+,r5
300 mov.l @r15+,r6
301 mov.l @r15+,r7
302 mov.l @r15+,r8
303 mov.l @r15+,r9
304 mov.l @r15+,r10
305 mov.l @r15+,r11
306 mov.l @r15+,r12
307 mov.l @r15+,r13
308 mov.l @r15+,r14
309 mov.l @r15,r15
310 rte
311 nop
312 2:
313 mov.l 1f,r8
314 mov.l 2f,r9
315 jmp @r9
316 lds r8,pr
317
318 .align 2
319 $current_thread_info:
320 .long __current_thread_info
321 $cpu_mode:
322 .long __cpu_mode
323 #ifdef CONFIG_TRACE_IRQFLAGS
324 3: .long trace_hardirqs_off
325 #endif
326
327 ! common exception handler
328 #include "../../entry-common.S"
329
330 .data
331 ! cpu operation mode
332 ! bit30 = MD (compatible SH3/4)
333 __cpu_mode:
334 .long 0x40000000
335
336 .section .bss
337 __current_thread_info:
338 .long 0
339
340 ENTRY(exception_handling_table)
341 .space 4*32
This page took 0.037621 seconds and 4 git commands to generate.