add retry to write_byte_program_jedec(), 99% success rate
[coreboot.git] / util / flash_and_burn / flash_rom.c
index 6abd4898b164318fa9647a336efd8673f32c68a8..bf338ccb3c361801df22538d85bf861b571d7e72 100644 (file)
@@ -3,6 +3,8 @@
  *
  *
  * Copyright 2000 Silicon Integrated System Corporation
+ * Copyright 2004 Tyan Corp
+ *     yhlu yhlu@tyan.com add exclude start and end option
  *
  *     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
@@ -46,6 +48,7 @@
 #include "sst49lf040.h"
 #include "pm49fl004.h"
 #include "mx29f002.h"
+#include "sst_fwhub.h"
 
 struct flashchip flashchips[] = {
        {"Am29F040B",   AMD_ID,         AM_29F040B,     NULL, 512, 64 * 1024,
@@ -66,14 +69,14 @@ struct flashchip flashchips[] = {
         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},
+       {"SST49LF002A/B", SST_ID,       SST_49LF002A,   NULL, 256, 16 * 1024,
+        probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub, NULL},
+       {"SST49LF003A/B", SST_ID,       SST_49LF003A,   NULL, 384, 64 * 1024,
+        probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub,NULL},
+       {"SST49LF004A/B", SST_ID,       SST_49LF004A,   NULL, 512, 64 * 1024,
+        probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub,NULL},
+       {"SST49LF008A", SST_ID,         SST_49LF008A,   NULL, 1024, 64 * 1024 ,
+        probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub, 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,
@@ -170,16 +173,20 @@ int verify_flash(struct flashchip *flash, char *buf, int verbose)
 
 void usage(const char *name)
 {
-       printf("usage: %s [-rwv] [-c chipname][file]\n", name);
+       printf("usage: %s [-rwv] [-c chipname] [-s exclude_start] [-e exclude_end] [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"
+              "-s: exclude start position\n"
+              "-e: exclude end postion\n"
               " If no file is specified, then all that happens\n"
               " is that flash info is dumped\n");
        exit(1);
 }
 
+int exclude_start_page, exclude_end_page;
+
 int main(int argc, char *argv[])
 {
        char *buf;
@@ -190,9 +197,21 @@ int main(int argc, char *argv[])
        int read_it = 0, write_it = 0, verify_it = 0, verbose = 0;
        char *filename = NULL;
 
+
+        unsigned int exclude_start_position=0, exclude_end_position=0; // [x,y)
+       char *tempstr=NULL;
+
+       if (argc > 1) {
+               /* Yes, print them. */
+               int i;
+               printf ("The arguments are:\n");
+               for (i = 1; i < argc; ++i)
+                       printf ("%s\n", argv[i]);
+       }
+
        setbuf(stdout, NULL);
 
-       while ((opt = getopt(argc, argv, "rwvVc:")) != EOF) {
+       while ((opt = getopt(argc, argv, "rwvVc:s:e:")) != EOF) {
                switch (opt) {
                case 'r':
                        read_it = 1;
@@ -209,11 +228,21 @@ int main(int argc, char *argv[])
                case 'V':
                        verbose = 1;
                        break;
+               case 's':
+                       tempstr = strdup(optarg);
+                       sscanf(tempstr,"%x",&exclude_start_position);
+                       break;
+               case 'e':
+                       tempstr = strdup(optarg);
+                       sscanf(tempstr,"%x",&exclude_end_position);
+                       break;
+
                default:
                        usage(argv[0]);
                        break;
                }
        }
+
        if (read_it && write_it) {
                printf("-r and -w are mutually exclusive\n");
                usage(argv[0]);
@@ -254,6 +283,11 @@ int main(int argc, char *argv[])
                        memcpy(buf, (const char *) flash->virt_addr, size);
                else
                        flash->read(flash, buf);
+
+               if (exclude_end_position - exclude_start_position > 0)
+                       memset(buf+exclude_start_position, 0,
+                              exclude_end_position-exclude_start_position);
+
                fwrite(buf, sizeof(char), size, image);
                fclose(image);
                printf("done\n");
@@ -266,8 +300,20 @@ int main(int argc, char *argv[])
                fclose(image);
        }
 
-       if (write_it || (!read_it && !verify_it))
+       if (exclude_end_position - exclude_start_position > 0)
+               memcpy(buf+exclude_start_position,
+                      (const char *) flash->virt_addr+exclude_start_position, 
+                      exclude_end_position-exclude_start_position);
+
+        exclude_start_page = exclude_start_position/flash->page_size;
+       if ((exclude_start_position%flash->page_size) != 0) {
+               exclude_start_page++;
+       }
+       exclude_end_page = exclude_end_position/flash->page_size;
+
+       if (write_it || (!read_it && !verify_it)) {
                flash->write(flash, buf);
+       }       
        if (verify_it)
                verify_flash(flash, buf, verbose);
        return 0;