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 }