svn commit: r325810 - in stable/11/sys: arm/arm arm/include arm64/include kern mips/include powerpc/include riscv/include sparc64/include sys x86/include

John Baldwin jhb at FreeBSD.org
Tue Nov 14 16:03:10 UTC 2017


Author: jhb
Date: Tue Nov 14 16:03:07 2017
New Revision: 325810
URL: https://svnweb.freebsd.org/changeset/base/325810

Log:
  MFC 323580,323933,323934,324814,324817: Enable AT_HWCAP on arm.
  
  I reused the SV_HWCAP stub to cover the sv_hwcap2 field as well.
  
  323580:
  Add AT_HWCAP flags for VFP settings for FreeBSD/arm.
  
  These flags match the meaning and value of flags in Linux, though
  Linux has many more flags.
  
  323933:
  Correct HWCAP_VFP3* values to match Linux.
  
  323934:
  Detect NEON and set HWCAP_NEON if present.
  
  324814:
  Add AT_HWCAP2 ELF auxiliary vector.
   - allocate value for new AT_HWCAP2 auxiliary vector on all platforms.
   - expand 'struct sysentvec' by new 'u_long *sv_hwcap2', in exactly
     same way as for AT_HWCAP.
  
  324817:
  Fullify implementation of AT_HWCAP and AT_HWCAP2 for ARMv6,7.
  This makes elf_aux_info(3) useable for ARM ports.
  
  Tested by:	mmel

Modified:
  stable/11/sys/arm/arm/cpuinfo.c
  stable/11/sys/arm/arm/elf_machdep.c
  stable/11/sys/arm/arm/vfp.c
  stable/11/sys/arm/include/elf.h
  stable/11/sys/arm/include/md_var.h
  stable/11/sys/arm/include/vfp.h
  stable/11/sys/arm64/include/elf.h
  stable/11/sys/kern/imgact_elf.c
  stable/11/sys/mips/include/elf.h
  stable/11/sys/powerpc/include/elf.h
  stable/11/sys/riscv/include/elf.h
  stable/11/sys/sparc64/include/elf.h
  stable/11/sys/sys/sysent.h
  stable/11/sys/x86/include/elf.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/arm/cpuinfo.c
==============================================================================
--- stable/11/sys/arm/arm/cpuinfo.c	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/arm/arm/cpuinfo.c	Tue Nov 14 16:03:07 2017	(r325810)
@@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/cpu.h>
 #include <machine/cpuinfo.h>
+#include <machine/elf.h>
+#include <machine/md_var.h>
 
 struct cpuinfo cpuinfo =
 {
@@ -47,6 +49,9 @@ struct cpuinfo cpuinfo =
 void
 cpuinfo_init(void)
 {
+#if __ARM_ARCH >= 6
+	uint32_t tmp;
+#endif
 
 	cpuinfo.midr = cp15_midr_get();
 	/* Test old version id schemes first */
@@ -150,6 +155,47 @@ cpuinfo_init(void)
 	}
 	cpuinfo.dcache_line_mask = cpuinfo.dcache_line_size - 1;
 	cpuinfo.icache_line_mask = cpuinfo.icache_line_size - 1;
+
+	/* Fill AT_HWCAP bits. */
+	elf_hwcap |= HWCAP_HALF | HWCAP_FAST_MULT; /* Requierd for all CPUs */
+	elf_hwcap |= HWCAP_TLS | HWCAP_EDSP;	   /* Requierd for v6+ CPUs */
+
+	tmp = (cpuinfo.id_isar0 >> 24) & 0xF;	/* Divide_instrs */
+	if (tmp >= 1)
+		elf_hwcap |= HWCAP_IDIVT;
+	if (tmp >= 2)
+		elf_hwcap |= HWCAP_IDIVA;
+
+	tmp = (cpuinfo.id_pfr0 >> 4) & 0xF; 	/* State1  */
+	if (tmp >= 1)
+		elf_hwcap |= HWCAP_THUMB;
+
+	tmp = (cpuinfo.id_pfr0 >> 12) & 0xF; 	/* State3  */
+	if (tmp >= 1)
+		elf_hwcap |= HWCAP_THUMBEE;
+
+	tmp = (cpuinfo.id_mmfr0 >> 0) & 0xF; 	/* VMSA */
+	if (tmp >= 5)
+		elf_hwcap |= HWCAP_LPAE;
+
+	/* Fill AT_HWCAP2 bits. */
+	tmp = (cpuinfo.id_isar5 >> 4) & 0xF;	/* AES */
+	if (tmp >= 1)
+		elf_hwcap2 |= HWCAP2_AES;
+	if (tmp >= 2)
+		elf_hwcap2 |= HWCAP2_PMULL;
+
+	tmp = (cpuinfo.id_isar5 >> 8) & 0xF;	/* SHA1 */
+	if (tmp >= 1)
+		elf_hwcap2 |= HWCAP2_SHA1;
+
+	tmp = (cpuinfo.id_isar5 >> 12) & 0xF;	/* SHA2 */
+	if (tmp >= 1)
+		elf_hwcap2 |= HWCAP2_SHA2;
+
+	tmp = (cpuinfo.id_isar5 >> 16) & 0xF;	/* CRC32 */
+	if (tmp >= 1)
+		elf_hwcap2 |= HWCAP2_CRC32;
 #endif
 }
 

