/*
 * flash_rom.c: Flash programming utility for SiS 630/950 M/Bs
 *
 *
 * Copyright 2000 Silicon Integrated System Corporation
 *
 *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 * Reference:
 *	1. SiS 630 Specification
 *	2. SiS 950 Specification
 *
 * $Id$
 */

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "flash.h"
#include "jedec.h"
#include "m29f400bt.h"
#include "82802ab.h"
#include "msys_doc.h"
#include "am29f040b.h"
#include "sst28sf040.h"
#include "w49f002u.h"
#include "sst39sf020.h"
#include "sst49lf040.h"
#include "pm49fl004.h"
#include "mx29f002.h"

struct flashchip flashchips[] = {
	{"Am29F040B",   AMD_ID,     AM_29F040B,   NULL, 512, 64*1024,
	 probe_29f040b, erase_29f040b, write_29f040b, NULL},
	{"At29C040A",   ATMEL_ID,   AT_29C040A,   NULL, 512, 256,
	 probe_jedec,   erase_jedec,   write_jedec, NULL},
	{"Mx29f002",    MX_ID,      MX_29F002,    NULL, 256, 64*1024,
	 probe_29f002,  erase_29f002,  write_29f002, NULL},
	{"SST29EE020A", SST_ID,     SST_29EE020A, NULL, 256, 128,
	 probe_jedec,   erase_jedec,   write_jedec, NULL},
	{"SST28SF040A", SST_ID,     SST_28SF040,  NULL, 512, 256,
	 probe_28sf040, erase_28sf040, write_28sf040, NULL},
	{"SST39SF020A", SST_ID,     SST_39SF020,  NULL, 256, 4096,
	 probe_39sf020, erase_39sf020, write_39sf020, NULL},
	{"SST39VF020",  SST_ID,     SST_39VF020,  NULL, 256, 4096,
	 probe_39sf020, erase_39sf020, write_39sf020, NULL},
	{"SST49LF040",  SST_ID,     SST_49LF040,  NULL, 512, 4096,
	 probe_49lf040, erase_49lf040, write_49lf040, NULL},
	{"SST49LF080A", SST_ID,     SST_49LF080A,  NULL, 1024, 4096,
	 probe_49lf040, erase_49lf040, write_49lf040, NULL},
	{"SST49LF002A", SST_ID,     SST_49LF002A,  NULL, 256, 4096,
	 probe_49lf040, erase_49lf040, write_49lf040, NULL},
	{"SST49LF003A", SST_ID,     SST_49LF003A,  NULL, 384, 4096,
	 probe_49lf040, erase_49lf040, write_49lf040, NULL},
	{"SST49LF004A", SST_ID,     SST_49LF004A,  NULL, 512, 4096,
	 probe_49lf040, erase_49lf040, write_49lf040, NULL},
	{"SST49LF008A", SST_ID,     SST_49LF008A,  NULL, 1024, 4096,
	 probe_49lf040, erase_49lf040, write_49lf040, NULL},
	
	//By LYH begin
	{"Pm49FL004",   PMC_ID,     PMC_49FL004,  NULL, 512, 64*1024,
	 probe_49fl004, erase_49fl004, write_49fl004, NULL},
	//END
	{"W29C011",     WINBOND_ID, W_29C011,    NULL, 128, 128,
	 probe_jedec,   erase_jedec,   write_jedec, NULL},
	{"W29C020C",    WINBOND_ID, W_29C020C,    NULL, 256, 128,
	 probe_jedec,   erase_jedec,   write_jedec, NULL},
	{"W49F002U",    WINBOND_ID, W_49F002U,    NULL, 256, 128,
	 probe_49f002,  erase_49f002,   write_49f002, NULL},
	{"M29F400BT",   ST_ID, ST_M29F400BT ,    NULL, 512, 64*1024,
	 probe_m29f400bt,   erase_m29f400bt,   write_linuxbios_m29f400bt, NULL},
	{"82802ab",     137,   173 ,    NULL, 512, 64*1024,
	 probe_82802ab, erase_82802ab,   write_82802ab, NULL},
	{"82802ac",     137,   172 ,    NULL, 1024, 64*1024,
	 probe_82802ab, erase_82802ab,   write_82802ab, NULL},
	{"MD-2802 (M-Systems DiskOnChip Millennium Module)",
	 MSYSTEMS_ID, MSYSTEMS_MD2802,
	 NULL, 8, 8*1024,
	 probe_md2802, erase_md2802, write_md2802, read_md2802},
	{NULL,}
};

char *chip_to_probe = NULL;

struct flashchip * probe_flash(struct flashchip * flash)
{
	int fd_mem;
	volatile char * bios;
	unsigned long size;

