xref: /xnu-11215/osfmk/i386/cpuid.h (revision 8d741a5d)
1 /*
2  * Copyright (c) 2000-2024 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_COPYRIGHT@
30  */
31 
32 /*
33  * x86 CPU identification
34  *
35  */
36 
37 #ifndef _MACHINE_CPUID_H_
38 #define _MACHINE_CPUID_H_
39 
40 #include <sys/appleapiopts.h>
41 
42 #if defined(MACH_KERNEL_PRIVATE) && !defined(ASSEMBLER)
43 #include <i386/hw_defs.h>
44 #include <i386/pio.h>
45 #include <i386/machine_routines.h>
46 #endif
47 
48 #ifdef __APPLE_API_PRIVATE
49 
50 #define CPUID_VID_INTEL         "GenuineIntel"
51 #define CPUID_VID_AMD           "AuthenticAMD"
52 
53 #define CPUID_VMM_ID_VMWARE     "VMwareVMware"
54 #define CPUID_VMM_ID_PARALLELS  "Parallels\0\0\0"
55 #define CPUID_VMM_ID_HYVE       "bhyve bhyve "
56 #define CPUID_VMM_ID_HVF        "HVFHVFHVFHVF"
57 #define CPUID_VMM_ID_KVM        "KVMKVMKVM\0\0\0"
58 
59 #define CPUID_STRING_UNKNOWN    "Unknown CPU Typ"
60 
61 #define _Bit(n)                 (1ULL << n)
62 #define _HBit(n)                (1ULL << ((n)+32))
63 
64 /*
65  * The CPUID_FEATURE_XXX values define 64-bit values
66  * returned in %ecx:%edx to a CPUID request with %eax of 1:
67  */
68 #define CPUID_FEATURE_FPU       _Bit(0)   /* Floating point unit on-chip */
69 #define CPUID_FEATURE_VME       _Bit(1)   /* Virtual Mode Extension */
70 #define CPUID_FEATURE_DE        _Bit(2)   /* Debugging Extension */
71 #define CPUID_FEATURE_PSE       _Bit(3)   /* Page Size Extension */
72 #define CPUID_FEATURE_TSC       _Bit(4)   /* Time Stamp Counter */
73 #define CPUID_FEATURE_MSR       _Bit(5)   /* Model Specific Registers */
74 #define CPUID_FEATURE_PAE       _Bit(6)   /* Physical Address Extension */
75 #define CPUID_FEATURE_MCE       _Bit(7)   /* Machine Check Exception */
76 #define CPUID_FEATURE_CX8       _Bit(8)   /* CMPXCHG8B */
77 #define CPUID_FEATURE_APIC      _Bit(9)   /* On-chip APIC */
78 #define CPUID_FEATURE_SEP       _Bit(11)  /* Fast System Call */
79 #define CPUID_FEATURE_MTRR      _Bit(12)  /* Memory Type Range Register */
80 #define CPUID_FEATURE_PGE       _Bit(13)  /* Page Global Enable */
81 #define CPUID_FEATURE_MCA       _Bit(14)  /* Machine Check Architecture */
82 #define CPUID_FEATURE_CMOV      _Bit(15)  /* Conditional Move Instruction */
83 #define CPUID_FEATURE_PAT       _Bit(16)  /* Page Attribute Table */
84 #define CPUID_FEATURE_PSE36     _Bit(17)  /* 36-bit Page Size Extension */
85 #define CPUID_FEATURE_PSN       _Bit(18)  /* Processor Serial Number */
86 #define CPUID_FEATURE_CLFSH     _Bit(19)  /* CLFLUSH Instruction supported */
87 #define CPUID_FEATURE_DS        _Bit(21)  /* Debug Store */
88 #define CPUID_FEATURE_ACPI      _Bit(22)  /* Thermal monitor and Clock Ctrl */
89 #define CPUID_FEATURE_MMX       _Bit(23)  /* MMX supported */
90 #define CPUID_FEATURE_FXSR      _Bit(24)  /* Fast floating pt save/restore */
91 #define CPUID_FEATURE_SSE       _Bit(25)  /* Streaming SIMD extensions */
92 #define CPUID_FEATURE_SSE2      _Bit(26)  /* Streaming SIMD extensions 2 */
93 #define CPUID_FEATURE_SS        _Bit(27)  /* Self-Snoop */
94 #define CPUID_FEATURE_HTT       _Bit(28)  /* Hyper-Threading Technology */
95 #define CPUID_FEATURE_TM        _Bit(29)  /* Thermal Monitor (TM1) */
96 #define CPUID_FEATURE_PBE       _Bit(31)  /* Pend Break Enable */
97 
98 #define CPUID_FEATURE_SSE3      _HBit(0)  /* Streaming SIMD extensions 3 */
99 #define CPUID_FEATURE_PCLMULQDQ _HBit(1)  /* PCLMULQDQ instruction */
100 #define CPUID_FEATURE_DTES64    _HBit(2)  /* 64-bit DS layout */
101 #define CPUID_FEATURE_MONITOR   _HBit(3)  /* Monitor/mwait */
102 #define CPUID_FEATURE_DSCPL     _HBit(4)  /* Debug Store CPL */
103 #define CPUID_FEATURE_VMX       _HBit(5)  /* VMX */
104 #define CPUID_FEATURE_SMX       _HBit(6)  /* SMX */
105 #define CPUID_FEATURE_EST       _HBit(7)  /* Enhanced SpeedsTep (GV3) */
106 #define CPUID_FEATURE_TM2       _HBit(8)  /* Thermal Monitor 2 */
107 #define CPUID_FEATURE_SSSE3     _HBit(9)  /* Supplemental SSE3 instructions */
108 #define CPUID_FEATURE_CID       _HBit(10) /* L1 Context ID */
109 #define CPUID_FEATURE_SEGLIM64  _HBit(11) /* 64-bit segment limit checking */
110 #define CPUID_FEATURE_FMA       _HBit(12) /* Fused-Multiply-Add support */
111 #define CPUID_FEATURE_CX16      _HBit(13) /* CmpXchg16b instruction */
112 #define CPUID_FEATURE_xTPR      _HBit(14) /* Send Task PRiority msgs */
113 #define CPUID_FEATURE_PDCM      _HBit(15) /* Perf/Debug Capability MSR */
114 
115 #define CPUID_FEATURE_PCID      _HBit(17) /* ASID-PCID support */
116 #define CPUID_FEATURE_DCA       _HBit(18) /* Direct Cache Access */
117 #define CPUID_FEATURE_SSE4_1    _HBit(19) /* Streaming SIMD extensions 4.1 */
118 #define CPUID_FEATURE_SSE4_2    _HBit(20) /* Streaming SIMD extensions 4.2 */
119 #define CPUID_FEATURE_x2APIC    _HBit(21) /* Extended APIC Mode */
120 #define CPUID_FEATURE_MOVBE     _HBit(22) /* MOVBE instruction */
121 #define CPUID_FEATURE_POPCNT    _HBit(23) /* POPCNT instruction */
122 #define CPUID_FEATURE_TSCTMR    _HBit(24) /* TSC deadline timer */
123 #define CPUID_FEATURE_AES       _HBit(25) /* AES instructions */
124 #define CPUID_FEATURE_XSAVE     _HBit(26) /* XSAVE instructions */
125 #define CPUID_FEATURE_OSXSAVE   _HBit(27) /* XGETBV/XSETBV instructions */
126 #define CPUID_FEATURE_AVX1_0    _HBit(28) /* AVX 1.0 instructions */
127 #define CPUID_FEATURE_F16C      _HBit(29) /* Float16 convert instructions */
128 #define CPUID_FEATURE_RDRAND    _HBit(30) /* RDRAND instruction */
129 #define CPUID_FEATURE_VMM       _HBit(31) /* VMM (Hypervisor) present */
130 
131 /*
132  * Leaf 7, subleaf 0 additional features.
133  * Bits returned in %ebx:%ecx to a CPUID request with {%eax,%ecx} of (0x7,0x0}:
134  */
135 #define CPUID_LEAF7_FEATURE_RDWRFSGS   _Bit(0)    /* FS/GS base read/write */
136 #define CPUID_LEAF7_FEATURE_TSCOFF     _Bit(1)    /* TSC thread offset */
137 #define CPUID_LEAF7_FEATURE_SGX        _Bit(2)    /* Software Guard eXtensions */
138 #define CPUID_LEAF7_FEATURE_BMI1       _Bit(3)    /* Bit Manipulation Instrs, set 1 */
139 #define CPUID_LEAF7_FEATURE_HLE        _Bit(4)    /* Hardware Lock Elision*/
140 #define CPUID_LEAF7_FEATURE_AVX2       _Bit(5)    /* AVX2 Instructions */
141 #define CPUID_LEAF7_FEATURE_FDPEO      _Bit(6)    /* x87 FPU Data Pointer updated only on x87 exceptions */
142 #define CPUID_LEAF7_FEATURE_SMEP       _Bit(7)    /* Supervisor Mode Execute Protect */
143 #define CPUID_LEAF7_FEATURE_BMI2       _Bit(8)    /* Bit Manipulation Instrs, set 2 */
144 #define CPUID_LEAF7_FEATURE_ERMS       _Bit(9)    /* Enhanced Rep Movsb/Stosb */
145 #define CPUID_LEAF7_FEATURE_INVPCID    _Bit(10)   /* INVPCID intruction, TDB */
146 #define CPUID_LEAF7_FEATURE_RTM        _Bit(11)   /* RTM */
147 #define CPUID_LEAF7_FEATURE_PQM        _Bit(12)   /* Platform Qos Monitoring */
148 #define CPUID_LEAF7_FEATURE_FPU_CSDS   _Bit(13)   /* FPU CS/DS deprecation */
149 #define CPUID_LEAF7_FEATURE_MPX        _Bit(14)   /* Memory Protection eXtensions */
150 #define CPUID_LEAF7_FEATURE_PQE        _Bit(15)   /* Platform Qos Enforcement */
151 #define CPUID_LEAF7_FEATURE_AVX512F    _Bit(16)   /* AVX512F instructions */
152 #define CPUID_LEAF7_FEATURE_AVX512DQ   _Bit(17)   /* AVX512DQ instructions */
153 #define CPUID_LEAF7_FEATURE_RDSEED     _Bit(18)   /* RDSEED Instruction */
154 #define CPUID_LEAF7_FEATURE_ADX        _Bit(19)   /* ADX Instructions */
155 #define CPUID_LEAF7_FEATURE_SMAP       _Bit(20)   /* Supervisor Mode Access Protect */
156 #define CPUID_LEAF7_FEATURE_AVX512IFMA _Bit(21)   /* AVX512IFMA instructions */
157 #define CPUID_LEAF7_FEATURE_CLFSOPT    _Bit(23)   /* CLFSOPT */
158 #define CPUID_LEAF7_FEATURE_CLWB       _Bit(24)   /* CLWB */
159 #define CPUID_LEAF7_FEATURE_IPT        _Bit(25)   /* Intel Processor Trace */
160 #define CPUID_LEAF7_FEATURE_AVX512CD   _Bit(28)   /* AVX512CD instructions */
161 #define CPUID_LEAF7_FEATURE_SHA        _Bit(29)   /* SHA instructions */
162 #define CPUID_LEAF7_FEATURE_AVX512BW   _Bit(30)   /* AVX512BW instructions */
163 #define CPUID_LEAF7_FEATURE_AVX512VL   _Bit(31)   /* AVX512VL instructions */
164 
165 #define CPUID_LEAF7_FEATURE_PREFETCHWT1  _HBit(0)  /* Prefetch Write/T1 hint */
166 #define CPUID_LEAF7_FEATURE_AVX512VBMI   _HBit(1)  /* AVX512VBMI instructions */
167 #define CPUID_LEAF7_FEATURE_UMIP         _HBit(2)  /* User Mode Instruction Prevention */
168 #define CPUID_LEAF7_FEATURE_PKU          _HBit(3)  /* Protection Keys for Usermode */
169 #define CPUID_LEAF7_FEATURE_OSPKE        _HBit(4)  /* OS has enabled PKE */
170 #define CPUID_LEAF7_FEATURE_WAITPKG      _HBit(5)  /* WAITPKG instructions */
171 #define CPUID_LEAF7_FEATURE_GFNI         _HBit(8)  /* Galois Field New Instructions */
172 #define CPUID_LEAF7_FEATURE_VAES         _HBit(9)  /* Vector-encoded AES */
173 #define CPUID_LEAF7_FEATURE_VPCLMULQDQ   _HBit(10) /* Vector Carryless-multiply */
174 #define CPUID_LEAF7_FEATURE_AVX512VNNI   _HBit(11) /* AVX512 Vector Neural Net Instructions */
175 #define CPUID_LEAF7_FEATURE_AVX512BITALG _HBit(12) /* AVX512 VPOPCNT{B,W} and VPSHUFBITQMB */
176 #define CPUID_LEAF7_FEATURE_AVX512VPCDQ  _HBit(14) /* AVX512 VPOPCNTDQ instruction */
177 #define CPUID_LEAF7_FEATURE_RDPID        _HBit(22) /* RDPID and IA32_TSC_AUX */
178 #define CPUID_LEAF7_FEATURE_CLDEMOTE     _HBit(25) /* Cache line demote */
179 #define CPUID_LEAF7_FEATURE_MOVDIRI      _HBit(27) /* MOVDIRI instruction */
180 #define CPUID_LEAF7_FEATURE_MOVDIRI64B   _HBit(28) /* MOVDIRI64B instruction */
181 #define CPUID_LEAF7_FEATURE_SGXLC        _HBit(30) /* SGX Launch Configuration */
182 
183 /*
184  * Values in EDX returned by CPUID Leaf 7, subleaf 0
185  */
186 #define CPUID_LEAF7_EXTFEATURE_AVX5124VNNIW     _Bit(2)         /* AVX512_4VNNIW */
187 #define CPUID_LEAF7_EXTFEATURE_AVX5124FMAPS     _Bit(3)         /* AVX512_4FMAPS */
188 #define CPUID_LEAF7_EXTFEATURE_FSREPMOV         _Bit(4)         /* Fast Short REP MOV */
189 #define CPUID_LEAF7_EXTFEATURE_SRBDS_CTRL       _Bit(9)         /* SRBDS MSR Presence and Mitigation Control */
190 #define CPUID_LEAF7_EXTFEATURE_MDCLEAR          _Bit(10)        /* Overloaded VERW / L1D_FLUSH */
191 #define CPUID_LEAF7_EXTFEATURE_TSXFA            _Bit(13)        /* TSX RTM_FORCE_ABORT MSR */
192 #define CPUID_LEAF7_EXTFEATURE_IBRS             _Bit(26)        /* IBRS / IBPB */
193 #define CPUID_LEAF7_EXTFEATURE_STIBP            _Bit(27)        /* Single Thread Indirect Branch Predictors */
194 #define CPUID_LEAF7_EXTFEATURE_L1DF             _Bit(28)        /* L1D_FLUSH MSR */
195 #define CPUID_LEAF7_EXTFEATURE_ACAPMSR          _Bit(29)        /* ARCH_CAP MSR */
196 #define CPUID_LEAF7_EXTFEATURE_CCAPMSR          _Bit(30)        /* CORE_CAP MSR */
197 #define CPUID_LEAF7_EXTFEATURE_SSBD             _Bit(31)        /* Speculative Store Bypass Disable */
198 
199 /*
200  * The CPUID_EXTFEATURE_XXX values define 64-bit values
201  * returned in %ecx:%edx to a CPUID request with %eax of 0x80000001:
202  */
203 #define CPUID_EXTFEATURE_SYSCALL   _Bit(11)     /* SYSCALL/sysret */
204 #define CPUID_EXTFEATURE_XD        _Bit(20)     /* eXecute Disable */
205 
206 #define CPUID_EXTFEATURE_1GBPAGE   _Bit(26)     /* 1GB pages */
207 #define CPUID_EXTFEATURE_RDTSCP    _Bit(27)     /* RDTSCP */
208 #define CPUID_EXTFEATURE_EM64T     _Bit(29)     /* Extended Mem 64 Technology */
209 
210 #define CPUID_EXTFEATURE_LAHF      _HBit(0)     /* LAFH/SAHF instructions */
211 #define CPUID_EXTFEATURE_LZCNT     _HBit(5)     /* LZCNT instruction */
212 #define CPUID_EXTFEATURE_PREFETCHW _HBit(8)     /* PREFETCHW instruction */
213 
214 /*
215  * The CPUID_EXTFEATURE_XXX values define 64-bit values
216  * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007:
217  */
218 #define CPUID_EXTFEATURE_TSCI      _Bit(8)      /* TSC Invariant */
219 
220 /*
221  * CPUID_X86_64_H_FEATURE_SUBSET and CPUID_X86_64_H_LEAF7_FEATURE_SUBSET
222  * indicate the bitmask of features that must be present before the system
223  * is eligible to run the "x86_64h" "Haswell feature subset" slice.
224  */
225 #define CPUID_X86_64_H_FEATURE_SUBSET ( CPUID_FEATURE_FMA    | \
226 	                                CPUID_FEATURE_SSE4_2 | \
227 	                                CPUID_FEATURE_MOVBE  | \
228 	                                CPUID_FEATURE_POPCNT | \
229 	                                CPUID_FEATURE_AVX1_0   \
230 	                              )
231 
232 #define CPUID_X86_64_H_EXTFEATURE_SUBSET ( CPUID_EXTFEATURE_LZCNT \
233 	                                 )
234 
235 #define CPUID_X86_64_H_LEAF7_FEATURE_SUBSET ( CPUID_LEAF7_FEATURE_BMI1 | \
236 	                                      CPUID_LEAF7_FEATURE_AVX2 | \
237 	                                      CPUID_LEAF7_FEATURE_BMI2   \
238 	                                    )
239 
240 #define CPUID_CACHE_SIZE        16      /* Number of descriptor values */
241 
242 #define CPUID_MWAIT_EXTENSION   _Bit(0) /* enumeration of WMAIT extensions */
243 #define CPUID_MWAIT_BREAK       _Bit(1) /* interrupts are break events	   */
244 
245 #define CPUID_MODEL_PENRYN              0x17
246 #define CPUID_MODEL_NEHALEM             0x1A
247 #define CPUID_MODEL_FIELDS              0x1E    /* Lynnfield, Clarksfield */
248 #define CPUID_MODEL_DALES               0x1F    /* Havendale, Auburndale */
249 #define CPUID_MODEL_NEHALEM_EX          0x2E
250 #define CPUID_MODEL_DALES_32NM          0x25    /* Clarkdale, Arrandale */
251 #define CPUID_MODEL_WESTMERE            0x2C    /* Gulftown, Westmere-EP/-WS */
252 #define CPUID_MODEL_WESTMERE_EX         0x2F
253 #define CPUID_MODEL_SANDYBRIDGE         0x2A
254 #define CPUID_MODEL_JAKETOWN            0x2D
255 #define CPUID_MODEL_IVYBRIDGE           0x3A
256 #define CPUID_MODEL_IVYBRIDGE_EP        0x3E
257 #define CPUID_MODEL_CRYSTALWELL         0x46
258 #define CPUID_MODEL_HASWELL             0x3C
259 #define CPUID_MODEL_HASWELL_EP          0x3F
260 #define CPUID_MODEL_HASWELL_ULT         0x45
261 #define CPUID_MODEL_BROADWELL           0x3D
262 #define CPUID_MODEL_BROADWELL_ULX       0x3D
263 #define CPUID_MODEL_BROADWELL_ULT       0x3D
264 #define CPUID_MODEL_BRYSTALWELL         0x47
265 #define CPUID_MODEL_SKYLAKE             0x4E
266 #define CPUID_MODEL_SKYLAKE_ULT         0x4E
267 #define CPUID_MODEL_SKYLAKE_ULX         0x4E
268 #define CPUID_MODEL_SKYLAKE_DT          0x5E
269 #define CPUID_MODEL_SKYLAKE_W           0x55
270 #define PLATID_XEON_SP_1                0x00
271 #define PLATID_XEON_SP_2                0x07
272 #define PLATID_MAYBE_XEON_SP            0x01
273 #define CPUID_MODEL_KABYLAKE            0x8E
274 #define CPUID_MODEL_KABYLAKE_ULT        0x8E
275 #define CPUID_MODEL_KABYLAKE_ULX        0x8E
276 #define CPUID_MODEL_KABYLAKE_DT         0x9E
277 #define CPUID_MODEL_ICELAKE             0x7E
278 #define CPUID_MODEL_ICELAKE_ULT         0x7E
279 #define CPUID_MODEL_ICELAKE_ULX         0x7E
280 #define CPUID_MODEL_ICELAKE_DT          0x7D
281 #define CPUID_MODEL_ICELAKE_H           0x9F
282 #define CPUID_MODEL_COMETLAKE_DT        0xA5
283 
284 #define CPUID_VMM_FAMILY_NONE           0x0
285 #define CPUID_VMM_FAMILY_UNKNOWN        0x1
286 #define CPUID_VMM_FAMILY_VMWARE         0x2
287 #define CPUID_VMM_FAMILY_PARALLELS      0x3
288 #define CPUID_VMM_FAMILY_HYVE           0x4
289 #define CPUID_VMM_FAMILY_HVF            0x5
290 #define CPUID_VMM_FAMILY_KVM            0x6
291 
292 /*
293  * KVM features
294  */
295 
296 #define CPUID_KVM_FEATURE_PV_UNHALT     _Bit(7)
297 
298 /*
299  * Apple Paravirtualization CPUID leaves
300  * The base leaf can be placed at any unused 0x100 aligned boundary
301  * in the hypervisor class leaves [0x4000_0000-0x4001_0000].
302  */
303 
304 #define APPLEPV_INTERFACE_LEAF_INDEX    1
305 #define APPLEPV_FEATURES_LEAF_INDEX     2
306 #define APPLEPV_LEAF_INDEX_MAX          APPLEPV_FEATURES_LEAF_INDEX
307 
308 #define APPLEPV_SIGNATURE               "apple-pv-xnu"
309 #define APPLEPV_INTERFACE               "AH#1"
310 
311 /*
312  *  Apple Hypercall Feature Vector:
313  *  Values in ECX:EDX returned by the base leaf
314  */
315 
316 #define CPUID_LEAF_FEATURE_COREDUMP         _Bit(0)
317 #define CPUID_LEAF_FEATURE_XNU_DEBUG        _Bit(1)
318 #define CPUID_LEAF_FEATURE_MABS_OFFSET      _Bit(2)
319 #define CPUID_LEAF_FEATURE_BOOTSESSIONUUID  _Bit(3)
320 
321 
322 #ifndef ASSEMBLER
323 #include <stdint.h>
324 #include <mach/mach_types.h>
325 #include <kern/kern_types.h>
326 #include <mach/machine.h>
327 
328 
329 typedef enum { eax, ebx, ecx, edx } cpuid_register_t;
330 static inline void
cpuid(uint32_t * data)331 cpuid(uint32_t *data)
332 {
333 	__asm__ volatile ("cpuid"
334                 : "=a" (data[eax]),
335                   "=b" (data[ebx]),
336                   "=c" (data[ecx]),
337                   "=d" (data[edx])
338                 : "a"  (data[eax]),
339                   "b"  (data[ebx]),
340                   "c"  (data[ecx]),
341                   "d"  (data[edx]));
342 }
343 
344 static inline void
do_cpuid(uint32_t selector,uint32_t * data)345 do_cpuid(uint32_t selector, uint32_t *data)
346 {
347 	__asm__ volatile ("cpuid"
348                 : "=a" (data[0]),
349                   "=b" (data[1]),
350                   "=c" (data[2]),
351                   "=d" (data[3])
352                 : "a"(selector),
353                   "b" (0),
354                   "c" (0),
355                   "d" (0));
356 }
357 
358 /*
359  * Cache ID descriptor structure, used to parse CPUID leaf 2.
360  * Note: not used in kernel.
361  */
362 typedef enum { Lnone, L1I, L1D, L2U, L3U, LCACHE_MAX } cache_type_t;
363 typedef struct {
364 	unsigned char   value;          /* Descriptor value */
365 	cache_type_t    type;           /* Cache type */
366 	unsigned int    size;           /* Cache size */
367 	unsigned int    linesize;       /* Cache line size */
368 #ifdef KERNEL
369 	const char      *description;   /* Cache description */
370 #endif /* KERNEL */
371 } cpuid_cache_desc_t;
372 
373 #ifdef KERNEL
374 #define CACHE_DESC(value, type, size, linesize, text) \
375 	{ value, type, size, linesize, text }
376 #else
377 #define CACHE_DESC(value, type, size, linesize, text) \
378 	{ value, type, size, linesize }
379 #endif /* KERNEL */
380 
381 /* Monitor/mwait Leaf: */
382 typedef struct {
383 	uint32_t        linesize_min;
384 	uint32_t        linesize_max;
385 	uint32_t        extensions;
386 	uint32_t        sub_Cstates;
387 } cpuid_mwait_leaf_t;
388 
389 /* Thermal and Power Management Leaf: */
390 typedef struct {
391 	boolean_t       sensor;
392 	boolean_t       dynamic_acceleration;
393 	boolean_t       invariant_APIC_timer;
394 	boolean_t       core_power_limits;
395 	boolean_t       fine_grain_clock_mod;
396 	boolean_t       package_thermal_intr;
397 	uint32_t        thresholds;
398 	boolean_t       ACNT_MCNT;
399 	boolean_t       hardware_feedback;
400 	boolean_t       energy_policy;
401 } cpuid_thermal_leaf_t;
402 
403 
404 /* XSAVE Feature Leaf: */
405 typedef struct {
406 	uint32_t        extended_state[4];      /* eax .. edx */
407 } cpuid_xsave_leaf_t;
408 
409 
410 /* Architectural Performance Monitoring Leaf: */
411 typedef struct {
412 	uint8_t         version;
413 	uint8_t         number;
414 	uint8_t         width;
415 	uint8_t         events_number;
416 	uint32_t        events;
417 	uint8_t         fixed_number;
418 	uint8_t         fixed_width;
419 } cpuid_arch_perf_leaf_t;
420 
421 /* The TSC to Core Crystal (RefCLK) Clock Information leaf */
422 typedef struct {
423 	uint32_t        numerator;
424 	uint32_t        denominator;
425 } cpuid_tsc_leaf_t;
426 
427 /* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */
428 typedef struct i386_cpu_info {
429 	char            cpuid_vendor[16];
430 	char            cpuid_brand_string[48];
431 	const char      *cpuid_model_string;
432 
433 	cpu_type_t      cpuid_type;     /* this is *not* a cpu_type_t in our <mach/machine.h> */
434 	uint8_t         cpuid_family;
435 	uint8_t         cpuid_model;
436 	uint8_t         cpuid_extmodel;
437 	uint8_t         cpuid_extfamily;
438 	uint8_t         cpuid_stepping;
439 	uint64_t        cpuid_features;
440 	uint64_t        cpuid_extfeatures;
441 	uint32_t        cpuid_signature;
442 	uint8_t         cpuid_brand;
443 	uint8_t         cpuid_processor_flag;
444 
445 	uint32_t        cache_size[LCACHE_MAX];
446 	uint32_t        cache_linesize;
447 
448 	uint8_t         cache_info[64];    /* list of cache descriptors */
449 
450 	uint32_t        cpuid_cores_per_package;
451 	uint32_t        cpuid_logical_per_package;
452 	uint32_t        cache_sharing[LCACHE_MAX];
453 	uint32_t        cache_partitions[LCACHE_MAX];
454 
455 	cpu_type_t      cpuid_cpu_type;                 /* <mach/machine.h> */
456 	cpu_subtype_t   cpuid_cpu_subtype;              /* <mach/machine.h> */
457 
458 	/* Per-vendor info */
459 	cpuid_mwait_leaf_t      cpuid_mwait_leaf;
460 #define cpuid_mwait_linesize_max        cpuid_mwait_leaf.linesize_max
461 #define cpuid_mwait_linesize_min        cpuid_mwait_leaf.linesize_min
462 #define cpuid_mwait_extensions          cpuid_mwait_leaf.extensions
463 #define cpuid_mwait_sub_Cstates         cpuid_mwait_leaf.sub_Cstates
464 	cpuid_thermal_leaf_t    cpuid_thermal_leaf;
465 	cpuid_arch_perf_leaf_t  cpuid_arch_perf_leaf;
466 	uint32_t        unused[4];                      /* cpuid_xsave_leaf */
467 
468 	/* Cache details: */
469 	uint32_t        cpuid_cache_linesize;
470 	uint32_t        cpuid_cache_L2_associativity;
471 	uint32_t        cpuid_cache_size;
472 
473 	/* Virtual and physical address aize: */
474 	uint32_t        cpuid_address_bits_physical;
475 	uint32_t        cpuid_address_bits_virtual;
476 
477 	uint32_t        cpuid_microcode_version;
478 
479 	/* Numbers of tlbs per processor [i|d, small|large, level0|level1] */
480 	uint32_t        cpuid_tlb[2][2][2];
481 			#define TLB_INST        0
482 			#define TLB_DATA        1
483 			#define TLB_SMALL       0
484 			#define TLB_LARGE       1
485 	uint32_t        cpuid_stlb;
486 
487 	uint32_t        core_count;
488 	uint32_t        thread_count;
489 
490 	/* Max leaf ids available from CPUID */
491 	uint32_t        cpuid_max_basic;
492 	uint32_t        cpuid_max_ext;
493 
494 	/* Family-specific info links */
495 	uint32_t                cpuid_cpufamily;
496 	cpuid_mwait_leaf_t      *cpuid_mwait_leafp;
497 	cpuid_thermal_leaf_t    *cpuid_thermal_leafp;
498 	cpuid_arch_perf_leaf_t  *cpuid_arch_perf_leafp;
499 	cpuid_xsave_leaf_t      *cpuid_xsave_leafp;
500 	uint64_t                cpuid_leaf7_features;
501 	uint64_t                cpuid_leaf7_extfeatures;
502 	cpuid_tsc_leaf_t        cpuid_tsc_leaf;
503 	cpuid_xsave_leaf_t      cpuid_xsave_leaf[8];
504 } i386_cpu_info_t;
505 
506 #if defined(MACH_KERNEL_PRIVATE) && !defined(ASSEMBLER)
507 /* Only for 32bit values */
508 #define bit32(n)                (1U << (n))
509 #define bitmask32(h, l)          ((bit32(h)|(bit32(h)-1)) & ~(bit32(l)-1))
510 #define bitfield32(x, h, l)       ((((x) & bitmask32(h,l)) >> l))
511 
512 typedef struct {
513 	char            cpuid_vmm_vendor[16];
514 	uint32_t        cpuid_vmm_family;
515 	uint32_t        cpuid_vmm_bus_frequency;
516 	uint32_t        cpuid_vmm_tsc_frequency;
517 	uint64_t        cpuid_vmm_applepv_features;
518 	uint64_t        cpuid_vmm_kvm_features;
519 } i386_vmm_info_t;
520 
521 typedef enum {
522 	CPU_INTEL_RSBST = 0,
523 	CPU_INTEL_SEGCHK = 1,
524 	CPU_INTEL_TSXFA = 2,
525 	CPU_INTEL_TSXDA = 3,
526 	CPU_INTEL_SRBDS = 4
527 } cpu_wa_e;
528 
529 typedef enum {
530 	CWA_ON = 2,
531 	CWA_FORCE_ON = 3,       /* FORCE_ON shares bit 1 so consumers can test that for ON */
532 	CWA_OFF = 4,
533 	CWA_FORCE_OFF = 5       /* Similarly for FORCE_OFF sharing bit 2 */
534 } cwa_classifier_e;
535 
536 static inline int
is_xeon_sp(uint8_t platid)537 is_xeon_sp(uint8_t platid)
538 {
539 	if (platid == PLATID_XEON_SP_1 || platid == PLATID_XEON_SP_2) {
540 		return 1;
541 	}
542 	if (platid != PLATID_MAYBE_XEON_SP) {
543 		return 0;
544 	}
545 
546 	boolean_t intrs = ml_set_interrupts_enabled(FALSE);
547 	outl(cfgAdr, XeonCapID5);
548 	uint32_t cap5reg = inl(cfgDat);
549 	ml_set_interrupts_enabled(intrs);
550 	/* Read from PCI config space 1:30:3:0x98 [bits 13:9] */
551 	if (bitfield32(cap5reg, 13, 9) == 3) {
552 		return 1;
553 	}
554 	return 0;
555 }
556 
557 extern int force_tecs_at_idle;
558 
559 #endif /* defined(MACH_KERNEL_PRIVATE) && !defined(ASSEMBLER) */
560 
561 #ifdef __cplusplus
562 extern "C" {
563 #endif
564 
565 /*
566  * External declarations
567  */
568 extern cpu_type_t       cpuid_cputype(void);
569 extern cpu_subtype_t    cpuid_cpusubtype(void);
570 extern void             cpuid_cpu_display(const char *);
571 extern void             cpuid_feature_display(const char *);
572 extern void             cpuid_extfeature_display(const char *);
573 extern char *           cpuid_get_feature_names(uint64_t, char *, unsigned);
574 extern char *           cpuid_get_extfeature_names(uint64_t, char *, unsigned);
575 extern char *           cpuid_get_leaf7_feature_names(uint64_t, char *, unsigned);
576 extern char *           cpuid_get_leaf7_extfeature_names(uint64_t, char *, unsigned);
577 
578 extern uint64_t         cpuid_features(void);
579 extern uint64_t         cpuid_extfeatures(void);
580 extern uint64_t         cpuid_leaf7_features(void);
581 extern uint64_t         cpuid_leaf7_extfeatures(void);
582 extern uint32_t         cpuid_family(void);
583 extern uint32_t         cpuid_cpufamily(void);
584 
585 extern i386_cpu_info_t  *cpuid_info(void);
586 extern void             cpuid_set_info(void);
587 extern boolean_t        cpuid_vmm_present(void);
588 extern uint32_t         cpuid_vmm_family(void);
589 extern uint64_t         cpuid_vmm_get_kvm_features(void);
590 extern uint64_t         cpuid_vmm_get_applepv_features(void);
591 
592 #ifdef MACH_KERNEL_PRIVATE
593 extern i386_vmm_info_t  *cpuid_vmm_info(void);
594 extern cwa_classifier_e cpuid_wa_required(cpu_wa_e wa);
595 extern void cpuid_do_was(void);
596 extern const char       *cpuid_vmm_family_string(void);
597 #endif
598 
599 #ifdef __cplusplus
600 }
601 #endif
602 
603 #endif /* ASSEMBLER */
604 
605 #endif /* __APPLE_API_PRIVATE */
606 #endif /* _MACHINE_CPUID_H_ */
607