// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2018 NXP
 *
 * Peng Fan <peng.fan@nxp.com>
 */


#include "imagetool.h"
#include <image.h>
#include "imximage.h"
#include "compiler.h"

static uint32_t ap_start_addr, sld_start_addr, sld_src_off;
static char *ap_img, *sld_img, *signed_hdmi;
static imx_header_v3_t imx_header[2]; /* At most there are 3 IVT headers */
static uint32_t rom_image_offset;
static uint32_t sector_size = 0x200;
static uint32_t image_off;
static uint32_t sld_header_off;
static uint32_t ivt_offset;
static uint32_t using_fit;

#define ROM_V1 1
#define ROM_V2 2

static uint32_t rom_version = ROM_V1;

#define CSF_SIZE 0x2000
#define HDMI_IVT_ID 0
#define IMAGE_IVT_ID 1

#define HDMI_FW_SIZE		0x17000 /* Use Last 0x1000 for IVT and CSF */
#define ALIGN_SIZE		0x1000
#define ALIGN_IMX(x, a)			__ALIGN_MASK_IMX((x), (__typeof__(x))(a) - 1, a)
#define __ALIGN_MASK_IMX(x, mask, mask2)	(((x) + (mask)) / (mask2) * (mask2))

static uint32_t get_cfg_value(char *token, char *name,  int linenr)
{
	char *endptr;
	uint32_t value;

	errno = 0;
	value = strtoul(token, &endptr, 16);
	if (errno || token == endptr) {
		fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
			name,  linenr, token);
		exit(EXIT_FAILURE);
	}
	return value;
}

int imx8mimage_check_params(struct image_tool_params *params)
{
	return 0;
}

static void imx8mimage_set_header(void *ptr, struct stat *sbuf, int ifd,
				  struct image_tool_params *params)
{
}

static void imx8mimage_print_header(const void *ptr)
{
}

static int imx8mimage_check_image_types(uint8_t type)
{
	return (type == IH_TYPE_IMX8MIMAGE) ? EXIT_SUCCESS : EXIT_FAILURE;
}

static table_entry_t imx8mimage_cmds[] = {
	{CMD_BOOT_FROM,         "BOOT_FROM",            "boot command",	      },
	{CMD_FIT,               "FIT",                  "fit image",	      },
	{CMD_SIGNED_HDMI,       "SIGNED_HDMI",          "signed hdmi image",  },
	{CMD_LOADER,            "LOADER",               "loader image",       },
	{CMD_SECOND_LOADER,     "SECOND_LOADER",        "2nd loader image",   },
	{CMD_DDR_FW,            "DDR_FW",               "ddr firmware",       },
	{CMD_ROM_VERSION,       "ROM_VERSION",          "rom version",        },
	{-1,                    "",                     "",	              },
};

static table_entry_t imx8mimage_ivt_offset[] = {
	{0x400,		"sd",			"sd/emmc",},
	{0x400,		"emmc_fastboot",	"emmc fastboot",},
	{0x1000,	"fspi",			"flexspi",	},
	{-1,		"",			"Invalid",	},
};

static void parse_cfg_cmd(int32_t cmd, char *token, char *name, int lineno)
{
	switch (cmd) {
	case CMD_BOOT_FROM:
		ivt_offset = get_table_entry_id(imx8mimage_ivt_offset,
						"imx8mimage ivt offset",
						token);
		if (!strncmp(token, "sd", 2))
			rom_image_offset = 0x8000;

		if (rom_version == ROM_V2)
			ivt_offset = 0;
		break;
	case CMD_LOADER:
		ap_img = token;
		break;
	case CMD_SECOND_LOADER:
		sld_img = token;
		break;
	case CMD_SIGNED_HDMI:
		signed_hdmi = token;
		break;
	case CMD_DDR_FW:
		/* Do nothing */
		break;
	case CMD_ROM_VERSION:
		if (!strncmp(token, "v2", 2)) {
			rom_version = ROM_V2;
			ivt_offset = 0;
		} else if (!strncmp(token, "v1", 2)) {
			rom_version = ROM_V1;
		}
		break;

	}
}

