CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: rin Date: Tue Jun 1 00:30:22 UTC 2021 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: PR port-arm/55790 Fix KASSERT failure with floating-point exception in userland. Consider the case in which curlwp owns enabled FPU in vfp_handler(). If FPE is raised, we must skip pcu_load(9) rather than just falling through. Otherwise, KASSERT fires in vfp_state_load(), since curlwp already owns enabled FPU. No regression for ATF is introduced. To generate a diff of this commit: cvs rdiff -u -r1.73 -r1.74 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.73 src/sys/arch/arm/vfp/vfp_init.c:1.74 --- src/sys/arch/arm/vfp/vfp_init.c:1.73 Tue Jun 1 00:13:19 2021 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Jun 1 00:30:22 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.73 2021/06/01 00:13:19 rin Exp $ */ +/* $NetBSD: vfp_init.c,v 1.74 2021/06/01 00:30:22 rin Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -32,7 +32,7 @@ #include "opt_cputypes.h" #include -__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.73 2021/06/01 00:13:19 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.74 2021/06/01 00:30:22 rin Exp $"); #include #include @@ -423,6 +423,7 @@ static int vfp_handler(u_int address, u_int insn, trapframe_t *frame, int fault_code) { struct cpu_info * const ci = curcpu(); + uint32_t fpexc; /* This shouldn't ever happen. */ if (fault_code != FAULT_USER && @@ -436,12 +437,19 @@ vfp_handler(u_int address, u_int insn, t /* * If we already own the FPU and it's enabled (and no exception), raise - * SIGILL. If there is an exception, drop through to raise a SIGFPE. + * SIGILL. If there is an exception, raise SIGFPE. */ - if (curlwp->l_pcu_cpu[PCU_FPU] == ci - && (armreg_fpexc_read() & (VFP_FPEXC_EX|VFP_FPEXC_EN)) == VFP_FPEXC_EN) { + if (curlwp->l_pcu_cpu[PCU_FPU] == ci) { KASSERT(ci->ci_pcu_curlwp[PCU_FPU] == curlwp); - return 1; + + fpexc = armreg_fpexc_read(); + if (fpexc & VFP_FPEXC_EN) { + if ((fpexc & VFP_FPEXC_EX) == 0) { +return 1; /* SIGILL */ + } else { +goto fpe; /* SIGFPE; skip pcu_load(9) */ + } + } } /* @@ -449,11 +457,12 @@ vfp_handler(u_int address, u_int insn, t */ pcu_load(_vfp_ops); - uint32_t fpexc = armreg_fpexc_read(); + fpexc = armreg_fpexc_read(); if (fpexc & VFP_FPEXC_EX) { ksiginfo_t ksi; KASSERT(fpexc & VFP_FPEXC_EN); +fpe: curcpu()->ci_vfp_evs[2].ev_count++; /*
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: rin Date: Tue Jun 1 00:13:19 UTC 2021 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: PR port-arm/55790 Style fix for clarity, in preparation of main fix. Replace condition ``curcpu()->ci_pcu_curlwp[PCU_FPU] == curlwp'' with ``curlwp->l_pcu_cpu[PCU_FPU] == curcpu()''. And add KASSERT to check the two conditions are equivalent, as done for MI pcu code: https://nxr.netbsd.org/xref/src/sys/kern/subr_pcu.c#323 No functional changes. To generate a diff of this commit: cvs rdiff -u -r1.72 -r1.73 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.72 src/sys/arch/arm/vfp/vfp_init.c:1.73 --- src/sys/arch/arm/vfp/vfp_init.c:1.72 Fri Oct 30 18:54:37 2020 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Jun 1 00:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.72 2020/10/30 18:54:37 skrll Exp $ */ +/* $NetBSD: vfp_init.c,v 1.73 2021/06/01 00:13:19 rin Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -32,7 +32,7 @@ #include "opt_cputypes.h" #include -__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.72 2020/10/30 18:54:37 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.73 2021/06/01 00:13:19 rin Exp $"); #include #include @@ -438,9 +438,11 @@ vfp_handler(u_int address, u_int insn, t * If we already own the FPU and it's enabled (and no exception), raise * SIGILL. If there is an exception, drop through to raise a SIGFPE. */ - if (curcpu()->ci_pcu_curlwp[PCU_FPU] == curlwp - && (armreg_fpexc_read() & (VFP_FPEXC_EX|VFP_FPEXC_EN)) == VFP_FPEXC_EN) + if (curlwp->l_pcu_cpu[PCU_FPU] == ci + && (armreg_fpexc_read() & (VFP_FPEXC_EX|VFP_FPEXC_EN)) == VFP_FPEXC_EN) { + KASSERT(ci->ci_pcu_curlwp[PCU_FPU] == curlwp); return 1; + } /* * Make sure we own the FP.
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: riastradh Date: Sat Aug 1 02:13:04 UTC 2020 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add kthread_fpu_enter/exit support to arm. To generate a diff of this commit: cvs rdiff -u -r1.70 -r1.71 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.70 src/sys/arch/arm/vfp/vfp_init.c:1.71 --- src/sys/arch/arm/vfp/vfp_init.c:1.70 Mon Jul 27 20:51:29 2020 +++ src/sys/arch/arm/vfp/vfp_init.c Sat Aug 1 02:13:04 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.70 2020/07/27 20:51:29 riastradh Exp $ */ +/* $NetBSD: vfp_init.c,v 1.71 2020/08/01 02:13:04 riastradh Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -32,12 +32,13 @@ #include "opt_cputypes.h" #include -__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.70 2020/07/27 20:51:29 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.71 2020/08/01 02:13:04 riastradh Exp $"); #include #include #include #include +#include #include #include @@ -424,7 +425,8 @@ vfp_handler(u_int address, u_int insn, t struct cpu_info * const ci = curcpu(); /* This shouldn't ever happen. */ - if (fault_code != FAULT_USER) + if (fault_code != FAULT_USER && + (curlwp->l_flag & (LW_SYSTEM|LW_SYSTEM_FPU)) == LW_SYSTEM) panic("VFP fault at %#x in non-user mode", frame->tf_pc); if (ci->ci_vfp_id == 0) { @@ -504,7 +506,8 @@ neon_handler(u_int address, u_int insn, return 1; /* This shouldn't ever happen. */ - if (fault_code != FAULT_USER) + if (fault_code != FAULT_USER && + (curlwp->l_flag & (LW_SYSTEM|LW_SYSTEM_FPU)) == LW_SYSTEM) panic("NEON fault in non-user mode"); /* if we already own the FPU and it's enabled, raise SIGILL */ @@ -668,6 +671,19 @@ vfp_setcontext(struct lwp *l, const mcon sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx)); } +/* + * True if this is a system thread with its own private FPU state. + */ +static inline bool +lwp_system_fpu_p(struct lwp *l) +{ + + return (l->l_flag & (LW_SYSTEM|LW_SYSTEM_FPU)) == + (LW_SYSTEM|LW_SYSTEM_FPU); +} + +static const struct vfpreg zero_vfpreg; + void fpu_kern_enter(void) { @@ -675,6 +691,11 @@ fpu_kern_enter(void) uint32_t fpexc; int s; + if (lwp_system_fpu_p(curlwp) && !cpu_intr_p()) { + KASSERT(!cpu_softintr_p()); + return; + } + /* * Block interrupts up to IPL_VM. We must block preemption * since -- if this is a user thread -- there is nowhere to @@ -701,11 +722,15 @@ fpu_kern_enter(void) void fpu_kern_leave(void) { - static const struct vfpreg zero_vfpreg; struct cpu_info *ci = curcpu(); int s; uint32_t fpexc; + if (lwp_system_fpu_p(curlwp) && !cpu_intr_p()) { + KASSERT(!cpu_softintr_p()); + return; + } + KASSERT(ci->ci_cpl == IPL_VM); KASSERT(ci->ci_kfpu_spl != -1); @@ -730,4 +755,20 @@ fpu_kern_leave(void) splx(s); } +void +kthread_fpu_enter_md(void) +{ + + pcu_load(_vfp_ops); +} + +void +kthread_fpu_exit_md(void) +{ + + /* XXX Should vfp_state_release zero the registers itself? */ + load_vfpregs(_vfpreg); + vfp_discardcontext(curlwp, 0); +} + #endif /* FPU_VFP */
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: riastradh Date: Mon Jul 13 16:53:06 UTC 2020 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Limit arm32 fpu_kern_enter/leave to IPL_VM or below. To generate a diff of this commit: cvs rdiff -u -r1.66 -r1.67 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.66 src/sys/arch/arm/vfp/vfp_init.c:1.67 --- src/sys/arch/arm/vfp/vfp_init.c:1.66 Mon Jun 29 23:56:31 2020 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Jul 13 16:53:06 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.66 2020/06/29 23:56:31 riastradh Exp $ */ +/* $NetBSD: vfp_init.c,v 1.67 2020/07/13 16:53:06 riastradh Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -32,7 +32,7 @@ #include "opt_cputypes.h" #include -__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.66 2020/06/29 23:56:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.67 2020/07/13 16:53:06 riastradh Exp $"); #include #include @@ -674,14 +674,15 @@ fpu_kern_enter(void) int s; /* - * Block all interrupts. We must block preemption since -- if - * this is a user thread -- there is nowhere to save the kernel - * fpu state, and if we want this to be usable in interrupts, - * we can't let interrupts interfere with the fpu state in use - * since there's nowhere for them to save it. + * Block interrupts up to IPL_VM. We must block preemption + * since -- if this is a user thread -- there is nowhere to + * save the kernel fpu state, and if we want this to be usable + * in interrupts, we can't let interrupts interfere with the + * fpu state in use since there's nowhere for them to save it. */ - s = splhigh(); + s = splvm(); ci = curcpu(); + KASSERTMSG(ci->ci_cpl <= IPL_VM, "cpl=%d", ci->ci_cpl); KASSERT(ci->ci_kfpu_spl == -1); ci->ci_kfpu_spl = s; @@ -709,7 +710,7 @@ fpu_kern_leave(void) int s; uint32_t fpexc; - KASSERT(ci->ci_cpl == IPL_HIGH); + KASSERT(ci->ci_cpl == IPL_VM); KASSERT(ci->ci_kfpu_spl != -1); /*
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: skrll Date: Sat Apr 6 08:48:53 UTC 2019 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Install the undefined instruction handlers only once, i.e. when attaching on the BP. To generate a diff of this commit: cvs rdiff -u -r1.61 -r1.62 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.61 src/sys/arch/arm/vfp/vfp_init.c:1.62 --- src/sys/arch/arm/vfp/vfp_init.c:1.61 Sun Mar 17 08:41:42 2019 +++ src/sys/arch/arm/vfp/vfp_init.c Sat Apr 6 08:48:53 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.61 2019/03/17 08:41:42 skrll Exp $ */ +/* $NetBSD: vfp_init.c,v 1.62 2019/04/06 08:48:53 skrll Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -32,7 +32,7 @@ #include "opt_cputypes.h" #include -__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.61 2019/03/17 08:41:42 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.62 2019/04/06 08:48:53 skrll Exp $"); #include #include @@ -260,7 +260,8 @@ vfp_attach(struct cpu_info *ci) if ((nsacr & nsacr_vfp) != nsacr_vfp) { aprint_normal_dev(ci->ci_dev, "VFP access denied (NSACR=%#x)\n", nsacr); - install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); + if (CPU_IS_PRIMARY(ci)) +install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); ci->ci_vfp_id = 0; evcnt_attach_dynamic(>ci_vfp_evs[0], EVCNT_TYPE_TRAP, NULL, ci->ci_cpuname, @@ -290,7 +291,8 @@ vfp_attach(struct cpu_info *ci) if (!vfp_p) { aprint_normal_dev(ci->ci_dev, "VFP access denied (CPACR=%#x)\n", cpacr); - install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); + if (CPU_IS_PRIMARY(ci)) +install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); ci->ci_vfp_id = 0; evcnt_attach_dynamic(>ci_vfp_evs[0], EVCNT_TYPE_TRAP, NULL, ci->ci_cpuname, @@ -309,7 +311,8 @@ vfp_attach(struct cpu_info *ci) if (undefined_test != 0) { aprint_normal_dev(ci->ci_dev, "No VFP detected\n"); - install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); + if (CPU_IS_PRIMARY(ci)) + install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); ci->ci_vfp_id = 0; return; } @@ -343,7 +346,8 @@ vfp_attach(struct cpu_info *ci) default: aprint_normal_dev(ci->ci_dev, "unrecognized VFP version %#x\n", fpsid); - install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); + if (CPU_IS_PRIMARY(ci)) + install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); vfp_fpscr_changable = VFP_FPSCR_CSUM|VFP_FPSCR_ESUM |VFP_FPSCR_RMODE; vfp_fpscr_default = 0; @@ -391,12 +395,14 @@ vfp_attach(struct cpu_info *ci) ci->ci_cpuname, "vfp coproc re-use"); evcnt_attach_dynamic(>ci_vfp_evs[2], EVCNT_TYPE_TRAP, NULL, ci->ci_cpuname, "vfp coproc fault"); - install_coproc_handler(VFP_COPROC, vfp_handler); - install_coproc_handler(VFP_COPROC2, vfp_handler); + if (CPU_IS_PRIMARY(ci)) { + install_coproc_handler(VFP_COPROC, vfp_handler); + install_coproc_handler(VFP_COPROC2, vfp_handler); #ifdef CPU_CORTEX - if (cpu_neon_present) - install_coproc_handler(CORE_UNKNOWN_HANDLER, neon_handler); + if (cpu_neon_present) + install_coproc_handler(CORE_UNKNOWN_HANDLER, neon_handler); #endif + } } /* The real handler for VFP bounces. */
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: skrll Date: Sun Mar 17 08:41:42 UTC 2019 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Trailing whitespace To generate a diff of this commit: cvs rdiff -u -r1.60 -r1.61 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.60 src/sys/arch/arm/vfp/vfp_init.c:1.61 --- src/sys/arch/arm/vfp/vfp_init.c:1.60 Sun Jan 27 02:08:37 2019 +++ src/sys/arch/arm/vfp/vfp_init.c Sun Mar 17 08:41:42 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.60 2019/01/27 02:08:37 pgoyette Exp $ */ +/* $NetBSD: vfp_init.c,v 1.61 2019/03/17 08:41:42 skrll Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -32,7 +32,7 @@ #include "opt_cputypes.h" #include -__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.60 2019/01/27 02:08:37 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.61 2019/03/17 08:41:42 skrll Exp $"); #include #include @@ -225,7 +225,7 @@ vfp_fpscr_handler(u_int address, u_int i } curcpu()->ci_vfp_evs[0].ev_count++; - + frame->tf_pc += INSN_SIZE; return 0; }
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: skrll Date: Wed Aug 15 05:52:15 UTC 2018 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add __KERNEL_RCSID To generate a diff of this commit: cvs rdiff -u -r1.57 -r1.58 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.57 src/sys/arch/arm/vfp/vfp_init.c:1.58 --- src/sys/arch/arm/vfp/vfp_init.c:1.57 Sun Apr 8 09:19:27 2018 +++ src/sys/arch/arm/vfp/vfp_init.c Wed Aug 15 05:52:15 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.57 2018/04/08 09:19:27 bouyer Exp $ */ +/* $NetBSD: vfp_init.c,v 1.58 2018/08/15 05:52:15 skrll Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -29,6 +29,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +__KERNEL_RCSID(0, "$NetBSD: vfp_init.c,v 1.58 2018/08/15 05:52:15 skrll Exp $"); + #include #include #include
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: bouyer Date: Sun Apr 8 09:19:27 UTC 2018 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Remove the call to vfp_fpscr_handler() from vfp_handler(). It actually never avoids a full FPU switch, and costs a function call and a few tests. Discussed on port-arm@ on october 2017: http://mail-index.netbsd.org/port-arm/2017/10/16/msg004411.html To generate a diff of this commit: cvs rdiff -u -r1.56 -r1.57 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.56 src/sys/arch/arm/vfp/vfp_init.c:1.57 --- src/sys/arch/arm/vfp/vfp_init.c:1.56 Fri Mar 2 23:07:55 2018 +++ src/sys/arch/arm/vfp/vfp_init.c Sun Apr 8 09:19:27 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.56 2018/03/02 23:07:55 christos Exp $ */ +/* $NetBSD: vfp_init.c,v 1.57 2018/04/08 09:19:27 bouyer Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -409,13 +409,6 @@ vfp_handler(u_int address, u_int insn, t return 1; } - /* - * If we are just changing/fetching FPSCR, don't bother loading it - * just emulate the instruction. - */ - if (!vfp_fpscr_handler(address, insn, frame, fault_code)) - return 0; - /* * If we already own the FPU and it's enabled (and no exception), raise * SIGILL. If there is an exception, drop through to raise a SIGFPE.
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: christos Date: Fri Mar 2 23:07:55 UTC 2018 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add more vfp directives for gcc-6 To generate a diff of this commit: cvs rdiff -u -r1.55 -r1.56 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.55 src/sys/arch/arm/vfp/vfp_init.c:1.56 --- src/sys/arch/arm/vfp/vfp_init.c:1.55 Mon Oct 16 11:13:00 2017 +++ src/sys/arch/arm/vfp/vfp_init.c Fri Mar 2 18:07:55 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.55 2017/10/16 15:13:00 bouyer Exp $ */ +/* $NetBSD: vfp_init.c,v 1.56 2018/03/02 23:07:55 christos Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -47,23 +47,26 @@ #ifdef FPU_VFP #ifdef CPU_CORTEX -__asm(".fpu\tvfpv4"); +#define SETFPU __asm(".fpu\tvfpv4") #else -__asm(".fpu\tvfp"); +#define SETFPU __asm(".fpu\tvfp") #endif +SETFPU; /* FLDMD , {d0-d15} */ static inline void load_vfpregs_lo(const uint64_t *p) { - __asm __volatile("vldmia %0, {d0-d15}" :: "r" (p) : "memory"); + SETFPU; + __asm __volatile("vldmia\t%0, {d0-d15}" :: "r" (p) : "memory"); } /* FSTMD , {d0-d15} */ static inline void save_vfpregs_lo(uint64_t *p) { - __asm __volatile("vstmia %0, {d0-d15}" :: "r" (p) : "memory"); + SETFPU; + __asm __volatile("vstmia\t%0, {d0-d15}" :: "r" (p) : "memory"); } #ifdef CPU_CORTEX @@ -71,6 +74,7 @@ save_vfpregs_lo(uint64_t *p) static inline void load_vfpregs_hi(const uint64_t *p) { + SETFPU; __asm __volatile("vldmia\t%0, {d16-d31}" :: "r" ([16]) : "memory"); } @@ -78,6 +82,7 @@ load_vfpregs_hi(const uint64_t *p) static inline void save_vfpregs_hi(uint64_t *p) { + SETFPU; __asm __volatile("vstmia\t%0, {d16-d31}" :: "r" ([16]) : "memory"); } #endif
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: bouyer Date: Mon Oct 16 15:13:01 UTC 2017 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: We KASSERT((fregs->vfp_fpexc & VFP_FPEXC_EN) == 0) just before, so enabled is always false. remove. To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 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.54 src/sys/arch/arm/vfp/vfp_init.c:1.55 --- src/sys/arch/arm/vfp/vfp_init.c:1.54 Mon Oct 16 15:08:24 2017 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Oct 16 15:13:00 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.54 2017/10/16 15:08:24 bouyer Exp $ */ +/* $NetBSD: vfp_init.c,v 1.55 2017/10/16 15:13:00 bouyer Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -535,17 +535,8 @@ vfp_state_load(lwp_t *l, u_int flags) /* * Load and Enable the VFP (so that we can write the registers). */ - bool enabled = fregs->vfp_fpexc & VFP_FPEXC_EN; fregs->vfp_fpexc |= VFP_FPEXC_EN; armreg_fpexc_write(fregs->vfp_fpexc); - if (enabled) { - /* - * If we think the VFP is enabled, it must have be - * disabled by vfp_state_release for another LWP so - * we can now just return. - */ - return; - } KASSERT(curcpu()->ci_pcu_curlwp[PCU_FPU] == NULL); KASSERT(l->l_pcu_cpu[PCU_FPU] == NULL);
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: bouyer Date: Mon Oct 16 15:08:24 UTC 2017 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: In the REENABLE case, make sur the fpexc copy in the pcb also has VFP_FPEXC_EN set. Otherwise we could trap on every context switch even if the CPU already has the VFP state. To generate a diff of this commit: cvs rdiff -u -r1.53 -r1.54 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.53 src/sys/arch/arm/vfp/vfp_init.c:1.54 --- src/sys/arch/arm/vfp/vfp_init.c:1.53 Fri May 26 21:17:46 2017 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Oct 16 15:08:24 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.53 2017/05/26 21:17:46 jmcneill Exp $ */ +/* $NetBSD: vfp_init.c,v 1.54 2017/10/16 15:08:24 bouyer Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -520,14 +520,17 @@ vfp_state_load(lwp_t *l, u_int flags) curcpu()->ci_vfp_evs[1].ev_count++; } + KASSERT((armreg_fpexc_read() & VFP_FPEXC_EN) == 0); /* * If the VFP is already enabled we must be bouncing an instruction. */ if (flags & PCU_REENABLE) { uint32_t fpexc = armreg_fpexc_read(); armreg_fpexc_write(fpexc | VFP_FPEXC_EN); + fregs->vfp_fpexc |= VFP_FPEXC_EN; return; } + KASSERT((fregs->vfp_fpexc & VFP_FPEXC_EN) == 0); /* * Load and Enable the VFP (so that we can write the registers). @@ -543,6 +546,8 @@ vfp_state_load(lwp_t *l, u_int flags) */ return; } + KASSERT(curcpu()->ci_pcu_curlwp[PCU_FPU] == NULL); + KASSERT(l->l_pcu_cpu[PCU_FPU] == NULL); load_vfpregs(fregs); armreg_fpscr_write(fregs->vfp_fpscr); @@ -562,6 +567,9 @@ vfp_state_save(lwp_t *l) struct vfpreg * const fregs = >pcb_vfp; uint32_t fpexc = armreg_fpexc_read(); + KASSERT(curcpu()->ci_pcu_curlwp[PCU_FPU] == l); + KASSERT(curcpu() == l->l_pcu_cpu[PCU_FPU]); + KASSERT(curlwp == l || curlwp->l_pcu_cpu[PCU_FPU] != curcpu()); /* * Enable the VFP (so we can read the registers). * Make sure the exception bit is cleared so that we can
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: chs Date: Wed Mar 22 23:36:02 UTC 2017 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: in vfp_state_load(), fix backwards logic for fpinst vs. fpinst2. To generate a diff of this commit: cvs rdiff -u -r1.51 -r1.52 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.51 src/sys/arch/arm/vfp/vfp_init.c:1.52 --- src/sys/arch/arm/vfp/vfp_init.c:1.51 Thu Mar 16 16:13:20 2017 +++ src/sys/arch/arm/vfp/vfp_init.c Wed Mar 22 23:36:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.51 2017/03/16 16:13:20 chs Exp $ */ +/* $NetBSD: vfp_init.c,v 1.52 2017/03/22 23:36:02 chs Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -546,9 +546,9 @@ vfp_state_load(lwp_t *l, u_int flags) if (fregs->vfp_fpexc & VFP_FPEXC_EX) { /* Need to restore the exception handling state. */ - armreg_fpinst2_write(fregs->vfp_fpinst2); + armreg_fpinst_write(fregs->vfp_fpinst); if (fregs->vfp_fpexc & VFP_FPEXC_FP2V) - armreg_fpinst_write(fregs->vfp_fpinst); + armreg_fpinst2_write(fregs->vfp_fpinst2); } }
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: jmcneill Date: Tue Apr 28 17:14:21 UTC 2015 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: isb after writing cpacr, from Andrew Turner To generate a diff of this commit: cvs rdiff -u -r1.47 -r1.48 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.47 src/sys/arch/arm/vfp/vfp_init.c:1.48 --- src/sys/arch/arm/vfp/vfp_init.c:1.47 Mon Mar 23 17:42:02 2015 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Apr 28 17:14:21 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.47 2015/03/23 17:42:02 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.48 2015/04/28 17:14:21 jmcneill Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -265,6 +265,8 @@ vfp_attach(struct cpu_info *ci) cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp2); armreg_cpacr_write(cpacr); + arm_isb(); + /* * If we could enable them, then they exist. */
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Mon Mar 23 17:42:02 UTC 2015 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Fix some inverted return values. Don't return SIGILL if there is an active FPU exception. To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.47 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.46 src/sys/arch/arm/vfp/vfp_init.c:1.47 --- src/sys/arch/arm/vfp/vfp_init.c:1.46 Fri Mar 20 01:27:34 2015 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Mar 23 17:42:02 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.46 2015/03/20 01:27:34 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.47 2015/03/23 17:42:02 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -397,15 +397,19 @@ vfp_handler(u_int address, u_int insn, t } /* - * If we are just changing/fetching FPSCR, don't bother loading it. + * If we are just changing/fetching FPSCR, don't bother loading it + * just emulate the instruction. */ if (!vfp_fpscr_handler(address, insn, frame, fault_code)) - return 1; + return 0; - /* if we already own the FPU and it's enabled, raise SIGILL */ + /* + * If we already own the FPU and it's enabled (and no exception), raise + * SIGILL. If there is an exception, drop through to raise a SIGFPE. + */ if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp - (armreg_fpexc_read() VFP_FPEXC_EN) != 0) - return 0; + (armreg_fpexc_read() (VFP_FPEXC_EX|VFP_FPEXC_EN)) == VFP_FPEXC_EN) + return 1; /* * Make sure we own the FP. @@ -477,7 +481,7 @@ neon_handler(u_int address, u_int insn, /* if we already own the FPU and it's enabled, raise SIGILL */ if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp (armreg_fpexc_read() VFP_FPEXC_EN) != 0) - return 0; + return 1; pcu_load(arm_vfp_ops);
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Fri Mar 20 01:27:34 UTC 2015 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Remove extra ) To generate a diff of this commit: cvs rdiff -u -r1.45 -r1.46 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.45 src/sys/arch/arm/vfp/vfp_init.c:1.46 --- src/sys/arch/arm/vfp/vfp_init.c:1.45 Fri Mar 20 00:54:30 2015 +++ src/sys/arch/arm/vfp/vfp_init.c Fri Mar 20 01:27:34 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.45 2015/03/20 00:54:30 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.46 2015/03/20 01:27:34 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -403,7 +403,7 @@ vfp_handler(u_int address, u_int insn, t return 1; /* if we already own the FPU and it's enabled, raise SIGILL */ - if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp) + if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp (armreg_fpexc_read() VFP_FPEXC_EN) != 0) return 0;
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Fri Mar 20 00:54:30 UTC 2015 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Not only check to see if we own the VFP but that the VFP is enabled. To generate a diff of this commit: cvs rdiff -u -r1.44 -r1.45 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.44 src/sys/arch/arm/vfp/vfp_init.c:1.45 --- src/sys/arch/arm/vfp/vfp_init.c:1.44 Tue Mar 17 22:34:10 2015 +++ src/sys/arch/arm/vfp/vfp_init.c Fri Mar 20 00:54:30 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.44 2015/03/17 22:34:10 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.45 2015/03/20 00:54:30 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -402,8 +402,9 @@ vfp_handler(u_int address, u_int insn, t if (!vfp_fpscr_handler(address, insn, frame, fault_code)) return 1; - /* if we already own the FPU, raise SIGILL */ + /* if we already own the FPU and it's enabled, raise SIGILL */ if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp) + (armreg_fpexc_read() VFP_FPEXC_EN) != 0) return 0; /* @@ -473,8 +474,9 @@ neon_handler(u_int address, u_int insn, if (fault_code != FAULT_USER) panic(NEON fault in non-user mode); - /* if we already own the FPU, raise SIGILL */ - if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp) + /* if we already own the FPU and it's enabled, raise SIGILL */ + if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp + (armreg_fpexc_read() VFP_FPEXC_EN) != 0) return 0; pcu_load(arm_vfp_ops);
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Tue Mar 17 17:20:55 UTC 2015 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: If we own the FPU, don't take anymore undefined faults. Instead generate SIGILLs since we obviously don't understand the instruction. To generate a diff of this commit: cvs rdiff -u -r1.42 -r1.43 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.42 src/sys/arch/arm/vfp/vfp_init.c:1.43 --- src/sys/arch/arm/vfp/vfp_init.c:1.42 Mon Feb 9 07:55:52 2015 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Mar 17 17:20:55 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.42 2015/02/09 07:55:52 slp Exp $ */ +/* $NetBSD: vfp_init.c,v 1.43 2015/03/17 17:20:55 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -376,7 +376,8 @@ vfp_attach(struct cpu_info *ci) install_coproc_handler(VFP_COPROC, vfp_handler); install_coproc_handler(VFP_COPROC2, vfp_handler); #ifdef CPU_CORTEX - install_coproc_handler(CORE_UNKNOWN_HANDLER, neon_handler); + if (cpu_neon_present) + install_coproc_handler(CORE_UNKNOWN_HANDLER, neon_handler); #endif } @@ -399,7 +400,7 @@ vfp_handler(u_int address, u_int insn, t * If we are just changing/fetching FPSCR, don't bother loading it. */ if (!vfp_fpscr_handler(address, insn, frame, fault_code)) - return 0; + return 1; /* * Make sure we own the FP. @@ -468,6 +469,10 @@ neon_handler(u_int address, u_int insn, if (fault_code != FAULT_USER) panic(NEON fault in non-user mode); + /* if we already own the FPU, raise SIGILL */ + if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp) + return 0; + pcu_load(arm_vfp_ops); /* Need to restart the faulted instruction. */
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Tue Mar 17 22:34:10 UTC 2015 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Don't try to catch undefined VFP instructions if we own the the FPU. Let them raise SIGILL. To generate a diff of this commit: cvs rdiff -u -r1.43 -r1.44 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.43 src/sys/arch/arm/vfp/vfp_init.c:1.44 --- src/sys/arch/arm/vfp/vfp_init.c:1.43 Tue Mar 17 17:20:55 2015 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Mar 17 22:34:10 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.43 2015/03/17 17:20:55 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.44 2015/03/17 22:34:10 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -402,6 +402,10 @@ vfp_handler(u_int address, u_int insn, t if (!vfp_fpscr_handler(address, insn, frame, fault_code)) return 1; + /* if we already own the FPU, raise SIGILL */ + if (curcpu()-ci_pcu_curlwp[PCU_FPU] == curlwp) + return 0; + /* * Make sure we own the FP. */
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Fri Jul 18 22:54:53 UTC 2014 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: fix typo reported in PR/48948 To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 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.40 src/sys/arch/arm/vfp/vfp_init.c:1.41 --- src/sys/arch/arm/vfp/vfp_init.c:1.40 Sun Jun 15 23:07:36 2014 +++ src/sys/arch/arm/vfp/vfp_init.c Fri Jul 18 22:54:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.40 2014/06/15 23:07:36 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.41 2014/07/18 22:54:53 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -334,7 +334,7 @@ vfp_attach(struct cpu_info *ci) cpu_media_and_vfp_features[1] = armreg_mvfr1_read(); if (fpsid != 0) { uint32_t f0 = armreg_mvfr0_read(); - uint32_t f1 = armreg_mvfr0_read(); + uint32_t f1 = armreg_mvfr1_read(); aprint_normal(vfp%d at %s: %s%s%s%s%s\n, device_unit(ci-ci_dev), device_xname(ci-ci_dev),
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Sun Jun 15 23:07:36 UTC 2014 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Cleanup a bit of the init logic. To generate a diff of this commit: cvs rdiff -u -r1.39 -r1.40 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.39 src/sys/arch/arm/vfp/vfp_init.c:1.40 --- src/sys/arch/arm/vfp/vfp_init.c:1.39 Fri May 16 00:48:41 2014 +++ src/sys/arch/arm/vfp/vfp_init.c Sun Jun 15 23:07:36 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.39 2014/05/16 00:48:41 rmind Exp $ */ +/* $NetBSD: vfp_init.c,v 1.40 2014/06/15 23:07:36 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -242,7 +242,8 @@ vfp_attach(struct cpu_info *ci) const uint32_t nsacr = armreg_nsacr_read(); const uint32_t nsacr_vfp = __BITS(VFP_COPROC,VFP_COPROC2); if ((nsacr nsacr_vfp) != nsacr_vfp) { - aprint_normal_dev(ci-ci_dev, VFP access denied\n); + aprint_normal_dev(ci-ci_dev, + VFP access denied (NSACR=%#x)\n, nsacr); install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); ci-ci_vfp_id = 0; evcnt_attach_dynamic(ci-ci_vfp_evs[0], @@ -266,10 +267,11 @@ vfp_attach(struct cpu_info *ci) * If we could enable them, then they exist. */ cpacr = armreg_cpacr_read(); - bool vfp_p = __SHIFTOUT(cpacr, cpacr_vfp2) != CPACR_NOACCESS - || __SHIFTOUT(cpacr, cpacr_vfp) != CPACR_NOACCESS; + bool vfp_p = __SHIFTOUT(cpacr, cpacr_vfp2) == CPACR_ALL + __SHIFTOUT(cpacr, cpacr_vfp) == CPACR_ALL; if (!vfp_p) { - aprint_normal_dev(ci-ci_dev, No VFP detected\n); + aprint_normal_dev(ci-ci_dev, + VFP access denied (CPACR=%#x)\n, cpacr); install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); ci-ci_vfp_id = 0; evcnt_attach_dynamic(ci-ci_vfp_evs[0],
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Tue Mar 4 08:32:23 UTC 2014 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add a different version vfp_fpscr_changable if FPU_VFP was not defined. If no FPU was found, reinit vfp_fpscr_changeable/default to values appropriate for softfloat. To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 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.34 src/sys/arch/arm/vfp/vfp_init.c:1.35 --- src/sys/arch/arm/vfp/vfp_init.c:1.34 Mon Mar 3 08:45:18 2014 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Mar 4 08:32:23 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.34 2014/03/03 08:45:18 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.35 2014/03/04 08:32:23 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -44,9 +44,6 @@ #include uvm/uvm_extern.h /* for pmap.h */ -extern int cpu_media_and_vfp_features[]; -extern int cpu_neon_present; - #ifdef FPU_VFP #ifdef CPU_CORTEX @@ -171,6 +168,9 @@ vfp_test(u_int address, u_int insn, trap return 0; } +#else +/* determine what bits can be changed */ +uint32_t vfp_fpscr_changable = VFP_FPSCR_CSUM|VFP_FPSCR_ESUM|VFP_FPSCR_RMODE; #endif /* FPU_VFP */ struct evcnt vfp_fpscr_ev = @@ -201,8 +201,7 @@ vfp_fpscr_handler(u_int address, u_int i return 1; if (__predict_false(!vfp_used_p())) { - pcb-pcb_vfp.vfp_fpscr = - (VFP_FPSCR_DN | VFP_FPSCR_FZ | VFP_FPSCR_RN); /* Runfast */ + pcb-pcb_vfp.vfp_fpscr = vfp_fpscr_default; } #endif @@ -341,6 +340,9 @@ vfp_attach(void) aprint_normal_dev(ci-ci_dev, unrecognized VFP version %x\n, fpsid); install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); + vfp_fpscr_changable = VFP_FPSCR_CSUM|VFP_FPSCR_ESUM + |VFP_FPSCR_RMODE; + vfp_fpscr_default = 0; return; }
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: skrll Date: Fri Jan 24 08:26:39 UTC 2014 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Be consistent about setting fpscr for Runfast. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 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.31 src/sys/arch/arm/vfp/vfp_init.c:1.32 --- src/sys/arch/arm/vfp/vfp_init.c:1.31 Thu Jan 23 17:44:13 2014 +++ src/sys/arch/arm/vfp/vfp_init.c Fri Jan 24 08:26:39 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.31 2014/01/23 17:44:13 skrll Exp $ */ +/* $NetBSD: vfp_init.c,v 1.32 2014/01/24 08:26:39 skrll Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -197,7 +197,7 @@ vfp_fpscr_handler(u_int address, u_int i if (__predict_false(!vfp_used_p())) { pcb-pcb_vfp.vfp_fpscr = - (VFP_FPSCR_DN | VFP_FPSCR_FZ); /* Runfast */ + (VFP_FPSCR_DN | VFP_FPSCR_FZ | VFP_FPSCR_RN); /* Runfast */ } #endif @@ -500,8 +500,8 @@ vfp_state_load(lwp_t *l, u_int flags) */ if (__predict_false((flags PCU_LOADED) == 0)) { vfpevent_use.ev_count++; - pcb-pcb_vfp.vfp_fpscr = /* Runfast */ - (VFP_FPSCR_DN | VFP_FPSCR_FZ | VFP_FPSCR_RN); + pcb-pcb_vfp.vfp_fpscr = + (VFP_FPSCR_DN | VFP_FPSCR_FZ | VFP_FPSCR_RN); /* Runfast */ } else { vfpevent_reuse.ev_count++; }
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: skrll Date: Tue Jan 21 12:47:21 UTC 2014 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Typo in comment To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 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.29 src/sys/arch/arm/vfp/vfp_init.c:1.30 --- src/sys/arch/arm/vfp/vfp_init.c:1.29 Fri Dec 27 12:16:01 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Jan 21 12:47:20 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.29 2013/12/27 12:16:01 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.30 2014/01/21 12:47:20 skrll Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -202,7 +202,7 @@ vfp_fpscr_handler(u_int address, u_int i #endif /* - * We know know the pcb has the saved copy. + * We now know the pcb has the saved copy. */ register_t * const regp = frame-tf_r0 + regno; if (insn 0x0010) {
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Sat Dec 14 15:47:18 UTC 2013 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: If we can't enable VFP/VFP2 via the CPACCESS register, bail since there isn't a VFP. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 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.27 src/sys/arch/arm/vfp/vfp_init.c:1.28 --- src/sys/arch/arm/vfp/vfp_init.c:1.27 Mon Nov 18 18:02:01 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Sat Dec 14 15:47:18 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.27 2013/11/18 18:02:01 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.28 2013/12/14 15:47:18 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -261,7 +261,6 @@ vfp_attach(void) { struct cpu_info * const ci = curcpu(); const char *model = NULL; - bool vfp_p = false; if (CPU_ID_ARM11_P(curcpu()-ci_arm_cpuid) || CPU_ID_CORTEX_P(curcpu()-ci_arm_cpuid)) { @@ -289,8 +288,14 @@ vfp_attach(void) * If we could enable them, then they exist. */ cpacr = armreg_cpacr_read(); - vfp_p = __SHIFTOUT(cpacr, cpacr_vfp2) != CPACR_NOACCESS + bool vfp_p = __SHIFTOUT(cpacr, cpacr_vfp2) != CPACR_NOACCESS || __SHIFTOUT(cpacr, cpacr_vfp) != CPACR_NOACCESS; + if (!vfp_p) { + aprint_normal_dev(ci-ci_dev, No VFP detected\n); + install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); + ci-ci_vfp_id = 0; + return; + } } void *uh = install_coproc_handler(VFP_COPROC, vfp_test);
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Mon Nov 18 18:02:01 UTC 2013 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Before checking for an exception, make sure we own the VFP. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 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.26 src/sys/arch/arm/vfp/vfp_init.c:1.27 --- src/sys/arch/arm/vfp/vfp_init.c:1.26 Fri Aug 23 18:11:47 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Nov 18 18:02:01 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.26 2013/08/23 18:11:47 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.27 2013/11/18 18:02:01 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -374,9 +374,21 @@ vfp_handler(u_int address, u_int insn, t if (fault_code != FAULT_USER) panic(VFP fault at %#x in non-user mode, frame-tf_pc); - if (ci-ci_vfp_id == 0) + if (ci-ci_vfp_id == 0) { /* No VFP detected, just fault. */ return 1; + } + + /* + * If we are just changing/fetching FPSCR, don't bother loading it. + */ + if (!vfp_fpscr_handler(address, insn, frame, fault_code)) + return 0; + + /* + * Make sure we own the FP. + */ + pcu_load(arm_vfp_ops); uint32_t fpexc = armreg_fpexc_read(); if (fpexc VFP_FPEXC_EX) { @@ -411,14 +423,6 @@ vfp_handler(u_int address, u_int insn, t return 0; } - /* - * If we are just changing/fetching FPSCR, don't bother loading it. - */ - if (!vfp_fpscr_handler(address, insn, frame, fault_code)) - return 0; - - pcu_load(arm_vfp_ops); - /* Need to restart the faulted instruction. */ // frame-tf_pc -= INSN_SIZE; return 0;
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Fri Aug 23 18:11:47 UTC 2013 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Deal with lack of VFP. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 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.25 src/sys/arch/arm/vfp/vfp_init.c:1.26 --- src/sys/arch/arm/vfp/vfp_init.c:1.25 Fri Aug 23 05:22:01 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Fri Aug 23 18:11:47 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.25 2013/08/23 05:22:01 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.26 2013/08/23 18:11:47 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -189,12 +189,12 @@ vfp_fpscr_handler(u_int address, u_int i */ if (pcb-pcb_vfp.vfp_fpexc VFP_FPEXC_EN) return 1; -#endif if (__predict_false(!vfp_used_p())) { pcb-pcb_vfp.vfp_fpscr = (VFP_FPSCR_DN | VFP_FPSCR_FZ); /* Runfast */ } +#endif /* * We know know the pcb has the saved copy.
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Sat Aug 3 20:16:44 UTC 2013 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add VFP_FPSCR_RN (even though it's 0) just to be explicit. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 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.21 src/sys/arch/arm/vfp/vfp_init.c:1.22 --- src/sys/arch/arm/vfp/vfp_init.c:1.21 Fri Aug 2 03:48:19 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Sat Aug 3 20:16:44 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.21 2013/08/02 03:48:19 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.22 2013/08/03 20:16:44 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -487,8 +487,8 @@ vfp_state_load(lwp_t *l, u_int flags) if (__predict_false((l-l_md.md_flags MDLWP_VFPUSED) == 0)) { vfpevent_use.ev_count++; l-l_md.md_flags |= MDLWP_VFPUSED; - pcb-pcb_vfp.vfp_fpscr = - (VFP_FPSCR_DN | VFP_FPSCR_FZ); /* Runfast */ + pcb-pcb_vfp.vfp_fpscr = /* Runfast */ + (VFP_FPSCR_DN | VFP_FPSCR_FZ | VFP_FPSCR_RN); } else { vfpevent_reuse.ev_count++; }
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Fri Aug 2 03:48:19 UTC 2013 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Use armreg inlines. Add exception - trapsignal code. To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 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.20 src/sys/arch/arm/vfp/vfp_init.c:1.21 --- src/sys/arch/arm/vfp/vfp_init.c:1.20 Thu Jun 20 05:24:46 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Fri Aug 2 03:48:19 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.20 2013/06/20 05:24:46 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.21 2013/08/02 03:48:19 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -46,68 +46,6 @@ extern int cpu_media_and_vfp_features[]; extern int cpu_neon_present; -/* - * Use generic co-processor instructions to avoid assembly problems. - */ - -/* FMRX X, fpsid */ -static inline uint32_t -read_fpsid(void) -{ - uint32_t rv; - __asm __volatile(mrc p10, 7, %0, c0, c0, 0 : =r (rv)); - return rv; -} - -/* FMRX X, fpexc */ -static inline uint32_t -read_fpscr(void) -{ - uint32_t rv; - __asm __volatile(mrc p10, 7, %0, c1, c0, 0 : =r (rv)); - return rv; -} - -/* FMRX X, fpexc */ -static inline uint32_t -read_fpexc(void) -{ - uint32_t rv; - __asm __volatile(mrc p10, 7, %0, c8, c0, 0 : =r (rv)); - return rv; -} - -/* FMRX X, fpinst */ -static inline uint32_t -read_fpinst(void) -{ - uint32_t rv; - __asm __volatile(mrc p10, 7, %0, c9, c0, 0 : =r (rv)); - return rv; -} - -/* FMRX X, fpinst2 */ -static inline uint32_t -read_fpinst2(void) -{ - uint32_t rv; - __asm __volatile(mrc p10, 7, %0, c10, c0, 0 : =r (rv)); - return rv; -} - -/* FMXR X, fpscr */ -#define write_fpscr(X) __asm __volatile(mcr p10, 7, %0, c1, c0, 0 : \ - : r (X)) -/* FMXR X, fpexc */ -#define write_fpexc(X) __asm __volatile(mcr p10, 7, %0, c8, c0, 0 : \ - : r (X)) -/* FMXR X, fpinst */ -#define write_fpinst(X) __asm __volatile(mcr p10, 7, %0, c9, c0, 0 : \ - : r (X)) -/* FMXR X, fpinst2 */ -#define write_fpinst2(X) __asm __volatile(mcr p10, 7, %0, c10, c0, 0 : \ - : r (X)) - #ifdef FPU_VFP /* FLDMD X, {d0-d15} */ @@ -202,6 +140,7 @@ const pcu_ops_t arm_vfp_ops = { struct evcnt vfpevent_use; struct evcnt vfpevent_reuse; +struct evcnt vfpevent_fpe; /* * Used to test for a VFP. The following function is installed as a coproc10 @@ -264,7 +203,10 @@ vfp_fpscr_handler(u_int address, u_int i if (insn 0x0010) { *regp = pcb-pcb_vfp.vfp_fpscr; } else { - pcb-pcb_vfp.vfp_fpscr = *regp; + register_t tmp = *regp; + if (!(cpu_media_and_vfp_features[0] ARM_MVFR0_EXCEPT_MASK)) + tmp = ~VFP_FPSCR_ESUM; + pcb-pcb_vfp.vfp_fpscr = tmp; } vfp_fpscr_ev.ev_count++; @@ -355,7 +297,7 @@ vfp_attach(void) undefined_test = 0; - const uint32_t fpsid = read_fpsid(); + const uint32_t fpsid = armreg_fpsid_read(); remove_coproc_handler(uh); @@ -390,17 +332,24 @@ vfp_attach(void) } cpu_fpu_present = 1; - __asm(mrc p10,7,%0,c7,c0,0 : =r(cpu_media_and_vfp_features[0])); - __asm(mrc p10,7,%0,c6,c0,0 : =r(cpu_media_and_vfp_features[1])); + cpu_media_and_vfp_features[0] = armreg_mvfr0_read(); + cpu_media_and_vfp_features[1] = armreg_mvfr1_read(); if (fpsid != 0) { aprint_normal(vfp%d at %s: %s\n, - device_unit(curcpu()-ci_dev), device_xname(curcpu()-ci_dev), + device_unit(curcpu()-ci_dev), + device_xname(curcpu()-ci_dev), model); + aprint_verbose(vfp%d: mvfr: [0]=%#x [1]=%#x\n, + device_unit(curcpu()-ci_dev), + cpu_media_and_vfp_features[0], + cpu_media_and_vfp_features[1]); } evcnt_attach_dynamic(vfpevent_use, EVCNT_TYPE_MISC, NULL, VFP, coproc use); evcnt_attach_dynamic(vfpevent_reuse, EVCNT_TYPE_MISC, NULL, VFP, coproc re-use); + evcnt_attach_dynamic(vfpevent_fpe, EVCNT_TYPE_TRAP, NULL, + VFP, coproc fault); install_coproc_handler(VFP_COPROC, vfp_handler); install_coproc_handler(VFP_COPROC2, vfp_handler); #ifdef CPU_CORTEX @@ -417,8 +366,7 @@ vfp_attach(void) /* The real handler for VFP bounces. */ static int -vfp_handler(u_int address, u_int insn, trapframe_t *frame, -int fault_code) +vfp_handler(u_int address, u_int insn, trapframe_t *frame, int fault_code) { struct cpu_info * const ci = curcpu(); @@ -430,6 +378,39 @@ vfp_handler(u_int address, u_int insn, t /* No VFP detected, just fault. */ return 1; + uint32_t fpexc = armreg_fpexc_read(); + if (fpexc VFP_FPEXC_EX) { + ksiginfo_t ksi; + KASSERT(fpexc VFP_FPEXC_EN); + + vfpevent_fpe.ev_count++; + + pcu_save(arm_vfp_ops); + + /* + * Need the clear the exception condition so any signal + * can run. + */ + armreg_fpexc_write(fpexc ~(VFP_FPEXC_EX|VFP_FPEXE_FSUM)); + + KSI_INIT_TRAP(ksi); + ksi.ksi_signo = SIGFPE; + if (fpexc VFP_FPEXC_IXF) + ksi.ksi_code
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Tue Feb 5 23:23:34 UTC 2013 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Use the mrc form of the vmrs rX, mvfrX instruction to shut up gas. To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 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.18 src/sys/arch/arm/vfp/vfp_init.c:1.19 --- src/sys/arch/arm/vfp/vfp_init.c:1.18 Thu Jan 31 22:35:25 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Feb 5 23:23:34 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.18 2013/01/31 22:35:25 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.19 2013/02/05 23:23:34 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -387,8 +387,8 @@ vfp_attach(void) } cpu_fpu_present = 1; - __asm(fmrx %0, mvfr0 : =r(cpu_media_and_vfp_features[0])); - __asm(fmrx %0, mvfr1 : =r(cpu_media_and_vfp_features[1])); + __asm(mrc p10,7,%0,c7,c0,0 : =r(cpu_media_and_vfp_features[0])); + __asm(mrc p10,7,%0,c6,c0,0 : =r(cpu_media_and_vfp_features[1])); if (fpsid != 0) { aprint_normal(vfp%d at %s: %s\n, device_unit(curcpu()-ci_dev), device_xname(curcpu()-ci_dev),
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Thu Jan 31 22:35:25 UTC 2013 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add support for machdep neon_present and id_mvfr sysctls To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 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.17 src/sys/arch/arm/vfp/vfp_init.c:1.18 --- src/sys/arch/arm/vfp/vfp_init.c:1.17 Mon Jan 28 23:49:13 2013 +++ src/sys/arch/arm/vfp/vfp_init.c Thu Jan 31 22:35:25 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.17 2013/01/28 23:49:13 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.18 2013/01/31 22:35:25 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -43,6 +43,9 @@ #include uvm/uvm_extern.h /* for pmap.h */ +extern int cpu_media_and_vfp_features[]; +extern int cpu_neon_present; + /* * Use generic co-processor instructions to avoid assembly problems. */ @@ -374,6 +377,7 @@ vfp_attach(void) case FPU_VFP_CORTEXA8: case FPU_VFP_CORTEXA9: model = NEON MPE (VFP 3.0+); + cpu_neon_present = 1; break; default: aprint_normal_dev(ci-ci_dev, unrecognized VFP version %x\n, @@ -383,6 +387,8 @@ vfp_attach(void) } cpu_fpu_present = 1; + __asm(fmrx %0, mvfr0 : =r(cpu_media_and_vfp_features[0])); + __asm(fmrx %0, mvfr1 : =r(cpu_media_and_vfp_features[1])); if (fpsid != 0) { aprint_normal(vfp%d at %s: %s\n, device_unit(curcpu()-ci_dev), device_xname(curcpu()-ci_dev),
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Mon Dec 31 00:01:48 UTC 2012 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: print the PC of the VFP kernel fault in the panic message. To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 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.13 src/sys/arch/arm/vfp/vfp_init.c:1.14 --- src/sys/arch/arm/vfp/vfp_init.c:1.13 Wed Dec 26 18:34:56 2012 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Dec 31 00:01:48 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.13 2012/12/26 18:34:56 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.14 2012/12/31 00:01:48 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -410,7 +410,7 @@ vfp_handler(u_int address, u_int insn, t /* This shouldn't ever happen. */ if (fault_code != FAULT_USER) - panic(VFP fault in non-user mode); + panic(VFP fault at %#x in non-user mode, frame-tf_pc); if (ci-ci_vfp_id == 0) /* No VFP detected, just fault. */
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Mon Dec 31 01:19:37 UTC 2012 Modified Files: src/sys/arch/arm/vfp: pmap_vfp.S Log Message: Switch to using vfp_kernel_{acquire,release} so that softints don't cause the VFP to become disabled. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/vfp/pmap_vfp.S 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/pmap_vfp.S diff -u src/sys/arch/arm/vfp/pmap_vfp.S:1.5 src/sys/arch/arm/vfp/pmap_vfp.S:1.6 --- src/sys/arch/arm/vfp/pmap_vfp.S:1.5 Wed Dec 26 18:35:47 2012 +++ src/sys/arch/arm/vfp/pmap_vfp.S Mon Dec 31 01:19:36 2012 @@ -32,7 +32,7 @@ #include machine/asm.h #include assym.h -RCSID($NetBSD: pmap_vfp.S,v 1.5 2012/12/26 18:35:47 matt Exp $) +RCSID($NetBSD: pmap_vfp.S,v 1.6 2012/12/31 01:19:36 matt Exp $) /* * This zeroes a page 64-bytes at a time. 64 was chosen over 32 since @@ -40,16 +40,9 @@ RCSID($NetBSD: pmap_vfp.S,v 1.5 2012/12 */ /* LINTSTUB: void bzero_page_vfp(vaddr_t); */ ENTRY(bzero_page_vfp) -#if 0 - str lr, [sp, #-8]! + push {r0, lr} bl _C_LABEL(vfp_kernel_acquire) -#else - mrc p10, 7, r3, c8, c0, 0 - tst r3, #VFP_FPEXC_EN - orreq r2, r3, #VFP_FPEXC_EN - mcreq p10, 7, r2, c8, c0, 0 - vpush {d0-d7} -#endif + pop {r0, lr} #if (CPU_CORTEX == 0) mov ip, #0 vmov s0, ip @@ -74,14 +67,7 @@ ENTRY(bzero_page_vfp) vstmia r0!, {d0-d7} cmp r0, r2 blt 1b -#if 0 - ldr lr, [sp], #8 /* fetch LR */ b _C_LABEL(vfp_kernel_release) /* tailcall the vfp release */ -#else - vpop {d0-d7} - mcr p10, 7, r3, c8, c0, 0 - RET -#endif END(bzero_page_vfp) /* @@ -96,17 +82,12 @@ ENTRY(bcopy_page_vfp) pld [r0, #64] pld [r0, #96] #endif -#if 0 str lr, [sp, #-8]! + push {r0, r1} bl _C_LABEL(vfp_kernel_acquire) -#else - mrc p10, 7, r3, c8, c0, 0 - tst r3, #VFP_FPEXC_EN - orreq r2, r3, #VFP_FPEXC_EN - mcreq p10, 7, r2, c8, c0, 0 - vpush {d0-d7} + pop {r0, r1} + ldr lr, [sp], #8 /* fetch LR */ add r2, r0, #PAGE_SIZE-128 -#endif 1: #ifdef _ARM_ARCH_DWORD_OK pld [r0, #128] @ preload the next 128 @@ -121,12 +102,5 @@ ENTRY(bcopy_page_vfp) cmp r0, r2 blt 1b beq 2b -#if 0 - ldr lr, [sp], #8 /* fetch LR */ b _C_LABEL(vfp_kernel_release) /* tailcall the vfp release */ -#else - vpop {d0-d7} - mcr p10, 7, r3, c8, c0, 0 - RET -#endif END(bcopy_page_vfp)
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Mon Dec 31 03:23:53 UTC 2012 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Always re-enable the VFP when loading for a kernel LWP. To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 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.14 src/sys/arch/arm/vfp/vfp_init.c:1.15 --- src/sys/arch/arm/vfp/vfp_init.c:1.14 Mon Dec 31 00:01:48 2012 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Dec 31 03:23:53 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.14 2012/12/31 00:01:48 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.15 2012/12/31 03:23:53 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -468,8 +468,8 @@ vfp_state_load(lwp_t *l, u_int flags) if (flags PCU_KERNEL) { if ((flags PCU_LOADED) == 0) { pcb-pcb_kernel_vfp.vfp_fpexc = pcb-pcb_vfp.vfp_fpexc; - pcb-pcb_vfp.vfp_fpexc = VFP_FPEXC_EN; } + pcb-pcb_vfp.vfp_fpexc = VFP_FPEXC_EN; write_fpexc(pcb-pcb_vfp.vfp_fpexc); /* * Load the kernel registers (just the first 16) if they've
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Wed Dec 26 18:34:57 UTC 2012 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add support for PCU_KERNEL and vfp_kernel_acquire/vfp_kernel_release. Add an undefined handler to catch NEON instructions. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 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.12 src/sys/arch/arm/vfp/vfp_init.c:1.13 --- src/sys/arch/arm/vfp/vfp_init.c:1.12 Tue Dec 11 01:52:30 2012 +++ src/sys/arch/arm/vfp/vfp_init.c Wed Dec 26 18:34:56 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.12 2012/12/11 01:52:30 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.13 2012/12/26 18:34:56 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -109,7 +109,7 @@ read_fpinst2(void) /* FLDMD X, {d0-d15} */ static inline void -load_vfpregs_lo(uint64_t *p) +load_vfpregs_lo(const uint64_t *p) { /* vldmia rN, {d0-d15} */ __asm __volatile(ldc\tp11, c0, [%0], {32} :: r (p) : memory); @@ -125,7 +125,7 @@ save_vfpregs_lo(uint64_t *p) #ifdef CPU_CORTEX /* FLDMD X, {d16-d31} */ static inline void -load_vfpregs_hi(uint64_t *p) +load_vfpregs_hi(const uint64_t *p) { __asm __volatile(ldcl\tp11, c0, [%0], {32} :: r (p[16]) : memory); } @@ -138,18 +138,60 @@ save_vfpregs_hi(uint64_t *p) } #endif +static inline void +load_vfpregs(const struct vfpreg *fregs) +{ + 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 +} + +static inline void +save_vfpregs(struct vfpreg *fregs) +{ + 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 +} + /* The real handler for VFP bounces. */ static int vfp_handler(u_int, u_int, trapframe_t *, int); -static int vfp_handler(u_int, u_int, trapframe_t *, int); +#ifdef CPU_CORTEX +static int neon_handler(u_int, u_int, trapframe_t *, int); +#endif -static void vfp_state_load(lwp_t *, bool); -static void vfp_state_save(lwp_t *); -static void vfp_state_release(lwp_t *); +static void vfp_state_load(lwp_t *, u_int); +static void vfp_state_save(lwp_t *, u_int); +static void vfp_state_release(lwp_t *, u_int); const pcu_ops_t arm_vfp_ops = { .pcu_id = PCU_FPU, - .pcu_state_load = vfp_state_load, .pcu_state_save = vfp_state_save, + .pcu_state_load = vfp_state_load, .pcu_state_release = vfp_state_release, }; @@ -349,6 +391,9 @@ vfp_attach(void) VFP, coproc re-use); install_coproc_handler(VFP_COPROC, vfp_handler); install_coproc_handler(VFP_COPROC2, vfp_handler); +#ifdef CPU_CORTEX + install_coproc_handler(CORE_UNKNOWN_HANDLER, neon_handler); +#endif vfp_patch_branch((uintptr_t)pmap_copy_page_generic, (uintptr_t)bcopy_page, (uintptr_t)bcopy_page_vfp); @@ -384,10 +429,57 @@ vfp_handler(u_int address, u_int insn, t return 0; } +#ifdef CPU_CORTEX +/* The real handler for NEON bounces. */ +static int +neon_handler(u_int address, u_int insn, trapframe_t *frame, +int fault_code) +{ + struct cpu_info * const ci = curcpu(); + + if (ci-ci_vfp_id == 0) + /* No VFP detected, just fault. */ + return 1; + + if ((insn 0xfe00) != 0xf200 + (insn 0xfe00) != 0xf400) + /* Not NEON instruction, just fault. */ + return 1; + + /* This shouldn't ever happen. */ + if (fault_code != FAULT_USER) + panic(NEON fault in non-user mode); + + pcu_load(arm_vfp_ops); + + /* Need to restart the faulted instruction. */ +// frame-tf_pc -= INSN_SIZE; + return 0; +} +#endif + static void -vfp_state_load(lwp_t *l, bool used) +vfp_state_load(lwp_t *l, u_int flags) { struct pcb * const pcb = lwp_getpcb(l); + + KASSERT(flags PCU_ENABLE); + + if (flags PCU_KERNEL) { + if ((flags PCU_LOADED) == 0) { + pcb-pcb_kernel_vfp.vfp_fpexc = pcb-pcb_vfp.vfp_fpexc; + pcb-pcb_vfp.vfp_fpexc = VFP_FPEXC_EN; + } + write_fpexc(pcb-pcb_vfp.vfp_fpexc); + /* + * Load the kernel registers (just the first 16) if they've + * been used.. + */ + if (flags PCU_LOADED) { + load_vfpregs_lo(pcb-pcb_kernel_vfp.vfp_regs); + } + return; + } struct vfpreg * const fregs = pcb-pcb_vfp; /* @@ -417,44 +509,32 @@ vfp_state_load(lwp_t *l, bool used) return; } - /* Enable the VFP (so that we can write the registers). */ - uint32_t fpexc = read_fpexc(); - KDASSERT((fpexc VFP_FPEXC_EX) == 0); - write_fpexc(fpexc | VFP_FPEXC_EN); - - load_vfpregs_lo(fregs-vfp_regs); -#ifdef CPU_CORTEX
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Wed Dec 26 18:35:47 UTC 2012 Modified Files: src/sys/arch/arm/vfp: pmap_vfp.S Log Message: Add not-yet-enabled code to use vfp_kernel_{acquire,release} To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/vfp/pmap_vfp.S 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/pmap_vfp.S diff -u src/sys/arch/arm/vfp/pmap_vfp.S:1.4 src/sys/arch/arm/vfp/pmap_vfp.S:1.5 --- src/sys/arch/arm/vfp/pmap_vfp.S:1.4 Tue Dec 11 23:59:18 2012 +++ src/sys/arch/arm/vfp/pmap_vfp.S Wed Dec 26 18:35:47 2012 @@ -32,7 +32,7 @@ #include machine/asm.h #include assym.h -RCSID($NetBSD: pmap_vfp.S,v 1.4 2012/12/11 23:59:18 matt Exp $) +RCSID($NetBSD: pmap_vfp.S,v 1.5 2012/12/26 18:35:47 matt Exp $) /* * This zeroes a page 64-bytes at a time. 64 was chosen over 32 since @@ -40,11 +40,16 @@ RCSID($NetBSD: pmap_vfp.S,v 1.4 2012/12 */ /* LINTSTUB: void bzero_page_vfp(vaddr_t); */ ENTRY(bzero_page_vfp) +#if 0 + str lr, [sp, #-8]! + bl _C_LABEL(vfp_kernel_acquire) +#else mrc p10, 7, r3, c8, c0, 0 tst r3, #VFP_FPEXC_EN orreq r2, r3, #VFP_FPEXC_EN mcreq p10, 7, r2, c8, c0, 0 vpush {d0-d7} +#endif #if (CPU_CORTEX == 0) mov ip, #0 vmov s0, ip @@ -69,9 +74,14 @@ ENTRY(bzero_page_vfp) vstmia r0!, {d0-d7} cmp r0, r2 blt 1b +#if 0 + ldr lr, [sp], #8 /* fetch LR */ + b _C_LABEL(vfp_kernel_release) /* tailcall the vfp release */ +#else vpop {d0-d7} mcr p10, 7, r3, c8, c0, 0 RET +#endif END(bzero_page_vfp) /* @@ -86,12 +96,17 @@ ENTRY(bcopy_page_vfp) pld [r0, #64] pld [r0, #96] #endif +#if 0 + str lr, [sp, #-8]! + bl _C_LABEL(vfp_kernel_acquire) +#else mrc p10, 7, r3, c8, c0, 0 tst r3, #VFP_FPEXC_EN orreq r2, r3, #VFP_FPEXC_EN mcreq p10, 7, r2, c8, c0, 0 vpush {d0-d7} add r2, r0, #PAGE_SIZE-128 +#endif 1: #ifdef _ARM_ARCH_DWORD_OK pld [r0, #128] @ preload the next 128 @@ -106,7 +121,12 @@ ENTRY(bcopy_page_vfp) cmp r0, r2 blt 1b beq 2b +#if 0 + ldr lr, [sp], #8 /* fetch LR */ + b _C_LABEL(vfp_kernel_release) /* tailcall the vfp release */ +#else vpop {d0-d7} mcr p10, 7, r3, c8, c0, 0 RET +#endif END(bcopy_page_vfp)
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Tue Dec 11 23:59:18 UTC 2012 Modified Files: src/sys/arch/arm/vfp: pmap_vfp.S Log Message: Use RET, not bx lr. Due to evbarm/conf/INTEGRATOR conditional use of pld. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/vfp/pmap_vfp.S 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/pmap_vfp.S diff -u src/sys/arch/arm/vfp/pmap_vfp.S:1.3 src/sys/arch/arm/vfp/pmap_vfp.S:1.4 --- src/sys/arch/arm/vfp/pmap_vfp.S:1.3 Tue Dec 11 01:13:05 2012 +++ src/sys/arch/arm/vfp/pmap_vfp.S Tue Dec 11 23:59:18 2012 @@ -32,7 +32,7 @@ #include machine/asm.h #include assym.h -RCSID($NetBSD: pmap_vfp.S,v 1.3 2012/12/11 01:13:05 matt Exp $) +RCSID($NetBSD: pmap_vfp.S,v 1.4 2012/12/11 23:59:18 matt Exp $) /* * This zeroes a page 64-bytes at a time. 64 was chosen over 32 since @@ -71,7 +71,7 @@ ENTRY(bzero_page_vfp) blt 1b vpop {d0-d7} mcr p10, 7, r3, c8, c0, 0 - bx lr + RET END(bzero_page_vfp) /* @@ -80,20 +80,25 @@ END(bzero_page_vfp) */ /* LINTSTUB: void bcopy_page_vfp(vaddr_t, vaddr_t); */ ENTRY(bcopy_page_vfp) +#ifdef _ARM_ARCH_DWORD_OK pld [r0] @ preload the first 128 bytes pld [r0, #32] pld [r0, #64] pld [r0, #96] +#endif mrc p10, 7, r3, c8, c0, 0 tst r3, #VFP_FPEXC_EN orreq r2, r3, #VFP_FPEXC_EN mcreq p10, 7, r2, c8, c0, 0 vpush {d0-d7} add r2, r0, #PAGE_SIZE-128 -1: pld [r0, #128] @ preload the next 128 +1: +#ifdef _ARM_ARCH_DWORD_OK + pld [r0, #128] @ preload the next 128 pld [r0, #160] pld [r0, #192] pld [r0, #224] +#endif 2: vldmia r0!, {d0-d7} @ read 0-63 vstmia r1!, {d0-d7} @ write 0-63 vldmia r0!, {d0-d7} @ read 64-127 @@ -103,5 +108,5 @@ ENTRY(bcopy_page_vfp) beq 2b vpop {d0-d7} mcr p10, 7, r3, c8, c0, 0 - bx lr + RET END(bcopy_page_vfp)
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Tue Dec 11 01:13:06 UTC 2012 Modified Files: src/sys/arch/arm/vfp: pmap_vfp.S Log Message: These contain to just contain bzero_page_vfp and bcopy_page_vfp To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/vfp/pmap_vfp.S 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/pmap_vfp.S diff -u src/sys/arch/arm/vfp/pmap_vfp.S:1.2 src/sys/arch/arm/vfp/pmap_vfp.S:1.3 --- src/sys/arch/arm/vfp/pmap_vfp.S:1.2 Mon Dec 10 06:51:05 2012 +++ src/sys/arch/arm/vfp/pmap_vfp.S Tue Dec 11 01:13:05 2012 @@ -32,22 +32,18 @@ #include machine/asm.h #include assym.h -RCSID($NetBSD: pmap_vfp.S,v 1.2 2012/12/10 06:51:05 matt Exp $) - -#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS +RCSID($NetBSD: pmap_vfp.S,v 1.3 2012/12/11 01:13:05 matt Exp $) /* - * This zeroes a page 64-bytes at a time. 64 is chosen over 32 since + * This zeroes a page 64-bytes at a time. 64 was chosen over 32 since * 64 is the cache line size of the Cortex-A8. */ -ENTRY(pmap_zero_page_vfp) - ldr ip, .Lkbase @ phys - ldr r3, .Lkbase+4 @ virt - sub r3, r3, ip @ diff = virt - phys - add r0, r0, r3 @ phys - virt +/* LINTSTUB: void bzero_page_vfp(vaddr_t); */ +ENTRY(bzero_page_vfp) mrc p10, 7, r3, c8, c0, 0 - orr r2, r3, #VFP_FPEXC_EN - mcr p10, 7, r2, c8, c0, 0 + tst r3, #VFP_FPEXC_EN + orreq r2, r3, #VFP_FPEXC_EN + mcreq p10, 7, r2, c8, c0, 0 vpush {d0-d7} #if (CPU_CORTEX == 0) mov ip, #0 @@ -76,25 +72,22 @@ ENTRY(pmap_zero_page_vfp) vpop {d0-d7} mcr p10, 7, r3, c8, c0, 0 bx lr -END(pmap_zero_page_vfp) +END(bzero_page_vfp) /* - * This copies a page 64-bytes at a time. 64 is chosen over 32 since + * This copies a page 64-bytes at a time. 64 was chosen over 32 since * 64 is the cache line size of the Cortex-A8. */ -ENTRY(pmap_copy_page_vfp) - ldr ip, .Lkbase @ phys - ldr r3, .Lkbase+4 @ virt - sub r3, r3, ip @ diff = virt - phys - add r0, r0, r3 @ convert from phys to virt - add r1, r1, r3 @ convert from phys to virt +/* LINTSTUB: void bcopy_page_vfp(vaddr_t, vaddr_t); */ +ENTRY(bcopy_page_vfp) pld [r0] @ preload the first 128 bytes pld [r0, #32] pld [r0, #64] pld [r0, #96] mrc p10, 7, r3, c8, c0, 0 - orr r2, r3, #VFP_FPEXC_EN - mcr p10, 7, r2, c8, c0, 0 + tst r3, #VFP_FPEXC_EN + orreq r2, r3, #VFP_FPEXC_EN + mcreq p10, 7, r2, c8, c0, 0 vpush {d0-d7} add r2, r0, #PAGE_SIZE-128 1: pld [r0, #128] @ preload the next 128 @@ -111,11 +104,4 @@ ENTRY(pmap_copy_page_vfp) vpop {d0-d7} mcr p10, 7, r3, c8, c0, 0 bx lr -END(pmap_copy_page_vfp) - - .p2align 2 -.Lkbase: - .word KERNEL_BASE_phys - .word KERNEL_BASE_virt - -#endif /* __HAVE_MM_MD_DIRECT_MAPPED_PHYS */ +END(bcopy_page_vfp)
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Tue Dec 11 01:52:30 UTC 2012 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add code to patch pmap_{copy,zero}_page_generic to change calls to b{copy,zero}_page to b{copy,zero}_page_vfp To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 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.11 src/sys/arch/arm/vfp/vfp_init.c:1.12 --- src/sys/arch/arm/vfp/vfp_init.c:1.11 Mon Dec 10 01:35:28 2012 +++ src/sys/arch/arm/vfp/vfp_init.c Tue Dec 11 01:52:30 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.11 2012/12/10 01:35:28 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.12 2012/12/11 01:52:30 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -41,6 +41,8 @@ #include arm/vfpreg.h #include arm/mcontext.h +#include uvm/uvm_extern.h /* for pmap.h */ + /* * Use generic co-processor instructions to avoid assembly problems. */ @@ -236,6 +238,33 @@ vfp_attach(void) } #else +static bool +vfp_patch_branch(uintptr_t code, uintptr_t func, uintptr_t newfunc) +{ + for (;; code += sizeof(uint32_t)) { + uint32_t insn = *(uint32_t *)code; + if ((insn 0xffd08000) == 0xe8908000) /* ldm ... { pc } */ + return false; + if ((insn 0xfff0) == 0xe12fff10) /* bx rN */ + return false; + if ((insn 0xf1a0f000) == 0xe1a0f000) /* mov pc, ... */ + return false; + if ((insn 25) != 0x75) /* not b/bl insn */ + continue; + intptr_t imm26 = ((int32_t)insn 8) 6; + if (code + imm26 + 8 == func) { + int32_t imm24 = (newfunc - (code + 8)) 2; + uint32_t new_insn = (insn 0xff00) + | (imm24 0xff); + KASSERTMSG((uint32_t)((imm24 24) + 1) = 1, %x, + ((imm24 24) + 1)); + *(uint32_t *)code = new_insn; + cpu_idcache_wbinv_range(code, sizeof(uint32_t)); + return true; + } + } +} + void vfp_attach(void) { @@ -243,7 +272,6 @@ vfp_attach(void) const char *model = NULL; bool vfp_p = false; -#ifdef FPU_VFP if (CPU_ID_ARM11_P(curcpu()-ci_arm_cpuid) || CPU_ID_CORTEX_P(curcpu()-ci_arm_cpuid)) { const uint32_t cpacr_vfp = CPACR_CPn(VFP_COPROC); @@ -273,7 +301,6 @@ vfp_attach(void) vfp_p = __SHIFTOUT(cpacr, cpacr_vfp2) != CPACR_NOACCESS || __SHIFTOUT(cpacr, cpacr_vfp) != CPACR_NOACCESS; } -#endif void *uh = install_coproc_handler(VFP_COPROC, vfp_test); @@ -317,11 +344,16 @@ vfp_attach(void) model); } evcnt_attach_dynamic(vfpevent_use, EVCNT_TYPE_MISC, NULL, - VFP, proc use); + VFP, coproc use); evcnt_attach_dynamic(vfpevent_reuse, EVCNT_TYPE_MISC, NULL, - VFP, proc re-use); + VFP, coproc re-use); install_coproc_handler(VFP_COPROC, vfp_handler); install_coproc_handler(VFP_COPROC2, vfp_handler); + + vfp_patch_branch((uintptr_t)pmap_copy_page_generic, + (uintptr_t)bcopy_page, (uintptr_t)bcopy_page_vfp); + vfp_patch_branch((uintptr_t)pmap_zero_page_generic, + (uintptr_t)bzero_page, (uintptr_t)bzero_page_vfp); } /* The real handler for VFP bounces. */
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Mon Dec 10 01:35:28 UTC 2012 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: move inlines into FPU_VFP To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 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.10 src/sys/arch/arm/vfp/vfp_init.c:1.11 --- src/sys/arch/arm/vfp/vfp_init.c:1.10 Sat Dec 8 06:49:00 2012 +++ src/sys/arch/arm/vfp/vfp_init.c Mon Dec 10 01:35:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.10 2012/12/08 06:49:00 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.11 2012/12/10 01:35:28 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -102,8 +102,11 @@ read_fpinst2(void) /* FMXR X, fpinst2 */ #define write_fpinst2(X) __asm __volatile(mcr p10, 7, %0, c10, c0, 0 : \ : r (X)) + +#ifdef FPU_VFP + /* FLDMD X, {d0-d15} */ -static void +static inline void load_vfpregs_lo(uint64_t *p) { /* vldmia rN, {d0-d15} */ @@ -111,7 +114,7 @@ load_vfpregs_lo(uint64_t *p) } /* FSTMD X, {d0-d15} */ -static void +static inline void save_vfpregs_lo(uint64_t *p) { __asm __volatile(stc\tp11, c0, [%0], {32} :: r (p) : memory); @@ -119,22 +122,20 @@ save_vfpregs_lo(uint64_t *p) #ifdef CPU_CORTEX /* FLDMD X, {d16-d31} */ -static void +static inline void load_vfpregs_hi(uint64_t *p) { __asm __volatile(ldcl\tp11, c0, [%0], {32} :: r (p[16]) : memory); } /* FLDMD X, {d16-d31} */ -static void +static inline void save_vfpregs_hi(uint64_t *p) { __asm __volatile(stcl\tp11, c0, [%0], {32} :: r (p[16]) : memory); } #endif -#ifdef FPU_VFP - /* The real handler for VFP bounces. */ static int vfp_handler(u_int, u_int, trapframe_t *, int); static int vfp_handler(u_int, u_int, trapframe_t *, int);
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Mon Dec 10 06:51:05 UTC 2012 Modified Files: src/sys/arch/arm/vfp: pmap_vfp.S Log Message: Make sure we can deal with VA != PA but still we need to have all of PA mapped. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/vfp/pmap_vfp.S 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/pmap_vfp.S diff -u src/sys/arch/arm/vfp/pmap_vfp.S:1.1 src/sys/arch/arm/vfp/pmap_vfp.S:1.2 --- src/sys/arch/arm/vfp/pmap_vfp.S:1.1 Mon Dec 10 04:58:54 2012 +++ src/sys/arch/arm/vfp/pmap_vfp.S Mon Dec 10 06:51:05 2012 @@ -32,11 +32,19 @@ #include machine/asm.h #include assym.h +RCSID($NetBSD: pmap_vfp.S,v 1.2 2012/12/10 06:51:05 matt Exp $) + +#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS + /* * This zeroes a page 64-bytes at a time. 64 is chosen over 32 since * 64 is the cache line size of the Cortex-A8. */ ENTRY(pmap_zero_page_vfp) + ldr ip, .Lkbase @ phys + ldr r3, .Lkbase+4 @ virt + sub r3, r3, ip @ diff = virt - phys + add r0, r0, r3 @ phys - virt mrc p10, 7, r3, c8, c0, 0 orr r2, r3, #VFP_FPEXC_EN mcr p10, 7, r2, c8, c0, 0 @@ -75,6 +83,11 @@ END(pmap_zero_page_vfp) * 64 is the cache line size of the Cortex-A8. */ ENTRY(pmap_copy_page_vfp) + ldr ip, .Lkbase @ phys + ldr r3, .Lkbase+4 @ virt + sub r3, r3, ip @ diff = virt - phys + add r0, r0, r3 @ convert from phys to virt + add r1, r1, r3 @ convert from phys to virt pld [r0] @ preload the first 128 bytes pld [r0, #32] pld [r0, #64] @@ -99,3 +112,10 @@ ENTRY(pmap_copy_page_vfp) mcr p10, 7, r3, c8, c0, 0 bx lr END(pmap_copy_page_vfp) + + .p2align 2 +.Lkbase: + .word KERNEL_BASE_phys + .word KERNEL_BASE_virt + +#endif /* __HAVE_MM_MD_DIRECT_MAPPED_PHYS */
CVS commit: src/sys/arch/arm/vfp
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; } }
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Wed Dec 5 19:30:10 UTC 2012 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: For armv7 (cortex), disable access to the upper 16 FP registers (restrict the register space to 16 64-bit FP registers). To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 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.8 src/sys/arch/arm/vfp/vfp_init.c:1.9 --- src/sys/arch/arm/vfp/vfp_init.c:1.8 Wed Dec 5 19:05:46 2012 +++ src/sys/arch/arm/vfp/vfp_init.c Wed Dec 5 19:30:10 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.8 2012/12/05 19:05:46 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.9 2012/12/05 19:30:10 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -231,6 +231,12 @@ vfp_attach(void) uint32_t cpacr = armreg_cpacr_read(); cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp); cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp2); + if (CPU_ID_CORTEX_P(curcpu()-ci_arm_cpuid)) { + /* + * Disable access to the upper 16 FP registers. + */ + cpacr |= CPACR_V7_D32DIS; + } armreg_cpacr_write(cpacr); /*
CVS commit: src/sys/arch/arm/vfp
Module Name:src Committed By: matt Date: Thu Aug 16 18:16:25 UTC 2012 Modified Files: src/sys/arch/arm/vfp: vfp_init.c Log Message: Add include of arm/pcb.h To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 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.4 src/sys/arch/arm/vfp/vfp_init.c:1.5 --- src/sys/arch/arm/vfp/vfp_init.c:1.4 Sun Aug 12 05:05:47 2012 +++ src/sys/arch/arm/vfp/vfp_init.c Thu Aug 16 18:16:25 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfp_init.c,v 1.4 2012/08/12 05:05:47 matt Exp $ */ +/* $NetBSD: vfp_init.c,v 1.5 2012/08/16 18:16:25 matt Exp $ */ /* * Copyright (c) 2008 ARM Ltd @@ -36,6 +36,7 @@ #include sys/proc.h #include sys/cpu.h +#include arm/pcb.h #include arm/undefined.h #include arm/vfpreg.h