1/*
2 * Copyright (c) 2000-2006 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#ifdef __APPLE_API_PRIVATE
43
44#define	CPUID_VID_INTEL		"GenuineIntel"
45#define	CPUID_VID_AMD		"AuthenticAMD"
46
47#define CPUID_VMM_ID_VMWARE	"VMwareVMware"
48
49#define CPUID_STRING_UNKNOWN    "Unknown CPU Typ"
50
51#define _Bit(n)			(1ULL << n)
52#define _HBit(n)		(1ULL << ((n)+32))
53
54/*
55 * The CPUID_FEATURE_XXX values define 64-bit values
56 * returned in %ecx:%edx to a CPUID request with %eax of 1:
57 */
58#define CPUID_FEATURE_FPU       _Bit(0)   /* Floating point unit on-chip */
59#define CPUID_FEATURE_VME       _Bit(1)   /* Virtual Mode Extension */
60#define CPUID_FEATURE_DE        _Bit(2)   /* Debugging Extension */
61#define CPUID_FEATURE_PSE       _Bit(3)   /* Page Size Extension */
62#define CPUID_FEATURE_TSC       _Bit(4)   /* Time Stamp Counter */
63#define CPUID_FEATURE_MSR       _Bit(5)   /* Model Specific Registers */
64#define CPUID_FEATURE_PAE       _Bit(6)   /* Physical Address Extension */
65#define CPUID_FEATURE_MCE       _Bit(7)   /* Machine Check Exception */
66#define CPUID_FEATURE_CX8       _Bit(8)   /* CMPXCHG8B */
67#define CPUID_FEATURE_APIC      _Bit(9)   /* On-chip APIC */
68#define CPUID_FEATURE_SEP       _Bit(11)  /* Fast System Call */
69#define CPUID_FEATURE_MTRR      _Bit(12)  /* Memory Type Range Register */
70#define CPUID_FEATURE_PGE       _Bit(13)  /* Page Global Enable */
71#define CPUID_FEATURE_MCA       _Bit(14)  /* Machine Check Architecture */
72#define CPUID_FEATURE_CMOV      _Bit(15)  /* Conditional Move Instruction */
73#define CPUID_FEATURE_PAT       _Bit(16)  /* Page Attribute Table */
74#define CPUID_FEATURE_PSE36     _Bit(17)  /* 36-bit Page Size Extension */
75#define CPUID_FEATURE_PSN       _Bit(18)  /* Processor Serial Number */
76#define CPUID_FEATURE_CLFSH     _Bit(19)  /* CLFLUSH Instruction supported */
77#define CPUID_FEATURE_DS        _Bit(21)  /* Debug Store */
78#define CPUID_FEATURE_ACPI      _Bit(22)  /* Thermal monitor and Clock Ctrl */
79#define CPUID_FEATURE_MMX       _Bit(23)  /* MMX supported */
80#define CPUID_FEATURE_FXSR      _Bit(24)  /* Fast floating pt save/restore */
81#define CPUID_FEATURE_SSE       _Bit(25)  /* Streaming SIMD extensions */
82#define CPUID_FEATURE_SSE2      _Bit(26)  /* Streaming SIMD extensions 2 */
83#define CPUID_FEATURE_SS        _Bit(27)  /* Self-Snoop */
84#define CPUID_FEATURE_HTT       _Bit(28)  /* Hyper-Threading Technology */
85#define CPUID_FEATURE_TM        _Bit(29)  /* Thermal Monitor (TM1) */
86#define CPUID_FEATURE_PBE       _Bit(31)  /* Pend Break Enable */
87
88#define CPUID_FEATURE_SSE3      _HBit(0)  /* Streaming SIMD extensions 3 */
89#define CPUID_FEATURE_PCLMULQDQ _HBit(1)  /* PCLMULQDQ instruction */
90#define CPUID_FEATURE_DTES64    _HBit(2)  /* 64-bit DS layout */
91#define CPUID_FEATURE_MONITOR   _HBit(3)  /* Monitor/mwait */
92#define CPUID_FEATURE_DSCPL     _HBit(4)  /* Debug Store CPL */
93#define CPUID_FEATURE_VMX       _HBit(5)  /* VMX */
94#define CPUID_FEATURE_SMX       _HBit(6)  /* SMX */
95#define CPUID_FEATURE_EST       _HBit(7)  /* Enhanced SpeedsTep (GV3) */
96#define CPUID_FEATURE_TM2       _HBit(8)  /* Thermal Monitor 2 */
97#define CPUID_FEATURE_SSSE3     _HBit(9)  /* Supplemental SSE3 instructions */
98#define CPUID_FEATURE_CID       _HBit(10) /* L1 Context ID */
99#define CPUID_FEATURE_SEGLIM64  _HBit(11) /* 64-bit segment limit checking */
100#define CPUID_FEATURE_FMA       _HBit(12) /* Fused-Multiply-Add support */
101#define CPUID_FEATURE_CX16      _HBit(13) /* CmpXchg16b instruction */
102#define CPUID_FEATURE_xTPR      _HBit(14) /* Send Task PRiority msgs */
103#define CPUID_FEATURE_PDCM      _HBit(15) /* Perf/Debug Capability MSR */
104
105#define CPUID_FEATURE_PCID      _HBit(17) /* ASID-PCID support */
106#define CPUID_FEATURE_DCA       _HBit(18) /* Direct Cache Access */
107#define CPUID_FEATURE_SSE4_1    _HBit(19) /* Streaming SIMD extensions 4.1 */
108#define CPUID_FEATURE_SSE4_2    _HBit(20) /* Streaming SIMD extensions 4.2 */
109#define CPUID_FEATURE_x2APIC    _HBit(21) /* Extended APIC Mode */
110#define CPUID_FEATURE_MOVBE     _HBit(22) /* MOVBE instruction */
111#define CPUID_FEATURE_POPCNT    _HBit(23) /* POPCNT instruction */
112#define CPUID_FEATURE_TSCTMR    _HBit(24) /* TSC deadline timer */
113#define CPUID_FEATURE_AES       _HBit(25) /* AES instructions */
114#define CPUID_FEATURE_XSAVE     _HBit(26) /* XSAVE instructions */
115#define CPUID_FEATURE_OSXSAVE   _HBit(27) /* XGETBV/XSETBV instructions */
116#define CPUID_FEATURE_AVX1_0	_HBit(28) /* AVX 1.0 instructions */
117#define CPUID_FEATURE_VMM       _HBit(31) /* VMM (Hypervisor) present */
118#define CPUID_FEATURE_SEGLIM64  _HBit(11) /* 64-bit segment limit checking */
119#define CPUID_FEATURE_PCID      _HBit(17) /* ASID-PCID support */
120#define CPUID_FEATURE_TSCTMR    _HBit(24) /* TSC deadline timer */
121#define CPUID_FEATURE_AVX1_0	_HBit(28) /* AVX 1.0 instructions */
122#define CPUID_FEATURE_F16C	_HBit(29) /* Float16 convert instructions */
123#define CPUID_FEATURE_RDRAND	_HBit(30) /* RDRAND instruction */
124
125/*
126 * Leaf 7, subleaf 0 additional features.
127 * Bits returned in %ebx to a CPUID request with {%eax,%ecx} of (0x7,0x0}:
128 */
129#define CPUID_LEAF7_FEATURE_RDWRFSGS _Bit(0)	/* FS/GS base read/write */
130#define CPUID_LEAF7_FEATURE_TSCOFF   _Bit(1)	/* TSC thread offset */
131#define CPUID_LEAF7_FEATURE_BMI1     _Bit(3)	/* Bit Manipulation Instrs, set 1 */
132#define CPUID_LEAF7_FEATURE_HLE      _Bit(4)	/* Hardware Lock Elision*/
133#define CPUID_LEAF7_FEATURE_AVX2     _Bit(5)	/* AVX2 Instructions */
134#define CPUID_LEAF7_FEATURE_SMEP     _Bit(7)	/* Supervisor Mode Execute Protect */
135#define CPUID_LEAF7_FEATURE_BMI2     _Bit(8)	/* Bit Manipulation Instrs, set 2 */
136#define CPUID_LEAF7_FEATURE_ENFSTRG  _Bit(9)	/* ENhanced Fast STRinG copy */
137#define CPUID_LEAF7_FEATURE_INVPCID  _Bit(10)	/* INVPCID intruction, TDB */
138#define CPUID_LEAF7_FEATURE_RTM      _Bit(11)	/* TBD */
139
140/*
141 * The CPUID_EXTFEATURE_XXX values define 64-bit values
142 * returned in %ecx:%edx to a CPUID request with %eax of 0x80000001:
143 */
144#define CPUID_EXTFEATURE_SYSCALL   _Bit(11)	/* SYSCALL/sysret */
145#define CPUID_EXTFEATURE_XD	   _Bit(20)	/* eXecute Disable */
146
147#define CPUID_EXTFEATURE_1GBPAGE   _Bit(26)	/* 1GB pages */
148#define CPUID_EXTFEATURE_RDTSCP	   _Bit(27)	/* RDTSCP */
149#define CPUID_EXTFEATURE_EM64T	   _Bit(29)	/* Extended Mem 64 Technology */
150
151#define CPUID_EXTFEATURE_LAHF	   _HBit(0)	/* LAFH/SAHF instructions */
152
153/*
154 * The CPUID_EXTFEATURE_XXX values define 64-bit values
155 * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007:
156 */
157#define CPUID_EXTFEATURE_TSCI      _Bit(8)	/* TSC Invariant */
158
159#define	CPUID_CACHE_SIZE	16	/* Number of descriptor values */
160
161#define CPUID_MWAIT_EXTENSION	_Bit(0)	/* enumeration of WMAIT extensions */
162#define CPUID_MWAIT_BREAK	_Bit(1)	/* interrupts are break events	   */
163
164#define CPUID_MODEL_YONAH	0x0E
165#define CPUID_MODEL_MEROM	0x0F
166#define CPUID_MODEL_PENRYN	0x17
167#define CPUID_MODEL_NEHALEM	0x1A
168#define CPUID_MODEL_FIELDS	0x1E	/* Lynnfield, Clarksfield, Jasper */
169#define CPUID_MODEL_DALES	0x1F	/* Havendale, Auburndale */
170#define CPUID_MODEL_NEHALEM_EX	0x2E
171#define CPUID_MODEL_DALES_32NM	0x25	/* Clarkdale, Arrandale */
172#define CPUID_MODEL_WESTMERE	0x2C	/* Gulftown, Westmere-EP, Westmere-WS */
173#define CPUID_MODEL_WESTMERE_EX	0x2F
174#define CPUID_MODEL_SANDYBRIDGE	0x2A
175#define CPUID_MODEL_JAKETOWN	0x2D
176#define CPUID_MODEL_IVYBRIDGE	0x3A
177#define CPUID_MODEL_HASWELL	0x3C
178#define CPUID_MODEL_HASWELL_SVR	0x3F
179#define CPUID_MODEL_HASWELL_ULT	0x45
180#define CPUID_MODEL_CRYSTALWELL	0x46
181
182
183#define CPUID_VMM_FAMILY_UNKNOWN	0x0
184#define CPUID_VMM_FAMILY_VMWARE		0x1
185
186#ifndef ASSEMBLER
187#include <stdint.h>
188#include <mach/mach_types.h>
189#include <kern/kern_types.h>
190#include <mach/machine.h>
191
192
193typedef enum { eax, ebx, ecx, edx } cpuid_register_t;
194static inline void
195cpuid(uint32_t *data)
196{
197	asm("cpuid"
198		: "=a" (data[eax]),
199		  "=b" (data[ebx]),
200		  "=c" (data[ecx]),
201		  "=d" (data[edx])
202		: "a"  (data[eax]),
203		  "b"  (data[ebx]),
204		  "c"  (data[ecx]),
205		  "d"  (data[edx]));
206}
207
208static inline void
209do_cpuid(uint32_t selector, uint32_t *data)
210{
211	asm("cpuid"
212		: "=a" (data[0]),
213		  "=b" (data[1]),
214		  "=c" (data[2]),
215		  "=d" (data[3])
216		: "a"(selector),
217		  "b" (0),
218		  "c" (0),
219		  "d" (0));
220}
221
222/*
223 * Cache ID descriptor structure, used to parse CPUID leaf 2.
224 * Note: not used in kernel.
225 */
226typedef enum { Lnone, L1I, L1D, L2U, L3U, LCACHE_MAX } cache_type_t ;
227typedef struct {
228	unsigned char	value;          /* Descriptor value */
229	cache_type_t 	type;           /* Cache type */
230	unsigned int 	size;           /* Cache size */
231	unsigned int 	linesize;       /* Cache line size */
232#ifdef KERNEL
233	const char	*description;   /* Cache description */
234#endif /* KERNEL */
235} cpuid_cache_desc_t;
236
237#ifdef KERNEL
238#define CACHE_DESC(value,type,size,linesize,text) \
239	{ value, type, size, linesize, text }
240#else
241#define CACHE_DESC(value,type,size,linesize,text) \
242	{ value, type, size, linesize }
243#endif /* KERNEL */
244
245/* Monitor/mwait Leaf: */
246typedef struct {
247	uint32_t	linesize_min;
248	uint32_t	linesize_max;
249	uint32_t	extensions;
250	uint32_t	sub_Cstates;
251} cpuid_mwait_leaf_t;
252
253/* Thermal and Power Management Leaf: */
254typedef struct {
255	boolean_t	sensor;
256	boolean_t	dynamic_acceleration;
257	boolean_t	invariant_APIC_timer;
258	boolean_t	core_power_limits;
259	boolean_t	fine_grain_clock_mod;
260	boolean_t	package_thermal_intr;
261	uint32_t	thresholds;
262	boolean_t	ACNT_MCNT;
263	boolean_t	hardware_feedback;
264	boolean_t	energy_policy;
265} cpuid_thermal_leaf_t;
266
267
268/* XSAVE Feature Leaf: */
269typedef struct {
270	uint32_t	extended_state[4];	/* eax .. edx */
271} cpuid_xsave_leaf_t;
272
273
274/* Architectural Performance Monitoring Leaf: */
275typedef struct {
276	uint8_t		version;
277	uint8_t		number;
278	uint8_t		width;
279	uint8_t		events_number;
280	uint32_t	events;
281	uint8_t		fixed_number;
282	uint8_t		fixed_width;
283} cpuid_arch_perf_leaf_t;
284
285/* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */
286typedef struct {
287	char		cpuid_vendor[16];
288	char		cpuid_brand_string[48];
289	const char	*cpuid_model_string;
290
291	cpu_type_t	cpuid_type;	/* this is *not* a cpu_type_t in our <mach/machine.h> */
292	uint8_t		cpuid_family;
293	uint8_t		cpuid_model;
294	uint8_t		cpuid_extmodel;
295	uint8_t		cpuid_extfamily;
296	uint8_t		cpuid_stepping;
297	uint64_t	cpuid_features;
298	uint64_t	cpuid_extfeatures;
299	uint32_t	cpuid_signature;
300	uint8_t   	cpuid_brand;
301	uint8_t		cpuid_processor_flag;
302
303	uint32_t	cache_size[LCACHE_MAX];
304	uint32_t	cache_linesize;
305
306	uint8_t		cache_info[64];    /* list of cache descriptors */
307
308	uint32_t	cpuid_cores_per_package;
309	uint32_t	cpuid_logical_per_package;
310	uint32_t	cache_sharing[LCACHE_MAX];
311	uint32_t	cache_partitions[LCACHE_MAX];
312
313	cpu_type_t	cpuid_cpu_type;			/* <mach/machine.h> */
314	cpu_subtype_t	cpuid_cpu_subtype;		/* <mach/machine.h> */
315
316	/* Per-vendor info */
317	cpuid_mwait_leaf_t	cpuid_mwait_leaf;
318#define cpuid_mwait_linesize_max	cpuid_mwait_leaf.linesize_max
319#define cpuid_mwait_linesize_min	cpuid_mwait_leaf.linesize_min
320#define cpuid_mwait_extensions		cpuid_mwait_leaf.extensions
321#define cpuid_mwait_sub_Cstates		cpuid_mwait_leaf.sub_Cstates
322	cpuid_thermal_leaf_t	cpuid_thermal_leaf;
323	cpuid_arch_perf_leaf_t	cpuid_arch_perf_leaf;
324	cpuid_xsave_leaf_t	cpuid_xsave_leaf;
325
326	/* Cache details: */
327	uint32_t	cpuid_cache_linesize;
328	uint32_t	cpuid_cache_L2_associativity;
329	uint32_t	cpuid_cache_size;
330
331	/* Virtual and physical address aize: */
332	uint32_t	cpuid_address_bits_physical;
333	uint32_t	cpuid_address_bits_virtual;
334
335	uint32_t	cpuid_microcode_version;
336
337	/* Numbers of tlbs per processor [i|d, small|large, level0|level1] */
338	uint32_t	cpuid_tlb[2][2][2];
339			#define	TLB_INST	0
340			#define	TLB_DATA	1
341			#define	TLB_SMALL	0
342			#define	TLB_LARGE	1
343	uint32_t	cpuid_stlb;
344
345	uint32_t	core_count;
346	uint32_t	thread_count;
347
348	/* Max leaf ids available from CPUID */
349	uint32_t	cpuid_max_basic;
350	uint32_t	cpuid_max_ext;
351
352	/* Family-specific info links */
353	uint32_t		cpuid_cpufamily;
354	cpuid_mwait_leaf_t	*cpuid_mwait_leafp;
355	cpuid_thermal_leaf_t	*cpuid_thermal_leafp;
356	cpuid_arch_perf_leaf_t	*cpuid_arch_perf_leafp;
357	cpuid_xsave_leaf_t	*cpuid_xsave_leafp;
358	uint32_t		cpuid_leaf7_features;
359} i386_cpu_info_t;
360
361#ifdef MACH_KERNEL_PRIVATE
362typedef struct {
363	char		cpuid_vmm_vendor[16];
364	uint32_t	cpuid_vmm_family;
365	uint32_t	cpuid_vmm_bus_frequency;
366	uint32_t	cpuid_vmm_tsc_frequency;
367} i386_vmm_info_t;
368#endif
369
370#ifdef __cplusplus
371extern "C" {
372#endif
373
374/*
375 * External declarations
376 */
377extern cpu_type_t	cpuid_cputype(void);
378extern cpu_subtype_t	cpuid_cpusubtype(void);
379extern void		cpuid_cpu_display(const char *);
380extern void		cpuid_feature_display(const char *);
381extern void		cpuid_extfeature_display(const char *);
382extern char *		cpuid_get_feature_names(uint64_t, char *, unsigned);
383extern char *		cpuid_get_extfeature_names(uint64_t, char *, unsigned);
384extern char *		cpuid_get_leaf7_feature_names(uint64_t, char *, unsigned);
385
386extern uint64_t		cpuid_features(void);
387extern uint64_t		cpuid_extfeatures(void);
388extern uint64_t		cpuid_leaf7_features(void);
389extern uint32_t		cpuid_family(void);
390extern uint32_t		cpuid_cpufamily(void);
391
392extern void		cpuid_get_info(i386_cpu_info_t *info_p);
393extern i386_cpu_info_t	*cpuid_info(void);
394
395extern void		cpuid_set_info(void);
396
397#ifdef MACH_KERNEL_PRIVATE
398extern boolean_t	cpuid_vmm_present(void);
399extern i386_vmm_info_t	*cpuid_vmm_info(void);
400extern uint32_t		cpuid_vmm_family(void);
401#endif
402
403#ifdef __cplusplus
404}
405#endif
406
407#endif /* ASSEMBLER */
408
409#endif /* __APPLE_API_PRIVATE */
410#endif /* _MACHINE_CPUID_H_ */
411