1*fb1b10abSAndroid Build Coastguard Worker /* 2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2017 The WebM project authors. All Rights Reserved. 3*fb1b10abSAndroid Build Coastguard Worker * 4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*fb1b10abSAndroid Build Coastguard Worker */ 10*fb1b10abSAndroid Build Coastguard Worker 11*fb1b10abSAndroid Build Coastguard Worker #include <fcntl.h> 12*fb1b10abSAndroid Build Coastguard Worker #include <unistd.h> 13*fb1b10abSAndroid Build Coastguard Worker #include <stdint.h> 14*fb1b10abSAndroid Build Coastguard Worker #include <asm/cputable.h> 15*fb1b10abSAndroid Build Coastguard Worker #include <linux/auxvec.h> 16*fb1b10abSAndroid Build Coastguard Worker 17*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h" 18*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/ppc.h" 19*fb1b10abSAndroid Build Coastguard Worker 20*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RUNTIME_CPU_DETECT cpu_env_flags(int * flags)21*fb1b10abSAndroid Build Coastguard Workerstatic int cpu_env_flags(int *flags) { 22*fb1b10abSAndroid Build Coastguard Worker char *env; 23*fb1b10abSAndroid Build Coastguard Worker env = getenv("VPX_SIMD_CAPS"); 24*fb1b10abSAndroid Build Coastguard Worker if (env && *env) { 25*fb1b10abSAndroid Build Coastguard Worker *flags = (int)strtol(env, NULL, 0); 26*fb1b10abSAndroid Build Coastguard Worker return 0; 27*fb1b10abSAndroid Build Coastguard Worker } 28*fb1b10abSAndroid Build Coastguard Worker *flags = 0; 29*fb1b10abSAndroid Build Coastguard Worker return -1; 30*fb1b10abSAndroid Build Coastguard Worker } 31*fb1b10abSAndroid Build Coastguard Worker cpu_env_mask(void)32*fb1b10abSAndroid Build Coastguard Workerstatic int cpu_env_mask(void) { 33*fb1b10abSAndroid Build Coastguard Worker char *env; 34*fb1b10abSAndroid Build Coastguard Worker env = getenv("VPX_SIMD_CAPS_MASK"); 35*fb1b10abSAndroid Build Coastguard Worker return env && *env ? (int)strtol(env, NULL, 0) : ~0; 36*fb1b10abSAndroid Build Coastguard Worker } 37*fb1b10abSAndroid Build Coastguard Worker ppc_simd_caps(void)38*fb1b10abSAndroid Build Coastguard Workerint ppc_simd_caps(void) { 39*fb1b10abSAndroid Build Coastguard Worker int flags; 40*fb1b10abSAndroid Build Coastguard Worker int mask; 41*fb1b10abSAndroid Build Coastguard Worker int fd; 42*fb1b10abSAndroid Build Coastguard Worker ssize_t count; 43*fb1b10abSAndroid Build Coastguard Worker unsigned int i; 44*fb1b10abSAndroid Build Coastguard Worker uint64_t buf[64]; 45*fb1b10abSAndroid Build Coastguard Worker 46*fb1b10abSAndroid Build Coastguard Worker // If VPX_SIMD_CAPS is set then allow only those capabilities. 47*fb1b10abSAndroid Build Coastguard Worker if (!cpu_env_flags(&flags)) { 48*fb1b10abSAndroid Build Coastguard Worker return flags; 49*fb1b10abSAndroid Build Coastguard Worker } 50*fb1b10abSAndroid Build Coastguard Worker 51*fb1b10abSAndroid Build Coastguard Worker mask = cpu_env_mask(); 52*fb1b10abSAndroid Build Coastguard Worker 53*fb1b10abSAndroid Build Coastguard Worker fd = open("/proc/self/auxv", O_RDONLY); 54*fb1b10abSAndroid Build Coastguard Worker if (fd < 0) { 55*fb1b10abSAndroid Build Coastguard Worker return 0; 56*fb1b10abSAndroid Build Coastguard Worker } 57*fb1b10abSAndroid Build Coastguard Worker 58*fb1b10abSAndroid Build Coastguard Worker while ((count = read(fd, buf, sizeof(buf))) > 0) { 59*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < (count / sizeof(*buf)); i += 2) { 60*fb1b10abSAndroid Build Coastguard Worker if (buf[i] == AT_HWCAP) { 61*fb1b10abSAndroid Build Coastguard Worker #if HAVE_VSX 62*fb1b10abSAndroid Build Coastguard Worker if (buf[i + 1] & PPC_FEATURE_HAS_VSX) { 63*fb1b10abSAndroid Build Coastguard Worker flags |= HAS_VSX; 64*fb1b10abSAndroid Build Coastguard Worker } 65*fb1b10abSAndroid Build Coastguard Worker #endif // HAVE_VSX 66*fb1b10abSAndroid Build Coastguard Worker goto out_close; 67*fb1b10abSAndroid Build Coastguard Worker } else if (buf[i] == AT_NULL) { 68*fb1b10abSAndroid Build Coastguard Worker goto out_close; 69*fb1b10abSAndroid Build Coastguard Worker } 70*fb1b10abSAndroid Build Coastguard Worker } 71*fb1b10abSAndroid Build Coastguard Worker } 72*fb1b10abSAndroid Build Coastguard Worker out_close: 73*fb1b10abSAndroid Build Coastguard Worker close(fd); 74*fb1b10abSAndroid Build Coastguard Worker return flags & mask; 75*fb1b10abSAndroid Build Coastguard Worker } 76*fb1b10abSAndroid Build Coastguard Worker #else 77*fb1b10abSAndroid Build Coastguard Worker // If there is no RTCD the function pointers are not used and can not be 78*fb1b10abSAndroid Build Coastguard Worker // changed. ppc_simd_caps(void)79*fb1b10abSAndroid Build Coastguard Workerint ppc_simd_caps(void) { return 0; } 80*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_RUNTIME_CPU_DETECT 81