/*
 * Copyright 2012 Freescale Semiconductor, Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#define _GNU_SOURCE

#include "mkimage.h"
#include <image.h>
#include "pblimage.h"

/*
 * The PBL can load up to 64 bytes at a time, so we split the U-Boot
 * image into 64 byte chunks. PBL needs a command for each piece, of
 * the form "81xxxxxx", where "xxxxxx" is the offset. SYS_TEXT_BASE
 * is 0xFFF80000 for PBL boot, and PBL only cares about low 24-bit,
 * so it starts from 0x81F80000.
 */
static uint32_t next_pbl_cmd = 0x81F80000;
/*
 * need to store all bytes in memory for calculating crc32, then write the
 * bytes to image file for PBL boot.
 */
static unsigned char mem_buf[600000];
static unsigned char *pmem_buf = mem_buf;
static int pbl_size;
static char *fname = "Unknown";
static int lineno = -1;
static struct pbl_header pblimage_header;

static union
{
	char c[4];
	unsigned char l;
} endian_test = { {'l', '?', '?', 'b'} };

#define ENDIANNESS ((char)endian_test.l)

static void generate_pbl_cmd(void)
{
	uint32_t val = next_pbl_cmd;
	next_pbl_cmd += 0x40;
	int i;

	for (i = 3; i >= 0; i--) {
		*pmem_buf++ = (val >> (i * 8)) & 0xff;
		pbl_size++;
	}
}

static void pbl_fget(size_t size, FILE *stream)
{
	unsigned char c;
	int c_temp;

	while (size && (c_temp = fgetc(stream)) != EOF) {
		c = (unsigned char)c_temp;
		*pmem_buf++ = c;
		pbl_size++;
		size--;
	}
}

/* load split u-boot with PBI command 81xxxxxx. */
static void load_uboot(FILE *fp_uboot)
{
	while (next_pbl_cmd < 0x82000000) {
		generate_pbl_cmd();
		pbl_fget(64, fp_uboot);
	}
}

static void check_get_hexval(char *token)
{
	uint32_t hexval;
	int i;

	if (!sscanf(token, "%x", &hexval)) {
		printf("Error:%s[%d] - Invalid hex data(%s)\n", fname,
			lineno, token);
		exit(EXIT_FAILURE);
	}
	for (i = 3; i >= 0; i--) {
		*pmem_buf++ = (hexval >> (i * 8)) & 0xff;
		pbl_size++;
	}
}

static void pbl_parser(char *name)
{
	FILE *fd = NULL;
	char *line = NULL;
	char *token, *saveptr1, *saveptr2;
	size_t len = 0;

	fname = name;
	fd = fopen(name, "r");
	if (fd == NULL) {
		printf("Error:%s - Can't open\n", fname);
		exit(EXIT_FAILURE);
	}

	while ((getline(&line, &len, fd)) > 0) {
		lineno++;
		token = strtok_r(line, "\r\n", &saveptr1);
		/* drop all lines with zero tokens (= empty lines) */
		if (token == NULL)
			continue;
		for (line = token;; line = NULL) {
			token = strtok_r(line, " \t", &saveptr2);
			if (token == NULL)
				break;
			/* Drop all text starting with '#' as comments */
			if (token[0] == '#')
				break;
			check_get_hexval(token);
		}
	}
	if (line)
		free(line);
	fclose(fd);
}

static uint32_t crc_table[256];

static void make_crc_table(void)
{
	uint32_t mask;
	int i, j;
	uint32_t poly; /* polynomial exclusive-or pattern */

	/*
	 * the polynomial used by PBL is 1 + x1 + x2 + x4 + x5 + x7 + x8 + x10
	 * + x11 + x12 + x16 + x22 + x23 + x26 + x32.
	 */
	poly = 0x04c11db7;

	for (i = 0; i < 256; i++) {
		mask = i << 24;
		for (j = 0; j < 8; j++) {
			if (mask & 0x80000000)
				mask = (mask << 1) ^ poly;
			else
				mask <<= 1;
		}
		crc_table[i] = mask;
	}
}

unsigned long pbl_crc32(unsigned long crc, const char *buf, uint32_t len)
{
	uint32_t crc32_val = 0xffffffff;
	uint32_t xor = 0x0;
	int i;

	make_crc_table();

	for (i = 0; i < len; i++)
		crc32_val = (crc32_val << 8) ^
			crc_table[(crc32_val >> 24) ^ (*buf++ & 0xff)];

	crc32_val = crc32_val ^ xor;
	if (crc32_val < 0) {
		crc32_val += 0xffffffff;
		crc32_val += 1;
	}
	return crc32_val;
}