static void parse_cfg_fld(int32_t *cmd, char *token,
			  char *name, int lineno, int fld)
{
	switch (fld) {
	case CFG_COMMAND:
		*cmd = get_table_entry_id(imx8mimage_cmds,
					  "imx8mimage commands", token);
		if (*cmd < 0) {
			fprintf(stderr, "Error: %s[%d] - Invalid command" "(%s)\n",
				name, lineno, token);
			exit(EXIT_FAILURE);
		}
		switch (*cmd) {
		case CMD_FIT:
			using_fit = 1;
			break;
		}
		break;
	case CFG_REG_SIZE:
		parse_cfg_cmd(*cmd, token, name, lineno);
		break;
	case CFG_REG_ADDRESS:
		switch (*cmd) {
		case CMD_LOADER:
			ap_start_addr = get_cfg_value(token, name, lineno);
			break;
		case CMD_SECOND_LOADER:
			sld_start_addr = get_cfg_value(token, name, lineno);
			break;
		}
		break;
	case CFG_REG_VALUE:
		switch (*cmd) {
		case CMD_SECOND_LOADER:
			sld_src_off = get_cfg_value(token, name, lineno);
			break;
		}
	default:
		break;
	}
}

static uint32_t parse_cfg_file(char *name)
{
	FILE *fd = NULL;
	char *line = NULL;
	char *token, *saveptr1, *saveptr2;
	int lineno = 0;
	int fld;
	size_t len;
	int32_t cmd;

	fd = fopen(name, "r");
	if (fd == 0) {
		fprintf(stderr, "Error: %s - Can't open cfg file\n", name);
		exit(EXIT_FAILURE);
	}

	/*
	 * Very simple parsing, line starting with # are comments
	 * and are dropped
	 */
	while ((getline(&line, &len, fd)) > 0) {
		lineno++;

		token = strtok_r(line, "\r\n", &saveptr1);
		if (!token)
			continue;

		/* Check inside the single line */
		for (fld = CFG_COMMAND, cmd = CFG_INVALID,
		     line = token; ; line = NULL, fld++) {
			token = strtok_r(line, " \t", &saveptr2);
			if (!token)
				break;

			/* Drop all text starting with '#' as comments */
			if (token[0] == '#')
				break;

			parse_cfg_fld(&cmd, token, name, lineno, fld);
		}
	}

	return 0;
}

static void fill_zero(int ifd, int size, int offset)
{
	int fill_size;
	uint8_t zeros[4096];
	int ret;

	memset(zeros, 0, sizeof(zeros));

	ret = lseek(ifd, offset, SEEK_SET);
	if (ret < 0) {
		fprintf(stderr, "%s seek: %s\n", __func__, strerror(errno));
		exit(EXIT_FAILURE);
	}

	while (size) {
		if (size > 4096)
			fill_size = 4096;
		else
			fill_size = size;

		if (write(ifd, (char *)&zeros, fill_size) != fill_size) {
			fprintf(stderr, "Write error: %s\n",
				strerror(errno));
			exit(EXIT_FAILURE);
		}

		size -= fill_size;
	};
}

