/*
 * (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 <asm/4xx_pci.h>
#endif
#ifdef CONFIG_MIP405
#include "../mip405/mip405.h"
#include <asm/4xx_pci.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

#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 ((char *)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, (uchar *)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, (uchar *)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((char *)name,"baudrate",8)!=0) {
				setenv((char *)name,(char *)value);
			}

		}
	}
}


void check_env(void)
{
	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 defined(CONFIG_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
		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 defined(CONFIG_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 */
	PPC4xx_SYS_INFO sys_info;
	char rev;
	int i,boot;
	unsigned long pvr;
	char buf[64];
	char tmp[16];
	char cpustr[16];
	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 */
