#!/usr/bin/env python3
#
# Copyright (c) 2019 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

# This script will add specific headers and FW load message to tell
# intel_s1000 ROM bootloader to load the firmware
# Usage python3 ${ZEPHYR_BASE}/scripts/create_board_img.py
#                    -i in_file.bin -o out_file.bin -l zephyr_prebuilt.elf
#                    [-m|--no_sram] [-c|--no_l1cache] [-t|--no_tlb]
#                    [-x|--no_exec] [-s|--no_sha] [-k|--clk_sel]

import argparse
import os
import sys
import struct
from elftools.elf.elffile import ELFFile

help_text="""
The flash memory needs to have specific headers and fw load message to tell
the ROM bootloader to load firmware.

To run script use command:

create_board_img.py -i in_file.bin -o out_file.bin -l zephyr_prebuilt.elf
                    [-m|--no_sram] [-c|--no_l1cache] [-t|--no_tlb]
                    [-x|--no_exec] [-s|--no_sha] [-k|--clk_sel]
"""

FLASH_PART_TABLE_OFFSET	= (0x1000)
FLASH_SECTOR_SIZE	= (4 * 1024)
FLASH_MAGIC_WORD	= (0x30504353)

SRAM_SIZE		= (1024*1024*4)
MAX_FLASH_FILE_SIZE	= (1024*1024*2)
SIZEOF_IPC64		= (64)
ROM_CONTROL_MEMWRITE	= (0x11)
ROM_CONTROL_LOADFW	= (0x2)
ROM_CONTROL_EXEC	= (0x13)

FW_LOAD_NO_L1_CACHE	= (1 << 29)
FW_LOAD_NO_SRAM_FLAG	= (1 << 28)
FW_LOAD_NO_TLB_FLAG	= (1 << 27)
FW_LOAD_NO_EXEC_FLAG	= (1 << 26)
FW_LOAD_NO_SHA_FLAG	= (1 << 25)
FW_LOAD_CLK_SEL		= (1 << 21)

# File write buffer
flash_content = []
write_buf     = []

def debug(text):
    sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n")

def error(text):
    sys.stderr.write(os.path.basename(sys.argv[0]) + ": " + text + "\n")
    sys.exit(1)

def set_magic_number(value):
    flash_content.append(value)

def set_partition_table_pointer(value):
    flash_content.append(value)

def ipc_load_fw(fw_size, fw_offset):
    dword_count = 3;
    load_flags = 0;
    clock_sel = 0;

    dword_count = 0x3ff & dword_count;

    debug("Creating flash image with following options:")

    if args.no_sram:
        load_flags |= FW_LOAD_NO_SRAM_FLAG
        debug("-m    no_sram")

    if args.no_l1cache:
        load_flags |= FW_LOAD_NO_L1_CACHE
        debug("-c    no_l1cache")

    if args.no_tlb:
        load_flags |= FW_LOAD_NO_TLB_FLAG
        debug("-t    no_tlb")

    if args.no_exec:
        load_flags |= FW_LOAD_NO_EXEC_FLAG
        debug("-x    no_exec")

    if args.no_sha:
        load_flags |= FW_LOAD_NO_SHA_FLAG
        debug("-s    no_sha")

    if args.clk_sel:
        clock_sel = FW_LOAD_CLK_SEL
        debug("-k    clk_sel")

    with open(args.kernel, "rb") as fp_kernel:
        kernel = ELFFile(fp_kernel)
        load_address = kernel.header['e_entry']
        debug("load address = 0x%X" % load_address)

    msg_header = 0x81000000 | ROM_CONTROL_LOADFW
    ext_header = 0x80000000 | dword_count | load_flags | clock_sel

    flash_content.append(msg_header)
    flash_content.append(ext_header)
    flash_content.append(load_address)
    flash_content.append(fw_offset)
    flash_content.append(fw_size)

def ipc_dbg_exec(address):
    dword_count = 1
    dword_count = 0x3ff & dword_count

    msg_header = 0x81000000 | ROM_CONTROL_EXEC
    ext_header = 0x0 | dword_count

    flash_content.append(msg_header)
    flash_content.append(ext_header)
    flash_content.append(address)

