board_inspector: make filtering by device status optional

It is witnessed on some boards that the device status (as is reported by
the _STA object) returns 0 while the device object is still useful for
pass-through devices. The original implementation, however, assumes that
only a device is a non-zero status is useful as long as the _STA object
exists.

This patch makes this filtering disabled by default and adds a command-line
argument `--check-device-status` to enable this filtering. As disabled or
non-present devices can have empty resources, the sorting algorithm is
updated accordingly to gracefully handle such descriptors.

This patch is added in v3 of the series.

Tracked-On: #6287
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
Junjie Mao 2021-08-05 15:37:42 +08:00 committed by wenlingz
parent 5d44640515
commit 3b41713c7e
8 changed files with 17 additions and 12 deletions

View File

@ -56,7 +56,7 @@ def main(board_name, board_xml, args):
module = import_module(f"extractors.{module_name}")
if not args.advanced and getattr(module, "advanced", False):
continue
module.extract(board_etree)
module.extract(args, board_etree)
# Finally overwrite the output with the updated XML
board_etree.write(board_xml, pretty_print=True)
@ -71,6 +71,7 @@ if __name__ == "__main__":
parser.add_argument("--out", help="the name of board info file")
parser.add_argument("--advanced", action="store_true", default=False, help="extract advanced information such as ACPI namespace")
parser.add_argument("--loglevel", default="warning", help="choose log level, e.g. info, warning or error")
parser.add_argument("--check-device-status", action="store_true", default=False, help="filter out devices whose _STA object evaluates to 0")
args = parser.parse_args()
try:
logging.basicConfig(level=args.loglevel.upper())

View File

@ -111,6 +111,6 @@ def extract_topology(processors_node):
last_shift = leaf_topo.num_bit_shift
subleaf += 1
def extract(board_etree):
def extract(args, board_etree):
processors_node = get_node(board_etree, "//processors")
extract_topology(processors_node)

View File

@ -95,7 +95,7 @@ def extract_tcc_capabilities(caches_node):
except FileNotFoundError:
pass
def extract(board_etree):
def extract(args, board_etree):
root_node = board_etree.getroot()
caches_node = get_node(board_etree, "//caches")
extract_topology(root_node, caches_node)

View File

@ -18,6 +18,6 @@ def extract_layout(memory_node):
size = e820_entry.end - e820_entry.start + 1
add_child(memory_node, "range", start=start, end=end, size=str(size))
def extract(board_etree):
def extract(args, board_etree):
memory_node = get_node(board_etree, "//memory")
extract_layout(memory_node)

View File

@ -379,7 +379,7 @@ def add_object_to_device(interpreter, device_path, obj_name, result):
except NotImplementedError as e:
logging.info(f"{device_path}.{obj_name}: will not be added to vACPI, reason: {str(e)}")
def fetch_device_info(devices_node, interpreter, namepath):
def fetch_device_info(devices_node, interpreter, namepath, args):
logging.info(f"Fetch information about device object {namepath}")
try:
@ -393,7 +393,7 @@ def fetch_device_info(devices_node, interpreter, namepath):
if interpreter.context.has_symbol(f"{namepath}._STA"):
result = interpreter.interpret_method_call(f"{namepath}._STA")
sta = result.get()
if sta & 0x1 == 0:
if args.check_device_status and sta & 0x1 == 0:
return
add_object_to_device(interpreter, namepath, "_STA", result)
@ -532,7 +532,7 @@ def fetch_device_info(devices_node, interpreter, namepath):
except FutureWork:
pass
def extract(board_etree):
def extract(args, board_etree):
devices_node = get_node(board_etree, "//devices")
try:
@ -553,7 +553,7 @@ def extract(board_etree):
for device in sorted(namespace.devices, key=lambda x:x.name):
try:
fetch_device_info(devices_node, interpreter, device.name)
fetch_device_info(devices_node, interpreter, device.name, args)
except Exception as e:
logging.info(f"Fetch information about device object {device.name} failed: {str(e)}")

View File

@ -182,7 +182,7 @@ def enum_devices(bus_node, root_path):
device_node = parse_device(bus_node, p)
enum_devices(device_node, p)
def extract(board_etree):
def extract(args, board_etree):
# Assume we only care about PCI devices under domain 0, as the hypervisor only uses BDF (without domain) for device
# identification.
root_regex = re.compile("pci0000:([0-9a-f]{2})")

View File

@ -125,5 +125,5 @@ def lookup_pci_devices(board_etree):
else:
logging.info(f"Cannot find pci.ids under /usr/share. PCI device names will not be available.")
def extract(board_etree):
def extract(args, board_etree):
lookup_pci_devices(board_etree)

View File

@ -11,7 +11,11 @@ def getkey(child):
if typ in ["memory", "io_port"]:
return int(node.get("min"), base=16)
elif typ == "irq":
return int(node.get("int").split(", ")[0])
first_irq = node.get("int").split(", ")[0]
if first_irq:
return int(node.get("int").split(", ")[0])
else:
return 0
else:
return 0
@ -33,7 +37,7 @@ def getkey(child):
else:
return (tags.index(child.tag),)
def extract(board_etree):
def extract(args, board_etree):
# Sort children of bus and device nodes
bus_nodes = board_etree.xpath("//bus")
for bus_node in bus_nodes: