From 90c2df4a7ea9068a4697ee6e47ef251f8a5dad8a Mon Sep 17 00:00:00 2001 From: "Yang,Yu-chu" Date: Thu, 9 Dec 2021 14:06:43 -0800 Subject: [PATCH] config-tools: add 40-acpi-tables.py to board_inspector/extractors Add a new extractor 40-acpi-tables.py which extracts ioapics basic information such as: ioapic id, address, gsi base and gsi number. An example:
0xfec00000
0x0 240
Tracked-On: #6986 Signed-off-by: Yang,Yu-chu Reviewed-by: Junjie Mao Acked-by: Anthony Xu --- .../board_inspector/board_inspector.py | 1 + .../extractors/40-acpi-tables.py | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 misc/config_tools/board_inspector/extractors/40-acpi-tables.py diff --git a/misc/config_tools/board_inspector/board_inspector.py b/misc/config_tools/board_inspector/board_inspector.py index dbfd28650..41067d12b 100755 --- a/misc/config_tools/board_inspector/board_inspector.py +++ b/misc/config_tools/board_inspector/board_inspector.py @@ -74,6 +74,7 @@ def main(board_name, board_xml, args): root_node.append(lxml.etree.Element("processors")) root_node.append(lxml.etree.Element("caches")) root_node.append(lxml.etree.Element("memory")) + root_node.append(lxml.etree.Element("ioapics")) root_node.append(lxml.etree.Element("devices")) extractors_path = os.path.join(script_dir, "extractors") diff --git a/misc/config_tools/board_inspector/extractors/40-acpi-tables.py b/misc/config_tools/board_inspector/extractors/40-acpi-tables.py new file mode 100644 index 000000000..0eec06c03 --- /dev/null +++ b/misc/config_tools/board_inspector/extractors/40-acpi-tables.py @@ -0,0 +1,59 @@ +# Copyright (C) 2021 Intel Corporation. +# +# SPDX-License-Identifier: BSD-3-Clause +# + + +import logging +import re, os, fcntl, errno +import lxml.etree +from extractors.helpers import add_child, get_node + +from acpiparser import parse_apic, apic + +DEFAULT_MAX_IOAPIC_LINES = 240 + +def extract_gsi_number(ioapic_node, apic_id): + f = open("/dev/kmsg", 'r') + fd = os.dup(f.fileno()) + f.close() + + ret = fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) + if ret != 0: + os.close(fd) + add_child(ioapic_node, "gsi_number", DEFAULT_MAX_IOAPIC_LINES) + return + + while True: + try: + line = os.read(fd, 512).decode("utf-8") + m = re.match(r"\s*\d+,\d+,\d+,-;IOAPIC\[[\d+]\]:\s+apic_id\s+{},\s+version\s+\d+,\s+address\s+0x[0-9a-f]+,\s+GSI\s+(\d+)-(\d+)".format(apic_id), line) + if m: + previous_max = int(m.group(1)) + current_max = int(m.group(2)) + 1 + add_child(ioapic_node, "gsi_number", str(current_max - previous_max)) + break + except: + add_child(ioapic_node, "gsi_number", DEFAULT_MAX_IOAPIC_LINES) + break + os.close(fd) + +def extract_topology(ioapics_node, tables): + for subtable in tables.interrupt_controller_structures: + if subtable.subtype == apic.MADT_TYPE_IO_APIC: + apic_id = subtable.io_apic_id + ioapic_node = add_child(ioapics_node, "ioapic", None, id=hex(apic_id)) + add_child(ioapic_node, "address", hex(subtable.io_apic_addr)) + add_child(ioapic_node, "gsi_base", hex(subtable.global_sys_int_base)) + extract_gsi_number(ioapic_node, apic_id) + +def extract(args, board_etree): + try: + tables = parse_apic() + except Exception as e: + logging.warning(f"Parse ACPI tables failed: {str(e)}") + logging.warning(f"Will not extract information from ACPI tables") + return + + ioapics_node = get_node(board_etree, "//ioapics") + extract_topology(ioapics_node, tables)