Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[pandora-kernel.git] / arch / mn10300 / kernel / fpu-low.S
1 /* MN10300 Low level FPU management operations
2  *
3  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
11 #include <linux/linkage.h>
12 #include <asm/cpu-regs.h>
13 #include <asm/smp.h>
14 #include <asm/thread_info.h>
15 #include <asm/asm-offsets.h>
16 #include <asm/frame.inc>
17
18 .macro FPU_INIT_STATE_ALL
19         fmov    0,fs0
20         fmov    fs0,fs1
21         fmov    fs0,fs2
22         fmov    fs0,fs3
23         fmov    fs0,fs4
24         fmov    fs0,fs5
25         fmov    fs0,fs6
26         fmov    fs0,fs7
27         fmov    fs0,fs8
28         fmov    fs0,fs9
29         fmov    fs0,fs10
30         fmov    fs0,fs11
31         fmov    fs0,fs12
32         fmov    fs0,fs13
33         fmov    fs0,fs14
34         fmov    fs0,fs15
35         fmov    fs0,fs16
36         fmov    fs0,fs17
37         fmov    fs0,fs18
38         fmov    fs0,fs19
39         fmov    fs0,fs20
40         fmov    fs0,fs21
41         fmov    fs0,fs22
42         fmov    fs0,fs23
43         fmov    fs0,fs24
44         fmov    fs0,fs25
45         fmov    fs0,fs26
46         fmov    fs0,fs27
47         fmov    fs0,fs28
48         fmov    fs0,fs29
49         fmov    fs0,fs30
50         fmov    fs0,fs31
51         fmov    FPCR_INIT,fpcr
52 .endm
53
54 .macro FPU_SAVE_ALL areg,dreg
55         fmov    fs0,(\areg+)
56         fmov    fs1,(\areg+)
57         fmov    fs2,(\areg+)
58         fmov    fs3,(\areg+)
59         fmov    fs4,(\areg+)
60         fmov    fs5,(\areg+)
61         fmov    fs6,(\areg+)
62         fmov    fs7,(\areg+)
63         fmov    fs8,(\areg+)
64         fmov    fs9,(\areg+)
65         fmov    fs10,(\areg+)
66         fmov    fs11,(\areg+)
67         fmov    fs12,(\areg+)
68         fmov    fs13,(\areg+)
69         fmov    fs14,(\areg+)
70         fmov    fs15,(\areg+)
71         fmov    fs16,(\areg+)
72         fmov    fs17,(\areg+)
73         fmov    fs18,(\areg+)
74         fmov    fs19,(\areg+)
75         fmov    fs20,(\areg+)
76         fmov    fs21,(\areg+)
77         fmov    fs22,(\areg+)
78         fmov    fs23,(\areg+)
79         fmov    fs24,(\areg+)
80         fmov    fs25,(\areg+)
81         fmov    fs26,(\areg+)
82         fmov    fs27,(\areg+)
83         fmov    fs28,(\areg+)
84         fmov    fs29,(\areg+)
85         fmov    fs30,(\areg+)
86         fmov    fs31,(\areg+)
87         fmov    fpcr,\dreg
88         mov     \dreg,(\areg)
89 .endm
90
91 .macro FPU_RESTORE_ALL areg,dreg
92         fmov    (\areg+),fs0
93         fmov    (\areg+),fs1
94         fmov    (\areg+),fs2
95         fmov    (\areg+),fs3
96         fmov    (\areg+),fs4
97         fmov    (\areg+),fs5
98         fmov    (\areg+),fs6
99         fmov    (\areg+),fs7
100         fmov    (\areg+),fs8
101         fmov    (\areg+),fs9
102         fmov    (\areg+),fs10
103         fmov    (\areg+),fs11
104         fmov    (\areg+),fs12
105         fmov    (\areg+),fs13
106         fmov    (\areg+),fs14
107         fmov    (\areg+),fs15
108         fmov    (\areg+),fs16
109         fmov    (\areg+),fs17
110         fmov    (\areg+),fs18
111         fmov    (\areg+),fs19
112         fmov    (\areg+),fs20
113         fmov    (\areg+),fs21
114         fmov    (\areg+),fs22
115         fmov    (\areg+),fs23
116         fmov    (\areg+),fs24
117         fmov    (\areg+),fs25
118         fmov    (\areg+),fs26
119         fmov    (\areg+),fs27
120         fmov    (\areg+),fs28
121         fmov    (\areg+),fs29
122         fmov    (\areg+),fs30
123         fmov    (\areg+),fs31
124         mov     (\areg),\dreg
125         fmov    \dreg,fpcr
126 .endm
127
128 ###############################################################################
129 #
130 # void fpu_init_state(void)
131 # - initialise the FPU
132 #
133 ###############################################################################
134         .globl  fpu_init_state
135         .type   fpu_init_state,@function
136 fpu_init_state:
137         mov     epsw,d0
138         or      EPSW_FE,epsw
139
140 #ifdef CONFIG_MN10300_PROC_MN103E010
141         nop
142         nop
143         nop
144 #endif
145         FPU_INIT_STATE_ALL
146 #ifdef CONFIG_MN10300_PROC_MN103E010
147         nop
148         nop
149         nop
150 #endif
151         mov     d0,epsw
152         ret     [],0
153
154         .size   fpu_init_state,.-fpu_init_state
155
156 ###############################################################################
157 #
158 # void fpu_save(struct fpu_state_struct *)
159 # - save the fpu state
160 # - note that an FPU Operational exception might occur during this process
161 #
162 ###############################################################################
163         .globl  fpu_save
164         .type   fpu_save,@function
165 fpu_save:
166         mov     epsw,d1
167         or      EPSW_FE,epsw            /* enable the FPU so we can access it */
168
169 #ifdef CONFIG_MN10300_PROC_MN103E010
170         nop
171         nop
172 #endif
173         mov     d0,a0
174         FPU_SAVE_ALL    a0,d0
175 #ifdef CONFIG_MN10300_PROC_MN103E010
176         nop
177         nop
178 #endif
179
180         mov     d1,epsw
181         ret     [],0
182
183         .size   fpu_save,.-fpu_save
184
185 ###############################################################################
186 #
187 # void fpu_disabled(void)
188 # - handle an exception due to the FPU being disabled
189 #   when CONFIG_FPU is enabled
190 #
191 ###############################################################################
192         .type   fpu_disabled,@function
193         .globl  fpu_disabled
194 fpu_disabled:
195         or      EPSW_nAR|EPSW_FE,epsw
196         nop
197         nop
198         nop
199
200         mov     sp,a1
201         mov     (a1),d1                 /* get epsw of user context */
202         and     ~(THREAD_SIZE-1),a1     /* a1: (thread_info *ti) */
203         mov     (TI_task,a1),a2         /* a2: (task_struct *tsk) */
204         btst    EPSW_nSL,d1
205         beq     fpu_used_in_kernel
206
207         or      EPSW_FE,d1
208         mov     d1,(sp)
209         mov     (TASK_THREAD+THREAD_FPU_FLAGS,a2),d1
210 #ifndef CONFIG_LAZY_SAVE_FPU
211         or      __THREAD_HAS_FPU,d1
212         mov     d1,(TASK_THREAD+THREAD_FPU_FLAGS,a2)
213 #else  /* !CONFIG_LAZY_SAVE_FPU */
214         mov     (fpu_state_owner),a0
215         cmp     0,a0
216         beq     fpu_regs_save_end
217
218         mov     (TASK_THREAD+THREAD_UREGS,a0),a1
219         add     TASK_THREAD+THREAD_FPU_STATE,a0
220         FPU_SAVE_ALL a0,d0
221
222         mov     (REG_EPSW,a1),d0
223         and     ~EPSW_FE,d0
224         mov     d0,(REG_EPSW,a1)
225
226 fpu_regs_save_end:
227         mov     a2,(fpu_state_owner)
228 #endif /* !CONFIG_LAZY_SAVE_FPU */
229
230         btst    __THREAD_USING_FPU,d1
231         beq     fpu_regs_init
232         add     TASK_THREAD+THREAD_FPU_STATE,a2
233         FPU_RESTORE_ALL a2,d0
234         rti
235
236 fpu_regs_init:
237         FPU_INIT_STATE_ALL
238         add     TASK_THREAD+THREAD_FPU_FLAGS,a2
239         bset    __THREAD_USING_FPU,(0,a2)
240         rti
241
242 fpu_used_in_kernel:
243         and     ~(EPSW_nAR|EPSW_FE),epsw
244         nop
245         nop
246
247         add     -4,sp
248         SAVE_ALL
249         mov     -1,d0
250         mov     d0,(REG_ORIG_D0,fp)
251
252         and     ~EPSW_NMID,epsw
253
254         mov     fp,d0
255         call    fpu_disabled_in_kernel[],0
256         jmp     ret_from_exception
257
258         .size   fpu_disabled,.-fpu_disabled