// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Michal Simek <michals@xilinx.com>
 * Copyright (C) 2015 Nathan Rossi <nathan@nathanrossi.com>
 *
 * The following Boot Header format/structures and values are defined in the
 * following documents:
 *   * ug1085 ZynqMP TRM doc v1.4 (Chapter 11, Table 11-4)
 *   * ug1137 ZynqMP Software Developer Guide v6.0 (Chapter 16)
 *
 * Expected Header Size = 0x9C0
 * Forced as 'little' endian, 32-bit words
 *
 *  0x  0 - Interrupt table (8 words)
 *  ...     (Default value = 0xeafffffe)
 *  0x 1f
 *  0x 20 - Width detection
 *         * DEFAULT_WIDTHDETECTION    0xaa995566
 *  0x 24 - Image identifier
 *         * DEFAULT_IMAGEIDENTIFIER   0x584c4e58
 *  0x 28 - Encryption
 *         * 0x00000000 - None
 *         * 0xa5c3c5a3 - eFuse
 *         * 0xa5c3c5a7 - obfuscated key in eFUSE
 *         * 0x3a5c3c5a - bbRam
 *         * 0xa35c7ca5 - obfuscated key in boot header
 *  0x 2C - Image load
 *  0x 30 - Image offset
 *  0x 34 - PFW image length
 *  0x 38 - Total PFW image length
 *  0x 3C - Image length
 *  0x 40 - Total image length
 *  0x 44 - Image attributes
 *  0x 48 - Header checksum
 *  0x 4c - Obfuscated key
 *  ...
 *  0x 68
 *  0x 6c - Reserved
 *  0x 70 - User defined
 *  ...
 *  0x 9c
 *  0x a0 - Secure header initialization vector
 *  ...
 *  0x a8
 *  0x ac - Obfuscated key initialization vector
 *  ...
 *  0x b4
 *  0x b8 - Register Initialization, 511 Address and Data word pairs
 *         * List is terminated with an address of 0xffffffff or
 *  ...    * at the max number of entries
 *  0x8b4
 *  0x8b8 - Reserved
 *  ...
 *  0x9bf
 *  0x9c0 - Data/Image starts here or above
 */

#include "imagetool.h"
#include "mkimage.h"
#include "zynqmpimage.h"
#include <image.h>

static struct zynqmp_header zynqmpimage_header;
static void *dynamic_header;
static FILE *fpmu;

static uint32_t zynqmpimage_checksum(struct zynqmp_header *ptr)
{
	uint32_t checksum = 0;

	if (ptr == NULL)
		return 0;

	checksum += le32_to_cpu(ptr->width_detection);
	checksum += le32_to_cpu(ptr->image_identifier);
	checksum += le32_to_cpu(ptr->encryption);
	checksum += le32_to_cpu(ptr->image_load);
	checksum += le32_to_cpu(ptr->image_offset);
	checksum += le32_to_cpu(ptr->pfw_image_length);
	checksum += le32_to_cpu(ptr->total_pfw_image_length);
	checksum += le32_to_cpu(ptr->image_size);
	checksum += le32_to_cpu(ptr->image_stored_size);
	checksum += le32_to_cpu(ptr->image_attributes);
	checksum = ~checksum;

	return cpu_to_le32(checksum);
}

void zynqmpimage_default_header(struct zynqmp_header *ptr)
{
	int i;

	if (ptr == NULL)
		return;

	ptr->width_detection = HEADER_WIDTHDETECTION;
	ptr->image_attributes = HEADER_CPU_SELECT_A53_64BIT;
	ptr->image_identifier = HEADER_IMAGEIDENTIFIER;
	ptr->encryption = cpu_to_le32(ENCRYPTION_NONE);

	/* Setup not-supported/constant/reserved fields */
	for (i = 0; i < HEADER_INTERRUPT_VECTORS; i++)
		ptr->interrupt_vectors[i] = HEADER_INTERRUPT_DEFAULT;

	for (i = 0; i < HEADER_REGINITS; i++) {
		ptr->register_init[i].address = HEADER_REGINIT_NULL;
		ptr->register_init[i].data = 0;
	}

	/*
	 * Certain reserved fields are required to be set to 0, ensure they are
	 * set as such.
	 */
	ptr->pfw_image_length = 0x0;
	ptr->total_pfw_image_length = 0x0;
}

