// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2014 Charles Manning <cdhmanning@gmail.com>
 *
 * Reference documents:
 *   Cyclone V SoC: https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/cyclone-v/cv_5400a.pdf
 *   Arria V SoC:   https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/arria-v/av_5400a.pdf
 *   Arria 10 SoC:  https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/arria-10/a10_5400a.pdf
 *
 * Bootable SoCFPGA image requires a structure of the following format
 * positioned at offset 0x40 of the bootable image. Endian is LSB.
 *
 * There are two versions of the SoCFPGA header format, v0 and v1.
 * The version 0 is used by Cyclone V SoC and Arria V SoC, while
 * the version 1 is used by the Arria 10 SoC.
 *
 * Version 0:
 * Offset   Length   Usage
 * -----------------------
 *   0x40        4   Validation word (0x31305341)
 *   0x44        1   Version (0x0)
 *   0x45        1   Flags (unused, zero is fine)
 *   0x46        2   Length (in units of u32, including the end checksum).
 *   0x48        2   Zero (0x0)
 *   0x4A        2   Checksum over the header. NB Not CRC32
 *
 * Version 1:
 * Offset   Length   Usage
 * -----------------------
 *   0x40        4   Validation word (0x31305341)
 *   0x44        1   Version (0x1)
 *   0x45        1   Flags (unused, zero is fine)
 *   0x46        2   Header length (in units of u8).
 *   0x48        4   Length (in units of u8).
 *   0x4C        4   Image entry offset from standard of header
 *   0x50        2   Zero (0x0)
 *   0x52        2   Checksum over the header. NB Not CRC32
 *
 * At the end of the code we have a 32-bit CRC checksum over whole binary
 * excluding the CRC.
 *
 * Note that the CRC used here is **not** the zlib/Adler crc32. It is the
 * CRC-32 used in bzip2, ethernet and elsewhere.
 *
 * The Image entry offset in version 1 image is relative the the start of
 * the header, 0x40, and must not be a negative number. Therefore, it is
 * only possible to make the SoCFPGA jump forward. The U-Boot bootloader
 * places a trampoline instruction at offset 0x5c, 0x14 bytes from the
 * start of the SoCFPGA header, which jumps to the reset vector.
 *
 * The image is padded out to 64k, because that is what is
 * typically used to write the image to the boot medium.
 */

#include "pbl_crc32.h"
#include "imagetool.h"
#include "mkimage.h"
#include <u-boot/crc.h>

#include <image.h>

#define HEADER_OFFSET	0x40
#define VALIDATION_WORD	0x31305341
#define IMAGE_ALIGN	16

/* Minimum and default entry point offset */
#define ENTRY_POINT_OFFSET	0x14

static uint8_t buffer_v0[0x10000];
static uint8_t buffer_v1[0x40000];

struct socfpga_header_v0 {
	uint32_t	validation;
	uint8_t		version;
	uint8_t		flags;
	uint16_t	length_u32;
	uint16_t	zero;
	uint16_t	checksum;
};

struct socfpga_header_v1 {
	uint32_t	validation;
	uint8_t		version;
	uint8_t		flags;
	uint16_t	header_u8;
	uint32_t	length_u8;
	uint32_t	entry_offset;
	uint16_t	zero;
	uint16_t	checksum;
};

static unsigned int sfp_hdr_size(uint8_t ver)
{
	if (ver == 0)
		return sizeof(struct socfpga_header_v0);
	if (ver == 1)
		return sizeof(struct socfpga_header_v1);
	return 0;
}

static unsigned int sfp_max_size(uint8_t ver)
{
	if (ver == 0)
		return sizeof(buffer_v0);
	if (ver == 1)
		return sizeof(buffer_v1);
	return 0;
}

static unsigned int sfp_aligned_len(uint32_t size)
{
	/* Add 4 bytes for CRC and align to 16 bytes */
	return ALIGN(size + sizeof(uint32_t), IMAGE_ALIGN);
}

/*
 * The header checksum is just a very simple checksum over
 * the header area.
 * There is still a crc32 over the whole lot.
 */
