rockchip: rk3399: Add Nanopi M4 2GB board support
[platform/kernel/u-boot.git] / tools / binman / etype / section.py
index 6db3c7a..89b7bf6 100644 (file)
@@ -17,6 +17,7 @@ import sys
 from entry import Entry
 import fdt_util
 import tools
 from entry import Entry
 import fdt_util
 import tools
+import tout
 
 
 class Entry_section(Entry):
 
 
 class Entry_section(Entry):
@@ -45,29 +46,15 @@ class Entry_section(Entry):
     def __init__(self, section, etype, node, test=False):
         if not test:
             Entry.__init__(self, section, etype, node)
     def __init__(self, section, etype, node, test=False):
         if not test:
             Entry.__init__(self, section, etype, node)
-        if section:
-            self.image = section.image
         self._entries = OrderedDict()
         self._pad_byte = 0
         self._sort = False
         self._skip_at_start = None
         self._end_4gb = False
         self._entries = OrderedDict()
         self._pad_byte = 0
         self._sort = False
         self._skip_at_start = None
         self._end_4gb = False
-        if not test:
-            self._ReadNode()
-            self._ReadEntries()
 
 
-    def _Raise(self, msg):
-        """Raises an error for this section
-
-        Args:
-            msg: Error message to use in the raise string
-        Raises:
-            ValueError()
-        """
-        raise ValueError("Section '%s': %s" % (self._node.path, msg))
-
-    def _ReadNode(self):
+    def ReadNode(self):
         """Read properties from the image node"""
         """Read properties from the image node"""
+        Entry.ReadNode(self)
         self._pad_byte = fdt_util.GetInt(self._node, 'pad-byte', 0)
         self._sort = fdt_util.GetBool(self._node, 'sort-by-offset')
         self._end_4gb = fdt_util.GetBool(self._node, 'end-at-4gb')
         self._pad_byte = fdt_util.GetInt(self._node, 'pad-byte', 0)
         self._sort = fdt_util.GetBool(self._node, 'sort-by-offset')
         self._end_4gb = fdt_util.GetBool(self._node, 'end-at-4gb')
@@ -87,19 +74,32 @@ class Entry_section(Entry):
         if filename:
             self._filename = filename
 
         if filename:
             self._filename = filename
 
+        self._ReadEntries()
+
     def _ReadEntries(self):
         for node in self._node.subnodes:
             if node.name == 'hash':
                 continue
             entry = Entry.Create(self, node)
     def _ReadEntries(self):
         for node in self._node.subnodes:
             if node.name == 'hash':
                 continue
             entry = Entry.Create(self, node)
+            entry.ReadNode()
             entry.SetPrefix(self._name_prefix)
             self._entries[node.name] = entry
 
             entry.SetPrefix(self._name_prefix)
             self._entries[node.name] = entry
 
-    def GetFdtSet(self):
-        fdt_set = set()
+    def _Raise(self, msg):
+        """Raises an error for this section
+
+        Args:
+            msg: Error message to use in the raise string
+        Raises:
+            ValueError()
+        """
+        raise ValueError("Section '%s': %s" % (self._node.path, msg))
+
+    def GetFdts(self):
+        fdts = {}
         for entry in self._entries.values():
         for entry in self._entries.values():
-            fdt_set.update(entry.GetFdtSet())
-        return fdt_set
+            fdts.update(entry.GetFdts())
+        return fdts
 
     def ProcessFdt(self, fdt):
         """Allow entries to adjust the device tree
 
     def ProcessFdt(self, fdt):
         """Allow entries to adjust the device tree
@@ -142,13 +142,21 @@ class Entry_section(Entry):
         return self.GetEntryContents()
 
     def GetData(self):
         return self.GetEntryContents()
 
     def GetData(self):
-        section_data = tools.GetBytes(self._pad_byte, self.size)
+        section_data = b''
 
         for entry in self._entries.values():
             data = entry.GetData()
 
         for entry in self._entries.values():
             data = entry.GetData()
-            base = self.pad_before + entry.offset - self._skip_at_start
-            section_data = (section_data[:base] + data +
-                            section_data[base + len(data):])
+            base = self.pad_before + (entry.offset or 0) - self._skip_at_start
+            pad = base - len(section_data)
+            if pad > 0:
+                section_data += tools.GetBytes(self._pad_byte, pad)
+            section_data += data
+        if self.size:
+            pad = self.size - len(section_data)
+            if pad > 0:
+                section_data += tools.GetBytes(self._pad_byte, pad)
+        self.Detail('GetData: %d entries, total size %#x' %
+                    (len(self._entries), len(section_data)))
         return section_data
 
     def GetOffsets(self):
         return section_data
 
     def GetOffsets(self):
@@ -282,13 +290,16 @@ class Entry_section(Entry):
                 return entry.GetData()
         source_entry.Raise("Cannot find entry for node '%s'" % node.name)
 
                 return entry.GetData()
         source_entry.Raise("Cannot find entry for node '%s'" % node.name)
 
