/*
 * (C) Copyright 2001
 * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
 *
 * 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 <video_fb.h>
#include "common_util.h"
#include <asm/processor.h>
#include <asm/byteorder.h>
#include <i2c.h>
#include <devices.h>
#include <pci.h>
#include <malloc.h>
#include <bzlib.h>

#ifdef CONFIG_PIP405
#include "../pip405/pip405.h"
#include <405gp_pci.h>
#endif
#ifdef CONFIG_MIP405
#include "../mip405/mip405.h"
#include <405gp_pci.h>
#endif
#if defined(CONFIG_PATI)
#define FIRM_START 0xFFF00000
#endif

extern int gunzip(void *, int, uchar *, unsigned long *);
extern int mem_test(ulong start, ulong ramsize, int quiet);

#define I2C_BACKUP_ADDR 0x7C00		/* 0x200 bytes for backup */
#define IMAGE_SIZE CFG_MONITOR_LEN	/* ugly, but it works for now */

extern flash_info_t flash_info[];	/* info for FLASH chips */

static image_header_t header;


static int
mpl_prg(uchar *src, ulong size)
{
	ulong start;
	flash_info_t *info;
	int i, rc;
#if defined(CONFIG_PATI)
	int start_sect;
#endif
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
	char *copystr = (char *)src;
	ulong *magic = (ulong *)src;
#endif

	info = &flash_info[0];

#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
	if (ntohl(magic[0]) != IH_MAGIC) {
		puts("Bad Magic number\n");
		return -1;
	}
	/* some more checks before we delete the Flash... */
	/* Checking the ISO_STRING prevents to program a
	 * wrong Firmware Image into the flash.
	 */
	i = 4; /* skip Magic number */
	while (1) {
		if (strncmp(&copystr[i], "MEV-", 4) == 0)
			break;
		if (i++ >= 0x100) {
			puts("Firmware Image for unknown Target\n");
			return -1;
		}
	}
	/* we have the ISO STRING, check */
	if (strncmp(&copystr[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) {
		printf("Wrong Firmware Image: %s\n", &copystr[i]);
		return -1;
	}
#if !defined(CONFIG_PATI)
	start = 0 - size;
	for (i = info->sector_count-1; i > 0; i--) {
		info->protect[i] = 0; /* unprotect this sector */
		if (start >= info->start[i])
			break;
	}
	/* set-up flash location */
	/* now erase flash */
	printf("Erasing at %lx (sector %d) (start %lx)\n",
				start,i,info->start[i]);
	if ((rc = flash_erase (info, i, info->sector_count-1)) != 0) {
		puts("ERROR ");
		flash_perror(rc);
		return (1);
	}

#else /* #if !defined(CONFIG_PATI */
	start = FIRM_START;
	start_sect = -1;
	for (i = 0; i < info->sector_count; i++) {
		if (start < info->start[i]) {
			start_sect = i - 1;
			break;
		}
	}

	info->protect[i - 1] = 0;	/* unprotect this sector */
	for (; i < info->sector_count; i++) {
		if ((start + size) < info->start[i])
			break;
		info->protect[i] = 0;	/* unprotect this sector */
	}

	i--;
	/* set-up flash location */
	/* now erase flash */
	printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n",
		start, start + size, start_sect, i,
		info->start[start_sect], info->start[i]);
	if ((rc = flash_erase (info, start_sect, i)) != 0) {
		puts ("ERROR ");
		flash_perror (rc);
		return (1);
	}
#endif /* defined(CONFIG_PATI) */

#elif defined(CONFIG_VCMA9)
	start = 0;
	for (i = 0; i <info->sector_count; i++) {
		info->protect[i] = 0; /* unprotect this sector */
		if (size < info->start[i])
		    break;
	}
	/* set-up flash location */
	/* now erase flash */
	printf("Erasing at %lx (sector %d) (start %lx)\n",
				start,0,info->start[0]);
	if ((rc = flash_erase (info, 0, i)) != 0) {
		puts("ERROR ");
		flash_perror(rc);
		return (1);
	}

#endif
	printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",
		(ulong)src, size);
	if ((rc = flash_write (src, start, size)) != 0) {
		puts("ERROR ");
		flash_perror(rc);
		return (1);
	}
	puts("OK programming done\n");
	return 0;
}


