1 /* 2 * Copyright (c) 2017 The WebM 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 <fcntl.h> 12 #include <unistd.h> 13 #include <stdint.h> 14 #include <asm/cputable.h> 15 #include <linux/auxvec.h> 16 17 #include "./vpx_config.h" 18 #include "vpx_ports/ppc.h" 19 20 #if CONFIG_RUNTIME_CPU_DETECT cpu_env_flags(int * flags)21static int cpu_env_flags(int *flags) { 22 char *env; 23 env = getenv("VPX_SIMD_CAPS"); 24 if (env && *env) { 25 *flags = (int)strtol(env, NULL, 0); 26 return 0; 27 } 28 *flags = 0; 29 return -1; 30 } 31 cpu_env_mask(void)32static int cpu_env_mask(void) { 33 char *env; 34 env = getenv("VPX_SIMD_CAPS_MASK"); 35 return env && *env ? (int)strtol(env, NULL, 0) : ~0; 36 } 37 ppc_simd_caps(void)38int ppc_simd_caps(void) { 39 int flags; 40 int mask; 41 int fd; 42 ssize_t count; 43 unsigned int i; 44 uint64_t buf[64]; 45 46 // If VPX_SIMD_CAPS is set then allow only those capabilities. 47 if (!cpu_env_flags(&flags)) { 48 return flags; 49 } 50 51 mask = cpu_env_mask(); 52 53 fd = open("/proc/self/auxv", O_RDONLY); 54 if (fd < 0) { 55 return 0; 56 } 57 58 while ((count = read(fd, buf, sizeof(buf))) > 0) { 59 for (i = 0; i < (count / sizeof(*buf)); i += 2) { 60 if (buf[i] == AT_HWCAP) { 61 #if HAVE_VSX 62 if (buf[i + 1] & PPC_FEATURE_HAS_VSX) { 63 flags |= HAS_VSX; 64 } 65 #endif // HAVE_VSX 66 goto out_close; 67 } else if (buf[i] == AT_NULL) { 68 goto out_close; 69 } 70 } 71 } 72 out_close: 73 close(fd); 74 return flags & mask; 75 } 76 #else 77 // If there is no RTCD the function pointers are not used and can not be 78 // changed. ppc_simd_caps(void)79int ppc_simd_caps(void) { return 0; } 80 #endif // CONFIG_RUNTIME_CPU_DETECT 81