/*
 * 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_chip_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_chip_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_jedec, erase_chip_jedec, write_39sf020, NULL},
	{"SST39VF020", SST_ID, SST_39VF020, NULL, 256, 4096,
	 probe_jedec, erase_chip_jedec, write_39sf020, NULL},
	{"SST49LF040", SST_ID, SST_49LF040, NULL, 512, 4096,
	 probe_jedec, erase_chip_jedec, write_49lf040, NULL},
	{"SST49LF080A", SST_ID, SST_49LF080A, NULL, 1024, 4096,
	 probe_jedec, erase_chip_jedec, write_49lf040, NULL},
	{"SST49LF002A", SST_ID, SST_49LF002A, NULL, 256, 4096,
	 probe_jedec, erase_chip_jedec, write_49lf040, NULL},
	{"SST49LF003A", SST_ID, SST_49LF003A, NULL, 384, 4096,
	 probe_jedec, erase_chip_jedec, write_49lf040, NULL},
	{"SST49LF004A", SST_ID, SST_49LF004A, NULL, 512, 4096,
	 probe_jedec, erase_chip_jedec, write_49lf040, NULL},
	{"SST49LF008A", SST_ID, SST_49LF008A, NULL, 1024, 4096,
	 probe_jedec, erase_chip_jedec, write_49lf040, NULL},
	{"Pm49FL004", PMC_ID, PMC_49FL004, NULL, 512, 64 * 1024,
	 probe_jedec, erase_chip_jedec, write_49fl004, NULL},
	{"W29C011", WINBOND_ID, W_29C011, NULL, 128, 128,
	 probe_jedec, erase_chip_jedec, write_jedec, NULL},
	{"W29C020C", WINBOND_ID, W_29C020C, NULL, 256, 128,
	 probe_jedec, erase_chip_jedec, write_jedec, NULL},
	{"W49F002U", WINBOND_ID, W_49F002U, NULL, 256, 128,
	 probe_jedec, erase_chip_jedec, 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;
	int total_size = flash->total_size * 1024;
	volatile char *bios = flash->virt_addr;

	printf("Verifying address: ");
	for (i = 0; i < total_size; i++) {
		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");
	}
	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;
}
