1 /*
2 * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2026 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 "asm/assembler.inline.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "compiler/compilerDefinitions.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 {
69 FLAG_SET_ERGO(PowerArchitecturePPC64, 8);
70 }
71 }
72
73 bool PowerArchitecturePPC64_ok = false;
74 switch (PowerArchitecturePPC64) {
75 case 10: if (!VM_Version::has_brw() ) break;
76 case 9: if (!VM_Version::has_darn() ) break;
77 case 8: PowerArchitecturePPC64_ok = true; break;
78 default: break;
79 }
80 guarantee(PowerArchitecturePPC64_ok, "PowerArchitecturePPC64 cannot be set to "
81 "%zu on this machine", PowerArchitecturePPC64);
82
83 // Power 8: Configure Data Stream Control Register.
84 if (VM_Version::has_mfdscr()) {
85 config_dscr();
86 }
87
88 if (!UseSIGTRAP) {
89 MSG(TrapBasedICMissChecks);
90 MSG(TrapBasedNullChecks);
91 MSG(TrapBasedNMethodEntryBarriers);
92 FLAG_SET_ERGO(TrapBasedNullChecks, false);
93 FLAG_SET_ERGO(TrapBasedICMissChecks, false);
94 FLAG_SET_ERGO(TrapBasedNMethodEntryBarriers, false);
95 }
96
97 #ifdef COMPILER2
98 if (!UseSIGTRAP) {
99 MSG(TrapBasedRangeChecks);
100 FLAG_SET_ERGO(TrapBasedRangeChecks, false);
101 }
102
103 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
104 FLAG_SET_ERGO(UsePopCountInstruction, true);
105 }
106
107 if (PowerArchitecturePPC64 >= 9) {
108 // Performance is good since Power9.
109 if (FLAG_IS_DEFAULT(SuperwordUseVSX) && CompilerConfig::is_c2_enabled()) {
110 FLAG_SET_ERGO(SuperwordUseVSX, true);
111 }
112 } else if (SuperwordUseVSX) {
113 warning("SuperwordUseVSX specified, but needs at least Power9.");
114 FLAG_SET_DEFAULT(SuperwordUseVSX, false);
115 }
116
117 MaxVectorSize = SuperwordUseVSX ? 16 : 8;
118 if (!SuperwordUseVSX && FLAG_IS_DEFAULT(EnableVectorSupport)) {
119 // VectorSupport intrinsics currently have issues with MaxVectorSize < 16 (JDK-8370803).
120 FLAG_SET_ERGO(EnableVectorSupport, false);
121 }
122 if (FLAG_IS_DEFAULT(AlignVector)) {
123 FLAG_SET_ERGO(AlignVector, false);
124 }
125
126 if (PowerArchitecturePPC64 >= 9) {
127 if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstructionsPPC64)) {
128 FLAG_SET_ERGO(UseCountTrailingZerosInstructionsPPC64, true);
129 }
130 if (FLAG_IS_DEFAULT(UseCharacterCompareIntrinsics)) {
131 FLAG_SET_ERGO(UseCharacterCompareIntrinsics, true);
132 }
133 if (SuperwordUseVSX) {
134 if (FLAG_IS_DEFAULT(UseVectorByteReverseInstructionsPPC64)) {
135 FLAG_SET_ERGO(UseVectorByteReverseInstructionsPPC64, true);
136 }
137 } else if (UseVectorByteReverseInstructionsPPC64) {
138 warning("UseVectorByteReverseInstructionsPPC64 specified, but needs SuperwordUseVSX.");
139 FLAG_SET_DEFAULT(UseVectorByteReverseInstructionsPPC64, false);
140 }
141 if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) {
142 FLAG_SET_ERGO(UseBASE64Intrinsics, true);
143 }
144 } else {
145 if (UseCountTrailingZerosInstructionsPPC64) {
146 warning("UseCountTrailingZerosInstructionsPPC64 specified, but needs at least Power9.");
147 FLAG_SET_DEFAULT(UseCountTrailingZerosInstructionsPPC64, false);
148 }
149 if (UseCharacterCompareIntrinsics) {
150 warning("UseCharacterCompareIntrinsics specified, but needs at least Power9.");
151 FLAG_SET_DEFAULT(UseCharacterCompareIntrinsics, false);
152 }
153 if (UseVectorByteReverseInstructionsPPC64) {
154 warning("UseVectorByteReverseInstructionsPPC64 specified, but needs at least Power9.");
155 FLAG_SET_DEFAULT(UseVectorByteReverseInstructionsPPC64, false);
156 }
157 if (UseBASE64Intrinsics) {
158 warning("UseBASE64Intrinsics specified, but needs at least Power9.");
159 FLAG_SET_DEFAULT(UseBASE64Intrinsics, false);
160 }
161 }
162
163 if (PowerArchitecturePPC64 >= 10) {
164 if (FLAG_IS_DEFAULT(UseByteReverseInstructions)) {
165 FLAG_SET_ERGO(UseByteReverseInstructions, true);
166 }
167 } else {
168 if (UseByteReverseInstructions) {
169 warning("UseByteReverseInstructions specified, but needs at least Power10.");
170 FLAG_SET_DEFAULT(UseByteReverseInstructions, false);
171 }
172 }
173
174 if (OptimizeFill) {
175 warning("OptimizeFill is not supported on this CPU.");
176 FLAG_SET_DEFAULT(OptimizeFill, false);
177 }
178
179 if (OptoScheduling) {
180 // The OptoScheduling information is not maintained in ppd.ad.
181 warning("OptoScheduling is not supported on this CPU.");
182 FLAG_SET_DEFAULT(OptoScheduling, false);
183 }
184 #endif
185
186 // Create and print feature-string.
187 char buf[(num_features+1) * 16]; // Max 16 chars per feature.
188 jio_snprintf(buf, sizeof(buf),
189 "ppc64 sha aes%s%s%s",
190 (has_mfdscr() ? " mfdscr" : ""),
191 (has_darn() ? " darn" : ""),
192 (has_brw() ? " brw" : "")
193 // Make sure number of %s matches num_features!
194 );
195 _cpu_info_string = os::strdup(buf);
196 if (Verbose) {
197 print_features();
198 }
199
200 // Used by C1.
201 _supports_atomic_getset4 = true;
202 _supports_atomic_getadd4 = true;
203 _supports_atomic_getset8 = true;
204 _supports_atomic_getadd8 = true;
205
206 intx cache_line_size = L1_data_cache_line_size();
207
208 if (PowerArchitecturePPC64 >= 9) {
209 if (os::supports_map_sync() == true) {
210 _data_cache_line_flush_size = cache_line_size;
211 }
212 }
213
214 if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) AllocatePrefetchStyle = 1;
215
216 if (cache_line_size > AllocatePrefetchStepSize) AllocatePrefetchStepSize = cache_line_size;
217 // PPC processors have an automatic prefetch engine.
218 if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) AllocatePrefetchLines = 1;
219 if (AllocatePrefetchDistance < 0) AllocatePrefetchDistance = 3 * cache_line_size;
220
221 assert(AllocatePrefetchLines > 0, "invalid value");
222 if (AllocatePrefetchLines < 1) { // Set valid value in product VM.
223 AllocatePrefetchLines = 1; // Conservative value.
224 }
225
226 if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) {
227 AllocatePrefetchStyle = 1; // Fall back if inappropriate.
228 }
229
230 assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive");
231
232 if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && (cache_line_size > ContendedPaddingWidth)) {
233 ContendedPaddingWidth = cache_line_size;
234 }
235
236 // If running on Power8 or newer hardware, the implementation uses the available vector instructions.
237 // In all other cases, the implementation uses only generally available instructions.
238 if (!UseCRC32Intrinsics) {
239 if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
240 FLAG_SET_DEFAULT(UseCRC32Intrinsics, true);
241 }
242 }
243
244 // Implementation does not use any of the vector instructions available with Power8.
245 // Their exploitation is still pending (aka "work in progress").
246 if (!UseCRC32CIntrinsics) {
247 if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
248 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
249 }
250 }
251
252 // TODO: Provide implementation.
253 if (UseAdler32Intrinsics) {
254 warning("Adler32Intrinsics not available on this CPU.");
255 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
256 }
257
258 // The AES intrinsic stubs require AES instruction support.
259 if (FLAG_IS_DEFAULT(UseAES)) {
260 UseAES = true;
261 }
262
263 if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
264 UseAESIntrinsics = true;
265 }
266
267 if (UseAESCTRIntrinsics) {
268 warning("AES/CTR intrinsics are not available on this CPU");
269 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
270 }
271
272 if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
273 UseGHASHIntrinsics = true;
274 }
275
276 if (FLAG_IS_DEFAULT(UseFMA)) {
277 FLAG_SET_DEFAULT(UseFMA, true);
278 }
279
280 if (UseMD5Intrinsics) {
281 warning("MD5 intrinsics are not available on this CPU");
282 FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
283 }
284
285 if (FLAG_IS_DEFAULT(UseSHA)) {
286 UseSHA = true;
287 }
288
289 if (UseSHA1Intrinsics) {
290 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
291 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
292 }
293
294 if (UseSHA) {
295 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
296 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
297 }
298 } else if (UseSHA256Intrinsics) {
299 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
300 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
301 }
302
303 if (UseSHA) {
304 if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
305 FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
306 }
307 } else if (UseSHA512Intrinsics) {
308 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
309 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
310 }
311
312 if (UseSHA3Intrinsics) {
313 warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
314 FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
315 }
316
317 #ifdef COMPILER2
318 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
319 UseSquareToLenIntrinsic = true;
320 }
321 if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
322 UseMulAddIntrinsic = true;
323 }
324 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
325 UseMultiplyToLenIntrinsic = true;
326 }
327 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
328 UseMontgomeryMultiplyIntrinsic = true;
329 }
330 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
331 UseMontgomerySquareIntrinsic = true;
332 }
333 #endif
334
335 if (UseVectorizedMismatchIntrinsic) {
336 warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU.");
337 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
338 }
339
340 // This machine allows unaligned memory accesses
341 if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
342 FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
343 }
344
345 check_virtualizations();
346 }
347
348 void VM_Version::check_virtualizations() {
349 #if defined(_AIX)
350 int rc = 0;
351 perfstat_partition_total_t pinfo;
352 rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
353 if (rc == 1) {
354 Abstract_VM_Version::_detected_virtualization = PowerVM;
355 }
356 #else
357 const char* info_file = "/proc/ppc64/lparcfg";
358 // system_type=...qemu indicates PowerKVM
359 // e.g. system_type=IBM pSeries (emulated by qemu)
360 char line[500];
361 FILE* fp = os::fopen(info_file, "r");
362 if (fp == nullptr) {
363 return;
364 }
365 const char* system_type="system_type="; // in case this line contains qemu, it is KVM
366 const char* num_lpars="NumLpars="; // in case of non-KVM : if this line is found it is PowerVM
367 bool num_lpars_found = false;
368
369 while (fgets(line, sizeof(line), fp) != nullptr) {
370 if (strncmp(line, system_type, strlen(system_type)) == 0) {
371 if (strstr(line, "qemu") != nullptr) {
372 Abstract_VM_Version::_detected_virtualization = PowerKVM;
373 fclose(fp);
374 return;
375 }
376 }
377 if (strncmp(line, num_lpars, strlen(num_lpars)) == 0) {
378 num_lpars_found = true;
379 }
380 }
381 if (num_lpars_found) {
382 Abstract_VM_Version::_detected_virtualization = PowerVM;
383 } else {
384 Abstract_VM_Version::_detected_virtualization = PowerFullPartitionMode;
385 }
386 fclose(fp);
387 #endif
388 }
389
390 void VM_Version::print_platform_virtualization_info(outputStream* st) {
391 #if defined(_AIX)
392 // more info about perfstat API see
393 // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.prftools/idprftools_perfstat_glob_partition.htm
394 int rc = 0;
395 perfstat_partition_total_t pinfo;
396 memset(&pinfo, 0, sizeof(perfstat_partition_total_t));
397 rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
398 if (rc != 1) {
399 return;
400 } else {
401 st->print_cr("Virtualization type : PowerVM");
402 }
403 // CPU information
404 perfstat_cpu_total_t cpuinfo;
405 memset(&cpuinfo, 0, sizeof(perfstat_cpu_total_t));
406 rc = perfstat_cpu_total(nullptr, &cpuinfo, sizeof(perfstat_cpu_total_t), 1);
407 if (rc != 1) {
408 return;
409 }
410
411 st->print_cr("Processor description : %s", cpuinfo.description);
412 st->print_cr("Processor speed : %llu Hz", cpuinfo.processorHZ);
413
414 st->print_cr("LPAR partition name : %s", pinfo.name);
415 st->print_cr("LPAR partition number : %u", pinfo.lpar_id);
416 st->print_cr("LPAR partition type : %s", pinfo.type.b.shared_enabled ? "shared" : "dedicated");
417 st->print_cr("LPAR mode : %s", pinfo.type.b.donate_enabled ? "donating" : pinfo.type.b.capped ? "capped" : "uncapped");
418 st->print_cr("LPAR partition group ID : %u", pinfo.group_id);
419 st->print_cr("LPAR shared pool ID : %u", pinfo.pool_id);
420
421 st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_capable ? "capable" : "not capable");
422 st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_enabled ? "on" : "off");
423 st->print_cr("AME (active memory expansion) : %s", pinfo.type.b.ame_enabled ? "on" : "off");
424
425 if (pinfo.type.b.ame_enabled) {
426 st->print_cr("AME true memory in bytes : %llu", pinfo.true_memory);
427 st->print_cr("AME expanded memory in bytes : %llu", pinfo.expanded_memory);
428 }
429
430 st->print_cr("SMT : %s", pinfo.type.b.smt_capable ? "capable" : "not capable");
431 st->print_cr("SMT : %s", pinfo.type.b.smt_enabled ? "on" : "off");
432 int ocpus = pinfo.online_cpus > 0 ? pinfo.online_cpus : 1;
433 st->print_cr("LPAR threads : %d", cpuinfo.ncpus/ocpus);
434 st->print_cr("LPAR online virtual cpus : %d", pinfo.online_cpus);
435 st->print_cr("LPAR logical cpus : %d", cpuinfo.ncpus);
436 st->print_cr("LPAR maximum virtual cpus : %u", pinfo.max_cpus);
437 st->print_cr("LPAR minimum virtual cpus : %u", pinfo.min_cpus);
438 st->print_cr("LPAR entitled capacity : %4.2f", (double) (pinfo.entitled_proc_capacity/100.0));
439 st->print_cr("LPAR online memory : %llu MB", pinfo.online_memory);
440 st->print_cr("LPAR maximum memory : %llu MB", pinfo.max_memory);
441 st->print_cr("LPAR minimum memory : %llu MB", pinfo.min_memory);
442 #else
443 const char* info_file = "/proc/ppc64/lparcfg";
444 const char* kw[] = { "system_type=", // qemu indicates PowerKVM
445 "partition_entitled_capacity=", // entitled processor capacity percentage
446 "partition_max_entitled_capacity=",
447 "capacity_weight=", // partition CPU weight
448 "partition_active_processors=",
449 "partition_potential_processors=",
450 "entitled_proc_capacity_available=",
451 "capped=", // 0 - uncapped, 1 - vcpus capped at entitled processor capacity percentage
452 "shared_processor_mode=", // (non)dedicated partition
453 "system_potential_processors=",
454 "pool=", // CPU-pool number
455 "pool_capacity=",
456 "NumLpars=", // on non-KVM machines, NumLpars is not found for full partition mode machines
457 nullptr };
458 if (!print_matching_lines_from_file(info_file, st, kw)) {
459 st->print_cr(" <%s Not Available>", info_file);
460 }
461 #endif
462 }
463
464 void VM_Version::print_features() {
465 tty->print_cr("Version: %s L1_data_cache_line_size=%d", cpu_info_string(), L1_data_cache_line_size());
466
467 if (Verbose) {
468 if (ContendedPaddingWidth > 0) {
469 tty->cr();
470 tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
471 }
472 }
473 }
474
475 void VM_Version::determine_features() {
476 #if defined(ABI_ELFv2)
477 const int code_size = (num_features + 1 /*blr*/) * BytesPerInstWord;
478 #else
479 const int code_size = (num_features + 1 /*blr*/ + 6 /* fd */) * BytesPerInstWord;
480 #endif
481 int features = 0;
482
483 // Allocate space for the code.
484 ResourceMark rm;
485 CodeBuffer cb("detect_cpu_features", code_size, 0);
486 MacroAssembler* a = new MacroAssembler(&cb);
487
488 // Must be set to true so we can generate the test code.
489 _features = VM_Version::all_features_m;
490
491 // Emit code.
492 void (*test)() = (void(*)())(void *)a->function_entry();
493 uint32_t *code = (uint32_t *)a->pc();
494 a->mfdscr(R0);
495 a->darn(R7);
496 a->brw(R5, R6);
497 a->blr();
498
499 uint32_t *code_end = (uint32_t *)a->pc();
500 a->flush();
501 _features = VM_Version::unknown_m;
502
503 // Print the detection code.
504 if (PrintAssembly) {
505 ttyLocker ttyl;
506 tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
507 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
508 }
509
510 // Execute code. Illegal instructions will be replaced by 0 in the signal handler.
511 VM_Version::_is_determine_features_test_running = true;
512 (*test)();
513 VM_Version::_is_determine_features_test_running = false;
514
515 // determine which instructions are legal.
516 int feature_cntr = 0;
517 if (code[feature_cntr++]) features |= mfdscr_m;
518 if (code[feature_cntr++]) features |= darn_m;
519 if (code[feature_cntr++]) features |= brw_m;
520
521 // Print the detection code.
522 if (PrintAssembly) {
523 ttyLocker ttyl;
524 tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " after execution:", p2i(code));
525 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
526 }
527
528 _features = features;
529
530 _L1_data_cache_line_size = VM_Version::get_dcache_line_size();
531 assert(_L1_data_cache_line_size >= DEFAULT_CACHE_LINE_SIZE,
532 "processors with smaller cache line size are no longer supported");
533 }
534
535 // Power 8: Configure Data Stream Control Register.
536 void VM_Version::config_dscr() {
537 // 7 InstWords for each call (function descriptor + blr instruction).
538 const int code_size = (2+2*7)*BytesPerInstWord;
539
540 // Allocate space for the code.
541 ResourceMark rm;
542 CodeBuffer cb("config_dscr", code_size, 0);
543 MacroAssembler* a = new MacroAssembler(&cb);
544
545 // Emit code.
546 uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->function_entry();
547 uint32_t *code = (uint32_t *)a->pc();
548 a->mfdscr(R3);
549 a->blr();
550
551 void (*set_dscr)(long) = (void(*)(long))(void *)a->function_entry();
552 a->mtdscr(R3);
553 a->blr();
554
555 uint32_t *code_end = (uint32_t *)a->pc();
556 a->flush();
557
558 // Print the detection code.
559 if (PrintAssembly) {
560 ttyLocker ttyl;
561 tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", p2i(code));
562 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
563 }
564
565 // Apply the configuration if needed.
566 _dscr_val = (*get_dscr)();
567 if (Verbose) {
568 tty->print_cr("dscr value was 0x%lx" , _dscr_val);
569 }
570 bool change_requested = false;
571 if (DSCR_PPC64 != (uintx)-1) {
572 _dscr_val = DSCR_PPC64;
573 change_requested = true;
574 }
575 if (DSCR_DPFD_PPC64 <= 7) {
576 uint64_t mask = 0x7;
577 if ((_dscr_val & mask) != DSCR_DPFD_PPC64) {
578 _dscr_val = (_dscr_val & ~mask) | (DSCR_DPFD_PPC64);
579 change_requested = true;
580 }
581 }
582 if (DSCR_URG_PPC64 <= 7) {
583 uint64_t mask = 0x7 << 6;
584 if ((_dscr_val & mask) != DSCR_DPFD_PPC64 << 6) {
585 _dscr_val = (_dscr_val & ~mask) | (DSCR_URG_PPC64 << 6);
586 change_requested = true;
587 }
588 }
589 if (change_requested) {
590 (*set_dscr)(_dscr_val);
591 if (Verbose) {
592 tty->print_cr("dscr was set to 0x%lx" , (*get_dscr)());
593 }
594 }
595 }
596
597 static uint64_t saved_features = 0;
598
599 void VM_Version::allow_all() {
600 saved_features = _features;
601 _features = all_features_m;
602 }
603
604 void VM_Version::revert() {
605 _features = saved_features;
606 }
607
608 // get cpu information.
609 void VM_Version::initialize_cpu_information(void) {
610 // do nothing if cpu info has been initialized
611 if (_initialized) {
612 return;
613 }
614
615 _no_of_cores = os::processor_count();
616 _no_of_threads = _no_of_cores;
617 _no_of_sockets = _no_of_cores;
618 os::snprintf_checked(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64);
619 os::snprintf_checked(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", cpu_info_string());
620 _initialized = true;
621 }