#!/usr/bin/python

# Copyright (c) 2013 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.

"""crosfw - Chrome OS Firmware build/flash script.

Builds a firmware image for any board and writes it to the board. The image
can be pure upstream or include Chrome OS components (-V). Some device
tree parameters can be provided, including silent console (-C) and secure
boot (-S). Use -i for a faster incremental build. The image is written to
the board by default using USB/em100 (or sdcard with -x). Use -b to specify
the board to build. Options can be added to ~/.crosfwrc - see the script for
details.

It can also flash SPI by writing a 'magic flasher' U-Boot with a payload
to the board.

Usage: crosfw [options]

The script is normally run from within the U-Boot directory which is
.../src/third_party/u-boot/files

Example 1: Build upstream image for coreboot and write to a 'link':

 crosfw -b link

Example 2: Build verified boot image (V) for daisy/snow and boot in secure
 mode (S) so that breaking in on boot is not possible.

 crosfw -b daisy -VS
 crosfw -b daisy -VSC         (no console output)

Example 3: Build a magic flasher (F) with full verified boot for peach_pit,
 but with console enabled, write to SD card (x)

 crosfw -b peach_pit -VSFx

This sript does not use an ebuild. It does a similar thing to the
chromeos-u-boot ebuild, and runs cros_bundle_firmware to produce various
types of image, a little like the chromeos-bootimage ebuild.

The purpose of this script is to make it easier and faster to perform
common firmware build tasks without changing boards, manually updating
device tree files or lots of USE flags and complexity in the ebuilds.

This script has been tested with snow, link and peach_pit. It builds for
peach_pit by default. Note that it will also build any upstream ARM
board - e.g. "-b snapper9260" will build an image for that board.

Mostly you can use the script inside and outside the chroot. The main
limitation is that dut-control doesn't really work outside the chroot,
so writing the image to the board over USB is not possible, nor can the
board be automatically reset on x86 platforms.

For an incremental build (faster), run with -i

To get faster clean builds, install ccache, and create ~/.crosfwrc with
this line:

 USE_CCACHE = True

(make sure ~/.ccache is not on NFS, or set CCACHE_DIR)

Other options are the default board to build, and verbosity (0-4), e.g.:

 DEFAULT_BOARD = 'daisy'
 VERBOSE = 1

It is possible to use multiple servo boards, each on its own port. Add
these lines to your ~/.crosfwrc to set the servo port to use for each
board:

 SERVO_PORT['link'] = 8888
 SERVO_PORT['daisy'] = 9999
 SERVO_PORT['peach_pit'] = 7777

All builds appear in the <outdir>/<board> subdirectory and images are written
to <outdir>/<uboard>/out, where <uboard> is the U-Boot name for the board (in
the U-Boot boards.cfg file)

The value for <outdir> defaults to /tmp/crosfw but can be configured in your
~/.crosfwrc file, e.g.:"

 OUT_DIR = '/tmp/u-boot'

For the -a option here are some useful options:

--add-blob cros-splash /dev/null
--gbb-flags -force-dev-switch-on
--add-node-enable /spi@131b0000/cros-ecp@0 1
--verify --full-erase
--bootcmd "cros_test sha"
--gbb-flags -force-dev-switch-on
--bmpblk ~/trunk/src/third_party/u-boot/bmp.bin

For example: -a "--gbb-flags -force-dev-switch-on"

Note the standard bmpblk is at:
  /home/$USER/trunk/src/third_party/chromiumos-overlay/sys-boot/
      chromeos-bootimage/files/bmpblk.bin"
"""

import glob
import logging
import multiprocessing
import os
import re
import sys

from chromite.buildbot import constants
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import parallel


arch = None
board = None
compiler = None
default_board = None
family = None
in_chroot = True

logger = logging.getLogger('chromite')
logging.basicConfig(format='%(message)s')
kwargs = {'print_cmd': False, 'error_code_ok': True,
          'debug_level': logger.getEffectiveLevel()}

outdir = ''

 # If you have multiple boards connected on different servo ports, put lines
# like 'SERVO_PORT{"peach_pit"} = 7777' in your ~/.crosfwrc
SERVO_PORT = {}

