bundle_firmware: limit size of CBFS for RW slots

Now that boards are switched over to a CBFS in each RW
slot the hashing taking place is a lot more than the
component method. The reason is that 1. there's more
things within the CBFS 2. the RW slots weren't always
fully utilized. To gain back more boot speed limit
the size of the CBFS that is hashed in the RW slots.

This is accomplished by taking advatage of the cbfstool
'compact' command which removes empty file fragmentation
from CBFS regions. This command is invoked for nodes
which contin a cbfs-files subnode. Additionally, the
cbfstool 'print' command is ran with a parseable option
which allows limiting the CBFS region to be hashed by
changing the size of the region to the offset of the
last file if it is empty. i.e. if the last file entry
is empty there's no need to include it in the hashed

Lastly, there's no reason to include a master header
within the RW slots so remove that as well.

TEST=Built and booted chell with cbfstool and dev-util patches.

Change-Id: I1be6b3c7f3a780bff343e32333ba790f42ad09b8
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Previous-Reviewed-on: https://chromium-review.googlesource.com/324023
(cherry picked from commit 152e76150ee0ebadf71716be8afa0efeae999e3f)
Reviewed-on: https://chromium-review.googlesource.com/325055
Tested-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Commit-Queue: Duncan Laurie <dlaurie@chromium.org>
diff --git a/host/lib/bundle_firmware.py b/host/lib/bundle_firmware.py
index ef3880e..2c3fa49 100644
--- a/host/lib/bundle_firmware.py
+++ b/host/lib/bundle_firmware.py
@@ -785,6 +785,11 @@
         except CmdError:
           pass # the most likely error is that the file doesn't already exist
+      # Compact the CBFS image after removing the files so all the non-empty
+      # files are at the beginning of the region.
+      self._tools.Run('sh', [ '-c',
+        ' '.join(['cbfstool', cb_copy, 'compact', '-r', fmap_dst]) ])
       # now add the files
       for val in cbfs_config.itervalues():
         f = val.split(' ')
@@ -967,10 +972,6 @@
     self._tools.Run('cbfstool', [cb_copy, 'copy', '-r', fmap_dst,
                                  '-R', fmap_src])
-    # Add a CBFS master header for good measure
-    self._tools.Run('cbfstool', [cb_copy, 'add-master-header',
-                                 '-r', fmap_dst])
     # Add coreboot payload if so requested. Note that the some images use
     # different payload for the rw sections, which is passed in as the value
     # of the --uboot option in the command line.
@@ -1000,6 +1001,16 @@
     node = self.fdt.GetFlashNode(*part_sections)
     self._ProcessCbfsFileProperty(cb_copy, node)
+    # Parse the file list to obtain the last entry. If its empty use its
+    # offset as the size of the CBFS to hash.
+    stdout = self._tools.Run('cbfstool',
+        [ cb_copy, 'print', '-k', '-r', fmap_dst ])
+    # Fields are tab separated in the following order.
+    # Name    Offset  Type    Metadata Size   Data Size       Total Size
+    last_entry = stdout.strip().splitlines()[-1].split('\t')
+    if last_entry[0] == '(empty)' and last_entry[2] == 'null':
+        size = int(last_entry[1], 16)
     # And extract the blob for the FW section
     rw_section = os.path.join(self._tools.outdir, '_'.join(part_sections))