// 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 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(x,a)	__ALIGN_MASK((x), (__typeof__(x))(a) - 1, a)
#define __ALIGN_MASK(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",       },
	{-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;
		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;
	}
}

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 = (fit_size + 3) & ~3;

	fit_size = ALIGN(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(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(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
			 */
			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
);
