Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/frv/kernel/switch_to.S
10817 views
1
###############################################################################
2
#
3
# switch_to.S: context switch operation
4
#
5
# Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
6
# Written by David Howells ([email protected])
7
#
8
# This program is free software; you can redistribute it and/or
9
# modify it under the terms of the GNU General Public License
10
# as published by the Free Software Foundation; either version
11
# 2 of the License, or (at your option) any later version.
12
#
13
###############################################################################
14
15
#include <linux/linkage.h>
16
#include <asm/thread_info.h>
17
#include <asm/processor.h>
18
#include <asm/registers.h>
19
#include <asm/spr-regs.h>
20
21
.macro LEDS val
22
setlos #~\val,gr27
23
st gr27,@(gr30,gr0)
24
membar
25
dcf @(gr30,gr0)
26
.endm
27
28
.section .sdata
29
.balign 8
30
31
# address of frame 0 (userspace) on current kernel stack
32
.globl __kernel_frame0_ptr
33
__kernel_frame0_ptr:
34
.long init_thread_union + THREAD_SIZE - FRV_FRAME0_SIZE
35
36
# address of current task
37
.globl __kernel_current_task
38
__kernel_current_task:
39
.long init_task
40
41
.section .text
42
.balign 4
43
44
###############################################################################
45
#
46
# struct task_struct *__switch_to(struct thread_struct *prev_thread,
47
# struct thread_struct *next_thread,
48
# struct task_struct *prev)
49
#
50
###############################################################################
51
.globl __switch_to
52
__switch_to:
53
# save outgoing process's context
54
sethi.p %hi(__switch_back),gr13
55
setlo %lo(__switch_back),gr13
56
movsg lr,gr12
57
58
stdi gr28,@(gr8,#__THREAD_FRAME)
59
sti sp ,@(gr8,#__THREAD_SP)
60
sti fp ,@(gr8,#__THREAD_FP)
61
stdi gr12,@(gr8,#__THREAD_LR)
62
stdi gr16,@(gr8,#__THREAD_GR(16))
63
stdi gr18,@(gr8,#__THREAD_GR(18))
64
stdi gr20,@(gr8,#__THREAD_GR(20))
65
stdi gr22,@(gr8,#__THREAD_GR(22))
66
stdi gr24,@(gr8,#__THREAD_GR(24))
67
stdi.p gr26,@(gr8,#__THREAD_GR(26))
68
69
or gr8,gr8,gr22
70
ldi.p @(gr8,#__THREAD_USER),gr8
71
call save_user_regs
72
or gr22,gr22,gr8
73
74
# retrieve the new context
75
sethi.p %hi(__kernel_frame0_ptr),gr6
76
setlo %lo(__kernel_frame0_ptr),gr6
77
movsg psr,gr4
78
79
lddi.p @(gr9,#__THREAD_FRAME),gr10
80
or gr10,gr10,gr27 ; save prev for the return value
81
82
ldi @(gr11,#4),gr19 ; get new_current->thread_info
83
84
lddi @(gr9,#__THREAD_SP),gr12
85
ldi @(gr9,#__THREAD_LR),gr14
86
ldi @(gr9,#__THREAD_PC),gr18
87
ldi.p @(gr9,#__THREAD_FRAME0),gr7
88
89
# actually switch kernel contexts with ordinary exceptions disabled
90
andi gr4,#~PSR_ET,gr5
91
movgs gr5,psr
92
93
or.p gr10,gr0,gr28 ; set __frame
94
or gr11,gr0,gr29 ; set __current
95
or.p gr12,gr0,sp
96
or gr13,gr0,fp
97
or gr19,gr0,gr15 ; set __current_thread_info
98
99
sti gr7,@(gr6,#0) ; set __kernel_frame0_ptr
100
sti gr29,@(gr6,#4) ; set __kernel_current_task
101
102
movgs gr14,lr
103
bar
104
105
# jump to __switch_back or ret_from_fork as appropriate
106
# - move prev to GR8
107
movgs gr4,psr
108
jmpl.p @(gr18,gr0)
109
or gr27,gr27,gr8
110
111
###############################################################################
112
#
113
# restore incoming process's context
114
# - on entry:
115
# - SP, FP, LR, GR15, GR28 and GR29 will have been set up appropriately
116
# - GR8 will point to the outgoing task_struct
117
# - GR9 will point to the incoming thread_struct
118
#
119
###############################################################################
120
__switch_back:
121
lddi @(gr9,#__THREAD_GR(16)),gr16
122
lddi @(gr9,#__THREAD_GR(18)),gr18
123
lddi @(gr9,#__THREAD_GR(20)),gr20
124
lddi @(gr9,#__THREAD_GR(22)),gr22
125
lddi @(gr9,#__THREAD_GR(24)),gr24
126
lddi @(gr9,#__THREAD_GR(26)),gr26
127
128
# fall through into restore_user_regs()
129
ldi.p @(gr9,#__THREAD_USER),gr8
130
or gr8,gr8,gr9
131
132
###############################################################################
133
#
134
# restore extra general regs and FP/Media regs
135
# - void *restore_user_regs(const struct user_context *target, void *retval)
136
# - on entry:
137
# - GR8 will point to the user context to swap in
138
# - GR9 will contain the value to be returned in GR8 (prev task on context switch)
139
#
140
###############################################################################
141
.globl restore_user_regs
142
restore_user_regs:
143
movsg hsr0,gr6
144
ori gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
145
movgs gr6,hsr0
146
movsg hsr0,gr6
147
148
movsg psr,gr7
149
ori gr7,#PSR_EF|PSR_EM,gr7
150
movgs gr7,psr
151
movsg psr,gr7
152
srli gr7,#24,gr7
153
bar
154
155
lddi @(gr8,#__FPMEDIA_MSR(0)),gr4
156
157
movgs gr4,msr0
158
movgs gr5,msr1
159
160
lddfi @(gr8,#__FPMEDIA_ACC(0)),fr16
161
lddfi @(gr8,#__FPMEDIA_ACC(2)),fr18
162
ldbfi @(gr8,#__FPMEDIA_ACCG(0)),fr20
163
ldbfi @(gr8,#__FPMEDIA_ACCG(1)),fr21
164
ldbfi @(gr8,#__FPMEDIA_ACCG(2)),fr22
165
ldbfi @(gr8,#__FPMEDIA_ACCG(3)),fr23
166
167
mwtacc fr16,acc0
168
mwtacc fr17,acc1
169
mwtacc fr18,acc2
170
mwtacc fr19,acc3
171
mwtaccg fr20,accg0
172
mwtaccg fr21,accg1
173
mwtaccg fr22,accg2
174
mwtaccg fr23,accg3
175
176
# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
177
subicc.p gr7,#0x50,gr0,icc0
178
subicc gr7,#0x31,gr0,icc1
179
beq icc0,#0,__restore_acc_fr451
180
beq icc1,#0,__restore_acc_fr555
181
__restore_acc_cont:
182
183
# some CPU's have GR32-GR63
184
setlos #HSR0_FRHE,gr4
185
andcc gr6,gr4,gr0,icc0
186
beq icc0,#1,__restore_skip_gr32_gr63
187
188
lddi @(gr8,#__INT_GR(32)),gr32
189
lddi @(gr8,#__INT_GR(34)),gr34
190
lddi @(gr8,#__INT_GR(36)),gr36
191
lddi @(gr8,#__INT_GR(38)),gr38
192
lddi @(gr8,#__INT_GR(40)),gr40
193
lddi @(gr8,#__INT_GR(42)),gr42
194
lddi @(gr8,#__INT_GR(44)),gr44
195
lddi @(gr8,#__INT_GR(46)),gr46
196
lddi @(gr8,#__INT_GR(48)),gr48
197
lddi @(gr8,#__INT_GR(50)),gr50
198
lddi @(gr8,#__INT_GR(52)),gr52
199
lddi @(gr8,#__INT_GR(54)),gr54
200
lddi @(gr8,#__INT_GR(56)),gr56
201
lddi @(gr8,#__INT_GR(58)),gr58
202
lddi @(gr8,#__INT_GR(60)),gr60
203
lddi @(gr8,#__INT_GR(62)),gr62
204
__restore_skip_gr32_gr63:
205
206
# all CPU's have FR0-FR31
207
lddfi @(gr8,#__FPMEDIA_FR( 0)),fr0
208
lddfi @(gr8,#__FPMEDIA_FR( 2)),fr2
209
lddfi @(gr8,#__FPMEDIA_FR( 4)),fr4
210
lddfi @(gr8,#__FPMEDIA_FR( 6)),fr6
211
lddfi @(gr8,#__FPMEDIA_FR( 8)),fr8
212
lddfi @(gr8,#__FPMEDIA_FR(10)),fr10
213
lddfi @(gr8,#__FPMEDIA_FR(12)),fr12
214
lddfi @(gr8,#__FPMEDIA_FR(14)),fr14
215
lddfi @(gr8,#__FPMEDIA_FR(16)),fr16
216
lddfi @(gr8,#__FPMEDIA_FR(18)),fr18
217
lddfi @(gr8,#__FPMEDIA_FR(20)),fr20
218
lddfi @(gr8,#__FPMEDIA_FR(22)),fr22
219
lddfi @(gr8,#__FPMEDIA_FR(24)),fr24
220
lddfi @(gr8,#__FPMEDIA_FR(26)),fr26
221
lddfi @(gr8,#__FPMEDIA_FR(28)),fr28
222
lddfi.p @(gr8,#__FPMEDIA_FR(30)),fr30
223
224
# some CPU's have FR32-FR63
225
setlos #HSR0_FRHE,gr4
226
andcc gr6,gr4,gr0,icc0
227
beq icc0,#1,__restore_skip_fr32_fr63
228
229
lddfi @(gr8,#__FPMEDIA_FR(32)),fr32
230
lddfi @(gr8,#__FPMEDIA_FR(34)),fr34
231
lddfi @(gr8,#__FPMEDIA_FR(36)),fr36
232
lddfi @(gr8,#__FPMEDIA_FR(38)),fr38
233
lddfi @(gr8,#__FPMEDIA_FR(40)),fr40
234
lddfi @(gr8,#__FPMEDIA_FR(42)),fr42
235
lddfi @(gr8,#__FPMEDIA_FR(44)),fr44
236
lddfi @(gr8,#__FPMEDIA_FR(46)),fr46
237
lddfi @(gr8,#__FPMEDIA_FR(48)),fr48
238
lddfi @(gr8,#__FPMEDIA_FR(50)),fr50
239
lddfi @(gr8,#__FPMEDIA_FR(52)),fr52
240
lddfi @(gr8,#__FPMEDIA_FR(54)),fr54
241
lddfi @(gr8,#__FPMEDIA_FR(56)),fr56
242
lddfi @(gr8,#__FPMEDIA_FR(58)),fr58
243
lddfi @(gr8,#__FPMEDIA_FR(60)),fr60
244
lddfi @(gr8,#__FPMEDIA_FR(62)),fr62
245
__restore_skip_fr32_fr63:
246
247
lddi @(gr8,#__FPMEDIA_FNER(0)),gr4
248
movsg fner0,gr4
249
movsg fner1,gr5
250
or.p gr9,gr9,gr8
251
bralr
252
253
# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
254
__restore_acc_fr451:
255
lddfi @(gr8,#__FPMEDIA_ACC(4)),fr16
256
lddfi @(gr8,#__FPMEDIA_ACC(6)),fr18
257
ldbfi @(gr8,#__FPMEDIA_ACCG(4)),fr20
258
ldbfi @(gr8,#__FPMEDIA_ACCG(5)),fr21
259
ldbfi @(gr8,#__FPMEDIA_ACCG(6)),fr22
260
ldbfi @(gr8,#__FPMEDIA_ACCG(7)),fr23
261
262
mwtacc fr16,acc8
263
mwtacc fr17,acc9
264
mwtacc fr18,acc10
265
mwtacc fr19,acc11
266
mwtaccg fr20,accg8
267
mwtaccg fr21,accg9
268
mwtaccg fr22,accg10
269
mwtaccg fr23,accg11
270
bra __restore_acc_cont
271
272
# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
273
__restore_acc_fr555:
274
lddfi @(gr8,#__FPMEDIA_ACC(4)),fr16
275
lddfi @(gr8,#__FPMEDIA_ACC(6)),fr18
276
ldbfi @(gr8,#__FPMEDIA_ACCG(4)),fr20
277
ldbfi @(gr8,#__FPMEDIA_ACCG(5)),fr21
278
ldbfi @(gr8,#__FPMEDIA_ACCG(6)),fr22
279
ldbfi @(gr8,#__FPMEDIA_ACCG(7)),fr23
280
281
mnop.p
282
mwtacc fr16,acc4
283
mnop.p
284
mwtacc fr17,acc5
285
mnop.p
286
mwtacc fr18,acc6
287
mnop.p
288
mwtacc fr19,acc7
289
mnop.p
290
mwtaccg fr20,accg4
291
mnop.p
292
mwtaccg fr21,accg5
293
mnop.p
294
mwtaccg fr22,accg6
295
mnop.p
296
mwtaccg fr23,accg7
297
298
ldi @(gr8,#__FPMEDIA_FSR(0)),gr4
299
movgs gr4,fsr0
300
301
bra __restore_acc_cont
302
303
304
###############################################################################
305
#
306
# save extra general regs and FP/Media regs
307
# - void save_user_regs(struct user_context *target)
308
#
309
###############################################################################
310
.globl save_user_regs
311
save_user_regs:
312
movsg hsr0,gr6
313
ori gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
314
movgs gr6,hsr0
315
movsg hsr0,gr6
316
317
movsg psr,gr7
318
ori gr7,#PSR_EF|PSR_EM,gr7
319
movgs gr7,psr
320
movsg psr,gr7
321
srli gr7,#24,gr7
322
bar
323
324
movsg fner0,gr4
325
movsg fner1,gr5
326
stdi.p gr4,@(gr8,#__FPMEDIA_FNER(0))
327
328
# some CPU's have GR32-GR63
329
setlos #HSR0_GRHE,gr4
330
andcc gr6,gr4,gr0,icc0
331
beq icc0,#1,__save_skip_gr32_gr63
332
333
stdi gr32,@(gr8,#__INT_GR(32))
334
stdi gr34,@(gr8,#__INT_GR(34))
335
stdi gr36,@(gr8,#__INT_GR(36))
336
stdi gr38,@(gr8,#__INT_GR(38))
337
stdi gr40,@(gr8,#__INT_GR(40))
338
stdi gr42,@(gr8,#__INT_GR(42))
339
stdi gr44,@(gr8,#__INT_GR(44))
340
stdi gr46,@(gr8,#__INT_GR(46))
341
stdi gr48,@(gr8,#__INT_GR(48))
342
stdi gr50,@(gr8,#__INT_GR(50))
343
stdi gr52,@(gr8,#__INT_GR(52))
344
stdi gr54,@(gr8,#__INT_GR(54))
345
stdi gr56,@(gr8,#__INT_GR(56))
346
stdi gr58,@(gr8,#__INT_GR(58))
347
stdi gr60,@(gr8,#__INT_GR(60))
348
stdi gr62,@(gr8,#__INT_GR(62))
349
__save_skip_gr32_gr63:
350
351
# all CPU's have FR0-FR31
352
stdfi fr0 ,@(gr8,#__FPMEDIA_FR( 0))
353
stdfi fr2 ,@(gr8,#__FPMEDIA_FR( 2))
354
stdfi fr4 ,@(gr8,#__FPMEDIA_FR( 4))
355
stdfi fr6 ,@(gr8,#__FPMEDIA_FR( 6))
356
stdfi fr8 ,@(gr8,#__FPMEDIA_FR( 8))
357
stdfi fr10,@(gr8,#__FPMEDIA_FR(10))
358
stdfi fr12,@(gr8,#__FPMEDIA_FR(12))
359
stdfi fr14,@(gr8,#__FPMEDIA_FR(14))
360
stdfi fr16,@(gr8,#__FPMEDIA_FR(16))
361
stdfi fr18,@(gr8,#__FPMEDIA_FR(18))
362
stdfi fr20,@(gr8,#__FPMEDIA_FR(20))
363
stdfi fr22,@(gr8,#__FPMEDIA_FR(22))
364
stdfi fr24,@(gr8,#__FPMEDIA_FR(24))
365
stdfi fr26,@(gr8,#__FPMEDIA_FR(26))
366
stdfi fr28,@(gr8,#__FPMEDIA_FR(28))
367
stdfi.p fr30,@(gr8,#__FPMEDIA_FR(30))
368
369
# some CPU's have FR32-FR63
370
setlos #HSR0_FRHE,gr4
371
andcc gr6,gr4,gr0,icc0
372
beq icc0,#1,__save_skip_fr32_fr63
373
374
stdfi fr32,@(gr8,#__FPMEDIA_FR(32))
375
stdfi fr34,@(gr8,#__FPMEDIA_FR(34))
376
stdfi fr36,@(gr8,#__FPMEDIA_FR(36))
377
stdfi fr38,@(gr8,#__FPMEDIA_FR(38))
378
stdfi fr40,@(gr8,#__FPMEDIA_FR(40))
379
stdfi fr42,@(gr8,#__FPMEDIA_FR(42))
380
stdfi fr44,@(gr8,#__FPMEDIA_FR(44))
381
stdfi fr46,@(gr8,#__FPMEDIA_FR(46))
382
stdfi fr48,@(gr8,#__FPMEDIA_FR(48))
383
stdfi fr50,@(gr8,#__FPMEDIA_FR(50))
384
stdfi fr52,@(gr8,#__FPMEDIA_FR(52))
385
stdfi fr54,@(gr8,#__FPMEDIA_FR(54))
386
stdfi fr56,@(gr8,#__FPMEDIA_FR(56))
387
stdfi fr58,@(gr8,#__FPMEDIA_FR(58))
388
stdfi fr60,@(gr8,#__FPMEDIA_FR(60))
389
stdfi fr62,@(gr8,#__FPMEDIA_FR(62))
390
__save_skip_fr32_fr63:
391
392
mrdacc acc0 ,fr4
393
mrdacc acc1 ,fr5
394
395
stdfi.p fr4 ,@(gr8,#__FPMEDIA_ACC(0))
396
397
mrdacc acc2 ,fr6
398
mrdacc acc3 ,fr7
399
400
stdfi.p fr6 ,@(gr8,#__FPMEDIA_ACC(2))
401
402
mrdaccg accg0,fr4
403
stbfi.p fr4 ,@(gr8,#__FPMEDIA_ACCG(0))
404
405
mrdaccg accg1,fr5
406
stbfi.p fr5 ,@(gr8,#__FPMEDIA_ACCG(1))
407
408
mrdaccg accg2,fr6
409
stbfi.p fr6 ,@(gr8,#__FPMEDIA_ACCG(2))
410
411
mrdaccg accg3,fr7
412
stbfi fr7 ,@(gr8,#__FPMEDIA_ACCG(3))
413
414
movsg msr0 ,gr4
415
movsg msr1 ,gr5
416
417
stdi gr4 ,@(gr8,#__FPMEDIA_MSR(0))
418
419
# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
420
subicc.p gr7,#0x50,gr0,icc0
421
subicc gr7,#0x31,gr0,icc1
422
beq icc0,#0,__save_acc_fr451
423
beq icc1,#0,__save_acc_fr555
424
__save_acc_cont:
425
426
lddfi @(gr8,#__FPMEDIA_FR(4)),fr4
427
lddfi.p @(gr8,#__FPMEDIA_FR(6)),fr6
428
bralr
429
430
# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
431
__save_acc_fr451:
432
mrdacc acc8 ,fr4
433
mrdacc acc9 ,fr5
434
435
stdfi.p fr4 ,@(gr8,#__FPMEDIA_ACC(4))
436
437
mrdacc acc10,fr6
438
mrdacc acc11,fr7
439
440
stdfi.p fr6 ,@(gr8,#__FPMEDIA_ACC(6))
441
442
mrdaccg accg8,fr4
443
stbfi.p fr4 ,@(gr8,#__FPMEDIA_ACCG(4))
444
445
mrdaccg accg9,fr5
446
stbfi.p fr5 ,@(gr8,#__FPMEDIA_ACCG(5))
447
448
mrdaccg accg10,fr6
449
stbfi.p fr6 ,@(gr8,#__FPMEDIA_ACCG(6))
450
451
mrdaccg accg11,fr7
452
stbfi fr7 ,@(gr8,#__FPMEDIA_ACCG(7))
453
bra __save_acc_cont
454
455
# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
456
__save_acc_fr555:
457
mnop.p
458
mrdacc acc4 ,fr4
459
mnop.p
460
mrdacc acc5 ,fr5
461
462
stdfi fr4 ,@(gr8,#__FPMEDIA_ACC(4))
463
464
mnop.p
465
mrdacc acc6 ,fr6
466
mnop.p
467
mrdacc acc7 ,fr7
468
469
stdfi fr6 ,@(gr8,#__FPMEDIA_ACC(6))
470
471
mnop.p
472
mrdaccg accg4,fr4
473
stbfi fr4 ,@(gr8,#__FPMEDIA_ACCG(4))
474
475
mnop.p
476
mrdaccg accg5,fr5
477
stbfi fr5 ,@(gr8,#__FPMEDIA_ACCG(5))
478
479
mnop.p
480
mrdaccg accg6,fr6
481
stbfi fr6 ,@(gr8,#__FPMEDIA_ACCG(6))
482
483
mnop.p
484
mrdaccg accg7,fr7
485
stbfi fr7 ,@(gr8,#__FPMEDIA_ACCG(7))
486
487
movsg fsr0 ,gr4
488
sti gr4 ,@(gr8,#__FPMEDIA_FSR(0))
489
bra __save_acc_cont
490
491