]> git.sur5r.net Git - u-boot/blobdiff - tools/dtoc/fdt.py
dtoc: Drop use of a local dtb buffer
[u-boot] / tools / dtoc / fdt.py
index 63a32ea2d7bfcaeb9897406a986ff8dc65ac61c5..e24acf12804f2d05917f2eefe801569ed73d52d4 100644 (file)
@@ -1,16 +1,16 @@
 #!/usr/bin/python
 #!/usr/bin/python
+# SPDX-License-Identifier: GPL-2.0+
 #
 # Copyright (C) 2016 Google, Inc
 # Written by Simon Glass <sjg@chromium.org>
 #
 #
 # Copyright (C) 2016 Google, Inc
 # Written by Simon Glass <sjg@chromium.org>
 #
-# SPDX-License-Identifier:      GPL-2.0+
-#
 
 import struct
 import sys
 
 import fdt_util
 import libfdt
 
 import struct
 import sys
 
 import fdt_util
 import libfdt
+from libfdt import QUIET_NOTFOUND
 
 # This deals with a device tree, presenting it as an assortment of Node and
 # Prop objects, representing nodes and properties, respectively. This file
 
 # This deals with a device tree, presenting it as an assortment of Node and
 # Prop objects, representing nodes and properties, respectively. This file
@@ -21,7 +21,7 @@ import libfdt
 # so it is fairly efficient.
 
 # A list of types we support
 # so it is fairly efficient.
 
 # A list of types we support
-(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4)
+(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, TYPE_INT64) = range(5)
 
 def CheckErr(errnum, msg):
     if errnum:
 
 def CheckErr(errnum, msg):
     if errnum:
@@ -139,6 +139,7 @@ class Prop:
         else:
             return TYPE_INT, val
 
         else:
             return TYPE_INT, val
 
+    @classmethod
     def GetEmpty(self, type):
         """Get an empty / zero value of the given type
 
     def GetEmpty(self, type):
         """Get an empty / zero value of the given type
 
@@ -174,8 +175,9 @@ class Node:
         props: A dict of properties for this node, each a Prop object.
             Keyed by property name
     """
         props: A dict of properties for this node, each a Prop object.
             Keyed by property name
     """
-    def __init__(self, fdt, offset, name, path):
+    def __init__(self, fdt, parent, offset, name, path):
         self._fdt = fdt
         self._fdt = fdt
+        self.parent = parent
         self._offset = offset
         self.name = name
         self.path = path
         self._offset = offset
         self.name = name
         self.path = path
@@ -210,18 +212,22 @@ class Node:
         This fills in the props and subnodes properties, recursively
         searching into subnodes so that the entire tree is built.
         """
         This fills in the props and subnodes properties, recursively
         searching into subnodes so that the entire tree is built.
         """
+        fdt_obj = self._fdt._fdt_obj
         self.props = self._fdt.GetProps(self)
         self.props = self._fdt.GetProps(self)
+        phandle = fdt_obj.get_phandle(self.Offset())
+        if phandle:
+            self._fdt.phandle_to_node[phandle] = self
 
 
-        offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self.Offset())
+        offset = fdt_obj.first_subnode(self.Offset(), QUIET_NOTFOUND)
         while offset >= 0:
             sep = '' if self.path[-1] == '/' else '/'
         while offset >= 0:
             sep = '' if self.path[-1] == '/' else '/'
-            name = self._fdt._fdt_obj.get_name(offset)
+            name = fdt_obj.get_name(offset)
             path = self.path + sep + name
             path = self.path + sep + name
-            node = Node(self._fdt, offset, name, path)
+            node = Node(self._fdt, self, offset, name, path)
             self.subnodes.append(node)
 
             node.Scan()
             self.subnodes.append(node)
 
             node.Scan()
-            offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset)
+            offset = fdt_obj.next_subnode(offset, QUIET_NOTFOUND)
 
     def Refresh(self, my_offset):
         """Fix up the _offset for each node, recursively
 
     def Refresh(self, my_offset):
         """Fix up the _offset for each node, recursively
@@ -229,13 +235,13 @@ class Node:
         Note: This does not take account of property offsets - these will not
         be updated.
         """
         Note: This does not take account of property offsets - these will not
         be updated.
         """
+        fdt_obj = self._fdt._fdt_obj
         if self._offset != my_offset:
         if self._offset != my_offset:
-            #print '%s: %d -> %d\n' % (self.path, self._offset, my_offset)
             self._offset = my_offset
             self._offset = my_offset
-        offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self._offset)
+        offset = fdt_obj.first_subnode(self._offset, QUIET_NOTFOUND)
         for subnode in self.subnodes:
             subnode.Refresh(offset)
         for subnode in self.subnodes:
             subnode.Refresh(offset)
-            offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset)
+            offset = fdt_obj.next_subnode(offset, QUIET_NOTFOUND)
 
     def DeleteProp(self, prop_name):
         """Delete a property of a node
 
     def DeleteProp(self, prop_name):
         """Delete a property of a node
@@ -247,7 +253,7 @@ class Node:
         Raises:
             ValueError if the property does not exist
         """
         Raises:
             ValueError if the property does not exist
         """
-        CheckErr(libfdt.fdt_delprop(self._fdt.GetFdt(), self.Offset(), prop_name),
+        CheckErr(self._fdt._fdt_obj.delprop(self.Offset(), prop_name),
                  "Node '%s': delete property: '%s'" % (self.path, prop_name))
         del self.props[prop_name]
         self._fdt.Invalidate()
                  "Node '%s': delete property: '%s'" % (self.path, prop_name))
         del self.props[prop_name]
         self._fdt.Invalidate()
