Module Name:    src
Committed By:   bouyer
Date:           Thu Nov 19 08:50:05 UTC 2015

Modified Files:
        src/sys/arch/powerpc/include [netbsd-6]: psl.h userret.h
        src/sys/arch/powerpc/oea [netbsd-6]: altivec.c oea_machdep.c
        src/sys/arch/powerpc/powerpc [netbsd-6]: fpu.c

Log Message:
Revert ticket 1310 (second try):
> sys/arch/powerpc/include/psl.h                        1.20
> sys/arch/powerpc/include/userret.h            1.29, 1.30
> sys/arch/powerpc/oea/altivec.c                        1.30
> sys/arch/powerpc/oea/oea_machdep.c            1.72
> sys/arch/powerpc/powerpc/fpu.c                        1.36
>
>       powerpc PCU fixes

because it breaks the build:
http://releng.netbsd.org/builds/netbsd-6/201511152000Z/


To generate a diff of this commit:
cvs rdiff -u -r1.18.8.2 -r1.18.8.3 src/sys/arch/powerpc/include/psl.h
cvs rdiff -u -r1.22.8.3 -r1.22.8.4 src/sys/arch/powerpc/include/userret.h
cvs rdiff -u -r1.25.8.2 -r1.25.8.3 src/sys/arch/powerpc/oea/altivec.c
cvs rdiff -u -r1.63.2.2 -r1.63.2.3 src/sys/arch/powerpc/oea/oea_machdep.c
cvs rdiff -u -r1.31.8.2 -r1.31.8.3 src/sys/arch/powerpc/powerpc/fpu.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/powerpc/include/psl.h
diff -u src/sys/arch/powerpc/include/psl.h:1.18.8.2 src/sys/arch/powerpc/include/psl.h:1.18.8.3
--- src/sys/arch/powerpc/include/psl.h:1.18.8.2	Mon Nov 16 09:00:01 2015
+++ src/sys/arch/powerpc/include/psl.h	Thu Nov 19 08:50:05 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: psl.h,v 1.18.8.2 2015/11/16 09:00:01 bouyer Exp $	*/
+/*	$NetBSD: psl.h,v 1.18.8.3 2015/11/19 08:50:05 bouyer Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -102,8 +102,7 @@
 #include "opt_ppcarch.h"
 #endif /* _KERNEL_OPT */
 
-#if defined(PPC_OEA) || defined (PPC_OEA64_BRIDGE) || defined (PPC_OEA64) \
-    || defined(_MODULE)
+#if defined(PPC_OEA) || defined (PPC_OEA64_BRIDGE) || defined(_MODULE)
 extern register_t cpu_psluserset, cpu_pslusermod, cpu_pslusermask;
 
 #define	PSL_USERSET		cpu_psluserset
@@ -112,7 +111,7 @@ extern register_t cpu_psluserset, cpu_ps
 #elif defined(PPC_BOOKE)
 #define	PSL_USERSET		(PSL_EE | PSL_PR | PSL_IS | PSL_DS | PSL_ME | PSL_CE | PSL_DE)
 #define	PSL_USERMASK		(PSL_SPV | PSL_CE | 0xFFFF)
-#define	PSL_USERMOD		(0)
+#define	PSL_USERMOD		(PSL_SPV)
 #else /* PPC_IBM4XX */
 #ifdef PPC_IBM403
 #define	PSL_USERSET		(PSL_EE | PSL_PR | PSL_IR | PSL_DR | PSL_ME)

Index: src/sys/arch/powerpc/include/userret.h
diff -u src/sys/arch/powerpc/include/userret.h:1.22.8.3 src/sys/arch/powerpc/include/userret.h:1.22.8.4
--- src/sys/arch/powerpc/include/userret.h:1.22.8.3	Mon Nov 16 09:00:01 2015
+++ src/sys/arch/powerpc/include/userret.h	Thu Nov 19 08:50:05 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: userret.h,v 1.22.8.3 2015/11/16 09:00:01 bouyer Exp $	*/
+/*	$NetBSD: userret.h,v 1.22.8.4 2015/11/19 08:50:05 bouyer Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -58,16 +58,7 @@ userret(struct lwp *l, struct trapframe 
 	/* Invoke MI userret code */
 	mi_userret(l);
 