static uint16_t sfp_hdr_checksum(uint8_t *buf, unsigned char ver)
{
	uint16_t ret = 0;
	int len = sfp_hdr_size(ver) - sizeof(ret);

	while (--len)
		ret += *buf++;

	return ret;
}

static void sfp_build_header(uint8_t *buf, uint8_t ver, uint8_t flags,
			     uint32_t length_bytes,
			     struct image_tool_params *params)
{
	uint32_t entry_offset = params->eflag ? params->ep : ENTRY_POINT_OFFSET;
	struct socfpga_header_v0 header_v0 = {
		.validation	= cpu_to_le32(VALIDATION_WORD),
		.version	= 0,
		.flags		= flags,
		.length_u32	= cpu_to_le16(length_bytes / 4),
		.zero		= 0,
	};

	struct socfpga_header_v1 header_v1 = {
		.validation	= cpu_to_le32(VALIDATION_WORD),
		.version	= 1,
		.flags		= flags,
		.header_u8	= cpu_to_le16(sizeof(header_v1)),
		.length_u8	= cpu_to_le32(length_bytes),
		/* Trampoline offset */
		.entry_offset	= cpu_to_le32(entry_offset),
		.zero		= 0,
	};

	uint16_t csum;

	if (ver == 0) {
		csum = sfp_hdr_checksum((uint8_t *)&header_v0, 0);
		header_v0.checksum = cpu_to_le16(csum);
		memcpy(buf, &header_v0, sizeof(header_v0));
	} else {
		csum = sfp_hdr_checksum((uint8_t *)&header_v1, 1);
		header_v1.checksum = cpu_to_le16(csum);
		memcpy(buf, &header_v1, sizeof(header_v1));
	}
}

/*
 * Perform a rudimentary verification of header and return
 * size of image.
 */
static int sfp_verify_header(const uint8_t *buf, uint8_t *ver)
{
	struct socfpga_header_v0 header_v0;
	struct socfpga_header_v1 header_v1;
	uint16_t hdr_csum, sfp_csum;
	uint32_t img_len;

	/*
	 * Header v0 is always smaller than Header v1 and the validation
	 * word and version field is at the same place, so use Header v0
	 * to check for version during verifiction and upgrade to Header
	 * v1 if needed.
	 */
	memcpy(&header_v0, buf, sizeof(header_v0));

	if (le32_to_cpu(header_v0.validation) != VALIDATION_WORD)
		return -1;

	if (header_v0.version == 0) {
		hdr_csum = le16_to_cpu(header_v0.checksum);
		sfp_csum = sfp_hdr_checksum((uint8_t *)&header_v0, 0);
		img_len = le16_to_cpu(header_v0.length_u32) * 4;
	} else if (header_v0.version == 1) {
		memcpy(&header_v1, buf, sizeof(header_v1));
		hdr_csum = le16_to_cpu(header_v1.checksum);
		sfp_csum = sfp_hdr_checksum((uint8_t *)&header_v1, 1);
		img_len = le32_to_cpu(header_v1.length_u8);
	} else {	/* Invalid version */
		return -EINVAL;
	}

	/* Verify checksum */
	if (hdr_csum != sfp_csum)
		return -EINVAL;

	*ver = header_v0.version;
	return img_len;
}

/* Sign the buffer and return the signed buffer size */
static int sfp_sign_buffer(uint8_t *buf, uint8_t ver, uint8_t flags,
			   int len, int pad_64k,
			   struct image_tool_params *params)
{
	uint32_t calc_crc;
	uint32_t crc_off;

	/* Align the length up */
	len = sfp_aligned_len(len);

	/* Build header */
	sfp_build_header(buf + HEADER_OFFSET, ver, flags, len, params);

	/* Calculate and apply the CRC */
	crc_off = len - sizeof(uint32_t); /* at last 4 bytes of image */
	calc_crc = ~pbl_crc32(0, (char *)buf, crc_off);

	*((uint32_t *)(buf + crc_off)) = cpu_to_le32(calc_crc);

	if (!pad_64k)
		return len + 4;

	return sfp_max_size(ver);
}

