From owner-svn-src-all@FreeBSD.ORG Mon Nov 11 17:37:53 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id EB0EB210; Mon, 11 Nov 2013 17:37:52 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id D6B832950; Mon, 11 Nov 2013 17:37:52 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rABHbq3U048295; Mon, 11 Nov 2013 17:37:52 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rABHbpVg048284; Mon, 11 Nov 2013 17:37:51 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201311111737.rABHbpVg048284@svn.freebsd.org> From: Nathan Whitehorn Date: Mon, 11 Nov 2013 17:37:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r258002 - in head/sys: conf powerpc/aim powerpc/booke powerpc/include powerpc/powerpc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Nov 2013 17:37:53 -0000 Author: nwhitehorn Date: Mon Nov 11 17:37:50 2013 New Revision: 258002 URL: http://svnweb.freebsd.org/changeset/base/258002 Log: Follow up r223485, which made AIM use the ABI thread pointer instead of PCPU fields for curthread, by doing the same to Book-E. This closes some potential races switching between CPUs. As a side effect, it turns out the AIM and Book-E swtch.S implementations were the same to within a few registers, so move that to powerpc/powerpc. MFC after: 3 months Added: head/sys/powerpc/powerpc/swtch32.S - copied, changed from r257990, head/sys/powerpc/aim/swtch32.S head/sys/powerpc/powerpc/swtch64.S - copied unchanged from r257990, head/sys/powerpc/aim/swtch64.S Deleted: head/sys/powerpc/aim/swtch32.S head/sys/powerpc/aim/swtch64.S head/sys/powerpc/booke/swtch.S Modified: head/sys/conf/files.powerpc head/sys/powerpc/booke/locore.S head/sys/powerpc/booke/machdep.c head/sys/powerpc/booke/mp_cpudep.c head/sys/powerpc/booke/pmap.c head/sys/powerpc/booke/trap_subr.S head/sys/powerpc/include/pcpu.h Modified: head/sys/conf/files.powerpc ============================================================================== --- head/sys/conf/files.powerpc Mon Nov 11 17:07:02 2013 (r258001) +++ head/sys/conf/files.powerpc Mon Nov 11 17:37:50 2013 (r258002) @@ -96,8 +96,6 @@ powerpc/aim/moea64_if.m optional aim powerpc/aim/moea64_native.c optional aim powerpc/aim/mp_cpudep.c optional aim smp powerpc/aim/slb.c optional aim powerpc64 -powerpc/aim/swtch32.S optional aim powerpc -powerpc/aim/swtch64.S optional aim powerpc64 powerpc/aim/trap.c optional aim powerpc/aim/uma_machdep.c optional aim powerpc/booke/copyinout.c optional booke @@ -108,7 +106,6 @@ powerpc/booke/machdep_e500.c optional bo powerpc/booke/mp_cpudep.c optional booke smp powerpc/booke/platform_bare.c optional booke powerpc/booke/pmap.c optional booke -powerpc/booke/swtch.S optional booke powerpc/booke/trap.c optional booke powerpc/cpufreq/dfs.c optional cpufreq powerpc/cpufreq/pcr.c optional cpufreq aim @@ -205,6 +202,8 @@ powerpc/powerpc/sc_machdep.c optional sc powerpc/powerpc/setjmp.S standard powerpc/powerpc/sigcode32.S optional powerpc | compat_freebsd32 powerpc/powerpc/sigcode64.S optional powerpc64 +powerpc/powerpc/swtch32.S optional powerpc +powerpc/powerpc/swtch64.S optional powerpc64 powerpc/powerpc/stack_machdep.c optional ddb | stack powerpc/powerpc/suswintr.c standard powerpc/powerpc/syncicache.c standard Modified: head/sys/powerpc/booke/locore.S ============================================================================== --- head/sys/powerpc/booke/locore.S Mon Nov 11 17:07:02 2013 (r258001) +++ head/sys/powerpc/booke/locore.S Mon Nov 11 17:37:50 2013 (r258002) @@ -738,8 +738,7 @@ ENTRY(icache_enable) setfault: mflr %r0 mfsprg0 %r4 - lwz %r4, PC_CURTHREAD(%r4) - lwz %r4, TD_PCB(%r4) + lwz %r4, TD_PCB(%r2) stw %r3, PCB_ONFAULT(%r4) mfcr %r10 mfctr %r11 Modified: head/sys/powerpc/booke/machdep.c ============================================================================== --- head/sys/powerpc/booke/machdep.c Mon Nov 11 17:07:02 2013 (r258001) +++ head/sys/powerpc/booke/machdep.c Mon Nov 11 17:37:50 2013 (r258002) @@ -409,6 +409,11 @@ booke_init(uint32_t arg1, uint32_t arg2) pc = &__pcpu[0]; pcpu_init(pc, 0, sizeof(struct pcpu)); pc->pc_curthread = &thread0; +#ifdef __powerpc64__ + __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread)); +#else + __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread)); +#endif __asm __volatile("mtsprg 0, %0" :: "r"(pc)); /* Initialize system mutexes. */ Modified: head/sys/powerpc/booke/mp_cpudep.c ============================================================================== --- head/sys/powerpc/booke/mp_cpudep.c Mon Nov 11 17:07:02 2013 (r258001) +++ head/sys/powerpc/booke/mp_cpudep.c Mon Nov 11 17:37:50 2013 (r258002) @@ -71,6 +71,11 @@ cpudep_ap_bootstrap() /* Assign pcpu fields, return ptr to this AP's idle thread kstack */ pcpup->pc_curthread = pcpup->pc_idlethread; +#ifdef __powerpc64__ + __asm __volatile("mr 13,%0" :: "r"(pcpup->pc_curthread)); +#else + __asm __volatile("mr 2,%0" :: "r"(pcpup->pc_curthread)); +#endif pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb; sp = pcpup->pc_curpcb->pcb_sp; Modified: head/sys/powerpc/booke/pmap.c ============================================================================== --- head/sys/powerpc/booke/pmap.c Mon Nov 11 17:07:02 2013 (r258001) +++ head/sys/powerpc/booke/pmap.c Mon Nov 11 17:37:50 2013 (r258002) @@ -100,8 +100,6 @@ __FBSDID("$FreeBSD$"); #define TODO panic("%s: not implemented", __func__); -extern struct mtx sched_lock; - extern int dumpsys_minidump; extern unsigned char _etext[]; @@ -1906,7 +1904,7 @@ mmu_booke_activate(mmu_t mmu, struct thr KASSERT((pmap != kernel_pmap), ("mmu_booke_activate: kernel_pmap!")); - mtx_lock_spin(&sched_lock); + sched_pin(); cpuid = PCPU_GET(cpuid); CPU_SET_ATOMIC(cpuid, &pmap->pm_active); @@ -1919,7 +1917,7 @@ mmu_booke_activate(mmu_t mmu, struct thr mtspr(SPR_PID0, pmap->pm_tid[cpuid]); __asm __volatile("isync"); - mtx_unlock_spin(&sched_lock); + sched_unpin(); CTR3(KTR_PMAP, "%s: e (tid = %d for '%s')", __func__, pmap->pm_tid[PCPU_GET(cpuid)], td->td_proc->p_comm); Modified: head/sys/powerpc/booke/trap_subr.S ============================================================================== --- head/sys/powerpc/booke/trap_subr.S Mon Nov 11 17:07:02 2013 (r258001) +++ head/sys/powerpc/booke/trap_subr.S Mon Nov 11 17:37:50 2013 (r258002) @@ -219,7 +219,8 @@ lwz %r30, (savearea+CPUSAVE_SRR0)(%r2); \ lwz %r31, (savearea+CPUSAVE_SRR1)(%r2); \ stw %r30, FRAME_SRR0+8(%r1); \ - stw %r31, FRAME_SRR1+8(%r1) + stw %r31, FRAME_SRR1+8(%r1); \ + lwz %r2,PC_CURTHREAD(%r2) /* set curthread pointer */ /* * @@ -734,7 +735,8 @@ interrupt_vector_top: INTERRUPT(int_debug) STANDARD_CRIT_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1) FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_DEBUG) - lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0)(%r2); + GET_CPUINFO(%r3) + lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0)(%r3) lis %r4, interrupt_vector_base@ha addi %r4, %r4, interrupt_vector_base@l cmplw cr0, %r3, %r4 @@ -748,9 +750,10 @@ INTERRUPT(int_debug) rlwinm %r3, %r3, 0, 23, 21 stw %r3, FRAME_SRR1+8(%r1); /* Restore srr0 and srr1 as they could have been clobbered. */ - lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0+8)(%r2); + GET_CPUINFO(%r4) + lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0+8)(%r4); mtspr SPR_SRR0, %r3 - lwz %r4, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR1+8)(%r2); + lwz %r4, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR1+8)(%r4); mtspr SPR_SRR1, %r4 b 9f 1: Modified: head/sys/powerpc/include/pcpu.h ============================================================================== --- head/sys/powerpc/include/pcpu.h Mon Nov 11 17:07:02 2013 (r258001) +++ head/sys/powerpc/include/pcpu.h Mon Nov 11 17:37:50 2013 (r258002) @@ -135,7 +135,6 @@ struct pmap; #define pcpup ((struct pcpu *) powerpc_get_pcpup()) -#ifdef AIM /* Book-E not yet adapted */ static __inline __pure2 struct thread * __curthread(void) { @@ -148,7 +147,6 @@ __curthread(void) return (td); } #define curthread (__curthread()) -#endif #define PCPU_GET(member) (pcpup->pc_ ## member) Copied and modified: head/sys/powerpc/powerpc/swtch32.S (from r257990, head/sys/powerpc/aim/swtch32.S) ============================================================================== --- head/sys/powerpc/aim/swtch32.S Mon Nov 11 14:08:25 2013 (r257990, copy source) +++ head/sys/powerpc/powerpc/swtch32.S Mon Nov 11 17:37:50 2013 (r258002) @@ -64,6 +64,7 @@ #include #include #include +#include /* * void cpu_throw(struct thread *old, struct thread *new) @@ -88,6 +89,14 @@ ENTRY(cpu_switch) stw %r16,PCB_CR(%r6) mflr %r16 /* Save the link register */ stw %r16,PCB_LR(%r6) +#ifdef BOOKE + mfctr %r16 + stw %r16,PCB_BOOKE_CTR(%r6) + mfxer %r16 + stw %r16,PCB_BOOKE_XER(%r6) + mfspr %r16,SPR_DBCR0 + stw %r16,PCB_BOOKE_DBCR0(%r6) +#endif stw %r1,PCB_SP(%r6) /* Save the stack pointer */ mr %r14,%r3 /* Copy the old thread ptr... */ @@ -95,6 +104,7 @@ ENTRY(cpu_switch) mr %r16,%r5 /* and the new lock */ mr %r17,%r6 /* and the PCB */ +#ifdef AIM lwz %r7,PCB_FLAGS(%r17) /* Save FPU context if needed */ andi. %r7, %r7, PCB_FPU @@ -110,6 +120,7 @@ ENTRY(cpu_switch) bl save_vec .L2: +#endif mr %r3,%r14 /* restore old thread ptr */ bl pmap_deactivate /* Deactivate the current pmap */ @@ -136,6 +147,7 @@ blocked_loop: mr %r3,%r2 /* Get new thread ptr */ bl pmap_activate /* Activate the new address space */ +#ifdef AIM lwz %r6, PCB_FLAGS(%r17) /* Restore FPU context if needed */ andi. %r6, %r6, PCB_FPU @@ -151,18 +163,29 @@ blocked_loop: mr %r3,%r2 /* Pass curthread to enable_vec */ bl enable_vec - /* thread to restore is in r3 */ .L4: +#endif + /* thread to restore is in r3 */ mr %r3,%r17 /* Recover PCB ptr */ lmw %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs */ lwz %r5,PCB_CR(%r3) /* Load the condition register */ mtcr %r5 lwz %r5,PCB_LR(%r3) /* Load the link register */ mtlr %r5 +#ifdef AIM lwz %r5,PCB_AIM_USR_VSID(%r3) /* Load the USER_SR segment reg */ isync mtsr USER_SR,%r5 isync +#endif +#ifdef BOOKE + lwz %r5,PCB_BOOKE_CTR(%r3) + mtctr %r5 + lwz %r5,PCB_BOOKE_XER(%r3) + mtctr %r5 + lwz %r5,PCB_BOOKE_DBCR0(%r3) + mtspr SPR_DBCR0,%r5 +#endif lwz %r1,PCB_SP(%r3) /* Load the stack pointer */ /* * Perform a dummy stwcx. to clear any reservations we may have Copied: head/sys/powerpc/powerpc/swtch64.S (from r257990, head/sys/powerpc/aim/swtch64.S) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/powerpc/powerpc/swtch64.S Mon Nov 11 17:37:50 2013 (r258002, copy of r257990, head/sys/powerpc/aim/swtch64.S) @@ -0,0 +1,287 @@ +/* $FreeBSD$ */ +/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */ + +/*- + * Copyright (C) 2001 Benno Rice + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "assym.s" +#include "opt_sched.h" + +#include + +#include +#include +#include + +/* + * void cpu_throw(struct thread *old, struct thread *new) + */ +ENTRY(cpu_throw) + mr %r13, %r4 + b cpu_switchin + +/* + * void cpu_switch(struct thread *old, + * struct thread *new, + * struct mutex *mtx); + * + * Switch to a new thread saving the current state in the old thread. + */ +ENTRY(cpu_switch) + ld %r6,TD_PCB(%r3) /* Get the old thread's PCB ptr */ + std %r12,PCB_CONTEXT(%r6) /* Save the non-volatile GP regs. + These can now be used for scratch */ + std %r14,PCB_CONTEXT+2*8(%r6) + std %r15,PCB_CONTEXT+3*8(%r6) + std %r16,PCB_CONTEXT+4*8(%r6) + std %r17,PCB_CONTEXT+5*8(%r6) + std %r18,PCB_CONTEXT+6*8(%r6) + std %r19,PCB_CONTEXT+7*8(%r6) + std %r20,PCB_CONTEXT+8*8(%r6) + std %r21,PCB_CONTEXT+9*8(%r6) + std %r22,PCB_CONTEXT+10*8(%r6) + std %r23,PCB_CONTEXT+11*8(%r6) + std %r24,PCB_CONTEXT+12*8(%r6) + std %r25,PCB_CONTEXT+13*8(%r6) + std %r26,PCB_CONTEXT+14*8(%r6) + std %r27,PCB_CONTEXT+15*8(%r6) + std %r28,PCB_CONTEXT+16*8(%r6) + std %r29,PCB_CONTEXT+17*8(%r6) + std %r30,PCB_CONTEXT+18*8(%r6) + std %r31,PCB_CONTEXT+19*8(%r6) + + mfcr %r16 /* Save the condition register */ + std %r16,PCB_CR(%r6) + mflr %r16 /* Save the link register */ + std %r16,PCB_LR(%r6) + std %r1,PCB_SP(%r6) /* Save the stack pointer */ + std %r2,PCB_TOC(%r6) /* Save the TOC pointer */ + + mr %r14,%r3 /* Copy the old thread ptr... */ + mr %r13,%r4 /* and the new thread ptr in curthread*/ + mr %r16,%r5 /* and the new lock */ + mr %r17,%r6 /* and the PCB */ + + stdu %r1,-48(%r1) + + lwz %r7,PCB_FLAGS(%r17) + /* Save FPU context if needed */ + andi. %r7, %r7, PCB_FPU + beq .L1 + bl save_fpu + nop + +.L1: + mr %r3,%r14 /* restore old thread ptr */ + lwz %r7,PCB_FLAGS(%r17) + /* Save Altivec context if needed */ + andi. %r7, %r7, PCB_VEC + beq .L2 + bl save_vec + nop + +.L2: + mr %r3,%r14 /* restore old thread ptr */ + bl pmap_deactivate /* Deactivate the current pmap */ + nop + + addi %r1,%r1,48 + + sync /* Make sure all of that finished */ + std %r16,TD_LOCK(%r14) /* ULE: update old thread's lock */ + +cpu_switchin: +#if defined(SMP) && defined(SCHED_ULE) + /* Wait for the new thread to become unblocked */ + lis %r6,blocked_lock@ha + addi %r6,%r6,blocked_lock@l +blocked_loop: + ld %r7,TD_LOCK(%r13) + cmpd %r6,%r7 + beq- blocked_loop + isync +#endif + + mfsprg %r7,0 /* Get the pcpu pointer */ + std %r13,PC_CURTHREAD(%r7) /* Store new current thread */ + ld %r17,TD_PCB(%r13) /* Store new current PCB */ + std %r17,PC_CURPCB(%r7) + + stdu %r1,-48(%r1) + + mr %r3,%r13 /* Get new thread ptr */ + bl pmap_activate /* Activate the new address space */ + nop + + lwz %r6, PCB_FLAGS(%r17) + /* Restore FPU context if needed */ + andi. %r6, %r6, PCB_FPU + beq .L3 + mr %r3,%r13 /* Pass curthread to enable_fpu */ + bl enable_fpu + nop + +.L3: + lwz %r6, PCB_FLAGS(%r17) + /* Restore Altivec context if needed */ + andi. %r6, %r6, PCB_VEC + beq .L4 + mr %r3,%r13 /* Pass curthread to enable_vec */ + bl enable_vec + nop + + /* thread to restore is in r3 */ +.L4: + addi %r1,%r1,48 + mr %r3,%r17 /* Recover PCB ptr */ + ld %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs. */ + ld %r14,PCB_CONTEXT+2*8(%r3) + ld %r15,PCB_CONTEXT+3*8(%r3) + ld %r16,PCB_CONTEXT+4*8(%r3) + ld %r17,PCB_CONTEXT+5*8(%r3) + ld %r18,PCB_CONTEXT+6*8(%r3) + ld %r19,PCB_CONTEXT+7*8(%r3) + ld %r20,PCB_CONTEXT+8*8(%r3) + ld %r21,PCB_CONTEXT+9*8(%r3) + ld %r22,PCB_CONTEXT+10*8(%r3) + ld %r23,PCB_CONTEXT+11*8(%r3) + ld %r24,PCB_CONTEXT+12*8(%r3) + ld %r25,PCB_CONTEXT+13*8(%r3) + ld %r26,PCB_CONTEXT+14*8(%r3) + ld %r27,PCB_CONTEXT+15*8(%r3) + ld %r28,PCB_CONTEXT+16*8(%r3) + ld %r29,PCB_CONTEXT+17*8(%r3) + ld %r30,PCB_CONTEXT+18*8(%r3) + ld %r31,PCB_CONTEXT+19*8(%r3) + ld %r5,PCB_CR(%r3) /* Load the condition register */ + mtcr %r5 + ld %r5,PCB_LR(%r3) /* Load the link register */ + mtlr %r5 + ld %r1,PCB_SP(%r3) /* Load the stack pointer */ + ld %r2,PCB_TOC(%r3) /* Load the TOC pointer */ + + lis %r5,USER_ADDR@highesta /* Load the copyin/out segment reg */ + ori %r5,%r5,USER_ADDR@highera + sldi %r5,%r5,32 + oris %r5,%r5,USER_ADDR@ha + isync + slbie %r5 + lis %r6,USER_SLB_SLBE@highesta + ori %r6,%r6,USER_SLB_SLBE@highera + sldi %r6,%r6,32 + oris %r6,%r6,USER_SLB_SLBE@ha + ori %r6,%r6,USER_SLB_SLBE@l + ld %r5,PCB_AIM_USR_VSID(%r3) + slbmte %r5,%r6 + isync + + /* + * Perform a dummy stdcx. to clear any reservations we may have + * inherited from the previous thread. It doesn't matter if the + * stdcx succeeds or not. pcb_context[0] can be clobbered. + */ + stdcx. %r1, 0, %r3 + blr + +/* + * savectx(pcb) + * Update pcb, saving current processor state + */ +ENTRY(savectx) + std %r12,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs. */ + std %r13,PCB_CONTEXT+1*8(%r3) + std %r14,PCB_CONTEXT+2*8(%r3) + std %r15,PCB_CONTEXT+3*8(%r3) + std %r16,PCB_CONTEXT+4*8(%r3) + std %r17,PCB_CONTEXT+5*8(%r3) + std %r18,PCB_CONTEXT+6*8(%r3) + std %r19,PCB_CONTEXT+7*8(%r3) + std %r20,PCB_CONTEXT+8*8(%r3) + std %r21,PCB_CONTEXT+9*8(%r3) + std %r22,PCB_CONTEXT+10*8(%r3) + std %r23,PCB_CONTEXT+11*8(%r3) + std %r24,PCB_CONTEXT+12*8(%r3) + std %r25,PCB_CONTEXT+13*8(%r3) + std %r26,PCB_CONTEXT+14*8(%r3) + std %r27,PCB_CONTEXT+15*8(%r3) + std %r28,PCB_CONTEXT+16*8(%r3) + std %r29,PCB_CONTEXT+17*8(%r3) + std %r30,PCB_CONTEXT+18*8(%r3) + std %r31,PCB_CONTEXT+19*8(%r3) + + mfcr %r4 /* Save the condition register */ + std %r4,PCB_CR(%r3) + std %r2,PCB_TOC(%r3) /* Save the TOC pointer */ + blr + +/* + * fork_trampoline() + * Set up the return from cpu_fork() + */ + +ENTRY_NOPROF(fork_trampoline) + ld %r3,CF_FUNC(%r1) + ld %r4,CF_ARG0(%r1) + ld %r5,CF_ARG1(%r1) + + stdu %r1,-48(%r1) + bl fork_exit + nop + addi %r1,%r1,48+CF_SIZE-FSP /* Allow 8 bytes in front of + trapframe to simulate FRAME_SETUP + does when allocating space for + a frame pointer/saved LR */ + b trapexit + nop