[PATCH 10/12] dtoc: Support copying the contents of a node into another
Simon Glass
sjg at chromium.org
Wed Jun 28 13:41:43 CEST 2023
This permits implementation of a simple templating system, where a node
can be reused as a base for others.
For now this adds new subnodes after any existing ones.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
tools/dtoc/fdt.py | 22 ++++++++++++++
tools/dtoc/test/dtoc_test_simple.dts | 3 ++
tools/dtoc/test_fdt.py | 43 ++++++++++++++++++++++++++++
3 files changed, 68 insertions(+)
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index a8e05349a720..fcf229f83036 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -13,6 +13,7 @@ from dtoc import fdt_util
import libfdt
from libfdt import QUIET_NOTFOUND
from u_boot_pylib import tools
+from u_boot_pylib import tout
# This deals with a device tree, presenting it as an assortment of Node and
# Prop objects, representing nodes and properties, respectively. This file
@@ -635,6 +636,27 @@ class Node:
prop.Sync(auto_resize)
return added
+ def copy_node(self, src):
+ """Copy a node and all its subnodes into this node
+
+ Args:
+ src (Node): Node to copy
+
+ This works recursively.
+
+ The new node is put after all other nodes. If the node already
+ exists, just its properties are copied. Properties which exist in the
+ destination node already are not copied.
+ """
+ dst = self.FindNode(src.name)
+ if not dst:
+ dst = self.AddSubnode(src.name)
+ for name, src_prop in src.props.items():
+ if name not in dst.props:
+ dst.props[name] = Prop(dst, None, name, src_prop.bytes)
+ for node in src.subnodes:
+ dst.copy_node(node)
+
class Fdt:
"""Provides simple access to a flat device tree blob using libfdts.
diff --git a/tools/dtoc/test/dtoc_test_simple.dts b/tools/dtoc/test/dtoc_test_simple.dts
index 08f667ee5a10..c51f1a5908ce 100644
--- a/tools/dtoc/test/dtoc_test_simple.dts
+++ b/tools/dtoc/test/dtoc_test_simple.dts
@@ -45,6 +45,9 @@
stringarray = "one";
longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
maybe-empty-int = <1>;
+
+ first-node {
+ };
};
i2c at 0 {
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index 4fe8d12c403a..5d9d99eb384b 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -306,6 +306,49 @@ class TestNode(unittest.TestCase):
self.assertIn("Internal error, node '/spl-test' name mismatch 'i2c at 0'",
str(exc.exception))
+ def test_copy_node(self):
+ """Test copy_node() function"""
+ tmpl = self.dtb.GetNode('/i2c at 0')
+ dst = self.dtb.GetNode('/spl-test3')
+ dst.copy_node(tmpl)
+
+ self.assertEqual(['/spl-test3/first-node', '/spl-test3/i2c at 0'],
+ [n.path for n in dst.subnodes])
+
+ chk = self.dtb.GetNode('/spl-test3/i2c at 0')
+ self.assertTrue(chk)
+ self.assertEqual(
+ {'bootph-all', 'compatible', '#address-cells', '#size-cells'},
+ chk.props.keys())
+
+ # Check the first property
+ prop = chk.props['bootph-all']
+ self.assertEqual('bootph-all', prop.name)
+ self.assertEqual(True, prop.value)
+ self.assertIsNone(prop._offset)
+ self.assertEqual(chk.path, prop._node.path)
+
+ # Check the second property
+ prop = chk.props['compatible']
+ self.assertEqual('compatible', prop.name)
+ self.assertEqual('sandbox,i2c', prop.value)
+ self.assertIsNone(prop._offset)
+ self.assertEqual(chk.path, prop._node.path)
+
+ pmic = chk.FindNode('pmic at 9')
+ self.assertTrue(chk)
+
+ pmic = self.dtb.GetNode('/spl-test3/i2c at 0/pmic at 9')
+ self.assertTrue(pmic)
+ self.assertEqual([pmic], chk.subnodes)
+ self.assertEqual(chk, pmic.parent)
+ self.assertIsNone(pmic._offset)
+ self.assertEqual(
+ {'bootph-all', 'compatible', 'reg', 'low-power'},
+ pmic.props.keys())
+
+ self.dtb.Sync(auto_resize=True)
+
class TestProp(unittest.TestCase):
"""Test operation of the Prop class"""
--
2.41.0.162.gfafddb0af9-goog
More information about the U-Boot
mailing list