acrn-hypervisor/misc/config_tools/board_inspector/cpuparser/msr.py
Wu Zhou 635120e3f2 config-tools: extract CPU frequency info in board_inspector
This patch adds CPU frequency info extraction for board_inspector.

It is supposed to be used by ACRN CPU performance management.

Including those:
  - Capabilities for HWP base regs, and turbo boost, by reading cpuids.
  - Reporting all CPUID bits in LEAF 06H.
  - Max none turbo ratio and max turbo ratio, by reading MSRs.
  - HWP capabilities, by reading IA32_HWP_CAPABILITIES. Reading this
    register requires HWP enabled in IA32_PM_ENABLE. (SDM Vol3 14.4.2:
    Additional MSRs associated with HWP may only be accessed after HWP
    is enabled)
  - ACPI _PSD info, by reading sys nodes of Linux acpi-pstate driver.
    This table describes frequency domains in which CPUs shares the same
    frequency.

Tracked-On: #8168
Signed-off-by: Wu Zhou <wu.zhou@intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
2022-10-08 11:13:21 +08:00

305 lines
8.9 KiB
Python

# Copyright (C) 2022 Intel Corporation.
#
# SPDX-License-Identifier: BSD-3-Clause
#
from cpuparser.platformbase import MSR, msrfield
class MSR_IA32_MISC_ENABLE(MSR):
addr = 0x1a0
fast_string = msrfield(0, 0, doc="Fast-strings enable")
capability_bits = [
"fast_string",
]
class MSR_IA32_FEATURE_CONTROL(MSR):
addr = 0x03a
lock = msrfield(0, 0, doc="Lock bit")
vmx_outside_smx = msrfield(2, 2, doc="Enable VMX outside SMX operation")
@property
def disable_vmx(self):
return self.lock and not self.vmx_outside_smx
capability_bits = [
"disable_vmx",
]
class VMXCapabilityReportingMSR(MSR):
def get_field_idx(self, field):
if isinstance(field, int):
return field
if isinstance(field, str):
return getattr(type(self), field).lsb
assert False, f"Invalid field type: {field}, {type(field)}"
def allows_0_setting(self, field):
field_idx = self.get_field_idx(field)
if field_idx >= 32:
return False
bit_mask = (1 << field_idx)
return (self.value & bit_mask) == 0
def allows_1_setting(self, field):
field_idx = self.get_field_idx(field)
if field_idx >= 32:
return False
bit_mask = (1 << field_idx)
high = self.value >> 32
return (high & bit_mask) == bit_mask
def allows_flexible_setting(self, field):
field_idx = self.get_field_idx(field)
return self.allows_0_setting(field_idx) and self.allows_1_setting(field_idx)
class MSR_IA32_VMX_PROCBASED_CTLS2(VMXCapabilityReportingMSR):
addr = 0x0000048B
vapic_access = msrfield(0, 0, doc="Virtualize APIC accesses")
ept = msrfield(1, 1, doc="Enable EPT")
rdtscp = msrfield(3, 3, doc="Enable RDTSCP")
vx2apic = msrfield(4, 4, doc="Virtualize x2APIC mode")
vpid = msrfield(5, 5, doc="Enable VPID")
unrestricted_guest = msrfield(7, 7, doc="Unrestricted guest")
apic_reg_virt = msrfield(8, 8, doc="APIC-register virtualization")
@property
def vmx_procbased_ctls2_vapic(self):
return self.allows_flexible_setting("vapic_access")
@property
def vmx_procbased_ctls2_ept(self):
return self.allows_flexible_setting("ept")
@property
def vmx_procbased_ctls2_vpid(self):
return self.allows_flexible_setting("vpid")
@property
def vmx_procbased_ctls2_rdtscp(self):
return self.allows_flexible_setting("rdtscp")
@property
def vmx_procbased_ctls2_unrestrict(self):
return self.allows_flexible_setting("unrestricted_guest")
capability_bits = [
"vmx_procbased_ctls2_vapic",
"vmx_procbased_ctls2_ept",
"vmx_procbased_ctls2_vpid",
"vmx_procbased_ctls2_rdtscp",
"vmx_procbased_ctls2_unrestrict",
]
class MSR_IA32_VMX_PINBASED_CTLS(VMXCapabilityReportingMSR):
addr = 0x00000481
irq_exiting = msrfield(0, 0, doc="External-interrupt existing")
@property
def vmx_pinbased_ctls_irq_exit(self):
return self.allows_flexible_setting("irq_exiting")
capability_bits = [
"vmx_pinbased_ctls_irq_exit",
]
class MSR_IA32_VMX_PROCBASED_CTLS(VMXCapabilityReportingMSR):
addr = 0x00000482
tsc_offsetting = msrfield(3, 3, doc="Use TSC offsetting")
hlt_exiting = msrfield(7, 7, doc="HLT exiting")
tpr_shadow = msrfield(21, 21, doc="Use TPR shadow")
io_bitmaps = msrfield(25, 25, doc="Use I/O bitmaps")
msr_bitmaps = msrfield(28, 28, doc="Use MSR bitmaps")
secondary_ctrls = msrfield(31, 31, doc="Activate secondary controls")
@property
def vmx_procbased_ctls_tsc_off(self):
return self.allows_flexible_setting("tsc_offsetting")
@property
def vmx_procbased_ctls_tpr_shadow(self):
return self.allows_flexible_setting("tpr_shadow")
@property
def vmx_procbased_ctls_io_bitmap(self):
return self.allows_flexible_setting("io_bitmaps")
@property
def vmx_procbased_ctls_msr_bitmap(self):
return self.allows_flexible_setting("msr_bitmaps")
@property
def vmx_procbased_ctls_hlt(self):
return self.allows_flexible_setting("hlt_exiting")
@property
def vmx_procbased_ctls_secondary(self):
return self.allows_flexible_setting("secondary_ctrls")
@property
def ept(self):
if self.allows_1_setting("secondary_ctrls"):
ctls2 = MSR_IA32_VMX_PROCBASED_CTLS2.rdmsr(self.cpu_id)
return ctls2.allows_1_setting("ept")
return False
@property
def apicv(self):
if not self.allows_1_setting("tpr_shadow"):
return False
ctls2 = MSR_IA32_VMX_PROCBASED_CTLS2.rdmsr(self.cpu_id)
return \
ctls2.allows_1_setting("vapic_access") and \
ctls2.allows_1_setting("vx2apic")
capability_bits = [
"ept",
"apicv",
"vmx_procbased_ctls_tsc_off",
"vmx_procbased_ctls_tpr_shadow",
"vmx_procbased_ctls_io_bitmap",
"vmx_procbased_ctls_msr_bitmap",
"vmx_procbased_ctls_hlt",
"vmx_procbased_ctls_secondary",
]
class MSR_IA32_VMX_EPT_VPID_CAP(MSR):
addr = 0x0000048C
invept = msrfield(20, 20, doc="INVEPT instruction supported")
ept_2mb_page = msrfield(16, 16, doc="EPT 2-Mbyte page supported")
vmx_ept_1gb_page = msrfield(17, 17, doc="EPT 1-Gbyte page supported")
invvpid_inst = msrfield(32, 32, doc="INVVPID instruction supported")
invvpid_single_context = msrfield(41, 41, doc="single-context INVVPID type supported")
invvpid_all_context = msrfield(42, 42, doc="all-context INVVPID type supported")
@property
def invvpid(self):
return self.invvpid_inst and self.invvpid_single_context and self.invvpid_all_context
capability_bits = [
"invept",
"invvpid",
"ept_2mb_page",
"vmx_ept_1gb_page",
]
class MSR_IA32_VMX_MISC(MSR):
addr = 0x00000485
stores_lma_on_exit = msrfield(5, 5, doc="VM exits stores the value of IA32_EFER.LMA into the 'IA-32e mode guest' VM-entry control")
capability_bits = [
"stores_lma_on_exit",
]
class MSR_IA32_VMX_BASIC(MSR):
addr = 0x00000480
set_32bit_addr_width = msrfield(48, 48, doc="Addresses of VMXON, VMCS and referenced structures limited to 32-bit")
capability_bits = [
"set_32bit_addr_width",
]
class MSR_IA32_VMX_EXIT_CTLS(VMXCapabilityReportingMSR):
addr = 0x00000483
host_addr_size = msrfield(9, 9, doc="Host address-space size")
ack_irq_on_exit = msrfield(15, 15, doc="Acknowledge interrupt on exit")
save_pat = msrfield(18, 18, doc="Save IA32_PAT")
load_pat = msrfield(19, 19, doc="Load IA32_PAT")
@property
def vmx_exit_ctls_ack_irq(self):
return self.allows_flexible_setting("ack_irq_on_exit")
@property
def vmx_exit_ctls_save_pat(self):
return self.allows_flexible_setting("save_pat")
@property
def vmx_exit_ctls_load_pat(self):
return self.allows_flexible_setting("load_pat")
@property
def vmx_exit_ctls_host_addr64(self):
return self.allows_flexible_setting("host_addr_size")
capability_bits = [
"vmx_exit_ctls_ack_irq",
"vmx_exit_ctls_save_pat",
"vmx_exit_ctls_load_pat",
"vmx_exit_ctls_host_addr64",
]
class MSR_IA32_VMX_ENTRY_CTLS(VMXCapabilityReportingMSR):
addr = 0x00000484
ia32e_mode_guest = msrfield(9, 9, doc="IA-32e mode guest")
load_pat = msrfield(14, 14, doc="Load IA32_PAT")
@property
def vmx_entry_ctls_load_pat(self):
return self.allows_flexible_setting("load_pat")
@property
def vmx_entry_ctls_ia32e_mode(self):
return self.allows_flexible_setting("ia32e_mode_guest")
capability_bits = [
"vmx_entry_ctls_load_pat",
"vmx_entry_ctls_ia32e_mode",
]
class MSR_IA32_L3_QOS_CFG(MSR):
addr = 0x00000c81
cdp_enable = msrfield(0, 0, doc="L3 CDP enable")
def MSR_IA32_L3_MASK_n(n):
if n >= 128:
logging.debug("Attempt to access an out-of-range IA32_L3_MASK_n register. Fall back to 0.")
n = 0
class IA32_L3_MASK_n(MSR):
addr = 0x00000c90 + n
bit_mask = msrfield(32, 0, doc="Capacity bit mask")
return IA32_L3_MASK_n
class MSR_IA32_PM_ENABLE(MSR):
addr = 0x00000770
hwp_enable = msrfield(0, 0, doc=None)
class MSR_IA32_HWP_CAPABILITIES(MSR):
addr = 0x00000771
highest_performance_lvl = msrfield(7, 0, doc=None)
guaranteed_performance_lvl = msrfield(15, 8, doc=None)
lowest_performance_lvl = msrfield(31, 24, doc=None)
attribute_bits = [
"highest_performance_lvl",
"guaranteed_performance_lvl",
"lowest_performance_lvl",
]
class MSR_TURBO_RATIO_LIMIT(MSR):
addr = 0x000001ad
max_ratio_1core = msrfield(7, 0, doc=None)
attribute_bits = [
"max_ratio_1core",
]
class MSR_TURBO_ACTIVATION_RATIO(MSR):
addr = 0x0000064c
max_none_turbo_ratio = msrfield(7, 0, doc=None)
attribute_bits = [
"max_none_turbo_ratio",
]