1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/linkage.h>
18#include <asm/ptrace.h>
19#include <asm/thread_info.h>
20#include <asm/asm-offsets.h>
21#include <asm/assembler.h>
22
23
24#define PJ4(code...) code
25#define XSC(code...)
26
27 defined(CONFIG_CPU_XSC3) || \
28 defined(CONFIG_CPU_XSCALE)
29#define PJ4(code...)
30#define XSC(code...) code
31#else
32
33#endif
34
35#define MMX_WR0 (0x00)
36#define MMX_WR1 (0x08)
37#define MMX_WR2 (0x10)
38#define MMX_WR3 (0x18)
39#define MMX_WR4 (0x20)
40#define MMX_WR5 (0x28)
41#define MMX_WR6 (0x30)
42#define MMX_WR7 (0x38)
43#define MMX_WR8 (0x40)
44#define MMX_WR9 (0x48)
45#define MMX_WR10 (0x50)
46#define MMX_WR11 (0x58)
47#define MMX_WR12 (0x60)
48#define MMX_WR13 (0x68)
49#define MMX_WR14 (0x70)
50#define MMX_WR15 (0x78)
51#define MMX_WCSSF (0x80)
52#define MMX_WCASF (0x84)
53#define MMX_WCGR0 (0x88)
54#define MMX_WCGR1 (0x8C)
55#define MMX_WCGR2 (0x90)
56#define MMX_WCGR3 (0x94)
57
58#define MMX_SIZE (0x98)
59
60 .text
61 .arm
62
63
64
65
66
67
68
69
70
71
72
73ENTRY(iwmmxt_task_enable)
74 inc_preempt_count r10, r3
75
76 XSC(mrc p15, 0, r2, c15, c1, 0)
77 PJ4(mrc p15, 0, r2, c1, c0, 2)
78 @ CP0 and CP1 accessible?
79 XSC(tst r2,
80 PJ4(tst r2,
81 bne 4f @ if so no business here
82 @ enable access to CP0 and CP1
83 XSC(orr r2, r2,
84 XSC(mcr p15, 0, r2, c15, c1, 0)
85 PJ4(orr r2, r2,
86 PJ4(mcr p15, 0, r2, c1, c0, 2)
87
88 ldr r3, =concan_owner
89 add r0, r10,
90 ldr r2, [sp,
91 ldr r1, [r3] @ get current Concan owner
92 str r0, [r3] @ this task now owns Concan regs
93 sub r2, r2,
94 str r2, [sp,
95
96 mrc p15, 0, r2, c2, c0, 0
97 mov r2, r2 @ cpwait
98 bl concan_save
99
100#ifdef CONFIG_PREEMPT_COUNT
101 get_thread_info r10
102#endif
1034: dec_preempt_count r10, r3
104 ret r9 @ normal exit from exception
105
106concan_save:
107
108 teq r1,
109 beq concan_load @ no owner, skip save
110
111 tmrc r2, wCon
112
113 @ CUP? wCx
114 tst r2,
115 beq 1f
116
117concan_dump:
118
119 wstrw wCSSF, [r1,
120 wstrw wCASF, [r1,
121 wstrw wCGR0, [r1,
122 wstrw wCGR1, [r1,
123 wstrw wCGR2, [r1,
124 wstrw wCGR3, [r1,
125
1261: @ MUP? wRn
127 tst r2,
128 beq 2f
129
130 wstrd wR0, [r1,
131 wstrd wR1, [r1,
132 wstrd wR2, [r1,
133 wstrd wR3, [r1,
134 wstrd wR4, [r1,
135 wstrd wR5, [r1,
136 wstrd wR6, [r1,
137 wstrd wR7, [r1,
138 wstrd wR8, [r1,
139 wstrd wR9, [r1,
140 wstrd wR10, [r1,
141 wstrd wR11, [r1,
142 wstrd wR12, [r1,
143 wstrd wR13, [r1,
144 wstrd wR14, [r1,
145 wstrd wR15, [r1,
146
1472: teq r0,
148 reteq lr @ if not, return
149
150concan_load:
151
152 @ Load wRn
153 wldrd wR0, [r0,
154 wldrd wR1, [r0,
155 wldrd wR2, [r0,
156 wldrd wR3, [r0,
157 wldrd wR4, [r0,
158 wldrd wR5, [r0,
159 wldrd wR6, [r0,
160 wldrd wR7, [r0,
161 wldrd wR8, [r0,
162 wldrd wR9, [r0,
163 wldrd wR10, [r0,
164 wldrd wR11, [r0,
165 wldrd wR12, [r0,
166 wldrd wR13, [r0,
167 wldrd wR14, [r0,
168 wldrd wR15, [r0,
169
170 @ Load wCx
171 wldrw wCSSF, [r0,
172 wldrw wCASF, [r0,
173 wldrw wCGR0, [r0,
174 wldrw wCGR1, [r0,
175 wldrw wCGR2, [r0,
176 wldrw wCGR3, [r0,
177
178 @ clear CUP/MUP (only if r1 != 0)
179 teq r1,
180 mov r2,
181 reteq lr
182
183 tmcr wCon, r2
184 ret lr
185
186ENDPROC(iwmmxt_task_enable)
187
188
189
190
191
192
193
194
195ENTRY(iwmmxt_task_disable)
196
197 stmfd sp!, {r4, lr}
198
199 mrs ip, cpsr
200 orr r2, ip,
201 msr cpsr_c, r2
202
203 ldr r3, =concan_owner
204 add r2, r0,
205 ldr r1, [r3] @ get current Concan owner
206 teq r1,
207 beq 1f @ no: quit
208 teq r0,
209 teqne r1, r2 @ or specified one?
210 bne 1f @ no: quit
211
212 @ enable access to CP0 and CP1
213 XSC(mrc p15, 0, r4, c15, c1, 0)
214 XSC(orr r4, r4,
215 XSC(mcr p15, 0, r4, c15, c1, 0)
216 PJ4(mrc p15, 0, r4, c1, c0, 2)
217 PJ4(orr r4, r4,
218 PJ4(mcr p15, 0, r4, c1, c0, 2)
219
220 mov r0,
221 str r0, [r3] @ no more current owner
222 mrc p15, 0, r2, c2, c0, 0
223 mov r2, r2 @ cpwait
224 bl concan_save
225
226 @ disable access to CP0 and CP1
227 XSC(bic r4, r4,
228 XSC(mcr p15, 0, r4, c15, c1, 0)
229 PJ4(bic r4, r4,
230 PJ4(mcr p15, 0, r4, c1, c0, 2)
231
232 mrc p15, 0, r2, c2, c0, 0
233 mov r2, r2 @ cpwait
234
2351: msr cpsr_c, ip @ restore interrupt mode
236 ldmfd sp!, {r4, pc}
237
238ENDPROC(iwmmxt_task_disable)
239
240
241
242
243
244
245
246
247
248
249ENTRY(iwmmxt_task_copy)
250
251 mrs ip, cpsr
252 orr r2, ip,
253 msr cpsr_c, r2
254
255 ldr r3, =concan_owner
256 add r2, r0,
257 ldr r3, [r3] @ get current Concan owner
258 teq r2, r3 @ does this task own it...
259 beq 1f
260
261 @ current Concan values are in the task save area
262 msr cpsr_c, ip @ restore interrupt mode
263 mov r0, r1
264 mov r1, r2
265 mov r2,
266 b memcpy
267
2681: @ this task owns Concan regs -- grab a copy from there
269 mov r0,
270 mov r2,
271 mov r3, lr @ preserve return address
272 bl concan_dump
273 msr cpsr_c, ip @ restore interrupt mode
274 ret r3
275
276ENDPROC(iwmmxt_task_copy)
277
278
279
280
281
282
283
284
285
286
287ENTRY(iwmmxt_task_restore)
288
289 mrs ip, cpsr
290 orr r2, ip,
291 msr cpsr_c, r2
292
293 ldr r3, =concan_owner
294 add r2, r0,
295 ldr r3, [r3] @ get current Concan owner
296 bic r2, r2,
297 teq r2, r3 @ does this task own it...
298 beq 1f
299
300 @ this task doesn't own Concan regs -- use its save area
301 msr cpsr_c, ip @ restore interrupt mode
302 mov r0, r2
303 mov r2,
304 b memcpy
305
3061: @ this task owns Concan regs -- load them directly
307 mov r0, r1
308 mov r1,
309 mov r3, lr @ preserve return address
310 bl concan_load
311 msr cpsr_c, ip @ restore interrupt mode
312 ret r3
313
314ENDPROC(iwmmxt_task_restore)
315
316
317
318
319
320
321
322
323ENTRY(iwmmxt_task_switch)
324
325 XSC(mrc p15, 0, r1, c15, c1, 0)
326 PJ4(mrc p15, 0, r1, c1, c0, 2)
327 @ CP0 and CP1 accessible?
328 XSC(tst r1,
329 PJ4(tst r1,
330 bne 1f @ yes: block them for next task
331
332 ldr r2, =concan_owner
333 add r3, r0,
334 ldr r2, [r2] @ get current Concan owner
335 teq r2, r3 @ next task owns it?
336 retne lr @ no: leave Concan disabled
337
3381: @ flip Concan access
339 XSC(eor r1, r1,
340 XSC(mcr p15, 0, r1, c15, c1, 0)
341 PJ4(eor r1, r1,
342 PJ4(mcr p15, 0, r1, c1, c0, 2)
343
344 mrc p15, 0, r1, c2, c0, 0
345 sub pc, lr, r1, lsr
346
347ENDPROC(iwmmxt_task_switch)
348
349
350
351
352
353
354ENTRY(iwmmxt_task_release)
355
356 mrs r2, cpsr
357 orr ip, r2,
358 msr cpsr_c, ip
359 ldr r3, =concan_owner
360 add r0, r0,
361 ldr r1, [r3] @ get current Concan owner
362 eors r0, r0, r1 @ if equal...
363 streq r0, [r3] @ then clear ownership
364 msr cpsr_c, r2 @ restore interrupts
365 ret lr
366
367ENDPROC(iwmmxt_task_release)
368
369 .data
370 .align 2
371concan_owner:
372 .word 0
373
374