#!/usr/bin/python
# 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()
