diff options
| -rw-r--r-- | flash_rom.c | 132 | ||||
| -rw-r--r-- | sst39sf020.c | 4 | 
2 files changed, 106 insertions, 30 deletions
| diff --git a/flash_rom.c b/flash_rom.c index 0ec1e042..488d9327 100644 --- a/flash_rom.c +++ b/flash_rom.c @@ -136,6 +136,9 @@ enable_flash_e7500(struct pci_dev *dev, char *name) {    new = old | 1; +  if (new == old) +      return 0; +    ok = pci_write_byte(dev, 0x4e, new);    if (ok != new) { @@ -146,6 +149,28 @@ enable_flash_e7500(struct pci_dev *dev, char *name) {    return 0;  } +int +enable_flash_vt8231(struct pci_dev *dev, char *name) { +  unsigned char old, new; +  int ok; +   +  old = pci_read_byte(dev, 0x40); + +  new = old | 0x10; + +  if (new == old) +      return 0; + +  ok = pci_write_byte(dev, 0x40, new); + +  if (ok != 0) { +    printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",  +	   old, new, name); +    return -1; +  } +  return 0; +} +  struct flashchip * probe_flash(struct flashchip * flash)  {      int fd_mem; @@ -206,29 +231,29 @@ int verify_flash (struct flashchip * flash, char * buf, int verbose)  // count to a billion. Time it. If it's < 1 sec, count to 10B, etc. -unsigned long micro = 0; +unsigned long micro = 1;  void   myusec_calibrate_delay()  { -	unsigned long count = 10 *  1024 * 1024; +        int count = 1000;  	volatile unsigned long i;  	unsigned long timeusec;  	struct timeval start, end;  	int ok = 0; +	void myusec_delay(int time);  	printf("Setting up microsecond timing loop\n");  	while (! ok) {  		//fprintf(stderr, "Try %d\n", count);  		gettimeofday(&start, 0); -		for( i = count; i; i--) -			; +                myusec_delay(count);  		gettimeofday(&end, 0);  		timeusec = 1000000 * (end.tv_sec - start.tv_sec ) +   				(end.tv_usec - start.tv_usec); -		fprintf(stderr, "timeusec is %d\n", timeusec); -		count *= 100; -		if (timeusec < 1000000) +		//fprintf(stderr, "timeusec is %d\n", timeusec); +		count *= 2; +		if (timeusec < 1000000/4)  			continue;  		ok = 1;  	} @@ -236,18 +261,17 @@ myusec_calibrate_delay()  	// compute one microsecond. That will be count / time  	micro = count / timeusec; -	//fprintf(stderr, "one us is %d count\n", micro); +	fprintf(stderr, "%dM loops per second\n", micro);  }  void -myusec_delay(time) +myusec_delay(int time)  {    volatile unsigned long i;    for(i = 0; i < time * micro; i++)  	; -  }  typedef struct penable { @@ -260,6 +284,7 @@ FLASH_ENABLE enables[] = {    {0x1, 0x1, "sis630 -- what's the ID?", enable_flash_sis630},    {0x8086, 0x2480, "E7500", enable_flash_e7500}, +  {0x1106, 0x8231, "VT8231", enable_flash_vt8231},  };  int @@ -291,10 +316,25 @@ enable_flash_write() {    }    /* now do the deed. */ -  enable->doit(dev, enable->name); +  if (enable) { +      printf("Enabling flash write on %s...", enable->name); +      if (enable->doit(dev, enable->name) == 0) +          printf("OK\n"); +  }    return 0;  } +void usage(const char *name) +{ +    printf("usage: %s [-rwv] [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" +        " 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[])  { @@ -302,13 +342,37 @@ main (int argc, char * argv[])      unsigned long size;      FILE * image;      struct flashchip * flash; - -    if (argc > 2){ -	printf("usage: %s [romimage]\n", argv[0]); -	printf(" If no romimage is specified, then all that happens\n"); -	printf(" is that flash info is dumped\n"); +    int opt; +    int read_it = 0, write_it = 0, verify_it = 0; +    char *filename = NULL; +    while ((opt = getopt(argc, argv, "rwv")) != EOF) { +        switch (opt) { +        case 'r': +            read_it = 1; +            break; +        case 'w': +            write_it = 1; +            break; +        case 'v': +            verify_it = 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.       */ @@ -320,25 +384,35 @@ main (int argc, char * argv[])      }      printf("Part is %s\n", flash->name); -    if (argc < 2){ +    if (!filename){  	printf("OK, only ENABLING flash write, but NOT FLASHING\n");  	return 0;      }      size = flash->total_size * 1024; - -    if ((image = fopen (argv[1], "r")) == NULL) { -	perror("Error opening image file"); -	exit(1); -    } -      buf = (char *) calloc (size, sizeof(char)); -    fread (buf, sizeof(char), size, image); -    printf("Calibrating timer since microsleep sucks ... takes a second\n"); -    myusec_calibrate_delay(); -    printf("OK, calibrated, now do the deed\n"); +    if (read_it) { +        if ((image = fopen (filename, "w")) == NULL) { +            perror("Error opening image file"); +            exit(1); +        } +        printf("Reading Flash..."); +        memcpy(buf, (const char *) flash->virt_addr, size); +        fwrite(buf, sizeof(char), size, image); +        fclose(image); +        printf("done\n"); +    } else { +        if ((image = fopen (filename, "r")) == NULL) { +            perror("Error opening image file"); +            exit(1); +        } +        fread (buf, sizeof(char), size, image); +        fclose(image); +    } -    flash->write (flash, buf); -    verify_flash (flash, buf, /* verbose = */ 0); +    if (write_it) +        flash->write (flash, buf); +    if (verify_it) +        verify_flash (flash, buf, /* verbose = */ 0);      return 0;  } diff --git a/sst39sf020.c b/sst39sf020.c index 7e0853a0..80116aef 100644 --- a/sst39sf020.c +++ b/sst39sf020.c @@ -27,6 +27,7 @@  #include "flash.h"  #include "jedec.h" +#include <stdio.h>  #define AUTO_PG_ERASE1		0x20  #define AUTO_PG_ERASE2		0xD0 @@ -160,7 +161,7 @@ int erase_39sf020 (struct flashchip * flash)          Temp  = bios + 0x5555; /* set up address to be C000:5555h      */          *Temp = 0x10;       /* write data 0x55 to the address       */ -	myusec_delay(20000); +	myusec_delay(50000);  }  int write_39sf020 (struct flashchip * flash, char * buf) @@ -181,6 +182,7 @@ int write_39sf020 (struct flashchip * flash, char * buf)  		write_sector_39sf020(bios, buf + i * page_size, bios + i * page_size,  				     page_size);  		printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +                fflush(stdout);  	}  	printf("\n"); | 
