1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2015 Intel Corporation 3 */ 4 5 #include "rte_cpuflags.h" 6 7 #include <stdio.h> 8 #include <errno.h> 9 #include <stdint.h> 10 #include <string.h> 11 12 #include "rte_cpuid.h" 13 14 /** 15 * Struct to hold a processor feature entry 16 */ 17 struct feature_entry { 18 uint32_t leaf; /**< cpuid leaf */ 19 uint32_t subleaf; /**< cpuid subleaf */ 20 uint32_t reg; /**< cpuid register */ 21 uint32_t bit; /**< cpuid register bit */ 22 #define CPU_FLAG_NAME_MAX_LEN 64 23 char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ 24 }; 25 26 #define FEAT_DEF(name, leaf, subleaf, reg, bit) \ 27 [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, 28 29 const struct feature_entry rte_cpu_feature_table[] = { 30 FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX, 0) 31 FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX, 1) 32 FEAT_DEF(DTES64, 0x00000001, 0, RTE_REG_ECX, 2) 33 FEAT_DEF(MONITOR, 0x00000001, 0, RTE_REG_ECX, 3) 34 FEAT_DEF(DS_CPL, 0x00000001, 0, RTE_REG_ECX, 4) 35 FEAT_DEF(VMX, 0x00000001, 0, RTE_REG_ECX, 5) 36 FEAT_DEF(SMX, 0x00000001, 0, RTE_REG_ECX, 6) 37 FEAT_DEF(EIST, 0x00000001, 0, RTE_REG_ECX, 7) 38 FEAT_DEF(TM2, 0x00000001, 0, RTE_REG_ECX, 8) 39 FEAT_DEF(SSSE3, 0x00000001, 0, RTE_REG_ECX, 9) 40 FEAT_DEF(CNXT_ID, 0x00000001, 0, RTE_REG_ECX, 10) 41 FEAT_DEF(FMA, 0x00000001, 0, RTE_REG_ECX, 12) 42 FEAT_DEF(CMPXCHG16B, 0x00000001, 0, RTE_REG_ECX, 13) 43 FEAT_DEF(XTPR, 0x00000001, 0, RTE_REG_ECX, 14) 44 FEAT_DEF(PDCM, 0x00000001, 0, RTE_REG_ECX, 15) 45 FEAT_DEF(PCID, 0x00000001, 0, RTE_REG_ECX, 17) 46 FEAT_DEF(DCA, 0x00000001, 0, RTE_REG_ECX, 18) 47 FEAT_DEF(SSE4_1, 0x00000001, 0, RTE_REG_ECX, 19) 48 FEAT_DEF(SSE4_2, 0x00000001, 0, RTE_REG_ECX, 20) 49 FEAT_DEF(X2APIC, 0x00000001, 0, RTE_REG_ECX, 21) 50 FEAT_DEF(MOVBE, 0x00000001, 0, RTE_REG_ECX, 22) 51 FEAT_DEF(POPCNT, 0x00000001, 0, RTE_REG_ECX, 23) 52 FEAT_DEF(TSC_DEADLINE, 0x00000001, 0, RTE_REG_ECX, 24) 53 FEAT_DEF(AES, 0x00000001, 0, RTE_REG_ECX, 25) 54 FEAT_DEF(XSAVE, 0x00000001, 0, RTE_REG_ECX, 26) 55 FEAT_DEF(OSXSAVE, 0x00000001, 0, RTE_REG_ECX, 27) 56 FEAT_DEF(AVX, 0x00000001, 0, RTE_REG_ECX, 28) 57 FEAT_DEF(F16C, 0x00000001, 0, RTE_REG_ECX, 29) 58 FEAT_DEF(RDRAND, 0x00000001, 0, RTE_REG_ECX, 30) 59 FEAT_DEF(HYPERVISOR, 0x00000001, 0, RTE_REG_ECX, 31) 60 61 FEAT_DEF(FPU, 0x00000001, 0, RTE_REG_EDX, 0) 62 FEAT_DEF(VME, 0x00000001, 0, RTE_REG_EDX, 1) 63 FEAT_DEF(DE, 0x00000001, 0, RTE_REG_EDX, 2) 64 FEAT_DEF(PSE, 0x00000001, 0, RTE_REG_EDX, 3) 65 FEAT_DEF(TSC, 0x00000001, 0, RTE_REG_EDX, 4) 66 FEAT_DEF(MSR, 0x00000001, 0, RTE_REG_EDX, 5) 67 FEAT_DEF(PAE, 0x00000001, 0, RTE_REG_EDX, 6) 68 FEAT_DEF(MCE, 0x00000001, 0, RTE_REG_EDX, 7) 69 FEAT_DEF(CX8, 0x00000001, 0, RTE_REG_EDX, 8) 70 FEAT_DEF(APIC, 0x00000001, 0, RTE_REG_EDX, 9) 71 FEAT_DEF(SEP, 0x00000001, 0, RTE_REG_EDX, 11) 72 FEAT_DEF(MTRR, 0x00000001, 0, RTE_REG_EDX, 12) 73 FEAT_DEF(PGE, 0x00000001, 0, RTE_REG_EDX, 13) 74 FEAT_DEF(MCA, 0x00000001, 0, RTE_REG_EDX, 14) 75 FEAT_DEF(CMOV, 0x00000001, 0, RTE_REG_EDX, 15) 76 FEAT_DEF(PAT, 0x00000001, 0, RTE_REG_EDX, 16) 77 FEAT_DEF(PSE36, 0x00000001, 0, RTE_REG_EDX, 17) 78 FEAT_DEF(PSN, 0x00000001, 0, RTE_REG_EDX, 18) 79 FEAT_DEF(CLFSH, 0x00000001, 0, RTE_REG_EDX, 19) 80 FEAT_DEF(DS, 0x00000001, 0, RTE_REG_EDX, 21) 81 FEAT_DEF(ACPI, 0x00000001, 0, RTE_REG_EDX, 22) 82 FEAT_DEF(MMX, 0x00000001, 0, RTE_REG_EDX, 23) 83 FEAT_DEF(FXSR, 0x00000001, 0, RTE_REG_EDX, 24) 84 FEAT_DEF(SSE, 0x00000001, 0, RTE_REG_EDX, 25) 85 FEAT_DEF(SSE2, 0x00000001, 0, RTE_REG_EDX, 26) 86 FEAT_DEF(SS, 0x00000001, 0, RTE_REG_EDX, 27) 87 FEAT_DEF(HTT, 0x00000001, 0, RTE_REG_EDX, 28) 88 FEAT_DEF(TM, 0x00000001, 0, RTE_REG_EDX, 29) 89 FEAT_DEF(PBE, 0x00000001, 0, RTE_REG_EDX, 31) 90 91 FEAT_DEF(DIGTEMP, 0x00000006, 0, RTE_REG_EAX, 0) 92 FEAT_DEF(TRBOBST, 0x00000006, 0, RTE_REG_EAX, 1) 93 FEAT_DEF(ARAT, 0x00000006, 0, RTE_REG_EAX, 2) 94 FEAT_DEF(PLN, 0x00000006, 0, RTE_REG_EAX, 4) 95 FEAT_DEF(ECMD, 0x00000006, 0, RTE_REG_EAX, 5) 96 FEAT_DEF(PTM, 0x00000006, 0, RTE_REG_EAX, 6) 97 98 FEAT_DEF(MPERF_APERF_MSR, 0x00000006, 0, RTE_REG_ECX, 0) 99 FEAT_DEF(ACNT2, 0x00000006, 0, RTE_REG_ECX, 1) 100 FEAT_DEF(ENERGY_EFF, 0x00000006, 0, RTE_REG_ECX, 3) 101 102 FEAT_DEF(FSGSBASE, 0x00000007, 0, RTE_REG_EBX, 0) 103 FEAT_DEF(BMI1, 0x00000007, 0, RTE_REG_EBX, 3) 104 FEAT_DEF(HLE, 0x00000007, 0, RTE_REG_EBX, 4) 105 FEAT_DEF(AVX2, 0x00000007, 0, RTE_REG_EBX, 5) 106 FEAT_DEF(SMEP, 0x00000007, 0, RTE_REG_EBX, 7) 107 FEAT_DEF(BMI2, 0x00000007, 0, RTE_REG_EBX, 8) 108 FEAT_DEF(ERMS, 0x00000007, 0, RTE_REG_EBX, 9) 109 FEAT_DEF(INVPCID, 0x00000007, 0, RTE_REG_EBX, 10) 110 FEAT_DEF(RTM, 0x00000007, 0, RTE_REG_EBX, 11) 111 FEAT_DEF(AVX512F, 0x00000007, 0, RTE_REG_EBX, 16) 112 FEAT_DEF(AVX512DQ, 0x00000007, 0, RTE_REG_EBX, 17) 113 FEAT_DEF(RDSEED, 0x00000007, 0, RTE_REG_EBX, 18) 114 FEAT_DEF(AVX512IFMA, 0x00000007, 0, RTE_REG_EBX, 21) 115 FEAT_DEF(AVX512CD, 0x00000007, 0, RTE_REG_EBX, 28) 116 FEAT_DEF(AVX512BW, 0x00000007, 0, RTE_REG_EBX, 30) 117 FEAT_DEF(AVX512VL, 0x00000007, 0, RTE_REG_EBX, 31) 118 119 FEAT_DEF(AVX512VBMI, 0x00000007, 0, RTE_REG_ECX, 1) 120 FEAT_DEF(WAITPKG, 0x00000007, 0, RTE_REG_ECX, 5) 121 FEAT_DEF(AVX512VBMI2, 0x00000007, 0, RTE_REG_ECX, 6) 122 FEAT_DEF(GFNI, 0x00000007, 0, RTE_REG_ECX, 8) 123 FEAT_DEF(VAES, 0x00000007, 0, RTE_REG_ECX, 9) 124 FEAT_DEF(VPCLMULQDQ, 0x00000007, 0, RTE_REG_ECX, 10) 125 FEAT_DEF(AVX512VNNI, 0x00000007, 0, RTE_REG_ECX, 11) 126 FEAT_DEF(AVX512BITALG, 0x00000007, 0, RTE_REG_ECX, 12) 127 FEAT_DEF(AVX512VPOPCNTDQ, 0x00000007, 0, RTE_REG_ECX, 14) 128 FEAT_DEF(CLDEMOTE, 0x00000007, 0, RTE_REG_ECX, 25) 129 FEAT_DEF(MOVDIRI, 0x00000007, 0, RTE_REG_ECX, 27) 130 FEAT_DEF(MOVDIR64B, 0x00000007, 0, RTE_REG_ECX, 28) 131 132 FEAT_DEF(AVX512VP2INTERSECT, 0x00000007, 0, RTE_REG_EDX, 8) 133 134 FEAT_DEF(LAHF_SAHF, 0x80000001, 0, RTE_REG_ECX, 0) 135 FEAT_DEF(LZCNT, 0x80000001, 0, RTE_REG_ECX, 4) 136 137 FEAT_DEF(SYSCALL, 0x80000001, 0, RTE_REG_EDX, 11) 138 FEAT_DEF(XD, 0x80000001, 0, RTE_REG_EDX, 20) 139 FEAT_DEF(1GB_PG, 0x80000001, 0, RTE_REG_EDX, 26) 140 FEAT_DEF(RDTSCP, 0x80000001, 0, RTE_REG_EDX, 27) 141 FEAT_DEF(EM64T, 0x80000001, 0, RTE_REG_EDX, 29) 142 143 FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX, 8) 144 }; 145 146 int 147 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) 148 { 149 const struct feature_entry *feat; 150 cpuid_registers_t regs; 151 unsigned int maxleaf; 152 153 if (feature >= RTE_CPUFLAG_NUMFLAGS) 154 /* Flag does not match anything in the feature tables */ 155 return -ENOENT; 156 157 feat = &rte_cpu_feature_table[feature]; 158 159 if (!feat->leaf) 160 /* This entry in the table wasn't filled out! */ 161 return -EFAULT; 162 163 maxleaf = __get_cpuid_max(feat->leaf & 0x80000000, NULL); 164 165 if (maxleaf < feat->leaf) 166 return 0; 167 168 __cpuid_count(feat->leaf, feat->subleaf, 169 regs[RTE_REG_EAX], regs[RTE_REG_EBX], 170 regs[RTE_REG_ECX], regs[RTE_REG_EDX]); 171 172 /* check if the feature is enabled */ 173 return (regs[feat->reg] >> feat->bit) & 1; 174 } 175 176 const char * 177 rte_cpu_get_flag_name(enum rte_cpu_flag_t feature) 178 { 179 if (feature >= RTE_CPUFLAG_NUMFLAGS) 180 return NULL; 181 return rte_cpu_feature_table[feature].name; 182 } 183 184 void 185 rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics) 186 { 187 memset(intrinsics, 0, sizeof(*intrinsics)); 188 189 if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_WAITPKG)) { 190 intrinsics->power_monitor = 1; 191 intrinsics->power_pause = 1; 192 if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_RTM)) 193 intrinsics->power_monitor_multi = 1; 194 } 195 } 196