10 unsigned int OPENSSL_armcap_P=0;
12 #if __ARM_MAX_ARCH__<7
13 void OPENSSL_cpuid_setup(void) {}
14 unsigned long OPENSSL_rdtsc(void) { return 0; }
16 static sigset_t all_masked;
18 static sigjmp_buf ill_jmp;
19 static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
22 * Following subroutines could have been inlined, but it's not all
23 * ARM compilers support inline assembler...
25 void _armv7_neon_probe(void);
26 void _armv8_aes_probe(void);
27 void _armv8_sha1_probe(void);
28 void _armv8_sha256_probe(void);
29 void _armv8_pmull_probe(void);
30 unsigned long _armv7_tick(void);
32 unsigned long OPENSSL_rdtsc(void)
34 if (OPENSSL_armcap_P & ARMV7_TICK)
41 * Use a weak reference to getauxval() so we can use it if it is available but
42 * don't break the build if it is not.
44 #if defined(__GNUC__) && __GNUC__>=2
45 void OPENSSL_cpuid_setup(void) __attribute__((constructor));
46 extern unsigned long getauxval(unsigned long type) __attribute__((weak));
48 static unsigned long (*getauxval)(unsigned long) = NULL;
52 * ARM puts the the feature bits for Crypto Extensions in AT_HWCAP2, whereas
53 * AArch64 used AT_HWCAP.
55 #if defined(__arm__) || defined (__arm)
56 # define HWCAP 16 /* AT_HWCAP */
57 # define HWCAP_NEON (1 << 12)
59 # define HWCAP_CE 26 /* AT_HWCAP2 */
60 # define HWCAP_CE_AES (1 << 0)
61 # define HWCAP_CE_PMULL (1 << 1)
62 # define HWCAP_CE_SHA1 (1 << 2)
63 # define HWCAP_CE_SHA256 (1 << 3)
64 #elif defined(__aarch64__)
65 # define HWCAP 16 /* AT_HWCAP */
66 # define HWCAP_NEON (1 << 1)
68 # define HWCAP_CE HWCAP
69 # define HWCAP_CE_AES (1 << 3)
70 # define HWCAP_CE_PMULL (1 << 4)
71 # define HWCAP_CE_SHA1 (1 << 5)
72 # define HWCAP_CE_SHA256 (1 << 6)
75 void OPENSSL_cpuid_setup(void)
78 struct sigaction ill_oact,ill_act;
85 if ((e=getenv("OPENSSL_armcap")))
87 OPENSSL_armcap_P=(unsigned int)strtoul(e,NULL,0);
91 sigfillset(&all_masked);
92 sigdelset(&all_masked,SIGILL);
93 sigdelset(&all_masked,SIGTRAP);
94 sigdelset(&all_masked,SIGFPE);
95 sigdelset(&all_masked,SIGBUS);
96 sigdelset(&all_masked,SIGSEGV);
100 memset(&ill_act,0,sizeof(ill_act));
101 ill_act.sa_handler = ill_handler;
102 ill_act.sa_mask = all_masked;
104 sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
105 sigaction(SIGILL,&ill_act,&ill_oact);
107 if (getauxval != NULL)
109 if (getauxval(HWCAP) & HWCAP_NEON)
111 unsigned long hwcap = getauxval(HWCAP_CE);
113 OPENSSL_armcap_P |= ARMV7_NEON;
115 if (hwcap & HWCAP_CE_AES)
116 OPENSSL_armcap_P |= ARMV8_AES;
118 if (hwcap & HWCAP_CE_PMULL)
119 OPENSSL_armcap_P |= ARMV8_PMULL;
121 if (hwcap & HWCAP_CE_SHA1)
122 OPENSSL_armcap_P |= ARMV8_SHA1;
124 if (hwcap & HWCAP_CE_SHA256)
125 OPENSSL_armcap_P |= ARMV8_SHA256;
128 else if (sigsetjmp(ill_jmp,1) == 0)
131 OPENSSL_armcap_P |= ARMV7_NEON;
132 if (sigsetjmp(ill_jmp,1) == 0)
134 _armv8_pmull_probe();
135 OPENSSL_armcap_P |= ARMV8_PMULL|ARMV8_AES;
137 else if (sigsetjmp(ill_jmp,1) == 0)
140 OPENSSL_armcap_P |= ARMV8_AES;
142 if (sigsetjmp(ill_jmp,1) == 0)
145 OPENSSL_armcap_P |= ARMV8_SHA1;
147 if (sigsetjmp(ill_jmp,1) == 0)
149 _armv8_sha256_probe();
150 OPENSSL_armcap_P |= ARMV8_SHA256;
153 if (sigsetjmp(ill_jmp,1) == 0)
156 OPENSSL_armcap_P |= ARMV7_TICK;
159 sigaction (SIGILL,&ill_oact,NULL);
160 sigprocmask(SIG_SETMASK,&oset,NULL);