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