arm_arch_queries.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Unix implementation of the OS query functions that detect Arm
  3. * architecture extensions.
  4. */
  5. #include "putty.h"
  6. #include "ssh.h"
  7. #include "utils/arm_arch_queries.h"
  8. #if defined __arm__ || defined __aarch64__
  9. bool platform_aes_neon_available(void)
  10. {
  11. #if defined HWCAP_AES
  12. return getauxval(AT_HWCAP) & HWCAP_AES;
  13. #elif defined HWCAP2_AES
  14. return getauxval(AT_HWCAP2) & HWCAP2_AES;
  15. #elif defined __APPLE__
  16. SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_AES");
  17. /* Older M1 macOS didn't provide this flag, but as far as I know
  18. * implemented the crypto extension anyway, so treat 'feature
  19. * missing' as 'implemented' */
  20. return res != SYSCTL_OFF;
  21. #else
  22. return false;
  23. #endif
  24. }
  25. bool platform_pmull_neon_available(void)
  26. {
  27. #if defined HWCAP_PMULL
  28. return getauxval(AT_HWCAP) & HWCAP_PMULL;
  29. #elif defined HWCAP2_PMULL
  30. return getauxval(AT_HWCAP2) & HWCAP2_PMULL;
  31. #elif defined __APPLE__
  32. SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_PMULL");
  33. /* As above, treat 'missing' as enabled */
  34. return res != SYSCTL_OFF;
  35. #else
  36. return false;
  37. #endif
  38. }
  39. bool platform_sha256_neon_available(void)
  40. {
  41. #if defined HWCAP_SHA2
  42. return getauxval(AT_HWCAP) & HWCAP_SHA2;
  43. #elif defined HWCAP2_SHA2
  44. return getauxval(AT_HWCAP2) & HWCAP2_SHA2;
  45. #elif defined __APPLE__
  46. SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_SHA256");
  47. /* As above, treat 'missing' as enabled */
  48. return res != SYSCTL_OFF;
  49. #else
  50. return false;
  51. #endif
  52. }
  53. bool platform_sha1_neon_available(void)
  54. {
  55. #if defined HWCAP_SHA1
  56. return getauxval(AT_HWCAP) & HWCAP_SHA1;
  57. #elif defined HWCAP2_SHA1
  58. return getauxval(AT_HWCAP2) & HWCAP2_SHA1;
  59. #elif defined __APPLE__
  60. SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_SHA1");
  61. /* As above, treat 'missing' as enabled */
  62. return res != SYSCTL_OFF;
  63. #else
  64. return false;
  65. #endif
  66. }
  67. bool platform_sha512_neon_available(void)
  68. {
  69. #if defined HWCAP_SHA512
  70. return getauxval(AT_HWCAP) & HWCAP_SHA512;
  71. #elif defined HWCAP2_SHA512
  72. return getauxval(AT_HWCAP2) & HWCAP2_SHA512;
  73. #elif defined __APPLE__
  74. /* There are two sysctl flags for this, apparently invented at
  75. * different times. Try both, falling back to the older one. */
  76. SysctlResult res = test_sysctl_flag("hw.optional.arm.FEAT_SHA512");
  77. if (res != SYSCTL_MISSING)
  78. return res == SYSCTL_ON;
  79. res = test_sysctl_flag("hw.optional.armv8_2_sha512");
  80. return res == SYSCTL_ON;
  81. #else
  82. return false;
  83. #endif
  84. }
  85. #else /* defined __arm__ || defined __aarch64__ */
  86. /*
  87. * Include _something_ in this file to prevent an annoying compiler
  88. * warning, and to avoid having to condition out this file in
  89. * CMakeLists. It's in a library, so this variable shouldn't end up in
  90. * any actual program, because nothing will refer to it.
  91. */
  92. const int arm_arch_queries_dummy_variable = 0;
  93. #endif /* defined __arm__ || defined __aarch64__ */