smdk = None
src_root = os.path.join(constants.SOURCE_ROOT, 'src')
in_chroot = cros_build_lib.IsInsideChroot()

uboard = ''

default_board = 'peach_pit'
use_ccache = False
vendor = None
verbose = False

# Special cases for the U-Boot board config, the SOCs and default device tree
# since the naming is not always consistent.
# x86 has a lot of boards, but to U-Boot they are all the same
UBOARDS = {
    'daisy': 'smdk5250',
    'peach': 'smdk5420',
}
for b in ['alex', 'butterfly', 'emeraldlake2', 'link', 'lumpy', 'parrot',
          'stout', 'stumpy']:
  UBOARDS[b] = 'coreboot-x86'
  UBOARDS['chromeos_%s' % b] = 'chromeos_coreboot'

SOCS = {
    'coreboot-x86': '',
    'chromeos_coreboot': '',
    'daisy': 'exynos5250-',
    'peach': 'exynos5420-',
}

DEFAULT_DTS = {
    'daisy': 'snow',
    'daisy_spring': 'spring',
    'peach_pit': 'peach-pit',
}

OUT_DIR = '/tmp/crosfw'

rc_file = os.path.expanduser('~/.crosfwrc')
if os.path.exists(rc_file):
  execfile(rc_file)


def Log(msg):
  """Print out a message if we are in verbose mode.

  Args:
    msg: Message to print
  """
  if verbose:
    cros_build_lib.Info(msg)


def Dumper(flag, infile, outfile):
  """Run objdump on an input file.

  Args:
    flag: Flag to pass objdump (e.g. '-d').
    infile: Input file to process.
    outfile: Output file to write to.
  """
  result = cros_build_lib.RunCommand(
      [CompilerTool('objdump'), flag, infile],
      log_stdout_to_file=outfile, **kwargs)
  if result.returncode:
    sys.exit()


def CompilerTool(tool):
  """Returns the cross-compiler tool filename.

  Args:
    tool: Tool name to return, e.g. 'size'.

  Returns:
    Filename of requested tool.
  """
  return '%s%s' % (compiler, tool)


def ParseCmdline(argv):
  """Parse all command line options.

  Args:
    argv: Arguments to parse.

  Returns:
    Tuple containing:
      options: Command line options from optpase
      args: List of command line arguments
  """
  parser = commandline.OptionParser(__doc__)
  parser.add_option('-a', '--cbfargs', action='append',
                    help='Pass extra arguments to cros_bundle_firmware')
  parser.add_option('-b', '--board', type='string', default=default_board,
                    help='Select board to build (daisy/peach_pit/link)')
  parser.add_option('-B', '--build', action='store_false', default=True,
                    help="Don't build U-Boot, just configure device tree")
  parser.add_option('-C', '--console', action='store_false', default=True,
                    help='Permit console output')
  parser.add_option('-d', '--dt', default='seaboard',
                    help='Select name of device tree file to use')
  parser.add_option('-D', '--nodefaults', dest='use_defaults',
                    action='store_false', default=True,
                    help="Don't select default filenames for those not given")
  parser.add_option('-F', '--flash', action='store_true', default=False,
                    help='Create magic flasher for SPI flash')
  parser.add_option('-M', '--mmc', action='store_true', default=False,
                    help='Create magic flasher for eMMC')
  parser.add_option('-i', '--incremental', action='store_true', default=False,
                    help="Don't reconfigure and clean")
  parser.add_option('-k', '--kernel', action='store_true', default=False,
                    help='Send kernel to board also')
  parser.add_option('-O', '--objdump', action='store_true', default=False,
                    help='Write disassembly output')
  parser.add_option('-r', '--run', action='store_false', default=True,
                    help='Run the boot command')
  parser.add_option('--ro', action='store_true', default=False,
                    help='Create Chrome OS read-only image')
  parser.add_option('--rw', action='store_true', default=False,
                    help='Create Chrome OS read-write image')
  parser.add_option('-s', '--separate', action='store_false', default=True,
                    help='Link device tree into U-Boot, instead of separate')
  parser.add_option('-S', '--secure', action='store_true', default=False,
                    help='Use vboot_twostop secure boot')
  parser.add_option('--small', action='store_true', default=False,
                    help='Create Chrome OS small image')
  parser.add_option('-t', '--trace', action='store_true', default=False,
                    help='Enable trace support')
  parser.add_option('-v', '--verbose', type='int', default=0,
                    help='Make cros_bundle_firmware verbose')
  parser.add_option('-V', '--verified', action='store_true', default=False,
                    help='Include Chrome OS verified boot components')
  parser.add_option('-w', '--write', action='store_false', default=True,
                    help="Don't write image to board using usb/em100")
  parser.add_option('-x', '--sdcard', action='store_true', default=False,
                    help='Write to SD card instead of USB/em100')
  parser.add_option('-z', '--size', action='store_true', default=False,
                    help='Display U-Boot image size')
  return parser.parse_args(argv)


