1# Copyright (C) 2021-2022 Intel Corporation.
2#
3# SPDX-License-Identifier: BSD-3-Clause
4#
5
6"""CPUID register decoding."""
7
8from cpuparser.platformbase import CPUID, cpuidfield
9import struct
10
11EAX = 0
12EBX = 1
13ECX = 2
14EDX = 3
15
16class LEAF_0(CPUID):
17    """Basic CPUID information including vendor and max supported basic leaf."""
18
19    leaf = 0x0
20    max_leaf = cpuidfield(EAX, 31, 0, doc="Highest value the CPUID recognizes for returning basic processor information")
21
22    @property
23    def cpuid_level(self):
24        return hex(self.regs.eax)
25
26    @property
27    def vendor(self):
28        """Vendor identification string"""
29        return struct.pack('III', self.regs.ebx, self.regs.edx, self.regs.ecx)
30
31    attribute_bits = [
32        "cpuid_level",
33    ]
34
35class LEAF_1(CPUID):
36    """Basic CPUID Information
37
38    Contains version type, family, model, and stepping ID; brand index; CLFLUSH
39    line size; maximum number of addressable IDs for logical processors in the
40    physical package; initial APIC ID; and feature information"""
41
42    leaf = 0x1
43
44    stepping = cpuidfield(EAX, 3, 0, doc="Stepping ID")
45    model = cpuidfield(EAX, 7, 4, doc="Model")
46    family = cpuidfield(EAX, 11, 8, doc="Family ID")
47    processor_type = cpuidfield(EAX, 13, 12, doc="Processor Type")
48    ext_model = cpuidfield(EAX, 19, 16, doc="Extended Model ID")
49    ext_family = cpuidfield(EAX, 27, 20, doc="Extended Family ID")
50
51    brand_index = cpuidfield(EBX, 7, 0, doc="Brand index")
52    CLFLUSH_line_size = cpuidfield(EBX, 15, 8, doc="CLFLUSH instruction cache line size (in 8-byte words)")
53    max_logical_processor_ids = cpuidfield(EBX, 23, 16, doc="The maximum number of addressable IDs for logical processors in the physical package.")
54    initial_apic_id = cpuidfield(EBX, 31, 24, doc="Initial APIC ID")
55
56    sse3 = cpuidfield(ECX, 0, 0)
57    pclmulqdq = cpuidfield(ECX, 1, 1)
58    dtes64 = cpuidfield(ECX, 2, 2)
59    monitor = cpuidfield(ECX, 3, 3)
60    ds_cpl = cpuidfield(ECX, 4, 4)
61    vmx = cpuidfield(ECX, 5, 5)
62    smx = cpuidfield(ECX, 6, 6)
63    est = cpuidfield(ECX, 7, 7)
64    tm2 = cpuidfield(ECX, 8, 8)
65    ssse3 = cpuidfield(ECX, 9, 9)
66    cnxt_id = cpuidfield(ECX, 10, 10)
67    sdbg = cpuidfield(ECX, 11, 11)
68    fma = cpuidfield(ECX, 12, 12)
69    cmpxchg16b = cpuidfield(ECX, 13, 13)
70    xtpr = cpuidfield(ECX, 14, 14)
71    pdcm = cpuidfield(ECX, 15, 15)
72    pcid = cpuidfield(ECX, 17, 17)
73    dca = cpuidfield(ECX, 18, 18)
74    sse4_1 = cpuidfield(ECX, 19, 19)
75    sse4_2 = cpuidfield(ECX, 20, 20)
76    x2apic = cpuidfield(ECX, 21, 21)
77    movbe = cpuidfield(ECX, 22, 22)
78    popcnt = cpuidfield(ECX, 23, 23)
79    tsc_deadline = cpuidfield(ECX, 24, 24)
80    aes = cpuidfield(ECX, 25, 25)
81    xsave = cpuidfield(ECX, 26, 26)
82    osxsave = cpuidfield(ECX, 27, 27)
83    avx = cpuidfield(ECX, 28, 28)
84    f16c = cpuidfield(ECX, 29, 29)
85    rdrand = cpuidfield(ECX, 30, 30)
86    hypervisor = cpuidfield(ECX, 31, 31)
87
88    fpu = cpuidfield(EDX, 0, 0)
89    vme = cpuidfield(EDX, 1, 1)
90    de = cpuidfield(EDX, 2, 2)
91    pse = cpuidfield(EDX, 3, 3)
92    tsc = cpuidfield(EDX, 4, 4)
93    msr = cpuidfield(EDX, 5, 5)
94    pae = cpuidfield(EDX, 6, 6)
95    mce = cpuidfield(EDX, 7, 7)
96    cx8 = cpuidfield(EDX, 8, 8)
97    apic = cpuidfield(EDX, 9, 9)
98    sep = cpuidfield(EDX, 11, 11)
99    mtrr = cpuidfield(EDX, 12, 12)
100    pge = cpuidfield(EDX, 13, 13)
101    mca = cpuidfield(EDX, 14, 14)
102    cmov = cpuidfield(EDX, 15, 15)
103    pat = cpuidfield(EDX, 16, 16)
104    pse36 = cpuidfield(EDX, 17, 17)
105    psn = cpuidfield(EDX, 18, 18)
106    clfsh = cpuidfield(EDX, 19, 19)
107    ds = cpuidfield(EDX, 21, 21)
108    acpi = cpuidfield(EDX, 22, 22)
109    mmx = cpuidfield(EDX, 23, 23)
110    fxsr = cpuidfield(EDX, 24, 24)
111    sse = cpuidfield(EDX, 25, 25)
112    sse2 = cpuidfield(EDX, 26, 26)
113    ss = cpuidfield(EDX, 27, 27)
114    htt = cpuidfield(EDX, 28, 28)
115    tm = cpuidfield(EDX, 29, 29)
116    pbe = cpuidfield(EDX, 31, 31)
117
118    @property
119    def display_family(self):
120        if self.family == 0xf:
121            return self.ext_family + self.family
122        return self.family
123
124    @property
125    def display_model(self):
126        if self.family == 0xf or self.family == 0x6:
127            return (self.ext_model << 4) + self.model
128        return self.model
129
130    capability_bits = [
131        "sse3",
132        "pclmulqdq",
133        "dtes64",
134        "monitor",
135        "ds_cpl",
136        "vmx",
137        "smx",
138        "est",
139        "tm2",
140        "ssse3",
141        "cnxt_id",
142        "sdbg",
143        "fma",
144        "cmpxchg16b",
145        "xtpr",
146        "pdcm",
147        "pcid",
148        "dca",
149        "sse4_1",
150        "sse4_2",
151        "x2apic",
152        "movbe",
153        "popcnt",
154        "tsc_deadline",
155        "aes",
156        "xsave",
157        "avx",
158        "f16c",
159        "rdrand",
160        "fpu",
161        "vme",
162        "de",
163        "pse",
164        "tsc",
165        "msr",
166        "pae",
167        "mce",
168        "cx8",
169        "apic",
170        "sep",
171        "mtrr",
172        "pge",
173        "mca",
174        "cmov",
175        "pat",
176        "pse36",
177        "psn",
178        "clfsh",
179        "ds",
180        "acpi",
181        "mmx",
182        "fxsr",
183        "sse",
184        "sse2",
185        "ss",
186        "htt",
187        "tm",
188        "pbe",
189    ]
190
191class LEAF_2(CPUID):
192    """TLB, Cache, and Prefetch Information"""
193
194    leaf = 0x2
195    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")
196
197class LEAF_4(CPUID):
198    """Deterministic cache parameters
199
200    Returns encoded data that describes a set of deterministic cache parameters
201    for the cache level associated in ECX"""
202
203    leaf = 0x4
204    cache_type = cpuidfield(EAX, 4, 0, doc="Cache Type Field")
205    cache_level = cpuidfield(EAX, 7, 5, doc="Cache Level")
206    self_initializing = cpuidfield(EAX, 8, 8, doc="Self Initializing Cache Level")
207    fully_associative = cpuidfield(EAX, 9, 9, doc="Fully Associative Cache")
208    max_logical_processors_sharing_cache_z = cpuidfield(EAX, 25, 14, doc="Max number of addressable IDs for logical processors sharing this cache (zero based)")
209    max_cores_sharing_cache_z = cpuidfield(EAX, 31, 26, doc="Max number of addressable IDs for processor cores in the physical package (zero based)")
210
211    line_size_z = cpuidfield(EBX, 11, 0, doc="System Coherency Line Size (zero-based)")
212    partitions_z = cpuidfield(EBX, 21, 12, doc="Physical Line Partitions (zero-based)")
213    ways_z = cpuidfield(EBX, 31, 22, doc="Ways of associativity (zero-based)")
214
215    sets_z = cpuidfield(ECX, 31, 0, doc="Sets (zero-based)")
216
217    write_back_invalidate = cpuidfield(EDX, 0, 0, doc="Write-back Invalidate/Invalidate")
218    cache_inclusiveness = cpuidfield(EDX, 1, 1, doc="Cache Inclusiveness")
219    complex_cache_indexing = cpuidfield(EDX, 2, 2, doc="Complex Cache indexing")
220
221    @property
222    def max_logical_processors_sharing_cache(self):
223        """Maximum number of addressable IDs for logical processors sharing this cache"""
224        return self.max_logical_processors_sharing_cache_z + 1
225
226    @property
227    def max_cores_sharing_cache(self):
228        """Maximum number of addressable IDs for processor cores in the physical pacakge"""
229        return self.max_cores_sharing_cache_z + 1
230
231    @property
232    def partitions(self):
233        """Number of physical line partitions"""
234        return self.partitions_z + 1
235
236    @property
237    def line_size(self):
238        """System Coherency line size"""
239        return self.line_size_z + 1
240
241    @property
242    def ways(self):
243        """Ways of associativity"""
244        return self.ways_z + 1
245
246    @property
247    def sets(self):
248        """Number of sets"""
249        return self.sets_z + 1
250
251    @property
252    def cache_size(self):
253        """Cache size in bytes"""
254        return self.ways * self.partitions * self.line_size * self.sets
255
256class LEAF_5(CPUID):
257    """MONITOR/MWAIT Leaf
258
259    Returns information about features available to MONITOR/MWAIT instructions"""
260
261    leaf = 0x5
262
263    smallest_monitor_line_size = cpuidfield(EAX, 15, 0, doc="Smallest monitor-line size in bytes")
264
265    largest_monitor_line_size = cpuidfield(EBX, 15, 0, doc="Largest monitor-line size in bytes")
266
267    monitor_mwait_supported = cpuidfield(ECX, 0, 0, doc="Enumeration of MONITOR/MWAIT extensions supported")
268    interrupt_break_event_supported = cpuidfield(ECX, 1, 1, doc="Supports treating interrupts as break-events for MWAIT, even when interrupts disabled")
269
270    c0 = cpuidfield(EDX, 3, 0, doc="Number of C0 sub C-states supported using MWAIT")
271    c1 = cpuidfield(EDX, 7, 4, doc="Number of C1 sub C-states supported using MWAIT")
272    c2 = cpuidfield(EDX, 11, 8, doc="Number of C2 sub C-states supported using MWAIT")
273    c3 = cpuidfield(EDX, 15, 12, doc="Number of C3 sub C-states supported using MWAIT")
274    c4 = cpuidfield(EDX, 19, 16, doc="Number of C4 sub C-states supported using MWAIT")
275
276class LEAF_6(CPUID):
277    """Thermal and Power Management leaf
278
279    Returns information about the maximum input values for sub-leaves that contain extended feature flags."""
280
281    leaf = 0x6
282
283    digital_temperature_sensor_supported = cpuidfield(EAX, 0, 0, doc = "Digital temperature sensor is supported if set")
284    turbo_boost_available = cpuidfield(EAX, 1, 1, doc = "Intel Turbo Boost technology available")
285    arat_supported = cpuidfield(EAX, 2, 2, doc = "APIC-Timer-always-running feature is supported if set")
286    pln_supported = cpuidfield(EAX, 4, 4, doc = "Power limit notification controls are supported if set")
287    ecmd_supported = cpuidfield(EAX, 5, 5, doc = "Clock modulation duty cycle extension is supported if set")
288    package_thermal_management_supported = cpuidfield(EAX, 6, 6, doc = "Package thermal management is supported if set")
289    hwp_supported = cpuidfield(EAX, 7, 7, doc = "HWP base registers (IA32_PM_ENABLE[bit 0], IA32_HWP_CAPABILITIES, IA32_HWP_REQUEST, IA32_HWP_STATUS) are supported if set")
290    hwp_notification = cpuidfield(EAX, 8, 8, doc = "HWP_Notification. IA32_HWP_INTERRUPT MSR is supported if set.")
291    hwp_activity_window = cpuidfield(EAX, 9, 9, doc = "HWP_Activity_Window. IA32_HWP_REQUEST[bits 41:32] is supported if set.")
292    hwp_energy_performance_preference = cpuidfield(EAX, 10, 10, doc = "HWP_Energy_Performance_Preference. IA32_HWP_REQUEST[bits 31:24] is supported if set.")
293    hwp_package_level_request = cpuidfield(EAX, 11, 11, doc = "HWP_Package_Level_Request. IA32_HWP_REQUEST_PKG MSR is supported if set.")
294    hdc = cpuidfield(EAX, 13, 13, doc = "HDC. HDC base registers IA32_PKG_HDC_CTL, IA32_PM_CTL1, IA32_THREAD_STALL MSRs are supported if set.")
295    turbo_boost_30 = cpuidfield(EAX, 14, 14, doc = "Intel® Turbo Boost Max Technology 3.0 available.")
296    hwp_capabilities = cpuidfield(EAX, 15, 15, doc = "HWP Capabilities. Highest Performance change is supported if set.")
297    hwp_peci_override = cpuidfield(EAX, 16, 16, doc = "HWP PECI override is supported if set.")
298    flexible_hwp = cpuidfield(EAX, 17, 17, doc = "Flexible HWP is supported if set.")
299    fast_hwp_request = cpuidfield(EAX, 18, 18, doc = "Fast access mode for the IA32_HWP_REQUEST MSR is supported if set.")
300    hw_feedback = cpuidfield(EAX, 19, 19, doc = "HW_FEEDBACK. IA32_HW_FEEDBACK_PTR MSR, IA32_HW_FEEDBACK_CONFIG MSR, IA32_PACKAGE_THERM_STATUS MSR bit 26, and IA32_PACKAGE_THERM_INTERRUPT MSR bit 25 are supported if set.")
301    ignoring_idle_hwp = cpuidfield(EAX, 20, 20, doc = "Ignoring Idle Logical Processor HWP request is supported if set.")
302    thread_director = cpuidfield(EAX, 23, 23, doc = "Intel® Thread Director supported if set. IA32_HW_FEEDBACK_CHAR and IA32_HW_FEEDBACK_THREAD_CONFIG MSRs are supported if set.")
303
304    num_interrupt_thresholds = cpuidfield(EBX, 3, 0, doc="Number of interrupt thresholds in digital thermal sensor")
305
306    hardware_coordination_feedback_capability = cpuidfield(ECX, 0, 0, doc="Hardware coordination feedback capability")
307    performance_energy_bias = cpuidfield(ECX, 3, 3, doc="Performance-energy bias preference support")
308    num_thread_director_classes = cpuidfield(ECX, 15, 8, "Number of Intel® Thread Director classes supported by the processor. Information for that many classes is written into the Intel Thread Director Table by the hardware.")
309
310    hardware_feedback_interface_bitmap = cpuidfield(EDX, 7, 0, doc = "Bitmap of supported hardware feedback interface capabilities.")
311    hardware_feedback_interface_structure_size = cpuidfield(EDX, 11, 8, doc = "Enumerates the size of the hardware feedback interface structure in number of 4 KB pages.")
312    hardware_feedback_index = cpuidfield(EDX, 31, 16, doc = "Index (starting at 0) of this logical processor's row in the hardware feedback interface structure.")
313
314    capability_bits = [
315        "digital_temperature_sensor_supported",
316        "turbo_boost_available",
317        "arat_supported",
318        "pln_supported",
319        "ecmd_supported",
320        "package_thermal_management_supported",
321        "hwp_supported",
322        "hwp_notification",
323        "hwp_activity_window",
324        "hwp_energy_performance_preference",
325        "hwp_package_level_request",
326        "hdc",
327        "turbo_boost_30",
328        "hwp_capabilities",
329        "hwp_peci_override",
330        "flexible_hwp",
331        "fast_hwp_request",
332        "hw_feedback",
333        "ignoring_idle_hwp",
334        "thread_director",
335        "num_interrupt_thresholds",
336        "hardware_coordination_feedback_capability",
337        "performance_energy_bias",
338        "num_thread_director_classes",
339        "hardware_feedback_interface_bitmap",
340        "hardware_feedback_interface_structure_size",
341        "hardware_feedback_index",
342        "digital_temperature_sensor_supported",
343        "turbo_boost_available",
344        "arat_supported",
345        "pln_supported",
346        "ecmd_supported",
347        "package_thermal_management_supported",
348        "hwp_supported",
349        "hwp_notification",
350        "hwp_activity_window",
351        "hwp_energy_performance_preference",
352        "hwp_package_level_request",
353        "hdc",
354        "turbo_boost_30",
355        "hwp_capabilities",
356        "hwp_peci_override",
357        "flexible_hwp",
358        "fast_hwp_request",
359        "hw_feedback",
360        "ignoring_idle_hwp",
361        "thread_director",
362        "num_interrupt_thresholds",
363        "hardware_coordination_feedback_capability",
364        "performance_energy_bias",
365        "num_thread_director_classes",
366        "hardware_feedback_interface_bitmap",
367        "hardware_feedback_interface_structure_size",
368        "hardware_feedback_index",
369    ]
370
371class LEAF_7(CPUID):
372    """Structured Extended Feature Flags Enumeration Leaf
373
374    Returns information about the maximum input value for sub-leaves that contain
375    extended feature flags"""
376
377    leaf = 0x7
378
379    max_input_values = cpuidfield(EAX, 31, 0, doc="Reports the maximum input value for supported leaf 7 sub-leaves")
380
381    fsgsbase = cpuidfield(EBX, 0, 0, doc="Supports RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE if 1")
382    ia32_tsc_adjust_msr = cpuidfield(EBX, 1, 1, doc="IA32_TSC_ADJUST MSR is supported if 1")
383    sgx = cpuidfield(EBX, 2, 2, doc="Supports Intel® Software Guard Extensions (Intel® SGX Extensions) if 1")
384    bmi1 = cpuidfield(EBX, 3, 3)
385    hle = cpuidfield(EBX, 4, 4)
386    avx2 = cpuidfield(EBX, 5, 5)
387    fdp_excptn_only = cpuidfield(EBX, 6, 6, doc="x87 FPU Data Pointer updated only on x87 exceptions if 1")
388    smep = cpuidfield(EBX, 7, 7, doc="Supports Supervisor Mode Execution Protection if 1")
389    bmi2 = cpuidfield(EBX, 8, 8)
390    erms = cpuidfield(EBX, 9, 9, doc="Supports Enhanced REP MOVSB/STOSB if 1")
391    invpcid = cpuidfield(EBX, 10, 10, doc="Supports INVPCID instruction for system software that manages process-context identifiers if 1")
392    rtm = cpuidfield(EBX, 11, 11)
393    qm = cpuidfield(EBX, 12, 12, doc="Supports Quality of Service Monitoring capability if 1")
394    deprecate_fpu = cpuidfield(EBX, 13, 13, doc="Deprecates FPS CS and FPU DS values if 1")
395    mpx = cpuidfield(EBX, 14, 14, doc="Supports Intel® Memory Protection Extensions if 1")
396    rdt_a = cpuidfield(EBX, 15, 15, doc="Supports Intel® Resource Director Technology (Intel® RDT) Allocation capability if 1")
397    avx512f = cpuidfield(EBX, 16, 16)
398    avx512dq = cpuidfield(EBX, 17, 17)
399    rdseed = cpuidfield(EBX, 18, 18)
400    adx = cpuidfield(EBX, 19, 19)
401    smap = cpuidfield(EBX, 20, 20, doc="Supports Supervisor-Mode Access Prevention (and the CLAC/STAC instructions) if 1")
402    avx512_ifma = cpuidfield(EBX, 21, 21)
403    clflushopt = cpuidfield(EBX, 23, 23)
404    clwb = cpuidfield(EBX, 24, 24)
405    intel_pt = cpuidfield(EBX, 25, 25)
406    avx512pf = cpuidfield(EBX, 26, 26)
407    avx512er = cpuidfield(EBX, 27, 27)
408    avx512cd = cpuidfield(EBX, 28, 28)
409    sha = cpuidfield(EBX, 29, 29, doc="Supports Intel® Secure Hash Algorithm Extensions (Intel® SHA Extensions) if 1")
410    avx512bw = cpuidfield(EBX, 30, 30)
411    avx512vl = cpuidfield(EBX, 31, 31)
412
413    prefetchwt1 = cpuidfield(ECX, 0, 0)
414    avx512_vbmi = cpuidfield(ECX, 1, 1)
415    umip = cpuidfield(ECX, 2, 2, doc="Supports user-mode instruction prevention if 1")
416    pku = cpuidfield(ECX, 3, 3, doc="Supports protection keys for user-mode pages if 1")
417    ospke = cpuidfield(ECX, 4, 4, doc="If 1, OS has set CR4.PKE to enable protection keys (and the RDPKRU/WRPKRU instructions)")
418    waitpkg = cpuidfield(ECX, 5, 5)
419    avx512_vbmi2 = cpuidfield(ECX, 6, 6)
420    cet_ss = cpuidfield(ECX, 7, 7, doc="Supports CET shadow stack features if 1")
421    gfni = cpuidfield(ECX, 8, 8)
422    vaes = cpuidfield(ECX, 9, 9)
423    vpclmulqdq = cpuidfield(ECX, 10, 10)
424    avx512_vnni = cpuidfield(ECX, 11, 11)
425    avx512_bitalg = cpuidfield(ECX, 12, 12)
426    tme_en = cpuidfield(ECX, 13, 13)
427    avx512_vpopcntdq = cpuidfield(ECX, 14, 14)
428    la57 = cpuidfield(ECX, 16, 16, doc="Supports 57-bit linear addresses and five-level paging if 1")
429    mawau = cpuidfield(ECX, 21, 17, doc="The value of MAWAU used by the BNDLDX and BNDSTX instructions in 64-bit mode")
430    rdpid = cpuidfield(ECX, 22, 22, doc="RDPID and IA32_TSC_AUX are available if 1")
431    kl = cpuidfield(ECX, 23, 23, doc="Supports Key Locker if 1")
432    cldemote = cpuidfield(ECX, 25, 25, doc="Supports cache line demote if 1")
433    movdiri = cpuidfield(ECX, 27, 27, doc="Supports MOVDIRI if 1")
434    movdiri64b = cpuidfield(ECX, 28, 28, doc="Supports MOVDIRI64B if 1")
435    sgx_lc = cpuidfield(ECX, 30, 30, doc="Supports SGX Launch Configuration if 1")
436    pks = cpuidfield(ECX, 31, 31, doc="Supports protection keys for supervisor-mode pages if 1")
437
438    avx512_4vnniw = cpuidfield(EDX, 2, 2)
439    avx512_4fmaps = cpuidfield(EDX, 3, 3)
440    fast_short_rep_mov = cpuidfield(EDX, 4, 4)
441    avx512_vp2intersect = cpuidfield(EDX, 8, 8)
442    md_clear = cpuidfield(EDX, 10, 10)
443    hybrid = cpuidfield(EDX, 15, 15, doc="If 1, the processor is identified as a hybrid part")
444    pconfig = cpuidfield(EDX, 18, 18, doc="Supports PCONFIG if 1")
445    cet_ibt = cpuidfield(EDX, 20, 20, doc="Supports CET indirect branch tracking features if 1")
446    ibrs_ibpb = cpuidfield(EDX, 26, 26, doc="Enumerates support for indirect branch restricted speculation (IBRS) and the indirect branch predictor barrier (IBPB)")
447    stibp = cpuidfield(EDX, 27, 27, doc="Enumerates support for single thread indirect branch predictors (STIBP)")
448    l1d_flush = cpuidfield(EDX, 28, 28, doc="Enumerates support for L1D_FLUSH")
449    ia32_arch_capabilities = cpuidfield(EDX, 29, 29, doc="Enumerates support for the IA32_ARCH_CAPABILITIES MSR")
450    ia32_core_capabilities = cpuidfield(EDX, 30, 30, doc="Enumerates support for the IA32_CORE_CAPABILITIES MSR")
451    ssbd = cpuidfield(EDX, 31, 31, doc="Enumerates support for Speculative Store Bypass Disable (SSBD)")
452
453    capability_bits = [
454        "fsgsbase",
455        "ia32_tsc_adjust_msr",
456        "sgx",
457        "bmi1",
458        "hle",
459        "avx2",
460        "fdp_excptn_only",
461        "smep",
462        "bmi2",
463        "erms",
464        "invpcid",
465        "rtm",
466        "qm",
467        "deprecate_fpu",
468        "mpx",
469        "rdt_a",
470        "avx512f",
471        "avx512dq",
472        "rdseed",
473        "adx",
474        "smap",
475        "avx512_ifma",
476        "clflushopt",
477        "clwb",
478        "intel_pt",
479        "avx512pf",
480        "avx512er",
481        "avx512cd",
482        "sha",
483        "avx512bw",
484        "avx512vl",
485        "prefetchwt1",
486        "avx512_vbmi",
487        "umip",
488        "pku",
489        "waitpkg",
490        "avx512_vbmi2",
491        "cet_ss",
492        "gfni",
493        "vaes",
494        "vpclmulqdq",
495        "avx512_vnni",
496        "avx512_bitalg",
497        "tme_en",
498        "avx512_vpopcntdq",
499        "la57",
500        "mawau",
501        "rdpid",
502        "kl",
503        "cldemote",
504        "movdiri",
505        "movdiri64b",
506        "sgx_lc",
507        "pks",
508        "avx512_4vnniw",
509        "avx512_4fmaps",
510        "fast_short_rep_mov",
511        "avx512_vp2intersect",
512        "md_clear",
513        "hybrid",
514        "pconfig",
515        "cet_ibt",
516        "ibrs_ibpb",
517        "stibp",
518        "l1d_flush",
519        "ia32_arch_capabilities",
520        "ia32_core_capabilities",
521        "ssbd",
522    ]
523
524class LEAF_9(CPUID):
525    """Direct Cache Access Information leaf
526
527    Returns information about Direct Cache Access capabilities"""
528
529    leaf = 0x9
530
531    platform_dca_cap = cpuidfield(EAX, 31, 0, doc="Value of bits of IA32_PLATFORM_DCA_CAP MSR (address 1F8H)")
532
533class LEAF_A(CPUID):
534    """Architectural Performance Monitoring Leaf
535
536    Returns information about support for architectural performance monitoring capabilities"""
537
538    leaf = 0xA
539
540    architectural_performance_monitor_version_id = cpuidfield(EAX, 7, 0, doc="Version ID of architectural performance monitoring")
541    gp_performance_monitor_counters = cpuidfield(EAX, 15, 8, doc="Number of general-purpose performance monitoring counter per logical processor")
542    gp_performance_counter_width = cpuidfield(EAX, 23, 16, doc="Bit width of general-purpose, performance monitoring counter")
543    ebx_bit_vector_length = cpuidfield(EAX, 31, 24, doc="Length of EBX bit vector to enumerate architectural performance monitoring events")
544
545    core_cycle_event = cpuidfield(EBX, 0, 0, doc="Core cycle event not available if 1")
546    instruction_retired_event = cpuidfield(EBX, 1, 1, doc="Instruction retired event not available if 1")
547    reference_cycles_event = cpuidfield(EBX, 2, 2, doc="Reference cycles event not available if 1")
548    llc_ref_event = cpuidfield(EBX, 3, 3, doc="Last-level cache reference event not available if 1")
549    llc_misses_event = cpuidfield(EBX, 4, 4, doc= "Last-level cache misses event not available if 1")
550    branch_instruction_retired_event = cpuidfield(EBX, 5, 5, doc="Branch instruction retired event not available if 1")
551    branch_mispredict_retired_event = cpuidfield(EBX, 6, 6, doc="Branch mispredict retired event not available if 1")
552
553    ff_performance_counters = cpuidfield(EDX, 4, 0, doc="Number of fixed-function performance counters")
554    ff_performance_counter_width = cpuidfield(EDX, 12, 5, doc="Bit width of fixed-function performance counters")
555
556class LEAF_B(CPUID):
557    """Extended Topology Enumeration Leaf
558
559    Returns information about extended topology enumeration data"""
560
561    leaf = 0xB
562
563    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")
564
565    logical_proccessors_at_level = cpuidfield(EBX, 15, 0, doc="Number of logical processors at this level type.")
566
567    level_number = cpuidfield(ECX, 7, 0, doc="Level number")
568    level_type = cpuidfield(ECX, 15, 8, doc="Level type")
569
570    x2apic_id = cpuidfield(EDX, 31, 0, doc="x2APIC ID of the current logical processor")
571
572class LEAF_D(CPUID):
573    """Processor Extended State Enumeration Main Leaf and Sub-Leaves.
574
575    Returns information about the bit-vector representation of all processor
576    state extensions that are supported in the processor, and storage size
577    requirements of the XSAVE/XRSTOR area. Output depends on initial value of ECX."""
578
579    leaf = 0xD
580
581    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")
582
583    legacy_x87 = cpuidfield(EAX, 0, 0, doc="legacy x87")
584    sse_128_bit = cpuidfield(EAX, 1, 1, doc="128-bit SSE")
585    avx_256_bit = cpuidfield(EAX, 2, 2, doc="256-bit AVX")
586
587    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.")
588
589    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.")
590
591    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.")
592
593    def __getitem__(self, subleaf):
594        if subleaf == 0:
595            return self.read(self.cpu_id, subleaf)
596        elif subleaf == 1:
597            return LEAF_D_1.read(self.cpu_id, subleaf)
598        return LEAF_D_n.read(self.cpu_id, subleaf)
599
600class LEAF_D_1(CPUID):
601    """Processor Extended State Enumeration Main Leaf and Sub-Leaves.
602
603    Returns information about the bit-vector representation of all processor
604    state extensions that are supported in the processor, and storage size
605    requirements of the XSAVE/XRSTOR area. Output depends on initial value of ECX."""
606
607    leaf = 0xD
608
609    xsaveopt = cpuidfield(EAX, 0, 0, doc="XSAVEOPT is available")
610
611class LEAF_D_n(CPUID):
612    """Processor Extended State Enumeration Main Leaf and Sub-Leaves.
613
614    Returns information about the bit-vector representation of all processor
615    state extensions that are supported in the processor, and storage size
616    requirements of the XSAVE/XRSTOR area. Output depends on initial value of ECX."""
617
618    leaf = 0xD
619
620    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")
621
622    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.")
623
624class LEAF_F(CPUID):
625    """Quality of Service Resource Type Enumeration Sub-Leaf and L3 Cache QoS Capability Enumeration Sub-leaf. Depends on value of ECX
626
627    Returns Quality of Service (QoS) Enumeration Information."""
628
629    leaf = 0xF
630
631    def __getitem__(self, subleaf):
632        if subleaf == 0:
633            return self.read(self.cpu_id, subleaf)
634        elif subleaf == 1:
635            return LEAF_F_1.read(self.cpu_id, subleaf)
636        return LEAF_F_n.read(self.cpu_id, subleaf)
637
638    max_range_rmid_z = cpuidfield(EBX, 31, 0, doc="Maximum range (zero-based) of RMID within this physical processor of all types.")
639
640    l3_cache_qos = cpuidfield(EDX, 1, 1, doc="Supports L3 Cache QoS if 1")
641
642    @property
643    def max_range_rmid(self):
644        """Maximum range of RMID within this physical processor of all types."""
645        return self.max_range_rmid_z + 1
646
647class LEAF_F_1(CPUID):
648    """Quality of Service Resource Type Enumeration Sub-Leaf and L3 Cache QoS Capability Enumeration Sub-leaf. Depends on value of ECX
649
650    Returns L3 Cache QoS Capability Enumeration Information."""
651
652    leaf = 0xF
653
654    qm_ctr_conversion_factor = cpuidfield(EBX, 31, 0, doc="Conversion factor from reported IA32_QM_CTR value to occupancy metric (bytes).")
655
656    l3_occupancy_monitoring = cpuidfield(EDX, 0, 0, doc="Supports L3 occupancy monitoring if 1")
657
658    max_range_rmid_z = cpuidfield(ECX, 31, 0, doc="Maximum range (zero-based) of RMID of this resource type")
659
660    @property
661    def max_range_rmid(self):
662        """Maximum range of RMID of this resource type"""
663        return self.max_range_rmid_z + 1
664
665class LEAF_F_n(CPUID):
666    """Quality of Service Resource Type Enumeration Sub-Leaf and L3 Cache QoS Capability Enumeration Sub-leaf. Depends on value of ECX
667
668    Returns Quality of Service (QoS) Enumeration Information."""
669
670    leaf = 0xF
671
672class LEAF_10(CPUID):
673    """Intel Resource Director Technology (Intel RDT) Allocation Enumeration Sub-leaf"""
674
675    leaf = 0x10
676
677    l3_cache_allocation = cpuidfield(EBX, 1, 1, doc="Supports L3 Cache Allocation Technology if 1.")
678    l2_cache_allocation = cpuidfield(EBX, 2, 2, doc="Supports L2 Cache Allocation Technology if 1.")
679    memory_bandwidth_allocation = cpuidfield(EBX, 3, 3, doc="Supports Memory Bandwidth Allocation if 1.")
680
681class LEAF_10_1(CPUID):
682    """L3/L2 Cache Allocation Technology Enumeration Sub-leaf"""
683
684    leaf = 0x10
685
686    capacity_mask_length_z = cpuidfield(EAX, 4, 0, doc="Length of the capacity bit mask for the corresponding ResID (zero based).")
687    isolation_map = cpuidfield(EBX, 31, 0, doc="Bit-granular map of isolation/contention of allocation units.")
688    code_and_data_prioritization = cpuidfield(ECX, 2, 2, doc="Code and Data Prioritization Technology supported if 1.")
689    clos_number_z = cpuidfield(EDX, 15, 0, doc="Highest COS number supported for this ResID.")
690
691    @property
692    def capacity_mask_length(self):
693        return self.capacity_mask_length_z + 1
694
695    @property
696    def clos_number(self):
697        return self.clos_number_z + 1
698
699class LEAF_10_3(CPUID):
700    """Memory Bandwidth Allocation Enumeration Sub-leaf"""
701
702    leaf = 0x10
703
704    max_throttling_value_z = cpuidfield(EAX, 11, 0, doc="Reports the maximum MBA throttling value supported for the corresponding ResID (zero based).")
705    linear_response_delay = cpuidfield(ECX, 2, 2, doc="Reports whether the response of the delay values is linear.")
706    clos_number_z = cpuidfield(EDX, 15, 0, doc="Highest COS number supported for this ResID.")
707
708    @property
709    def max_throttling_value(self):
710        return self.max_throttling_value_z + 1
711
712    @property
713    def clos_number(self):
714        return self.clos_number_z + 1
715
716class LEAF_1A(CPUID):
717    """Hybrid Information Enumeration Leaf"""
718
719    leaf = 0x1A
720
721    core_type_id = cpuidfield(EAX, 31, 24, doc="Core type")
722    native_model_id = cpuidfield(EAX, 23, 0, doc="Native model ID")
723
724    core_types = {
725        0x20: "Atom",
726        0x40: "Core",
727    }
728
729    @property
730    def core_type(self):
731        if self.core_type_id in self.core_types:
732            return self.core_types[self.core_type_id]
733        return "Reserved"
734
735class LEAF_1F(LEAF_B):
736    """Extened Topology Enumeration Leaf v2"""
737
738    leaf = 0x1F
739
740class LEAF_80000000(CPUID):
741    """Extended Function CPUID Information"""
742
743    leaf = 0x80000000
744
745    max_extended_leaf = cpuidfield(EAX, 31, 0, doc="Highest extended function input value understood by CPUID")
746
747class LEAF_80000001(CPUID):
748    """Extended Function CPUID Information"""
749
750    leaf = 0x80000001
751
752    ext_signature_feature_bits = cpuidfield(EAX, 31, 0, doc="Extended processor signature and feature bits")
753
754    lahf_sahf_64 = cpuidfield(ECX, 0, 0, doc="LAHF/SAHF available in 64-bit mode")
755    lzcnt = cpuidfield(ECX, 5, 5)
756    prefetchw = cpuidfield(ECX, 8, 8)
757
758    syscall_sysret_64 = cpuidfield(EDX, 11, 11, doc="SYSCALL/SYSRET available in 64-bit mode")
759    execute_disable = cpuidfield(EDX, 20, 20, doc="Execute Disable Bit available")
760    gbyte_pages = cpuidfield(EDX, 26, 26, doc="GByte pages are available if 1")
761    rdtscp_ia32_tsc_aux = cpuidfield(EDX, 27, 27, doc="RDTSCP and IA32_TSC_AUX are available if 1")
762    intel_64 = cpuidfield(EDX, 29, 29, doc="Intel(R) 64 Architecture available if 1")
763
764    capability_bits = [
765        "lahf_sahf_64",
766        "lzcnt",
767        "prefetchw",
768        "syscall_sysret_64",
769        "execute_disable",
770        "gbyte_pages",
771        "rdtscp_ia32_tsc_aux",
772        "intel_64",
773    ]
774
775class LEAF_80000002(CPUID):
776    """Extended Function CPUID Information
777
778    Processor Brand String"""
779
780    leaf = 0x80000002
781
782    @property
783    def brandstring(self):
784        """Processor Brand String"""
785        return struct.pack('IIII', self.regs.eax, self.regs.ebx, self.regs.ecx, self.regs.edx).rstrip(b"\x00")
786
787class LEAF_80000003(CPUID):
788    """Extended Function CPUID Information
789
790    Processor Brand String Continued"""
791
792    leaf = 0x80000003
793
794    @property
795    def brandstring(self):
796        """Processor Brand String"""
797        return struct.pack('IIII', self.regs.eax, self.regs.ebx, self.regs.ecx, self.regs.edx).rstrip(b"\x00")
798
799class LEAF_80000004(CPUID):
800    """Extended Function CPUID Information
801
802    Processor Brand String Continued"""
803
804    leaf = 0x80000004
805
806    @property
807    def brandstring(self):
808        """Processor Brand String"""
809        return struct.pack('IIII', self.regs.eax, self.regs.ebx, self.regs.ecx, self.regs.edx).rstrip(b"\x00")
810
811class LEAF_80000006(CPUID):
812    """Extended Function CPUID Information"""
813
814    leaf = 0x80000006
815
816    cache_line_size = cpuidfield(ECX, 7, 0, doc="Cache Line size in bytes")
817
818    l2_associativity = cpuidfield(ECX, 15, 12, doc="L2 Associativity field")
819    cache_size_k = cpuidfield(ECX, 31, 16, doc="Cache size in 1K units")
820
821class LEAF_80000007(CPUID):
822    """Misc Feature Flags"""
823
824    leaf = 0x80000007
825
826    invariant_tsc = cpuidfield(EDX, 8, 8, doc="Invariant TSC available if 1")
827
828    capability_bits = [
829        "invariant_tsc",
830    ]
831
832class LEAF_80000008(CPUID):
833    """Returns linear/physical address size"""
834
835    leaf = 0x80000008
836    physical_address_bits = cpuidfield(EAX, 7, 0, doc="# Physical Address bits")
837    linear_address_bits = cpuidfield(EAX, 15, 8, doc="# Linear Address bits")
838
839    attribute_bits = [
840        "physical_address_bits",
841        "linear_address_bits",
842    ]
843