@@ -262,12 +268,12 @@ class Fdt:
     def __init__(self, fname):
         self._fname = fname
         self._cached_offsets = False
     def __init__(self, fname):
         self._fname = fname
         self._cached_offsets = False
+        self.phandle_to_node = {}
         if self._fname:
             self._fname = fdt_util.EnsureCompiled(self._fname)
 
             with open(self._fname) as fd:
         if self._fname:
             self._fname = fdt_util.EnsureCompiled(self._fname)
 
             with open(self._fname) as fd:
-                self._fdt = bytearray(fd.read())
-                self._fdt_obj = libfdt.Fdt(self._fdt)
+                self._fdt_obj = libfdt.Fdt(fd.read())
 
     def Scan(self, root='/'):
         """Scan a device tree, building up a tree of Node objects
 
     def Scan(self, root='/'):
         """Scan a device tree, building up a tree of Node objects
@@ -279,7 +285,7 @@ class Fdt:
 
         TODO(sjg@chromium.org): Implement the 'root' parameter
         """
 
         TODO(sjg@chromium.org): Implement the 'root' parameter
         """
-        self._root = self.Node(self, 0, '/', '/')
+        self._root = self.Node(self, None, 0, '/', '/')
         self._root.Scan()
 
     def GetRoot(self):
         self._root.Scan()
 
     def GetRoot(self):
@@ -311,7 +317,7 @@ class Fdt:
         If the device tree has changed in memory, write it back to the file.
         """
         with open(self._fname, 'wb') as fd:
         If the device tree has changed in memory, write it back to the file.
         """
         with open(self._fname, 'wb') as fd:
-            fd.write(self._fdt)
+            fd.write(self._fdt_obj.as_bytearray())
 
     def Pack(self):
         """Pack the device tree down to its minimum size
 
     def Pack(self):
         """Pack the device tree down to its minimum size
@@ -319,24 +325,30 @@ class Fdt:
         When nodes and properties shrink or are deleted, wasted space can
         build up in the device tree binary.
         """
         When nodes and properties shrink or are deleted, wasted space can
         build up in the device tree binary.
         """
-        CheckErr(libfdt.fdt_pack(self._fdt), 'pack')
-        fdt_len = libfdt.fdt_totalsize(self._fdt)
-        del self._fdt[fdt_len:]
+        CheckErr(self._fdt_obj.pack(), 'pack')
+        self.Invalidate()
 
 
-    def GetFdt(self):
+    def GetContents(self):
         """Get the contents of the FDT
 
         Returns:
             The FDT contents as a string of bytes
         """
         """Get the contents of the FDT
 
         Returns:
             The FDT contents as a string of bytes
         """
-        return self._fdt
+        return self._fdt_obj.as_bytearray()
+
+    def GetFdtObj(self):
+        """Get the contents of the FDT
+
+        Returns:
+            The FDT contents as a libfdt.Fdt object
+        """
+        return self._fdt_obj
 
 
-    def CheckErr(errnum, msg):
+    def CheckErr(self, errnum, msg):
         if errnum:
             raise ValueError('Error %d: %s: %s' %
                 (errnum, libfdt.fdt_strerror(errnum), msg))
 
         if errnum:
             raise ValueError('Error %d: %s: %s' %
                 (errnum, libfdt.fdt_strerror(errnum), msg))
 
-
     def GetProps(self, node):
         """Get all properties from a node.
 
     def GetProps(self, node):
         """Get all properties from a node.
 
@@ -351,13 +363,15 @@ class Fdt:
             ValueError: if the node does not exist.
         """
         props_dict = {}
             ValueError: if the node does not exist.
         """
         props_dict = {}
-        poffset = libfdt.fdt_first_property_offset(self._fdt, node._offset)
+        poffset = self._fdt_obj.first_property_offset(node._offset,
+                                                      QUIET_NOTFOUND)
         while poffset >= 0:
             p = self._fdt_obj.get_property_by_offset(poffset)
         while poffset >= 0:
             p = self._fdt_obj.get_property_by_offset(poffset)
-            prop = Prop(node, poffset, p.name, p.value)
+            prop = Prop(node, poffset, p.name, p)
             props_dict[prop.name] = prop
 
             props_dict[prop.name] = prop
 
-            poffset = libfdt.fdt_next_property_offset(self._fdt, poffset)
+            poffset = self._fdt_obj.next_property_offset(poffset,
+                                                         QUIET_NOTFOUND)
         return props_dict
 
     def Invalidate(self):
         return props_dict
 
     def Invalidate(self):
@@ -383,10 +397,10 @@ class Fdt:
         Returns:
             Position of @offset within the device tree binary
         """
         Returns:
             Position of @offset within the device tree binary
         """
-        return libfdt.fdt_off_dt_struct(self._fdt) + offset
+        return self._fdt_obj.off_dt_struct() + offset
 
     @classmethod
 
     @classmethod
-    def Node(self, fdt, offset, name, path):
+    def Node(self, fdt, parent, offset, name, path):
         """Create a new node
 
         This is used by Fdt.Scan() to create a new node using the correct
         """Create a new node
 
         This is used by Fdt.Scan() to create a new node using the correct
@@ -394,11 +408,12 @@ class Fdt:
 
         Args:
             fdt: Fdt object
 
         Args:
             fdt: Fdt object
+            parent: Parent node, or None if this is the root node
             offset: Offset of node
             name: Node name
             path: Full path to node
         """
             offset: Offset of node
             name: Node name
             path: Full path to node
         """
-        node = Node(fdt, offset, name, path)
+        node = Node(fdt, parent, offset, name, path)
         return node
 
 def FdtScan(fname):
         return node
 
 def FdtScan(fname):