/*
 * (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 #%d 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;
}

static struct image_type_params atmelimage_params = {
	.name		= "ATMEL ROM-Boot Image support",
	.header_size	= 0,
	.hdr		= NULL,
	.check_image_type = atmel_check_image_type,
	.verify_header	= atmel_verify_header,
	.print_header	= atmel_print_header,
	.set_header	= atmel_set_header,
	.check_params	= atmel_check_params,
	.vrec_header	= atmel_vrec_header,
};

void init_atmel_image_type(void)
{
	register_image_type(&atmelimage_params);
}
