diff --git a/misc/config_tools/board_inspector/extractors/50-acpi.py b/misc/config_tools/board_inspector/extractors/50-acpi.py index cd7bd7b7f..1ed76a8a9 100644 --- a/misc/config_tools/board_inspector/extractors/50-acpi.py +++ b/misc/config_tools/board_inspector/extractors/50-acpi.py @@ -8,13 +8,19 @@ import lxml.etree from collections import defaultdict from acpiparser import parse_dsdt, parse_resource_data, parse_pci_routing +from acpiparser.aml.tree import Visitor, Direction +import acpiparser.aml.builder as builder import acpiparser.aml.context as context +import acpiparser.aml.datatypes as datatypes from acpiparser.aml.interpreter import ConcreteInterpreter from acpiparser.aml.exception import UndefinedSymbol, FutureWork +from acpiparser.aml.visitors import GenerateBinaryVisitor from acpiparser.rdt import * from extractors.helpers import add_child, get_node +device_objects = defaultdict(lambda: {}) + def parse_eisa_id(eisa_id): chars = [ (eisa_id & 0x7c) >> 2, # Bit 6:2 of the first byte @@ -111,6 +117,14 @@ resource_parsers = { (1, LARGE_RESOURCE_ITEM_EXTENDED_ADDRESS_SPACE): parse_address_space_resource, } +def add_object_to_device(context, device_path, obj_name, result): + if not obj_name in device_objects[device_path].keys(): + tree = builder.build_value(result) + if tree: + device_objects[device_path][obj_name] = builder.DefName(obj_name, tree) + else: + logging.warning(f"{device_path}.{obj_name}: will not added to vACPI due to unrecognized type: {result.__class__.__name__}") + def fetch_device_info(devices_node, interpreter, namepath): logging.info(f"Fetch information about device object {namepath}") @@ -123,14 +137,17 @@ def fetch_device_info(devices_node, interpreter, namepath): sta = None if interpreter.context.has_symbol(f"{namepath}._STA"): - sta = interpreter.interpret_method_call(f"{namepath}._STA").get() + result = interpreter.interpret_method_call(f"{namepath}._STA") + sta = result.get() if sta & 0x1 == 0: return + add_object_to_device(interpreter.context, namepath, "_STA", result) # Hardware ID hid = "" if interpreter.context.has_symbol(f"{namepath}._HID"): - hid = interpreter.interpret_method_call(f"{namepath}._HID").get() + result = interpreter.interpret_method_call(f"{namepath}._HID") + hid = result.get() if isinstance(hid, str): pass elif isinstance(hid, int): @@ -141,6 +158,7 @@ def fetch_device_info(devices_node, interpreter, namepath): hid = hex(hid) else: hid = "" + add_object_to_device(interpreter.context, namepath, "_HID", result) # Compatible ID cids = [] @@ -169,20 +187,32 @@ def fetch_device_info(devices_node, interpreter, namepath): for cid in cids: add_child(element, "compatible_id", cid) + # Unique ID + uid = "" + if interpreter.context.has_symbol(f"{namepath}._UID"): + result = interpreter.interpret_method_call(f"{namepath}._UID") + uid = result.get() + add_child(element, "acpi_uid", str(uid)) + add_object_to_device(interpreter.context, namepath, "_UID", result) + # Description if interpreter.context.has_symbol(f"{namepath}._STR"): - desc = interpreter.interpret_method_call(f"{namepath}._STR").get().decode(encoding="utf-16").strip("\00") + result = interpreter.interpret_method_call(f"{namepath}._STR") + desc = result.get().decode(encoding="utf-16").strip("\00") element.set("description", desc) + add_object_to_device(interpreter.context, namepath, "_STR", result) # Address if interpreter.context.has_symbol(f"{namepath}._ADR"): - adr = interpreter.interpret_method_call(f"{namepath}._ADR").get() + result = interpreter.interpret_method_call(f"{namepath}._ADR") + adr = result.get() if isinstance(adr, int): adr = hex(adr) if len(element.xpath(f"../*[@address='{adr}']")) > 0: logging.info(f"{namepath} has siblings with duplicated address {adr}.") else: element.set("address", hex(adr) if isinstance(adr, int) else adr) + add_object_to_device(interpreter.context, namepath, "_ADR", result) # Status if sta is not None: @@ -194,7 +224,8 @@ def fetch_device_info(devices_node, interpreter, namepath): # Resources if interpreter.context.has_symbol(f"{namepath}._CRS"): - data = interpreter.interpret_method_call(f"{namepath}._CRS").get() + result = interpreter.interpret_method_call(f"{namepath}._CRS") + data = result.get() rdt = parse_resource_data(data) for idx, item in enumerate(rdt.items): @@ -204,6 +235,8 @@ def fetch_device_info(devices_node, interpreter, namepath): else: add_child(element, "resource", type=item.__class__.__name__, id=f"res{idx}") + add_object_to_device(interpreter.context, namepath, "_CRS", result) + # PCI interrupt routing if interpreter.context.has_symbol(f"{namepath}._PRT"): pkg = interpreter.interpret_method_call(f"{namepath}._PRT") @@ -261,4 +294,14 @@ def extract(board_etree): except Exception as e: logging.info(f"Fetch information about device object {device.name} failed: {str(e)}") + visitor = GenerateBinaryVisitor() + for dev, objs in device_objects.items(): + element = get_node(devices_node, f"//device[acpi_object='{dev}']") + if element is not None: + tree = builder.DefDevice( + builder.PkgLength(), + dev, + builder.TermList(*list(objs.values()))) + add_child(element, "aml_template", visitor.generate(tree).hex()) + advanced = True diff --git a/misc/config_tools/board_inspector/extractors/90-sorting.py b/misc/config_tools/board_inspector/extractors/90-sorting.py index 82d485fc2..2d2cf7f8e 100644 --- a/misc/config_tools/board_inspector/extractors/90-sorting.py +++ b/misc/config_tools/board_inspector/extractors/90-sorting.py @@ -23,7 +23,7 @@ def getkey(child): return 0xFFFFFFFF tags = ["vendor", "identifier", "subsystem_vendor", "subsystem_identifier", "class", - "acpi_object", "compatible_id", "status", + "acpi_object", "compatible_id", "acpi_uid", "aml_template", "status", "resource", "capability", "interrupt_pin_routing", "bus", "device"] if child.tag == "resource":