-	KASSERTMSG((tf->tf_srr1 & PSL_PR) != 0,
-	    "tf=%p: srr1 (%#lx): PSL_PR isn't set!",
-	    tf, tf->tf_srr1);
-	KASSERTMSG((tf->tf_srr1 & PSL_FP) == 0
-	    || l->l_cpu->ci_data.cpu_pcu_curlwp[PCU_FPU] == l,
-	    "tf=%p: srr1 (%#lx): PSL_FP set but FPU curlwp %p is not curlwp %p!",
-	    tf, tf->tf_srr1, l->l_cpu->ci_data.cpu_pcu_curlwp[PCU_FPU], l);
-
-	/* clear SRR1 status bits */
-	tf->tf_srr1 &= (PSL_USERSRR1|PSL_FP|PSL_VEC);
+	tf->tf_srr1 &= PSL_USERSRR1;	/* clear SRR1 status bits */
 
 #ifdef ALTIVEC
 	/*
@@ -79,12 +70,12 @@ userret(struct lwp *l, struct trapframe 
 #endif
 #ifdef PPC_BOOKE
 	/*
-	 * BookE doesn't have PSL_SE but it does have a debug instruction
-	 * completion exception but it needs PSL_DE to fire.  Instead we
-	 * use IAC1/IAC2 to match the next PC.
+	 * BookE doesn't PSL_SE but it does have a debug instruction completion
+	 * exception but it needs PSL_DE to fire.  Since we don't want it to
+	 * happen in the kernel, we must disable PSL_DE and let it get
+	 * restored by rfi/rfci.
 	 */
 	if (__predict_false(tf->tf_srr1 & PSL_SE)) {
-		tf->tf_srr1 &= ~PSL_SE;
 		extern void booke_sstep(struct trapframe *); /* ugly */
 		booke_sstep(tf);
 	}

Index: src/sys/arch/powerpc/oea/altivec.c
diff -u src/sys/arch/powerpc/oea/altivec.c:1.25.8.2 src/sys/arch/powerpc/oea/altivec.c:1.25.8.3
--- src/sys/arch/powerpc/oea/altivec.c:1.25.8.2	Mon Nov 16 09:00:01 2015
+++ src/sys/arch/powerpc/oea/altivec.c	Thu Nov 19 08:50:05 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: altivec.c,v 1.25.8.2 2015/11/16 09:00:01 bouyer Exp $	*/
+/*	$NetBSD: altivec.c,v 1.25.8.3 2015/11/19 08:50:05 bouyer Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.25.8.2 2015/11/16 09:00:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.25.8.3 2015/11/19 08:50:05 bouyer Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -49,7 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: altivec.c,v 
 #include <powerpc/oea/spr.h>
 #include <powerpc/psl.h>
 
-static void vec_state_load(lwp_t *, u_int);
+static void vec_state_load(lwp_t *, bool);
 static void vec_state_save(lwp_t *);
 static void vec_state_release(lwp_t *);
 
@@ -63,45 +63,37 @@ const pcu_ops_t vec_ops = {
 bool
 vec_used_p(lwp_t *l)
 {
-	return pcu_valid_p(&vec_ops);
+	return (l->l_md.md_flags & MDLWP_USEDVEC) != 0;
 }
 
 void
 vec_mark_used(lwp_t *l)
 {
-	return pcu_discard(&vec_ops, true);
+	l->l_md.md_flags |= MDLWP_USEDVEC;
 }
 
 void
-vec_state_load(lwp_t *l, u_int flags)
+vec_state_load(lwp_t *l, bool used)
 {
 	struct pcb * const pcb = lwp_getpcb(l);
 
-	if ((flags & PCU_VALID) == 0) {
+	if (__predict_false(!vec_used_p(l))) {
 		memset(&pcb->pcb_vr, 0, sizeof(pcb->pcb_vr));
 		vec_mark_used(l);
 	}
 
-	if ((flags & PCU_REENABLE) == 0) {
-		/*
-		 * Enable AltiVec temporarily (and disable interrupts).
-		 */
-		const register_t msr = mfmsr();
-		mtmsr((msr & ~PSL_EE) | PSL_VEC);
-		__asm volatile ("isync");
-
-		/*
-		 * Load the vector unit from vreg which is best done in
-		 * assembly.
-		 */
-		vec_load_from_vreg(&pcb->pcb_vr);
-
-		/*
-		 * Restore MSR (turn off AltiVec)
-		 */
-		mtmsr(msr);
-		__asm volatile ("isync");
-	}
+	/*
+	 * Enable AltiVec temporarily (and disable interrupts).
+	 */
+	const register_t msr = mfmsr();
+	mtmsr((msr & ~PSL_EE) | PSL_VEC);
+	__asm volatile ("isync");
+
+	/*
+	 * Load the vector unit from vreg which is best done in
+	 * assembly.
+	 */
+	vec_load_from_vreg(&pcb->pcb_vr);
 
 	/*
 	 * VRSAVE will be restored when trap frame returns
@@ -109,9 +101,15 @@ vec_state_load(lwp_t *l, u_int flags)
 	l->l_md.md_utf->tf_vrsave = pcb->pcb_vr.vrsave;
 
 	/*
+	 * Restore MSR (turn off AltiVec)
+	 */
+	mtmsr(msr);
+	__asm volatile ("isync");
+
+	/*
 	 * Mark vector registers as modified.
 	 */
