Linux Audio

Check our new training course

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