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; } }