767 lines
28 KiB
Python
767 lines
28 KiB
Python
# Copyright (C) 2021 Intel Corporation.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
"""CPUID register decoding."""
|
|
|
|
from cpuparser.platformbase import CPUID, cpuidfield
|
|
import struct
|
|
|
|
EAX = 0
|
|
EBX = 1
|
|
ECX = 2
|
|
EDX = 3
|
|
|
|
class LEAF_0(CPUID):
|
|
"""Basic CPUID information including vendor and max supported basic leaf."""
|
|
|
|
leaf = 0x0
|
|
max_leaf = cpuidfield(EAX, 31, 0, doc="Highest value the CPUID recognizes for returning basic processor information")
|
|
|
|
@property
|
|
def cpuid_level(self):
|
|
return hex(self.regs.eax)
|
|
|
|
@property
|
|
def vendor(self):
|
|
"""Vendor identification string"""
|
|
return struct.pack('III', self.regs.ebx, self.regs.edx, self.regs.ecx)
|
|
|
|
attribute_bits = [
|
|
"cpuid_level",
|
|
]
|
|
|
|
class LEAF_1(CPUID):
|
|
"""Basic CPUID Information
|
|
|
|
Contains version type, family, model, and stepping ID; brand index; CLFLUSH
|
|
line size; maximum number of addressable IDs for logical processors in the
|
|
physical package; initial APIC ID; and feature information"""
|
|
|
|
leaf = 0x1
|
|
|
|
stepping = cpuidfield(EAX, 3, 0, doc="Stepping ID")
|
|
model = cpuidfield(EAX, 7, 4, doc="Model")
|
|
family = cpuidfield(EAX, 11, 8, doc="Family ID")
|
|
processor_type = cpuidfield(EAX, 13, 12, doc="Processor Type")
|
|
ext_model = cpuidfield(EAX, 19, 16, doc="Extended Model ID")
|
|
ext_family = cpuidfield(EAX, 27, 20, doc="Extended Family ID")
|
|
|
|
brand_index = cpuidfield(EBX, 7, 0, doc="Brand index")
|
|
CLFLUSH_line_size = cpuidfield(EBX, 15, 8, doc="CLFLUSH instruction cache line size (in 8-byte words)")
|
|
max_logical_processor_ids = cpuidfield(EBX, 23, 16, doc="The maximum number of addressable IDs for logical processors in the physical package.")
|
|
initial_apic_id = cpuidfield(EBX, 31, 24, doc="Initial APIC ID")
|
|
|
|
sse3 = cpuidfield(ECX, 0, 0)
|
|
pclmulqdq = cpuidfield(ECX, 1, 1)
|
|
dtes64 = cpuidfield(ECX, 2, 2)
|
|
monitor = cpuidfield(ECX, 3, 3)
|
|
ds_cpl = cpuidfield(ECX, 4, 4)
|
|
vmx = cpuidfield(ECX, 5, 5)
|
|
smx = cpuidfield(ECX, 6, 6)
|
|
est = cpuidfield(ECX, 7, 7)
|
|
tm2 = cpuidfield(ECX, 8, 8)
|
|
ssse3 = cpuidfield(ECX, 9, 9)
|
|
cnxt_id = cpuidfield(ECX, 10, 10)
|
|
sdbg = cpuidfield(ECX, 11, 11)
|
|
fma = cpuidfield(ECX, 12, 12)
|
|
cmpxchg16b = cpuidfield(ECX, 13, 13)
|
|
xtpr = cpuidfield(ECX, 14, 14)
|
|
pdcm = cpuidfield(ECX, 15, 15)
|
|
pcid = cpuidfield(ECX, 17, 17)
|
|
dca = cpuidfield(ECX, 18, 18)
|
|
sse4_1 = cpuidfield(ECX, 19, 19)
|
|
sse4_2 = cpuidfield(ECX, 20, 20)
|
|
x2apic = cpuidfield(ECX, 21, 21)
|
|
movbe = cpuidfield(ECX, 22, 22)
|
|
popcnt = cpuidfield(ECX, 23, 23)
|
|
tsc_deadline = cpuidfield(ECX, 24, 24)
|
|
aes = cpuidfield(ECX, 25, 25)
|
|
xsave = cpuidfield(ECX, 26, 26)
|
|
osxsave = cpuidfield(ECX, 27, 27)
|
|
avx = cpuidfield(ECX, 28, 28)
|
|
f16c = cpuidfield(ECX, 29, 29)
|
|
rdrand = cpuidfield(ECX, 30, 30)
|
|
hypervisor = cpuidfield(ECX, 31, 31)
|
|
|
|
fpu = cpuidfield(EDX, 0, 0)
|
|
vme = cpuidfield(EDX, 1, 1)
|
|
de = cpuidfield(EDX, 2, 2)
|
|
pse = cpuidfield(EDX, 3, 3)
|
|
tsc = cpuidfield(EDX, 4, 4)
|
|
msr = cpuidfield(EDX, 5, 5)
|
|
pae = cpuidfield(EDX, 6, 6)
|
|
mce = cpuidfield(EDX, 7, 7)
|
|
cx8 = cpuidfield(EDX, 8, 8)
|
|
apic = cpuidfield(EDX, 9, 9)
|
|
sep = cpuidfield(EDX, 11, 11)
|
|
mtrr = cpuidfield(EDX, 12, 12)
|
|
pge = cpuidfield(EDX, 13, 13)
|
|
mca = cpuidfield(EDX, 14, 14)
|
|
cmov = cpuidfield(EDX, 15, 15)
|
|
pat = cpuidfield(EDX, 16, 16)
|
|
pse36 = cpuidfield(EDX, 17, 17)
|
|
psn = cpuidfield(EDX, 18, 18)
|
|
clfsh = cpuidfield(EDX, 19, 19)
|
|
ds = cpuidfield(EDX, 21, 21)
|
|
acpi = cpuidfield(EDX, 22, 22)
|
|
mmx = cpuidfield(EDX, 23, 23)
|
|
fxsr = cpuidfield(EDX, 24, 24)
|
|
sse = cpuidfield(EDX, 25, 25)
|
|
sse2 = cpuidfield(EDX, 26, 26)
|
|
ss = cpuidfield(EDX, 27, 27)
|
|
htt = cpuidfield(EDX, 28, 28)
|
|
tm = cpuidfield(EDX, 29, 29)
|
|
pbe = cpuidfield(EDX, 31, 31)
|
|
|
|
@property
|
|
def display_family(self):
|
|
if self.family == 0xf:
|
|
return self.ext_family + self.family
|
|
return self.family
|
|
|
|
@property
|
|
def display_model(self):
|
|
if self.family == 0xf or self.family == 0x6:
|
|
return (self.ext_model << 4) + self.model
|
|
return self.model
|
|
|
|
capability_bits = [
|
|
"sse3",
|
|
"pclmulqdq",
|
|
"dtes64",
|
|
"monitor",
|
|
"ds_cpl",
|
|
"vmx",
|
|
"smx",
|
|
"est",
|
|
"tm2",
|
|
"ssse3",
|
|
"cnxt_id",
|
|
"sdbg",
|
|
"fma",
|
|
"cmpxchg16b",
|
|
"xtpr",
|
|
"pdcm",
|
|
"pcid",
|
|
"dca",
|
|
"sse4_1",
|
|
"sse4_2",
|
|
"x2apic",
|
|
"movbe",
|
|
"popcnt",
|
|
"tsc_deadline",
|
|
"aes",
|
|
"xsave",
|
|
"avx",
|
|
"f16c",
|
|
"rdrand",
|
|
"fpu",
|
|
"vme",
|
|
"de",
|
|
"pse",
|
|
"tsc",
|
|
"msr",
|
|
"pae",
|
|
"mce",
|
|
"cx8",
|
|
"apic",
|
|
"sep",
|
|
"mtrr",
|
|
"pge",
|
|
"mca",
|
|
"cmov",
|
|
"pat",
|
|
"pse36",
|
|
"psn",
|
|
"clfsh",
|
|
"ds",
|
|
"acpi",
|
|
"mmx",
|
|
"fxsr",
|
|
"sse",
|
|
"sse2",
|
|
"ss",
|
|
"htt",
|
|
"tm",
|
|
"pbe",
|
|
]
|
|
|
|
class LEAF_2(CPUID):
|
|
"""TLB, Cache, and Prefetch Information"""
|
|
|
|
leaf = 0x2
|
|
times_to_run = cpuidfield(EAX, 7, 0, doc="Number of times CPUID must be executed with EAX = 2 to retrieve a complete description of the processor's TLB, Cache, and Prefetch hardware")
|
|
|
|
class LEAF_4(CPUID):
|
|
"""Deterministic cache parameters
|
|
|
|
Returns encoded data that describes a set of deterministic cache parameters
|
|
for the cache level associated in ECX"""
|
|
|
|
leaf = 0x4
|
|
cache_type = cpuidfield(EAX, 4, 0, doc="Cache Type Field")
|
|
cache_level = cpuidfield(EAX, 7, 5, doc="Cache Level")
|
|
self_initializing = cpuidfield(EAX, 8, 8, doc="Self Initializing Cache Level")
|
|
fully_associative = cpuidfield(EAX, 9, 9, doc="Fully Associative Cache")
|
|
max_logical_processors_sharing_cache_z = cpuidfield(EAX, 25, 14, doc="Max number of addressable IDs for logical processors sharing this cache (zero based)")
|
|
max_cores_sharing_cache_z = cpuidfield(EAX, 31, 26, doc="Max number of addressable IDs for processor cores in the physical package (zero based)")
|
|
|
|
line_size_z = cpuidfield(EBX, 11, 0, doc="System Coherency Line Size (zero-based)")
|
|
partitions_z = cpuidfield(EBX, 21, 12, doc="Physical Line Partitions (zero-based)")
|
|
ways_z = cpuidfield(EBX, 31, 22, doc="Ways of associativity (zero-based)")
|
|
|
|
sets_z = cpuidfield(ECX, 31, 0, doc="Sets (zero-based)")
|
|
|
|
write_back_invalidate = cpuidfield(EDX, 0, 0, doc="Write-back Invalidate/Invalidate")
|
|
cache_inclusiveness = cpuidfield(EDX, 1, 1, doc="Cache Inclusiveness")
|
|
complex_cache_indexing = cpuidfield(EDX, 2, 2, doc="Complex Cache indexing")
|
|
|
|
@property
|
|
def max_logical_processors_sharing_cache(self):
|
|
"""Maximum number of addressable IDs for logical processors sharing this cache"""
|
|
return self.max_logical_processors_sharing_cache_z + 1
|
|
|
|
@property
|
|
def max_cores_sharing_cache(self):
|
|
"""Maximum number of addressable IDs for processor cores in the physical pacakge"""
|
|
return self.max_cores_sharing_cache_z + 1
|
|
|
|
@property
|
|
def partitions(self):
|
|
"""Number of physical line partitions"""
|
|
return self.partitions_z + 1
|
|
|
|
@property
|
|
def line_size(self):
|
|
"""System Coherency line size"""
|
|
return self.line_size_z + 1
|
|
|
|
@property
|
|
def ways(self):
|
|
"""Ways of associativity"""
|
|
return self.ways_z + 1
|
|
|
|
@property
|
|
def sets(self):
|
|
"""Number of sets"""
|
|
return self.sets_z + 1
|
|
|
|
@property
|
|
def cache_size(self):
|
|
"""Cache size in bytes"""
|
|
return self.ways * self.partitions * self.line_size * self.sets
|
|
|
|
class LEAF_5(CPUID):
|
|
"""MONITOR/MWAIT Leaf
|
|
|
|
Returns information about features available to MONITOR/MWAIT instructions"""
|
|
|
|
leaf = 0x5
|
|
|
|
smallest_monitor_line_size = cpuidfield(EAX, 15, 0, doc="Smallest monitor-line size in bytes")
|
|
|
|
largest_monitor_line_size = cpuidfield(EBX, 15, 0, doc="Largest monitor-line size in bytes")
|
|
|
|
monitor_mwait_supported = cpuidfield(ECX, 0, 0, doc="Enumeration of MONITOR/MWAIT extensions supported")
|
|
interrupt_break_event_supported = cpuidfield(ECX, 1, 1, doc="Supports treating interrupts as break-events for MWAIT, even when interrupts disabled")
|
|
|
|
c0 = cpuidfield(EDX, 3, 0, doc="Number of C0 sub C-states supported using MWAIT")
|
|
c1 = cpuidfield(EDX, 7, 4, doc="Number of C1 sub C-states supported using MWAIT")
|
|
c2 = cpuidfield(EDX, 11, 8, doc="Number of C2 sub C-states supported using MWAIT")
|
|
c3 = cpuidfield(EDX, 15, 12, doc="Number of C3 sub C-states supported using MWAIT")
|
|
c4 = cpuidfield(EDX, 19, 16, doc="Number of C4 sub C-states supported using MWAIT")
|
|
|
|
class LEAF_6(CPUID):
|
|
"""Thermal and Power Management leaf
|
|
|
|
Returns information about the maximum input values for sub-leaves that contain extended feature flags."""
|
|
|
|
leaf = 0x6
|
|
|
|
digital_temperature_sensor_supported = cpuidfield(EAX, 0, 0, doc = "Digital temperature sensor is supported if set")
|
|
turbo_boost_available = cpuidfield(EAX, 1, 1, doc = "Intel Turbo Boost technology available")
|
|
arat_supported = cpuidfield(EAX, 2, 2, doc = "APIC-Timer-always-running feature is supported if set")
|
|
pln_supported = cpuidfield(EAX, 4, 4, doc = "Power limit notification controls are supported if set")
|
|
ecmd_supported = cpuidfield(EAX, 5, 5, doc = "Clock modulation duty cycle extension is supported if set")
|
|
package_thermal_management_supported = cpuidfield(EAX, 6, 6, doc = "Package thermal management is supported if set")
|
|
|
|
num_interrupt_thresholds = cpuidfield(EBX, 3, 0, doc="Number of interrupt thresholds in digital thermal sensor")
|
|
|
|
hardware_coordination_feedback_capability = cpuidfield(ECX, 0, 0, doc="Hardware coordination feedback capability")
|
|
performance_energy_bias = cpuidfield(ECX, 3, 3, doc="Performance-energy bias preference support")
|
|
|
|
class LEAF_7(CPUID):
|
|
"""Structured Extended Feature Flags Enumeration Leaf
|
|
|
|
Returns information about the maximum input value for sub-leaves that contain
|
|
extended feature flags"""
|
|
|
|
leaf = 0x7
|
|
|
|
max_input_values = cpuidfield(EAX, 31, 0, doc="Reports the maximum input value for supported leaf 7 sub-leaves")
|
|
|
|
fsgsbase = cpuidfield(EBX, 0, 0, doc="Supports RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE if 1")
|
|
ia32_tsc_adjust_msr = cpuidfield(EBX, 1, 1, doc="IA32_TSC_ADJUST MSR is supported if 1")
|
|
sgx = cpuidfield(EBX, 2, 2, doc="Supports Intel® Software Guard Extensions (Intel® SGX Extensions) if 1")
|
|
bmi1 = cpuidfield(EBX, 3, 3)
|
|
hle = cpuidfield(EBX, 4, 4)
|
|
avx2 = cpuidfield(EBX, 5, 5)
|
|
fdp_excptn_only = cpuidfield(EBX, 6, 6, doc="x87 FPU Data Pointer updated only on x87 exceptions if 1")
|
|
smep = cpuidfield(EBX, 7, 7, doc="Supports Supervisor Mode Execution Protection if 1")
|
|
bmi2 = cpuidfield(EBX, 8, 8)
|
|
erms = cpuidfield(EBX, 9, 9, doc="Supports Enhanced REP MOVSB/STOSB if 1")
|
|
invpcid = cpuidfield(EBX, 10, 10, doc="Supports INVPCID instruction for system software that manages process-context identifiers if 1")
|
|
rtm = cpuidfield(EBX, 11, 11)
|
|
qm = cpuidfield(EBX, 12, 12, doc="Supports Quality of Service Monitoring capability if 1")
|
|
deprecate_fpu = cpuidfield(EBX, 13, 13, doc="Deprecates FPS CS and FPU DS values if 1")
|
|
mpx = cpuidfield(EBX, 14, 14, doc="Supports Intel® Memory Protection Extensions if 1")
|
|
rdt_a = cpuidfield(EBX, 15, 15, doc="Supports Intel® Resource Director Technology (Intel® RDT) Allocation capability if 1")
|
|
avx512f = cpuidfield(EBX, 16, 16)
|
|
avx512dq = cpuidfield(EBX, 17, 17)
|
|
rdseed = cpuidfield(EBX, 18, 18)
|
|
adx = cpuidfield(EBX, 19, 19)
|
|
smap = cpuidfield(EBX, 20, 20, doc="Supports Supervisor-Mode Access Prevention (and the CLAC/STAC instructions) if 1")
|
|
avx512_ifma = cpuidfield(EBX, 21, 21)
|
|
clflushopt = cpuidfield(EBX, 23, 23)
|
|
clwb = cpuidfield(EBX, 24, 24)
|
|
intel_pt = cpuidfield(EBX, 25, 25)
|
|
avx512pf = cpuidfield(EBX, 26, 26)
|
|
avx512er = cpuidfield(EBX, 27, 27)
|
|
avx512cd = cpuidfield(EBX, 28, 28)
|
|
sha = cpuidfield(EBX, 29, 29, doc="Supports Intel® Secure Hash Algorithm Extensions (Intel® SHA Extensions) if 1")
|
|
avx512bw = cpuidfield(EBX, 30, 30)
|
|
avx512vl = cpuidfield(EBX, 31, 31)
|
|
|
|
prefetchwt1 = cpuidfield(ECX, 0, 0)
|
|
avx512_vbmi = cpuidfield(ECX, 1, 1)
|
|
umip = cpuidfield(ECX, 2, 2, doc="Supports user-mode instruction prevention if 1")
|
|
pku = cpuidfield(ECX, 3, 3, doc="Supports protection keys for user-mode pages if 1")
|
|
ospke = cpuidfield(ECX, 4, 4, doc="If 1, OS has set CR4.PKE to enable protection keys (and the RDPKRU/WRPKRU instructions)")
|
|
waitpkg = cpuidfield(ECX, 5, 5)
|
|
avx512_vbmi2 = cpuidfield(ECX, 6, 6)
|
|
cet_ss = cpuidfield(ECX, 7, 7, doc="Supports CET shadow stack features if 1")
|
|
gfni = cpuidfield(ECX, 8, 8)
|
|
vaes = cpuidfield(ECX, 9, 9)
|
|
vpclmulqdq = cpuidfield(ECX, 10, 10)
|
|
avx512_vnni = cpuidfield(ECX, 11, 11)
|
|
avx512_bitalg = cpuidfield(ECX, 12, 12)
|
|
tme_en = cpuidfield(ECX, 13, 13)
|
|
avx512_vpopcntdq = cpuidfield(ECX, 14, 14)
|
|
la57 = cpuidfield(ECX, 16, 16, doc="Supports 57-bit linear addresses and five-level paging if 1")
|
|
mawau = cpuidfield(ECX, 21, 17, doc="The value of MAWAU used by the BNDLDX and BNDSTX instructions in 64-bit mode")
|
|
rdpid = cpuidfield(ECX, 22, 22, doc="RDPID and IA32_TSC_AUX are available if 1")
|
|
kl = cpuidfield(ECX, 23, 23, doc="Supports Key Locker if 1")
|
|
cldemote = cpuidfield(ECX, 25, 25, doc="Supports cache line demote if 1")
|
|
movdiri = cpuidfield(ECX, 27, 27, doc="Supports MOVDIRI if 1")
|
|
movdiri64b = cpuidfield(ECX, 28, 28, doc="Supports MOVDIRI64B if 1")
|
|
sgx_lc = cpuidfield(ECX, 30, 30, doc="Supports SGX Launch Configuration if 1")
|
|
pks = cpuidfield(ECX, 31, 31, doc="Supports protection keys for supervisor-mode pages if 1")
|
|
|
|
avx512_4vnniw = cpuidfield(EDX, 2, 2)
|
|
avx512_4fmaps = cpuidfield(EDX, 3, 3)
|
|
fast_short_rep_mov = cpuidfield(EDX, 4, 4)
|
|
avx512_vp2intersect = cpuidfield(EDX, 8, 8)
|
|
md_clear = cpuidfield(EDX, 10, 10)
|
|
hybrid = cpuidfield(EDX, 15, 15, doc="If 1, the processor is identified as a hybrid part")
|
|
pconfig = cpuidfield(EDX, 18, 18, doc="Supports PCONFIG if 1")
|
|
cet_ibt = cpuidfield(EDX, 20, 20, doc="Supports CET indirect branch tracking features if 1")
|
|
ibrs_ibpb = cpuidfield(EDX, 26, 26, doc="Enumerates support for indirect branch restricted speculation (IBRS) and the indirect branch predictor barrier (IBPB)")
|
|
stibp = cpuidfield(EDX, 27, 27, doc="Enumerates support for single thread indirect branch predictors (STIBP)")
|
|
l1d_flush = cpuidfield(EDX, 28, 28, doc="Enumerates support for L1D_FLUSH")
|
|
ia32_arch_capabilities = cpuidfield(EDX, 29, 29, doc="Enumerates support for the IA32_ARCH_CAPABILITIES MSR")
|
|
ia32_core_capabilities = cpuidfield(EDX, 30, 30, doc="Enumerates support for the IA32_CORE_CAPABILITIES MSR")
|
|
ssbd = cpuidfield(EDX, 31, 31, doc="Enumerates support for Speculative Store Bypass Disable (SSBD)")
|
|
|
|
capability_bits = [
|
|
"fsgsbase",
|
|
"ia32_tsc_adjust_msr",
|
|
"sgx",
|
|
"bmi1",
|
|
"hle",
|
|
"avx2",
|
|
"fdp_excptn_only",
|
|
"smep",
|
|
"bmi2",
|
|
"erms",
|
|
"invpcid",
|
|
"rtm",
|
|
"qm",
|
|
"deprecate_fpu",
|
|
"mpx",
|
|
"rdt_a",
|
|
"avx512f",
|
|
"avx512dq",
|
|
"rdseed",
|
|
"adx",
|
|
"smap",
|
|
"avx512_ifma",
|
|
"clflushopt",
|
|
"clwb",
|
|
"intel_pt",
|
|
"avx512pf",
|
|
"avx512er",
|
|
"avx512cd",
|
|
"sha",
|
|
"avx512bw",
|
|
"avx512vl",
|
|
"prefetchwt1",
|
|
"avx512_vbmi",
|
|
"umip",
|
|
"pku",
|
|
"waitpkg",
|
|
"avx512_vbmi2",
|
|
"cet_ss",
|
|
"gfni",
|
|
"vaes",
|
|
"vpclmulqdq",
|
|
"avx512_vnni",
|
|
"avx512_bitalg",
|
|
"tme_en",
|
|
"avx512_vpopcntdq",
|
|
"la57",
|
|
"mawau",
|
|
"rdpid",
|
|
"kl",
|
|
"cldemote",
|
|
"movdiri",
|
|
"movdiri64b",
|
|
"sgx_lc",
|
|
"pks",
|
|
"avx512_4vnniw",
|
|
"avx512_4fmaps",
|
|
"fast_short_rep_mov",
|
|
"avx512_vp2intersect",
|
|
"md_clear",
|
|
"hybrid",
|
|
"pconfig",
|
|
"cet_ibt",
|
|
"ibrs_ibpb",
|
|
"stibp",
|
|
"l1d_flush",
|
|
"ia32_arch_capabilities",
|
|
"ia32_core_capabilities",
|
|
"ssbd",
|
|
]
|
|
|
|
class LEAF_9(CPUID):
|
|
"""Direct Cache Access Information leaf
|
|
|
|
Returns information about Direct Cache Access capabilities"""
|
|
|
|
leaf = 0x9
|
|
|
|
platform_dca_cap = cpuidfield(EAX, 31, 0, doc="Value of bits of IA32_PLATFORM_DCA_CAP MSR (address 1F8H)")
|
|
|
|
class LEAF_A(CPUID):
|
|
"""Architectural Performance Monitoring Leaf
|
|
|
|
Returns information about support for architectural performance monitoring capabilities"""
|
|
|
|
leaf = 0xA
|
|
|
|
architectural_performance_monitor_version_id = cpuidfield(EAX, 7, 0, doc="Version ID of architectural performance monitoring")
|
|
gp_performance_monitor_counters = cpuidfield(EAX, 15, 8, doc="Number of general-purpose performance monitoring counter per logical processor")
|
|
gp_performance_counter_width = cpuidfield(EAX, 23, 16, doc="Bit width of general-purpose, performance monitoring counter")
|
|
ebx_bit_vector_length = cpuidfield(EAX, 31, 24, doc="Length of EBX bit vector to enumerate architectural performance monitoring events")
|
|
|
|
core_cycle_event = cpuidfield(EBX, 0, 0, doc="Core cycle event not available if 1")
|
|
instruction_retired_event = cpuidfield(EBX, 1, 1, doc="Instruction retired event not available if 1")
|
|
reference_cycles_event = cpuidfield(EBX, 2, 2, doc="Reference cycles event not available if 1")
|
|
llc_ref_event = cpuidfield(EBX, 3, 3, doc="Last-level cache reference event not available if 1")
|
|
llc_misses_event = cpuidfield(EBX, 4, 4, doc= "Last-level cache misses event not available if 1")
|
|
branch_instruction_retired_event = cpuidfield(EBX, 5, 5, doc="Branch instruction retired event not available if 1")
|
|
branch_mispredict_retired_event = cpuidfield(EBX, 6, 6, doc="Branch mispredict retired event not available if 1")
|
|
|
|
ff_performance_counters = cpuidfield(EDX, 4, 0, doc="Number of fixed-function performance counters")
|
|
ff_performance_counter_width = cpuidfield(EDX, 12, 5, doc="Bit width of fixed-function performance counters")
|
|
|
|
class LEAF_B(CPUID):
|
|
"""Extended Topology Enumeration Leaf
|
|
|
|
Returns information about extended topology enumeration data"""
|
|
|
|
leaf = 0xB
|
|
|
|
num_bit_shift = cpuidfield(EAX, 4, 0, doc="Number of bits to shift right on x2APID ID to get a unique topology ID of the next level type")
|
|
|
|
logical_proccessors_at_level = cpuidfield(EBX, 15, 0, doc="Number of logical processors at this level type.")
|
|
|
|
level_number = cpuidfield(ECX, 7, 0, doc="Level number")
|
|
level_type = cpuidfield(ECX, 15, 8, doc="Level type")
|
|
|
|
x2apic_id = cpuidfield(EDX, 31, 0, doc="x2APIC ID of the current logical processor")
|
|
|
|
class LEAF_D(CPUID):
|
|
"""Processor Extended State Enumeration Main Leaf and Sub-Leaves.
|
|
|
|
Returns information about the bit-vector representation of all processor
|
|
state extensions that are supported in the processor, and storage size
|
|
requirements of the XSAVE/XRSTOR area. Output depends on initial value of ECX."""
|
|
|
|
leaf = 0xD
|
|
|
|
valid_bits_xcr0_lower = cpuidfield(EAX, 31, 0, doc="Reports the valid bit fields of the lower 32 bits of XCR0. If a bit is 0, the corresponding bit field in XCR0 is reserved")
|
|
|
|
legacy_x87 = cpuidfield(EAX, 0, 0, doc="legacy x87")
|
|
sse_128_bit = cpuidfield(EAX, 1, 1, doc="128-bit SSE")
|
|
avx_256_bit = cpuidfield(EAX, 2, 2, doc="256-bit AVX")
|
|
|
|
max_size_enabled_xcr0 = cpuidfield(EBX, 31, 0, doc="Maximum size (bytes, from the beginning of the XSAVE/XRSTOR save area) required by enabled features in XCR0. May be different than ECX if some features at the end of the XSAVE save area are not enabled.")
|
|
|
|
max_size_supported_xcr0 = cpuidfield(ECX, 31, 0, doc="Maximum size (bytes, from the beginning of the XSAVE/XRSTOR save area) of the XSAVE/XRSTOR save area required by all supported features in the processor, i.e all the valid bit fields in XCR0.")
|
|
|
|
valid_bits_xcr0_upper = cpuidfield(EDX, 31, 0, doc="The valid bit fields of the upper 32 bits of XCR0. If a bit is 0, the corresponding bit field in XCR0 is reserved.")
|
|
|
|
def __getitem__(self, subleaf):
|
|
if subleaf == 0:
|
|
return self.read(self.cpu_id, subleaf)
|
|
elif subleaf == 1:
|
|
return LEAF_D_1.read(self.cpu_id, subleaf)
|
|
return LEAF_D_n.read(self.cpu_id, subleaf)
|
|
|
|
class LEAF_D_1(CPUID):
|
|
"""Processor Extended State Enumeration Main Leaf and Sub-Leaves.
|
|
|
|
Returns information about the bit-vector representation of all processor
|
|
state extensions that are supported in the processor, and storage size
|
|
requirements of the XSAVE/XRSTOR area. Output depends on initial value of ECX."""
|
|
|
|
leaf = 0xD
|
|
|
|
xsaveopt = cpuidfield(EAX, 0, 0, doc="XSAVEOPT is available")
|
|
|
|
class LEAF_D_n(CPUID):
|
|
"""Processor Extended State Enumeration Main Leaf and Sub-Leaves.
|
|
|
|
Returns information about the bit-vector representation of all processor
|
|
state extensions that are supported in the processor, and storage size
|
|
requirements of the XSAVE/XRSTOR area. Output depends on initial value of ECX."""
|
|
|
|
leaf = 0xD
|
|
|
|
size = cpuidfield(EAX, 31, 0, doc="The size in bytes (from the offset specified in EBX) of the save area for an extended state feature associated with a valid sub-leaf index")
|
|
|
|
offset = cpuidfield(EBX, 31, 0, doc="The offset in bytes of this extended state component's save area from the beginning of the XSAVE/XRSTOR area.")
|
|
|
|
class LEAF_F(CPUID):
|
|
"""Quality of Service Resource Type Enumeration Sub-Leaf and L3 Cache QoS Capability Enumeration Sub-leaf. Depends on value of ECX
|
|
|
|
Returns Quality of Service (QoS) Enumeration Information."""
|
|
|
|
leaf = 0xF
|
|
|
|
def __getitem__(self, subleaf):
|
|
if subleaf == 0:
|
|
return self.read(self.cpu_id, subleaf)
|
|
elif subleaf == 1:
|
|
return LEAF_F_1.read(self.cpu_id, subleaf)
|
|
return LEAF_F_n.read(self.cpu_id, subleaf)
|
|
|
|
max_range_rmid_z = cpuidfield(EBX, 31, 0, doc="Maximum range (zero-based) of RMID within this physical processor of all types.")
|
|
|
|
l3_cache_qos = cpuidfield(EDX, 1, 1, doc="Supports L3 Cache QoS if 1")
|
|
|
|
@property
|
|
def max_range_rmid(self):
|
|
"""Maximum range of RMID within this physical processor of all types."""
|
|
return self.max_range_rmid_z + 1
|
|
|
|
class LEAF_F_1(CPUID):
|
|
"""Quality of Service Resource Type Enumeration Sub-Leaf and L3 Cache QoS Capability Enumeration Sub-leaf. Depends on value of ECX
|
|
|
|
Returns L3 Cache QoS Capability Enumeration Information."""
|
|
|
|
leaf = 0xF
|
|
|
|
qm_ctr_conversion_factor = cpuidfield(EBX, 31, 0, doc="Conversion factor from reported IA32_QM_CTR value to occupancy metric (bytes).")
|
|
|
|
l3_occupancy_monitoring = cpuidfield(EDX, 0, 0, doc="Supports L3 occupancy monitoring if 1")
|
|
|
|
max_range_rmid_z = cpuidfield(ECX, 31, 0, doc="Maximum range (zero-based) of RMID of this resource type")
|
|
|
|
@property
|
|
def max_range_rmid(self):
|
|
"""Maximum range of RMID of this resource type"""
|
|
return self.max_range_rmid_z + 1
|
|
|
|
class LEAF_F_n(CPUID):
|
|
"""Quality of Service Resource Type Enumeration Sub-Leaf and L3 Cache QoS Capability Enumeration Sub-leaf. Depends on value of ECX
|
|
|
|
Returns Quality of Service (QoS) Enumeration Information."""
|
|
|
|
leaf = 0xF
|
|
|
|
class LEAF_10(CPUID):
|
|
"""Intel Resource Director Technology (Intel RDT) Allocation Enumeration Sub-leaf"""
|
|
|
|
leaf = 0x10
|
|
|
|
l3_cache_allocation = cpuidfield(EBX, 1, 1, doc="Supports L3 Cache Allocation Technology if 1.")
|
|
l2_cache_allocation = cpuidfield(EBX, 2, 2, doc="Supports L2 Cache Allocation Technology if 1.")
|
|
memory_bandwidth_allocation = cpuidfield(EBX, 3, 3, doc="Supports Memory Bandwidth Allocation if 1.")
|
|
|
|
class LEAF_10_1(CPUID):
|
|
"""L3/L2 Cache Allocation Technology Enumeration Sub-leaf"""
|
|
|
|
leaf = 0x10
|
|
|
|
capacity_mask_length_z = cpuidfield(EAX, 4, 0, doc="Length of the capacity bit mask for the corresponding ResID (zero based).")
|
|
isolation_map = cpuidfield(EBX, 31, 0, doc="Bit-granular map of isolation/contention of allocation units.")
|
|
code_and_data_prioritization = cpuidfield(ECX, 2, 2, doc="Code and Data Prioritization Technology supported if 1.")
|
|
clos_number_z = cpuidfield(EDX, 15, 0, doc="Highest COS number supported for this ResID.")
|
|
|
|
@property
|
|
def capacity_mask_length(self):
|
|
return self.capacity_mask_length_z + 1
|
|
|
|
@property
|
|
def clos_number(self):
|
|
return self.clos_number_z + 1
|
|
|
|
class LEAF_10_3(CPUID):
|
|
"""Memory Bandwidth Allocation Enumeration Sub-leaf"""
|
|
|
|
leaf = 0x10
|
|
|
|
max_throttling_value_z = cpuidfield(EAX, 11, 0, doc="Reports the maximum MBA throttling value supported for the corresponding ResID (zero based).")
|
|
linear_response_delay = cpuidfield(ECX, 2, 2, doc="Reports whether the response of the delay values is linear.")
|
|
clos_number_z = cpuidfield(EDX, 15, 0, doc="Highest COS number supported for this ResID.")
|
|
|
|
@property
|
|
def max_throttling_value(self):
|
|
return self.max_throttling_value_z + 1
|
|
|
|
@property
|
|
def clos_number(self):
|
|
return self.clos_number_z + 1
|
|
|
|
class LEAF_1A(CPUID):
|
|
"""Hybrid Information Enumeration Leaf"""
|
|
|
|
leaf = 0x1A
|
|
|
|
core_type_id = cpuidfield(EAX, 31, 24, doc="Core type")
|
|
native_model_id = cpuidfield(EAX, 23, 0, doc="Native model ID")
|
|
|
|
core_types = {
|
|
0x20: "Atom",
|
|
0x40: "Core",
|
|
}
|
|
|
|
@property
|
|
def core_type(self):
|
|
if self.core_type_id in self.core_types:
|
|
return self.core_types[self.core_type_id]
|
|
return "Reserved"
|
|
|
|
class LEAF_1F(LEAF_B):
|
|
"""Extened Topology Enumeration Leaf v2"""
|
|
|
|
leaf = 0x1F
|
|
|
|
class LEAF_80000000(CPUID):
|
|
"""Extended Function CPUID Information"""
|
|
|
|
leaf = 0x80000000
|
|
|
|
max_extended_leaf = cpuidfield(EAX, 31, 0, doc="Highest extended function input value understood by CPUID")
|
|
|
|
class LEAF_80000001(CPUID):
|
|
"""Extended Function CPUID Information"""
|
|
|
|
leaf = 0x80000001
|
|
|
|
ext_signature_feature_bits = cpuidfield(EAX, 31, 0, doc="Extended processor signature and feature bits")
|
|
|
|
lahf_sahf_64 = cpuidfield(ECX, 0, 0, doc="LAHF/SAHF available in 64-bit mode")
|
|
lzcnt = cpuidfield(ECX, 5, 5)
|
|
prefetchw = cpuidfield(ECX, 8, 8)
|
|
|
|
syscall_sysret_64 = cpuidfield(EDX, 11, 11, doc="SYSCALL/SYSRET available in 64-bit mode")
|
|
execute_disable = cpuidfield(EDX, 20, 20, doc="Execute Disable Bit available")
|
|
gbyte_pages = cpuidfield(EDX, 26, 26, doc="GByte pages are available if 1")
|
|
rdtscp_ia32_tsc_aux = cpuidfield(EDX, 27, 27, doc="RDTSCP and IA32_TSC_AUX are available if 1")
|
|
intel_64 = cpuidfield(EDX, 29, 29, doc="Intel(R) 64 Architecture available if 1")
|
|
|
|
capability_bits = [
|
|
"lahf_sahf_64",
|
|
"lzcnt",
|
|
"prefetchw",
|
|
"syscall_sysret_64",
|
|
"execute_disable",
|
|
"gbyte_pages",
|
|
"rdtscp_ia32_tsc_aux",
|
|
"intel_64",
|
|
]
|
|
|
|
class LEAF_80000002(CPUID):
|
|
"""Extended Function CPUID Information
|
|
|
|
Processor Brand String"""
|
|
|
|
leaf = 0x80000002
|
|
|
|
@property
|
|
def brandstring(self):
|
|
"""Processor Brand String"""
|
|
return struct.pack('IIII', self.regs.eax, self.regs.ebx, self.regs.ecx, self.regs.edx).rstrip(b"\x00")
|
|
|
|
class LEAF_80000003(CPUID):
|
|
"""Extended Function CPUID Information
|
|
|
|
Processor Brand String Continued"""
|
|
|
|
leaf = 0x80000003
|
|
|
|
@property
|
|
def brandstring(self):
|
|
"""Processor Brand String"""
|
|
return struct.pack('IIII', self.regs.eax, self.regs.ebx, self.regs.ecx, self.regs.edx).rstrip(b"\x00")
|
|
|
|
class LEAF_80000004(CPUID):
|
|
"""Extended Function CPUID Information
|
|
|
|
Processor Brand String Continued"""
|
|
|
|
leaf = 0x80000004
|
|
|
|
@property
|
|
def brandstring(self):
|
|
"""Processor Brand String"""
|
|
return struct.pack('IIII', self.regs.eax, self.regs.ebx, self.regs.ecx, self.regs.edx).rstrip(b"\x00")
|
|
|
|
class LEAF_80000006(CPUID):
|
|
"""Extended Function CPUID Information"""
|
|
|
|
leaf = 0x80000006
|
|
|
|
cache_line_size = cpuidfield(ECX, 7, 0, doc="Cache Line size in bytes")
|
|
|
|
l2_associativity = cpuidfield(ECX, 15, 12, doc="L2 Associativity field")
|
|
cache_size_k = cpuidfield(ECX, 31, 16, doc="Cache size in 1K units")
|
|
|
|
class LEAF_80000007(CPUID):
|
|
"""Misc Feature Flags"""
|
|
|
|
leaf = 0x80000007
|
|
|
|
invariant_tsc = cpuidfield(EDX, 8, 8, doc="Invariant TSC available if 1")
|
|
|
|
capability_bits = [
|
|
"invariant_tsc",
|
|
]
|
|
|
|
class LEAF_80000008(CPUID):
|
|
"""Returns linear/physical address size"""
|
|
|
|
leaf = 0x80000008
|
|
physical_address_bits = cpuidfield(EAX, 7, 0, doc="# Physical Address bits")
|
|
linear_address_bits = cpuidfield(EAX, 15, 8, doc="# Linear Address bits")
|
|
|
|
attribute_bits = [
|
|
"physical_address_bits",
|
|
"linear_address_bits",
|
|
]
|