[PATCH v2 2/2] config-tools: add topology extract_display


Yang, Yu-chu
 

From: "Yang,Yu-chu" <yu-chu.yang@...>

This mothod get connected displays and add them as child nodes to
a corresponding graphics card.

v1->v2
1. refine the exception in extract_display
2. add full name of HDMI and VGA
3. use defaultdict for default value of display_ids

Tracked-On: #7970
Signed-off-by: Yang,Yu-chu <yu-chu.yang@...>
---
.../extractors/70-device-classes.py | 51 +++++++++++++++++--
.../board_inspector/extractors/90-sorting.py | 3 +-
2 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/misc/config_tools/board_inspector/extractors/70-device-classes.py b/misc/config_tools/board_inspector/extractors/70-device-classes.py
index dbd50519e..ad8470fb7 100644
--- a/misc/config_tools/board_inspector/extractors/70-device-classes.py
+++ b/misc/config_tools/board_inspector/extractors/70-device-classes.py
@@ -5,10 +5,14 @@

import re, os
import logging
-from extractors.helpers import add_child, get_node
+
+from extractors.helpers import add_child, get_node, get_bdf_from_realpath
+from collections import defaultdict
+from pathlib import Path

SYS_INPUT_DEVICES_CLASS_PATH = "/sys/class/input/"
SYS_TTY_DEVICES_CLASS_PATH = "/sys/class/tty/"
+SYS_DISPLAYS_INFO_PATH = "/sys/class/drm/"

def add_child_with_file_contents(parent_node, tag, filepath, translations = {}):
try:
@@ -48,10 +52,51 @@ def extract_ttys(device_classes_node):
add_child(serial_node, "dev_path", f"/dev/{serial_dev}")
add_child_with_file_contents(serial_node, "type", f"{SYS_TTY_DEVICES_CLASS_PATH}{serial_dev}/type")

-def extract_topology(device_classes_node):
+def extract_display(board_etree):
+ display_regex = re.compile("(card[0-9])-(DP|HDMI|VGA)-.*")
+ display_types = {
+ "DP": "display port",
+ "HDMI": "High Definition Multimedia Interface",
+ "VGA": "Video Graphics Array",
+ }
+ display_ids = defaultdict(lambda: 0)
+ for root in filter(lambda x: x.startswith("card"), os.listdir(SYS_DISPLAYS_INFO_PATH)):
+ displays_path = SYS_DISPLAYS_INFO_PATH + root
+ status_path = f"{displays_path}/status"
+ device_path = f"{displays_path }/device/device"
+ m = display_regex.match(root)
+ if m:
+ try:
+ assert Path(status_path).exists(), \
+ f"{status_path} does not exist, {root} connection status is unknown. {root} information " \
+ "is not added to board configuration file."
+ assert Path(device_path).exists(), \
+ f"{device_path} does not exist, the graphics card which {root} is connected to cannot be detected. " \
+ f"Failed to add {root} information to board configuration file."
+ with open(f"{status_path}", "r") as f:
+ if f.read().strip() == "connected":
+ bus, device, function = \
+ get_bdf_from_realpath(f"{device_path}")
+ adr = hex((device << 16) + function)
+ bus_node = get_node(board_etree, f"//bus[@type='pci' and @address='{hex(bus)}']")
+ if bus_node is None:
+ devices_node = get_node(board_etree, "//devices")
+ bus_node = add_child(devices_node, "bus", type="pci", address=hex(bus))
+ device_node = get_node(bus_node, f"./device[@address='{adr}']")
+ if device_node is None:
+ device_node = add_child(bus_node, "device", None, address=adr)
+ bdf = (bus, device, function)
+ display_id = display_ids[bdf]
+ add_child(device_node, "display", f"{display_id}", type=display_types[m.group(2)])
+ display_ids[bdf] += 1
+ except Exception as e:
+ logging.warning(f"{e}")
+
+def extract_topology(device_classes_node, board_etree):
extract_inputs(device_classes_node)
extract_ttys(device_classes_node)
+ extract_display(board_etree)

def extract(args, board_etree):
device_classes_node = get_node(board_etree, "//device-classes")
- extract_topology(device_classes_node)
+ extract_topology(device_classes_node, board_etree)
diff --git a/misc/config_tools/board_inspector/extractors/90-sorting.py b/misc/config_tools/board_inspector/extractors/90-sorting.py
index 480482041..49c3c0708 100644
--- a/misc/config_tools/board_inspector/extractors/90-sorting.py
+++ b/misc/config_tools/board_inspector/extractors/90-sorting.py
@@ -28,7 +28,8 @@ def getkey(child):

tags = ["vendor", "identifier", "subsystem_vendor", "subsystem_identifier", "class",
"acpi_object", "compatible_id", "acpi_uid", "aml_template", "status",
- "resource", "capability", "interrupt_pin_routing", "dependency", "bus", "device", "physfn"]
+ "resource", "capability", "interrupt_pin_routing", "dependency", "bus", "device",
+ "physfn", "display"]

if child.tag == "resource":
return (tags.index(child.tag), child.get("type"), resource_subkey(child))
--
2.25.1


Junjie Mao
 

-----Original Message-----
From: Yang, Yu-chu <yu-chu.yang@...>
Sent: Thursday, October 13, 2022 5:18 AM
To: acrn-dev@...
Cc: Mao, Junjie <junjie.mao@...>
Subject: [PATCH v2 2/2] config-tools: add topology extract_display

From: "Yang,Yu-chu" <yu-chu.yang@...>

