Commit | Line | Data |
---|---|---|
b920de1b DH |
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 | */ | |
278d91c4 | 11 | #include <linux/linkage.h> |
b920de1b | 12 | #include <asm/cpu-regs.h> |
278d91c4 AT |
13 | #include <asm/smp.h> |
14 | #include <asm/thread_info.h> | |
15 | #include <asm/asm-offsets.h> | |
16 | #include <asm/frame.inc> | |
b920de1b | 17 | |
278d91c4 | 18 | .macro FPU_INIT_STATE_ALL |
b920de1b DH |
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 | |
278d91c4 AT |
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 | |
b920de1b | 127 | |
278d91c4 AT |
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 | |
b920de1b DH |
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 | |
278d91c4 | 174 | FPU_SAVE_ALL a0,d0 |
b920de1b DH |
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 | # | |
278d91c4 AT |
187 | # void fpu_disabled(void) |
188 | # - handle an exception due to the FPU being disabled | |
189 | # when CONFIG_FPU is enabled | |
b920de1b DH |
190 | # |
191 | ############################################################################### | |
278d91c4 AT |
192 | .type fpu_disabled,@function |
193 | .globl fpu_disabled | |
194 | fpu_disabled: | |
195 | or EPSW_nAR|EPSW_FE,epsw | |
b920de1b DH |
196 | nop |
197 | nop | |
b920de1b | 198 | nop |
278d91c4 AT |
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 | |
b920de1b DH |
244 | nop |
245 | nop | |
b920de1b | 246 | |
278d91c4 AT |
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 | |
b920de1b | 257 | |
278d91c4 | 258 | .size fpu_disabled,.-fpu_disabled |