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>
67258002Snwhitehorn#include <machine/spr.h>
6877957Sbenno
6977957Sbenno/*
70178628Smarcel * void cpu_throw(struct thread *old, struct thread *new)
71178628Smarcel */
72178628SmarcelENTRY(cpu_throw)
73223485Snwhitehorn	mr	%r2, %r4
74178628Smarcel	b	cpu_switchin
75178628Smarcel
76178628Smarcel/*
77172887Sgrehan * void cpu_switch(struct thread *old,
78172887Sgrehan *		   struct thread *new,
79172887Sgrehan *		   struct mutex *mtx);
80118893Sgrehan *
81118893Sgrehan * Switch to a new thread saving the current state in the old thread.
8277957Sbenno */
8377957SbennoENTRY(cpu_switch)
84198723Snwhitehorn	lwz	%r6,TD_PCB(%r3)		/* Get the old thread's PCB ptr */
85198723Snwhitehorn	stmw	%r12,PCB_CONTEXT(%r6)	/* Save the non-volatile GP regs.
86118893Sgrehan					   These can now be used for scratch */
87118893Sgrehan
8891486Sbenno	mfcr	%r16			/* Save the condition register */
89198723Snwhitehorn	stw	%r16,PCB_CR(%r6)
9091486Sbenno	mflr	%r16			/* Save the link register */
91198723Snwhitehorn	stw	%r16,PCB_LR(%r6)
92258002Snwhitehorn#ifdef BOOKE
93258002Snwhitehorn	mfspr	%r16,SPR_DBCR0
94258002Snwhitehorn	stw	%r16,PCB_BOOKE_DBCR0(%r6)
95258002Snwhitehorn#endif
96198723Snwhitehorn	stw	%r1,PCB_SP(%r6)		/* Save the stack pointer */
9777957Sbenno
98118893Sgrehan	mr	%r14,%r3		/* Copy the old thread ptr... */
99223485Snwhitehorn	mr	%r2,%r4			/* and the new thread ptr in curthread */
100198723Snwhitehorn	mr	%r16,%r5		/* and the new lock */
101198731Snwhitehorn	mr	%r17,%r6		/* and the PCB */
102118893Sgrehan
103198731Snwhitehorn	lwz	%r7,PCB_FLAGS(%r17)
104178628Smarcel	/* Save FPU context if needed */
105198731Snwhitehorn	andi.	%r7, %r7, PCB_FPU
10686066Smp	beq	.L1
10786066Smp	bl	save_fpu
108188860Snwhitehorn
109188860Snwhitehorn.L1:
110198731Snwhitehorn	mr	%r3,%r14		/* restore old thread ptr */
111198731Snwhitehorn	lwz	%r7,PCB_FLAGS(%r17)
112188860Snwhitehorn	/* Save Altivec context if needed */
113198731Snwhitehorn	andi.	%r7, %r7, PCB_VEC
114188860Snwhitehorn	beq	.L2
115188860Snwhitehorn	bl	save_vec
116188860Snwhitehorn
117188860Snwhitehorn.L2:
118118893Sgrehan	mr	%r3,%r14		/* restore old thread ptr */
11991486Sbenno	bl	pmap_deactivate		/* Deactivate the current pmap */
12091486Sbenno
121234517Snwhitehorn	sync				/* Make sure all of that finished */
122198723Snwhitehorn	stw	%r16,TD_LOCK(%r14)	/* ULE:	update old thread's lock */
123198723Snwhitehorn
124178628Smarcelcpu_switchin:
125198723Snwhitehorn#if defined(SMP) && defined(SCHED_ULE)
126198723Snwhitehorn	/* Wait for the new thread to become unblocked */
127198723Snwhitehorn	lis	%r6,blocked_lock@ha
128198723Snwhitehorn	addi	%r6,%r6,blocked_lock@l
129198723Snwhitehornblocked_loop:
130223485Snwhitehorn	lwz	%r7,TD_LOCK(%r2)
131198723Snwhitehorn	cmpw	%r6,%r7
132235013Snwhitehorn	beq-	blocked_loop
133235013Snwhitehorn	isync
134198723Snwhitehorn#endif
135198723Snwhitehorn
136118893Sgrehan	mfsprg	%r7,0			/* Get the pcpu pointer */
137223485Snwhitehorn	stw	%r2,PC_CURTHREAD(%r7)	/* Store new current thread */
138223485Snwhitehorn	lwz	%r17,TD_PCB(%r2)	/* Store new current PCB */
139118893Sgrehan	stw	%r17,PC_CURPCB(%r7)
14077957Sbenno
141223485Snwhitehorn	mr	%r3,%r2			/* Get new thread ptr */
142183088Smarcel	bl	pmap_activate		/* Activate the new address space */
143183088Smarcel
144178628Smarcel	lwz	%r6, PCB_FLAGS(%r17)
145178628Smarcel	/* Restore FPU context if needed */
146118893Sgrehan	andi.	%r6, %r6, PCB_FPU
147188860Snwhitehorn	beq	.L3
148223485Snwhitehorn	mr	%r3,%r2			/* Pass curthread to enable_fpu */
14986066Smp	bl	enable_fpu
15086066Smp
151188860Snwhitehorn.L3:
152188860Snwhitehorn	lwz	%r6, PCB_FLAGS(%r17)
153188860Snwhitehorn	/* Restore Altivec context if needed */
154188860Snwhitehorn	andi.	%r6, %r6, PCB_VEC
155188860Snwhitehorn	beq	.L4
156223485Snwhitehorn	mr	%r3,%r2			/* Pass curthread to enable_vec */
157188860Snwhitehorn	bl	enable_vec
158188860Snwhitehorn
159258002Snwhitehorn.L4:
16099036Sbenno	/* thread to restore is in r3 */
161118893Sgrehan	mr	%r3,%r17		/* Recover PCB ptr */
16299036Sbenno	lmw	%r12,PCB_CONTEXT(%r3)	/* Load the non-volatile GP regs */
16399036Sbenno	lwz	%r5,PCB_CR(%r3)		/* Load the condition register */
16484945Smp	mtcr	%r5
16599036Sbenno	lwz	%r5,PCB_LR(%r3)		/* Load the link register */
16691486Sbenno	mtlr	%r5
167258002Snwhitehorn#ifdef AIM
168209975Snwhitehorn	lwz	%r5,PCB_AIM_USR_VSID(%r3) /* Load the USER_SR segment reg */
169214607Snwhitehorn	isync
170105611Sgrehan	mtsr	USER_SR,%r5
171105611Sgrehan	isync
172258002Snwhitehorn#endif
173258002Snwhitehorn#ifdef BOOKE
174258002Snwhitehorn	lwz	%r5,PCB_BOOKE_DBCR0(%r3)
175258002Snwhitehorn	mtspr	SPR_DBCR0,%r5
176258002Snwhitehorn#endif
17799036Sbenno	lwz	%r1,PCB_SP(%r3)		/* Load the stack pointer */
178190704Smarcel	/*
179190704Smarcel	 * Perform a dummy stwcx. to clear any reservations we may have
180190704Smarcel	 * inherited from the previous thread. It doesn't matter if the
181190704Smarcel	 * stwcx succeeds or not. pcb_context[0] can be clobbered.
182190704Smarcel	 */
183190704Smarcel	stwcx.	%r1, 0, %r3
18477957Sbenno	blr
18577957Sbenno
18677957Sbenno/*
18784945Smp * savectx(pcb)
18884945Smp * Update pcb, saving current processor state
18977957Sbenno */
19077957SbennoENTRY(savectx)
19199036Sbenno	stmw	%r12,PCB_CONTEXT(%r3)	/* Save the non-volatile GP regs */
19284945Smp	mfcr	%r4			/* Save the condition register */
193197962Snwhitehorn	stw	%r4,PCB_CR(%r3)
19477957Sbenno	blr
19591467Sbenno
19691467Sbenno/*
19791467Sbenno * fork_trampoline()
19891467Sbenno * Set up the return from cpu_fork()
19991467Sbenno */
20091467SbennoENTRY(fork_trampoline)
20195719Sbenno	lwz	%r3,CF_FUNC(%r1)
20295719Sbenno	lwz	%r4,CF_ARG0(%r1)
20395719Sbenno	lwz	%r5,CF_ARG1(%r1)
20491467Sbenno	bl	fork_exit
205132520Sgrehan	addi	%r1,%r1,CF_SIZE-FSP	/* Allow 8 bytes in front of
206132520Sgrehan					   trapframe to simulate FRAME_SETUP
207132520Sgrehan					   does when allocating space for
208132520Sgrehan					   a frame pointer/saved LR */
20995719Sbenno	b	trapexit
210