Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Oct 2017 12:16:21 +0000 (UTC)
From:      Michal Meloun <mmel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r324817 - in head/sys/arm: arm include
Message-ID:  <201710211216.v9LCGLhW037272@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mmel
Date: Sat Oct 21 12:16:21 2017
New Revision: 324817
URL: https://svnweb.freebsd.org/changeset/base/324817

Log:
  Fullify implementation of AT_HWCAP and AT_HWCAP2 for ARMv6,7.
  This makes elf_aux_info(3) useable for ARM ports.
  
  MFC after:	1 month

Modified:
  head/sys/arm/arm/cpuinfo.c
  head/sys/arm/arm/elf_machdep.c
  head/sys/arm/arm/vfp.c
  head/sys/arm/include/elf.h
  head/sys/arm/include/md_var.h
  head/sys/arm/include/vfp.h

Modified: head/sys/arm/arm/cpuinfo.c
==============================================================================
--- head/sys/arm/arm/cpuinfo.c	Sat Oct 21 12:15:12 2017	(r324816)
+++ head/sys/arm/arm/cpuinfo.c	Sat Oct 21 12:16:21 2017	(r324817)
@@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/cpu.h>
 #include <machine/cpuinfo.h>
+#include <machine/elf.h>
+#include <machine/md_var.h>
 
 #if __ARM_ARCH >= 6
 void reinit_mmu(uint32_t ttb, uint32_t aux_clr, uint32_t aux_set);
@@ -77,6 +79,9 @@ SYSCTL_INT(_hw_cpu_quirks, OID_AUTO, actlr_set,
 void
 cpuinfo_init(void)
 {
+#if __ARM_ARCH >= 6
+	uint32_t tmp;
+#endif
 
 	/*
 	 * Prematurely fetch CPU quirks. Standard fetch for tunable
@@ -190,6 +195,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: head/sys/arm/arm/elf_machdep.c
==============================================================================
--- head/sys/arm/arm/elf_machdep.c	Sat Oct 21 12:15:12 2017	(r324816)
+++ head/sys/arm/arm/elf_machdep.c	Sat Oct 21 12:16:21 2017	(r324817)
@@ -52,6 +52,7 @@ __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,
@@ -92,6 +93,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_thread_detach = NULL,
 	.sv_trap	= NULL,
 	.sv_hwcap	= &elf_hwcap,
+	.sv_hwcap2	= &elf_hwcap2,
 };
 INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
 

Modified: head/sys/arm/arm/vfp.c
==============================================================================
--- head/sys/arm/arm/vfp.c	Sat Oct 21 12:15:12 2017	(r324816)
+++ head/sys/arm/arm/vfp.c	Sat Oct 21 12:16:21 2017	(r324817)
@@ -149,6 +149,8 @@ vfp_init(void)
 			    (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: head/sys/arm/include/elf.h
==============================================================================
--- head/sys/arm/include/elf.h	Sat Oct 21 12:15:12 2017	(r324816)
+++ head/sys/arm/include/elf.h	Sat Oct 21 12:16:21 2017	(r324817)
@@ -117,10 +117,36 @@ __ElfType(Auxinfo);
 #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: head/sys/arm/include/md_var.h
==============================================================================
--- head/sys/arm/include/md_var.h	Sat Oct 21 12:15:12 2017	(r324816)
+++ head/sys/arm/include/md_var.h	Sat Oct 21 12:16:21 2017	(r324817)
@@ -39,6 +39,7 @@ 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: head/sys/arm/include/vfp.h
==============================================================================
--- head/sys/arm/include/vfp.h	Sat Oct 21 12:15:12 2017	(r324816)
+++ head/sys/arm/include/vfp.h	Sat Oct 21 12:16:21 2017	(r324817)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201710211216.v9LCGLhW037272>