You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

113 lines
3.3 KiB

  1. /* Copyright (c) 2014, Google Inc.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. #include <openssl/cpu.h>
  15. #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
  16. #include <inttypes.h>
  17. #include <stdio.h>
  18. #include "arm_arch.h"
  19. /* We can't include <sys/auxv.h> because the Android SDK version against which
  20. * Chromium builds is too old to have it. Instead we define all the constants
  21. * that we need and have a weak pointer to getauxval. */
  22. unsigned long getauxval(unsigned long type) __attribute__((weak));
  23. static const unsigned long AT_HWCAP = 16;
  24. static const unsigned long AT_HWCAP2 = 26;
  25. char CRYPTO_is_NEON_capable(void) {
  26. return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
  27. }
  28. void CRYPTO_set_NEON_capable(char neon_capable) {
  29. if (neon_capable) {
  30. OPENSSL_armcap_P |= ARMV7_NEON;
  31. } else {
  32. OPENSSL_armcap_P &= ~ARMV7_NEON;
  33. }
  34. }
  35. char CRYPTO_is_NEON_functional(void) {
  36. static const uint32_t kWantFlags = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
  37. return (OPENSSL_armcap_P & kWantFlags) == kWantFlags;
  38. }
  39. void CRYPTO_set_NEON_functional(char neon_functional) {
  40. if (neon_functional) {
  41. OPENSSL_armcap_P |= ARMV7_NEON_FUNCTIONAL;
  42. } else {
  43. OPENSSL_armcap_P &= ~ARMV7_NEON_FUNCTIONAL;
  44. }
  45. }
  46. void OPENSSL_cpuid_setup(void) {
  47. if (getauxval == NULL) {
  48. return;
  49. }
  50. unsigned long hwcap = getauxval(AT_HWCAP);
  51. #if defined(OPENSSL_ARM)
  52. static const unsigned long kNEON = 1 << 12;
  53. if ((hwcap & kNEON) == 0) {
  54. return;
  55. }
  56. /* In 32-bit mode, the ARMv8 feature bits are in a different aux vector
  57. * value. */
  58. hwcap = getauxval(AT_HWCAP2);
  59. /* See /usr/include/asm/hwcap.h on an ARM installation for the source of
  60. * these values. */
  61. static const unsigned long kAES = 1 << 0;
  62. static const unsigned long kPMULL = 1 << 1;
  63. static const unsigned long kSHA1 = 1 << 2;
  64. static const unsigned long kSHA256 = 1 << 3;
  65. #elif defined(OPENSSL_AARCH64)
  66. /* See /usr/include/asm/hwcap.h on an aarch64 installation for the source of
  67. * these values. */
  68. static const unsigned long kNEON = 1 << 1;
  69. static const unsigned long kAES = 1 << 3;
  70. static const unsigned long kPMULL = 1 << 4;
  71. static const unsigned long kSHA1 = 1 << 5;
  72. static const unsigned long kSHA256 = 1 << 6;
  73. if ((hwcap & kNEON) == 0) {
  74. return;
  75. }
  76. #endif
  77. OPENSSL_armcap_P |= ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
  78. if (hwcap & kAES) {
  79. OPENSSL_armcap_P |= ARMV8_AES;
  80. }
  81. if (hwcap & kPMULL) {
  82. OPENSSL_armcap_P |= ARMV8_PMULL;
  83. }
  84. if (hwcap & kSHA1) {
  85. OPENSSL_armcap_P |= ARMV8_SHA1;
  86. }
  87. if (hwcap & kSHA256) {
  88. OPENSSL_armcap_P |= ARMV8_SHA256;
  89. }
  90. }
  91. #endif /* defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) */