From e555957f0447e9555503979304c570beb11c0467 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Fri, 28 Mar 2003 03:29:43 +0000 Subject: [PATCH] Fixes ... Corresponding to coreboot v1 svn r760. --- flash_rom.c | 132 ++++++++++++++++++++++++++++++++++++++++----------- sst39sf020.c | 4 +- 2 files changed, 106 insertions(+), 30 deletions(-) diff --git a/flash_rom.c b/flash_rom.c index 0ec1e0422..488d93270 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,12 +342,36 @@ 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; + buf = (char *) calloc (size, sizeof(char)); - if ((image = fopen (argv[1], "r")) == NULL) { - perror("Error opening image file"); - exit(1); + 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); } - 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"); - - 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 7e0853a06..80116aefe 100644 --- a/sst39sf020.c +++ b/sst39sf020.c @@ -27,6 +27,7 @@ #include "flash.h" #include "jedec.h" +#include #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");