static uint32_t reverse_byte(uint32_t val)
{
	uint32_t temp;
	unsigned char *p1;
	int j;

	temp = val;
	p1 = (unsigned char *)&temp;
	for (j = 3; j >= 0; j--)
		*p1++ = (val >> (j * 8)) & 0xff;
	return temp;
}

/* write end command and crc command to memory. */
static void add_end_cmd(void)
{
	uint32_t pbl_end_cmd[4] = {0x09138000, 0x00000000,
		0x091380c0, 0x00000000};
	uint32_t crc32_pbl;
	int i;
	unsigned char *p = (unsigned char *)&pbl_end_cmd;

	if (ENDIANNESS == 'l') {
		for (i = 0; i < 4; i++)
			pbl_end_cmd[i] = reverse_byte(pbl_end_cmd[i]);
	}

	for (i = 0; i < 16; i++) {
		*pmem_buf++ = *p++;
		pbl_size++;
	}

	/* Add PBI CRC command. */
	*pmem_buf++ = 0x08;
	*pmem_buf++ = 0x13;
	*pmem_buf++ = 0x80;
	*pmem_buf++ = 0x40;
	pbl_size += 4;

	/* calculated CRC32 and write it to memory. */
	crc32_pbl = pbl_crc32(0, (const char *)mem_buf, pbl_size);
	*pmem_buf++ = (crc32_pbl >> 24) & 0xff;
	*pmem_buf++ = (crc32_pbl >> 16) & 0xff;
	*pmem_buf++ = (crc32_pbl >> 8) & 0xff;
	*pmem_buf++ = (crc32_pbl) & 0xff;
	pbl_size += 4;

	if ((pbl_size % 16) != 0) {
		for (i = 0; i < 8; i++) {
			*pmem_buf++ = 0x0;
			pbl_size++;
		}
	}
	if ((pbl_size % 16 != 0)) {
		printf("Error: Bad size of image file\n");
		exit(EXIT_FAILURE);
	}
}

void pbl_load_uboot(int ifd, struct mkimage_params *params)
{
	FILE *fp_uboot;
	int size;

	/* parse the rcw.cfg file. */
	pbl_parser(params->imagename);

	/* parse the pbi.cfg file. */
	pbl_parser(params->imagename2);

	fp_uboot = fopen(params->datafile, "r");
	if (fp_uboot == NULL) {
		printf("Error: %s open failed\n", params->datafile);
		exit(EXIT_FAILURE);
	}

	load_uboot(fp_uboot);
	add_end_cmd();
	fclose(fp_uboot);
	lseek(ifd, 0, SEEK_SET);

	size = pbl_size;
	if (write(ifd, (const void *)&mem_buf, size) != size) {
		fprintf(stderr, "Write error on %s: %s\n",
			params->imagefile, strerror(errno));
		exit(EXIT_FAILURE);
	}
}

static int pblimage_check_image_types(uint8_t type)
{
	if (type == IH_TYPE_PBLIMAGE)
		return EXIT_SUCCESS;
	else
		return EXIT_FAILURE;
}

static int pblimage_verify_header(unsigned char *ptr, int image_size,
			struct mkimage_params *params)
{
	struct pbl_header *pbl_hdr = (struct pbl_header *) ptr;

	/* Only a few checks can be done: search for magic numbers */
	if (ENDIANNESS == 'l') {
		if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE))
			return -FDT_ERR_BADSTRUCTURE;

		if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER))
			return -FDT_ERR_BADSTRUCTURE;
	} else {
		if (pbl_hdr->preamble != RCW_PREAMBLE)
			return -FDT_ERR_BADSTRUCTURE;

		if (pbl_hdr->rcwheader != RCW_HEADER)
			return -FDT_ERR_BADSTRUCTURE;
	}
	return 0;
}

static void pblimage_print_header(const void *ptr)
{
	printf("Image Type:   Freescale PBL Boot Image\n");
}

static void pblimage_set_header(void *ptr, struct stat *sbuf, int ifd,
				struct mkimage_params *params)
{
	/*nothing need to do, pbl_load_uboot takes care of whole file. */
}

/* pblimage parameters */
static struct image_type_params pblimage_params = {
	.name		= "Freescale PBL Boot Image support",
	.header_size	= sizeof(struct pbl_header),
	.hdr		= (void *)&pblimage_header,
	.check_image_type = pblimage_check_image_types,
	.verify_header	= pblimage_verify_header,
	.print_header	= pblimage_print_header,
	.set_header	= pblimage_set_header,
};

void init_pbl_image_type(void)
{
	pbl_size = 0;
	mkimage_register(&pblimage_params);
}
