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 const char* const pretty() { return _pretty; } 59 const uint64_t feature_bit() { return _feature_bit; } 60 const bool feature_string() { return _feature_string; } 61 bool enabled() { return _enabled; } 62 int64_t value() { return _value; } 63 virtual void update_flag() = 0; 64 }; 65 66 #define UPDATE_DEFAULT(flag) \ 67 void update_flag() { \ 68 assert(enabled(), "Must be."); \ 69 if (FLAG_IS_DEFAULT(flag)) { \ 70 FLAG_SET_DEFAULT(flag, true); \ 71 } \ 72 } \ 73 74 #define NO_UPDATE_DEFAULT \ 75 void update_flag() {} \ 76 77 // Frozen standard extensions 78 // I RV64I 79 // M Integer Multiplication and Division 80 // A Atomic Instructions 81 // F Single-Precision Floating-Point 82 // D Single-Precision Floating-Point 83 // (G = M + A + F + D) 84 // Q Quad-Precision Floating-Point 85 // C Compressed Instructions 86 // H Hypervisor 87 // 88 // Others, open and non-standard 89 // V Vector 90 // 91 // Cache Management Operations 92 // Zicbom Cache Block Management Operations 93 // Zicboz Cache Block Zero Operations 94 // Zicbop Cache Block Prefetch Operations 95 // 96 // Bit-manipulation 97 // Zba Address generation instructions 98 // Zbb Basic bit-manipulation 99 // Zbc Carry-less multiplication 100 // Zbs Single-bit instructions 101 // 102 // Zicsr Control and Status Register (CSR) Instructions 103 // Zifencei Instruction-Fetch Fence 104 // Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space. 105 // Zihintpause Pause instruction HINT 106 // 107 // Other features and settings 108 // mvendorid Manufactory JEDEC id encoded, ISA vol 2 3.1.2.. 109 // marchid Id for microarch. Mvendorid plus marchid uniquely identify the microarch. 110 // mimpid A unique encoding of the version of the processor implementation. 111 // unaligned_access Unaligned memory accesses (unknown, unspported, emulated, slow, firmware, fast) 112 // satp mode SATP bits (number of virtual addr bits) mbare, sv39, sv48, sv57, sv64 113 114 #define RV_NO_FLAG_BIT (BitsPerWord+1) // nth_bit will return 0 on values larger than BitsPerWord 115 116 // declaration name , extension name, bit pos ,in str, mapped flag) 117 #define RV_FEATURE_FLAGS(decl) \ 118 decl(ext_I , "i" , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \ 119 decl(ext_M , "m" , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \ 120 decl(ext_A , "a" , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \ 121 decl(ext_F , "f" , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \ 122 decl(ext_D , "d" , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \ 123 decl(ext_C , "c" , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \ 124 decl(ext_Q , "q" , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \ 125 decl(ext_H , "h" , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \ 126 decl(ext_V , "v" , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \ 127 decl(ext_Zicbom , "Zicbom" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \ 128 decl(ext_Zicboz , "Zicboz" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \ 129 decl(ext_Zicbop , "Zicbop" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \ 130 decl(ext_Zba , "Zba" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \ 131 decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \ 132 decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ 133 decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \ 134 decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ 135 decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ 136 decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \ 137 decl(ext_Zihintpause , "Zihintpause" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \ 138 decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 139 decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 140 decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 141 decl(unaligned_access, "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 142 decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ 143 144 #define DECLARE_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \ 145 struct NAME##RVFeatureValue : public RVFeatureValue { \ 146 NAME##RVFeatureValue(const char* pretty, int bit, bool fstring) : \ 147 RVFeatureValue(pretty, bit, fstring) {} \ 148 FLAGF; \ 149 }; \ 150 static NAME##RVFeatureValue NAME; \ 151 152 RV_FEATURE_FLAGS(DECLARE_RV_FEATURE) 153 #undef DECLARE_RV_FEATURE 154 155 // VM modes (satp.mode) privileged ISA 1.10 156 enum VM_MODE : int { 157 VM_NOTSET = -1, 158 VM_MBARE = 0, 159 VM_SV39 = 39, 160 VM_SV48 = 48, 161 VM_SV57 = 57, 162 VM_SV64 = 64 163 }; 164 165 static VM_MODE parse_satp_mode(const char* vm_mode); 166 167 // Values from riscv_hwprobe() 168 enum UNALIGNED_ACCESS : int { 169 MISALIGNED_UNKNOWN = 0, 170 MISALIGNED_EMULATED = 1, 171 MISALIGNED_SLOW = 2, 172 MISALIGNED_FAST = 3, 173 MISALIGNED_UNSUPPORTED = 4 174 }; 175 176 // Null terminated list 177 static RVFeatureValue* _feature_list[]; 178 179 // Enables features in _feature_list 180 static void setup_cpu_available_features(); 181 // Helper for specific queries 182 static void os_aux_features(); 183 static char* os_uarch_additional_features(); 184 static void vendor_features(); 185 // Vendors specific features 186 static void rivos_features(); 187 188 // Determine vector length iff ext_V/UseRVV 189 static uint32_t cpu_vector_length(); 190 static uint32_t _initial_vector_length; 191 192 #ifdef COMPILER2 193 static void c2_initialize(); 194 #endif // COMPILER2 195 196 public: 197 // Initialization 198 static void initialize(); 199 static void initialize_cpu_information(); 200 201 constexpr static bool supports_stack_watermark_barrier() { return true; } 202 203 static bool supports_on_spin_wait() { return UseZihintpause; } 204 205 // RISCV64 supports fast class initialization checks 206 static bool supports_fast_class_init_checks() { return true; } 207 }; 208 209 #endif // CPU_RISCV_VM_VERSION_RISCV_HPP