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_SMEP     _Bit(7)	/* Supervisor Mode Execute Protect */
131#define CPUID_LEAF7_FEATURE_ENFSTRG  _Bit(9)	/* ENhanced Fast STRinG copy */
132#define CPUID_LEAF7_FEATURE_TSCOFF   _Bit(1)	/* TSC thread offset */
133#define CPUID_LEAF7_FEATURE_BMI1     _Bit(3)	/* Bit Manipulation Instrs, set 1 */
134#define CPUID_LEAF7_FEATURE_HLE      _Bit(4)	/* Hardware Lock Elision*/
135#define CPUID_LEAF7_FEATURE_AVX2     _Bit(5)	/* AVX2 Instructions */
136#define CPUID_LEAF7_FEATURE_BMI2     _Bit(8)	/* Bit Manipulation Instrs, set 2 */
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 */
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/-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#ifdef PRIVATE
178#define CPUID_MODEL_IVYBRIDGE_EP	0x3E
179#define CPUID_MODEL_CRYSTALWELL		0x46
180#endif
181#define CPUID_MODEL_HASWELL		0x3C
182#define CPUID_MODEL_HASWELL_SVR		0x3F
183#define CPUID_MODEL_HASWELL_ULT		0x45
184
185#define CPUID_VMM_FAMILY_UNKNOWN	0x0
186#define CPUID_VMM_FAMILY_VMWARE		0x1
187
188#ifndef ASSEMBLER
189#include <stdint.h>
190#include <mach/mach_types.h>
191#include <kern/kern_types.h>
192#include <mach/machine.h>
193
194
195typedef enum { eax, ebx, ecx, edx } cpuid_register_t;
196static inline void
197cpuid(uint32_t *data)
198{
199	asm("cpuid"
200		: "=a" (data[eax]),
201		  "=b" (data[ebx]),
202		  "=c" (data[ecx]),
203		  "=d" (data[edx])
204		: "a"  (data[eax]),
205		  "b"  (data[ebx]),
206		  "c"  (data[ecx]),
207		  "d"  (data[edx]));
208}
209
210static inline void
211do_cpuid(uint32_t selector, uint32_t *data)
212{
213	asm("cpuid"
214		: "=a" (data[0]),
215		  "=b" (data[1]),
216		  "=c" (data[2]),
217		  "=d" (data[3])
218		: "a"(selector),
219		  "b" (0),
220		  "c" (0),
221		  "d" (0));
222}
223
224/*
225 * Cache ID descriptor structure, used to parse CPUID leaf 2.
226 * Note: not used in kernel.
227 */
228typedef enum { Lnone, L1I, L1D, L2U, L3U, LCACHE_MAX } cache_type_t ;
229typedef struct {
230	unsigned char	value;          /* Descriptor value */
231	cache_type_t 	type;           /* Cache type */
232	unsigned int 	size;           /* Cache size */
233	unsigned int 	linesize;       /* Cache line size */
234#ifdef KERNEL
235	const char	*description;   /* Cache description */
236#endif /* KERNEL */
237} cpuid_cache_desc_t;
238
239#ifdef KERNEL
240#define CACHE_DESC(value,type,size,linesize,text) \
241	{ value, type, size, linesize, text }
242#else
243#define CACHE_DESC(value,type,size,linesize,text) \
244	{ value, type, size, linesize }
245#endif /* KERNEL */
246
247/* Monitor/mwait Leaf: */
248typedef struct {
249	uint32_t	linesize_min;
250	uint32_t	linesize_max;
251	uint32_t	extensions;
252	uint32_t	sub_Cstates;
253} cpuid_mwait_leaf_t;
254
255/* Thermal and Power Management Leaf: */
256typedef struct {
257	boolean_t	sensor;
258	boolean_t	dynamic_acceleration;
259	boolean_t	invariant_APIC_timer;
260	boolean_t	core_power_limits;
261	boolean_t	fine_grain_clock_mod;
262	boolean_t	package_thermal_intr;
263	uint32_t	thresholds;
264	boolean_t	ACNT_MCNT;
265	boolean_t	hardware_feedback;
266	boolean_t	energy_policy;
267} cpuid_thermal_leaf_t;
268
269
270/* XSAVE Feature Leaf: */
271typedef struct {
272	uint32_t	extended_state[4];	/* eax .. edx */
273} cpuid_xsave_leaf_t;
274
275
276/* Architectural Performance Monitoring Leaf: */
277typedef struct {
278	uint8_t		version;
279	uint8_t		number;
280	uint8_t		width;
281	uint8_t		events_number;
282	uint32_t	events;
283	uint8_t		fixed_number;
284	uint8_t		fixed_width;
285} cpuid_arch_perf_leaf_t;
286
287/* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */
288typedef struct {
289	char		cpuid_vendor[16];
290	char		cpuid_brand_string[48];
291	const char	*cpuid_model_string;
292
293	cpu_type_t	cpuid_type;	/* this is *not* a cpu_type_t in our <mach/machine.h> */
294	uint8_t		cpuid_family;
295	uint8_t		cpuid_model;
296	uint8_t		cpuid_extmodel;
297	uint8_t		cpuid_extfamily;
298	uint8_t		cpuid_stepping;
299	uint64_t	cpuid_features;
300	uint64_t	cpuid_extfeatures;
301	uint32_t	cpuid_signature;
302	uint8_t   	cpuid_brand;
303	uint8_t		cpuid_processor_flag;
304
305	uint32_t	cache_size[LCACHE_MAX];
306	uint32_t	cache_linesize;
307
308	uint8_t		cache_info[64];    /* list of cache descriptors */
309
310	uint32_t	cpuid_cores_per_package;
311	uint32_t	cpuid_logical_per_package;
312	uint32_t	cache_sharing[LCACHE_MAX];
313	uint32_t	cache_partitions[LCACHE_MAX];
314
315	cpu_type_t	cpuid_cpu_type;			/* <mach/machine.h> */
316	cpu_subtype_t	cpuid_cpu_subtype;		/* <mach/machine.h> */
317
318	/* Per-vendor info */
319	cpuid_mwait_leaf_t	cpuid_mwait_leaf;
320#define cpuid_mwait_linesize_max	cpuid_mwait_leaf.linesize_max
321#define cpuid_mwait_linesize_min	cpuid_mwait_leaf.linesize_min
322#define cpuid_mwait_extensions		cpuid_mwait_leaf.extensions
323#define cpuid_mwait_sub_Cstates		cpuid_mwait_leaf.sub_Cstates
324	cpuid_thermal_leaf_t	cpuid_thermal_leaf;
325	cpuid_arch_perf_leaf_t	cpuid_arch_perf_leaf;
326	cpuid_xsave_leaf_t	cpuid_xsave_leaf;
327
328	/* Cache details: */
329	uint32_t	cpuid_cache_linesize;
330	uint32_t	cpuid_cache_L2_associativity;
331	uint32_t	cpuid_cache_size;
332
333	/* Virtual and physical address aize: */
334	uint32_t	cpuid_address_bits_physical;
335	uint32_t	cpuid_address_bits_virtual;
336
337	uint32_t	cpuid_microcode_version;
338
339	/* Numbers of tlbs per processor [i|d, small|large, level0|level1] */
340	uint32_t	cpuid_tlb[2][2][2];
341			#define	TLB_INST	0
342			#define	TLB_DATA	1
343			#define	TLB_SMALL	0
344			#define	TLB_LARGE	1
345	uint32_t	cpuid_stlb;
346
347	uint32_t	core_count;
348	uint32_t	thread_count;
349
350	/* Max leaf ids available from CPUID */
351	uint32_t	cpuid_max_basic;
352	uint32_t	cpuid_max_ext;
353
354	/* Family-specific info links */
355	uint32_t		cpuid_cpufamily;
356	cpuid_mwait_leaf_t	*cpuid_mwait_leafp;
357	cpuid_thermal_leaf_t	*cpuid_thermal_leafp;
358	cpuid_arch_perf_leaf_t	*cpuid_arch_perf_leafp;
359	cpuid_xsave_leaf_t	*cpuid_xsave_leafp;
360	uint32_t		cpuid_leaf7_features;
361} i386_cpu_info_t;
362
363#ifdef MACH_KERNEL_PRIVATE
364typedef struct {
365	char		cpuid_vmm_vendor[16];
366	uint32_t	cpuid_vmm_family;
367	uint32_t	cpuid_vmm_bus_frequency;
368	uint32_t	cpuid_vmm_tsc_frequency;
369} i386_vmm_info_t;
370#endif
371
372#ifdef __cplusplus
373extern "C" {
374#endif
375
376/*
377 * External declarations
378 */
379extern cpu_type_t	cpuid_cputype(void);
380extern cpu_subtype_t	cpuid_cpusubtype(void);
381extern void		cpuid_cpu_display(const char *);
382extern void		cpuid_feature_display(const char *);
383extern void		cpuid_extfeature_display(const char *);
384extern char *		cpuid_get_feature_names(uint64_t, char *, unsigned);
385extern char *		cpuid_get_extfeature_names(uint64_t, char *, unsigned);
386extern char *		cpuid_get_leaf7_feature_names(uint64_t, char *, unsigned);
387
388extern uint64_t		cpuid_features(void);
389extern uint64_t		cpuid_extfeatures(void);
390extern uint64_t		cpuid_leaf7_features(void);
391extern uint32_t		cpuid_family(void);
392extern uint32_t		cpuid_cpufamily(void);
393
394extern i386_cpu_info_t	*cpuid_info(void);
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