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;
}