aboutsummaryrefslogtreecommitdiff
path: root/src/hwcaps.c
diff options
context:
space:
mode:
authorMykola Hohsadze <koliagogsadze@gmail.com>2023-09-19 12:02:25 +0300
committerGitHub <noreply@github.com>2023-09-19 11:02:25 +0200
commit89a3f0358a32268d1870a2e35e2a13b49ab7f126 (patch)
tree59669536b3d9c642c11d719f9ad2834e448965e9 /src/hwcaps.c
parent494d9657ef0435cd267ca0ed55c2d726704da9a4 (diff)
downloadcpu_features-89a3f0358a32268d1870a2e35e2a13b49ab7f126.tar.gz
Add FreeBSD Arm64 support (#295)
* Add FreeBSD Arm64 detection Getting all the features is handled by reading /var/run/dmesg.boot. Feature detections were taken from the freebsd kernel code sys/arm64/arm64/identcpu.c * Add FreeBSD Arm64 tests * Add flagm, flagm2 and rng detection * Add HWCAP FreeBSD AArch64 * Update include to use linux hwcaps for powerpc * Add FreeBSD aarch64 impl * Separate Hwacps to freebsd and linux implementation * Add aarch64 midr_el1 implementation * Add detection hwcap cpuid to hwcaps.h * Add MIDR_EL1 tests
Diffstat (limited to 'src/hwcaps.c')
-rw-r--r--src/hwcaps.c143
1 files changed, 1 insertions, 142 deletions
diff --git a/src/hwcaps.c b/src/hwcaps.c
index f44f6c3..6e2e9a8 100644
--- a/src/hwcaps.c
+++ b/src/hwcaps.c
@@ -14,12 +14,7 @@
#include "internal/hwcaps.h"
-#include <stdlib.h>
-#include <string.h>
-
-#include "cpu_features_macros.h"
-#include "internal/filesystem.h"
-#include "internal/string_view.h"
+#include <stdbool.h>
static bool IsSet(const uint32_t mask, const uint32_t value) {
if (mask == 0) return false;
@@ -31,139 +26,3 @@ bool CpuFeatures_IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) ||
IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2);
}
-
-#ifdef CPU_FEATURES_TEST
-// In test mode, hwcaps_for_testing will define the following functions.
-HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
-const char* CpuFeatures_GetPlatformPointer(void);
-const char* CpuFeatures_GetBasePlatformPointer(void);
-#else
-
-// Debug facilities
-#if defined(NDEBUG)
-#define D(...)
-#else
-#include <stdio.h>
-#define D(...) \
- do { \
- printf(__VA_ARGS__); \
- fflush(stdout); \
- } while (0)
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Implementation of GetElfHwcapFromGetauxval
-////////////////////////////////////////////////////////////////////////////////
-
-#define AT_HWCAP 16
-#define AT_HWCAP2 26
-#define AT_PLATFORM 15
-#define AT_BASE_PLATFORM 24
-
-#if defined(HAVE_STRONG_GETAUXVAL)
-#include <sys/auxv.h>
-static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
- return getauxval(hwcap_type);
-}
-#elif defined(HAVE_DLFCN_H)
-// On Android we probe the system's C library for a 'getauxval' function and
-// call it if it exits, or return 0 for failure. This function is available
-// since API level 18.
-//
-// Note that getauxval() can't really be re-implemented here, because its
-// implementation does not parse /proc/self/auxv. Instead it depends on values
-// that are passed by the kernel at process-init time to the C runtime
-// initialization layer.
-
-#include <dlfcn.h>
-
-typedef unsigned long getauxval_func_t(unsigned long);
-
-static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
- uint32_t ret = 0;
- void *libc_handle = NULL;
- getauxval_func_t *func = NULL;
-
- dlerror(); // Cleaning error state before calling dlopen.
- libc_handle = dlopen("libc.so", RTLD_NOW);
- if (!libc_handle) {
- D("Could not dlopen() C library: %s\n", dlerror());
- return 0;
- }
- func = (getauxval_func_t *)dlsym(libc_handle, "getauxval");
- if (!func) {
- D("Could not find getauxval() in C library\n");
- } else {
- // Note: getauxval() returns 0 on failure. Doesn't touch errno.
- ret = (uint32_t)(*func)(hwcap_type);
- }
- dlclose(libc_handle);
- return ret;
-}
-#else
-#error "This platform does not provide hardware capabilities."
-#endif
-
-// Implementation of GetHardwareCapabilities for OS that provide
-// GetElfHwcapFromGetauxval().
-
-// Fallback when getauxval is not available, retrieves hwcaps from
-// "/proc/self/auxv".
-static uint32_t GetElfHwcapFromProcSelfAuxv(uint32_t hwcap_type) {
- struct {
- uint32_t tag;
- uint32_t value;
- } entry;
- uint32_t result = 0;
- const char filepath[] = "/proc/self/auxv";
- const int fd = CpuFeatures_OpenFile(filepath);
- if (fd < 0) {
- D("Could not open %s\n", filepath);
- return 0;
- }
- for (;;) {
- const int ret = CpuFeatures_ReadFile(fd, (char *)&entry, sizeof entry);
- if (ret < 0) {
- D("Error while reading %s\n", filepath);
- break;
- }
- // Detect end of list.
- if (ret == 0 || (entry.tag == 0 && entry.value == 0)) {
- break;
- }
- if (entry.tag == hwcap_type) {
- result = entry.value;
- break;
- }
- }
- CpuFeatures_CloseFile(fd);
- return result;
-}
-
-// Retrieves hardware capabilities by first trying to call getauxval, if not
-// available falls back to reading "/proc/self/auxv".
-static unsigned long GetHardwareCapabilitiesFor(uint32_t type) {
- unsigned long hwcaps = GetElfHwcapFromGetauxval(type);
- if (!hwcaps) {
- D("Parsing /proc/self/auxv to extract ELF hwcaps!\n");
- hwcaps = GetElfHwcapFromProcSelfAuxv(type);
- }
- return hwcaps;
-}
-
-HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void) {
- HardwareCapabilities capabilities;
- capabilities.hwcaps = GetHardwareCapabilitiesFor(AT_HWCAP);
- capabilities.hwcaps2 = GetHardwareCapabilitiesFor(AT_HWCAP2);
- return capabilities;
-}
-
-const char *CpuFeatures_GetPlatformPointer(void) {
- return (const char *)GetHardwareCapabilitiesFor(AT_PLATFORM);
-}
-
-const char *CpuFeatures_GetBasePlatformPointer(void) {
- return (const char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM);
-}
-
-#endif // CPU_FEATURES_TEST