-    def LookupSymbol(self, sym_name, optional, msg):
+    def LookupSymbol(self, sym_name, optional, msg, base_addr):
         """Look up a symbol in an ELF file
 
         Looks up a symbol in an ELF file. Only entry types which come from an
         ELF image can be used by this function.
 
         """Look up a symbol in an ELF file
 
         Looks up a symbol in an ELF file. Only entry types which come from an
         ELF image can be used by this function.
 
-        At present the only entry property supported is offset.
+        At present the only entry properties supported are:
+            offset
+            image_pos - 'base_addr' is added if this is not an end-at-4gb image
+            size
 
         Args:
             sym_name: Symbol name in the ELF file to look up in the format
 
         Args:
             sym_name: Symbol name in the ELF file to look up in the format
@@ -301,6 +312,12 @@ class Entry_section(Entry):
             optional: True if the symbol is optional. If False this function
                 will raise if the symbol is not found
             msg: Message to display if an error occurs
             optional: True if the symbol is optional. If False this function
                 will raise if the symbol is not found
             msg: Message to display if an error occurs
+            base_addr: Base address of image. This is added to the returned
+                image_pos in most cases so that the returned position indicates
+                where the targetted entry/binary has actually been loaded. But
+                if end-at-4gb is used, this is not done, since the binary is
+                already assumed to be linked to the ROM position and using
+                execute-in-place (XIP).
 
         Returns:
             Value that should be assigned to that symbol, or None if it was
 
         Returns:
             Value that should be assigned to that symbol, or None if it was
@@ -335,7 +352,12 @@ class Entry_section(Entry):
         if prop_name == 'offset':
             return entry.offset
         elif prop_name == 'image_pos':
         if prop_name == 'offset':
             return entry.offset
         elif prop_name == 'image_pos':
-            return entry.image_pos
+            value = entry.image_pos
+            if not self.GetImage()._end_4gb:
+                value += base_addr
+            return value
+        if prop_name == 'size':
+            return entry.size
         else:
             raise ValueError("%s: No such property '%s'" % (msg, prop_name))
 
         else:
             raise ValueError("%s: No such property '%s'" % (msg, prop_name))
 
@@ -371,7 +393,7 @@ class Entry_section(Entry):
             Image size as an integer number of bytes, which may be None if the
                 image size is dynamic and its sections have not yet been packed
         """
             Image size as an integer number of bytes, which may be None if the
                 image size is dynamic and its sections have not yet been packed
         """
-        return self.image.size
+        return self.GetImage().size
 
     def FindEntryType(self, etype):
         """Find an entry type in the section
 
     def FindEntryType(self, etype):
         """Find an entry type in the section
@@ -460,3 +482,58 @@ class Entry_section(Entry):
                            self.image_pos, None, self.offset, self)
         for entry in self._entries.values():
             entry.ListEntries(entries, indent + 1)
                            self.image_pos, None, self.offset, self)
         for entry in self._entries.values():
             entry.ListEntries(entries, indent + 1)
+
+    def LoadData(self, decomp=True):
+        for entry in self._entries.values():
+            entry.LoadData(decomp)
+        self.Detail('Loaded data')
+
+    def GetImage(self):
+        """Get the image containing this section
+
+        Note that a top-level section is actually an Image, so this function may
+        return self.
+
+        Returns:
+            Image object containing this section
+        """
+        if not self.section:
+            return self
+        return self.section.GetImage()
+
+    def GetSort(self):
+        """Check if the entries in this section will be sorted
+
+        Returns:
+            True if to be sorted, False if entries will be left in the order
+                they appear in the device tree
+        """
+        return self._sort
+
+    def ReadData(self, decomp=True):
+        tout.Info("ReadData path='%s'" % self.GetPath())
+        parent_data = self.section.ReadData(True)
+        tout.Info('%s: Reading data from offset %#x-%#x, size %#x' %
+                  (self.GetPath(), self.offset, self.offset + self.size,
+                   self.size))
+        data = parent_data[self.offset:self.offset + self.size]
+        return data
+
+    def ReadChildData(self, child, decomp=True):
+        tout.Debug("ReadChildData for child '%s'" % child.GetPath())
+        parent_data = self.ReadData(True)
+        offset = child.offset - self._skip_at_start
+        tout.Debug("Extract for child '%s': offset %#x, skip_at_start %#x, result %#x" %
+                   (child.GetPath(), child.offset, self._skip_at_start, offset))
+        data = parent_data[offset:offset + child.size]
+        if decomp:
+            indata = data
+            data = tools.Decompress(indata, child.compress)
+            if child.uncomp_size:
+                tout.Info("%s: Decompressing data size %#x with algo '%s' to data size %#x" %
+                            (child.GetPath(), len(indata), child.compress,
+                            len(data)))
+        return data
+
+    def WriteChildData(self, child):
+        return True