-	l->l_md.md_flags |= PSL_VEC;
+	l->l_md.md_flags |= MDLWP_USEDVEC|PSL_VEC;
 	l->l_md.md_utf->tf_srr1 |= PSL_VEC;
 }
 
@@ -166,7 +164,7 @@ vec_restore_from_mcontext(struct lwp *l,
 	KASSERT(l == curlwp);
 
 	/* we don't need to save the state, just drop it */
-	pcu_discard(&vec_ops, true);
+	pcu_discard(&vec_ops);
 	memcpy(pcb->pcb_vr.vreg, &mcp->__vrf.__vrs, sizeof (pcb->pcb_vr.vreg));
 	pcb->pcb_vr.vscr = mcp->__vrf.__vscr;
 	pcb->pcb_vr.vrsave = mcp->__vrf.__vrsave;

Index: src/sys/arch/powerpc/oea/oea_machdep.c
diff -u src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.2 src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.3
--- src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.2	Mon Nov 16 09:00:01 2015
+++ src/sys/arch/powerpc/oea/oea_machdep.c	Thu Nov 19 08:50:05 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: oea_machdep.c,v 1.63.2.2 2015/11/16 09:00:01 bouyer Exp $	*/
+/*	$NetBSD: oea_machdep.c,v 1.63.2.3 2015/11/19 08:50:05 bouyer Exp $	*/
 
 /*
  * Copyright (C) 2002 Matt Thomas
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.63.2.2 2015/11/16 09:00:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.63.2.3 2015/11/19 08:50:05 bouyer Exp $");
 
 #include "opt_ppcarch.h"
 #include "opt_compat_netbsd.h"
@@ -56,7 +56,6 @@ __KERNEL_RCSID(0, "$NetBSD: oea_machdep.
 #include <sys/syscallargs.h>
 #include <sys/syslog.h>
 #include <sys/systm.h>
-#include <sys/cpu.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -148,14 +147,6 @@ oea_init(void (*handler)(void))
 #endif
 	KASSERT(mfspr(SPR_SPRG0) == (uintptr_t)ci);
 
-#if defined (PPC_OEA64_BRIDGE) && defined (PPC_OEA)
-	if (oeacpufeat & OEACPU_64_BRIDGE)
-		pmap_setup64bridge();
-	else
-		pmap_setup32();
-#endif
-
-
 	cpuvers = mfpvr() >> 16;
 
 	/*
@@ -289,8 +280,8 @@ oea_init(void (*handler)(void))
 	 * Install a branch absolute to trap0 to force a panic.
 	 */
 	if ((uintptr_t)trap0 < 0x2000000) {
-		*(volatile uint32_t *) 0 = 0x7c6802a6;
-		*(volatile uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0;
+		*(uint32_t *) 0 = 0x7c6802a6;
+		*(uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0;
 	}
 
 	/*
@@ -307,16 +298,6 @@ oea_init(void (*handler)(void))
 #define	B		0x48000000
 #define	TLBSYNC		0x7c00046c
 #define	SYNC		0x7c0004ac
-#ifdef PPC_OEA64_BRIDGE
-#define	MFMSR_MASK	0xfc1fffff
-#define	MFMSR		0x7c0000a6
-#define	MTMSRD_MASK	0xfc1effff
-#define	MTMSRD		0x7c000164
-#define RLDICL_MASK	0xfc00001c
-#define RLDICL		0x78000000
-#define	RFID		0x4c000024
-#define	RFI		0x4c000064
-#endif
 
 #ifdef ALTIVEC
 #define	MFSPR_VRSAVE	0x7c0042a6
@@ -339,7 +320,9 @@ oea_init(void (*handler)(void))
 	if (scratch & PSL_VEC) {
 		cpu_altivec = 1;
 	} else {
-		for (int *ip = trapstart; ip < trapend; ip++) {
+		int *ip = trapstart;
+		
+		for (; ip < trapend; ip++) {
 			if ((ip[0] & MxSPR_MASK) == MFSPR_VRSAVE) {
 				ip[0] = NOP;	/* mfspr */
 				ip[1] = NOP;	/* stw */
@@ -360,7 +343,9 @@ oea_init(void (*handler)(void))
 	 * sequences where we zap/restore BAT registers on kernel exit/entry.
 	 */
 	if (cpuvers != MPC601) {
-		for (int *ip = trapstart; ip < trapend; ip++) {
+		int *ip = trapstart;
+		
+		for (; ip < trapend; ip++) {
 			if ((ip[0] & MxSPR_MASK) == MFSPR_MQ) {
 				ip[0] = NOP;	/* mfspr */
 				ip[1] = NOP;	/* stw */
@@ -376,39 +361,6 @@ oea_init(void (*handler)(void))
 		}
 	}
 
-#ifdef PPC_OEA64_BRIDGE
-	if ((oeacpufeat & OEACPU_64_BRIDGE) == 0) {
-		for (int *ip = (int *)exc_base;
-		     (uintptr_t)ip <= exc_base + EXC_LAST;
-		     ip++) {
-			if ((ip[0] & MFMSR_MASK) == MFMSR
-			    && (ip[1] & RLDICL_MASK) == RLDICL
-			    && (ip[2] & MTMSRD_MASK) == MTMSRD) {
-				*ip++ = NOP;
-				*ip++ = NOP;
-				ip[0] = NOP;
-			} else if (*ip == RFID) {
-				*ip = RFI;
-			}
-		}
-
-		/*
-		 * Now replace each rfid instruction with a rfi instruction.
-		 */
-		for (int *ip = trapstart; ip < trapend; ip++) {
-			if ((ip[0] & MFMSR_MASK) == MFMSR
-			    && (ip[1] & RLDICL_MASK) == RLDICL
-			    && (ip[2] & MTMSRD_MASK) == MTMSRD) {
-				*ip++ = NOP;
-				*ip++ = NOP;
-				ip[0] = NOP;
-			} else if (*ip == RFID) {
-				*ip = RFI;
-			}
-		}
-	}
-#endif /* PPC_OEA64_BRIDGE */
-
 	/*
 	 * Sync the changed instructions.
 	 */
@@ -429,27 +381,29 @@ oea_init(void (*handler)(void))
 		extern int kernel_text[], etext[];
 		int *ip;
 
-		for (ip = kernel_text; ip < etext; ip++) {
+		for (ip = kernel_text; ip < etext; ip++)
 			if (*ip == TLBSYNC) {
 				*ip = SYNC;
 				__syncicache(ip, sizeof(*ip));
-			}
 		}
 	}
 #endif /* PPC_OEA601 */
 
         /*
 	 * Configure a PSL user mask matching this processor.
-	 * Don't allow to set PSL_FP/PSL_VEC, since that will affect PCU.
  	 */
 	cpu_psluserset = PSL_EE | PSL_PR | PSL_ME | PSL_IR | PSL_DR | PSL_RI;
-	cpu_pslusermod = PSL_FE0 | PSL_FE1 | PSL_LE | PSL_SE | PSL_BE;
+	cpu_pslusermod = PSL_FP | PSL_FE0 | PSL_FE1 | PSL_LE | PSL_SE | PSL_BE;
 #ifdef PPC_OEA601
 	if (cpuvers == MPC601) {
 		cpu_psluserset &= PSL_601_MASK;
 		cpu_pslusermod &= PSL_601_MASK;
 	}
 #endif
+#ifdef ALTIVEC
+	if (cpu_altivec)
+		cpu_pslusermod |= PSL_VEC;
+#endif
 #ifdef PPC_HIGH_VEC
 	cpu_psluserset |= PSL_IP;	/* XXX ok? */
 #endif
@@ -494,16 +448,9 @@ mpc601_ioseg_add(paddr_t pa, register_t 
 	 * in pmap_bootstrap().
 	 */
 	iosrtable[i] = SR601(SR601_Ks, SR601_BUID_MEMFORCED, 0, i);
-
-	/*
-	 * XXX Setting segment register 0xf on my powermac 7200
-	 * wedges machine so set later in pmap.c
-	 */
-	/*
 	__asm volatile ("mtsrin %0,%1"
 	    ::	"r"(iosrtable[i]),
 		"r"(pa));
-	*/
 }
 #endif /* PPC_OEA601 */
 
@@ -526,25 +473,12 @@ void
 oea_iobat_add(paddr_t pa, register_t len)
 {
 	static int z = 1;
-	const u_int n = BAT_BL_TO_SIZE(len) / BAT_BL_TO_SIZE(BAT_BL_8M);
+	const u_int n = __SHIFTOUT(len, (BAT_XBL|BAT_BL) & ~BAT_BL_8M);
 	const u_int i = BAT_VA2IDX(pa) & -n; /* in case pa was in the middle */
 	const int after_bat3 = (oeacpufeat & OEACPU_HIGHBAT) ? 4 : 8;
 
 	KASSERT(len >= BAT_BL_8M);
 
-	/*
-	 * If the caller wanted a bigger BAT than the hardware supports,
-	 * split it into smaller BATs.
-	 */
-	if (len > BAT_BL_256M && (oeacpufeat & OEACPU_XBSEN) == 0) {
-		u_int xn = BAT_BL_TO_SIZE(len) >> 28;
-		while (xn-- > 0) {
-			oea_iobat_add(pa, BAT_BL_256M);
-			pa += 0x10000000;
-		}
-		return;
-	} 
-
 	const register_t batl = BATL(pa, BAT_I|BAT_G, BAT_PP_RW);
 	const register_t batu = BATU(pa, len, BAT_Vs);
 
@@ -661,14 +595,11 @@ void
 oea_batinit(paddr_t pa, ...)
 {
 	struct mem_region *allmem, *availmem, *mp;
+	unsigned int cpuvers;
 	register_t msr = mfmsr();
 	va_list ap;
-#ifdef PPC_OEA601
-	unsigned int cpuvers;
 
 	cpuvers = mfpvr() >> 16;
-#endif /* PPC_OEA601 */
-
 	/*
 	 * we need to call this before zapping BATs so OF calls work
 	 */
@@ -885,11 +816,6 @@ oea_install_extint(void (*handler)(void)
 	extern int extint[], extsize[];
 	extern int extint_call[];
 	uintptr_t offset = (uintptr_t)handler - (uintptr_t)extint_call;
-#ifdef PPC_HIGH_VEC
-	const uintptr_t exc_exi_base = EXC_HIGHVEC + EXC_EXI;
-#else
-	const uintptr_t exc_exi_base = EXC_EXI;
-#endif
 	int omsr, msr;
 
 #ifdef	DIAGNOSTIC
@@ -902,26 +828,13 @@ oea_install_extint(void (*handler)(void)
 	    :	"K" ((u_short)~PSL_EE));
 	extint_call[0] = (extint_call[0] & 0xfc000003) | offset;
 	__syncicache((void *)extint_call, sizeof extint_call[0]);
-	memcpy((void *)exc_exi_base, extint, (size_t)extsize);
-#ifdef PPC_OEA64_BRIDGE
-	if ((oeacpufeat & OEACPU_64_BRIDGE) == 0) {
-		for (int *ip = (int *)exc_exi_base;
-		     (uintptr_t)ip <= exc_exi_base + (size_t)extsize;
-		     ip++) {
-			if ((ip[0] & MFMSR_MASK) == MFMSR
-			    && (ip[1] & RLDICL_MASK) == RLDICL
-			    && (ip[2] & MTMSRD_MASK) == MTMSRD) {
-				*ip++ = NOP;
-				*ip++ = NOP;
-				ip[0] = NOP;
-			} else if (*ip == RFID) {
-				*ip = RFI;
-			}
-		}
-	}
+#ifdef PPC_HIGH_VEC
+	memcpy((void *)(EXC_HIGHVEC + EXC_EXI), extint, (size_t)extsize);
+	__syncicache((void *)(EXC_HIGHVEC + EXC_EXI), (int)extsize);
+#else
+	memcpy((void *)EXC_EXI, extint, (size_t)extsize);
+	__syncicache((void *)EXC_EXI, (int)extsize);
 #endif
-	__syncicache((void *)exc_exi_base, (size_t)extsize);
-
 	__asm volatile ("mtmsr %0" :: "r"(omsr));
 }
 
@@ -934,7 +847,7 @@ oea_startup(const char *model)
 	uintptr_t sz;
 	void *v;
 	vaddr_t minaddr, maxaddr;
-	char pbuf[9], mstr[128];
+	char pbuf[9];
 
 	KASSERT(curcpu() != NULL);
 	KASSERT(lwp0.l_cpu != NULL);
@@ -971,8 +884,7 @@ oea_startup(const char *model)
 	printf("%s%s", copyright, version);
 	if (model != NULL)
 		printf("Model: %s\n", model);
-	cpu_identify(mstr, sizeof(mstr));
-	cpu_setmodel("%s", mstr);
+	cpu_identify(NULL, 0);
 
 	format_bytes(pbuf, sizeof(pbuf), ctob((u_int)physmem));
 	printf("total memory = %s\n", pbuf);

Index: src/sys/arch/powerpc/powerpc/fpu.c
diff -u src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.2 src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.3
--- src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.2	Mon Nov 16 09:00:01 2015
+++ src/sys/arch/powerpc/powerpc/fpu.c	Thu Nov 19 08:50:05 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: fpu.c,v 1.31.8.2 2015/11/16 09:00:01 bouyer Exp $	*/
+/*	$NetBSD: fpu.c,v 1.31.8.3 2015/11/19 08:50:05 bouyer Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31.8.2 2015/11/16 09:00:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31.8.3 2015/11/19 08:50:05 bouyer Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -48,7 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31
 #include <machine/psl.h>
 
 #ifdef PPC_HAVE_FPU
-static void fpu_state_load(lwp_t *, u_int);
+static void fpu_state_load(lwp_t *, bool);
 static void fpu_state_save(lwp_t *);
 static void fpu_state_release(lwp_t *);
 #endif
@@ -65,39 +65,39 @@ const pcu_ops_t fpu_ops = {
 bool
 fpu_used_p(lwp_t *l)
 {
-	return pcu_valid_p(&fpu_ops);
+	return (l->l_md.md_flags & MDLWP_USEDFPU) != 0;
 }
 
 void
 fpu_mark_used(lwp_t *l)
 {
-	pcu_discard(&fpu_ops, true);
+	l->l_md.md_flags |= MDLWP_USEDFPU;
 }
 
 #ifdef PPC_HAVE_FPU
 void
-fpu_state_load(lwp_t *l, u_int flags)
+fpu_state_load(lwp_t *l, bool used)
 {
 	struct pcb * const pcb = lwp_getpcb(l);
 
-	if ((flags & PCU_VALID) == 0) {
+	if (__predict_false(!fpu_used_p(l))) {
 		memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu));
+		fpu_mark_used(l);
 	}
 
-	if ((flags & PCU_REENABLE) == 0) {
-		const register_t msr = mfmsr();
-		mtmsr((msr & ~PSL_EE) | PSL_FP);
-		__asm volatile ("isync");
+	const register_t msr = mfmsr();
+        mtmsr((msr & ~PSL_EE) | PSL_FP);
+	__asm volatile ("isync");
 
-		fpu_load_from_fpreg(&pcb->pcb_fpu);
-		__asm volatile ("sync");
+	fpu_load_from_fpreg(&pcb->pcb_fpu);
+	__asm volatile ("sync");
 
-		mtmsr(msr);
-		__asm volatile ("isync");
-	}
+	mtmsr(msr);
+	__asm volatile ("isync");
 
 	curcpu()->ci_ev_fpusw.ev_count++;
 	l->l_md.md_utf->tf_srr1 |= PSL_FP|(pcb->pcb_flags & (PCB_FE0|PCB_FE1));
+	l->l_md.md_flags |= MDLWP_USEDFPU;
 }
 
 /*
@@ -213,7 +213,7 @@ fpu_save_to_mcontext(lwp_t *l, mcontext_
 {
 	KASSERT(l == curlwp);
 
-	if (!pcu_valid_p(&fpu_ops))
+	if (!pcu_used_p(&fpu_ops))
 		return false;
 
 	struct pcb * const pcb = lwp_getpcb(l);
@@ -242,7 +242,7 @@ fpu_restore_from_mcontext(lwp_t *l, cons
 #ifdef PPC_HAVE_FPU
 	/* we don't need to save the state, just drop it */
 	if (l == curlwp)
-		pcu_discard(&fpu_ops, true);
+		pcu_discard(&fpu_ops);
 #endif
 	(void)memcpy(&pcb->pcb_fpu.fpreg, &mcp->__fpregs.__fpu_regs,
 	    sizeof (pcb->pcb_fpu.fpreg));

Reply via email to