/*
 * (C) Copyright 2003-2004
 * Gary Jennejohn, DENX Software Engineering, gj@denx.de.
 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
 *
 * 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
 */

#include <common.h>

#include <command.h>
#include <image.h>
#include <asm/byteorder.h>
#if defined(CFG_NAND_LEGACY)
#include <linux/mtd/nand_legacy.h>
#endif
#include <fat.h>
#include <part.h>

#include "auto_update.h"

#ifdef CONFIG_AUTO_UPDATE

#if !defined(CONFIG_CMD_FAT)
#error "must define CONFIG_CMD_FAT"
#endif

extern au_image_t au_image[];
extern int N_AU_IMAGES;

#define AU_DEBUG
#undef AU_DEBUG

#undef debug
#ifdef	AU_DEBUG
#define debug(fmt,args...)	printf (fmt ,##args)
#else
#define debug(fmt,args...)
#endif	/* AU_DEBUG */


#define LOAD_ADDR ((unsigned char *)0x100000)   /* where to load files into memory */
#define MAX_LOADSZ 0x1e00000

/* externals */
extern int fat_register_device(block_dev_desc_t *, int);
extern int file_fat_detectfs(void);
extern long file_fat_read(const char *, void *, unsigned long);
long do_fat_read (const char *filename, void *buffer, unsigned long maxsize, int dols);
#ifdef CONFIG_VFD
extern int trab_vfd (ulong);
extern int transfer_pic(unsigned char, unsigned char *, int, int);
#endif
extern int flash_sect_erase(ulong, ulong);
extern int flash_sect_protect (int, ulong, ulong);
extern int flash_write (char *, ulong, ulong);

#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
/* references to names in cmd_nand.c */
#define NANDRW_READ	0x01
#define NANDRW_WRITE	0x00
#define NANDRW_JFFS2	0x02
#define NANDRW_JFFS2_SKIP	0x04
extern struct nand_chip nand_dev_desc[];
extern int nand_legacy_rw(struct nand_chip* nand, int cmd, size_t start, size_t len,
		   size_t * retlen, u_char * buf);
extern int nand_legacy_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);
#endif

extern block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];


int au_check_cksum_valid(int i, long nbytes)
{
	image_header_t *hdr;

	hdr = (image_header_t *)LOAD_ADDR;

	if ((au_image[i].type == AU_FIRMWARE) &&
	    (au_image[i].size != image_get_data_size (hdr))) {
		printf ("Image %s has wrong size\n", au_image[i].name);
		return -1;
	}

	if (nbytes != (image_get_image_size (hdr))) {
		printf ("Image %s bad total SIZE\n", au_image[i].name);
		return -1;
	}

	/* check the data CRC */
	if (!image_check_dcrc (hdr)) {
		printf ("Image %s bad data checksum\n", au_image[i].name);
		return -1;
	}
	return 0;
}


int au_check_header_valid(int i, long nbytes)
{
	image_header_t *hdr;
	unsigned long checksum;

	hdr = (image_header_t *)LOAD_ADDR;
	/* check the easy ones first */
#undef CHECK_VALID_DEBUG
#ifdef CHECK_VALID_DEBUG
	printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
	printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_PPC);
	printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
	printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
#endif
	if (nbytes < image_get_header_size ())
	{
		printf ("Image %s bad header SIZE\n", au_image[i].name);
		return -1;
	}
	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC))
	{
		printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name);
		return -1;
	}
	if (!image_check_hcrc (hdr)) {
		printf ("Image %s bad header checksum\n", au_image[i].name);
		return -1;
	}

	/* check the type - could do this all in one gigantic if() */
	if ((au_image[i].type == AU_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
		printf ("Image %s wrong type\n", au_image[i].name);
		return -1;
	}
	if ((au_image[i].type == AU_SCRIPT) && !image_check_type (hdr, IH_TYPE_SCRIPT)) {
		printf ("Image %s wrong type\n", au_image[i].name);
		return -1;
	}

	/* recycle checksum */
	checksum = image_get_data_size (hdr);

#if 0 /* test-only */
	/* for kernel and app the image header must also fit into flash */
	if (idx != IDX_DISK)
		checksum += image_get_header_size ();
	/* check the size does not exceed space in flash. HUSH scripts */
	/* all have ausize[] set to 0 */
	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
		printf ("Image %s is bigger than FLASH\n", au_image[i].name);
		return -1;
	}
#endif

	return 0;
}


