2336 lines
115 KiB
C
2336 lines
115 KiB
C
/*********************************************************
|
|
* Copyright (C) 1998-2020 VMware, Inc. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation version 2 and no later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*********************************************************/
|
|
|
|
#ifndef _X86CPUID_H_
|
|
#define _X86CPUID_H_
|
|
|
|
/* http://www.sandpile.org/ia32/cpuid.htm */
|
|
|
|
#define INCLUDE_ALLOW_USERLEVEL
|
|
#define INCLUDE_ALLOW_VMX
|
|
|
|
#define INCLUDE_ALLOW_VMKERNEL
|
|
#define INCLUDE_ALLOW_MODULE
|
|
#define INCLUDE_ALLOW_DISTRIBUTE
|
|
#define INCLUDE_ALLOW_VMK_MODULE
|
|
#define INCLUDE_ALLOW_VMCORE
|
|
#define INCLUDE_ALLOW_VMMON
|
|
#include "includeCheck.h"
|
|
|
|
#include "vm_basic_types.h"
|
|
#include "community_source.h"
|
|
#include "x86vendor.h"
|
|
#include "vm_assert.h"
|
|
|
|
#if defined __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
/*
|
|
* The linux kernel's ptrace.h stupidly defines the bare
|
|
* EAX/EBX/ECX/EDX, which wrecks havoc with our preprocessor tricks.
|
|
*/
|
|
#undef EAX
|
|
#undef EBX
|
|
#undef ECX
|
|
#undef EDX
|
|
|
|
typedef struct CPUIDRegs {
|
|
uint32 eax, ebx, ecx, edx;
|
|
} CPUIDRegs;
|
|
|
|
typedef union CPUIDRegsUnion {
|
|
uint32 array[4];
|
|
CPUIDRegs regs;
|
|
uint64 force8byteAlign[2]; /* See CpuidInfoNodePtr (needed on Apple Mac). */
|
|
} CPUIDRegsUnion;
|
|
|
|
/*
|
|
* Results of calling cpuid(eax, ecx) on all host logical CPU.
|
|
*/
|
|
#ifdef _MSC_VER
|
|
// TODO: Move this under the push
|
|
#pragma warning (disable :4200) // non-std extension: zero-sized array in struct
|
|
#pragma warning (push)
|
|
#pragma warning (disable :4100) // unreferenced parameters
|
|
#endif
|
|
|
|
typedef
|
|
#include "vmware_pack_begin.h"
|
|
struct CPUIDReply {
|
|
/*
|
|
* Unique host logical CPU identifier. It does not change across queries, so
|
|
* we use it to correlate the replies of multiple queries.
|
|
*/
|
|
uint64 tag; // OUT
|
|
|
|
CPUIDRegs regs; // OUT
|
|
}
|
|
#include "vmware_pack_end.h"
|
|
CPUIDReply;
|
|
|
|
typedef
|
|
#include "vmware_pack_begin.h"
|
|
struct CPUIDQuery {
|
|
uint32 eax; // IN
|
|
uint32 ecx; // IN
|
|
uint32 numLogicalCPUs; // IN/OUT
|
|
CPUIDReply logicalCPUs[0]; // OUT
|
|
}
|
|
#include "vmware_pack_end.h"
|
|
CPUIDQuery;
|
|
|
|
/*
|
|
* CPUID levels the monitor caches.
|
|
*
|
|
* The first parameter defines whether the level has its default masks
|
|
* generated from the values in this file. Any level which is marked as FALSE
|
|
* here *must* have all monitor support types set to NA. A static assert in
|
|
* lib/cpuidcompat/cpuidcompat.c will check this.
|
|
*
|
|
* The second parameter is the "short name" of the level. It's mainly used for
|
|
* token concatenation in various macros.
|
|
*
|
|
* The third parameter is the actual numeric value of that level (the EAX input
|
|
* value).
|
|
*
|
|
* The fourth parameter is a "subleaf count", where 0 means that ecx is
|
|
* ignored, otherwise is the count of sub-leaves.
|
|
*
|
|
* The fifth parameter is the first hardware version that is *aware* of the
|
|
* CPUID level (0 = existed since dawn of time), even though we may not expose
|
|
* this level or parts of it to guest.
|
|
*/
|
|
|
|
/* MASKS, LVL, VAL, CNT, HWV */
|
|
#define CPUID_CACHED_LEVELS \
|
|
CPUIDLEVEL(TRUE, 0, 0x0, 0, 0) \
|
|
CPUIDLEVEL(TRUE, 1, 0x1, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 2, 0x2, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 4, 0x4, 7, 0) \
|
|
CPUIDLEVEL(FALSE, 5, 0x5, 0, 0) \
|
|
CPUIDLEVEL(TRUE, 6, 0x6, 0, 0) \
|
|
CPUIDLEVEL(TRUE, 7, 0x7, 2, 0) \
|
|
CPUIDLEVEL(TRUE, 9, 0x9, 0, 17) \
|
|
CPUIDLEVEL(FALSE, A, 0xa, 0, 0) \
|
|
CPUIDLEVEL(FALSE, B, 0xb, 3, 0) \
|
|
CPUIDLEVEL(TRUE, D, 0xd, 10, 0) \
|
|
CPUIDLEVEL(TRUE, F, 0xf, 2, 13) \
|
|
CPUIDLEVEL(TRUE, 10, 0x10, 4, 13) \
|
|
CPUIDLEVEL(TRUE, 12, 0x12, 4, 13) \
|
|
CPUIDLEVEL(TRUE, 14, 0x14, 2, 13) \
|
|
CPUIDLEVEL(TRUE, 15, 0x15, 0, 13) \
|
|
CPUIDLEVEL(TRUE, 16, 0x16, 0, 13) \
|
|
CPUIDLEVEL(TRUE, 17, 0x17, 4, 14) \
|
|
CPUIDLEVEL(TRUE, 18, 0x18, 8, 17) \
|
|
CPUIDLEVEL(TRUE, 1A, 0x1a, 0, 17) \
|
|
CPUIDLEVEL(TRUE, 1B, 0x1b, 2, 17) \
|
|
CPUIDLEVEL(FALSE, 1F, 0x1f, 6, 17) \
|
|
CPUIDLEVEL(FALSE, 400, 0x40000000, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 401, 0x40000001, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 402, 0x40000002, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 403, 0x40000003, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 404, 0x40000004, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 405, 0x40000005, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 406, 0x40000006, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 410, 0x40000010, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 80, 0x80000000, 0, 0) \
|
|
CPUIDLEVEL(TRUE, 81, 0x80000001, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 82, 0x80000002, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 83, 0x80000003, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 84, 0x80000004, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 85, 0x80000005, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 86, 0x80000006, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 87, 0x80000007, 0, 0) \
|
|
CPUIDLEVEL(TRUE, 88, 0x80000008, 0, 0) \
|
|
CPUIDLEVEL(TRUE, 8A, 0x8000000a, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 819, 0x80000019, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 81A, 0x8000001a, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 81B, 0x8000001b, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 81C, 0x8000001c, 0, 0) \
|
|
CPUIDLEVEL(FALSE, 81D, 0x8000001d, 5, 0) \
|
|
CPUIDLEVEL(FALSE, 81E, 0x8000001e, 0, 0) \
|
|
CPUIDLEVEL(TRUE, 81F, 0x8000001f, 0, 14) \
|
|
CPUIDLEVEL(TRUE, 820, 0x80000020, 2, 17) \
|
|
CPUIDLEVEL(TRUE, 821, 0x80000021, 0, 17)
|
|
|
|
#define CPUID_ALL_LEVELS CPUID_CACHED_LEVELS
|
|
|
|
/* Define cached CPUID levels in the form: CPUID_LEVEL_<ShortName> */
|
|
typedef enum {
|
|
#define CPUIDLEVEL(t, s, v, c, h) CPUID_LEVEL_##s,
|
|
CPUID_CACHED_LEVELS
|
|
#undef CPUIDLEVEL
|
|
CPUID_NUM_CACHED_LEVELS
|
|
} CpuidCachedLevel;
|
|
|
|
/* Enum to translate between shorthand name and actual CPUID level value. */
|
|
enum {
|
|
#define CPUIDLEVEL(t, s, v, c, h) CPUID_LEVEL_VAL_##s = v,
|
|
CPUID_ALL_LEVELS
|
|
#undef CPUIDLEVEL
|
|
};
|
|
|
|
|
|
/* Named feature leaves */
|
|
#define CPUID_FEATURE_INFORMATION 0x01
|
|
#define CPUID_PROCESSOR_TOPOLOGY 4
|
|
#define CPUID_MWAIT_FEATURES 5
|
|
#define CPUID_PMC_FEATURES 0xa
|
|
#define CPUID_XSAVE_FEATURES 0xd
|
|
#define CPUID_SGX_FEATURES 0x12
|
|
#define CPUID_PT_FEATURES 0x14
|
|
#define CPUID_HYPERVISOR_LEVEL_0 0x40000000
|
|
#define CPUID_VMW_FEATURES 0x40000010
|
|
#define CPUID_SVM_FEATURES 0x8000000a
|
|
#define CPUID_SEV_INFO 0x8000001f
|
|
|
|
/*
|
|
* CPUID result registers
|
|
*/
|
|
|
|
#define CPUID_REGS \
|
|
CPUIDREG(EAX, eax) \
|
|
CPUIDREG(EBX, ebx) \
|
|
CPUIDREG(ECX, ecx) \
|
|
CPUIDREG(EDX, edx)
|
|
|
|
typedef enum {
|
|
#define CPUIDREG(uc, lc) CPUID_REG_##uc,
|
|
CPUID_REGS
|
|
#undef CPUIDREG
|
|
CPUID_NUM_REGS
|
|
} CpuidReg;
|
|
|
|
#define CPUID_INTEL_VENDOR_STRING "GenuntelineI"
|
|
#define CPUID_AMD_VENDOR_STRING "AuthcAMDenti"
|
|
#define CPUID_CYRIX_VENDOR_STRING "CyriteadxIns"
|
|
#define CPUID_VIA_VENDOR_STRING "CentaulsaurH"
|
|
#define CPUID_HYGON_VENDOR_STRING "HygouinenGen"
|
|
|
|
#define CPUID_HYPERV_HYPERVISOR_VENDOR_STRING "Microsoft Hv"
|
|
#define CPUID_KVM_HYPERVISOR_VENDOR_STRING "KVMKVMKVM\0\0\0"
|
|
#define CPUID_VMWARE_HYPERVISOR_VENDOR_STRING "VMwareVMware"
|
|
#define CPUID_XEN_HYPERVISOR_VENDOR_STRING "XenVMMXenVMM"
|
|
|
|
#define CPUID_INTEL_VENDOR_STRING_FIXED "GenuineIntel"
|
|
#define CPUID_AMD_VENDOR_STRING_FIXED "AuthenticAMD"
|
|
#define CPUID_CYRIX_VENDOR_STRING_FIXED "CyrixInstead"
|
|
#define CPUID_VIA_VENDOR_STRING_FIXED "CentaurHauls"
|
|
#define CPUID_HYGON_VENDOR_STRING_FIXED "HygonGenuine"
|
|
|
|
/*
|
|
* FIELD can be defined to process the CPUID information provided in the
|
|
* following CPUID_FIELD_DATA macro.
|
|
*
|
|
* The first parameter is the CPUID level of the feature (must be defined in
|
|
* CPUID_ALL_LEVELS, above).
|
|
*
|
|
* The second parameter is the CPUID sub-level (subleaf) of the feature. Please
|
|
* make sure here the number is consistent with the "subleaf count" in
|
|
* CPUIDLEVEL macro. I.e., if a feature is being added to a _new_ subleaf,
|
|
* update the subleaf count above as well.
|
|
*
|
|
* The third parameter is the result register.
|
|
*
|
|
* The fourth and fifth parameters are the bit position of the field and the
|
|
* width, respectively.
|
|
*
|
|
* The sixth is the name of the field.
|
|
*
|
|
* The seventh parameter specifies the monitor support characteristics for
|
|
* this field. The value must be a valid CpuidFieldSupported value (omitting
|
|
* CPUID_FIELD_SUPPORT_ for convenience). The meaning of those values are
|
|
* described below.
|
|
*
|
|
* The eighth parameter specifies the first virtual hardware version that
|
|
* implements the field (if 7th field is YES or ANY), or 0 (if 7th field is
|
|
* NO or NA). The value FUT means HW_VERSION_FUTURE. The field's hardware
|
|
* version must match the version in defaultMasks (cpuidcompat.c) if defined
|
|
* there, and must be less than or equal to the version of the cpuid leaf
|
|
* it's in.
|
|
*
|
|
* FLAG is defined identically to FIELD, but its accessors are more appropriate
|
|
* for 1-bit flags, and compile-time asserts enforce that the size is 1 bit
|
|
* wide.
|
|
*/
|
|
|
|
|
|
/*
|
|
* CpuidFieldSupported is made up of the following values:
|
|
*
|
|
* NO: A feature/field that IS NOT SUPPORTED by the monitor. Even
|
|
* if the host supports this feature, we will never expose it to
|
|
* the guest.
|
|
*
|
|
* YES: A feature/field that IS SUPPORTED by the monitor. If the
|
|
* host supports this feature, we will expose it to the guest. If
|
|
* not, then we will not set the feature.
|
|
*
|
|
* ANY: A feature/field that IS ALWAYS SUPPORTED by the monitor.
|
|
* Even if the host does not support the feature, the monitor can
|
|
* expose the feature to the guest. As with "YES", the guest cpuid
|
|
* value defaults to the host/evc cpuid value. But usually the
|
|
* guest cpuid value is recomputed at power on, ignoring the default
|
|
* value.
|
|
*
|
|
* NA: Only legal for levels not masked/tested by default (see
|
|
* above for this definition). Such fields must always be marked
|
|
* as NA.
|
|
*
|
|
* These distinctions can be translated into a common CPUID mask string as
|
|
* follows:
|
|
*
|
|
* YES --> "H" (Host). We support the feature, so show it to the
|
|
* guest if the host has the feature.
|
|
*
|
|
* ANY/NA --> "X" (Ignore). By default, don't perform checks for
|
|
* this feature bit. Per-GOS masks may choose to set this bit in
|
|
* the guest. (e.g. the APIC feature bit is always set to 1.)
|
|
*
|
|
* See lib/cpuidcompat/cpuidcompat.c for any possible overrides to
|
|
* these defaults.
|
|
*/
|
|
|
|
/*
|
|
* XSAVEOPT was incorrectly missed until HWv11. See comment for
|
|
* DisableReqHWVersion in vmFeatureCPUID.c for more detail.
|
|
*/
|
|
|
|
typedef enum {
|
|
CPUID_FIELD_SUPPORTED_NO,
|
|
CPUID_FIELD_SUPPORTED_YES,
|
|
CPUID_FIELD_SUPPORTED_ANY,
|
|
CPUID_FIELD_SUPPORTED_NA,
|
|
CPUID_NUM_FIELD_SUPPORTEDS
|
|
} CpuidFieldSupported;
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_0 \
|
|
FIELD( 0, 0, EAX, 0, 32, NUMLEVELS, ANY, 4 ) \
|
|
FIELD( 0, 0, EBX, 0, 32, VENDOR1, YES, 4 ) \
|
|
FIELD( 0, 0, ECX, 0, 32, VENDOR3, YES, 4 ) \
|
|
FIELD( 0, 0, EDX, 0, 32, VENDOR2, YES, 4 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_1 \
|
|
FIELD( 1, 0, EAX, 0, 4, STEPPING, ANY, 4 ) \
|
|
FIELD( 1, 0, EAX, 4, 4, MODEL, ANY, 4 ) \
|
|
FIELD( 1, 0, EAX, 8, 4, FAMILY, YES, 4 ) \
|
|
FIELD( 1, 0, EAX, 12, 2, TYPE, ANY, 4 ) \
|
|
FIELD( 1, 0, EAX, 16, 4, EXTENDED_MODEL, ANY, 4 ) \
|
|
FIELD( 1, 0, EAX, 20, 8, EXTENDED_FAMILY, YES, 4 ) \
|
|
FIELD( 1, 0, EBX, 0, 8, BRAND_ID, ANY, 4 ) \
|
|
FIELD( 1, 0, EBX, 8, 8, CLFL_SIZE, ANY, 4 ) \
|
|
FIELD( 1, 0, EBX, 16, 8, LCPU_COUNT, ANY, 4 ) \
|
|
FIELD( 1, 0, EBX, 24, 8, APICID, ANY, 4 ) \
|
|
FLAG( 1, 0, ECX, 0, 1, SSE3, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 1, 1, PCLMULQDQ, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 2, 1, DTES64, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 3, 1, MWAIT, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 4, 1, DSCPL, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 5, 1, VMX, YES, 8 ) \
|
|
FLAG( 1, 0, ECX, 6, 1, SMX, YES, FUT ) \
|
|
FLAG( 1, 0, ECX, 7, 1, EIST, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 8, 1, TM2, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 9, 1, SSSE3, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 10, 1, CNXTID, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 11, 1, SDBG, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 12, 1, FMA, YES, 8 ) \
|
|
FLAG( 1, 0, ECX, 13, 1, CMPXCHG16B, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 14, 1, xTPR, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 15, 1, PDCM, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 17, 1, PCID, YES, 9 ) \
|
|
FLAG( 1, 0, ECX, 18, 1, DCA, NO, 0 ) \
|
|
FLAG( 1, 0, ECX, 19, 1, SSE41, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 20, 1, SSE42, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 21, 1, x2APIC, ANY, 9 ) \
|
|
FLAG( 1, 0, ECX, 22, 1, MOVBE, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 23, 1, POPCNT, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 24, 1, TSC_DEADLINE, ANY, 11 ) \
|
|
FLAG( 1, 0, ECX, 25, 1, AES, YES, 4 ) \
|
|
FLAG( 1, 0, ECX, 26, 1, XSAVE, YES, 8 ) \
|
|
FLAG( 1, 0, ECX, 27, 1, OSXSAVE, ANY, 8 ) \
|
|
FLAG( 1, 0, ECX, 28, 1, AVX, YES, 8 ) \
|
|
FLAG( 1, 0, ECX, 29, 1, F16C, YES, 9 ) \
|
|
FLAG( 1, 0, ECX, 30, 1, RDRAND, YES, 9 ) \
|
|
FLAG( 1, 0, ECX, 31, 1, HYPERVISOR, ANY, 4 ) \
|
|
FLAG( 1, 0, EDX, 0, 1, FPU, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 1, 1, VME, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 2, 1, DE, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 3, 1, PSE, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 4, 1, TSC, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 5, 1, MSR, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 6, 1, PAE, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 7, 1, MCE, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 8, 1, CX8, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 9, 1, APIC, ANY, 4 ) \
|
|
FLAG( 1, 0, EDX, 11, 1, SEP, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 12, 1, MTRR, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 13, 1, PGE, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 14, 1, MCA, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 15, 1, CMOV, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 16, 1, PAT, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 17, 1, PSE36, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 18, 1, PSN, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 19, 1, CLFSH, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 21, 1, DS, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 22, 1, ACPI, ANY, 4 ) \
|
|
FLAG( 1, 0, EDX, 23, 1, MMX, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 24, 1, FXSR, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 25, 1, SSE, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 26, 1, SSE2, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 27, 1, SS, YES, 4 ) \
|
|
FLAG( 1, 0, EDX, 28, 1, HTT, ANY, 7 ) \
|
|
FLAG( 1, 0, EDX, 29, 1, TM, NO, 0 ) \
|
|
FLAG( 1, 0, EDX, 30, 1, IA64, NO, 0 ) \
|
|
FLAG( 1, 0, EDX, 31, 1, PBE, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_2 \
|
|
FIELD( 2, 0, EAX, 0, 8, LEAF2_COUNT, NA, 0 ) \
|
|
FIELD( 2, 0, EAX, 8, 8, LEAF2_CACHE1, NA, 0 ) \
|
|
FIELD( 2, 0, EAX, 16, 8, LEAF2_CACHE2, NA, 0 ) \
|
|
FIELD( 2, 0, EAX, 24, 8, LEAF2_CACHE3, NA, 0 ) \
|
|
FIELD( 2, 0, EBX, 0, 8, LEAF2_CACHE4, NA, 0 ) \
|
|
FIELD( 2, 0, EBX, 8, 8, LEAF2_CACHE5, NA, 0 ) \
|
|
FIELD( 2, 0, EBX, 16, 8, LEAF2_CACHE6, NA, 0 ) \
|
|
FIELD( 2, 0, EBX, 24, 8, LEAF2_CACHE7, NA, 0 ) \
|
|
FIELD( 2, 0, ECX, 0, 8, LEAF2_CACHE8, NA, 0 ) \
|
|
FIELD( 2, 0, ECX, 8, 8, LEAF2_CACHE9, NA, 0 ) \
|
|
FIELD( 2, 0, ECX, 16, 8, LEAF2_CACHE10, NA, 0 ) \
|
|
FIELD( 2, 0, ECX, 24, 8, LEAF2_CACHE11, NA, 0 ) \
|
|
FIELD( 2, 0, EDX, 0, 8, LEAF2_CACHE12, NA, 0 ) \
|
|
FIELD( 2, 0, EDX, 8, 8, LEAF2_CACHE13, NA, 0 ) \
|
|
FIELD( 2, 0, EDX, 16, 8, LEAF2_CACHE14, NA, 0 ) \
|
|
FIELD( 2, 0, EDX, 24, 8, LEAF2_CACHE15, NA, 0 ) \
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_4 \
|
|
FIELD( 4, 0, EAX, 0, 5, LEAF4_CACHE_TYPE, NA, 0 ) \
|
|
FIELD( 4, 0, EAX, 5, 3, LEAF4_CACHE_LEVEL, NA, 0 ) \
|
|
FLAG( 4, 0, EAX, 8, 1, LEAF4_CACHE_SELF_INIT, NA, 0 ) \
|
|
FLAG( 4, 0, EAX, 9, 1, LEAF4_CACHE_FULLY_ASSOC, NA, 0 ) \
|
|
FIELD( 4, 0, EAX, 14, 12, LEAF4_CACHE_NUMHT_SHARING, NA, 0 ) \
|
|
FIELD( 4, 0, EAX, 26, 6, LEAF4_CORE_COUNT, NA, 0 ) \
|
|
FIELD( 4, 0, EBX, 0, 12, LEAF4_CACHE_LINE, NA, 0 ) \
|
|
FIELD( 4, 0, EBX, 12, 10, LEAF4_CACHE_PART, NA, 0 ) \
|
|
FIELD( 4, 0, EBX, 22, 10, LEAF4_CACHE_WAYS, NA, 0 ) \
|
|
FIELD( 4, 0, ECX, 0, 32, LEAF4_CACHE_SETS, NA, 0 ) \
|
|
FLAG( 4, 0, EDX, 0, 1, LEAF4_CACHE_WBINVD_NOT_GUARANTEED, NA, 0 ) \
|
|
FLAG( 4, 0, EDX, 1, 1, LEAF4_CACHE_IS_INCLUSIVE, NA, 0 ) \
|
|
FLAG( 4, 0, EDX, 2, 1, LEAF4_CACHE_COMPLEX_INDEXING, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_5 \
|
|
FIELD( 5, 0, EAX, 0, 16, MWAIT_MIN_SIZE, NA, 0 ) \
|
|
FIELD( 5, 0, EBX, 0, 16, MWAIT_MAX_SIZE, NA, 0 ) \
|
|
FLAG( 5, 0, ECX, 0, 1, MWAIT_EXTENSIONS, NA, 0 ) \
|
|
FLAG( 5, 0, ECX, 1, 1, MWAIT_INTR_BREAK, NA, 0 ) \
|
|
FIELD( 5, 0, EDX, 0, 4, MWAIT_C0_SUBSTATE, NA, 0 ) \
|
|
FIELD( 5, 0, EDX, 4, 4, MWAIT_C1_SUBSTATE, NA, 0 ) \
|
|
FIELD( 5, 0, EDX, 8, 4, MWAIT_C2_SUBSTATE, NA, 0 ) \
|
|
FIELD( 5, 0, EDX, 12, 4, MWAIT_C3_SUBSTATE, NA, 0 ) \
|
|
FIELD( 5, 0, EDX, 16, 4, MWAIT_C4_SUBSTATE, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_6 \
|
|
FLAG( 6, 0, EAX, 0, 1, THERMAL_SENSOR, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 1, 1, TURBO_MODE, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 2, 1, APIC_INVARIANT, ANY, 4 ) \
|
|
FLAG( 6, 0, EAX, 4, 1, PLN, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 5, 1, ECMD, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 6, 1, PTM, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 7, 1, HWP, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 8, 1, HWP_NOTIFICATION, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 9, 1, HWP_ACTIVITY_WINDOW, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 10, 1, HWP_ENERGY_PERFORMANCE_PREFERENCE, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 11, 1, HWP_PACKAGE_LEVEL_REQUEST, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 13, 1, HDC, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 14, 1, TURBO_BOOST_MAX_3, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 15, 1, HWP_CAPABILITIES, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 16, 1, HWP_PECI, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 17, 1, HWP_FLEXIBLE, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 18, 1, HWP_FAST_ACCESS, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 19, 1, HW_FEEDBACK, NO, 0 ) \
|
|
FLAG( 6, 0, EAX, 20, 1, HWP_IGNORE_IDLE_REQUEST, NO, 0 ) \
|
|
FIELD( 6, 0, EBX, 0, 4, NUM_INTR_THRESHOLDS, NO, 0 ) \
|
|
FLAG( 6, 0, ECX, 0, 1, HW_COORD_FEEDBACK, NO, 0 ) \
|
|
FLAG( 6, 0, ECX, 1, 1, ACNT2, ANY, 13 ) \
|
|
FLAG( 6, 0, ECX, 3, 1, ENERGY_PERF_BIAS, NO, 0 ) \
|
|
FLAG( 6, 0, EDX, 0, 1, PERF_CAP_REPORTING, NO, 0 ) \
|
|
FLAG( 6, 0, EDX, 1, 1, ENERGY_CAP_REPORTING, NO, 0 ) \
|
|
FIELD( 6, 0, EDX, 8, 4, HW_FEEDBACK_SIZE, NO, 0 ) \
|
|
FIELD( 6, 0, EDX, 16, 16, HW_FEEDBACK_INDEX, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_7 \
|
|
FIELD( 7, 0, EAX, 0, 32, LEAF_7_MAX_SUBLEVEL, YES, 18 ) \
|
|
FLAG( 7, 0, EBX, 0, 1, FSGSBASE, YES, 9 ) \
|
|
FLAG( 7, 0, EBX, 1, 1, TSC_ADJUST, ANY, 11 ) \
|
|
FLAG( 7, 0, EBX, 2, 1, SGX, ANY, 17 ) \
|
|
FLAG( 7, 0, EBX, 3, 1, BMI1, YES, 9 ) \
|
|
FLAG( 7, 0, EBX, 4, 1, HLE, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 5, 1, AVX2, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 6, 1, FDP_EXCPTN_ONLY, ANY, 4 ) \
|
|
FLAG( 7, 0, EBX, 7, 1, SMEP, YES, 9 ) \
|
|
FLAG( 7, 0, EBX, 8, 1, BMI2, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 9, 1, ENFSTRG, YES, 9 ) \
|
|
FLAG( 7, 0, EBX, 10, 1, INVPCID, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 11, 1, RTM, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 12, 1, PQM, NO, 0 ) \
|
|
FLAG( 7, 0, EBX, 13, 1, FP_SEGMENT_ZERO, ANY, 11 ) \
|
|
FLAG( 7, 0, EBX, 14, 1, MPX, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 15, 1, PQE, NO, 0 ) \
|
|
FLAG( 7, 0, EBX, 16, 1, AVX512F, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 17, 1, AVX512DQ, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 18, 1, RDSEED, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 19, 1, ADX, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 20, 1, SMAP, YES, 11 ) \
|
|
FLAG( 7, 0, EBX, 21, 1, AVX512IFMA, YES, 17 ) \
|
|
FLAG( 7, 0, EBX, 23, 1, CLFLUSHOPT, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 24, 1, CLWB, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 25, 1, PT, YES, FUT ) \
|
|
FLAG( 7, 0, EBX, 26, 1, AVX512PF, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 27, 1, AVX512ER, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 28, 1, AVX512CD, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 29, 1, SHA, YES, 14 ) \
|
|
FLAG( 7, 0, EBX, 30, 1, AVX512BW, YES, 13 ) \
|
|
FLAG( 7, 0, EBX, 31, 1, AVX512VL, YES, 13 ) \
|
|
FLAG( 7, 0, ECX, 0, 1, PREFETCHWT1, YES, 13 ) \
|
|
FLAG( 7, 0, ECX, 1, 1, AVX512VBMI, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 2, 1, UMIP, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 3, 1, PKU, YES, 13 ) \
|
|
FLAG( 7, 0, ECX, 4, 1, OSPKE, ANY, 13 ) \
|
|
FLAG( 7, 0, ECX, 5, 1, WAITPKG, NO, 0 ) \
|
|
FLAG( 7, 0, ECX, 6, 1, AVX512VBMI2, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 7, 1, CET_SS, NO, 0 ) \
|
|
FLAG( 7, 0, ECX, 8, 1, GFNI, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 9, 1, VAES, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 10, 1, VPCLMULQDQ, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 11, 1, AVX512VNNI, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 12, 1, AVX512BITALG, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 14, 1, AVX512VPOPCNTDQ, YES, 16 ) \
|
|
FLAG( 7, 0, ECX, 16, 1, VA57, NO, 0 ) \
|
|
FIELD( 7, 0, ECX, 17, 5, MAWA, NO, 0 ) \
|
|
FLAG( 7, 0, ECX, 22, 1, RDPID, YES, 17 ) \
|
|
FLAG( 7, 0, ECX, 25, 1, CLDEMOTE, YES, 18 ) \
|
|
FLAG( 7, 0, ECX, 27, 1, MOVDIRI, YES, 18 ) \
|
|
FLAG( 7, 0, ECX, 28, 1, MOVDIR64B, YES, 18 ) \
|
|
FLAG( 7, 0, ECX, 29, 1, ENQCMD, NO, 0 ) \
|
|
FLAG( 7, 0, ECX, 30, 1, SGX_LC, ANY, 17 ) \
|
|
FLAG( 7, 0, EDX, 2, 1, AVX512QVNNIW, YES, 16 ) \
|
|
FLAG( 7, 0, EDX, 3, 1, AVX512QFMAPS, YES, 16 ) \
|
|
FLAG( 7, 0, EDX, 4, 1, FAST_SHORT_REPMOV, YES, 18 ) \
|
|
FLAG( 7, 0, EDX, 8, 1, AVX512VP2INTERSECT, YES, 18 ) \
|
|
FLAG( 7, 0, EDX, 10, 1, MDCLEAR, YES, 9 ) \
|
|
FLAG( 7, 0, EDX, 13, 1, TSX_MICROCODE_UPDATE, NO, 0 ) \
|
|
FLAG( 7, 0, EDX, 14, 1, SERIALIZE, NO, 0 ) \
|
|
FLAG( 7, 0, EDX, 15, 1, HYBRID, NO, 0 ) \
|
|
FLAG( 7, 0, EDX, 16, 1, TSXLDTRK, NO, 0 ) \
|
|
FLAG( 7, 0, EDX, 18, 1, PCONFIG, NO, 0 ) \
|
|
FLAG( 7, 0, EDX, 20, 1, CET_IBT, NO, 0 ) \
|
|
FLAG( 7, 0, EDX, 26, 1, IBRSIBPB, ANY, 9 ) \
|
|
FLAG( 7, 0, EDX, 27, 1, STIBP, YES, 9 ) \
|
|
FLAG( 7, 0, EDX, 28, 1, FCMD, YES, 9 ) \
|
|
FLAG( 7, 0, EDX, 29, 1, ARCH_CAPABILITIES, ANY, 9 ) \
|
|
FLAG( 7, 0, EDX, 30, 1, CORE_CAPABILITIES, NO, 0 ) \
|
|
FLAG( 7, 0, EDX, 31, 1, SSBD, YES, 9 ) \
|
|
FLAG( 7, 1, EAX, 5, 1, AVX512BF16, YES, 18 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_9 \
|
|
FIELD( 9, 0, EAX, 0, 32, IA32_PLATFORM_DCA_CAP_VAL, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_A \
|
|
FIELD( A, 0, EAX, 0, 8, PMC_VERSION, NA, 0 ) \
|
|
FIELD( A, 0, EAX, 8, 8, PMC_NUM_GEN, NA, 0 ) \
|
|
FIELD( A, 0, EAX, 16, 8, PMC_WIDTH_GEN, NA, 0 ) \
|
|
FIELD( A, 0, EAX, 24, 8, PMC_EBX_LENGTH, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 0, 1, PMC_CORE_CYCLES, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 1, 1, PMC_INSTR_RETIRED, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 2, 1, PMC_REF_CYCLES, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 3, 1, PMC_LAST_LVL_CREF, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 4, 1, PMC_LAST_LVL_CMISS, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 5, 1, PMC_BR_INST_RETIRED, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 6, 1, PMC_BR_MISS_RETIRED, NA, 0 ) \
|
|
FLAG( A, 0, EBX, 7, 1, PMC_TOPDOWN_SLOTS, NA, 0 ) \
|
|
FLAG( A, 0, ECX, 0, 1, PMC_FIXED0, NA, 0 ) \
|
|
FLAG( A, 0, ECX, 1, 1, PMC_FIXED1, NA, 0 ) \
|
|
FLAG( A, 0, ECX, 2, 1, PMC_FIXED2, NA, 0 ) \
|
|
FLAG( A, 0, ECX, 3, 1, PMC_FIXED3, NA, 0 ) \
|
|
FIELD( A, 0, EDX, 0, 5, PMC_NUM_FIXED, NA, 0 ) \
|
|
FIELD( A, 0, EDX, 5, 8, PMC_WIDTH_FIXED, NA, 0 ) \
|
|
FLAG( A, 0, EDX, 15, 1, PMC_ANYTHREAD_DEPRECATED, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_B \
|
|
FIELD( B, 0, EAX, 0, 5, TOPOLOGY_MASK_WIDTH, NA, 0 ) \
|
|
FIELD( B, 0, EBX, 0, 16, TOPOLOGY_CPUS_SHARING_LEVEL, NA, 0 ) \
|
|
FIELD( B, 0, ECX, 0, 8, TOPOLOGY_LEVEL_NUMBER, NA, 0 ) \
|
|
FIELD( B, 0, ECX, 8, 8, TOPOLOGY_LEVEL_TYPE, NA, 0 ) \
|
|
FIELD( B, 0, EDX, 0, 32, TOPOLOGY_X2APIC_ID, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_D \
|
|
FLAG( D, 0, EAX, 0, 1, XCR0_MASTER_LEGACY_FP, YES, 8 ) \
|
|
FLAG( D, 0, EAX, 1, 1, XCR0_MASTER_SSE, YES, 8 ) \
|
|
FLAG( D, 0, EAX, 2, 1, XCR0_MASTER_YMM_H, YES, 8 ) \
|
|
FLAG( D, 0, EAX, 3, 1, XCR0_MASTER_BNDREGS, YES, 13 ) \
|
|
FLAG( D, 0, EAX, 4, 1, XCR0_MASTER_BNDCSR, YES, 13 ) \
|
|
FLAG( D, 0, EAX, 5, 1, XCR0_MASTER_OPMASK, YES, 13 ) \
|
|
FLAG( D, 0, EAX, 6, 1, XCR0_MASTER_ZMM_H, YES, 13 ) \
|
|
FLAG( D, 0, EAX, 7, 1, XCR0_MASTER_HI16_ZMM, YES, 13 ) \
|
|
FLAG( D, 0, EAX, 8, 1, XCR0_MASTER_XSS, NO, 0 ) \
|
|
FLAG( D, 0, EAX, 9, 1, XCR0_MASTER_PKRU, YES, 13 ) \
|
|
FIELD( D, 0, EAX, 10, 22, XCR0_MASTER_LOWER, NO, 0 ) \
|
|
FIELD( D, 0, EBX, 0, 32, XSAVE_ENABLED_SIZE, ANY, 8 ) \
|
|
FIELD( D, 0, ECX, 0, 32, XSAVE_MAX_SIZE, YES, 8 ) \
|
|
FIELD( D, 0, EDX, 0, 29, XCR0_MASTER_UPPER, NO, 0 ) \
|
|
FLAG( D, 0, EDX, 30, 1, XCR0_MASTER_LWP, NO, 0 ) \
|
|
FLAG( D, 0, EDX, 31, 1, XCR0_MASTER_EXTENDED_XSAVE, NO, 0 ) \
|
|
FLAG( D, 1, EAX, 0, 1, XSAVEOPT, YES, 11 ) \
|
|
FLAG( D, 1, EAX, 1, 1, XSAVEC, YES, 13 ) \
|
|
FLAG( D, 1, EAX, 2, 1, XGETBV_ECX1, YES, 17 ) \
|
|
FLAG( D, 1, EAX, 3, 1, XSAVES, YES, 13 ) \
|
|
FIELD( D, 1, EBX, 0, 32, XSAVES_ENABLED_SIZE, ANY, 13 ) \
|
|
FIELD( D, 1, ECX, 0, 7, XSS_XCR0_USED0, NO, 0 ) \
|
|
FLAG( D, 1, ECX, 8, 1, XSS_PT, NO, 0 ) \
|
|
FIELD( D, 1, ECX, 9, 1, XSS_XCR0_USED1, NO, 0 ) \
|
|
FIELD( D, 1, ECX, 10, 22, XSS_RSVD0, NO, 0 ) \
|
|
FIELD( D, 1, EDX, 0, 32, XSS_RSVD1, NO, 0 ) \
|
|
FIELD( D, 2, EAX, 0, 32, XSAVE_YMM_SIZE, YES, 8 ) \
|
|
FIELD( D, 2, EBX, 0, 32, XSAVE_YMM_OFFSET, YES, 8 ) \
|
|
FLAG( D, 2, ECX, 0, 1, XSAVE_YMM_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 2, ECX, 1, 1, XSAVE_YMM_ALIGN, YES, 13 ) \
|
|
FIELD( D, 2, ECX, 2, 30, XSAVE_YMM_RSVD1, NO, 0 ) \
|
|
FIELD( D, 2, EDX, 0, 32, XSAVE_YMM_RSVD2, NO, 0 ) \
|
|
FIELD( D, 3, EAX, 0, 32, XSAVE_BNDREGS_SIZE, YES, 13 ) \
|
|
FIELD( D, 3, EBX, 0, 32, XSAVE_BNDREGS_OFFSET, YES, 13 ) \
|
|
FLAG( D, 3, ECX, 0, 1, XSAVE_BNDREGS_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 3, ECX, 1, 1, XSAVE_BNDREGS_ALIGN, YES, 13 ) \
|
|
FIELD( D, 3, ECX, 2, 30, XSAVE_BNDREGS_RSVD1, NO, 0 ) \
|
|
FIELD( D, 3, EDX, 0, 32, XSAVE_BNDREGS_RSVD2, NO, 0 ) \
|
|
FIELD( D, 4, EAX, 0, 32, XSAVE_BNDCSR_SIZE, YES, 13 ) \
|
|
FIELD( D, 4, EBX, 0, 32, XSAVE_BNDCSR_OFFSET, YES, 13 ) \
|
|
FLAG( D, 4, ECX, 0, 1, XSAVE_BNDCSR_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 4, ECX, 1, 1, XSAVE_BNDCSR_ALIGN, YES, 13 ) \
|
|
FIELD( D, 4, ECX, 2, 30, XSAVE_BNDCSR_RSVD1, NO, 0 ) \
|
|
FIELD( D, 4, EDX, 0, 32, XSAVE_BNDCSR_RSVD2, NO, 0 ) \
|
|
FIELD( D, 5, EAX, 0, 32, XSAVE_OPMASK_SIZE, YES, 13 ) \
|
|
FIELD( D, 5, EBX, 0, 32, XSAVE_OPMASK_OFFSET, YES, 13 ) \
|
|
FLAG( D, 5, ECX, 0, 1, XSAVE_OPMASK_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 5, ECX, 1, 1, XSAVE_OPMASK_ALIGN, YES, 13 ) \
|
|
FIELD( D, 5, ECX, 2, 30, XSAVE_OPMASK_RSVD1, NO, 0 ) \
|
|
FIELD( D, 5, EDX, 0, 32, XSAVE_OPMASK_RSVD2, NO, 0 ) \
|
|
FIELD( D, 6, EAX, 0, 32, XSAVE_ZMM_H_SIZE, YES, 13 ) \
|
|
FIELD( D, 6, EBX, 0, 32, XSAVE_ZMM_H_OFFSET, YES, 13 ) \
|
|
FLAG( D, 6, ECX, 0, 1, XSAVE_ZMM_H_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 6, ECX, 1, 1, XSAVE_ZMM_H_ALIGN, YES, 13 ) \
|
|
FIELD( D, 6, ECX, 2, 30, XSAVE_ZMM_H_RSVD1, NO, 0 ) \
|
|
FIELD( D, 6, EDX, 0, 32, XSAVE_ZMM_H_RSVD2, NO, 0 ) \
|
|
FIELD( D, 7, EAX, 0, 32, XSAVE_HI16_ZMM_SIZE, YES, 13 ) \
|
|
FIELD( D, 7, EBX, 0, 32, XSAVE_HI16_ZMM_OFFSET, YES, 13 ) \
|
|
FLAG( D, 7, ECX, 0, 1, XSAVE_HI16_ZMM_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 7, ECX, 1, 1, XSAVE_HI16_ZMM_ALIGN, YES, 13 ) \
|
|
FIELD( D, 7, ECX, 2, 30, XSAVE_HI16_ZMM_RSVD1, NO, 0 ) \
|
|
FIELD( D, 7, EDX, 0, 32, XSAVE_HI16_ZMM_RSVD2, NO, 0 ) \
|
|
FIELD( D, 8, EAX, 0, 32, XSAVE_PT_STATE_SIZE, NO, 0 ) \
|
|
FIELD( D, 8, EBX, 0, 32, XSAVE_PT_STATE_OFFSET, NO, 0 ) \
|
|
FLAG( D, 8, ECX, 0, 1, XSAVE_PT_STATE_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 8, ECX, 1, 1, XSAVE_PT_STATE_ALIGN, NO, 0 ) \
|
|
FIELD( D, 8, ECX, 2, 30, XSAVE_PT_STATE_RSVD1, NO, 0 ) \
|
|
FIELD( D, 8, EDX, 0, 32, XSAVE_PT_STATE_RSVD2, NO, 0 ) \
|
|
FIELD( D, 9, EAX, 0, 32, XSAVE_PKRU_SIZE, YES, 13 ) \
|
|
FIELD( D, 9, EBX, 0, 32, XSAVE_PKRU_OFFSET, YES, 13 ) \
|
|
FLAG( D, 9, ECX, 0, 1, XSAVE_PKRU_SUP_BY_XSS, NO, 0 ) \
|
|
FLAG( D, 9, ECX, 1, 1, XSAVE_PKRU_ALIGN, YES, 13 ) \
|
|
FIELD( D, 9, ECX, 2, 30, XSAVE_PKRU_RSVD1, NO, 0 ) \
|
|
FIELD( D, 9, EDX, 0, 32, XSAVE_PKRU_RSVD2, NO, 0 )
|
|
/* D, 62: AMD LWP leaf on BD, PD, SR. Dropped in Zen. Never referenced. */
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_F \
|
|
FIELD( F, 0, EBX, 0, 32, PQM_MAX_RMID, NO, 0 ) \
|
|
FLAG( F, 0, EDX, 1, 1, PQM_CMT_SUPPORT, NO, 0 ) \
|
|
FIELD( F, 1, EBX, 0, 32, PQM_CMT_CONV, NO, 0 ) \
|
|
FIELD( F, 1, ECX, 0, 32, PQM_CMT_NUM_RMID, NO, 0 ) \
|
|
FLAG( F, 1, EDX, 0, 1, PQM_CMT_OCCUPANCY, NO, 0 ) \
|
|
FLAG( F, 1, EDX, 1, 1, PQM_MBM_TOTAL, NO, 0 ) \
|
|
FLAG( F, 1, EDX, 2, 1, PQM_MBM_LOCAL, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_10 \
|
|
FLAG( 10, 0, EBX, 1, 1, PQE_L3, NO, 0 ) \
|
|
FIELD( 10, 1, EAX, 0, 5, PQE_L3_MASK_LENGTH, NO, 0 ) \
|
|
FIELD( 10, 1, EBX, 0, 32, PQE_L3_ISOLATION_UNIT_MAP, NO, 0 ) \
|
|
FLAG( 10, 1, ECX, 2, 1, PQE_L3_CDP, NO, 0 ) \
|
|
FIELD( 10, 1, EDX, 0, 16, PQE_L3_MAX_COS_NUMBER, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_12 \
|
|
FLAG( 12, 0, EAX, 0, 1, SGX1, ANY, 17 ) \
|
|
FLAG( 12, 0, EAX, 1, 1, SGX2, ANY, FUT ) \
|
|
FLAG( 12, 0, EAX, 5, 1, SGX_OVERSUB_ENCLV, ANY, FUT ) \
|
|
FLAG( 12, 0, EAX, 6, 1, SGX_OVERSUB_ENCLS, ANY, FUT ) \
|
|
FLAG( 12, 0, EBX, 0, 1, SGX_MISCSELECT_EXINFO, ANY, FUT ) \
|
|
FIELD( 12, 0, EBX, 1, 31, SGX_MISCSELECT_RSVD, NO, 0 ) \
|
|
FIELD( 12, 0, EDX, 0, 8, MAX_ENCLAVE_SIZE_NOT64, ANY, 17 ) \
|
|
FIELD( 12, 0, EDX, 8, 8, MAX_ENCLAVE_SIZE_64, ANY, 17 ) \
|
|
FIELD( 12, 1, EAX, 0, 32, SECS_ATTRIBUTES0, ANY, 17 ) \
|
|
FIELD( 12, 1, EBX, 0, 32, SECS_ATTRIBUTES1, ANY, 17 ) \
|
|
FIELD( 12, 1, ECX, 0, 32, SECS_ATTRIBUTES2, ANY, 17 ) \
|
|
FIELD( 12, 1, EDX, 0, 32, SECS_ATTRIBUTES3, ANY, 17 ) \
|
|
FIELD( 12, 2, EAX, 0, 4, EPC00_VALID, ANY, 17 ) \
|
|
FIELD( 12, 2, EAX, 12, 20, EPC00_BASE_LOW, ANY, 17 ) \
|
|
FIELD( 12, 2, EBX, 0, 20, EPC00_BASE_HIGH, ANY, 17 ) \
|
|
FIELD( 12, 2, ECX, 0, 4, EPC00_PROTECTED, ANY, 17 ) \
|
|
FIELD( 12, 2, ECX, 12, 20, EPC00_SIZE_LOW, ANY, 17 ) \
|
|
FIELD( 12, 2, EDX, 0, 20, EPC00_SIZE_HIGH, ANY, 17 ) \
|
|
FIELD( 12, 3, EAX, 0, 4, EPC01_VALID, NO, 0 ) \
|
|
FIELD( 12, 3, EAX, 12, 20, EPC01_BASE_LOW, NO, 0 ) \
|
|
FIELD( 12, 3, EBX, 0, 20, EPC01_BASE_HIGH, NO, 0 ) \
|
|
FIELD( 12, 3, ECX, 0, 4, EPC01_PROTECTED, NO, 0 ) \
|
|
FIELD( 12, 3, ECX, 12, 20, EPC01_SIZE_LOW, NO, 0 ) \
|
|
FIELD( 12, 3, EDX, 0, 20, EPC01_SIZE_HIGH, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_14 \
|
|
FIELD( 14, 0, EAX, 0, 32, PT_MAX_SUBLEAF, YES, FUT ) \
|
|
FLAG( 14, 0, EBX, 0, 1, PT_CR3_FILTER, YES, FUT ) \
|
|
FLAG( 14, 0, EBX, 1, 1, PT_CFG_PSB_CYC, YES, FUT ) \
|
|
FLAG( 14, 0, EBX, 2, 1, PT_IP_FILTER_PERSIST_MSR, YES, FUT ) \
|
|
FLAG( 14, 0, EBX, 3, 1, PT_MTC, YES, FUT ) \
|
|
FLAG( 14, 0, EBX, 4, 1, PT_PTWRITE, NO, 0 ) \
|
|
FLAG( 14, 0, EBX, 5, 1, PT_POWER_EVENT, NO, 0 ) \
|
|
FLAG( 14, 0, ECX, 0, 1, PT_TOPA, YES, FUT ) \
|
|
FLAG( 14, 0, ECX, 1, 1, PT_TOPA_MULTI, YES, FUT ) \
|
|
FLAG( 14, 0, ECX, 2, 1, PT_SRO, YES, FUT ) \
|
|
FLAG( 14, 0, ECX, 3, 1, PT_TRACE_TRANS, NO, 0 ) \
|
|
FLAG( 14, 0, ECX, 31, 1, PT_LIP, YES, FUT ) \
|
|
FIELD( 14, 1, EAX, 0, 3, PT_NUM_ADDR_RANGES, YES, FUT ) \
|
|
FIELD( 14, 1, EAX, 16, 16, PT_AVAIL_MTC_ENCS, YES, FUT ) \
|
|
FIELD( 14, 1, EBX, 0, 16, PT_AVAIL_CYC_THRESH_ENCS, YES, FUT ) \
|
|
FIELD( 14, 1, EBX, 16, 16, PT_AVAIL_PSB_FREQ_ENCS, YES, FUT ) \
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_15 \
|
|
FIELD( 15, 0, EAX, 0, 32, DENOM_TSC_TO_CORE_CRYSTAL_CLK, NO, 0 ) \
|
|
FIELD( 15, 0, EBX, 0, 32, NUMER_TSC_TO_CORE_CRYSTAL_CLK, NO, 0 ) \
|
|
FIELD( 15, 0, ECX, 0, 32, CORE_CRYSTAL_CLK_FREQ, NO, 0 ) \
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_16 \
|
|
FIELD( 16, 0, EAX, 0, 16, PROC_BASE_FREQ, NO, 0 ) \
|
|
FIELD( 16, 0, EBX, 0, 16, PROC_MIN_FREQ, NO, 0 ) \
|
|
FIELD( 16, 0, ECX, 0, 16, BUS_FREQ, NO, 0 ) \
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_17 \
|
|
FIELD( 17, 0, EAX, 0, 31, MAX_SOCID_INDEX, NO, 0 ) \
|
|
FIELD( 17, 0, EBX, 0, 16, SOC_VENDOR_ID, NO, 0 ) \
|
|
FIELD( 17, 0, EBX, 16, 1, SOC_INDUSTRY_STD, NO, 0 ) \
|
|
FIELD( 17, 0, ECX, 0, 31, SOC_PROJECT_ID, NO, 0 ) \
|
|
FIELD( 17, 0, EDX, 0, 31, SOC_STEPPING_ID, NO, 0 ) \
|
|
FIELD( 17, 1, EAX, 0, 32, SOC_VENDOR_BRAND_STRING_1_0, NO, 0 ) \
|
|
FIELD( 17, 1, EBX, 0, 32, SOC_VENDOR_BRAND_STRING_1_1, NO, 0 ) \
|
|
FIELD( 17, 1, ECX, 0, 32, SOC_VENDOR_BRAND_STRING_1_2, NO, 0 ) \
|
|
FIELD( 17, 1, EDX, 0, 32, SOC_VENDOR_BRAND_STRING_1_3, NO, 0 ) \
|
|
FIELD( 17, 2, EAX, 0, 32, SOC_VENDOR_BRAND_STRING_2_0, NO, 0 ) \
|
|
FIELD( 17, 2, EBX, 0, 32, SOC_VENDOR_BRAND_STRING_2_1, NO, 0 ) \
|
|
FIELD( 17, 2, ECX, 0, 32, SOC_VENDOR_BRAND_STRING_2_2, NO, 0 ) \
|
|
FIELD( 17, 2, EDX, 0, 32, SOC_VENDOR_BRAND_STRING_2_3, NO, 0 ) \
|
|
FIELD( 17, 3, EAX, 0, 32, SOC_VENDOR_BRAND_STRING_3_0, NO, 0 ) \
|
|
FIELD( 17, 3, EBX, 0, 32, SOC_VENDOR_BRAND_STRING_3_1, NO, 0 ) \
|
|
FIELD( 17, 3, ECX, 0, 32, SOC_VENDOR_BRAND_STRING_3_2, NO, 0 ) \
|
|
FIELD( 17, 3, EDX, 0, 32, SOC_VENDOR_BRAND_STRING_3_3, NO, 0 ) \
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_18 \
|
|
FIELD( 18, 0, EAX, 0, 32, TLB_INFO_MAX_SUBLEAF, NO, 0 ) \
|
|
FLAG( 18, 0, EBX, 0, 1, TLB_INFO_LEVEL_SIZE_4K, NO, 0 ) \
|
|
FLAG( 18, 0, EBX, 1, 1, TLB_INFO_LEVEL_SIZE_2M, NO, 0 ) \
|
|
FLAG( 18, 0, EBX, 2, 1, TLB_INFO_LEVEL_SIZE_4M, NO, 0 ) \
|
|
FLAG( 18, 0, EBX, 3, 1, TLB_INFO_LEVEL_SIZE_1G, NO, 0 ) \
|
|
FIELD( 18, 0, EBX, 8, 3, TLB_INFO_PARTITIONING, NO, 0 ) \
|
|
FIELD( 18, 0, EBX, 16, 16, TLB_INFO_NUM_WAYS, NO, 0 ) \
|
|
FIELD( 18, 0, ECX, 0, 32, TLB_INFO_NUM_SETS, NO, 0 ) \
|
|
FIELD( 18, 0, EDX, 0, 5, TLB_INFO_TYPE, NO, 0 ) \
|
|
FIELD( 18, 0, EDX, 5, 3, TLB_INFO_LEVEL, NO, 0 ) \
|
|
FLAG( 18, 0, EDX, 8, 1, TLB_INFO_FULLY_ASSOCIATIVE, NO, 0 ) \
|
|
FIELD( 18, 0, EDX, 14, 12, TLB_INFO_MAX_ADDRESSABLE_IDS, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_1A \
|
|
FIELD( 1A, 0, EAX, 0, 24, NATIVE_MODEL_ID, NO, 0 ) \
|
|
FIELD( 1A, 0, EAX, 24, 8, CORE_TYPE, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_1B \
|
|
FIELD( 1B, 0, EAX, 0, 12, PCONFIG_SUBLEAF_TYPE, NO, 0 ) \
|
|
FIELD( 1B, 0, EBX, 0, 32, PCONFIG_TARGET_ID1, NO, 0 ) \
|
|
FIELD( 1B, 0, ECX, 0, 32, PCONFIG_TARGET_ID2, NO, 0 ) \
|
|
FIELD( 1B, 0, EDX, 0, 32, PCONFIG_TARGET_ID3, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_1F \
|
|
FIELD( 1F, 0, EAX, 0, 5, TOPOLOGY_V2_MASK_WIDTH, NA, 0 ) \
|
|
FIELD( 1F, 0, EBX, 0, 16, TOPOLOGY_V2_CPUS_SHARING_LEVEL, NA, 0 ) \
|
|
FIELD( 1F, 0, ECX, 0, 8, TOPOLOGY_V2_LEVEL_NUMBER, NA, 0 ) \
|
|
FIELD( 1F, 0, ECX, 8, 8, TOPOLOGY_V2_LEVEL_TYPE, NA, 0 ) \
|
|
FIELD( 1F, 0, EDX, 0, 32, TOPOLOGY_V2_X2APIC_ID, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_400 \
|
|
FIELD(400, 0, EAX, 0, 32, MAX_HYP_LEVEL, NA, 0 ) \
|
|
FIELD(400, 0, EBX, 0, 32, HYPERVISOR_VENDOR0, NA, 0 ) \
|
|
FIELD(400, 0, ECX, 0, 32, HYPERVISOR_VENDOR1, NA, 0 ) \
|
|
FIELD(400, 0, EDX, 0, 32, HYPERVISOR_VENDOR2, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_401 \
|
|
FIELD(401, 0, EAX, 0, 32, HV_INTERFACE_SIGNATURE, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_402 \
|
|
FIELD(402, 0, EAX, 0, 32, BUILD_NUMBER, NA, 0 ) \
|
|
FIELD(402, 0, EBX, 0, 16, MINOR_VERSION, NA, 0 ) \
|
|
FIELD(402, 0, EBX, 16, 16, MAJOR_VERSION, NA, 0 ) \
|
|
FIELD(402, 0, ECX, 0, 32, SERVICE_PACK, NA, 0 ) \
|
|
FIELD(402, 0, EDX, 0, 24, SERVICE_NUMBER, NA, 0 ) \
|
|
FIELD(402, 0, EDX, 24, 8, SERVICE_BRANCH, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_403 \
|
|
FLAG( 403, 0, EAX, 0, 1, VP_RUNTIME_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 1, 1, REF_COUNTER_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 2, 1, BASIC_SYNIC_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 3, 1, SYNTH_TIMER_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 4, 1, APIC_ACCESS_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 5, 1, HYPERCALL_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 6, 1, VP_INDEX_MSR_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 7, 1, VIRT_RESET_MSR_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 8, 1, STATS_PAGES_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 9, 1, REF_TSC_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 10, 1, GUEST_IDLE_MSR_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 11, 1, FREQUENCY_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EAX, 12, 1, SYNTH_DEBUG_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 0, 1, CREATE_PARTITIONS_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 1, 1, ACCESS_PARTITION_ID_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 2, 1, ACCESS_MEMORY_POOL_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 3, 1, ADJUST_MESSAGE_BUFFERS_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 4, 1, POST_MESSAGES_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 5, 1, SIGNAL_EVENTS_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 6, 1, CREATE_PORT_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 7, 1, CONNECT_PORT_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 8, 1, ACCESS_STATS_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 11, 1, DEBUGGING_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 12, 1, CPU_MANAGEMENT_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 13, 1, CONFIGURE_PROFILER_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 14, 1, ENABLE_EXPANDED_STACKWALKING_FLAG, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 16, 1, ACCESS_VSM, NA, 0 ) \
|
|
FLAG( 403, 0, EBX, 17, 1, ACCESS_VP_REGISTERS, NA, 0 ) \
|
|
FIELD(403, 0, ECX, 0, 4, MAX_POWER_STATE, NA, 0 ) \
|
|
FLAG( 403, 0, ECX, 4, 1, HPET_NEEDED_FOR_C3, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 0, 1, MWAIT_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 1, 1, GUEST_DEBUGGING_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 2, 1, PERFORMANCE_MONITOR_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 3, 1, CPU_DYN_PARTITIONING_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 4, 1, XMM_REGS_FOR_HYPERCALL_INPUT, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 5, 1, GUEST_IDLE_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 6, 1, HYPERVISOR_SLEEP_STATE_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 7, 1, NUMA_DISTANCE_QUERY_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 8, 1, TIMER_FREQUENCY_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 9, 1, SYNTH_MACHINE_CHECK_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 10, 1, GUEST_CRASH_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 11, 1, DEBUG_MSRS_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 12, 1, NPIEP1_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 13, 1, DISABLE_HYPERVISOR_AVAIL, NA, 0 ) \
|
|
FLAG( 403, 0, EDX, 15, 1, XMM_REGS_FOR_HYPERCALL_OUTPUT, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_404 \
|
|
FLAG( 404, 0, EAX, 0, 1, USE_HYPERCALL_TO_SWITCH_ADDR_SPACE, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 1, 1, USE_HYPERCALL_TO_FLUSH_TLB, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 2, 1, USE_HYPERCALL_FOR_TLB_SHOOTDOWN, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 3, 1, USE_MSRS_FOR_EOI_ICR_TPR, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 4, 1, USE_MSR_FOR_RESET, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 5, 1, USE_RELAXED_TIMING, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 6, 1, USE_DMA_REMAPPING, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 7, 1, USE_INTERRUPT_REMAPPING, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 8, 1, USE_X2APIC, NA, 0 ) \
|
|
FLAG( 404, 0, EAX, 9, 1, DEPRECATE_AUTOEOI, NA, 0 ) \
|
|
FIELD(404, 0, EBX, 0, 32, SPINLOCK_RETRIES, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_405 \
|
|
FIELD(405, 0, EAX, 0, 32, MAX_VCPU, NA, 0 ) \
|
|
FIELD(405, 0, EBX, 0, 32, MAX_LCPU, NA, 0 ) \
|
|
FIELD(405, 0, ECX, 0, 32, MAX_REMAPPABLE_VECTORS, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_406 \
|
|
FLAG( 406, 0, EAX, 0, 1, APIC_OVERLAY_ASSIST, NA, 0 ) \
|
|
FLAG( 406, 0, EAX, 1, 1, MSR_BITMAPS, NA, 0 ) \
|
|
FLAG( 406, 0, EAX, 2, 1, ARCH_PMCS, NA, 0 ) \
|
|
FLAG( 406, 0, EAX, 3, 1, SLAT, NA, 0 ) \
|
|
FLAG( 406, 0, EAX, 4, 1, DMA_REMAPPING, NA, 0 ) \
|
|
FLAG( 406, 0, EAX, 5, 1, INTERRUPT_REMAPPING, NA, 0 ) \
|
|
FLAG( 406, 0, EAX, 6, 1, MEMORY_PATROL_SCRUBBER, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_410 \
|
|
FIELD(410, 0, EAX, 0, 32, TSC_HZ, NA, 0 ) \
|
|
FIELD(410, 0, EBX, 0, 32, APICBUS_HZ, NA, 0 ) \
|
|
FLAG( 410, 0, ECX, 0, 1, VMMCALL_BACKDOOR, NA, 0 ) \
|
|
FLAG( 410, 0, ECX, 1, 1, VMCALL_BACKDOOR, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_80 \
|
|
FIELD( 80, 0, EAX, 0, 32, NUM_EXT_LEVELS, NA, 0 ) \
|
|
FIELD( 80, 0, EBX, 0, 32, LEAF80_VENDOR1, NA, 0 ) \
|
|
FIELD( 80, 0, ECX, 0, 32, LEAF80_VENDOR3, NA, 0 ) \
|
|
FIELD( 80, 0, EDX, 0, 32, LEAF80_VENDOR2, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_81 \
|
|
FIELD( 81, 0, EAX, 0, 4, LEAF81_STEPPING, ANY, 4 ) \
|
|
FIELD( 81, 0, EAX, 4, 4, LEAF81_MODEL, ANY, 4 ) \
|
|
FIELD( 81, 0, EAX, 8, 4, LEAF81_FAMILY, ANY, 4 ) \
|
|
FIELD( 81, 0, EAX, 12, 2, LEAF81_TYPE, ANY, 4 ) \
|
|
FIELD( 81, 0, EAX, 16, 4, LEAF81_EXTENDED_MODEL, ANY, 4 ) \
|
|
FIELD( 81, 0, EAX, 20, 8, LEAF81_EXTENDED_FAMILY, ANY, 4 ) \
|
|
FIELD( 81, 0, EBX, 0, 16, LEAF81_BRAND_ID, ANY, 4 ) \
|
|
FIELD( 81, 0, EBX, 16, 16, UNDEF, ANY, 4 ) \
|
|
FLAG( 81, 0, ECX, 0, 1, LAHF64, YES, 4 ) \
|
|
FLAG( 81, 0, ECX, 1, 1, CMPLEGACY, ANY, 9 ) \
|
|
FLAG( 81, 0, ECX, 2, 1, SVM, YES, 8 ) \
|
|
FLAG( 81, 0, ECX, 3, 1, EXTAPICSPC, YES, 4 ) \
|
|
FLAG( 81, 0, ECX, 4, 1, CR8AVAIL, YES, 9 ) \
|
|
FLAG( 81, 0, ECX, 5, 1, ABM, YES, 4 ) \
|
|
FLAG( 81, 0, ECX, 6, 1, SSE4A, YES, 4 ) \
|
|
FLAG( 81, 0, ECX, 7, 1, MISALIGNED_SSE, YES, 4 ) \
|
|
FLAG( 81, 0, ECX, 8, 1, 3DNPREFETCH, YES, 4 ) \
|
|
FLAG( 81, 0, ECX, 9, 1, OSVW, ANY, 8 ) \
|
|
FLAG( 81, 0, ECX, 10, 1, IBS, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 11, 1, XOP, YES, 8 ) \
|
|
FLAG( 81, 0, ECX, 12, 1, SKINIT, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 13, 1, WATCHDOG, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 15, 1, LWP, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 16, 1, FMA4, YES, 8 ) \
|
|
FLAG( 81, 0, ECX, 17, 1, TCE, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 19, 1, NODEID_MSR, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 21, 1, TBM, YES, 9 ) \
|
|
FLAG( 81, 0, ECX, 22, 1, TOPOLOGY, ANY, 18 ) \
|
|
FLAG( 81, 0, ECX, 23, 1, PERFCORE, ANY, 4 ) \
|
|
FLAG( 81, 0, ECX, 24, 1, PERFNB, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 26, 1, DATABK, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 27, 1, PERFTSC, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 28, 1, PERFL3, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 29, 1, MWAITX, NO, 0 ) \
|
|
FLAG( 81, 0, ECX, 30, 1, ADDR_MASK_EXT, NO, 0 ) \
|
|
FLAG( 81, 0, EDX, 0, 1, LEAF81_FPU, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 1, 1, LEAF81_VME, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 2, 1, LEAF81_DE, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 3, 1, LEAF81_PSE, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 4, 1, LEAF81_TSC, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 5, 1, LEAF81_MSR, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 6, 1, LEAF81_PAE, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 7, 1, LEAF81_MCE, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 8, 1, LEAF81_CX8, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 9, 1, LEAF81_APIC, ANY, 4 ) \
|
|
FLAG( 81, 0, EDX, 11, 1, SYSC, ANY, 4 ) \
|
|
FLAG( 81, 0, EDX, 12, 1, LEAF81_MTRR, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 13, 1, LEAF81_PGE, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 14, 1, LEAF81_MCA, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 15, 1, LEAF81_CMOV, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 16, 1, LEAF81_PAT, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 17, 1, LEAF81_PSE36, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 20, 1, NX, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 22, 1, MMXEXT, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 23, 1, LEAF81_MMX, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 24, 1, LEAF81_FXSR, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 25, 1, FFXSR, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 26, 1, PDPE1GB, YES, 9 ) \
|
|
FLAG( 81, 0, EDX, 27, 1, RDTSCP, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 29, 1, LM, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 30, 1, 3DNOWPLUS, YES, 4 ) \
|
|
FLAG( 81, 0, EDX, 31, 1, 3DNOW, YES, 4 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_82 \
|
|
FIELD( 82, 0, EAX, 0, 32, LEAF82_BRAND_STRING_EAX, NA, 0 ) \
|
|
FIELD( 82, 0, EBX, 0, 32, LEAF82_BRAND_STRING_EBX, NA, 0 ) \
|
|
FIELD( 82, 0, ECX, 0, 32, LEAF82_BRAND_STRING_ECX, NA, 0 ) \
|
|
FIELD( 82, 0, EDX, 0, 32, LEAF82_BRAND_STRING_EDX, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_83 \
|
|
FIELD( 83, 0, EAX, 0, 32, LEAF83_BRAND_STRING_EAX, NA, 0 ) \
|
|
FIELD( 83, 0, EBX, 0, 32, LEAF83_BRAND_STRING_EBX, NA, 0 ) \
|
|
FIELD( 83, 0, ECX, 0, 32, LEAF83_BRAND_STRING_ECX, NA, 0 ) \
|
|
FIELD( 83, 0, EDX, 0, 32, LEAF83_BRAND_STRING_EDX, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_84 \
|
|
FIELD( 84, 0, EAX, 0, 32, LEAF84_BRAND_STRING_EAX, NA, 0 ) \
|
|
FIELD( 84, 0, EBX, 0, 32, LEAF84_BRAND_STRING_EBX, NA, 0 ) \
|
|
FIELD( 84, 0, ECX, 0, 32, LEAF84_BRAND_STRING_ECX, NA, 0 ) \
|
|
FIELD( 84, 0, EDX, 0, 32, LEAF84_BRAND_STRING_EDX, NA, 0 )
|
|
|
|
/* LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_85 \
|
|
FIELD( 85, 0, EAX, 0, 8, ITLB_ENTRIES_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, EAX, 8, 8, ITLB_ASSOC_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, EAX, 16, 8, DTLB_ENTRIES_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, EAX, 24, 8, DTLB_ASSOC_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, EBX, 0, 8, ITLB_ENTRIES_4K_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, EBX, 8, 8, ITLB_ASSOC_4K_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, EBX, 16, 8, DTLB_ENTRIES_4K_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, EBX, 24, 8, DTLB_ASSOC_4K_PGS, NA, 0 ) \
|
|
FIELD( 85, 0, ECX, 0, 8, L1_DCACHE_LINE_SIZE, NA, 0 ) \
|
|
FIELD( 85, 0, ECX, 8, 8, L1_DCACHE_LINES_PER_TAG, NA, 0 ) \
|
|
FIELD( 85, 0, ECX, 16, 8, L1_DCACHE_ASSOC, NA, 0 ) \
|
|
FIELD( 85, 0, ECX, 24, 8, L1_DCACHE_SIZE, NA, 0 ) \
|
|
FIELD( 85, 0, EDX, 0, 8, L1_ICACHE_LINE_SIZE, NA, 0 ) \
|
|
FIELD( 85, 0, EDX, 8, 8, L1_ICACHE_LINES_PER_TAG, NA, 0 ) \
|
|
FIELD( 85, 0, EDX, 16, 8, L1_ICACHE_ASSOC, NA, 0 ) \
|
|
FIELD( 85, 0, EDX, 24, 8, L1_ICACHE_SIZE, NA, 0 )
|
|
|
|
/* LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_86 \
|
|
FIELD( 86, 0, EAX, 0, 12, L2_ITLB_ENTRIES_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, EAX, 12, 4, L2_ITLB_ASSOC_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, EAX, 16, 12, L2_DTLB_ENTRIES_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, EAX, 28, 4, L2_DTLB_ASSOC_2M4M_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, EBX, 0, 12, L2_ITLB_ENTRIES_4K_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, EBX, 12, 4, L2_ITLB_ASSOC_4K_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, EBX, 16, 12, L2_DTLB_ENTRIES_4K_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, EBX, 28, 4, L2_DTLB_ASSOC_4K_PGS, NA, 0 ) \
|
|
FIELD( 86, 0, ECX, 0, 8, L2CACHE_LINE, NA, 0 ) \
|
|
FIELD( 86, 0, ECX, 8, 4, L2CACHE_LINE_PER_TAG, NA, 0 ) \
|
|
FIELD( 86, 0, ECX, 12, 4, L2CACHE_WAYS, NA, 0 ) \
|
|
FIELD( 86, 0, ECX, 16, 16, L2CACHE_SIZE, NA, 0 ) \
|
|
FIELD( 86, 0, EDX, 0, 8, L3CACHE_LINE, NA, 0 ) \
|
|
FIELD( 86, 0, EDX, 8, 4, L3CACHE_LINE_PER_TAG, NA, 0 ) \
|
|
FIELD( 86, 0, EDX, 12, 4, L3CACHE_WAYS, NA, 0 ) \
|
|
FIELD( 86, 0, EDX, 18, 14, L3CACHE_SIZE, NA, 0 )
|
|
|
|
/* LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_87 \
|
|
FLAG( 87, 0, EBX, 0, 1, MCA_OVERFLOW_RECOV, NA, 0 ) \
|
|
FLAG( 87, 0, EBX, 1, 1, SUCCOR, NA, 0 ) \
|
|
FLAG( 87, 0, EBX, 2, 1, HWA, NA, 0 ) \
|
|
FLAG( 87, 0, EBX, 3, 1, SCALABLE_MCA, NA, 0 ) \
|
|
FLAG( 87, 0, EBX, 4, 1, PFEH_SUPPORT_PRESENT, NA, 0 ) \
|
|
FIELD( 87, 0, ECX, 0, 32, POWER_SAMPLE_TIME_RATIO, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 0, 1, TS, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 1, 1, FID, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 2, 1, VID, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 3, 1, TTP, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 4, 1, LEAF87_TM, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 5, 1, STC, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 6, 1, 100MHZSTEPS, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 7, 1, HWPSTATE, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 8, 1, TSC_INVARIANT, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 9, 1, CORE_PERF_BOOST, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 10, 1, EFFECTIVE_FREQUENCY, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 11, 1, PROC_FEEDBACK_INTERFACE, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 12, 1, PROC_POWER_REPORTING, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 13, 1, CONNECTED_STANDBY, NA, 0 ) \
|
|
FLAG( 87, 0, EDX, 14, 1, RAPL, NA, 0 )
|
|
|
|
/* LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_88 \
|
|
FIELD( 88, 0, EAX, 0, 8, PHYS_BITS, YES, 4 ) \
|
|
FIELD( 88, 0, EAX, 8, 8, VIRT_BITS, YES, 4 ) \
|
|
FIELD( 88, 0, EAX, 16, 8, GUEST_PHYS_ADDR_SZ, YES, 8 ) \
|
|
FLAG( 88, 0, EBX, 0, 1, CLZERO, YES, 14 ) \
|
|
FLAG( 88, 0, EBX, 1, 1, IRPERF, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 2, 1, XSAVE_ERR_PTR, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 3, 1, INVLPGB, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 4, 1, RDPRU, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 6, 1, MBE, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 8, 1, MCOMMIT, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 9, 1, WBNOINVD, YES, 17 ) \
|
|
FLAG( 88, 0, EBX, 10, 1, LBREXTN, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 12, 1, LEAF88_IBPB, ANY, 9 ) \
|
|
FLAG( 88, 0, EBX, 13, 1, WBINVD_INT, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 14, 1, LEAF88_IBRS, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 15, 1, LEAF88_STIBP, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 16, 1, LEAF88_IBRS_ALWAYS, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 17, 1, LEAF88_STIBP_ALWAYS, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 18, 1, LEAF88_PREFER_IBRS, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 19, 1, LEAF88_IBRS_SAME_MODE, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 20, 1, LMSLE_UNSUPPORTED, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 23, 1, PPIN, NO, 0 ) \
|
|
FLAG( 88, 0, EBX, 24, 1, LEAF88_SSBD_SPEC_CTRL, ANY, 9 ) \
|
|
FLAG( 88, 0, EBX, 25, 1, LEAF88_SSBD_VIRT_SPEC_CTRL, ANY, 9 ) \
|
|
FLAG( 88, 0, EBX, 26, 1, LEAF88_SSBD_NOT_NEEDED, NO, 0 ) \
|
|
FIELD( 88, 0, ECX, 0, 8, LEAF88_CORE_COUNT, YES, 4 ) \
|
|
FIELD( 88, 0, ECX, 12, 4, APICID_COREID_SIZE, YES, 7 ) \
|
|
FIELD( 88, 0, ECX, 16, 2, PERFTSC_SIZE, NO, 0 ) \
|
|
FIELD( 88, 0, EDX, 0, 16, INVLPGB_MAX, NO, 0 ) \
|
|
FIELD( 88, 0, EDX, 16, 8, RDPRU_MAX, NO, 0 )
|
|
|
|
#define CPUID_8A_EDX_11 \
|
|
FLAG( 8A, 0, EDX, 11, 1, SVMEDX_RSVD1, NO, 0 )
|
|
#define CPUID_8A_EDX_14 \
|
|
FLAG( 8A, 0, EDX, 14, 1, SVMEDX_RSVD2, NO, 0 )
|
|
|
|
/* LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_8A \
|
|
FIELD( 8A, 0, EAX, 0, 8, SVM_REVISION, YES, 4 ) \
|
|
FLAG( 8A, 0, EAX, 8, 1, SVM_HYPERVISOR, NO, 0 ) \
|
|
FIELD( 8A, 0, EAX, 9, 23, SVMEAX_RSVD, NO, 0 ) \
|
|
FIELD( 8A, 0, EBX, 0, 32, SVM_NUM_ASIDS, YES, 7 ) \
|
|
FIELD( 8A, 0, ECX, 0, 32, SVMECX_RSVD, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 0, 1, SVM_NPT, YES, 7 ) \
|
|
FLAG( 8A, 0, EDX, 1, 1, SVM_LBR, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 2, 1, SVM_LOCK, ANY, 7 ) \
|
|
FLAG( 8A, 0, EDX, 3, 1, SVM_NRIP, YES, 7 ) \
|
|
FLAG( 8A, 0, EDX, 4, 1, SVM_TSC_RATE_MSR, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 5, 1, SVM_VMCB_CLEAN, YES, 7 ) \
|
|
FLAG( 8A, 0, EDX, 6, 1, SVM_FLUSH_BY_ASID, YES, 7 ) \
|
|
FLAG( 8A, 0, EDX, 7, 1, SVM_DECODE_ASSISTS, YES, 7 ) \
|
|
FIELD( 8A, 0, EDX, 8, 2, SVMEDX_RSVD0, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 10, 1, SVM_PAUSE_FILTER, NO, 0 ) \
|
|
CPUID_8A_EDX_11 \
|
|
FLAG( 8A, 0, EDX, 12, 1, SVM_PAUSE_THRESHOLD, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 13, 1, SVM_AVIC, NO, 0 ) \
|
|
CPUID_8A_EDX_14 \
|
|
FLAG( 8A, 0, EDX, 15, 1, SVM_V_VMSAVE_VMLOAD, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 16, 1, SVM_VGIF, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 17, 1, SVM_GMET, YES, 17 ) \
|
|
FIELD( 8A, 0, EDX, 18, 2, SVMEDX_RSVD3, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 20, 1, SVM_GUEST_SPEC_CTRL, NO, 0 ) \
|
|
FIELD( 8A, 0, EDX, 21, 3, SVMEDX_RSVD4, NO, 0 ) \
|
|
FLAG( 8A, 0, EDX, 24, 1, SVM_TLB_CTL, NO, 0 ) \
|
|
FIELD( 8A, 0, EDX, 25, 7, SVMEDX_RSVD5, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_819 \
|
|
FIELD(819, 0, EAX, 0, 12, L1_ITLB_ENTRIES_1G_PGS, NA, 0 ) \
|
|
FIELD(819, 0, EAX, 12, 4, L1_ITLB_ASSOC_1G_PGS, NA, 0 ) \
|
|
FIELD(819, 0, EAX, 16, 12, L1_DTLB_ENTRIES_1G_PGS, NA, 0 ) \
|
|
FIELD(819, 0, EAX, 28, 4, L1_DTLB_ASSOC_1G_PGS, NA, 0 ) \
|
|
FIELD(819, 0, EBX, 0, 12, L2_ITLB_ENTRIES_1G_PGS, NA, 0 ) \
|
|
FIELD(819, 0, EBX, 12, 4, L2_ITLB_ASSOC_1G_PGS, NA, 0 ) \
|
|
FIELD(819, 0, EBX, 16, 12, L2_DTLB_ENTRIES_1G_PGS, NA, 0 ) \
|
|
FIELD(819, 0, EBX, 28, 4, L2_DTLB_ASSOC_1G_PGS, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_81A \
|
|
FLAG( 81A, 0, EAX, 0, 1, FP128, NA, 0 ) \
|
|
FLAG( 81A, 0, EAX, 1, 1, MOVU, NA, 0 ) \
|
|
FLAG( 81A, 0, EAX, 2, 1, FP256, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_81B \
|
|
FLAG( 81B, 0, EAX, 0, 1, IBS_FFV, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 1, 1, IBS_FETCHSAM, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 2, 1, IBS_OPSAM, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 3, 1, RW_OPCOUNT, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 4, 1, OPCOUNT, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 5, 1, BRANCH_TARGET_ADDR, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 6, 1, OPCOUNT_EXT, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 7, 1, RIP_INVALID_CHECK, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 8, 1, OP_BRN_FUSE, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 9, 1, IBS_FETCH_CTL_EXTD, NA, 0 ) \
|
|
FLAG( 81B, 0, EAX, 10, 1, IBS_OP_DATA4, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_81C \
|
|
FLAG( 81C, 0, EAX, 0, 1, LWP_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 1, 1, LWP_VAL_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 2, 1, LWP_IRE_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 3, 1, LWP_BRE_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 4, 1, LWP_DME_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 5, 1, LWP_CNH_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 6, 1, LWP_RNH_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 29, 1, LWP_CONT_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 30, 1, LWP_PTSC_AVAIL, NA, 0 ) \
|
|
FLAG( 81C, 0, EAX, 31, 1, LWP_INT_AVAIL, NA, 0 ) \
|
|
FIELD(81C, 0, EBX, 0, 8, LWP_CB_SIZE, NA, 0 ) \
|
|
FIELD(81C, 0, EBX, 8, 8, LWP_EVENT_SIZE, NA, 0 ) \
|
|
FIELD(81C, 0, EBX, 16, 8, LWP_MAX_EVENTS, NA, 0 ) \
|
|
FIELD(81C, 0, EBX, 24, 8, LWP_EVENT_OFFSET, NA, 0 ) \
|
|
FIELD(81C, 0, ECX, 0, 4, LWP_LATENCY_MAX, NA, 0 ) \
|
|
FLAG( 81C, 0, ECX, 5, 1, LWP_DATA_ADDR_VALID, NA, 0 ) \
|
|
FIELD(81C, 0, ECX, 6, 3, LWP_LATENCY_ROUND, NA, 0 ) \
|
|
FIELD(81C, 0, ECX, 9, 7, LWP_VERSION, NA, 0 ) \
|
|
FIELD(81C, 0, ECX, 16, 8, LWP_MIN_BUF_SIZE, NA, 0 ) \
|
|
FLAG( 81C, 0, ECX, 28, 1, LWP_BRANCH_PRED, NA, 0 ) \
|
|
FLAG( 81C, 0, ECX, 29, 1, LWP_IP_FILTERING, NA, 0 ) \
|
|
FLAG( 81C, 0, ECX, 30, 1, LWP_CACHE_LEVEL, NA, 0 ) \
|
|
FLAG( 81C, 0, ECX, 31, 1, LWP_CACHE_LATENCY, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 0, 1, LWP_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 1, 1, LWP_VAL_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 2, 1, LWP_IRE_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 3, 1, LWP_BRE_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 4, 1, LWP_DME_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 5, 1, LWP_CNH_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 6, 1, LWP_RNH_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 29, 1, LWP_CONT_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 30, 1, LWP_PTSC_SUPPORTED, NA, 0 ) \
|
|
FLAG( 81C, 0, EDX, 31, 1, LWP_INT_SUPPORTED, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_81D \
|
|
FIELD(81D, 0, EAX, 0, 5, LEAF81D_CACHE_TYPE, NA, 0 ) \
|
|
FIELD(81D, 0, EAX, 5, 3, LEAF81D_CACHE_LEVEL, NA, 0 ) \
|
|
FLAG( 81D, 0, EAX, 8, 1, LEAF81D_CACHE_SELF_INIT, NA, 0 ) \
|
|
FLAG( 81D, 0, EAX, 9, 1, LEAF81D_CACHE_FULLY_ASSOC, NA, 0 ) \
|
|
FIELD(81D, 0, EAX, 14, 12, LEAF81D_NUM_SHARING_CACHE, NA, 0 ) \
|
|
FIELD(81D, 0, EBX, 0, 12, LEAF81D_CACHE_LINE_SIZE, NA, 0 ) \
|
|
FIELD(81D, 0, EBX, 12, 10, LEAF81D_CACHE_PHYS_PARTITIONS, NA, 0 ) \
|
|
FIELD(81D, 0, EBX, 22, 10, LEAF81D_CACHE_WAYS, NA, 0 ) \
|
|
FIELD(81D, 0, ECX, 0, 32, LEAF81D_CACHE_NUM_SETS, NA, 0 ) \
|
|
FLAG( 81D, 0, EDX, 0, 1, LEAF81D_CACHE_WBINVD, NA, 0 ) \
|
|
FLAG( 81D, 0, EDX, 1, 1, LEAF81D_CACHE_INCLUSIVE, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_81E \
|
|
FIELD(81E, 0, EAX, 0, 32, EXTENDED_APICID, NA, 0 ) \
|
|
FIELD(81E, 0, EBX, 0, 8, COMPUTE_UNIT_ID, NA, 0 ) \
|
|
FIELD(81E, 0, EBX, 8, 2, CORES_PER_COMPUTE_UNIT, NA, 0 ) \
|
|
FIELD(81E, 0, ECX, 0, 8, NODEID_VAL, NA, 0 ) \
|
|
FIELD(81E, 0, ECX, 8, 3, NODES_PER_PKG, NA, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_81F \
|
|
FLAG( 81F, 0, EAX, 0, 1, SME, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 1, 1, SEV, YES, 17 ) \
|
|
FLAG( 81F, 0, EAX, 2, 1, PAGE_FLUSH_MSR, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 3, 1, SEV_ES, YES, 17 ) \
|
|
FLAG( 81F, 0, EAX, 4, 1, SEV_SNP, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 5, 1, VMPL, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 10, 1, SEV_HEC, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 11, 1, SEV_64BIT_REQ, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 12, 1, SEV_RESTR_INJECTION, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 13, 1, SEV_ALT_INJECTION, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 14, 1, SEV_DEBUG_SWAP, NO, 0 ) \
|
|
FLAG( 81F, 0, EAX, 15, 1, SEV_NO_HOST_IBS, NO, 0 ) \
|
|
FIELD(81F, 0, EBX, 0, 6, SME_PAGE_TABLE_BIT_NUM, YES, 17 ) \
|
|
FIELD(81F, 0, EBX, 6, 6, SME_PHYS_ADDR_SPACE_REDUCTION, NO, 0 ) \
|
|
FIELD(81F, 0, EBX, 12, 4, NUM_VMPL, NO, 0 ) \
|
|
FIELD(81F, 0, ECX, 0, 32, NUM_ENCRYPTED_GUESTS, NO, 0 ) \
|
|
FIELD(81F, 0, EDX, 0, 32, SEV_MIN_ASID, NO, 0 )
|
|
|
|
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV */
|
|
#define CPUID_FIELD_DATA_LEVEL_820 \
|
|
FLAG( 820, 0, EBX, 1, 1, LEAF820_MBE, NO, 0 ) \
|
|
FIELD(820, 1, EAX, 0, 32, CAPACITY_MASK_LEN, NO, 0 ) \
|
|
FIELD(820, 1, EDX, 0, 32, NUM_SERVICE_CLASSES, NO, 0 )
|
|
|
|
#define CPUID_FIELD_DATA_LEVEL_821
|
|
|
|
#define CPUID_FIELD_DATA \
|
|
CPUID_FIELD_DATA_LEVEL_0 \
|
|
CPUID_FIELD_DATA_LEVEL_1 \
|
|
CPUID_FIELD_DATA_LEVEL_2 \
|
|
CPUID_FIELD_DATA_LEVEL_4 \
|
|
CPUID_FIELD_DATA_LEVEL_5 \
|
|
CPUID_FIELD_DATA_LEVEL_6 \
|
|
CPUID_FIELD_DATA_LEVEL_7 \
|
|
CPUID_FIELD_DATA_LEVEL_9 \
|
|
CPUID_FIELD_DATA_LEVEL_A \
|
|
CPUID_FIELD_DATA_LEVEL_B \
|
|
CPUID_FIELD_DATA_LEVEL_D \
|
|
CPUID_FIELD_DATA_LEVEL_F \
|
|
CPUID_FIELD_DATA_LEVEL_10 \
|
|
CPUID_FIELD_DATA_LEVEL_12 \
|
|
CPUID_FIELD_DATA_LEVEL_14 \
|
|
CPUID_FIELD_DATA_LEVEL_15 \
|
|
CPUID_FIELD_DATA_LEVEL_16 \
|
|
CPUID_FIELD_DATA_LEVEL_17 \
|
|
CPUID_FIELD_DATA_LEVEL_18 \
|
|
CPUID_FIELD_DATA_LEVEL_1A \
|
|
CPUID_FIELD_DATA_LEVEL_1B \
|
|
CPUID_FIELD_DATA_LEVEL_1F \
|
|
CPUID_FIELD_DATA_LEVEL_400 \
|
|
CPUID_FIELD_DATA_LEVEL_401 \
|
|
CPUID_FIELD_DATA_LEVEL_402 \
|
|
CPUID_FIELD_DATA_LEVEL_403 \
|
|
CPUID_FIELD_DATA_LEVEL_404 \
|
|
CPUID_FIELD_DATA_LEVEL_405 \
|
|
CPUID_FIELD_DATA_LEVEL_406 \
|
|
CPUID_FIELD_DATA_LEVEL_410 \
|
|
CPUID_FIELD_DATA_LEVEL_80 \
|
|
CPUID_FIELD_DATA_LEVEL_81 \
|
|
CPUID_FIELD_DATA_LEVEL_82 \
|
|
CPUID_FIELD_DATA_LEVEL_83 \
|
|
CPUID_FIELD_DATA_LEVEL_84 \
|
|
CPUID_FIELD_DATA_LEVEL_85 \
|
|
CPUID_FIELD_DATA_LEVEL_86 \
|
|
CPUID_FIELD_DATA_LEVEL_87 \
|
|
CPUID_FIELD_DATA_LEVEL_88 \
|
|
CPUID_FIELD_DATA_LEVEL_8A \
|
|
CPUID_FIELD_DATA_LEVEL_819 \
|
|
CPUID_FIELD_DATA_LEVEL_81A \
|
|
CPUID_FIELD_DATA_LEVEL_81B \
|
|
CPUID_FIELD_DATA_LEVEL_81C \
|
|
CPUID_FIELD_DATA_LEVEL_81D \
|
|
CPUID_FIELD_DATA_LEVEL_81E \
|
|
CPUID_FIELD_DATA_LEVEL_81F \
|
|
CPUID_FIELD_DATA_LEVEL_820 \
|
|
CPUID_FIELD_DATA_LEVEL_821
|
|
|
|
/*
|
|
* Define all field and flag values as an enum. The result is a full
|
|
* set of values taken from the table above in the form:
|
|
*
|
|
* CPUID_<name>_MASK == mask for feature/field
|
|
* CPUID_<name>_SHIFT == offset of field
|
|
*
|
|
* e.g. - CPUID_VIRT_BITS_MASK = 0xff00
|
|
* - CPUID_VIRT_BITS_SHIFT = 8
|
|
*/
|
|
#define VMW_BIT_MASK(shift) (0xffffffffu >> (32 - shift))
|
|
|
|
#define FIELD(lvl, ecxIn, reg, bitpos, size, name, s, hwv) \
|
|
CPUID_##name##_SHIFT = bitpos, \
|
|
CPUID_##name##_MASK = VMW_BIT_MASK(size) << bitpos, \
|
|
CPUID_INTERNAL_SHIFT_##name = bitpos, \
|
|
CPUID_INTERNAL_MASK_##name = VMW_BIT_MASK(size) << bitpos, \
|
|
CPUID_INTERNAL_REG_##name = CPUID_REG_##reg, \
|
|
CPUID_INTERNAL_EAXIN_##name = CPUID_LEVEL_VAL_##lvl, \
|
|
CPUID_INTERNAL_ECXIN_##name = ecxIn,
|
|
|
|
#define FLAG FIELD
|
|
|
|
enum {
|
|
/* Define data for every CPUID field we have */
|
|
CPUID_FIELD_DATA
|
|
};
|
|
#undef VMW_BIT_MASK
|
|
#undef FIELD
|
|
#undef FLAG
|
|
|
|
/*
|
|
* CPUID_MASK --
|
|
* CPUID_SHIFT --
|
|
* CPUID_ISSET --
|
|
* CPUID_GET --
|
|
* CPUID_SET --
|
|
* CPUID_CLEAR --
|
|
* CPUID_SETTO --
|
|
*
|
|
* Accessor macros for all CPUID consts/fields/flags. Level and reg are not
|
|
* required, but are used to force compile-time asserts which help verify that
|
|
* the flag is being used on the right CPUID input and result register.
|
|
*
|
|
* Note: ASSERT_ON_COMPILE is duplicated rather than factored into its own
|
|
* macro, because token concatenation does not work as expected if an input is
|
|
* #defined (e.g. APIC) when macros are nested. Also, compound statements
|
|
* within parenthes is a GCC extension, so we must use runtime asserts with
|
|
* other compilers.
|
|
*/
|
|
|
|
#if defined(__GNUC__) && !defined(__clang__)
|
|
|
|
#define CPUID_MASK(eaxIn, reg, flag) \
|
|
({ \
|
|
ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##flag && \
|
|
CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \
|
|
CPUID_INTERNAL_MASK_##flag; \
|
|
})
|
|
|
|
#define CPUID_SHIFT(eaxIn, reg, flag) \
|
|
({ \
|
|
ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##flag && \
|
|
CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \
|
|
CPUID_INTERNAL_SHIFT_##flag; \
|
|
})
|
|
|
|
#define CPUID_ISSET(eaxIn, reg, flag, data) \
|
|
({ \
|
|
ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##flag && \
|
|
CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \
|
|
(((data) & CPUID_INTERNAL_MASK_##flag) != 0); \
|
|
})
|
|
|
|
#define CPUID_GET(eaxIn, reg, field, data) \
|
|
({ \
|
|
ASSERT_ON_COMPILE(eaxIn == CPUID_INTERNAL_EAXIN_##field && \
|
|
CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##field); \
|
|
(((uint32)(data) & CPUID_INTERNAL_MASK_##field) >> \
|
|
CPUID_INTERNAL_SHIFT_##field); \
|
|
})
|
|
|
|
#else
|
|
|
|
/*
|
|
* CPUIDCheck --
|
|
*
|
|
* Return val after verifying parameters.
|
|
*/
|
|
|
|
static INLINE uint32
|
|
CPUIDCheck(int32 eaxIn, int32 eaxInCheck,
|
|
CpuidReg reg, CpuidReg regCheck, uint32 val)
|
|
{
|
|
ASSERT(eaxIn == eaxInCheck && reg == regCheck);
|
|
return val;
|
|
}
|
|
|
|
#define CPUID_MASK(eaxIn, reg, flag) \
|
|
CPUIDCheck(eaxIn, CPUID_INTERNAL_EAXIN_##flag, \
|
|
CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##flag, \
|
|
CPUID_INTERNAL_MASK_##flag)
|
|
|
|
#define CPUID_SHIFT(eaxIn, reg, flag) \
|
|
CPUIDCheck(eaxIn, CPUID_INTERNAL_EAXIN_##flag, \
|
|
CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##flag, \
|
|
CPUID_INTERNAL_SHIFT_##flag)
|
|
|
|
#define CPUID_ISSET(eaxIn, reg, flag, data) \
|
|
(CPUIDCheck(eaxIn, CPUID_INTERNAL_EAXIN_##flag, \
|
|
CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##flag, \
|
|
CPUID_INTERNAL_MASK_##flag & (data)) != 0)
|
|
|
|
#define CPUID_GET(eaxIn, reg, field, data) \
|
|
CPUIDCheck(eaxIn, CPUID_INTERNAL_EAXIN_##field, \
|
|
CPUID_REG_##reg, (CpuidReg)CPUID_INTERNAL_REG_##field, \
|
|
((uint32)(data) & CPUID_INTERNAL_MASK_##field) >> \
|
|
CPUID_INTERNAL_SHIFT_##field)
|
|
|
|
#endif
|
|
|
|
|
|
#define CPUID_SET(eaxIn, reg, flag, dataPtr) \
|
|
do { \
|
|
ASSERT_ON_COMPILE( \
|
|
(uint32)eaxIn == (uint32)CPUID_INTERNAL_EAXIN_##flag && \
|
|
CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \
|
|
*(dataPtr) |= CPUID_INTERNAL_MASK_##flag; \
|
|
} while (0)
|
|
|
|
#define CPUID_CLEAR(eaxIn, reg, flag, dataPtr) \
|
|
do { \
|
|
ASSERT_ON_COMPILE( \
|
|
(uint32)eaxIn == (uint32)CPUID_INTERNAL_EAXIN_##flag && \
|
|
CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##flag); \
|
|
*(dataPtr) &= ~CPUID_INTERNAL_MASK_##flag; \
|
|
} while (0)
|
|
|
|
#define CPUID_SETTO(eaxIn, reg, field, dataPtr, val) \
|
|
do { \
|
|
uint32 _v = val; \
|
|
uint32 *_d = dataPtr; \
|
|
ASSERT_ON_COMPILE( \
|
|
(uint32)eaxIn == (uint32)CPUID_INTERNAL_EAXIN_##field && \
|
|
CPUID_REG_##reg == (CpuidReg)CPUID_INTERNAL_REG_##field); \
|
|
*_d = (*_d & ~CPUID_INTERNAL_MASK_##field) | \
|
|
(_v << CPUID_INTERNAL_SHIFT_##field); \
|
|
ASSERT(_v == (*_d & CPUID_INTERNAL_MASK_##field) >> \
|
|
CPUID_INTERNAL_SHIFT_##field); \
|
|
} while (0)
|
|
|
|
|
|
/*
|
|
* Definitions of various fields' values and more complicated
|
|
* macros/functions for reading cpuid fields.
|
|
*/
|
|
|
|
#define CPUID_FAMILY_EXTENDED 15
|
|
|
|
/* Effective Intel CPU Families */
|
|
#define CPUID_FAMILY_486 4
|
|
#define CPUID_FAMILY_P5 5
|
|
#define CPUID_FAMILY_P6 6
|
|
#define CPUID_FAMILY_P4 15
|
|
|
|
/* Effective AMD CPU Families */
|
|
#define CPUID_FAMILY_5x86 0x4
|
|
#define CPUID_FAMILY_K5 0x5
|
|
#define CPUID_FAMILY_K6 0x5
|
|
#define CPUID_FAMILY_K7 0x6
|
|
#define CPUID_FAMILY_K8 0xf
|
|
#define CPUID_FAMILY_K8L 0x10
|
|
#define CPUID_FAMILY_K8MOBILE 0x11
|
|
#define CPUID_FAMILY_LLANO 0x12
|
|
#define CPUID_FAMILY_BOBCAT 0x14
|
|
#define CPUID_FAMILY_BULLDOZER 0x15 // BD PD SR EX
|
|
#define CPUID_FAMILY_KYOTO 0x16 // Note: Jaguar microarch
|
|
#define CPUID_FAMILY_ZEN 0x17
|
|
#define CPUID_FAMILY_ZEN3 0x19
|
|
|
|
/* Effective VIA CPU Families */
|
|
#define CPUID_FAMILY_C7 6
|
|
|
|
/* Effective Hygon CPU Families. */
|
|
#define CPUID_FAMILY_DHYANA 0x18
|
|
|
|
/* Intel model information */
|
|
#define CPUID_MODEL_PPRO 1
|
|
#define CPUID_MODEL_PII_03 3
|
|
#define CPUID_MODEL_PII_05 5
|
|
#define CPUID_MODEL_CELERON_06 6
|
|
#define CPUID_MODEL_PM_09 9
|
|
#define CPUID_MODEL_PM_0D 13
|
|
#define CPUID_MODEL_PM_0E 14 // Yonah / Sossaman
|
|
#define CPUID_MODEL_CORE_0F 15 // Conroe / Merom
|
|
#define CPUID_MODEL_CORE_17 0x17 // Penryn
|
|
#define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown
|
|
#define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville
|
|
#define CPUID_MODEL_CORE_1D 0x1d // Dunnington
|
|
#define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield
|
|
#define CPUID_MODEL_NEHALEM_1F 0x1f // Havendale
|
|
#define CPUID_MODEL_NEHALEM_25 0x25 // Westmere / Clarkdale
|
|
#define CPUID_MODEL_ATOM_26 0x26 // Lincroft
|
|
#define CPUID_MODEL_ATOM_27 0x27 // Saltwell
|
|
#define CPUID_MODEL_SANDYBRIDGE_2A 0x2a // Sandybridge (desktop/mobile)
|
|
#define CPUID_MODEL_NEHALEM_2C 0x2c // Westmere-EP
|
|
#define CPUID_MODEL_SANDYBRIDGE_2D 0x2d // Sandybridge-EP
|
|
#define CPUID_MODEL_NEHALEM_2E 0x2e // Nehalem-EX
|
|
#define CPUID_MODEL_NEHALEM_2F 0x2f // Westmere-EX
|
|
#define CPUID_MODEL_ATOM_35 0x35 // Cloverview
|
|
#define CPUID_MODEL_ATOM_36 0x36 // Cedarview
|
|
#define CPUID_MODEL_ATOM_37 0x37 // Bay Trail
|
|
#define CPUID_MODEL_SANDYBRIDGE_3A 0x3a // Ivy Bridge
|
|
#define CPUID_MODEL_HASWELL_3C 0x3c // Haswell DT
|
|
#define CPUID_MODEL_BROADWELL_3D 0x3d // Broadwell-Ult
|
|
#define CPUID_MODEL_SANDYBRIDGE_3E 0x3e // Ivy Bridge-EP
|
|
#define CPUID_MODEL_HASWELL_3F 0x3f // Haswell EP/EN/EX
|
|
#define CPUID_MODEL_HASWELL_45 0x45 // Haswell Ultrathin
|
|
#define CPUID_MODEL_HASWELL_46 0x46 // Haswell (Crystal Well)
|
|
#define CPUID_MODEL_BROADWELL_47 0x47 // Broadwell (Denlow)
|
|
#define CPUID_MODEL_ATOM_4A 0x4a // Future Silvermont
|
|
#define CPUID_MODEL_ATOM_4C 0x4c // Airmont
|
|
#define CPUID_MODEL_ATOM_4D 0x4d // Avoton
|
|
#define CPUID_MODEL_SKYLAKE_4E 0x4e // Skylake-Y / Kaby Lake U/Y ES
|
|
#define CPUID_MODEL_BROADWELL_4F 0x4f // Broadwell EP/EN/EX
|
|
#define CPUID_MODEL_SKYLAKE_55 0x55 // Skylake EP/EN/EX
|
|
#define CPUID_MODEL_BROADWELL_56 0x56 // Broadwell DE
|
|
#define CPUID_MODEL_KNL_57 0x57 // Knights Landing
|
|
#define CPUID_MODEL_ATOM_5A 0x5a // Future Silvermont
|
|
#define CPUID_MODEL_ATOM_5D 0x5d // Future Silvermont
|
|
#define CPUID_MODEL_SKYLAKE_5E 0x5e // Skylake-S / Kaby Lake S/H ES
|
|
#define CPUID_MODEL_ATOM_5F 0x5f // Denverton
|
|
#define CPUID_MODEL_ATOM_86 0x86 // Snow Ridge
|
|
#define CPUID_MODEL_CANNONLAKE_66 0x66 // Cannon Lake
|
|
#define CPUID_MODEL_KNM_85 0x85 // Knights Mill
|
|
#define CPUID_MODEL_KABYLAKE_8E 0x8e // Kaby Lake U/Y QS
|
|
#define CPUID_MODEL_KABYLAKE_9E 0x9e // Kaby Lake S/H QS
|
|
#define CPUID_MODEL_COMETLAKE_A5 0xa5 // Comet Lake S
|
|
#define CPUID_MODEL_COMETLAKE_A6 0xa6 // Comet Lake U
|
|
|
|
/* Intel stepping information */
|
|
#define CPUID_STEPPING_KABYLAKE_ES 0x8 // Kaby Lake S/H/U/Y ES
|
|
#define CPUID_STEPPING_COFFEELAKE_A 0xA // Coffee Lake U/S/H
|
|
#define CPUID_STEPPING_COFFEELAKE_D 0xD // Last Coffee Lake stepping
|
|
#define CPUID_STEPPING_CASCADELAKE_A 0x5 // Cascade Lake A-step
|
|
#define CPUID_STEPPING_CASCADELAKE_B1 0x7 // Cascade Lake B1-step
|
|
#define CPUID_STEPPING_WHISKEYLAKE 0xB // Whiskey Lake U
|
|
#define CPUID_STEPPING_AMBERLAKE 0xC // Amber Lake Y
|
|
|
|
#define CPUID_MODEL_PIII_07 7
|
|
#define CPUID_MODEL_PIII_08 8
|
|
#define CPUID_MODEL_PIII_0A 10
|
|
|
|
/* AMD model information */
|
|
#define CPUID_MODEL_BARCELONA_02 0x02 // Barcelona (Opteron & Phenom)
|
|
#define CPUID_MODEL_SHANGHAI_04 0x04 // Shanghai RB
|
|
#define CPUID_MODEL_SHANGHAI_05 0x05 // Shanghai BL
|
|
#define CPUID_MODEL_SHANGHAI_06 0x06 // Shanghai DA
|
|
#define CPUID_MODEL_ISTANBUL_MAGNY_08 0x08 // Istanbul (6 core) & Magny-cours (12) HY
|
|
#define CPUID_MODEL_ISTANBUL_MAGNY_09 0x09 // HY - G34 package
|
|
#define CPUID_MODEL_PHAROAH_HOUND_0A 0x0A // Pharoah Hound
|
|
#define CPUID_MODEL_PILEDRIVER_1F 0x1F // Max piledriver model defined in BKDG
|
|
#define CPUID_MODEL_PILEDRIVER_10 0x10 // family == CPUID_FAMILY_BULLDOZER
|
|
#define CPUID_MODEL_PILEDRIVER_02 0x02 // family == CPUID_FAMILY_BULLDOZER
|
|
#define CPUID_MODEL_OPTERON_REVF_41 0x41 // family == CPUID_FAMILY_K8
|
|
#define CPUID_MODEL_KYOTO_00 0x00 // family == CPUID_FAMILY_KYOTO
|
|
#define CPUID_MODEL_STEAMROLLER_3F 0x3F // Max Steamroller model defined in BKDG
|
|
#define CPUID_MODEL_STEAMROLLER_30 0x30 // family == CPUID_FAMILY_BULLDOZER
|
|
#define CPUID_MODEL_EXCAVATOR_60 0x60 // family == CPUID_FAMILY_BULLDOZER
|
|
#define CPUID_MODEL_EXCAVATOR_6F 0x6F // Max Excavator model defined in BKDG
|
|
#define CPUID_MODEL_ZEN_00 0x00 // family == CPUID_FAMILY_ZEN
|
|
#define CPUID_MODEL_ZEN_NAPLES_01 0x01 // family == CPUID_FAMILY_ZEN
|
|
#define CPUID_MODEL_ZEN_1F 0x1F // Max Zen model defined in BKDG
|
|
#define CPUID_MODEL_ZEN2_30 0x30 // family == CPUID_FAMILY_ZEN
|
|
#define CPUID_MODEL_ZEN2_3F 0x3F // Max Zen2 model
|
|
#define CPUID_MODEL_ZEN2_70 0x70 // Ryzen3: family Zen, model Zen2
|
|
#define CPUID_MODEL_ZEN2_7F 0x7F // Ryzen3: max model
|
|
#define CPUID_MODEL_ZEN3_00 0x00 // family == CPUID_FAMILY_ZEN3
|
|
#define CPUID_MODEL_ZEN3_0F 0x0F // Max Zen3 model
|
|
|
|
/* AMD stepping information */
|
|
#define CPUID_STEPPING_ZEN_NAPLES_B2 0x02 // Zen Naples ZP-B2
|
|
|
|
/* VIA model information */
|
|
#define CPUID_MODEL_NANO 15 // Isaiah
|
|
|
|
/* Hygon model information. */
|
|
#define CPUID_MODEL_DHYANA_A 0 // Dhyana A
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* CPUID_IsVendor{AMD,Intel,VIA,Hygon} --
|
|
*
|
|
* Determines if the vendor string in cpuid id0 is from
|
|
* {AMD,Intel,VIA,Hygon}.
|
|
*
|
|
* Results:
|
|
* True iff vendor string is CPUID_{AMD,INTEL,VIA,HYGON}_VENDOR_STRING
|
|
*
|
|
* Side effects:
|
|
* None.
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_IsRawVendor(CPUIDRegs *id0, const char* vendor)
|
|
{
|
|
// hard to get strcmp() in some environments, so do it in the raw
|
|
return (id0->ebx == *(const uint32 *)(uintptr_t) (vendor + 0) &&
|
|
id0->ecx == *(const uint32 *)(uintptr_t) (vendor + 4) &&
|
|
id0->edx == *(const uint32 *)(uintptr_t) (vendor + 8));
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_IsVendorAMD(CPUIDRegs *id0)
|
|
{
|
|
return CPUID_IsRawVendor(id0, CPUID_AMD_VENDOR_STRING);
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_IsVendorIntel(CPUIDRegs *id0)
|
|
{
|
|
return CPUID_IsRawVendor(id0, CPUID_INTEL_VENDOR_STRING);
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_IsVendorVIA(CPUIDRegs *id0)
|
|
{
|
|
return CPUID_IsRawVendor(id0, CPUID_VIA_VENDOR_STRING);
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_IsVendorHygon(CPUIDRegs *id0)
|
|
{
|
|
return CPUID_IsRawVendor(id0, CPUID_HYGON_VENDOR_STRING);
|
|
}
|
|
|
|
static INLINE uint32
|
|
CPUID_EFFECTIVE_FAMILY(uint32 v) /* %eax from CPUID with %eax=1. */
|
|
{
|
|
uint32 f = CPUID_GET(1, EAX, FAMILY, v);
|
|
return f != CPUID_FAMILY_EXTENDED ? f : f +
|
|
CPUID_GET(1, EAX, EXTENDED_FAMILY, v);
|
|
}
|
|
|
|
/* Normally only used when FAMILY==CPUID_FAMILY_EXTENDED, but Intel is
|
|
* now using the extended model field for FAMILY==CPUID_FAMILY_P6 to
|
|
* refer to the newer Core2 CPUs
|
|
*/
|
|
static INLINE uint32
|
|
CPUID_EFFECTIVE_MODEL(uint32 v) /* %eax from CPUID with %eax=1. */
|
|
{
|
|
uint32 m = CPUID_GET(1, EAX, MODEL, v);
|
|
uint32 em = CPUID_GET(1, EAX, EXTENDED_MODEL, v);
|
|
return m + (em << 4);
|
|
}
|
|
|
|
static INLINE uint32
|
|
CPUID_EFFECTIVE_STEPPING(uint32 v) /* %eax from CPUID with %eax=1. */
|
|
{
|
|
return CPUID_GET(1, EAX, STEPPING, v);
|
|
}
|
|
|
|
/*
|
|
* Notice that CPUID families for Intel and AMD overlap. The following macros
|
|
* should only be used AFTER the manufacturer has been established (through
|
|
* the use of CPUID standard function 0).
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_486(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_486;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_P5(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_P5;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_P6(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_P6;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_PENTIUM4(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_P4;
|
|
}
|
|
|
|
/*
|
|
* Intel Pentium M processors are Yonah/Sossaman or an older P-M
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_PENTIUM_M(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_09 ||
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0D ||
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0E);
|
|
}
|
|
|
|
/*
|
|
* Intel Core processors are Merom, Conroe, Woodcrest, Clovertown,
|
|
* Penryn, Dunnington, Kentsfield, Yorktown, Harpertown, ........
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_CORE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
uint32 model = CPUID_EFFECTIVE_MODEL(v);
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
model >= CPUID_MODEL_CORE_0F &&
|
|
(model < CPUID_MODEL_NEHALEM_1A ||
|
|
model == CPUID_MODEL_CORE_1D);
|
|
}
|
|
|
|
/*
|
|
* Intel Nehalem processors are: Nehalem, Gainestown, Lynnfield, Clarkdale.
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
|
|
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(effectiveModel == CPUID_MODEL_NEHALEM_1A ||
|
|
effectiveModel == CPUID_MODEL_NEHALEM_1E ||
|
|
effectiveModel == CPUID_MODEL_NEHALEM_1F ||
|
|
effectiveModel == CPUID_MODEL_NEHALEM_25 ||
|
|
effectiveModel == CPUID_MODEL_NEHALEM_2C ||
|
|
effectiveModel == CPUID_MODEL_NEHALEM_2E ||
|
|
effectiveModel == CPUID_MODEL_NEHALEM_2F);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_SANDYBRIDGE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
|
|
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(effectiveModel == CPUID_MODEL_SANDYBRIDGE_2A ||
|
|
effectiveModel == CPUID_MODEL_SANDYBRIDGE_2D ||
|
|
effectiveModel == CPUID_MODEL_SANDYBRIDGE_3E ||
|
|
effectiveModel == CPUID_MODEL_SANDYBRIDGE_3A);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_BROADWELL(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
|
|
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(effectiveModel == CPUID_MODEL_BROADWELL_3D ||
|
|
effectiveModel == CPUID_MODEL_BROADWELL_47 ||
|
|
effectiveModel == CPUID_MODEL_BROADWELL_4F ||
|
|
effectiveModel == CPUID_MODEL_BROADWELL_56);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_HASWELL(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
|
|
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(effectiveModel == CPUID_MODEL_HASWELL_3C ||
|
|
effectiveModel == CPUID_MODEL_HASWELL_3F ||
|
|
effectiveModel == CPUID_MODEL_HASWELL_45 ||
|
|
effectiveModel == CPUID_MODEL_HASWELL_46);
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_CASCADELAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_SKYLAKE_55 &&
|
|
CPUID_EFFECTIVE_STEPPING(v) >= CPUID_STEPPING_CASCADELAKE_A &&
|
|
CPUID_EFFECTIVE_STEPPING(v) <= CPUID_STEPPING_CASCADELAKE_B1;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_SKYLAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
((CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_SKYLAKE_5E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) != CPUID_STEPPING_KABYLAKE_ES) ||
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_SKYLAKE_55 &&
|
|
!CPUID_MODEL_IS_CASCADELAKE(v)) ||
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_SKYLAKE_4E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) != CPUID_STEPPING_KABYLAKE_ES));
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_COFFEELAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
((CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KABYLAKE_9E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) >= CPUID_STEPPING_COFFEELAKE_A &&
|
|
CPUID_EFFECTIVE_STEPPING(v) <= CPUID_STEPPING_COFFEELAKE_D) ||
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KABYLAKE_8E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) == CPUID_STEPPING_COFFEELAKE_A));
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_WHISKEYLAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KABYLAKE_8E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) == CPUID_STEPPING_WHISKEYLAKE;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_COMETLAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_COMETLAKE_A5 ||
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_COMETLAKE_A6);
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_AMBERLAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KABYLAKE_8E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) == CPUID_STEPPING_AMBERLAKE;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_KABYLAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
((CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KABYLAKE_9E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) < CPUID_STEPPING_COFFEELAKE_A) ||
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KABYLAKE_8E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) < CPUID_STEPPING_COFFEELAKE_A) ||
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_SKYLAKE_5E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) == CPUID_STEPPING_KABYLAKE_ES) ||
|
|
(CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_SKYLAKE_4E &&
|
|
CPUID_EFFECTIVE_STEPPING(v) == CPUID_STEPPING_KABYLAKE_ES));
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_CANNONLAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_CANNONLAKE_66;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_SKYLAKE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_MODEL_IS_SKYLAKE(v) ||
|
|
CPUID_MODEL_IS_KABYLAKE(v) ||
|
|
CPUID_MODEL_IS_COFFEELAKE(v) ||
|
|
CPUID_MODEL_IS_WHISKEYLAKE(v) ||
|
|
CPUID_MODEL_IS_COMETLAKE(v) ||
|
|
CPUID_MODEL_IS_AMBERLAKE(v) ||
|
|
CPUID_MODEL_IS_CASCADELAKE(v) ||
|
|
CPUID_MODEL_IS_CANNONLAKE(v);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_HASWELL(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(CPUID_MODEL_IS_BROADWELL(v) || CPUID_MODEL_IS_HASWELL(v));
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_CENTERTON(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_ATOM_1C;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_AVOTON(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_ATOM_4D;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_BAYTRAIL(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_ATOM_37;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_SILVERMONT(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(CPUID_MODEL_IS_AVOTON(v) || CPUID_MODEL_IS_BAYTRAIL(v));
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_DENVERTON(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_ATOM_5F;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_SNOWRIDGE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_ATOM_86;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_UARCH_IS_TREMONT(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) && CPUID_MODEL_IS_SNOWRIDGE(v);
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_WESTMERE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
|
|
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(effectiveModel == CPUID_MODEL_NEHALEM_25 || // Clarkdale
|
|
effectiveModel == CPUID_MODEL_NEHALEM_2C || // Westmere-EP
|
|
effectiveModel == CPUID_MODEL_NEHALEM_2F); // Westmere-EX
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_SANDYBRIDGE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
|
|
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
(effectiveModel == CPUID_MODEL_SANDYBRIDGE_2A ||
|
|
effectiveModel == CPUID_MODEL_SANDYBRIDGE_2D);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_IVYBRIDGE(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
|
|
|
|
return CPUID_FAMILY_IS_P6(v) && (
|
|
effectiveModel == CPUID_MODEL_SANDYBRIDGE_3E ||
|
|
effectiveModel == CPUID_MODEL_SANDYBRIDGE_3A);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_KNIGHTS_LANDING(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KNL_57;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_KNIGHTS_MILL(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is Intel. */
|
|
return CPUID_FAMILY_IS_P6(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_KNM_85;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_K7(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K7;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_K8(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K8;
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* CPUID_FAMILY_IS_K8EXT --
|
|
*
|
|
* Return TRUE for family K8 with effective model >= 0x10.
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_K8EXT(uint32 eax)
|
|
{
|
|
return CPUID_FAMILY_IS_K8(eax) &&
|
|
CPUID_GET(1, EAX, EXTENDED_MODEL, eax) != 0;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_K8L(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K8L ||
|
|
CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_LLANO;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_LLANO(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_LLANO;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_K8MOBILE(uint32 eax)
|
|
{
|
|
/* Essentially a K8 (not K8L) part, but with mobile features. */
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_K8MOBILE;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_K8STAR(uint32 eax)
|
|
{
|
|
/*
|
|
* Read function name as "K8*", as in wildcard.
|
|
* Matches K8 or K8L or K8MOBILE
|
|
*/
|
|
return CPUID_FAMILY_IS_K8(eax) || CPUID_FAMILY_IS_K8L(eax) ||
|
|
CPUID_FAMILY_IS_K8MOBILE(eax);
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_BOBCAT(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BOBCAT;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_BULLDOZER(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BULLDOZER;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_KYOTO(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_KYOTO;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_ZEN(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_ZEN;
|
|
}
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_ZEN3(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_ZEN3;
|
|
}
|
|
|
|
/*
|
|
* AMD Barcelona (of either Opteron or Phenom kind).
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_BARCELONA(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is AMD. */
|
|
return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_BARCELONA_02;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_SHANGHAI(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is AMD. */
|
|
return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L &&
|
|
(CPUID_MODEL_SHANGHAI_04 <= CPUID_EFFECTIVE_MODEL(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) <= CPUID_MODEL_SHANGHAI_06);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_ISTANBUL_MAGNY(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is AMD. */
|
|
return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L &&
|
|
(CPUID_MODEL_ISTANBUL_MAGNY_08 <= CPUID_EFFECTIVE_MODEL(v) &&
|
|
CPUID_EFFECTIVE_MODEL(v) <= CPUID_MODEL_ISTANBUL_MAGNY_09);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_PHAROAH_HOUND(uint32 v) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
/* Assumes the CPU manufacturer is AMD. */
|
|
return CPUID_EFFECTIVE_FAMILY(v) == CPUID_FAMILY_K8L &&
|
|
CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PHAROAH_HOUND_0A;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_BULLDOZER(uint32 eax)
|
|
{
|
|
/*
|
|
* Bulldozer is models of family 0x15 that are below 10 excluding
|
|
* Piledriver 02.
|
|
*/
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BULLDOZER &&
|
|
CPUID_EFFECTIVE_MODEL(eax) < CPUID_MODEL_PILEDRIVER_10 &&
|
|
CPUID_EFFECTIVE_MODEL(eax) != CPUID_MODEL_PILEDRIVER_02;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_PILEDRIVER(uint32 eax)
|
|
{
|
|
/* Piledriver is models 0x02 & 0x10 of family 0x15 (so far). */
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BULLDOZER &&
|
|
((CPUID_EFFECTIVE_MODEL(eax) >= CPUID_MODEL_PILEDRIVER_10 &&
|
|
CPUID_EFFECTIVE_MODEL(eax) <= CPUID_MODEL_PILEDRIVER_1F) ||
|
|
CPUID_EFFECTIVE_MODEL(eax) == CPUID_MODEL_PILEDRIVER_02);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_STEAMROLLER(uint32 eax)
|
|
{
|
|
/* Steamroller is model 0x30 of family 0x15 (so far). */
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BULLDOZER &&
|
|
(CPUID_EFFECTIVE_MODEL(eax) >= CPUID_MODEL_STEAMROLLER_30 &&
|
|
CPUID_EFFECTIVE_MODEL(eax) <= CPUID_MODEL_STEAMROLLER_3F);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_EXCAVATOR(uint32 eax)
|
|
{
|
|
/* Excavator is model 0x60 of family 0x15 (so far). */
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_BULLDOZER &&
|
|
(CPUID_EFFECTIVE_MODEL(eax) >= CPUID_MODEL_EXCAVATOR_60 &&
|
|
CPUID_EFFECTIVE_MODEL(eax) <= CPUID_MODEL_EXCAVATOR_6F);
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_KYOTO(uint32 eax)
|
|
{
|
|
/* Kyoto is models 0x00 of family 0x16 (so far). */
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_KYOTO &&
|
|
CPUID_EFFECTIVE_MODEL(eax) == CPUID_MODEL_KYOTO_00;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_ZEN(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_ZEN &&
|
|
CPUID_EFFECTIVE_MODEL(eax) <= CPUID_MODEL_ZEN_1F;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_ZEN2(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_ZEN &&
|
|
((CPUID_EFFECTIVE_MODEL(eax) >= CPUID_MODEL_ZEN2_30 &&
|
|
CPUID_EFFECTIVE_MODEL(eax) <= CPUID_MODEL_ZEN2_3F) ||
|
|
(CPUID_EFFECTIVE_MODEL(eax) >= CPUID_MODEL_ZEN2_70 &&
|
|
CPUID_EFFECTIVE_MODEL(eax) <= CPUID_MODEL_ZEN2_7F));
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_FAMILY_IS_DHYANA(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_DHYANA;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_DHYANA_A(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_DHYANA &&
|
|
CPUID_EFFECTIVE_MODEL(eax) == CPUID_MODEL_DHYANA_A;
|
|
}
|
|
|
|
|
|
static INLINE Bool
|
|
CPUID_MODEL_IS_ZEN3(uint32 eax)
|
|
{
|
|
return CPUID_EFFECTIVE_FAMILY(eax) == CPUID_FAMILY_ZEN3 &&
|
|
CPUID_EFFECTIVE_MODEL(eax) <= CPUID_MODEL_ZEN3_0F;
|
|
}
|
|
|
|
|
|
#define CPUID_TYPE_PRIMARY 0
|
|
#define CPUID_TYPE_OVERDRIVE 1
|
|
#define CPUID_TYPE_SECONDARY 2
|
|
|
|
#define CPUID_LEAF4_CACHE_TYPE_NULL 0
|
|
#define CPUID_LEAF4_CACHE_TYPE_DATA 1
|
|
#define CPUID_LEAF4_CACHE_TYPE_INST 2
|
|
#define CPUID_LEAF4_CACHE_TYPE_UNIF 3
|
|
#define CPUID_LEAF4_CACHE_INDEXING_DIRECT 0
|
|
#define CPUID_LEAF4_CACHE_INDEXING_COMPLEX 1
|
|
|
|
#define CPUID_LEAF4_CACHE_SELF_INIT 0x00000100
|
|
#define CPUID_LEAF4_CACHE_FULLY_ASSOC 0x00000200
|
|
|
|
#define CPUID_TOPOLOGY_LEVEL_TYPE_INVALID 0
|
|
#define CPUID_TOPOLOGY_LEVEL_TYPE_SMT 1
|
|
#define CPUID_TOPOLOGY_LEVEL_TYPE_CORE 2
|
|
#define CPUID_TOPOLOGY_LEVEL_TYPE_MODULE 3
|
|
#define CPUID_TOPOLOGY_LEVEL_TYPE_TILE 4
|
|
#define CPUID_TOPOLOGY_LEVEL_TYPE_DIE 5
|
|
|
|
#define CPUID_AMD_LEAF85_L1_CACHE_FULLY_ASSOC 0xff
|
|
#define CPUID_AMD_LEAF86_L2_L3_CACHE_FULLY_ASSOC 0x0f
|
|
#define CPUID_AMD_LEAF81D_CACHE_TYPE_NULL 0
|
|
#define CPUID_AMD_LEAF81D_CACHE_TYPE_DATA 1
|
|
#define CPUID_AMD_LEAF81D_CACHE_TYPE_INST 2
|
|
#define CPUID_AMD_LEAF81D_CACHE_TYPE_UNIF 3
|
|
|
|
/*
|
|
* For certain AMD processors, an lfence instruction is necessary at various
|
|
* places to ensure ordering.
|
|
*/
|
|
|
|
static INLINE Bool
|
|
CPUID_RequiresFence(CpuidVendor vendor, // IN
|
|
uint32 version) // IN: %eax from CPUID with %eax=1.
|
|
{
|
|
return vendor == CPUID_VENDOR_AMD &&
|
|
CPUID_EFFECTIVE_FAMILY(version) == CPUID_FAMILY_K8 &&
|
|
CPUID_EFFECTIVE_MODEL(version) < 0x40;
|
|
}
|
|
|
|
|
|
/*
|
|
* Hypervisor CPUID space is 0x400000XX.
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_IsHypervisorLevel(uint32 level)
|
|
{
|
|
return (level & 0xffffff00) == 0x40000000;
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* CPUID_LevelUsesEcx --
|
|
*
|
|
* Returns TRUE for leaves that support input ECX != 0 (subleaves).
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
|
|
static INLINE Bool
|
|
CPUID_LevelUsesEcx(uint32 level) {
|
|
switch (level)
|
|
{
|
|
|
|
#define CPUIDLEVEL(t, s, v, c, h) \
|
|
case v: \
|
|
return c != 0;
|
|
|
|
CPUID_ALL_LEVELS
|
|
|
|
#undef CPUIDLEVEL
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* CPUID_SupportsMsrPlatformInfo --
|
|
*
|
|
* Uses vendor and cpuid.1.0.eax to determine if the processor
|
|
* supports MSR_PLATFORM_INFO.
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
static INLINE Bool
|
|
CPUID_SupportsMsrPlatformInfo(CpuidVendor vendor, uint32 version)
|
|
{
|
|
return vendor == CPUID_VENDOR_INTEL &&
|
|
(CPUID_UARCH_IS_NEHALEM(version) ||
|
|
CPUID_UARCH_IS_SANDYBRIDGE(version) ||
|
|
CPUID_UARCH_IS_HASWELL(version) ||
|
|
CPUID_UARCH_IS_SKYLAKE(version) ||
|
|
CPUID_MODEL_IS_KNIGHTS_LANDING(version) ||
|
|
CPUID_MODEL_IS_DENVERTON(version) ||
|
|
CPUID_UARCH_IS_SILVERMONT(version) ||
|
|
CPUID_UARCH_IS_TREMONT(version));
|
|
}
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
|
|
#if defined __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#endif // _X86CPUID_H_
|