[coreboot-gerrit] Patch set updated for coreboot: util/marvell: Add Marvell doimage utility and dependency in relevant Makefile

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Thu Feb 4 11:34:14 CET 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13137

-gerrit

commit fea19c57c42afb54e5d6406440beb1ca16bf961d
Author: Ruilin Hao <rlhao at marvell.com>
Date:   Thu Dec 10 00:36:10 2015 -0800

    util/marvell: Add Marvell doimage utility and dependency in relevant Makefile
    
    - Add the doimage sources in util/marvell
    - Add dependency in root makefile
    - Add dependency in makefile for armada38x soc
    
    BUG=chrome-os-partner:47462
    TEST=emerge-cyclone coreboot
    BRANCH=tot
    
    Change-Id: I81b30e0865cbd619a41659c3f2819ad3bafc5f24
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 4b2a990150580e0b879a346ed8b71b3765b66bab
    Original-Change-Id: I7e89b5e96206fde97ce69c296850122fd6c858f9
    Original-Signed-off-by: Kefei Yao <kfyao at marvell.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/318046
    Original-Commit-Ready: Kan Yan <kyan at google.com>
    Original-Tested-by: Kan Yan <kyan at google.com>
    Original-Reviewed-by: Furquan Shaikh <furquan at chromium.org>
    Original-Reviewed-by: Kan Yan <kyan at google.com>
    Original-Reviewed-by: Yuji Sasaki <sasakiy at chromium.org>
