Module Name:    src
Committed By:   matt
Date:           Sat Dec  8 06:49:00 UTC 2012

Modified Files:
        src/sys/arch/arm/vfp: vfp_init.c

Log Message:
On Cortex, make sure to load/save the upper 16 64-FP registers.
When creating a mcontext_t, make sure _UC_ARM_VFP is set.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/vfp/vfp_init.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/arm/vfp/vfp_init.c
diff -u src/sys/arch/arm/vfp/vfp_init.c:1.9 src/sys/arch/arm/vfp/vfp_init.c:1.10
--- src/sys/arch/arm/vfp/vfp_init.c:1.9	Wed Dec  5 19:30:10 2012
+++ src/sys/arch/arm/vfp/vfp_init.c	Sat Dec  8 06:49:00 2012
@@ -1,4 +1,4 @@
-/*      $NetBSD: vfp_init.c,v 1.9 2012/12/05 19:30:10 matt Exp $ */
+/*      $NetBSD: vfp_init.c,v 1.10 2012/12/08 06:49:00 matt Exp $ */
 
 /*
  * Copyright (c) 2008 ARM Ltd
@@ -90,10 +90,6 @@ read_fpinst2(void)
 	return rv;
 }
 
-/* FSTMD <X>, {d0-d15} */
-#define save_vfpregs(X)	__asm __volatile("stc p11, c0, [%0], {32}" : \
-			    : "r" (X) : "memory")
-
 /* FMXR <X>, fpscr */
 #define write_fpscr(X)	__asm __volatile("mcr p10, 7, %0, c1, c0, 0" : \
 			    : "r" (X))
@@ -107,8 +103,35 @@ read_fpinst2(void)
 #define write_fpinst2(X) __asm __volatile("mcr p10, 7, %0, c10, c0, 0" : \
 			    : "r" (X))
 /* FLDMD <X>, {d0-d15} */
-#define load_vfpregs(X)	__asm __volatile("ldc p11, c0, [%0], {32}" : \
-			    : "r" (X) : "memory");
+static void
+load_vfpregs_lo(uint64_t *p)
+{
+	/* vldmia rN, {d0-d15} */
+	__asm __volatile("ldc\tp11, c0, [%0], {32}" :: "r" (p) : "memory");
+}
+
+/* FSTMD <X>, {d0-d15} */
+static void
+save_vfpregs_lo(uint64_t *p)
+{
+	__asm __volatile("stc\tp11, c0, [%0], {32}" :: "r" (p) : "memory");
+}
+
+#ifdef CPU_CORTEX
+/* FLDMD <X>, {d16-d31} */
+static void
+load_vfpregs_hi(uint64_t *p)
+{
+	__asm __volatile("ldcl\tp11, c0, [%0], {32}" :: "r" (&p[16]) : "memory");
+}
+
+/* FLDMD <X>, {d16-d31} */
+static void
+save_vfpregs_hi(uint64_t *p)
+{
+	__asm __volatile("stcl\tp11, c0, [%0], {32}" :: "r" (&p[16]) : "memory");
+}
+#endif
 
 #ifdef FPU_VFP
 
@@ -231,12 +254,15 @@ vfp_attach(void)
 		uint32_t cpacr = armreg_cpacr_read();
 		cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp);
 		cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp2);
+#if 0
 		if (CPU_ID_CORTEX_P(curcpu()->ci_arm_cpuid)) {
 			/*
-			 * Disable access to the upper 16 FP registers.
+			 * Disable access to the upper 16 FP registers and NEON.
 			 */
 			cpacr |= CPACR_V7_D32DIS;
+			cpacr |= CPACR_V7_ASEDIS;
 		}
+#endif
 		armreg_cpacr_write(cpacr);
 
 		/*
@@ -363,7 +389,21 @@ vfp_state_load(lwp_t *l, bool used)
 	KDASSERT((fpexc & VFP_FPEXC_EX) == 0);
 	write_fpexc(fpexc | VFP_FPEXC_EN);
 
-	load_vfpregs(fregs->vfp_regs);
+	load_vfpregs_lo(fregs->vfp_regs);
+#ifdef CPU_CORTEX
+#ifdef CPU_ARM11
+	switch (curcpu()->ci_vfp_id) {
+	case FPU_VFP_CORTEXA5:
+	case FPU_VFP_CORTEXA7:
+	case FPU_VFP_CORTEXA8:
+	case FPU_VFP_CORTEXA9:
+#endif
+		load_vfpregs_hi(fregs->vfp_regs);
+#ifdef CPU_ARM11
+		break;
+	}
+#endif
+#endif
 	write_fpscr(fregs->vfp_fpscr);
 
 	if (fregs->vfp_fpexc & VFP_FPEXC_EX) {
@@ -431,7 +471,21 @@ vfp_state_save(lwp_t *l)
 		}
 	}
 	fregs->vfp_fpscr = read_fpscr();
-	save_vfpregs(fregs->vfp_regs);
+	save_vfpregs_lo(fregs->vfp_regs);
+#ifdef CPU_CORTEX
+#ifdef CPU_ARM11
+	switch (curcpu()->ci_vfp_id) {
+	case FPU_VFP_CORTEXA5:
+	case FPU_VFP_CORTEXA7:
+	case FPU_VFP_CORTEXA8:
+	case FPU_VFP_CORTEXA9:
+#endif
+		save_vfpregs_hi(fregs->vfp_regs);
+#ifdef CPU_ARM11
+		break;
+	}
+#endif
+#endif
 
 	/* Disable the VFP.  */
 	write_fpexc(fpexc);
@@ -480,7 +534,7 @@ vfp_getcontext(struct lwp *l, mcontext_t
 		mcp->__fpu.__vfpregs.__vfp_fpscr = pcb->pcb_vfp.vfp_fpscr;
 		memcpy(mcp->__fpu.__vfpregs.__vfp_fstmx, pcb->pcb_vfp.vfp_regs,
 		    sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));
-		*flagsp |= _UC_FPU;
+		*flagsp |= _UC_FPU|_UC_ARM_VFP;
 	}
 }
 

Reply via email to