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   constexpr static bool supports_recursive_lightweight_locking() { return true; }
204 
205   static bool supports_on_spin_wait() { return UseZihintpause; }
206 
207   // RISCV64 supports fast class initialization checks
208   static bool supports_fast_class_init_checks() { return true; }
209 };
210 
211 #endif // CPU_RISCV_VM_VERSION_RISCV_HPP