---
 Makefile.inc                            |    2 +-
 src/soc/marvell/armada38x/Makefile.inc  |    6 +-
 util/marvell/Makefile.inc               |    1 +
 util/marvell/doimage_mv/Makefile.inc    |   13 +
 util/marvell/doimage_mv/bootstrap_def.h |  171 +++
 util/marvell/doimage_mv/bootstrap_os.h  |  403 +++++++
 util/marvell/doimage_mv/doimage.c       | 1781 +++++++++++++++++++++++++++++++
 util/marvell/doimage_mv/doimage.h       |  155 +++
 8 files changed, 2528 insertions(+), 4 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index fb0d888..58cc041 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -71,7 +71,7 @@ subdirs-y += src/ec/acpi $(wildcard src/ec/*/*) $(wildcard src/southbridge/*/*)
 subdirs-y += $(wildcard src/soc/*/*) $(wildcard src/northbridge/*/*)
 subdirs-y += src/superio $(wildcard src/drivers/*) src/cpu src/vendorcode
 subdirs-y += util/cbfstool util/sconfig util/nvramtool util/broadcom
-subdirs-y += util/futility
+subdirs-y += util/futility util/marvell
 subdirs-y += $(wildcard src/arch/*)
 subdirs-y += src/mainboard/$(MAINBOARDDIR)
 subdirs-y += payloads/external
diff --git a/src/soc/marvell/armada38x/Makefile.inc b/src/soc/marvell/armada38x/Makefile.inc
index c62d95f..c55bfff 100644
--- a/src/soc/marvell/armada38x/Makefile.inc
+++ b/src/soc/marvell/armada38x/Makefile.inc
@@ -34,10 +34,10 @@ ramstage-y += clock.c
 
 CPPFLAGS_common += -Isrc/soc/marvell/armada38x/include/ -Isrc/commonlib/include/commonlib/
 
-BIN_HDR = 3rdparty/blobs/cpu/marvell/armada38x/bin_hdr.bin
-DOIMAGE = 3rdparty/blobs/cpu/marvell/armada38x/doimage
+BIN_HDR = 3rdparty/cpu/marvell/armada38x/bin_hdr.bin
+DOIMAGE = $(objutil)/marvell/doimage_mv/doimage
 
-$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin
+$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin $(DOIMAGE)
 	@chmod a+x $(DOIMAGE)
 	$(DOIMAGE) -T flash -D 0 -E 0 -G $(BIN_HDR) $< $@
 	rm $<
diff --git a/util/marvell/Makefile.inc b/util/marvell/Makefile.inc
new file mode 100644
index 0000000..08dbf72
--- /dev/null
+++ b/util/marvell/Makefile.inc
@@ -0,0 +1 @@
+subdirs-$(CONFIG_SOC_MARVELL_ARMADA38X) += doimage_mv
diff --git a/util/marvell/doimage_mv/Makefile.inc b/util/marvell/doimage_mv/Makefile.inc
new file mode 100644
index 0000000..83665df
--- /dev/null
+++ b/util/marvell/doimage_mv/Makefile.inc
@@ -0,0 +1,13 @@
+DOIMAGE_FOLDER = marvell/doimage_mv
+DOIMAGE_BINARY = doimage
+
+CFLAGS  = -g -O1 -I./../inc -DMV_CPU_LE
+
+$(objutil)/$(DOIMAGE_FOLDER):
+	mkdir -p $@
+
+$(objutil)/$(DOIMAGE_FOLDER)/doimage.o: $(top)/util/marvell/doimage_mv/doimage.c $(objutil)/$(DOIMAGE_FOLDER)
+	$(HOSTCC) $(CFLAGS) -c $< -o $@
+
+$(objutil)/$(DOIMAGE_FOLDER)/$(DOIMAGE_BINARY): $(objutil)/$(DOIMAGE_FOLDER)/doimage.o
+	$(HOSTCC) $(CFLAGS) -o $@ $^
diff --git a/util/marvell/doimage_mv/bootstrap_def.h b/util/marvell/doimage_mv/bootstrap_def.h
new file mode 100644
index 0000000..1585b81
--- /dev/null
+++ b/util/marvell/doimage_mv/bootstrap_def.h
@@ -0,0 +1,171 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+
+*******************************************************************************/
+
+#ifndef _INC_BOOTSTRAP__DEF_H
+#define _INC_BOOTSTRAP__DEF_H
+#include "bootstrap_os.h"
+
+#ifndef MV_ASMLANGUAGE
+
+#define MAIN_HDR_VERSION 1
+
+#define MAIN_HDR_NAND_SLC 0
+#define MAIN_HDR_NAND_MLC 1
+
+typedef struct BHR_t {
+	/*	type        name                byte order */
+	MV_U8 blockID;		/*   0   */
+	MV_U8 flags;		/*   1   */
+	MV_U16 nandPageSize;    /*  2-3  */
+	MV_U32 blockSize;       /*  4-7  */
+	MV_U8 version;		/*   8   */
+	MV_U8 hdrSizeMsb;       /*   9   */
+	MV_U16 hdrSizeLsb;      /* 10-11 */
+	MV_U32 sourceAddr;      /* 12-15 */
+	MV_U32 destinationAddr; /* 16-19 */
+	MV_U32 executionAddr;   /* 20-23 */
+	MV_U8 options;		/*   24  */
+	MV_U8 nandBlockSize;    /*   25  */
+	MV_U8 nandTechnology;   /*   26  */
+	MV_U8 rsvd4;		/*   27  */
+	MV_U16 rsvd2;		/* 28-29 */
+	MV_U8 ext;		/*   30  */
+	MV_U8 checkSum;		/*   31  */
+
+} BHR_t, *pBHR_t;
+
+#define MAIN_HDR_GET_LEN(pHdr)                                                 \
+	(((MV_U32)((pHdr)->hdrSizeMsb) << 16) | ((MV_U32)((pHdr)->hdrSizeLsb)))
+
+#define EXT_HDR_TYP_SECURITY 0x01
+#define EXT_HDR_TYP_BINARY 0x02
+#define EXT_HDR_TYP_REGISTER 0x03
+
+typedef struct headExtBHR_t {/* Common extension header head */
+			     //  type        name        byte order
+	MV_U8 type;
+	MV_U8 lenMsb;
+	MV_U16 lenLsb;
+
+} headExtBHR_t;
+
+#define EXT_HDR_SET_LEN(pHead, len)                                            \
+	do {                                                                   \
+		(pHead)->lenMsb = ((len)&0x00FF0000) >> 16;                    \
+		(pHead)->lenLsb = (len)&0x0000FFFF;                            \
+	} while (0)
+
+#define EXT_HDR_GET_LEN(pHead)                                                 \
+	(((MV_U32)((pHead)->lenMsb) << 16) | ((pHead)->lenLsb))
+
+typedef struct tailExtBHR_t {/* Common extension header tail */
+			     // type        name        byte order
+	MV_U8 nextHdr;
+	MV_U8 delay;
+	MV_U16 rsvd2;
+
+} tailExtBHR_t;
+
+typedef struct publicKey_t {/* public key*/
+	MV_U8 Key[524];
+} publicKey_t;
+
+#define RSA_MAX_KEY_LEN_BYTES 256
+
+typedef struct secExtBHR_t {
+	headExtBHR_t head;
+	MV_U8 encrypt;
+	MV_U8 rsrvd0;
+	MV_U16 rsrvd1;
+	publicKey_t pubKey;
+	MV_U8 jtagEn;
+	MV_U8 rsrvd2;
+	MV_U16 rsrvd3;
+	MV_U32 boxId;
+	MV_U32 flashId;
+	MV_U8 hdrSign[256];
+	MV_U8 imgSign[256];
+	publicKey_t cskArray[16];
+	MV_U8 cskBlockSign[256];
+	tailExtBHR_t tail;
+
+} secExtBHR_t, *pSecExtBHR_T;
+
+/***********************/
+/* SECURE PARAMS       */
+/***********************/
+#define CSK_BLOCK_OFFSET 0x420
+#define PUB_KEY_SIZE 524
+#define CSK_KEY_NUM 16
+#define CSK_BLOCK_SIGN_OFFSET (CSK_BLOCK_OFFSET + (PUB_KEY_SIZE * CSK_KEY_NUM))
+/* 16 keys + 256 bytes long signature */
+#define CSK_BLOCK_SIZE ((PUB_KEY_SIZE * CSK_KEY_NUM) + 0x100)
+
+#define BOOTROM_SIZE (64 * 1024)
+#define EXT_HDR_BASE_SIZE (sizeof(headExtBHR_t) + sizeof(tailExtBHR_t))
+/* MAX size of entire headers block */
+#define MAX_HEADER_SIZE (192 * 1024)
+#define MAX_TWSI_HDR_SIZE                                                      \
+	(60 * 1024) /* MAX eeprom is 64K & leave 4K for image and header */
+
+/* Boot Type - block ID */
+#define IBR_HDR_I2C_ID 0x4D
+#define IBR_HDR_SPI_ID 0x5A
+#define IBR_HDR_NAND_ID 0x8B
+#define IBR_HDR_SATA_ID 0x78
+#define IBR_HDR_PEX_ID 0x9C
+#define IBR_HDR_MMC_ID 0xAE
+#define IBR_HDR_UART_ID 0x69
+#define IBR_DEF_ATTRIB 0x00
+
+/* ROM flags */
+#define BHR_FLAG_PRINT_EN 0x01
+#define BHR_FLAG_RESERVED1 0x02
+#define BHR_FLAG_RESERVED2 0x04
+#define BHR_FLAG_RESERVED3 0x08
+#define BHR_FLAG_RESERVED4 0x10
+#define BHR_FLAG_RESERVED5 0x20
+#define BHR_FLAG_RESERVED6 0x40
+#define BHR_FLAG_RESERVED7 0x80
+
+/* ROM options */
+#define BHR_OPT_BAUDRATE_OFFS 0x0
+#define BHR_OPT_BAUDRATE_MASK (0x7 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_DEFAULT (0x0 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_2400 (0x1 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_4800 (0x2 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_9600 (0x3 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_19200 (0x4 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_38400 (0x5 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_57600 (0x6 << BHR_OPT_BAUDRATE_OFFS)
+#define BHR_OPT_BAUD_115200 (0x7 << BHR_OPT_BAUDRATE_OFFS)
+
+#define BHR_OPT_UART_PORT_OFFS 0x3
+#define BHR_OPT_UART_PORT_MASK (0x3 << BHR_OPT_UART_PORT_OFFS)
+
+#define BHR_OPT_UART_MPPS_OFFS 0x5
+#define BHR_OPT_UART_MPPS_MASK (0x7 << BHR_OPT_UART_MPPS_OFFS)
+
+typedef struct _mvCpuArmClk {
+	MV_U32 cpuClk; /* CPU clock MHz */
+	MV_U32 ddrClk; /* DDR clock MHz */
+	MV_U32 l2cClk; /* L2 cache clock MHz */
+} MV_CPU_ARM_CLK;
+
+#endif /* MV_ASMLANGUAGE */
+#endif /* _INC_BOOTSTRAP_H */
diff --git a/util/marvell/doimage_mv/bootstrap_os.h b/util/marvell/doimage_mv/bootstrap_os.h
new file mode 100644
index 0000000..888e730
--- /dev/null
+++ b/util/marvell/doimage_mv/bootstrap_os.h
@@ -0,0 +1,403 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+
+*******************************************************************************/
+#ifndef _INC_BOOTSTRAP_OS_H
+#define _INC_BOOTSTRAP_OS_H
+
+/* BE/ LE swap for Asm */
+#if defined(MV_CPU_LE)
+
+#define htoll(x) x
+#define HTOLL(sr, tr)
+
+#elif defined(MV_CPU_BE)
+
+#define htoll(x)                                                               \
+	((((x)&0x00ff) << 24) | (((x)&0xff00) << 8) | (((x) >> 8) & 0xff00) |  \
+	 (((x) >> 24) & 0x00ff))
+
+#define HTOLL(sr, temp) do {	/*sr   = A  ,B  ,C  ,D    */        \
+	eor temp, sr, sr, ROR #16; /*temp = A^C,B^D,C^A,D^B  */     \
+	bic temp, temp, #0xFF0000; /*temp = A^C,0  ,C^A,D^B  */      \
+	mov sr, sr, ROR #8;	/*sr   = D  ,A  ,B  ,C    */         \
+	eor sr, sr, temp, LSR #8   /*sr   = D  ,C  ,B  ,A    */	    \
+	} while (0)
+
+#endif
+
+#define MV_REG_READ_ASM(toReg, tmpReg, regOffs)	do {                   \
+	ldr tmpReg, = (INTER_REGS_BASE + regOffs);                     \
+	ldr toReg, [tmpReg];                                           \
+	HTOLL(toReg, tmpReg)						\
+	} while (0)
+
+#define MV_REG_WRITE_ASM(fromReg, tmpReg, regOffs)                             \
+	HTOLL(fromReg, tmpReg);                                                \
+	ldr tmpReg, = (INTER_REGS_BASE + regOffs);                             \
+	str fromReg, [tmpReg]
+
+#define MV_DV_REG_READ_ASM(toReg, tmpReg, regOffs)                             \
+	ldr tmpReg, = (CFG_DFL_MV_REGS + regOffs);                             \
+	ldr toReg, [tmpReg];                                                   \
+	HTOLL(toReg, tmpReg)
+
+#define MV_DV_REG_WRITE_ASM(fromReg, tmpReg, regOffs)                          \
+	HTOLL(fromReg, tmpReg);                                                \
+	ldr tmpReg, = (CFG_DFL_MV_REGS + regOffs);                             \
+	str fromReg, [tmpReg]
+
+/* Defines */
+
+/* The following is a list of Marvell status    */
+#define MV_ERROR (-1)
+#define MV_OK (0x00)		  /* Operation succeeded                   */
+#define MV_FAIL (0x01)		  /* Operation failed                      */
+#define MV_BAD_VALUE (0x02)       /* Illegal value (general)               */
+#define MV_OUT_OF_RANGE (0x03)    /* The value is out of range             */
+#define MV_BAD_PARAM (0x04)       /* Illegal parameter in function called  */
+#define MV_BAD_PTR (0x05)	 /* Illegal pointer value                 */
+#define MV_BAD_SIZE (0x06)	/* Illegal size                          */
+#define MV_BAD_STATE (0x07)       /* Illegal state of state machine        */
+#define MV_SET_ERROR (0x08)       /* Set operation failed                  */
+#define MV_GET_ERROR (0x09)       /* Get operation failed                  */
+#define MV_CREATE_ERROR (0x0A)    /* Fail while creating an item           */
+#define MV_NOT_FOUND (0x0B)       /* Item not found                        */
+#define MV_NO_MORE (0x0C)	 /* No more items found                   */
+#define MV_NO_SUCH (0x0D)	 /* No such item                          */
+#define MV_TIMEOUT (0x0E)	 /* Time Out                              */
+#define MV_NO_CHANGE (0x0F)       /* Parameter(s) is already in this value */
+#define MV_NOT_SUPPORTED (0x10)   /* This request is not support           */
+#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented */
+#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized           */
+#define MV_NO_RESOURCE (0x13)     /* Resource not available (memory ...)   */
+#define MV_FULL (0x14)		  /* Item is full (Queue or table etc...)  */
+#define MV_EMPTY (0x15)		  /* Item is empty (Queue or table etc...) */
+#define MV_INIT_ERROR (0x16)      /* Error occurred while INIT process      */
+#define MV_HW_ERROR (0x17)	/* Hardware error                        */
+#define MV_TX_ERROR (0x18)	/* Transmit operation not succeeded      */
+#define MV_RX_ERROR (0x19)	/* Receive operation not succeeded       */
+#define MV_NOT_READY (0x1A)       /* The other side is not ready yet       */
+#define MV_ALREADY_EXIST (0x1B)   /* Tried to create existing item         */
+#define MV_OUT_OF_CPU_MEM (0x1C)  /* Cpu memory allocation failed.         */
+#define MV_NOT_STARTED (0x1D)     /* Not started yet         */
+#define MV_BUSY (0x1E)		  /* Item is busy.                         */
+#define MV_TERMINATE (0x1F)       /* Item terminates it's work.            */
+#define MV_NOT_ALIGNED (0x20)     /* Wrong alignment                       */
+#define MV_NOT_ALLOWED (0x21)     /* Operation NOT allowed                 */
+#define MV_WRITE_PROTECT (0x22)   /* Write protected                       */
+
+#define MV_INVALID (int)(-1)
+
+#define MV_FALSE 0
+#define MV_TRUE (!(MV_FALSE))
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#ifndef MV_ASMLANGUAGE
+/* typedefs */
+
+typedef char MV_8;
+typedef unsigned char MV_U8;
+
+typedef int MV_32;
+typedef unsigned int MV_U32;
+
+typedef short MV_16;
+typedef unsigned short MV_U16;
+/*
+#ifdef MV_PPC64
+typedef long		MV_64;
+typedef unsigned long	MV_U64;
+#else
+typedef long long		MV_64;
+typedef unsigned long long	MV_U64;
+#endif
+*/
+typedef long MV_LONG;		/* 32/64 */
+typedef unsigned long MV_ULONG; /* 32/64 */
+
+typedef int MV_STATUS;
+typedef int MV_BOOL;
+/*typedef void    MV_VOID;*/
+#define MV_VOID void
+typedef float MV_FLOAT;
+
+typedef int (*MV_FUNCPTR)(void);       /* ptr to function returning int   */
+typedef void (*MV_VOIDFUNCPTR)(void);  /* ptr to function returning void  */
+typedef double (*MV_DBLFUNCPTR)(void); /* ptr to function returning double*/
+typedef float (*MV_FLTFUNCPTR)(void);  /* ptr to function returning float */
+
+typedef MV_U32 MV_KHZ;
+typedef MV_U32 MV_MHZ;
+typedef MV_U32 MV_HZ;
+#if defined(_HOST_COMPILER)
+#define __MV_PACKED
+#else
+#define __MV_PACKED /*__packed*/
+#endif
+
+#endif /* MV_ASMLANGUAGE */
+
+/* Bit field definitions */
+#define NO_BIT 0x00000000
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+/* includes */
+#define _1K 0x00000400
+#define _4K 0x00001000
+#define _8K 0x00002000
+#define _16K 0x00004000
+#define _32K 0x00008000
+#define _64K 0x00010000
+#define _128K 0x00020000
+#define _256K 0x00040000
+#define _512K 0x00080000
+/* Sizes */
+#define _1M 0x00100000
+#define _2M 0x00200000
+#define _4M 0x00400000
+#define _8M 0x00800000
+#define _16M 0x01000000
+#define _32M 0x02000000
+#define _64M 0x04000000
+#define _128M 0x08000000
+#define _256M 0x10000000
+#define _512M 0x20000000
+#define _1G 0x40000000
+#define _2G 0x80000000
+/* Speed */
+#define _25MHZ 25000000
+#define _125MHZ 125000000
+#define _133MHZ 133333333
+#define _150MHZ 150000000
+#define _166MHZ 166666667
+#define _200MHZ 200000000
+#define _250MHZ 250000000
+
+/* Swap tool */
+
+/* 16bit nibble swap. For example 0x1234 -> 0x2143                          */
+#define MV_NIBBLE_SWAP_16BIT(X)                                                \
+	(((X & 0xf) << 4) | ((X & 0xf0) >> 4) | ((X & 0xf00) << 4) |           \
+	 ((X & 0xf000) >> 4))
+
+/* 32bit nibble swap. For example 0x12345678 -> 0x21436587                  */
+#define MV_NIBBLE_SWAP_32BIT(X)                                                \
+	(((X & 0xf) << 4) | ((X & 0xf0) >> 4) | ((X & 0xf00) << 4) |           \
+	 ((X & 0xf000) >> 4) | ((X & 0xf0000) << 4) | ((X & 0xf00000) >> 4) |  \
+	 ((X & 0xf000000) << 4) | ((X & 0xf0000000) >> 4))
+
+/* 16bit byte swap. For example 0x1122 -> 0x2211                            */
+#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff) << 8) | (((X)&0xff00) >> 8))
+
+/* 32bit byte swap. For example 0x11223344 -> 0x44332211                    */
+#define MV_BYTE_SWAP_32BIT(X)                                                  \
+	((((X)&0xff) << 24) | (((X)&0xff00) << 8) | (((X)&0xff0000) >> 8) |    \
+	 (((X)&0xff000000) >> 24))
+
+/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211  */
+#define MV_BYTE_SWAP_64BIT(X)                                                  \
+	((l64)((((X)&0xffULL) << 56) | (((X)&0xff00ULL) << 40) |               \
+	       (((X)&0xff0000ULL) << 24) | (((X)&0xff000000ULL) << 8) |        \
+	       (((X)&0xff00000000ULL) >> 8) |                                  \
+	       (((X)&0xff0000000000ULL) >> 24) |                               \
+	       (((X)&0xff000000000000ULL) >> 40) |                             \
+	       (((X)&0xff00000000000000ULL) >> 56)))
+
+/* Endianness macros.                                                        */
+#if defined(MV_CPU_LE)
+#define MV_16BIT_LE(X) (X)
+#define MV_32BIT_LE(X) (X)
+#define MV_64BIT_LE(X) (X)
+#define MV_16BIT_BE(X) MV_BYTE_SWAP_16BIT(X)
+#define MV_32BIT_BE(X) MV_BYTE_SWAP_32BIT(X)
+#define MV_64BIT_BE(X) MV_BYTE_SWAP_64BIT(X)
+#elif defined(MV_CPU_BE)
+#define MV_16BIT_LE(X) MV_BYTE_SWAP_16BIT(X)
+#define MV_32BIT_LE(X) MV_BYTE_SWAP_32BIT(X)
+#define MV_64BIT_LE(X) MV_BYTE_SWAP_64BIT(X)
+#define MV_16BIT_BE(X) (X)
+#define MV_32BIT_BE(X) (X)
+#define MV_64BIT_BE(X) (X)
+#else
+#error "CPU endianness isn't defined!\n"
+#endif
+
+#ifndef MV_ASMLANGUAGE
+/* Get the min between 'a' or 'b'                                           */
+#define MV_MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/* Marvell controller register read/write macros */
+#define CPU_PHY_MEM(x) ((MV_U32) x)
+#define CPU_MEMIO_CACHED_ADDR(x) ((void *) x)
+#define CPU_MEMIO_UNCACHED_ADDR(x) ((void *) x)
+
+/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */
+#define MV_MEMIO32_WRITE(addr, data)                                           \
+	((*((volatile unsigned int *)(addr))) = ((unsigned int)(data)))
+
+#define MV_MEMIO32_READ(addr) ((*((volatile unsigned int *)(addr))))
+
+#define MV_MEMIO16_WRITE(addr, data)                                           \
+	((*((volatile unsigned short *)(addr))) = ((unsigned short)(data)))
+
+#define MV_MEMIO16_READ(addr) ((*((volatile unsigned short *)(addr))))
+
+#define MV_MEMIO8_WRITE(addr, data)                                            \
+	((*((volatile unsigned char *)(addr))) = ((unsigned char)(data)))
+
+#define MV_MEMIO8_READ(addr) ((*((volatile unsigned char *)(addr))))
+
+/* No Fast Swap implementation (in assembler) for ARM */
+#define MV_32BIT_LE_FAST(val) MV_32BIT_LE(val)
+#define MV_16BIT_LE_FAST(val) MV_16BIT_LE(val)
+#define MV_32BIT_BE_FAST(val) MV_32BIT_BE(val)
+#define MV_16BIT_BE_FAST(val) MV_16BIT_BE(val)
+
+/* 32 and 16 bit read/write in big/little endian mode */
+
+/* 16bit write in little endian mode */
+#define MV_MEMIO_LE16_WRITE(addr, data)                                        \
+	MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))
+
+/* 16bit read in little endian mode */
+static inline MV_U16 MV_MEMIO_LE16_READ(void *addr)
+{
+	MV_U16 data;
+	MV_U16 *addr1 = (MV_U16 *)addr;
+
+	data = (MV_U16)MV_MEMIO16_READ(addr1);
+
+	return (MV_U16)MV_16BIT_LE_FAST(data);
+}
+
+/* 32bit write in little endian mode */
+#define MV_MEMIO_LE32_WRITE(addr, data)                                        \
+	MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
+
+/* 32bit read in little endian mode */
+static inline MV_U32 MV_MEMIO_LE32_READ(void *addr)
+{
+	MV_U32 data;
+	MV_U32 *addr1 = (MV_U32 *)addr;
+
+	data = (MV_U32)MV_MEMIO32_READ(addr1);
+
+	return (MV_U32)MV_32BIT_LE_FAST(data);
+}
+
+/* Flash APIs */
+#define MV_FL_8_READ MV_MEMIO8_READ
+#define MV_FL_16_READ MV_MEMIO_LE16_READ
+#define MV_FL_32_READ MV_MEMIO_LE32_READ
+#define MV_FL_8_DATA_READ MV_MEMIO8_READ
+#define MV_FL_16_DATA_READ MV_MEMIO16_READ
+#define MV_FL_32_DATA_READ MV_MEMIO32_READ
+#define MV_FL_8_WRITE MV_MEMIO8_WRITE
+#define MV_FL_16_WRITE MV_MEMIO_LE16_WRITE
+#define MV_FL_32_WRITE MV_MEMIO_LE32_WRITE
+#define MV_FL_8_DATA_WRITE MV_MEMIO8_WRITE
+#define MV_FL_16_DATA_WRITE MV_MEMIO16_WRITE
+#define MV_FL_32_DATA_WRITE MV_MEMIO32_WRITE
+
+/* CPU cache information */
+#define CPU_I_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
+#define CPU_D_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
+
+#define MV_REG_VALUE(offset) (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))
+
+#define MV_REG_READ(offset) (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))
+
+#define MV_REG_WRITE(offset, val)                                              \
+	MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val))
+
+#define MV_REG_BYTE_READ(offset) (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))
+
+#define MV_REG_BYTE_WRITE(offset, val)                                         \
+	MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))
+
+#define MV_REG_SHORT_READ(offset)                                              \
+	(MV_MEMIO_LE16_READ(INTER_REGS_BASE | (offset)))
+
+#define MV_REG_BIT_SET(offset, bitMask)                                        \
+	(MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)),                        \
+			  (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))) |     \
+			   MV_32BIT_LE_FAST((bitMask)))))
+
+#define MV_REG_BIT_RESET(offset, bitMask)                                      \
+	(MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)),                        \
+			  (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))) &     \
+			   MV_32BIT_LE_FAST(~(bitMask)))))
+
+#define mvOsUDelay uDelay
+#define mvOsMDelay(msec) uDelay(msec * 1000)
+#define mvOsDelay(sec) mvOsMDelay(sec * 1000)
+
+#define u32 MV_U32
+#define u16 MV_U16
+#define u8 MV_U8
+#define s16 short
+#define s32 long
+#define s8 char
+
+#define UINT32 MV_U32
+#define UINT16 MV_U16
+#define UINT8 MV_U8
+
+typedef UINT32 * PUINT32;
+typedef UINT16 * PUINT16;
+typedef UINT8 * PUINT8;
+
+#define TRUE MV_TRUE
+#define FALSE MV_FALSE
+
+#endif /* #ifndef MV_ASMLANGUAGE */
+
+#endif /* _INC_BOOTSTRAP_OS_H */
diff --git a/util/marvell/doimage_mv/doimage.c b/util/marvell/doimage_mv/doimage.c
new file mode 100644
index 0000000..18675aa
--- /dev/null
+++ b/util/marvell/doimage_mv/doimage.c
@@ -0,0 +1,1781 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+
+*******************************************************************************/
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <limits.h>
+
+#define _HOST_COMPILER
+#include "bootstrap_def.h"
+
+#include "doimage.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DB(x...) fprintf(stdout, x)
+#else
+#define DB(x...)
+#endif
+
+/* Global variables */
+
+int f_in = -1;
+int f_out = -1;
+int f_header = -1;
+struct stat fs_stat;
+
+/*******************************************************************************
+*    pre_load_image
+*          pre-load the binary image into memory buffer taking into account
+*paddings
+*    INPUT:
+*          opt        user options
+*          buf_in     mmapped input file
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+*******************************************************************************/
+int pre_load_image(USER_OPTIONS *opt, char *buf_in)
+{
+	int offset = 0;
+
+	opt->image_buf = malloc(opt->image_sz);
+	if (opt->image_buf == NULL)
+		return -1;
+
+	memset(opt->image_buf, 0, opt->image_sz);
+
+	if ((opt->pre_padding) && (opt->prepadding_size)) {
+		memset(opt->image_buf, 0x5, opt->prepadding_size);
+		offset = opt->prepadding_size;
+	}
+
+	if ((opt->post_padding) && (opt->postpadding_size))
+		memset(opt->image_buf + opt->image_sz - 4 -
+			   opt->postpadding_size,
+		       0xA, opt->postpadding_size);
+
+	memcpy(opt->image_buf + offset, buf_in, fs_stat.st_size);
+
+	return 0;
+} /* end of pre_load_image() */
+
+/*******************************************************************************
+*    build_twsi_header
+*          create TWSI header and write it into output stream
+*    INPUT:
+*          opt        user options
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+*******************************************************************************/
+int build_twsi_header(USER_OPTIONS *opt)
+{
+	FILE *f_twsi;
+	MV_U8 *tmpTwsi = NULL;
+	MV_U32 *twsi_reg;
+	int i;
+	MV_U32 twsi_size = 0;
+
+	tmpTwsi = malloc(MAX_TWSI_HDR_SIZE);
+	if (tmpTwsi == NULL) {
+		fprintf(stderr, "TWSI space allocation error!\n");
+		return -1;
+	}
+	memset(tmpTwsi, 0xFF, MAX_TWSI_HDR_SIZE);
+	twsi_reg = (MV_U32 *)tmpTwsi;
+
+	f_twsi = fopen(opt->fname_twsi, "r");
+	if (f_twsi == NULL) {
+		fprintf(stderr, "Failed to open file '%s'\n", opt->fname_twsi);
+		perror("Error:");
+		return -1;
+	}
+
+	for (i = 0; i < (MAX_TWSI_HDR_SIZE / 4); i++) {
+		if (EOF == fscanf(f_twsi, "%x\n", twsi_reg))
+			break;
+
+		/* Swap Enianess */
+		*twsi_reg =
+		    (((*twsi_reg >> 24) & 0xFF) | ((*twsi_reg >> 8) & 0xFF00) |
+		     ((*twsi_reg << 8) & 0xFF0000) |
+		     ((*twsi_reg << 24) & 0xFF000000));
+		twsi_reg++;
+	}
+
+	fclose(f_twsi);
+
+	/* Align to size = 512,1024,.. with at least 8 0xFF bytes @ the end */
+	twsi_size = ((((i + 2) * 4) & ~0x1FF) + 0x200);
+
+	if ((write(f_out, tmpTwsi, twsi_size)) != twsi_size) {
+		fprintf(stderr, "Error writing %s file\n", opt->fname.out);
+		return -1;
+	}
+
+	return 0;
+} /* end of build_twsi_header() */
+
+/*******************************************************************************
+*    build_reg_header
+*        create BIN header and write it into output stream
+*    INPUT:
+*       fname        - source file name
+*       buffer       - Start address of boot image buffer
+*       current_size - number of bytes already placed into the boot image buffer
+*    OUTPUT:
+*       none
+*    RETURN:
+*	size of a reg header or 0 on fail
+*******************************************************************************/
+int build_reg_header(char *fname, MV_U8 *buffer, MV_U32 current_size)
+{
+	FILE *f_dram;
+	BHR_t *mainHdr = (BHR_t *)buffer;
+	headExtBHR_t *headExtHdr = headExtHdr =
+	    (headExtBHR_t *)(buffer + current_size);
+	tailExtBHR_t *prevExtHdrTail =
+	    NULL; /* tail of the previous extension header */
+	MV_U32 max_bytes_to_write;
+	MV_U32 *dram_reg =
+	    (MV_U32 *)(buffer + current_size + sizeof(headExtBHR_t));
+	MV_U32 tmp_len;
+	int i;
+
+	if (mainHdr->ext == 255) {
+		fprintf(stderr, "Maximum number of extensions reached!\n");
+		return 0;
+	}
+
+	/* Indicate next header in previous extension if any */
+	if (mainHdr->ext != 0) {
+		prevExtHdrTail = (tailExtBHR_t *)(buffer + current_size -
+						  sizeof(tailExtBHR_t));
+		prevExtHdrTail->nextHdr = 1;
+	}
+
+	/* Count extension headers in the main header */
+	mainHdr->ext++;
+
+	headExtHdr->type = EXT_HDR_TYP_REGISTER;
+	max_bytes_to_write = MAX_HEADER_SIZE - current_size - EXT_HDR_BASE_SIZE;
+	f_dram = fopen(fname, "r");
+	if (f_dram  == NULL) {
+		fprintf(stderr, "Failed to open file '%s'\n", fname);
+		perror("Error:");
+		return 0;
+	}
+
+	for (i = 0; i < (max_bytes_to_write / 8); i += 2) {
+		if (fscanf(f_dram, "%x %x\n", &dram_reg[i], &dram_reg[i + 1]) ==
+		    EOF)
+			break;
+		else if ((dram_reg[i] == 0x0) && (dram_reg[i + 1] == 0x0))
+			break;
+	}
+
+	fclose(f_dram);
+
+	if (i >= (max_bytes_to_write / 8)) {
+		fprintf(stderr, "Registers configure exceeds maximum size\n");
+		return 0;
+	}
+
+	/* Include extended header head and tail sizes */
+	tmp_len = EXT_HDR_BASE_SIZE + i * 4;
+	/* Write total length into the current header fields */
+	EXT_HDR_SET_LEN(headExtHdr, tmp_len);
+
+	return tmp_len;
+} /* end of build_reg_header() */
+
+/*******************************************************************************
+*    build_bin_header
+*        create BIN header and write it into putput stream
+*    INPUT:
+*       fname        - source file name
+*       buffer       - Start address of boot image buffer
+*       current_size - number of bytes already placed into the boot image buffer
+*    OUTPUT:
+*       none
+*    RETURN:
+*	size of reg header
+*******************************************************************************/
+int build_bin_header(char *fname, MV_U8 *buffer, MV_U32 current_size)
+{
+	FILE *f_bin;
+	BHR_t *mainHdr = (BHR_t *)buffer;
+	headExtBHR_t *headExtHdr = (headExtBHR_t *)(buffer + current_size);
+	tailExtBHR_t *prevExtHdrTail =
+	    NULL; /* tail of the previous extension header */
+	MV_U32 max_bytes_to_write;
+	MV_U32 *bin_reg =
+	    (MV_U32 *)(buffer + current_size + sizeof(headExtBHR_t));
+	MV_U32 tmp_len;
+	int i;
+
+	if (mainHdr->ext == 255) {
+		fprintf(stderr, "Maximum number of extensions reached!\n");
+		return 0;
+	}
+
+	/* Indicate next header in previous extension if any */
+	if (mainHdr->ext != 0) {
+		prevExtHdrTail = (tailExtBHR_t *)(buffer + current_size -
+						  sizeof(tailExtBHR_t));
+		prevExtHdrTail->nextHdr = 1;
+	}
+
+	/* Count extension headers in main header */
+	mainHdr->ext++;
+
+	headExtHdr->type = EXT_HDR_TYP_BINARY;
+	max_bytes_to_write = MAX_HEADER_SIZE - current_size - EXT_HDR_BASE_SIZE;
+
+	f_bin = fopen(fname, "r");
+	if (f_bin == NULL) {
+		fprintf(stderr, "Failed to open file '%s'\n", fname);
+		perror("Error:");
+		return 0;
+	}
+
+	for (i = 0; i < (max_bytes_to_write / 4); i++) {
+		if (fread(bin_reg, 1, 4, f_bin) != 4)
+			break;
+
+		bin_reg++;
+	}
+
+	fclose(f_bin);
+
+	if (i >= (max_bytes_to_write / 4)) {
+		fprintf(stderr, "Binary extension exeeds the maximum size\n");
+		return 0;
+	}
+
+	/* Include extended header head and tail sizes */
+	tmp_len = EXT_HDR_BASE_SIZE + i * 4;
+	/* Write total length into the current header fields */
+	EXT_HDR_SET_LEN(headExtHdr, tmp_len);
+
+	return tmp_len;
+} /* end of build_exec_header() */
+
+/*******************************************************************************
+*    build_headers
+*          build headers block based on user options and write it into output
+*stream
+*    INPUT:
+*          opt        user options
+*          buf_in     mmapped input file
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+*******************************************************************************/
+int build_headers(USER_OPTIONS *opt, char *buf_in)
+{
+	BHR_t *hdr = NULL;
+	secExtBHR_t *secExtHdr = NULL;
+	headExtBHR_t *headExtHdr = NULL;
+	tailExtBHR_t *tailExtHdr = NULL;
+	MV_U8 *tmpHeader = NULL;
+	int i;
+	MV_U32 header_size = 0;
+	int size_written = 0;
+	MV_U32 max_bytes_to_write;
+	int error = 1;
+
+	tmpHeader = malloc(MAX_HEADER_SIZE);
+	if (tmpHeader == NULL) {
+		fprintf(stderr, "Header space allocation error!\n");
+		goto header_error;
+	}
+
+	memset(tmpHeader, 0, MAX_HEADER_SIZE);
+	hdr = (BHR_t *)tmpHeader;
+
+	switch (opt->image_type) {
+	case IMG_SATA:
+		hdr->blockID = IBR_HDR_SATA_ID;
+		break;
+
+	case IMG_UART:
+		hdr->blockID = IBR_HDR_UART_ID;
+		break;
+
+	case IMG_FLASH:
+		hdr->blockID = IBR_HDR_SPI_ID;
+		break;
+
+	case IMG_MMC:
+		hdr->blockID = IBR_HDR_MMC_ID;
+		break;
+
+	case IMG_NAND:
+		hdr->blockID = IBR_HDR_NAND_ID;
+		/*hdr->nandEccMode = (MV_U8)opt->nandEccMode; <<== reserved */
+		/*hdr->nandPageSize = (MV_U16)opt->nandPageSize; <<== reserved
+		 */
+		hdr->nandBlockSize = (MV_U8)opt->nandBlkSize;
+		if ((opt->nandCellTech == 'S') || (opt->nandCellTech == 's'))
+			hdr->nandTechnology = MAIN_HDR_NAND_SLC;
+		else
+			hdr->nandTechnology = MAIN_HDR_NAND_MLC;
+		break;
+
+	case IMG_PEX:
+		hdr->blockID = IBR_HDR_PEX_ID;
+		break;
+
+	case IMG_I2C:
+		hdr->blockID = IBR_HDR_I2C_ID;
+		break;
+
+	default:
+		fprintf(stderr,
+			"Illegal image type %d for header construction!\n",
+			opt->image_type);
+		return 1;
+	}
+
+	/* Debug print options */
+	if (opt->flags & p_OPTION_MASK)
+		hdr->flags &= ~BHR_FLAG_PRINT_EN;
+	else
+		hdr->flags |=
+		    BHR_FLAG_PRINT_EN; /* Enable printing by default */
+
+	if (opt->flags & b_OPTION_MASK) {
+		switch (opt->baudRate) {
+		case 2400:
+			hdr->options = BHR_OPT_BAUD_2400;
+			break;
+
+		case 4800:
+			hdr->options = BHR_OPT_BAUD_4800;
+			break;
+
+		case 9600:
+			hdr->options = BHR_OPT_BAUD_9600;
+			break;
+
+		case 19200:
+			hdr->options = BHR_OPT_BAUD_19200;
+			break;
+
+		case 38400:
+			hdr->options = BHR_OPT_BAUD_38400;
+			break;
+
+		case 57600:
+			hdr->options = BHR_OPT_BAUD_57600;
+			break;
+
+		case 115200:
+			hdr->options = BHR_OPT_BAUD_115200;
+			break;
+
+		default:
+			fprintf(stderr, "Unsupported baud rate - %d!\n",
+				opt->baudRate);
+			return 1;
+		}
+	} else
+		hdr->options = BHR_OPT_BAUD_DEFAULT;
+
+	/* debug port number */
+	if (opt->flags & u_OPTION_MASK)
+		hdr->options |= (opt->debugPortNum << BHR_OPT_UART_PORT_OFFS) &
+				BHR_OPT_UART_PORT_MASK;
+
+	/* debug port MPP setup index */
+	if (opt->flags & m_OPTION_MASK)
+		hdr->options |= (opt->debugPortMpp << BHR_OPT_UART_MPPS_OFFS) &
+				BHR_OPT_UART_MPPS_MASK;
+
+	hdr->destinationAddr = opt->image_dest;
+	hdr->executionAddr = (MV_U32)opt->image_exec;
+	hdr->version = MAIN_HDR_VERSION;
+	hdr->blockSize = fs_stat.st_size;
+
+	header_size = sizeof(BHR_t);
+
+	/* Update Block size address */
+	if ((opt->flags & X_OPTION_MASK) || (opt->flags & Y_OPTION_MASK)) {
+		/* Align padding to 32 bit */
+		if (opt->prepadding_size & 0x3)
+			opt->prepadding_size +=
+			    (4 - (opt->prepadding_size & 0x3));
+
+		if (opt->postpadding_size & 0x3)
+			opt->postpadding_size +=
+			    (4 - (opt->postpadding_size & 0x3));
+
+		hdr->blockSize += opt->prepadding_size + opt->postpadding_size;
+	}
+
+	/* Align the image size to 4 byte boundary */
+	if (hdr->blockSize & 0x3) {
+		opt->bytesToAlign = (4 - (hdr->blockSize & 0x3));
+		hdr->blockSize += opt->bytesToAlign;
+	}
+
+	/***************************** TWSI Header
+	 * ********************************/
+
+	/* TWSI header has a special purpose and placed ahead of the main header
+	 */
+	if (opt->flags & M_OPTION_MASK) {
+		if (opt->fname_twsi) {
+			if (build_twsi_header(opt) != 0)
+				goto header_error;
+		} /* opt->fname_twsi */
+	}	 /* (opt->flags & M_OPTION_MASK) */
+
+	/************************** End of TWSI Header
+	 * ****************************/
+
+	/********************** Single Register Header
+	 * ***************************/
+
+	if (opt->flags & R_OPTION_MASK) {
+		if (opt->fname_dram) {
+			MV_U32 rhdr_len = build_reg_header(
+			    opt->fname_dram, tmpHeader, header_size);
+			if (rhdr_len <= 0)
+				goto header_error;
+
+			header_size += rhdr_len;
+			tailExtHdr = (tailExtBHR_t *)(tmpHeader + header_size -
+						      sizeof(tailExtBHR_t));
+		} /* if (fname_dram) */
+	}	 /* if (opts & R_OPTION_MASK) */
+
+	/******************** End of Single Register Header
+	 * ************************/
+
+	/************************* Single Binary Header
+	 * ****************************/
+
+	if (opt->flags & G_OPTION_MASK) {
+		if (opt->fname_bin) {
+			MV_U32 bhdr_len = build_bin_header(
+			    opt->fname_bin, tmpHeader, header_size);
+			if (bhdr_len <= 0)
+				goto header_error;
+
+			header_size += bhdr_len;
+			tailExtHdr = (tailExtBHR_t *)(tmpHeader + header_size -
+						      sizeof(tailExtBHR_t));
+		} /* if (fname_bin) */
+	}	 /* (opt->flags & G_OPTION_MASK) */
+
+	/******************* End of Single Binary Header
+	 * ***************************/
+
+	/************************* BIN/REG Headers list
+	 * ****************************/
+
+	if (opt->flags & C_OPTION_MASK) {
+		if (opt->fname_list) {
+			FILE *f_list;
+			char buffer[PATH_MAX + 5];
+			char *fname;
+			MV_U32 hdr_len = 0, last;
+			int (*build_hdr_func)(char *, MV_U8 *, MV_U32);
+
+			f_list = fopen(opt->fname_list, "r");
+			if (f_list == NULL) {
+				fprintf(stderr, "File not found\n");
+				goto header_error;
+			}
+			/* read the headers list row by row */
+			while (fgets(buffer, PATH_MAX + 4, f_list) != NULL) {
+				/* Ignore strings that are not starting with
+				 * BIN/REG */
+				if (strncmp(buffer, "BIN", 3) == 0)
+					build_hdr_func = build_bin_header;
+				else if (strncmp(buffer, "REG", 3) == 0)
+					build_hdr_func = build_reg_header;
+				else
+					continue;
+
+				fname = buffer + 3;
+				/* strip leading spaces/tabs if any */
+				while ((strncmp(fname, " ", 1) == 0) ||
+				       (strncmp(fname, "\t", 1) == 0))
+					fname++;
+
+				/* strip trailing LF/CR symbols */
+				last = strlen(fname) - 1;
+				while ((strncmp(fname + last, "\n", 1) == 0) ||
+				       (strncmp(fname + last, "\r", 1) == 0)) {
+					fname[last] = 0;
+					last--;
+				}
+				/* Insert required header into the output buffer
+				 */
+				hdr_len = build_hdr_func(fname, tmpHeader,
+							 header_size);
+				if (hdr_len <= 0)
+					goto header_error;
+
+				header_size += hdr_len;
+				tailExtHdr =
+				    (tailExtBHR_t *)(tmpHeader + header_size -
+						     sizeof(tailExtBHR_t));
+			}
+
+			fclose(f_list);
+		} /* if (fname_list) */
+	}	 /* (opt->flags & C_OPTION_MASK) */
+
+	/********************** End of BIN/REG Headers list
+	 * ************************/
+
+	/* Align the headers block to... */
+	if (opt->image_type == IMG_NAND) {
+		/* ... NAND page size */
+		header_size +=
+		    opt->nandPageSize - (header_size & (opt->nandPageSize - 1));
+	} else if ((opt->image_type == IMG_SATA) ||
+		   (opt->image_type == IMG_MMC)) {
+		/* ... disk logical block size */
+		header_size += 512 - (header_size & 0x1FF);
+	} else if (opt->image_type == IMG_UART) {
+		/* ... Xmodem packet size */
+		header_size += 128 - (header_size & 0x7F);
+	}
+	/* Setup the image source address */
+	if (opt->image_type == IMG_SATA) {
+		if ((opt->image_source) && (opt->image_source > header_size))
+			hdr->sourceAddr = opt->image_source;
+		else
+			hdr->sourceAddr =
+			    header_size >> 9; /* Already aligned to 512 */
+	} else {
+		if ((opt->image_source) && (opt->image_source > header_size)) {
+			hdr->sourceAddr = opt->image_source;
+			opt->img_gap = opt->image_source - header_size;
+		} else {
+			/* The source imgage address should be aligned
+			   to 32 byte boundary (cache line size).
+			   For NAND it should be aligned to 512 bytes boundary
+			   (for ECC)
+			   The image immediately follows the header block,
+			   so if the source addess is undefined, it should be
+			   derived from the header size.
+			   The headers size is always  alighed to 4 byte
+			   boundary */
+			int boundary = 32;
+
+			if ((opt->image_type == IMG_NAND) ||
+			    (opt->image_type == IMG_MMC))
+				boundary = 512;
+
+			if (header_size & (boundary - 1))
+				opt->img_gap =
+				    boundary - (header_size & (boundary - 1));
+
+			hdr->sourceAddr = header_size + opt->img_gap;
+		}
+	}
+
+	/* source address and extension headers number can be written now */
+	fprintf(stdout,
+		"Ext. headers = %d, Header size = %d bytes Hdr-to-Img gap = %d bytes\n",
+		hdr->ext, header_size, opt->img_gap);
+
+	/* If not UART/TWSI image, an extra word for boot image checksum is
+	 * needed */
+	if ((opt->image_type == IMG_FLASH) || (opt->image_type == IMG_NAND) ||
+	    (opt->image_type == IMG_MMC) || (opt->image_type == IMG_SATA) ||
+	    (opt->image_type == IMG_PEX) || (opt->image_type == IMG_I2C))
+		hdr->blockSize += 4;
+
+	fprintf(stdout,
+		"New image size = %#x[%d] Source image size = %#x[%d]\n",
+		hdr->blockSize, hdr->blockSize, (unsigned int)fs_stat.st_size,
+		(int)fs_stat.st_size);
+
+	hdr->hdrSizeMsb = (header_size & 0x00FF0000) >> 16;
+	hdr->hdrSizeLsb = header_size & 0x0000FFFF;
+
+	opt->image_sz = hdr->blockSize;
+
+	/* Load image into memory buffer */
+	if (REGULAR_IMAGE(opt)) {
+		if (0 != pre_load_image(opt, buf_in)) {
+			fprintf(stderr, "Failed image pre-load!\n");
+			goto header_error;
+		}
+	}
+
+	/* Now the headers block checksum should be calculated and wrote in the
+	 * header */
+	/* This checksum value should be valid for both secure and unsecure boot
+	 * modes */
+	/* This value will be checked first before RSA key and signature
+	 * verification */
+	hdr->checkSum = checksum8((void *)hdr, MAIN_HDR_GET_LEN(hdr), 0);
+
+	/* Write to file(s) */
+	if (opt->header_mode == HDR_IMG_TWO_FILES) {
+		/* copy header to output image */
+		size_written = write(f_header, tmpHeader, header_size);
+		if (size_written != header_size) {
+			fprintf(stderr, "Error writing %s file\n"
+						, opt->fname.hdr_out);
+			goto header_error;
+		}
+
+		fprintf(stdout, "====>>>> %s was created\n",
+			opt->fname_arr[HDR_FILE_INDX]);
+		/* if (header_mode == HDR_IMG_TWO_FILES) */
+	} else {
+		/* copy header to output image */
+		size_written = write(f_out, tmpHeader, header_size);
+		if (size_written != header_size) {
+			fprintf(stderr, "Error writing %s file\n"
+						, opt->fname.out);
+			goto header_error;
+		}
+
+	} /* if (header_mode != HDR_IMG_TWO_FILES) */
+
+	error = 0;
+
+header_error:
+
+	if (tmpHeader)
+		free(tmpHeader);
+
+	return error;
+
+} /* end of build_headers() */
+
+/*******************************************************************************
+*    build_bootrom_img
+*          create image in bootrom format and write it into output stream
+*    INPUT:
+*          opt        user options
+*          buf_in     mmapped input file
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+*******************************************************************************/
+int build_bootrom_img(USER_OPTIONS *opt, char *buf_in)
+{
+	unsigned int CRC_32 = 0;
+	int tmpSize = BOOTROM_SIZE - sizeof(CRC_32);
+	char *tmpImg = NULL;
+	int size_written = 0;
+	int error = 1;
+
+	tmpImg = malloc(tmpSize);
+	if (tmpImg == NULL)
+		return 1;
+
+	/* PAD image with Zeros until BOOTROM_SIZE*/
+	memcpy(tmpImg, buf_in, fs_stat.st_size);
+	memset(tmpImg + fs_stat.st_size, 0, tmpSize - fs_stat.st_size);
+
+	/* copy input image to output image */
+	size_written = write(f_out, tmpImg, tmpSize);
+
+	/* calculate checsum */
+	CRC_32 = crc32(0, (u32 *)tmpImg, tmpSize / 4);
+	tmpSize += sizeof(CRC_32);
+	printf("Image CRC32 (size = %d) = 0x%08x\n", tmpSize, CRC_32);
+
+	size_written += write(f_out, &CRC_32, sizeof(CRC_32));
+
+	if (size_written == tmpSize)
+		error = 0;
+
+bootrom_img_error:
+
+	if (tmpImg)
+		free(tmpImg);
+
+	return error;
+} /* end of build_bootrom_img() */
+
+/*******************************************************************************
+*    build_hex_img
+*          create image in hex format and write it into output stream
+*    INPUT:
+*          opt        user options
+*          buf_in     mmapped input file
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+*******************************************************************************/
+int build_hex_img(USER_OPTIONS *opt, char *buf_in)
+{
+	FILE *f_desc[2] = {NULL};
+	char *tmpImg = NULL;
+	int hex_len;
+	int hex_unaligned_len = 0;
+	unsigned char *hex8 = NULL;
+	unsigned char tmp8;
+	unsigned short *hex16 = NULL;
+	unsigned short tmp16;
+	unsigned int *hex32 = NULL;
+	unsigned int tmp32;
+	unsigned int tmp32_low;
+	int size_written = 0;
+	int alignment = 0;
+	int files_num;
+	int i;
+	int error = 1;
+
+	/* Calculate aligned image size */
+	hex_len = fs_stat.st_size;
+
+	alignment = opt->hex_width >> 3;
+	hex_unaligned_len = fs_stat.st_size & (alignment - 1);
+
+	if (hex_unaligned_len) {
+		hex_len -= hex_unaligned_len;
+		hex_len += alignment;
+	}
+
+	/* Copy the input image to memory buffer */
+	tmpImg = malloc(hex_len);
+	if (tmpImg == NULL)
+		goto hex_image_end;
+
+	memset(tmpImg, 0, hex_len);
+	memcpy(tmpImg, buf_in, fs_stat.st_size);
+
+	if (opt->fname.hdr_out)
+		files_num = 2;
+	else
+		files_num = 1;
+
+	for (i = 0; i < files_num; i++) {
+		f_desc[i] = fopen(opt->fname_arr[i + 1], "w");
+		if (f_desc[i] == NULL)
+			goto hex_image_end;
+	}
+
+	switch (opt->hex_width) {
+	case 8:
+		hex8 = (unsigned char *)tmpImg;
+
+		for (i = 0; hex_len > 0; hex_len--) {
+			fprintf(f_desc[i], "%02X\n", *hex8++);
+			size_written += 1;
+			i ^= files_num - 1;
+		}
+		break;
+
+	case 16:
+		hex16 = (unsigned short *)tmpImg;
+
+		for (; hex_len > 0; hex_len -= 2) {
+			fprintf(f_desc[0], "%04X\n", *hex16++);
+			size_written += 2;
+		}
+		break;
+
+	case 32:
+		hex32 = (unsigned int *)tmpImg;
+
+		for (; hex_len > 0; hex_len -= 4) {
+			fprintf(f_desc[0], "%08X\n", *hex32++);
+			size_written += 4;
+		}
+		break;
+
+	case 64:
+		hex32 = (unsigned int *)tmpImg;
+
+		for (; hex_len > 0; hex_len -= 8) {
+			fprintf(f_desc[0], "%08X%08X\n", *hex32++, *hex32++);
+			size_written += 8;
+		}
+		break;
+
+	} /* switch (opt->hex_width)*/
+
+	error = 0;
+
+hex_image_end:
+
+	if (tmpImg)
+		free(tmpImg);
+
+	for (i = 0; i < files_num; i++) {
+		if (f_desc[i] != NULL)
+			fclose(f_desc[i]);
+	}
+
+	return error;
+} /* end of build_hex_img() */
+
+/*******************************************************************************
+*    build_bin_img
+*          create image in binary format and write it into output stream
+*    INPUT:
+*          opt        user options
+*          buf_in     mmapped input file
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+*******************************************************************************/
+int build_bin_img(USER_OPTIONS *opt, char *buf_in)
+{
+	FILE *f_ds = NULL;
+	FILE *f_desc[4] = {NULL};
+	char *tmpImg = NULL;
+	int hex_len = 0;
+	int one_file_len = 0;
+	int size_written = 0;
+	int alignment = 0;
+	int hex_unaligned_len = 0;
+	unsigned char *hex8 = NULL;
+	unsigned char tmp8;
+	unsigned short *hex16 = NULL;
+	unsigned short tmp16;
+	unsigned long *hex32 = NULL;
+	unsigned long tmp32;
+	unsigned long tmp32low;
+	int i;
+	int fidx;
+	int files_num = 1;
+	int error = 1;
+
+	/* Calculate aligned image size */
+	hex_len = fs_stat.st_size;
+
+	alignment = opt->hex_width >> 3;
+	hex_unaligned_len = fs_stat.st_size & (alignment - 1);
+
+	if (hex_unaligned_len) {
+		hex_len -= hex_unaligned_len;
+		hex_len += alignment;
+	}
+
+	/* prepare output files */
+	if (opt->fname.romd) /*16KB*/
+		files_num = 4;
+	else if (opt->fname.romc) /*12KB*/
+		files_num = 3;
+	else if (opt->fname.hdr_out)
+		files_num = 2;
+
+	one_file_len = hex_len / files_num;
+
+	for (i = 0; i < files_num; i++) {
+		f_desc[i] = fopen(opt->fname_arr[i + 1], "w");
+		if (f_desc[i] == NULL)
+			goto bin_image_end;
+	}
+
+	/* Copy the input image to memory buffer */
+	tmpImg = malloc(hex_len);
+	if (tmpImg == NULL)
+		goto bin_image_end;
+
+	memset(tmpImg, 0, (hex_len));
+	memcpy(tmpImg, buf_in, fs_stat.st_size);
+
+	/* Split output image buffer according to width and number of files */
+	switch (opt->hex_width) {
+	case 8:
+		hex8 = (unsigned char *)tmpImg;
+		if (files_num != 2) {
+			fprintf(stderr,
+				"Must supply two output file names for this width!\n");
+			goto bin_image_end;
+		}
+
+		for (fidx = 1; (fidx >= 0) && (hex_len > 0); fidx--) {
+			f_ds = f_desc[1 - fidx];
+
+			for (; hex_len > (fidx * one_file_len); hex_len--) {
+				tmp8 = *hex8;
+
+				for (i = 0; i < opt->hex_width; i++) {
+					fprintf(f_ds, "%d",
+						((tmp8 & 0x80) >> 7));
+					tmp8 <<= 1;
+				}
+				fprintf(f_ds, "\n");
+
+				hex8++;
+				size_written += 1;
+			}
+		}
+		break;
+
+	case 16:
+		hex16 = (unsigned short *)tmpImg;
+
+		for (; hex_len > 0; hex_len -= 2) {
+			tmp16 = *hex16;
+
+			for (i = 0; i < opt->hex_width; i++) {
+				fprintf(f_desc[0], "%d",
+					((tmp16 & 0x8000) >> 15));
+				tmp16 <<= 1;
+			}
+			fprintf(f_desc[0], "\n");
+
+			hex16++;
+			size_written += 2;
+		}
+		break;
+
+	case 32:
+		hex32 = (long *)tmpImg;
+
+		for (fidx = files_num - 1; (fidx >= 0) && (hex_len > 0);
+		     fidx--) {
+			f_ds = f_desc[files_num - 1 - fidx];
+
+			for (; hex_len > (fidx * one_file_len); hex_len -= 4) {
+				tmp32 = *hex32;
+
+				for (i = 0; i < opt->hex_width; i++) {
+					fprintf(f_ds, "%ld",
+						((tmp32 & 0x80000000) >> 31));
+					tmp32 <<= 1;
+				}
+				fprintf(f_ds, "\n");
+				hex32++;
+				size_written += 4;
+			}
+		}
+		break;
+
+	case 64:
+		hex32 = (long *)tmpImg;
+
+		for (; hex_len > 0; hex_len -= 8) {
+			tmp32low = *hex32++;
+			tmp32 = *hex32++;
+
+			for (i = 0; i < 32; i++) {
+				fprintf(f_desc[0], "%ld",
+					((tmp32 & 0x80000000) >> 31));
+				tmp32 <<= 1;
+			}
+			for (i = 0; i < 32; i++) {
+				fprintf(f_desc[0], "%ld",
+					((tmp32low & 0x80000000) >> 31));
+				tmp32low <<= 1;
+			}
+			fprintf(f_desc[0], "\n");
+			size_written += 8;
+		}
+		break;
+	} /* switch (opt->hex_width) */
+
+	error = 0;
+
+bin_image_end:
+
+	if (tmpImg)
+		free(tmpImg);
+
+	for (i = 0; i < files_num; i++) {
+		if (f_desc[i] != NULL)
+			fclose(f_desc[i]);
+	}
+
+	return error;
+
+} /*  end of build_bin_img() */
+
+/*******************************************************************************
+*    build_regular_img
+*          create regular boot image and write it into output stream
+*    INPUT:
+*          opt        user options
+*          buf_in     mmapped input file
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+*******************************************************************************/
+int build_regular_img(USER_OPTIONS *opt, char *buf_in)
+{
+	int size_written = 0;
+	int new_file_size = 0;
+	MV_U32 chsum32 = 0;
+
+	new_file_size = opt->image_sz;
+
+	if (0 != opt->img_gap) { /* cache line/NAND page/requested offset image
+				    alignment */
+		MV_U8 *gap_buf;
+
+		gap_buf = calloc(opt->img_gap, sizeof(MV_U8));
+		if (gap_buf == NULL) {
+			fprintf(stderr,
+				"Failed to allocate memory for header to image gap!\n");
+			return 1;
+		}
+		size_written += write(f_out, gap_buf, opt->img_gap);
+		new_file_size += opt->img_gap;
+		free(gap_buf);
+	}
+
+	/* Calculate checksum and copy it to the image tail */
+	chsum32 = checksum32((void *)opt->image_buf, opt->image_sz - 4, 0);
+	memcpy(opt->image_buf + opt->image_sz - 4, &chsum32, 4);
+
+	/* copy input image to output image */
+	size_written += write(f_out, opt->image_buf, opt->image_sz);
+	free(opt->image_buf);
+
+	if (new_file_size != size_written) {
+		fprintf(stderr, "Size mismatch between calculated/written\n");
+		return 1;
+	}
+
+	return 0;
+} /* end of build_other_img() */
+
+/*******************************************************************************
+*    process_image
+*          handle input and output file options, read and verify RSA and AES
+*keys.
+*    INPUT:
+*          opt        user options
+*    OUTPUT:
+*          none
+*    RETURN:
+*          0 on success
+******************************************************************************/
+int process_image(USER_OPTIONS *opt)
+{
+	int i;
+	int override[2];
+	char *buf_in = NULL;
+	int err = 1;
+
+	/* check if the output image exist */
+	printf(" ");
+	for (i = IMG_FILE_INDX; i <= HDR_FILE_INDX; i++) {
+		if (opt->fname_arr[i]) {
+			override[i] = 0;
+
+			if (0 == stat(opt->fname_arr[i], &fs_stat)) {
+				char c;
+				/* ask for overwrite permissions */
+				fprintf(stderr,
+					"File '%s' already exist! Overwrite it (Y/n)?",
+					opt->fname_arr[i]);
+				c = getc(stdin);
+				if ((c == 'N') || (c == 'n')) {
+					printf("exit.. nothing done.\n");
+					exit(0);
+				} else if ((c == 'Y') || (c == 'y')) {
+					/* additional read is needed for Enter
+					 * key */
+					c = getc(stdin);
+				}
+				override[i] = 1;
+			}
+		}
+	}
+
+	/* open input image file and check if it's size is OK */
+	if (opt->header_mode != HDR_ONLY) {
+		f_in = open(opt->fname.in, O_RDONLY | O_BINARY);
+		if (f_in == -1) {
+			fprintf(stderr, "File '%s' not found\n", opt->fname.in);
+			goto end;
+		}
+		/* get the size of the input image */
+		if (0 != fstat(f_in, &fs_stat)) {
+			fprintf(stderr, "fstat failed for file: '%s' err=%d\n",
+				opt->fname.in, err);
+			goto end;
+		}
+		/*Check the source image size for limited output storage
+		 * (bootrom) */
+		if (opt->image_type == IMG_BOOTROM) {
+			int max_img_size = BOOTROM_SIZE - sizeof(u32);
+
+			if (fs_stat.st_size > max_img_size) {
+				fprintf(stderr,
+					"ERROR : source image is bigger than %d bytes\n",
+					max_img_size);
+				goto end;
+			}
+		}
+		/* map the input image */
+		buf_in =
+		    mmap(0, fs_stat.st_size, PROT_READ, MAP_SHARED, f_in, 0);
+		if (!buf_in) {
+			fprintf(stderr, "Error mapping %s file\n",
+				opt->fname.in);
+			goto end;
+		}
+	}
+
+	/* open the output image file */
+	if (override[IMG_FILE_INDX] == 0)
+		f_out = open(opt->fname.out,
+			     O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0666);
+	else
+		f_out = open(opt->fname.out, O_RDWR | O_BINARY);
+
+	if (f_out == -1) {
+		fprintf(stderr, "Error opening %s file\n", opt->fname.out);
+		goto end;
+	}
+
+	/* open the output header file */
+	if (opt->header_mode == HDR_IMG_TWO_FILES) {
+		if (override[HDR_FILE_INDX] == 0)
+			f_header =
+			    open(opt->fname.hdr_out,
+				 O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0666);
+		else
+			f_header = open(opt->fname.hdr_out, O_RDWR | O_BINARY);
+
+		if (f_header == -1) {
+			fprintf(stderr, "Error opening %s file\n",
+				opt->fname.hdr_out);
+			goto end;
+		}
+	}
+
+	/* Image Header(s)  */
+	if (opt->header_mode != IMG_ONLY) {
+		if (0 != build_headers(opt, buf_in))
+			goto end;
+	}
+
+	/* Output Image  */
+	if (opt->header_mode != HDR_ONLY) {
+		if (opt->image_type == IMG_BOOTROM)
+			err = build_bootrom_img(opt, buf_in);
+		else if (opt->image_type == IMG_HEX)
+			err = build_hex_img(opt, buf_in);
+		else if (opt->image_type == IMG_BIN)
+			err = build_bin_img(opt, buf_in);
+		else
+			err = build_regular_img(opt, buf_in);
+
+		if (err != 0) {
+			fprintf(stderr, "Error writing %s file\n"
+						, opt->fname.out);
+			goto end;
+		}
+
+		fprintf(stdout, "====>>>> %s was created\n",
+			opt->fname_arr[IMG_FILE_INDX]);
+
+	} /* if (opt->header_mode != HDR_ONLY) */
+
+end:
+	/* close handles */
+	if (f_out != -1)
+		close(f_out);
+
+	if (f_header != -1)
+		close(f_header);
+
+	if (buf_in)
+		munmap((void *)buf_in, fs_stat.st_size);
+
+	if (f_in != -1)
+		close(f_in);
+
+	return err;
+
+} /* end of process_image() */
+
+/*******************************************************************************
+*    print_usage
+*          print command switches and their description
+*    INPUT:
+*          none
+*    OUTPUT:
+*          none
+*    RETURN:
+*          none
+*******************************************************************************/
+void print_usage(void)
+{
+	printf(
+	    "==============================================================================================\n\n");
+	printf("Marvell doimage Tool version %s\n", VERSION_NUMBER);
+	printf("Supported SoC devices:\n\t%s\n", PRODUCT_SUPPORT);
+	printf(
+	    "==============================================================================================\n\n");
+	printf("Usage:\n");
+	printf(
+	    "doimage <mandatory_opt> [other_options] [bootrom_output] <image_in> <image_out> [header_out]\n\n");
+
+	printf("<mandatory_opt> - can be one or more of the following:\n");
+	printf(
+	    "==============================================================================================\n\n");
+
+	printf(
+	    "-T image_type:   sata\\uart\\flash\\bootrom\\nand\\hex\\bin\\pex\\mmc\n");
+	printf("-D image_dest:   image destination in dram (in hex)\n");
+	printf("-E image_exec:   execution address in dram (in hex)\n");
+	printf(
+	    "                 if image_type is 'flash' and image_dest is 0xffffffff\n");
+	printf("                 then execution address on the flash\n");
+	printf(
+	    "-S image_source: if image_type is sata then the starting sector of\n");
+	printf("                 the source image on the disk\n");
+	printf(
+	    "                 if image_type is flash\\nand then the starting offset of\n");
+	printf(
+	    "                 the source image at the flash - optional for flash\\nand\n");
+	printf("-W hex_width :   HEX file width, can be 8,16,32,64\n");
+	printf(
+	    "-M twsi_file:    ascii file name that contains the I2C init regs set by h/w.\n");
+	printf("                 this is used in i2c boot only\n");
+
+	printf("\nThe following options are mandatory for NAND image type:\n");
+	printf(
+	    "-----------------------------------------------------------------------------------------------\n\n");
+
+	printf(
+	    "-L nand_blk_size:NAND block size in KBytes (decimal int in range 64-16320)\n");
+	printf(
+	    "                 This parameter is ignored for flashes with  512B pages\n");
+	printf(
+	    "                 Such small page flashes always use 16K block sizes\n");
+	printf(
+	    "-N nand_cell_typ:NAND cell technology type (char: M for MLC, S for SLC)\n");
+	printf(
+	    "-P nand_pg_size: NAND page size: (decimal 512, 2048, 4096 or 8192)\n");
+
+	printf(
+	    "-G exec_file:    ascii file name that contains binary routine (ARM 5TE THUMB)\n");
+	printf(
+	    "                 to run before the bootloader image execution.\n");
+	printf(
+	    "                 The routine must contain an appropriate code for saving\n");
+	printf(
+	    "                 all registers at the routine start and restore them\n");
+	printf("                 before return from the routine\n");
+	printf(
+	    "-R dram_file:    ascii file name that contains the list of dram regs\n");
+	printf(
+	    "-C hdrs_file:    ascii file name that defines BIN/REG headers order and their sources\n");
+	printf("-X pre_padding_size (hex)\n");
+	printf("-Y post_padding_size (hex)\n");
+	printf("-H header_mode: Header mode, can be:\n");
+	printf(
+	    "                -H 1 : will create one file (image_out) for header and image\n");
+	printf(
+	    "                -H 2 : will create two files, (image_out) for image , (header_out) for header\n");
+	printf(
+	    "                -H 3 : will create one file (image_out) for header only\n");
+	printf(
+	    "                -H 4 : will create one file (image_out) for image only\n");
+
+	printf(
+	    "\n[bootrom_output] - optional and can be one or more of the following:\n");
+	printf(
+	    "==============================================================================================\n\n");
+
+	printf(
+	    "-p               Disable BootROM messages output to UART port (enabled by default)\n");
+	printf("-b baudrate      Set BootROM debug port UART baudrate\n");
+	printf(
+	    "                 value = 2400,4800,9600,19200,38400,57600,115200 (use default baudrate is omitted)\n");
+	printf(
+	    "-u port_num      Set BootROM debug port UART number value = 0-3 (use default port if omitted)\n");
+	printf(
+	    "-m mpp_config    Select BootROM debug port MPPs configuration value = 0-7 (BootROM-specific)\n");
+
+	printf("\nCommand examples:\n\n");
+
+	printf("doimage -T hex -W width image_in image_out\n");
+	printf("doimage -T bootrom image_in image_out\n");
+	printf("doimage -T resume image_in image_out\n");
+	printf("doimage -T sata -S sector -D image_dest -E image_exec\n");
+	printf("         [other_options] image_in image_out header_out\n\n");
+	printf("doimage -T flash -D image_dest -E image_exec [-S address]\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf("doimage -T pex -D image_dest -E image_exec\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf(
+	    "doimage -T nand -D image_dest -E image_exec [-S address] -P page_size\n");
+	printf("         -L 2 -N S [other_options] image_in image_out\n\n");
+	printf("doimage -T uart -D image_dest -E image_exec\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf("doimage -T pex -D image_dest -E image_exec\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf("\n\n");
+
+} /* end of print_usage() */
+
+/*******************************************************************************
+*    checksum8
+*          calculate 8-bit checksum of memory buffer
+*    INPUT:
+*          start        buffer start
+*          len          buffer length
+*          csum         initial checksum value
+*    OUTPUT:
+*          none
+*    RETURN:
+*          8-bit buffer checksum
+*******************************************************************************/
+MV_U8 checksum8(void *start, MV_U32 len, MV_U8 csum)
+{
+	register MV_U8 sum = csum;
+
+	volatile MV_U8 *startp = (volatile MV_U8 *)start;
+
+	do {
+		sum += *(MV_U8 *)startp;
+		startp++;
+
+	} while (--len);
+
+	return sum;
+
+} /* end of checksum8 */
+
+/*******************************************************************************
+*    checksum32
+*          calculate 32-bit checksum of memory buffer
+*    INPUT:
+*          start        buffer start
+*          len          buffer length
+*          csum         initial checksum value
+*    OUTPUT:
+*          none
+*    RETURN:
+*          32-bit buffer checksum
+*******************************************************************************/
+MV_U32 checksum32(void *start, MV_U32 len, MV_U32 csum)
+{
+	register MV_U32 sum = csum;
+	volatile MV_U32 *startp = (volatile MV_U32 *)start;
+
+	do {
+		sum += *(MV_U32 *)startp;
+		startp++;
+		len -= 4;
+
+	} while (len);
+
+	return sum;
+
+} /* *end of checksum32() */
+
+/*******************************************************************************
+*    make_crc_table
+*          init CRC table
+*    INPUT:
+*          crc_table   CRC table location
+*    OUTPUT:
+*          crc_table   CRC table location
+*    RETURN:
+*          none
+*******************************************************************************/
+void make_crc_table(MV_U32 *crc_table)
+{
+	MV_U32 c;
+	MV_32 n, k;
+	MV_U32 poly;
+
+	/* terms of polynomial defining this crc (except x^32): */
+	static const MV_U8 p[] = {0,  1,  2,  4,  5,  7,  8,
+				  10, 11, 12, 16, 22, 23, 26};
+
+	/* make exclusive-or pattern from polynomial (0xedb88320L) */
+	poly = 0L;
+	for (n = 0; n < sizeof(p) / sizeof(MV_U8); n++)
+		poly |= 1L << (31 - p[n]);
+
+	for (n = 0; n < 256; n++) {
+		c = (MV_U32)n;
+		for (k = 0; k < 8; k++)
+			c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+		crc_table[n] = c;
+	}
+
+} /* end of make_crc_table */
+
+#define DO1(buf) (crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8))
+#define DO2(buf) do {                                                 \
+	DO1(buf);                                                     \
+	DO1(buf);							\
+	} while (0)
+#define DO4(buf) do {                                                   \
+	DO2(buf);                                                       \
+	DO2(buf);							\
+	} while (0)
+#define DO8(buf) do {                                                   \
+	DO4(buf);                                                       \
+	DO4(buf);							\
+	} while (0)
+
+/*******************************************************************************
+*    crc32
+*          calculate CRC32 on memory buffer
+*    INPUT:
+*          crc       initial CRC value
+*          buf       memory buffer
+*          len       buffer length
+*    OUTPUT:
+*          none
+*    RETURN:
+*          CRC32 of the memory buffer
+*******************************************************************************/
+MV_U32 crc32(MV_U32 crc, volatile MV_U32 *buf, MV_U32 len)
+{
+	MV_U32 crc_table[256];
+
+	/* Create the CRC table */
+	make_crc_table(crc_table);
+
+	crc = crc ^ 0xffffffffL;
+	while (len >= 8) {
+		DO8(buf);
+		len -= 8;
+	}
+
+	if (len) {
+		do {
+			DO1(buf);
+		} while (--len);
+	}
+
+	return crc ^ 0xffffffffL;
+
+} /* end of crc32() */
+
+/*******************************************************************************
+*    select_image
+*          select image options by the image name
+*    INPUT:
+*          img_name       image name
+*    OUTPUT:
+*          opt            image options
+*    RETURN:
+*          0 on success, 1 if image name is invalid
+*******************************************************************************/
+int select_image(char *img_name, USER_OPTIONS *opt)
+{
+	int i;
+
+	static IMG_MAP img_map[] = {
+	    {IMG_SATA, "sata", D_OPTION_MASK | T_OPTION_MASK | E_OPTION_MASK},
+	    {IMG_UART, "uart", D_OPTION_MASK | T_OPTION_MASK | E_OPTION_MASK},
+	    {IMG_FLASH, "flash", D_OPTION_MASK | T_OPTION_MASK | E_OPTION_MASK},
+	    {IMG_MMC, "mmc", D_OPTION_MASK | T_OPTION_MASK | E_OPTION_MASK},
+	    {IMG_BOOTROM, "bootrom", T_OPTION_MASK},
+	    {IMG_NAND, "nand", D_OPTION_MASK | T_OPTION_MASK | E_OPTION_MASK |
+				   L_OPTION_MASK | N_OPTION_MASK |
+				   P_OPTION_MASK},
+	    {IMG_HEX, "hex", T_OPTION_MASK | W_OPTION_MASK},
+	    {IMG_BIN, "bin", T_OPTION_MASK | W_OPTION_MASK},
+	    {IMG_PEX, "pex", D_OPTION_MASK | T_OPTION_MASK | E_OPTION_MASK},
+	    {IMG_I2C, "i2c",
+	     D_OPTION_MASK | T_OPTION_MASK | E_OPTION_MASK | M_OPTION_MASK},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(img_map); i++) {
+		if (strcmp(img_name, img_map[i].img_name) == 0) {
+			opt->image_type = img_map[i].img_type;
+			opt->req_flags = img_map[i].img_opt;
+			return 0;
+		}
+	}
+
+	return 1;
+
+} /* *end of select_image() */
+
+/*******************************************************************************
+*    main
+*******************************************************************************/
+int main(int argc, char **argv)
+{
+	USER_OPTIONS options;
+	int optch; /* command-line option char */
+	static char optstring[] =
+	    "T:D:E:X:Y:S:P:W:H:R:M:G:L:N:C:b:u:m:p";
+	int i, k;
+
+	if (argc < 2)
+		goto parse_error;
+
+	memset(&options, 0, sizeof(USER_OPTIONS));
+	options.header_mode = HDR_IMG_ONE_FILE;
+
+	fprintf(stdout, "\n");
+
+	while ((optch = getopt(argc, argv, optstring)) != -1) {
+		char *endptr = NULL;
+
+		switch (optch) {
+		case 'T': /* image type */
+			if ((select_image(optarg, &options) != 0) ||
+			    (options.flags & T_OPTION_MASK))
+				goto parse_error;
+			options.flags |= T_OPTION_MASK;
+			break;
+
+		case 'D': /* image destination  */
+			options.image_dest = strtoul(optarg, &endptr, 16);
+			if (*endptr || (options.flags & D_OPTION_MASK))
+				goto parse_error;
+			options.flags |= D_OPTION_MASK;
+			DB("Image destination address %#x\n",
+			   options.image_dest);
+			break;
+
+		case 'E': /* image execution  */
+			options.image_exec = strtoul(optarg, &endptr, 16);
+			if (*endptr || (options.flags & E_OPTION_MASK))
+				goto parse_error;
+			options.flags |= E_OPTION_MASK;
+			DB("Image execution address %#x\n", options.image_exec);
+			break;
+
+		case 'X': /* Pre - Padding */
+			options.prepadding_size = strtoul(optarg, &endptr, 16);
+			if (*endptr || (options.flags & X_OPTION_MASK))
+				goto parse_error;
+			options.pre_padding = 1;
+			options.flags |= X_OPTION_MASK;
+			DB("Pre-pad image by %#x bytes\n",
+			   options.prepadding_size);
+			break;
+
+		case 'Y': /* Post - Padding */
+			options.postpadding_size = strtoul(optarg, &endptr, 16);
+			if (*endptr || (options.flags & Y_OPTION_MASK))
+				goto parse_error;
+			options.post_padding = 1;
+			options.flags |= Y_OPTION_MASK;
+			DB("Post-pad image by %#x bytes\n",
+			   options.postpadding_size);
+			break;
+
+		case 'S': /* starting sector */
+			options.image_source = strtoul(optarg, &endptr, 16);
+			if (*endptr || (options.flags & S_OPTION_MASK))
+				goto parse_error;
+			options.flags |= S_OPTION_MASK;
+			DB("Image start sector (image source) %#x\n",
+			   options.image_source);
+			break;
+
+		case 'P': /* NAND Page Size */
+			options.nandPageSize = strtoul(optarg, &endptr, 10);
+			if (*endptr || (options.flags & P_OPTION_MASK))
+				goto parse_error;
+			options.flags |= P_OPTION_MASK;
+			DB("NAND page size %d bytes\n", options.nandPageSize);
+			break;
+
+		case 'C': /* headers definition filename */
+			options.fname_list = optarg;
+			if (options.flags & C_OPTION_MASK)
+				goto parse_error;
+			options.flags |= C_OPTION_MASK;
+			DB("Headers definition file name %s\n",
+			   options.fname_list);
+			break;
+
+		case 'W': /* HEX file width */
+			options.hex_width = strtoul(optarg, &endptr, 10);
+			if (*endptr || (options.flags & W_OPTION_MASK))
+				goto parse_error;
+			options.flags |= W_OPTION_MASK;
+			DB("HEX file width %d bytes\n", options.hex_width);
+			break;
+
+		case 'H': /* Header file mode */
+			options.header_mode = strtoul(optarg, &endptr, 10);
+			if (*endptr || (options.flags & H_OPTION_MASK))
+				goto parse_error;
+			options.flags |= H_OPTION_MASK;
+			DB("Header file mode is %d\n", options.header_mode);
+			break;
+
+		case 'R': /* dram file */
+			options.fname_dram = optarg;
+			if (options.flags & R_OPTION_MASK)
+				goto parse_error;
+			options.flags |= R_OPTION_MASK;
+			DB("Registers header file name %s\n",
+			   options.fname_dram);
+			break;
+
+		case 'M': /* TWSI file */
+			options.fname_twsi = optarg;
+			if (options.flags & M_OPTION_MASK)
+				goto parse_error;
+			options.flags |= M_OPTION_MASK;
+			DB("TWSI header file name %s\n", options.fname_twsi);
+			break;
+
+		case 'G': /* binary file */
+			options.fname_bin = optarg;
+			if (options.flags & G_OPTION_MASK)
+				goto parse_error;
+			options.flags |= G_OPTION_MASK;
+			DB("Binary header file name %s\n", options.fname_bin);
+			break;
+
+		case 'L': /* NAND block size */
+			options.nandBlkSize = strtoul(optarg, &endptr, 10) / 64;
+			if (*endptr || (options.flags & L_OPTION_MASK))
+				goto parse_error;
+			options.flags |= L_OPTION_MASK;
+			DB("NAND block size %d\n", options.nandBlkSize);
+			break;
+
+		case 'N': /* NAND cell technology */
+			options.nandCellTech = optarg[0];
+			if (options.flags & N_OPTION_MASK)
+				goto parse_error;
+			options.flags |= N_OPTION_MASK;
+			DB("NAND cell technology %c\n", options.nandCellTech);
+			break;
+
+		case 'p': /* BootROM debug output */
+			if (options.flags & p_OPTION_MASK)
+				goto parse_error;
+			options.flags |= p_OPTION_MASK;
+			DB("BootROM debug output disabled\n");
+			break;
+
+		case 'b': /* BootROM debug port baudrate */
+			options.baudRate = strtoul(optarg, &endptr, 10);
+			if (*endptr || (options.flags & b_OPTION_MASK))
+				goto parse_error;
+			options.flags |= b_OPTION_MASK;
+			DB("BootROM debug port baudrate %d\n",
+			   options.baudRate);
+			break;
+
+		case 'u': /* BootROM debug port number */
+			options.debugPortNum = strtoul(optarg, &endptr, 10);
+			if (*endptr || (options.flags & u_OPTION_MASK))
+				goto parse_error;
+			options.flags |= u_OPTION_MASK;
+			DB("BootROM debug port number %d\n",
+			   options.debugPortNum);
+			break;
+
+		case 'm': /* BootROM debug port MPP settings */
+			options.debugPortMpp = strtoul(optarg, &endptr, 10);
+			if (*endptr || (options.flags & m_OPTION_MASK))
+				goto parse_error;
+			options.flags |= m_OPTION_MASK;
+			DB("BootROM debug port MPP setup # %d\n",
+			   options.debugPortMpp);
+			break;
+
+		default:
+			goto parse_error;
+		}
+	} /* parse command-line options */
+
+	/* assign file names */
+	for (i = 0; (optind < argc) && (i < ARRAY_SIZE(options.fname_arr));
+	     ++optind, i++) {
+		options.fname_arr[i] = argv[optind];
+		DB("File @ array index %d is %s (option index is %d)\n", i,
+		   argv[optind], optind);
+		/* verify that all file names are different */
+		for (k = 0; k < i; k++) {
+			if (0 == strcmp(options.fname_arr[i],
+					options.fname_arr[k])) {
+				fprintf(stderr,
+				    "\nError: Input and output images can't be the same\n");
+				exit(1);
+			}
+		}
+	}
+
+	if (!(options.flags & T_OPTION_MASK))
+		goto parse_error;
+
+	/* verify HEX/BIN file width selection to be valid */
+	if ((options.flags & W_OPTION_MASK) && (options.hex_width != 8) &&
+	    (options.hex_width != 16) && (options.hex_width != 32) &&
+	    (options.hex_width != 64))
+		goto parse_error;
+	/* BootROM test images, no header is needed */
+	if ((options.image_type == IMG_BOOTROM) ||
+	    (options.image_type == IMG_HEX) || (options.image_type == IMG_BIN))
+		options.header_mode = IMG_ONLY;
+
+	if (options.header_mode == IMG_ONLY) {
+		/* remove unneeded options */
+		options.req_flags &=
+		    ~(D_OPTION_MASK | E_OPTION_MASK | S_OPTION_MASK |
+		      R_OPTION_MASK | P_OPTION_MASK | L_OPTION_MASK |
+		      N_OPTION_MASK);
+	}
+
+	if (options.req_flags != (options.flags & options.req_flags))
+		goto parse_error;
+
+	if ((options.flags & L_OPTION_MASK) &&
+	    ((options.nandBlkSize > 255) ||
+	     ((options.nandBlkSize == 0) && (options.nandPageSize != 512)))) {
+		fprintf(stderr, "Error: wrong NAND block size %d!\n\n\n\n\n",
+			64 * options.nandBlkSize);
+		goto parse_error;
+	}
+
+	if ((options.flags & N_OPTION_MASK) && (options.nandCellTech != 'S') &&
+	    (options.nandCellTech != 'M') && (options.nandCellTech != 's') &&
+	    (options.nandCellTech != 'm')) {
+		fprintf(stderr,
+			"Error: Wrong NAND cell technology type!\n\n\n\n\n");
+		goto parse_error;
+	}
+
+	return process_image(&options);
+
+parse_error:
+
+	print_usage();
+	exit(1);
+
+} /* end of main() */
diff --git a/util/marvell/doimage_mv/doimage.h b/util/marvell/doimage_mv/doimage.h
new file mode 100644
index 0000000..d0000c2
--- /dev/null
+++ b/util/marvell/doimage_mv/doimage.h
@@ -0,0 +1,155 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED.  The GPL License provides additional details about this warranty
+disclaimer.
+
+*******************************************************************************/
+#ifndef _INC_DOIMAGE_H
+#define _INC_DOIMAGE_H
+
+#include <sys/types.h>
+
+/* use the same version as in "bootrom.inc" file */
+#define VERSION_NUMBER "2.20"
+#define PRODUCT_SUPPORT "Marvell Armada-3xx series"
+
+#define RSA_KEY_SIZE 2048
+#define RSA_EXPONENT 65537
+
+#define T_OPTION_MASK 0x1       /* image type */
+#define D_OPTION_MASK 0x2       /* image destination */
+#define E_OPTION_MASK 0x4       /* image execution address */
+#define S_OPTION_MASK 0x8       /* starting sector */
+#define R_OPTION_MASK 0x10      /* DRAM file */
+#define C_OPTION_MASK 0x20      /* headers definition file */
+#define P_OPTION_MASK 0x40      /* NAND Page size */
+#define M_OPTION_MASK 0x80      /* TWSI serial init file */
+#define W_OPTION_MASK 0x100     /* HEX file width */
+#define H_OPTION_MASK 0x200     /* Header mode */
+#define X_OPTION_MASK 0x400     /* Pre padding */
+#define Y_OPTION_MASK 0x800     /* Post padding */
+#define J_OPTION_MASK 0x1000    /* JTAG Enabled */
+#define B_OPTION_MASK 0x2000    /* Box ID */
+#define Z_OPTION_MASK 0x4000    /* secure boot mode - KAK private key */
+#define F_OPTION_MASK 0x8000    /* Flash ID */
+#define A_OPTION_MASK 0x10000   /* secure boot mode - CSK private key */
+#define G_OPTION_MASK 0x20000   /* binary file */
+#define K_OPTION_MASK 0x40000   /* secure boot mode - CSK private key index */
+#define L_OPTION_MASK 0x80000   /* NAND block size (in 64K chunks) */
+#define N_OPTION_MASK 0x100000  /* NAND cell technology MLC/SLC */
+#define p_OPTION_MASK 0x200000  /* Print enable */
+#define b_OPTION_MASK 0x400000  /* Baudrate */
+#define u_OPTION_MASK 0x800000  /* debug serial port number */
+#define m_OPTION_MASK 0x1000000 /* debug serial port MPP configuration */
+
+#ifndef O_BINARY /* should be defined on __WIN32__ */
+#define O_BINARY 0
+#endif
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+typedef enum {
+	IMG_SATA,
+	IMG_UART,
+	IMG_FLASH,
+	IMG_MMC,
+	IMG_BOOTROM,
+	IMG_NAND,
+	IMG_HEX,
+	IMG_BIN,
+	IMG_PEX,
+	IMG_I2C
+
+} IMG_TYPE;
+
+#define REGULAR_IMAGE(opt)                                                     \
+	(((opt)->image_type != IMG_BOOTROM) &&                                 \
+	 ((opt)->image_type != IMG_HEX) && ((opt)->image_type != IMG_BIN))
+
+typedef struct {
+	IMG_TYPE img_type;    /* image type */
+	char *img_name;       /* image name string */
+	unsigned int img_opt; /* mandatory options for this image type */
+
+} IMG_MAP;
+
+typedef enum {
+	IMG_FILE_INDX = 1,
+	HDR_FILE_INDX = 2
+
+} FILE_IDX;
+
+typedef enum {
+	HDR_IMG_ONE_FILE = 1,  /* Create one file with header and image */
+	HDR_IMG_TWO_FILES = 2, /* Create separate header and image files */
+	HDR_ONLY = 3,	  /* Create only header */
+	IMG_ONLY = 4,	  /* Create only image */
+
+} HEADER_MODE;
+
+typedef struct {
+	IMG_TYPE image_type;
+	char *fname_dram;	 /* DRAM init file for "register" header */
+	char *fname_twsi;	 /* TWSI serial init file */
+	char *fname_bin;	  /* binary code file for "binary" header */
+	char *fname_prkey;	/* KAK RSA Private key file */
+	char *fname_prkeyCsk;     /* CSK RSA Private key file */
+	char *fname_list;	 /* headers definition file */
+	u32 flags;		  /* user-defined flags */
+	u32 req_flags;		  /* mandatory flags */
+	u32 image_source;	 /* starting sector */
+	u32 image_dest;		  /* image destination  */
+	u32 image_exec;		  /* image execution  */
+	unsigned int hex_width;   /* HEX file width */
+	unsigned int header_mode; /* Header file mode */
+	int csk_index;
+	int pre_padding;
+	int post_padding;
+	int prepadding_size;
+	int postpadding_size;
+	unsigned int bytesToAlign;
+	unsigned int nandPageSize;
+	unsigned int nandBlkSize;
+	char nandCellTech;
+	u32 boxId;
+	u32 flashId;
+	u32 jtagDelay;
+	char *image_buf;  /* image buffer for image pre-load */
+	u32 image_sz;     /* total size of pre-loaded image buffer including
+			     paddings */
+	u32 img_gap;      /* gap between header and image start point */
+	u32 baudRate;     /* debug print port baudrate */
+	u32 debugPortNum; /* debug print port number */
+	u32 debugPortMpp; /* debug print port MPP configuration */
+	union {
+		char *fname_arr[5];
+		struct {
+			char *in;
+			char *out;
+			char *hdr_out;
+			char *romc;
+			char *romd;
+		} fname;
+	};
+} USER_OPTIONS;
+
+/* Function declaration */
+void print_usage(void);
+
+/* 32 bit checksum */
+MV_U32 checksum32(void *start, MV_U32 len, MV_U32 csum);
+MV_U8 checksum8(void *start, MV_U32 len, MV_U8 csum);
+MV_U32 crc32(MV_U32 crc, volatile MV_U32 *buf, MV_U32 len);
+
+#endif /* _INC_DOIMAGE_H */



More information about the coreboot-gerrit mailing list