]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/armcap.c
7e46d07a3232c06cb359fbc64110c21680c80e84
10 unsigned int OPENSSL_armcap_P
;
12 static sigset_t all_masked
;
14 static sigjmp_buf ill_jmp
;
15 static void ill_handler (int sig
) { siglongjmp(ill_jmp
,sig
); }
18 * Following subroutines could have been inlined, but it's not all
19 * ARM compilers support inline assembler...
21 void _armv7_neon_probe(void);
22 void _armv8_aes_probe(void);
23 void _armv8_sha1_probe(void);
24 void _armv8_sha256_probe(void);
25 void _armv8_pmull_probe(void);
26 unsigned long _armv7_tick(void);
28 unsigned long OPENSSL_rdtsc(void)
30 if (OPENSSL_armcap_P
& ARMV7_TICK
)
37 * Use a weak reference to getauxval() so we can use it if it is available but
38 * don't break the build if it is not.
40 #if defined(__GNUC__) && __GNUC__>=2
41 void OPENSSL_cpuid_setup(void) __attribute__((constructor
));
42 extern unsigned long getauxval(unsigned long type
) __attribute__((weak
));
44 static unsigned long (*getauxval
)(unsigned long) = NULL
;
48 * ARM puts the the feature bits for Crypto Extensions in AT_HWCAP2, whereas
49 * AArch64 used AT_HWCAP.
51 #if defined(__arm__) || defined (__arm)
52 # define HWCAP 16 /* AT_HWCAP */
53 # define HWCAP_NEON (1 << 12)
55 # define HWCAP_CE 26 /* AT_HWCAP2 */
56 # define HWCAP_CE_AES (1 << 0)
57 # define HWCAP_CE_PMULL (1 << 1)
58 # define HWCAP_CE_SHA1 (1 << 2)
59 # define HWCAP_CE_SHA256 (1 << 3)
60 #elif defined(__aarch64__)
61 # define HWCAP 16 /* AT_HWCAP */
62 # define HWCAP_NEON (1 << 1)
64 # define HWCAP_CE HWCAP
65 # define HWCAP_CE_AES (1 << 3)
66 # define HWCAP_CE_PMULL (1 << 4)
67 # define HWCAP_CE_SHA1 (1 << 5)
68 # define HWCAP_CE_SHA256 (1 << 6)
71 void OPENSSL_cpuid_setup(void)
74 struct sigaction ill_oact
,ill_act
;
81 if ((e
=getenv("OPENSSL_armcap")))
83 OPENSSL_armcap_P
=(unsigned int)strtoul(e
,NULL
,0);
87 sigfillset(&all_masked
);
88 sigdelset(&all_masked
,SIGILL
);
89 sigdelset(&all_masked
,SIGTRAP
);
90 sigdelset(&all_masked
,SIGFPE
);
91 sigdelset(&all_masked
,SIGBUS
);
92 sigdelset(&all_masked
,SIGSEGV
);
96 memset(&ill_act
,0,sizeof(ill_act
));
97 ill_act
.sa_handler
= ill_handler
;
98 ill_act
.sa_mask
= all_masked
;
100 sigprocmask(SIG_SETMASK
,&ill_act
.sa_mask
,&oset
);
101 sigaction(SIGILL
,&ill_act
,&ill_oact
);
103 if (getauxval
!= NULL
)
105 if (getauxval(HWCAP
) & HWCAP_NEON
)
107 unsigned long hwcap
= getauxval(HWCAP_CE
);
109 OPENSSL_armcap_P
|= ARMV7_NEON
;
111 if (hwcap
& HWCAP_CE_AES
)
112 OPENSSL_armcap_P
|= ARMV8_AES
;
114 if (hwcap
& HWCAP_CE_PMULL
)
115 OPENSSL_armcap_P
|= ARMV8_PMULL
;
117 if (hwcap
& HWCAP_CE_SHA1
)
118 OPENSSL_armcap_P
|= ARMV8_SHA1
;
120 if (hwcap
& HWCAP_CE_SHA256
)
121 OPENSSL_armcap_P
|= ARMV8_SHA256
;
124 else if (sigsetjmp(ill_jmp
,1) == 0)
127 OPENSSL_armcap_P
|= ARMV7_NEON
;
128 if (sigsetjmp(ill_jmp
,1) == 0)
130 _armv8_pmull_probe();
131 OPENSSL_armcap_P
|= ARMV8_PMULL
|ARMV8_AES
;
133 else if (sigsetjmp(ill_jmp
,1) == 0)
136 OPENSSL_armcap_P
|= ARMV8_AES
;
138 if (sigsetjmp(ill_jmp
,1) == 0)
141 OPENSSL_armcap_P
|= ARMV8_SHA1
;
143 if (sigsetjmp(ill_jmp
,1) == 0)
145 _armv8_sha256_probe();
146 OPENSSL_armcap_P
|= ARMV8_SHA256
;
149 if (sigsetjmp(ill_jmp
,1) == 0)
152 OPENSSL_armcap_P
|= ARMV7_TICK
;
155 sigaction (SIGILL
,&ill_oact
,NULL
);
156 sigprocmask(SIG_SETMASK
,&oset
,NULL
);