static int
mpl_prg_image(uchar *ld_addr)
{
	unsigned long len, checksum;
	uchar *data;
	image_header_t *hdr = &header;
	int rc;

	/* Copy header so we can blank CRC field for re-calculation */
	memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
	if (ntohl(hdr->ih_magic)  != IH_MAGIC) {
		puts("Bad Magic Number\n");
		return 1;
	}
	print_image_hdr(hdr);
	if (hdr->ih_os  != IH_OS_U_BOOT) {
		puts("No U-Boot Image\n");
		return 1;
	}
	if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
		puts("No Firmware Image\n");
		return 1;
	}
	data = (uchar *)&header;
	len  = sizeof(image_header_t);
	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = 0;
	if (crc32 (0, (char *)data, len) != checksum) {
		puts("Bad Header Checksum\n");
		return 1;
	}
	data = ld_addr + sizeof(image_header_t);
	len  = ntohl(hdr->ih_size);
	puts("Verifying Checksum ... ");
	if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
		puts("Bad Data CRC\n");
		return 1;
	}
	puts("OK\n");

	if (hdr->ih_comp != IH_COMP_NONE) {
		uchar *buf;
		/* reserve space for uncompressed image */
		if ((buf = malloc(IMAGE_SIZE)) == NULL) {
		    	puts("Insufficient space for decompression\n");
			return 1;
		}

		switch (hdr->ih_comp) {
		case IH_COMP_GZIP:
			puts("Uncompressing (GZIP) ... ");
			rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
			if (rc != 0) {
				puts("GUNZIP ERROR\n");
				free(buf);
				return 1;
			}
			puts("OK\n");
			break;
#ifdef CONFIG_BZIP2
		case IH_COMP_BZIP2:
			puts("Uncompressing (BZIP2) ... ");
			{
			uint retlen = IMAGE_SIZE;
			rc = BZ2_bzBuffToBuffDecompress ((char *)(buf), &retlen,
				(char *)data, len, 0, 0);
			len = retlen;
			}
			if (rc != BZ_OK) {
				printf ("BUNZIP2 ERROR: %d\n", rc);
				free(buf);
				return 1;
			}
			puts("OK\n");
			break;
#endif
		default:
			printf ("Unimplemented compression type %d\n", hdr->ih_comp);
			free(buf);
			return 1;
		}

		rc = mpl_prg(buf, len);
		free(buf);
	} else {
		rc = mpl_prg(data, len);
	}

	return(rc);
}

#if !defined(CONFIG_PATI)
void get_backup_values(backup_t *buf)
{
	i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
}

void set_backup_values(int overwrite)
{
	backup_t back;
	int i;

	get_backup_values(&back);
	if(!overwrite) {
		if(strncmp(back.signature,"MPL\0",4)==0) {
			puts("Not possible to write Backup\n");
			return;
		}
	}
	memcpy(back.signature,"MPL\0",4);
	i = getenv_r("serial#",back.serial_name,16);
	if(i < 0) {
		puts("Not possible to write Backup\n");
		return;
	}
	back.serial_name[16]=0;
	i = getenv_r("ethaddr",back.eth_addr,20);
	if(i < 0) {
		puts("Not possible to write Backup\n");
		return;
	}
	back.eth_addr[20]=0;
	i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
}

void clear_env_values(void)
{
	backup_t back;
	unsigned char env_crc[4];

	memset(&back,0xff,sizeof(backup_t));
	memset(env_crc,0x00,4);
	i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
	i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
}

/*
 * check crc of "older" environment
 */
int check_env_old_size(ulong oldsize)
{
	ulong crc, len, new;
	unsigned off;
	uchar buf[64];

	/* read old CRC */
	eeprom_read (CFG_DEF_EEPROM_ADDR,
		     CFG_ENV_OFFSET,
		     (uchar *)&crc, sizeof(ulong));

	new = 0;
	len = oldsize;
	off = sizeof(long);
	len = oldsize-off;
	while (len > 0) {
		int n = (len > sizeof(buf)) ? sizeof(buf) : len;

		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
		new = crc32 (new, buf, n);
		len -= n;
		off += n;
	}

	return (crc == new);
}

static ulong oldsizes[] = {
	0x200,
	0x800,
	0
};