/* Verify that the buffer looks sane */
static int sfp_verify_buffer(const uint8_t *buf)
{
	int len; /* Including 32bit CRC */
	uint32_t calc_crc;
	uint32_t buf_crc;
	uint8_t ver = 0;

	len = sfp_verify_header(buf + HEADER_OFFSET, &ver);
	if (len < 0) {
		debug("Invalid header\n");
		return -1;
	}

	if (len < HEADER_OFFSET || len > sfp_max_size(ver)) {
		debug("Invalid header length (%i)\n", len);
		return -1;
	}

	/*
	 * Adjust length to the base of the CRC.
	 * Check the CRC.
	*/
	len -= 4;

	calc_crc = ~pbl_crc32(0, (const char *)buf, len);

	buf_crc = le32_to_cpu(*((uint32_t *)(buf + len)));

	if (buf_crc != calc_crc) {
		fprintf(stderr, "CRC32 does not match (%08x != %08x)\n",
			buf_crc, calc_crc);
		return -1;
	}

	return 0;
}

/* mkimage glue functions */
static int socfpgaimage_verify_header(unsigned char *ptr, int image_size,
				      struct image_tool_params *params)
{
	if (image_size < 0x80)
		return -1;

	return sfp_verify_buffer(ptr);
}

static void socfpgaimage_print_header_v0(struct socfpga_header_v0 *header)
{
	printf("Image Type\t: Cyclone V / Arria V SoC Image\n");
	printf("Validation word\t: 0x%08x\n",
	       le32_to_cpu(header->validation));
	printf("Version\t\t: 0x%08x\n", header->version);
	printf("Flags\t\t: 0x%08x\n", header->flags);
	printf("Program length\t: 0x%08x\n",
	       le16_to_cpu(header->length_u32));
	printf("Header checksum\t: 0x%08x\n",
	       le16_to_cpu(header->checksum));
}

static void socfpgaimage_print_header_v1(struct socfpga_header_v1 *header)
{
	printf("Image Type\t: Arria 10 SoC Image\n");
	printf("Validation word\t: 0x%08x\n",
	       le32_to_cpu(header->validation));
	printf("Version\t\t: 0x%08x\n", header->version);
	printf("Flags\t\t: 0x%08x\n", header->flags);
	printf("Header length\t: 0x%08x\n",
	       le16_to_cpu(header->header_u8));
	printf("Program length\t: 0x%08x\n",
	       le32_to_cpu(header->length_u8));
	printf("Program entry\t: 0x%08x\n",
	       le32_to_cpu(header->entry_offset));
	printf("Header checksum\t: 0x%08x\n",
	       le16_to_cpu(header->checksum));
}

static void socfpgaimage_print_header(const void *ptr)
{
	const void *header = ptr + HEADER_OFFSET;
	struct socfpga_header_v0 *header_v0;

	if (sfp_verify_buffer(ptr) == 0) {
		header_v0 = (struct socfpga_header_v0 *)header;

		if (header_v0->version == 0)
			socfpgaimage_print_header_v0(header_v0);
		else
			socfpgaimage_print_header_v1((struct socfpga_header_v1 *)header);
	} else {
		printf("Not a sane SOCFPGA preloader\n");
	}
}

static int socfpgaimage_check_params_v0(struct image_tool_params *params)
{
	/* Not sure if we should be accepting fflags */
	return	(params->dflag && (params->fflag || params->lflag)) ||
		(params->fflag && (params->dflag || params->lflag)) ||
		(params->lflag && (params->dflag || params->fflag));
}

static int socfpgaimage_check_params_v1(struct image_tool_params *params)
{
	/*
	 * If the entry point is specified, ensure it is >= ENTRY_POINT_OFFSET
	 * and it is 4 bytes aligned.
	 */
	if (params->eflag && (params->ep < ENTRY_POINT_OFFSET ||
			      params->ep % 4 != 0)) {
		fprintf(stderr,
			"Error: Entry point must be greater than 0x%x.\n",
			ENTRY_POINT_OFFSET);
		return -1;
	}

	/* Not sure if we should be accepting fflags */
	return	(params->dflag && (params->fflag || params->lflag)) ||
		(params->fflag && (params->dflag || params->lflag)) ||
		(params->lflag && (params->dflag || params->fflag));
}

