# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This module builds a firmware image.

This modules uses a few rudimentary other libraries for its activity.

Here are the names we give to the various files we deal with. It is important
to keep these consistent!

  uboot     u-boot.bin (with no device tree)
  fdt       the fdt blob
  bct       the BCT file
  bootstub  uboot + fdt
  signed    (uboot + fdt + bct) signed blob
"""

import glob
import hashlib
import os
import re

from fdt import Fdt
from pack_firmware import PackFirmware
import shutil
import struct
from flashmaps import default_flashmaps
from tools import CmdError
from exynos import ExynosBl2

# Build GBB flags.
# (src/platform/vboot_reference/firmware/include/gbb_header.h)
gbb_flag_properties = {
  'dev-screen-short-delay': 0x00000001,
  'load-option-roms': 0x00000002,
  'enable-alternate-os': 0x00000004,
  'force-dev-switch-on': 0x00000008,
  'force-dev-boot-usb': 0x00000010,
  'disable-fw-rollback-check': 0x00000020,
  'enter-triggers-tonorm': 0x00000040,
  'force-dev-boot-legacy': 0x00000080,
  'faft-key-overide': 0x00000100,
  'disable-ec-software-sync': 0x00000200,
  'default-dev-boot-legacy': 0x00000400,
  'disable-pd-software-sync': 0x00000800,
  'force-dev-boot-fastboot-full-cap': 0x00002000,
  'enable-serial': 0x00004000,
}

# Maps board name to Exynos product number
type_to_model = {
  'peach' : '5420',
  'daisy' : '5250'
}

def ListGoogleBinaryBlockFlags():
  """Print out a list of GBB flags."""
  print '   %-30s %s' % ('Available GBB flags:', 'Hex')
  for name, value in gbb_flag_properties.iteritems():
    print '   %-30s %02x' % (name, value)

class BlobDeferral(Exception):
  """An error indicating deferal of blob generation."""
  pass

class Bundle:
  """This class encapsulates the entire bundle firmware logic.

  Sequence of events:
    bundle = Bundle(tools.Tools(), cros_output.Output())
    bundle.SetDirs(...)
    bundle.SetFiles(...)
    bundle.SetOptions(...)
    bundle.SelectFdt(fdt.Fdt('filename.dtb')
    .. can call bundle.AddConfigList(), AddEnableList() if required
    bundle.Start(...)

  Public properties:
    fdt: The fdt object that we use for building our image. This wil be the
        one specified by the user, except that we might add config options
        to it. This is set up by SelectFdt() which must be called before
        bundling starts.
    uboot_fname: Full filename of the U-Boot binary we use.
    bct_fname: Full filename of the BCT file we use.
    spl_source: Source device to load U-Boot from, in SPL:
        straps: Select device according to CPU strap pins
        spi: Boot from SPI
        emmc: Boot from eMMC

  Private attributes:
    _small: True to create a 'small' signed U-Boot, False to produce a
        full image. The small U-Boot is enough to boot but will not have
        access to GBB, RW U-Boot, etc.
  """

  def __init__(self, tools, output):
    """Set up a new Bundle object.

    Args:
      tools: A tools.Tools object to use for external tools.
      output: A cros_output.Output object to use for program output.
    """
    self._tools = tools
    self._out = output

    # Set up the things we need to know in order to operate.
    self._board = None          # Board name, e.g. nyan.
    self._fdt_fname = None      # Filename of our FDT.
    self._force_rw = None
    self._force_efs = None
    self._gbb_flags = None
    self._keydir = None
    self._small = False
    self.bct_fname = None       # Filename of our BCT file.
    self.blobs = {}             # Table of (type, filename) of arbitrary blobs
    self.bmpblk_fname = None    # Filename of our Bitmap Block
    self.coreboot_elf = None
    self.coreboot_fname = None  # Filename of our coreboot binary.
    self.ecro_fname = None      # Filename of EC read-only file
    self.ecrw_fname = None      # Filename of EC file
    self.pdrw_fname = None      # Filename of PD file
    self.exynos_bl1 = None      # Filename of Exynos BL1 (pre-boot)
    self.exynos_bl2 = None      # Filename of Exynos BL2 (SPL)
    self.fdt = None             # Our Fdt object.
    self.kernel_fname = None
    self.seabios_fname = None   # Filename of our SeaBIOS payload.
    self.skeleton_fname = None  # Filename of Coreboot skeleton file
    self.uboot_fname = None     # Filename of our U-Boot binary.

  def SetDirs(self, keydir):
    """Set up directories required for Bundle.

    Args:
      keydir: Directory containing keys to use for signing firmware.
    """
    self._keydir = keydir

  def SetFiles(self, board, bct, uboot=None, bmpblk=None, coreboot=None,
               coreboot_elf=None,
               seabios=None, exynos_bl1=None, exynos_bl2=None,
               skeleton=None, ecrw=None, ecro=None, pdrw=None,
               kernel=None, blobs=None, skip_bmpblk=False, cbfs_files=None,
               rocbfs_files=None):
    """Set up files required for Bundle.

    Args:
      board: The name of the board to target (e.g. nyan).
      uboot: The filename of the u-boot.bin image to use.
      bct: The filename of the binary BCT file to use.
      bmpblk: The filename of bitmap block file to use.
      coreboot: The filename of the coreboot image to use (on x86).
      coreboot_elf: If not none, the ELF file to add as a Coreboot payload.
      seabios: The filename of the SeaBIOS payload to use if any.
      exynos_bl1: The filename of the exynos BL1 file
      exynos_bl2: The filename of the exynos BL2 file (U-Boot spl)
      skeleton: The filename of the coreboot skeleton file.
      ecrw: The filename of the EC (Embedded Controller) read-write file.
      ecro: The filename of the EC (Embedded Controller) read-only file.
      pdrw: The filename of the PD (PD embedded controller) read-write file.
      kernel: The filename of the kernel file if any.
      blobs: List of (type, filename) of arbitrary blobs.
      skip_bmpblk: True if no bmpblk is required
      cbfs_files: Root directory of files to be stored in RO and RW CBFS
      rocbfs_files: Root directory of files to be stored in RO CBFS
    """
    self._board = board
    self.uboot_fname = uboot
    self.bct_fname = bct
    self.bmpblk_fname = bmpblk
    self.coreboot_fname = coreboot
    self.coreboot_elf = coreboot_elf
    self.seabios_fname = seabios
    self.exynos_bl1 = exynos_bl1
    self.exynos_bl2 = exynos_bl2
    self.skeleton_fname = skeleton
    self.ecrw_fname = ecrw
    self.ecro_fname = ecro
    self.pdrw_fname = pdrw
    self.kernel_fname = kernel
    self.blobs = dict(blobs or ())
    self.skip_bmpblk = skip_bmpblk
    self.cbfs_files = cbfs_files
    self.rocbfs_files = rocbfs_files

  def SetOptions(self, small, gbb_flags, force_rw=False, force_efs=False):
    """Set up options supported by Bundle.

    Args:
      small: Only create a signed U-Boot - don't produce the full packed
          firmware image. This is useful for devs who want to replace just the
          U-Boot part while keeping the keys, gbb, etc. the same.
      gbb_flags: Specification for string containing adjustments to make.
      force_rw: Force firmware into RW mode.
      force_efs: Force firmware to use 'early firmware selection' feature,
          where RW firmware is selected before SDRAM is initialized.
    """
    self._small = small
    self._gbb_flags = gbb_flags
    self._force_rw = force_rw
    self._force_efs = force_efs

  def _GetBuildRoot(self):
    """Get the path to this board's 'firmware' directory.

    Returns:
      Path to firmware directory, with ## representing the path to the
      chroot.
    """
    if not self._board:
      raise ValueError('No board defined - please define a board to use')
    return os.path.join('##', 'build', self._board, 'firmware')

  def _CheckFdtFilename(self, fname):
    """Check provided FDT filename and return the correct name if needed.

    Where the filename lacks a path, add a default path for this board.
    Where no FDT filename is provided, select a default one for this board.

    Args:
      fname: Proposed FDT filename.

    Returns:
      Selected FDT filename, after validation.
    """
    build_root = self._GetBuildRoot()
    dir_name = os.path.join(build_root, 'dtb')
    if not fname:
      # Figure out where the file should be, and the name we expect.
      base_name = re.sub('_', '-', self._board)

      # In case the name exists with a prefix or suffix, find it.
      wildcard = os.path.join(dir_name, '*%s.dtb' % base_name)
      found_list = glob.glob(self._tools.Filename(wildcard))
      if len(found_list) == 1:
        fname = found_list[0]
      else:
        # We didn't find anything definite, so set up our expected name.
        fname = os.path.join(dir_name, '%s.dtb' % base_name)

    # Convert things like 'exynos5250-daisy' into a full path.
    root, ext = os.path.splitext(fname)
    if not ext and not os.path.dirname(root):
      fname = os.path.join(dir_name, '%s.dtb' % root)
    return fname

  def CheckOptions(self):
    """Check provided options and select defaults."""
    build_root = self._GetBuildRoot()

    board_type = self._board.split('_')[0]
    model = type_to_model.get(board_type)

    if not self.uboot_fname:
      self.uboot_fname = os.path.join(build_root, 'u-boot.bin')
    if not self.bct_fname:
      self.bct_fname = os.path.join(build_root, 'bct', 'board.bct')
    if not self.bmpblk_fname:
      self.bmpblk_fname = os.path.join(build_root, 'bmpblk.bin')
    if model:
      if not self.exynos_bl1:
        self.exynos_bl1 = os.path.join(build_root, 'u-boot.bl1.bin')
      if not self.exynos_bl2:
        self.exynos_bl2 = os.path.join(build_root, 'u-boot-spl.wrapped.bin')
    if not self.coreboot_fname:
      self.coreboot_fname = os.path.join(build_root, 'coreboot.rom')
    if not self.skeleton_fname:
      self.skeleton_fname = os.path.join(build_root, 'coreboot.rom')
    if not self.seabios_fname:
      self.seabios_fname = 'seabios.cbfs'
    if not self.ecrw_fname:
      self.ecrw_fname = os.path.join(build_root, 'ec.RW.bin')
    if not self.pdrw_fname:
      self.pdrw_fname = os.path.join(build_root, 'pd.RW.bin')
    if not self.ecro_fname:
      self.ecro_fname = os.path.join(build_root, 'ec.RO.bin')

  def GetFiles(self):
    """Get a list of files that we know about.

    This is the opposite of SetFiles except that we may have put in some
    default names. It returns a dictionary containing the filename for
    each of a number of pre-defined files.

    Returns:
      Dictionary, with one entry for each file.
    """
    file_list = {
        'bct' : self.bct_fname,
        'exynos-bl1' : self.exynos_bl1,
        'exynos-bl2' : self.exynos_bl2,
        }
    return file_list

  def DecodeGBBFlagsFromFdt(self):
    """Get Google Binary Block flags from the FDT.

    These should be in the chromeos-config node, like this:

      chromeos-config {
                  gbb-flag-dev-screen-short-delay;
                  gbb-flag-force-dev-switch-on;
                  gbb-flag-force-dev-boot-usb;
                  gbb-flag-disable-fw-rollback-check;
      };

    Returns:
      GBB flags value from FDT.
    """
    chromeos_config = self.fdt.GetProps("/chromeos-config")
    gbb_flags = 0
    for name in chromeos_config:
      if name.startswith('gbb-flag-'):
        flag_value = gbb_flag_properties.get(name[9:])
        if flag_value:
          gbb_flags |= flag_value
          self._out.Notice("FDT: Enabling %s." % name)
        else:
          raise ValueError("FDT contains invalid GBB flags '%s'" % name)
    return gbb_flags

  def DecodeGBBFlagsFromOptions(self, gbb_flags, adjustments):
    """Decode ajustments to the provided GBB flags.

    We support three options:

       hex value: c2
       defined value: force-dev-boot-usb,load-option-roms
       adjust default value: -load-option-roms,+force-dev-boot-usb

    The last option starts from the passed-in GBB flags and adds or removes
    flags.

    Args:
      gbb_flags: Base (default) FDT flags.
      adjustments: String containing adjustments to make.

    Returns:
      Updated FDT flags.
    """
    use_base_value = True
    if adjustments:
      try:
        return int(adjustments, base=16)
      except (ValueError, TypeError):
        pass
      for flag in adjustments.split(','):
        oper = None
        if flag[0] in ['-', '+']:
          oper = flag[0]
          flag = flag[1:]
        value = gbb_flag_properties.get(flag)
        if not value:
          raise ValueError("Invalid GBB flag '%s'" % flag)
        if oper == '+':
          gbb_flags |= value
          self._out.Notice("Cmdline: Enabling %s." % flag)
        elif oper == '-':
          gbb_flags &= ~value
          self._out.Notice("Cmdline: Disabling %s." % flag)
        else:
          if use_base_value:
            gbb_flags = 0
            use_base_value = False
            self._out.Notice('Cmdline: Resetting flags to 0')
          gbb_flags |= value
          self._out.Notice("Cmdline: Enabling %s." % flag)

    return gbb_flags

  def _CreateGoogleBinaryBlock(self, hardware_id):
    """Create a GBB for the image.

    Args:
      hardware_id: Hardware ID to use for this board. If None, then the
          default from the Fdt will be used

    Returns:
      Path of the created GBB file.
    """
    if not hardware_id:
      hardware_id = self.fdt.GetString('/config', 'hwid')
    gbb_size = self.fdt.GetFlashPartSize('ro', 'gbb')
    odir = self._tools.outdir

    gbb_flags = self.DecodeGBBFlagsFromFdt()

    # Allow command line to override flags
    gbb_flags = self.DecodeGBBFlagsFromOptions(gbb_flags, self._gbb_flags)

    self._out.Notice("GBB flags value %#x" % gbb_flags)
    self._out.Progress('Creating GBB')
    if self.skip_bmpblk:
        bmpfv_size = 0
    else:
        bmpfv_size = gbb_size - 0x2180
    sizes = [0x100, 0x1000, bmpfv_size, 0x1000]
    sizes = ['%#x' % size for size in sizes]
    gbb = 'gbb.bin'
    keydir = self._tools.Filename(self._keydir)

    gbb_set_command = ['-s',
                       '--hwid=%s' % hardware_id,
                       '--rootkey=%s/root_key.vbpubk' % keydir,
                       '--recoverykey=%s/recovery_key.vbpubk' % keydir,
                       '--flags=%d' % gbb_flags,
                       gbb]
    if not self.skip_bmpblk:
      gbb_set_command[-1:-1] = ['--bmpfv=%s' % self._tools.Filename(
          self.bmpblk_fname),]

    self._tools.Run('gbb_utility', ['-c', ','.join(sizes), gbb], cwd=odir)
    self._tools.Run('gbb_utility', gbb_set_command, cwd=odir)
    return os.path.join(odir, gbb)

  def _SignBootstub(self, bct, bootstub, text_base):
    """Sign an image so that the Tegra SOC will boot it.

    Args:
      bct: BCT file to use.
      bootstub: Boot stub (U-Boot + fdt) file to sign.
      text_base: Address of text base for image.

    Returns:
      filename of signed image.
    """
    # First create a config file - this is how we instruct cbootimage
    signed = os.path.join(self._tools.outdir, 'signed.bin')
    self._out.Progress('Signing Bootstub')
    config = os.path.join(self._tools.outdir, 'boot.cfg')
    fd = open(config, 'w')
    fd.write('Version    = 1;\n')
    fd.write('Redundancy = 1;\n')
    fd.write('Bctfile    = %s;\n' % bct)

    # TODO(dianders): Right now, we don't have enough space in our flash map
    # for two copies of the BCT when we're using NAND, so hack it to 1.  Not
    # sure what this does for reliability, but at least things will fit...
    is_nand = "NvBootDevType_Nand" in self._tools.Run('bct_dump', [bct])
    if is_nand:
      fd.write('Bctcopy = 1;\n')

    fd.write('BootLoader = %s,%#x,%#x,Complete;\n' % (bootstub, text_base,
        text_base))

    fd.close()

    self._tools.Run('cbootimage', [config, signed])
    self._tools.OutputSize('BCT', bct)
    self._tools.OutputSize('Signed image', signed)
    return signed

  def SetBootcmd(self, bootcmd, bootsecure):
    """Set the boot command for U-Boot.

    Args:
      bootcmd: Boot command to use, as a string (if None this this is a nop).
      bootsecure: We'll set '/config/bootsecure' to 1 if True and 0 if False.
    """
    if bootcmd is not None:
      if bootcmd == 'none':
        bootcmd = ''
      self.fdt.PutString('/config', 'bootcmd', bootcmd)
      self.fdt.PutInteger('/config', 'bootsecure', int(bootsecure))
      self._out.Info('Boot command: %s' % bootcmd)

  def SetNodeEnabled(self, node_name, enabled):
    """Set whether an node is enabled or disabled.

    This simply sets the 'status' property of a node to "ok", or "disabled".

    The node should either be a full path to the node (like '/uart@10200000')
    or an alias property.

    Aliases are supported like this:

        aliases {
                console = "/uart@10200000";
        };

    pointing to a node:

        uart@10200000 {
                status = "okay";
        };

    In this case, this function takes the name of the alias ('console' in
    this case) and updates the status of the node that is pointed to, to
    either ok or disabled. If the alias does not exist, a warning is
    displayed.

    Args:
      node_name: Name of node (e.g. '/uart@10200000') or alias alias
          (e.g. 'console') to adjust
      enabled: True to enable, False to disable
    """
    # Look up the alias if this is an alias reference
    if not node_name.startswith('/'):
      lookup = self.fdt.GetString('/aliases', node_name, '')
      if not lookup:
        self._out.Warning("Cannot find alias '%s' - ignoring" % node_name)
        return
      node_name = lookup
    if enabled:
      status = 'okay'
    else:
      status = 'disabled'
    self.fdt.PutString(node_name, 'status', status)

  def AddEnableList(self, enable_list):
    """Process a list of nodes to enable/disable.

    Args:
      enable_list: List of (node, value) tuples to add to the fdt. For each
          tuple:
              node: The fdt node to write to will be <node> or pointed to by
                  /aliases/<node>. We can tell which
              value: 0 to disable the node, 1 to enable it

    Raises:
      CmdError if a command fails.
    """
    if enable_list:
      for node_name, enabled in enable_list:
        try:
          enabled = int(enabled)
          if enabled not in (0, 1):
            raise ValueError
        except ValueError:
          raise CmdError("Invalid enable option value '%s' "
              "(should be 0 or 1)" % str(enabled))
        self.SetNodeEnabled(node_name, enabled)

  def AddConfigList(self, config_list, use_int=False):
    """Add a list of config items to the fdt.

    Normally these values are written to the fdt as strings, but integers
    are also supported, in which case the values will be converted to integers
    (if necessary) before being stored.

    Args:
      config_list: List of (config, value) tuples to add to the fdt. For each
          tuple:
              config: The fdt node to write to will be /config/<config>.
              value: An integer or string value to write.
      use_int: True to only write integer values.

    Raises:
      CmdError: if a value is required to be converted to integer but can't be.
    """
    if config_list:
      for config in config_list:
        value = config[1]
        if use_int:
          try:
            value = int(value)
          except ValueError:
            raise CmdError("Cannot convert config option '%s' to integer" %
                str(value))
        if type(value) == type(1):
          self.fdt.PutInteger('/config', '%s' % config[0], value)
        else:
          self.fdt.PutString('/config', '%s' % config[0], value)

  def DecodeTextBase(self, data):
    """Look at a U-Boot image and try to decode its TEXT_BASE.

    This works because U-Boot has a header with the value 0x12345678
    immediately followed by the TEXT_BASE value. We can therefore read this
    from the image with some certainty. We check only the first 40 words
    since the header should be within that region.

    Since upstream Tegra has moved to having a 16KB SPL region at the start,
    and currently this does holds the U-Boot text base (e.g. 0x10c000) instead
    of the SPL one (e.g. 0x108000), we search in the U-Boot part as well.

    Args:
      data: U-Boot binary data

    Returns:
      Text base (integer) or None if none was found
    """
    found = False
    for start in (0, 0x4000):
      for i in range(start, start + 160, 4):
        word = data[i:i + 4]

        # TODO(sjg): This does not cope with a big-endian target
        value = struct.unpack('<I', word)[0]
        if found:
          return value - start
        if value == 0x12345678:
          found = True

    return None

  def CalcTextBase(self, name, fdt, fname):
    """Calculate the TEXT_BASE to use for U-Boot.

    Normally this value is in the fdt, so we just read it from there. But as
    a second check we look at the image itself in case this is different, and
    switch to that if it is.

    This allows us to flash any U-Boot even if its TEXT_BASE is different.
    This is particularly useful with upstream U-Boot which uses a different
    value (which we will move to).
    """
    data = self._tools.ReadFile(fname)
    # The value that comes back from fdt.GetInt is signed, which makes no
    # sense for an address base.  Force it to unsigned.
    fdt_text_base = fdt.GetInt('/chromeos-config', 'textbase', 0) & 0xffffffff
    text_base = self.DecodeTextBase(data)
    text_base_str = '%#x' % text_base if text_base else 'None'
    self._out.Info('TEXT_BASE: fdt says %#x, %s says %s' % (fdt_text_base,
        fname, text_base_str))

    # If they are different, issue a warning and switch over.
    if text_base and text_base != fdt_text_base:
      self._out.Warning("TEXT_BASE %x in %sU-Boot doesn't match "
              "fdt value of %x. Using %x" % (text_base, name,
                  fdt_text_base, text_base))
      fdt_text_base = text_base
    return fdt_text_base

  def _CreateBootStub(self, uboot, base_fdt):
    """Create a boot stub and a signed boot stub.

    Args:
      uboot: Path to u-boot.bin (may be chroot-relative).
      base_fdt: Fdt object containing the flat device tree.

    Returns:
      Tuple containing:
        Full path to bootstub (uboot + fdt(-1)).
        Full path to signed (uboot + fdt(flash pos) + bct).

    Raises:
      CmdError if a command fails.
    """
    bootstub = os.path.join(self._tools.outdir, 'u-boot-fdt.bin')
    text_base = self.CalcTextBase('', self.fdt, uboot)
    uboot_data = self._tools.ReadFile(uboot)

    # Make a copy of the fdt for the bootstub
    fdt = base_fdt.Copy(os.path.join(self._tools.outdir, 'bootstub.dtb'))
    fdt_data = self._tools.ReadFile(fdt.fname)

    self._tools.WriteFile(bootstub, uboot_data + fdt_data)
    self._tools.OutputSize('U-Boot binary', self.uboot_fname)
    self._tools.OutputSize('U-Boot fdt', self._fdt_fname)
    self._tools.OutputSize('Combined binary', bootstub)

    # Sign the bootstub; this is a combination of the board specific
    # bct and the stub u-boot image.
    signed = self._SignBootstub(self._tools.Filename(self.bct_fname),
        bootstub, text_base)

    self._tools.OutputSize('Final bootstub', signed)

    return bootstub, signed

  def _AddCbfsFiles(self, bootstub, cbfs_files):
    for dir, subs, files in os.walk(cbfs_files):
      for file in files:
        file = os.path.join(dir, file)
        cbfs_name = file.replace(cbfs_files, '', 1).strip('/')
        self._tools.Run('cbfstool', [bootstub, 'add', '-f', file,
                                '-n', cbfs_name, '-t', 'raw', '-c', 'lzma'])

  def _CreateCorebootStub(self, pack, coreboot):
    """Create a coreboot boot stub and add pack properties.

    Args:
      pack: a PackFirmware object describing the firmware image to build.
      coreboot: Path to coreboot.rom
    """
    bootstub = os.path.join(self._tools.outdir, 'coreboot-full.rom')
    shutil.copyfile(self._tools.Filename(coreboot), bootstub)

    pack.AddProperty('coreboot', bootstub)
    pack.AddProperty('image', bootstub)

    # Add files to to RO and RW CBFS if provided.
    if self.cbfs_files:
      self._AddCbfsFiles(bootstub, self.cbfs_files)

    # Create a coreboot copy to use as a scratch pad. Order matters. The
    # cbfs_files were added prior to this action. That's so the RW CBFS
    # regions inherit the files from the RO CBFS region. Additionally,
    # include the full FMAP within the file.
    cb_copy = os.path.abspath(os.path.join(self._tools.outdir, 'cb_with_fmap'))
    self._tools.WriteFile(cb_copy, self._tools.ReadFile(bootstub))
    binary = self._tools.ReadFile(bootstub)
    fmap_offset, fmap = pack.GetFmap()
    if len(binary) < fmap_offset + len(fmap):
        raise CmdError('FMAP will not fit')
    # Splice in FMAP data.
    binary = binary[:fmap_offset] + fmap + binary[fmap_offset + len(fmap):]
    self._tools.WriteFile(cb_copy, binary)
    # Publish where coreboot is with the FMAP data.
    pack.AddProperty('cb_with_fmap', cb_copy)

    # Add files to to RO CBFS if provided. This done here such that the
    # copy above does not contain the RO CBFS files.
    if self.rocbfs_files:
      self._AddCbfsFiles(bootstub, self.rocbfs_files)


  def _PackOutput(self, msg):
    """Helper function to write output from PackFirmware (verbose level 2).

    This is passed to PackFirmware for it to use to write output.

    Args:
      msg: Message to display.
    """
    self._out.Notice(msg)

  def _FmapNameByPath(self, path):
    """ Take list of names to form node path. Return FMAP name.

    Obtain the FMAP name described by the node path.

    Args:
      path: list forming a node path.

    Returns:
      FMAP name of fdt node.

    Raises:
      CmdError if path not found.
    """
    lbl = self.fdt.GetLabel(self.fdt.GetFlashNode(*path))
    return re.sub('-', '_', lbl).upper()

  def _PrepareCbfsHash(self, pack, blob_name):
    """Create blob in rw-{a,b}-boothash with 'cbfstool hashcbfs'.

    When the blob name is defined as cbfshash/<section>/<subsection>, fill the
    <section>_<subsection> area in the flash map with CBFS hash generated
    using the 'cbfstool hashcbfs' command.

    Args:
      pack: a PackFirmware object describing the firmware image to build.
      blob_name: a string, blob name describing what FMAP section this CBFS
                 copy is destined to
    Raises:
      CmdError if cbfs-files node has incorrect parameters.
      BlobDeferral if the CBFS region is not populated yet or if the coreboot
      image with fmap is not available yet.
    """
    cb_copy = pack.GetProperty('cb_with_fmap')
    if cb_copy is None:
      raise BlobDeferral("Waiting for '%s'" % cb_copy)

    part_sections = blob_name.split('/')[1:]
    fmap_dst = self._FmapNameByPath(part_sections)

    # Example of FDT ndoes asking for CBFS hash:
    #  rw-b-boot {
    #          label = "fw-main-b";
    #          reg = <0x00700000 0x002dff80>;
    #          type = "blob cbfs/rw/b-boot";
    #  };
    #  rw-b-boothash {
    #          label = "fw-main-b-hash";
    #          reg = <0x009dff80 0x00000040>;
    #          type = "blob cbfshash/rw/b-boothash";
    #          cbfs-node = "cbfs/rw/b-boot";
    #  };
    hash_node = self.fdt.GetFlashNode(*part_sections)
    cbfs_blob_name =  self.fdt.GetString(hash_node, 'cbfs-node')

    if not pack.GetProperty(cbfs_blob_name):
      raise BlobDeferral("Waiting for '%s'" % cbfs_blob_name)

    cbfs_node_path = cbfs_blob_name.split('/')[1:]
    fmap_src = self._FmapNameByPath(cbfs_node_path)

    # Compute CBFS hash and place it in the corect spot.
    self._tools.Run('cbfstool', [cb_copy, 'hashcbfs', '-r', fmap_dst,
                                 '-R', fmap_src, '-A', 'sha256'])

    # Base address and size of the desitnation partition
    base, size = self.fdt.GetFlashPart(*part_sections)

    # And extract the blob for the FW section
    rw_section = os.path.join(self._tools.outdir, '_'.join(part_sections))
    self._tools.WriteFile(rw_section,
                          self._tools.ReadFile(cb_copy)[base:base+size])

    pack.AddProperty(blob_name, rw_section)


  def _PrepareCbfs(self, pack, blob_name):
    """Create CBFS blob in rw-boot-{a,b} FMAP sections.

    When the blob name is defined as cbfs#<section>#<subsection>, fill the
    <section>_<subsection> area in the flash map with a CBFS copy, putting the
    CBFS header of the copy at the base of the section.

    If --coreboot-elf parameter was specified during cros_bumdle_firmware
    invocation, add the parameter of this option as the payload to the new
    CBFS instance.

    Args:
      pack: a PackFirmware object describing the firmware image to build.
      blob_name: a string, blob name describing what FMAP section this CBFS
                 copy is destined to
    Raises:
      CmdError if cbfs-files node has incorrect parameters.
      BlobDeferral if coreboot image with fmap is not available yet.
    """
    cb_copy = pack.GetProperty('cb_with_fmap')
    if cb_copy is None:
      raise BlobDeferral("Waiting for 'cb_with_fmap' property")

    part_sections = blob_name.split('/')[1:]
    fmap_dst = self._FmapNameByPath(part_sections)

    # Base address and size of the desitnation partition
    base, size = self.fdt.GetFlashPart(*part_sections)

    # 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.
    if self.uboot_fname:
      payload_fname = self.uboot_fname
    elif self.coreboot_elf:
      payload_fname = self.coreboot_elf
    else:
      payload_fname = None

    if payload_fname:
      self._tools.Run('cbfstool', [
        cb_copy, 'add-payload', '-f', payload_fname,
        '-n', 'fallback/payload', '-c', 'lzma' , '-r', fmap_dst])

    if self.ecrw_fname:
      self._tools.Run('cbfstool', [
        cb_copy, 'add', '-f', self.ecrw_fname, '-t', 'raw',
        '-n', 'ecrw', '-A', 'sha256', '-r', fmap_dst ])

    if self.pdrw_fname:
      self._tools.Run('cbfstool', [
        cb_copy, 'add', '-f', self.pdrw_fname, '-t', 'raw',
        '-n', 'pdrw', '-A', 'sha256', '-r', fmap_dst ])

    # 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))
    self._tools.WriteFile(rw_section,
                          self._tools.ReadFile(cb_copy)[base:base+size])

    pack.AddProperty(blob_name, rw_section)


  def _BuildBlob(self, pack, fdt, blob_type):
    """Build the blob data for a particular blob type.

    Args:
      pack: a PackFirmware object describing the firmware image to build.
      fdt: an fdt object including image layout information
      blob_type: The type of blob to create data for. Supported types are:
          coreboot    A coreboot image (ROM plus U-boot and .dtb payloads).
          signed      Nvidia T20/T30 signed image (BCT, U-Boot, .dtb).

    Raises:
      CmdError if a command fails.
      BlobDeferral if a blob is waiting for a dependency.
    """
    # stupid pylint insists that sha256 is not in hashlib.
    # pylint: disable=E1101
    if blob_type == 'coreboot':
      self._CreateCorebootStub(pack, self.coreboot_fname)
    elif blob_type == 'legacy':
      pack.AddProperty('legacy', self.seabios_fname)
    elif blob_type == 'signed':
      bootstub, signed = self._CreateBootStub(self.uboot_fname, fdt, None)
      pack.AddProperty('bootstub', bootstub)
      pack.AddProperty('signed', signed)
      pack.AddProperty('image', signed)
    elif blob_type == 'exynos-bl1':
      pack.AddProperty(blob_type, self.exynos_bl1)

    # TODO(sjg@chromium.org): Deprecate ecbin
    elif blob_type in ['ecrw', 'ecbin']:
      pack.AddProperty('ecrw', self.ecrw_fname)
      pack.AddProperty('ecbin', self.ecrw_fname)
    elif blob_type == 'pdrw':
      pack.AddProperty('pdrw', self.pdrw_fname)
    elif blob_type == 'ecrwhash':
      ec_hash_file = os.path.join(self._tools.outdir, 'ec_hash.bin')
      ecrw = self._tools.ReadFile(self.ecrw_fname)
      hasher = hashlib.sha256()
      hasher.update(ecrw)
      self._tools.WriteFile(ec_hash_file, hasher.digest())
      pack.AddProperty(blob_type, ec_hash_file)
    elif blob_type == 'pdrwhash':
      pd_hash_file = os.path.join(self._tools.outdir, 'pd_hash.bin')
      pdrw = self._tools.ReadFile(self.pdrw_fname)
      hasher = hashlib.sha256()
      hasher.update(pdrw)
      self._tools.WriteFile(pd_hash_file, hasher.digest())
      pack.AddProperty(blob_type, pd_hash_file)
    elif blob_type == 'ecro':
      # crosbug.com/p/13143
      # We cannot have an fmap in the EC image since there can be only one,
      # which is the main fmap describing the whole image.
      # Ultimately the EC will not have an fmap, since with software sync
      # there is no flashrom involvement in updating the EC flash, and thus
      # no need for the fmap.
      # For now, mangle the fmap name to avoid problems.
      updated_ecro = os.path.join(self._tools.outdir, 'updated-ecro.bin')
      data = self._tools.ReadFile(self.ecro_fname)
      data = re.sub('__FMAP__', '__fMAP__', data)
      self._tools.WriteFile(updated_ecro, data)
      pack.AddProperty(blob_type, updated_ecro)
    elif blob_type.startswith('exynos-bl2'):
      # We need to configure this per node, so do it later
      pass
    elif blob_type.startswith('cbfshash'):
      self._PrepareCbfsHash(pack, blob_type)
    elif blob_type.startswith('cbfs'):
      self._PrepareCbfs(pack, blob_type)
    elif pack.GetProperty(blob_type):
      pass
    elif blob_type in self.blobs:
      pack.AddProperty(blob_type, self.blobs[blob_type])
    else:
      raise CmdError("Unknown blob type '%s' required in flash map" %
          blob_type)

  def _BuildBlobs(self, pack, fdt):
    """Build the blob data for the list of blobs in the pack.

    Args:
      pack: a PackFirmware object describing the firmware image to build.
      fdt: an fdt object including image layout information

    Raises:
      CmdError if a command fails.
      BlobDeferral if dependencies cannot be met because of cycles.
    """
    blob_list = pack.GetBlobList()
    self._out.Info('Building blobs %s\n' % blob_list)

    complete = False
    deferred_list = []

    # Build blobs allowing for dependencies between blobs. While this is
    # an potential O(n^2) operation, in practice most blobs aren't dependent
    # and should resolve in a few passes.
    while not complete:
      orig = set(blob_list)
      for blob_type in blob_list:
        try:
          self._BuildBlob(pack, fdt, blob_type)
        except (BlobDeferral):
          deferred_list.append(blob_type)
      if not deferred_list:
        complete = True
      # If deferred is the same as the original no progress is being made.
      if not orig - set(deferred_list):
        raise BlobDeferral("Blob cyle '%s'" % orig)
      # Process the deferred blobs
      blob_list = deferred_list[:]
      deferred_list = []

  def _CreateImage(self, gbb, fdt):
    """Create a full firmware image, along with various by-products.

    This uses the provided u-boot.bin, fdt and bct to create a firmware
    image containing all the required parts. If the GBB is not supplied
    then this will just return a signed U-Boot as the image.

    Args:
      gbb: a string, full path to the GBB file, or empty if a GBB is not
           required.
      fdt: an fdt object containing required information.

    Returns:
      Path to image file
    """
    self._out.Notice("Model: %s" % fdt.GetString('/', 'model'))

    pack = PackFirmware(self._tools, self._out)
    if self._force_rw:
      fdt.PutInteger('/flash/rw-a-vblock', 'preamble-flags', 0)
      fdt.PutInteger('/flash/rw-b-vblock', 'preamble-flags', 0)
    if self._force_efs:
      fdt.PutInteger('/chromeos-config', 'early-firmware-selection', 1)
    pack.use_efs = fdt.GetInt('/chromeos-config', 'early-firmware-selection',
                              0)

    pack.SelectFdt(fdt, self._board)

    # Get all our blobs ready
    if self.uboot_fname:
      pack.AddProperty('boot', self.uboot_fname)
    if self.skeleton_fname:
      pack.AddProperty('skeleton', self.skeleton_fname)
    pack.AddProperty('dtb', fdt.fname)

    # If we are writing a kernel, add its offset from TEXT_BASE to the fdt.
    if self.kernel_fname:
      fdt.PutInteger('/config', 'kernel-offset', pack.image_size)

    if gbb:
      pack.AddProperty('gbb', gbb)

    # Build the blobs out.
    self._BuildBlobs(pack, fdt)

    self._out.Progress('Packing image')
    if gbb:
      pack.RequireAllEntries()
      fwid = '.'.join([
          re.sub('[ ,]+', '_', fdt.GetString('/', 'model')),
          self._tools.GetChromeosVersion()])
      self._out.Notice('Firmware ID: %s' % fwid)
      pack.AddProperty('fwid', fwid)
      pack.AddProperty('keydir', self._keydir)

    # Some blobs need to be configured according to the node they are in.
    todo = pack.GetMissingBlobs()
    for blob in todo:
      if blob.key.startswith('exynos-bl2'):
        bl2 = ExynosBl2(self._tools, self._out)
        pack.AddProperty(blob.key, bl2.MakeSpl(pack, fdt, blob,
                         self.exynos_bl2))

    pack.CheckProperties()

    # Record position and size of all blob members in the FDT
    pack.UpdateBlobPositionsAndHashes(fdt)

    # Recalculate the Exynos BL2, since it may have a hash. The call to
    # UpdateBlobPositionsAndHashes() may have updated the hash-target so we
    # need to recalculate the hash.
    for blob in todo:
      if blob.key.startswith('exynos-bl2'):
        bl2 = ExynosBl2(self._tools, self._out)
        pack.AddProperty(blob.key, bl2.MakeSpl(pack, fdt, blob,
                                               self.exynos_bl2))

    # Make a copy of the fdt for the bootstub
    fdt_data = self._tools.ReadFile(fdt.fname)
    if self.uboot_fname:
      uboot_data = self._tools.ReadFile(self.uboot_fname)
      uboot_copy = os.path.join(self._tools.outdir, 'u-boot.bin')
      self._tools.WriteFile(uboot_copy, uboot_data)

      uboot_dtb = os.path.join(self._tools.outdir, 'u-boot-dtb.bin')
      self._tools.WriteFile(uboot_dtb, uboot_data + fdt_data)

    # Fix up the coreboot image here, since we can't do this until we have
    # a final device tree binary.
    if 'coreboot' in pack.GetBlobList():
      bootstub = pack.GetProperty('coreboot')
      fdt = fdt.Copy(os.path.join(self._tools.outdir, 'bootstub.dtb'))
      if self.coreboot_elf:
        self._tools.Run('cbfstool', [bootstub, 'add-payload', '-f',
            self.coreboot_elf, '-n', 'fallback/payload', '-c', 'lzma'])
      elif self.uboot_fname:
        text_base = 0x1110000

        # This is the the 'movw $GD_FLG_COLD_BOOT, %bx' instruction
        # 1110015:       66 bb 00 01             mov    $0x100,%bx
        marker = struct.pack('<L', 0x0100bb66)
        pos = uboot_data.find(marker)
        if pos == -1 or pos > 0x100:
          raise ValueError('Cannot find U-Boot cold boot entry point')
        entry = text_base + pos
        self._out.Notice('U-Boot entry point %#08x' % entry)
        self._tools.Run('cbfstool', [bootstub, 'add-flat-binary', '-f',
            uboot_dtb, '-n', 'fallback/payload', '-c', 'lzma',
            '-l', '%#x' % text_base, '-e', '%#x' % entry])
      self._tools.Run('cbfstool', [bootstub, 'add', '-f', fdt.fname,
          '-n', 'u-boot.dtb', '-t', '0xac'])
      data = self._tools.ReadFile(bootstub)
      bootstub_copy = os.path.join(self._tools.outdir, 'coreboot-8mb.rom')
      self._tools.WriteFile(bootstub_copy, data)

      # Use offset and size from fmap.dts to extract CBFS area from coreboot.rom
      cbfs_offset, cbfs_size = fdt.GetFlashPart('ro', 'boot')
      self._tools.WriteFile(bootstub, data[cbfs_offset:cbfs_offset+cbfs_size])

    pack.AddProperty('fdtmap', fdt.fname)
    image = os.path.join(self._tools.outdir, 'image.bin')
    pack.PackImage(self._tools.outdir, image)
    pack.AddProperty('image', image)

    image = pack.GetProperty('image')
    self._tools.OutputSize('Final image', image)
    return image, pack

  def SelectFdt(self, fdt_fname, use_defaults):
    """Select an FDT to control the firmware bundling

    We make a copy of this which will include any on-the-fly changes we want
    to make.

    Args:
      fdt_fname: The filename of the fdt to use.
      use_defaults: True to use a default FDT name if available, and to add
          a full path to the provided filename if necessary.

    Returns:
      The Fdt object of the original fdt file, which we will not modify.

    Raises:
      ValueError if no FDT is provided (fdt_fname is None and use_defaults is
          False).
    """
    if use_defaults:
      fdt_fname = self._CheckFdtFilename(fdt_fname)
    if not fdt_fname:
      raise ValueError('Please provide an FDT filename')
    fdt = Fdt(self._tools, fdt_fname)
    self._fdt_fname = fdt_fname

    # For upstream, select the correct architecture .dtsi manually.
    if self._board == 'link' or 'x86' in self._board:
      arch_dts = 'coreboot.dtsi'
    elif self._board == 'daisy':
      arch_dts = 'exynos5250.dtsi'
    else:
      arch_dts = 'tegra124.dtsi'

    fdt.Compile(arch_dts)
    fdt = fdt.Copy(os.path.join(self._tools.outdir, 'updated.dtb'))

    # Get the flashmap so we know what to build. For board variants use the
    # main board name as the key (drop the _<variant> suffix).
    default_flashmap = default_flashmaps.get(self._board.split('_')[0], [])

    if not fdt.GetProp('/flash', 'reg', ''):
      fdt.InsertNodes(default_flashmap)

    # Remember our board type.
    fdt.PutString('/chromeos-config', 'board', self._board)

    self.fdt = fdt
    return fdt

  def Start(self, hardware_id, output_fname, show_map):
    """This creates a firmware bundle according to settings provided.

      - Checks options, tools, output directory, fdt.
      - Creates GBB and image.

    Args:
      hardware_id: Hardware ID to use for this board. If None, then the
          default from the Fdt will be used
      output_fname: Output filename for the image. If this is not None, then
          the final image will be copied here.
      show_map: Show a flash map, with each area's name and position

    Returns:
      Filename of the resulting image (not the output_fname copy).
    """
    if self._small or self.fdt.GetProp('/config', 'nogbb', 'any') != 'any':
      gbb = ''  # Building a small image or `nogbb' is requested in device tree.
    else:
      gbb = self._CreateGoogleBinaryBlock(hardware_id)

    # This creates the actual image.
    image, pack = self._CreateImage(gbb, self.fdt)
    if show_map:
      pack.ShowMap()
    if output_fname:
      shutil.copyfile(image, output_fname)
      self._out.Notice("Output image '%s'" % output_fname)
    return image, pack.props
