]>
Commit | Line | Data |
---|---|---|
88cb5972 AP |
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; | |
10621efd MC |
15 | static void ill_handler(int sig) |
16 | { | |
17 | siglongjmp(ill_jmp, sig); | |
18 | } | |
88cb5972 AP |
19 | |
20 | /* | |
21 | * Following subroutines could have been inlined, but it's not all | |
22 | * ARM compilers support inline assembler... | |
23 | */ | |
24 | void _armv7_neon_probe(void); | |
25 | unsigned int _armv7_tick(void); | |
26 | ||
27 | unsigned int OPENSSL_rdtsc(void) | |
10621efd MC |
28 | { |
29 | if (OPENSSL_armcap_P & ARMV7_TICK) | |
30 | return _armv7_tick(); | |
31 | else | |
32 | return 0; | |
33 | } | |
88cb5972 AP |
34 | |
35 | #if defined(__GNUC__) && __GNUC__>=2 | |
10621efd | 36 | void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); |
88cb5972 AP |
37 | #endif |
38 | void OPENSSL_cpuid_setup(void) | |
10621efd MC |
39 | { |
40 | char *e; | |
41 | struct sigaction ill_oact, ill_act; | |
42 | sigset_t oset; | |
43 | static int trigger = 0; | |
88cb5972 | 44 | |
10621efd MC |
45 | if (trigger) |
46 | return; | |
47 | trigger = 1; | |
88cb5972 | 48 | |
10621efd MC |
49 | if ((e = getenv("OPENSSL_armcap"))) { |
50 | OPENSSL_armcap_P = strtoul(e, NULL, 0); | |
51 | return; | |
52 | } | |
88cb5972 | 53 | |
10621efd MC |
54 | sigfillset(&all_masked); |
55 | sigdelset(&all_masked, SIGILL); | |
56 | sigdelset(&all_masked, SIGTRAP); | |
57 | sigdelset(&all_masked, SIGFPE); | |
58 | sigdelset(&all_masked, SIGBUS); | |
59 | sigdelset(&all_masked, SIGSEGV); | |
88cb5972 | 60 | |
10621efd | 61 | OPENSSL_armcap_P = 0; |
88cb5972 | 62 | |
10621efd MC |
63 | memset(&ill_act, 0, sizeof(ill_act)); |
64 | ill_act.sa_handler = ill_handler; | |
65 | ill_act.sa_mask = all_masked; | |
88cb5972 | 66 | |
10621efd MC |
67 | sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); |
68 | sigaction(SIGILL, &ill_act, &ill_oact); | |
88cb5972 | 69 | |
10621efd MC |
70 | if (sigsetjmp(ill_jmp, 1) == 0) { |
71 | _armv7_neon_probe(); | |
72 | OPENSSL_armcap_P |= ARMV7_NEON; | |
73 | } | |
74 | if (sigsetjmp(ill_jmp, 1) == 0) { | |
75 | _armv7_tick(); | |
76 | OPENSSL_armcap_P |= ARMV7_TICK; | |
77 | } | |
78 | ||
79 | sigaction(SIGILL, &ill_oact, NULL); | |
80 | sigprocmask(SIG_SETMASK, &oset, NULL); | |
81 | } |