summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/sparcv9cap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/sparcv9cap.c')
-rw-r--r--src/lib/libcrypto/sparcv9cap.c235
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
15static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED; 15static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED;
16 16
17int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num) 17int
18 { 18bn_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
30unsigned long _sparcv9_rdtick(void); 32unsigned long _sparcv9_rdtick(void);
31void _sparcv9_vis1_probe(void); 33void _sparcv9_vis1_probe(void);
@@ -33,8 +35,9 @@ unsigned long _sparcv9_vis1_instrument(void);
33void _sparcv9_vis2_probe(void); 35void _sparcv9_vis2_probe(void);
34void _sparcv9_fmadd_probe(void); 36void _sparcv9_fmadd_probe(void);
35 37
36unsigned long OPENSSL_rdtsc(void) 38unsigned long
37 { 39OPENSSL_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
57typedef di_node_t (*di_init_t)(const char *,uint_t); 60typedef di_node_t (*di_init_t)(const char *, uint_t);
58typedef void (*di_fini_t)(di_node_t); 61typedef void (*di_fini_t)(di_node_t);
59typedef char * (*di_node_name_t)(di_node_t); 62typedef char * (*di_node_name_t)(di_node_t);
60typedef int (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t)); 63typedef 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
64static int walk_nodename(di_node_t node, di_node_name_t di_node_name) 67static int
65 { 68walk_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
91void OPENSSL_cpuid_setup(void) 94void
92 { 95OPENSSL_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
165static sigjmp_buf common_jmp; 172static sigjmp_buf common_jmp;
166static void common_handler(int sig) { siglongjmp(common_jmp,sig); } 173static void common_handler(int sig)
167 174{
168void OPENSSL_cpuid_setup(void) 175 siglongjmp(common_jmp, sig);
169 { 176}
177
178void
179OPENSSL_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