Patch to flash_rom

SONE Takeshi ts1 at cma.co.jp
Wed Mar 12 08:43:01 CET 2003


Hi,
I modified the flash_rom program a little and it might be useful for
others.

- Add "enable" for VIA VT8231 (southbridge of EPIA board)
 This does same thing as what is in src/mainboard/via/epia/README.

 (Btw, I downloaded the datasheet for VT8231 from here:
     http://www.google.com/search?q=vt8231+application%2Fpdf
 It's publically online ;-)

- Fixed segfault when no "enable" is defined for a board.
- Fixed delay calibration so it really finishes in a second
 (original code takes up to 100 seconds theoretically, >10 seconds on my
 box)
- Support for -r (read), -w (write), and -v (verify).

Writing is not really tested since I don't have my BIOS Savior yet.
Looking forward to trying out LinuxBIOS on my box.
Thanks for the great work.

-- 
Takeshi




Index: flash_rom.c
===================================================================
RCS file: /cvsroot/freebios/freebios/util/flash_and_burn/flash_rom.c,v
retrieving revision 1.16
diff -u -r1.16 flash_rom.c
--- flash_rom.c	28 Feb 2003 17:21:37 -0000	1.16
+++ flash_rom.c	12 Mar 2003 14:03:11 -0000
@@ -136,6 +136,9 @@
 
   new = old | 1;
 
+  if (new == old)
+      return 0;
+
   ok = pci_write_byte(dev, 0x4e, new);
 
   if (ok != new) {
@@ -146,6 +149,28 @@
   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;
@@ -227,8 +252,8 @@
 		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)
+		count *= 2;
+		if (timeusec < 1000000/3)
 			continue;
 		ok = 1;
 	}
@@ -260,6 +285,7 @@
 
   {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 +317,25 @@
   }
 
   /* 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 +343,36 @@
     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 +385,35 @@
     }
 
     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;
 }



More information about the coreboot mailing list