177957Sbenno/* $FreeBSD$ */
277957Sbenno/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */
377957Sbenno
4139825Simp/*-
577957Sbenno * Copyright (C) 2001 Benno Rice
677957Sbenno * All rights reserved.
777957Sbenno *
877957Sbenno * Redistribution and use in source and binary forms, with or without
977957Sbenno * modification, are permitted provided that the following conditions
1077957Sbenno * are met:
1177957Sbenno * 1. Redistributions of source code must retain the above copyright
1277957Sbenno *    notice, this list of conditions and the following disclaimer.
1377957Sbenno * 2. Redistributions in binary form must reproduce the above copyright
1477957Sbenno *    notice, this list of conditions and the following disclaimer in the
1577957Sbenno *    documentation and/or other materials provided with the distribution.
1677957Sbenno *
1777957Sbenno * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
1877957Sbenno * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1977957Sbenno * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2077957Sbenno * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2177957Sbenno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2277957Sbenno * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2377957Sbenno * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2477957Sbenno * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2577957Sbenno * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2677957Sbenno * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2777957Sbenno*/
28139825Simp/*-
2977957Sbenno * Copyright (C) 1995, 1996 Wolfgang Solfrank.
3077957Sbenno * Copyright (C) 1995, 1996 TooLs GmbH.
3177957Sbenno * All rights reserved.
3277957Sbenno *
3377957Sbenno * Redistribution and use in source and binary forms, with or without
3477957Sbenno * modification, are permitted provided that the following conditions
3577957Sbenno * are met:
3677957Sbenno * 1. Redistributions of source code must retain the above copyright
3777957Sbenno *    notice, this list of conditions and the following disclaimer.
3877957Sbenno * 2. Redistributions in binary form must reproduce the above copyright
3977957Sbenno *    notice, this list of conditions and the following disclaimer in the
4077957Sbenno *    documentation and/or other materials provided with the distribution.
4177957Sbenno * 3. All advertising materials mentioning features or use of this software
4277957Sbenno *    must display the following acknowledgement:
4377957Sbenno *	This product includes software developed by TooLs GmbH.
4477957Sbenno * 4. The name of TooLs GmbH may not be used to endorse or promote products
4577957Sbenno *    derived from this software without specific prior written permission.
4677957Sbenno *
4777957Sbenno * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
4877957Sbenno * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
4977957Sbenno * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5077957Sbenno * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5177957Sbenno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
5277957Sbenno * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
5377957Sbenno * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5477957Sbenno * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
5577957Sbenno * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
5677957Sbenno * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5777957Sbenno */
5877957Sbenno
5977957Sbenno#include "assym.s"
60198723Snwhitehorn#include "opt_sched.h"
6177957Sbenno
6277957Sbenno#include <sys/syscall.h>
6377957Sbenno
6477957Sbenno#include <machine/trap.h>
6577957Sbenno#include <machine/param.h>
6677957Sbenno#include <machine/asm.h>
6777957Sbenno
6877957Sbenno/*
69178628Smarcel * void cpu_throw(struct thread *old, struct thread *new)
70178628Smarcel */
71231019SandreastENTRY(cpu_throw)
72223485Snwhitehorn	mr	%r13, %r4
73178628Smarcel	b	cpu_switchin
74178628Smarcel
75178628Smarcel/*
76172887Sgrehan * void cpu_switch(struct thread *old,
77172887Sgrehan *		   struct thread *new,
78172887Sgrehan *		   struct mutex *mtx);
79118893Sgrehan *
80118893Sgrehan * Switch to a new thread saving the current state in the old thread.
8177957Sbenno */
82231019SandreastENTRY(cpu_switch)
83209975Snwhitehorn	ld	%r6,TD_PCB(%r3)		/* Get the old thread's PCB ptr */
84209975Snwhitehorn	std	%r12,PCB_CONTEXT(%r6)	/* Save the non-volatile GP regs.
85118893Sgrehan					   These can now be used for scratch */
86209975Snwhitehorn	std	%r14,PCB_CONTEXT+2*8(%r6)
87209975Snwhitehorn	std	%r15,PCB_CONTEXT+3*8(%r6)
88209975Snwhitehorn	std	%r16,PCB_CONTEXT+4*8(%r6)
89209975Snwhitehorn	std	%r17,PCB_CONTEXT+5*8(%r6)
90209975Snwhitehorn	std	%r18,PCB_CONTEXT+6*8(%r6)
91209975Snwhitehorn	std	%r19,PCB_CONTEXT+7*8(%r6)
92209975Snwhitehorn	std	%r20,PCB_CONTEXT+8*8(%r6)
93209975Snwhitehorn	std	%r21,PCB_CONTEXT+9*8(%r6)
94209975Snwhitehorn	std	%r22,PCB_CONTEXT+10*8(%r6)
95209975Snwhitehorn	std	%r23,PCB_CONTEXT+11*8(%r6)
96209975Snwhitehorn	std	%r24,PCB_CONTEXT+12*8(%r6)
97209975Snwhitehorn	std	%r25,PCB_CONTEXT+13*8(%r6)
98209975Snwhitehorn	std	%r26,PCB_CONTEXT+14*8(%r6)
99209975Snwhitehorn	std	%r27,PCB_CONTEXT+15*8(%r6)
100209975Snwhitehorn	std	%r28,PCB_CONTEXT+16*8(%r6)
101209975Snwhitehorn	std	%r29,PCB_CONTEXT+17*8(%r6)
102209975Snwhitehorn	std	%r30,PCB_CONTEXT+18*8(%r6)
103209975Snwhitehorn	std	%r31,PCB_CONTEXT+19*8(%r6)
104118893Sgrehan
10591486Sbenno	mfcr	%r16			/* Save the condition register */
106209975Snwhitehorn	std	%r16,PCB_CR(%r6)
10791486Sbenno	mflr	%r16			/* Save the link register */
108209975Snwhitehorn	std	%r16,PCB_LR(%r6)
109209975Snwhitehorn	std	%r1,PCB_SP(%r6)		/* Save the stack pointer */
110209975Snwhitehorn	std	%r2,PCB_TOC(%r6)	/* Save the TOC pointer */
111209975Snwhitehorn
112118893Sgrehan	mr	%r14,%r3		/* Copy the old thread ptr... */
113223485Snwhitehorn	mr	%r13,%r4		/* and the new thread ptr in curthread*/
114198723Snwhitehorn	mr	%r16,%r5		/* and the new lock */
115198731Snwhitehorn	mr	%r17,%r6		/* and the PCB */
116118893Sgrehan
117209975Snwhitehorn	stdu	%r1,-48(%r1)
118209975Snwhitehorn
119198731Snwhitehorn	lwz	%r7,PCB_FLAGS(%r17)
120178628Smarcel	/* Save FPU context if needed */
121198731Snwhitehorn	andi.	%r7, %r7, PCB_FPU
12286066Smp	beq	.L1
123218824Snwhitehorn	bl	save_fpu
124209975Snwhitehorn	nop
125188860Snwhitehorn
126188860Snwhitehorn.L1:
127198731Snwhitehorn	mr	%r3,%r14		/* restore old thread ptr */
128198731Snwhitehorn	lwz	%r7,PCB_FLAGS(%r17)
129188860Snwhitehorn	/* Save Altivec context if needed */
130198731Snwhitehorn	andi.	%r7, %r7, PCB_VEC
131188860Snwhitehorn	beq	.L2
132218824Snwhitehorn	bl	save_vec
133209975Snwhitehorn	nop
134188860Snwhitehorn
135188860Snwhitehorn.L2:
136118893Sgrehan	mr	%r3,%r14		/* restore old thread ptr */
137218824Snwhitehorn	bl	pmap_deactivate	/* Deactivate the current pmap */
138209975Snwhitehorn	nop
13991486Sbenno
140209975Snwhitehorn	addi	%r1,%r1,48
141198723Snwhitehorn
142234517Snwhitehorn	sync				/* Make sure all of that finished */
143209975Snwhitehorn	std	%r16,TD_LOCK(%r14)	/* ULE:	update old thread's lock */
144209975Snwhitehorn
145178628Smarcelcpu_switchin:
146198723Snwhitehorn#if defined(SMP) && defined(SCHED_ULE)
147198723Snwhitehorn	/* Wait for the new thread to become unblocked */
148198723Snwhitehorn	lis	%r6,blocked_lock@ha
149198723Snwhitehorn	addi	%r6,%r6,blocked_lock@l
150198723Snwhitehornblocked_loop:
151223485Snwhitehorn	ld	%r7,TD_LOCK(%r13)
152209975Snwhitehorn	cmpd	%r6,%r7
153235013Snwhitehorn	beq-	blocked_loop
154235013Snwhitehorn	isync
155198723Snwhitehorn#endif
156198723Snwhitehorn
157118893Sgrehan	mfsprg	%r7,0			/* Get the pcpu pointer */
158223485Snwhitehorn	std	%r13,PC_CURTHREAD(%r7)	/* Store new current thread */
159223485Snwhitehorn	ld	%r17,TD_PCB(%r13)	/* Store new current PCB */
160209975Snwhitehorn	std	%r17,PC_CURPCB(%r7)
16177957Sbenno
162209975Snwhitehorn	stdu	%r1,-48(%r1)
163209975Snwhitehorn
164223485Snwhitehorn	mr	%r3,%r13		/* Get new thread ptr */
165218824Snwhitehorn	bl	pmap_activate		/* Activate the new address space */
166209975Snwhitehorn	nop
167183088Smarcel
168178628Smarcel	lwz	%r6, PCB_FLAGS(%r17)
169178628Smarcel	/* Restore FPU context if needed */
170118893Sgrehan	andi.	%r6, %r6, PCB_FPU
171188860Snwhitehorn	beq	.L3
172223485Snwhitehorn	mr	%r3,%r13		/* Pass curthread to enable_fpu */
173218824Snwhitehorn	bl	enable_fpu
174209975Snwhitehorn	nop
17586066Smp
176188860Snwhitehorn.L3:
177188860Snwhitehorn	lwz	%r6, PCB_FLAGS(%r17)
178188860Snwhitehorn	/* Restore Altivec context if needed */
179188860Snwhitehorn	andi.	%r6, %r6, PCB_VEC
180188860Snwhitehorn	beq	.L4
181223485Snwhitehorn	mr	%r3,%r13		/* Pass curthread to enable_vec */
182218824Snwhitehorn	bl	enable_vec
183209975Snwhitehorn	nop
184188860Snwhitehorn
18599036Sbenno	/* thread to restore is in r3 */
186188860Snwhitehorn.L4:
187209975Snwhitehorn	addi	%r1,%r1,48
188118893Sgrehan	mr	%r3,%r17		/* Recover PCB ptr */
189209975Snwhitehorn	ld	%r12,PCB_CONTEXT(%r3)	/* Load the non-volatile GP regs. */
190209975Snwhitehorn	ld	%r14,PCB_CONTEXT+2*8(%r3)
191209975Snwhitehorn	ld	%r15,PCB_CONTEXT+3*8(%r3)
192209975Snwhitehorn	ld	%r16,PCB_CONTEXT+4*8(%r3)
193209975Snwhitehorn	ld	%r17,PCB_CONTEXT+5*8(%r3)
194209975Snwhitehorn	ld	%r18,PCB_CONTEXT+6*8(%r3)
195209975Snwhitehorn	ld	%r19,PCB_CONTEXT+7*8(%r3)
196209975Snwhitehorn	ld	%r20,PCB_CONTEXT+8*8(%r3)
197209975Snwhitehorn	ld	%r21,PCB_CONTEXT+9*8(%r3)
198209975Snwhitehorn	ld	%r22,PCB_CONTEXT+10*8(%r3)
199209975Snwhitehorn	ld	%r23,PCB_CONTEXT+11*8(%r3)
200209975Snwhitehorn	ld	%r24,PCB_CONTEXT+12*8(%r3)
201209975Snwhitehorn	ld	%r25,PCB_CONTEXT+13*8(%r3)
202209975Snwhitehorn	ld	%r26,PCB_CONTEXT+14*8(%r3)
203209975Snwhitehorn	ld	%r27,PCB_CONTEXT+15*8(%r3)
204209975Snwhitehorn	ld	%r28,PCB_CONTEXT+16*8(%r3)
205209975Snwhitehorn	ld	%r29,PCB_CONTEXT+17*8(%r3)
206209975Snwhitehorn	ld	%r30,PCB_CONTEXT+18*8(%r3)
207209975Snwhitehorn	ld	%r31,PCB_CONTEXT+19*8(%r3)
208209975Snwhitehorn	ld	%r5,PCB_CR(%r3)		/* Load the condition register */
20984945Smp	mtcr	%r5
210209975Snwhitehorn	ld	%r5,PCB_LR(%r3)		/* Load the link register */
21191486Sbenno	mtlr	%r5
212209975Snwhitehorn	ld	%r1,PCB_SP(%r3)		/* Load the stack pointer */
213209975Snwhitehorn	ld	%r2,PCB_TOC(%r3)	/* Load the TOC pointer */
214209975Snwhitehorn
215214574Snwhitehorn	lis	%r5,USER_ADDR@highesta	/* Load the copyin/out segment reg */
216209975Snwhitehorn	ori	%r5,%r5,USER_ADDR@highera
217209975Snwhitehorn	sldi	%r5,%r5,32
218209975Snwhitehorn	oris	%r5,%r5,USER_ADDR@ha
219214607Snwhitehorn	isync
220209975Snwhitehorn	slbie	%r5
221214574Snwhitehorn	lis	%r6,USER_SLB_SLBE@highesta
222214574Snwhitehorn	ori	%r6,%r6,USER_SLB_SLBE@highera
223214574Snwhitehorn	sldi	%r6,%r6,32
224214574Snwhitehorn	oris	%r6,%r6,USER_SLB_SLBE@ha
225214574Snwhitehorn	ori	%r6,%r6,USER_SLB_SLBE@l
226209975Snwhitehorn	ld	%r5,PCB_AIM_USR_VSID(%r3)
227209975Snwhitehorn	slbmte	%r5,%r6
228214607Snwhitehorn	isync
229209975Snwhitehorn
230190704Smarcel	/*
231209975Snwhitehorn	 * Perform a dummy stdcx. to clear any reservations we may have
232190704Smarcel	 * inherited from the previous thread. It doesn't matter if the
233209975Snwhitehorn	 * stdcx succeeds or not. pcb_context[0] can be clobbered.
234190704Smarcel	 */
235209975Snwhitehorn	stdcx.	%r1, 0, %r3
23677957Sbenno	blr
23777957Sbenno
23877957Sbenno/*
23984945Smp * savectx(pcb)
24084945Smp * Update pcb, saving current processor state
24177957Sbenno */
242231019SandreastENTRY(savectx)
243209975Snwhitehorn	std	%r12,PCB_CONTEXT(%r3)	/* Save the non-volatile GP regs. */
244209975Snwhitehorn	std	%r13,PCB_CONTEXT+1*8(%r3)
245209975Snwhitehorn	std	%r14,PCB_CONTEXT+2*8(%r3)
246209975Snwhitehorn	std	%r15,PCB_CONTEXT+3*8(%r3)
247209975Snwhitehorn	std	%r16,PCB_CONTEXT+4*8(%r3)
248209975Snwhitehorn	std	%r17,PCB_CONTEXT+5*8(%r3)
249209975Snwhitehorn	std	%r18,PCB_CONTEXT+6*8(%r3)
250209975Snwhitehorn	std	%r19,PCB_CONTEXT+7*8(%r3)
251209975Snwhitehorn	std	%r20,PCB_CONTEXT+8*8(%r3)
252209975Snwhitehorn	std	%r21,PCB_CONTEXT+9*8(%r3)
253209975Snwhitehorn	std	%r22,PCB_CONTEXT+10*8(%r3)
254209975Snwhitehorn	std	%r23,PCB_CONTEXT+11*8(%r3)
255209975Snwhitehorn	std	%r24,PCB_CONTEXT+12*8(%r3)
256209975Snwhitehorn	std	%r25,PCB_CONTEXT+13*8(%r3)
257209975Snwhitehorn	std	%r26,PCB_CONTEXT+14*8(%r3)
258209975Snwhitehorn	std	%r27,PCB_CONTEXT+15*8(%r3)
259209975Snwhitehorn	std	%r28,PCB_CONTEXT+16*8(%r3)
260209975Snwhitehorn	std	%r29,PCB_CONTEXT+17*8(%r3)
261209975Snwhitehorn	std	%r30,PCB_CONTEXT+18*8(%r3)
262209975Snwhitehorn	std	%r31,PCB_CONTEXT+19*8(%r3)
263209975Snwhitehorn
26484945Smp	mfcr	%r4			/* Save the condition register */
265209975Snwhitehorn	std	%r4,PCB_CR(%r3)
266209975Snwhitehorn	std	%r2,PCB_TOC(%r3)	/* Save the TOC pointer */
26777957Sbenno	blr
26891467Sbenno
26991467Sbenno/*
27091467Sbenno * fork_trampoline()
27191467Sbenno * Set up the return from cpu_fork()
27291467Sbenno */
273230400Sandreast
274230400SandreastENTRY_NOPROF(fork_trampoline)
275209975Snwhitehorn	ld	%r3,CF_FUNC(%r1)
276209975Snwhitehorn	ld	%r4,CF_ARG0(%r1)
277209975Snwhitehorn	ld	%r5,CF_ARG1(%r1)
278209975Snwhitehorn
279209975Snwhitehorn	stdu	%r1,-48(%r1)
280218824Snwhitehorn	bl	fork_exit
281209975Snwhitehorn	nop
282209975Snwhitehorn	addi	%r1,%r1,48+CF_SIZE-FSP	/* Allow 8 bytes in front of
283132520Sgrehan					   trapframe to simulate FRAME_SETUP
284132520Sgrehan					   does when allocating space for
285132520Sgrehan					   a frame pointer/saved LR */
28695719Sbenno	b	trapexit
287209975Snwhitehorn	nop
288