1 /*
2 * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2023 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "precompiled.hpp"
27 #include "asm/assembler.inline.hpp"
28 #include "asm/macroAssembler.inline.hpp"
29 #include "compiler/disassembler.hpp"
30 #include "jvm.h"
31 #include "memory/resourceArea.hpp"
32 #include "runtime/globals_extension.hpp"
33 #include "runtime/java.hpp"
34 #include "runtime/os.hpp"
35 #include "runtime/stubCodeGenerator.hpp"
36 #include "runtime/vm_version.hpp"
37 #include "utilities/align.hpp"
38 #include "utilities/defaultStream.hpp"
39 #include "utilities/globalDefinitions.hpp"
40 #include "utilities/powerOfTwo.hpp"
41
42 #include <sys/sysinfo.h>
43 #if defined(_AIX)
44 #include "os_aix.hpp"
45 #include <libperfstat.h>
46 #endif
47
48 bool VM_Version::_is_determine_features_test_running = false;
49 uint64_t VM_Version::_dscr_val = 0;
50
51 #define MSG(flag) \
52 if (flag && !FLAG_IS_DEFAULT(flag)) \
53 jio_fprintf(defaultStream::error_stream(), \
54 "warning: -XX:+" #flag " requires -XX:+UseSIGTRAP\n" \
55 " -XX:+" #flag " will be disabled!\n");
56
57 void VM_Version::initialize() {
58
59 // Test which instructions are supported and measure cache line size.
60 determine_features();
61
62 // If PowerArchitecturePPC64 hasn't been specified explicitly determine from features.
63 if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) {
64 if (VM_Version::has_brw()) {
65 FLAG_SET_ERGO(PowerArchitecturePPC64, 10);
66 } else if (VM_Version::has_darn()) {
67 FLAG_SET_ERGO(PowerArchitecturePPC64, 9);
68 } else if (VM_Version::has_lqarx()) {
69 FLAG_SET_ERGO(PowerArchitecturePPC64, 8);
70 } else if (VM_Version::has_popcntw()) {
71 FLAG_SET_ERGO(PowerArchitecturePPC64, 7);
72 } else if (VM_Version::has_cmpb()) {
73 FLAG_SET_ERGO(PowerArchitecturePPC64, 6);
74 } else if (VM_Version::has_popcntb()) {
75 FLAG_SET_ERGO(PowerArchitecturePPC64, 5);
76 } else {
77 FLAG_SET_ERGO(PowerArchitecturePPC64, 0);
78 }
79 }
80
81 bool PowerArchitecturePPC64_ok = false;
82 switch (PowerArchitecturePPC64) {
83 case 10: if (!VM_Version::has_brw() ) break;
84 case 9: if (!VM_Version::has_darn() ) break;
85 case 8: if (!VM_Version::has_lqarx() ) break;
86 case 7: if (!VM_Version::has_popcntw()) break;
87 case 6: if (!VM_Version::has_cmpb() ) break;
88 case 5: if (!VM_Version::has_popcntb()) break;
89 case 0: PowerArchitecturePPC64_ok = true; break;
90 default: break;
91 }
92 guarantee(PowerArchitecturePPC64_ok, "PowerArchitecturePPC64 cannot be set to "
93 UINTX_FORMAT " on this machine", PowerArchitecturePPC64);
94
95 // Power 8: Configure Data Stream Control Register.
96 if (PowerArchitecturePPC64 >= 8 && has_mfdscr()) {
97 config_dscr();
98 }
99
100 if (!UseSIGTRAP) {
101 MSG(TrapBasedICMissChecks);
102 MSG(TrapBasedNullChecks);
103 FLAG_SET_ERGO(TrapBasedNullChecks, false);
104 FLAG_SET_ERGO(TrapBasedICMissChecks, false);
105 }
106
107 #ifdef COMPILER2
108 if (!UseSIGTRAP) {
109 MSG(TrapBasedRangeChecks);
110 FLAG_SET_ERGO(TrapBasedRangeChecks, false);
111 }
112
113 if (PowerArchitecturePPC64 >= 8) {
114 if (FLAG_IS_DEFAULT(SuperwordUseVSX)) {
115 FLAG_SET_ERGO(SuperwordUseVSX, true);
116 }
117 } else {
118 if (SuperwordUseVSX) {
119 warning("SuperwordUseVSX specified, but needs at least Power8.");
120 FLAG_SET_DEFAULT(SuperwordUseVSX, false);
121 }
122 }
123 MaxVectorSize = SuperwordUseVSX ? 16 : 8;
124
125 if (PowerArchitecturePPC64 >= 9) {
126 if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstructionsPPC64)) {
127 FLAG_SET_ERGO(UseCountTrailingZerosInstructionsPPC64, true);
128 }
129 if (FLAG_IS_DEFAULT(UseCharacterCompareIntrinsics)) {
130 FLAG_SET_ERGO(UseCharacterCompareIntrinsics, true);
131 }
132 if (SuperwordUseVSX) {
133 if (FLAG_IS_DEFAULT(UseVectorByteReverseInstructionsPPC64)) {
134 FLAG_SET_ERGO(UseVectorByteReverseInstructionsPPC64, true);
135 }
136 } else if (UseVectorByteReverseInstructionsPPC64) {
137 warning("UseVectorByteReverseInstructionsPPC64 specified, but needs SuperwordUseVSX.");
138 FLAG_SET_DEFAULT(UseVectorByteReverseInstructionsPPC64, false);
139 }
140 if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) {
141 FLAG_SET_ERGO(UseBASE64Intrinsics, true);
142 }
143 } else {
144 if (UseCountTrailingZerosInstructionsPPC64) {
145 warning("UseCountTrailingZerosInstructionsPPC64 specified, but needs at least Power9.");
146 FLAG_SET_DEFAULT(UseCountTrailingZerosInstructionsPPC64, false);
147 }
148 if (UseCharacterCompareIntrinsics) {
149 warning("UseCharacterCompareIntrinsics specified, but needs at least Power9.");
150 FLAG_SET_DEFAULT(UseCharacterCompareIntrinsics, false);
151 }
152 if (UseVectorByteReverseInstructionsPPC64) {
153 warning("UseVectorByteReverseInstructionsPPC64 specified, but needs at least Power9.");
154 FLAG_SET_DEFAULT(UseVectorByteReverseInstructionsPPC64, false);
155 }
156 if (UseBASE64Intrinsics) {
157 warning("UseBASE64Intrinsics specified, but needs at least Power9.");
158 FLAG_SET_DEFAULT(UseBASE64Intrinsics, false);
159 }
160 }
161
162 if (PowerArchitecturePPC64 >= 10) {
163 if (FLAG_IS_DEFAULT(UseByteReverseInstructions)) {
164 FLAG_SET_ERGO(UseByteReverseInstructions, true);
165 }
166 } else {
167 if (UseByteReverseInstructions) {
168 warning("UseByteReverseInstructions specified, but needs at least Power10.");
169 FLAG_SET_DEFAULT(UseByteReverseInstructions, false);
170 }
171 }
172 #endif
173
174 // Create and print feature-string.
175 char buf[(num_features+1) * 16]; // Max 16 chars per feature.
176 jio_snprintf(buf, sizeof(buf),
177 "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
178 (has_fsqrt() ? " fsqrt" : ""),
179 (has_isel() ? " isel" : ""),
180 (has_lxarxeh() ? " lxarxeh" : ""),
181 (has_cmpb() ? " cmpb" : ""),
182 (has_popcntb() ? " popcntb" : ""),
183 (has_popcntw() ? " popcntw" : ""),
184 (has_fcfids() ? " fcfids" : ""),
185 (has_vand() ? " vand" : ""),
186 (has_lqarx() ? " lqarx" : ""),
187 (has_vcipher() ? " aes" : ""),
188 (has_vpmsumb() ? " vpmsumb" : ""),
189 (has_mfdscr() ? " mfdscr" : ""),
190 (has_vsx() ? " vsx" : ""),
191 (has_ldbrx() ? " ldbrx" : ""),
192 (has_stdbrx() ? " stdbrx" : ""),
193 (has_vshasig() ? " sha" : ""),
194 (has_darn() ? " darn" : ""),
195 (has_brw() ? " brw" : "")
196 // Make sure number of %s matches num_features!
197 );
198 _features_string = os::strdup(buf);
199 if (Verbose) {
200 print_features();
201 }
202
203 // PPC64 supports 8-byte compare-exchange operations (see Atomic::cmpxchg)
204 // and 'atomic long memory ops' (see Unsafe_GetLongVolatile).
205 _supports_cx8 = true;
206
207 // Used by C1.
208 _supports_atomic_getset4 = true;
209 _supports_atomic_getadd4 = true;
210 _supports_atomic_getset8 = true;
211 _supports_atomic_getadd8 = true;
212
213 intx cache_line_size = L1_data_cache_line_size();
214
215 if (PowerArchitecturePPC64 >= 9) {
216 if (os::supports_map_sync() == true) {
217 _data_cache_line_flush_size = cache_line_size;
218 }
219 }
220
221 if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) AllocatePrefetchStyle = 1;
222
223 if (cache_line_size > AllocatePrefetchStepSize) AllocatePrefetchStepSize = cache_line_size;
224 // PPC processors have an automatic prefetch engine.
225 if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) AllocatePrefetchLines = 1;
226 if (AllocatePrefetchDistance < 0) AllocatePrefetchDistance = 3 * cache_line_size;
227
228 assert(AllocatePrefetchLines > 0, "invalid value");
229 if (AllocatePrefetchLines < 1) { // Set valid value in product VM.
230 AllocatePrefetchLines = 1; // Conservative value.
231 }
232
233 if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) {
234 AllocatePrefetchStyle = 1; // Fall back if inappropriate.
235 }
236
237 assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive");
238
239 if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && (cache_line_size > ContendedPaddingWidth)) {
240 ContendedPaddingWidth = cache_line_size;
241 }
242
243 // If running on Power8 or newer hardware, the implementation uses the available vector instructions.
244 // In all other cases, the implementation uses only generally available instructions.
245 if (!UseCRC32Intrinsics) {
246 if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
247 FLAG_SET_DEFAULT(UseCRC32Intrinsics, true);
248 }
249 }
250
251 // Implementation does not use any of the vector instructions available with Power8.
252 // Their exploitation is still pending (aka "work in progress").
253 if (!UseCRC32CIntrinsics) {
254 if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
255 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
256 }
257 }
258
259 // TODO: Provide implementation.
260 if (UseAdler32Intrinsics) {
261 warning("Adler32Intrinsics not available on this CPU.");
262 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
263 }
264
265 // The AES intrinsic stubs require AES instruction support.
266 if (has_vcipher()) {
267 if (FLAG_IS_DEFAULT(UseAES)) {
268 UseAES = true;
269 }
270 } else if (UseAES) {
271 if (!FLAG_IS_DEFAULT(UseAES))
272 warning("AES instructions are not available on this CPU");
273 FLAG_SET_DEFAULT(UseAES, false);
274 }
275
276 if (UseAES && has_vcipher()) {
277 if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
278 UseAESIntrinsics = true;
279 }
280 } else if (UseAESIntrinsics) {
281 if (!FLAG_IS_DEFAULT(UseAESIntrinsics))
282 warning("AES intrinsics are not available on this CPU");
283 FLAG_SET_DEFAULT(UseAESIntrinsics, false);
284 }
285
286 if (UseAESCTRIntrinsics) {
287 warning("AES/CTR intrinsics are not available on this CPU");
288 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
289 }
290
291 if (UseGHASHIntrinsics) {
292 warning("GHASH intrinsics are not available on this CPU");
293 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
294 }
295
296 if (FLAG_IS_DEFAULT(UseFMA)) {
297 FLAG_SET_DEFAULT(UseFMA, true);
298 }
299
300 if (UseMD5Intrinsics) {
301 warning("MD5 intrinsics are not available on this CPU");
302 FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
303 }
304
305 if (has_vshasig()) {
306 if (FLAG_IS_DEFAULT(UseSHA)) {
307 UseSHA = true;
308 }
309 } else if (UseSHA) {
310 if (!FLAG_IS_DEFAULT(UseSHA))
311 warning("SHA instructions are not available on this CPU");
312 FLAG_SET_DEFAULT(UseSHA, false);
313 }
314
315 if (UseSHA1Intrinsics) {
316 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
317 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
318 }
319
320 if (UseSHA && has_vshasig()) {
321 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
322 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
323 }
324 } else if (UseSHA256Intrinsics) {
325 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
326 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
327 }
328
329 if (UseSHA && has_vshasig()) {
330 if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
331 FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
332 }
333 } else if (UseSHA512Intrinsics) {
334 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
335 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
336 }
337
338 if (UseSHA3Intrinsics) {
339 warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
340 FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
341 }
342
343 if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
344 FLAG_SET_DEFAULT(UseSHA, false);
345 }
346
347 #ifdef COMPILER2
348 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
349 UseSquareToLenIntrinsic = true;
350 }
351 if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
352 UseMulAddIntrinsic = true;
353 }
354 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
355 UseMultiplyToLenIntrinsic = true;
356 }
357 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
358 UseMontgomeryMultiplyIntrinsic = true;
359 }
360 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
361 UseMontgomerySquareIntrinsic = true;
362 }
363 #endif
364
365 if (UseVectorizedMismatchIntrinsic) {
366 warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU.");
367 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
368 }
369
370 // This machine allows unaligned memory accesses
371 if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
372 FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
373 }
374
375 check_virtualizations();
376 }
377
378 void VM_Version::check_virtualizations() {
379 #if defined(_AIX)
380 int rc = 0;
381 perfstat_partition_total_t pinfo;
382 rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
383 if (rc == 1) {
384 Abstract_VM_Version::_detected_virtualization = PowerVM;
385 }
386 #else
387 const char* info_file = "/proc/ppc64/lparcfg";
388 // system_type=...qemu indicates PowerKVM
389 // e.g. system_type=IBM pSeries (emulated by qemu)
390 char line[500];
391 FILE* fp = os::fopen(info_file, "r");
392 if (fp == nullptr) {
393 return;
394 }
395 const char* system_type="system_type="; // in case this line contains qemu, it is KVM
396 const char* num_lpars="NumLpars="; // in case of non-KVM : if this line is found it is PowerVM
397 bool num_lpars_found = false;
398
399 while (fgets(line, sizeof(line), fp) != nullptr) {
400 if (strncmp(line, system_type, strlen(system_type)) == 0) {
401 if (strstr(line, "qemu") != 0) {
402 Abstract_VM_Version::_detected_virtualization = PowerKVM;
403 fclose(fp);
404 return;
405 }
406 }
407 if (strncmp(line, num_lpars, strlen(num_lpars)) == 0) {
408 num_lpars_found = true;
409 }
410 }
411 if (num_lpars_found) {
412 Abstract_VM_Version::_detected_virtualization = PowerVM;
413 } else {
414 Abstract_VM_Version::_detected_virtualization = PowerFullPartitionMode;
415 }
416 fclose(fp);
417 #endif
418 }
419
420 void VM_Version::print_platform_virtualization_info(outputStream* st) {
421 #if defined(_AIX)
422 // more info about perfstat API see
423 // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.prftools/idprftools_perfstat_glob_partition.htm
424 int rc = 0;
425 perfstat_partition_total_t pinfo;
426 memset(&pinfo, 0, sizeof(perfstat_partition_total_t));
427 rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
428 if (rc != 1) {
429 return;
430 } else {
431 st->print_cr("Virtualization type : PowerVM");
432 }
433 // CPU information
434 perfstat_cpu_total_t cpuinfo;
435 memset(&cpuinfo, 0, sizeof(perfstat_cpu_total_t));
436 rc = perfstat_cpu_total(nullptr, &cpuinfo, sizeof(perfstat_cpu_total_t), 1);
437 if (rc != 1) {
438 return;
439 }
440
441 st->print_cr("Processor description : %s", cpuinfo.description);
442 st->print_cr("Processor speed : %llu Hz", cpuinfo.processorHZ);
443
444 st->print_cr("LPAR partition name : %s", pinfo.name);
445 st->print_cr("LPAR partition number : %u", pinfo.lpar_id);
446 st->print_cr("LPAR partition type : %s", pinfo.type.b.shared_enabled ? "shared" : "dedicated");
447 st->print_cr("LPAR mode : %s", pinfo.type.b.donate_enabled ? "donating" : pinfo.type.b.capped ? "capped" : "uncapped");
448 st->print_cr("LPAR partition group ID : %u", pinfo.group_id);
449 st->print_cr("LPAR shared pool ID : %u", pinfo.pool_id);
450
451 st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_capable ? "capable" : "not capable");
452 st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_enabled ? "on" : "off");
453 st->print_cr("AME (active memory expansion) : %s", pinfo.type.b.ame_enabled ? "on" : "off");
454
455 if (pinfo.type.b.ame_enabled) {
456 st->print_cr("AME true memory in bytes : %llu", pinfo.true_memory);
457 st->print_cr("AME expanded memory in bytes : %llu", pinfo.expanded_memory);
458 }
459
460 st->print_cr("SMT : %s", pinfo.type.b.smt_capable ? "capable" : "not capable");
461 st->print_cr("SMT : %s", pinfo.type.b.smt_enabled ? "on" : "off");
462 int ocpus = pinfo.online_cpus > 0 ? pinfo.online_cpus : 1;
463 st->print_cr("LPAR threads : %d", cpuinfo.ncpus/ocpus);
464 st->print_cr("LPAR online virtual cpus : %d", pinfo.online_cpus);
465 st->print_cr("LPAR logical cpus : %d", cpuinfo.ncpus);
466 st->print_cr("LPAR maximum virtual cpus : %u", pinfo.max_cpus);
467 st->print_cr("LPAR minimum virtual cpus : %u", pinfo.min_cpus);
468 st->print_cr("LPAR entitled capacity : %4.2f", (double) (pinfo.entitled_proc_capacity/100.0));
469 st->print_cr("LPAR online memory : %llu MB", pinfo.online_memory);
470 st->print_cr("LPAR maximum memory : %llu MB", pinfo.max_memory);
471 st->print_cr("LPAR minimum memory : %llu MB", pinfo.min_memory);
472 #else
473 const char* info_file = "/proc/ppc64/lparcfg";
474 const char* kw[] = { "system_type=", // qemu indicates PowerKVM
475 "partition_entitled_capacity=", // entitled processor capacity percentage
476 "partition_max_entitled_capacity=",
477 "capacity_weight=", // partition CPU weight
478 "partition_active_processors=",
479 "partition_potential_processors=",
480 "entitled_proc_capacity_available=",
481 "capped=", // 0 - uncapped, 1 - vcpus capped at entitled processor capacity percentage
482 "shared_processor_mode=", // (non)dedicated partition
483 "system_potential_processors=",
484 "pool=", // CPU-pool number
485 "pool_capacity=",
486 "NumLpars=", // on non-KVM machines, NumLpars is not found for full partition mode machines
487 nullptr };
488 if (!print_matching_lines_from_file(info_file, st, kw)) {
489 st->print_cr(" <%s Not Available>", info_file);
490 }
491 #endif
492 }
493
494 void VM_Version::print_features() {
495 tty->print_cr("Version: %s L1_data_cache_line_size=%d", features_string(), L1_data_cache_line_size());
496
497 if (Verbose) {
498 if (ContendedPaddingWidth > 0) {
499 tty->cr();
500 tty->print_cr("ContendedPaddingWidth " INTX_FORMAT, ContendedPaddingWidth);
501 }
502 }
503 }
504
505 void VM_Version::determine_features() {
506 #if defined(ABI_ELFv2)
507 // 1 InstWord per call for the blr instruction.
508 const int code_size = (num_features+1+2*1)*BytesPerInstWord;
509 #else
510 // 7 InstWords for each call (function descriptor + blr instruction).
511 const int code_size = (num_features+1+2*7)*BytesPerInstWord;
512 #endif
513 int features = 0;
514
515 // create test area
516 enum { BUFFER_SIZE = 2*4*K }; // Needs to be >=2* max cache line size (cache line size can't exceed min page size).
517 char test_area[BUFFER_SIZE];
518 char *mid_of_test_area = &test_area[BUFFER_SIZE>>1];
519
520 // Allocate space for the code.
521 ResourceMark rm;
522 CodeBuffer cb("detect_cpu_features", code_size, 0);
523 MacroAssembler* a = new MacroAssembler(&cb);
524
525 // Must be set to true so we can generate the test code.
526 _features = VM_Version::all_features_m;
527
528 // Emit code.
529 void (*test)(address addr, uint64_t offset)=(void(*)(address addr, uint64_t offset))(void *)a->function_entry();
530 uint32_t *code = (uint32_t *)a->pc();
531 // Don't use R0 in ldarx.
532 // Keep R3_ARG1 unmodified, it contains &field (see below).
533 // Keep R4_ARG2 unmodified, it contains offset = 0 (see below).
534 a->fsqrt(F3, F4); // code[0] -> fsqrt_m
535 a->fsqrts(F3, F4); // code[1] -> fsqrts_m
536 a->isel(R7, R5, R6, 0); // code[2] -> isel_m
537 a->ldarx_unchecked(R7, R3_ARG1, R4_ARG2, 1); // code[3] -> lxarx_m
538 a->cmpb(R7, R5, R6); // code[4] -> cmpb
539 a->popcntb(R7, R5); // code[5] -> popcntb
540 a->popcntw(R7, R5); // code[6] -> popcntw
541 a->fcfids(F3, F4); // code[7] -> fcfids
542 a->vand(VR0, VR0, VR0); // code[8] -> vand
543 // arg0 of lqarx must be an even register, (arg1 + arg2) must be a multiple of 16
544 a->lqarx_unchecked(R6, R3_ARG1, R4_ARG2, 1); // code[9] -> lqarx_m
545 a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher
546 a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb
547 a->mfdscr(R0); // code[12] -> mfdscr
548 a->lxvd2x(VSR0, R3_ARG1); // code[13] -> vsx
549 a->ldbrx(R7, R3_ARG1, R4_ARG2); // code[14] -> ldbrx
550 a->stdbrx(R7, R3_ARG1, R4_ARG2); // code[15] -> stdbrx
551 a->vshasigmaw(VR0, VR1, 1, 0xF); // code[16] -> vshasig
552 a->darn(R7); // code[17] -> darn
553 a->brw(R5, R6); // code[18] -> brw
554 a->blr();
555
556 // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
557 void (*zero_cacheline_func_ptr)(char*) = (void(*)(char*))(void *)a->function_entry();
558 a->dcbz(R3_ARG1); // R3_ARG1 = addr
559 a->blr();
560
561 uint32_t *code_end = (uint32_t *)a->pc();
562 a->flush();
563 _features = VM_Version::unknown_m;
564
565 // Print the detection code.
566 if (PrintAssembly) {
567 ttyLocker ttyl;
568 tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
569 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
570 }
571
572 // Measure cache line size.
573 memset(test_area, 0xFF, BUFFER_SIZE); // Fill test area with 0xFF.
574 (*zero_cacheline_func_ptr)(mid_of_test_area); // Call function which executes dcbz to the middle.
575 int count = 0; // count zeroed bytes
576 for (int i = 0; i < BUFFER_SIZE; i++) if (test_area[i] == 0) count++;
577 guarantee(is_power_of_2(count), "cache line size needs to be a power of 2");
578 _L1_data_cache_line_size = count;
579
580 // Execute code. Illegal instructions will be replaced by 0 in the signal handler.
581 VM_Version::_is_determine_features_test_running = true;
582 // We must align the first argument to 16 bytes because of the lqarx check.
583 (*test)(align_up((address)mid_of_test_area, 16), 0);
584 VM_Version::_is_determine_features_test_running = false;
585
586 // determine which instructions are legal.
587 int feature_cntr = 0;
588 if (code[feature_cntr++]) features |= fsqrt_m;
589 if (code[feature_cntr++]) features |= fsqrts_m;
590 if (code[feature_cntr++]) features |= isel_m;
591 if (code[feature_cntr++]) features |= lxarxeh_m;
592 if (code[feature_cntr++]) features |= cmpb_m;
593 if (code[feature_cntr++]) features |= popcntb_m;
594 if (code[feature_cntr++]) features |= popcntw_m;
595 if (code[feature_cntr++]) features |= fcfids_m;
596 if (code[feature_cntr++]) features |= vand_m;
597 if (code[feature_cntr++]) features |= lqarx_m;
598 if (code[feature_cntr++]) features |= vcipher_m;
599 if (code[feature_cntr++]) features |= vpmsumb_m;
600 if (code[feature_cntr++]) features |= mfdscr_m;
601 if (code[feature_cntr++]) features |= vsx_m;
602 if (code[feature_cntr++]) features |= ldbrx_m;
603 if (code[feature_cntr++]) features |= stdbrx_m;
604 if (code[feature_cntr++]) features |= vshasig_m;
605 if (code[feature_cntr++]) features |= darn_m;
606 if (code[feature_cntr++]) features |= brw_m;
607
608 // Print the detection code.
609 if (PrintAssembly) {
610 ttyLocker ttyl;
611 tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " after execution:", p2i(code));
612 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
613 }
614
615 _features = features;
616 }
617
618 // Power 8: Configure Data Stream Control Register.
619 void VM_Version::config_dscr() {
620 // 7 InstWords for each call (function descriptor + blr instruction).
621 const int code_size = (2+2*7)*BytesPerInstWord;
622
623 // Allocate space for the code.
624 ResourceMark rm;
625 CodeBuffer cb("config_dscr", code_size, 0);
626 MacroAssembler* a = new MacroAssembler(&cb);
627
628 // Emit code.
629 uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->function_entry();
630 uint32_t *code = (uint32_t *)a->pc();
631 a->mfdscr(R3);
632 a->blr();
633
634 void (*set_dscr)(long) = (void(*)(long))(void *)a->function_entry();
635 a->mtdscr(R3);
636 a->blr();
637
638 uint32_t *code_end = (uint32_t *)a->pc();
639 a->flush();
640
641 // Print the detection code.
642 if (PrintAssembly) {
643 ttyLocker ttyl;
644 tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", p2i(code));
645 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
646 }
647
648 // Apply the configuration if needed.
649 _dscr_val = (*get_dscr)();
650 if (Verbose) {
651 tty->print_cr("dscr value was 0x%lx" , _dscr_val);
652 }
653 bool change_requested = false;
654 if (DSCR_PPC64 != (uintx)-1) {
655 _dscr_val = DSCR_PPC64;
656 change_requested = true;
657 }
658 if (DSCR_DPFD_PPC64 <= 7) {
659 uint64_t mask = 0x7;
660 if ((_dscr_val & mask) != DSCR_DPFD_PPC64) {
661 _dscr_val = (_dscr_val & ~mask) | (DSCR_DPFD_PPC64);
662 change_requested = true;
663 }
664 }
665 if (DSCR_URG_PPC64 <= 7) {
666 uint64_t mask = 0x7 << 6;
667 if ((_dscr_val & mask) != DSCR_DPFD_PPC64 << 6) {
668 _dscr_val = (_dscr_val & ~mask) | (DSCR_URG_PPC64 << 6);
669 change_requested = true;
670 }
671 }
672 if (change_requested) {
673 (*set_dscr)(_dscr_val);
674 if (Verbose) {
675 tty->print_cr("dscr was set to 0x%lx" , (*get_dscr)());
676 }
677 }
678 }
679
680 static uint64_t saved_features = 0;
681
682 void VM_Version::allow_all() {
683 saved_features = _features;
684 _features = all_features_m;
685 }
686
687 void VM_Version::revert() {
688 _features = saved_features;
689 }
690
691 // get cpu information.
692 void VM_Version::initialize_cpu_information(void) {
693 // do nothing if cpu info has been initialized
694 if (_initialized) {
695 return;
696 }
697
698 _no_of_cores = os::processor_count();
699 _no_of_threads = _no_of_cores;
700 _no_of_sockets = _no_of_cores;
701 snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64);
702 snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", features_string());
703 _initialized = true;
704 }