This mothod get connected displays and add them as child nodes to
a corresponding graphics card.

v1->v2
1. refine the exception in extract_display
2. add full name of HDMI and VGA
3. use defaultdict for default value of display_ids

Tracked-On: #7970
Signed-off-by: Yang,Yu-chu <yu-chu.yang@...>
---
.../extractors/70-device-classes.py | 51 +++++++++++++++++--
.../board_inspector/extractors/90-sorting.py | 3 +-
2 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/misc/config_tools/board_inspector/extractors/70-device-classes.py
b/misc/config_tools/board_inspector/extractors/70-device-classes.py
index dbd50519e..ad8470fb7 100644
--- a/misc/config_tools/board_inspector/extractors/70-device-classes.py
+++ b/misc/config_tools/board_inspector/extractors/70-device-classes.py
@@ -5,10 +5,14 @@

import re, os
import logging
-from extractors.helpers import add_child, get_node
+
+from extractors.helpers import add_child, get_node, get_bdf_from_realpath
+from collections import defaultdict
+from pathlib import Path

SYS_INPUT_DEVICES_CLASS_PATH = "/sys/class/input/"
SYS_TTY_DEVICES_CLASS_PATH = "/sys/class/tty/"
+SYS_DISPLAYS_INFO_PATH = "/sys/class/drm/"

def add_child_with_file_contents(parent_node, tag, filepath, translations = {}):
try:
@@ -48,10 +52,51 @@ def extract_ttys(device_classes_node):
add_child(serial_node, "dev_path", f"/dev/{serial_dev}")
add_child_with_file_contents(serial_node, "type",
f"{SYS_TTY_DEVICES_CLASS_PATH}{serial_dev}/type")

-def extract_topology(device_classes_node):
+def extract_display(board_etree):
+ display_regex = re.compile("(card[0-9])-(DP|HDMI|VGA)-.*")
+ display_types = {
+ "DP": "display port",
Please be consistent on the usage of upper cases. For DP, you may want to use "DisplayPort (DP)" (note that there is no space between "Display" and "Port" in its offical name).

+ "HDMI": "High Definition Multimedia Interface",
I suggest to also include the acronym for better readability, i.e., "High Definition Multimedia Interface (HDMI)".

+ "VGA": "Video Graphics Array",
Ditto.

+ }
+ display_ids = defaultdict(lambda: 0)
+ for root in filter(lambda x: x.startswith("card"),
os.listdir(SYS_DISPLAYS_INFO_PATH)):
+ displays_path = SYS_DISPLAYS_INFO_PATH + root
+ status_path = f"{displays_path}/status"
+ device_path = f"{displays_path }/device/device"
Remove the unnecessary whitespace after `displays_path`.

+ m = display_regex.match(root)
+ if m:
+ try:
+ assert Path(status_path).exists(), \
+ f"{status_path} does not exist, {root} connection status is unknown.
{root} information " \
+ "is not added to board configuration file."
That sentence looks strange to me grammatically.

Also the official name is "board XML file" or "board XML". We do not have any file named "board configuration".

+ assert Path(device_path).exists(), \
+ f"{device_path} does not exist, the graphics card which {root} is
connected to cannot be detected. " \
+ f"Failed to add {root} information to board configuration file."
Ditto.

---
Best Regards
Junjie Mao

+ with open(f"{status_path}", "r") as f:
+ if f.read().strip() == "connected":
+ bus, device, function = \
+ get_bdf_from_realpath(f"{device_path}")
+ adr = hex((device << 16) + function)
+ bus_node = get_node(board_etree, f"//bus[@type='pci' and
@address='{hex(bus)}']")
+ if bus_node is None:
+ devices_node = get_node(board_etree, "//devices")
+ bus_node = add_child(devices_node, "bus", type="pci",
address=hex(bus))
+ device_node = get_node(bus_node, f"./device[@address='{adr}']")
+ if device_node is None:
+ device_node = add_child(bus_node, "device", None, address=adr)
+ bdf = (bus, device, function)
+ display_id = display_ids[bdf]
+ add_child(device_node, "display", f"{display_id}",
type=display_types[m.group(2)])
+ display_ids[bdf] += 1
+ except Exception as e:
+ logging.warning(f"{e}")
+
+def extract_topology(device_classes_node, board_etree):
extract_inputs(device_classes_node)
extract_ttys(device_classes_node)
+ extract_display(board_etree)

def extract(args, board_etree):
device_classes_node = get_node(board_etree, "//device-classes")
- extract_topology(device_classes_node)
+ extract_topology(device_classes_node, board_etree)
diff --git a/misc/config_tools/board_inspector/extractors/90-sorting.py
b/misc/config_tools/board_inspector/extractors/90-sorting.py
index 480482041..49c3c0708 100644
--- a/misc/config_tools/board_inspector/extractors/90-sorting.py
+++ b/misc/config_tools/board_inspector/extractors/90-sorting.py
@@ -28,7 +28,8 @@ def getkey(child):

tags = ["vendor", "identifier", "subsystem_vendor", "subsystem_identifier", "class",
"acpi_object", "compatible_id", "acpi_uid", "aml_template", "status",
- "resource", "capability", "interrupt_pin_routing", "dependency", "bus",
"device", "physfn"]
+ "resource", "capability", "interrupt_pin_routing", "dependency", "bus",
"device",
+ "physfn", "display"]

if child.tag == "resource":
return (tags.index(child.tag), child.get("type"), resource_subkey(child))
--
2.25.1