Merge tag 'locks-v3.16-2' of git://git.samba.org/jlayton/linux
[linux/fpc-iii.git] / arch / sh / kernel / cpu / sh2a / entry.S
blob222742ddc0d6a656ae16b3e5eb9ae5ba0ddb3691
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  */
14 #include <linux/linkage.h>
15 #include <asm/asm-offsets.h>
16 #include <asm/thread_info.h>
17 #include <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         ! 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
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
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
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
125         mov.l   5f,r10
126         jmp     @r8
127          lds    r10,pr
129 interrupt_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
137         .align  2
138 4:      .long   exception_handling_table
139 5:      .long   ret_from_exception
140 6:      .long   ret_from_irq
141 7:      .long   do_IRQ
142 8:      .long   exception_error
144 trap_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
149 1:      
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 */
156 ENTRY(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         mov.l   @r15+,r15
180         rte
181          nop
182         .align  2
183 1:      .long   gdb_vbr_vector
184 #endif /* CONFIG_SH_STANDARD_BIOS */
186 ENTRY(address_error_trap_handler)
187         mov     r15,r4                          ! regs
188         mov.l   @(OFF_PC,r15),r6                ! pc
189         mov.l   1f,r0
190         jmp     @r0
191          mov    #0,r5                           ! writeaccess is unknown
193         .align  2
194 1:      .long   do_address_error
196 restore_all:
197         stc     sr,r0
198         or      #0xf0,r0
199         ldc     r0,sr                           ! all interrupt block (same BL = 1)
200         ! restore special register
201         ! overlap exception frame
202         mov     r15,r0
203         add     #17*4,r0
204         lds.l   @r0+,pr
205         add     #4,r0
206         ldc.l   @r0+,gbr
207         lds.l   @r0+,mach
208         lds.l   @r0+,macl
209         mov     r15,r0
210         mov.l   $cpu_mode,r2
211         bld.b   #6,@(OFF_SR,r15)
212         bst.b   #6,@(0,r2)                      ! save CPU mode
213         mov.l   @(OFF_SR,r0),r1
214         shll2   r1
215         shlr2   r1                              ! clear MD bit
216         mov.l   @(OFF_SP,r0),r2
217         add     #-8,r2
218         mov.l   r2,@(OFF_SP,r0)                 ! point exception frame top
219         mov.l   r1,@(4,r2)                      ! set sr
220         mov.l   @(OFF_PC,r0),r1
221         mov.l   r1,@r2                          ! set pc
222         get_current_thread_info r0, r1
223         mov.l   $current_thread_info,r1
224         mov.l   r0,@r1
225         movml.l @r15+,r14
226         mov.l   @r15,r15
227         rte
228          nop
230         .align 2
231 $current_thread_info:
232         .long   __current_thread_info
233 $cpu_mode:      
234         .long   __cpu_mode
235                 
236 ! common exception handler
237 #include "../../entry-common.S"
238         
239         .data
240 ! cpu operation mode 
241 ! bit30 = MD (compatible SH3/4)
242 __cpu_mode:
243         .long   0x40000000
244                 
245         .section        .bss
246 __current_thread_info:
247         .long   0
249 ENTRY(exception_handling_table)
250         .space  4*32