	if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
		perror("Can not open /dev/mem");
		exit(1);
	}

	while (flash->name != NULL) {
		if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0) {
			flash++;
			continue;
		}
		printf("Trying %s, %d KB\n", flash->name, flash->total_size);
		size = flash->total_size * 1024;
		/* BUG? what happens if getpagesize() > size!?
		   -> ``Error MMAP /dev/mem: Invalid argument'' NIKI */
		if (getpagesize() > size) {
			size = getpagesize();
			printf("%s: warning: size: %d -> %ld\n", __FUNCTION__,
			       flash->total_size * 1024, (unsigned long)size);
		}
		bios = mmap (0, size, PROT_WRITE | PROT_READ, MAP_SHARED,
			     fd_mem, (off_t) (0xffffffff - size + 1));
		if (bios == MAP_FAILED) {
			perror("Error MMAP /dev/mem");
			exit(1);
		}
		flash->virt_addr = bios;
		flash->fd_mem = fd_mem;

		if (flash->probe(flash) == 1) {
			printf ("%s found at physical address: 0x%lx\n",
				flash->name, (0xffffffff - size + 1));
			return flash;
		}
		munmap ((void *) bios, size);
		flash++;
	}
	return NULL;
}

int verify_flash (struct flashchip * flash, char * buf, int verbose)
{
	int i = 0;
	int total_size = flash->total_size *1024;
	volatile char * bios = flash->virt_addr;

	printf("Verifying address: ");
	while (i < total_size) {
		if (verbose) 
			printf("0x%08x", i);
		if (*(bios+i) != *(buf+i)) {
			printf("FAILED\n");
			return 0;
		}
		if (verbose) 
			printf("\b\b\b\b\b\b\b\b\b\b");
		i++;
	}
	if (verbose)
		printf("\n");
	else
		printf("VERIFIED\n");
	return 1;
}


void usage(const char *name)
{
	printf("usage: %s [-rwv] [-c chipname][file]\n", name);
	printf("-r: read flash and save into file\n"
	       "-w: write file into flash (default when file is specified)\n"
	       "-v: verify flash against file\n"
	       "-c: probe only for specified flash chip\n"
	       " If no file is specified, then all that happens\n"
	       " is that flash info is dumped\n");
	exit(1);
}

int main (int argc, char * argv[])
{
	char * buf;
	unsigned long size;
	FILE * image;
	struct flashchip * flash;
	int opt;
	int read_it = 0, write_it = 0, verify_it = 0, verbose = 0;
	char *filename = NULL;

	setbuf(stdout, NULL);

	while ((opt = getopt(argc, argv, "rwvVc:")) != EOF) {
		switch (opt) {
		case 'r':
			read_it = 1;
			break;
		case 'w':
			write_it = 1;
			break;
		case 'v':
			verify_it = 1;
			break;
		case 'c':
			chip_to_probe = strdup(optarg);
			break;
		case 'V':
			verbose = 1;
			break;
		default:
			usage(argv[0]);
			break;
		}
	}
	if (read_it && write_it) {
		printf("-r and -w are mutually exclusive\n");
		usage(argv[0]);
	}

	if (optind < argc)
		filename = argv[optind++];

	printf("Calibrating timer since microsleep sucks ... takes a second\n");
	myusec_calibrate_delay();
	printf("OK, calibrated, now do the deed\n");

	/* try to enable it. Failure IS an option, since not all motherboards
	 * really need this to be done, etc., etc. It sucks.
	 */
	(void) enable_flash_write();
    
	if ((flash = probe_flash (flashchips)) == NULL) {
		printf("EEPROM not found\n");
		exit(1);
	}

	printf("Part is %s\n", flash->name);
	if (!filename){
		printf("OK, only ENABLING flash write, but NOT FLASHING\n");
		return 0;
	}
	size = flash->total_size * 1024;
	buf = (char *) calloc (size, sizeof(char));

	if (read_it) {
		if ((image = fopen (filename, "w")) == NULL) {
			perror(filename);
			exit(1);
		}
		printf("Reading Flash...");
		if(flash->read == NULL)
			memcpy(buf, (const char *) flash->virt_addr, size);
		else
			flash->read (flash, buf);
		fwrite(buf, sizeof(char), size, image);
		fclose(image);
		printf("done\n");
	} else {
		if ((image = fopen (filename, "r")) == NULL) {
			perror(filename);
			exit(1);
		}
		fread (buf, sizeof(char), size, image);
		fclose(image);
	}

	if (write_it || (!read_it && !verify_it))
		flash->write (flash, buf);
	if (verify_it)
		verify_flash (flash, buf, verbose);
	return 0;
}
