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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to