From e21c27af47183619c7ec7097abb1dec34410e775 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 14 Sep 2018 04:57:15 -0600 Subject: [PATCH] dtoc: Support adding new nodes Add a way to add new nodes and sync them back to the blob. Signed-off-by: Simon Glass --- tools/dtoc/fdt.py | 20 ++++++++++++++++++++ tools/dtoc/test_fdt.py | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index ccf3b23..26f4a4e 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -337,6 +337,12 @@ class Node: """ self.props[prop_name].SetInt(val) + def AddSubnode(self, name): + path = self.path + '/' + name + subnode = Node(self._fdt, self, None, name, path) + self.subnodes.append(subnode) + return subnode + def Sync(self, auto_resize=False): """Sync node changes back to the device tree @@ -350,6 +356,20 @@ class Node: Raises: FdtException if auto_resize is False and there is not enough space """ + if self._offset is None: + # The subnode doesn't exist yet, so add it + fdt_obj = self._fdt._fdt_obj + if auto_resize: + while True: + offset = fdt_obj.add_subnode(self.parent._offset, self.name, + (libfdt.NOSPACE,)) + if offset != -libfdt.NOSPACE: + break + fdt_obj.resize(fdt_obj.totalsize() + 1024) + else: + offset = fdt_obj.add_subnode(self.parent._offset, self.name) + self._offset = offset + # Sync subnodes in reverse so that we don't disturb node offsets for # nodes that are earlier in the DT. This avoids an O(n^2) rescan of # node offsets. diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 4a67f89..c94e455 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -355,6 +355,14 @@ class TestProp(unittest.TestCase): def testAddNode(self): self.fdt.pack() + self.node.AddSubnode('subnode') + with self.assertRaises(libfdt.FdtException) as e: + self.dtb.Sync(auto_resize=False) + self.assertIn('FDT_ERR_NOSPACE', str(e.exception)) + + self.dtb.Sync(auto_resize=True) + offset = self.fdt.path_offset('/spl-test/subnode') + self.assertTrue(offset > 0) class TestFdtUtil(unittest.TestCase):