int au_do_update(int i, long sz)
{
	image_header_t *hdr;
	char *addr;
	long start, end;
	int off, rc;
	uint nbytes;
	int k;
#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
	int total;
#endif

	hdr = (image_header_t *)LOAD_ADDR;

	switch (au_image[i].type) {
	case AU_SCRIPT:
		printf("Executing script %s\n", au_image[i].name);

		/* execute a script */
		if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
			addr = (char *)((char *)hdr + image_get_header_size ());
			/* stick a NULL at the end of the script, otherwise */
			/* parse_string_outer() runs off the end. */
			addr[image_get_data_size (hdr)] = 0;
			addr += 8;

			/*
			 * Replace cr/lf with ;
			 */
			k = 0;
			while (addr[k] != 0) {
				if ((addr[k] == 10) || (addr[k] == 13)) {
					addr[k] = ';';
				}
				k++;
			}

			run_command(addr, 0);
			return 0;
		}

		break;

	case AU_FIRMWARE:
	case AU_NOR:
	case AU_NAND:
		start = au_image[i].start;
		end = au_image[i].start + au_image[i].size - 1;

		/*
		 * do not update firmware when image is already in flash.
		 */
		if (au_image[i].type == AU_FIRMWARE) {
			char *orig = (char*)start;
			char *new  = (char *)((char *)hdr + image_get_header_size ());
			nbytes = image_get_data_size (hdr);

			while(--nbytes) {
				if (*orig++ != *new++) {
					break;
				}
			}
			if (!nbytes) {
				printf("Skipping firmware update - images are identical\n");
				break;
			}
		}

		/* unprotect the address range */
		/* this assumes that ONLY the firmware is protected! */
		if (au_image[i].type == AU_FIRMWARE) {
			flash_sect_protect(0, start, end);
		}

		/*
		 * erase the address range.
		 */
		if (au_image[i].type != AU_NAND) {
			printf("Updating NOR FLASH with image %s\n", au_image[i].name);
			debug ("flash_sect_erase(%lx, %lx);\n", start, end);
			flash_sect_erase(start, end);
		} else {
#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
			printf("Updating NAND FLASH with image %s\n", au_image[i].name);
			debug ("nand_legacy_erase(%lx, %lx);\n", start, end);
			rc = nand_legacy_erase (nand_dev_desc, start, end - start + 1, 0);
			debug ("nand_legacy_erase returned %x\n", rc);
#endif
		}

		udelay(10000);

		/* strip the header - except for the kernel and ramdisk */
		if (au_image[i].type != AU_FIRMWARE) {
			addr = (char *)hdr;
			off = image_get_header_size ();
			nbytes = image_get_image_size (hdr);
		} else {
			addr = (char *)((char *)hdr + image_get_header_size ());
			off = 0;
			nbytes = image_get_data_size (hdr);
		}

		/*
		 * copy the data from RAM to FLASH
		 */
		if (au_image[i].type != AU_NAND) {
			debug ("flash_write(%p, %lx %x)\n", addr, start, nbytes);
			rc = flash_write((char *)addr, start, nbytes);
		} else {
#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
			debug ("nand_legacy_rw(%p, %lx %x)\n", addr, start, nbytes);
			rc = nand_legacy_rw(nand_dev_desc, NANDRW_WRITE | NANDRW_JFFS2,
				     start, nbytes, (size_t *)&total, (uchar *)addr);
			debug ("nand_legacy_rw: ret=%x total=%d nbytes=%d\n", rc, total, nbytes);
#else
			rc = -1;
#endif
		}
		if (rc != 0) {
			printf("Flashing failed due to error %d\n", rc);
			return -1;
		}

		/*
		 * check the dcrc of the copy
		 */
		if (au_image[i].type != AU_NAND) {
			rc = crc32 (0, (uchar *)(start + off), image_get_data_size (hdr));
		} else {
#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
			rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP,
				     start, nbytes, (size_t *)&total, (uchar *)addr);
			rc = crc32 (0, (uchar *)(addr + off), image_get_data_size (hdr));
#endif
		}
		if (rc != image_get_dcrc (hdr)) {
			printf ("Image %s Bad Data Checksum After COPY\n", au_image[i].name);
			return -1;
		}

		/* protect the address range */
		/* this assumes that ONLY the firmware is protected! */
		if (au_image[i].type == AU_FIRMWARE) {
			flash_sect_protect(1, start, end);
		}

		break;

	default:
		printf("Wrong image type selected!\n");
	}

	return 0;
}


static void process_macros (const char *input, char *output)
{
	char c, prev;
	const char *varname_start = NULL;
	int inputcnt  = strlen (input);
	int outputcnt = CFG_CBSIZE;
	int state = 0;	/* 0 = waiting for '$'	*/
			/* 1 = waiting for '(' or '{' */
			/* 2 = waiting for ')' or '}' */
			/* 3 = waiting for '''  */
#ifdef DEBUG_PARSER
	char *output_start = output;

	printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen(input), input);
