cpuid.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include <aws/common/cpuid.h>
  16. #include <stdlib.h>
  17. #if defined(__linux__) || defined(__FreeBSD__)
  18. # include <sys/auxv.h>
  19. static unsigned long s_hwcap[2];
  20. static bool s_hwcap_cached;
  21. struct cap_bits {
  22. unsigned long cap;
  23. unsigned long bit;
  24. };
  25. # if (defined(__aarch64__))
  26. struct cap_bits s_check_cap[AWS_CPU_FEATURE_COUNT] = {
  27. [AWS_CPU_FEATURE_ARM_CRC] = {0, 1 << 7 /* HWCAP_CRC */},
  28. };
  29. # else
  30. struct cap_bits s_check_cap[AWS_CPU_FEATURE_COUNT] = {
  31. [AWS_CPU_FEATURE_ARM_CRC] = {1, 1 << 4 /* HWCAP_CRC */},
  32. };
  33. # endif
  34. # if (defined(__linux__))
  35. static void s_cache_hwcap(void) {
  36. s_hwcap[0] = getauxval(AT_HWCAP);
  37. s_hwcap[1] = getauxval(AT_HWCAP2);
  38. s_hwcap_cached = true;
  39. }
  40. # elif (defined(__FreeBSD__))
  41. static void s_cache_hwcap(void) {
  42. int ret;
  43. ret = elf_aux_info(AT_HWCAP, &s_hwcap[0], sizeof(unsigned long));
  44. if (ret)
  45. s_hwcap[0] = 0;
  46. ret = elf_aux_info(AT_HWCAP2, &s_hwcap[1], sizeof(unsigned long));
  47. if (ret)
  48. s_hwcap[1] = 0;
  49. s_hwcap_cached = true;
  50. }
  51. # else
  52. # error "Unknown method"
  53. # endif
  54. bool aws_cpu_has_feature(enum aws_cpu_feature_name feature_name) {
  55. if (!s_hwcap_cached)
  56. s_cache_hwcap();
  57. switch (feature_name) {
  58. case AWS_CPU_FEATURE_ARM_CRC:
  59. return s_hwcap[s_check_cap[feature_name].cap] & s_check_cap[feature_name].bit;
  60. default:
  61. return false;
  62. }
  63. }
  64. #else /* defined(__linux__) || defined(__FreeBSD__) */
  65. bool aws_cpu_has_feature(enum aws_cpu_feature_name feature_name) {
  66. return false;
  67. }
  68. #endif /* defined(__linux__) || defined(__FreeBSD__) */