Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / arch / sh / kernel / cpu / sh2 / entry.S
blob0fc89069d8c7cd65566d19d1c06da515000dc014
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  */
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)
36 #include <asm/entry-macros.S>
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
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
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
153 #if defined(CONFIG_SH_FPU)
154         mov     #13,r8
155         cmp/eq  r8,r9
156         bt      10f             ! fpu
157         nop
158 #endif
160         mov.l   4f,r8
161         mov     r9,r4
162         shll2   r9
163         add     r9,r8
164         mov.l   @r8,r8
165         mov     #0,r9
166         cmp/eq  r9,r8
167         bf      3f
168         mov.l   8f,r8           ! unhandled exception
169 #if defined(CONFIG_SH_FPU)
171         mov.l   9f, r8          ! unhandled exception
172 #endif
174         mov.l   5f,r10
175         jmp     @r8
176          lds    r10,pr
178 interrupt_entry:
179         mov     r9,r4
180         mov     r15,r5
181         mov.l   6f,r9
182         mov.l   7f,r8
183         jmp     @r8
184          lds    r9,pr
186         .align  2
187 4:      .long   exception_handling_table
188 5:      .long   ret_from_exception
189 6:      .long   ret_from_irq
190 7:      .long   do_IRQ
191 8:      .long   do_exception_error
192 #ifdef CONFIG_SH_FPU
193 9:      .long   fpu_error_trap_handler
194 #endif
196 trap_entry:
197         mov     #0x30,r8
198         cmp/ge  r8,r9           ! vector 0x20-0x2f is systemcall
199         bt      1f
200         add     #-0x10,r9       ! convert SH2 to SH3/4 ABI
201 1:      
202         shll2   r9                      ! TRA
203         mov     #OFF_TRA,r8
204         add     r15,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         
216         .align  2
217 #ifdef CONFIG_TRACE_IRQFLAGS
218 2:      .long   trace_hardirqs_on
219 #endif
221 #if defined(CONFIG_SH_STANDARD_BIOS)
222         /* Unwind the stack and jmp to the debug entry */
223 ENTRY(sh_bios_handler)
224         mov     r15,r0
225         add     #(22-4)*4-4,r0
226         ldc.l   @r0+,gbr
227         lds.l   @r0+,mach
228         lds.l   @r0+,macl
229         mov     r15,r0
230         mov.l   @(OFF_SP,r0),r1
231         mov     #OFF_SR,r2
232         mov.l   @(r0,r2),r3
233         mov.l   r3,@-r1
234         mov     #OFF_SP,r2
235         mov.l   @(r0,r2),r3
236         mov.l   r3,@-r1
237         mov     r15,r0
238         add     #(22-4)*4-8,r0
239         mov.l   1f,r2
240         mov.l   @r2,r2
241         stc     sr,r3
242         mov.l   r2,@r0
243         mov.l   r3,@r0
244         mov.l   r1,@(8,r0)      
245         mov.l   @r15+, r0
246         mov.l   @r15+, r1
247         mov.l   @r15+, r2
248         mov.l   @r15+, r3
249         mov.l   @r15+, r4
250         mov.l   @r15+, r5
251         mov.l   @r15+, r6
252         mov.l   @r15+, r7
253         mov.l   @r15+, r8
254         mov.l   @r15+, r9
255         mov.l   @r15+, r10
256         mov.l   @r15+, r11
257         mov.l   @r15+, r12
258         mov.l   @r15+, r13
259         mov.l   @r15+, r14
260         add     #8,r15
261         lds.l   @r15+, pr
262         rte
263          mov.l  @r15+,r15
264         .align  2
265 1:      .long   gdb_vbr_vector
266 #endif /* CONFIG_SH_STANDARD_BIOS */
268 ENTRY(address_error_trap_handler)
269         mov     r15,r4                          ! regs
270         mov     #OFF_PC,r0
271         mov.l   @(r0,r15),r6                    ! pc
272         mov.l   1f,r0
273         jmp     @r0
274          mov    #0,r5                           ! writeaccess is unknown
275         .align  2
277 1:      .long   do_address_error
279 restore_all:
280         cli
281 #ifdef CONFIG_TRACE_IRQFLAGS
282         mov.l   1f, r0
283         jsr     @r0
284          nop
285 #endif
286         mov     r15,r0
287         mov.l   $cpu_mode,r2
288         mov     #OFF_SR,r3
289         mov.l   @(r0,r3),r1
290         mov.l   r1,@r2
291         shll2   r1                              ! clear MD bit
292         shlr2   r1
293         mov.l   @(OFF_SP,r0),r2
294         add     #-8,r2
295         mov.l   r2,@(OFF_SP,r0)                 ! point exception frame top
296         mov.l   r1,@(4,r2)                      ! set sr
297         mov     #OFF_PC,r3
298         mov.l   @(r0,r3),r1
299         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
307         mov.l   $current_thread_info,r1
308         mov.l   r0,@r1
309         mov.l   @r15+,r0
310         mov.l   @r15+,r1
311         mov.l   @r15+,r2
312         mov.l   @r15+,r3
313         mov.l   @r15+,r4
314         mov.l   @r15+,r5
315         mov.l   @r15+,r6
316         mov.l   @r15+,r7
317         mov.l   @r15+,r8
318         mov.l   @r15+,r9
319         mov.l   @r15+,r10
320         mov.l   @r15+,r11
321         mov.l   @r15+,r12
322         mov.l   @r15+,r13
323         mov.l   @r15+,r14
324         mov.l   @r15,r15
325         rte
326          nop
328         .align 2
329 #ifdef CONFIG_TRACE_IRQFLAGS
330 1:     .long   trace_hardirqs_off
331 #endif
332 $current_thread_info:
333         .long   __current_thread_info
334 $cpu_mode:      
335         .long   __cpu_mode
336                 
337 ! common exception handler
338 #include "../../entry-common.S"
339         
340         .data
341 ! cpu operation mode 
342 ! bit30 = MD (compatible SH3/4)
343 __cpu_mode:
344         .long   0x40000000
345                 
346         .section        .bss
347 __current_thread_info:
348         .long   0
350 ENTRY(exception_handling_table)
351         .space  4*32