mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 13:37:10 +00:00
board_inspector/extractors: extract CPU topology and models
This patch extracts information on CPU topology and capability and put them under the `/acrn-config/processors` node in the board XML. The added information can be divided into two categories. 1. The topology of CPUs like the following. Each thread (which is a leaf node in the topology) contains its addresses (i.e. CPU ID, APIC ID, x2APIC ID) and model identifiers (i.e. family, model, stepping IDs, core types and native model ID). <die id="0"> <core id="0x0"> <thread id="0x0"> <cpu_id>0</cpu_id> <apic_id>0x0</apic_id> <x2apic_id>0x0</x2apic_id> <family_id>0x6</family_id> <model_id>0x9e</model_id> <stepping_id>0x9</stepping_id> <core_type></core_type> <native_model_id></native_model_id> </thread> <thread id="0x1"> ... </thread> </core> <core id="0x1"> <thread id="0x2"> ... </thread> <thread id="0x3"> ... </thread> </core> <core id="0x2"> <thread id="0x4"> ... </thread> <thread id="0x5"> ... </thread> </core> <core id="0x3"> <thread id="0x6"> ... </thread> <thread id="0x7"> ... </thread> </core> </die> 2. The CPU models identified by the quadruple (family_id, model_id, core_type, native_model_id). Each model is described by its brandstring and capabilities, both of which are fetched from CPUID leaves. <model description="Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz"> <family_id>0x6</family_id> <model_id>0x9e</model_id> <core_type></core_type> <native_model_id></native_model_id> <capability id="sse3"/> <capability id="pclmulqdq"/> <capability id="dtes64"/> <capability id="monitor"/> ... </model> Tracked-On: #5922 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
4d3a765708
commit
3e3120d342
128
misc/config_tools/board_inspector/extractors/10-processors.py
Normal file
128
misc/config_tools/board_inspector/extractors/10-processors.py
Normal file
@ -0,0 +1,128 @@
|
||||
# Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
import logging
|
||||
import lxml.etree
|
||||
|
||||
from cpuparser import parse_cpuid
|
||||
from extractors.helpers import add_child, get_node
|
||||
|
||||
level_types = {
|
||||
1: "thread",
|
||||
2: "core",
|
||||
3: "module",
|
||||
4: "tile",
|
||||
5: "die",
|
||||
}
|
||||
|
||||
def get_online_cpu_ids():
|
||||
acc = list()
|
||||
with open("/sys/devices/system/cpu/online", "r") as f:
|
||||
line = f.read().strip()
|
||||
for r in line.split(","):
|
||||
if r.find("-") > 0:
|
||||
first, last = tuple(map(int, r.split("-")))
|
||||
acc.extend(range(first, last + 1))
|
||||
else:
|
||||
acc.append(int(r))
|
||||
return acc
|
||||
|
||||
def get_parent(processors_node, topo_level, topo_id):
|
||||
n = get_node(processors_node, f"//{topo_level}[@id='{topo_id}']")
|
||||
return n
|
||||
|
||||
def get_or_create_parent(processors_node, topo_level, topo_id):
|
||||
n = get_parent(processors_node, topo_level, topo_id)
|
||||
if n is None:
|
||||
n = lxml.etree.Element(topo_level)
|
||||
n.set("id", topo_id)
|
||||
return (n, True)
|
||||
return (n, False)
|
||||
|
||||
def extract_model(processors_node, cpu_id, family_id, model_id, core_type, native_model_id):
|
||||
n = get_node(processors_node, f"//model[family_id='{family_id}' and model_id='{model_id}' and core_type='{core_type}' and native_model_id='{native_model_id}']")
|
||||
if n is None:
|
||||
n = add_child(processors_node, "model")
|
||||
|
||||
add_child(n, "family_id", family_id)
|
||||
add_child(n, "model_id", model_id)
|
||||
add_child(n, "core_type", core_type)
|
||||
add_child(n, "native_model_id", native_model_id)
|
||||
|
||||
brandstring = b""
|
||||
for leaf in [0x80000002, 0x80000003, 0x80000004]:
|
||||
leaf_data = parse_cpuid(leaf, 0, cpu_id)
|
||||
brandstring += leaf_data.brandstring
|
||||
n.set("description", brandstring.decode())
|
||||
|
||||
leaves = [(1, 0), (7, 0), (0x80000001, 0), (0x80000007, 0)]
|
||||
for leaf in leaves:
|
||||
leaf_data = parse_cpuid(leaf[0], leaf[1], cpu_id)
|
||||
for cap in leaf_data.capability_bits:
|
||||
if getattr(leaf_data, cap) == 1:
|
||||
add_child(n, "capability", id=cap)
|
||||
|
||||
def extract_topology(processors_node):
|
||||
cpu_ids = get_online_cpu_ids()
|
||||
for cpu_id in cpu_ids:
|
||||
subleaf = 0
|
||||
last_shift = 0
|
||||
last_node = None
|
||||
|
||||
leaf_0 = parse_cpuid(0, 0, cpu_id)
|
||||
if leaf_0.max_leaf >= 0x1f:
|
||||
topo_leaf = 0x1f
|
||||
else:
|
||||
topo_leaf = 0xb
|
||||
|
||||
while True:
|
||||
leaf_topo = parse_cpuid(topo_leaf, subleaf, cpu_id)
|
||||
if leaf_topo.level_type == 0:
|
||||
if last_node.tag != "package":
|
||||
n, _ = get_or_create_parent(processors_node, "die", "0")
|
||||
n.append(last_node)
|
||||
last_node = n
|
||||
processors_node.append(last_node)
|
||||
break
|
||||
|
||||
topo_level = level_types[leaf_topo.level_type]
|
||||
topo_id = hex(leaf_topo.x2apic_id >> last_shift)
|
||||
n, created = get_or_create_parent(processors_node, topo_level, topo_id)
|
||||
|
||||
if last_node is None:
|
||||
leaf_1 = parse_cpuid(1, 0, cpu_id)
|
||||
family_id = hex(leaf_1.display_family)
|
||||
model_id = hex(leaf_1.display_model)
|
||||
if leaf_0.max_leaf >= 0x1a:
|
||||
leaf_1a = parse_cpuid(0x1a, 0, cpu_id)
|
||||
core_type = leaf_1a.core_type
|
||||
native_model_id = hex(leaf_1a.native_model_id)
|
||||
else:
|
||||
core_type = ""
|
||||
native_model_id = ""
|
||||
|
||||
add_child(n, "cpu_id", text=str(cpu_id))
|
||||
add_child(n, "apic_id", text=hex(leaf_1.initial_apic_id))
|
||||
add_child(n, "x2apic_id", text=hex(leaf_topo.x2apic_id))
|
||||
add_child(n, "family_id", text=family_id)
|
||||
add_child(n, "model_id", text=model_id)
|
||||
add_child(n, "stepping_id", text=hex(leaf_1.stepping))
|
||||
add_child(n, "core_type", text=core_type)
|
||||
add_child(n, "native_model_id", text=native_model_id)
|
||||
|
||||
extract_model(processors_node, cpu_id, family_id, model_id, core_type, native_model_id)
|
||||
else:
|
||||
n.append(last_node)
|
||||
|
||||
if not created:
|
||||
break
|
||||
|
||||
last_node = n
|
||||
last_shift = leaf_topo.num_bit_shift
|
||||
subleaf += 1
|
||||
|
||||
def extract(board_etree):
|
||||
processors_node = get_node(board_etree, "//processors")
|
||||
extract_topology(processors_node)
|
Loading…
Reference in New Issue
Block a user