dtoc: Support adding new nodes
authorSimon Glass <sjg@chromium.org>
Fri, 14 Sep 2018 10:57:15 +0000 (04:57 -0600)
committerSimon Glass <sjg@chromium.org>
Fri, 28 Sep 2018 17:09:01 +0000 (11:09 -0600)
Add a way to add new nodes and sync them back to the blob.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/dtoc/fdt.py
tools/dtoc/test_fdt.py

index ccf3b23ced475205064968e1ad6a94c825fcc17e..26f4a4ee56293366bf22d6bc57f222d20e36b141 100644 (file)
@@ -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.
index 4a67f8949df9c4c1518f3b93aa74ef97a7e28d59..c94e455d121adcc0f011a494e997c321cf9f2ad5 100755 (executable)
@@ -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):