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 Use armreg inlines.
details: https://anonhg.NetBSD.org/src/rev/38a393384b70
branches: trunk
changeset: 788988:38a393384b70
user: matt <matt%NetBSD.org@localhost>
date: Fri Aug 02 03:48:19 2013 +0000
description:
Use armreg inlines.
Add exception -> trapsignal code.
diffstat:
sys/arch/arm/vfp/vfp_init.c | 188 ++++++++++++++++---------------------------
1 files changed, 71 insertions(+), 117 deletions(-)
diffs (truncated from 328 to 300 lines):
diff -r 15fcf16ca2db -r 38a393384b70 sys/arch/arm/vfp/vfp_init.c
--- a/sys/arch/arm/vfp/vfp_init.c Fri Aug 02 02:07:00 2013 +0000
+++ b/sys/arch/arm/vfp/vfp_init.c Fri Aug 02 03:48:19 2013 +0000
@@ -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 @@
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 @@
if (insn & 0x00100000) {
*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 @@
undefined_test = 0;
- const uint32_t fpsid = read_fpsid();
+ const uint32_t fpsid = armreg_fpsid_read();
remove_coproc_handler(uh);
@@ -390,17 +332,24 @@
}
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 @@
/* 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 @@
/* 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 = FPE_FLTRES;
+ else if (fpexc & VFP_FPEXC_UFF)
+ ksi.ksi_code = FPE_FLTUND;
+ else if (fpexc & VFP_FPEXC_OFF)
+ ksi.ksi_code = FPE_FLTOVF;
+ else if (fpexc & VFP_FPEXC_DZF)
+ ksi.ksi_code = FPE_FLTDIV;
+ else if (fpexc & VFP_FPEXC_IOF)
+ ksi.ksi_code = FPE_FLTINV;
+ ksi.ksi_addr = (uint32_t *)address;
+ ksi.ksi_trap = 0;
+ trapsignal(curlwp, &ksi);
+ return 0;
+ }
+
/*
* If we are just changing/fetching FPSCR, don't bother loading it.
*/
@@ -446,8 +427,7 @@
#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)
+neon_handler(u_int address, u_int insn, trapframe_t *frame, int fault_code)
{
struct cpu_info * const ci = curcpu();
@@ -484,7 +464,7 @@
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);
+ armreg_fpexc_write(pcb->pcb_vfp.vfp_fpexc);
/*
* Load the kernel registers (just the first 16) if they've
* been used..
@@ -519,51 +499,38 @@
* vfp_state_release for another LWP so we can just restore
* FPEXC and return since our VFP state is still loaded.
*/
- write_fpexc(fregs->vfp_fpexc);
+ 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 = read_fpexc();
+ uint32_t fpexc = armreg_fpexc_read();
KDASSERT((fpexc & VFP_FPEXC_EX) == 0);
- write_fpexc(fpexc | VFP_FPEXC_EN);
+ armreg_fpexc_write(fpexc | VFP_FPEXC_EN);
load_vfpregs(fregs);
- write_fpscr(fregs->vfp_fpscr);
+ armreg_fpscr_write(fregs->vfp_fpscr);
if (fregs->vfp_fpexc & VFP_FPEXC_EX) {
- struct cpu_info * const ci = curcpu();
/* Need to restore the exception handling state. */
- switch (ci->ci_vfp_id) {
- case FPU_VFP10_ARM10E:
- case FPU_VFP11_ARM11:
- case FPU_VFP_CORTEXA5:
- case FPU_VFP_CORTEXA7:
- case FPU_VFP_CORTEXA8:
- case FPU_VFP_CORTEXA9:
- case FPU_VFP_CORTEXA15:
- write_fpinst2(fregs->vfp_fpinst2);
- write_fpinst(fregs->vfp_fpinst);
- break;
- default:
- panic("%s: Unsupported VFP %#x",
- __func__, ci->ci_vfp_id);
- }
+ armreg_fpinst2_write(fregs->vfp_fpinst2);
+ if (fregs->vfp_fpexc & VFP_FPEXC_FP2V)
+ armreg_fpinst_write(fregs->vfp_fpinst);
}
}
/* Finally, restore the FPEXC but don't enable the VFP. */
fregs->vfp_fpexc |= VFP_FPEXC_EN;
- write_fpexc(fregs->vfp_fpexc);
+ armreg_fpexc_write(fregs->vfp_fpexc);
}
void
vfp_state_save(lwp_t *l, u_int flags)
{
struct pcb * const pcb = lwp_getpcb(l);
- uint32_t fpexc = read_fpexc();
- write_fpexc((fpexc | VFP_FPEXC_EN) & ~VFP_FPEXC_EX);
+ uint32_t fpexc = armreg_fpexc_read();
+ armreg_fpexc_write((fpexc | VFP_FPEXC_EN) & ~VFP_FPEXC_EX);
if (flags & PCU_KERNEL) {
/*
@@ -583,29 +550,16 @@
*/
fregs->vfp_fpexc = fpexc;
if (fpexc & VFP_FPEXC_EX) {
- struct cpu_info * const ci = curcpu();
/* Need to save the exception handling state */
- switch (ci->ci_vfp_id) {
- case FPU_VFP10_ARM10E:
- case FPU_VFP11_ARM11:
- case FPU_VFP_CORTEXA5:
- case FPU_VFP_CORTEXA7:
- case FPU_VFP_CORTEXA8:
- case FPU_VFP_CORTEXA9:
- case FPU_VFP_CORTEXA15:
- fregs->vfp_fpinst = read_fpinst();
- fregs->vfp_fpinst2 = read_fpinst2();
- break;
- default:
- panic("%s: Unsupported VFP %#x",
- __func__, ci->ci_vfp_id);
- }
+ fregs->vfp_fpinst = armreg_fpinst_read();
+ if (fpexc & VFP_FPEXC_FP2V)
+ fregs->vfp_fpinst2 = armreg_fpinst2_read();
}
- fregs->vfp_fpscr = read_fpscr();
+ fregs->vfp_fpscr = armreg_fpscr_read();
save_vfpregs(fregs);
/* Disable the VFP. */
- write_fpexc(fpexc);
+ armreg_fpexc_write(fpexc);
}
Home |
Main Index |
Thread Index |
Old Index