/*
 * (C) Copyright 2014
 * Andreas Bießmann <andreas.devel@googlemail.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include "imagetool.h"
#include "mkimage.h"

#include <image.h>

#define pr_err(fmt, args...) fprintf(stderr, "atmelimage Error: " fmt, ##args)

static int atmel_check_image_type(uint8_t type)
{
	if (type == IH_TYPE_ATMELIMAGE)
		return EXIT_SUCCESS;
	else
		return EXIT_FAILURE;
}

static uint32_t nand_pmecc_header[52];

/*
 * A helper struct for parsing the mkimage -n parameter
 *
 * Keep in same order as the configs array!
 */
static struct pmecc_config {
	int use_pmecc;
	int sector_per_page;
	int spare_size;
	int ecc_bits;
	int sector_size;
	int ecc_offset;
} pmecc;

/*
 * Strings used for configure the PMECC header via -n mkimage switch
 *
 * We estimate a coma separated list of key=value pairs. The mkimage -n
 * parameter argument should not contain any whitespace.
 *
 * Keep in same order as struct pmecc_config!
 */
static const char * const configs[] = {
	"usePmecc",
	"sectorPerPage",
	"spareSize",
	"eccBits",
	"sectorSize",
	"eccOffset"
};

static int atmel_find_pmecc_parameter_in_token(const char *token)
{
	size_t pos;
	char *param;

	debug("token: '%s'\n", token);

	for (pos = 0; pos < ARRAY_SIZE(configs); pos++) {
		if (strncmp(token, configs[pos], strlen(configs[pos])) == 0) {
			param = strstr(token, "=");
			if (!param)
				goto err;

			param++;
			debug("\t%s parameter: '%s'\n", configs[pos], param);

			switch (pos) {
			case 0:
				pmecc.use_pmecc = strtol(param, NULL, 10);
				return EXIT_SUCCESS;
			case 1:
				pmecc.sector_per_page = strtol(param, NULL, 10);
				return EXIT_SUCCESS;
			case 2:
				pmecc.spare_size = strtol(param, NULL, 10);
				return EXIT_SUCCESS;
			case 3:
				pmecc.ecc_bits = strtol(param, NULL, 10);
				return EXIT_SUCCESS;
			case 4:
				pmecc.sector_size = strtol(param, NULL, 10);
				return EXIT_SUCCESS;
			case 5:
				pmecc.ecc_offset = strtol(param, NULL, 10);
				return EXIT_SUCCESS;
			}
		}
	}

err:
	pr_err("Could not find parameter in token '%s'\n", token);
	return EXIT_FAILURE;
}

static int atmel_parse_pmecc_params(char *txt)
{
	char *token;

	token = strtok(txt, ",");
	while (token != NULL) {
		if (atmel_find_pmecc_parameter_in_token(token))
			return EXIT_FAILURE;

		token = strtok(NULL, ",");
	}

	return EXIT_SUCCESS;
}

static int atmel_verify_header(unsigned char *ptr, int image_size,
			struct image_tool_params *params)
{
	uint32_t *ints = (uint32_t *)ptr;
	size_t pos;
	size_t size = image_size;

	/* check if we have an PMECC header attached */
	for (pos = 0; pos < ARRAY_SIZE(nand_pmecc_header); pos++)
		if (ints[pos] >> 28 != 0xC)
			break;

	if (pos == ARRAY_SIZE(nand_pmecc_header)) {
		ints += ARRAY_SIZE(nand_pmecc_header);
		size -= sizeof(nand_pmecc_header);
	}

	/* check the seven interrupt vectors of binary */
	for (pos = 0; pos < 7; pos++) {
		debug("atmelimage: interrupt vector #%zu is 0x%08X\n", pos+1,
		      ints[pos]);
		/*
		 * all vectors except the 6'th one must contain valid
		 * LDR or B Opcode
		 */
		if (pos == 5)
			/* 6'th vector has image size set, check later */
			continue;
		if ((ints[pos] & 0xff000000) == 0xea000000)
			/* valid B Opcode */
			continue;
		if ((ints[pos] & 0xfffff000) == 0xe59ff000)
			/* valid LDR (I=0, P=1, U=1, B=0, W=0, L=1) */
			continue;
		/* ouch, one of the checks has missed ... */
		return 1;
	}

	return ints[5] != cpu_to_le32(size);
}

static void atmel_print_pmecc_header(const uint32_t word)
{
	int val;

	printf("\t\tPMECC header\n");

	printf("\t\t====================\n");

	val = (word >> 18) & 0x1ff;
	printf("\t\teccOffset: %9i\n", val);

	val = (((word >> 16) & 0x3) == 0) ? 512 : 1024;
	printf("\t\tsectorSize: %8i\n", val);

	if (((word >> 13) & 0x7) <= 2)
		val = (2 << ((word >> 13) & 0x7));
	else
		val = (12 << (((word >> 13) & 0x7) - 3));
	printf("\t\teccBitReq: %9i\n", val);

	val = (word >> 4) & 0x1ff;
	printf("\t\tspareSize: %9i\n", val);

	val = (1 << ((word >> 1) & 0x3));
	printf("\t\tnbSectorPerPage: %3i\n", val);

	printf("\t\tusePmecc: %10i\n", word & 0x1);
	printf("\t\t====================\n");
}