Modified: stable/11/sys/arm/arm/elf_machdep.c
==============================================================================
--- stable/11/sys/arm/arm/elf_machdep.c	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/arm/arm/elf_machdep.c	Tue Nov 14 16:03:07 2017	(r325810)
@@ -48,6 +48,9 @@ __FBSDID("$FreeBSD$");
 
 static boolean_t elf32_arm_abi_supported(struct image_params *);
 
+u_long elf_hwcap;
+u_long elf_hwcap2;
+
 struct sysentvec elf32_freebsd_sysvec = {
 	.sv_size	= SYS_MAXSYSCALL,
 	.sv_table	= sysent,
@@ -77,7 +80,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 #if __ARM_ARCH >= 6
 			  SV_SHP | SV_TIMEKEEP |
 #endif
-			  SV_ABI_FREEBSD | SV_ILP32,
+			  SV_ABI_FREEBSD | SV_ILP32 | SV_HWCAP,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,
@@ -86,6 +89,8 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_schedtail	= NULL,
 	.sv_thread_detach = NULL,
 	.sv_trap	= NULL,
+	.sv_hwcap	= &elf_hwcap,
+	.sv_hwcap2	= &elf_hwcap2,
 };
 INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
 

Modified: stable/11/sys/arm/arm/vfp.c
==============================================================================
--- stable/11/sys/arm/arm/vfp.c	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/arm/arm/vfp.c	Tue Nov 14 16:03:07 2017	(r325810)
@@ -33,9 +33,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
+#include <sys/imgact_elf.h>
 #include <sys/kernel.h>
 
 #include <machine/armreg.h>
+#include <machine/elf.h>
 #include <machine/frame.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
@@ -115,6 +117,7 @@ vfp_init(void)
 		vfp_exists = 1;
 		is_d32 = 0;
 		PCPU_SET(vfpsid, fpsid);	/* save the fpsid */
+		elf_hwcap |= HWCAP_VFP;
 
 		vfp_arch =
 		    (fpsid & VFPSID_SUBVERSION2_MASK) >> VFPSID_SUBVERSION_OFF;
@@ -122,9 +125,13 @@ vfp_init(void)
 		if (vfp_arch >= VFP_ARCH3) {
 			tmp = fmrx(mvfr0);
 			PCPU_SET(vfpmvfr0, tmp);
+			elf_hwcap |= HWCAP_VFPv3;
 
-			if ((tmp & VMVFR0_RB_MASK) == 2)
+			if ((tmp & VMVFR0_RB_MASK) == 2) {
+				elf_hwcap |= HWCAP_VFPD32;
 				is_d32 = 1;
+			} else
+				elf_hwcap |= HWCAP_VFPv3D16;
 
 			tmp = fmrx(mvfr1);
 			PCPU_SET(vfpmvfr1, tmp);
@@ -137,6 +144,13 @@ vfp_init(void)
 					    initial_fpscr;
 				}
 			}
