1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2022 StarFive 3 * Copyright(c) 2022 SiFive 4 * Copyright(c) 2022 Semihalf 5 */ 6 7 #include "rte_cpuflags.h" 8 9 #include <elf.h> 10 #include <fcntl.h> 11 #include <assert.h> 12 #include <unistd.h> 13 #include <string.h> 14 15 #ifndef AT_HWCAP 16 #define AT_HWCAP 16 17 #endif 18 19 #ifndef AT_HWCAP2 20 #define AT_HWCAP2 26 21 #endif 22 23 #ifndef AT_PLATFORM 24 #define AT_PLATFORM 15 25 #endif 26 27 enum cpu_register_t { 28 REG_NONE = 0, 29 REG_HWCAP, 30 REG_HWCAP2, 31 REG_PLATFORM, 32 REG_MAX 33 }; 34 35 typedef uint32_t hwcap_registers_t[REG_MAX]; 36 37 /** 38 * Struct to hold a processor feature entry 39 */ 40 struct feature_entry { 41 uint32_t reg; 42 uint32_t bit; 43 #define CPU_FLAG_NAME_MAX_LEN 64 44 char name[CPU_FLAG_NAME_MAX_LEN]; 45 }; 46 47 #define FEAT_DEF(name, reg, bit) \ 48 [RTE_CPUFLAG_##name] = {reg, bit, #name}, 49 50 typedef Elf64_auxv_t _Elfx_auxv_t; 51 52 const struct feature_entry rte_cpu_feature_table[] = { 53 FEAT_DEF(RISCV_ISA_A, REG_HWCAP, 0) 54 FEAT_DEF(RISCV_ISA_B, REG_HWCAP, 1) 55 FEAT_DEF(RISCV_ISA_C, REG_HWCAP, 2) 56 FEAT_DEF(RISCV_ISA_D, REG_HWCAP, 3) 57 FEAT_DEF(RISCV_ISA_E, REG_HWCAP, 4) 58 FEAT_DEF(RISCV_ISA_F, REG_HWCAP, 5) 59 FEAT_DEF(RISCV_ISA_G, REG_HWCAP, 6) 60 FEAT_DEF(RISCV_ISA_H, REG_HWCAP, 7) 61 FEAT_DEF(RISCV_ISA_I, REG_HWCAP, 8) 62 FEAT_DEF(RISCV_ISA_J, REG_HWCAP, 9) 63 FEAT_DEF(RISCV_ISA_K, REG_HWCAP, 10) 64 FEAT_DEF(RISCV_ISA_L, REG_HWCAP, 11) 65 FEAT_DEF(RISCV_ISA_M, REG_HWCAP, 12) 66 FEAT_DEF(RISCV_ISA_N, REG_HWCAP, 13) 67 FEAT_DEF(RISCV_ISA_O, REG_HWCAP, 14) 68 FEAT_DEF(RISCV_ISA_P, REG_HWCAP, 15) 69 FEAT_DEF(RISCV_ISA_Q, REG_HWCAP, 16) 70 FEAT_DEF(RISCV_ISA_R, REG_HWCAP, 17) 71 FEAT_DEF(RISCV_ISA_S, REG_HWCAP, 18) 72 FEAT_DEF(RISCV_ISA_T, REG_HWCAP, 19) 73 FEAT_DEF(RISCV_ISA_U, REG_HWCAP, 20) 74 FEAT_DEF(RISCV_ISA_V, REG_HWCAP, 21) 75 FEAT_DEF(RISCV_ISA_W, REG_HWCAP, 22) 76 FEAT_DEF(RISCV_ISA_X, REG_HWCAP, 23) 77 FEAT_DEF(RISCV_ISA_Y, REG_HWCAP, 24) 78 FEAT_DEF(RISCV_ISA_Z, REG_HWCAP, 25) 79 }; 80 /* 81 * Read AUXV software register and get cpu features for ARM 82 */ 83 static void 84 rte_cpu_get_features(hwcap_registers_t out) 85 { 86 out[REG_HWCAP] = rte_cpu_getauxval(AT_HWCAP); 87 out[REG_HWCAP2] = rte_cpu_getauxval(AT_HWCAP2); 88 } 89 90 /* 91 * Checks if a particular flag is available on current machine. 92 */ 93 int 94 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) 95 { 96 const struct feature_entry *feat; 97 hwcap_registers_t regs = {0}; 98 99 if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table)) 100 return -ENOENT; 101 102 feat = &rte_cpu_feature_table[feature]; 103 if (feat->reg == REG_NONE) 104 return -EFAULT; 105 106 rte_cpu_get_features(regs); 107 return (regs[feat->reg] >> feat->bit) & 1; 108 } 109 110 const char * 111 rte_cpu_get_flag_name(enum rte_cpu_flag_t feature) 112 { 113 if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table)) 114 return NULL; 115 return rte_cpu_feature_table[feature].name; 116 } 117 118 void 119 rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics) 120 { 121 memset(intrinsics, 0, sizeof(*intrinsics)); 122 } 123