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