199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2015 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #include "rte_cpuflags.h" 699a2dd95SBruce Richardson 799a2dd95SBruce Richardson #include <stdio.h> 899a2dd95SBruce Richardson #include <errno.h> 999a2dd95SBruce Richardson #include <stdint.h> 1099a2dd95SBruce Richardson #include <string.h> 11*4225db8dSBruce Richardson #include <stdbool.h> 1299a2dd95SBruce Richardson 1399a2dd95SBruce Richardson #include "rte_cpuid.h" 14*4225db8dSBruce Richardson #include "rte_atomic.h" 1599a2dd95SBruce Richardson 1699a2dd95SBruce Richardson /** 1799a2dd95SBruce Richardson * Struct to hold a processor feature entry 1899a2dd95SBruce Richardson */ 1999a2dd95SBruce Richardson struct feature_entry { 2099a2dd95SBruce Richardson uint32_t leaf; /**< cpuid leaf */ 2199a2dd95SBruce Richardson uint32_t subleaf; /**< cpuid subleaf */ 2299a2dd95SBruce Richardson uint32_t reg; /**< cpuid register */ 2399a2dd95SBruce Richardson uint32_t bit; /**< cpuid register bit */ 2499a2dd95SBruce Richardson #define CPU_FLAG_NAME_MAX_LEN 64 2599a2dd95SBruce Richardson char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ 26*4225db8dSBruce Richardson bool has_value; 27*4225db8dSBruce Richardson bool value; 2899a2dd95SBruce Richardson }; 2999a2dd95SBruce Richardson 3099a2dd95SBruce Richardson #define FEAT_DEF(name, leaf, subleaf, reg, bit) \ 3199a2dd95SBruce Richardson [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, 3299a2dd95SBruce Richardson 33*4225db8dSBruce Richardson struct feature_entry rte_cpu_feature_table[] = { 3499a2dd95SBruce Richardson FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX, 0) 3599a2dd95SBruce Richardson FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX, 1) 3699a2dd95SBruce Richardson FEAT_DEF(DTES64, 0x00000001, 0, RTE_REG_ECX, 2) 3799a2dd95SBruce Richardson FEAT_DEF(MONITOR, 0x00000001, 0, RTE_REG_ECX, 3) 3899a2dd95SBruce Richardson FEAT_DEF(DS_CPL, 0x00000001, 0, RTE_REG_ECX, 4) 3999a2dd95SBruce Richardson FEAT_DEF(VMX, 0x00000001, 0, RTE_REG_ECX, 5) 4099a2dd95SBruce Richardson FEAT_DEF(SMX, 0x00000001, 0, RTE_REG_ECX, 6) 4199a2dd95SBruce Richardson FEAT_DEF(EIST, 0x00000001, 0, RTE_REG_ECX, 7) 4299a2dd95SBruce Richardson FEAT_DEF(TM2, 0x00000001, 0, RTE_REG_ECX, 8) 4399a2dd95SBruce Richardson FEAT_DEF(SSSE3, 0x00000001, 0, RTE_REG_ECX, 9) 4499a2dd95SBruce Richardson FEAT_DEF(CNXT_ID, 0x00000001, 0, RTE_REG_ECX, 10) 4599a2dd95SBruce Richardson FEAT_DEF(FMA, 0x00000001, 0, RTE_REG_ECX, 12) 4699a2dd95SBruce Richardson FEAT_DEF(CMPXCHG16B, 0x00000001, 0, RTE_REG_ECX, 13) 4799a2dd95SBruce Richardson FEAT_DEF(XTPR, 0x00000001, 0, RTE_REG_ECX, 14) 4899a2dd95SBruce Richardson FEAT_DEF(PDCM, 0x00000001, 0, RTE_REG_ECX, 15) 4999a2dd95SBruce Richardson FEAT_DEF(PCID, 0x00000001, 0, RTE_REG_ECX, 17) 5099a2dd95SBruce Richardson FEAT_DEF(DCA, 0x00000001, 0, RTE_REG_ECX, 18) 5199a2dd95SBruce Richardson FEAT_DEF(SSE4_1, 0x00000001, 0, RTE_REG_ECX, 19) 5299a2dd95SBruce Richardson FEAT_DEF(SSE4_2, 0x00000001, 0, RTE_REG_ECX, 20) 5399a2dd95SBruce Richardson FEAT_DEF(X2APIC, 0x00000001, 0, RTE_REG_ECX, 21) 5499a2dd95SBruce Richardson FEAT_DEF(MOVBE, 0x00000001, 0, RTE_REG_ECX, 22) 5599a2dd95SBruce Richardson FEAT_DEF(POPCNT, 0x00000001, 0, RTE_REG_ECX, 23) 5699a2dd95SBruce Richardson FEAT_DEF(TSC_DEADLINE, 0x00000001, 0, RTE_REG_ECX, 24) 5799a2dd95SBruce Richardson FEAT_DEF(AES, 0x00000001, 0, RTE_REG_ECX, 25) 5899a2dd95SBruce Richardson FEAT_DEF(XSAVE, 0x00000001, 0, RTE_REG_ECX, 26) 5999a2dd95SBruce Richardson FEAT_DEF(OSXSAVE, 0x00000001, 0, RTE_REG_ECX, 27) 6099a2dd95SBruce Richardson FEAT_DEF(AVX, 0x00000001, 0, RTE_REG_ECX, 28) 6199a2dd95SBruce Richardson FEAT_DEF(F16C, 0x00000001, 0, RTE_REG_ECX, 29) 6299a2dd95SBruce Richardson FEAT_DEF(RDRAND, 0x00000001, 0, RTE_REG_ECX, 30) 6399a2dd95SBruce Richardson FEAT_DEF(HYPERVISOR, 0x00000001, 0, RTE_REG_ECX, 31) 6499a2dd95SBruce Richardson 6599a2dd95SBruce Richardson FEAT_DEF(FPU, 0x00000001, 0, RTE_REG_EDX, 0) 6699a2dd95SBruce Richardson FEAT_DEF(VME, 0x00000001, 0, RTE_REG_EDX, 1) 6799a2dd95SBruce Richardson FEAT_DEF(DE, 0x00000001, 0, RTE_REG_EDX, 2) 6899a2dd95SBruce Richardson FEAT_DEF(PSE, 0x00000001, 0, RTE_REG_EDX, 3) 6999a2dd95SBruce Richardson FEAT_DEF(TSC, 0x00000001, 0, RTE_REG_EDX, 4) 7099a2dd95SBruce Richardson FEAT_DEF(MSR, 0x00000001, 0, RTE_REG_EDX, 5) 7199a2dd95SBruce Richardson FEAT_DEF(PAE, 0x00000001, 0, RTE_REG_EDX, 6) 7299a2dd95SBruce Richardson FEAT_DEF(MCE, 0x00000001, 0, RTE_REG_EDX, 7) 7399a2dd95SBruce Richardson FEAT_DEF(CX8, 0x00000001, 0, RTE_REG_EDX, 8) 7499a2dd95SBruce Richardson FEAT_DEF(APIC, 0x00000001, 0, RTE_REG_EDX, 9) 7599a2dd95SBruce Richardson FEAT_DEF(SEP, 0x00000001, 0, RTE_REG_EDX, 11) 7699a2dd95SBruce Richardson FEAT_DEF(MTRR, 0x00000001, 0, RTE_REG_EDX, 12) 7799a2dd95SBruce Richardson FEAT_DEF(PGE, 0x00000001, 0, RTE_REG_EDX, 13) 7899a2dd95SBruce Richardson FEAT_DEF(MCA, 0x00000001, 0, RTE_REG_EDX, 14) 7999a2dd95SBruce Richardson FEAT_DEF(CMOV, 0x00000001, 0, RTE_REG_EDX, 15) 8099a2dd95SBruce Richardson FEAT_DEF(PAT, 0x00000001, 0, RTE_REG_EDX, 16) 8199a2dd95SBruce Richardson FEAT_DEF(PSE36, 0x00000001, 0, RTE_REG_EDX, 17) 8299a2dd95SBruce Richardson FEAT_DEF(PSN, 0x00000001, 0, RTE_REG_EDX, 18) 8399a2dd95SBruce Richardson FEAT_DEF(CLFSH, 0x00000001, 0, RTE_REG_EDX, 19) 8499a2dd95SBruce Richardson FEAT_DEF(DS, 0x00000001, 0, RTE_REG_EDX, 21) 8599a2dd95SBruce Richardson FEAT_DEF(ACPI, 0x00000001, 0, RTE_REG_EDX, 22) 8699a2dd95SBruce Richardson FEAT_DEF(MMX, 0x00000001, 0, RTE_REG_EDX, 23) 8799a2dd95SBruce Richardson FEAT_DEF(FXSR, 0x00000001, 0, RTE_REG_EDX, 24) 8899a2dd95SBruce Richardson FEAT_DEF(SSE, 0x00000001, 0, RTE_REG_EDX, 25) 8999a2dd95SBruce Richardson FEAT_DEF(SSE2, 0x00000001, 0, RTE_REG_EDX, 26) 9099a2dd95SBruce Richardson FEAT_DEF(SS, 0x00000001, 0, RTE_REG_EDX, 27) 9199a2dd95SBruce Richardson FEAT_DEF(HTT, 0x00000001, 0, RTE_REG_EDX, 28) 9299a2dd95SBruce Richardson FEAT_DEF(TM, 0x00000001, 0, RTE_REG_EDX, 29) 9399a2dd95SBruce Richardson FEAT_DEF(PBE, 0x00000001, 0, RTE_REG_EDX, 31) 9499a2dd95SBruce Richardson 9599a2dd95SBruce Richardson FEAT_DEF(DIGTEMP, 0x00000006, 0, RTE_REG_EAX, 0) 9699a2dd95SBruce Richardson FEAT_DEF(TRBOBST, 0x00000006, 0, RTE_REG_EAX, 1) 9799a2dd95SBruce Richardson FEAT_DEF(ARAT, 0x00000006, 0, RTE_REG_EAX, 2) 9899a2dd95SBruce Richardson FEAT_DEF(PLN, 0x00000006, 0, RTE_REG_EAX, 4) 9999a2dd95SBruce Richardson FEAT_DEF(ECMD, 0x00000006, 0, RTE_REG_EAX, 5) 10099a2dd95SBruce Richardson FEAT_DEF(PTM, 0x00000006, 0, RTE_REG_EAX, 6) 10199a2dd95SBruce Richardson 10299a2dd95SBruce Richardson FEAT_DEF(MPERF_APERF_MSR, 0x00000006, 0, RTE_REG_ECX, 0) 10399a2dd95SBruce Richardson FEAT_DEF(ACNT2, 0x00000006, 0, RTE_REG_ECX, 1) 10499a2dd95SBruce Richardson FEAT_DEF(ENERGY_EFF, 0x00000006, 0, RTE_REG_ECX, 3) 10599a2dd95SBruce Richardson 10699a2dd95SBruce Richardson FEAT_DEF(FSGSBASE, 0x00000007, 0, RTE_REG_EBX, 0) 107aae3037aSDavid Marchand FEAT_DEF(BMI1, 0x00000007, 0, RTE_REG_EBX, 3) 10899a2dd95SBruce Richardson FEAT_DEF(HLE, 0x00000007, 0, RTE_REG_EBX, 4) 10999a2dd95SBruce Richardson FEAT_DEF(AVX2, 0x00000007, 0, RTE_REG_EBX, 5) 110aae3037aSDavid Marchand FEAT_DEF(SMEP, 0x00000007, 0, RTE_REG_EBX, 7) 111aae3037aSDavid Marchand FEAT_DEF(BMI2, 0x00000007, 0, RTE_REG_EBX, 8) 112aae3037aSDavid Marchand FEAT_DEF(ERMS, 0x00000007, 0, RTE_REG_EBX, 9) 11399a2dd95SBruce Richardson FEAT_DEF(INVPCID, 0x00000007, 0, RTE_REG_EBX, 10) 11499a2dd95SBruce Richardson FEAT_DEF(RTM, 0x00000007, 0, RTE_REG_EBX, 11) 11599a2dd95SBruce Richardson FEAT_DEF(AVX512F, 0x00000007, 0, RTE_REG_EBX, 16) 1162f375875SDavid Marchand FEAT_DEF(AVX512DQ, 0x00000007, 0, RTE_REG_EBX, 17) 11799a2dd95SBruce Richardson FEAT_DEF(RDSEED, 0x00000007, 0, RTE_REG_EBX, 18) 1182f375875SDavid Marchand FEAT_DEF(AVX512IFMA, 0x00000007, 0, RTE_REG_EBX, 21) 1192f375875SDavid Marchand FEAT_DEF(AVX512CD, 0x00000007, 0, RTE_REG_EBX, 28) 1202f375875SDavid Marchand FEAT_DEF(AVX512BW, 0x00000007, 0, RTE_REG_EBX, 30) 1212f375875SDavid Marchand FEAT_DEF(AVX512VL, 0x00000007, 0, RTE_REG_EBX, 31) 12299a2dd95SBruce Richardson 1232f375875SDavid Marchand FEAT_DEF(AVX512VBMI, 0x00000007, 0, RTE_REG_ECX, 1) 12499a2dd95SBruce Richardson FEAT_DEF(WAITPKG, 0x00000007, 0, RTE_REG_ECX, 5) 1252f375875SDavid Marchand FEAT_DEF(AVX512VBMI2, 0x00000007, 0, RTE_REG_ECX, 6) 1262f375875SDavid Marchand FEAT_DEF(GFNI, 0x00000007, 0, RTE_REG_ECX, 8) 1272f375875SDavid Marchand FEAT_DEF(VAES, 0x00000007, 0, RTE_REG_ECX, 9) 1282f375875SDavid Marchand FEAT_DEF(VPCLMULQDQ, 0x00000007, 0, RTE_REG_ECX, 10) 1292f375875SDavid Marchand FEAT_DEF(AVX512VNNI, 0x00000007, 0, RTE_REG_ECX, 11) 1302f375875SDavid Marchand FEAT_DEF(AVX512BITALG, 0x00000007, 0, RTE_REG_ECX, 12) 1312f375875SDavid Marchand FEAT_DEF(AVX512VPOPCNTDQ, 0x00000007, 0, RTE_REG_ECX, 14) 1322f375875SDavid Marchand FEAT_DEF(CLDEMOTE, 0x00000007, 0, RTE_REG_ECX, 25) 1332f375875SDavid Marchand FEAT_DEF(MOVDIRI, 0x00000007, 0, RTE_REG_ECX, 27) 1342f375875SDavid Marchand FEAT_DEF(MOVDIR64B, 0x00000007, 0, RTE_REG_ECX, 28) 1352f375875SDavid Marchand 1362f375875SDavid Marchand FEAT_DEF(AVX512VP2INTERSECT, 0x00000007, 0, RTE_REG_EDX, 8) 13799a2dd95SBruce Richardson 13899a2dd95SBruce Richardson FEAT_DEF(LAHF_SAHF, 0x80000001, 0, RTE_REG_ECX, 0) 13999a2dd95SBruce Richardson FEAT_DEF(LZCNT, 0x80000001, 0, RTE_REG_ECX, 4) 140c359a72fSSivaprasad Tummala FEAT_DEF(MONITORX, 0x80000001, 0, RTE_REG_ECX, 29) 14199a2dd95SBruce Richardson 14299a2dd95SBruce Richardson FEAT_DEF(SYSCALL, 0x80000001, 0, RTE_REG_EDX, 11) 14399a2dd95SBruce Richardson FEAT_DEF(XD, 0x80000001, 0, RTE_REG_EDX, 20) 14499a2dd95SBruce Richardson FEAT_DEF(1GB_PG, 0x80000001, 0, RTE_REG_EDX, 26) 14599a2dd95SBruce Richardson FEAT_DEF(RDTSCP, 0x80000001, 0, RTE_REG_EDX, 27) 14699a2dd95SBruce Richardson FEAT_DEF(EM64T, 0x80000001, 0, RTE_REG_EDX, 29) 14799a2dd95SBruce Richardson 14899a2dd95SBruce Richardson FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX, 8) 14999a2dd95SBruce Richardson }; 15099a2dd95SBruce Richardson 15199a2dd95SBruce Richardson int 15299a2dd95SBruce Richardson rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) 15399a2dd95SBruce Richardson { 154*4225db8dSBruce Richardson struct feature_entry *feat; 15599a2dd95SBruce Richardson cpuid_registers_t regs; 15699a2dd95SBruce Richardson unsigned int maxleaf; 15799a2dd95SBruce Richardson 15848c33e8cSSivaprasad Tummala if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table)) 15999a2dd95SBruce Richardson /* Flag does not match anything in the feature tables */ 16099a2dd95SBruce Richardson return -ENOENT; 16199a2dd95SBruce Richardson 16299a2dd95SBruce Richardson feat = &rte_cpu_feature_table[feature]; 163*4225db8dSBruce Richardson if (feat->has_value) 164*4225db8dSBruce Richardson return feat->value; 16599a2dd95SBruce Richardson 16699a2dd95SBruce Richardson if (!feat->leaf) 16799a2dd95SBruce Richardson /* This entry in the table wasn't filled out! */ 16899a2dd95SBruce Richardson return -EFAULT; 16999a2dd95SBruce Richardson 17099a2dd95SBruce Richardson maxleaf = __get_cpuid_max(feat->leaf & 0x80000000, NULL); 17199a2dd95SBruce Richardson 172*4225db8dSBruce Richardson if (maxleaf < feat->leaf) { 173*4225db8dSBruce Richardson feat->value = 0; 174*4225db8dSBruce Richardson goto out; 175*4225db8dSBruce Richardson } 17699a2dd95SBruce Richardson 1772454b37bSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC 1782454b37bSTyler Retzlaff __cpuidex(regs, feat->leaf, feat->subleaf); 1792454b37bSTyler Retzlaff #else 18099a2dd95SBruce Richardson __cpuid_count(feat->leaf, feat->subleaf, 18199a2dd95SBruce Richardson regs[RTE_REG_EAX], regs[RTE_REG_EBX], 18299a2dd95SBruce Richardson regs[RTE_REG_ECX], regs[RTE_REG_EDX]); 1832454b37bSTyler Retzlaff #endif 18499a2dd95SBruce Richardson 18599a2dd95SBruce Richardson /* check if the feature is enabled */ 186*4225db8dSBruce Richardson feat->value = (regs[feat->reg] >> feat->bit) & 1; 187*4225db8dSBruce Richardson out: 188*4225db8dSBruce Richardson rte_compiler_barrier(); 189*4225db8dSBruce Richardson feat->has_value = true; 190*4225db8dSBruce Richardson return feat->value; 19199a2dd95SBruce Richardson } 19299a2dd95SBruce Richardson 19399a2dd95SBruce Richardson const char * 19499a2dd95SBruce Richardson rte_cpu_get_flag_name(enum rte_cpu_flag_t feature) 19599a2dd95SBruce Richardson { 19648c33e8cSSivaprasad Tummala if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table)) 19799a2dd95SBruce Richardson return NULL; 19899a2dd95SBruce Richardson return rte_cpu_feature_table[feature].name; 19999a2dd95SBruce Richardson } 20099a2dd95SBruce Richardson 20199a2dd95SBruce Richardson void 20299a2dd95SBruce Richardson rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics) 20399a2dd95SBruce Richardson { 20499a2dd95SBruce Richardson memset(intrinsics, 0, sizeof(*intrinsics)); 20599a2dd95SBruce Richardson 20699a2dd95SBruce Richardson if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_WAITPKG)) { 20799a2dd95SBruce Richardson intrinsics->power_monitor = 1; 20899a2dd95SBruce Richardson intrinsics->power_pause = 1; 20966834f29SAnatoly Burakov if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_RTM)) 21066834f29SAnatoly Burakov intrinsics->power_monitor_multi = 1; 211c359a72fSSivaprasad Tummala } else if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_MONITORX)) { 212c359a72fSSivaprasad Tummala intrinsics->power_monitor = 1; 21399a2dd95SBruce Richardson } 21499a2dd95SBruce Richardson } 215