Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/kernel/crunch-bits.S
10817 views
1
/*
2
* arch/arm/kernel/crunch-bits.S
3
* Cirrus MaverickCrunch context switching and handling
4
*
5
* Copyright (C) 2006 Lennert Buytenhek <[email protected]>
6
*
7
* Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is
8
* Copyright (c) 2003-2004, MontaVista Software, Inc.
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License version 2 as
12
* published by the Free Software Foundation.
13
*/
14
15
#include <linux/linkage.h>
16
#include <asm/ptrace.h>
17
#include <asm/thread_info.h>
18
#include <asm/asm-offsets.h>
19
#include <mach/ep93xx-regs.h>
20
21
/*
22
* We can't use hex constants here due to a bug in gas.
23
*/
24
#define CRUNCH_MVDX0 0
25
#define CRUNCH_MVDX1 8
26
#define CRUNCH_MVDX2 16
27
#define CRUNCH_MVDX3 24
28
#define CRUNCH_MVDX4 32
29
#define CRUNCH_MVDX5 40
30
#define CRUNCH_MVDX6 48
31
#define CRUNCH_MVDX7 56
32
#define CRUNCH_MVDX8 64
33
#define CRUNCH_MVDX9 72
34
#define CRUNCH_MVDX10 80
35
#define CRUNCH_MVDX11 88
36
#define CRUNCH_MVDX12 96
37
#define CRUNCH_MVDX13 104
38
#define CRUNCH_MVDX14 112
39
#define CRUNCH_MVDX15 120
40
#define CRUNCH_MVAX0L 128
41
#define CRUNCH_MVAX0M 132
42
#define CRUNCH_MVAX0H 136
43
#define CRUNCH_MVAX1L 140
44
#define CRUNCH_MVAX1M 144
45
#define CRUNCH_MVAX1H 148
46
#define CRUNCH_MVAX2L 152
47
#define CRUNCH_MVAX2M 156
48
#define CRUNCH_MVAX2H 160
49
#define CRUNCH_MVAX3L 164
50
#define CRUNCH_MVAX3M 168
51
#define CRUNCH_MVAX3H 172
52
#define CRUNCH_DSPSC 176
53
54
#define CRUNCH_SIZE 184
55
56
.text
57
58
/*
59
* Lazy switching of crunch coprocessor context
60
*
61
* r10 = struct thread_info pointer
62
* r9 = ret_from_exception
63
* lr = undefined instr exit
64
*
65
* called from prefetch exception handler with interrupts disabled
66
*/
67
ENTRY(crunch_task_enable)
68
ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
69
70
ldr r1, [r8, #0x80]
71
tst r1, #0x00800000 @ access to crunch enabled?
72
movne pc, lr @ if so no business here
73
mov r3, #0xaa @ unlock syscon swlock
74
str r3, [r8, #0xc0]
75
orr r1, r1, #0x00800000 @ enable access to crunch
76
str r1, [r8, #0x80]
77
78
ldr r3, =crunch_owner
79
add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area
80
ldr r2, [sp, #60] @ current task pc value
81
ldr r1, [r3] @ get current crunch owner
82
str r0, [r3] @ this task now owns crunch
83
sub r2, r2, #4 @ adjust pc back
84
str r2, [sp, #60]
85
86
ldr r2, [r8, #0x80]
87
mov r2, r2 @ flush out enable (@@@)
88
89
teq r1, #0 @ test for last ownership
90
mov lr, r9 @ normal exit from exception
91
beq crunch_load @ no owner, skip save
92
93
crunch_save:
94
cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers
95
cfstr64 mvdx1, [r1, #CRUNCH_MVDX1]
96
cfstr64 mvdx2, [r1, #CRUNCH_MVDX2]
97
cfstr64 mvdx3, [r1, #CRUNCH_MVDX3]
98
cfstr64 mvdx4, [r1, #CRUNCH_MVDX4]
99
cfstr64 mvdx5, [r1, #CRUNCH_MVDX5]
100
cfstr64 mvdx6, [r1, #CRUNCH_MVDX6]
101
cfstr64 mvdx7, [r1, #CRUNCH_MVDX7]
102
cfstr64 mvdx8, [r1, #CRUNCH_MVDX8]
103
cfstr64 mvdx9, [r1, #CRUNCH_MVDX9]
104
cfstr64 mvdx10, [r1, #CRUNCH_MVDX10]
105
cfstr64 mvdx11, [r1, #CRUNCH_MVDX11]
106
cfstr64 mvdx12, [r1, #CRUNCH_MVDX12]
107
cfstr64 mvdx13, [r1, #CRUNCH_MVDX13]
108
cfstr64 mvdx14, [r1, #CRUNCH_MVDX14]
109
cfstr64 mvdx15, [r1, #CRUNCH_MVDX15]
110
111
#ifdef __ARMEB__
112
#error fix me for ARMEB
113
#endif
114
115
cfmv32al mvfx0, mvax0 @ save 72b accumulators
116
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L]
117
cfmv32am mvfx0, mvax0
118
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M]
119
cfmv32ah mvfx0, mvax0
120
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H]
121
cfmv32al mvfx0, mvax1
122
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L]
123
cfmv32am mvfx0, mvax1
124
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M]
125
cfmv32ah mvfx0, mvax1
126
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H]
127
cfmv32al mvfx0, mvax2
128
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L]
129
cfmv32am mvfx0, mvax2
130
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M]
131
cfmv32ah mvfx0, mvax2
132
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H]
133
cfmv32al mvfx0, mvax3
134
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L]
135
cfmv32am mvfx0, mvax3
136
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M]
137
cfmv32ah mvfx0, mvax3
138
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H]
139
140
cfmv32sc mvdx0, dspsc @ save status word
141
cfstr64 mvdx0, [r1, #CRUNCH_DSPSC]
142
143
teq r0, #0 @ anything to load?
144
cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered
145
moveq pc, lr
146
147
crunch_load:
148
cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word
149
cfmvsc32 dspsc, mvdx0
150
151
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators
152
cfmval32 mvax0, mvfx0
153
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M]
154
cfmvam32 mvax0, mvfx0
155
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H]
156
cfmvah32 mvax0, mvfx0
157
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L]
158
cfmval32 mvax1, mvfx0
159
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M]
160
cfmvam32 mvax1, mvfx0
161
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H]
162
cfmvah32 mvax1, mvfx0
163
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L]
164
cfmval32 mvax2, mvfx0
165
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M]
166
cfmvam32 mvax2, mvfx0
167
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H]
168
cfmvah32 mvax2, mvfx0
169
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L]
170
cfmval32 mvax3, mvfx0
171
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M]
172
cfmvam32 mvax3, mvfx0
173
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H]
174
cfmvah32 mvax3, mvfx0
175
176
cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers
177
cfldr64 mvdx1, [r0, #CRUNCH_MVDX1]
178
cfldr64 mvdx2, [r0, #CRUNCH_MVDX2]
179
cfldr64 mvdx3, [r0, #CRUNCH_MVDX3]
180
cfldr64 mvdx4, [r0, #CRUNCH_MVDX4]
181
cfldr64 mvdx5, [r0, #CRUNCH_MVDX5]
182
cfldr64 mvdx6, [r0, #CRUNCH_MVDX6]
183
cfldr64 mvdx7, [r0, #CRUNCH_MVDX7]
184
cfldr64 mvdx8, [r0, #CRUNCH_MVDX8]
185
cfldr64 mvdx9, [r0, #CRUNCH_MVDX9]
186
cfldr64 mvdx10, [r0, #CRUNCH_MVDX10]
187
cfldr64 mvdx11, [r0, #CRUNCH_MVDX11]
188
cfldr64 mvdx12, [r0, #CRUNCH_MVDX12]
189
cfldr64 mvdx13, [r0, #CRUNCH_MVDX13]
190
cfldr64 mvdx14, [r0, #CRUNCH_MVDX14]
191
cfldr64 mvdx15, [r0, #CRUNCH_MVDX15]
192
193
mov pc, lr
194
195
/*
196
* Back up crunch regs to save area and disable access to them
197
* (mainly for gdb or sleep mode usage)
198
*
199
* r0 = struct thread_info pointer of target task or NULL for any
200
*/
201
ENTRY(crunch_task_disable)
202
stmfd sp!, {r4, r5, lr}
203
204
mrs ip, cpsr
205
orr r2, ip, #PSR_I_BIT @ disable interrupts
206
msr cpsr_c, r2
207
208
ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
209
210
ldr r3, =crunch_owner
211
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
212
ldr r1, [r3] @ get current crunch owner
213
teq r1, #0 @ any current owner?
214
beq 1f @ no: quit
215
teq r0, #0 @ any owner?
216
teqne r1, r2 @ or specified one?
217
bne 1f @ no: quit
218
219
ldr r5, [r4, #0x80] @ enable access to crunch
220
mov r2, #0xaa
221
str r2, [r4, #0xc0]
222
orr r5, r5, #0x00800000
223
str r5, [r4, #0x80]
224
225
mov r0, #0 @ nothing to load
226
str r0, [r3] @ no more current owner
227
ldr r2, [r4, #0x80] @ flush out enable (@@@)
228
mov r2, r2
229
bl crunch_save
230
231
mov r2, #0xaa @ disable access to crunch
232
str r2, [r4, #0xc0]
233
bic r5, r5, #0x00800000
234
str r5, [r4, #0x80]
235
ldr r5, [r4, #0x80] @ flush out enable (@@@)
236
mov r5, r5
237
238
1: msr cpsr_c, ip @ restore interrupt mode
239
ldmfd sp!, {r4, r5, pc}
240
241
/*
242
* Copy crunch state to given memory address
243
*
244
* r0 = struct thread_info pointer of target task
245
* r1 = memory address where to store crunch state
246
*
247
* this is called mainly in the creation of signal stack frames
248
*/
249
ENTRY(crunch_task_copy)
250
mrs ip, cpsr
251
orr r2, ip, #PSR_I_BIT @ disable interrupts
252
msr cpsr_c, r2
253
254
ldr r3, =crunch_owner
255
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
256
ldr r3, [r3] @ get current crunch owner
257
teq r2, r3 @ does this task own it...
258
beq 1f
259
260
@ current crunch values are in the task save area
261
msr cpsr_c, ip @ restore interrupt mode
262
mov r0, r1
263
mov r1, r2
264
mov r2, #CRUNCH_SIZE
265
b memcpy
266
267
1: @ this task owns crunch regs -- grab a copy from there
268
mov r0, #0 @ nothing to load
269
mov r3, lr @ preserve return address
270
bl crunch_save
271
msr cpsr_c, ip @ restore interrupt mode
272
mov pc, r3
273
274
/*
275
* Restore crunch state from given memory address
276
*
277
* r0 = struct thread_info pointer of target task
278
* r1 = memory address where to get crunch state from
279
*
280
* this is used to restore crunch state when unwinding a signal stack frame
281
*/
282
ENTRY(crunch_task_restore)
283
mrs ip, cpsr
284
orr r2, ip, #PSR_I_BIT @ disable interrupts
285
msr cpsr_c, r2
286
287
ldr r3, =crunch_owner
288
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
289
ldr r3, [r3] @ get current crunch owner
290
teq r2, r3 @ does this task own it...
291
beq 1f
292
293
@ this task doesn't own crunch regs -- use its save area
294
msr cpsr_c, ip @ restore interrupt mode
295
mov r0, r2
296
mov r2, #CRUNCH_SIZE
297
b memcpy
298
299
1: @ this task owns crunch regs -- load them directly
300
mov r0, r1
301
mov r1, #0 @ nothing to save
302
mov r3, lr @ preserve return address
303
bl crunch_load
304
msr cpsr_c, ip @ restore interrupt mode
305
mov pc, r3
306
307