1 /*
2  * cpufeature.h
3  *
4  * Defines x86 CPU feature bits
5  */
6 #ifndef __ASM_I386_CPUFEATURE_H
7 #define __ASM_I386_CPUFEATURE_H
8 
9 #include <xen/cache.h>
10 #include <xen/const.h>
11 #include <xen/macros.h>
12 
13 #include <asm/cpuid.h>
14 
15 #define cpufeat_word(idx)	((idx) / 32)
16 #define cpufeat_bit(idx)	((idx) % 32)
17 #define cpufeat_mask(idx)	(_AC(1, U) << cpufeat_bit(idx))
18 
19 /* An alias of a feature we know is always going to be present. */
20 #define X86_FEATURE_ALWAYS      X86_FEATURE_LM
21 
22 /*
23  * Layout tied to cpuinfo_x86.vfm
24  */
25 #define VFM_MODEL_MASK  0x000000ff
26 #define VFM_FAMILY_MASK 0x0000ff00
27 #define VFM_VENDOR_MASK 0x00ff0000
28 
29 #define VFM_MAKE(v, f, m) (MASK_INSR(v, VFM_VENDOR_MASK) | \
30                            MASK_INSR(f, VFM_FAMILY_MASK) | \
31                            MASK_INSR(m, VFM_MODEL_MASK))
32 
33 #define VFM_MODEL(vfm)  MASK_EXTR(vfm, VFM_MODEL_MASK)
34 #define VFM_FAMILY(vfm) MASK_EXTR(vfm, VFM_FAMILY_MASK)
35 #define VFM_VENDOR(vfm) MASK_EXTR(vfm, VFM_VENDOR_MASK)
36 
37 #ifndef __ASSEMBLY__
38 
39 struct cpuinfo_x86 {
40     /* TODO: Phase out the x86 prefixed names. */
41     union {
42         struct {
43             union {
44                 uint8_t x86_model;
45                 uint8_t model;
46             };
47             union {
48                 uint8_t x86;
49                 uint8_t family;
50             };
51             union {
52                 uint8_t x86_vendor;
53                 uint8_t vendor;
54             };
55             uint8_t _rsvd;             /* Use of this needs coordinating with VFM_MAKE() */
56         };
57         uint32_t vfm;                  /* Vendor Family Model */
58     };
59     union {
60         uint8_t x86_mask;
61         uint8_t stepping;
62     };
63 
64     unsigned int cpuid_level;          /* Maximum supported CPUID level */
65     unsigned int extended_cpuid_level; /* Maximum supported CPUID extended level */
66     unsigned int x86_capability[NCAPINTS];
67     char x86_vendor_id[16];
68     char x86_model_id[64];
69     unsigned int x86_cache_size;       /* in KB - valid only when supported */
70     unsigned int x86_cache_alignment;  /* In bytes */
71     unsigned int x86_max_cores;        /* cpuid returned max cores value */
72     unsigned int booted_cores;         /* number of cores as seen by OS */
73     unsigned int x86_num_siblings;     /* cpuid logical cpus per chip value */
74     unsigned int apicid;
75     unsigned int phys_proc_id;         /* package ID of each logical CPU */
76     unsigned int cpu_core_id;          /* core ID of each logical CPU */
77     unsigned int compute_unit_id;      /* AMD compute unit ID of each logical CPU */
78     unsigned short x86_clflush_size;
79 } __cacheline_aligned;
80 
81 #define CPU_DATA_INIT(what...)                     \
82         what.cpuid_level = 1,                      \
83         what.extended_cpuid_level = 0,             \
84         what.x86_cache_size = -1,                  \
85         what.x86_max_cores = 1,                    \
86         what.x86_num_siblings = 1,                 \
87         what.apicid = BAD_APICID,                  \
88         what.phys_proc_id = XEN_INVALID_SOCKET_ID, \
89         what.cpu_core_id = XEN_INVALID_CORE_ID,    \
90         what.compute_unit_id = INVALID_CUID
91 
92 /*
93  * @keep_basic set to true retains data firmly assumed to be symmetric
94  * across all CPUs.  Only CPU_DATA_INIT() will be invoked in that case
95  * on the passed structure.
96  */
97 void reset_cpuinfo(struct cpuinfo_x86 *c, bool keep_basic);
98 
99 extern struct cpuinfo_x86 boot_cpu_data;
100 
cpu_has(const struct cpuinfo_x86 * info,unsigned int feat)101 static inline bool cpu_has(const struct cpuinfo_x86 *info, unsigned int feat)
102 {
103     return info->x86_capability[cpufeat_word(feat)] & cpufeat_mask(feat);
104 }
105 
boot_cpu_has(unsigned int feat)106 static inline bool boot_cpu_has(unsigned int feat)
107 {
108     return cpu_has(&boot_cpu_data, feat);
109 }
110 
111 #define CPUID_PM_LEAF                                6
112 #define CPUID6_EAX_HWP                               BIT(7, U)
113 #define CPUID6_EAX_HWP_NOTIFICATION                  BIT(8, U)
114 #define CPUID6_EAX_HWP_ACTIVITY_WINDOW               BIT(9, U)
115 #define CPUID6_EAX_HWP_ENERGY_PERFORMANCE_PREFERENCE BIT(10, U)
116 #define CPUID6_EAX_HWP_PACKAGE_LEVEL_REQUEST         BIT(11, U)
117 #define CPUID6_EAX_HDC                               BIT(13, U)
118 #define CPUID6_EAX_HWP_PECI                          BIT(16, U)
119 #define CPUID6_EAX_HW_FEEDBACK                       BIT(19, U)
120 #define CPUID6_ECX_APERFMPERF_CAPABILITY             BIT(0, U)
121 
122 /* CPUID level 0x00000001.edx */
123 #define cpu_has_fpu             1
124 #define cpu_has_de              1
125 #define cpu_has_pse             1
126 #define cpu_has_apic            boot_cpu_has(X86_FEATURE_APIC)
127 #define cpu_has_sep             boot_cpu_has(X86_FEATURE_SEP)
128 #define cpu_has_mtrr            boot_cpu_has(X86_FEATURE_MTRR)
129 #define cpu_has_pge             1
130 #define cpu_has_pse36           boot_cpu_has(X86_FEATURE_PSE36)
131 #define cpu_has_clflush         boot_cpu_has(X86_FEATURE_CLFLUSH)
132 #define cpu_has_mmx             1
133 #define cpu_has_htt             boot_cpu_has(X86_FEATURE_HTT)
134 
135 /* CPUID level 0x00000001.ecx */
136 #define cpu_has_sse3            boot_cpu_has(X86_FEATURE_SSE3)
137 #define cpu_has_pclmulqdq       boot_cpu_has(X86_FEATURE_PCLMULQDQ)
138 #define cpu_has_monitor         boot_cpu_has(X86_FEATURE_MONITOR)
139 #define cpu_has_vmx             boot_cpu_has(X86_FEATURE_VMX)
140 #define cpu_has_eist            boot_cpu_has(X86_FEATURE_EIST)
141 #define cpu_has_ssse3           boot_cpu_has(X86_FEATURE_SSSE3)
142 #define cpu_has_fma             boot_cpu_has(X86_FEATURE_FMA)
143 #define cpu_has_cx16            boot_cpu_has(X86_FEATURE_CX16)
144 #define cpu_has_pdcm            boot_cpu_has(X86_FEATURE_PDCM)
145 #define cpu_has_pcid            boot_cpu_has(X86_FEATURE_PCID)
146 #define cpu_has_sse4_1          boot_cpu_has(X86_FEATURE_SSE4_1)
147 #define cpu_has_sse4_2          boot_cpu_has(X86_FEATURE_SSE4_2)
148 #define cpu_has_x2apic          boot_cpu_has(X86_FEATURE_X2APIC)
149 #define cpu_has_popcnt          boot_cpu_has(X86_FEATURE_POPCNT)
150 #define cpu_has_aesni           boot_cpu_has(X86_FEATURE_AESNI)
151 #define cpu_has_xsave           boot_cpu_has(X86_FEATURE_XSAVE)
152 #define cpu_has_avx             boot_cpu_has(X86_FEATURE_AVX)
153 #define cpu_has_f16c            boot_cpu_has(X86_FEATURE_F16C)
154 #define cpu_has_rdrand          boot_cpu_has(X86_FEATURE_RDRAND)
155 #define cpu_has_hypervisor      boot_cpu_has(X86_FEATURE_HYPERVISOR)
156 
157 /* CPUID level 0x80000001.edx */
158 #define cpu_has_nx              (IS_ENABLED(CONFIG_REQUIRE_NX) || \
159                                  boot_cpu_has(X86_FEATURE_NX))
160 #define cpu_has_page1gb         boot_cpu_has(X86_FEATURE_PAGE1GB)
161 #define cpu_has_rdtscp          boot_cpu_has(X86_FEATURE_RDTSCP)
162 #define cpu_has_3dnow_ext       boot_cpu_has(X86_FEATURE_3DNOWEXT)
163 #define cpu_has_3dnow           boot_cpu_has(X86_FEATURE_3DNOW)
164 
165 /* CPUID level 0x80000001.ecx */
166 #define cpu_has_cmp_legacy      boot_cpu_has(X86_FEATURE_CMP_LEGACY)
167 #define cpu_has_svm             boot_cpu_has(X86_FEATURE_SVM)
168 #define cpu_has_sse4a           boot_cpu_has(X86_FEATURE_SSE4A)
169 #define cpu_has_xop             boot_cpu_has(X86_FEATURE_XOP)
170 #define cpu_has_skinit          boot_cpu_has(X86_FEATURE_SKINIT)
171 #define cpu_has_fma4            boot_cpu_has(X86_FEATURE_FMA4)
172 #define cpu_has_tbm             boot_cpu_has(X86_FEATURE_TBM)
173 
174 /* CPUID level 0x0000000D:1.eax */
175 #define cpu_has_xsaveopt        boot_cpu_has(X86_FEATURE_XSAVEOPT)
176 #define cpu_has_xsavec          boot_cpu_has(X86_FEATURE_XSAVEC)
177 #define cpu_has_xgetbv1         boot_cpu_has(X86_FEATURE_XGETBV1)
178 #define cpu_has_xsaves          boot_cpu_has(X86_FEATURE_XSAVES)
179 
180 /* CPUID level 0x00000007:0.ebx */
181 #define cpu_has_bmi1            boot_cpu_has(X86_FEATURE_BMI1)
182 #define cpu_has_hle             boot_cpu_has(X86_FEATURE_HLE)
183 #define cpu_has_avx2            boot_cpu_has(X86_FEATURE_AVX2)
184 #define cpu_has_smep            boot_cpu_has(X86_FEATURE_SMEP)
185 #define cpu_has_bmi2            boot_cpu_has(X86_FEATURE_BMI2)
186 #define cpu_has_invpcid         boot_cpu_has(X86_FEATURE_INVPCID)
187 #define cpu_has_rtm             boot_cpu_has(X86_FEATURE_RTM)
188 #define cpu_has_pqe             boot_cpu_has(X86_FEATURE_PQE)
189 #define cpu_has_fpu_sel         (!boot_cpu_has(X86_FEATURE_NO_FPU_SEL))
190 #define cpu_has_mpx             boot_cpu_has(X86_FEATURE_MPX)
191 #define cpu_has_avx512f         boot_cpu_has(X86_FEATURE_AVX512F)
192 #define cpu_has_avx512dq        boot_cpu_has(X86_FEATURE_AVX512DQ)
193 #define cpu_has_rdseed          boot_cpu_has(X86_FEATURE_RDSEED)
194 #define cpu_has_smap            boot_cpu_has(X86_FEATURE_SMAP)
195 #define cpu_has_avx512_ifma     boot_cpu_has(X86_FEATURE_AVX512_IFMA)
196 #define cpu_has_clflushopt      boot_cpu_has(X86_FEATURE_CLFLUSHOPT)
197 #define cpu_has_clwb            boot_cpu_has(X86_FEATURE_CLWB)
198 #define cpu_has_avx512cd        boot_cpu_has(X86_FEATURE_AVX512CD)
199 #define cpu_has_proc_trace      boot_cpu_has(X86_FEATURE_PROC_TRACE)
200 #define cpu_has_sha             boot_cpu_has(X86_FEATURE_SHA)
201 #define cpu_has_avx512bw        boot_cpu_has(X86_FEATURE_AVX512BW)
202 #define cpu_has_avx512vl        boot_cpu_has(X86_FEATURE_AVX512VL)
203 
204 /* CPUID level 0x00000007:0.ecx */
205 #define cpu_has_avx512_vbmi     boot_cpu_has(X86_FEATURE_AVX512_VBMI)
206 #define cpu_has_pku             boot_cpu_has(X86_FEATURE_PKU)
207 #define cpu_has_avx512_vbmi2    boot_cpu_has(X86_FEATURE_AVX512_VBMI2)
208 #define cpu_has_gfni            boot_cpu_has(X86_FEATURE_GFNI)
209 #define cpu_has_vaes            boot_cpu_has(X86_FEATURE_VAES)
210 #define cpu_has_vpclmulqdq      boot_cpu_has(X86_FEATURE_VPCLMULQDQ)
211 #define cpu_has_avx512_vnni     boot_cpu_has(X86_FEATURE_AVX512_VNNI)
212 #define cpu_has_avx512_bitalg   boot_cpu_has(X86_FEATURE_AVX512_BITALG)
213 #define cpu_has_avx512_vpopcntdq boot_cpu_has(X86_FEATURE_AVX512_VPOPCNTDQ)
214 #define cpu_has_rdpid           boot_cpu_has(X86_FEATURE_RDPID)
215 #define cpu_has_movdiri         boot_cpu_has(X86_FEATURE_MOVDIRI)
216 #define cpu_has_movdir64b       boot_cpu_has(X86_FEATURE_MOVDIR64B)
217 #define cpu_has_enqcmd          boot_cpu_has(X86_FEATURE_ENQCMD)
218 #define cpu_has_pks             boot_cpu_has(X86_FEATURE_PKS)
219 
220 /* CPUID level 0x80000007.edx */
221 #define cpu_has_hw_pstate       boot_cpu_has(X86_FEATURE_HW_PSTATE)
222 #define cpu_has_itsc            boot_cpu_has(X86_FEATURE_ITSC)
223 
224 /* CPUID level 0x80000008.ebx */
225 #define cpu_has_amd_ssbd        boot_cpu_has(X86_FEATURE_AMD_SSBD)
226 #define cpu_has_virt_ssbd       boot_cpu_has(X86_FEATURE_VIRT_SSBD)
227 #define cpu_has_ssb_no          boot_cpu_has(X86_FEATURE_SSB_NO)
228 #define cpu_has_cppc            boot_cpu_has(X86_FEATURE_CPPC)
229 #define cpu_has_auto_ibrs       boot_cpu_has(X86_FEATURE_AUTO_IBRS)
230 
231 /* CPUID level 0x00000007:0.edx */
232 #define cpu_has_avx512_vp2intersect boot_cpu_has(X86_FEATURE_AVX512_VP2INTERSECT)
233 #define cpu_has_srbds_ctrl      boot_cpu_has(X86_FEATURE_SRBDS_CTRL)
234 #define cpu_has_md_clear        boot_cpu_has(X86_FEATURE_MD_CLEAR)
235 #define cpu_has_rtm_always_abort boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT)
236 #define cpu_has_tsx_force_abort boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)
237 #define cpu_has_serialize       boot_cpu_has(X86_FEATURE_SERIALIZE)
238 #define cpu_has_hybrid          boot_cpu_has(X86_FEATURE_HYBRID)
239 #define cpu_has_avx512_fp16     boot_cpu_has(X86_FEATURE_AVX512_FP16)
240 #define cpu_has_arch_caps       boot_cpu_has(X86_FEATURE_ARCH_CAPS)
241 
242 /* CPUID level 0x00000007:1.eax */
243 #define cpu_has_sha512          boot_cpu_has(X86_FEATURE_SHA512)
244 #define cpu_has_sm3             boot_cpu_has(X86_FEATURE_SM3)
245 #define cpu_has_sm4             boot_cpu_has(X86_FEATURE_SM4)
246 #define cpu_has_avx_vnni        boot_cpu_has(X86_FEATURE_AVX_VNNI)
247 #define cpu_has_avx512_bf16     boot_cpu_has(X86_FEATURE_AVX512_BF16)
248 #define cpu_has_cmpccxadd       boot_cpu_has(X86_FEATURE_CMPCCXADD)
249 #define cpu_has_avx_ifma        boot_cpu_has(X86_FEATURE_AVX_IFMA)
250 
251 /* CPUID level 0x80000021.eax */
252 #define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
253 #define cpu_has_verw_clear      boot_cpu_has(X86_FEATURE_VERW_CLEAR)
254 #define cpu_has_nscb            boot_cpu_has(X86_FEATURE_NSCB)
255 
256 /* CPUID level 0x00000007:1.edx */
257 #define cpu_has_avx_vnni_int8   boot_cpu_has(X86_FEATURE_AVX_VNNI_INT8)
258 #define cpu_has_avx_ne_convert  boot_cpu_has(X86_FEATURE_AVX_NE_CONVERT)
259 #define cpu_has_avx_vnni_int16  boot_cpu_has(X86_FEATURE_AVX_VNNI_INT16)
260 
261 /* MSR_ARCH_CAPS */
262 #define cpu_has_rdcl_no         boot_cpu_has(X86_FEATURE_RDCL_NO)
263 #define cpu_has_eibrs           boot_cpu_has(X86_FEATURE_EIBRS)
264 #define cpu_has_rsba            boot_cpu_has(X86_FEATURE_RSBA)
265 #define cpu_has_skip_l1dfl      boot_cpu_has(X86_FEATURE_SKIP_L1DFL)
266 #define cpu_has_mds_no          boot_cpu_has(X86_FEATURE_MDS_NO)
267 #define cpu_has_if_pschange_mc_no boot_cpu_has(X86_FEATURE_IF_PSCHANGE_MC_NO)
268 #define cpu_has_tsx_ctrl        boot_cpu_has(X86_FEATURE_TSX_CTRL)
269 #define cpu_has_taa_no          boot_cpu_has(X86_FEATURE_TAA_NO)
270 #define cpu_has_mcu_ctrl        boot_cpu_has(X86_FEATURE_MCU_CTRL)
271 #define cpu_has_doitm           boot_cpu_has(X86_FEATURE_DOITM)
272 #define cpu_has_fb_clear        boot_cpu_has(X86_FEATURE_FB_CLEAR)
273 #define cpu_has_rrsba           boot_cpu_has(X86_FEATURE_RRSBA)
274 #define cpu_has_gds_ctrl        boot_cpu_has(X86_FEATURE_GDS_CTRL)
275 #define cpu_has_gds_no          boot_cpu_has(X86_FEATURE_GDS_NO)
276 #define cpu_has_rfds_no         boot_cpu_has(X86_FEATURE_RFDS_NO)
277 #define cpu_has_rfds_clear      boot_cpu_has(X86_FEATURE_RFDS_CLEAR)
278 #define cpu_has_pb_opt_ctrl     boot_cpu_has(X86_FEATURE_PB_OPT_CTRL)
279 #define cpu_has_its_no          boot_cpu_has(X86_FEATURE_ITS_NO)
280 
281 /* CPUID level 0x80000021.ecx */
282 #define cpu_has_tsa_sq_no       boot_cpu_has(X86_FEATURE_TSA_SQ_NO)
283 #define cpu_has_tsa_l1_no       boot_cpu_has(X86_FEATURE_TSA_L1_NO)
284 
285 /* Synthesized. */
286 #define cpu_has_arch_perfmon    boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
287 #define cpu_has_cpuid_faulting  boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
288 #define cpu_has_aperfmperf      boot_cpu_has(X86_FEATURE_APERFMPERF)
289 #define cpu_has_xen_lbr         boot_cpu_has(X86_FEATURE_XEN_LBR)
290 #define cpu_has_xen_shstk       (IS_ENABLED(CONFIG_XEN_SHSTK) && \
291                                  boot_cpu_has(X86_FEATURE_XEN_SHSTK))
292 #define cpu_has_xen_ibt         (IS_ENABLED(CONFIG_XEN_IBT) && \
293                                  boot_cpu_has(X86_FEATURE_XEN_IBT))
294 
295 #define cpu_has_msr_tsc_aux     (cpu_has_rdtscp || cpu_has_rdpid)
296 
297 /* Bugs. */
298 #define cpu_bug_fpu_ptrs        boot_cpu_has(X86_BUG_FPU_PTRS)
299 #define cpu_bug_null_seg        boot_cpu_has(X86_BUG_NULL_SEG)
300 
301 enum _cache_type {
302     CACHE_TYPE_NULL = 0,
303     CACHE_TYPE_DATA = 1,
304     CACHE_TYPE_INST = 2,
305     CACHE_TYPE_UNIFIED = 3
306 };
307 
308 union _cpuid4_leaf_eax {
309     struct {
310         enum _cache_type type:5;
311         unsigned int level:3;
312         unsigned int is_self_initializing:1;
313         unsigned int is_fully_associative:1;
314         unsigned int reserved:4;
315         unsigned int num_threads_sharing:12;
316         unsigned int num_cores_on_die:6;
317     } split;
318     u32 full;
319 };
320 
321 union _cpuid4_leaf_ebx {
322     struct {
323         unsigned int coherency_line_size:12;
324         unsigned int physical_line_partition:10;
325         unsigned int ways_of_associativity:10;
326     } split;
327     u32 full;
328 };
329 
330 union _cpuid4_leaf_ecx {
331     struct {
332         unsigned int number_of_sets:32;
333     } split;
334     u32 full;
335 };
336 
337 struct cpuid4_info {
338     union _cpuid4_leaf_eax eax;
339     union _cpuid4_leaf_ebx ebx;
340     union _cpuid4_leaf_ecx ecx;
341     unsigned long size;
342 };
343 
344 int cpuid4_cache_lookup(int index, struct cpuid4_info *this_leaf);
345 #endif /* !__ASSEMBLY__ */
346 
347 #endif /* __ASM_I386_CPUFEATURE_H */
348 
349 /*
350  * Local Variables:
351  * mode:c
352  * comment-column:42
353  * End:
354  */
355