Query the media and vfp feature registers to determine what our default
mode should be and what bits in the fpscr can be changed. Print what features are supported: vfp0 at cpu0: NEON MPE (VFP 3.0+), rounding, NaN propogation, denormals
This commit is contained in:
parent
5daa42d650
commit
82ca37398f
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sys_machdep.c,v 1.19 2013/08/23 14:39:50 matt Exp $ */
|
||||
/* $NetBSD: sys_machdep.c,v 1.20 2014/03/03 08:45:18 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995-1997 Mark Brinicombe.
|
||||
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.19 2013/08/23 14:39:50 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.20 2014/03/03 08:45:18 matt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -106,11 +106,12 @@ arm32_vfp_fpscr(struct lwp *l, const void *uap, register_t *retval)
|
||||
|
||||
retval[0] = pcb->pcb_vfp.vfp_fpscr;
|
||||
if (uap) {
|
||||
extern uint32_t vfp_fpscr_changable;
|
||||
struct arm_vfp_fpscr_args ua;
|
||||
int error;
|
||||
if ((error = copyin(uap, &ua, sizeof(ua))) != 0)
|
||||
return (error);
|
||||
if (((ua.fpscr_clear|ua.fpscr_set) & ~VFP_FPSCR_RMODE) != 0)
|
||||
if ((ua.fpscr_clear|ua.fpscr_set) & ~vfp_fpscr_changable)
|
||||
return EINVAL;
|
||||
pcb->pcb_vfp.vfp_fpscr &= ~ua.fpscr_clear;
|
||||
pcb->pcb_vfp.vfp_fpscr |= ua.fpscr_set;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vfp_init.c,v 1.33 2014/01/25 17:30:56 skrll Exp $ */
|
||||
/* $NetBSD: vfp_init.c,v 1.34 2014/03/03 08:45:18 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 ARM Ltd
|
||||
@ -148,6 +148,11 @@ struct evcnt vfpevent_use;
|
||||
struct evcnt vfpevent_reuse;
|
||||
struct evcnt vfpevent_fpe;
|
||||
|
||||
/* determine what bits can be changed */
|
||||
uint32_t vfp_fpscr_changable = VFP_FPSCR_CSUM;
|
||||
/* default to run fast */
|
||||
uint32_t vfp_fpscr_default = (VFP_FPSCR_DN | VFP_FPSCR_FZ | VFP_FPSCR_RN);
|
||||
|
||||
/*
|
||||
* Used to test for a VFP. The following function is installed as a coproc10
|
||||
* handler on the undefined instruction vector and then we issue a VFP
|
||||
@ -208,10 +213,8 @@ vfp_fpscr_handler(u_int address, u_int insn, trapframe_t *frame, int fault_code)
|
||||
if (insn & 0x00100000) {
|
||||
*regp = pcb->pcb_vfp.vfp_fpscr;
|
||||
} else {
|
||||
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;
|
||||
pcb->pcb_vfp.vfp_fpscr &= ~vfp_fpscr_changable;
|
||||
pcb->pcb_vfp.vfp_fpscr |= *regp & vfp_fpscr_changable;
|
||||
}
|
||||
|
||||
vfp_fpscr_ev.ev_count++;
|
||||
@ -345,14 +348,34 @@ vfp_attach(void)
|
||||
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",
|
||||
uint32_t f0 = armreg_mvfr0_read();
|
||||
uint32_t f1 = armreg_mvfr0_read();
|
||||
aprint_normal("vfp%d at %s: %s%s%s%s%s\n",
|
||||
device_unit(curcpu()->ci_dev),
|
||||
device_xname(curcpu()->ci_dev),
|
||||
model);
|
||||
model,
|
||||
((f0 & ARM_MVFR0_ROUNDING_MASK) ? ", rounding" : ""),
|
||||
((f0 & ARM_MVFR0_EXCEPT_MASK) ? ", exceptions" : ""),
|
||||
((f1 & ARM_MVFR1_D_NAN_MASK) ? ", NaN propogation" : ""),
|
||||
((f1 & ARM_MVFR1_FTZ_MASK) ? ", denormals" : ""));
|
||||
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]);
|
||||
device_unit(curcpu()->ci_dev), f0, f1);
|
||||
if (cpu_media_and_vfp_features[0] & ARM_MVFR0_ROUNDING_MASK) {
|
||||
vfp_fpscr_changable |= VFP_FPSCR_RMODE;
|
||||
}
|
||||
if (cpu_media_and_vfp_features[0] & ARM_MVFR0_EXCEPT_MASK) {
|
||||
vfp_fpscr_changable |= VFP_FPSCR_ESUM;
|
||||
}
|
||||
// If hardware supports propogation of NaNs, select it.
|
||||
if (cpu_media_and_vfp_features[1] & ARM_MVFR1_D_NAN_MASK) {
|
||||
vfp_fpscr_default &= ~VFP_FPSCR_DN;
|
||||
vfp_fpscr_changable |= VFP_FPSCR_DN;
|
||||
}
|
||||
// If hardware supports denormalized numbers, use it.
|
||||
if (cpu_media_and_vfp_features[1] & ARM_MVFR1_FTZ_MASK) {
|
||||
vfp_fpscr_default &= ~VFP_FPSCR_FZ;
|
||||
vfp_fpscr_changable |= VFP_FPSCR_FZ;
|
||||
}
|
||||
}
|
||||
evcnt_attach_dynamic(&vfpevent_use, EVCNT_TYPE_MISC, NULL,
|
||||
"VFP", "coproc use");
|
||||
@ -505,8 +528,7 @@ vfp_state_load(lwp_t *l, u_int flags)
|
||||
if (__predict_false((flags & PCU_LOADED) == 0)) {
|
||||
KASSERT(flags & PCU_RELOAD);
|
||||
vfpevent_use.ev_count++;
|
||||
pcb->pcb_vfp.vfp_fpscr =
|
||||
(VFP_FPSCR_DN | VFP_FPSCR_FZ | VFP_FPSCR_RN); /* Runfast */
|
||||
pcb->pcb_vfp.vfp_fpscr = vfp_fpscr_default;
|
||||
} else {
|
||||
vfpevent_reuse.ev_count++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user