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