Skip to content

Commit

Permalink
adt: format phandles using target node path
Browse files Browse the repository at this point in the history
Signed-off-by: Alba Mendez <[email protected]>
  • Loading branch information
mildsunrise committed Nov 2, 2024
1 parent 282ac4f commit 799944f
Showing 1 changed file with 52 additions and 6 deletions.
58 changes: 52 additions & 6 deletions proxyclient/m1n1/adt.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,23 @@ def build_prop(path, name, v, t=None):

return t.build(v)

PHANDLE_PROPS = {
'AAPL,phandle',
'interrupt-parent',
'iommu-parent',
'dma-parent',
'hdcp-parent',
'external-power-provider',

'atc-phy-parent',
'atc-phy',
'acio-parent',

'dp2hdmi-gpio-parent',
'dock',
'audio',
}

class ADTNode:
def __init__(self, val=None, path="/", parent=None):
self._children = []
Expand Down Expand Up @@ -642,13 +659,15 @@ def interrupt_cells(self):
except KeyError:
raise AttributeError("#interrupt-cells")

def _fmt_prop(self, k, v):
def _fmt_prop(self, k, v, fmt_phandle=None):
t, is_template = self._types.get(k, (None, False))
if is_template:
return f"<< {v} >>"
elif k == 'reg' and isinstance(v, ListContainer) and all(isinstance(x, Container) for x in v):
fmt_value = lambda n: f'{n:#018x}' if isinstance(n, int) else ' '.join(f'{x:#010x}' for x in n)
return "\n".join(["[", *(f" (addr = {fmt_value(x.addr)}, size = {fmt_value(x.size)})," for x in v), "]"])
elif k in PHANDLE_PROPS:
return fmt_phandle(v, self) if fmt_phandle else f'@{v!r}'
elif isinstance(v, ListContainer):
vs = [self._fmt_prop((k, i), x) for i, x in enumerate(v)]
if any(('\n' in v) for v in vs) or (len(vs) > 1 and max(map(len, vs)) > 20):
Expand All @@ -670,14 +689,15 @@ def _fmt_prop(self, k, v):
b = arg.to_bytes(4, "big")
is_ascii = all(0x20 <= c <= 0x7e for c in b)
args.append(f"{arg:#x}" if not is_ascii else f"'{b.decode('ascii')}'")
return f"{v.phandle}:{v.name}({', '.join(args)})"
phandle = fmt_phandle(v.phandle, self) if fmt_phandle else f'@{v!r}'
return f"{phandle}:{repr(v.name)[1:-1]}({', '.join(args)})"
name.startswith("function-")
elif isinstance(v, str):
return repr(v)
else:
return str(v)

def __str__(self, t="", sort_keys=False, sort_nodes=False):
def __str__(self, t="", sort_keys=False, sort_nodes=False, fmt_phandle=None):
props = self._properties.items()
if sort_keys:
props = sorted(props)
Expand All @@ -686,9 +706,9 @@ def __str__(self, t="", sort_keys=False, sort_nodes=False):
children = sorted(children, key=lambda n: n.name)
return "\n".join([
t + f"{self.name} {{",
*(t + f" {repr(k)[1:-1]} = {self._fmt_prop(k, v).replace('\n', '\n'+t+' ')}" for k, v in props if k != "name"),
*(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"),
*([""] if self._children else []),
*(i.__str__(t + " ", sort_keys, sort_nodes) for i in children),
*(i.__str__(t + " ", sort_keys, sort_nodes, fmt_phandle) for i in children),
t + "}"
])

Expand Down Expand Up @@ -775,6 +795,22 @@ def walk_tree(self):
for child in self:
yield from child.walk_tree()

def build_phandle_lookup(self, verify_continuity=False, last_phandle=0):
phandles = {}
for node in self.walk_tree():
if 'AAPL,phandle' not in node._properties:
continue
ph = node._properties['AAPL,phandle']

assert isinstance(ph, int) and (ph not in phandles)
phandles[ph] = node

if verify_continuity:
assert ph == last_phandle + 1
last_phandle = ph

return phandles

def build_addr_lookup(self):
lookup = AddrLookup()
for node in self.walk_tree():
Expand Down Expand Up @@ -833,7 +869,17 @@ def load_adt(data):
adt_data = args.input.read_bytes()

adt = load_adt(adt_data)
print(adt.__str__(sort_keys=args.sort_keys, sort_nodes=args.sort_nodes))
phandles = adt.build_phandle_lookup(verify_continuity=True)
# since we'll refer to nodes by their path, make sure paths are unique
for node in adt.walk_tree():
assert '/' not in node.name
assert len(set(n.name for n in node)) == len(node._children)
def fmt_phandle(ph, context):
if isinstance(ph, int) and ph in phandles:
ph = phandles[ph]._path
return f"@{ph!r}"

print(adt.__str__(sort_keys=args.sort_keys, sort_nodes=args.sort_nodes, fmt_phandle=fmt_phandle))
new_data = adt.build()
if args.output is not None:
args.output.write_bytes(new_data)
Expand Down

0 comments on commit 799944f

Please sign in to comment.