mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-01 03:45:29 +00:00
board_inspector: add AML templates to board XML
This patch adds AML template (in XML hexBinary format) for each device to board XMLs. For now these templates contain the following objects if they exists in the physical DSDT: - Device identification objects: _ADR, _HID, _UID and _STR - _CRS which encodes the current resources consumed by the device - _STA which encodes the status of the device An AML template is always a DefScope with a single DefDevice so that they can be appended anywhere in the vDSDT. v1 -> v2: * Remove the temporary visitor that collects cross-device dependencies. Such check will be replaced with another visitor introduced in the next patch. v2 -> v3: * The AML templates are now DefDevice objects with their names being the full namepath. The vDSDT generator will take care of this and organize the objects properly. Tracked-On: #6287 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
6ccd7660a4
commit
52c3ed7e09
@ -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 = "<unknown>"
|
||||
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
|
||||
|
@ -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":
|
||||
|
Loading…
Reference in New Issue
Block a user