1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <stdlib.h> 12 #include <string.h> 13 #include <features.h> 14 #ifndef __GLIBC_PREREQ 15 #define __GLIBC_PREREQ(a, b) 0 16 #endif 17 #if __GLIBC_PREREQ(2, 16) 18 #include <sys/auxv.h> 19 #else 20 #include <fcntl.h> 21 #include <unistd.h> 22 #include <errno.h> 23 #include <link.h> 24 #endif 25 #include "rtc_base/system/arch.h" 26 #include "system_wrappers/include/cpu_features_wrapper.h" 27 28 #if defined(WEBRTC_ARCH_ARM_FAMILY) 29 #include <asm/hwcap.h> 30 WebRtc_GetCPUFeaturesARM(void)31uint64_t WebRtc_GetCPUFeaturesARM(void) { 32 uint64_t result = 0; 33 int architecture = 0; 34 unsigned long hwcap = 0; 35 const char* platform = NULL; 36 #if __GLIBC_PREREQ(2, 16) 37 hwcap = getauxval(AT_HWCAP); 38 platform = (const char*)getauxval(AT_PLATFORM); 39 #else 40 ElfW(auxv_t) auxv; 41 int fd = open("/proc/self/auxv", O_RDONLY); 42 if (fd >= 0) { 43 while (hwcap == 0 || platform == NULL) { 44 if (read(fd, &auxv, sizeof(auxv)) < (ssize_t)sizeof(auxv)) { 45 if (errno == EINTR) 46 continue; 47 break; 48 } 49 switch (auxv.a_type) { 50 case AT_HWCAP: 51 hwcap = auxv.a_un.a_val; 52 break; 53 case AT_PLATFORM: 54 platform = (const char*)auxv.a_un.a_val; 55 break; 56 } 57 } 58 close(fd); 59 } 60 #endif // __GLIBC_PREREQ(2,16) 61 #if defined(__aarch64__) 62 architecture = 8; 63 if ((hwcap & HWCAP_FP) != 0) 64 result |= kCPUFeatureVFPv3; 65 if ((hwcap & HWCAP_ASIMD) != 0) 66 result |= kCPUFeatureNEON; 67 #else 68 if (platform != NULL) { 69 /* expect a string in the form "v6l" or "v7l", etc. 70 */ 71 if (platform[0] == 'v' && '0' <= platform[1] && platform[1] <= '9' && 72 (platform[2] == 'l' || platform[2] == 'b')) { 73 architecture = platform[1] - '0'; 74 } 75 } 76 if ((hwcap & HWCAP_VFPv3) != 0) 77 result |= kCPUFeatureVFPv3; 78 if ((hwcap & HWCAP_NEON) != 0) 79 result |= kCPUFeatureNEON; 80 #endif 81 if (architecture >= 7) 82 result |= kCPUFeatureARMv7; 83 if (architecture >= 6) 84 result |= kCPUFeatureLDREXSTREX; 85 return result; 86 } 87 #endif // WEBRTC_ARCH_ARM_FAMILY 88