1
/*********************************************************
2
* Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
4
* The contents of this file are subject to the terms of the Common
5
* Development and Distribution License (the "License") version 1.0
6
* and no later version. You may not use this file except in
7
* compliance with the License.
9
* You can obtain a copy of the License at
10
* http://www.opensource.org/licenses/cddl1.php
12
* See the License for the specific language governing permissions
13
* and limitations under the License.
15
*********************************************************/
20
/* http://www.sandpile.org/ia32/cpuid.htm */
22
#define INCLUDE_ALLOW_USERLEVEL
23
#define INCLUDE_ALLOW_VMX
24
#define INCLUDE_ALLOW_VMMEXT
25
#define INCLUDE_ALLOW_VMKERNEL
26
#define INCLUDE_ALLOW_MODULE
27
#define INCLUDE_ALLOW_VMNIXMOD
28
#define INCLUDE_ALLOW_DISTRIBUTE
29
#define INCLUDE_ALLOW_VMK_MODULE
30
#define INCLUDE_ALLOW_VMCORE
31
#define INCLUDE_ALLOW_VMMON
32
#include "includeCheck.h"
34
#include "vm_basic_types.h"
37
* The linux kernel's ptrace.h stupidly defines the bare
38
* EAX/EBX/ECX/EDX, which wrecks havoc with our preprocessor tricks.
45
typedef struct CPUIDRegs {
46
uint32 eax, ebx, ecx, edx;
49
typedef union CPUIDRegsUnion {
55
* Results of calling cpuid(eax, ecx) on all host logical CPU.
58
#pragma warning (disable :4200) // non-std extension: zero-sized array in struct
62
#include "vmware_pack_begin.h"
65
* Unique host logical CPU identifier. It does not change across queries, so
66
* we use it to correlate the replies of multiple queries.
70
CPUIDRegs regs; // OUT
72
#include "vmware_pack_end.h"
76
#include "vmware_pack_begin.h"
80
uint32 numLogicalCPUs; // IN/OUT
81
CPUIDReply logicalCPUs[0]; // OUT
83
#include "vmware_pack_end.h"
87
* CPUID levels the monitor caches and ones that are not cached, but
88
* have fields defined below (short name and actual value).
90
* The first parameter defines whether the level is masked/tested
91
* during power-on/migration. Any level which is marked as FALSE here
92
* *must* have all field masks defined as IGNORE in CPUID_FIELD_DATA.
93
* A static assert in lib/cpuidcompat/cpuidcompat.c will check this.
95
* IMPORTANT: WHEN ADDING A NEW FIELD TO THE CACHED LEVELS, make sure
96
* you update vmcore/vmm/cpu/priv.c:Priv_CPUID() and vmcore/vmm64/bt/
97
* cpuid_shared.S (and geninfo) to include the new level.
100
#define CPUID_CACHED_LEVELS \
101
CPUIDLEVEL(TRUE, 0, 0) \
102
CPUIDLEVEL(TRUE, 1, 1) \
103
CPUIDLEVEL(FALSE,400, 0x40000000) \
104
CPUIDLEVEL(FALSE,410, 0x40000010) \
105
CPUIDLEVEL(FALSE, 80, 0x80000000) \
106
CPUIDLEVEL(TRUE, 81, 0x80000001) \
107
CPUIDLEVEL(FALSE, 88, 0x80000008) \
108
CPUIDLEVEL(TRUE, 8A, 0x8000000A)
110
#define CPUID_UNCACHED_LEVELS \
111
CPUIDLEVEL(FALSE, 4, 4) \
112
CPUIDLEVEL(FALSE, 5, 5) \
113
CPUIDLEVEL(FALSE, 6, 6) \
114
CPUIDLEVEL(FALSE, A, 0xA) \
115
CPUIDLEVEL(FALSE, 86, 0x80000006) \
116
CPUIDLEVEL(FALSE, 87, 0x80000007) \
118
#define CPUID_ALL_LEVELS \
119
CPUID_CACHED_LEVELS \
120
CPUID_UNCACHED_LEVELS
122
/* Define cached CPUID levels in the form: CPUID_LEVEL_<ShortName> */
124
#define CPUIDLEVEL(t, s, v) CPUID_LEVEL_##s,
131
* CPUID result registers
141
#define CPUIDREG(uc, lc) CPUID_REG_##uc,
152
CPUID_VENDOR_UNKNOWN,
161
#define CPUID_INTEL_VENDOR_STRING "GenuntelineI"
162
#define CPUID_AMD_VENDOR_STRING "AuthcAMDenti"
163
#define CPUID_CYRIX_VENDOR_STRING "CyriteadxIns"
164
#define CPUID_VIA_VENDOR_STRING "CentaulsaurH"
165
#define CPUID_HYPERV_HYPERVISOR_VENDOR_STRING "Microsoft Hv"
166
#define CPUID_INTEL_VENDOR_STRING_FIXED "GenuineIntel"
167
#define CPUID_AMD_VENDOR_STRING_FIXED "AuthenticAMD"
168
#define CPUID_CYRIX_VENDOR_STRING_FIXED "CyrixInstead"
169
#define CPUID_VIA_VENDOR_STRING_FIXED "CentaurHauls"
172
* FIELDDEF can be defined to process the CPUID information provided
173
* in the following CPUID_FIELD_DATA macro. The first parameter is
174
* the CPUID level of the feature (must be defined in CPUID_*_LEVELS.
175
* The second parameter is the register the field is contained in
176
* (defined in CPUID_REGS). The third field is the vendor this
177
* feature applies to. "COMMON" means all vendors apply. UNKNOWN may
178
* not be used here. The fourth and fifth parameters are the bit
179
* position of the field and the width, respectively. The sixth is
180
* the text name of the field.
182
* The seventh and eighth parameters specify the default CPUID
183
* behavior for power-on, guest view, and migration tests (cpt/rsm &
184
* vmotion). The eighth parameter is ignored for types other than
185
* MASK & TEST, and must be zero in this case.
187
* When adding a new field, be sure to consider its purpose. The
188
* following list of types is provided in order of likely use.
190
* NOTE: this form of representation is separate from the masking
191
* system specified via the config file. That is because this
192
* representation must take into account multi-bit fields.
194
* HOST - Passthrough host value and cannot change during migration.
195
* MASK, 0 - Hide from the guest, because we don't support it or we
196
* don't want the guest to know that it exists.
197
* IGNORE - Ignore this field for all tests
199
* (Think twice before using the below mask types/combinations)
201
* MASK, x - Force the guest to always see x, and don't compare for
202
* migration -- only APIC as of today; it is controlled by
203
* software and we know how to toggle it
204
* TEST, x - Require host CPUID field to be x for power-on
205
* RSVD - Hidden from the guest, but compared during migration
208
* Table to explain mask type meanings:
210
* IGNR MASK TEST HOST RSVD
211
* --------------------------------------------------------
212
* Req'd val for power-on - - x - -
213
* Value guest sees * x * * 0
214
* Checked on migration? N N Y Y Y
216
* * - initial host's power-on CPUID value
218
* FIELDDEFA takes a ninth parameter, the name used when creating
219
* accessor functions in lib/public/cpuidInfoFuncs.h.
221
* FLAGDEF/FLAGDEFA is defined identically to fields, but their
222
* accessors are more appropriate for 1-bit flags.
226
CPUID_FIELD_MASK_IGNORE,
227
CPUID_FIELD_MASK_MASK,
228
CPUID_FIELD_MASK_TEST,
229
CPUID_FIELD_MASK_HOST,
230
CPUID_FIELD_MASK_RSVD,
231
CPUID_NUM_FIELD_MASKS
236
CPUID_FIELD_SUPPORTED_NO,
237
CPUID_FIELD_SUPPORTED_YES,
238
CPUID_FIELD_SUPPORTED_ANY,
239
CPUID_FIELD_SUPPORTED_NA,
240
CPUID_NUM_FIELD_SUPPORTEDS
241
} CpuidFieldSupported;
244
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
245
#define CPUID_FIELD_DATA_LEVEL_0 \
246
FIELDDEF( 0, EAX, COMMON, 0, 32, NUMLEVELS, ANY, IGNORE, 0, FALSE) \
247
FIELDDEF( 0, EBX, COMMON, 0, 32, VENDOR1, YES, HOST, 0, TRUE) \
248
FIELDDEF( 0, ECX, COMMON, 0, 32, VENDOR3, YES, HOST, 0, TRUE) \
249
FIELDDEF( 0, EDX, COMMON, 0, 32, VENDOR2, YES, HOST, 0, TRUE)
251
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
252
#define CPUID_FIELD_DATA_LEVEL_1 \
253
FIELDDEFA( 1, EAX, COMMON, 0, 4, STEPPING, ANY, IGNORE, 0, FALSE, STEPPING) \
254
FIELDDEFA( 1, EAX, COMMON, 4, 4, MODEL, ANY, IGNORE, 0, FALSE, MODEL) \
255
FIELDDEFA( 1, EAX, COMMON, 8, 4, FAMILY, YES, HOST, 0, FALSE, FAMILY) \
256
FIELDDEF( 1, EAX, COMMON, 12, 2, TYPE, ANY, IGNORE, 0, FALSE) \
257
FIELDDEFA( 1, EAX, COMMON, 16, 4, EXTMODEL, ANY, IGNORE, 0, FALSE, EXT_MODEL) \
258
FIELDDEFA( 1, EAX, COMMON, 20, 8, EXTFAMILY, YES, HOST, 0, FALSE, EXT_FAMILY) \
259
FIELDDEF( 1, EBX, COMMON, 0, 8, BRAND_ID, ANY, IGNORE, 0, FALSE) \
260
FIELDDEF( 1, EBX, COMMON, 8, 8, CLFL_SIZE, ANY, IGNORE, 0, FALSE) \
261
FIELDDEFA( 1, EBX, COMMON, 16, 8, LCPU_COUNT, ANY, IGNORE, 0, FALSE, LCPU_COUNT) \
262
FIELDDEFA( 1, EBX, COMMON, 24, 8, APICID, ANY, IGNORE, 0, FALSE, APICID) \
263
FLAGDEFA( 1, ECX, COMMON, 0, 1, SSE3, YES, HOST, 0, TRUE, SSE3) \
264
FLAGDEF( 1, ECX, INTEL, 2, 1, NDA2, NO, MASK, 0, FALSE) \
265
FLAGDEFA( 1, ECX, COMMON, 3, 1, MWAIT, NO, MASK, 0, FALSE, MWAIT) \
266
FLAGDEFA( 1, ECX, INTEL, 4, 1, DSCPL, NO, MASK, 0, FALSE, DSCPL) \
267
FLAGDEFA( 1, ECX, INTEL, 5, 1, VMX, NO, MASK, 0, FALSE, VMX) \
268
FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
269
FLAGDEF( 1, ECX, INTEL, 7, 1, EST, NO, MASK, 0, FALSE) \
270
FLAGDEF( 1, ECX, INTEL, 8, 1, TM2, NO, MASK, 0, FALSE) \
271
FLAGDEFA( 1, ECX, COMMON, 9, 1, SSSE3, YES, HOST, 0, TRUE, SSSE3) \
272
FLAGDEF( 1, ECX, INTEL, 10, 1, HTCACHE, NO, MASK, 0, FALSE) \
273
FLAGDEFA( 1, ECX, COMMON, 13, 1, CMPX16, YES, HOST, 0, TRUE, CMPX16) \
274
FLAGDEF( 1, ECX, INTEL, 14, 1, xPPR, NO, MASK, 0, FALSE) \
275
FLAGDEF( 1, ECX, INTEL, 15, 1, PERF_MSR, NO, MASK, 0, FALSE) \
276
FLAGDEF( 1, ECX, INTEL, 18, 1, DCA, NO, MASK, 0, FALSE) \
277
FLAGDEFA( 1, ECX, INTEL, 19, 1, SSE41, YES, HOST, 0, TRUE, SSE41) \
278
FLAGDEFA( 1, ECX, INTEL, 20, 1, SSE42, YES, HOST, 0, TRUE, SSE42) \
279
FLAGDEF( 1, ECX, INTEL, 21, 1, X2APIC, NO, MASK, 0, FALSE) \
280
FLAGDEF( 1, ECX, INTEL, 22, 1, MOVBE, NO, RSVD, 0, TRUE) \
281
FLAGDEFA( 1, ECX, COMMON, 23, 1, POPCNT, YES, HOST, 0, TRUE, POPCNT) \
282
FLAGDEF( 1, ECX, INTEL, 24, 1, ULE, NO, RSVD, 0, TRUE) \
283
FLAGDEF( 1, ECX, INTEL, 26, 1, XSAVE, NO, MASK, 0, FALSE) \
284
FLAGDEF( 1, ECX, INTEL, 27, 1, OSXSAVE, NO, RSVD, 0, TRUE) \
285
FLAGDEFA( 1, ECX, COMMON, 31, 1, HYPERVISOR, ANY, IGNORE, 0, FALSE, HYPERVISOR)\
286
FLAGDEFA( 1, EDX, COMMON, 0, 1, FPU, YES, HOST, 0, TRUE, FPU) \
287
FLAGDEFA( 1, EDX, COMMON, 1, 1, VME, YES, HOST, 0, FALSE, VME) \
288
FLAGDEF( 1, EDX, COMMON, 2, 1, DBGE, YES, HOST, 0, FALSE) \
289
FLAGDEF( 1, EDX, COMMON, 3, 1, PGSZE, YES, HOST, 0, FALSE) \
290
FLAGDEFA( 1, EDX, COMMON, 4, 1, TSC, YES, HOST, 0, TRUE, TSC) \
291
FLAGDEF( 1, EDX, COMMON, 5, 1, MSR, YES, HOST, 0, FALSE) \
292
FLAGDEFA( 1, EDX, COMMON, 6, 1, PAE, YES, HOST, 0, FALSE, PAE) \
293
FLAGDEF( 1, EDX, COMMON, 7, 1, MCK, YES, HOST, 0, FALSE) \
294
FLAGDEF( 1, EDX, COMMON, 8, 1, CPMX, YES, HOST, 0, TRUE) \
295
FLAGDEFA( 1, EDX, COMMON, 9, 1, APIC, ANY, MASK, 1, FALSE, APIC) \
296
FLAGDEFA( 1, EDX, COMMON, 11, 1, SEP, YES, HOST, 0, TRUE, SEP) \
297
FLAGDEFA( 1, EDX, COMMON, 12, 1, MTRR, YES, HOST, 0, FALSE, MTRR) \
298
FLAGDEFA( 1, EDX, COMMON, 13, 1, PGE, YES, HOST, 0, FALSE, PGE) \
299
FLAGDEFA( 1, EDX, COMMON, 14, 1, MCA, YES, HOST, 0, FALSE, MCA) \
300
FLAGDEFA( 1, EDX, COMMON, 15, 1, CMOV, YES, HOST, 0, TRUE, CMOV) \
301
FLAGDEFA( 1, EDX, COMMON, 16, 1, PAT, YES, HOST, 0, FALSE, PAT) \
302
FLAGDEF( 1, EDX, COMMON, 17, 1, 36PG, YES, HOST, 0, FALSE) \
303
FLAGDEF( 1, EDX, INTEL, 18, 1, PSN, YES, HOST, 0, FALSE) \
304
FLAGDEFA( 1, EDX, COMMON, 19, 1, CLFL, YES, HOST, 0, TRUE, CLFL) \
305
FLAGDEF( 1, EDX, INTEL, 21, 1, DTES, YES, HOST, 0, FALSE) \
306
FLAGDEF( 1, EDX, INTEL, 22, 1, ACPI, YES, HOST, 0, FALSE) \
307
FLAGDEFA( 1, EDX, COMMON, 23, 1, MMX, YES, HOST, 0, TRUE, MMX) \
308
FLAGDEFA( 1, EDX, COMMON, 24, 1, FXSAVE, YES, HOST, 0, TRUE, FXSAVE) \
309
FLAGDEFA( 1, EDX, COMMON, 25, 1, SSE, YES, HOST, 0, TRUE, SSE) \
310
FLAGDEFA( 1, EDX, COMMON, 26, 1, SSE2, YES, HOST, 0, TRUE, SSE2) \
311
FLAGDEF( 1, EDX, INTEL, 27, 1, SS, YES, HOST, 0, FALSE) \
312
FLAGDEFA( 1, EDX, COMMON, 28, 1, HT, NO, MASK, 0, FALSE, HT) \
313
FLAGDEF( 1, EDX, INTEL, 29, 1, TM, NO, MASK, 0, FALSE) \
314
FLAGDEF( 1, EDX, INTEL, 30, 1, IA64, NO, MASK, 0, FALSE) \
315
FLAGDEF( 1, EDX, INTEL, 31, 1, PBE, NO, MASK, 0, FALSE)
317
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
318
#define CPUID_FIELD_DATA_LEVEL_4 \
319
FIELDDEF( 4, EAX, INTEL, 0, 5, CACHE_TYPE, NA, IGNORE, 0, FALSE) \
320
FIELDDEF( 4, EAX, INTEL, 5, 3, CACHE_LEVEL, NA, IGNORE, 0, FALSE) \
321
FIELDDEF( 4, EAX, INTEL, 14, 12, CACHE_NUMHT_SHARING, NA, IGNORE, 0, FALSE) \
322
FIELDDEFA( 4, EAX, INTEL, 26, 6, CORE_COUNT, NA, IGNORE, 0, FALSE, INTEL_CORE_COUNT) \
323
FIELDDEF( 4, EBX, INTEL, 0, 12, CACHE_LINE, NA, IGNORE, 0, FALSE) \
324
FIELDDEF( 4, EBX, INTEL, 12, 10, CACHE_PART, NA, IGNORE, 0, FALSE) \
325
FIELDDEF( 4, EBX, INTEL, 22, 10, CACHE_WAYS, NA, IGNORE, 0, FALSE)
327
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
328
#define CPUID_FIELD_DATA_LEVEL_5 \
329
FIELDDEF( 5, EAX, COMMON, 0, 16, MWAIT_MIN_SIZE, NA, IGNORE, 0, FALSE) \
330
FIELDDEF( 5, EBX, COMMON, 0, 16, MWAIT_MAX_SIZE, NA, IGNORE, 0, FALSE) \
331
FLAGDEF( 5, ECX, COMMON, 0, 1, MWAIT_EXTENSIONS, NA, IGNORE, 0, FALSE) \
332
FLAGDEF( 5, ECX, COMMON, 1, 1, MWAIT_INTR_BREAK, NA, IGNORE, 0, FALSE) \
333
FIELDDEF( 5, EDX, INTEL, 0, 4, MWAIT_C0_SUBSTATE, NA, IGNORE, 0, FALSE) \
334
FIELDDEF( 5, EDX, INTEL, 4, 4, MWAIT_C1_SUBSTATE, NA, IGNORE, 0, FALSE) \
335
FIELDDEF( 5, EDX, INTEL, 8, 4, MWAIT_C2_SUBSTATE, NA, IGNORE, 0, FALSE) \
336
FIELDDEF( 5, EDX, INTEL, 12, 4, MWAIT_C3_SUBSTATE, NA, IGNORE, 0, FALSE) \
337
FIELDDEF( 5, EDX, INTEL, 16, 4, MWAIT_C4_SUBSTATE, NA, IGNORE, 0, FALSE)
339
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
340
#define CPUID_FIELD_DATA_LEVEL_6 \
341
FLAGDEF( 6, EAX, INTEL, 0, 1, THERMAL_SENSOR, NA, IGNORE, 0, FALSE) \
342
FLAGDEF( 6, EAX, INTEL, 1, 1, TURBO_MODE, NA, IGNORE, 0, FALSE) \
343
FIELDDEF( 6, EBX, INTEL, 0, 4, NUM_INTR_THRESHOLDS, NA, IGNORE, 0, FALSE) \
344
FLAGDEF( 6, ECX, INTEL, 0, 1, HW_COORD_FEEDBACK, NA, IGNORE, 0, FALSE)
346
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
347
#define CPUID_FIELD_DATA_LEVEL_A \
348
FIELDDEFA( A, EAX, INTEL, 0, 8, PMC_VERSION, NA, IGNORE, 0, FALSE, PMC_VERSION) \
349
FIELDDEFA( A, EAX, INTEL, 8, 8, NUM_PMCS, NA, IGNORE, 0, FALSE, NUM_PMCS) \
350
FIELDDEF( A, EAX, INTEL, 16, 8, PMC_BIT_WIDTH, NA, IGNORE, 0, FALSE) \
351
FIELDDEFA( A, EAX, INTEL, 24, 8, PMC_EBX_LENGTH, NA, IGNORE, 0, FALSE, PMC_EBX_LENGTH) \
352
FLAGDEF( A, EBX, INTEL, 0, 1, PMC_CORE_CYCLE, NA, IGNORE, 0, FALSE) \
353
FLAGDEF( A, EBX, INTEL, 1, 1, PMC_INSTR_RETIRED, NA, IGNORE, 0, FALSE) \
354
FLAGDEF( A, EBX, INTEL, 2, 1, PMC_REF_CYCLES, NA, IGNORE, 0, FALSE) \
355
FLAGDEF( A, EBX, INTEL, 3, 1, PMC_LAST_LVL_CREF, NA, IGNORE, 0, FALSE) \
356
FLAGDEF( A, EBX, INTEL, 4, 1, PMC_LAST_LVL_CMISS, NA, IGNORE, 0, FALSE) \
357
FLAGDEF( A, EBX, INTEL, 5, 1, PMC_BR_INST_RETIRED, NA, IGNORE, 0, FALSE) \
358
FLAGDEF( A, EBX, INTEL, 6, 1, PMC_BR_MISS_RETIRED, NA, IGNORE, 0, FALSE) \
359
FIELDDEF( A, EDX, INTEL, 0, 5, PMC_FIXED_NUM, NA, IGNORE, 0, FALSE) \
360
FIELDDEF( A, EDX, INTEL, 5, 8, PMC_FIXED_SIZE, NA, IGNORE, 0, FALSE)
362
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
363
#define CPUID_FIELD_DATA_LEVEL_80 \
364
FIELDDEF( 80, EAX, COMMON, 0, 32, NUM_EXT_LEVELS, NA, IGNORE, 0, FALSE) \
365
FIELDDEF( 80, EBX, AMD, 0, 32, AMD_VENDOR1, NA, IGNORE, 0, FALSE) \
366
FIELDDEF( 80, ECX, AMD, 0, 32, AMD_VENDOR3, NA, IGNORE, 0, FALSE) \
367
FIELDDEF( 80, EDX, AMD, 0, 32, AMD_VENDOR2, NA, IGNORE, 0, FALSE)
369
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
370
#define CPUID_FIELD_DATA_LEVEL_81 \
371
FIELDDEF( 81, EAX, INTEL, 0, 32, UNKNOWN81EAX, ANY, IGNORE, 0, FALSE) \
372
FIELDDEF( 81, EAX, AMD, 0, 4, STEPPING, ANY, IGNORE, 0, FALSE) \
373
FIELDDEF( 81, EAX, AMD, 4, 4, MODEL, ANY, IGNORE, 0, FALSE) \
374
FIELDDEF( 81, EAX, AMD, 8, 4, FAMILY, ANY, IGNORE, 0, FALSE) \
375
FIELDDEF( 81, EAX, AMD, 12, 2, TYPE, ANY, IGNORE, 0, FALSE) \
376
FIELDDEF( 81, EAX, AMD, 16, 4, EXTMODEL, ANY, IGNORE, 0, FALSE) \
377
FIELDDEF( 81, EAX, AMD, 20, 8, EXTFAMILY, ANY, IGNORE, 0, FALSE) \
378
FIELDDEF( 81, EBX, INTEL, 0, 32, UNKNOWN81EBX, ANY, IGNORE, 0, FALSE) \
379
FIELDDEF( 81, EBX, AMD, 0, 16, BRAND_ID, ANY, IGNORE, 0, FALSE) \
380
FIELDDEF( 81, EBX, AMD, 16, 16, UNDEF, ANY, IGNORE, 0, FALSE) \
381
FLAGDEFA( 81, ECX, COMMON, 0, 1, LAHF, YES, HOST, 0, TRUE, LAHF64) \
382
FLAGDEFA( 81, ECX, AMD, 1, 1, CMPLEGACY, NO, MASK, 0, FALSE, CMPLEGACY) \
383
FLAGDEFA( 81, ECX, AMD, 2, 1, SVM, NO, MASK, 0, FALSE, SVM) \
384
FLAGDEFA( 81, ECX, AMD, 3, 1, EXTAPICSPC, YES, HOST, 0, FALSE, EXTAPICSPC) \
385
FLAGDEFA( 81, ECX, AMD, 4, 1, CR8AVAIL, NO, MASK, 0, FALSE, CR8AVAIL) \
386
FLAGDEFA( 81, ECX, AMD, 5, 1, ABM, YES, HOST, 0, TRUE, ABM) \
387
FLAGDEFA( 81, ECX, AMD, 6, 1, SSE4A, YES, HOST, 0, TRUE, SSE4A) \
388
FLAGDEF( 81, ECX, AMD, 7, 1, MISALIGNED_SSE, YES, HOST, 0, TRUE) \
389
FLAGDEFA( 81, ECX, AMD, 8, 1, 3DNPREFETCH, YES, HOST, 0, TRUE, 3DNPREFETCH) \
390
FLAGDEF( 81, ECX, AMD, 9, 1, OSVW, NO, MASK, 0, FALSE) \
391
FLAGDEF( 81, ECX, AMD, 10, 1, IBS, NO, MASK, 0, FALSE) \
392
FLAGDEF( 81, ECX, AMD, 11, 1, SSE5, NO, RSVD, 0, TRUE) \
393
FLAGDEF( 81, ECX, AMD, 12, 1, SKINIT, NO, MASK, 0, FALSE) \
394
FLAGDEF( 81, ECX, AMD, 13, 1, WATCHDOG, NO, MASK, 0, FALSE) \
395
FLAGDEF( 81, EDX, AMD, 0, 1, FPU, YES, HOST, 0, TRUE) \
396
FLAGDEF( 81, EDX, AMD, 1, 1, VME, YES, HOST, 0, FALSE) \
397
FLAGDEF( 81, EDX, AMD, 2, 1, DBGE, YES, HOST, 0, FALSE) \
398
FLAGDEF( 81, EDX, AMD, 3, 1, PGSZE, YES, HOST, 0, FALSE) \
399
FLAGDEF( 81, EDX, AMD, 4, 1, TSC, YES, HOST, 0, TRUE) \
400
FLAGDEF( 81, EDX, AMD, 5, 1, MSR, YES, HOST, 0, FALSE) \
401
FLAGDEF( 81, EDX, AMD, 6, 1, PAE, YES, HOST, 0, FALSE) \
402
FLAGDEF( 81, EDX, AMD, 7, 1, MCK, YES, HOST, 0, FALSE) \
403
FLAGDEF( 81, EDX, AMD, 8, 1, CPMX, YES, HOST, 0, TRUE) \
404
FLAGDEF( 81, EDX, AMD, 9, 1, APIC, ANY, MASK, 1, FALSE) \
405
FLAGDEFA( 81, EDX, COMMON, 11, 1, SYSC, ANY, IGNORE, 0, TRUE, SYSC) \
406
FLAGDEF( 81, EDX, AMD, 12, 1, MTRR, YES, HOST, 0, FALSE) \
407
FLAGDEF( 81, EDX, AMD, 13, 1, PGE, YES, HOST, 0, FALSE) \
408
FLAGDEF( 81, EDX, AMD, 14, 1, MCA, YES, HOST, 0, FALSE) \
409
FLAGDEF( 81, EDX, AMD, 15, 1, CMOV, YES, HOST, 0, TRUE) \
410
FLAGDEF( 81, EDX, AMD, 16, 1, PAT, YES, HOST, 0, FALSE) \
411
FLAGDEF( 81, EDX, AMD, 17, 1, 36PG, YES, HOST, 0, FALSE) \
412
FLAGDEFA( 81, EDX, COMMON, 20, 1, NX, YES, HOST, 0, FALSE, NX) \
413
FLAGDEFA( 81, EDX, AMD, 22, 1, MMXEXT, YES, HOST, 0, TRUE, MMXEXT) \
414
FLAGDEF( 81, EDX, AMD, 23, 1, MMX, YES, HOST, 0, TRUE) \
415
FLAGDEF( 81, EDX, AMD, 24, 1, FXSAVE, YES, HOST, 0, TRUE) \
416
FLAGDEFA( 81, EDX, AMD, 25, 1, FFXSR, YES, HOST, 0, FALSE, FFXSR) \
417
FLAGDEF( 81, EDX, AMD, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
418
FLAGDEFA( 81, EDX, COMMON, 27, 1, RDTSCP, YES, HOST, 0, TRUE, RDTSCP) \
419
FLAGDEFA( 81, EDX, COMMON, 29, 1, LM, YES, TEST, 1, FALSE, LM) \
420
FLAGDEFA( 81, EDX, AMD, 30, 1, 3DNOWPLUS, YES, HOST, 0, TRUE, 3DNOWPLUS) \
421
FLAGDEFA( 81, EDX, AMD, 31, 1, 3DNOW, YES, HOST, 0, TRUE, 3DNOW)
423
/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
424
#define CPUID_FIELD_DATA_LEVEL_8x \
425
FIELDDEF( 86, ECX, AMD, 0, 8, L2CACHE_LINE, NA, IGNORE, 0, FALSE) \
426
FIELDDEF( 86, ECX, AMD, 8, 4, L2CACHE_LINE_PER_TAG, NA, IGNORE, 0, FALSE) \
427
FIELDDEF( 86, ECX, AMD, 12, 4, L2CACHE_WAYS, NA, IGNORE, 0, FALSE) \
428
FIELDDEF( 86, ECX, AMD, 16, 16, L2CACHE_SIZE, NA, IGNORE, 0, FALSE) \
429
FIELDDEF( 86, EDX, AMD, 0, 8, L3CACHE_LINE, NA, IGNORE, 0, FALSE) \
430
FIELDDEF( 86, EDX, AMD, 8, 4, L3CACHE_LINE_PER_TAG,NA, IGNORE, 0, FALSE) \
431
FIELDDEF( 86, EDX, AMD, 12, 4, L3CACHE_WAYS, NA, IGNORE, 0, FALSE) \
432
FIELDDEF( 86, EDX, AMD, 18, 14, L3CACHE_SIZE, NA, IGNORE, 0, FALSE) \
433
FLAGDEF( 87, EDX, AMD, 0, 1, TS, NA, IGNORE, 0, FALSE) \
434
FLAGDEF( 87, EDX, AMD, 1, 1, FID, NA, IGNORE, 0, FALSE) \
435
FLAGDEF( 87, EDX, AMD, 2, 1, VID, NA, IGNORE, 0, FALSE) \
436
FLAGDEF( 87, EDX, AMD, 3, 1, TTP, NA, IGNORE, 0, FALSE) \
437
FLAGDEF( 87, EDX, AMD, 4, 1, TM, NA, IGNORE, 0, FALSE) \
438
FLAGDEF( 87, EDX, AMD, 5, 1, STC, NA, IGNORE, 0, FALSE) \
439
FLAGDEF( 87, EDX, AMD, 6, 1, 100MHZSTEPS, NA, IGNORE, 0, FALSE) \
440
FLAGDEF( 87, EDX, AMD, 7, 1, HWPSTATE, NA, IGNORE, 0, FALSE) \
441
FLAGDEF( 87, EDX, COMMON, 8, 1, TSC_INVARIANT, NA, IGNORE, 0, FALSE) \
442
FIELDDEFA(88, EAX, COMMON, 0, 8, PHYSBITS, NA, IGNORE, 0, FALSE, PHYS_BITS) \
443
FIELDDEFA(88, EAX, COMMON, 8, 8, VIRTBITS, NA, IGNORE, 0, FALSE, VIRT_BITS) \
444
FIELDDEFA(88, ECX, AMD, 0, 8, CORE_COUNT, NA, IGNORE, 0, FALSE, AMD_CORE_COUNT) \
445
FIELDDEFA(88, ECX, AMD, 12, 4, APICID_COREID_SIZE, NA, IGNORE, 0, FALSE, AMD_APICID_COREID_SIZE) \
446
FIELDDEFA(8A, EAX, AMD, 0, 8, SVM_REVISION, NO, MASK, 0, FALSE, SVM_REVISION) \
447
FLAGDEF( 8A, EAX, AMD, 8, 1, SVM_HYPERVISOR, NO, MASK, 0, FALSE) \
448
FIELDDEF( 8A, EAX, AMD, 9, 23, SVMEAX_RSVD, NO, MASK, 0, FALSE) \
449
FIELDDEF( 8A, EBX, AMD, 0, 32, SVM_N_ASIDS, NO, MASK, 0, FALSE) \
450
FIELDDEF( 8A, ECX, AMD, 0, 32, SVMECX_RSVD, NO, MASK, 0, FALSE) \
451
FLAGDEFA( 8A, EDX, AMD, 0, 1, SVM_NP, NO, MASK, 0, FALSE, NPT) \
452
FLAGDEF( 8A, EDX, AMD, 1, 1, SVM_LBR, NO, MASK, 0, FALSE) \
453
FLAGDEF( 8A, EDX, AMD, 2, 1, SVM_LOCK, NO, MASK, 0, FALSE) \
454
FLAGDEF( 8A, EDX, AMD, 3, 1, SVM_NRIP, NO, MASK, 0, FALSE) \
455
FIELDDEF( 8A, EDX, AMD, 4, 28, SVMEDX_RSVD, NO, MASK, 0, FALSE)
457
#define CPUID_FIELD_DATA \
458
CPUID_FIELD_DATA_LEVEL_0 \
459
CPUID_FIELD_DATA_LEVEL_1 \
460
CPUID_FIELD_DATA_LEVEL_4 \
461
CPUID_FIELD_DATA_LEVEL_5 \
462
CPUID_FIELD_DATA_LEVEL_6 \
463
CPUID_FIELD_DATA_LEVEL_A \
464
CPUID_FIELD_DATA_LEVEL_80 \
465
CPUID_FIELD_DATA_LEVEL_81 \
466
CPUID_FIELD_DATA_LEVEL_8x
469
* Define all field and flag values as an enum. The result is a full
470
* set of values taken from the table above in the form:
472
* CPUID_FEATURE_<vendor>_ID<level><reg>_<name> == mask for feature
473
* CPUID_<vendor>_ID<level><reg>_<name>_MASK == mask for field
474
* CPUID_<vendor>_ID<level><reg>_<name>_SHIFT == offset of field
476
* e.g. - CPUID_FEATURE_COMMON_ID1EDX_FPU = 0x1
477
* - CPUID_COMMON_ID88EAX_VIRTBITS_MASK = 0xff00
478
* - CPUID_COMMON_ID88EAX_VIRTBITS_SHIFT = 8
480
* Note: The FEATURE/MASK definitions must use some gymnastics to get
481
* around a warning when shifting left by 32.
483
#define VMW_BIT_MASK(shift) (((1 << (shift - 1)) << 1) - 1)
485
#define FIELDDEF(lvl, reg, vend, bitpos, size, name, s, m, v, c3) \
486
CPUID_##vend##_ID##lvl##reg##_##name##_SHIFT = bitpos, \
487
CPUID_##vend##_ID##lvl##reg##_##name##_MASK = \
488
VMW_BIT_MASK(size) << bitpos, \
489
CPUID_FEATURE_##vend##_ID##lvl##reg##_##name = \
490
CPUID_##vend##_ID##lvl##reg##_##name##_MASK,
492
/* Before simplifying this take a look at bug 293638... */
493
#define FIELDDEFA(lvl, reg, vend, bitpos, size, name, s, m, v, c3, f) \
494
CPUID_##vend##_ID##lvl##reg##_##name##_SHIFT = bitpos, \
495
CPUID_##vend##_ID##lvl##reg##_##name##_MASK = \
496
VMW_BIT_MASK(size) << bitpos, \
497
CPUID_FEATURE_##vend##_ID##lvl##reg##_##name = \
498
CPUID_##vend##_ID##lvl##reg##_##name##_MASK,
500
#define FLAGDEFA FIELDDEFA
501
#define FLAGDEF FIELDDEF
504
/* Define data for every CPUID field we have */
514
* Legal CPUID config file mask characters. For a description of the
515
* cpuid masking system, please see:
517
* http://vmweb.vmware.com/~mts/cgi-bin/view.cgi/Apps/CpuMigrationChecks
520
#define CPUID_MASK_HIDE_CHR '0'
521
#define CPUID_MASK_HIDE_STR "0"
522
#define CPUID_MASK_FORCE_CHR '1'
523
#define CPUID_MASK_FORCE_STR "1"
524
#define CPUID_MASK_PASS_CHR '-'
525
#define CPUID_MASK_PASS_STR "-"
526
#define CPUID_MASK_TRUE_CHR 'T'
527
#define CPUID_MASK_TRUE_STR "T"
528
#define CPUID_MASK_FALSE_CHR 'F'
529
#define CPUID_MASK_FALSE_STR "F"
530
#define CPUID_MASK_IGNORE_CHR 'X'
531
#define CPUID_MASK_IGNORE_STR "X"
532
#define CPUID_MASK_HOST_CHR 'H'
533
#define CPUID_MASK_HOST_STR "H"
534
#define CPUID_MASK_RSVD_CHR 'R'
535
#define CPUID_MASK_RSVD_STR "R"
536
#define CPUID_MASK_INSTALL_CHR 'I'
537
#define CPUID_MASK_INSTALL_STR "I"
540
* If a level is listed as not masked/tested in CPUID_LEVELS above,
541
* use all "don't care" values for its mask.
544
#define CPT_DFLT_UNDEFINED_MASK "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX"
547
* When LM is disabled, we overlay the following masks onto the
548
* guest's default masks. Any level that is not defined below should
549
* be treated as all "-"s
552
#define CPT_ID1ECX_LM_DISABLED "----:----:----:----:--0-:----:----:----"
553
#define CPT_ID81EDX_LM_DISABLED "--0-:----:----:----:----:----:----:----"
554
#define CPT_ID81ECX_LM_DISABLED "----:----:----:----:----:----:----:---0"
556
#define CPT_GET_LM_DISABLED_MASK(lvl, reg) \
557
((lvl == 1 && reg == CPUID_REG_ECX) ? CPT_ID1ECX_LM_DISABLED : \
558
(lvl == 0x80000001 && reg == CPUID_REG_ECX) ? CPT_ID81ECX_LM_DISABLED : \
559
(lvl == 0x80000001 && reg == CPUID_REG_EDX) ? CPT_ID81EDX_LM_DISABLED : \
563
* Macro to define GET and SET functions for various common CPUID
564
* fields. To create function for a new field, simply name it (CPUID_
565
* and CPUID_SET_ are automatically prepended), and list the field
566
* name that it needs to use.
569
#define FIELD_FUNC(name, field) \
570
static INLINE uint32 CPUID_##name(uint32 reg) \
572
return (reg & field##_MASK) >> field##_SHIFT; \
574
static INLINE void CPUID_SET_##name(uint32 *reg, uint32 val) \
576
*reg = (*reg & ~field##_MASK) | (val << field##_SHIFT); \
579
FIELD_FUNC(STEPPING, CPUID_COMMON_ID1EAX_STEPPING)
580
FIELD_FUNC(MODEL, CPUID_COMMON_ID1EAX_MODEL)
581
FIELD_FUNC(FAMILY, CPUID_COMMON_ID1EAX_FAMILY)
582
FIELD_FUNC(TYPE, CPUID_COMMON_ID1EAX_TYPE)
583
FIELD_FUNC(EXTENDED_MODEL, CPUID_COMMON_ID1EAX_EXTMODEL)
584
FIELD_FUNC(EXTENDED_FAMILY, CPUID_COMMON_ID1EAX_EXTFAMILY)
585
FIELD_FUNC(LCPU_COUNT, CPUID_COMMON_ID1EBX_LCPU_COUNT)
586
FIELD_FUNC(APICID, CPUID_COMMON_ID1EBX_APICID)
587
FIELD_FUNC(PA_BITS, CPUID_COMMON_ID88EAX_PHYSBITS)
588
FIELD_FUNC(VIRT_BITS, CPUID_COMMON_ID88EAX_VIRTBITS)
589
FIELD_FUNC(SVM_REVISION, CPUID_AMD_ID8AEAX_SVM_REVISION)
590
FIELD_FUNC(SVM_N_ASIDS, CPUID_AMD_ID8AEBX_SVM_N_ASIDS)
591
FIELD_FUNC(INTEL_CORE_COUNT, CPUID_INTEL_ID4EAX_CORE_COUNT)
592
FIELD_FUNC(AMD_CORE_COUNT, CPUID_AMD_ID88ECX_CORE_COUNT)
593
FIELD_FUNC(AMD_APICID_COREID_SIZE, CPUID_AMD_ID88ECX_APICID_COREID_SIZE)
594
FIELD_FUNC(AMD_EXTAPICSPC, CPUID_AMD_ID81ECX_EXTAPICSPC)
595
FIELD_FUNC(NUM_PMCS, CPUID_INTEL_IDAEAX_NUM_PMCS)
596
FIELD_FUNC(MWAIT_MIN_SIZE, CPUID_COMMON_ID5EAX_MWAIT_MIN_SIZE)
597
FIELD_FUNC(MWAIT_MAX_SIZE, CPUID_COMMON_ID5EBX_MWAIT_MAX_SIZE)
598
FIELD_FUNC(MWAIT_C0_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C0_SUBSTATE)
599
FIELD_FUNC(MWAIT_C1_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C1_SUBSTATE)
600
FIELD_FUNC(MWAIT_C2_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C2_SUBSTATE)
601
FIELD_FUNC(MWAIT_C3_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C3_SUBSTATE)
602
FIELD_FUNC(MWAIT_C4_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C4_SUBSTATE)
607
* Definitions of various fields' values and more complicated
608
* macros/functions for reading cpuid fields.
611
/* Effective Intel CPU Families */
612
#define CPUID_FAMILY_486 4
613
#define CPUID_FAMILY_P5 5
614
#define CPUID_FAMILY_P6 6
615
#define CPUID_FAMILY_P4 15
617
/* Effective AMD CPU Families */
618
#define CPUID_FAMILY_5x86 4
619
#define CPUID_FAMILY_K5 5
620
#define CPUID_FAMILY_K6 5
621
#define CPUID_FAMILY_K7 6
622
#define CPUID_FAMILY_K8 15
623
#define CPUID_FAMILY_K8L 16
624
#define CPUID_FAMILY_K8MOBILE 17
625
#define CPUID_FAMILY_EXTENDED 15
627
/* Intel model information */
628
#define CPUID_MODEL_PPRO 1
629
#define CPUID_MODEL_PII_03 3
630
#define CPUID_MODEL_PII_05 5
631
#define CPUID_MODEL_CELERON_06 6
632
#define CPUID_MODEL_PM_09 9
633
#define CPUID_MODEL_PM_0D 13
634
#define CPUID_MODEL_PM_0E 14 // Yonah / Sossaman
635
#define CPUID_MODEL_CORE_0F 15 // Conroe / Merom
636
#define CPUID_MODEL_CORE_17 0x17 // Penryn
637
#define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown
638
#define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville
639
#define CPUID_MODEL_CORE_1D 0x1d // Dunnington
640
#define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield
642
#define CPUID_MODEL_PIII_07 7
643
#define CPUID_MODEL_PIII_08 8
644
#define CPUID_MODEL_PIII_0A 10
646
/* AMD model information */
647
#define CPUID_MODEL_BARCELONA_02 0x02 // Barcelona (both Opteron & Phenom kind)
650
*----------------------------------------------------------------------
652
* CPUID_IsVendor{AMD,Intel} --
654
* Determines if the vendor string in cpuid id0 is from {AMD,Intel}.
657
* True iff vendor string is CPUID_{AMD,INTEL}_VENDOR_STRING
662
*----------------------------------------------------------------------
665
CPUID_IsRawVendor(CPUIDRegs *id0, const char* vendor)
667
// hard to get strcmp() in some environments, so do it in the raw
668
return (id0->ebx == *(const uint32 *) (vendor + 0) &&
669
id0->ecx == *(const uint32 *) (vendor + 4) &&
670
id0->edx == *(const uint32 *) (vendor + 8));
674
CPUID_IsVendorAMD(CPUIDRegs *id0)
676
return CPUID_IsRawVendor(id0, CPUID_AMD_VENDOR_STRING);
680
CPUID_IsVendorIntel(CPUIDRegs *id0)
682
return CPUID_IsRawVendor(id0, CPUID_INTEL_VENDOR_STRING);
687
CPUID_EFFECTIVE_FAMILY(uint32 v) /* %eax from CPUID with %eax=1. */
689
return CPUID_FAMILY(v) +
690
(CPUID_FAMILY(v) == CPUID_FAMILY_EXTENDED ? CPUID_EXTENDED_FAMILY(v) : 0);
693
/* Normally only used when FAMILY==CPUID_FAMILY_EXTENDED, but Intel is
694
* now using the extended model field for FAMILY==CPUID_FAMILY_P6 to
695
* refer to the newer Core2 CPUs
698
CPUID_EFFECTIVE_MODEL(uint32 v) /* %eax from CPUID with %eax=1. */
700
return CPUID_MODEL(v) + (CPUID_EXTENDED_MODEL(v) << 4);
704
* Notice that CPUID families for Intel and AMD overlap. The following macros
705
* should only be used AFTER the manufacturer has been established (through
706
* the use of CPUID standard function 0).
709
CPUID_FAMILY_IS_486(uint32 _eax)
711
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_486;
715
CPUID_FAMILY_IS_P5(uint32 _eax)
717
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P5;
721
CPUID_FAMILY_IS_P6(uint32 _eax)
723
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P6;
727
CPUID_FAMILY_IS_PENTIUM4(uint32 _eax)
729
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P4;
733
* Intel Pentium M processors are Yonah/Sossaman or an older P-M
736
CPUID_UARCH_IS_PENTIUM_M(uint32 v) // IN: %eax from CPUID with %eax=1.
738
/* Assumes the CPU manufacturer is Intel. */
739
return CPUID_FAMILY_IS_P6(v) &&
740
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_09 ||
741
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0D ||
742
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0E);
746
* Intel Core processors are Merom, Conroe, Woodcrest, Clovertown,
747
* Penryn, Dunnington, Kentsfield, Yorktown, Harpertown, ........
750
CPUID_UARCH_IS_CORE(uint32 v) // IN: %eax from CPUID with %eax=1.
752
uint32 model = CPUID_EFFECTIVE_MODEL(v);
753
/* Assumes the CPU manufacturer is Intel. */
754
return CPUID_FAMILY_IS_P6(v) &&
755
model >= CPUID_MODEL_CORE_0F &&
756
(model < CPUID_MODEL_NEHALEM_1A ||
757
model == CPUID_MODEL_CORE_1D);
761
* Intel Nehalem processors are: Nehalem, Gainestown, Lynnfield.
764
CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1.
766
/* Assumes the CPU manufacturer is Intel. */
767
return CPUID_FAMILY_IS_P6(v) &&
768
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1A ||
769
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1E);
773
CPUID_FAMILY_IS_K7(uint32 _eax)
775
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K7;
779
CPUID_FAMILY_IS_K8(uint32 _eax)
781
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8;
785
CPUID_FAMILY_IS_K8EXT(uint32 _eax)
788
* We check for this pattern often enough that it's
789
* worth a separate function, for syntactic sugar.
791
return CPUID_FAMILY_IS_K8(_eax) &&
792
CPUID_EXTENDED_MODEL(_eax) != 0;
796
CPUID_FAMILY_IS_K8L(uint32 _eax)
798
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8L;
802
CPUID_FAMILY_IS_K8MOBILE(uint32 _eax)
804
/* Essentially a K8 (not K8L) part, but with mobile features. */
805
return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8MOBILE;
809
CPUID_FAMILY_IS_K8STAR(uint32 _eax)
812
* Read function name as "K8*", as in wildcard.
813
* Matches K8 or K8L or K8MOBILE
815
return CPUID_FAMILY_IS_K8(_eax) || CPUID_FAMILY_IS_K8L(_eax) ||
816
CPUID_FAMILY_IS_K8MOBILE(_eax);
820
* AMD Barcelona (of either Opteron or Phenom kind).
823
CPUID_MODEL_IS_BARCELONA(uint32 v) // IN: %eax from CPUID with %eax=1.
825
/* Assumes the CPU manufacturer is AMD. */
826
return CPUID_FAMILY_IS_K8L(v) &&
827
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_BARCELONA_02;
831
#define CPUID_TYPE_PRIMARY 0
832
#define CPUID_TYPE_OVERDRIVE 1
833
#define CPUID_TYPE_SECONDARY 2
835
#define CPUID_INTEL_ID4EAX_CACHE_TYPE_NULL 0
836
#define CPUID_INTEL_ID4EAX_CACHE_TYPE_DATA 1
837
#define CPUID_INTEL_ID4EAX_CACHE_TYPE_INST 2
838
#define CPUID_INTEL_ID4EAX_CACHE_TYPE_UNIF 3
840
#define CPUID_INTEL_ID4EAX_CACHE_SELF_INIT 0x00000100
841
#define CPUID_INTEL_ID4EAX_CACHE_FULLY_ASSOC 0x00000200
845
* On AMD chips before Opteron and Intel chips before P4 model 3,
846
* WRMSR(TSC) clears the upper half of the TSC instead of using %edx.
849
CPUID_FullyWritableTSC(Bool isIntel, // IN
850
uint32 v) // IN: %eax from CPUID with %eax=1.
854
* - Intel && P6 (pre-core) or
855
* - Intel && P4 (model < 3) or
856
* - !Intel && pre-K8 Opteron
857
* Otherwise, returns TRUE.
860
((CPUID_FAMILY_IS_P6(v) &&
861
CPUID_EFFECTIVE_MODEL(v) < CPUID_MODEL_PM_0E) ||
862
(CPUID_FAMILY_IS_PENTIUM4(v) &&
863
CPUID_EFFECTIVE_MODEL(v) < 3))) ||
865
CPUID_FAMILY(v) < CPUID_FAMILY_K8));
870
* For certain AMD processors, an lfence instruction is necessary at various
871
* places to ensure ordering.
875
CPUID_VendorRequiresFence(CpuidVendors vendor)
877
return vendor == CPUID_VENDOR_AMD;
881
CPUID_VersionRequiresFence(uint32 version)
883
return CPUID_EFFECTIVE_FAMILY(version) == CPUID_FAMILY_K8 &&
884
CPUID_EFFECTIVE_MODEL(version) < 0x40;
888
CPUID_ID0RequiresFence(CPUIDRegs *id0)
893
return CPUID_IsVendorAMD(id0);
897
CPUID_ID1RequiresFence(CPUIDRegs *id1)
899
return CPUID_VersionRequiresFence(id1->eax);
903
CPUID_RequiresFence(CpuidVendors vendor, // IN
904
uint32 version) // IN: %eax from CPUID with %eax=1.
906
return CPUID_VendorRequiresFence(vendor) &&
907
CPUID_VersionRequiresFence(version);
912
*----------------------------------------------------------------------
914
* CPUID_CountsCPUIDAsBranch --
916
* Returns TRUE iff the cpuid given counts CPUID as a branch
917
* (i.e. is a pre-Merom E CPU).
919
*----------------------------------------------------------------------
923
CPUID_CountsCPUIDAsBranch(uint32 v) /* %eax from CPUID with %eax=1 */
926
* CPUID no longer a branch starting with Merom E. Bug 148411.
927
* Penryn (Extended Model: 1) also has this fixed.
929
* Merom E is: CPUID.1.eax & 0xfff = 0x6f9
931
return !(CPUID_FAMILY_IS_P6(v) &&
932
(CPUID_EFFECTIVE_MODEL(v) > CPUID_MODEL_CORE_0F ||
933
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_CORE_0F &&
934
CPUID_STEPPING(v) >= 9)));
938
* On Merom and later Intel chips, not present PDPTEs with reserved bits
939
* set do not fault with a #GP. See PR# 109120.
942
CPUID_FaultOnNPReservedPDPTE(uint32 v) // IN: %eax from CPUID with %eax=1.
944
return !(CPUID_FAMILY_IS_P6(v) &&
945
(CPUID_EFFECTIVE_MODEL(v) >= CPUID_MODEL_CORE_0F));
950
* The following low-level functions compute the number of
951
* cores per cpu. They should be used cautiously because
952
* they do not necessarily work on all types of CPUs.
953
* High-level functions that are correct for all CPUs are
954
* available elsewhere: see lib/cpuidInfo/cpuidInfo.c.
958
CPUID_IntelCoresPerPackage(uint32 v) /* %eax from CPUID with %eax=4 and %ecx=0. */
960
// Note: This is not guaranteed to work on older Intel CPUs.
961
return 1 + CPUID_INTEL_CORE_COUNT(v);
965
CPUID_AMDCoresPerPackage(uint32 v) /* %ecx from CPUID with %eax=0x80000008. */
967
// Note: This is not guaranteed to work on older AMD CPUs.
968
return 1 + CPUID_AMD_CORE_COUNT(v);
972
* Hypervisor CPUID space is 0x400000XX.
975
CPUID_IsHypervisorLevel(uint32 level, uint32 *offset)
977
*offset = level & 0xff;
978
return (level & 0xffffff00) == 0x40000000;