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