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