• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/sh/kernel/cpu/sh5/
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