mirror of
https://github.com/beard7n/bsdports.git
synced 2026-04-10 10:31:20 +02:00
112 lines
4.2 KiB
Plaintext
112 lines
4.2 KiB
Plaintext
Detect ARM CPU features on FreeBSD.
|
|
|
|
elf_aux_info is similar to getauxval but is nop on aarch64.
|
|
|
|
--- lib/freebl/blinit.c.orig 2019-08-30 15:46:32 UTC
|
|
+++ lib/freebl/blinit.c
|
|
@@ -96,8 +96,8 @@ CheckX86CPUSupport()
|
|
#ifndef __has_include
|
|
#define __has_include(x) 0
|
|
#endif
|
|
-#if (__has_include(<sys/auxv.h>) || defined(__linux__)) && \
|
|
- defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)
|
|
+#if defined(__linux__)
|
|
+#if defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)
|
|
/* This might be conflict with host compiler */
|
|
#if !defined(__ANDROID__)
|
|
#include <sys/auxv.h>
|
|
@@ -106,6 +106,10 @@ extern unsigned long getauxval(unsigned long type) __a
|
|
#else
|
|
static unsigned long (*getauxval)(unsigned long) = NULL;
|
|
#endif /* defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)*/
|
|
+#elif defined(__FreeBSD__) && __has_include(<sys/auxv.h>)
|
|
+#include <sys/auxv.h>
|
|
+#define HAVE_ELF_AUX_INFO
|
|
+#endif /* defined(__linux__) */
|
|
|
|
#ifndef AT_HWCAP2
|
|
#define AT_HWCAP2 26
|
|
@@ -118,6 +122,9 @@ static unsigned long (*getauxval)(unsigned long) = NUL
|
|
/* clang-format on */
|
|
|
|
#if defined(__aarch64__)
|
|
+#if defined(__FreeBSD__)
|
|
+#include <machine/armreg.h>
|
|
+#endif
|
|
// Defines from hwcap.h in Linux kernel - ARM64
|
|
#ifndef HWCAP_AES
|
|
#define HWCAP_AES (1 << 3)
|
|
@@ -138,6 +145,7 @@ CheckARMSupport()
|
|
char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON");
|
|
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
|
|
char *disable_pmull = PR_GetEnvSecure("NSS_DISABLE_PMULL");
|
|
+#if defined(__linux__)
|
|
if (getauxval) {
|
|
long hwcaps = getauxval(AT_HWCAP);
|
|
arm_aes_support_ = hwcaps & HWCAP_AES && disable_hw_aes == NULL;
|
|
@@ -145,6 +153,14 @@ CheckARMSupport()
|
|
arm_sha1_support_ = hwcaps & HWCAP_SHA1;
|
|
arm_sha2_support_ = hwcaps & HWCAP_SHA2;
|
|
}
|
|
+#elif defined(__FreeBSD__)
|
|
+ uint64_t id_aa64isar0;
|
|
+ id_aa64isar0 = READ_SPECIALREG(ID_AA64ISAR0_EL1);
|
|
+ arm_aes_support_ = ID_AA64ISAR0_AES(id_aa64isar0) >= ID_AA64ISAR0_AES_BASE && disable_hw_aes == NULL;
|
|
+ arm_pmull_support_ = ID_AA64ISAR0_AES(id_aa64isar0) == ID_AA64ISAR0_AES_PMULL && disable_pmull == NULL;
|
|
+ arm_sha1_support_ = ID_AA64ISAR0_SHA1(id_aa64isar0) == ID_AA64ISAR0_SHA1_BASE;
|
|
+ arm_sha2_support_ = ID_AA64ISAR0_SHA2(id_aa64isar0) >= ID_AA64ISAR0_SHA2_BASE;
|
|
+#endif /* defined(__linux__) */
|
|
/* aarch64 must support NEON. */
|
|
arm_neon_support_ = disable_arm_neon == NULL;
|
|
}
|
|
@@ -187,7 +203,7 @@ GetNeonSupport()
|
|
// If no getauxval, compiler generate NEON instruction by default,
|
|
// we should allow NOEN support.
|
|
return PR_TRUE;
|
|
-#elif !defined(__ANDROID__)
|
|
+#elif defined(__linux__) && !defined(__ANDROID__)
|
|
// Android's cpu-features.c detects features by the following logic
|
|
//
|
|
// - Call getauxval(AT_HWCAP)
|
|
@@ -201,6 +217,10 @@ GetNeonSupport()
|
|
if (getauxval) {
|
|
return (getauxval(AT_HWCAP) & HWCAP_NEON);
|
|
}
|
|
+#elif defined(__FreeBSD__) && defined(HAVE_ELF_AUX_INFO)
|
|
+ unsigned long hwcap = 0;
|
|
+ elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap));
|
|
+ return (hwcap & HWCAP_NEON);
|
|
#endif /* defined(__ARM_NEON) || defined(__ARM_NEON__) */
|
|
return PR_FALSE;
|
|
}
|
|
@@ -249,6 +269,7 @@ void
|
|
CheckARMSupport()
|
|
{
|
|
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
|
|
+#if defined(__linux__)
|
|
if (getauxval) {
|
|
// Android's cpu-features.c uses AT_HWCAP2 for newer features.
|
|
// AT_HWCAP2 is implemented on newer devices / kernel, so we can trust
|
|
@@ -257,13 +278,19 @@ CheckARMSupport()
|
|
// AT_HWCAP2 isn't supported by glibc or Linux kernel, getauxval will
|
|
// returns 0.
|
|
long hwcaps = getauxval(AT_HWCAP2);
|
|
-#ifdef __linux__
|
|
if (!hwcaps) {
|
|
// Some ARMv8 devices may not implement AT_HWCAP2. So we also
|
|
// read /proc/cpuinfo if AT_HWCAP2 is 0.
|
|
hwcaps = ReadCPUInfoForHWCAP2();
|
|
}
|
|
-#endif
|
|
+#elif defined(__FreeBSD__) && defined(HAVE_ELF_AUX_INFO)
|
|
+ unsigned long hwcaps = 0;
|
|
+ elf_aux_info(AT_HWCAP2, &hwcaps, sizeof(hwcaps));
|
|
+ {
|
|
+#else
|
|
+ if (0) {
|
|
+ unsigned long hwcaps = 0;
|
|
+#endif /* defined(__linux__) */
|
|
arm_aes_support_ = hwcaps & HWCAP2_AES && disable_hw_aes == NULL;
|
|
arm_pmull_support_ = hwcaps & HWCAP2_PMULL;
|
|
arm_sha1_support_ = hwcaps & HWCAP2_SHA1;
|