static void copy_file(int ifd, const char *datafile, int pad, int offset,
		      int datafile_offset)
{
	int dfd;
	struct stat sbuf;
	unsigned char *ptr;
	int tail;
	int zero = 0;
	uint8_t zeros[4096];
	int size, ret;

	memset(zeros, 0, sizeof(zeros));

	dfd = open(datafile, O_RDONLY | O_BINARY);
	if (dfd < 0) {
		fprintf(stderr, "Can't open %s: %s\n",
			datafile, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (fstat(dfd, &sbuf) < 0) {
		fprintf(stderr, "Can't stat %s: %s\n",
			datafile, strerror(errno));
		exit(EXIT_FAILURE);
	}

	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0);
	if (ptr == MAP_FAILED) {
		fprintf(stderr, "Can't read %s: %s\n",
			datafile, strerror(errno));
		exit(EXIT_FAILURE);
	}

	size = sbuf.st_size - datafile_offset;
	ret = lseek(ifd, offset, SEEK_SET);
	if (ret < 0) {
		fprintf(stderr, "lseek ifd fail\n");
		exit(EXIT_FAILURE);
	}

	if (write(ifd, ptr + datafile_offset, size) != size) {
		fprintf(stderr, "Write error %s\n",
			strerror(errno));
		exit(EXIT_FAILURE);
	}

	tail = size % 4;
	pad = pad - size;
	if (pad == 1 && tail != 0) {
		if (write(ifd, (char *)&zero, 4 - tail) != 4 - tail) {
			fprintf(stderr, "Write error on %s\n",
				strerror(errno));
			exit(EXIT_FAILURE);
		}
	} else if (pad > 1) {
		while (pad > 0) {
			int todo = sizeof(zeros);

			if (todo > pad)
				todo = pad;
			if (write(ifd, (char *)&zeros, todo) != todo) {
				fprintf(stderr, "Write error: %s\n",
					strerror(errno));
				exit(EXIT_FAILURE);
			}
			pad -= todo;
		}
	}

	munmap((void *)ptr, sbuf.st_size);
	close(dfd);
}

/* Return this IVT offset in the final output file */
static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep,
				uint32_t *fit_load_addr)
{
	image_header_t image_header;
	int ret;

	uint32_t fit_size, load_addr;
	int align_len = 64 - 1; /* 64 is cacheline size */

	ret = lseek(fd, fit_offset, SEEK_SET);
	if (ret < 0) {
		fprintf(stderr, "lseek fd fail for fit\n");
		exit(EXIT_FAILURE);
	}

	if (read(fd, (char *)&image_header, sizeof(image_header_t)) !=
	    sizeof(image_header_t)) {
		fprintf(stderr, "generate_ivt_for_fit read failed: %s\n",
			strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (be32_to_cpu(image_header.ih_magic) != FDT_MAGIC) {
		fprintf(stderr, "%s error: not a FIT file\n", __func__);
		exit(EXIT_FAILURE);
	}

	fit_size = fdt_totalsize(&image_header);

	fit_size = ALIGN_IMX(fit_size, ALIGN_SIZE);

	ret = lseek(fd, fit_offset + fit_size, SEEK_SET);
	if (ret < 0) {
		fprintf(stderr, "lseek fd fail for fit\n");
		exit(EXIT_FAILURE);
	}

	/*
	 * ep is the u-boot entry. SPL loads the FIT before the u-boot
	 * address. 0x2000 is for CSF_SIZE
	 */
	load_addr = (ep - (fit_size + CSF_SIZE) - 512 - align_len) &
		~align_len;

	flash_header_v2_t ivt_header = { { 0xd1, 0x2000, 0x40 },
		load_addr, 0, 0, 0,
		(load_addr + fit_size),
		(load_addr + fit_size + 0x20),
		0 };

	if (write(fd, &ivt_header, sizeof(flash_header_v2_t)) !=
	    sizeof(flash_header_v2_t)) {
		fprintf(stderr, "IVT writing error on fit image\n");
		exit(EXIT_FAILURE);
	}

	*fit_load_addr = load_addr;

	return fit_offset + fit_size;
}

static void dump_header_v2(imx_header_v3_t *imx_header, int index)
{
	const char *ivt_name[2] = {"HDMI FW", "LOADER IMAGE"};

	fprintf(stdout, "========= IVT HEADER [%s] =========\n",
		ivt_name[index]);
	fprintf(stdout, "header.tag: \t\t0x%x\n",
		imx_header[index].fhdr.header.tag);
	fprintf(stdout, "header.length: \t\t0x%x\n",
		imx_header[index].fhdr.header.length);
	fprintf(stdout, "header.version: \t0x%x\n",
		imx_header[index].fhdr.header.version);
	fprintf(stdout, "entry: \t\t\t0x%x\n",
		imx_header[index].fhdr.entry);
	fprintf(stdout, "reserved1: \t\t0x%x\n",
		imx_header[index].fhdr.reserved1);
	fprintf(stdout, "dcd_ptr: \t\t0x%x\n",
		imx_header[index].fhdr.dcd_ptr);
	fprintf(stdout, "boot_data_ptr: \t\t0x%x\n",
		imx_header[index].fhdr.boot_data_ptr);
	fprintf(stdout, "self: \t\t\t0x%x\n",
		imx_header[index].fhdr.self);
	fprintf(stdout, "csf: \t\t\t0x%x\n",
		imx_header[index].fhdr.csf);
	fprintf(stdout, "reserved2: \t\t0x%x\n",
		imx_header[index].fhdr.reserved2);

	fprintf(stdout, "boot_data.start: \t0x%x\n",
		imx_header[index].boot_data.start);
	fprintf(stdout, "boot_data.size: \t0x%x\n",
		imx_header[index].boot_data.size);
	fprintf(stdout, "boot_data.plugin: \t0x%x\n",
		imx_header[index].boot_data.plugin);
}

void build_image(int ofd)
{
	int file_off, header_hdmi_off = 0, header_image_off;
	int hdmi_fd, ap_fd, sld_fd;
	uint32_t sld_load_addr = 0;
	uint32_t csf_off, sld_csf_off = 0;
	int ret;
	struct stat sbuf;

	if (!ap_img) {
		fprintf(stderr, "No LOADER image specificed\n");
		exit(EXIT_FAILURE);
	}

	file_off = 0;

	if (signed_hdmi) {
		header_hdmi_off = file_off + ivt_offset;

		hdmi_fd = open(signed_hdmi, O_RDONLY | O_BINARY);
		if (hdmi_fd < 0) {
			fprintf(stderr, "%s: Can't open: %s\n",
				signed_hdmi, strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (fstat(hdmi_fd, &sbuf) < 0) {
			fprintf(stderr, "%s: Can't stat: %s\n",
				signed_hdmi, strerror(errno));
			exit(EXIT_FAILURE);
		}
		close(hdmi_fd);

		/*
		 * Aligned to 104KB = 92KB FW image + 0x8000
		 * (IVT and alignment) + 0x4000 (second IVT + CSF)
		 */
		file_off += ALIGN_IMX(sbuf.st_size,
				  HDMI_FW_SIZE + 0x2000 + 0x1000);
	}

	header_image_off = file_off + ivt_offset;

	ap_fd = open(ap_img, O_RDONLY | O_BINARY);
	if (ap_fd < 0) {
		fprintf(stderr, "%s: Can't open: %s\n",
			ap_img, strerror(errno));
		exit(EXIT_FAILURE);
	}
	if (fstat(ap_fd, &sbuf) < 0) {
		fprintf(stderr, "%s: Can't stat: %s\n",
			ap_img, strerror(errno));
		exit(EXIT_FAILURE);
	}
	close(ap_fd);

	imx_header[IMAGE_IVT_ID].fhdr.header.tag = IVT_HEADER_TAG; /* 0xD1 */
	imx_header[IMAGE_IVT_ID].fhdr.header.length =
		cpu_to_be16(sizeof(flash_header_v2_t));
	imx_header[IMAGE_IVT_ID].fhdr.header.version = IVT_VERSION_V3; /* 0x41 */
	imx_header[IMAGE_IVT_ID].fhdr.entry = ap_start_addr;
	imx_header[IMAGE_IVT_ID].fhdr.self = ap_start_addr -
		sizeof(imx_header_v3_t);
	imx_header[IMAGE_IVT_ID].fhdr.dcd_ptr = 0;
	imx_header[IMAGE_IVT_ID].fhdr.boot_data_ptr =
		imx_header[IMAGE_IVT_ID].fhdr.self +
		offsetof(imx_header_v3_t, boot_data);
	imx_header[IMAGE_IVT_ID].boot_data.start =
		imx_header[IMAGE_IVT_ID].fhdr.self - ivt_offset;
	imx_header[IMAGE_IVT_ID].boot_data.size =
		ALIGN_IMX(sbuf.st_size + sizeof(imx_header_v3_t) + ivt_offset,
		      sector_size);

	image_off = header_image_off + sizeof(imx_header_v3_t);
	file_off +=  imx_header[IMAGE_IVT_ID].boot_data.size;

	imx_header[IMAGE_IVT_ID].boot_data.plugin = 0;
	imx_header[IMAGE_IVT_ID].fhdr.csf =
		imx_header[IMAGE_IVT_ID].boot_data.start +
		imx_header[IMAGE_IVT_ID].boot_data.size;

	imx_header[IMAGE_IVT_ID].boot_data.size += CSF_SIZE; /* 8K region dummy CSF */

	csf_off = file_off;
	file_off += CSF_SIZE;

	/* Second boot loader image */
	if (sld_img) {
		if (!using_fit) {
			fprintf(stderr, "Not support no fit\n");
			exit(EXIT_FAILURE);
		} else {
			sld_header_off = sld_src_off - rom_image_offset;
			/*
			 * Record the second bootloader relative offset in
			 * image's IVT reserved1
			 */
			if (rom_version == ROM_V1) {
				imx_header[IMAGE_IVT_ID].fhdr.reserved1 =
					sld_header_off - header_image_off;
			}
			sld_fd = open(sld_img, O_RDONLY | O_BINARY);
			if (sld_fd < 0) {
				fprintf(stderr, "%s: Can't open: %s\n",
					sld_img, strerror(errno));
				exit(EXIT_FAILURE);
			}

			if (fstat(sld_fd, &sbuf) < 0) {
				fprintf(stderr, "%s: Can't stat: %s\n",
					sld_img, strerror(errno));
				exit(EXIT_FAILURE);
			}

			close(sld_fd);

			file_off = sld_header_off;
			file_off += sbuf.st_size + sizeof(image_header_t);
		}
	}

	if (signed_hdmi) {
		header_hdmi_off -= ivt_offset;
		ret = lseek(ofd, header_hdmi_off, SEEK_SET);
		if (ret < 0) {
			fprintf(stderr, "lseek ofd fail for hdmi\n");
			exit(EXIT_FAILURE);
		}

		/* The signed HDMI FW has 0x400 IVT offset, need remove it */
		copy_file(ofd, signed_hdmi, 0, header_hdmi_off, 0x400);
	}

	/* Main Image */
	header_image_off -= ivt_offset;
	image_off -= ivt_offset;
	ret = lseek(ofd, header_image_off, SEEK_SET);
	if (ret < 0) {
		fprintf(stderr, "lseek ofd fail\n");
		exit(EXIT_FAILURE);
	}

	/* Write image header */
	if (write(ofd, &imx_header[IMAGE_IVT_ID], sizeof(imx_header_v3_t)) !=
	    sizeof(imx_header_v3_t)) {
		fprintf(stderr, "error writing image hdr\n");
		exit(1);
	}

	copy_file(ofd, ap_img, 0, image_off, 0);

	csf_off -= ivt_offset;
	fill_zero(ofd, CSF_SIZE, csf_off);

	if (sld_img) {
		sld_header_off -= ivt_offset;
		ret = lseek(ofd, sld_header_off, SEEK_SET);
		if (ret < 0) {
			fprintf(stderr, "lseek ofd fail for sld_img\n");
			exit(EXIT_FAILURE);
		}

		/* Write image header */
		if (!using_fit) {
			/* TODO */
		} else {
			copy_file(ofd, sld_img, 0, sld_header_off, 0);
			sld_csf_off =
				generate_ivt_for_fit(ofd, sld_header_off,
						     sld_start_addr,
						     &sld_load_addr) + 0x20;
		}
	}

	if (!signed_hdmi)
		dump_header_v2(imx_header, 0);
	dump_header_v2(imx_header, 1);

	fprintf(stdout, "========= OFFSET dump =========");
	if (signed_hdmi) {
		fprintf(stdout, "\nSIGNED HDMI FW:\n");
		fprintf(stdout, " header_hdmi_off \t0x%x\n",
			header_hdmi_off);
	}

	fprintf(stdout, "\nLoader IMAGE:\n");
	fprintf(stdout, " header_image_off \t0x%x\n image_off \t\t0x%x\n csf_off \t\t0x%x\n",
		header_image_off, image_off, csf_off);
	fprintf(stdout, " spl hab block: \t0x%x 0x%x 0x%x\n",
		imx_header[IMAGE_IVT_ID].fhdr.self, header_image_off,
		csf_off - header_image_off);

	fprintf(stdout, "\nSecond Loader IMAGE:\n");
	fprintf(stdout, " sld_header_off \t0x%x\n",
		sld_header_off);
	fprintf(stdout, " sld_csf_off \t\t0x%x\n",
		sld_csf_off);
	fprintf(stdout, " sld hab block: \t0x%x 0x%x 0x%x\n",
		sld_load_addr, sld_header_off, sld_csf_off - sld_header_off);
}

int imx8mimage_copy_image(int outfd, struct image_tool_params *mparams)
{
	/*
	 * SECO FW is a container image, this is to calculate the
	 * 2nd container offset.
	 */
	fprintf(stdout, "parsing %s\n", mparams->imagename);
	parse_cfg_file(mparams->imagename);

	build_image(outfd);

	return 0;
}

/*
 * imx8mimage parameters
 */
U_BOOT_IMAGE_TYPE(
	imx8mimage,
	"NXP i.MX8M Boot Image support",
	0,
	NULL,
	imx8mimage_check_params,
	NULL,
	imx8mimage_print_header,
	imx8mimage_set_header,
	NULL,
	imx8mimage_check_image_types,
	NULL,
	NULL
);
