Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * This file is part of FFmpeg.
  3.  *
  4.  * FFmpeg is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Lesser General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2.1 of the License, or (at your option) any later version.
  8.  *
  9.  * FFmpeg is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Lesser General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with FFmpeg; if not, write to the Free Software
  16.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #ifdef __APPLE__
  22. #include <sys/sysctl.h>
  23. #elif defined(__linux__)
  24. #include <asm/cputable.h>
  25. #include <linux/auxvec.h>
  26. #include <fcntl.h>
  27. #if HAVE_UNISTD_H
  28. #include <unistd.h>
  29. #endif
  30. #elif defined(__OpenBSD__)
  31. #include <sys/param.h>
  32. #include <sys/sysctl.h>
  33. #include <machine/cpu.h>
  34. #elif defined(__AMIGAOS4__)
  35. #include <exec/exec.h>
  36. #include <interfaces/exec.h>
  37. #include <proto/exec.h>
  38. #endif /* __APPLE__ */
  39.  
  40. #include "libavutil/avassert.h"
  41. #include "libavutil/cpu.h"
  42. #include "libavutil/cpu_internal.h"
  43.  
  44. /**
  45.  * This function MAY rely on signal() or fork() in order to make sure AltiVec
  46.  * is present.
  47.  */
  48. int ff_get_cpu_flags_ppc(void)
  49. {
  50. #if HAVE_ALTIVEC
  51. #ifdef __AMIGAOS4__
  52.     ULONG result = 0;
  53.     extern struct ExecIFace *IExec;
  54.  
  55.     IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);
  56.     if (result == VECTORTYPE_ALTIVEC)
  57.         return AV_CPU_FLAG_ALTIVEC;
  58.     return 0;
  59. #elif defined(__APPLE__) || defined(__OpenBSD__)
  60. #ifdef __OpenBSD__
  61.     int sels[2] = {CTL_MACHDEP, CPU_ALTIVEC};
  62. #else
  63.     int sels[2] = {CTL_HW, HW_VECTORUNIT};
  64. #endif
  65.     int has_vu = 0;
  66.     size_t len = sizeof(has_vu);
  67.     int err;
  68.  
  69.     err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
  70.  
  71.     if (err == 0)
  72.         return has_vu ? AV_CPU_FLAG_ALTIVEC : 0;
  73.     return 0;
  74. #elif defined(__linux__)
  75.     // The linux kernel could have the altivec support disabled
  76.     // even if the cpu has it.
  77.     int i, ret = 0;
  78.     int fd = open("/proc/self/auxv", O_RDONLY);
  79.     unsigned long buf[64] = { 0 };
  80.     ssize_t count;
  81.  
  82.     if (fd < 0)
  83.         return 0;
  84.  
  85.     while ((count = read(fd, buf, sizeof(buf))) > 0) {
  86.         for (i = 0; i < count / sizeof(*buf); i += 2) {
  87.             if (buf[i] == AT_NULL)
  88.                 goto out;
  89.             if (buf[i] == AT_HWCAP) {
  90.                 if (buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC)
  91.                     ret = AV_CPU_FLAG_ALTIVEC;
  92. #ifdef PPC_FEATURE_HAS_VSX
  93.                 if (buf[i + 1] & PPC_FEATURE_HAS_VSX)
  94.                     ret |= AV_CPU_FLAG_VSX;
  95. #endif
  96. #ifdef PPC_FEATURE_ARCH_2_07
  97.                 if (buf[i + 1] & PPC_FEATURE_HAS_POWER8)
  98.                     ret |= AV_CPU_FLAG_POWER8;
  99. #endif
  100.                 if (ret & AV_CPU_FLAG_VSX)
  101.                     av_assert0(ret & AV_CPU_FLAG_ALTIVEC);
  102.                 goto out;
  103.             }
  104.         }
  105.     }
  106.  
  107. out:
  108.     close(fd);
  109.     return ret;
  110. #elif CONFIG_RUNTIME_CPUDETECT && defined(__linux__)
  111. #define PVR_G4_7400  0x000C
  112. #define PVR_G5_970   0x0039
  113. #define PVR_G5_970FX 0x003C
  114. #define PVR_G5_970MP 0x0044
  115. #define PVR_G5_970GX 0x0045
  116. #define PVR_POWER6   0x003E
  117. #define PVR_POWER7   0x003F
  118. #define PVR_POWER8   0x004B
  119. #define PVR_CELL_PPU 0x0070
  120.     int ret = 0;
  121.     int proc_ver;
  122.     // Support of mfspr PVR emulation added in Linux 2.6.17.
  123.     __asm__ volatile("mfspr %0, 287" : "=r" (proc_ver));
  124.     proc_ver >>= 16;
  125.     if (proc_ver  & 0x8000 ||
  126.         proc_ver == PVR_G4_7400  ||
  127.         proc_ver == PVR_G5_970   ||
  128.         proc_ver == PVR_G5_970FX ||
  129.         proc_ver == PVR_G5_970MP ||
  130.         proc_ver == PVR_G5_970GX ||
  131.         proc_ver == PVR_POWER6   ||
  132.         proc_ver == PVR_POWER7   ||
  133.         proc_ver == PVR_POWER8   ||
  134.         proc_ver == PVR_CELL_PPU)
  135.         ret = AV_CPU_FLAG_ALTIVEC;
  136.     if (proc_ver == PVR_POWER7 ||
  137.         proc_ver == PVR_POWER8)
  138.         ret |= AV_CPU_FLAG_VSX;
  139.     if (proc_ver == PVR_POWER8)
  140.         ret |= AV_CPU_FLAG_POWER8;
  141.  
  142.     return ret;
  143. #else
  144.     // Since we were compiled for AltiVec, just assume we have it
  145.     // until someone comes up with a proper way (not involving signal hacks).
  146.     return AV_CPU_FLAG_ALTIVEC;
  147. #endif /* __AMIGAOS4__ */
  148. #endif /* HAVE_ALTIVEC */
  149.     return 0;
  150. }
  151.