From d66c62aad1db1dc71f4e959a867200e8336b1e6d Mon Sep 17 00:00:00 2001 From: Junjie Mao Date: Wed, 4 Aug 2021 14:44:06 +0800 Subject: [PATCH] board_inspector: scanning all peer root hostbridges in domain 0 Servers typically have multiple peer host bridges that need to be scanned separately. This patch extends the PCI information extractor to visit all PCI host bridges by enumerating /sys/devices/pci* directories. Tracked-On: #6292 Signed-off-by: Junjie Mao --- .../board_inspector/extractors/50-acpi.py | 9 ++++++ .../board_inspector/extractors/60-pci.py | 31 ++++++++++--------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/misc/config_tools/board_inspector/extractors/50-acpi.py b/misc/config_tools/board_inspector/extractors/50-acpi.py index b7653680f..b5478a164 100644 --- a/misc/config_tools/board_inspector/extractors/50-acpi.py +++ b/misc/config_tools/board_inspector/extractors/50-acpi.py @@ -468,6 +468,15 @@ def fetch_device_info(devices_node, interpreter, namepath): element.set("address", hex(adr) if isinstance(adr, int) else adr) add_object_to_device(interpreter, namepath, "_ADR", result) + # Bus number that overrides _ADR when exists + if interpreter.context.has_symbol(f"{namepath}._BBN"): + result = interpreter.interpret_method_call(f"{namepath}._BBN") + bus_number = result.get() + if isinstance(bus_number, int): + bus_number = hex(bus_number) + element.set("address", bus_number) + add_object_to_device(interpreter, namepath, "_BBN", result) + # Status if sta is not None: status = add_child(element, "status") diff --git a/misc/config_tools/board_inspector/extractors/60-pci.py b/misc/config_tools/board_inspector/extractors/60-pci.py index 7a0106f3d..6cbc8ef4a 100644 --- a/misc/config_tools/board_inspector/extractors/60-pci.py +++ b/misc/config_tools/board_inspector/extractors/60-pci.py @@ -12,6 +12,7 @@ from pcieparser import parse_config_space from pcieparser.header import IOBar, MemoryBar32, MemoryBar64 from extractors.helpers import add_child, get_node +SYS_DEVICES_PATH = "/sys/devices" PCI_ROOT_PATH = "/sys/devices/pci0000:00" bdf_regex = re.compile(r"^([0-9a-f]{4}):([0-9a-f]{2}):([0-9a-f]{2}).([0-7]{1})$") @@ -22,11 +23,11 @@ interrupt_pin_names = { 4: "INTD#", } -def collect_hostbridge_resources(bus_node): +def collect_hostbridge_resources(bus_node, bus_number): with open("/proc/iomem", "r") as f: for line in f.readlines(): fields = line.strip().split(" : ") - if fields[1] == "PCI Bus 0000:00": + if fields[1] == f"PCI Bus 0000:{bus_number:02x}": begin, end = tuple(map(lambda x: int(f"0x{x}", base=16), fields[0].split("-"))) add_child(bus_node, "resource", type="memory", min=hex(begin), max=hex(end), len=hex(end - begin + 1)) @@ -182,16 +183,16 @@ def enum_devices(bus_node, root_path): enum_devices(device_node, p) def extract(board_etree): - bus_node = get_node(board_etree, "//bus[@type='pci']") - if bus_node is None: - devices_node = get_node(board_etree, "//devices") - bus_node = add_child(devices_node, "bus", type="pci", address="0x0") - collect_hostbridge_resources(bus_node) - else: - # Assume there is only one device object in the ACPI DSDT that represents a PCI bridge (which should be the host - # bridge in this case). If the ACPI table does not provide an _ADR object, add the default address of the host - # bridge (i.e. bus 0). - if bus_node.get("address") is None: - bus_node.set("address", "0x0") - - enum_devices(bus_node, PCI_ROOT_PATH) + # 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})") + for root in filter(lambda x: x.startswith("pci"), os.listdir(SYS_DEVICES_PATH)): + m = root_regex.match(root) + if m: + bus_number = int(m.group(1), 16) + bus_node = get_node(board_etree, f"//bus[@type='pci' and @address='{hex(bus_number)}']") + if bus_node is None: + devices_node = get_node(board_etree, "//devices") + bus_node = add_child(devices_node, "bus", type="pci", address=hex(bus_number)) + collect_hostbridge_resources(bus_node, bus_number) + enum_devices(bus_node, os.path.join(SYS_DEVICES_PATH, root))