/* mkimage glue functions */
static int zynqmpimage_verify_header(unsigned char *ptr, int image_size,
		struct image_tool_params *params)
{
	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;

	if (image_size < sizeof(struct zynqmp_header))
		return -1;

	if (zynqhdr->width_detection != HEADER_WIDTHDETECTION)
		return -1;
	if (zynqhdr->image_identifier != HEADER_IMAGEIDENTIFIER)
		return -1;

	if (zynqmpimage_checksum(zynqhdr) != zynqhdr->checksum)
		return -1;

	return 0;
}

static void print_partition(const void *ptr, const struct partition_header *ph)
{
	uint32_t attr = le32_to_cpu(ph->attributes);
	unsigned long len = le32_to_cpu(ph->len) * 4;
	const char *part_owner;
	const char *dest_devs[0x8] = {
		"none", "PS", "PL", "PMU", "unknown", "unknown", "unknown",
		"unknown"
	};

	switch (attr & PART_ATTR_PART_OWNER_MASK) {
	case PART_ATTR_PART_OWNER_FSBL:
		part_owner = "FSBL";
		break;
	case PART_ATTR_PART_OWNER_UBOOT:
		part_owner = "U-Boot";
		break;
	default:
		part_owner = "Unknown";
		break;
	}

	printf("%s payload on CPU %s (%s):\n", part_owner,
	       dest_cpus[(attr & PART_ATTR_DEST_CPU_MASK) >> 8],
	       dest_devs[(attr & PART_ATTR_DEST_DEVICE_MASK) >> 4]);

	printf("    Offset     : 0x%08x\n", le32_to_cpu(ph->offset) * 4);
	printf("    Size       : %lu (0x%lx) bytes\n", len, len);
	printf("    Load       : 0x%08llx",
	       (unsigned long long)le64_to_cpu(ph->load_address));
	if (ph->load_address != ph->entry_point)
		printf(" (entry=0x%08llx)\n",
		       (unsigned long long)le64_to_cpu(ph->entry_point));
	else
		printf("\n");
	printf("    Attributes : ");

	if (attr & PART_ATTR_VEC_LOCATION)
		printf("vec ");

	if (attr & PART_ATTR_ENCRYPTED)
		printf("encrypted ");

	switch (attr & PART_ATTR_CHECKSUM_MASK) {
	case PART_ATTR_CHECKSUM_MD5:
		printf("md5 ");
		break;
	case PART_ATTR_CHECKSUM_SHA2:
		printf("sha2 ");
		break;
	case PART_ATTR_CHECKSUM_SHA3:
		printf("sha3 ");
		break;
	}

	if (attr & PART_ATTR_BIG_ENDIAN)
		printf("BigEndian ");

	if (attr & PART_ATTR_RSA_SIG)
		printf("RSA ");

	if (attr & PART_ATTR_A53_EXEC_AARCH32)
		printf("AArch32 ");

	if (attr & PART_ATTR_TARGET_EL_MASK)
		printf("EL%d ", (attr & PART_ATTR_TARGET_EL_MASK) >> 1);

	if (attr & PART_ATTR_TZ_SECURE)
		printf("secure ");
	printf("\n");

	printf("    Checksum   : 0x%08x\n", le32_to_cpu(ph->checksum));
}

