xref: /netbsd-src/crypto/external/bsd/openssl/dist/crypto/armcap.c (revision a24efa7dea9f1f56c3bdb15a927d3516792ace1c)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <setjmp.h>
5 #include <signal.h>
6 #include <crypto.h>
7 
8 #include "arm_arch.h"
9 
10 unsigned int OPENSSL_armcap_P;
11 
12 static sigset_t all_masked;
13 
14 static sigjmp_buf ill_jmp;
15 static void ill_handler(int sig)
16 {
17     siglongjmp(ill_jmp, sig);
18 }
19 
20 /*
21  * Following subroutines could have been inlined, but it's not all
22  * ARM compilers support inline assembler...
23  */
24 #if __ARM_MAX_ARCH__>=7
25 void _armv7_neon_probe(void);
26 unsigned int _armv7_tick(void);
27 #endif
28 
29 unsigned int OPENSSL_rdtsc(void)
30 {
31 #if __ARM_MAX_ARCH__>=7
32     if (OPENSSL_armcap_P & ARMV7_TICK)
33         return _armv7_tick();
34     else
35 #endif
36         return 0;
37 }
38 
39 #if defined(__GNUC__) && __GNUC__>=2
40 void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
41 #endif
42 void OPENSSL_cpuid_setup(void)
43 {
44     char *e;
45     struct sigaction ill_oact, ill_act;
46     sigset_t oset;
47     static int trigger = 0;
48 
49     if (trigger)
50         return;
51     trigger = 1;
52 
53     if ((e = getenv("OPENSSL_armcap"))) {
54         OPENSSL_armcap_P = strtoul(e, NULL, 0);
55         return;
56     }
57 
58     sigfillset(&all_masked);
59     sigdelset(&all_masked, SIGILL);
60     sigdelset(&all_masked, SIGTRAP);
61     sigdelset(&all_masked, SIGFPE);
62     sigdelset(&all_masked, SIGBUS);
63     sigdelset(&all_masked, SIGSEGV);
64 
65     OPENSSL_armcap_P = 0;
66 
67     memset(&ill_act, 0, sizeof(ill_act));
68     ill_act.sa_handler = ill_handler;
69     ill_act.sa_mask = all_masked;
70 
71     sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
72     sigaction(SIGILL, &ill_act, &ill_oact);
73 
74 #if __ARM_MAX_ARCH__>=7
75     if (sigsetjmp(ill_jmp, 1) == 0) {
76         _armv7_neon_probe();
77         OPENSSL_armcap_P |= ARMV7_NEON;
78     }
79     if (sigsetjmp(ill_jmp, 1) == 0) {
80         _armv7_tick();
81         OPENSSL_armcap_P |= ARMV7_TICK;
82     }
83 #endif
84 
85     sigaction(SIGILL, &ill_oact, NULL);
86     sigprocmask(SIG_SETMASK, &oset, NULL);
87 }
88