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