1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <openssl/bn.h>
#define SPARCV9_TICK_PRIVILEGED (1<<0)
#define SPARCV9_PREFER_FPU (1<<1)
#define SPARCV9_VIS1 (1<<2)
#define SPARCV9_VIS2 (1<<3) /* reserved */
#define SPARCV9_FMADD (1<<4) /* reserved for SPARC64 V */
static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
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)
{
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);
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);
if ((OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
(SPARCV9_PREFER_FPU|SPARCV9_VIS1))
return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
else
return bn_mul_mont_int(rp,ap,bp,np,n0,num);
}
unsigned long OPENSSL_rdtsc(void)
{
unsigned long _sparcv9_rdtick(void);
if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED)
#if defined(__sun) && defined(__SVR4)
return gethrtime();
#else
return 0;
#endif
else
return _sparcv9_rdtick();
}
#if defined(__sun) && defined(__SVR4)
#include <dlfcn.h>
#include <libdevinfo.h>
typedef di_node_t (*di_init_t)(const char *,uint_t);
typedef void (*di_fini_t)(di_node_t);
typedef char * (*di_node_name_t)(di_node_t);
typedef int (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t));
#define DLLINK(h,name) (name=(name##_t)dlsym((h),#name))
static int walk_nodename(di_node_t node, di_node_name_t di_node_name)
{
char *name = (*di_node_name)(node);
/* This is expected to catch all UltraSPARC flavors prior T1 */
if (!strcmp (name,"SUNW,UltraSPARC") ||
!strncmp(name,"SUNW,UltraSPARC-I",17)) /* covers II,III,IV */
{
OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
/* %tick is privileged only on UltraSPARC-I/II, but not IIe */
if (name[14]!='\0' && name[17]!='\0' && name[18]!='\0')
OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
return DI_WALK_TERMINATE;
}
/* This is expected to catch remaining UltraSPARCs, such as T1 */
else if (!strncmp(name,"SUNW,UltraSPARC",15))
{
OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
return DI_WALK_TERMINATE;
}
return DI_WALK_CONTINUE;
}
void OPENSSL_cpuid_setup(void)
{
void *h;
char *e;
static int trigger=0;
if (trigger) return;
trigger=1;
if ((e=getenv("OPENSSL_sparcv9cap")))
{
OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
return;
}
if ((h = dlopen("libdevinfo.so.1",RTLD_LAZY))) do
{
di_init_t di_init;
di_fini_t di_fini;
di_walk_node_t di_walk_node;
di_node_name_t di_node_name;
di_node_t root_node;
if (!DLLINK(h,di_init)) break;
if (!DLLINK(h,di_fini)) break;
if (!DLLINK(h,di_walk_node)) break;
if (!DLLINK(h,di_node_name)) break;
if ((root_node = (*di_init)("/",DINFOSUBTREE))!=DI_NODE_NIL)
{
(*di_walk_node)(root_node,DI_WALK_SIBFIRST,
di_node_name,walk_nodename);
(*di_fini)(root_node);
}
} while(0);
if (h) dlclose(h);
}
#else
void OPENSSL_cpuid_setup(void)
{
char *e;
if ((e=getenv("OPENSSL_sparcv9cap")))
{
OPENSSL_sparcv9cap_P=strtoul(env,NULL,0);
return;
}
/* For now we assume that the rest supports UltraSPARC-I* only */
OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
}
#endif
|