void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params)
{
	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
	int i;

	printf("Image Type   : Xilinx ZynqMP Boot Image support\n");
	printf("Image Offset : 0x%08x\n", le32_to_cpu(zynqhdr->image_offset));
	printf("Image Size   : %lu bytes (%lu bytes packed)\n",
	       (unsigned long)le32_to_cpu(zynqhdr->image_size),
	       (unsigned long)le32_to_cpu(zynqhdr->image_stored_size));

	if (zynqhdr->pfw_image_length)
		printf("PMUFW Size   : %lu bytes (%lu bytes packed)\n",
		       (unsigned long)le32_to_cpu(zynqhdr->pfw_image_length),
		       (unsigned long)le32_to_cpu(
				zynqhdr->total_pfw_image_length));

	printf("Image Load   : 0x%08x\n", le32_to_cpu(zynqhdr->image_load));
	printf("Checksum     : 0x%08x\n", le32_to_cpu(zynqhdr->checksum));

	for (i = 0; i < HEADER_INTERRUPT_VECTORS; i++) {
		if (zynqhdr->interrupt_vectors[i] == HEADER_INTERRUPT_DEFAULT)
			continue;

		printf("Modified Interrupt Vector Address [%d]: 0x%08x\n", i,
		       le32_to_cpu(zynqhdr->interrupt_vectors[i]));
	}

	for (i = 0; i < HEADER_REGINITS; i++) {
		if (zynqhdr->register_init[i].address == HEADER_REGINIT_NULL)
			break;

		if (i == 0)
			printf("Custom Register Initialization:\n");

		printf("    @ 0x%08x -> 0x%08x\n",
		       le32_to_cpu(zynqhdr->register_init[i].address),
		       le32_to_cpu(zynqhdr->register_init[i].data));
	}

	if (zynqhdr->image_header_table_offset) {
		struct image_header_table *iht = (void *)ptr +
			zynqhdr->image_header_table_offset;
		struct partition_header *ph;
		uint32_t ph_offset;
		uint32_t next;
		int i;

		ph_offset = le32_to_cpu(iht->partition_header_offset) * 4;
		ph = (void *)ptr + ph_offset;
		for (i = 0; i < le32_to_cpu(iht->nr_parts); i++) {
			next = le32_to_cpu(ph->next_partition_offset) * 4;

			/* Partition 0 is the base image itself */
			if (i)
				print_partition(ptr, ph);

			ph = (void *)ptr + next;
		}
	}

	free(dynamic_header);
}

static int zynqmpimage_check_params(struct image_tool_params *params)
{
	if (!params)
		return 0;

	if (params->addr != 0x0) {
		fprintf(stderr, "Error: Load Address cannot be specified.\n");
		return -1;
	}

	/*
	 * If the entry point is specified ensure it is 64 byte aligned.
	 */
	if (params->eflag && (params->ep % 64 != 0)) {
		fprintf(stderr,
			"Error: Entry Point must be aligned to a 64-byte boundary.\n");
		return -1;
	}

	return !(params->lflag || params->dflag);
}

static int zynqmpimage_check_image_types(uint8_t type)
{
	if (type == IH_TYPE_ZYNQMPIMAGE)
		return EXIT_SUCCESS;
	return EXIT_FAILURE;
}

static uint32_t fsize(FILE *fp)
{
	int size, ret, origin;

	origin = ftell(fp);
	if (origin < 0) {
		fprintf(stderr, "Incorrect file size\n");
		fclose(fp);
		exit(2);
	}

	ret = fseek(fp, 0L, SEEK_END);
	if (ret) {
		fprintf(stderr, "Incorrect file SEEK_END\n");
		fclose(fp);
		exit(3);
	}

	size = ftell(fp);
	if (size < 0) {
		fprintf(stderr, "Incorrect file size\n");
		fclose(fp);
		exit(4);
	}

	/* going back */
	ret = fseek(fp, origin, SEEK_SET);
	if (ret) {
		fprintf(stderr, "Incorrect file SEEK_SET to %d\n", origin);
		fclose(fp);
		exit(3);
	}

	return size;
}

static void zynqmpimage_pmufw(struct zynqmp_header *zynqhdr,
			      const char *filename)
{
	uint32_t size;

	/* Setup PMU fw size */
	zynqhdr->pfw_image_length = fsize(fpmu);
	zynqhdr->total_pfw_image_length = zynqhdr->pfw_image_length;

	zynqhdr->image_size -= zynqhdr->pfw_image_length;
	zynqhdr->image_stored_size -= zynqhdr->total_pfw_image_length;

	/* Read the whole PMUFW to the header */
	size = fread(&zynqhdr->__reserved4[66], 1,
		     zynqhdr->pfw_image_length, fpmu);
	if (size != zynqhdr->pfw_image_length) {
		fprintf(stderr, "Cannot read PMUFW file: %s\n", filename);
		fclose(fpmu);
		exit(1);
	}

	fclose(fpmu);
}

