Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/vfp Improve PCU/VFP handling to the point that ...
details: https://anonhg.NetBSD.org/src/rev/3025f4d8d45e
branches: trunk
changeset: 326321:3025f4d8d45e
user: skrll <skrll%NetBSD.org@localhost>
date: Sat Jan 25 17:30:56 2014 +0000
description:
Improve PCU/VFP handling to the point that the atf tests don't trigger
KASSERTs on the Raspberry PI and its arm1176jzf-s.
XXX Need to emulate bounce instructions to get correct exception codes,
XXX etc.
diffstat:
sys/arch/arm/vfp/vfp_init.c | 65 ++++++++++++++++++++++++++------------------
1 files changed, 38 insertions(+), 27 deletions(-)
diffs (129 lines):
diff -r e32c44dfacfe -r 3025f4d8d45e sys/arch/arm/vfp/vfp_init.c
--- a/sys/arch/arm/vfp/vfp_init.c Sat Jan 25 17:30:45 2014 +0000
+++ b/sys/arch/arm/vfp/vfp_init.c Sat Jan 25 17:30:56 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfp_init.c,v 1.32 2014/01/24 08:26:39 skrll Exp $ */
+/* $NetBSD: vfp_init.c,v 1.33 2014/01/25 17:30:56 skrll Exp $ */
/*
* Copyright (c) 2008 ARM Ltd
@@ -407,14 +407,18 @@
vfpevent_fpe.ev_count++;
+ /*
+ * Need the clear the exception condition so any signal
+ * and future use can proceed.
+ */
+ armreg_fpexc_write(fpexc & ~(VFP_FPEXC_EX|VFP_FPEXC_FSUM));
+
pcu_save(&arm_vfp_ops);
/*
- * Need the clear the exception condition so any signal
- * can run.
+ * XXX Need to emulate bounce instructions here to get correct
+ * XXX exception codes, etc.
*/
- armreg_fpexc_write(fpexc & ~(VFP_FPEXC_EX|VFP_FPEXC_FSUM));
-
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGFPE;
if (fpexc & VFP_FPEXC_IXF)
@@ -499,6 +503,7 @@
* a trap to use it again" event.
*/
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 */
@@ -506,21 +511,24 @@
vfpevent_reuse.ev_count++;
}
- if (fregs->vfp_fpexc & VFP_FPEXC_EN) {
+ uint32_t fpexc = armreg_fpexc_read();
+ if (flags & PCU_RELOAD) {
+ bool enabled = fregs->vfp_fpexc & VFP_FPEXC_EN;
+
/*
- * If we think the VFP is enabled, it must have be disabled by
- * vfp_state_release for another LWP so we can just restore
- * FPEXC and return since our VFP state is still loaded.
+ * Load and Enable the VFP (so that we can write the
+ * registers).
*/
+ fregs->vfp_fpexc |= VFP_FPEXC_EN;
armreg_fpexc_write(fregs->vfp_fpexc);
- return;
- }
-
- /* Load and Enable the VFP (so that we can write the registers). */
- if (flags & PCU_RELOAD) {
- uint32_t fpexc = armreg_fpexc_read();
- KDASSERT((fpexc & VFP_FPEXC_EX) == 0);
- armreg_fpexc_write(fpexc | VFP_FPEXC_EN);
+ 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;
+ }
load_vfpregs(fregs);
armreg_fpscr_write(fregs->vfp_fpscr);
@@ -531,11 +539,13 @@
if (fregs->vfp_fpexc & VFP_FPEXC_FP2V)
armreg_fpinst_write(fregs->vfp_fpinst);
}
+ } else {
+ /*
+ * If the VFP is already enabled we must be bouncing an
+ * instruction.
+ */
+ armreg_fpexc_write(fpexc | VFP_FPEXC_EN);
}
-
- /* Finally, restore the FPEXC but don't enable the VFP. */
- fregs->vfp_fpexc |= VFP_FPEXC_EN;
- armreg_fpexc_write(fregs->vfp_fpexc);
}
void
@@ -543,6 +553,12 @@
{
struct pcb * const pcb = lwp_getpcb(l);
uint32_t fpexc = armreg_fpexc_read();
+
+ /*
+ * Enable the VFP (so we can read the registers).
+ * Make sure the exception bit is cleared so that we can
+ * safely dump the registers.
+ */
armreg_fpexc_write((fpexc | VFP_FPEXC_EN) & ~VFP_FPEXC_EX);
if (flags & PCU_KERNEL) {
@@ -556,11 +572,6 @@
struct vfpreg * const fregs = &pcb->pcb_vfp;
- /*
- * Enable the VFP (so we can read the registers).
- * Make sure the exception bit is cleared so that we can
- * safely dump the registers.
- */
fregs->vfp_fpexc = fpexc;
if (fpexc & VFP_FPEXC_EX) {
/* Need to save the exception handling state */
@@ -572,7 +583,7 @@
save_vfpregs(fregs);
/* Disable the VFP. */
- armreg_fpexc_write(fpexc);
+ armreg_fpexc_write(fpexc & ~VFP_FPEXC_EN);
}
void
Home |
Main Index |
Thread Index |
Old Index