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>
This commit is contained in:
Wu Zhou 2022-09-02 15:29:04 +08:00 committed by acrnsi-robot
parent dd7a71900b
commit 635120e3f2
3 changed files with 151 additions and 1 deletions

View File

@ -286,11 +286,87 @@ class LEAF_6(CPUID):
pln_supported = cpuidfield(EAX, 4, 4, doc = "Power limit notification controls are 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") 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") package_thermal_management_supported = cpuidfield(EAX, 6, 6, doc = "Package thermal management is supported if set")
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")
hwp_notification = cpuidfield(EAX, 8, 8, doc = "HWP_Notification. IA32_HWP_INTERRUPT MSR is supported if set.")
hwp_activity_window = cpuidfield(EAX, 9, 9, doc = "HWP_Activity_Window. IA32_HWP_REQUEST[bits 41:32] is supported if set.")
hwp_energy_performance_preference = cpuidfield(EAX, 10, 10, doc = "HWP_Energy_Performance_Preference. IA32_HWP_REQUEST[bits 31:24] is supported if set.")
hwp_package_level_request = cpuidfield(EAX, 11, 11, doc = "HWP_Package_Level_Request. IA32_HWP_REQUEST_PKG MSR is supported if set.")
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.")
turbo_boost_30 = cpuidfield(EAX, 14, 14, doc = "Intel® Turbo Boost Max Technology 3.0 available.")
hwp_capabilities = cpuidfield(EAX, 15, 15, doc = "HWP Capabilities. Highest Performance change is supported if set.")
hwp_peci_override = cpuidfield(EAX, 16, 16, doc = "HWP PECI override is supported if set.")
flexible_hwp = cpuidfield(EAX, 17, 17, doc = "Flexible HWP is supported if set.")
fast_hwp_request = cpuidfield(EAX, 18, 18, doc = "Fast access mode for the IA32_HWP_REQUEST MSR is supported if set.")
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.")
ignoring_idle_hwp = cpuidfield(EAX, 20, 20, doc = "Ignoring Idle Logical Processor HWP request is supported if set.")
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.")
num_interrupt_thresholds = cpuidfield(EBX, 3, 0, doc="Number of interrupt thresholds in digital thermal sensor") 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") 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") performance_energy_bias = cpuidfield(ECX, 3, 3, doc="Performance-energy bias preference support")
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.")
hardware_feedback_interface_bitmap = cpuidfield(EDX, 7, 0, doc = "Bitmap of supported hardware feedback interface capabilities.")
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.")
hardware_feedback_index = cpuidfield(EDX, 31, 16, doc = "Index (starting at 0) of this logical processor's row in the hardware feedback interface structure.")
capability_bits = [
"digital_temperature_sensor_supported",
"turbo_boost_available",
"arat_supported",
"pln_supported",
"ecmd_supported",
"package_thermal_management_supported",
"hwp_supported",
"hwp_notification",
"hwp_activity_window",
"hwp_energy_performance_preference",
"hwp_package_level_request",
"hdc",
"turbo_boost_30",
"hwp_capabilities",
"hwp_peci_override",
"flexible_hwp",
"fast_hwp_request",
"hw_feedback",
"ignoring_idle_hwp",
"thread_director",
"num_interrupt_thresholds",
"hardware_coordination_feedback_capability",
"performance_energy_bias",
"num_thread_director_classes",
"hardware_feedback_interface_bitmap",
"hardware_feedback_interface_structure_size",
"hardware_feedback_index",
"digital_temperature_sensor_supported",
"turbo_boost_available",
"arat_supported",
"pln_supported",
"ecmd_supported",
"package_thermal_management_supported",
"hwp_supported",
"hwp_notification",
"hwp_activity_window",
"hwp_energy_performance_preference",
"hwp_package_level_request",
"hdc",
"turbo_boost_30",
"hwp_capabilities",
"hwp_peci_override",
"flexible_hwp",
"fast_hwp_request",
"hw_feedback",
"ignoring_idle_hwp",
"thread_director",
"num_interrupt_thresholds",
"hardware_coordination_feedback_capability",
"performance_energy_bias",
"num_thread_director_classes",
"hardware_feedback_interface_bitmap",
"hardware_feedback_interface_structure_size",
"hardware_feedback_index",
]
class LEAF_7(CPUID): class LEAF_7(CPUID):
"""Structured Extended Feature Flags Enumeration Leaf """Structured Extended Feature Flags Enumeration Leaf

