dtoc: Add a way to create an Fdt object from a data block
[oweals/u-boot.git] / tools / dtoc / fdt.py
index 76cd66fbf958e6d0f516f35a39651c2ade9dd3b3..2df2d4b0cc7a67abcfbc60f1624b5e0db4b85467 100644 (file)
@@ -146,7 +146,7 @@ class Prop:
         if type == TYPE_BYTE:
             return chr(0)
         elif type == TYPE_INT:
-            return struct.pack('<I', 0);
+            return struct.pack('>I', 0);
         elif type == TYPE_STRING:
             return ''
         else:
@@ -175,6 +175,16 @@ class Prop:
         self.type = TYPE_INT
         self.dirty = True
 
+    def SetData(self, bytes):
+        """Set the value of a property as bytes
+
+        Args:
+            bytes: New property value to set
+        """
+        self.bytes = str(bytes)
+        self.type, self.value = self.BytesToValue(bytes)
+        self.dirty = True
+
     def Sync(self, auto_resize=False):
         """Sync property changes back to the device tree
 
@@ -326,17 +336,83 @@ class Node:
         """
         self.props[prop_name] = Prop(self, None, prop_name, '\0' * 4)
 
+    def AddEmptyProp(self, prop_name, len):
+        """Add a property with a fixed data size, for filling in later
+
+        The device tree is marked dirty so that the value will be written to
+        the blob on the next sync.
+
+        Args:
+            prop_name: Name of property
+            len: Length of data in property
+        """
+        value = chr(0) * len
+        self.props[prop_name] = Prop(self, None, prop_name, value)
+
     def SetInt(self, prop_name, val):
         """Update an integer property int the device tree.
 
         This is not allowed to change the size of the FDT.
 
+        The device tree is marked dirty so that the value will be written to
+        the blob on the next sync.
+
         Args:
             prop_name: Name of property
             val: Value to set
         """
         self.props[prop_name].SetInt(val)
 
+    def SetData(self, prop_name, val):
+        """Set the data value of a property
+
+        The device tree is marked dirty so that the value will be written to
+        the blob on the next sync.
+
+        Args:
+            prop_name: Name of property to set
+            val: Data value to set
+        """
+        self.props[prop_name].SetData(val)
+
+    def SetString(self, prop_name, val):
+        """Set the string value of a property
+
+        The device tree is marked dirty so that the value will be written to
+        the blob on the next sync.
+
+        Args:
+            prop_name: Name of property to set
+            val: String value to set (will be \0-terminated in DT)
+        """
+        self.props[prop_name].SetData(val + chr(0))
+
+    def AddString(self, prop_name, val):
+        """Add a new string property to a node
+
+        The device tree is marked dirty so that the value will be written to
+        the blob on the next sync.
+
+        Args:
+            prop_name: Name of property to add
+            val: String value of property
+        """
+        self.props[prop_name] = Prop(self, None, prop_name, val + chr(0))
+
+    def AddSubnode(self, name):
+        """Add a new subnode to the node
+
+        Args:
+            name: name of node to add
+
+        Returns:
+            New subnode that was created
+        """
+        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 +426,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.
@@ -382,6 +472,20 @@ class Fdt:
             with open(self._fname) as fd:
                 self._fdt_obj = libfdt.Fdt(fd.read())
 
+    @staticmethod
+    def FromData(data):
+        """Create a new Fdt object from the given data
+
+        Args:
+            data: Device-tree data blob
+
+        Returns:
+            Fdt object containing the data
+        """
+        fdt = Fdt(None)
+        fdt._fdt_obj = libfdt.Fdt(bytearray(data))
+        return fdt
+
     def LookupPhandle(self, phandle):
         """Look up a phandle