void copy_old_env(ulong size)
{
	uchar name_buf[64];
	uchar value_buf[0x800];
	uchar c;
	ulong len;
	unsigned off;
	uchar *name, *value;

	name=&name_buf[0];
	value=&value_buf[0];
	len=size;
	off = sizeof(long);
	while (len > off) {
		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
		if(c != '=') {
			*name++=c;
			off++;
		}
		else {
			*name++='\0';
			off++;
			do {
				eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
				*value++=c;
				off++;
				if(c == '\0')
					break;
			} while(len > off);
			name=&name_buf[0];
			value=&value_buf[0];
			if(strncmp(name,"baudrate",8)!=0) {
				setenv(name,value);
			}

		}
	}
}


void check_env(void)
{
	unsigned char *s;
	int i=0;
	char buf[32];
	backup_t back;

	s=getenv("serial#");
	if(!s) {
		while(oldsizes[i]) {
			if(check_env_old_size(oldsizes[i]))
				break;
			i++;
		}
		if(!oldsizes[i]) {
			/* no old environment has been found */
			get_backup_values (&back);
			if (strncmp (back.signature, "MPL\0", 4) == 0) {
				sprintf (buf, "%s", back.serial_name);
				setenv ("serial#", buf);
				sprintf (buf, "%s", back.eth_addr);
				setenv ("ethaddr", buf);
				printf ("INFO:  serial# and ethaddr recovered, use saveenv\n");
				return;
			}
		}
		else {
			copy_old_env(oldsizes[i]);
			puts("INFO:  old environment ajusted, use saveenv\n");
		}
	}
	else {
		/* check if back up is set */
		get_backup_values(&back);
		if(strncmp(back.signature,"MPL\0",4)!=0) {
			set_backup_values(0);
		}
	}
}


extern device_t *stdio_devices[];
extern char *stdio_names[];

void show_stdio_dev(void)
{
	/* Print information */
	puts("In:    ");
	if (stdio_devices[stdin] == NULL) {
		puts("No input devices available!\n");
	} else {
		printf ("%s\n", stdio_devices[stdin]->name);
	}

	puts("Out:   ");
	if (stdio_devices[stdout] == NULL) {
		puts("No output devices available!\n");
	} else {
		printf ("%s\n", stdio_devices[stdout]->name);
	}

	puts("Err:   ");
	if (stdio_devices[stderr] == NULL) {
		puts("No error devices available!\n");
	} else {
		printf ("%s\n", stdio_devices[stderr]->name);
	}
}

#endif /* #if !defined(CONFIG_PATI) */

int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
 	ulong size,src,ld_addr;
	int result;
#if !defined(CONFIG_PATI)
	backup_t back;
	src = MULTI_PURPOSE_SOCKET_ADDR;
	size = IMAGE_SIZE;
#endif

	if (strcmp(argv[1], "flash") == 0)
	{
#if (CONFIG_COMMANDS & CFG_CMD_FDC)
		if (strcmp(argv[2], "floppy") == 0) {
 			char *local_args[3];
			extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
			puts("\nupdating bootloader image from floppy\n");
			local_args[0] = argv[0];
	    		if(argc==4) {
				local_args[1] = argv[3];
				local_args[2] = NULL;
				ld_addr=simple_strtoul(argv[3], NULL, 16);
				result=do_fdcboot(cmdtp, 0, 2, local_args);
			}
			else {
				local_args[1] = NULL;
				ld_addr=CFG_LOAD_ADDR;
				result=do_fdcboot(cmdtp, 0, 1, local_args);
			}
			result=mpl_prg_image((uchar *)ld_addr);
			return result;
		}
#endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
		if (strcmp(argv[2], "mem") == 0) {
	    		if(argc==4) {
				ld_addr=simple_strtoul(argv[3], NULL, 16);
			}
			else {
				ld_addr=load_addr;
			}
			printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
			result=mpl_prg_image((uchar *)ld_addr);
			return result;
		}
#if !defined(CONFIG_PATI)
		if (strcmp(argv[2], "mps") == 0) {
			puts("\nupdating bootloader image from MPS\n");
			result=mpl_prg((uchar *)src,size);
			return result;
		}
#endif /* #if !defined(CONFIG_PATI)	*/
	}
	if (strcmp(argv[1], "mem") == 0)
	{
		result=0;
		if(argc==3)
		{
			result = (int)simple_strtol(argv[2], NULL, 16);
	    }
	    src=(unsigned long)&result;
	    src-=CFG_MEMTEST_START;
	    src-=(100*1024); /* - 100k */
	    src&=0xfff00000;
	    size=0;
	    do {
	    	size++;
			printf("\n\nPass %ld\n",size);
			mem_test(CFG_MEMTEST_START,src,1);
			if(ctrlc())
				break;
			if(result>0)
				result--;

		}while(result);
		return 0;
	}