def SetupBuild(options):
  """Set up parameters needed for the build.

  This checks the current environment and options and sets up various things
  needed for the build, including 'base' which holds the base flags for
  passing to the U-Boot Makefile.

  Args:
    options: Command line options

  Returns:
    Base flags to use for U-Boot, as a list.
  """
  global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose

  if not verbose:
    verbose = options.verbose != 0

  logger.setLevel(options.verbose)

  Log('Building for %s' % options.board)

  # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
  # But don't mess up upstream boards which use _ in their name.
  parts = options.board.split('_')
  if parts[0] in ['daisy', 'peach']:
    board = parts[0]
  else:
    board = options.board

  # To allow this to be run from 'cros_sdk'
  if in_chroot:
    os.chdir(os.path.join(src_root, 'third_party', 'u-boot', 'files'))

  base_board = board

  if options.verified:
    base_board = 'chromeos_%s' % base_board

  uboard = UBOARDS.get(base_board, base_board)
  Log('U-Boot board is %s' % uboard)

  # Pull out some information from the U-Boot boards config file
  family = None
  with open('boards.cfg') as f:
    for line in f:
      if uboard in line:
        if line[0] == '#':
          continue
        fields = line.split()
        if not fields:
          continue
        arch = fields[1]
        fields += [None, None, None]
        smdk = fields[3]
        vendor = fields[4]
        family = fields[5]
        break
  if not arch:
    cros_build_lib.Die("Selected board '%s' not found in boards.cfg." % board)

  vboot = os.path.join('build', board, 'usr')
  if arch == 'x86':
    family = 'em100'
    if in_chroot:
      compiler = 'i686-pc-linux-gnu-'
    else:
      compiler = '/opt/i686/bin/i686-unknown-elf-'
  elif arch == 'arm':
    if in_chroot:
      # Use the Chrome OS toolchain
      compiler = 'armv7a-cros-linux-gnueabi-'
    else:
      compiler = glob.glob('/opt/linaro/gcc-linaro-arm-linux-*/bin/*gcc')
      if not compiler:
        cros_build_lib.Die("""Please install an ARM toolchain for your machine.
'Install a Linaro toolchain from:'
'https://launchpad.net/linaro-toolchain-binaries'
'or see cros/commands/cros_chrome_sdk.py.""")
      compiler = compiler[0]
    compiler = re.sub('gcc$', '', compiler)
  elif arch == 'sandbox':
    compiler = ''
  else:
    cros_build_lib.Die("Selected arch '%s' not supported." % arch)

  if not options.build:
    options.incremental = True

  cpus = multiprocessing.cpu_count()

  outdir = os.path.join(OUT_DIR, uboard)
  base = [
      'make',
      '-j%d' % cpus,
      'O=%s' % outdir,
      'ARCH=%s' % arch,
      'CROSS_COMPILE=%s' % compiler,
      '--no-print-directory',
      'HOSTSTRIP=true',
      'DEV_TREE_SRC=%s-%s' % (family, options.dt),
      'QEMU_ARCH=']

  if options.verbose < 2:
    base.append('-s')

  if options.ro and options.rw:
    cros_build_lib.Die('Cannot specify both --ro and --rw options')
  if options.ro:
    base.append('CROS_RO=1')
    options.small = True

  if options.rw:
    base.append('CROS_RW=1')
    options.small = True

  if options.small:
    base.append('CROS_SMALL=1')
  else:
    base.append('CROS_FULL=1')

  if options.verified:
    base += [
        'VBOOT=%s' % vboot,
        'MAKEFLAGS_VBOOT=DEBUG=1',
        'QUIET=1',
        'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
        'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root]
    base.append('VBOOT_DEBUG=1')

  # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
  # to a recent change, the need for which I didn't fully understand. But
  # U-Boot doesn't normally use this. We have added an option to U-Boot to
  # enable use of <stdint.h> and without it vboot will fail to build. So we
  # need to enable it where ww can. We can't just enable it always since
  # that would prevent this script from building other non-Chrome OS boards
  # with a different (older) toolchain, or Chrome OS boards without vboot.
  # So use USE_STDINT if the toolchain supports it, and not if not. This
  # file was originally part of glibc but has recently migrated to the
  # compiler so it is reasonable to use it with a stand-alone program like
  # U-Boot. At this point the comment has got long enough that we may as
  # well include some poetry which seems to be sorely lacking the code base,
  # so this is from Ogden Nash:
  #    To keep your marriage brimming
  #    With love in the loving cup,
  #    Whenever you're wrong, admit it;
  #    Whenever you're right, shut up.
  cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
  result = cros_build_lib.RunCommandCaptureOutput(cmd,
                                                  input='#include <stdint.h>',
                                                  **kwargs)
  if result.returncode == 0:
    base.append('USE_STDINT=1')

  if options.trace:
    base.append('FTRACE=1')
  if options.separate:
    base.append('DEV_TREE_SEPARATE=1')

  if options.incremental:
    # Get the correct board for cros_write_firmware
    config_mk = '%s/include/config.mk' % outdir
    if not os.path.exists(config_mk):
      cros_build_lib.Warning('No build found for %s - dropping -i' % board)
      options.incremental = False

  config_mk = 'include/config.mk'
  if os.path.exists(config_mk):
    cros_build_lib.Warning("Warning: '%s' exists, try 'make distclean'"
                           % config_mk)

  # For when U-Boot supports ccache
  # See http://patchwork.ozlabs.org/patch/245079/
  if use_ccache:
    os.environ['CCACHE'] = 'ccache'

  return base


def RunBuild(options, base, target, queue):
  """Run the U-Boot build.

  Args:
    options: Command line options.
    base: Base U-Boot flags.
    target: Target to build.
    queue: A parallel queue to add jobs to.
  """
  Log('U-Boot build flags: %s' % ' '.join(base))

  # Reconfigure U-Boot.
  if not options.incremental:
    # Ignore any error from this, some older U-Boots fail on this.
    cros_build_lib.RunCommand(base + ['distclean'], **kwargs)
    result = cros_build_lib.RunCommand(base + ['%s_config' % uboard], **kwargs)
    if result.returncode:
      sys.exit()

  # Do the actual build.
  if options.build:
    result = cros_build_lib.RunCommand(base + [target], **kwargs)
    if result.returncode:
      sys.exit()

  files = ['%s/u-boot' % outdir]
  spl = glob.glob('%s/spl/u-boot-spl' % outdir)
  if spl:
    files += spl
  if options.size:
    result = cros_build_lib.RunCommand([CompilerTool('size')] + files,
                                       **kwargs)
    if result.returncode:
      sys.exit()

  # Create disassembly files .dis and .Dis (full dump)
  for f in files:
    base = os.path.splitext(f)[0]
    if options.objdump:
      queue.put(('-d', f, base + '.dis'))
      queue.put(('-D', f, base + '.Dis'))
    else:
      # Remove old files which otherwise might be confusing
      osutils.SafeUnlink(base + '.dis')
      osutils.SafeUnlink(base + '.Dis')

  Log('Output directory %s' % outdir)


def WriteFirmware(options):
  """Write firmware to the board.

  This uses cros_bundle_firmware to create a firmware image and write it to
  the board.

  Args:
    options: Command line options
  """
  flash = []
  kernel = []
  run = []
  secure = []
  servo = []
  silent = []
  verbose_arg = []
  ro_uboot = []

  bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]

  if options.use_defaults:
    bl1 = []
    bmpblk = []
    ecro = []
    ecrw = []
    defaults = []
  else:
    bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
    bmpblk = ['--bmpblk', '##/build/%s/firmware/bmpblk.bin' % options.board]
    ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
    ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
    defaults = ['-D']

  if arch == 'x86':
    seabios = ['--seabios',
               '##/build/%s/firmware/seabios.cbfs' % options.board]
  else:
    seabios = []

  if options.sdcard:
    dest = 'sd:.'
  elif arch == 'x86':
    dest = 'em100'
  elif arch == 'sandbox':
    dest = ''
  else:
    dest = 'usb'

  port = SERVO_PORT.get(options.board, '')
  if port:
    servo = ['--servo', '%d' % port]

  if options.flash:
    flash = ['-F', 'spi']

    # The small builds don't have the command line interpreter so cannot
    # run the magic flasher script. So use the standard U-Boot in this
    # case.
    if options.small:
      cros_build_lib.Warning('Using standard U-Boot as flasher')
      flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]

  if options.mmc:
    flash = ['-F', 'sdmmc']

  if options.verbose:
    verbose_arg = ['-v', '%s' % options.verbose]

  if options.secure:
    secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']

  if not options.verified:
    # Make a small image, without GBB, etc.
    secure.append('-s')

  if options.kernel:
    kernel = ['--kernel', '##/build/%s/boot/vmlinux.uimg' % options.board]

  if not options.console:
    silent = ['--add-config-int', 'silent-console', '1']

  if not options.run:
    run = ['--bootcmd', 'none']

  if arch != 'sandbox' and not in_chroot and servo:
    if dest == 'usb':
      cros_build_lib.Warning('Image cannot be written to board')
      dest = ''
      servo = []
    elif dest == 'em100':
      cros_build_lib.Warning('Please reset the board manually to boot firmware')
      servo = []

    if not servo:
      cros_build_lib.Warning('(sadly dut-control does not work outside chroot)')

  if dest:
    dest = ['-w', dest]
  else:
    dest = []

  soc = SOCS.get(board)
  if not soc:
    soc = SOCS.get(uboard, '')
  dt_name = DEFAULT_DTS.get(options.board, options.board)
  dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
  Log('Device tree: %s' % dts_file)

  if arch == 'sandbox':
    uboot_fname = '%s/u-boot' % outdir
  else:
    uboot_fname = '%s/u-boot.bin' % outdir

  if options.ro:
    # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
    # ebuild one as RW.
    # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
    # a fresh RW U-Boot.
    cros_build_lib.Warning('Using standard U-Boot for RW')
    ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
    uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
  cbf = ['%s/platform/dev/host/cros_bundle_firmware' % src_root,
         '-b', options.board,
         '-d', dts_file,
         '-I', 'arch/%s/dts' % arch, '-I', 'cros/dts',
         '-u', uboot_fname,
         '-O', '%s/out' % outdir,
         '-M', family]

  for other in [bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel,
                run, seabios, secure, servo, silent, verbose_arg, ro_uboot]:
    if other:
      cbf += other
  if options.cbfargs:
    for item in options.cbfargs:
      cbf += item.split(' ')
  os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
                              (src_root, src_root))
  Log(' '.join(cbf))
  result = cros_build_lib.RunCommand(cbf, **kwargs)
  if result.returncode:
    cros_build_lib.Die('cros_bundle_firmware failed')

  if not dest or not result.returncode:
    cros_build_lib.Info('Image is available at %s/out/image.bin' % outdir)
  else:
    if result.returncode:
      cros_build_lib.Die('Failed to write image to board')
    else:
      cros_build_lib.Info('Image written to board with %s' %
                          ' '.join(dest + servo))


def main(argv):
  """Main function for script to build/write firmware.

  Args:
    argv: Program arguments.
  """
  options, args = ParseCmdline(argv)
  base = SetupBuild(options)

  with parallel.BackgroundTaskRunner(Dumper) as queue:
    target = args[0] if args else 'all'
    RunBuild(options, base, target, queue)

    if options.write:
      WriteFirmware(options)

    if options.objdump:
      Log('Writing diasssembly files')
