xref: /dpdk/lib/eal/x86/rte_cpuflags.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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