Linux Audio

Check our new training course

Loading...
v3.1
  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
 21sh64_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
v5.4
  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