1 //=== cpu_model/riscv.c - Update RISC-V Feature Bits Structure -*- C -*-======// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "cpu_model.h" 10 11 #define RISCV_FEATURE_BITS_LENGTH 2 12 struct { 13 unsigned length; 14 unsigned long long features[RISCV_FEATURE_BITS_LENGTH]; 15 } __riscv_feature_bits __attribute__((visibility("hidden"), nocommon)); 16 17 #define RISCV_VENDOR_FEATURE_BITS_LENGTH 1 18 struct { 19 unsigned length; 20 unsigned long long features[RISCV_VENDOR_FEATURE_BITS_LENGTH]; 21 } __riscv_vendor_feature_bits __attribute__((visibility("hidden"), nocommon)); 22 23 struct { 24 unsigned mvendorid; 25 unsigned long long marchid; 26 unsigned long long mimpid; 27 } __riscv_cpu_model __attribute__((visibility("hidden"), nocommon)); 28 29 // NOTE: Should sync-up with RISCVFeatures.td 30 // TODO: Maybe generate a header from tablegen then include it. 31 #define A_GROUPID 0 32 #define A_BITMASK (1ULL << 0) 33 #define C_GROUPID 0 34 #define C_BITMASK (1ULL << 2) 35 #define D_GROUPID 0 36 #define D_BITMASK (1ULL << 3) 37 #define F_GROUPID 0 38 #define F_BITMASK (1ULL << 5) 39 #define I_GROUPID 0 40 #define I_BITMASK (1ULL << 8) 41 #define M_GROUPID 0 42 #define M_BITMASK (1ULL << 12) 43 #define V_GROUPID 0 44 #define V_BITMASK (1ULL << 21) 45 #define ZACAS_GROUPID 0 46 #define ZACAS_BITMASK (1ULL << 26) 47 #define ZBA_GROUPID 0 48 #define ZBA_BITMASK (1ULL << 27) 49 #define ZBB_GROUPID 0 50 #define ZBB_BITMASK (1ULL << 28) 51 #define ZBC_GROUPID 0 52 #define ZBC_BITMASK (1ULL << 29) 53 #define ZBKB_GROUPID 0 54 #define ZBKB_BITMASK (1ULL << 30) 55 #define ZBKC_GROUPID 0 56 #define ZBKC_BITMASK (1ULL << 31) 57 #define ZBKX_GROUPID 0 58 #define ZBKX_BITMASK (1ULL << 32) 59 #define ZBS_GROUPID 0 60 #define ZBS_BITMASK (1ULL << 33) 61 #define ZFA_GROUPID 0 62 #define ZFA_BITMASK (1ULL << 34) 63 #define ZFH_GROUPID 0 64 #define ZFH_BITMASK (1ULL << 35) 65 #define ZFHMIN_GROUPID 0 66 #define ZFHMIN_BITMASK (1ULL << 36) 67 #define ZICBOZ_GROUPID 0 68 #define ZICBOZ_BITMASK (1ULL << 37) 69 #define ZICOND_GROUPID 0 70 #define ZICOND_BITMASK (1ULL << 38) 71 #define ZIHINTNTL_GROUPID 0 72 #define ZIHINTNTL_BITMASK (1ULL << 39) 73 #define ZIHINTPAUSE_GROUPID 0 74 #define ZIHINTPAUSE_BITMASK (1ULL << 40) 75 #define ZKND_GROUPID 0 76 #define ZKND_BITMASK (1ULL << 41) 77 #define ZKNE_GROUPID 0 78 #define ZKNE_BITMASK (1ULL << 42) 79 #define ZKNH_GROUPID 0 80 #define ZKNH_BITMASK (1ULL << 43) 81 #define ZKSED_GROUPID 0 82 #define ZKSED_BITMASK (1ULL << 44) 83 #define ZKSH_GROUPID 0 84 #define ZKSH_BITMASK (1ULL << 45) 85 #define ZKT_GROUPID 0 86 #define ZKT_BITMASK (1ULL << 46) 87 #define ZTSO_GROUPID 0 88 #define ZTSO_BITMASK (1ULL << 47) 89 #define ZVBB_GROUPID 0 90 #define ZVBB_BITMASK (1ULL << 48) 91 #define ZVBC_GROUPID 0 92 #define ZVBC_BITMASK (1ULL << 49) 93 #define ZVFH_GROUPID 0 94 #define ZVFH_BITMASK (1ULL << 50) 95 #define ZVFHMIN_GROUPID 0 96 #define ZVFHMIN_BITMASK (1ULL << 51) 97 #define ZVKB_GROUPID 0 98 #define ZVKB_BITMASK (1ULL << 52) 99 #define ZVKG_GROUPID 0 100 #define ZVKG_BITMASK (1ULL << 53) 101 #define ZVKNED_GROUPID 0 102 #define ZVKNED_BITMASK (1ULL << 54) 103 #define ZVKNHA_GROUPID 0 104 #define ZVKNHA_BITMASK (1ULL << 55) 105 #define ZVKNHB_GROUPID 0 106 #define ZVKNHB_BITMASK (1ULL << 56) 107 #define ZVKSED_GROUPID 0 108 #define ZVKSED_BITMASK (1ULL << 57) 109 #define ZVKSH_GROUPID 0 110 #define ZVKSH_BITMASK (1ULL << 58) 111 #define ZVKT_GROUPID 0 112 #define ZVKT_BITMASK (1ULL << 59) 113 #define ZVE32X_GROUPID 0 114 #define ZVE32X_BITMASK (1ULL << 60) 115 #define ZVE32F_GROUPID 0 116 #define ZVE32F_BITMASK (1ULL << 61) 117 #define ZVE64X_GROUPID 0 118 #define ZVE64X_BITMASK (1ULL << 62) 119 #define ZVE64F_GROUPID 0 120 #define ZVE64F_BITMASK (1ULL << 63) 121 #define ZVE64D_GROUPID 1 122 #define ZVE64D_BITMASK (1ULL << 0) 123 #define ZIMOP_GROUPID 1 124 #define ZIMOP_BITMASK (1ULL << 1) 125 #define ZCA_GROUPID 1 126 #define ZCA_BITMASK (1ULL << 2) 127 #define ZCB_GROUPID 1 128 #define ZCB_BITMASK (1ULL << 3) 129 #define ZCD_GROUPID 1 130 #define ZCD_BITMASK (1ULL << 4) 131 #define ZCF_GROUPID 1 132 #define ZCF_BITMASK (1ULL << 5) 133 #define ZCMOP_GROUPID 1 134 #define ZCMOP_BITMASK (1ULL << 6) 135 #define ZAWRS_GROUPID 1 136 #define ZAWRS_BITMASK (1ULL << 7) 137 138 #if defined(__linux__) 139 140 // The RISC-V hwprobe interface is documented here: 141 // <https://docs.kernel.org/arch/riscv/hwprobe.html>. 142 143 static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3, 144 long arg4, long arg5) { 145 register long a7 __asm__("a7") = number; 146 register long a0 __asm__("a0") = arg1; 147 register long a1 __asm__("a1") = arg2; 148 register long a2 __asm__("a2") = arg3; 149 register long a3 __asm__("a3") = arg4; 150 register long a4 __asm__("a4") = arg5; 151 __asm__ __volatile__("ecall\n\t" 152 : "=r"(a0) 153 : "r"(a7), "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4) 154 : "memory"); 155 return a0; 156 } 157 158 #define RISCV_HWPROBE_KEY_MVENDORID 0 159 #define RISCV_HWPROBE_KEY_MARCHID 1 160 #define RISCV_HWPROBE_KEY_MIMPID 2 161 #define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3 162 #define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1ULL << 0) 163 #define RISCV_HWPROBE_KEY_IMA_EXT_0 4 164 #define RISCV_HWPROBE_IMA_FD (1ULL << 0) 165 #define RISCV_HWPROBE_IMA_C (1ULL << 1) 166 #define RISCV_HWPROBE_IMA_V (1ULL << 2) 167 #define RISCV_HWPROBE_EXT_ZBA (1ULL << 3) 168 #define RISCV_HWPROBE_EXT_ZBB (1ULL << 4) 169 #define RISCV_HWPROBE_EXT_ZBS (1ULL << 5) 170 #define RISCV_HWPROBE_EXT_ZICBOZ (1ULL << 6) 171 #define RISCV_HWPROBE_EXT_ZBC (1ULL << 7) 172 #define RISCV_HWPROBE_EXT_ZBKB (1ULL << 8) 173 #define RISCV_HWPROBE_EXT_ZBKC (1ULL << 9) 174 #define RISCV_HWPROBE_EXT_ZBKX (1ULL << 10) 175 #define RISCV_HWPROBE_EXT_ZKND (1ULL << 11) 176 #define RISCV_HWPROBE_EXT_ZKNE (1ULL << 12) 177 #define RISCV_HWPROBE_EXT_ZKNH (1ULL << 13) 178 #define RISCV_HWPROBE_EXT_ZKSED (1ULL << 14) 179 #define RISCV_HWPROBE_EXT_ZKSH (1ULL << 15) 180 #define RISCV_HWPROBE_EXT_ZKT (1ULL << 16) 181 #define RISCV_HWPROBE_EXT_ZVBB (1ULL << 17) 182 #define RISCV_HWPROBE_EXT_ZVBC (1ULL << 18) 183 #define RISCV_HWPROBE_EXT_ZVKB (1ULL << 19) 184 #define RISCV_HWPROBE_EXT_ZVKG (1ULL << 20) 185 #define RISCV_HWPROBE_EXT_ZVKNED (1ULL << 21) 186 #define RISCV_HWPROBE_EXT_ZVKNHA (1ULL << 22) 187 #define RISCV_HWPROBE_EXT_ZVKNHB (1ULL << 23) 188 #define RISCV_HWPROBE_EXT_ZVKSED (1ULL << 24) 189 #define RISCV_HWPROBE_EXT_ZVKSH (1ULL << 25) 190 #define RISCV_HWPROBE_EXT_ZVKT (1ULL << 26) 191 #define RISCV_HWPROBE_EXT_ZFH (1ULL << 27) 192 #define RISCV_HWPROBE_EXT_ZFHMIN (1ULL << 28) 193 #define RISCV_HWPROBE_EXT_ZIHINTNTL (1ULL << 29) 194 #define RISCV_HWPROBE_EXT_ZVFH (1ULL << 30) 195 #define RISCV_HWPROBE_EXT_ZVFHMIN (1ULL << 31) 196 #define RISCV_HWPROBE_EXT_ZFA (1ULL << 32) 197 #define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33) 198 #define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34) 199 #define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35) 200 #define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36) 201 #define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37) 202 #define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38) 203 #define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39) 204 #define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40) 205 #define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41) 206 #define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42) 207 #define RISCV_HWPROBE_EXT_ZCA (1ULL << 43) 208 #define RISCV_HWPROBE_EXT_ZCB (1ULL << 44) 209 #define RISCV_HWPROBE_EXT_ZCD (1ULL << 45) 210 #define RISCV_HWPROBE_EXT_ZCF (1ULL << 46) 211 #define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47) 212 #define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48) 213 #define RISCV_HWPROBE_KEY_CPUPERF_0 5 214 #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0) 215 #define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0) 216 #define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0) 217 #define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0) 218 #define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0) 219 #define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0) 220 #define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6 221 /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */ 222 223 struct riscv_hwprobe { 224 long long key; 225 unsigned long long value; 226 }; 227 228 #define __NR_riscv_hwprobe 258 229 static long initHwProbe(struct riscv_hwprobe *Hwprobes, int len) { 230 return syscall_impl_5_args(__NR_riscv_hwprobe, (long)Hwprobes, len, 0, 0, 0); 231 } 232 233 #define SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(EXTNAME) \ 234 SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_EXT_##EXTNAME, EXTNAME) 235 236 #define SET_SINGLE_IMAEXT_RISCV_FEATURE(HWPROBE_BITMASK, EXT) \ 237 SET_SINGLE_RISCV_FEATURE(IMAEXT0Value &HWPROBE_BITMASK, EXT) 238 239 #define SET_SINGLE_RISCV_FEATURE(COND, EXT) \ 240 if (COND) { \ 241 SET_RISCV_FEATURE(EXT); \ 242 } 243 244 #define SET_RISCV_FEATURE(EXT) features[EXT##_GROUPID] |= EXT##_BITMASK 245 246 static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) { 247 248 // Note: If a hwprobe key is unknown to the kernel, its key field 249 // will be cleared to -1, and its value set to 0. 250 // This unsets all extension bitmask bits. 251 252 // Init VendorID, ArchID, ImplID 253 __riscv_cpu_model.mvendorid = Hwprobes[2].value; 254 __riscv_cpu_model.marchid = Hwprobes[3].value; 255 __riscv_cpu_model.mimpid = Hwprobes[4].value; 256 257 // Init standard extension 258 // TODO: Maybe Extension implied generate from tablegen? 259 260 unsigned long long features[RISCV_FEATURE_BITS_LENGTH]; 261 int i; 262 263 for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++) 264 features[i] = 0; 265 266 // Check RISCV_HWPROBE_KEY_BASE_BEHAVIOR 267 unsigned long long BaseValue = Hwprobes[0].value; 268 if (BaseValue & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) { 269 SET_RISCV_FEATURE(I); 270 SET_RISCV_FEATURE(M); 271 SET_RISCV_FEATURE(A); 272 } 273 274 // Check RISCV_HWPROBE_KEY_IMA_EXT_0 275 unsigned long long IMAEXT0Value = Hwprobes[1].value; 276 if (IMAEXT0Value & RISCV_HWPROBE_IMA_FD) { 277 SET_RISCV_FEATURE(F); 278 SET_RISCV_FEATURE(D); 279 } 280 281 SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_C, C); 282 SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_V, V); 283 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBA); 284 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBB); 285 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBS); 286 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICBOZ); 287 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBC); 288 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKB); 289 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKC); 290 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKX); 291 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKND); 292 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKNE); 293 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKNH); 294 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKSED); 295 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKSH); 296 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKT); 297 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVBB); 298 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVBC); 299 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKB); 300 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKG); 301 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNED); 302 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNHA); 303 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNHB); 304 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKSED); 305 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKSH); 306 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKT); 307 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFH); 308 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFHMIN); 309 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIHINTNTL); 310 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIHINTPAUSE); 311 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFH); 312 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFHMIN); 313 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFA); 314 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZTSO); 315 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZACAS); 316 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICOND); 317 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32X); 318 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32F); 319 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64X); 320 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64F); 321 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64D); 322 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIMOP); 323 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCA); 324 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCB); 325 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCD); 326 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCF); 327 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCMOP); 328 SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAWRS); 329 330 for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++) 331 __riscv_feature_bits.features[i] = features[i]; 332 } 333 334 #endif // defined(__linux__) 335 336 static int FeaturesBitCached = 0; 337 338 void __init_riscv_feature_bits(void *); 339 static void __init_riscv_feature_bits_ctor(void) CONSTRUCTOR_ATTRIBUTE; 340 341 // A constructor function that sets __riscv_feature_bits, and 342 // __riscv_vendor_feature_bits to the right values. This needs to run 343 // only once. This constructor is given the highest priority and it should 344 // run before constructors without the priority set. However, it still runs 345 // after ifunc initializers and needs to be called explicitly there. 346 347 static void CONSTRUCTOR_ATTRIBUTE __init_riscv_feature_bits_ctor(void) { 348 __init_riscv_feature_bits(0); 349 } 350 351 // PlatformArgs allows the platform to provide pre-computed data and access it 352 // without extra effort. For example, Linux could pass the vDSO object to avoid 353 // an extra system call. 354 void __init_riscv_feature_bits(void *PlatformArgs) { 355 356 if (FeaturesBitCached) 357 return; 358 359 __riscv_feature_bits.length = RISCV_FEATURE_BITS_LENGTH; 360 __riscv_vendor_feature_bits.length = RISCV_VENDOR_FEATURE_BITS_LENGTH; 361 362 #if defined(__linux__) 363 struct riscv_hwprobe Hwprobes[] = { 364 {RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0}, {RISCV_HWPROBE_KEY_IMA_EXT_0, 0}, 365 {RISCV_HWPROBE_KEY_MVENDORID, 0}, {RISCV_HWPROBE_KEY_MARCHID, 0}, 366 {RISCV_HWPROBE_KEY_MIMPID, 0}, 367 }; 368 if (initHwProbe(Hwprobes, sizeof(Hwprobes) / sizeof(Hwprobes[0]))) 369 return; 370 371 initRISCVFeature(Hwprobes); 372 #endif // defined(__linux__) 373 374 FeaturesBitCached = 1; 375 } 376