Skip to content

Commit 799944f

Browse files
committed
adt: format phandles using target node path
Signed-off-by: Alba Mendez <[email protected]>
1 parent 282ac4f commit 799944f

1 file changed

Lines changed: 52 additions & 6 deletions

File tree

proxyclient/m1n1/adt.py

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,23 @@ def build_prop(path, name, v, t=None):
489489

490490
return t.build(v)
491491

492+
PHANDLE_PROPS = {
493+
'AAPL,phandle',
494+
'interrupt-parent',
495+
'iommu-parent',
496+
'dma-parent',
497+
'hdcp-parent',
498+
'external-power-provider',
499+
500+
'atc-phy-parent',
501+
'atc-phy',
502+
'acio-parent',
503+
504+
'dp2hdmi-gpio-parent',
505+
'dock',
506+
'audio',
507+
}
508+
492509
class ADTNode:
493510
def __init__(self, val=None, path="/", parent=None):
494511
self._children = []
@@ -642,13 +659,15 @@ def interrupt_cells(self):
642659
except KeyError:
643660
raise AttributeError("#interrupt-cells")
644661

645-
def _fmt_prop(self, k, v):
662+
def _fmt_prop(self, k, v, fmt_phandle=None):
646663
t, is_template = self._types.get(k, (None, False))
647664
if is_template:
648665
return f"<< {v} >>"
649666
elif k == 'reg' and isinstance(v, ListContainer) and all(isinstance(x, Container) for x in v):
650667
fmt_value = lambda n: f'{n:#018x}' if isinstance(n, int) else ' '.join(f'{x:#010x}' for x in n)
651668
return "\n".join(["[", *(f" (addr = {fmt_value(x.addr)}, size = {fmt_value(x.size)})," for x in v), "]"])
669+
elif k in PHANDLE_PROPS:
670+
return fmt_phandle(v, self) if fmt_phandle else f'@{v!r}'
652671
elif isinstance(v, ListContainer):
653672
vs = [self._fmt_prop((k, i), x) for i, x in enumerate(v)]
654673
if any(('\n' in v) for v in vs) or (len(vs) > 1 and max(map(len, vs)) > 20):
@@ -670,14 +689,15 @@ def _fmt_prop(self, k, v):
670689
b = arg.to_bytes(4, "big")
671690
is_ascii = all(0x20 <= c <= 0x7e for c in b)
672691
args.append(f"{arg:#x}" if not is_ascii else f"'{b.decode('ascii')}'")
673-
return f"{v.phandle}:{v.name}({', '.join(args)})"
692+
phandle = fmt_phandle(v.phandle, self) if fmt_phandle else f'@{v!r}'
693+
return f"{phandle}:{repr(v.name)[1:-1]}({', '.join(args)})"
674694
name.startswith("function-")
675695
elif isinstance(v, str):
676696
return repr(v)
677697
else:
678698
return str(v)
679699

680-
def __str__(self, t="", sort_keys=False, sort_nodes=False):
700+
def __str__(self, t="", sort_keys=False, sort_nodes=False, fmt_phandle=None):
681701
props = self._properties.items()
682702
if sort_keys:
683703
props = sorted(props)
@@ -686,9 +706,9 @@ def __str__(self, t="", sort_keys=False, sort_nodes=False):
686706
children = sorted(children, key=lambda n: n.name)
687707
return "\n".join([
688708
t + f"{self.name} {{",
689-
*(t + f" {repr(k)[1:-1]} = {self._fmt_prop(k, v).replace('\n', '\n'+t+' ')}" for k, v in props if k != "name"),
709+
*(t + f" {repr(k)[1:-1]} = {self._fmt_prop(k, v, fmt_phandle).replace('\n', '\n'+t+' ')}" for k, v in props if k != "name"),
690710
*([""] if self._children else []),
691-
*(i.__str__(t + " ", sort_keys, sort_nodes) for i in children),
711+
*(i.__str__(t + " ", sort_keys, sort_nodes, fmt_phandle) for i in children),
692712
t + "}"
693713
])
694714

@@ -775,6 +795,22 @@ def walk_tree(self):
775795
for child in self:
776796
yield from child.walk_tree()
777797

798+
def build_phandle_lookup(self, verify_continuity=False, last_phandle=0):
799+
phandles = {}
800+
for node in self.walk_tree():
801+
if 'AAPL,phandle' not in node._properties:
802+
continue
803+
ph = node._properties['AAPL,phandle']
804+
805+
assert isinstance(ph, int) and (ph not in phandles)
806+
phandles[ph] = node
807+
808+
if verify_continuity:
809+
assert ph == last_phandle + 1
810+
last_phandle = ph
811+
812+
return phandles
813+
778814
def build_addr_lookup(self):
779815
lookup = AddrLookup()
780816
for node in self.walk_tree():
@@ -833,7 +869,17 @@ def load_adt(data):
833869
adt_data = args.input.read_bytes()
834870

835871
adt = load_adt(adt_data)
836-
print(adt.__str__(sort_keys=args.sort_keys, sort_nodes=args.sort_nodes))
872+
phandles = adt.build_phandle_lookup(verify_continuity=True)
873+
# since we'll refer to nodes by their path, make sure paths are unique
874+
for node in adt.walk_tree():
875+
assert '/' not in node.name
876+
assert len(set(n.name for n in node)) == len(node._children)
877+
def fmt_phandle(ph, context):
878+
if isinstance(ph, int) and ph in phandles:
879+
ph = phandles[ph]._path
880+
return f"@{ph!r}"
881+
882+
print(adt.__str__(sort_keys=args.sort_keys, sort_nodes=args.sort_nodes, fmt_phandle=fmt_phandle))
837883
new_data = adt.build()
838884
if args.output is not None:
839885
args.output.write_bytes(new_data)

0 commit comments

Comments
 (0)