# 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

# This data is required by bmpblk_utility. Does it ever change?
# It was stored with the chromeos-bootimage ebuild, but we want
# this utility to work outside the chroot.
yaml_data = '''
bmpblock: 1.0

images:
    devmode:    DeveloperBmp/DeveloperBmp.bmp
    recovery:   RecoveryBmp/RecoveryBmp.bmp
    rec_yuck:   RecoveryNoOSBmp/RecoveryNoOSBmp.bmp
    rec_insert: RecoveryMissingOSBmp/RecoveryMissingOSBmp.bmp

screens:
  dev_en:
    - [0, 0, devmode]
  rec_en:
    - [0, 0, recovery]
  yuck_en:
    - [0, 0, rec_yuck]
  ins_en:
    - [0, 0, rec_insert]

localizations:
  - [ dev_en, rec_en, yuck_en, ins_en ]
'''

# 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,
}

# 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 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.postload_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,
               postload=None, seabios=None, exynos_bl1=None, exynos_bl2=None,
               skeleton=None, ecrw=None, ecro=None, pdrw=None,
               kernel=None, blobs=None, skip_bmpblk=False):
    """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.
      postload: The filename of the u-boot-post.bin image to use.
      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
    """
    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.postload_fname = postload
    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

  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')
    sizes = [0x100, 0x1000, gbb_size - 0x2180, 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, postload):
    """Create a boot stub and a signed boot stub.

    For postload:
    We add a /config/postload-text-offset entry to the signed bootstub's
    fdt so that U-Boot can find the postload code.

    The raw (unsigned) bootstub will have a value of -1 for this since we will
    simply append the postload code to the bootstub and it can find it there.
    This will be used for RW A/B firmware.

    For the signed case this value will specify where in the flash to find
    the postload code. This will be used for RO firmware.

    Args:
      uboot: Path to u-boot.bin (may be chroot-relative)
      base_fdt: Fdt object containing the flat device tree.
      postload: Path to u-boot-post.bin, or None if none.

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

    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.PutInteger('/config', 'postload-text-offset', 0xffffffff)
    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)

    signed_postload = os.path.join(self._tools.outdir, 'signed-postload.bin')
    data = self._tools.ReadFile(signed)

    if postload:
      # We must add postload to the bootstub since A and B will need to
      # be able to find it without the /config/postload-text-offset mechanism.
      bs_data = self._tools.ReadFile(bootstub)
      bs_data += self._tools.ReadFile(postload)
      bootstub = os.path.join(self._tools.outdir, 'u-boot-fdt-postload.bin')
      self._tools.WriteFile(bootstub, bs_data)
      self._tools.OutputSize('Combined binary with postload', bootstub)

      # Now that we know the file size, adjust the fdt and re-sign
      postload_bootstub = os.path.join(self._tools.outdir, 'postload.bin')
      fdt.PutInteger('/config', 'postload-text-offset', len(data))
      fdt_data = self._tools.ReadFile(fdt.fname)
      self._tools.WriteFile(postload_bootstub, uboot_data + fdt_data)
      signed = self._SignBootstub(self._tools.Filename(self.bct_fname),
          postload_bootstub, text_base)
      if len(data) != os.path.getsize(signed):
        raise CmdError('Signed file size changed from %d to %d after updating '
            'fdt' % (len(data), os.path.getsize(signed)))

      # Re-read the signed image, and add the post-load binary.
      data = self._tools.ReadFile(signed)
      data += self._tools.ReadFile(postload)
      self._tools.OutputSize('Post-load binary', postload)

    self._tools.WriteFile(signed_postload, data)
    self._tools.OutputSize('Final bootstub with postload', signed_postload)

    return bootstub, signed_postload

  def _CreateCorebootStub(self, coreboot):
    """Create a coreboot boot stub.

    Args:
      coreboot: Path to coreboot.rom

    Returns:
      Full path to bootstub (coreboot + uboot).
    """
    bootstub = os.path.join(self._tools.outdir, 'coreboot-full.rom')
    shutil.copyfile(self._tools.Filename(coreboot), bootstub)

    # Don't add the fdt yet since it is not in final form
    return bootstub


  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 _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 base coreboot image does not contain CBFS
    """

    if not self.coreboot_fname:
      raise CmdError("coreboot file needed for blob % s", blob_name)

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

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

    # Create a coreboot copy to use as a scratch pad.
    cb_copy = os.path.join(self._tools.outdir, 'cb_copy')
    if not os.path.exists(cb_copy):
      self._tools.WriteFile(cb_copy, self._tools.ReadFile(self.coreboot_fname))

    # Copy CBFS to the required offset
    self._tools.Run('cbfstool', [cb_copy, 'copy', '-D',
                                 '%d' % base, '-s', '%d' % size])

    # 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' , '-H', '%d' % base])

    # 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.
    """
    # stupid pylint insists that sha256 is not in hashlib.
    # pylint: disable=E1101
    if blob_type == 'coreboot':
      coreboot = self._CreateCorebootStub(self.coreboot_fname)
      pack.AddProperty('coreboot', coreboot)
      pack.AddProperty('image', coreboot)
    elif blob_type == 'legacy':
      pack.AddProperty('legacy', self.seabios_fname)
    elif blob_type == 'signed':
      bootstub, signed = self._CreateBootStub(self.uboot_fname, fdt,
                                              self.postload_fname)
      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('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 _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)
    blob_list = pack.GetBlobList()
    self._out.Info('Building blobs %s\n' % blob_list)
    for blob_type in pack.GetBlobList():
      self._BuildBlob(pack, fdt, blob_type)

    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 blob_list:
      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)

    # Only check for /iram and /config nodes for boards that require it.
    if self._board in ('daisy', 'peach'):
      # Insert default values for any essential properties that are missing.
      # This should only happen for upstream U-Boot, until our changes are
      # upstreamed.
      if not fdt.GetProp('/iram', 'reg', ''):
        self._out.Warning('Cannot find /iram, using default')
        fdt.InsertNodes([i for i in default_flashmap if i['path'] == '/iram'])

      # Sadly the pit branch has an invalid /memory node. Work around it
      # for now. crosbug.com/p/22184
      if (not fdt.GetProp('/memory', 'reg', '') or
          fdt.GetIntList('/memory', 'reg')[0] == 0):
        self._out.Warning('Cannot find /memory, using default')
        fdt.InsertNodes([i for i in default_flashmap if i['path'] == '/memory'])

      if not fdt.GetProp('/config', 'samsung,bl1-offset', ''):
        self._out.Warning('Missing properties in /config, using defaults')
        fdt.InsertNodes([i for i in default_flashmap if i['path'] == '/config'])

    # 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