#endif

	prev = '\0';			/* previous character	*/

	while (inputcnt && outputcnt) {
	    c = *input++;
	    inputcnt--;

	    if (state!=3) {
	    /* remove one level of escape characters */
	    if ((c == '\\') && (prev != '\\')) {
		if (inputcnt-- == 0)
			break;
		prev = c;
		c = *input++;
	    }
	    }

	    switch (state) {
	    case 0:			/* Waiting for (unescaped) $	*/
		if ((c == '\'') && (prev != '\\')) {
			state = 3;
			break;
		}
		if ((c == '$') && (prev != '\\')) {
			state++;
		} else {
			*(output++) = c;
			outputcnt--;
		}
		break;
	    case 1:			/* Waiting for (	*/
		if (c == '(' || c == '{') {
			state++;
			varname_start = input;
		} else {
			state = 0;
			*(output++) = '$';
			outputcnt--;

			if (outputcnt) {
				*(output++) = c;
				outputcnt--;
			}
		}
		break;
	    case 2:			/* Waiting for )	*/
		if (c == ')' || c == '}') {
			int i;
			char envname[CFG_CBSIZE], *envval;
			int envcnt = input-varname_start-1; /* Varname # of chars */

			/* Get the varname */
			for (i = 0; i < envcnt; i++) {
				envname[i] = varname_start[i];
			}
			envname[i] = 0;

			/* Get its value */
			envval = getenv (envname);

			/* Copy into the line if it exists */
			if (envval != NULL)
				while ((*envval) && outputcnt) {
					*(output++) = *(envval++);
					outputcnt--;
				}
			/* Look for another '$' */
			state = 0;
		}
		break;
	    case 3:			/* Waiting for '	*/
		if ((c == '\'') && (prev != '\\')) {
			state = 0;
		} else {
			*(output++) = c;
			outputcnt--;
		}
		break;
	    }
	    prev = c;
	}

	if (outputcnt)
		*output = 0;

#ifdef DEBUG_PARSER
	printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
		strlen(output_start), output_start);
#endif
}


/*
 * this is called from board_init() after the hardware has been set up
 * and is usable. That seems like a good time to do this.
 * Right now the return value is ignored.
 */
int do_auto_update(void)
{
	block_dev_desc_t *stor_dev;
	long sz;
	int i, res, cnt, old_ctrlc, got_ctrlc;
	char buffer[32];
	char str[80];

	/*
	 * Check whether a CompactFlash is inserted
	 */
	if (ide_dev_desc[0].type == DEV_TYPE_UNKNOWN) {
		return -1;       /* no disk detected! */
	}

	/* check whether it has a partition table */
	stor_dev = get_dev("ide", 0);
	if (stor_dev == NULL) {
		debug ("Uknown device type\n");
		return -1;
	}
	if (fat_register_device(stor_dev, 1) != 0) {
		debug ("Unable to register ide disk 0:1 for fatls\n");
		return -1;
	}

	/*
	 * Check if magic file is present
	 */
	if (do_fat_read(AU_MAGIC_FILE, buffer, sizeof(buffer), LS_NO) <= 0) {
		return -1;
	}

#ifdef CONFIG_AUTO_UPDATE_SHOW
	board_auto_update_show(1);
#endif
	puts("\nAutoUpdate Disk detected! Trying to update system...\n");

	/* make sure that we see CTRL-C and save the old state */
	old_ctrlc = disable_ctrlc(0);

	/* just loop thru all the possible files */
	for (i = 0; i < N_AU_IMAGES; i++) {
		/*
		 * Try to expand the environment var in the fname
		 */
		process_macros(au_image[i].name, str);
		strcpy(au_image[i].name, str);

		printf("Reading %s ...", au_image[i].name);
		/* just read the header */
		sz = do_fat_read(au_image[i].name, LOAD_ADDR, image_get_header_size (), LS_NO);
		debug ("read %s sz %ld hdr %d\n",
			au_image[i].name, sz, image_get_header_size ());
		if (sz <= 0 || sz < image_get_header_size ()) {
			puts(" not found\n");
			continue;
		}
		if (au_check_header_valid(i, sz) < 0) {
			puts(" header not valid\n");
			continue;
		}
		sz = do_fat_read(au_image[i].name, LOAD_ADDR, MAX_LOADSZ, LS_NO);
		debug ("read %s sz %ld hdr %d\n",
			au_image[i].name, sz, image_get_header_size ());
		if (sz <= 0 || sz <= image_get_header_size ()) {
			puts(" not found\n");
			continue;
		}
		if (au_check_cksum_valid(i, sz) < 0) {
			puts(" checksum not valid\n");
			continue;
		}
		puts(" done\n");

		do {
			res = au_do_update(i, sz);
			/* let the user break out of the loop */
			if (ctrlc() || had_ctrlc()) {
				clear_ctrlc();
				if (res < 0)
					got_ctrlc = 1;
				break;
			}
			cnt++;
		} while (res < 0);
	}

	/* restore the old state */
	disable_ctrlc(old_ctrlc);

	puts("AutoUpdate finished\n\n");
#ifdef CONFIG_AUTO_UPDATE_SHOW
	board_auto_update_show(0);
#endif

	return 0;
}


int auto_update(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	do_auto_update();

	return 0;
}
U_BOOT_CMD(
	autoupd,	1,	1,	auto_update,
	"autoupd - Automatically update images\n",
	NULL
);
#endif /* CONFIG_AUTO_UPDATE */
