diff options
Diffstat (limited to 'src/lib/libcrypto/sparcv9cap.c')
-rw-r--r-- | src/lib/libcrypto/sparcv9cap.c | 235 |
1 files changed, 121 insertions, 114 deletions
diff --git a/src/lib/libcrypto/sparcv9cap.c b/src/lib/libcrypto/sparcv9cap.c index 43b3ac6f81..08f7de3ec8 100644 --- a/src/lib/libcrypto/sparcv9cap.c +++ b/src/lib/libcrypto/sparcv9cap.c | |||
@@ -12,20 +12,22 @@ | |||
12 | #define SPARCV9_VIS2 (1<<3) /* reserved */ | 12 | #define SPARCV9_VIS2 (1<<3) /* reserved */ |
13 | #define SPARCV9_FMADD (1<<4) /* reserved for SPARC64 V */ | 13 | #define SPARCV9_FMADD (1<<4) /* reserved for SPARC64 V */ |
14 | 14 | ||
15 | static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED; | 15 | static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED; |
16 | 16 | ||
17 | int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num) | 17 | int |
18 | { | 18 | bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
19 | int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num); | 19 | const BN_ULONG *np, const BN_ULONG *n0, int num) |
20 | int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num); | 20 | { |
21 | 21 | int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); | |
22 | if (num>=8 && !(num&1) && | 22 | int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); |
23 | (OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) == | 23 | |
24 | (SPARCV9_PREFER_FPU|SPARCV9_VIS1)) | 24 | if (num >= 8 && !(num & 1) && |
25 | return bn_mul_mont_fpu(rp,ap,bp,np,n0,num); | 25 | (OPENSSL_sparcv9cap_P & (SPARCV9_PREFER_FPU|SPARCV9_VIS1)) == |
26 | (SPARCV9_PREFER_FPU|SPARCV9_VIS1)) | ||
27 | return bn_mul_mont_fpu(rp, ap, bp, np, n0, num); | ||
26 | else | 28 | else |
27 | return bn_mul_mont_int(rp,ap,bp,np,n0,num); | 29 | return bn_mul_mont_int(rp, ap, bp, np, n0, num); |
28 | } | 30 | } |
29 | 31 | ||
30 | unsigned long _sparcv9_rdtick(void); | 32 | unsigned long _sparcv9_rdtick(void); |
31 | void _sparcv9_vis1_probe(void); | 33 | void _sparcv9_vis1_probe(void); |
@@ -33,8 +35,9 @@ unsigned long _sparcv9_vis1_instrument(void); | |||
33 | void _sparcv9_vis2_probe(void); | 35 | void _sparcv9_vis2_probe(void); |
34 | void _sparcv9_fmadd_probe(void); | 36 | void _sparcv9_fmadd_probe(void); |
35 | 37 | ||
36 | unsigned long OPENSSL_rdtsc(void) | 38 | unsigned long |
37 | { | 39 | OPENSSL_rdtsc(void) |
40 | { | ||
38 | if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED) | 41 | if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED) |
39 | #if defined(__sun) && defined(__SVR4) | 42 | #if defined(__sun) && defined(__SVR4) |
40 | return gethrtime(); | 43 | return gethrtime(); |
@@ -43,7 +46,7 @@ unsigned long OPENSSL_rdtsc(void) | |||
43 | #endif | 46 | #endif |
44 | else | 47 | else |
45 | return _sparcv9_rdtick(); | 48 | return _sparcv9_rdtick(); |
46 | } | 49 | } |
47 | 50 | ||
48 | #if 0 && defined(__sun) && defined(__SVR4) | 51 | #if 0 && defined(__sun) && defined(__SVR4) |
49 | /* This code path is disabled, because of incompatibility of | 52 | /* This code path is disabled, because of incompatibility of |
@@ -54,21 +57,22 @@ unsigned long OPENSSL_rdtsc(void) | |||
54 | #include <libdevinfo.h> | 57 | #include <libdevinfo.h> |
55 | #include <sys/systeminfo.h> | 58 | #include <sys/systeminfo.h> |
56 | 59 | ||
57 | typedef di_node_t (*di_init_t)(const char *,uint_t); | 60 | typedef di_node_t (*di_init_t)(const char *, uint_t); |
58 | typedef void (*di_fini_t)(di_node_t); | 61 | typedef void (*di_fini_t)(di_node_t); |
59 | typedef char * (*di_node_name_t)(di_node_t); | 62 | typedef char * (*di_node_name_t)(di_node_t); |
60 | typedef int (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t)); | 63 | typedef int (*di_walk_node_t)(di_node_t, uint_t, di_node_name_t, int (*)(di_node_t, di_node_name_t)); |
61 | 64 | ||
62 | #define DLLINK(h,name) (name=(name##_t)dlsym((h),#name)) | 65 | #define DLLINK(h,name) (name=(name##_t)dlsym((h),#name)) |
63 | 66 | ||
64 | static int walk_nodename(di_node_t node, di_node_name_t di_node_name) | 67 | static int |
65 | { | 68 | walk_nodename(di_node_t node, di_node_name_t di_node_name) |
69 | { | ||
66 | char *name = (*di_node_name)(node); | 70 | char *name = (*di_node_name)(node); |
67 | 71 | ||
68 | /* This is expected to catch all UltraSPARC flavors prior T1 */ | 72 | /* This is expected to catch all UltraSPARC flavors prior T1 */ |
69 | if (!strcmp (name,"SUNW,UltraSPARC") || | 73 | if (!strcmp (name, "SUNW, UltraSPARC") || |
70 | !strncmp(name,"SUNW,UltraSPARC-I",17)) /* covers II,III,IV */ | 74 | !strncmp(name,"SUNW,UltraSPARC-I",17)) /* covers II,III,IV */ |
71 | { | 75 | { |
72 | OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1; | 76 | OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1; |
73 | 77 | ||
74 | /* %tick is privileged only on UltraSPARC-I/II, but not IIe */ | 78 | /* %tick is privileged only on UltraSPARC-I/II, but not IIe */ |
@@ -76,51 +80,48 @@ static int walk_nodename(di_node_t node, di_node_name_t di_node_name) | |||
76 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; | 80 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; |
77 | 81 | ||
78 | return DI_WALK_TERMINATE; | 82 | return DI_WALK_TERMINATE; |
79 | } | 83 | } |
80 | /* This is expected to catch remaining UltraSPARCs, such as T1 */ | 84 | /* This is expected to catch remaining UltraSPARCs, such as T1 */ |
81 | else if (!strncmp(name,"SUNW,UltraSPARC",15)) | 85 | else if (!strncmp(name, "SUNW, UltraSPARC", 15)) { |
82 | { | ||
83 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; | 86 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; |
84 | 87 | ||
85 | return DI_WALK_TERMINATE; | 88 | return DI_WALK_TERMINATE; |
86 | } | 89 | } |
87 | 90 | ||
88 | return DI_WALK_CONTINUE; | 91 | return DI_WALK_CONTINUE; |
89 | } | 92 | } |
90 | 93 | ||
91 | void OPENSSL_cpuid_setup(void) | 94 | void |
92 | { | 95 | OPENSSL_cpuid_setup(void) |
96 | { | ||
93 | void *h; | 97 | void *h; |
94 | char *e,si[256]; | 98 | char *e, si[256]; |
95 | static int trigger=0; | 99 | static int trigger = 0; |
96 | 100 | ||
97 | if (trigger) return; | 101 | if (trigger) |
98 | trigger=1; | 102 | return; |
103 | trigger = 1; | ||
99 | 104 | ||
100 | if ((e=getenv("OPENSSL_sparcv9cap"))) | 105 | if ((e = getenv("OPENSSL_sparcv9cap"))) { |
101 | { | 106 | OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0); |
102 | OPENSSL_sparcv9cap_P=strtoul(e,NULL,0); | ||
103 | return; | 107 | return; |
104 | } | 108 | } |
105 | 109 | ||
106 | if (sysinfo(SI_MACHINE,si,sizeof(si))>0) | 110 | if (sysinfo(SI_MACHINE, si, sizeof(si)) > 0) { |
107 | { | 111 | if (strcmp(si, "sun4v")) |
108 | if (strcmp(si,"sun4v")) | ||
109 | /* FPU is preferred for all CPUs, but US-T1/2 */ | 112 | /* FPU is preferred for all CPUs, but US-T1/2 */ |
110 | OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU; | 113 | OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU; |
111 | } | 114 | } |
112 | 115 | ||
113 | if (sysinfo(SI_ISALIST,si,sizeof(si))>0) | 116 | if (sysinfo(SI_ISALIST, si, sizeof(si)) > 0) { |
114 | { | 117 | if (strstr(si, "+vis")) |
115 | if (strstr(si,"+vis")) | ||
116 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS1; | 118 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS1; |
117 | if (strstr(si,"+vis2")) | 119 | if (strstr(si, "+vis2")) { |
118 | { | ||
119 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; | 120 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; |
120 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; | 121 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; |
121 | return; | 122 | return; |
122 | } | ||
123 | } | 123 | } |
124 | } | ||
124 | #ifdef M_KEEP | 125 | #ifdef M_KEEP |
125 | /* | 126 | /* |
126 | * Solaris libdevinfo.so.1 is effectively incomatible with | 127 | * Solaris libdevinfo.so.1 is effectively incomatible with |
@@ -129,109 +130,115 @@ void OPENSSL_cpuid_setup(void) | |||
129 | * free(3LIBMALLOC) called by di_fini. Prior call to | 130 | * free(3LIBMALLOC) called by di_fini. Prior call to |
130 | * mallopt(M_KEEP,0) somehow helps... But not always... | 131 | * mallopt(M_KEEP,0) somehow helps... But not always... |
131 | */ | 132 | */ |
132 | if ((h = dlopen(NULL,RTLD_LAZY))) | 133 | if ((h = dlopen(NULL, RTLD_LAZY))) { |
133 | { | 134 | union { void *p; |
134 | union { void *p; int (*f)(int,int); } sym; | 135 | int (*f)(int, int); |
135 | if ((sym.p = dlsym(h,"mallopt"))) (*sym.f)(M_KEEP,0); | 136 | } sym; |
136 | dlclose(h); | 137 | if ((sym.p = dlsym(h, "mallopt"))) (*sym.f)(M_KEEP, 0); |
137 | } | 138 | dlclose(h); |
139 | } | ||
138 | #endif | 140 | #endif |
139 | if ((h = dlopen("libdevinfo.so.1",RTLD_LAZY))) do | 141 | if ((h = dlopen("libdevinfo.so.1", RTLD_LAZY))) |
140 | { | 142 | do { |
141 | di_init_t di_init; | 143 | di_init_t di_init; |
142 | di_fini_t di_fini; | 144 | di_fini_t di_fini; |
143 | di_walk_node_t di_walk_node; | 145 | di_walk_node_t di_walk_node; |
144 | di_node_name_t di_node_name; | 146 | di_node_name_t di_node_name; |
145 | di_node_t root_node; | 147 | di_node_t root_node; |
146 | 148 | ||
147 | if (!DLLINK(h,di_init)) break; | 149 | if (!DLLINK(h, di_init)) |
148 | if (!DLLINK(h,di_fini)) break; | 150 | break; |
149 | if (!DLLINK(h,di_walk_node)) break; | 151 | if (!DLLINK(h, di_fini)) |
150 | if (!DLLINK(h,di_node_name)) break; | 152 | break; |
151 | 153 | if (!DLLINK(h, di_walk_node)) | |
152 | if ((root_node = (*di_init)("/",DINFOSUBTREE))!=DI_NODE_NIL) | 154 | break; |
153 | { | 155 | if (!DLLINK(h, di_node_name)) |
154 | (*di_walk_node)(root_node,DI_WALK_SIBFIRST, | 156 | break; |
155 | di_node_name,walk_nodename); | 157 | |
156 | (*di_fini)(root_node); | 158 | if ((root_node = (*di_init)("/", DINFOSUBTREE)) != |
159 | DI_NODE_NIL) { | ||
160 | (*di_walk_node)(root_node, DI_WALK_SIBFIRST, | ||
161 | di_node_name, walk_nodename); | ||
162 | (*di_fini)(root_node); | ||
157 | } | 163 | } |
158 | } while(0); | 164 | } while (0); |
159 | 165 | ||
160 | if (h) dlclose(h); | 166 | if (h) |
161 | } | 167 | dlclose(h); |
168 | } | ||
162 | 169 | ||
163 | #else | 170 | #else |
164 | 171 | ||
165 | static sigjmp_buf common_jmp; | 172 | static sigjmp_buf common_jmp; |
166 | static void common_handler(int sig) { siglongjmp(common_jmp,sig); } | 173 | static void common_handler(int sig) |
167 | 174 | { | |
168 | void OPENSSL_cpuid_setup(void) | 175 | siglongjmp(common_jmp, sig); |
169 | { | 176 | } |
177 | |||
178 | void | ||
179 | OPENSSL_cpuid_setup(void) | ||
180 | { | ||
170 | char *e; | 181 | char *e; |
171 | struct sigaction common_act,ill_oact,bus_oact; | 182 | struct sigaction common_act, ill_oact, bus_oact; |
172 | sigset_t all_masked,oset; | 183 | sigset_t all_masked, oset; |
173 | static int trigger=0; | 184 | static int trigger = 0; |
174 | 185 | ||
175 | if (trigger) return; | 186 | if (trigger) |
176 | trigger=1; | ||
177 | |||
178 | if ((e=getenv("OPENSSL_sparcv9cap"))) | ||
179 | { | ||
180 | OPENSSL_sparcv9cap_P=strtoul(e,NULL,0); | ||
181 | return; | 187 | return; |
182 | } | 188 | trigger = 1; |
189 | |||
190 | if ((e = getenv("OPENSSL_sparcv9cap"))) { | ||
191 | OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0); | ||
192 | return; | ||
193 | } | ||
183 | 194 | ||
184 | /* Initial value, fits UltraSPARC-I&II... */ | 195 | /* Initial value, fits UltraSPARC-I&II... */ |
185 | OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU|SPARCV9_TICK_PRIVILEGED; | 196 | OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU|SPARCV9_TICK_PRIVILEGED; |
186 | 197 | ||
187 | sigfillset(&all_masked); | 198 | sigfillset(&all_masked); |
188 | sigdelset(&all_masked,SIGILL); | 199 | sigdelset(&all_masked, SIGILL); |
189 | sigdelset(&all_masked,SIGTRAP); | 200 | sigdelset(&all_masked, SIGTRAP); |
190 | #ifdef SIGEMT | 201 | #ifdef SIGEMT |
191 | sigdelset(&all_masked,SIGEMT); | 202 | sigdelset(&all_masked, SIGEMT); |
192 | #endif | 203 | #endif |
193 | sigdelset(&all_masked,SIGFPE); | 204 | sigdelset(&all_masked, SIGFPE); |
194 | sigdelset(&all_masked,SIGBUS); | 205 | sigdelset(&all_masked, SIGBUS); |
195 | sigdelset(&all_masked,SIGSEGV); | 206 | sigdelset(&all_masked, SIGSEGV); |
196 | sigprocmask(SIG_SETMASK,&all_masked,&oset); | 207 | sigprocmask(SIG_SETMASK, &all_masked, &oset); |
197 | 208 | ||
198 | memset(&common_act,0,sizeof(common_act)); | 209 | memset(&common_act, 0, sizeof(common_act)); |
199 | common_act.sa_handler = common_handler; | 210 | common_act.sa_handler = common_handler; |
200 | common_act.sa_mask = all_masked; | 211 | common_act.sa_mask = all_masked; |
201 | 212 | ||
202 | sigaction(SIGILL,&common_act,&ill_oact); | 213 | sigaction(SIGILL, &common_act, &ill_oact); |
203 | sigaction(SIGBUS,&common_act,&bus_oact);/* T1 fails 16-bit ldda [on Linux] */ | 214 | sigaction(SIGBUS,&common_act,&bus_oact);/* T1 fails 16-bit ldda [on Linux] */ |
204 | 215 | ||
205 | if (sigsetjmp(common_jmp,1) == 0) | 216 | if (sigsetjmp(common_jmp, 1) == 0) { |
206 | { | ||
207 | _sparcv9_rdtick(); | 217 | _sparcv9_rdtick(); |
208 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; | 218 | OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; |
209 | } | 219 | } |
210 | 220 | ||
211 | if (sigsetjmp(common_jmp,1) == 0) | 221 | if (sigsetjmp(common_jmp, 1) == 0) { |
212 | { | ||
213 | _sparcv9_vis1_probe(); | 222 | _sparcv9_vis1_probe(); |
214 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS1; | 223 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS1; |
215 | /* detect UltraSPARC-Tx, see sparccpud.S for details... */ | 224 | /* detect UltraSPARC-Tx, see sparccpud.S for details... */ |
216 | if (_sparcv9_vis1_instrument() >= 12) | 225 | if (_sparcv9_vis1_instrument() >= 12) |
217 | OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1|SPARCV9_PREFER_FPU); | 226 | OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1|SPARCV9_PREFER_FPU); |
218 | else | 227 | else { |
219 | { | ||
220 | _sparcv9_vis2_probe(); | 228 | _sparcv9_vis2_probe(); |
221 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; | 229 | OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; |
222 | } | ||
223 | } | 230 | } |
231 | } | ||
224 | 232 | ||
225 | if (sigsetjmp(common_jmp,1) == 0) | 233 | if (sigsetjmp(common_jmp, 1) == 0) { |
226 | { | ||
227 | _sparcv9_fmadd_probe(); | 234 | _sparcv9_fmadd_probe(); |
228 | OPENSSL_sparcv9cap_P |= SPARCV9_FMADD; | 235 | OPENSSL_sparcv9cap_P |= SPARCV9_FMADD; |
229 | } | 236 | } |
230 | 237 | ||
231 | sigaction(SIGBUS,&bus_oact,NULL); | 238 | sigaction(SIGBUS, &bus_oact, NULL); |
232 | sigaction(SIGILL,&ill_oact,NULL); | 239 | sigaction(SIGILL, &ill_oact, NULL); |
233 | 240 | ||
234 | sigprocmask(SIG_SETMASK,&oset,NULL); | 241 | sigprocmask(SIG_SETMASK, &oset, NULL); |
235 | } | 242 | } |
236 | 243 | ||
237 | #endif | 244 | #endif |