View File

@ -270,3 +270,35 @@ def MSR_IA32_L3_MASK_n(n):
bit_mask = msrfield(32, 0, doc="Capacity bit mask") bit_mask = msrfield(32, 0, doc="Capacity bit mask")
return IA32_L3_MASK_n 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",
]

View File

@ -4,6 +4,7 @@
# #
import logging import logging
import subprocess
import lxml.etree import lxml.etree
import re import re
@ -47,7 +48,7 @@ def extract_model(processors_node, cpu_id, family_id, model_id, core_type, nativ
brandstring += leaf_data.brandstring brandstring += leaf_data.brandstring
n.set("description", re.sub('[^!-~]+', ' ', brandstring.decode()).strip()) n.set("description", re.sub('[^!-~]+', ' ', brandstring.decode()).strip())
leaves = [(1, 0), (7, 0), (0x80000001, 0), (0x80000007, 0)] leaves = [(1, 0), (6, 0), (7, 0), (0x80000001, 0), (0x80000007, 0)]
for leaf in leaves: for leaf in leaves:
leaf_data = parse_cpuid(leaf[0], leaf[1], cpu_id) leaf_data = parse_cpuid(leaf[0], leaf[1], cpu_id)
for cap in leaf_data.capability_bits: for cap in leaf_data.capability_bits:
@ -70,6 +71,12 @@ def extract_model(processors_node, cpu_id, family_id, model_id, core_type, nativ
for cap in leaf_data.attribute_bits: for cap in leaf_data.attribute_bits:
add_child(n, "attribute", str(getattr(leaf_data, cap)), id=cap) add_child(n, "attribute", str(getattr(leaf_data, cap)), id=cap)
msr_regs = [MSR_TURBO_RATIO_LIMIT, MSR_TURBO_ACTIVATION_RATIO]
for msr_reg in msr_regs:
msr_data = msr_reg.rdmsr(cpu_id)
for attr in msr_data.attribute_bits:
add_child(n, "attribute", str(getattr(msr_data, attr)), id=attr)
def extract_topology(processors_node): def extract_topology(processors_node):
cpu_ids = get_online_cpu_ids() cpu_ids = get_online_cpu_ids()
for cpu_id in cpu_ids: for cpu_id in cpu_ids:
@ -130,6 +137,41 @@ def extract_topology(processors_node):
last_shift = leaf_topo.num_bit_shift last_shift = leaf_topo.num_bit_shift
subleaf += 1 subleaf += 1
def extract_hwp_info(processors_node):
if processors_node.xpath("//capability[@id = 'hwp_supported']") is None:
return
# SDM Vol3 14.4.2: Additional MSRs associated with HWP may only be accessed after HWP is enabled
msr_hwp_en = MSR_IA32_PM_ENABLE()
msr_hwp_en.hwp_enable = 1
msr_hwp_en.wrmsr(0)
threads = processors_node.xpath("//thread")
for thread in threads:
cpu_id = get_node(thread, "cpu_id/text()")
msr_regs = [MSR_IA32_HWP_CAPABILITIES,]
for msr_reg in msr_regs:
msr_data = msr_reg.rdmsr(cpu_id)
for attr in msr_data.attribute_bits:
add_child(thread, attr, str(getattr(msr_data, attr)))
def extract_psd_info(processors_node):
sysnode = '/sys/devices/system/cpu/'
threads = processors_node.xpath("//thread")
for thread in threads:
cpu_id = get_node(thread, "cpu_id/text()")
try:
with open(sysnode + "cpu{cpu_id}/cpufreq/freqdomain_cpus", 'r') as f_node:
freqdomain_cpus = f_node.read()
except IOError:
logging.info("No _PSD info for cpu {cpu_id}")
freqdomain_cpus = cpu_id
freqdomain_cpus.replace('\n','')
add_child(thread, "freqdomain_cpus", freqdomain_cpus)
def extract(args, board_etree): def extract(args, board_etree):
processors_node = get_node(board_etree, "//processors") processors_node = get_node(board_etree, "//processors")
extract_topology(processors_node) extract_topology(processors_node)
extract_hwp_info(processors_node)
extract_psd_info(processors_node)