svn commit: r233216 - in projects/armv6/sys: arm/arm arm/conf
arm/include conf
Olivier Houchard
cognet at FreeBSD.org
Mon Mar 19 22:34:25 UTC 2012
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
More information about the svn-src-projects
mailing list