Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/sh/kernel/cpu/sh5/switchto.S
17372 views
1
/*
2
* arch/sh/kernel/cpu/sh5/switchto.S
3
*
4
* sh64 context switch
5
*
6
* Copyright (C) 2004 Richard Curnow
7
*
8
* This file is subject to the terms and conditions of the GNU General Public
9
* License. See the file "COPYING" in the main directory of this archive
10
* for more details.
11
*/
12
13
.section .text..SHmedia32,"ax"
14
.little
15
16
.balign 32
17
18
.type sh64_switch_to,@function
19
.global sh64_switch_to
20
.global __sh64_switch_to_end
21
sh64_switch_to:
22
23
/* Incoming args
24
r2 - prev
25
r3 - &prev->thread
26
r4 - next
27
r5 - &next->thread
28
29
Outgoing results
30
r2 - last (=prev) : this just stays in r2 throughout
31
32
Want to create a full (struct pt_regs) on the stack to allow backtracing
33
functions to work. However, we only need to populate the callee-save
34
register slots in this structure; since we're a function our ancestors must
35
have themselves preserved all caller saved state in the stack. This saves
36
some wasted effort since we won't need to look at the values.
37
38
In particular, all caller-save registers are immediately available for
39
scratch use.
40
41
*/
42
43
#define FRAME_SIZE (76*8 + 8)
44
45
movi FRAME_SIZE, r0
46
sub.l r15, r0, r15
47
! Do normal-style register save to support backtrace
48
49
st.l r15, 0, r18 ! save link reg
50
st.l r15, 4, r14 ! save fp
51
add.l r15, r63, r14 ! setup frame pointer
52
53
! hopefully this looks normal to the backtrace now.
54
55
addi.l r15, 8, r1 ! base of pt_regs
56
addi.l r1, 24, r0 ! base of pt_regs.regs
57
addi.l r0, (63*8), r8 ! base of pt_regs.trregs
58
59
/* Note : to be fixed?
60
struct pt_regs is really designed for holding the state on entry
61
to an exception, i.e. pc,sr,regs etc. However, for the context
62
switch state, some of this is not required. But the unwinder takes
63
struct pt_regs * as an arg so we have to build this structure
64
to allow unwinding switched tasks in show_state() */
65
66
st.q r0, ( 9*8), r9
67
st.q r0, (10*8), r10
68
st.q r0, (11*8), r11
69
st.q r0, (12*8), r12
70
st.q r0, (13*8), r13
71
st.q r0, (14*8), r14 ! for unwind, want to look as though we took a trap at
72
! the point where the process is left in suspended animation, i.e. current
73
! fp here, not the saved one.
74
st.q r0, (16*8), r16
75
76
st.q r0, (24*8), r24
77
st.q r0, (25*8), r25
78
st.q r0, (26*8), r26
79
st.q r0, (27*8), r27
80
st.q r0, (28*8), r28
81
st.q r0, (29*8), r29
82
st.q r0, (30*8), r30
83
st.q r0, (31*8), r31
84
st.q r0, (32*8), r32
85
st.q r0, (33*8), r33
86
st.q r0, (34*8), r34
87
st.q r0, (35*8), r35
88
89
st.q r0, (44*8), r44
90
st.q r0, (45*8), r45
91
st.q r0, (46*8), r46
92
st.q r0, (47*8), r47
93
st.q r0, (48*8), r48
94
st.q r0, (49*8), r49
95
st.q r0, (50*8), r50
96
st.q r0, (51*8), r51
97
st.q r0, (52*8), r52
98
st.q r0, (53*8), r53
99
st.q r0, (54*8), r54
100
st.q r0, (55*8), r55
101
st.q r0, (56*8), r56
102
st.q r0, (57*8), r57
103
st.q r0, (58*8), r58
104
st.q r0, (59*8), r59
105
106
! do this early as pta->gettr has no pipeline forwarding (=> 5 cycle latency)
107
! Use a local label to avoid creating a symbol that will confuse the !
108
! backtrace
109
pta .Lsave_pc, tr0
110
111
gettr tr5, r45
112
gettr tr6, r46
113
gettr tr7, r47
114
st.q r8, (5*8), r45
115
st.q r8, (6*8), r46
116
st.q r8, (7*8), r47
117
118
! Now switch context
119
gettr tr0, r9
120
st.l r3, 0, r15 ! prev->thread.sp
121
st.l r3, 8, r1 ! prev->thread.kregs
122
st.l r3, 4, r9 ! prev->thread.pc
123
st.q r1, 0, r9 ! save prev->thread.pc into pt_regs->pc
124
125
! Load PC for next task (init value or save_pc later)
126
ld.l r5, 4, r18 ! next->thread.pc
127
! Switch stacks
128
ld.l r5, 0, r15 ! next->thread.sp
129
ptabs r18, tr0
130
131
! Update current
132
ld.l r4, 4, r9 ! next->thread_info (2nd element of next task_struct)
133
putcon r9, kcr0 ! current = next->thread_info
134
135
! go to save_pc for a reschedule, or the initial thread.pc for a new process
136
blink tr0, r63
137
138
! Restore (when we come back to a previously saved task)
139
.Lsave_pc:
140
addi.l r15, 32, r0 ! r0 = next's regs
141
addi.l r0, (63*8), r8 ! r8 = next's tr_regs
142
143
ld.q r8, (5*8), r45
144
ld.q r8, (6*8), r46
145
ld.q r8, (7*8), r47
146
ptabs r45, tr5
147
ptabs r46, tr6
148
ptabs r47, tr7
149
150
ld.q r0, ( 9*8), r9
151
ld.q r0, (10*8), r10
152
ld.q r0, (11*8), r11
153
ld.q r0, (12*8), r12
154
ld.q r0, (13*8), r13
155
ld.q r0, (14*8), r14
156
ld.q r0, (16*8), r16
157
158
ld.q r0, (24*8), r24
159
ld.q r0, (25*8), r25
160
ld.q r0, (26*8), r26
161
ld.q r0, (27*8), r27
162
ld.q r0, (28*8), r28
163
ld.q r0, (29*8), r29
164
ld.q r0, (30*8), r30
165
ld.q r0, (31*8), r31
166
ld.q r0, (32*8), r32
167
ld.q r0, (33*8), r33
168
ld.q r0, (34*8), r34
169
ld.q r0, (35*8), r35
170
171
ld.q r0, (44*8), r44
172
ld.q r0, (45*8), r45
173
ld.q r0, (46*8), r46
174
ld.q r0, (47*8), r47
175
ld.q r0, (48*8), r48
176
ld.q r0, (49*8), r49
177
ld.q r0, (50*8), r50
178
ld.q r0, (51*8), r51
179
ld.q r0, (52*8), r52
180
ld.q r0, (53*8), r53
181
ld.q r0, (54*8), r54
182
ld.q r0, (55*8), r55
183
ld.q r0, (56*8), r56
184
ld.q r0, (57*8), r57
185
ld.q r0, (58*8), r58
186
ld.q r0, (59*8), r59
187
188
! epilogue
189
ld.l r15, 0, r18
190
ld.l r15, 4, r14
191
ptabs r18, tr0
192
movi FRAME_SIZE, r0
193
add r15, r0, r15
194
blink tr0, r63
195
__sh64_switch_to_end:
196
.LFE1:
197
.size sh64_switch_to,.LFE1-sh64_switch_to
198
199
200