mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 13:08:42 +00:00
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:
parent
dd7a71900b
commit
635120e3f2
@ -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
|
||||||
|
@ -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",
|
||||||
|
]
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user