source: rtems-libbsd/freebsd/crypto/openssl/crypto/armcap.c @ 6bed520

55-freebsd-126-freebsd-12
Last change on this file since 6bed520 was 6bed520, checked in by Sichen Zhao <1473996754@…>, on 08/01/17 at 12:31:19

Import openssl from FreeBSD.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <setjmp.h>
7#include <signal.h>
8#include <crypto.h>
9
10#include "arm_arch.h"
11
12unsigned int OPENSSL_armcap_P = 0;
13
14#if __ARM_MAX_ARCH__<7
15void OPENSSL_cpuid_setup(void)
16{
17}
18
19unsigned long OPENSSL_rdtsc(void)
20{
21    return 0;
22}
23#else
24static sigset_t all_masked;
25
26static sigjmp_buf ill_jmp;
27static void ill_handler(int sig)
28{
29    siglongjmp(ill_jmp, sig);
30}
31
32/*
33 * Following subroutines could have been inlined, but it's not all
34 * ARM compilers support inline assembler...
35 */
36void _armv7_neon_probe(void);
37void _armv8_aes_probe(void);
38void _armv8_sha1_probe(void);
39void _armv8_sha256_probe(void);
40void _armv8_pmull_probe(void);
41unsigned long _armv7_tick(void);
42
43unsigned long OPENSSL_rdtsc(void)
44{
45    if (OPENSSL_armcap_P & ARMV7_TICK)
46        return _armv7_tick();
47    else
48        return 0;
49}
50
51/*
52 * Use a weak reference to getauxval() so we can use it if it is available but
53 * don't break the build if it is not.
54 */
55# if defined(__GNUC__) && __GNUC__>=2
56void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
57extern unsigned long getauxval(unsigned long type) __attribute__ ((weak));
58# else
59static unsigned long (*getauxval) (unsigned long) = NULL;
60# endif
61
62/*
63 * ARM puts the the feature bits for Crypto Extensions in AT_HWCAP2, whereas
64 * AArch64 used AT_HWCAP.
65 */
66# if defined(__arm__) || defined (__arm)
67#  define HWCAP                  16
68                                  /* AT_HWCAP */
69#  define HWCAP_NEON             (1 << 12)
70
71#  define HWCAP_CE               26
72                                  /* AT_HWCAP2 */
73#  define HWCAP_CE_AES           (1 << 0)
74#  define HWCAP_CE_PMULL         (1 << 1)
75#  define HWCAP_CE_SHA1          (1 << 2)
76#  define HWCAP_CE_SHA256        (1 << 3)
77# elif defined(__aarch64__)
78#  define HWCAP                  16
79                                  /* AT_HWCAP */
80#  define HWCAP_NEON             (1 << 1)
81
82#  define HWCAP_CE               HWCAP
83#  define HWCAP_CE_AES           (1 << 3)
84#  define HWCAP_CE_PMULL         (1 << 4)
85#  define HWCAP_CE_SHA1          (1 << 5)
86#  define HWCAP_CE_SHA256        (1 << 6)
87# endif
88
89void OPENSSL_cpuid_setup(void)
90{
91    char *e;
92    struct sigaction ill_oact, ill_act;
93    sigset_t oset;
94    static int trigger = 0;
95
96    if (trigger)
97        return;
98    trigger = 1;
99
100    if ((e = getenv("OPENSSL_armcap"))) {
101        OPENSSL_armcap_P = (unsigned int)strtoul(e, NULL, 0);
102        return;
103    }
104
105    sigfillset(&all_masked);
106    sigdelset(&all_masked, SIGILL);
107    sigdelset(&all_masked, SIGTRAP);
108    sigdelset(&all_masked, SIGFPE);
109    sigdelset(&all_masked, SIGBUS);
110    sigdelset(&all_masked, SIGSEGV);
111
112    OPENSSL_armcap_P = 0;
113
114    memset(&ill_act, 0, sizeof(ill_act));
115    ill_act.sa_handler = ill_handler;
116    ill_act.sa_mask = all_masked;
117
118    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
119    sigaction(SIGILL, &ill_act, &ill_oact);
120
121    if (getauxval != NULL) {
122        if (getauxval(HWCAP) & HWCAP_NEON) {
123            unsigned long hwcap = getauxval(HWCAP_CE);
124
125            OPENSSL_armcap_P |= ARMV7_NEON;
126
127            if (hwcap & HWCAP_CE_AES)
128                OPENSSL_armcap_P |= ARMV8_AES;
129
130            if (hwcap & HWCAP_CE_PMULL)
131                OPENSSL_armcap_P |= ARMV8_PMULL;
132
133            if (hwcap & HWCAP_CE_SHA1)
134                OPENSSL_armcap_P |= ARMV8_SHA1;
135
136            if (hwcap & HWCAP_CE_SHA256)
137                OPENSSL_armcap_P |= ARMV8_SHA256;
138        }
139    } else if (sigsetjmp(ill_jmp, 1) == 0) {
140        _armv7_neon_probe();
141        OPENSSL_armcap_P |= ARMV7_NEON;
142        if (sigsetjmp(ill_jmp, 1) == 0) {
143            _armv8_pmull_probe();
144            OPENSSL_armcap_P |= ARMV8_PMULL | ARMV8_AES;
145        } else if (sigsetjmp(ill_jmp, 1) == 0) {
146            _armv8_aes_probe();
147            OPENSSL_armcap_P |= ARMV8_AES;
148        }
149        if (sigsetjmp(ill_jmp, 1) == 0) {
150            _armv8_sha1_probe();
151            OPENSSL_armcap_P |= ARMV8_SHA1;
152        }
153        if (sigsetjmp(ill_jmp, 1) == 0) {
154            _armv8_sha256_probe();
155            OPENSSL_armcap_P |= ARMV8_SHA256;
156        }
157    }
158    if (sigsetjmp(ill_jmp, 1) == 0) {
159        _armv7_tick();
160        OPENSSL_armcap_P |= ARMV7_TICK;
161    }
162
163    sigaction(SIGILL, &ill_oact, NULL);
164    sigprocmask(SIG_SETMASK, &oset, NULL);
165}
166#endif
Note: See TracBrowser for help on using the repository browser.