+
+			if ((tmp & VMVFR1_LS_MASK) >> VMVFR1_LS_OFF == 1 &&
+			    (tmp & VMVFR1_I_MASK) >> VMVFR1_I_OFF == 1 &&
+			    (tmp & VMVFR1_SP_MASK) >> VMVFR1_SP_OFF == 1)
+				elf_hwcap |= HWCAP_NEON;
+			if ((tmp & VMVFR1_FMAC_MASK) >>  VMVFR1_FMAC_OFF == 1)
+				elf_hwcap |= HWCAP_VFPv4;
 		}
 
 		/* initialize the coprocess 10 and 11 calls

Modified: stable/11/sys/arm/include/elf.h
==============================================================================
--- stable/11/sys/arm/include/elf.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/arm/include/elf.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -86,8 +86,9 @@ __ElfType(Auxinfo);
 #define	AT_STACKPROT	23	/* Initial stack protection. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 #define	R_ARM_COUNT	33	/* Count of defined relocation types. */
 
@@ -114,5 +115,38 @@ __ElfType(Auxinfo);
 #define	MAGIC_TRAMP_NUMBER	0x5c000003
 
 #define	ET_DYN_LOAD_ADDR	0x12000
+
+/* Flags passed in AT_HWCAP. */
+#define	HWCAP_SWP		0x00000001	/* Unsupported, never set.    */
+#define	HWCAP_HALF		0x00000002	/* Always set.                */
+#define	HWCAP_THUMB		0x00000004
+#define	HWCAP_26BIT		0x00000008	/* Unsupported, never set.    */
+#define	HWCAP_FAST_MULT		0x00000010	/* Always set.                */
+#define	HWCAP_FPA		0x00000020	/* Unsupported, never set.    */
+#define	HWCAP_VFP		0x00000040
+#define	HWCAP_EDSP		0x00000080	/* Always set for ARMv6+.     */
+#define	HWCAP_JAVA		0x00000100	/* Unsupported, never set.    */
+#define	HWCAP_IWMMXT		0x00000200	/* Unsupported, never set.    */
+#define	HWCAP_CRUNCH		0x00000400	/* Unsupported, never set.    */
+#define	HWCAP_THUMBEE		0x00000800
+#define	HWCAP_NEON		0x00001000
+#define	HWCAP_VFPv3		0x00002000
+#define	HWCAP_VFPv3D16		0x00004000
+#define	HWCAP_TLS		0x00008000	/* Always set for ARMv6+.     */
+#define	HWCAP_VFPv4		0x00010000
+#define	HWCAP_IDIVA		0x00020000
+#define	HWCAP_IDIVT		0x00040000
+#define	HWCAP_VFPD32		0x00080000
+#define	HWCAP_IDIV		(HWCAP_IDIVA | HWCAP_IDIVT)
+#define	HWCAP_LPAE		0x00100000
+#define	HWCAP_EVTSTRM		0x00200000	/* Not implemented yet.       */
+
+
+/* Flags passed in AT_HWCAP2. */
+#define	HWCAP2_AES		0x00000001
+#define	HWCAP2_PMULL		0x00000002
+#define	HWCAP2_SHA1		0x00000004
+#define	HWCAP2_SHA2		0x00000008
+#define	HWCAP2_CRC32		0x00000010
 
 #endif /* !_MACHINE_ELF_H_ */

Modified: stable/11/sys/arm/include/md_var.h
==============================================================================
--- stable/11/sys/arm/include/md_var.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/arm/include/md_var.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -38,6 +38,8 @@ extern char sigcode[];
 extern int szsigcode;
 extern uint32_t *vm_page_dump;
 extern int vm_page_dump_size;
+extern u_long elf_hwcap;
+extern u_long elf_hwcap2;
 
 extern int (*_arm_memcpy)(void *, void *, int, int);
 extern int (*_arm_bzero)(void *, int, int);

Modified: stable/11/sys/arm/include/vfp.h
==============================================================================
--- stable/11/sys/arm/include/vfp.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/arm/include/vfp.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -119,6 +119,12 @@
 #define	VMVFR0_RB_MASK		(0x0000000f)	/* VFP 64 bit media support */
 
 /* VMVFR1 */
+#define	VMVFR1_FMAC_OFF		28
+#define	VMVFR1_FMAC_MASK 	(0xf0000000)	/* Neon FMAC support */
+#define	VMVFR1_VFP_HP_OFF	24
+#define	VMVFR1_VFP_HP_MASK 	(0x0f000000)	/* VFP half prec support */
+#define	VMVFR1_HP_OFF		20
+#define	VMVFR1_HP_MASK 		(0x00f00000)	/* Neon half prec support */
 #define	VMVFR1_SP_OFF		16
 #define	VMVFR1_SP_MASK 		(0x000f0000)	/* Neon single prec support */
 #define VMVFR1_I_OFF		12