#if !defined(CONFIG_PATI)
	if (strcmp(argv[1], "clearenvvalues") == 0)
	{
 		if (strcmp(argv[2], "yes") == 0)
		{
			clear_env_values();
			return 0;
		}
	}
	if (strcmp(argv[1], "getback") == 0) {
		get_backup_values(&back);
		back.signature[3]=0;
		back.serial_name[16]=0;
		back.eth_addr[20]=0;
		printf("GetBackUp: signature: %s\n",back.signature);
		printf("           serial#:   %s\n",back.serial_name);
		printf("           ethaddr:   %s\n",back.eth_addr);
		return 0;
	}
	if (strcmp(argv[1], "setback") == 0) {
		set_backup_values(1);
		return 0;
	}
#endif
	printf("Usage:\n%s\n", cmdtp->usage);
	return 1;
}


#if (CONFIG_COMMANDS & CFG_CMD_DOC)
extern void doc_probe(ulong physadr);
void doc_init (void)
{
  doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
}
#endif


#ifdef CONFIG_VIDEO
/******************************************************
 * Routines to display the Board information
 * to the screen (since the VGA will be initialized as last,
 * we must resend the infos)
 */

#ifdef CONFIG_CONSOLE_EXTRA_INFO
extern GraphicDevice ctfb;
extern int get_boot_mode(void);

void video_get_info_str (int line_number, char *info)
{
	/* init video info strings for graphic console */
	DECLARE_GLOBAL_DATA_PTR;
	PPC405_SYS_INFO sys_info;
	char rev;
	int i,boot;
	unsigned long pvr;
	char buf[64];
	char tmp[16];
	char cpustr[16];
	unsigned char *s, *e, bc;
	switch (line_number)
	{
	case 2:
		/* CPU and board infos */
		pvr=get_pvr();
		get_sys_info (&sys_info);
		switch (pvr) {
			case PVR_405GP_RB: rev='B'; break;
			case PVR_405GP_RC: rev='C'; break;
			case PVR_405GP_RD: rev='D'; break;
			case PVR_405GP_RE: rev='E'; break;
			case PVR_405GPR_RB: rev='B'; break;
			default:           rev='?'; break;
		}
		if(pvr==PVR_405GPR_RB)
			sprintf(cpustr,"PPC405GPr %c",rev);
		else
			sprintf(cpustr,"PPC405GP %c",rev);
		/* Board info */
		i=0;
		s=getenv ("serial#");
#ifdef CONFIG_PIP405
		if (!s || strncmp (s, "PIP405", 6)) {
			sprintf(buf,"### No HW ID - assuming PIP405");
		}
#endif
#ifdef CONFIG_MIP405
		if (!s || strncmp (s, "MIP405", 6)) {
			sprintf(buf,"### No HW ID - assuming MIP405");
		}
#endif
		else {
			for (e = s; *e; ++e) {
				if (*e == ' ')
					break;
			}
			for (; s < e; ++s) {
				if (*s == '_') {
					++s;
					break;
				}
				buf[i++]=*s;
			}
			sprintf(&buf[i]," SN ");
			i+=4;
			for (; s < e; ++s) {
				buf[i++]=*s;
			}
			buf[i++]=0;
		}
		sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
			buf, cpustr,
			strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
			sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
			sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
		return;
	case 3:
		/* Memory Info */
		boot = get_boot_mode();
		bc = in8 (CONFIG_PORT_ADDR);
		sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
			gd->bd->bi_memsize / 0x100000,
			gd->bd->bi_flashsize / 0x100000,
			bc,
			(boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
			ctfb.modeIdent);
		return;
	case 1:
		sprintf	(buf, "%s",CONFIG_IDENT_STRING);
		sprintf (info, " %s", &buf[1]);
		return;
    }
    /* no more info lines */
    *info = 0;
    return;
}
#endif /* CONFIG_CONSOLE_EXTRA_INFO */

#endif /* CONFIG_VIDEO */
