# HG changeset patch # User lucy # Date 1619622588 -7200 # Wed Apr 28 17:09:48 2021 +0200 # Node ID 593dae459f1e6f06055da32bb55ae815c582057c # Parent 1ddf5ae17b35ba0e1623c6be2243d1afe367d4ae 8263260: [s390] Support latest hardware (z14 and z15) Reviewed-by: goetz, mdoerr diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -47,9 +47,25 @@ unsigned int VM_Version::_Dcache_lineSize = DEFAULT_CACHE_LINE_SIZE; unsigned int VM_Version::_Icache_lineSize = DEFAULT_CACHE_LINE_SIZE; -static const char* z_gen[] = {" ", "G1", "G2", "G3", "G4", "G5", "G6", "G7" }; -static const char* z_machine[] = {" ", "2064", "2084", "2094", "2097", "2817", " ", "2964" }; -static const char* z_name[] = {" ", "z900", "z990", "z9 EC", "z10 EC", "z196 EC", "ec12", "z13" }; +// The following list contains the (approximate) announcement/availability +// dates of the many System z generations in existence as of now. +// Information compiled from https://www.ibm.com/support/techdocs/atsmastr.nsf/WebIndex/TD105503 +// z900: 2000-10 +// z990: 2003-06 +// z9: 2005-09 +// z10: 2007-04 +// z10: 2008-02 +// z196: 2010-08 +// ec12: 2012-09 +// z13: 2015-03 +// z14: 2017-09 +// z15: 2019-09 + +static const char* z_gen[] = {" ", "G1", "G2", "G3", "G4", "G5", "G6", "G7", "G8", "G9" }; +static const char* z_machine[] = {" ", "2064", "2084", "2094", "2097", "2817", "2827", "2964", "3906", "8561" }; +static const char* z_name[] = {" ", "z900", "z990", "z9 EC", "z10 EC", "z196 EC", "ec12", "z13", "z14", "z15" }; +static const char* z_WDFM[] = {" ", "2006-06-30", "2008-06-30", "2010-06-30", "2012-06-30", "2014-06-30", "2016-12-31", "2019-06-30", "2021-06-30", "tbd" }; +static const char* z_EOS[] = {" ", "2014-12-31", "2014-12-31", "2017-10-31", "2019-12-31", "2021-12-31", "tbd", "tbd", "tbd", "tbd" }; void VM_Version::initialize() { determine_features(); // Get processor capabilities. @@ -262,64 +278,78 @@ // Furthermore, use one, and only one, separator space between features. // Multiple spaces are considered separate tokens, messing up everything. unsigned int ambiguity = 0; - _model_string = z_name[0]; + unsigned int model_ix = 0; + if (is_z15()) { + _features_string = "system-z g9-z15 ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr, instrext2, venh1, instrext3, VEnh2 )"; + model_ix = 9; + ambiguity++; + } + if (is_z14()) { + _features_string = "system-z g8-z14 ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr, instrext2, venh1)"; + model_ix = 8; + ambiguity++; + } if (is_z13()) { _features_string = "system-z, g7-z13, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr"; - _model_string = z_name[7]; + model_ix = 7; ambiguity++; } if (is_ec12()) { _features_string = "system-z, g6-ec12, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm"; - _model_string = z_name[6]; + model_ix = 6; ambiguity++; } if (is_z196()) { _features_string = "system-z, g5-z196, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update"; - _model_string = z_name[5]; + model_ix = 5; ambiguity++; } if (is_z10()) { _features_string = "system-z, g4-z10, ldisp_fast, extimm, pcrel_load/store, cmpb"; - _model_string = z_name[4]; + model_ix = 4; ambiguity++; } if (is_z9()) { - _features_string = "system-z, g3-z9, ldisp_fast, extimm, out-of-support as of 2016-04-01"; - _model_string = z_name[3]; + _features_string = "system-z, g3-z9, ldisp_fast, extimm"; + model_ix = 3; ambiguity++; } if (is_z990()) { - _features_string = "system-z, g2-z990, ldisp_fast, out-of-support as of 2014-07-01"; - _model_string = z_name[2]; + _features_string = "system-z, g2-z990, ldisp_fast"; + model_ix = 2; ambiguity++; } if (is_z900()) { - _features_string = "system-z, g1-z900, ldisp, out-of-support as of 2014-07-01"; - _model_string = z_name[1]; + _features_string = "system-z, g1-z900, ldisp"; + model_ix = 1; ambiguity++; } + char buf[512]; if (ambiguity == 0) { - _features_string = "z/Architecture (unknown generation)"; + strcpy(buf, "z/Architecture (unknown generation)"); + } else if (ambiguity == 1) { + _model_string = z_name[model_ix]; + jio_snprintf(buf, sizeof(buf), "%s, out-of-support_as_of_", _features_string, z_EOS[model_ix]); } else if (ambiguity > 1) { tty->print_cr("*** WARNING *** Ambiguous z/Architecture detection, ambiguity = %d", ambiguity); tty->print_cr(" oldest detected generation is %s", _features_string); - _features_string = "z/Architecture (ambiguous detection)"; + strcpy(buf, "z/Architecture (ambiguous detection)"); } + _features_string = os::strdup(buf); if (has_Crypto_AES()) { - char buf[256]; assert(strlen(_features_string) + 3*8 < sizeof(buf), "increase buffer size"); jio_snprintf(buf, sizeof(buf), "%s%s%s%s", _features_string, has_Crypto_AES128() ? ", aes128" : "", has_Crypto_AES192() ? ", aes192" : "", has_Crypto_AES256() ? ", aes256" : ""); + os::free((void *)_features_string); _features_string = os::strdup(buf); } if (has_Crypto_SHA()) { - char buf[256]; assert(strlen(_features_string) + 6 + 2*8 + 7 < sizeof(buf), "increase buffer size"); jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s", _features_string, @@ -327,7 +357,7 @@ has_Crypto_SHA256() ? ", sha256" : "", has_Crypto_SHA512() ? ", sha512" : "", has_Crypto_GHASH() ? ", ghash" : ""); - if (has_Crypto_AES()) { os::free((void *)_features_string); } + os::free((void *)_features_string); _features_string = os::strdup(buf); } } @@ -420,11 +450,14 @@ if (has_CryptoExt5() ) tty->print_cr("available: %s", "Crypto Extensions 5"); if (has_DFPPackedConversion() ) tty->print_cr("available: %s", "DFP Packed Conversions"); if (has_VectorFacility() ) tty->print_cr("available: %s", "Vector Facility"); - // test switches - if (has_TestFeature1Impl() ) tty->print_cr("available: %s", "TestFeature1Impl"); - if (has_TestFeature2Impl() ) tty->print_cr("available: %s", "TestFeature2Impl"); - if (has_TestFeature4Impl() ) tty->print_cr("available: %s", "TestFeature4Impl"); - if (has_TestFeature8Impl() ) tty->print_cr("available: %s", "TestFeature8Impl"); + // z14 + if (has_MiscInstrExt2() ) tty->print_cr("available: %s", "Miscelaneous Instruction Extensions 2"); + if (has_VectorEnhancements1() ) tty->print_cr("available: %s", "Vector Facility Enhancements 3"); + if (has_CryptoExt8() ) tty->print_cr("available: %s", "Crypto Extensions 8"); + // z15 + if (has_MiscInstrExt3() ) tty->print_cr("available: %s", "Miscelaneous Instruction Extensions 3"); + if (has_VectorEnhancements2() ) tty->print_cr("available: %s", "Vector Facility Enhancements 3"); + if (has_CryptoExt9() ) tty->print_cr("available: %s", "Crypto Extensions 9"); if (has_Crypto()) { tty->cr(); @@ -632,6 +665,26 @@ set_has_VectorFacility(); } +void VM_Version::set_features_z14(bool reset) { + reset_features(reset); + + set_features_z13(false); + set_has_MiscInstrExt2(); + set_has_VectorEnhancements1(); + has_VectorPackedDecimal(); + set_has_CryptoExt8(); +} + +void VM_Version::set_features_z15(bool reset) { + reset_features(reset); + + set_features_z14(false); + set_has_MiscInstrExt3(); + set_has_VectorEnhancements2(); + has_VectorPackedDecimalEnh(); + set_has_CryptoExt9(); +} + void VM_Version::set_features_from(const char* march) { bool err = false; bool prt = false; @@ -661,33 +714,10 @@ set_features_ec12(); } else if (!strcmp(march, "z13")) { set_features_z13(); - } else if (!strcmp(buf, "ztest")) { - assert(!has_TestFeaturesImpl(), "possible facility list flag conflict"); - if (strlen(march) > hdr_len) { - int itest = 0; - if ((strlen(march)-hdr_len) >= buf_len) err = true; - if (!err) { - memcpy(buf, &march[hdr_len], strlen(march)-hdr_len); - buf[strlen(march)-hdr_len] = '\00'; - for (size_t i = 0; !err && (i < strlen(buf)); i++) { - itest = itest*10 + buf[i]-'0'; - err = err || ((buf[i]-'0') < 0) || ((buf[i]-'0') > 9) || (itest > 15); - } - } - if (!err) { - prt = true; - if (itest & 0x01) { set_has_TestFeature1Impl(); } - if (itest & 0x02) { set_has_TestFeature2Impl(); } - if (itest & 0x04) { set_has_TestFeature4Impl(); } - if (itest & 0x08) { set_has_TestFeature8Impl(); } - } - } else { - prt = true; - set_has_TestFeature1Impl(); - set_has_TestFeature2Impl(); - set_has_TestFeature4Impl(); - set_has_TestFeature8Impl(); - } + } else if (!strcmp(march, "z14")) { + set_features_z14(); + } else if (!strcmp(march, "z15")) { + set_features_z15(); } else { err = true; } diff --git a/src/hotspot/cpu/s390/vm_version_s390.hpp b/src/hotspot/cpu/s390/vm_version_s390.hpp --- a/src/hotspot/cpu/s390/vm_version_s390.hpp +++ b/src/hotspot/cpu/s390/vm_version_s390.hpp @@ -33,21 +33,13 @@ class VM_Version: public Abstract_VM_Version { protected: -// The following list contains the (approximate) announcement/availability -// dates of the many System z generations in existence as of now which -// implement the z/Architecture. -// z900: 2000-10 -// z990: 2003-06 -// z9: 2005-09 -// z10: 2007-04 -// z10: 2008-02 -// z196: 2010-08 -// ec12: 2012-09 -// z13: 2015-03 -// // z/Architecture is the name of the 64-bit extension of the 31-bit s390 // architecture. // +// For information concerning the life span of the individual +// z/Architecture models, please check out the comments/tables +// in vm_version_s390.cpp + // ---------------------------------------------- // --- FeatureBitString Bits 0.. 63 (DW[0]) --- // ---------------------------------------------- @@ -94,11 +86,8 @@ #define LoadStoreConditional2Mask 0x0000000000000400UL // z13 #define CryptoExtension5Mask 0x0000000000000040UL // z13 // z13 end -// Feature-DW[0] starts to fill up. Use of these masks is risky. -#define TestFeature1ImplMask 0x0000000000000001UL -#define TestFeature2ImplMask 0x0000000000000002UL -#define TestFeature4ImplMask 0x0000000000000004UL -#define TestFeature8ImplMask 0x0000000000000008UL +#define MiscInstrExt2Mask 0x0000000000000020UL // z14 +#define MiscInstrExt3Mask 0x0000000000000004UL // z15 // ---------------------------------------------- // --- FeatureBitString Bits 64..127 (DW[1]) --- // ---------------------------------------------- @@ -116,6 +105,15 @@ // 23344455666778889 // 82604826048260482 #define VectorFacilityMask 0x4000000000000000UL // z13, not avail in VM guest mode! +#define ExecutionProtectionMask 0x2000000000000000UL // z14 +#define GuardedStorageMask 0x0400000000000000UL // z14 +#define VectorEnhancements1Mask 0x0100000000000000UL // z14 +#define VectorPackedDecimalMask 0x0200000000000000UL // z14 +#define CryptoExtension8Mask 0x0000200000000040UL // z14 +#define VectorEnhancements2Mask 0x0000080000000000UL // z15 +#define VectorPackedDecimalEnhMask 0x0000008000000000UL // z15 +#define CryptoExtension9Mask 0x0000001000000040UL // z15 +#define DeflateMask 0x0000010000000040UL // z15 enum { _max_cache_levels = 8, // As limited by ECAG instruction. @@ -143,7 +141,7 @@ unsigned int levelIndication, unsigned int typeIndication); - // Setting features via march=z900|z990|z9|z10|z196|ec12|z13|ztest commandline option. + // Setting features via march=z900|z990|z9|z10|z196|ec12|z13|z14|z15 commandline option. static void reset_features(bool reset); static void set_features_z900(bool reset = true); static void set_features_z990(bool reset = true); @@ -152,8 +150,17 @@ static void set_features_z196(bool reset = true); static void set_features_ec12(bool reset = true); static void set_features_z13(bool reset = true); + static void set_features_z14(bool reset = true); + static void set_features_z15(bool reset = true); static void set_features_from(const char* march); + // Get information about cache line sizes. + // As of now and the foreseeable future, line size of all levels will be the same and 256. + static unsigned int Dcache_lineSize(unsigned int level = 0) { return _Dcache_lineSize; } + static unsigned int Icache_lineSize(unsigned int level = 0) { return _Icache_lineSize; } + + public: + // Get the CPU type from feature bit settings. static bool is_z900() { return has_long_displacement() && !has_long_displacement_fast(); } static bool is_z990() { return has_long_displacement_fast() && !has_extended_immediate(); } @@ -161,14 +168,9 @@ static bool is_z10() { return has_GnrlInstrExtensions() && !has_DistinctOpnds(); } static bool is_z196() { return has_DistinctOpnds() && !has_MiscInstrExt(); } static bool is_ec12() { return has_MiscInstrExt() && !has_CryptoExt5(); } - static bool is_z13() { return has_CryptoExt5();} - - // Get information about cache line sizes. - // As of now and the foreseeable future, line size of all levels will be the same and 256. - static unsigned int Dcache_lineSize(unsigned int level = 0) { return _Dcache_lineSize; } - static unsigned int Icache_lineSize(unsigned int level = 0) { return _Icache_lineSize; } - - public: + static bool is_z13() { return has_CryptoExt5() && !has_MiscInstrExt2();} + static bool is_z14() { return has_MiscInstrExt2() && !has_MiscInstrExt3();} + static bool is_z15() { return has_MiscInstrExt3();} // Need to use nested class with unscoped enum. // C++11 declaration "enum class Cipher { ... } is not supported. @@ -399,6 +401,8 @@ static bool has_DFPZonedConversion() { return (_features[0] & DFPZonedConversionMask) == DFPZonedConversionMask; } static bool has_DFPPackedConversion() { return (_features[1] & DFPPackedConversionMask) == DFPPackedConversionMask; } static bool has_MiscInstrExt() { return (_features[0] & MiscInstrExtMask) == MiscInstrExtMask; } + static bool has_MiscInstrExt2() { return (_features[0] & MiscInstrExt2Mask) == MiscInstrExt2Mask; } + static bool has_MiscInstrExt3() { return (_features[0] & MiscInstrExt3Mask) == MiscInstrExt3Mask; } static bool has_ExecutionHint() { return (_features[0] & ExecutionHintMask) == ExecutionHintMask; } static bool has_LoadAndTrap() { return (_features[0] & LoadAndTrapMask) == LoadAndTrapMask; } static bool has_ProcessorAssist() { return (_features[0] & ProcessorAssistMask) == ProcessorAssistMask; } @@ -407,15 +411,14 @@ static bool has_TxMem() { return ((_features[1] & TransactionalExecutionMask) == TransactionalExecutionMask) && ((_features[0] & ConstrainedTxExecutionMask) == ConstrainedTxExecutionMask); } static bool has_CryptoExt5() { return (_features[0] & CryptoExtension5Mask) == CryptoExtension5Mask; } + static bool has_CryptoExt8() { return (_features[2] & CryptoExtension8Mask) == CryptoExtension8Mask; } + static bool has_CryptoExt9() { return (_features[2] & CryptoExtension9Mask) == CryptoExtension9Mask; } static bool has_LoadStoreConditional2() { return (_features[0] & LoadStoreConditional2Mask) == LoadStoreConditional2Mask; } static bool has_VectorFacility() { return (_features[2] & VectorFacilityMask) == VectorFacilityMask; } - - static bool has_TestFeatureImpl() { return (_features[0] & TestFeature1ImplMask) == TestFeature1ImplMask; } - static bool has_TestFeature1Impl() { return (_features[0] & TestFeature1ImplMask) == TestFeature1ImplMask; } - static bool has_TestFeature2Impl() { return (_features[0] & TestFeature2ImplMask) == TestFeature2ImplMask; } - static bool has_TestFeature4Impl() { return (_features[0] & TestFeature4ImplMask) == TestFeature4ImplMask; } - static bool has_TestFeature8Impl() { return (_features[0] & TestFeature8ImplMask) == TestFeature8ImplMask; } - static bool has_TestFeaturesImpl() { return has_TestFeature1Impl() || has_TestFeature2Impl() || has_TestFeature4Impl() || has_TestFeature8Impl(); } + static bool has_VectorEnhancements1() { return (_features[2] & VectorEnhancements1Mask) == VectorEnhancements1Mask; } + static bool has_VectorEnhancements2() { return (_features[2] & VectorEnhancements2Mask) == VectorEnhancements2Mask; } + static bool has_VectorPackedDecimal() { return (_features[2] & VectorPackedDecimalMask) == VectorPackedDecimalMask; } + static bool has_VectorPackedDecimalEnh() { return (_features[2] & VectorPackedDecimalEnhMask) == VectorPackedDecimalEnhMask; } // Crypto features query functions. static bool has_Crypto_AES128() { return has_Crypto() && test_feature_bit(&_cipher_features[0], Cipher::_AES128, Cipher::_featureBits); } @@ -430,10 +433,6 @@ static bool has_Crypto_SHA() { return has_Crypto_SHA1() || has_Crypto_SHA256() || has_Crypto_SHA512() || has_Crypto_GHASH(); } // CPU feature setters (to force model-specific behaviour). Test/debugging only. - static void set_has_TestFeature1Impl() { _features[0] |= TestFeature1ImplMask; } - static void set_has_TestFeature2Impl() { _features[0] |= TestFeature2ImplMask; } - static void set_has_TestFeature4Impl() { _features[0] |= TestFeature4ImplMask; } - static void set_has_TestFeature8Impl() { _features[0] |= TestFeature8ImplMask; } static void set_has_DecimalFloatingPoint() { _features[0] |= DecimalFloatingPointMask; } static void set_has_FPSupportEnhancements() { _features[0] |= FPSupportEnhancementsMask; } static void set_has_ExecuteExtensions() { _features[0] |= ExecuteExtensionsMask; } @@ -468,6 +467,8 @@ static void set_has_DistinctOpnds() { _features[0] |= DistinctOpndsMask; } static void set_has_FPExtensions() { _features[0] |= FPExtensionsMask; } static void set_has_MiscInstrExt() { _features[0] |= MiscInstrExtMask; } + static void set_has_MiscInstrExt2() { _features[0] |= MiscInstrExt2Mask; } + static void set_has_MiscInstrExt3() { _features[0] |= MiscInstrExt3Mask; } static void set_has_ProcessorAssist() { _features[0] |= ProcessorAssistMask; } static void set_has_InterlockedAccessV2() { _features[0] |= InterlockedAccess2Mask; } static void set_has_LoadAndALUAtomicV2() { _features[0] |= InterlockedAccess2Mask; } @@ -476,7 +477,13 @@ static void set_has_CryptoExt4() { _features[1] |= CryptoExtension4Mask; } static void set_has_LoadStoreConditional2() { _features[0] |= LoadStoreConditional2Mask; } static void set_has_CryptoExt5() { _features[0] |= CryptoExtension5Mask; } + static void set_has_CryptoExt8() { _features[2] |= CryptoExtension8Mask; } + static void set_has_CryptoExt9() { _features[2] |= CryptoExtension9Mask; } static void set_has_VectorFacility() { _features[2] |= VectorFacilityMask; } + static void set_has_VectorEnhancements1() { _features[2] |= VectorEnhancements1Mask; } + static void set_has_VectorEnhancements2() { _features[2] |= VectorEnhancements2Mask; } + static void set_has_VectorPackedDecimal() { _features[2] |= VectorPackedDecimalMask; } + static void set_has_VectorPackedDecimalEnh() { _features[2] |= VectorPackedDecimalEnhMask; } static void reset_has_VectorFacility() { _features[2] &= ~VectorFacilityMask; }