swtch.S revision 82909
1/*-
2 * Copyright (c) 2001 Jake Burkholder.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/sparc64/sparc64/swtch.S 82909 2001-09-03 23:18:02Z jake $
27 */
28
29#include <machine/asmacros.h>
30#include <machine/asi.h>
31#include <machine/ktr.h>
32#include <machine/tstate.h>
33
34#include "assym.s"
35
36/*
37 * Save and restore FPU state. This is done at switch time.
38 * We could use FPRS_DL and FPRS_DU; however, it is accessible to non-privileged
39 * software, so it is avoided for compatabilities sake.
40 * savefp clobbers %fprs.
41 */
42	.macro	savefp	state, tmp, fprs
43	or	\fprs, FPRS_FEF, \tmp
44	wr	\tmp, 0, %fprs
45	stx	%fsr, [\state + FP_FSR]
46	rd	%asi, \tmp
47	wr	%g0, ASI_BLK_S, %asi
48	stda	%f0, [\state + FP_FB0] %asi
49	stda	%f16, [\state + FP_FB1] %asi
50	stda	%f32, [\state + FP_FB2] %asi
51	stda	%f48, [\state + FP_FB3] %asi
52	wr	\tmp, 0, %asi
53	membar	#Sync
54	.endm
55
56	.macro	restrfp	state, tmp
57	rd	%fprs, \tmp
58	or	\tmp, FPRS_FEF, \tmp
59	wr	\tmp, 0, %fprs
60	rd	%asi, \tmp
61	wr	%g0, ASI_BLK_S, %asi
62	ldda	[\state + FP_FB0] %asi, %f0
63	ldda	[\state + FP_FB1] %asi, %f16
64	ldda	[\state + FP_FB2] %asi, %f32
65	ldda	[\state + FP_FB3] %asi, %f48
66	wr	\tmp, 0, %asi
67	membar	#Sync
68	ldx	[\state + FP_FSR], %fsr
69	.endm
70
71ENTRY(cpu_throw)
72	save	%sp, -CCFSZ, %sp
73	call	chooseproc
74	 ldx	[PCPU(CURPROC)], %l0
75	flushw
76	b,a	.Lsw1
77END(cpu_throw)
78
79ENTRY(cpu_switch)
80	/*
81	 * Choose a new process.  If its the same as the current one, do
82	 * nothing.
83	 */
84	save	%sp, -CCFSZ, %sp
85	call	chooseproc
86	 ldx	[PCPU(CURPROC)], %l0
87#if KTR_COMPILE & KTR_CT1
88	CATR(KTR_CT1, "cpu_switch: from=%p (%s) to=%p (%s)"
89	    , %g1, %g2, %g3, 7, 8, 9)
90	stx	%l0, [%g1 + KTR_PARM1]
91	add	%l0, P_COMM, %g2
92	stx	%g2, [%g1 + KTR_PARM2]
93	stx	%o0, [%g1 + KTR_PARM3]
94	add	%o0, P_COMM, %g2
95	stx	%g2, [%g1 + KTR_PARM4]
969:
97#endif
98	cmp	%l0, %o0
99	be,pn	%xcc, 3f
100	 EMPTY
101
102	/*
103	 * Always save %fprs and %y. Both are not used within the kernel
104	 * and are therefore not saved in the trap frame.
105	 * If the process was using floating point, save its context.
106	 */
107	 ldx	[%l0 + P_FRAME], %l1
108	ldx	[PCPU(CURPCB)], %l2
109	rd	%y, %l3
110	stx	%l3, [%l2 + PCB_Y]
111	rd	%fprs, %l3
112	stx	%l3, [%l2 + PCB_FPSTATE + FP_FPRS]
113	ldx	[%l1 + TF_TSTATE], %l1
114	andcc	%l1, TSTATE_PEF, %l1
115	be,pt	%xcc, 1f
116	 nop
117	savefp	%l2 + PCB_FPSTATE, %l4, %l3
118
119	/*
120	 * Flush the windows out to the stack and save the current frame
121	 * pointer and program counter.
122	 */
1231:	flushw
124	wrpr	%g0, 0, %cleanwin
125	rdpr	%cwp, %l3
126	stx	%l3, [%l2 + PCB_CWP]
127	stx	%fp, [%l2 + PCB_FP]
128	stx	%i7, [%l2 + PCB_PC]
129
130	/*
131	 * Load the new process's frame pointer and program counter, and set
132	 * the current process and pcb.
133	 */
134.Lsw1:	ldx	[%o0 + P_ADDR], %o1
135#if KTR_COMPILE & KTR_CT1
136	CATR(KTR_CT1, "cpu_switch: to=%p pc=%#lx fp=%#lx sp=%#lx cwp=%#lx"
137	    , %g1, %g2, %g3, 7, 8, 9)
138	stx	%o0, [%g1 + KTR_PARM1]
139	ldx	[%o1 + U_PCB + PCB_PC], %g2
140	stx	%g2, [%g1 + KTR_PARM2]
141	ldx	[%o1 + U_PCB + PCB_FP], %g2
142	stx	%g2, [%g1 + KTR_PARM3]
143	sub	%g2, CCFSZ, %g2
144	stx	%g2, [%g1 + KTR_PARM4]
145	ldx	[%o1 + U_PCB + PCB_CWP], %g2
146	stx	%g2, [%g1 + KTR_PARM5]
1479:
148#endif
149#if 1
150	mov	%o0, %g4
151	mov	%l0, %g5
152	ldx	[%o1 + U_PCB + PCB_CWP], %o2
153	wrpr	%o2, %cwp
154	mov	%g4, %o0
155	mov	%g5, %l0
156#endif
157	ldx	[%o0 + P_ADDR], %o1
158	ldx	[%o1 + U_PCB + PCB_FP], %fp
159	ldx	[%o1 + U_PCB + PCB_PC], %i7
160	sub	%fp, CCFSZ, %sp
161	stx	%o0, [PCPU(CURPROC)]
162	stx	%o1, [PCPU(CURPCB)]
163
164	/*
165	 * Point to the new process's vmspace and load its vm context number.
166	 * If its nucleus context we are done.
167	 */
168	ldx	[%o0 + P_VMSPACE], %o2
169	lduw	[%o2 + VM_PMAP + PM_CONTEXT], %o3
170#if KTR_COMPILE & KTR_CT1
171	CATR(KTR_CT1, "cpu_switch: to=%p vm=%p context=%#x"
172	    , %g1, %g2, %g3, 7, 8, 9)
173	stx	%o0, [%g1 + KTR_PARM1]
174	stx	%o2, [%g1 + KTR_PARM2]
175	stx	%o3, [%g1 + KTR_PARM3]
1769:
177#endif
178	brz,pn	%o3, 3f
179	 EMPTY
180
181	/*
182	 * If the new process was using floating point, restore its context.
183	 * Always restore %fprs and %y.
184	 */
185	 ldx	[%o0 + P_FRAME], %o4
186	ldx	[%o4 + TF_TSTATE], %o4
187	andcc	%o4, TSTATE_PEF, %o4
188	be,pt	%xcc, 2f
189	 nop
190	restrfp	%o1 + U_PCB + PCB_FPSTATE, %o4
191
1922:	ldx	[%o1 + PCB_FPSTATE + FP_FPRS], %o4
193	wr	%o4, 0, %fprs
194	ldx	[%o1 + PCB_Y], %o4
195	wr	%o4, 0, %y
196
197	/*
198	 * Point to the current process's vmspace and load the hardware
199	 * context number.  If its the same as the new process, we are
200	 * done.
201	 */
202	ldx	[%l0 + P_VMSPACE], %l1
203	lduw	[%l1 + VM_PMAP + PM_CONTEXT], %l3
204#if KTR_COMPILE & KTR_CT1
205	CATR(KTR_CT1, "cpu_switch: from=%p vm=%p context=%#x"
206	    , %g1, %g2, %g3, 7, 8, 9)
207	stx	%l0, [%g1 + KTR_PARM1]
208	stx	%l1, [%g1 + KTR_PARM2]
209	stx	%l3, [%g1 + KTR_PARM3]
2109:
211#endif
212	cmp	%l3, %o3
213	be,pn	%xcc, 3f
214	 EMPTY
215
216	/*
217	 * Install the new primary context.
218	 */
219	mov	AA_DMMU_PCXR, %o1
220	stxa	%o3, [%o1] ASI_DMMU
221	flush	%o0
222
223	/*
224	 * Map the primary user tsb.
225	 */
226	setx	TSB_USER_MIN_ADDRESS, %o1, %o0
227	mov	AA_DMMU_TAR, %o1
228	stxa	%o0, [%o1] ASI_DMMU
229	mov	TLB_DAR_TSB_USER_PRIMARY, %o1
230	ldx	[%o2 + VM_PMAP + PM_STTE + TTE_DATA], %o3
231	stxa	%o3, [%o1] ASI_DTLB_DATA_ACCESS_REG
232	membar	#Sync
233
234	/*
235	 * If the primary tsb page hasn't been initialized, initialize it
236	 * and update the bit in the tte.
237	 */
238	andcc	%o3, TD_INIT, %g0
239	bnz	%xcc, 3f
240	 or	%o3, TD_INIT, %o3
241	stx	%o3, [%o2 + VM_PMAP + PM_STTE + TTE_DATA]
242	call	tsb_page_init
243	 clr	%o1
244
245	/*
246	 * Done.  Return and load the new process's window from the stack.
247	 */
2483:
249#if KTR_COMPILE & KTR_CT1
250	CATR(KTR_CT1, "cpu_switch: return p=%p (%s)"
251	    , %g1, %g2, %g3, 7, 8, 9)
252	ldx	[PCPU(CURPROC)], %g2
253	stx	%g2, [%g1 + KTR_PARM1]
254	add	%g2, P_COMM, %g3
255	stx	%g3, [%g1 + KTR_PARM2]
2569:
257#endif
258	ret
259	 restore
260END(cpu_switch)
261
262ENTRY(savectx)
263	save	%sp, -CCFSZ, %sp
264	flushw
265	rd	%y, %l0
266	stx	%l0, [%i0 + PCB_Y]
267	rd	%fprs, %l0
268	stx	%l0, [%i0 + PCB_FPSTATE + FP_FPRS]
269	ldx	[PCPU(CURPROC)], %l0
270	ldx	[%l0 + P_FRAME], %l0
271	ldx	[%l0 + TF_TSTATE], %l0
272	andcc	%l0, TSTATE_PEF, %l0
273	be,pt	%xcc, 1f
274	 stx	%fp, [%i0 + PCB_FP]
275	add	%i0, PCB_FPSTATE, %o0
276	call	savefpctx
2771:	 stx	%i7, [%i0 + PCB_PC]
278	ret
279	 restore %g0, 0, %o0
280END(savectx)
281
282/* Note: this does not save %fprs. */
283ENTRY(savefpctx)
284	rd	%fprs, %o2
285	savefp	%o0, %o1, %o2
286	retl
287	 wr	%o2, 0, %fprs
288END(savefpctx)
289
290ENTRY(restorefpctx)
291	restrfp	%o0, %o1
292	ldx	[%o0 + FP_FPRS], %o1
293	retl
294	 wr	%o1, 0, %fprs
295END(restorefpctx)
296