def ipc_dbg_memwrite(address, value):
    dword_count = 2
    dword_count = 0x3ff & dword_count

    msg_header = 0x81000000 | ROM_CONTROL_MEMWRITE
    ext_header = 0x0 | dword_count

    flash_content.append(msg_header)
    flash_content.append(ext_header)
    flash_content.append(address)
    flash_content.append(value)

def parse_args():
    global args
    parser = argparse.ArgumentParser(
        description=help_text,
        formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument("-i", "--in_file", required=True,
					help="Input FW Bin File")
    parser.add_argument("-o", "--out_file", required=True,
					help="Output Flash Bin File")
    parser.add_argument("-l", "--kernel", required=True,
                                        help="Zephyr kernel image")
    parser.add_argument("-m", "--no_sram", action="store_true",
					help="No SRAM")
    parser.add_argument("-c", "--no_l1cache", action="store_true",
					help="No L1 Cache")
    parser.add_argument("-t", "--no_tlb", action="store_true",
					help="No TLB")
    parser.add_argument("-x", "--no_exec", action="store_true",
					help="No Exec")
    parser.add_argument("-s", "--no_sha", action="store_true",
					help="No SHA")
    parser.add_argument("-k", "--clk_sel", action="store_true",
					help="Clock Select")

    args = parser.parse_args()

def main():
    parse_args()

    in_file_size = os.path.getsize(args.in_file)
    if in_file_size == 0:
        error("%s file has no content\n",args.in_file)

    out_file_size = FLASH_PART_TABLE_OFFSET + in_file_size

    # round up the flash size to sector boundary
    zeropad_size = FLASH_SECTOR_SIZE - (out_file_size % FLASH_SECTOR_SIZE)
    out_file_size += zeropad_size
    if out_file_size > MAX_FLASH_FILE_SIZE:
        error("%s exceeds %d bytes\n", args.out_file, MAX_FLASH_FILE_SIZE)

    # pre-boot initialization commands
    set_magic_number(FLASH_MAGIC_WORD)
    set_partition_table_pointer(FLASH_PART_TABLE_OFFSET)
    ipc_dbg_memwrite(0x71d14, 0x0)
    ipc_dbg_memwrite(0x71d24, 0x0)
    ipc_dbg_memwrite(0x304628, 0xd)
    ipc_dbg_memwrite(0x71fd0, 0x3)

    # load the image at address FLASH_PART_TABLE_OFFSET in flash to SRAM
    # at load_address (determined by the entrypoint in the supplied elf)
    ipc_load_fw(SRAM_SIZE, FLASH_PART_TABLE_OFFSET)

    # pad zeros until FLASH_PART_TABLE_OFFSET
    num_zero_pad = (FLASH_PART_TABLE_OFFSET / 4) - len(flash_content)
    for x in range(int(num_zero_pad)):
        flash_content.append(0)

    # read contents of firmware input file and change the endianness
    with open(args.in_file, "rb") as in_fp:
        read_buf = in_fp.read()
        in_fp.close()
        for itr in range(int(in_file_size/4)):
            write_buf.append(read_buf[itr*4 + 3])
            write_buf.append(read_buf[itr*4 + 2])
            write_buf.append(read_buf[itr*4 + 1])
            write_buf.append(read_buf[itr*4 + 0])

        # pad zeros until the sector boundary
        for x in range(zeropad_size):
            write_buf.append(0)

    # Generate the file which should be downloaded to Flash
    with open(args.out_file, "wb") as out_fp:
        # write as a uint (4 bytes) with byte order swapped (big-endian)
        out_fp.write(struct.pack(">{}I".format(len(flash_content)),
                                                        *flash_content))

        # write as a byte
        out_fp.write(struct.pack("{}B".format(len(write_buf)),
                                                        *write_buf))

        out_fp.close()

    debug("Input %s = %ld bytes" % (args.in_file, in_file_size))
    debug("Output %s = %ld bytes" % (args.out_file, out_file_size))

if __name__ == "__main__":
    main()