static void zynqmpimage_parse_initparams(struct zynqmp_header *zynqhdr,
	const char *filename)
{
	FILE *fp;
	struct zynqmp_reginit reginit;
	unsigned int reg_count = 0;
	int r, err;
	struct stat path_stat;

	/* Expect a table of register-value pairs, e.g. "0x12345678 0x4321" */
	fp = fopen(filename, "r");
	if (!fp) {
		fprintf(stderr, "Cannot open initparams file: %s\n", filename);
		exit(1);
	}

	err = fstat(fileno(fp), &path_stat);
	if (err) {
		fclose(fp);
		return;
	}

	if (!S_ISREG(path_stat.st_mode)) {
		fclose(fp);
		return;
	}

	do {
		r = fscanf(fp, "%x %x", &reginit.address, &reginit.data);
		if (r == 2) {
			zynqhdr->register_init[reg_count] = reginit;
			++reg_count;
		}
		r = fscanf(fp, "%*[^\n]\n"); /* Skip to next line */
	} while ((r != EOF) && (reg_count < HEADER_REGINITS));
	fclose(fp);
}

static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
		struct image_tool_params *params)
{
	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
	zynqmpimage_default_header(zynqhdr);

	/* place image directly after header */
	zynqhdr->image_offset =
		cpu_to_le32((uint32_t)sizeof(struct zynqmp_header));
	zynqhdr->image_size = cpu_to_le32(params->file_size -
					  sizeof(struct zynqmp_header));
	zynqhdr->image_stored_size = zynqhdr->image_size;
	zynqhdr->image_load = 0xfffc0000;
	if (params->eflag)
		zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep);

	/* PMUFW */
	if (fpmu)
		zynqmpimage_pmufw(zynqhdr, params->imagename);

	/* User can pass in text file with init list */
	if (strlen(params->imagename2))
		zynqmpimage_parse_initparams(zynqhdr, params->imagename2);

	zynqhdr->checksum = zynqmpimage_checksum(zynqhdr);
}

static int zynqmpimage_vrec_header(struct image_tool_params *params,
				   struct image_type_params *tparams)
{
	struct stat path_stat;
	char *filename = params->imagename;
	int err;

	/* Handle static case without PMUFW */
	tparams->header_size = sizeof(struct zynqmp_header);
	tparams->hdr = (void *)&zynqmpimage_header;

	/* PMUFW name is passed via params->imagename */
	if (strlen(filename) == 0)
		return EXIT_SUCCESS;

	fpmu = fopen(filename, "r");
	if (!fpmu) {
		fprintf(stderr, "Cannot open PMUFW file: %s\n", filename);
		return EXIT_FAILURE;
	}

	err = fstat(fileno(fpmu), &path_stat);
	if (err) {
		fclose(fpmu);
		fpmu = NULL;
		return EXIT_FAILURE;
	}

	if (!S_ISREG(path_stat.st_mode)) {
		fclose(fpmu);
		fpmu = NULL;
		return EXIT_FAILURE;
	}

	/* Increase header size by PMUFW file size */
	tparams->header_size += fsize(fpmu);

	/* Allocate buffer with space for PMUFW */
	dynamic_header = calloc(1, tparams->header_size);
	tparams->hdr = dynamic_header;

	return EXIT_SUCCESS;
}

U_BOOT_IMAGE_TYPE(
	zynqmpimage,
	"Xilinx ZynqMP Boot Image support",
	sizeof(struct zynqmp_header),
	(void *)&zynqmpimage_header,
	zynqmpimage_check_params,
	zynqmpimage_verify_header,
	zynqmpimage_print_header,
	zynqmpimage_set_header,
	NULL,
	zynqmpimage_check_image_types,
	NULL,
	zynqmpimage_vrec_header
);
