64 |
64 |
65 os::free(buf); |
65 os::free(buf); |
66 } |
66 } |
67 |
67 |
68 int VM_Version::platform_features(int features) { |
68 int VM_Version::platform_features(int features) { |
69 // getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are |
69 assert(os::Solaris::supports_getisax(), "getisax() must be available"); |
70 // supported on Solaris 10 and later. |
70 |
71 if (os::Solaris::supports_getisax()) { |
71 // Check 32-bit architecture. |
72 |
72 do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m); |
73 // Check 32-bit architecture. |
73 |
74 do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m); |
74 // Check 64-bit architecture. |
75 |
75 do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m); |
76 // Check 64-bit architecture. |
76 |
77 do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m); |
77 // Extract valid instruction set extensions. |
78 |
78 uint_t avs[2]; |
79 // Extract valid instruction set extensions. |
79 uint_t avn = os::Solaris::getisax(avs, 2); |
80 uint_t avs[2]; |
80 assert(avn <= 2, "should return two or less av's"); |
81 uint_t avn = os::Solaris::getisax(avs, 2); |
81 uint_t av = avs[0]; |
82 assert(avn <= 2, "should return two or less av's"); |
|
83 uint_t av = avs[0]; |
|
84 |
82 |
85 #ifndef PRODUCT |
83 #ifndef PRODUCT |
86 if (PrintMiscellaneous && Verbose) { |
84 if (PrintMiscellaneous && Verbose) { |
87 tty->print("getisax(2) returned: " PTR32_FORMAT, av); |
85 tty->print("getisax(2) returned: " PTR32_FORMAT, av); |
88 if (avn > 1) { |
86 if (avn > 1) { |
89 tty->print(", " PTR32_FORMAT, avs[1]); |
87 tty->print(", " PTR32_FORMAT, avs[1]); |
90 } |
|
91 tty->cr(); |
|
92 } |
88 } |
93 #endif |
89 tty->cr(); |
94 |
90 } |
95 if (av & AV_SPARC_MUL32) features |= hardware_mul32_m; |
91 #endif |
96 if (av & AV_SPARC_DIV32) features |= hardware_div32_m; |
92 |
97 if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m; |
93 if (av & AV_SPARC_MUL32) features |= hardware_mul32_m; |
98 if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m; |
94 if (av & AV_SPARC_DIV32) features |= hardware_div32_m; |
99 if (av & AV_SPARC_POPC) features |= hardware_popc_m; |
95 if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m; |
100 if (av & AV_SPARC_VIS) features |= vis1_instructions_m; |
96 if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m; |
101 if (av & AV_SPARC_VIS2) features |= vis2_instructions_m; |
97 if (av & AV_SPARC_POPC) features |= hardware_popc_m; |
102 if (avn > 1) { |
98 if (av & AV_SPARC_VIS) features |= vis1_instructions_m; |
103 uint_t av2 = avs[1]; |
99 if (av & AV_SPARC_VIS2) features |= vis2_instructions_m; |
|
100 if (avn > 1) { |
|
101 uint_t av2 = avs[1]; |
104 #ifndef AV2_SPARC_SPARC5 |
102 #ifndef AV2_SPARC_SPARC5 |
105 #define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */ |
103 #define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */ |
106 #endif |
104 #endif |
107 if (av2 & AV2_SPARC_SPARC5) features |= sparc5_instructions_m; |
105 if (av2 & AV2_SPARC_SPARC5) features |= sparc5_instructions_m; |
108 } |
106 } |
109 |
107 |
110 // Next values are not defined before Solaris 10 |
108 // We only build on Solaris 10 and up, but some of the values below |
111 // but Solaris 8 is used for jdk6 update builds. |
109 // are not defined on all versions of Solaris 10, so we define them, |
|
110 // if necessary. |
112 #ifndef AV_SPARC_ASI_BLK_INIT |
111 #ifndef AV_SPARC_ASI_BLK_INIT |
113 #define AV_SPARC_ASI_BLK_INIT 0x0080 /* ASI_BLK_INIT_xxx ASI */ |
112 #define AV_SPARC_ASI_BLK_INIT 0x0080 /* ASI_BLK_INIT_xxx ASI */ |
114 #endif |
113 #endif |
115 if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m; |
114 if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m; |
116 |
115 |
117 #ifndef AV_SPARC_FMAF |
116 #ifndef AV_SPARC_FMAF |
118 #define AV_SPARC_FMAF 0x0100 /* Fused Multiply-Add */ |
117 #define AV_SPARC_FMAF 0x0100 /* Fused Multiply-Add */ |
119 #endif |
118 #endif |
120 if (av & AV_SPARC_FMAF) features |= fmaf_instructions_m; |
119 if (av & AV_SPARC_FMAF) features |= fmaf_instructions_m; |
121 |
120 |
122 #ifndef AV_SPARC_FMAU |
121 #ifndef AV_SPARC_FMAU |
123 #define AV_SPARC_FMAU 0x0200 /* Unfused Multiply-Add */ |
122 #define AV_SPARC_FMAU 0x0200 /* Unfused Multiply-Add */ |
124 #endif |
123 #endif |
125 if (av & AV_SPARC_FMAU) features |= fmau_instructions_m; |
124 if (av & AV_SPARC_FMAU) features |= fmau_instructions_m; |
126 |
125 |
127 #ifndef AV_SPARC_VIS3 |
126 #ifndef AV_SPARC_VIS3 |
128 #define AV_SPARC_VIS3 0x0400 /* VIS3 instruction set extensions */ |
127 #define AV_SPARC_VIS3 0x0400 /* VIS3 instruction set extensions */ |
129 #endif |
128 #endif |
130 if (av & AV_SPARC_VIS3) features |= vis3_instructions_m; |
129 if (av & AV_SPARC_VIS3) features |= vis3_instructions_m; |
131 |
130 |
132 #ifndef AV_SPARC_CBCOND |
131 #ifndef AV_SPARC_CBCOND |
133 #define AV_SPARC_CBCOND 0x10000000 /* compare and branch instrs supported */ |
132 #define AV_SPARC_CBCOND 0x10000000 /* compare and branch instrs supported */ |
134 #endif |
133 #endif |
135 if (av & AV_SPARC_CBCOND) features |= cbcond_instructions_m; |
134 if (av & AV_SPARC_CBCOND) features |= cbcond_instructions_m; |
136 |
135 |
137 #ifndef AV_SPARC_AES |
136 #ifndef AV_SPARC_AES |
138 #define AV_SPARC_AES 0x00020000 /* aes instrs supported */ |
137 #define AV_SPARC_AES 0x00020000 /* aes instrs supported */ |
139 #endif |
138 #endif |
140 if (av & AV_SPARC_AES) features |= aes_instructions_m; |
139 if (av & AV_SPARC_AES) features |= aes_instructions_m; |
141 |
140 |
142 #ifndef AV_SPARC_SHA1 |
141 #ifndef AV_SPARC_SHA1 |
143 #define AV_SPARC_SHA1 0x00400000 /* sha1 instruction supported */ |
142 #define AV_SPARC_SHA1 0x00400000 /* sha1 instruction supported */ |
144 #endif |
143 #endif |
145 if (av & AV_SPARC_SHA1) features |= sha1_instruction_m; |
144 if (av & AV_SPARC_SHA1) features |= sha1_instruction_m; |
146 |
145 |
147 #ifndef AV_SPARC_SHA256 |
146 #ifndef AV_SPARC_SHA256 |
148 #define AV_SPARC_SHA256 0x00800000 /* sha256 instruction supported */ |
147 #define AV_SPARC_SHA256 0x00800000 /* sha256 instruction supported */ |
149 #endif |
148 #endif |
150 if (av & AV_SPARC_SHA256) features |= sha256_instruction_m; |
149 if (av & AV_SPARC_SHA256) features |= sha256_instruction_m; |
151 |
150 |
152 #ifndef AV_SPARC_SHA512 |
151 #ifndef AV_SPARC_SHA512 |
153 #define AV_SPARC_SHA512 0x01000000 /* sha512 instruction supported */ |
152 #define AV_SPARC_SHA512 0x01000000 /* sha512 instruction supported */ |
154 #endif |
153 #endif |
155 if (av & AV_SPARC_SHA512) features |= sha512_instruction_m; |
154 if (av & AV_SPARC_SHA512) features |= sha512_instruction_m; |
156 |
|
157 } else { |
|
158 // getisax(2) failed, use the old legacy code. |
|
159 #ifndef PRODUCT |
|
160 if (PrintMiscellaneous && Verbose) |
|
161 tty->print_cr("getisax(2) is not supported."); |
|
162 #endif |
|
163 |
|
164 char tmp; |
|
165 size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1); |
|
166 char* buf = (char*) os::malloc(bufsize, mtInternal); |
|
167 |
|
168 if (buf != NULL) { |
|
169 if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) { |
|
170 // Figure out what kind of sparc we have |
|
171 char *sparc_string = strstr(buf, "sparc"); |
|
172 if (sparc_string != NULL) { features |= v8_instructions_m; |
|
173 if (sparc_string[5] == 'v') { |
|
174 if (sparc_string[6] == '8') { |
|
175 if (sparc_string[7] == '-') { features |= hardware_mul32_m; |
|
176 features |= hardware_div32_m; |
|
177 } else if (sparc_string[7] == 'p') features |= generic_v9_m; |
|
178 else features |= generic_v8_m; |
|
179 } else if (sparc_string[6] == '9') features |= generic_v9_m; |
|
180 } |
|
181 } |
|
182 |
|
183 // Check for visualization instructions |
|
184 char *vis = strstr(buf, "vis"); |
|
185 if (vis != NULL) { features |= vis1_instructions_m; |
|
186 if (vis[3] == '2') features |= vis2_instructions_m; |
|
187 } |
|
188 } |
|
189 os::free(buf); |
|
190 } |
|
191 } |
|
192 |
155 |
193 // Determine the machine type. |
156 // Determine the machine type. |
194 do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m); |
157 do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m); |
195 |
158 |
196 { |
159 { |
201 if (ksp != NULL) { |
164 if (ksp != NULL) { |
202 if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) { |
165 if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) { |
203 kstat_named_t* knm = (kstat_named_t *)ksp->ks_data; |
166 kstat_named_t* knm = (kstat_named_t *)ksp->ks_data; |
204 for (int i = 0; i < ksp->ks_ndata; i++) { |
167 for (int i = 0; i < ksp->ks_ndata; i++) { |
205 if (strcmp((const char*)&(knm[i].name),"implementation") == 0) { |
168 if (strcmp((const char*)&(knm[i].name),"implementation") == 0) { |
206 #ifndef KSTAT_DATA_STRING |
169 implementation = KSTAT_NAMED_STR_PTR(&knm[i]); |
207 #define KSTAT_DATA_STRING 9 |
|
208 #endif |
|
209 if (knm[i].data_type == KSTAT_DATA_CHAR) { |
|
210 // VM is running on Solaris 8 which does not have value.str. |
|
211 implementation = &(knm[i].value.c[0]); |
|
212 } else if (knm[i].data_type == KSTAT_DATA_STRING) { |
|
213 // VM is running on Solaris 10. |
|
214 #ifndef KSTAT_NAMED_STR_PTR |
|
215 // Solaris 8 was used to build VM, define the structure it misses. |
|
216 struct str_t { |
|
217 union { |
|
218 char *ptr; /* NULL-term string */ |
|
219 char __pad[8]; /* 64-bit padding */ |
|
220 } addr; |
|
221 uint32_t len; /* # bytes for strlen + '\0' */ |
|
222 }; |
|
223 #define KSTAT_NAMED_STR_PTR(knptr) (( (str_t*)&((knptr)->value) )->addr.ptr) |
|
224 #endif |
|
225 implementation = KSTAT_NAMED_STR_PTR(&knm[i]); |
|
226 } |
|
227 #ifndef PRODUCT |
170 #ifndef PRODUCT |
228 if (PrintMiscellaneous && Verbose) { |
171 if (PrintMiscellaneous && Verbose) { |
229 tty->print_cr("cpu_info.implementation: %s", implementation); |
172 tty->print_cr("cpu_info.implementation: %s", implementation); |
230 } |
173 } |
231 #endif |
174 #endif |
232 // Convert to UPPER case before compare. |
175 // Convert to UPPER case before compare. |
233 char* impl = os::strdup_check_oom(implementation); |
176 char* impl = os::strdup_check_oom(implementation); |
234 |
177 |
235 for (int i = 0; impl[i] != 0; i++) |
178 for (int i = 0; impl[i] != 0; i++) |
236 impl[i] = (char)toupper((uint)impl[i]); |
179 impl[i] = (char)toupper((uint)impl[i]); |
|
180 |
237 if (strstr(impl, "SPARC64") != NULL) { |
181 if (strstr(impl, "SPARC64") != NULL) { |
238 features |= sparc64_family_m; |
182 features |= sparc64_family_m; |
239 } else if (strstr(impl, "SPARC-M") != NULL) { |
183 } else if (strstr(impl, "SPARC-M") != NULL) { |
240 // M-series SPARC is based on T-series. |
184 // M-series SPARC is based on T-series. |
241 features |= (M_family_m | T_family_m); |
185 features |= (M_family_m | T_family_m); |