Date: Mon, 19 Mar 2012 22:34:25 +0000 (UTC) From: Olivier Houchard <cognet@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r233216 - in projects/armv6/sys: arm/arm arm/conf arm/include conf Message-ID: <201203192234.q2JMYPUL089600@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: cognet Date: Mon Mar 19 22:34:24 2012 New Revision: 233216 URL: http://svn.freebsd.org/changeset/base/233216 Log: Add VFP/Neon support Submitted by: Mark Tinguely Added: projects/armv6/sys/arm/arm/vfp.c (contents, props changed) projects/armv6/sys/arm/include/vfp.h (contents, props changed) Modified: projects/armv6/sys/arm/arm/genassym.c projects/armv6/sys/arm/arm/swtch.S projects/armv6/sys/arm/arm/undefined.c projects/armv6/sys/arm/conf/PANDABOARD projects/armv6/sys/arm/include/fp.h projects/armv6/sys/arm/include/pcb.h projects/armv6/sys/arm/include/pcpu.h projects/armv6/sys/conf/files.arm projects/armv6/sys/conf/options.arm Modified: projects/armv6/sys/arm/arm/genassym.c ============================================================================== --- projects/armv6/sys/arm/arm/genassym.c Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/arm/arm/genassym.c Mon Mar 19 22:34:24 2012 (r233216) @@ -34,7 +34,9 @@ __FBSDID("$FreeBSD$"); #include <sys/mbuf.h> #include <sys/vmmeter.h> #include <vm/vm.h> +#include <vm/vm_param.h> #include <vm/pmap.h> +#include <vm/vm_map.h> #include <machine/vmparam.h> #include <machine/armreg.h> #include <machine/pcb.h> @@ -105,11 +107,22 @@ ASSYM(TF_PC, offsetof(struct trapframe, ASSYM(P_PID, offsetof(struct proc, p_pid)); ASSYM(P_FLAG, offsetof(struct proc, p_flag)); -#if !defined(SMP) +#ifdef ARM_TP_ADDRESS ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS); ASSYM(ARM_RAS_START, ARM_RAS_START); ASSYM(ARM_RAS_END, ARM_RAS_END); #endif + +#ifdef ARM_VFP_SUPPORT +ASSYM(PCB_VFPSTATE, offsetof(struct pcb, pcb_vfpstate)); +ASSYM(PCB_VFPCPU, offsetof(struct pcb, pcb_vfpcpu)); + +ASSYM(PC_VFPCTHREAD, offsetof(struct pcpu, pc_vfpcthread)); +ASSYM(PC_CPU, offsetof(struct pcpu, pc_cpu)); + +ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap)); +#endif + ASSYM(PAGE_SIZE, PAGE_SIZE); ASSYM(PDESIZE, PDESIZE); ASSYM(PMAP_DOMAIN_KERNEL, PMAP_DOMAIN_KERNEL); Modified: projects/armv6/sys/arm/arm/swtch.S ============================================================================== --- projects/armv6/sys/arm/arm/swtch.S Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/arm/arm/swtch.S Mon Mar 19 22:34:24 2012 (r233216) @@ -88,15 +88,14 @@ __FBSDID("$FreeBSD$"); #define DOMAIN_CLIENT 0x01 #ifdef _ARM_ARCH_6 -#define GET_PCB(tmp) \ - mrc p15, 0, tmp, c13, c0, 4; \ - add tmp, tmp, #(PC_CURPCB) +#define GET_PCPU(tmp) \ + mrc p15, 0, tmp, c13, c0, 4; #else -.Lcurpcb: - .word _C_LABEL(__pcpu) + PC_CURPCB +.Lcurpcpu: + .word _C_LABEL(__pcpu) -#define GET_PCB(tmp) \ - ldr tmp, .Lcurpcb +#define GET_PCPU(tmp) \ + ldr tmp, .Lcurpcpu #endif .Lcpufuncs: @@ -108,11 +107,26 @@ ENTRY(cpu_throw) mov r5, r1 /* + * r0 = oldtd * r5 = newtd */ - ldr r7, [r5, #(TD_PCB)] /* r7 = new thread's PCB */ + GET_PCPU(r7) + +#ifdef ARM_VFP_SUPPORT + /* + * vfp_discard will clear pcpu->pc_vfpcthread, and modify + * and modify the control as needed. + */ + ldr r4, [r7, #(PC_VFPCTHREAD)] /* this thread using vfp? */ + cmp r0, r4 + bne 3f + bl _C_LABEL(vfp_discard) /* yes, shut down vfp */ +3: +#endif /* ARM_VFP_SUPPORT */ + ldr r7, [r5, #(TD_PCB)] /* r7 = new thread's PCB */ + /* Switch to lwp0 context */ ldr r9, .Lcpufuncs @@ -182,7 +196,7 @@ ENTRY(cpu_throw) /* Set the new tp */ ldr r6, [r5, #(TD_MD + MD_TP)] -#ifndef SMP +#ifdef ARM_TP_ADDRESS ldr r4, =ARM_TP_ADDRESS str r6, [r4] ldr r6, [r5, #(TD_MD + MD_RAS_START)] @@ -193,8 +207,8 @@ ENTRY(cpu_throw) mcr p15, 0, r6, c13, c0, 3 #endif /* Hook in a new pcb */ - GET_PCB(r6) - str r7, [r6] + GET_PCPU(r6) + str r7, [r6, #PC_CURPCB] ldmfd sp!, {r4-r7, pc} @@ -212,9 +226,9 @@ ENTRY(cpu_switch) str r1, [r7] /* Hook in a new pcb */ - GET_PCB(r7) + GET_PCPU(r7) ldr r2, [r1, #TD_PCB] - str r2, [r7] + str r2, [r7, #PC_CURPCB] /* rem: r1 = new process */ /* rem: interrupts are enabled */ @@ -240,7 +254,7 @@ ENTRY(cpu_switch) * NOTE: We can now use r8-r13 until it is time to restore * them for the new process. */ -#ifndef SMP +#ifdef ARM_TP_ADDRESS /* Store the old tp */ ldr r3, =ARM_TP_ADDRESS ldr r9, [r3] @@ -270,8 +284,6 @@ ENTRY(cpu_switch) /* Get the user structure for the new process in r9 */ ldr r9, [r1, #(TD_PCB)] - /* r1 now free! */ - mrs r3, cpsr /* * We can do that, since @@ -283,15 +295,39 @@ ENTRY(cpu_switch) str sp, [r2, #(PCB_UND_SP)] msr cpsr_c, r3 /* Restore the old mode */ - /* rem: r8 = old PCB */ + /* rem: r2 = old PCB */ /* rem: r9 = new PCB */ /* rem: interrupts are enabled */ - /* What else needs to be saved Only FPA stuff when that is supported */ +#ifdef ARM_VFP_SUPPORT + /* + * vfp_store will clear pcpu->pc_vfpcthread, save + * registers and state, and modify the control as needed. + * a future exception will bounce the backup settings in the fp unit. + * XXX vfp_store can't change r4 + */ + GET_PCPU(r7) + ldr r8, [r7, #(PC_VFPCTHREAD)] + cmp r4, r8 /* old thread used vfp? */ + bne 1f /* no, don't save */ + cmp r1, r4 /* same thread ? */ + beq 1f /* yes, skip vfp store */ +#ifdef SMP + ldr r8, [r7, #(PC_CPU)] /* last used on this cpu? */ + ldr r3, [r2, #(PCB_VFPCPU)] + cmp r8, r3 /* last cpu to use these registers? */ + bne 1f /* no. these values are stale */ +#endif + add r0, r2, #(PCB_VFPSTATE) + bl _C_LABEL(vfp_store) +1: +#endif /* ARM_VFP_SUPPORT */ + + /* r1 now free! */ /* Third phase : restore saved context */ - /* rem: r8 = old PCB */ + /* rem: r2 = old PCB */ /* rem: r9 = new PCB */ /* rem: interrupts are enabled */ @@ -459,6 +495,27 @@ ENTRY(savectx) /* Store all the registers in the process's pcb */ add r2, r0, #(PCB_R8) stmia r2, {r8-r13} +#ifdef ARM_VFP_SUPPORT + /* + * vfp_store will clear pcpu->pc_vfpcthread, save + * registers and state, and modify the control as needed. + * a future exception will bounce the backup settings in the fp unit. + */ + GET_PCPU(r7) + ldr r4, [r7, #(PC_VFPCTHREAD)] /* vfp thread */ + ldr r2, [r7, #(PC_CURTHREAD)] /* current thread */ + cmp r4, r2 + bne 1f +#ifdef SMP + ldr r2, [r7, #(PC_CPU)] /* last used on this cpu? */ + ldr r3, [r0, #(PCB_VFPCPU)] + cmp r2, r3 + bne 1f /* no. these values are stale */ +#endif + add r0, r0, #(PCB_VFPSTATE) + bl _C_LABEL(vfp_store) +1: +#endif /* ARM_VFP_SUPPORT */ ldmfd sp!, {r4-r7, pc} ENTRY(fork_trampoline) Modified: projects/armv6/sys/arm/arm/undefined.c ============================================================================== --- projects/armv6/sys/arm/arm/undefined.c Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/arm/arm/undefined.c Mon Mar 19 22:34:24 2012 (r233216) @@ -237,10 +237,16 @@ undefinedinstruction(trapframe_t *frame) * instruction trap. */ + coprocessor = 0; if ((fault_instruction & (1 << 27)) != 0) coprocessor = (fault_instruction >> 8) & 0x0f; - else - coprocessor = 0; +#ifdef ARM_VFP_SUPPORT + else { /* check for special instructions */ + if (((fault_instruction & 0xfe000000) == 0xf2000000) || + ((fault_instruction & 0xff100000) == 0xf4000000)) + coprocessor = 10; /* vfp / simd */ + } +#endif /* ARM_VFP_SUPPORT */ if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) { /* Added: projects/armv6/sys/arm/arm/vfp.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/arm/vfp.c Mon Mar 19 22:34:24 2012 (r233216) @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2012 Mark Tinguely + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/kernel.h> + +#include <machine/fp.h> +#include <machine/pcb.h> +#include <machine/undefined.h> +#include <machine/vfp.h> + +/* function prototypes */ +unsigned int get_coprocessorACR(void); +int vfp_bounce(u_int, u_int, struct trapframe *, int); +void vfp_discard(void); +void vfp_enable(void); +void vfp_init(void); +void vfp_restore(struct vfp_state *); +void vfp_store(struct vfp_state *); +void set_coprocessorACR(u_int); + +boolean_t vfp_exists; +static struct undefined_handler vfp10_uh, vfp11_uh; + +/* The VFMXR command using coprocessor commands */ +#define fmxr(reg, val) \ + __asm __volatile("mcr p10, 7, %0, " #reg " , c0, 0" :: "r" (val)); + +/* The VFMRX command using coprocessor commands */ +#define fmrx(reg) \ +({ u_int val = 0;\ + __asm __volatile("mrc p10, 7, %0, " #reg " , c0, 0" : "=r" (val));\ + val; \ +}) + +u_int +get_coprocessorACR(void) +{ + u_int val; + __asm __volatile("mrc p15, 0, %0, c1, c0, 2" : "=r" (val) : : "cc"); + return val; +} + +void +set_coprocessorACR(u_int val) +{ + __asm __volatile("mcr p15, 0, %0, c1, c0, 2\n\t" + "isb\n\t" + : : "r" (val) : "cc"); +} + + + /* called for each cpu */ +void +vfp_init(void) +{ + u_int fpsid, fpexc, tmp; + u_int coproc; + + coproc = get_coprocessorACR(); + coproc |= COPROC10 | COPROC11; + set_coprocessorACR(coproc); + + fpsid = fmrx(cr0); /* read the vfp system id */ + fpexc = fmrx(cr8); /* read the vfp exception reg */ + + if (!(fpsid & VFPSID_HARDSOFT_IMP)) { + vfp_exists = 1; + PCPU_SET(vfpsid, fpsid); /* save the VFPSID */ + if ((fpsid & VFPSID_SUBVERSION2_MASK) == VFP_ARCH3) { + tmp = fmrx(cr7); /* extended registers */ + PCPU_SET(vfpmvfr0, tmp); + tmp = fmrx(cr6); /* extended registers */ + PCPU_SET(vfpmvfr1, tmp); + } + /* initialize the coprocess 10 and 11 calls + * These are called to restore the registers and enable + * the VFP hardware. + */ + if (vfp10_uh.uh_handler == NULL) { + vfp10_uh.uh_handler = vfp_bounce; + vfp11_uh.uh_handler = vfp_bounce; + install_coproc_handler_static(10, &vfp10_uh); + install_coproc_handler_static(11, &vfp11_uh); + } + } +} + +SYSINIT(vfp, SI_SUB_CPU, SI_ORDER_ANY, vfp_init, NULL); + + +/* start VFP unit, restore the vfp registers from the PCB and retry + * the instruction + */ +int +vfp_bounce(u_int addr, u_int insn, struct trapframe *frame, int code) +{ + u_int fpexc; + struct pcb *curpcb; + struct thread *vfptd; + + if (!vfp_exists) + return 1; /* vfp does not exist */ + fpexc = fmrx(cr8); /* read the vfp exception reg */ + if (fpexc & VFPEXC_EN) { + vfptd = PCPU_GET(vfpcthread); + /* did the kernel call the vfp or exception that expect us + * to emulate the command. Newer hardware does not require + * emulation, so we don't emulate yet. + */ +#ifdef SMP + /* don't save if newer registers are on another processor */ + if (vfptd /* && (vfptd == curthread) */ && + (vfptd->td_pcb->pcb_vfpcpu == PCPU_GET(vfpcpu)) +#else + /* someone did not save their registers, */ + if (vfptd /* && (vfptd == curthread) */) +#endif + vfp_store(&vfptd->td_pcb->pcb_vfpstate); + + fpexc &= ~VFPEXC_EN; + fmxr(cr8, fpexc); /* turn vfp hardware off */ + if (vfptd == curthread) { + /* kill the process - we do not handle emulation */ + killproc(curthread->td_proc, "vfp emulation"); + return 1; + } + /* should not happen. someone did not save their context */ + printf("vfp_bounce: vfpcthread: %p curthread: %p\n", + vfptd, curthread); + } + fpexc |= VFPEXC_EN; + fmxr(cr8, fpexc); /* enable the vfp and repeat command */ + curpcb = PCPU_GET(curpcb); + /* If we were the last process to use the VFP, the process did not + * use a VFP on another processor, then the registers in the VFP + * will still be ours and are current. Eventually, we will make the + * restore smarter. + */ + vfp_restore(&curpcb->pcb_vfpstate); +#ifdef SMP + curpcb->pcb_cpu = PCPU_GET(cpu); +#endif + PCPU_SET(vfpcthread, PCPU_GET(curthread)); + return 0; +} + +/* vfs_store is called from from a VFP command to restore the registers and + * turn on the VFP hardware. + * Eventually we will use the information that this process was the last + * to use the VFP hardware and bypass the restore, just turn on the hardware. + */ +void +vfp_restore(struct vfp_state *vfpsave) +{ + u_int vfpscr = 0; + + if (vfpsave) { + __asm __volatile("ldc p10, c0, [%0], #128\n" /* d0-d31 */ +#ifndef VFPv2 + "ldcl p11, c0, [%0], #128\n" /* d16-d31 */ +#else + "add %0, %0, #128\n" /* slip missing regs */ +#endif + "ldr %1, [%0]\n" /* set old vfpscr */ + "mcr p10, 7, %1, cr1, c0, 0\n" + :: "r" (vfpsave), "r" (vfpscr)); + PCPU_SET(vfpcthread, PCPU_GET(curthread)); + } +} + +/* vfs_store is called from switch to save the vfp hardware registers + * into the pcb before switching to another process. + * we already know that the new process is different from this old + * process and that this process last used the VFP registers. + * Below we check to see if the VFP has been enabled since the last + * register save. + * This routine will exit with the VFP turned off. The next VFP user + * will trap to restore its registers and turn on the VFP hardware. + */ +void +vfp_store(struct vfp_state *vfpsave) +{ + u_int tmp, vfpscr = 0; + + tmp = fmrx(cr8); /* Is the vfp enabled? */ + if (vfpsave && tmp & VFPEXC_EN) { + __asm __volatile("stc p11, c0, [%1], #128\n" /* d0-d31 */ +#ifndef VFPv2 + "stcl p11, c0, [%1], #128\n" +#else + "add %1, %1, #128\n" +#endif + "mrc p10, 7, %0, cr1, c0, 0\n" + "str %0, [%1]\n" + : "=&r" (vfpscr) : "r" (vfpsave)); + } +#ifndef SMP + /* eventually we will use this information for UP also */ + PCPU_SET(vfpcthread, 0); +#endif + tmp &= ~VFPEXC_EN; /* disable the vfp hardware */ + fmxr(cr8 , tmp); +} + +/* discard the registers at cpu_thread_free() when fpcurthread == td. + * Turn off the VFP hardware. + */ +void +vfp_discard() +{ + u_int tmp = 0; + + PCPU_SET(vfpcthread, 0); /* permanent forget about reg */ + tmp = fmrx(cr8); + tmp &= ~VFPEXC_EN; /* turn off VFP hardware */ + fmxr(cr8, tmp); +} + +/* Enable the VFP hardware without restoring registers. + * Called when the registers are still in the VFP unit + */ +void +vfp_enable() +{ + u_int tmp = 0; + + tmp = fmrx(cr8); + tmp |= VFPEXC_EN; + fmxr(cr8 , tmp); +} Modified: projects/armv6/sys/arm/conf/PANDABOARD ============================================================================== --- projects/armv6/sys/arm/conf/PANDABOARD Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/arm/conf/PANDABOARD Mon Mar 19 22:34:24 2012 (r233216) @@ -138,3 +138,6 @@ device twl_vreg options FDT options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=pandaboard.dts + +device vfp # vfp/neon +options ARM_VFP_SUPPORT # vfp/neon Modified: projects/armv6/sys/arm/include/fp.h ============================================================================== --- projects/armv6/sys/arm/include/fp.h Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/arm/include/fp.h Mon Mar 19 22:34:24 2012 (r233216) @@ -66,12 +66,19 @@ typedef struct fp_extended_precision fp_ * This needs to move and be hidden from userland. */ +#ifdef ARM_VFP_SUPPORT +struct vfp_state { + u_int64_t reg[32]; + u_int32_t fpscr; +}; +#else struct fpe_sp_state { unsigned int fp_flags; unsigned int fp_sr; unsigned int fp_cr; fp_reg_t fp_registers[16]; }; +#endif /* * Type for a saved FP context, if we want to translate the context to a Modified: projects/armv6/sys/arm/include/pcb.h ============================================================================== --- projects/armv6/sys/arm/include/pcb.h Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/arm/include/pcb.h Mon Mar 19 22:34:24 2012 (r233216) @@ -80,7 +80,12 @@ struct pcb { #define PCB_NOALIGNFLT 0x00000002 caddr_t pcb_onfault; /* On fault handler */ struct pcb_arm32 un_32; +#ifdef ARM_VFP_SUPPORT + struct vfp_state pcb_vfpstate; /* VP/NEON state */ + u_int pcb_vfpcpu; /* VP/NEON last cpu */ +#else struct fpe_sp_state pcb_fpstate; /* Floating Point state */ +#endif }; /* Modified: projects/armv6/sys/arm/include/pcpu.h ============================================================================== --- projects/armv6/sys/arm/include/pcpu.h Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/arm/include/pcpu.h Mon Mar 19 22:34:24 2012 (r233216) @@ -41,7 +41,18 @@ struct vmspace; #endif /* _KERNEL */ -#define PCPU_MD_FIELDS +#ifdef ARM_VFP_SUPPORT +#define PCPU_MD_FIELDS \ + unsigned int pc_cpu; \ + unsigned int pc_vfpsid; \ + unsigned int pc_vfpmvfr0; \ + unsigned int pc_vfpmvfr1; \ + struct thread *pc_vfpcthread; \ + struct pmap *pc_curpmap; +#else +#define PCPU_MD_FIELDS +#endif + #ifdef _KERNEL @@ -50,6 +61,7 @@ struct pcpu; extern struct pcpu *pcpup; #if ARM_ARCH_6 || ARM_ARCH_7A +/* or ARM_TP_ADDRESS mark REMOVE ME NOTE */ static inline struct pcpu * get_pcpu(void) { Added: projects/armv6/sys/arm/include/vfp.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/include/vfp.h Mon Mar 19 22:34:24 2012 (r233216) @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012 Mark Tinguely + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * $FreeBSD$ + */ + + +#ifndef _MACHINE__VFP_H_ +#define _MACHINE__VFP_H_ + +/* fpsid, fpscr, fpexc are defined in the newer gas */ +#define VFPSID cr0 +#define VFPSCR cr1 +#define VMVFR1 cr6 +#define VMVFR0 cr7 +#define VFPEXC cr8 +#define VFPINST cr9 /* vfp 1 and 2 except instruction */ +#define VFPINST2 cr10 /* vfp 2? */ + +/* VFPSID */ +#define VFPSID_IMPLEMENTOR_OFF 24 +#define VFPSID_IMPLEMENTOR_MASK (0xff000000) +#define VFPSID_HARDSOFT_IMP (0x00800000) +#define VFPSID_SINGLE_PREC 20 /* version 1 and 2 */ +#define VFPSID_SUBVERSION_OFF 16 +#define VFPSID_SUBVERSION2_MASK (0x000f0000) /* version 1 and 2 */ +#define VFPSID_SUBVERSION3_MASK (0x007f0000) /* version 3 */ +#define VFP_ARCH3 (0x00030000) +#define VFPSID_PARTNUMBER_OFF 8 +#define VFPSID_PARTNUMBER_MASK (0x0000ff00) +#define VFPSID_VARIANT_OFF 4 +#define VFPSID_VARIANT_MASK (0x000000f0) +#define VFPSID_REVISION_MASK 0x0f + +/* VFPSCR */ +#define VFPSCR_CC_N (0x80000000) /* comparison less than */ +#define VFPSCR_CC_Z (0x40000000) /* comparison equal */ +#define VFPSCR_CC_C (0x20000000) /* comparison = > unordered */ +#define VFPSCR_CC_V (0x10000000) /* comparison unordered */ +#define VFPSCR_QC (0x08000000) /* saturation cululative */ +#define VFPSCR_DN (0x02000000) /* default NaN enable */ +#define VFPSCR_FZ (0x01000000) /* flush to zero enabled */ + +#define VFPSCR_RMODE_OFF 22 /* rounding mode offset */ +#define VFPSCR_RMODE_MASK (0x00c00000) /* rounding mode mask */ +#define VFPSCR_RMODE_RN (0x00000000) /* round nearest */ +#define VFPSCR_RMODE_RPI (0x00400000) /* round to plus infinity */ +#define VFPSCR_RMODE_RNI (0x00800000) /* round to neg infinity */ +#define VFPSCR_RMODE_RM (0x00c00000) /* round to zero */ + +#define VFPSCR_STRIDE_OFF 20 /* vector stride -1 */ +#define VFPSCR_STRIDE_MASK (0x00300000) +#define VFPSCR_LEN_OFF 16 /* vector length -1 */ +#define VFPSCR_LEN_MASK (0x00070000) +#define VFPSCR_IDE (0x00008000) /* input subnormal exc enable */ +#define VFPSCR_IXE (0x00001000) /* inexact exception enable */ +#define VFPSCR_UFE (0x00000800) /* underflow exception enable */ +#define VFPSCR_OFE (0x00000400) /* overflow exception enable */ +#define VFPSCR_DNZ (0x00000200) /* div by zero exception en */ +#define VFPSCR_IOE (0x00000100) /* invalid op exec enable */ +#define VFPSCR_IDC (0x00000080) /* input subnormal cumul */ +#define VFPSCR_IXC (0x00000010) /* Inexact cumulative flag */ +#define VFPSCR_UFC (0x00000008) /* underflow cumulative flag */ +#define VFPSCR_OFC (0x00000004) /* overflow cumulative flag */ +#define VFPSCR_DZC (0x00000002) /* division by zero flag */ +#define VFPSCR_IOC (0x00000001) /* invalid operation cumul */ + +/* VFPEXC */ +#define VFPEXC_EX (0x80000000) /* exception v1 v2 */ +#define VFPEXC_EN (0x40000000) /* vfp enable */ + +/* version 3 registers */ +/* VMVFR0 */ +#define VMVFR0_RM_OFF 28 +#define VMVFR0_RM_MASK (0xf0000000) /* VFP rounding modes */ + +#define VMVFR0_SV_OFF 24 +#define VMVFR0_SV_MASK (0x0f000000) /* VFP short vector supp */ +#define VMVFR0_SR_OFF 20 +#define VMVFR0_SR (0x00f00000) /* VFP hw sqrt supp */ +#define VMVFR0_D_OFF 16 +#define VMVFR0_D_MASK (0x000f0000) /* VFP divide supp */ +#define VMVFR0_TE_OFF 12 +#define VMVFR0_TE_MASK (0x0000f000) /* VFP trap exception supp */ +#define VMVFR0_DP_OFF 8 +#define VMVFR0_DP_MASK (0x00000f00) /* VFP double prec support */ +#define VMVFR0_SP_OFF 4 +#define VMVFR0_SP_MASK (0x000000f0) /* VFP single prec support */ +#define VMVFR0_RB_MASK (0x0000000f) /* VFP 64 bit media support */ + +/* VMVFR1 */ +#define VMVFR1_SP_OFF 16 +#define VMVFR1_SP_MASK (0x000f0000) /* Neon single prec support */ +#define VMVFR1_I_OFF 12 +#define VMVFR1_I_MASK (0x0000f000) /* Neon integer support */ +#define VMVFR1_LS_OFF 8 +#define VMVFR1_LS_MASK (0x00000f00) /* Neon ld/st instr support */ +#define VMVFR1_DN_OFF 4 +#define VMVFR1_DN_MASK (0x000000f0) /* Neon prop NaN support */ +#define VMVFR1_FZ_MASK (0x0000000f) /* Neon denormal arith supp */ + +#define COPROC10 (0x3 << 20) +#define COPROC11 (0x3 << 22) + + +#endif Modified: projects/armv6/sys/conf/files.arm ============================================================================== --- projects/armv6/sys/conf/files.arm Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/conf/files.arm Mon Mar 19 22:34:24 2012 (r233216) @@ -48,6 +48,7 @@ arm/arm/uio_machdep.c standard arm/arm/undefined.c standard arm/arm/vectors.S standard arm/arm/vm_machdep.c standard +arm/arm/vfp.c optional vfp arm/fpe-arm/armfpe_glue.S optional armfpe arm/fpe-arm/armfpe_init.c optional armfpe arm/fpe-arm/armfpe.S optional armfpe Modified: projects/armv6/sys/conf/options.arm ============================================================================== --- projects/armv6/sys/conf/options.arm Mon Mar 19 22:26:15 2012 (r233215) +++ projects/armv6/sys/conf/options.arm Mon Mar 19 22:34:24 2012 (r233216) @@ -5,6 +5,7 @@ ARMFPE opt_global.h ARM_KERN_DIRECTMAP opt_vm.h ARM_L2_PIPT opt_global.h ARM_USE_SMALL_ALLOC opt_global.h +ARM_VFP_SUPPORT opt_global.h AT91C_MASTER_CLOCK opt_global.h AT91C_MAIN_CLOCK opt_at91.h COUNTS_PER_SEC opt_timer.h
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203192234.q2JMYPUL089600>