From 7155646b22a9ef41100cdee18f39cf353810788a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 22 Jul 2023 21:43:53 -0600 Subject: dtoc: Make properties dirty when purging them Without the 'dirty' flag properties are not written back to the devicetree when synced. This means that new properties copied over to a node are not always written out. Fix this and add a test. Signed-off-by: Simon Glass --- tools/dtoc/fdt.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/dtoc/fdt.py') diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index fd0f3e94f5c..2589be990ae 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -272,6 +272,7 @@ class Prop: the FDT is synced """ self._offset = None + self.dirty = True class Node: """A device tree node -- cgit v1.2.3 From 8df8b6d670e299764e28f07cc9a607a4309e7c44 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 22 Jul 2023 21:43:54 -0600 Subject: dtoc: Add some debugging when copying nodes Show the operations being performed, when debugging is enabled. Convert a mistaken 'print' in test_copy_subnodes_from_phandles() while we are here. Signed-off-by: Simon Glass --- tools/dtoc/fdt.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools/dtoc/fdt.py') diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 2589be990ae..f6a9dee0db1 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -249,6 +249,7 @@ class Prop: """ if self.dirty: node = self._node + tout.debug(f'sync {node.path}: {self.name}') fdt_obj = node._fdt._fdt_obj node_name = fdt_obj.get_name(node._offset) if node_name and node_name != node.name: @@ -716,9 +717,13 @@ class Node: 'phandle' property is not copied since this might result in two nodes with the same phandle, thus making phandle references ambiguous. """ + tout.debug(f'copy to {self.path}: {src.path}') for name, src_prop in src.props.items(): + done = False if name != 'phandle' and name not in self.props: self.props[name] = Prop(self, None, name, src_prop.bytes) + done = True + tout.debug(f" {name}{'' if done else ' - ignored'}") def copy_node(self, src): """Copy a node and all its subnodes into this node -- cgit v1.2.3 From 589c2d9e514412aba4556d06ce3bdfb9c8800fa1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 22 Jul 2023 21:43:55 -0600 Subject: fdt: Allow copying phandles into templates Allow phandles to be copied over from a template. This can potentially cause duplicate phandles, so detect this and report an error. Signed-off-by: Simon Glass --- tools/dtoc/fdt.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'tools/dtoc/fdt.py') diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index f6a9dee0db1..5963925146a 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -337,6 +337,11 @@ class Node: self.props = self._fdt.GetProps(self) phandle = fdt_obj.get_phandle(self.Offset()) if phandle: + dup = self._fdt.phandle_to_node.get(phandle) + if dup: + raise ValueError( + f'Duplicate phandle {phandle} in nodes {dup.path} and {self.path}') + self._fdt.phandle_to_node[phandle] = self offset = fdt_obj.first_subnode(self.Offset(), QUIET_NOTFOUND) @@ -707,11 +712,12 @@ class Node: prop.Sync(auto_resize) return added - def merge_props(self, src): + def merge_props(self, src, copy_phandles): """Copy missing properties (except 'phandle') from another node Args: src (Node): Node containing properties to copy + copy_phandles (bool): True to copy phandle properties in nodes Adds properties which are present in src but not in this node. Any 'phandle' property is not copied since this might result in two nodes @@ -720,21 +726,24 @@ class Node: tout.debug(f'copy to {self.path}: {src.path}') for name, src_prop in src.props.items(): done = False - if name != 'phandle' and name not in self.props: - self.props[name] = Prop(self, None, name, src_prop.bytes) - done = True + if name not in self.props: + if copy_phandles or name != 'phandle': + self.props[name] = Prop(self, None, name, src_prop.bytes) + done = True tout.debug(f" {name}{'' if done else ' - ignored'}") - def copy_node(self, src): + def copy_node(self, src, copy_phandles=False): """Copy a node and all its subnodes into this node Args: src (Node): Node to copy + copy_phandles (bool): True to copy phandle properties in nodes Returns: Node: Resulting destination node - This works recursively. + This works recursively, with copy_phandles being set to True for the + recursive calls The new node is put before all other nodes. If the node already exists, just its subnodes and properties are copied, placing them before @@ -746,12 +755,12 @@ class Node: dst.move_to_first() else: dst = self.insert_subnode(src.name) - dst.merge_props(src) + dst.merge_props(src, copy_phandles) # Process in reverse order so that they appear correctly in the result, # since copy_node() puts the node first in the list for node in reversed(src.subnodes): - dst.copy_node(node) + dst.copy_node(node, True) return dst def copy_subnodes_from_phandles(self, phandle_list): @@ -774,7 +783,7 @@ class Node: dst = self.copy_node(node) tout.debug(f'merge props from {parent.path} to {dst.path}') - self.merge_props(parent) + self.merge_props(parent, False) class Fdt: @@ -835,6 +844,7 @@ class Fdt: TODO(sjg@chromium.org): Implement the 'root' parameter """ + self.phandle_to_node = {} self._cached_offsets = True self._root = self.Node(self, None, 0, '/', '/') self._root.Scan() -- cgit v1.2.3 From 288ae53cb73605500b7fc01e5919753c878466be Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 2 Aug 2023 09:23:13 -0600 Subject: binman: Add a temporary hack for duplicate phandles Three boards use a phandle in a FIT generator and the maintainer is away. For now, add a hack to allow this. Signed-off-by: Simon Glass --- tools/dtoc/fdt.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'tools/dtoc/fdt.py') diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 5963925146a..0b20d52f313 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -15,6 +15,9 @@ from libfdt import QUIET_NOTFOUND from u_boot_pylib import tools from u_boot_pylib import tout +# Temporary hack +IGNORE_DUP_PHANDLES = False + # This deals with a device tree, presenting it as an assortment of Node and # Prop objects, representing nodes and properties, respectively. This file # contains the base classes and defines the high-level API. You can use @@ -339,10 +342,11 @@ class Node: if phandle: dup = self._fdt.phandle_to_node.get(phandle) if dup: - raise ValueError( - f'Duplicate phandle {phandle} in nodes {dup.path} and {self.path}') - - self._fdt.phandle_to_node[phandle] = self + if not IGNORE_DUP_PHANDLES: + raise ValueError( + f'Duplicate phandle {phandle} in nodes {dup.path} and {self.path}') + else: + self._fdt.phandle_to_node[phandle] = self offset = fdt_obj.first_subnode(self.Offset(), QUIET_NOTFOUND) while offset >= 0: -- cgit v1.2.3