ppc_cpudetect.c 1.8 KB

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