summaryrefslogtreecommitdiff
path: root/sys/arm
diff options
context:
space:
mode:
authorMichal Meloun <mmel@FreeBSD.org>2017-10-21 12:16:21 +0000
committerMichal Meloun <mmel@FreeBSD.org>2017-10-21 12:16:21 +0000
commit0cbf724ed03571bc90ed22c3b4bf8c6c7b2da564 (patch)
tree3a658676797994364f9fcfa57d39de577bb0dbb8 /sys/arm
parentc8759f09966dfedc75faea567c2f159582436709 (diff)
downloadsrc-test2-0cbf724ed03571bc90ed22c3b4bf8c6c7b2da564.tar.gz
src-test2-0cbf724ed03571bc90ed22c3b4bf8c6c7b2da564.zip
Notes
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/cpuinfo.c46
-rw-r--r--sys/arm/arm/elf_machdep.c2
-rw-r--r--sys/arm/arm/vfp.c2
-rw-r--r--sys/arm/include/elf.h26
-rw-r--r--sys/arm/include/md_var.h1
-rw-r--r--sys/arm/include/vfp.h6
6 files changed, 83 insertions, 0 deletions
diff --git a/sys/arm/arm/cpuinfo.c b/sys/arm/arm/cpuinfo.c
index 5dceab37be00..0566f999bdbb 100644
--- a/sys/arm/arm/cpuinfo.c
+++ b/sys/arm/arm/cpuinfo.c
@@ -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
}
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index fba35eb159c6..cc8ef9994f0f 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -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);
diff --git a/sys/arm/arm/vfp.c b/sys/arm/arm/vfp.c
index 6a07a5595513..7e3e728ce1d2 100644
--- a/sys/arm/arm/vfp.c
+++ b/sys/arm/arm/vfp.c
@@ -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
diff --git a/sys/arm/include/elf.h b/sys/arm/include/elf.h
index 7e1564720026..ee854f76adde 100644
--- a/sys/arm/include/elf.h
+++ b/sys/arm/include/elf.h
@@ -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_ */
diff --git a/sys/arm/include/md_var.h b/sys/arm/include/md_var.h
index 46d834b9ba36..39a174ee7a42 100644
--- a/sys/arm/include/md_var.h
+++ b/sys/arm/include/md_var.h
@@ -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);
diff --git a/sys/arm/include/vfp.h b/sys/arm/include/vfp.h
index 94e7a2d20a88..15ae54030005 100644
--- a/sys/arm/include/vfp.h
+++ b/sys/arm/include/vfp.h
@@ -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