Merge tag 'dm-pull-9jul19-take2' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm
[oweals/u-boot.git] / tools / binman / control.py
index ab894a8aa8db5663e34571302e5ba0d7107494aa..20186ee1980282cfbd6b78d12d6ee1bbf7468fa3 100644 (file)
@@ -5,31 +5,23 @@
 # Creates binary images from input files controlled by a description
 #
 
+from __future__ import print_function
+
 from collections import OrderedDict
 import os
-import re
 import sys
 import tools
 
 import command
 import elf
-import fdt
-import fdt_util
 from image import Image
+import state
 import tout
 
 # List of images we plan to create
 # Make this global so that it can be referenced from tests
 images = OrderedDict()
 
-# Records the device-tree files known to binman, keyed by filename (e.g.
-# 'u-boot-spl.dtb')
-fdt_files = {}
-
-# Arguments passed to binman to provide arguments to entries
-entry_args = {}
-
-
 def _ReadImageDesc(binman_node):
     """Read the image descriptions from the /binman node
 
@@ -62,37 +54,17 @@ def _FindBinmanNode(dtb):
             return node
     return None
 
-def GetFdt(fname):
-    """Get the Fdt object for a particular device-tree filename
-
-    Binman keeps track of at least one device-tree file called u-boot.dtb but
-    can also have others (e.g. for SPL). This function looks up the given
-    filename and returns the associated Fdt object.
+def WriteEntryDocs(modules, test_missing=None):
+    """Write out documentation for all entries
 
     Args:
-        fname: Filename to look up (e.g. 'u-boot.dtb').
-
-    Returns:
-        Fdt object associated with the filename
+        modules: List of Module objects to get docs for
+        test_missing: Used for testing only, to force an entry's documeentation
+            to show as missing even if it is present. Should be set to None in
+            normal use.
     """
-    return fdt_files[fname]
-
-def GetFdtPath(fname):
-    return fdt_files[fname]._fname
-
-def SetEntryArgs(args):
-    global entry_args
-
-    entry_args = {}
-    if args:
-        for arg in args:
-            m = re.match('([^=]*)=(.*)', arg)
-            if not m:
-                raise ValueError("Invalid entry arguemnt '%s'" % arg)
-            entry_args[m.group(1)] = m.group(2)
-
-def GetEntryArg(name):
-    return entry_args.get(name)
+    from entry import Entry
+    Entry.WriteDocs(modules, test_missing)
 
 def Binman(options, args):
     """The main control code for binman
@@ -129,25 +101,27 @@ def Binman(options, args):
         options.indir.append(board_pathname)
 
     try:
+        # Import these here in case libfdt.py is not available, in which case
+        # the above help option still works.
+        import fdt
+        import fdt_util
+
         tout.Init(options.verbosity)
         elf.debug = options.debug
+        state.use_fake_dtb = options.fake_dtb
         try:
             tools.SetInputDirs(options.indir)
             tools.PrepareOutputDir(options.outdir, options.preserve)
-            SetEntryArgs(options.entry_arg)
+            state.SetEntryArgs(options.entry_arg)
 
             # Get the device tree ready by compiling it and copying the compiled
             # output into a file in our output directly. Then scan it for use
             # in binman.
             dtb_fname = fdt_util.EnsureCompiled(dtb_fname)
-            fname = tools.GetOutputFilename('u-boot-out.dtb')
-            with open(dtb_fname) as infd:
-                with open(fname, 'wb') as outfd:
-                    outfd.write(infd.read())
+            fname = tools.GetOutputFilename('u-boot.dtb.out')
+            tools.WriteFile(fname, tools.ReadFile(dtb_fname))
             dtb = fdt.FdtScan(fname)
 
-            # Note the file so that GetFdt() can find it
-            fdt_files['u-boot.dtb'] = dtb
             node = _FindBinmanNode(dtb)
             if not node:
                 raise ValueError("Device tree '%s' does not have a 'binman' "
@@ -155,6 +129,20 @@ def Binman(options, args):
 
             images = _ReadImageDesc(node)
 
+            if options.image:
+                skip = []
+                new_images = OrderedDict()
+                for name, image in images.items():
+                    if name in options.image:
+                        new_images[name] = image
+                    else:
+                        skip.append(name)
+                images = new_images
+                if skip and options.verbosity >= 2:
+                    print('Skipping images: %s' % ', '.join(skip))
+
+            state.Prepare(images, dtb)
+
             # Prepare the device tree by making sure that any missing
             # properties are added (e.g. 'pos' and 'size'). The values of these
             # may not be correct yet, but we add placeholders so that the
@@ -163,12 +151,15 @@ def Binman(options, args):
             # without changing the device-tree size, thus ensuring that our
             # entry offsets remain the same.
             for image in images.values():
+                image.ExpandEntries()
                 if options.update_fdt:
                     image.AddMissingProperties()
                 image.ProcessFdt(dtb)
 
-            dtb.Pack()
-            dtb.Flush()
+            for dtb_item in state.GetFdts():
+                dtb_item.Sync(auto_resize=True)
+                dtb_item.Pack()
+                dtb_item.Flush()
 
             for image in images.values():
                 # Perform all steps for this image, including checking and
@@ -177,19 +168,30 @@ def Binman(options, args):
                 # completed and written, but that does not seem important.
                 image.GetEntryContents()
                 image.GetEntryOffsets()
-                image.PackEntries()
-                image.CheckSize()
-                image.CheckEntries()
+                try:
+                    image.PackEntries()
+                    image.CheckSize()
+                    image.CheckEntries()
+                except Exception as e:
+                    if options.map:
+                        fname = image.WriteMap()
+                        print("Wrote map file '%s' to show errors"  % fname)
+                    raise
                 image.SetImagePos()
                 if options.update_fdt:
                     image.SetCalculatedProperties()
+                    for dtb_item in state.GetFdts():
+                        dtb_item.Sync()
                 image.ProcessEntryContents()
                 image.WriteSymbols()
                 image.BuildImage()
                 if options.map:
                     image.WriteMap()
-            with open(fname, 'wb') as outfd:
-                outfd.write(dtb.GetContents())
+
+            # Write the updated FDTs to our output files
+            for dtb_item in state.GetFdts():
+                tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
+
         finally:
             tools.FinaliseOutputDir()
     finally: