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