|
2 | 2 | * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
3 | 3 | * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
4 | 4 | * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
| 5 | + * Copyright (c) 2023, Rivos Inc. All rights reserved. |
5 | 6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
6 | 7 | *
|
7 | 8 | * This code is free software; you can redistribute it and/or modify it
|
|
30 | 31 | #include "runtime/abstract_vm_version.hpp"
|
31 | 32 | #include "runtime/arguments.hpp"
|
32 | 33 | #include "runtime/globals_extension.hpp"
|
| 34 | +#include "utilities/globalDefinitions.hpp" |
| 35 | +#include "utilities/growableArray.hpp" |
33 | 36 | #include "utilities/sizes.hpp"
|
34 | 37 |
|
| 38 | +class RiscvHwprobe; |
| 39 | + |
35 | 40 | class VM_Version : public Abstract_VM_Version {
|
36 |
| -#ifdef COMPILER2 |
37 |
| -private: |
38 |
| - static void c2_initialize(); |
39 |
| -#endif // COMPILER2 |
| 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 | + }; |
40 | 65 |
|
41 |
| -// VM modes (satp.mode) privileged ISA 1.10 |
42 |
| -enum VM_MODE { |
43 |
| - VM_MBARE = 0, |
44 |
| - VM_SV39 = 8, |
45 |
| - VM_SV48 = 9, |
46 |
| - VM_SV57 = 10, |
47 |
| - VM_SV64 = 11 |
48 |
| -}; |
| 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 | + }; |
49 | 175 |
|
50 |
| -protected: |
51 |
| - static const char* _uarch; |
52 |
| - static const char* _vm_mode; |
| 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(); |
53 | 190 | static uint32_t _initial_vector_length;
|
54 |
| - static void get_os_cpu_info(); |
55 |
| - static uint32_t get_current_vector_length(); |
56 |
| - static VM_MODE get_satp_mode(); |
57 | 191 |
|
58 |
| -public: |
| 192 | +#ifdef COMPILER2 |
| 193 | + static void c2_initialize(); |
| 194 | +#endif // COMPILER2 |
| 195 | + |
| 196 | + public: |
59 | 197 | // Initialization
|
60 | 198 | static void initialize();
|
| 199 | + static void initialize_cpu_information(); |
61 | 200 |
|
62 | 201 | constexpr static bool supports_stack_watermark_barrier() { return true; }
|
63 | 202 |
|
64 | 203 | static bool supports_on_spin_wait() { return UseZihintpause; }
|
65 |
| - |
66 |
| - enum Feature_Flag { |
67 |
| -#define CPU_FEATURE_FLAGS(decl) \ |
68 |
| - decl(I, "i", 8) \ |
69 |
| - decl(M, "m", 12) \ |
70 |
| - decl(A, "a", 0) \ |
71 |
| - decl(F, "f", 5) \ |
72 |
| - decl(D, "d", 3) \ |
73 |
| - decl(C, "c", 2) \ |
74 |
| - decl(V, "v", 21) |
75 |
| - |
76 |
| -#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit), |
77 |
| - CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG) |
78 |
| -#undef DECLARE_CPU_FEATURE_FLAG |
79 |
| - }; |
80 |
| - |
81 |
| - static void initialize_cpu_information(void); |
82 | 204 | };
|
83 | 205 |
|
84 | 206 | #endif // CPU_RISCV_VM_VERSION_RISCV_HPP
|
0 commit comments