static void atmel_print_header(const void *ptr)
{
	uint32_t *ints = (uint32_t *)ptr;
	size_t pos;

	/* check if we have an PMECC header attached */
	for (pos = 0; pos < ARRAY_SIZE(nand_pmecc_header); pos++)
		if (ints[pos] >> 28 != 0xC)
			break;

	if (pos == ARRAY_SIZE(nand_pmecc_header)) {
		printf("Image Type:\tATMEL ROM-Boot Image with PMECC Header\n");
		atmel_print_pmecc_header(ints[0]);
		pos += 5;
	} else {
		printf("Image Type:\tATMEL ROM-Boot Image without PMECC Header\n");
		pos = 5;
	}
	printf("\t\t6'th vector has %u set\n", le32_to_cpu(ints[pos]));
}

static void atmel_set_header(void *ptr, struct stat *sbuf, int ifd,
				struct image_tool_params *params)
{
	/* just save the image size into 6'th interrupt vector */
	uint32_t *ints = (uint32_t *)ptr;
	size_t cnt;
	size_t pos = 5;
	size_t size = sbuf->st_size;

	for (cnt = 0; cnt < ARRAY_SIZE(nand_pmecc_header); cnt++)
		if (ints[cnt] >> 28 != 0xC)
			break;

	if (cnt == ARRAY_SIZE(nand_pmecc_header)) {
		pos += ARRAY_SIZE(nand_pmecc_header);
		size -= sizeof(nand_pmecc_header);
	}

	ints[pos] = cpu_to_le32(size);
}

static int atmel_check_params(struct image_tool_params *params)
{
	if (strlen(params->imagename) > 0)
		if (atmel_parse_pmecc_params(params->imagename))
			return EXIT_FAILURE;

	return !(!params->eflag &&
		!params->fflag &&
		!params->xflag &&
		((params->dflag && !params->lflag) ||
		 (params->lflag && !params->dflag)));
}

static int atmel_vrec_header(struct image_tool_params *params,
				struct image_type_params *tparams)
{
	uint32_t tmp;
	size_t pos;

	if (strlen(params->imagename) == 0)
		return EXIT_SUCCESS;

	tmp = 0xC << 28;

	tmp |= (pmecc.ecc_offset & 0x1ff) << 18;

	switch (pmecc.sector_size) {
	case 512:
		tmp |= 0 << 16;
		break;
	case 1024:
		tmp |= 1 << 16;
		break;

	default:
		pr_err("Wrong sectorSize (%i) for PMECC header\n",
		       pmecc.sector_size);
		return EXIT_FAILURE;
	}

	switch (pmecc.ecc_bits) {
	case 2:
		tmp |= 0 << 13;
		break;
	case 4:
		tmp |= 1 << 13;
		break;
	case 8:
		tmp |= 2 << 13;
		break;
	case 12:
		tmp |= 3 << 13;
		break;
	case 24:
		tmp |= 4 << 13;
		break;

	default:
		pr_err("Wrong eccBits (%i) for PMECC header\n",
		       pmecc.ecc_bits);
		 return EXIT_FAILURE;
	}

	tmp |= (pmecc.spare_size & 0x1ff) << 4;

	switch (pmecc.sector_per_page) {
	case 1:
		tmp |= 0 << 1;
		break;
	case 2:
		tmp |= 1 << 1;
		break;
	case 4:
		tmp |= 2 << 1;
		break;
	case 8:
		tmp |= 3 << 1;
		break;

	default:
		pr_err("Wrong sectorPerPage (%i) for PMECC header\n",
		       pmecc.sector_per_page);
		return EXIT_FAILURE;
	}

	if (pmecc.use_pmecc)
		tmp |= 1;

	for (pos = 0; pos < ARRAY_SIZE(nand_pmecc_header); pos++)
		nand_pmecc_header[pos] = tmp;

	debug("PMECC header filled 52 times with 0x%08X\n", tmp);

	tparams->header_size = sizeof(nand_pmecc_header);
	tparams->hdr = nand_pmecc_header;

	return EXIT_SUCCESS;
}

U_BOOT_IMAGE_TYPE(
	atmelimage,
	"ATMEL ROM-Boot Image support",
	0,
	NULL,
	atmel_check_params,
	atmel_verify_header,
	atmel_print_header,
	atmel_set_header,
	NULL,
	atmel_check_image_type,
	NULL,
	atmel_vrec_header
);
