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 */
71178628SmarcelENTRY(cpu_throw)
72223485Snwhitehorn	mr	%r2, %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 */
8277957SbennoENTRY(cpu_switch)
83198723Snwhitehorn	lwz	%r6,TD_PCB(%r3)		/* Get the old thread's PCB ptr */
84198723Snwhitehorn	stmw	%r12,PCB_CONTEXT(%r6)	/* Save the non-volatile GP regs.
85118893Sgrehan					   These can now be used for scratch */
86118893Sgrehan
8791486Sbenno	mfcr	%r16			/* Save the condition register */
88198723Snwhitehorn	stw	%r16,PCB_CR(%r6)
8991486Sbenno	mflr	%r16			/* Save the link register */
90198723Snwhitehorn	stw	%r16,PCB_LR(%r6)
91198723Snwhitehorn	stw	%r1,PCB_SP(%r6)		/* Save the stack pointer */
9277957Sbenno
93118893Sgrehan	mr	%r14,%r3		/* Copy the old thread ptr... */
94223485Snwhitehorn	mr	%r2,%r4			/* and the new thread ptr in curthread */
95198723Snwhitehorn	mr	%r16,%r5		/* and the new lock */
96198731Snwhitehorn	mr	%r17,%r6		/* and the PCB */
97118893Sgrehan
98198731Snwhitehorn	lwz	%r7,PCB_FLAGS(%r17)
99178628Smarcel	/* Save FPU context if needed */
100198731Snwhitehorn	andi.	%r7, %r7, PCB_FPU
10186066Smp	beq	.L1
10286066Smp	bl	save_fpu
103188860Snwhitehorn
104188860Snwhitehorn.L1:
105198731Snwhitehorn	mr	%r3,%r14		/* restore old thread ptr */
106198731Snwhitehorn	lwz	%r7,PCB_FLAGS(%r17)
107188860Snwhitehorn	/* Save Altivec context if needed */
108198731Snwhitehorn	andi.	%r7, %r7, PCB_VEC
109188860Snwhitehorn	beq	.L2
110188860Snwhitehorn	bl	save_vec
111188860Snwhitehorn
112188860Snwhitehorn.L2:
113118893Sgrehan	mr	%r3,%r14		/* restore old thread ptr */
11491486Sbenno	bl	pmap_deactivate		/* Deactivate the current pmap */
11591486Sbenno
116234517Snwhitehorn	sync				/* Make sure all of that finished */
117198723Snwhitehorn	stw	%r16,TD_LOCK(%r14)	/* ULE:	update old thread's lock */
118198723Snwhitehorn
119178628Smarcelcpu_switchin:
120198723Snwhitehorn#if defined(SMP) && defined(SCHED_ULE)
121198723Snwhitehorn	/* Wait for the new thread to become unblocked */
122198723Snwhitehorn	lis	%r6,blocked_lock@ha
123198723Snwhitehorn	addi	%r6,%r6,blocked_lock@l
124198723Snwhitehornblocked_loop:
125223485Snwhitehorn	lwz	%r7,TD_LOCK(%r2)
126198723Snwhitehorn	cmpw	%r6,%r7
127235013Snwhitehorn	beq-	blocked_loop
128235013Snwhitehorn	isync
129198723Snwhitehorn#endif
130198723Snwhitehorn
131118893Sgrehan	mfsprg	%r7,0			/* Get the pcpu pointer */
132223485Snwhitehorn	stw	%r2,PC_CURTHREAD(%r7)	/* Store new current thread */
133223485Snwhitehorn	lwz	%r17,TD_PCB(%r2)	/* Store new current PCB */
134118893Sgrehan	stw	%r17,PC_CURPCB(%r7)
13577957Sbenno
136223485Snwhitehorn	mr	%r3,%r2			/* Get new thread ptr */
137183088Smarcel	bl	pmap_activate		/* Activate the new address space */
138183088Smarcel
139178628Smarcel	lwz	%r6, PCB_FLAGS(%r17)
140178628Smarcel	/* Restore FPU context if needed */
141118893Sgrehan	andi.	%r6, %r6, PCB_FPU
142188860Snwhitehorn	beq	.L3
143223485Snwhitehorn	mr	%r3,%r2			/* Pass curthread to enable_fpu */
14486066Smp	bl	enable_fpu
14586066Smp
146188860Snwhitehorn.L3:
147188860Snwhitehorn	lwz	%r6, PCB_FLAGS(%r17)
148188860Snwhitehorn	/* Restore Altivec context if needed */
149188860Snwhitehorn	andi.	%r6, %r6, PCB_VEC
150188860Snwhitehorn	beq	.L4
151223485Snwhitehorn	mr	%r3,%r2			/* Pass curthread to enable_vec */
152188860Snwhitehorn	bl	enable_vec
153188860Snwhitehorn
15499036Sbenno	/* thread to restore is in r3 */
155188860Snwhitehorn.L4:
156118893Sgrehan	mr	%r3,%r17		/* Recover PCB ptr */
15799036Sbenno	lmw	%r12,PCB_CONTEXT(%r3)	/* Load the non-volatile GP regs */
15899036Sbenno	lwz	%r5,PCB_CR(%r3)		/* Load the condition register */
15984945Smp	mtcr	%r5
16099036Sbenno	lwz	%r5,PCB_LR(%r3)		/* Load the link register */
16191486Sbenno	mtlr	%r5
162209975Snwhitehorn	lwz	%r5,PCB_AIM_USR_VSID(%r3) /* Load the USER_SR segment reg */
163214607Snwhitehorn	isync
164105611Sgrehan	mtsr	USER_SR,%r5
165105611Sgrehan	isync
16699036Sbenno	lwz	%r1,PCB_SP(%r3)		/* Load the stack pointer */
167190704Smarcel	/*
168190704Smarcel	 * Perform a dummy stwcx. to clear any reservations we may have
169190704Smarcel	 * inherited from the previous thread. It doesn't matter if the
170190704Smarcel	 * stwcx succeeds or not. pcb_context[0] can be clobbered.
171190704Smarcel	 */
172190704Smarcel	stwcx.	%r1, 0, %r3
17377957Sbenno	blr
17477957Sbenno
17577957Sbenno/*
17684945Smp * savectx(pcb)
17784945Smp * Update pcb, saving current processor state
17877957Sbenno */
17977957SbennoENTRY(savectx)
18099036Sbenno	stmw	%r12,PCB_CONTEXT(%r3)	/* Save the non-volatile GP regs */
18184945Smp	mfcr	%r4			/* Save the condition register */
182197962Snwhitehorn	stw	%r4,PCB_CR(%r3)
18377957Sbenno	blr
18491467Sbenno
18591467Sbenno/*
18691467Sbenno * fork_trampoline()
18791467Sbenno * Set up the return from cpu_fork()
18891467Sbenno */
18991467SbennoENTRY(fork_trampoline)
19095719Sbenno	lwz	%r3,CF_FUNC(%r1)
19195719Sbenno	lwz	%r4,CF_ARG0(%r1)
19295719Sbenno	lwz	%r5,CF_ARG1(%r1)
19391467Sbenno	bl	fork_exit
194132520Sgrehan	addi	%r1,%r1,CF_SIZE-FSP	/* Allow 8 bytes in front of
195132520Sgrehan					   trapframe to simulate FRAME_SETUP
196132520Sgrehan					   does when allocating space for
197132520Sgrehan					   a frame pointer/saved LR */
19895719Sbenno	b	trapexit
199