1 /* 2 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. 4 * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. 5 * Copyright (c) 2023, Rivos Inc. All rights reserved. 6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7 * 8 * This code is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 only, as 10 * published by the Free Software Foundation. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 * 26 */ 27 28 #ifndef CPU_RISCV_VM_VERSION_RISCV_HPP 29 #define CPU_RISCV_VM_VERSION_RISCV_HPP 30 31 #include "runtime/abstract_vm_version.hpp" 32 #include "runtime/arguments.hpp" 33 #include "runtime/globals_extension.hpp" 34 #include "utilities/globalDefinitions.hpp" 35 #include "utilities/growableArray.hpp" 36 #include "utilities/sizes.hpp" 37 38 class RiscvHwprobe; 39 40 class VM_Version : public Abstract_VM_Version { 41 friend RiscvHwprobe; 42 private: 43 class RVFeatureValue { 44 const char* const _pretty; 45 const bool _feature_string; 46 const uint64_t _feature_bit; 47 bool _enabled; 48 int64_t _value; 49 public: 50 RVFeatureValue(const char* pretty, int bit_num, bool fstring) : 51 _pretty(pretty), _feature_string(fstring), _feature_bit(nth_bit(bit_num)), 52 _enabled(false), _value(-1) { 53 } 54 void enable_feature(int64_t value = 0) { 55 _enabled = true; 56 _value = value; 57 } 58 void disable_feature() { 59 _enabled = false; 60 _value = -1; 61 } 62 const char* const pretty() { return _pretty; } 63 const uint64_t feature_bit() { return _feature_bit; } 64 const bool feature_string() { return _feature_string; } 65 bool enabled() { return _enabled; } 66 int64_t value() { return _value; } 67 virtual void update_flag() = 0; 68 }; 69 70 #define UPDATE_DEFAULT(flag) \ 71 void update_flag() { \ 72 assert(enabled(), "Must be."); \ 73 if (FLAG_IS_DEFAULT(flag)) { \ 74 FLAG_SET_DEFAULT(flag, true); \ 75 } else { \ 76 /* Sync CPU features with flags */ \ 77 if (!flag) { \ 78 disable_feature(); \ 79 } \ 80 } \ 81 } \ 82 83 #define NO_UPDATE_DEFAULT \ 84 void update_flag() {} \ 85 86 // Frozen standard extensions 87 // I RV64I 88 // M Integer Multiplication and Division 89 // A Atomic Instructions 90 // F Single-Precision Floating-Point 91 // D Single-Precision Floating-Point 92 // (G = M + A + F + D) 93 // Q Quad-Precision Floating-Point 94 // C Compressed Instructions 95 // H Hypervisor 96 // 97 // Others, open and non-standard 98 // V Vector 99 // 100 // Cache Management Operations 101 // Zicbom Cache Block Management Operations 102 // Zicboz Cache Block Zero Operations 103 // Zicbop Cache Block Prefetch Operations 104 // 105 // Bit-manipulation 106 // Zba Address generation instructions 107 // Zbb Basic bit-manipulation 108 // Zbc Carry-less multiplication 109 // Zbs Single-bit instructions 110 // 111 // Zicsr Control and Status Register (CSR) Instructions 112 // Zifencei Instruction-Fetch Fence 113 // Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space. 114 // Zihintpause Pause instruction HINT 115 // 116 // Other features and settings 117 // mvendorid Manufactory JEDEC id encoded, ISA vol 2 3.1.2.. 118 // marchid Id for microarch. Mvendorid plus marchid uniquely identify the microarch. 119 // mimpid A unique encoding of the version of the processor implementation. 120 // unaligned_access Unaligned memory accesses (unknown, unspported, emulated, slow, firmware, fast) 121 // satp mode SATP bits (number of virtual addr bits) mbare, sv39, sv48, sv57, sv64 122 123 #define RV_NO_FLAG_BIT (BitsPerWord+1) // nth_bit will return 0 on values larger than BitsPerWord 124 125 // declaration name , extension name, bit pos ,in str, mapped flag) 126 #define RV_FEATURE_FLAGS(decl) \ 127 decl(ext_I , "i" , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \ 128 decl(ext_M , "m" , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \ 129 decl(ext_A , "a" , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \ 130 decl(ext_F , "f" , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \ 131 decl(ext_D , "d" , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \ 132 decl(ext_C , "c" , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \ 133 decl(ext_Q , "q" , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \ 134 decl(ext_H , "h" , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \ 135 decl(ext_V , "v" , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \ 136 decl(ext_Zicbom , "Zicbom" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \ 137 decl(ext_Zicboz , "Zicboz" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \ 138 decl(ext_Zicbop , "Zicbop" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \ 139 decl(ext_Zba , "Zba" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \ 140 decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \ 141 decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ 142 decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \ 143 decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ 144 decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ 145 decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \ 146 decl(ext_Zihintpause , "Zihintpause" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \ 147 decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 148 decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 149 decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 150 decl(unaligned_access, "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 151 decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 152 153 #define DECLARE_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \ 154 struct NAME##RVFeatureValue : public RVFeatureValue { \ 155 NAME##RVFeatureValue(const char* pretty, int bit, bool fstring) : \ 156 RVFeatureValue(pretty, bit, fstring) {} \ 157 FLAGF; \ 158 }; \ 159 static NAME##RVFeatureValue NAME; \ 160 161 RV_FEATURE_FLAGS(DECLARE_RV_FEATURE) 162 #undef DECLARE_RV_FEATURE 163 164 // VM modes (satp.mode) privileged ISA 1.10 165 enum VM_MODE : int { 166 VM_NOTSET = -1, 167 VM_MBARE = 0, 168 VM_SV39 = 39, 169 VM_SV48 = 48, 170 VM_SV57 = 57, 171 VM_SV64 = 64 172 }; 173 174 static VM_MODE parse_satp_mode(const char* vm_mode); 175 176 // Values from riscv_hwprobe() 177 enum UNALIGNED_ACCESS : int { 178 MISALIGNED_UNKNOWN = 0, 179 MISALIGNED_EMULATED = 1, 180 MISALIGNED_SLOW = 2, 181 MISALIGNED_FAST = 3, 182 MISALIGNED_UNSUPPORTED = 4 183 }; 184 185 // Null terminated list 186 static RVFeatureValue* _feature_list[]; 187 188 // Enables features in _feature_list 189 static void setup_cpu_available_features(); 190 // Helper for specific queries 191 static void os_aux_features(); 192 static char* os_uarch_additional_features(); 193 static void vendor_features(); 194 // Vendors specific features 195 static void rivos_features(); 196 197 // Determine vector length iff ext_V/UseRVV 198 static uint32_t cpu_vector_length(); 199 static uint32_t _initial_vector_length; 200 201 #ifdef COMPILER2 202 static void c2_initialize(); 203 #endif // COMPILER2 204 205 public: 206 // Initialization 207 static void initialize(); 208 static void initialize_cpu_information(); 209 210 constexpr static bool supports_stack_watermark_barrier() { return true; } 211 212 constexpr static bool supports_recursive_lightweight_locking() { return true; } 213 214 static bool supports_on_spin_wait() { return UseZihintpause; } 215 216 // RISCV64 supports fast class initialization checks 217 static bool supports_fast_class_init_checks() { return true; } 218 }; 219 220 #endif // CPU_RISCV_VM_VERSION_RISCV_HPP