xref: /xnu-8020.101.4/osfmk/i386/cpuid.h (revision e7776783b89a353188416a9a346c6cdb4928faad)
1 /*
2  * Copyright (c) 2000-2020 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 
283 #define CPUID_VMM_FAMILY_NONE           0x0
284 #define CPUID_VMM_FAMILY_UNKNOWN        0x1
285 #define CPUID_VMM_FAMILY_VMWARE         0x2
286 #define CPUID_VMM_FAMILY_PARALLELS      0x3
287 #define CPUID_VMM_FAMILY_HYVE           0x4
288 #define CPUID_VMM_FAMILY_HVF            0x5
289 #define CPUID_VMM_FAMILY_KVM            0x6
290 
291 
292 /*
293  * Apple Paravirtualization CPUID leaves
294  * The base leaf can be placed at any unused 0x100 aligned boundary
295  * in the hypervisor class leaves [0x4000_0000-0x4001_0000].
296  */
297 
298 #define APPLEPV_INTERFACE_LEAF_INDEX    1
299 #define APPLEPV_FEATURES_LEAF_INDEX     2
300 #define APPLEPV_LEAF_INDEX_MAX          APPLEPV_FEATURES_LEAF_INDEX
301 
302 #define APPLEPV_SIGNATURE               "apple-pv-xnu"
303 #define APPLEPV_INTERFACE               "AH#1"
304 
305 /*
306  *  Apple Hypercall Feature Vector:
307  *  Values in ECX:EDX returned by the base leaf
308  */
309 
310 #define CPUID_LEAF_FEATURE_COREDUMP         _Bit(0)
311 #define CPUID_LEAF_FEATURE_XNU_DEBUG        _Bit(1)
312 
313 
314 #ifndef ASSEMBLER
315 #include <stdint.h>
316 #include <mach/mach_types.h>
317 #include <kern/kern_types.h>
318 #include <mach/machine.h>
319 
320 
321 typedef enum { eax, ebx, ecx, edx } cpuid_register_t;
322 static inline void
cpuid(uint32_t * data)323 cpuid(uint32_t *data)
324 {
325 	__asm__ volatile ("cpuid"
326                 : "=a" (data[eax]),
327                   "=b" (data[ebx]),
328                   "=c" (data[ecx]),
329                   "=d" (data[edx])
330                 : "a"  (data[eax]),
331                   "b"  (data[ebx]),
332                   "c"  (data[ecx]),
333                   "d"  (data[edx]));
334 }
335 
336 static inline void
do_cpuid(uint32_t selector,uint32_t * data)337 do_cpuid(uint32_t selector, uint32_t *data)
338 {
339 	__asm__ volatile ("cpuid"
340                 : "=a" (data[0]),
341                   "=b" (data[1]),
342                   "=c" (data[2]),
343                   "=d" (data[3])
344                 : "a"(selector),
345                   "b" (0),
346                   "c" (0),
347                   "d" (0));
348 }
349 
350 /*
351  * Cache ID descriptor structure, used to parse CPUID leaf 2.
352  * Note: not used in kernel.
353  */
354 typedef enum { Lnone, L1I, L1D, L2U, L3U, LCACHE_MAX } cache_type_t;
355 typedef struct {
356 	unsigned char   value;          /* Descriptor value */
357 	cache_type_t    type;           /* Cache type */
358 	unsigned int    size;           /* Cache size */
359 	unsigned int    linesize;       /* Cache line size */
360 #ifdef KERNEL
361 	const char      *description;   /* Cache description */
362 #endif /* KERNEL */
363 } cpuid_cache_desc_t;
364 
365 #ifdef KERNEL
366 #define CACHE_DESC(value, type, size, linesize, text) \
367 	{ value, type, size, linesize, text }
368 #else
369 #define CACHE_DESC(value, type, size, linesize, text) \
370 	{ value, type, size, linesize }
371 #endif /* KERNEL */
372 
373 /* Monitor/mwait Leaf: */
374 typedef struct {
375 	uint32_t        linesize_min;
376 	uint32_t        linesize_max;
377 	uint32_t        extensions;
378 	uint32_t        sub_Cstates;
379 } cpuid_mwait_leaf_t;
380 
381 /* Thermal and Power Management Leaf: */
382 typedef struct {
383 	boolean_t       sensor;
384 	boolean_t       dynamic_acceleration;
385 	boolean_t       invariant_APIC_timer;
386 	boolean_t       core_power_limits;
387 	boolean_t       fine_grain_clock_mod;
388 	boolean_t       package_thermal_intr;
389 	uint32_t        thresholds;
390 	boolean_t       ACNT_MCNT;
391 	boolean_t       hardware_feedback;
392 	boolean_t       energy_policy;
393 } cpuid_thermal_leaf_t;
394 
395 
396 /* XSAVE Feature Leaf: */
397 typedef struct {
398 	uint32_t        extended_state[4];      /* eax .. edx */
399 } cpuid_xsave_leaf_t;
400 
401 
402 /* Architectural Performance Monitoring Leaf: */
403 typedef struct {
404 	uint8_t         version;
405 	uint8_t         number;
406 	uint8_t         width;
407 	uint8_t         events_number;
408 	uint32_t        events;
409 	uint8_t         fixed_number;
410 	uint8_t         fixed_width;
411 } cpuid_arch_perf_leaf_t;
412 
413 /* The TSC to Core Crystal (RefCLK) Clock Information leaf */
414 typedef struct {
415 	uint32_t        numerator;
416 	uint32_t        denominator;
417 } cpuid_tsc_leaf_t;
418 
419 /* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */
420 typedef struct i386_cpu_info {
421 	char            cpuid_vendor[16];
422 	char            cpuid_brand_string[48];
423 	const char      *cpuid_model_string;
424 
425 	cpu_type_t      cpuid_type;     /* this is *not* a cpu_type_t in our <mach/machine.h> */
426 	uint8_t         cpuid_family;
427 	uint8_t         cpuid_model;
428 	uint8_t         cpuid_extmodel;
429 	uint8_t         cpuid_extfamily;
430 	uint8_t         cpuid_stepping;
431 	uint64_t        cpuid_features;
432 	uint64_t        cpuid_extfeatures;
433 	uint32_t        cpuid_signature;
434 	uint8_t         cpuid_brand;
435 	uint8_t         cpuid_processor_flag;
436 
437 	uint32_t        cache_size[LCACHE_MAX];
438 	uint32_t        cache_linesize;
439 
440 	uint8_t         cache_info[64];    /* list of cache descriptors */
441 
442 	uint32_t        cpuid_cores_per_package;
443 	uint32_t        cpuid_logical_per_package;
444 	uint32_t        cache_sharing[LCACHE_MAX];
445 	uint32_t        cache_partitions[LCACHE_MAX];
446 
447 	cpu_type_t      cpuid_cpu_type;                 /* <mach/machine.h> */
448 	cpu_subtype_t   cpuid_cpu_subtype;              /* <mach/machine.h> */
449 
450 	/* Per-vendor info */
451 	cpuid_mwait_leaf_t      cpuid_mwait_leaf;
452 #define cpuid_mwait_linesize_max        cpuid_mwait_leaf.linesize_max
453 #define cpuid_mwait_linesize_min        cpuid_mwait_leaf.linesize_min
454 #define cpuid_mwait_extensions          cpuid_mwait_leaf.extensions
455 #define cpuid_mwait_sub_Cstates         cpuid_mwait_leaf.sub_Cstates
456 	cpuid_thermal_leaf_t    cpuid_thermal_leaf;
457 	cpuid_arch_perf_leaf_t  cpuid_arch_perf_leaf;
458 	uint32_t        unused[4];                      /* cpuid_xsave_leaf */
459 
460 	/* Cache details: */
461 	uint32_t        cpuid_cache_linesize;
462 	uint32_t        cpuid_cache_L2_associativity;
463 	uint32_t        cpuid_cache_size;
464 
465 	/* Virtual and physical address aize: */
466 	uint32_t        cpuid_address_bits_physical;
467 	uint32_t        cpuid_address_bits_virtual;
468 
469 	uint32_t        cpuid_microcode_version;
470 
471 	/* Numbers of tlbs per processor [i|d, small|large, level0|level1] */
472 	uint32_t        cpuid_tlb[2][2][2];
473 			#define TLB_INST        0
474 			#define TLB_DATA        1
475 			#define TLB_SMALL       0
476 			#define TLB_LARGE       1
477 	uint32_t        cpuid_stlb;
478 
479 	uint32_t        core_count;
480 	uint32_t        thread_count;
481 
482 	/* Max leaf ids available from CPUID */
483 	uint32_t        cpuid_max_basic;
484 	uint32_t        cpuid_max_ext;
485 
486 	/* Family-specific info links */
487 	uint32_t                cpuid_cpufamily;
488 	cpuid_mwait_leaf_t      *cpuid_mwait_leafp;
489 	cpuid_thermal_leaf_t    *cpuid_thermal_leafp;
490 	cpuid_arch_perf_leaf_t  *cpuid_arch_perf_leafp;
491 	cpuid_xsave_leaf_t      *cpuid_xsave_leafp;
492 	uint64_t                cpuid_leaf7_features;
493 	uint64_t                cpuid_leaf7_extfeatures;
494 	cpuid_tsc_leaf_t        cpuid_tsc_leaf;
495 	cpuid_xsave_leaf_t      cpuid_xsave_leaf[2];
496 } i386_cpu_info_t;
497 
498 #if defined(MACH_KERNEL_PRIVATE) && !defined(ASSEMBLER)
499 /* Only for 32bit values */
500 #define bit32(n)                (1U << (n))
501 #define bitmask32(h, l)          ((bit32(h)|(bit32(h)-1)) & ~(bit32(l)-1))
502 #define bitfield32(x, h, l)       ((((x) & bitmask32(h,l)) >> l))
503 
504 typedef struct {
505 	char            cpuid_vmm_vendor[16];
506 	uint32_t        cpuid_vmm_family;
507 	uint32_t        cpuid_vmm_bus_frequency;
508 	uint32_t        cpuid_vmm_tsc_frequency;
509 	uint64_t        cpuid_vmm_applepv_features;
510 } i386_vmm_info_t;
511 
512 typedef enum {
513 	CPU_INTEL_RSBST = 0,
514 	CPU_INTEL_SEGCHK = 1,
515 	CPU_INTEL_TSXFA = 2,
516 	CPU_INTEL_TSXDA = 3,
517 	CPU_INTEL_SRBDS = 4
518 } cpu_wa_e;
519 
520 typedef enum {
521 	CWA_ON = 2,
522 	CWA_FORCE_ON = 3,       /* FORCE_ON shares bit 1 so consumers can test that for ON */
523 	CWA_OFF = 4,
524 	CWA_FORCE_OFF = 5       /* Similarly for FORCE_OFF sharing bit 2 */
525 } cwa_classifier_e;
526 
527 static inline int
is_xeon_sp(uint8_t platid)528 is_xeon_sp(uint8_t platid)
529 {
530 	if (platid == PLATID_XEON_SP_1 || platid == PLATID_XEON_SP_2) {
531 		return 1;
532 	}
533 	if (platid != PLATID_MAYBE_XEON_SP) {
534 		return 0;
535 	}
536 
537 	boolean_t intrs = ml_set_interrupts_enabled(FALSE);
538 	outl(cfgAdr, XeonCapID5);
539 	uint32_t cap5reg = inl(cfgDat);
540 	ml_set_interrupts_enabled(intrs);
541 	/* Read from PCI config space 1:30:3:0x98 [bits 13:9] */
542 	if (bitfield32(cap5reg, 13, 9) == 3) {
543 		return 1;
544 	}
545 	return 0;
546 }
547 
548 extern int force_tecs_at_idle;
549 
550 #endif /* defined(MACH_KERNEL_PRIVATE) && !defined(ASSEMBLER) */
551 
552 #ifdef __cplusplus
553 extern "C" {
554 #endif
555 
556 /*
557  * External declarations
558  */
559 extern cpu_type_t       cpuid_cputype(void);
560 extern cpu_subtype_t    cpuid_cpusubtype(void);
561 extern void             cpuid_cpu_display(const char *);
562 extern void             cpuid_feature_display(const char *);
563 extern void             cpuid_extfeature_display(const char *);
564 extern char *           cpuid_get_feature_names(uint64_t, char *, unsigned);
565 extern char *           cpuid_get_extfeature_names(uint64_t, char *, unsigned);
566 extern char *           cpuid_get_leaf7_feature_names(uint64_t, char *, unsigned);
567 extern char *           cpuid_get_leaf7_extfeature_names(uint64_t, char *, unsigned);
568 
569 extern uint64_t         cpuid_features(void);
570 extern uint64_t         cpuid_extfeatures(void);
571 extern uint64_t         cpuid_leaf7_features(void);
572 extern uint64_t         cpuid_leaf7_extfeatures(void);
573 extern uint32_t         cpuid_family(void);
574 extern uint32_t         cpuid_cpufamily(void);
575 
576 extern i386_cpu_info_t  *cpuid_info(void);
577 extern void             cpuid_set_info(void);
578 extern boolean_t        cpuid_vmm_present(void);
579 extern uint32_t         cpuid_vmm_family(void);
580 extern uint64_t         cpuid_vmm_get_applepv_features(void);
581 
582 #ifdef MACH_KERNEL_PRIVATE
583 extern i386_vmm_info_t  *cpuid_vmm_info(void);
584 extern cwa_classifier_e cpuid_wa_required(cpu_wa_e wa);
585 extern void cpuid_do_was(void);
586 extern const char       *cpuid_vmm_family_string(void);
587 #endif
588 
589 #ifdef __cplusplus
590 }
591 #endif
592 
593 #endif /* ASSEMBLER */
594 
595 #endif /* __APPLE_API_PRIVATE */
596 #endif /* _MACHINE_CPUID_H_ */
597