xref: /rk3399_ARM-atf/tools/nxp/create_pbl/create_pbl.c (revision 4bd8c929b4bc6e1731c2892b38d4a8c43e8e89dc)
132669476SPankaj Gupta /*
231af441aSBiwen Li  * Copyright 2021-2022 NXP
332669476SPankaj Gupta  *
432669476SPankaj Gupta  * SPDX-License-Identifier: BSD-3-Clause
532669476SPankaj Gupta  *
632669476SPankaj Gupta  */
732669476SPankaj Gupta 
832669476SPankaj Gupta #include <stdbool.h>
932669476SPankaj Gupta #include <stdint.h>
1032669476SPankaj Gupta #include <stdio.h>
1132669476SPankaj Gupta #include <stdlib.h>
1232669476SPankaj Gupta #include <string.h>
1332669476SPankaj Gupta 
1432669476SPankaj Gupta #include <getopt.h>
1532669476SPankaj Gupta #include <unistd.h>
1632669476SPankaj Gupta 
1732669476SPankaj Gupta #define NUM_MEM_BLOCK		1
1832669476SPankaj Gupta #define FOUR_BYTE_ALIGN		4
1932669476SPankaj Gupta #define EIGHT_BYTE_ALIGN	8
2032669476SPankaj Gupta #define SIZE_TWO_PBL_CMD	24
2132669476SPankaj Gupta 
2232669476SPankaj Gupta /* Define for add_boot_ptr_cmd() */
2332669476SPankaj Gupta #define BOOTPTR_ADDR 0x09570604
2432669476SPankaj Gupta #define CSF_ADDR_SB 0x09ee0200
2532669476SPankaj Gupta /* CCSR write command to address 0x1e00400 i.e BOOTLOCPTR */
2632669476SPankaj Gupta #define BOOTPTR_ADDR_CH3 0x31e00400
2732669476SPankaj Gupta /* Load CSF header command */
2832669476SPankaj Gupta #define CSF_ADDR_SB_CH3 0x80220000
2932669476SPankaj Gupta 
3032669476SPankaj Gupta #define	MAND_ARG_MASK				0xFFF3
3132669476SPankaj Gupta #define	ARG_INIT_MASK				0xFF00
3232669476SPankaj Gupta #define RCW_FILE_NAME_ARG_MASK			0x0080
3332669476SPankaj Gupta #define IN_FILE_NAME_ARG_MASK			0x0040
3432669476SPankaj Gupta #define CHASSIS_ARG_MASK			0x0020
3532669476SPankaj Gupta #define BOOT_SRC_ARG_MASK			0x0010
3632669476SPankaj Gupta #define ENTRY_POINT_ADDR_ARG_MASK		0x0008
3732669476SPankaj Gupta #define BL2_BIN_STRG_LOC_BOOT_SRC_ARG_MASK	0x0004
3832669476SPankaj Gupta #define BL2_BIN_CPY_DEST_ADDR_ARG_MASK		0x0002
3932669476SPankaj Gupta #define OP_FILE_NAME_ARG_MASK			0x0001
4032669476SPankaj Gupta 
4132669476SPankaj Gupta /* Define for add_cpy_cmd() */
4232669476SPankaj Gupta #define OFFSET_MASK		        0x00ffffff
4332669476SPankaj Gupta #define WRITE_CMD_BASE		    0x81000000
4432669476SPankaj Gupta #define MAX_PBI_DATA_LEN_BYTE	64
4532669476SPankaj Gupta 
4632669476SPankaj Gupta /* 140 Bytes = Preamble + LOAD RCW command + RCW (128 bytes) + Checksum */
4732669476SPankaj Gupta #define CHS3_CRC_PAYLOAD_START_OFFSET 140
4832669476SPankaj Gupta 
4932669476SPankaj Gupta #define PBI_CRC_POLYNOMIAL	0x04c11db7
5032669476SPankaj Gupta 
5132669476SPankaj Gupta typedef enum {
5232669476SPankaj Gupta 	CHASSIS_UNKNOWN,
5332669476SPankaj Gupta 	CHASSIS_2,
5432669476SPankaj Gupta 	CHASSIS_3,
5532669476SPankaj Gupta 	CHASSIS_3_2,
5632669476SPankaj Gupta 	CHASSIS_MAX    /* must be last item in list */
5732669476SPankaj Gupta } chassis_t;
5832669476SPankaj Gupta 
5932669476SPankaj Gupta typedef enum {
6032669476SPankaj Gupta 	UNKNOWN_BOOT = 0,
6132669476SPankaj Gupta 	IFC_NOR_BOOT,
6232669476SPankaj Gupta 	IFC_NAND_BOOT,
6332669476SPankaj Gupta 	QSPI_BOOT,
6432669476SPankaj Gupta 	SD_BOOT,
6532669476SPankaj Gupta 	EMMC_BOOT,
6632669476SPankaj Gupta 	FLXSPI_NOR_BOOT,
6732669476SPankaj Gupta 	FLXSPI_NAND_BOOT,
6832669476SPankaj Gupta 	FLXSPI_NAND4K_BOOT,
6932669476SPankaj Gupta 	MAX_BOOT    /* must be last item in list */
7032669476SPankaj Gupta } boot_src_t;
7132669476SPankaj Gupta 
7232669476SPankaj Gupta /* Base Addresses where PBL image is copied depending on the boot source.
7332669476SPankaj Gupta  * Boot address map varies as per Chassis architecture.
7432669476SPankaj Gupta  */
7532669476SPankaj Gupta #define BASE_ADDR_UNDEFINED  0xFFFFFFFF
7632669476SPankaj Gupta #define BASE_ADDR_QSPI       0x20000000
7732669476SPankaj Gupta #define BASE_ADDR_SD         0x00001000
7832669476SPankaj Gupta #define BASE_ADDR_IFC_NOR    0x30000000
7932669476SPankaj Gupta #define BASE_ADDR_EMMC       0x00001000
8032669476SPankaj Gupta #define BASE_ADDR_FLX_NOR    0x20000000
8132669476SPankaj Gupta #define BASE_ADDR_NAND       0x20000000
8232669476SPankaj Gupta 
8332669476SPankaj Gupta uint32_t base_addr_ch3[MAX_BOOT] = {
8432669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,
8532669476SPankaj Gupta 	BASE_ADDR_IFC_NOR,
8632669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,	/*IFC NAND */
8732669476SPankaj Gupta 	BASE_ADDR_QSPI,
8832669476SPankaj Gupta 	BASE_ADDR_SD,
8932669476SPankaj Gupta 	BASE_ADDR_EMMC,
9032669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,	/*FLXSPI NOR */
9132669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,	/*FLXSPI NAND 2K */
9232669476SPankaj Gupta 	BASE_ADDR_UNDEFINED	/*FLXSPI NAND 4K */
9332669476SPankaj Gupta };
9432669476SPankaj Gupta 
9532669476SPankaj Gupta uint32_t base_addr_ch32[MAX_BOOT] = {
9632669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,
9732669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,	/* IFC NOR */
9832669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,	/* IFC NAND */
9932669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,	/* QSPI */
10032669476SPankaj Gupta 	BASE_ADDR_SD,
10132669476SPankaj Gupta 	BASE_ADDR_EMMC,
10232669476SPankaj Gupta 	BASE_ADDR_FLX_NOR,
10332669476SPankaj Gupta 	BASE_ADDR_UNDEFINED,	/*FLXSPI NAND 2K */
10432669476SPankaj Gupta 	BASE_ADDR_UNDEFINED	/*FLXSPI NAND 4K */
10532669476SPankaj Gupta };
10632669476SPankaj Gupta 
10732669476SPankaj Gupta /* for Chassis 3 */
10832669476SPankaj Gupta uint32_t blk_cpy_hdr_map_ch3[] = {
10932669476SPankaj Gupta 
11032669476SPankaj Gupta 	0,		    /* Unknown Boot Source */
11132669476SPankaj Gupta 	0x80000020,	/* NOR_BOOT */
11232669476SPankaj Gupta 	0x0,		/* NAND_BOOT */
11332669476SPankaj Gupta 	0x80000062,	/* QSPI_BOOT */
11432669476SPankaj Gupta 	0x80000040,	/* SD_BOOT */
11532669476SPankaj Gupta 	0x80000041,	/* EMMC_BOOT */
11632669476SPankaj Gupta 	0x0,		/* FLEXSPI NOR_BOOT */
11732669476SPankaj Gupta 	0x0,	/* FLEX SPI NAND2K BOOT */
11832669476SPankaj Gupta 	0x0,	/* CHASIS3_2_NAND4K_BOOT */
11932669476SPankaj Gupta };
12032669476SPankaj Gupta 
12132669476SPankaj Gupta uint32_t blk_cpy_hdr_map_ch32[] = {
12232669476SPankaj Gupta 	0,		    /* Unknown Boot Source */
12332669476SPankaj Gupta 	0x0,		/* NOR_BOOT */
12432669476SPankaj Gupta 	0x0,		/* NAND_BOOT */
12532669476SPankaj Gupta 	0x0,		/* QSPI_BOOT */
12632669476SPankaj Gupta 	0x80000008,	/* SD_BOOT */
12732669476SPankaj Gupta 	0x80000009,	/* EMMC_BOOT */
12832669476SPankaj Gupta 	0x8000000F,	/* FLEXSPI NOR_BOOT */
12932669476SPankaj Gupta 	0x8000000C,	/* FLEX SPI NAND2K BOOT */
13032669476SPankaj Gupta 	0x8000000D,	/* CHASIS3_2_NAND4K_BOOT */
13132669476SPankaj Gupta };
13232669476SPankaj Gupta 
13332669476SPankaj Gupta char *boot_src_string[] = {
13432669476SPankaj Gupta 	"UNKNOWN_BOOT",
13532669476SPankaj Gupta 	"IFC_NOR_BOOT",
13632669476SPankaj Gupta 	"IFC_NAND_BOOT",
13732669476SPankaj Gupta 	"QSPI_BOOT",
13832669476SPankaj Gupta 	"SD_BOOT",
13932669476SPankaj Gupta 	"EMMC_BOOT",
14032669476SPankaj Gupta 	"FLXSPI_NOR_BOOT",
14132669476SPankaj Gupta 	"FLXSPI_NAND_BOOT",
14232669476SPankaj Gupta 	"FLXSPI_NAND4K_BOOT",
14332669476SPankaj Gupta };
14432669476SPankaj Gupta 
14532669476SPankaj Gupta enum stop_command {
14632669476SPankaj Gupta 	STOP_COMMAND = 0,
14732669476SPankaj Gupta 	CRC_STOP_COMMAND
14832669476SPankaj Gupta };
14932669476SPankaj Gupta 
15032669476SPankaj Gupta /* Structure will get populated in the main function
15132669476SPankaj Gupta  * as part of parsing the command line arguments.
15232669476SPankaj Gupta  * All member parameters are mandatory except:
15332669476SPankaj Gupta  *	-ep
15432669476SPankaj Gupta  *	-src_addr
15532669476SPankaj Gupta  */
15632669476SPankaj Gupta struct pbl_image {
15732669476SPankaj Gupta 	char *rcw_nm;		/* Input RCW File */
15832669476SPankaj Gupta 	char *sec_imgnm;	/* Input BL2 binary */
15932669476SPankaj Gupta 	char *imagefile;	/* Generated output file */
16032669476SPankaj Gupta 	boot_src_t boot_src;	/* Boot Source - QSPI, SD, NOR, NAND etc */
16132669476SPankaj Gupta 	uint32_t src_addr;	/* Source Address */
16232669476SPankaj Gupta 	uint32_t addr;		/* Load address */
16332669476SPankaj Gupta 	uint32_t ep;		/* Entry point <opt> default is load address */
16432669476SPankaj Gupta 	chassis_t chassis;	/* Chassis type */
16532669476SPankaj Gupta } pblimg;
16632669476SPankaj Gupta 
16732669476SPankaj Gupta #define SUCCESS			 0
16832669476SPankaj Gupta #define FAILURE			-1
16932669476SPankaj Gupta #define CRC_STOP_CMD_ARM	0x08610040
17032669476SPankaj Gupta #define CRC_STOP_CMD_ARM_CH3	0x808f0000
17132669476SPankaj Gupta #define STOP_CMD_ARM_CH3	0x80ff0000
17232669476SPankaj Gupta #define BYTE_SWAP_32(word)	((((word) & 0xff000000) >> 24)|	\
17332669476SPankaj Gupta 				(((word) & 0x00ff0000) >>  8) |	\
17432669476SPankaj Gupta 				(((word) & 0x0000ff00) <<  8) |	\
17532669476SPankaj Gupta 				(((word) & 0x000000ff) << 24))
17632669476SPankaj Gupta 
17732669476SPankaj Gupta #define PBI_LEN_MASK	0xFFF00000
17832669476SPankaj Gupta #define PBI_LEN_SHIFT	20
17932669476SPankaj Gupta #define NUM_RCW_WORD	35
18032669476SPankaj Gupta #define PBI_LEN_ADD		6
18132669476SPankaj Gupta 
18232669476SPankaj Gupta #define MAX_CRC_ENTRIES 256
18332669476SPankaj Gupta 
18432669476SPankaj Gupta /* SoC numeric identifier */
18532669476SPankaj Gupta #define SOC_LS1012 1012
18632669476SPankaj Gupta #define SOC_LS1023 1023
18732669476SPankaj Gupta #define SOC_LS1026 1026
18832669476SPankaj Gupta #define SOC_LS1028 1028
18932669476SPankaj Gupta #define SOC_LS1043 1043
19032669476SPankaj Gupta #define SOC_LS1046 1046
19132669476SPankaj Gupta #define SOC_LS1088 1088
19232669476SPankaj Gupta #define SOC_LS2080 2080
19332669476SPankaj Gupta #define SOC_LS2088 2088
19432669476SPankaj Gupta #define SOC_LX2160 2160
19532669476SPankaj Gupta 
19632669476SPankaj Gupta static uint32_t pbl_size;
19732669476SPankaj Gupta bool sb_flag;
19832669476SPankaj Gupta 
19932669476SPankaj Gupta /***************************************************************************
20032669476SPankaj Gupta  * Description	:	CRC32 Lookup Table
20132669476SPankaj Gupta  ***************************************************************************/
20232669476SPankaj Gupta static uint32_t crc32_lookup[] = {
20332669476SPankaj Gupta 	 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
20432669476SPankaj Gupta 	 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
20532669476SPankaj Gupta 	 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
20632669476SPankaj Gupta 	 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
20732669476SPankaj Gupta 	 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
20832669476SPankaj Gupta 	 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
20932669476SPankaj Gupta 	 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
21032669476SPankaj Gupta 	 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
21132669476SPankaj Gupta 	 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
21232669476SPankaj Gupta 	 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
21332669476SPankaj Gupta 	 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
21432669476SPankaj Gupta 	 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
21532669476SPankaj Gupta 	 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
21632669476SPankaj Gupta 	 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
21732669476SPankaj Gupta 	 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
21832669476SPankaj Gupta 	 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
21932669476SPankaj Gupta 	 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
22032669476SPankaj Gupta 	 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
22132669476SPankaj Gupta 	 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
22232669476SPankaj Gupta 	 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
22332669476SPankaj Gupta 	 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
22432669476SPankaj Gupta 	 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
22532669476SPankaj Gupta 	 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
22632669476SPankaj Gupta 	 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
22732669476SPankaj Gupta 	 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
22832669476SPankaj Gupta 	 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
22932669476SPankaj Gupta 	 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
23032669476SPankaj Gupta 	 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
23132669476SPankaj Gupta 	 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
23232669476SPankaj Gupta 	 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
23332669476SPankaj Gupta 	 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
23432669476SPankaj Gupta 	 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
23532669476SPankaj Gupta 	 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
23632669476SPankaj Gupta 	 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
23732669476SPankaj Gupta 	 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
23832669476SPankaj Gupta 	 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
23932669476SPankaj Gupta 	 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
24032669476SPankaj Gupta 	 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
24132669476SPankaj Gupta 	 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
24232669476SPankaj Gupta 	 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
24332669476SPankaj Gupta 	 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
24432669476SPankaj Gupta 	 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
24532669476SPankaj Gupta 	 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
24632669476SPankaj Gupta 	 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
24732669476SPankaj Gupta 	 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
24832669476SPankaj Gupta 	 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
24932669476SPankaj Gupta 	 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
25032669476SPankaj Gupta 	 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
25132669476SPankaj Gupta 	 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
25232669476SPankaj Gupta 	 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
25332669476SPankaj Gupta 	 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
25432669476SPankaj Gupta 	 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
25532669476SPankaj Gupta 	 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
25632669476SPankaj Gupta 	 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
25732669476SPankaj Gupta 	 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
25832669476SPankaj Gupta 	 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
25932669476SPankaj Gupta 	 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
26032669476SPankaj Gupta 	 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
26132669476SPankaj Gupta 	 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
26232669476SPankaj Gupta 	 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
26332669476SPankaj Gupta 	 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
26432669476SPankaj Gupta 	 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
26532669476SPankaj Gupta 	 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
26632669476SPankaj Gupta 	 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
26732669476SPankaj Gupta 	};
26832669476SPankaj Gupta 
26932669476SPankaj Gupta 
print_usage(void)27032669476SPankaj Gupta static void print_usage(void)
27132669476SPankaj Gupta {
27232669476SPankaj Gupta 	printf("\nCorrect Usage of Tool is:\n");
27332669476SPankaj Gupta 	printf("\n ./create_pbl [options] (mentioned below):\n\n");
27432669476SPankaj Gupta 	printf("\t-r  <RCW file-name>     - name of RCW binary file.\n");
27532669476SPankaj Gupta 	printf("\t-i  <BL2 Bin file-name> - file to be added to rcw file.\n");
27632669476SPankaj Gupta 	printf("\t-c  <Number>            - Chassis Architecture (=2 or =3\n");
27732669476SPankaj Gupta 	printf("\t                          or =4 for 3.2).\n");
27832669476SPankaj Gupta 	printf("\t-b  <qspi/nor/nand/sd>  - Boot source.\n");
27932669476SPankaj Gupta 	printf("\t-d  <Address>           - Destination address where BL2\n");
28032669476SPankaj Gupta 	printf("\t                          image is to be copied\n");
28132669476SPankaj Gupta 	printf("\t-o  <output filename>	  - Name of PBL image generated\n");
28232669476SPankaj Gupta 	printf("\t                          as an output of the tool.\n");
28332669476SPankaj Gupta 	printf("\t-f  <Address>           - BL2 image Src Offset\n");
28432669476SPankaj Gupta 	printf("\t                          on Boot Source for block copy.\n");
28532669476SPankaj Gupta 	printf("\t                          command for chassis >=3.)\n");
28632669476SPankaj Gupta 	printf("\t-e  <Address>           - [Optional] Entry Point Address\n");
28732669476SPankaj Gupta 	printf("\t                          of the BL2.bin\n");
28832669476SPankaj Gupta 	printf("\t-s  Secure Boot.\n");
28932669476SPankaj Gupta 	printf("\t-h  Help.\n");
29032669476SPankaj Gupta 	printf("\n\n");
29132669476SPankaj Gupta 	exit(0);
29232669476SPankaj Gupta 
29332669476SPankaj Gupta }
29432669476SPankaj Gupta 
29532669476SPankaj Gupta /***************************************************************************
29632669476SPankaj Gupta  * Function	:	crypto_calculate_checksum()
29732669476SPankaj Gupta  * Arguments	:	data - Pointer to FILE
29832669476SPankaj Gupta  *			num - Number of 32 bit words for checksum
29932669476SPankaj Gupta  * Return	:	Checksum Value
30032669476SPankaj Gupta  * Description	:	Calculate Checksum over the data
30132669476SPankaj Gupta  ***************************************************************************/
crypto_calculate_checksum(FILE * fp_rcw_pbi_op,uint32_t num)30232669476SPankaj Gupta uint32_t crypto_calculate_checksum(FILE *fp_rcw_pbi_op, uint32_t num)
30332669476SPankaj Gupta {
30432669476SPankaj Gupta 	uint32_t i;
30532669476SPankaj Gupta 	uint64_t sum = 0;
30632669476SPankaj Gupta 	uint32_t word;
30732669476SPankaj Gupta 
30832669476SPankaj Gupta 	fseek(fp_rcw_pbi_op, 0L, SEEK_SET);
30932669476SPankaj Gupta 	for (i = 0; i < num ; i++) {
31032669476SPankaj Gupta 		if ((fread(&word, sizeof(word), NUM_MEM_BLOCK, fp_rcw_pbi_op))
31132669476SPankaj Gupta 			< NUM_MEM_BLOCK) {
31232669476SPankaj Gupta 			printf("%s: Error reading word.\n", __func__);
31332669476SPankaj Gupta 			return FAILURE;
31432669476SPankaj Gupta 		}
31532669476SPankaj Gupta 		sum = sum + word;
31632669476SPankaj Gupta 		sum = sum & 0xFFFFFFFF;
31732669476SPankaj Gupta 	}
31832669476SPankaj Gupta 	return (uint32_t)sum;
31932669476SPankaj Gupta }
32032669476SPankaj Gupta 
32132669476SPankaj Gupta /***************************************************************************
32232669476SPankaj Gupta  * Function	:	add_pbi_stop_cmd
32332669476SPankaj Gupta  * Arguments	:	fp_rcw_pbi_op - output rcw_pbi file pointer
32432669476SPankaj Gupta  * Return	:	SUCCESS or FAILURE
32532669476SPankaj Gupta  * Description	:	This function insert pbi stop command.
32632669476SPankaj Gupta  ***************************************************************************/
add_pbi_stop_cmd(FILE * fp_rcw_pbi_op,enum stop_command flag)32732669476SPankaj Gupta int add_pbi_stop_cmd(FILE *fp_rcw_pbi_op, enum stop_command flag)
32832669476SPankaj Gupta {
32932669476SPankaj Gupta 	int ret = FAILURE;
33032669476SPankaj Gupta 	int32_t pbi_stop_cmd;
33132669476SPankaj Gupta 	uint32_t pbi_crc = 0xffffffff, i, j, c;
33232669476SPankaj Gupta 	uint32_t crc_table[MAX_CRC_ENTRIES];
33332669476SPankaj Gupta 	uint8_t data;
33432669476SPankaj Gupta 
33532669476SPankaj Gupta 	switch (pblimg.chassis) {
33632669476SPankaj Gupta 	case CHASSIS_2:
33732669476SPankaj Gupta 		pbi_stop_cmd = BYTE_SWAP_32(CRC_STOP_CMD_ARM);
33832669476SPankaj Gupta 		break;
33932669476SPankaj Gupta 	case CHASSIS_3:
34032669476SPankaj Gupta 	case CHASSIS_3_2:
34132669476SPankaj Gupta 		/* Based on flag add the corresponsding cmd
34232669476SPankaj Gupta 		 * -- stop cmd or stop with CRC cmd
34332669476SPankaj Gupta 		 */
34432669476SPankaj Gupta 		if (flag == CRC_STOP_COMMAND) {
34532669476SPankaj Gupta 			pbi_stop_cmd = CRC_STOP_CMD_ARM_CH3;
34632669476SPankaj Gupta 		} else {
34732669476SPankaj Gupta 			pbi_stop_cmd = STOP_CMD_ARM_CH3;
34832669476SPankaj Gupta 		}
34932669476SPankaj Gupta 		break;
35032669476SPankaj Gupta 	case CHASSIS_UNKNOWN:
35132669476SPankaj Gupta 	case CHASSIS_MAX:
35232669476SPankaj Gupta 	default:
35332669476SPankaj Gupta 		printf("Internal Error: Invalid Chassis val = %d.\n",
35432669476SPankaj Gupta 			pblimg.chassis);
35532669476SPankaj Gupta 		goto pbi_stop_err;
35632669476SPankaj Gupta 	}
35732669476SPankaj Gupta 
35832669476SPankaj Gupta 	if (fwrite(&pbi_stop_cmd, sizeof(pbi_stop_cmd), NUM_MEM_BLOCK,
35932669476SPankaj Gupta 			fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
36032669476SPankaj Gupta 		printf("%s: Error in Writing PBI STOP CMD\n", __func__);
36132669476SPankaj Gupta 		goto pbi_stop_err;
36232669476SPankaj Gupta 	}
36332669476SPankaj Gupta 
36432669476SPankaj Gupta 	if (flag == CRC_STOP_COMMAND) {
36532669476SPankaj Gupta 		for (i = 0; i < MAX_CRC_ENTRIES; i++) {
36632669476SPankaj Gupta 			c = i << 24;
36732669476SPankaj Gupta 			for (j = 0; j < 8; j++) {
36832669476SPankaj Gupta 				c = (c & 0x80000000) ?
36932669476SPankaj Gupta 					PBI_CRC_POLYNOMIAL ^ (c << 1) : c << 1;
37032669476SPankaj Gupta 			}
37132669476SPankaj Gupta 
37232669476SPankaj Gupta 			crc_table[i] = c;
37332669476SPankaj Gupta 		}
37432669476SPankaj Gupta 	}
37532669476SPankaj Gupta 
37632669476SPankaj Gupta 	switch (pblimg.chassis) {
37732669476SPankaj Gupta 	case CHASSIS_2:
37832669476SPankaj Gupta 		/* Chassis 2: CRC is calculated on  RCW + PBL cmd.*/
37932669476SPankaj Gupta 		fseek(fp_rcw_pbi_op, 0L, SEEK_SET);
38032669476SPankaj Gupta 		break;
38132669476SPankaj Gupta 	case CHASSIS_3:
38232669476SPankaj Gupta 	case CHASSIS_3_2:
38332669476SPankaj Gupta 		/* Chassis 3: CRC is calculated on  PBL cmd only. */
38432669476SPankaj Gupta 		fseek(fp_rcw_pbi_op, CHS3_CRC_PAYLOAD_START_OFFSET, SEEK_SET);
38532669476SPankaj Gupta 		break;
38632669476SPankaj Gupta 	case CHASSIS_UNKNOWN:
38732669476SPankaj Gupta 	case CHASSIS_MAX:
38832669476SPankaj Gupta 		printf("%s: Unknown Chassis.\n", __func__);
38932669476SPankaj Gupta 		goto pbi_stop_err;
39032669476SPankaj Gupta 	}
39132669476SPankaj Gupta 
39232669476SPankaj Gupta 	while ((fread(&data, sizeof(data), NUM_MEM_BLOCK, fp_rcw_pbi_op))
39332669476SPankaj Gupta 		== NUM_MEM_BLOCK) {
39432669476SPankaj Gupta 		if (flag == CRC_STOP_COMMAND) {
39532669476SPankaj Gupta 			if (pblimg.chassis == CHASSIS_2) {
39632669476SPankaj Gupta 				pbi_crc = crc_table
39732669476SPankaj Gupta 					  [((pbi_crc >> 24) ^ (data)) & 0xff] ^
39832669476SPankaj Gupta 					  (pbi_crc << 8);
39932669476SPankaj Gupta 			} else {
40032669476SPankaj Gupta 				pbi_crc =  (pbi_crc >> 8) ^
40132669476SPankaj Gupta 					   crc32_lookup[((pbi_crc) ^
40232669476SPankaj Gupta 							   (data)) & 0xff];
40332669476SPankaj Gupta 			}
40432669476SPankaj Gupta 		}
40532669476SPankaj Gupta 	}
40632669476SPankaj Gupta 
40732669476SPankaj Gupta 	switch (pblimg.chassis) {
40832669476SPankaj Gupta 	case CHASSIS_2:
40932669476SPankaj Gupta 		pbi_crc = BYTE_SWAP_32(pbi_crc);
41032669476SPankaj Gupta 		break;
41132669476SPankaj Gupta 	case CHASSIS_3:
41232669476SPankaj Gupta 	case CHASSIS_3_2:
41332669476SPankaj Gupta 		if (flag == CRC_STOP_COMMAND) {
41432669476SPankaj Gupta 			pbi_crc = pbi_crc ^ 0xFFFFFFFF;
41532669476SPankaj Gupta 		} else {
41632669476SPankaj Gupta 			pbi_crc = 0x00000000;
41732669476SPankaj Gupta 		}
41832669476SPankaj Gupta 		break;
41932669476SPankaj Gupta 	case CHASSIS_UNKNOWN:
42032669476SPankaj Gupta 	case CHASSIS_MAX:
42132669476SPankaj Gupta 		printf("%s: Unknown Chassis.\n", __func__);
42232669476SPankaj Gupta 		goto pbi_stop_err;
42332669476SPankaj Gupta 	}
42432669476SPankaj Gupta 
42532669476SPankaj Gupta 	if (fwrite(&pbi_crc, sizeof(pbi_crc), NUM_MEM_BLOCK, fp_rcw_pbi_op)
42632669476SPankaj Gupta 		!= NUM_MEM_BLOCK) {
42732669476SPankaj Gupta 		printf("%s: Error in Writing PBI PBI CRC\n", __func__);
42832669476SPankaj Gupta 		goto pbi_stop_err;
42932669476SPankaj Gupta 	}
43032669476SPankaj Gupta 	ret = SUCCESS;
43132669476SPankaj Gupta 
43232669476SPankaj Gupta pbi_stop_err:
43332669476SPankaj Gupta 	return ret;
43432669476SPankaj Gupta }
43532669476SPankaj Gupta 
43632669476SPankaj Gupta /*
43732669476SPankaj Gupta  * Returns:
43832669476SPankaj Gupta  *     File size in bytes, on Success.
43932669476SPankaj Gupta  *     FAILURE, on failure.
44032669476SPankaj Gupta  */
get_filesize(const char * c)44132669476SPankaj Gupta int get_filesize(const char *c)
44232669476SPankaj Gupta {
44332669476SPankaj Gupta 	FILE *fp;
44432669476SPankaj Gupta 	int ret = FAILURE;
44532669476SPankaj Gupta 
44632669476SPankaj Gupta 	fp = fopen(c, "rb");
44732669476SPankaj Gupta 	if (fp == NULL) {
44832669476SPankaj Gupta 		fprintf(stderr, "%s: Error in opening the file: %s\n",
44932669476SPankaj Gupta 			__func__, c);
45032669476SPankaj Gupta 		goto filesize_err;
45132669476SPankaj Gupta 	}
45232669476SPankaj Gupta 
45332669476SPankaj Gupta 	fseek(fp, 0L, SEEK_END);
45432669476SPankaj Gupta 	ret = ftell(fp);
45532669476SPankaj Gupta 	fclose(fp);
45632669476SPankaj Gupta 
45732669476SPankaj Gupta filesize_err:
45832669476SPankaj Gupta 	return ret;
45932669476SPankaj Gupta }
46032669476SPankaj Gupta 
46132669476SPankaj Gupta /***************************************************************************
46232669476SPankaj Gupta  * Function	:	get_bootptr
46332669476SPankaj Gupta  * Arguments	:	fp_rcw_pbi_op - Pointer to output file
46432669476SPankaj Gupta  * Return	:	SUCCESS or FAILURE
46532669476SPankaj Gupta  * Description	:	Add bootptr pbi command to output file
46632669476SPankaj Gupta  ***************************************************************************/
add_boot_ptr_cmd(FILE * fp_rcw_pbi_op)46732669476SPankaj Gupta int add_boot_ptr_cmd(FILE *fp_rcw_pbi_op)
46832669476SPankaj Gupta {
46932669476SPankaj Gupta 	uint32_t bootptr_addr;
47032669476SPankaj Gupta 	int ret = FAILURE;
47132669476SPankaj Gupta 
47232669476SPankaj Gupta 	switch (pblimg.chassis) {
47332669476SPankaj Gupta 	case CHASSIS_2:
47432669476SPankaj Gupta 		if (sb_flag == true)
47532669476SPankaj Gupta 			bootptr_addr = BYTE_SWAP_32(CSF_ADDR_SB);
47632669476SPankaj Gupta 		else
47732669476SPankaj Gupta 			bootptr_addr = BYTE_SWAP_32(BOOTPTR_ADDR);
47832669476SPankaj Gupta 		pblimg.ep    = BYTE_SWAP_32(pblimg.ep);
47932669476SPankaj Gupta 		break;
48032669476SPankaj Gupta 	case CHASSIS_3:
48132669476SPankaj Gupta 	case CHASSIS_3_2:
48232669476SPankaj Gupta 		if (sb_flag == true)
48332669476SPankaj Gupta 			bootptr_addr = CSF_ADDR_SB_CH3;
48432669476SPankaj Gupta 		else
48532669476SPankaj Gupta 			bootptr_addr = BOOTPTR_ADDR_CH3;
48632669476SPankaj Gupta 		break;
48732669476SPankaj Gupta 	case CHASSIS_UNKNOWN:
48832669476SPankaj Gupta 	case CHASSIS_MAX:
48932669476SPankaj Gupta 	default:
49032669476SPankaj Gupta 		printf("Internal Error: Invalid Chassis val = %d.\n",
49132669476SPankaj Gupta 			pblimg.chassis);
49232669476SPankaj Gupta 		goto bootptr_err;
49332669476SPankaj Gupta 	}
49432669476SPankaj Gupta 
49532669476SPankaj Gupta 	if (fwrite(&bootptr_addr, sizeof(bootptr_addr), NUM_MEM_BLOCK,
49632669476SPankaj Gupta 		fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
49732669476SPankaj Gupta 		printf("%s: Error in Writing PBI Words:[%d].\n",
49832669476SPankaj Gupta 			 __func__, ret);
49932669476SPankaj Gupta 		goto bootptr_err;
50032669476SPankaj Gupta 	}
50132669476SPankaj Gupta 
50232669476SPankaj Gupta 	if (pblimg.ep != 0) {
50332669476SPankaj Gupta 		if (fwrite(&pblimg.ep, sizeof(pblimg.ep), NUM_MEM_BLOCK,
50432669476SPankaj Gupta 			fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
50532669476SPankaj Gupta 			printf("%s: Error in Writing PBI Words\n", __func__);
50632669476SPankaj Gupta 			goto bootptr_err;
50732669476SPankaj Gupta 		}
50832669476SPankaj Gupta 	}
50932669476SPankaj Gupta 
51031af441aSBiwen Li 	printf("\nBoot Location Pointer= 0x%x\n",
51131af441aSBiwen Li 	       pblimg.chassis == CHASSIS_2 ? BYTE_SWAP_32(pblimg.ep) :
51231af441aSBiwen Li 	       pblimg.ep);
51332669476SPankaj Gupta 	ret = SUCCESS;
51432669476SPankaj Gupta 
51532669476SPankaj Gupta bootptr_err:
51632669476SPankaj Gupta 	return ret;
51732669476SPankaj Gupta }
51832669476SPankaj Gupta 
51932669476SPankaj Gupta /***************************************************************************
52032669476SPankaj Gupta  * Function	:	add_blk_cpy_cmd
52132669476SPankaj Gupta  * Arguments	:	pbi_word - pointer to pbi commands
52232669476SPankaj Gupta  *			args - Command  line args flag.
52332669476SPankaj Gupta  * Return	:	SUCCESS or FAILURE
52432669476SPankaj Gupta  * Description	:	Add pbi commands for block copy cmd in pbi_words
52532669476SPankaj Gupta  ***************************************************************************/
add_blk_cpy_cmd(FILE * fp_rcw_pbi_op,uint16_t args)52632669476SPankaj Gupta int add_blk_cpy_cmd(FILE *fp_rcw_pbi_op, uint16_t args)
52732669476SPankaj Gupta {
52832669476SPankaj Gupta 	uint32_t blk_cpy_hdr;
52932669476SPankaj Gupta 	uint32_t file_size, new_file_size;
53032669476SPankaj Gupta 	uint32_t align = 4;
53132669476SPankaj Gupta 	int ret = FAILURE;
53232669476SPankaj Gupta 	int num_pad_bytes = 0;
53332669476SPankaj Gupta 
53432669476SPankaj Gupta 	if ((args & BL2_BIN_STRG_LOC_BOOT_SRC_ARG_MASK) == 0) {
53532669476SPankaj Gupta 		printf("ERROR: Offset not specified for Block Copy Cmd.\n");
53632669476SPankaj Gupta 		printf("\tSee Usage and use -f option\n");
53732669476SPankaj Gupta 		goto blk_copy_err;
53832669476SPankaj Gupta 	}
53932669476SPankaj Gupta 
54032669476SPankaj Gupta 	switch (pblimg.chassis) {
54132669476SPankaj Gupta 	case CHASSIS_3:
54232669476SPankaj Gupta 		/* Block copy command */
54332669476SPankaj Gupta 		blk_cpy_hdr = blk_cpy_hdr_map_ch3[pblimg.boot_src];
54432669476SPankaj Gupta 		pblimg.src_addr += base_addr_ch3[pblimg.boot_src];
54532669476SPankaj Gupta 		break;
54632669476SPankaj Gupta 	case CHASSIS_3_2:
54732669476SPankaj Gupta 		/* Block copy command */
54832669476SPankaj Gupta 		blk_cpy_hdr = blk_cpy_hdr_map_ch32[pblimg.boot_src];
54932669476SPankaj Gupta 		pblimg.src_addr += base_addr_ch32[pblimg.boot_src];
55032669476SPankaj Gupta 		break;
55132669476SPankaj Gupta 	default:
55232669476SPankaj Gupta 		printf("%s: Error invalid chassis type for this command.\n",
55332669476SPankaj Gupta 				__func__);
55432669476SPankaj Gupta 		goto blk_copy_err;
55532669476SPankaj Gupta 	}
55632669476SPankaj Gupta 
55732669476SPankaj Gupta 	file_size = get_filesize(pblimg.sec_imgnm);
55832669476SPankaj Gupta 	if (file_size > 0) {
55932669476SPankaj Gupta 		new_file_size = (file_size + (file_size % align));
56032669476SPankaj Gupta 
56132669476SPankaj Gupta 		/* Add Block copy command */
56232669476SPankaj Gupta 		if (fwrite(&blk_cpy_hdr, sizeof(blk_cpy_hdr), NUM_MEM_BLOCK,
56332669476SPankaj Gupta 			fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
56432669476SPankaj Gupta 			printf("%s: Error writing blk_cpy_hdr to the file.\n",
56532669476SPankaj Gupta 				 __func__);
56632669476SPankaj Gupta 			goto blk_copy_err;
56732669476SPankaj Gupta 		}
56832669476SPankaj Gupta 
56932669476SPankaj Gupta 		if ((args & BL2_BIN_STRG_LOC_BOOT_SRC_ARG_MASK) == 0)
57032669476SPankaj Gupta 			num_pad_bytes = pblimg.src_addr % 4;
57132669476SPankaj Gupta 
57232669476SPankaj Gupta 		/* Add Src address word */
57332669476SPankaj Gupta 		if (fwrite(&pblimg.src_addr + num_pad_bytes,
57432669476SPankaj Gupta 			   sizeof(pblimg.src_addr), NUM_MEM_BLOCK,
57532669476SPankaj Gupta 			   fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
57632669476SPankaj Gupta 			printf("%s: Error writing BLK SRC Addr to the file.\n",
57732669476SPankaj Gupta 				 __func__);
57832669476SPankaj Gupta 			goto blk_copy_err;
57932669476SPankaj Gupta 		}
58032669476SPankaj Gupta 
58132669476SPankaj Gupta 		/* Add Dest address word */
58232669476SPankaj Gupta 		if (fwrite(&pblimg.addr, sizeof(pblimg.addr),
58332669476SPankaj Gupta 			NUM_MEM_BLOCK, fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
58432669476SPankaj Gupta 			printf("%s: Error writing DST Addr to the file.\n",
58532669476SPankaj Gupta 			__func__);
58632669476SPankaj Gupta 			goto blk_copy_err;
58732669476SPankaj Gupta 		}
58832669476SPankaj Gupta 
58932669476SPankaj Gupta 		/* Add size */
59032669476SPankaj Gupta 		if (fwrite(&new_file_size, sizeof(new_file_size),
59132669476SPankaj Gupta 			NUM_MEM_BLOCK, fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
59232669476SPankaj Gupta 			printf("%s: Error writing size to the file.\n",
59332669476SPankaj Gupta 				__func__);
59432669476SPankaj Gupta 			goto blk_copy_err;
59532669476SPankaj Gupta 		}
59632669476SPankaj Gupta 	}
59732669476SPankaj Gupta 
59832669476SPankaj Gupta 	ret = SUCCESS;
59932669476SPankaj Gupta 
60032669476SPankaj Gupta blk_copy_err:
60132669476SPankaj Gupta 	return ret;
60232669476SPankaj Gupta }
60332669476SPankaj Gupta 
60432669476SPankaj Gupta /***************************************************************************
60532669476SPankaj Gupta  * Function	:	add_cpy_cmd
60632669476SPankaj Gupta  * Arguments	:	pbi_word - pointer to pbi commands
60732669476SPankaj Gupta  * Return	:	SUCCESS or FAILURE
60832669476SPankaj Gupta  * Description	:	Append pbi commands for copying BL2 image to the
60932669476SPankaj Gupta  *			load address stored in pbl_image.addr
61032669476SPankaj Gupta  ***************************************************************************/
add_cpy_cmd(FILE * fp_rcw_pbi_op)61132669476SPankaj Gupta int add_cpy_cmd(FILE *fp_rcw_pbi_op)
61232669476SPankaj Gupta {
61332669476SPankaj Gupta 	uint32_t ALTCBAR_ADDRESS = BYTE_SWAP_32(0x09570158);
61432669476SPankaj Gupta 	uint32_t WAIT_CMD_WRITE_ADDRESS = BYTE_SWAP_32(0x096100c0);
61532669476SPankaj Gupta 	uint32_t WAIT_CMD = BYTE_SWAP_32(0x000FFFFF);
61632669476SPankaj Gupta 	int file_size;
61732669476SPankaj Gupta 	uint32_t pbi_cmd, altcbar;
61832669476SPankaj Gupta 	uint8_t pbi_data[MAX_PBI_DATA_LEN_BYTE];
61932669476SPankaj Gupta 	uint32_t dst_offset;
62032669476SPankaj Gupta 	FILE *fp_img = NULL;
62132669476SPankaj Gupta 	int ret = FAILURE;
62232669476SPankaj Gupta 
62332669476SPankaj Gupta 	altcbar = pblimg.addr;
62432669476SPankaj Gupta 	dst_offset = pblimg.addr;
62532669476SPankaj Gupta 	fp_img = fopen(pblimg.sec_imgnm, "rb");
62632669476SPankaj Gupta 	if (fp_img == NULL) {
62732669476SPankaj Gupta 		printf("%s: Error in opening the file: %s\n", __func__,
62832669476SPankaj Gupta 		      pblimg.sec_imgnm);
62932669476SPankaj Gupta 		goto add_cpy_err;
63032669476SPankaj Gupta 	}
63132669476SPankaj Gupta 	file_size = get_filesize(pblimg.sec_imgnm);
63232669476SPankaj Gupta 	altcbar = 0xfff00000 & altcbar;
63332669476SPankaj Gupta 	altcbar = BYTE_SWAP_32(altcbar >> 16);
63432669476SPankaj Gupta 	if (fwrite(&ALTCBAR_ADDRESS, sizeof(ALTCBAR_ADDRESS), NUM_MEM_BLOCK,
63532669476SPankaj Gupta 		fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
63632669476SPankaj Gupta 		printf("%s: Error in writing address of ALTCFG CMD.\n",
63732669476SPankaj Gupta 			 __func__);
63832669476SPankaj Gupta 		goto add_cpy_err;
63932669476SPankaj Gupta 	}
64032669476SPankaj Gupta 	if (fwrite(&altcbar, sizeof(altcbar), NUM_MEM_BLOCK, fp_rcw_pbi_op)
64132669476SPankaj Gupta 		!= NUM_MEM_BLOCK) {
64232669476SPankaj Gupta 		printf("%s: Error in writing ALTCFG CMD.\n", __func__);
64332669476SPankaj Gupta 		goto add_cpy_err;
64432669476SPankaj Gupta 	}
64532669476SPankaj Gupta 	if (fwrite(&WAIT_CMD_WRITE_ADDRESS, sizeof(WAIT_CMD_WRITE_ADDRESS),
64632669476SPankaj Gupta 		NUM_MEM_BLOCK, fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
64732669476SPankaj Gupta 		printf("%s: Error in writing address of WAIT_CMD.\n",
64832669476SPankaj Gupta 			__func__);
64932669476SPankaj Gupta 		goto add_cpy_err;
65032669476SPankaj Gupta 	}
65132669476SPankaj Gupta 	if (fwrite(&WAIT_CMD, sizeof(WAIT_CMD), NUM_MEM_BLOCK, fp_rcw_pbi_op)
65232669476SPankaj Gupta 		!= NUM_MEM_BLOCK) {
65332669476SPankaj Gupta 		printf("%s: Error in writing WAIT_CMD.\n", __func__);
65432669476SPankaj Gupta 		goto add_cpy_err;
65532669476SPankaj Gupta 	}
65632669476SPankaj Gupta 	do {
65732669476SPankaj Gupta 		memset(pbi_data, 0, MAX_PBI_DATA_LEN_BYTE);
65832669476SPankaj Gupta 
65932669476SPankaj Gupta 		ret = fread(&pbi_data, MAX_PBI_DATA_LEN_BYTE,
66032669476SPankaj Gupta 				NUM_MEM_BLOCK, fp_img);
66132669476SPankaj Gupta 		if ((ret != NUM_MEM_BLOCK) && (!feof(fp_img))) {
66232669476SPankaj Gupta 			printf("%s: Error writing ALTCFG Word: [%d].\n",
66332669476SPankaj Gupta 				__func__, ret);
66432669476SPankaj Gupta 			goto add_cpy_err;
66532669476SPankaj Gupta 		}
66632669476SPankaj Gupta 
66732669476SPankaj Gupta 		dst_offset &= OFFSET_MASK;
66832669476SPankaj Gupta 		pbi_cmd = WRITE_CMD_BASE | dst_offset;
66932669476SPankaj Gupta 		pbi_cmd = BYTE_SWAP_32(pbi_cmd);
67032669476SPankaj Gupta 		if (fwrite(&pbi_cmd, sizeof(pbi_cmd), NUM_MEM_BLOCK,
67132669476SPankaj Gupta 			fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
67232669476SPankaj Gupta 			printf("%s: Error writing ALTCFG Word write cmd.\n",
67332669476SPankaj Gupta 				 __func__);
67432669476SPankaj Gupta 			goto add_cpy_err;
67532669476SPankaj Gupta 		}
67632669476SPankaj Gupta 		if (fwrite(&pbi_data,  MAX_PBI_DATA_LEN_BYTE, NUM_MEM_BLOCK,
67732669476SPankaj Gupta 			fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
67832669476SPankaj Gupta 			printf("%s: Error writing ALTCFG_Word.\n", __func__);
67932669476SPankaj Gupta 			goto add_cpy_err;
68032669476SPankaj Gupta 		}
68132669476SPankaj Gupta 		dst_offset += MAX_PBI_DATA_LEN_BYTE;
68232669476SPankaj Gupta 		file_size -= MAX_PBI_DATA_LEN_BYTE;
68332669476SPankaj Gupta 	} while (!feof(fp_img));
68432669476SPankaj Gupta 
68532669476SPankaj Gupta 	ret = SUCCESS;
68632669476SPankaj Gupta 
68732669476SPankaj Gupta add_cpy_err:
68832669476SPankaj Gupta 	if (fp_img != NULL) {
68932669476SPankaj Gupta 		fclose(fp_img);
69032669476SPankaj Gupta 	}
69132669476SPankaj Gupta 	return ret;
69232669476SPankaj Gupta }
69332669476SPankaj Gupta 
main(int argc,char ** argv)69432669476SPankaj Gupta int main(int argc, char **argv)
69532669476SPankaj Gupta {
69632669476SPankaj Gupta 	FILE *file = NULL;
69732669476SPankaj Gupta 	char *ptr;
69832669476SPankaj Gupta 	int opt;
69932669476SPankaj Gupta 	int tmp;
70032669476SPankaj Gupta 	uint16_t args = ARG_INIT_MASK;
70132669476SPankaj Gupta 	FILE *fp_rcw_pbi_ip = NULL, *fp_rcw_pbi_op = NULL;
70232669476SPankaj Gupta 	uint32_t word, word_1;
70332669476SPankaj Gupta 	int ret = FAILURE;
70432669476SPankaj Gupta 	bool bootptr_flag = false;
70532669476SPankaj Gupta 	enum stop_command flag_stop_cmd = CRC_STOP_COMMAND;
70632669476SPankaj Gupta 
70732669476SPankaj Gupta 	/* Initializing the global structure to zero. */
70832669476SPankaj Gupta 	memset(&pblimg, 0x0, sizeof(struct pbl_image));
70932669476SPankaj Gupta 
71032669476SPankaj Gupta 	while ((opt = getopt(argc, argv,
71132669476SPankaj Gupta 			     ":b:f:r:i:e:d:c:o:h:s")) != -1) {
71232669476SPankaj Gupta 		switch (opt) {
71332669476SPankaj Gupta 		case 'd':
71432669476SPankaj Gupta 			pblimg.addr = strtoull(optarg, &ptr, 16);
71532669476SPankaj Gupta 			if (*ptr != 0) {
71632669476SPankaj Gupta 				fprintf(stderr, "CMD Error: invalid load or destination address %s\n", optarg);
71732669476SPankaj Gupta 				goto exit_main;
71832669476SPankaj Gupta 			}
71932669476SPankaj Gupta 			args |= BL2_BIN_CPY_DEST_ADDR_ARG_MASK;
72032669476SPankaj Gupta 			break;
72132669476SPankaj Gupta 		case 'r':
72232669476SPankaj Gupta 			pblimg.rcw_nm = optarg;
72332669476SPankaj Gupta 			file = fopen(pblimg.rcw_nm, "r");
72432669476SPankaj Gupta 			if (file == NULL) {
72532669476SPankaj Gupta 				printf("CMD Error: Opening the RCW File.\n");
72632669476SPankaj Gupta 				goto exit_main;
72732669476SPankaj Gupta 			} else {
72832669476SPankaj Gupta 				args |= RCW_FILE_NAME_ARG_MASK;
72932669476SPankaj Gupta 				fclose(file);
73032669476SPankaj Gupta 			}
73132669476SPankaj Gupta 			break;
73232669476SPankaj Gupta 		case 'e':
73332669476SPankaj Gupta 			bootptr_flag = true;
73432669476SPankaj Gupta 			pblimg.ep = strtoull(optarg, &ptr, 16);
73532669476SPankaj Gupta 			if (*ptr != 0) {
73632669476SPankaj Gupta 				fprintf(stderr,
73732669476SPankaj Gupta 				"CMD Error: Invalid entry point %s\n", optarg);
73832669476SPankaj Gupta 				goto exit_main;
73932669476SPankaj Gupta 			}
74032669476SPankaj Gupta 			break;
74132669476SPankaj Gupta 		case 'h':
74232669476SPankaj Gupta 			print_usage();
74332669476SPankaj Gupta 			break;
74432669476SPankaj Gupta 		case 'i':
74532669476SPankaj Gupta 			pblimg.sec_imgnm = optarg;
74632669476SPankaj Gupta 			file = fopen(pblimg.sec_imgnm, "r");
74732669476SPankaj Gupta 			if (file == NULL) {
74832669476SPankaj Gupta 				printf("CMD Error: Opening Input file.\n");
74932669476SPankaj Gupta 				goto exit_main;
75032669476SPankaj Gupta 			} else {
75132669476SPankaj Gupta 				args |= IN_FILE_NAME_ARG_MASK;
75232669476SPankaj Gupta 				fclose(file);
75332669476SPankaj Gupta 			}
75432669476SPankaj Gupta 			break;
75532669476SPankaj Gupta 		case 'c':
75632669476SPankaj Gupta 			tmp = atoi(optarg);
75732669476SPankaj Gupta 			switch (tmp) {
75832669476SPankaj Gupta 			case SOC_LS1012:
75932669476SPankaj Gupta 			case SOC_LS1023:
76032669476SPankaj Gupta 			case SOC_LS1026:
76132669476SPankaj Gupta 			case SOC_LS1043:
76232669476SPankaj Gupta 			case SOC_LS1046:
76332669476SPankaj Gupta 				pblimg.chassis = CHASSIS_2;
76432669476SPankaj Gupta 				break;
76532669476SPankaj Gupta 			case SOC_LS1088:
76632669476SPankaj Gupta 			case SOC_LS2080:
76732669476SPankaj Gupta 			case SOC_LS2088:
76832669476SPankaj Gupta 				pblimg.chassis = CHASSIS_3;
76932669476SPankaj Gupta 				break;
77032669476SPankaj Gupta 			case SOC_LS1028:
77132669476SPankaj Gupta 			case SOC_LX2160:
77232669476SPankaj Gupta 				pblimg.chassis = CHASSIS_3_2;
77332669476SPankaj Gupta 				break;
77432669476SPankaj Gupta 			default:
77532669476SPankaj Gupta 			printf("CMD Error: Invalid SoC Val = %d.\n", tmp);
77632669476SPankaj Gupta 				goto exit_main;
77732669476SPankaj Gupta 			}
77832669476SPankaj Gupta 
77932669476SPankaj Gupta 			args |= CHASSIS_ARG_MASK;
78032669476SPankaj Gupta 			break;
78132669476SPankaj Gupta 		case 'o':
78232669476SPankaj Gupta 			pblimg.imagefile = optarg;
78332669476SPankaj Gupta 			args |= OP_FILE_NAME_ARG_MASK;
78432669476SPankaj Gupta 			break;
78532669476SPankaj Gupta 		case 's':
78632669476SPankaj Gupta 			sb_flag = true;
78732669476SPankaj Gupta 			break;
78832669476SPankaj Gupta 		case 'b':
78932669476SPankaj Gupta 			if (strcmp(optarg, "qspi") == 0) {
79032669476SPankaj Gupta 				pblimg.boot_src = QSPI_BOOT;
79132669476SPankaj Gupta 			} else if (strcmp(optarg, "nor") == 0) {
79232669476SPankaj Gupta 				pblimg.boot_src = IFC_NOR_BOOT;
79332669476SPankaj Gupta 			} else if (strcmp(optarg, "nand") == 0) {
79432669476SPankaj Gupta 				pblimg.boot_src = IFC_NAND_BOOT;
79532669476SPankaj Gupta 			} else if (strcmp(optarg, "sd") == 0) {
79632669476SPankaj Gupta 				pblimg.boot_src = SD_BOOT;
79732669476SPankaj Gupta 			} else if (strcmp(optarg, "emmc") == 0) {
79832669476SPankaj Gupta 				pblimg.boot_src = EMMC_BOOT;
79932669476SPankaj Gupta 			} else if (strcmp(optarg, "flexspi_nor") == 0) {
80032669476SPankaj Gupta 				pblimg.boot_src = FLXSPI_NOR_BOOT;
80132669476SPankaj Gupta 			} else if (strcmp(optarg, "flexspi_nand") == 0) {
80232669476SPankaj Gupta 				pblimg.boot_src = FLXSPI_NAND_BOOT;
80332669476SPankaj Gupta 			} else if (strcmp(optarg, "flexspi_nand2k") == 0) {
80432669476SPankaj Gupta 				pblimg.boot_src = FLXSPI_NAND4K_BOOT;
80532669476SPankaj Gupta 			} else {
80632669476SPankaj Gupta 				printf("CMD Error: Invalid boot source.\n");
80732669476SPankaj Gupta 				goto exit_main;
80832669476SPankaj Gupta 			}
80932669476SPankaj Gupta 			args |= BOOT_SRC_ARG_MASK;
81032669476SPankaj Gupta 			break;
81132669476SPankaj Gupta 		case 'f':
81232669476SPankaj Gupta 			pblimg.src_addr = strtoull(optarg, &ptr, 16);
81332669476SPankaj Gupta 			if (*ptr != 0) {
81432669476SPankaj Gupta 				fprintf(stderr,
81532669476SPankaj Gupta 				"CMD Error: Invalid src offset %s\n", optarg);
81632669476SPankaj Gupta 				goto exit_main;
81732669476SPankaj Gupta 			}
81832669476SPankaj Gupta 			args |= BL2_BIN_STRG_LOC_BOOT_SRC_ARG_MASK;
81932669476SPankaj Gupta 			break;
82032669476SPankaj Gupta 		default:
82132669476SPankaj Gupta 			/* issue a warning and skip the unknown arg */
82232669476SPankaj Gupta 			printf("Cmd Warning: Invalid Arg = %c.\n", opt);
82332669476SPankaj Gupta 		}
82432669476SPankaj Gupta 	}
82532669476SPankaj Gupta 
8264fa0f097SJiafei Pan 	if ((args & MAND_ARG_MASK) != MAND_ARG_MASK
8274fa0f097SJiafei Pan 			|| pblimg.rcw_nm == NULL
8284fa0f097SJiafei Pan 			|| pblimg.imagefile == NULL) {
82932669476SPankaj Gupta 		print_usage();
83032669476SPankaj Gupta 	}
83132669476SPankaj Gupta 
83232669476SPankaj Gupta 	fp_rcw_pbi_ip = fopen(pblimg.rcw_nm, "rb");
83332669476SPankaj Gupta 	if (fp_rcw_pbi_ip == NULL) {
83432669476SPankaj Gupta 		printf("%s: Error in opening the rcw file: %s\n",
83532669476SPankaj Gupta 			__func__, pblimg.rcw_nm);
83632669476SPankaj Gupta 		goto exit_main;
83732669476SPankaj Gupta 	}
83832669476SPankaj Gupta 
83932669476SPankaj Gupta 	fp_rcw_pbi_op = fopen(pblimg.imagefile, "wb+");
84032669476SPankaj Gupta 	if (fp_rcw_pbi_op == NULL) {
84132669476SPankaj Gupta 		printf("%s: Error opening the input file: %s\n",
84232669476SPankaj Gupta 			__func__, pblimg.imagefile);
84332669476SPankaj Gupta 		goto exit_main;
84432669476SPankaj Gupta 	}
84532669476SPankaj Gupta 
84632669476SPankaj Gupta 	printf("\nInput Boot Source: %s\n", boot_src_string[pblimg.boot_src]);
84732669476SPankaj Gupta 	printf("Input RCW File: %s\n", pblimg.rcw_nm);
84832669476SPankaj Gupta 	printf("Input BL2 Binary File: %s\n", pblimg.sec_imgnm);
84932669476SPankaj Gupta 	printf("Input load address for BL2 Binary File: 0x%x\n", pblimg.addr);
85032669476SPankaj Gupta 
85132669476SPankaj Gupta 	printf("Chassis Type: %d\n", pblimg.chassis);
85232669476SPankaj Gupta 	switch (pblimg.chassis) {
85332669476SPankaj Gupta 	case CHASSIS_2:
85432669476SPankaj Gupta 		if (fread(&word, sizeof(word), NUM_MEM_BLOCK, fp_rcw_pbi_ip)
85532669476SPankaj Gupta 			!= NUM_MEM_BLOCK) {
85632669476SPankaj Gupta 			printf("%s: Error in reading word from the rcw file.\n",
85732669476SPankaj Gupta 				__func__);
85832669476SPankaj Gupta 			goto exit_main;
85932669476SPankaj Gupta 		}
86032669476SPankaj Gupta 		while (BYTE_SWAP_32(word) != 0x08610040) {
86132669476SPankaj Gupta 			if (BYTE_SWAP_32(word) == 0x09550000
86232669476SPankaj Gupta 				|| BYTE_SWAP_32(word) == 0x000f400c) {
86332669476SPankaj Gupta 				break;
86432669476SPankaj Gupta 			}
86532669476SPankaj Gupta 			if (fwrite(&word, sizeof(word), NUM_MEM_BLOCK,
86632669476SPankaj Gupta 				fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
86732669476SPankaj Gupta 				printf("%s: [CH2] Error in Writing PBI Words\n",
86832669476SPankaj Gupta 				__func__);
86932669476SPankaj Gupta 				goto exit_main;
87032669476SPankaj Gupta 			}
87132669476SPankaj Gupta 			if (fread(&word, sizeof(word), NUM_MEM_BLOCK,
87232669476SPankaj Gupta 				fp_rcw_pbi_ip) != NUM_MEM_BLOCK) {
87332669476SPankaj Gupta 				printf("%s: [CH2] Error in Reading PBI Words\n",
87432669476SPankaj Gupta 					__func__);
87532669476SPankaj Gupta 				goto exit_main;
87632669476SPankaj Gupta 			}
87732669476SPankaj Gupta 		}
87832669476SPankaj Gupta 
87932669476SPankaj Gupta 		if (bootptr_flag == true) {
88032669476SPankaj Gupta 			/* Add command to set boot_loc ptr */
88132669476SPankaj Gupta 			ret = add_boot_ptr_cmd(fp_rcw_pbi_op);
88232669476SPankaj Gupta 			if (ret != SUCCESS) {
88332669476SPankaj Gupta 				goto exit_main;
88432669476SPankaj Gupta 			}
88532669476SPankaj Gupta 		}
88632669476SPankaj Gupta 
88732669476SPankaj Gupta 		/* Write acs write commands to output file */
88832669476SPankaj Gupta 		ret = add_cpy_cmd(fp_rcw_pbi_op);
88932669476SPankaj Gupta 		if (ret != SUCCESS) {
89032669476SPankaj Gupta 			goto exit_main;
89132669476SPankaj Gupta 		}
89232669476SPankaj Gupta 
89332669476SPankaj Gupta 		/* Add stop command after adding pbi commands
89432669476SPankaj Gupta 		 * For Chasis 2.0 platforms it is always CRC &
89532669476SPankaj Gupta 		 * Stop command
89632669476SPankaj Gupta 		 */
89732669476SPankaj Gupta 		flag_stop_cmd = CRC_STOP_COMMAND;
89832669476SPankaj Gupta 		ret = add_pbi_stop_cmd(fp_rcw_pbi_op, flag_stop_cmd);
89932669476SPankaj Gupta 		if (ret != SUCCESS) {
90032669476SPankaj Gupta 			goto exit_main;
90132669476SPankaj Gupta 		}
90232669476SPankaj Gupta 
90332669476SPankaj Gupta 	break;
90432669476SPankaj Gupta 
90532669476SPankaj Gupta 	case CHASSIS_3:
90632669476SPankaj Gupta 	case CHASSIS_3_2:
90732669476SPankaj Gupta 		if (fread(&word, sizeof(word), NUM_MEM_BLOCK, fp_rcw_pbi_ip)
90832669476SPankaj Gupta 			!= NUM_MEM_BLOCK) {
90932669476SPankaj Gupta 			printf("%s: Error reading PBI Cmd.\n", __func__);
91032669476SPankaj Gupta 			goto exit_main;
91132669476SPankaj Gupta 		}
91232669476SPankaj Gupta 		while (word != 0x808f0000 && word != 0x80ff0000) {
91332669476SPankaj Gupta 			pbl_size++;
91432669476SPankaj Gupta 			/* 11th words in RCW has PBL length. Update it
915*1b491eeaSElyes Haouas 			 * with new length. 2 commands get added
91632669476SPankaj Gupta 			 * Block copy + CCSR Write/CSF header write
91732669476SPankaj Gupta 			 */
91832669476SPankaj Gupta 			if (pbl_size == 11) {
91932669476SPankaj Gupta 				word_1 = (word & PBI_LEN_MASK)
92032669476SPankaj Gupta 					+ (PBI_LEN_ADD << 20);
92132669476SPankaj Gupta 				word = word & ~PBI_LEN_MASK;
92232669476SPankaj Gupta 				word = word | word_1;
92332669476SPankaj Gupta 			}
92432669476SPankaj Gupta 			/* Update the CRC command */
92532669476SPankaj Gupta 			/* Check load command..
92632669476SPankaj Gupta 			 * add a check if command is Stop with CRC
92732669476SPankaj Gupta 			 * or stop without checksum
92832669476SPankaj Gupta 			 */
92932669476SPankaj Gupta 			if (pbl_size == 35) {
93032669476SPankaj Gupta 				word = crypto_calculate_checksum(fp_rcw_pbi_op,
93132669476SPankaj Gupta 						NUM_RCW_WORD - 1);
93232669476SPankaj Gupta 				if (word == FAILURE) {
93332669476SPankaj Gupta 					goto exit_main;
93432669476SPankaj Gupta 				}
93532669476SPankaj Gupta 			}
93632669476SPankaj Gupta 			if (fwrite(&word, sizeof(word),	NUM_MEM_BLOCK,
93732669476SPankaj Gupta 				fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
93832669476SPankaj Gupta 				printf("%s: [CH3] Error in Writing PBI Words\n",
93932669476SPankaj Gupta 					__func__);
94032669476SPankaj Gupta 				goto exit_main;
94132669476SPankaj Gupta 			}
94232669476SPankaj Gupta 			if (fread(&word, sizeof(word), NUM_MEM_BLOCK,
94332669476SPankaj Gupta 				fp_rcw_pbi_ip) != NUM_MEM_BLOCK) {
94432669476SPankaj Gupta 				printf("%s: [CH3] Error in Reading PBI Words\n",
94532669476SPankaj Gupta 					 __func__);
94632669476SPankaj Gupta 				goto exit_main;
94732669476SPankaj Gupta 			}
94832669476SPankaj Gupta 
94932669476SPankaj Gupta 			if (word == CRC_STOP_CMD_ARM_CH3) {
95032669476SPankaj Gupta 				flag_stop_cmd = CRC_STOP_COMMAND;
95132669476SPankaj Gupta 			} else if (word == STOP_CMD_ARM_CH3) {
95232669476SPankaj Gupta 				flag_stop_cmd = STOP_COMMAND;
95332669476SPankaj Gupta 			}
95432669476SPankaj Gupta 		}
95532669476SPankaj Gupta 		if (bootptr_flag == true) {
95632669476SPankaj Gupta 			/* Add command to set boot_loc ptr */
95732669476SPankaj Gupta 			ret = add_boot_ptr_cmd(fp_rcw_pbi_op);
95832669476SPankaj Gupta 			if (ret != SUCCESS) {
95932669476SPankaj Gupta 				printf("%s: add_boot_ptr_cmd return failure.\n",
96032669476SPankaj Gupta 					__func__);
96132669476SPankaj Gupta 				goto exit_main;
96232669476SPankaj Gupta 			}
96332669476SPankaj Gupta 		}
96432669476SPankaj Gupta 
96532669476SPankaj Gupta 		/* Write acs write commands to output file */
96632669476SPankaj Gupta 		ret = add_blk_cpy_cmd(fp_rcw_pbi_op, args);
96732669476SPankaj Gupta 		if (ret != SUCCESS) {
96832669476SPankaj Gupta 			printf("%s: Function add_blk_cpy_cmd return failure.\n",
96932669476SPankaj Gupta 				 __func__);
97032669476SPankaj Gupta 			goto exit_main;
97132669476SPankaj Gupta 		}
97232669476SPankaj Gupta 
97332669476SPankaj Gupta 		/* Add stop command after adding pbi commands */
97432669476SPankaj Gupta 		ret = add_pbi_stop_cmd(fp_rcw_pbi_op, flag_stop_cmd);
97532669476SPankaj Gupta 		if (ret != SUCCESS) {
97632669476SPankaj Gupta 			goto exit_main;
97732669476SPankaj Gupta 		}
97832669476SPankaj Gupta 
97932669476SPankaj Gupta 	break;
98032669476SPankaj Gupta 
98132669476SPankaj Gupta 	default:
98232669476SPankaj Gupta 		printf("%s: Unknown chassis type.\n",
98332669476SPankaj Gupta 				__func__);
98432669476SPankaj Gupta 	}
98532669476SPankaj Gupta 
98632669476SPankaj Gupta 	if (ret == SUCCESS) {
98732669476SPankaj Gupta 		printf("Output file successfully created with name: %s\n\n",
98832669476SPankaj Gupta 			   pblimg.imagefile);
98932669476SPankaj Gupta 	}
99032669476SPankaj Gupta 
99132669476SPankaj Gupta exit_main:
99232669476SPankaj Gupta 	if (fp_rcw_pbi_op != NULL) {
99332669476SPankaj Gupta 		fclose(fp_rcw_pbi_op);
99432669476SPankaj Gupta 	}
99532669476SPankaj Gupta 	if (fp_rcw_pbi_ip != NULL) {
99632669476SPankaj Gupta 		fclose(fp_rcw_pbi_ip);
99732669476SPankaj Gupta 	}
99832669476SPankaj Gupta 
99932669476SPankaj Gupta 	return ret;
100032669476SPankaj Gupta }
1001