Merge branch 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux...
[linux-block.git] / arch / sh / kernel / cpu / sh2 / entry.S
CommitLineData
de398406
YS
1/*
2 * arch/sh/kernel/cpu/sh2/entry.S
3 *
4 * The SH-2 exception entry
5 *
6e80f5e8 6 * Copyright (C) 2005-2008 Yoshinori Sato
de398406
YS
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>
f15cbe6f 17#include <cpu/mmu_context.h>
de398406
YS
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)
6e80f5e8
YS
39 ! stack
40 ! r0 <- point sp
41 ! r1
42 ! pc
43 ! sr
44 ! r0 = temporary
45 ! r1 = vector (pseudo EXPEVT / INTEVT / TRA)
de398406
YS
46 mov.l r2,@-sp
47 mov.l r3,@-sp
de398406
YS
48 cli
49 mov.l $cpu_mode,r2
50 mov.l @r2,r0
51 mov.l @(5*4,r15),r3 ! previous SR
6e80f5e8
YS
52 or r0,r3 ! set MD
53 tst r0,r0
54 bf/s 1f ! previous mode check
55 mov.l r3,@(5*4,r15) ! update SR
de398406 56 ! switch to kernel mode
6e80f5e8 57 mov.l __md_bit,r0
de398406
YS
58 mov.l r0,@r2 ! enter kernel mode
59 mov.l $current_thread_info,r2
60 mov.l @r2,r2
6e80f5e8 61 mov #(THREAD_SIZE >> 8),r0
de398406
YS
62 shll8 r0
63 add r2,r0
64 mov r15,r2 ! r2 = user stack top
65 mov r0,r15 ! switch kernel stack
de398406
YS
66 mov.l r1,@-r15 ! TRA
67 sts.l macl, @-r15
68 sts.l mach, @-r15
69 stc.l gbr, @-r15
6e80f5e8
YS
70 mov.l @(5*4,r2),r0
71 mov.l r0,@-r15 ! original SR
de398406 72 sts.l pr,@-r15
6e80f5e8 73 mov.l @(4*4,r2),r0
de398406
YS
74 mov.l r0,@-r15 ! original PC
75 mov r2,r3
76 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame
77 mov.l r3,@-r15 ! original SP
78 mov.l r14,@-r15
79 mov.l r13,@-r15
80 mov.l r12,@-r15
81 mov.l r11,@-r15
82 mov.l r10,@-r15
83 mov.l r9,@-r15
84 mov.l r8,@-r15
85 mov.l r7,@-r15
86 mov.l r6,@-r15
87 mov.l r5,@-r15
88 mov.l r4,@-r15
6e80f5e8 89 mov r1,r9 ! save TRA
de398406 90 mov r2,r8 ! copy user -> kernel stack
6e80f5e8 91 mov.l @(0,r8),r3
de398406 92 mov.l r3,@-r15
6e80f5e8 93 mov.l @(4,r8),r2
de398406 94 mov.l r2,@-r15
6e80f5e8 95 mov.l @(12,r8),r1
de398406 96 mov.l r1,@-r15
6e80f5e8 97 mov.l @(8,r8),r0
de398406
YS
98 bra 2f
99 mov.l r0,@-r15
1001:
101 ! in kernel exception
102 mov #(22-4-4-1)*4+4,r0
103 mov r15,r2
104 sub r0,r15
105 mov.l @r2+,r0 ! old R3
106 mov.l r0,@-r15
107 mov.l @r2+,r0 ! old R2
108 mov.l r0,@-r15
6e80f5e8 109 mov.l @(4,r2),r0 ! old R1
de398406 110 mov.l r0,@-r15
6e80f5e8
YS
111 mov.l @r2,r0 ! old R0
112 mov.l r0,@-r15
113 add #8,r2
de398406
YS
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
6e80f5e8 138 mov r1,r9
de398406
YS
139 mov.l @(OFF_R0,r15),r0
140 mov.l @(OFF_R1,r15),r1
141 mov.l @(OFF_R2,r15),r2
142 mov.l @(OFF_R3,r15),r3
1432:
de398406
YS
144 mov #64,r8
145 cmp/hs r8,r9
146 bt interrupt_entry ! vec >= 64 is interrupt
147 mov #32,r8
148 cmp/hs r8,r9
149 bt trap_entry ! 64 > vec >= 32 is trap
74d99a5e 150
de398406
YS
151 mov.l 4f,r8
152 mov r9,r4
153 shll2 r9
154 add r9,r8
6e80f5e8
YS
155 mov.l @r8,r8 ! exception handler address
156 tst r8,r8
de398406
YS
157 bf 3f
158 mov.l 8f,r8 ! unhandled exception
1593:
160 mov.l 5f,r10
161 jmp @r8
162 lds r10,pr
163
164interrupt_entry:
165 mov r9,r4
3afb209a 166 mov r15,r5
de398406
YS
167 mov.l 6f,r9
168 mov.l 7f,r8
169 jmp @r8
170 lds r9,pr
171
172 .align 2
1734: .long exception_handling_table
1745: .long ret_from_exception
1756: .long ret_from_irq
1767: .long do_IRQ
6e80f5e8 1778: .long exception_error
74d99a5e 178
e9cfc147 179trap_entry:
4aa362bb
YS
180 mov #0x30,r8
181 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
182 bt 1f
183 add #-0x10,r9 ! convert SH2 to SH3/4 ABI
e9cfc147 1841:
de398406 185 shll2 r9 ! TRA
6e80f5e8
YS
186 bra system_call ! jump common systemcall entry
187 mov r9,r8
de398406 188
de398406
YS
189#if defined(CONFIG_SH_STANDARD_BIOS)
190 /* Unwind the stack and jmp to the debug entry */
f413d0d9 191ENTRY(sh_bios_handler)
de398406
YS
192 mov r15,r0
193 add #(22-4)*4-4,r0
194 ldc.l @r0+,gbr
195 lds.l @r0+,mach
196 lds.l @r0+,macl
197 mov r15,r0
198 mov.l @(OFF_SP,r0),r1
199 mov #OFF_SR,r2
200 mov.l @(r0,r2),r3
201 mov.l r3,@-r1
202 mov #OFF_SP,r2
203 mov.l @(r0,r2),r3
204 mov.l r3,@-r1
205 mov r15,r0
206 add #(22-4)*4-8,r0
207 mov.l 1f,r2
208 mov.l @r2,r2
209 stc sr,r3
210 mov.l r2,@r0
6e80f5e8 211 mov.l r3,@(4,r0)
de398406
YS
212 mov.l r1,@(8,r0)
213 mov.l @r15+, r0
214 mov.l @r15+, r1
215 mov.l @r15+, r2
216 mov.l @r15+, r3
217 mov.l @r15+, r4
218 mov.l @r15+, r5
219 mov.l @r15+, r6
220 mov.l @r15+, r7
221 mov.l @r15+, r8
222 mov.l @r15+, r9
223 mov.l @r15+, r10
224 mov.l @r15+, r11
225 mov.l @r15+, r12
226 mov.l @r15+, r13
227 mov.l @r15+, r14
228 add #8,r15
229 lds.l @r15+, pr
7a90e00d 230 mov.l @r15+,r15
de398406 231 rte
7a90e00d 232 nop
de398406
YS
233 .align 2
2341: .long gdb_vbr_vector
235#endif /* CONFIG_SH_STANDARD_BIOS */
236
5a4f7c66 237ENTRY(address_error_trap_handler)
de398406 238 mov r15,r4 ! regs
de398406
YS
239 mov #OFF_PC,r0
240 mov.l @(r0,r15),r6 ! pc
241 mov.l 1f,r0
242 jmp @r0
243 mov #0,r5 ! writeaccess is unknown
de398406 244
6e80f5e8 245 .align 2
de398406
YS
2461: .long do_address_error
247
248restore_all:
6e80f5e8
YS
249 stc sr,r0
250 or #0xf0,r0
251 ldc r0,sr ! all interrupt block (same BL = 1)
252 ! restore special register
253 ! overlap exception frame
254 mov r15,r0
255 add #17*4,r0
256 lds.l @r0+,pr
257 add #4,r0
258 ldc.l @r0+,gbr
259 lds.l @r0+,mach
260 lds.l @r0+,macl
de398406
YS
261 mov r15,r0
262 mov.l $cpu_mode,r2
263 mov #OFF_SR,r3
264 mov.l @(r0,r3),r1
6e80f5e8
YS
265 mov.l __md_bit,r3
266 and r1,r3 ! copy MD bit
267 mov.l r3,@r2
de398406
YS
268 shll2 r1 ! clear MD bit
269 shlr2 r1
270 mov.l @(OFF_SP,r0),r2
271 add #-8,r2
272 mov.l r2,@(OFF_SP,r0) ! point exception frame top
273 mov.l r1,@(4,r2) ! set sr
274 mov #OFF_PC,r3
275 mov.l @(r0,r3),r1
276 mov.l r1,@r2 ! set pc
de398406
YS
277 get_current_thread_info r0, r1
278 mov.l $current_thread_info,r1
279 mov.l r0,@r1
280 mov.l @r15+,r0
281 mov.l @r15+,r1
282 mov.l @r15+,r2
283 mov.l @r15+,r3
284 mov.l @r15+,r4
285 mov.l @r15+,r5
286 mov.l @r15+,r6
287 mov.l @r15+,r7
288 mov.l @r15+,r8
289 mov.l @r15+,r9
290 mov.l @r15+,r10
291 mov.l @r15+,r11
292 mov.l @r15+,r12
293 mov.l @r15+,r13
294 mov.l @r15+,r14
295 mov.l @r15,r15
296 rte
297 nop
de398406 298
9f9a5de4 299 .align 2
6e80f5e8
YS
300__md_bit:
301 .long 0x40000000
de398406
YS
302$current_thread_info:
303 .long __current_thread_info
304$cpu_mode:
305 .long __cpu_mode
306
307! common exception handler
308#include "../../entry-common.S"
309
310 .data
311! cpu operation mode
312! bit30 = MD (compatible SH3/4)
313__cpu_mode:
314 .long 0x40000000
315
316 .section .bss
317__current_thread_info:
318 .long 0
319
320ENTRY(exception_handling_table)
321 .space 4*32