static int socfpgaimage_check_image_types_v0(uint8_t type)
{
	if (type == IH_TYPE_SOCFPGAIMAGE)
		return EXIT_SUCCESS;
	return EXIT_FAILURE;
}

static int socfpgaimage_check_image_types_v1(uint8_t type)
{
	if (type == IH_TYPE_SOCFPGAIMAGE_V1)
		return EXIT_SUCCESS;
	return EXIT_FAILURE;
}

/*
 * To work in with the mkimage framework, we do some ugly stuff...
 *
 * First, socfpgaimage_vrec_header() is called.
 * We prepend a fake header big enough to include crc32 and align image to 16
 * bytes.
 * This gives us enough space to do what we want later.
 *
 * Next, socfpgaimage_set_header() is called.
 * We fix up the buffer by moving the image to the start of the buffer.
 * We now have some room to do what we need (add CRC).
 */

static int data_size;

static int sfp_fake_header_size(unsigned int size, uint8_t ver)
{
	unsigned int align_size;

	align_size = sfp_aligned_len(size);

	/* extra bytes needed */
	return align_size - size;
}

static int sfp_vrec_header(struct image_tool_params *params,
			   struct image_type_params *tparams, uint8_t ver)
{
	struct stat sbuf;

	if (params->datafile &&
	    stat(params->datafile, &sbuf) == 0 &&
	    sbuf.st_size <= (sfp_max_size(ver) - sizeof(uint32_t))) {
		data_size = sbuf.st_size;
		tparams->header_size = sfp_fake_header_size(data_size, ver);
	}
	return 0;

}

static int socfpgaimage_vrec_header_v0(struct image_tool_params *params,
				       struct image_type_params *tparams)
{
	return sfp_vrec_header(params, tparams, 0);
}

static int socfpgaimage_vrec_header_v1(struct image_tool_params *params,
				       struct image_type_params *tparams)
{
	return sfp_vrec_header(params, tparams, 1);
}

static void sfp_set_header(void *ptr, unsigned char ver,
			   struct image_tool_params *params)
{
	uint8_t *buf = (uint8_t *)ptr;

	/*
	 * This function is called after vrec_header() has been called.
	 * At this stage we have the sfp_fake_header_size() dummy bytes
	 * followed by data_size image bytes.
	 * We need to fix the buffer by moving the image bytes back to
	 * the beginning of the buffer, then actually do the signing stuff...
	 */
	memmove(buf, buf + sfp_fake_header_size(data_size, ver), data_size);
	memset(buf + data_size, 0, sfp_fake_header_size(data_size, ver));

	sfp_sign_buffer(buf, ver, 0, data_size, 0, params);
}

static void socfpgaimage_set_header_v0(void *ptr, struct stat *sbuf, int ifd,
				       struct image_tool_params *params)
{
	sfp_set_header(ptr, 0, params);
}

static void socfpgaimage_set_header_v1(void *ptr, struct stat *sbuf, int ifd,
				       struct image_tool_params *params)
{
	sfp_set_header(ptr, 1, params);
}

U_BOOT_IMAGE_TYPE(
	socfpgaimage,
	"Altera SoCFPGA Cyclone V / Arria V image support",
	0, /* This will be modified by vrec_header() */
	(void *)buffer_v0,
	socfpgaimage_check_params_v0,
	socfpgaimage_verify_header,
	socfpgaimage_print_header,
	socfpgaimage_set_header_v0,
	NULL,
	socfpgaimage_check_image_types_v0,
	NULL,
	socfpgaimage_vrec_header_v0
);

U_BOOT_IMAGE_TYPE(
	socfpgaimage_v1,
	"Altera SoCFPGA Arria10 image support",
	0, /* This will be modified by vrec_header() */
	(void *)buffer_v1,
	socfpgaimage_check_params_v1,
	socfpgaimage_verify_header,
	socfpgaimage_print_header,
	socfpgaimage_set_header_v1,
	NULL,
	socfpgaimage_check_image_types_v1,
	NULL,
	socfpgaimage_vrec_header_v1
);
