#!/usr/bin/env python2
# Copyright (c) 2014, The Linux Foundation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#    * Redistributions of source code must retain the above copyright
#      notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above
#      copyright notice, this list of conditions and the following
#      disclaimer in the documentation and/or other materials provided
#      with the distribution.
#    * Neither the name of The Linux Foundation nor the names of its
#      contributors may be used to endorse or promote products derived
#      from this software without specific prior written permission.

# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import struct
import sys
import os

"""A utility to generate ipq8064 uber SBL..

The very first blob (aka 'uber SBL') read out of NOR SPI flash by the IPQ8064
maskrom is supposed to be a concatenation of up to three binaries: one to run
on the RPM, another one to run on the AP, and the third one - the actual
coreboot bootblock.

The uber SBL starts with the combined header descriptor of 80 bytes, with the
first two 4 byte words set to certain values, and the total size of the
payload saved at offsets 28 and 32.

To generate the uber SBL this utility expects two or three input file names in
the command line, the first file including the described header, and the
following one(s) - in QCA MBN format. This allows to create the uber SBL in
one or two invocations.

The input files are concatenated together aligned at 256 byte boundary offset
from the combined header. See Usage() below for more details.

The resulting uber SBL file is prepended by the same combined header adjusted
to reflect the new total file size.
"""

DEFAULT_OUTPUT_FILE_NAME = 'sbl-ro.mbn'

class NorSbl:
    """Object representing the uber SBL."""

    NOR_SBL1_HEADER    = '<II72s'
    NOR_SBL1_HEADER_SZ = struct.calcsize(NOR_SBL1_HEADER)
    ALIGNMENT          = 256    # Make sure this == UBER_SBL_PAD_SIZE
    NOR_CODE_WORD      = 0x844bdcd1
    MAGIC_NUM          = 0x73d71034

    def __init__(self, sbl1, verbose):
        """Initialize the object and verify the first file in the sequence.

        Args:
          sbl1: string, the name of the first out of the three input blobs,
                must be prepended by the combined header.
          verbose: boolean, if True - print debug information on the console.
        """
        self.verbose = verbose
        self.mbn_file_names = []
        if self.verbose:
            print 'Reading ' + sbl1

        try:
            self.sbl1 = open(sbl1, 'rb').read()
        except IOError as e:
            print 'I/O error({0}): {1}'.format(e.errno, e.strerror)
            raise

        (codeword, magic,  _) = struct.unpack_from(
            self.NOR_SBL1_HEADER, self.sbl1)

        if codeword != self.NOR_CODE_WORD:
            print '\n\nError: Unexpected Codeword!'
            print 'Codeword    : ' + ('0x%x' % self.NOR_CODE_WORD) + \
                ' != ' + ('0x%x' % codeword)
            sys.exit(-1)

        if magic != self.MAGIC_NUM:
            print '\n\nError: Unexpected Magic!'
            print 'Magic    : ' + ('0x%x' % self.MAGIC_NUM) + \
                ' != ' + ('0x%x' % magic)
            sys.exit(-1)

    def Append(self, src):
        """Add a file to the list of files to be concatenated"""
        self.mbn_file_names.append(src)

    def PadOutput(self, outfile, size):
        """Pad output file to the required alignment.

        Adds 0xff to the passed in file to get its size to the ALIGNMENT
        boundary.

        Args:
          outfile: file handle of the file to be padded
          size: int, current size of the file

       Returns number of bytes in the added padding.
       """

        # Is padding needed?
        overflow = size % self.ALIGNMENT
        if overflow:
            pad_size = self.ALIGNMENT - overflow
            pad = '\377' * pad_size
            outfile.write(pad)
            if self.verbose:
                print 'Added %d byte padding' % pad_size
            return pad_size
        return 0

    def Create(self, out_file_name):
        """Create the uber SBL.

        Concatenate input files with the appropriate padding and update the
        combined header to reflect the new blob size.

        Args:
          out_file_name: string, name of the file to save the generated uber
                         SBL in.
       """
        outfile = open(out_file_name, 'wb')
        total_size = len(self.sbl1) - self.NOR_SBL1_HEADER_SZ
        outfile.write(self.sbl1)

        for mbn_file_name in self.mbn_file_names:
            total_size += self.PadOutput(outfile, total_size)
            mbn_file_data = open(mbn_file_name, 'r').read()
            outfile.write(mbn_file_data)
            if self.verbose:
                print 'Added %s (%d bytes)' % (mbn_file_name,
                                               len(mbn_file_data))
            total_size += len(mbn_file_data)

        outfile.seek(28)
        outfile.write(struct.pack('<I', total_size))
        outfile.write(struct.pack('<I', total_size))


def Usage(v):
    print '%s: [-v] [-h] [-o Output MBN] sbl1 sbl2 [bootblock]' % (
        os.path.basename(sys.argv[0]))
    print
    print 'Concatenates up to three mbn files: two SBLs and a coreboot bootblock'
    print '    -h This message'
    print '    -v verbose'
    print '    -o Output file name, (default: %s)\n' % DEFAULT_OUTPUT_FILE_NAME
    sys.exit(v)

def main():
    verbose = 0
    mbn_output = DEFAULT_OUTPUT_FILE_NAME
    i = 0

    while i < (len(sys.argv) - 1):
        i += 1
        if (sys.argv[i] == '-h'):
            Usage(0)    # doesn't return

        if (sys.argv[i] == '-o'):
            mbn_output = sys.argv[i + 1]
            i += 1
            continue

        if (sys.argv[i] == '-v'):
            verbose = 1
            continue

        break

    argv = sys.argv[i:]
    if len(argv) < 2 or len(argv) > 3:
        Usage(-1)

    nsbl = NorSbl(argv[0], verbose)

    for mbnf in argv[1:]:
        nsbl.Append(mbnf)

    nsbl.Create(mbn_output)

if __name__ == '__main__':
    main()