Modified: stable/11/sys/arm64/include/elf.h
==============================================================================
--- stable/11/sys/arm64/include/elf.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/arm64/include/elf.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -92,8 +92,9 @@ __ElfType(Auxinfo);
 #define	AT_STACKPROT	23	/* Initial stack protection. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 /* Define "machine" characteristics */
 #define	ELF_TARG_CLASS	ELFCLASS64

Modified: stable/11/sys/kern/imgact_elf.c
==============================================================================
--- stable/11/sys/kern/imgact_elf.c	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/kern/imgact_elf.c	Tue Nov 14 16:03:07 2017	(r325810)
@@ -1133,9 +1133,12 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct 
 	AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->sysent->sv_shared_page_obj
 	    != NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
 	    imgp->sysent->sv_stackprot);
-	if ((imgp->sysent->sv_flags & SV_HWCAP) != 0 &&
-	    imgp->sysent->sv_hwcap != NULL)
-		AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap);
+	if ((imgp->sysent->sv_flags & SV_HWCAP) != 0) {
+		if (imgp->sysent->sv_hwcap != NULL)
+			AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap);
+		if (imgp->sysent->sv_hwcap2 != NULL)
+			AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2);
+	}
 	AUXARGS_ENTRY(pos, AT_NULL, 0);
 
 	free(imgp->auxargs, M_TEMP);

Modified: stable/11/sys/mips/include/elf.h
==============================================================================
--- stable/11/sys/mips/include/elf.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/mips/include/elf.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -146,8 +146,9 @@ __ElfType(Auxinfo);
 #define	AT_STACKPROT	23	/* Initial stack protection. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 #define	ET_DYN_LOAD_ADDR 0x0120000
 

Modified: stable/11/sys/powerpc/include/elf.h
==============================================================================
--- stable/11/sys/powerpc/include/elf.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/powerpc/include/elf.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -109,8 +109,9 @@ __ElfType(Auxinfo);
 #define	AT_TIMEKEEP	22	/* Pointer to timehands. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 /*
  * Relocation types.

Modified: stable/11/sys/riscv/include/elf.h
==============================================================================
--- stable/11/sys/riscv/include/elf.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/riscv/include/elf.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -92,8 +92,9 @@ __ElfType(Auxinfo);
 #define	AT_STACKPROT	23	/* Initial stack protection. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 /* Define "machine" characteristics */
 #define	ELF_TARG_CLASS	ELFCLASS64

Modified: stable/11/sys/sparc64/include/elf.h
==============================================================================
--- stable/11/sys/sparc64/include/elf.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/sparc64/include/elf.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -94,8 +94,9 @@ __ElfType(Auxinfo);
 #define	AT_STACKPROT	23	/* Initial stack protection. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 /* Define "machine" characteristics */
 #if __ELF_WORD_SIZE == 32

Modified: stable/11/sys/sys/sysent.h
==============================================================================
--- stable/11/sys/sys/sysent.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/sys/sysent.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -130,6 +130,7 @@ struct sysentvec {
 	void		(*sv_thread_detach)(struct thread *);
 	int		(*sv_trap)(struct thread *);
 	u_long		*sv_hwcap;	/* Value passed in AT_HWCAP. */
+	u_long		*sv_hwcap2;	/* Value passed in AT_HWCAP2. */
 };
 
 #define	SV_ILP32	0x000100	/* 32-bit executable. */

Modified: stable/11/sys/x86/include/elf.h
==============================================================================
--- stable/11/sys/x86/include/elf.h	Tue Nov 14 16:00:21 2017	(r325809)
+++ stable/11/sys/x86/include/elf.h	Tue Nov 14 16:03:07 2017	(r325810)
@@ -102,8 +102,9 @@ __ElfType(Auxinfo);
 #define	AT_STACKPROT	23	/* Initial stack protection. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 /*
  * Relocation types.
@@ -189,8 +190,9 @@ __ElfType(Auxinfo);
 #define	AT_STACKPROT	23	/* Initial stack protection. */
 #define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
 #define	AT_HWCAP	25	/* CPU feature flags. */
+#define	AT_HWCAP2	26	/* CPU feature flags 2. */
 
-#define	AT_COUNT	26	/* Count of defined aux entry types. */
+#define	AT_COUNT	27	/* Count of defined aux entry types. */
 
 /*
  * Relocation types.


More information about the svn-src-all mailing list