From d85d15fdfebd040e58bdf80e40ef09d67a8ac808 Mon Sep 17 00:00:00 2001 From: Moteen Shah Date: Fri, 16 May 2025 17:11:47 +0530 Subject: tools: binman: control.py: Propagate bootph-all/bootph-some-ram properties to supernodes As per bootph schema, bootph-* property in child node should be implied in their parent, but this feature is not implemented in the U-Boot proper stage (before relocation) resulting in devices not being bound because of the missing bootph-all or bootph-some-ram property in the parent node. To mitigate this issue, add a function to scan through all the nodes in the device-tree for bootph-all and bootph-some-ram properties. If found, propagate it to all of its parent nodes up the hierarchy. Signed-off-by: Moteen Shah Signed-off-by: Simon Glass Reviewed-by: Simon Glass Reviewed-by: Quentin Schulz --- tools/binman/control.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tools/binman/control.py b/tools/binman/control.py index 81f61e3e152..dcbc028adcc 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -530,6 +530,57 @@ def _RemoveTemplates(parent): for node in del_nodes: node.Delete() +def propagate_prop(node, prop): + """Propagate the provided property to all the parent nodes up the hierarchy + + Args: + node (fdt.Node): Node and all its parent nodes up to the root to + propagate the property. + prop (str): Boolean property to propagate + + Return: + True if any change was made, else False + """ + changed = False + while node: + if prop not in node.props: + node.AddEmptyProp(prop, 0) + changed = True + node = node.parent + return changed + +def scan_and_prop_bootph(node): + """Propagate bootph properties from children to parents + + The bootph schema indicates that bootph properties in children should be + implied in their parents, all the way up the hierarchy. This is expensive + to implement in U-Boot before relocation at runtime, so this function + explicitly propagates these bootph properties upwards during build time. + + This is used to set the bootph-all, bootph-some-ram property in the parent + node if the respective property is found in any of the parent's subnodes. + The other bootph-* properties are associated with the SPL stage and hence + handled by fdtgrep.c. + + Args: + node (fdt.Node): Node to scan for bootph-all and bootph-some-ram + property + + Return: + True if any change was made, else False + + """ + bootph_prop = {'bootph-all', 'bootph-some-ram'} + + changed = False + for prop in bootph_prop: + if prop in node.props: + changed |= propagate_prop(node.parent, prop) + + for subnode in node.subnodes: + changed |= scan_and_prop_bootph(subnode) + return changed + def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, indir): """Prepare the images to be processed and select the device tree @@ -589,6 +640,9 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, ind fname = tools.get_output_filename('u-boot.dtb.tmpl2') tools.write_file(fname, dtb.GetContents()) + if scan_and_prop_bootph(dtb.GetRoot()): + dtb.Sync(True) + images = _ReadImageDesc(node, use_expanded) if select_images: -- cgit v1.3.1 From 1b5e41964c34ee062fe9932ef5f9ccc747c50ea1 Mon Sep 17 00:00:00 2001 From: Moteen Shah Date: Fri, 16 May 2025 17:11:48 +0530 Subject: tools: binman: ftest.py: Add testcase for bootph-* propagation Add a testcase to ensure that scan_and_prop_bootph() actually propagates bootph-* properties to supernodes. Signed-off-by: Moteen Shah Reviewed-by: Simon Glass --- tools/binman/ftest.py | 24 ++++++++++++++++++++++++ tools/binman/test/347_bootph_prop.dts | 21 +++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 tools/binman/test/347_bootph_prop.dts diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index fa174900014..1bbb5e2b2ab 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -8011,5 +8011,29 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self._DoTestFile('346_remove_template.dts', force_missing_bintools='openssl',) + def testBootphPropagation(self): + """Test that bootph-* properties are propagated correctly to supernodes""" + _, _, _, out_dtb_fname = self._DoReadFileDtb( + '347_bootph_prop.dts', use_real_dtb=True, update_dtb=True) + dtb = fdt.Fdt(out_dtb_fname) + dtb.Scan() + root = dtb.GetRoot() + parent_node = root.FindNode('dummy-parent') + subnode1 = parent_node.FindNode('subnode-1') + subnode2 = subnode1.FindNode('subnode-2') + subnode3 = subnode1.FindNode('subnode-3') + subnode4 = subnode3.FindNode('subnode-4') + + self.assertIn('bootph-some-ram', subnode1.props, + "Child node is missing 'bootph-some-ram' property") + self.assertIn('bootph-all', subnode1.props, + "Child node is missing 'bootph-all' property") + self.assertIn('bootph-some-ram', parent_node.props, + "Parent node is missing 'bootph-some-ram' property") + self.assertIn('bootph-all', parent_node.props, + "Parent node is missing 'bootph-all' property") + self.assertEqual(len(subnode4.props), 0, + "subnode shouldn't have any properties") + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/347_bootph_prop.dts b/tools/binman/test/347_bootph_prop.dts new file mode 100644 index 00000000000..91d4e4ad600 --- /dev/null +++ b/tools/binman/test/347_bootph_prop.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; +/ { + dummy-parent { + subnode-1 { + subnode-2 { + bootph-all; + }; + subnode-3 { + bootph-some-ram; + subnode-4 { + }; + }; + }; + }; + + binman: binman { + }; +}; + -- cgit v1.3.1