Hi,
flashrom hasn't seen any major design changes in the last few months and most chips still perform whole-chip erase instead of sector-based erase.
I'd like to introduce a function which takes a range and rounds the start and the end of the range to the nearest block boundary. void roundup(struct flashchip *flash, int *startpos, int *endpos);
Take an example 256 kByte flash chip with the following sector layout: 0x00000-0x0ffff 64kB block 0x10000-0x1ffff 64kB block 0x20000-0x2ffff 64kB block 0x30000-0x37fff 32kB block 0x38000-0x3bfff 16kB block 0x3c000-0x3dfff 8kB block 0x3e000-0x3efff 4kB block 0x3f000-0x3ffff 4kB block
startpos=0x38123; endpos=0x3e005; roundup(flash, &startpos, &endpos); //results follow: //startpos=0x38000; //endpos=0x3efff;
That way, it is easily possible to check whether a given range can be handled by sector-based erase and write. You can use that result to tell the user that a range outside the intended range will get flashed. It is also possible to refuse flashing in that case.
Since the function will be generic and take a struct flashchip, there's no need to store a pointer to it with each chip and you can call the generic one from anywhere.
What do you think?
Regards, Carl-Daniel
On Fri, Oct 10, 2008 at 8:38 PM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Hi,
flashrom hasn't seen any major design changes in the last few months and most chips still perform whole-chip erase instead of sector-based erase.
I'd like to introduce a function which takes a range and rounds the start and the end of the range to the nearest block boundary. void roundup(struct flashchip *flash, int *startpos, int *endpos);
Take an example 256 kByte flash chip with the following sector layout: 0x00000-0x0ffff 64kB block 0x10000-0x1ffff 64kB block 0x20000-0x2ffff 64kB block 0x30000-0x37fff 32kB block 0x38000-0x3bfff 16kB block 0x3c000-0x3dfff 8kB block 0x3e000-0x3efff 4kB block 0x3f000-0x3ffff 4kB block
startpos=0x38123; endpos=0x3e005; roundup(flash, &startpos, &endpos); //results follow: //startpos=0x38000; //endpos=0x3efff;
That way, it is easily possible to check whether a given range can be handled by sector-based erase and write. You can use that result to tell the user that a range outside the intended range will get flashed. It is also possible to refuse flashing in that case.
Since the function will be generic and take a struct flashchip, there's no need to store a pointer to it with each chip and you can call the generic one from anywhere.
What do you think?
This is a good idea. Once cheap trick we could also do (or do we?): before sector erase, see if the sector is already erased, and skip that one.
ron
On 11.10.2008 06:07, ron minnich wrote:
On Fri, Oct 10, 2008 at 8:38 PM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Hi,
flashrom hasn't seen any major design changes in the last few months and most chips still perform whole-chip erase instead of sector-based erase.
I'd like to introduce a function which takes a range and rounds the start and the end of the range to the nearest block boundary. void roundup(struct flashchip *flash, int *startpos, int *endpos);
Take an example 256 kByte flash chip with the following sector layout: 0x00000-0x0ffff 64kB block 0x10000-0x1ffff 64kB block 0x20000-0x2ffff 64kB block 0x30000-0x37fff 32kB block 0x38000-0x3bfff 16kB block 0x3c000-0x3dfff 8kB block 0x3e000-0x3efff 4kB block 0x3f000-0x3ffff 4kB block
startpos=0x38123; endpos=0x3e005; roundup(flash, &startpos, &endpos); //results follow: //startpos=0x38000; //endpos=0x3efff;
That way, it is easily possible to check whether a given range can be handled by sector-based erase and write. You can use that result to tell the user that a range outside the intended range will get flashed. It is also possible to refuse flashing in that case.
Since the function will be generic and take a struct flashchip, there's no need to store a pointer to it with each chip and you can call the generic one from anywhere.
What do you think?
This is a good idea. Once cheap trick we could also do (or do we?): before sector erase, see if the sector is already erased, and skip that one.
This is a patch which stores eraseblock sizes in struct flashchip. I decided to fill in the info for a few chips to illustrate how this works both for uniform and non-uniform sector sizes.
And since I dislike incorrect code, I went ahead and fixed some stuff. As an added bonus there are new definitions in there as well.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Regards, Carl-Daniel
Index: flash.h =================================================================== --- flash.h (Revision 3648) +++ flash.h (Arbeitskopie) @@ -51,6 +51,11 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+struct eraseblock{ + int size; /* Eraseblock size */ + int count; /* Number of contiguous blocks with that size */ +}; + struct flashchip { const char *vendor; const char *name; @@ -63,6 +68,7 @@
int total_size; int page_size; + struct eraseblock eraseblocks[4];
/* Indicate if flashrom has been tested with this flash chip and if * everything worked correctly. @@ -213,7 +219,8 @@ #define MX_25L6405 0x2017 /* MX25L3205{,D} */ #define MX_25L1635D 0x2415 #define MX_25L3235D 0x2416 -#define MX_29F002 0xB0 +#define MX_29F002B 0x34 +#define MX_29F002T 0xB0
/* Programmable Micro Corp is listed in JEP106W in bank 2, so it should have * a 0x7F continuation code prefix. Index: flashchips.c =================================================================== --- flashchips.c (Revision 3648) +++ flashchips.c (Arbeitskopie) @@ -30,124 +30,132 @@ */ struct flashchip flashchips[] = { /**********************************************************************************************************************************************************************************************************************/ - /* Vendor Chip Vendor ID Chip ID TODO TODO Test status Probe function Erase function Write function Read function */ + /* Vendor Chip Vendor ID Chip ID Total size (kB) Page size (kB) Eraseblocks Test status Probe function Erase function Write function Read function */ /**********************************************************************************************************************************************************************************************************************/ - {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, - {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, TEST_OK_PREW, probe_29f002, erase_29f002, write_29f002}, - {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, TEST_OK_PR, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC_STRANGE, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX29F002", MX_ID, MX_29F002, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, write_lhf00l04}, - {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, TEST_UNTESTED, probe_28sf040, erase_28sf040, write_28sf040}, - {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, write_39sf020}, + {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, + {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, + {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, + {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, + {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, + {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, + {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, + {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, + {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, + {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16386,1}},TEST_OK_PREW, probe_29f002, erase_29f002, write_29f002}, + {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, {}, TEST_OK_PR, probe_29f040b, erase_29f040b, write_29f040b}, + {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, + {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, + {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, + {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, {{65536,3},{32768,1},{8192,2},{16386,1}},TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, + {"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, + {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, + {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, + {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, + {"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, {{4096,16}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, {{4096,32}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, {{4096,64}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, {{4096,128}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, {{4096,256}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, {{4096,512}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L1605eLite", MX_ID, MX_25L1605, 2048, 256, {{65536,32}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, {{4096,1024}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L3205eLite", MX_ID, MX_25L3205, 4096, 256, {{65536,64}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, {{4096,2048}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, + {"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, + {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, + {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, + {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, write_lhf00l04}, + {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, {}, TEST_UNTESTED, probe_28sf040, erase_28sf040, write_28sf040}, + {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, + {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, + {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, + {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, + {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, + {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, + {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, + {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, {}, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, write_39sf020}, // assume similar to 004B, ignoring data sheet - {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, - {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, write_jedec}, - {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V040C", 0xda, 0x50, 512, 64*1024, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, write_w39v040c}, - {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, TEST_OK_PR, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub}, - {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub}, + {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, + {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, {}, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, + {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, + {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, + {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, + {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, + {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, + {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_49lf040, write_49lf040}, + {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, + {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, + {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, + {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, + {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, {}, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, + {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, {}, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, + {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, + {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, + {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, + {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, + {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, + {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, + {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, + {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, + {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, + {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, + {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, + {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, + {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, write_jedec}, + {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, + {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, + {"Winbond", "W39V040C", 0xda, 0x50, 512, 64*1024, {}, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, write_w39v040c}, + {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, {}, TEST_OK_PR, probe_jedec, erase_chip_jedec, write_39sf020}, + {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, + {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, + {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, + {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, + {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, {}, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub}, + {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, {}, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub},
- {"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{NULL,} };
On 11.10.2008 23:43, Carl-Daniel Hailfinger wrote:
On 11.10.2008 06:07, ron minnich wrote:
On Fri, Oct 10, 2008 at 8:38 PM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Hi,
flashrom hasn't seen any major design changes in the last few months and most chips still perform whole-chip erase instead of sector-based erase.
I'd like to introduce a function which takes a range and rounds the start and the end of the range to the nearest block boundary. void roundup(struct flashchip *flash, int *startpos, int *endpos);
Take an example 256 kByte flash chip with the following sector layout: 0x00000-0x0ffff 64kB block 0x10000-0x1ffff 64kB block 0x20000-0x2ffff 64kB block 0x30000-0x37fff 32kB block 0x38000-0x3bfff 16kB block 0x3c000-0x3dfff 8kB block 0x3e000-0x3efff 4kB block 0x3f000-0x3ffff 4kB block
startpos=0x38123; endpos=0x3e005; roundup(flash, &startpos, &endpos); //results follow: //startpos=0x38000; //endpos=0x3efff;
That way, it is easily possible to check whether a given range can be handled by sector-based erase and write. You can use that result to tell the user that a range outside the intended range will get flashed. It is also possible to refuse flashing in that case.
Since the function will be generic and take a struct flashchip, there's no need to store a pointer to it with each chip and you can call the generic one from anywhere.
What do you think?
This is a good idea. Once cheap trick we could also do (or do we?): before sector erase, see if the sector is already erased, and skip that one.
This is a patch which stores eraseblock sizes in struct flashchip. I decided to fill in the info for a few chips to illustrate how this works both for uniform and non-uniform sector sizes.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Since the codebase has changed a bit, I decided to rediff. This patch already uses sector-based erase if available. The write functions with implicit erase still need to be hooked up, but the patch is functional as-is.
Attached for Gmail users.
Index: flashrom-eraseblocks/flash.h =================================================================== --- flashrom-eraseblocks/flash.h (Revision 3730) +++ flashrom-eraseblocks/flash.h (Arbeitskopie) @@ -51,6 +51,11 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+struct eraseblock{ + int size; /* Eraseblock size */ + int count; /* Number of contiguous blocks with that size */ +}; + struct flashchip { const char *vendor; const char *name; @@ -64,6 +69,7 @@
int total_size; int page_size; + struct eraseblock eraseblocks[4];
/* * Indicate if flashrom has been tested with this flash chip and if @@ -73,6 +79,7 @@
int (*probe) (struct flashchip *flash); int (*erase) (struct flashchip *flash); + int (*block_erase) (struct flashchip *flash, unsigned long addr); int (*write) (struct flashchip *flash, uint8_t *buf); int (*read) (struct flashchip *flash, uint8_t *buf);
Index: flashrom-eraseblocks/flashchips.c =================================================================== --- flashrom-eraseblocks/flashchips.c (Revision 3730) +++ flashrom-eraseblocks/flashchips.c (Arbeitskopie) @@ -30,138 +30,138 @@ */ struct flashchip flashchips[] = { /**********************************************************************************************************************************************************************************************************************/ - /* Vendor Chip Vendor ID Chip ID Total size (kB) Page size (B) Test status Probe function Erase function Write function Read function */ + /* Vendor Chip Vendor ID Chip ID Total size (kB) Page size (B) Eraseblocks Test status Probe function Chip erase function Block erase Write function Read function */ /**********************************************************************************************************************************************************************************************************************/ - {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, - {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, TEST_OK_PREW, probe_29f002, erase_29f002, write_29f002}, - {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, TEST_OK_PR, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, NULL, NULL}, - {"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, NULL, NULL}, - {"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"Numonyx", "M25PE10", ST_ID, 0x8011, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE20", ST_ID, 0x8012, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE40", ST_ID, 0x8013, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE80", ST_ID, 0x8014, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE16", ST_ID, 0x8015, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, write_lhf00l04}, - {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, TEST_UNTESTED, probe_28sf040, erase_28sf040, write_28sf040}, - {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, write_39sf020}, + {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002}, + {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_29f002, erase_29f002, NULL, write_29f002}, + {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, {}, TEST_OK_PR, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x}, + {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL}, + {"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL}, + {"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt}, + {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt}, + {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, {{4096,16}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, {{4096,32}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, {{4096,64}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, {{4096,128}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, {{4096,256}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, {{4096,512}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, {{4096,1024}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, {{4096,2048}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002}, + {"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002}, + {"Numonyx", "M25PE10", ST_ID, 0x8011, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE20", ST_ID, 0x8012, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE40", ST_ID, 0x8013, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE80", ST_ID, 0x8014, 1024, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE16", ST_ID, 0x8015, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x}, + {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x}, + {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, NULL, write_lhf00l04}, + {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, {}, TEST_UNTESTED, probe_28sf040, erase_28sf040, NULL, write_28sf040}, + {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, {}, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, // assume similar to 004B, ignoring data sheet - {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, - {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FW002", ST_ID, ST_M50FW002, 256, 64 * 1024, TEST_UNTESTED, probe_49lfxxxc, NULL, NULL}, - {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, write_jedec}, - {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V040C", WINBOND_ID, 0x50, 512, 64*1024, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, write_w39v040c}, - {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub}, - {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub}, + {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, {}, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_49lf040, NULL, write_49lf040}, + {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, NULL, write_49lf040}, + {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, NULL, write_49lf040}, + {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, {}, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, {}, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt}, + {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FW002", ST_ID, ST_M50FW002, 256, 64 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, NULL, NULL, NULL}, + {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W39V040C", WINBOND_ID, 0x50, 512, 64*1024, {}, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, NULL, write_w39v040c}, + {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, {}, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, NULL, write_winbond_fwhub}, + {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, {}, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, NULL, write_winbond_fwhub},
- {"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{NULL,} }; Index: flashrom-eraseblocks/flashrom.c =================================================================== --- flashrom-eraseblocks/flashrom.c (Revision 3730) +++ flashrom-eraseblocks/flashrom.c (Arbeitskopie) @@ -534,11 +534,33 @@
if (erase_it) { printf("Erasing flash chip.\n"); - if (!flash->erase) { - fprintf(stderr, "Error: flashrom has no erase function for this flash chip.\n"); + if (!flash->block_erase && flash->eraseblocks[0].count) { + fprintf(stderr, "Hint: flashrom knows the eraseblock " + "layout, but there is no blockwise erase " + "function for this flash chip. " + "Using whole-chip erase.\n"); + } + if (flash->block_erase && !flash->eraseblocks[0].count) { + fprintf(stderr, "Hint: flashrom has a blockwise erase " + "function for this flash chip, but the " + "eraseblock layout is unknown. " + "Using whole-chip erase.\n"); + } + if (flash->block_erase && flash->eraseblocks[0].count) { + unsigned long done = 0; + int i, j; + for (i = 0; done < flash->total_size * 1024; i++) { + for (j = 0; j < flash->eraseblocks[i].count; j++) { + flash->block_erase(flash, done + flash->eraseblocks[i].size * j); + } + done += flash->eraseblocks[i].count * flash->eraseblocks[i].size; + } + } else if (flash->erase) { + flash->erase(flash); + } else { + fprintf(stderr, "Error: flashrom has no chip erase function for this flash chip.\n"); return 1; } - flash->erase(flash); exit(0); } else if (read_it) { if ((image = fopen(filename, "w")) == NULL) {
Carl-Daniel Hailfinger wrote:
@@ -64,6 +69,7 @@
int total_size; int page_size;
- struct eraseblock eraseblocks[4];
I don't know.. What about chips with more blocks than 4?
//Peter
On 05.11.2008 10:21, Peter Stuge wrote:
Carl-Daniel Hailfinger wrote:
@@ -64,6 +69,7 @@
int total_size; int page_size;
- struct eraseblock eraseblocks[4];
I don't know.. What about chips with more blocks than 4?
No problem. Let me quote another part of the patch.
+struct eraseblock{
- int size; /* Eraseblock size */
- int count; /* Number of contiguous blocks with that size */
+};
struct eraseblock doesn't correspond with a single erase block, but with a group of contiguous erase blocks having the same size. Given a (top boot block) flash chip with the following weird, but real-life structure:
top 16384 8192 8192 32768 65536 65536 65536 65536 65536 65536 65536 bottom
we get the following encoding: {65536,7},{32768,1},{8192,2},{16384,1}
Although the number of blocks is bigger than 4, the number of block groups is only 4. If you ever add some flash chips with more than 4 contiguous block groups, the definition will not fit into the 4-member array anymore and gcc will recognize that and error out. No undetected overflow possible. In that case, you simply increase array size a bit. For modern flash chips with uniform erase block size, you only need one array member anyway.
Of course data types will need to be changed if you ever get flash chips with more than 2^30 erase blocks, but even with the lowest known erase granularity of 256 bytes, these flash chips will have to have a size of a quarter Terabyte. I'm pretty confident we won't see such big EEPROMs in the near future (or at least not attached in a way that makes flashrom usable). For SPI chips, we even have a guaranteed safety factor of 4096 over the maximum SPI chip size (which is 2^24). And if such a big flash chip has uniform erase block size, you could even split it among the 4 array members. If you change int count to unsigned int count, the storable size doubles. So with a split and a slight change of data type, the maximum ROM chip size is 2 Terabytes.
Regards, Carl-Daniel
This is a patch which stores eraseblock sizes in struct flashchip. I decided to fill in the info for a few chips to illustrate how this works both for uniform and non-uniform sector sizes.
struct eraseblock{ int size; /* Eraseblock size */ int count; /* Number of contiguous blocks with that size */ };
struct eraseblock doesn't correspond with a single erase block, but with a group of contiguous erase blocks having the same size. Given a (top boot block) flash chip with the following weird, but real-life structure:
top 16384 8192 8192 32768 65536 65536 65536 65536 65536 65536 65536 bottom
we get the following encoding: {65536,7},{32768,1},{8192,2},{16384,1}
Although the number of blocks is bigger than 4, the number of block groups is only 4. If you ever add some flash chips with more than 4 contiguous block groups, the definition will not fit into the 4-member array anymore and gcc will recognize that and error out. No undetected overflow possible. In that case, you simply increase array size a bit. For modern flash chips with uniform erase block size, you only need one array member anyway.
Of course data types will need to be changed if you ever get flash chips with more than 2^30 erase blocks, but even with the lowest known erase granularity of 256 bytes, these flash chips will have to have a size of a quarter Terabyte. I'm pretty confident we won't see such big EEPROMs in the near future (or at least not attached in a way that makes flashrom usable). For SPI chips, we even have a guaranteed safety factor of 4096 over the maximum SPI chip size (which is 2^24). And if such a big flash chip has uniform erase block size, you could even split it among the 4 array members. If you change int count to unsigned int count, the storable size doubles. So with a split and a slight change of data type, the maximum ROM chip size is 2 Terabytes.
This patch addresses all comments which came up in the review. Attached for Gmail users.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-eraseblocks/flash.h =================================================================== --- flashrom-eraseblocks/flash.h (Revision 3776) +++ flashrom-eraseblocks/flash.h (Arbeitskopie) @@ -51,6 +51,11 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+struct eraseblock{ + int size; /* Eraseblock size */ + int count; /* Number of contiguous blocks with that size */ +}; + struct flashchip { const char *vendor; const char *name; @@ -64,6 +69,7 @@
int total_size; int page_size; + struct eraseblock eraseblocks[4];
/* * Indicate if flashrom has been tested with this flash chip and if @@ -73,6 +79,7 @@
int (*probe) (struct flashchip *flash); int (*erase) (struct flashchip *flash); + int (*block_erase) (struct flashchip *flash, unsigned long addr); int (*write) (struct flashchip *flash, uint8_t *buf); int (*read) (struct flashchip *flash, uint8_t *buf);
Index: flashrom-eraseblocks/flashchips.c =================================================================== --- flashrom-eraseblocks/flashchips.c (Revision 3776) +++ flashrom-eraseblocks/flashchips.c (Arbeitskopie) @@ -30,166 +30,166 @@ */ struct flashchip flashchips[] = { /**********************************************************************************************************************************************************************************************************************/ - /* Vendor Chip Vendor ID Chip ID Total size (kB) Page size (B) Test status Probe function Erase function Write function Read function */ + /* Vendor Chip Vendor ID Chip ID Total size (kB) Page size (B) Eraseblocks Test status Probe function Chip erase function Block erase Write function Read function */ /**********************************************************************************************************************************************************************************************************************/ - {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, - {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT25DF021", ATMEL_ID, AT_25DF021, 256, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25DF041A", ATMEL_ID, AT_25DF041A, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25DF081", ATMEL_ID, AT_25DF081, 1024, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25DF161", ATMEL_ID, AT_25DF161, 2048, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Atmel", "AT25DF321A", ATMEL_ID, AT_25DF321A, 4096, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25DF641", ATMEL_ID, AT_25DF641, 8192, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25F512B", ATMEL_ID, AT_25F512B, 64, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25FS010", ATMEL_ID, AT_25FS010, 128, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT25FS040", ATMEL_ID, AT_25FS040, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT26DF041", ATMEL_ID, AT_26DF041, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL /* Incompatible Page write */,spi_chip_read}, - {"Atmel", "AT26DF081A", ATMEL_ID, AT_26DF081A, 1024, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT26DF161", ATMEL_ID, AT_26DF161, 2048, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, - {"Atmel", "AT26DF161A", ATMEL_ID, AT_26DF161A, 2048, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read}, + {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Atmel", "AT25DF021", ATMEL_ID, AT_25DF021, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25DF041A", ATMEL_ID, AT_25DF041A, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25DF081", ATMEL_ID, AT_25DF081, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25DF161", ATMEL_ID, AT_25DF161, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Atmel", "AT25DF321A", ATMEL_ID, AT_25DF321A, 4096, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25DF641", ATMEL_ID, AT_25DF641, 8192, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25F512B", ATMEL_ID, AT_25F512B, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25FS010", ATMEL_ID, AT_25FS010, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT25FS040", ATMEL_ID, AT_25FS040, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT26DF041", ATMEL_ID, AT_26DF041, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL /* Incompatible Page write */,spi_chip_read}, + {"Atmel", "AT26DF081A", ATMEL_ID, AT_26DF081A, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT26DF161", ATMEL_ID, AT_26DF161, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, + {"Atmel", "AT26DF161A", ATMEL_ID, AT_26DF161A, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, /*The AT26DF321 has the same ID as the AT25DF321. */ - /*{"Atmel", "AT26DF321", ATMEL_ID, AT_26DF321, 4096, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},*/ - {"Atmel", "AT26F004", ATMEL_ID, AT_26F004, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL /* Incompatible Page write */,spi_chip_read}, - {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Atmel", "AT45CS1282", ATMEL_ID, AT_45CS1282, 16896/*!*/,1056/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL /* Incompatible Page write */, NULL /* Incompatible read */}, /* No power of two sizes */ - {"Atmel", "AT45DB011D", ATMEL_ID, AT_45DB011D, 128/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */ - {"Atmel", "AT45DB021D", ATMEL_ID, AT_45DB021D, 256/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */ - {"Atmel", "AT45DB041D", ATMEL_ID, AT_45DB041D, 512/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */ - {"Atmel", "AT45DB081D", ATMEL_ID, AT_45DB081D, 1024/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */ - {"Atmel", "AT45DB161D", ATMEL_ID, AT_45DB161D, 2048/*!*/,512/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */ - {"Atmel", "AT45DB321C", ATMEL_ID, AT_45DB321C, 4224/*!*/,528/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL /* Incompatible read */}, /* No power of two sizes */ - {"Atmel", "AT45DB321D", ATMEL_ID, AT_45DB321D, 4096/*!*/,512/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */ - {"Atmel", "AT45DB642D", ATMEL_ID, AT_45DB642D, 8192/*!*/,1024/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */ - {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, TEST_OK_PREW, probe_29f002, erase_29f002, write_29f002}, - {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, TEST_OK_PR, probe_29f040b, erase_29f040b, write_29f040b}, - {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, - {"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, NULL, NULL}, - {"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, NULL, NULL}, - {"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002}, - {"Numonyx", "M25PE10", ST_ID, 0x8011, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE20", ST_ID, 0x8012, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE40", ST_ID, 0x8013, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE80", ST_ID, 0x8014, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"Numonyx", "M25PE16", ST_ID, 0x8015, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, - {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, write_lhf00l04}, - {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF032B", SST_ID, SST_25VF032B, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF080B", SST_ID, SST_25VF080B, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_60_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, TEST_UNTESTED, probe_28sf040, erase_28sf040, write_28sf040}, - {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, write_39sf020}, + /*{"Atmel", "AT26DF321", ATMEL_ID, AT_26DF321, 4096, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},*/ + {"Atmel", "AT26F004", ATMEL_ID, AT_26F004, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL /* Incompatible Page write */,spi_chip_read}, + {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Atmel", "AT45CS1282", ATMEL_ID, AT_45CS1282, 16896/*!*/,1056/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL /* Incompatible Page write */, NULL /* Incompatible read */}, /* No power of two sizes */ + {"Atmel", "AT45DB011D", ATMEL_ID, AT_45DB011D, 128/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */ + {"Atmel", "AT45DB021D", ATMEL_ID, AT_45DB021D, 256/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */ + {"Atmel", "AT45DB041D", ATMEL_ID, AT_45DB041D, 512/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */ + {"Atmel", "AT45DB081D", ATMEL_ID, AT_45DB081D, 1024/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */ + {"Atmel", "AT45DB161D", ATMEL_ID, AT_45DB161D, 2048/*!*/,512/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */ + {"Atmel", "AT45DB321C", ATMEL_ID, AT_45DB321C, 4224/*!*/,528/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL /* Incompatible read */}, /* No power of two sizes */ + {"Atmel", "AT45DB321D", ATMEL_ID, AT_45DB321D, 4096/*!*/,512/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */ + {"Atmel", "AT45DB642D", ATMEL_ID, AT_45DB642D, 8192/*!*/,1024/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */ + {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002}, + {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_29f002, erase_29f002, NULL, write_29f002}, + {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, {}, TEST_OK_PR, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x}, + {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a}, + {"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL}, + {"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL}, + {"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt}, + {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt}, + {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, {{4096,16}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, {{4096,32}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, {{4096,64}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, {{4096,128}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, {{4096,256}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, {{4096,512}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, {{4096,1024}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, {{4096,2048}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002}, + {"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002}, + {"Numonyx", "M25PE10", ST_ID, 0x8011, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE20", ST_ID, 0x8012, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE40", ST_ID, 0x8013, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE80", ST_ID, 0x8014, 1024, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"Numonyx", "M25PE16", ST_ID, 0x8015, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x}, + {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x}, + {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, NULL, write_lhf00l04}, + {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF032B", SST_ID, SST_25VF032B, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF080B", SST_ID, SST_25VF080B, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_60_c7, NULL, spi_chip_write, spi_chip_read}, + {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, {}, TEST_UNTESTED, probe_28sf040, erase_28sf040, NULL, write_28sf040}, + {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, {}, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, // assume similar to 004B, ignoring data sheet - {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, - {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040}, - {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b}, - {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, - {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x}, - {"ST", "M50FW002", ST_ID, ST_M50FW002, 256, 64 * 1024, TEST_UNTESTED, probe_49lfxxxc, NULL, NULL}, - {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, - {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, write_jedec}, - {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V040C", WINBOND_ID, 0x50, 512, 64*1024, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, write_w39v040c}, - {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020}, - {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub}, - {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub}, + {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, {}, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_49lf040, NULL, write_49lf040}, + {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, NULL, write_49lf040}, + {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub}, + {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, NULL, write_49lf040}, + {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc}, + {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, {}, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, NULL, write_29f040b}, + {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, {}, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt}, + {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x}, + {"ST", "M50FW002", ST_ID, ST_M50FW002, 256, 64 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, NULL, NULL, NULL}, + {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, NULL, write_82802ab}, + {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read}, + {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, NULL, write_jedec}, + {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W39V040C", WINBOND_ID, 0x50, 512, 64*1024, {}, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, NULL, write_w39v040c}, + {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020}, + {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002}, + {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, {}, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, NULL, write_winbond_fwhub}, + {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, {}, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, NULL, write_winbond_fwhub},
- {"Atmel", "unknown Atmel SPI chip",ATMEL_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, - {"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"Atmel", "unknown Atmel SPI chip",ATMEL_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{NULL,} }; Index: flashrom-eraseblocks/flashrom.c =================================================================== --- flashrom-eraseblocks/flashrom.c (Revision 3776) +++ flashrom-eraseblocks/flashrom.c (Arbeitskopie) @@ -534,11 +534,33 @@
if (erase_it) { printf("Erasing flash chip.\n"); - if (!flash->erase) { - fprintf(stderr, "Error: flashrom has no erase function for this flash chip.\n"); + if (!flash->block_erase && flash->eraseblocks[0].count) { + fprintf(stderr, "Hint: flashrom knows the eraseblock " + "layout, but there is no blockwise erase " + "function for this flash chip. " + "Using whole-chip erase.\n"); + } + if (flash->block_erase && !flash->eraseblocks[0].count) { + fprintf(stderr, "Hint: flashrom has a blockwise erase " + "function for this flash chip, but the " + "eraseblock layout is unknown. " + "Using whole-chip erase.\n"); + } + if (flash->block_erase && flash->eraseblocks[0].count) { + unsigned long done = 0; + int i, j; + for (i = 0; done < flash->total_size * 1024; i++) { + for (j = 0; j < flash->eraseblocks[i].count; j++) { + flash->block_erase(flash, done + flash->eraseblocks[i].size * j); + } + done += flash->eraseblocks[i].count * flash->eraseblocks[i].size; + } + } else if (flash->erase) { + flash->erase(flash); + } else { + fprintf(stderr, "Error: flashrom has no chip erase function for this flash chip.\n"); return 1; } - flash->erase(flash); exit(0); } else if (read_it) { if ((image = fopen(filename, "w")) == NULL) {
On 29.11.2008 02:15, Carl-Daniel Hailfinger wrote:
This is a patch which stores eraseblock sizes in struct flashchip. I decided to fill in the info for a few chips to illustrate how this works both for uniform and non-uniform sector sizes.
Oh, and here is the command I used for conversion: sed -i "s/(TEST_[^,]*,[^,]*,[^,]*,[[:blank:]]*)/{},\t\t\t\t\t\1NULL,\t/" flashchips.c Of course the erase block sizes still need to filled in after the conversion, but it is good enough to verify what I did. The "-i" parameter to sed means in-place and is only available with newer versions.
Regards, Carl-Daniel
From here, I can see 2 problems. 1. the flashchips structure will become even more difficult to read. 2. vaste of memory.
What about a pointer to an eraseblock array ? The last element of the array could be zeroed to indicate the end of the array. Several chips could share the same eraseblock array.
Carl-Daniel Hailfinger a écrit :
This is a patch which stores eraseblock sizes in struct flashchip. I decided to fill in the info for a few chips to illustrate how this works both for uniform and non-uniform sector sizes.
struct eraseblock{ int size; /* Eraseblock size */ int count; /* Number of contiguous blocks with that size */ };
struct eraseblock doesn't correspond with a single erase block, but with a group of contiguous erase blocks having the same size. Given a (top boot block) flash chip with the following weird, but real-life structure:
top 16384 8192 8192 32768 65536 65536 65536 65536 65536 65536 65536 bottom
we get the following encoding: {65536,7},{32768,1},{8192,2},{16384,1}
Although the number of blocks is bigger than 4, the number of block groups is only 4. If you ever add some flash chips with more than 4 contiguous block groups, the definition will not fit into the 4-member array anymore and gcc will recognize that and error out. No undetected overflow possible. In that case, you simply increase array size a bit. For modern flash chips with uniform erase block size, you only need one array member anyway.
Of course data types will need to be changed if you ever get flash chips with more than 2^30 erase blocks, but even with the lowest known erase granularity of 256 bytes, these flash chips will have to have a size of a quarter Terabyte. I'm pretty confident we won't see such big EEPROMs in the near future (or at least not attached in a way that makes flashrom usable). For SPI chips, we even have a guaranteed safety factor of 4096 over the maximum SPI chip size (which is 2^24). And if such a big flash chip has uniform erase block size, you could even split it among the 4 array members. If you change int count to unsigned int count, the storable size doubles. So with a split and a slight change of data type, the maximum ROM chip size is 2 Terabytes.
This patch addresses all comments which came up in the review. Attached for Gmail users.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-eraseblocks/flash.h
--- flashrom-eraseblocks/flash.h (Revision 3776) +++ flashrom-eraseblocks/flash.h (Arbeitskopie) @@ -51,6 +51,11 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+struct eraseblock{
- int size; /* Eraseblock size */
- int count; /* Number of contiguous blocks with that size */
+};
struct flashchip { const char *vendor; const char *name; @@ -64,6 +69,7 @@
int total_size; int page_size;
struct eraseblock eraseblocks[4];
/*
- Indicate if flashrom has been tested with this flash chip and if
@@ -73,6 +79,7 @@
int (*probe) (struct flashchip *flash); int (*erase) (struct flashchip *flash);
- int (*block_erase) (struct flashchip *flash, unsigned long addr); int (*write) (struct flashchip *flash, uint8_t *buf); int (*read) (struct flashchip *flash, uint8_t *buf);
Index: flashrom-eraseblocks/flashchips.c
--- flashrom-eraseblocks/flashchips.c (Revision 3776) +++ flashrom-eraseblocks/flashchips.c (Arbeitskopie) @@ -30,166 +30,166 @@ */ struct flashchip flashchips[] = { /**********************************************************************************************************************************************************************************************************************/
- /* Vendor Chip Vendor ID Chip ID Total size (kB) Page size (B) Test status Probe function Erase function Write function Read function */
- /* Vendor Chip Vendor ID Chip ID Total size (kB) Page size (B) Eraseblocks Test status Probe function Chip erase function Block erase Write function Read function */ /**********************************************************************************************************************************************************************************************************************/
- {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a},
- {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a},
- {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b},
- {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b},
- {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, TEST_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b},
- {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"Atmel", "AT25DF021", ATMEL_ID, AT_25DF021, 256, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF041A", ATMEL_ID, AT_25DF041A, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF081", ATMEL_ID, AT_25DF081, 1024, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF161", ATMEL_ID, AT_25DF161, 2048, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Atmel", "AT25DF321A", ATMEL_ID, AT_25DF321A, 4096, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF641", ATMEL_ID, AT_25DF641, 8192, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25F512B", ATMEL_ID, AT_25F512B, 64, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25FS010", ATMEL_ID, AT_25FS010, 128, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25FS040", ATMEL_ID, AT_25FS040, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT26DF041", ATMEL_ID, AT_26DF041, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL /* Incompatible Page write */,spi_chip_read},
- {"Atmel", "AT26DF081A", ATMEL_ID, AT_26DF081A, 1024, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT26DF161", ATMEL_ID, AT_26DF161, 2048, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"Atmel", "AT26DF161A", ATMEL_ID, AT_26DF161A, 2048, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},
- {"AMD", "Am29F002(N)BB", AMD_ID, AM_29F002BB, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
- {"AMD", "Am29F002(N)BT", AMD_ID, AM_29F002BT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
- {"AMD", "Am29F016D", AMD_ID, AM_29F016D, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, NULL, write_29f040b},
- {"AMD", "Am29F040B", AMD_ID, AM_29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, NULL, write_29f040b},
- {"AMD", "Am29LV040B", AMD_ID, AM_29LV040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_29f040b, erase_29f040b, NULL, write_29f040b},
- {"ASD", "AE49F2008", ASD_ID, ASD_AE49F2008, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"Atmel", "AT25DF021", ATMEL_ID, AT_25DF021, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF041A", ATMEL_ID, AT_25DF041A, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF081", ATMEL_ID, AT_25DF081, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF161", ATMEL_ID, AT_25DF161, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF321", ATMEL_ID, AT_25DF321, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Atmel", "AT25DF321A", ATMEL_ID, AT_25DF321A, 4096, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25DF641", ATMEL_ID, AT_25DF641, 8192, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25F512B", ATMEL_ID, AT_25F512B, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25FS010", ATMEL_ID, AT_25FS010, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT25FS040", ATMEL_ID, AT_25FS040, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT26DF041", ATMEL_ID, AT_26DF041, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL /* Incompatible Page write */,spi_chip_read},
- {"Atmel", "AT26DF081A", ATMEL_ID, AT_26DF081A, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT26DF161", ATMEL_ID, AT_26DF161, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},
- {"Atmel", "AT26DF161A", ATMEL_ID, AT_26DF161A, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read}, /*The AT26DF321 has the same ID as the AT25DF321. */
- /*{"Atmel", "AT26DF321", ATMEL_ID, AT_26DF321, 4096, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, spi_chip_read},*/
- {"Atmel", "AT26F004", ATMEL_ID, AT_26F004, 512, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL /* Incompatible Page write */,spi_chip_read},
- {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec},
- {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"Atmel", "AT45CS1282", ATMEL_ID, AT_45CS1282, 16896/*!*/,1056/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL /* Incompatible Page write */, NULL /* Incompatible read */}, /* No power of two sizes */
- {"Atmel", "AT45DB011D", ATMEL_ID, AT_45DB011D, 128/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB021D", ATMEL_ID, AT_45DB021D, 256/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB041D", ATMEL_ID, AT_45DB041D, 512/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB081D", ATMEL_ID, AT_45DB081D, 1024/*!*/,256/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB161D", ATMEL_ID, AT_45DB161D, 2048/*!*/,512/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB321C", ATMEL_ID, AT_45DB321C, 4224/*!*/,528/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL /* Incompatible read */}, /* No power of two sizes */
- {"Atmel", "AT45DB321D", ATMEL_ID, AT_45DB321D, 4096/*!*/,512/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB642D", ATMEL_ID, AT_45DB642D, 8192/*!*/,1024/*!*/, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002},
- {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002},
- {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002},
- {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, TEST_OK_PREW, probe_29f002, erase_29f002, write_29f002},
- {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, TEST_OK_PR, probe_29f040b, erase_29f040b, write_29f040b},
- {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x},
- {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002},
- {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a},
- {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a},
- {"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, NULL, NULL},
- {"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, NULL, NULL},
- {"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt},
- {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt},
- {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab},
- {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab},
- {"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002},
- {"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, TEST_UNTESTED, probe_29f002, erase_29f002, write_29f002},
- {"Numonyx", "M25PE10", ST_ID, 0x8011, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE20", ST_ID, 0x8012, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE40", ST_ID, 0x8013, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE80", ST_ID, 0x8014, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE16", ST_ID, 0x8015, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x},
- {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x},
- {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, write_lhf00l04},
- {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF032B", SST_ID, SST_25VF032B, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF080B", SST_ID, SST_25VF080B, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_60_c7, spi_chip_write, spi_chip_read},
- {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, TEST_UNTESTED, probe_28sf040, erase_28sf040, write_28sf040},
- {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec},
- {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020},
- {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020},
- {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020},
- {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020},
- {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020},
- {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020},
- {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, write_39sf020},
- /*{"Atmel", "AT26DF321", ATMEL_ID, AT_26DF321, 4096, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL, spi_chip_read},*/
- {"Atmel", "AT26F004", ATMEL_ID, AT_26F004, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL, NULL /* Incompatible Page write */,spi_chip_read},
- {"Atmel", "AT29C020", ATMEL_ID, AT_29C020, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"Atmel", "AT29C040A", ATMEL_ID, AT_29C040A, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"Atmel", "AT45CS1282", ATMEL_ID, AT_45CS1282, 16896/*!*/,1056/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL /* Incompatible Page write */, NULL /* Incompatible read */}, /* No power of two sizes */
- {"Atmel", "AT45DB011D", ATMEL_ID, AT_45DB011D, 128/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB021D", ATMEL_ID, AT_45DB021D, 256/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB041D", ATMEL_ID, AT_45DB041D, 512/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB081D", ATMEL_ID, AT_45DB081D, 1024/*!*/,256/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB161D", ATMEL_ID, AT_45DB161D, 2048/*!*/,512/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB321C", ATMEL_ID, AT_45DB321C, 4224/*!*/,528/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL /* Incompatible read */}, /* No power of two sizes */
- {"Atmel", "AT45DB321D", ATMEL_ID, AT_45DB321D, 4096/*!*/,512/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT45DB642D", ATMEL_ID, AT_45DB642D, 8192/*!*/,1024/*!*/, {}, TEST_BAD_READ, probe_spi_rdid, NULL, NULL, NULL, NULL}, /* Size can only be determined from status register */
- {"Atmel", "AT49F002(N)", ATMEL_ID, AT_49F002N, 256, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"Atmel", "AT49F002(N)T", ATMEL_ID, AT_49F002NT, 256, 256, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"AMIC", "A25L40P", AMIC_ID, AMIC_A25L40P, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid4, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
- {"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_29f002, erase_29f002, NULL, write_29f002},
- {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, {}, TEST_OK_PR, probe_29f040b, erase_29f040b, NULL, write_29f040b},
- {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x},
- {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
- {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
- {"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL},
- {"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL},
- {"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt},
- {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt},
- {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab},
- {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab},
- {"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, {{4096,16}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, {{4096,32}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, {{4096,64}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, {{4096,128}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, {{4096,256}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, {{4096,512}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, {{4096,1024}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, {{4096,2048}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
- {"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
- {"Numonyx", "M25PE10", ST_ID, 0x8011, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE20", ST_ID, 0x8012, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE40", ST_ID, 0x8013, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE80", ST_ID, 0x8014, 1024, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read},
- {"Numonyx", "M25PE16", ST_ID, 0x8015, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_d8, NULL, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"PMC", "Pm49FL002", PMC_ID_NOPREFIX,PMC_49FL002, 256, 16 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x},
- {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, {}, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, NULL, write_49fl00x},
- {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, NULL, write_lhf00l04},
- {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF032B", SST_ID, SST_25VF032B, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"SST", "SST25VF080B", SST_ID, SST_25VF080B, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_60_c7, NULL, spi_chip_write, spi_chip_read},
- {"SST", "SST28SF040A", SST_ID, SST_28SF040, 512, 256, {}, TEST_UNTESTED, probe_28sf040, erase_28sf040, NULL, write_28sf040},
- {"SST", "SST29EE010", SST_ID, SST_29EE010, 128, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"SST", "SST29LE010", SST_ID, SST_29LE010, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"SST", "SST29EE020A", SST_ID, SST_29EE020A, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"SST", "SST29LE020", SST_ID, SST_29LE020, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"SST", "SST39SF010A", SST_ID, SST_39SF010, 128, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"SST", "SST39SF020A", SST_ID, SST_39SF020, 256, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"SST", "SST39SF040", SST_ID, SST_39SF040, 512, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"SST", "SST39VF512", SST_ID, SST_39VF512, 64, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"SST", "SST39VF010", SST_ID, SST_39VF010, 128, 4096, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"SST", "SST39VF020", SST_ID, SST_39VF020, 256, 4096, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"SST", "SST39VF040", SST_ID, SST_39VF040, 512, 4096, {}, TEST_OK_PROBE, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
// assume similar to 004B, ignoring data sheet
- {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub},
- {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub},
- {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub},
- {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc},
- {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub},
- {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc},
- {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc},
- {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_49lf040, write_49lf040},
- {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040},
- {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub},
- {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, TEST_OK_PREW, probe_jedec, erase_49lf040, write_49lf040},
- {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc},
- {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, TEST_OK_PREW, probe_29f040b, erase_29f040b, write_29f040b},
- {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt},
- {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x},
- {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x},
- {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x},
- {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, write_stm50flw0x0x},
- {"ST", "M50FW002", ST_ID, ST_M50FW002, 256, 64 * 1024, TEST_UNTESTED, probe_49lfxxxc, NULL, NULL},
- {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab},
- {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab},
- {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab},
- {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002},
- {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002},
- {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002},
- {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002},
- {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read},
- {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec},
- {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_jedec},
- {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec},
- {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, write_jedec},
- {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_39sf020},
- {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020},
- {"Winbond", "W39V040C", WINBOND_ID, 0x50, 512, 64*1024, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, write_w39v040c},
- {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020},
- {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_39sf020},
- {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002},
- {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_49f002},
- {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002},
- {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub},
- {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, write_winbond_fwhub},
- {"SST", "SST49LF002A/B", SST_ID, SST_49LF002A, 256, 16 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub},
- {"SST", "SST49LF003A/B", SST_ID, SST_49LF003A, 384, 64 * 1024, {}, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub},
- {"SST", "SST49LF004A/B", SST_ID, SST_49LF004A, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub},
- {"SST", "SST49LF004C", SST_ID, SST_49LF004C, 512, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc},
- {"SST", "SST49LF008A", SST_ID, SST_49LF008A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub},
- {"SST", "SST49LF008C", SST_ID, SST_49LF008C, 1024, 4 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc},
- {"SST", "SST49LF016C", SST_ID, SST_49LF016C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc},
- {"SST", "SST49LF020A", SST_ID, SST_49LF020A, 256, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_49lf040, NULL, write_49lf040},
- {"SST", "SST49LF040", SST_ID, SST_49LF040, 512, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, NULL, write_49lf040},
- {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_sst_fwhub, erase_sst_fwhub, NULL, write_sst_fwhub},
- {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, {}, TEST_OK_PREW, probe_jedec, erase_49lf040, NULL, write_49lf040},
- {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, {}, TEST_OK_PREW, probe_49lfxxxc, erase_49lfxxxc, NULL, write_49lfxxxc},
- {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P40-old", ST_ID, ST_M25P40_RES, 512, 256, {}, TEST_UNTESTED, probe_spi_res, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"ST", "M29F002B", ST_ID, ST_M29F002B, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"ST", "M29F002T/NT", ST_ID, ST_M29F002T, 256, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"ST", "M29F040B", ST_ID, ST_M29F040B, 512, 64 * 1024, {}, TEST_OK_PREW, probe_29f040b, erase_29f040b, NULL, write_29f040b},
- {"ST", "M29F400BT", ST_ID, ST_M29F400BT, 512, 64 * 1024, {}, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt},
- {"ST", "M29W010B", ST_ID, ST_M29W010B, 128, 16 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"ST", "M29W040B", ST_ID, ST_M29W040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"ST", "M50FLW040A", ST_ID, ST_M50FLW040A, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x},
- {"ST", "M50FLW040B", ST_ID, ST_M50FLW040B, 512, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x},
- {"ST", "M50FLW080A", ST_ID, ST_M50FLW080A, 1024, 64 * 1024, {}, TEST_OK_PREW, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x},
- {"ST", "M50FLW080B", ST_ID, ST_M50FLW080B, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_stm50flw0x0x, erase_stm50flw0x0x, NULL, write_stm50flw0x0x},
- {"ST", "M50FW002", ST_ID, ST_M50FW002, 256, 64 * 1024, {}, TEST_UNTESTED, probe_49lfxxxc, NULL, NULL, NULL},
- {"ST", "M50FW016", ST_ID, ST_M50FW016, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, NULL, write_82802ab},
- {"ST", "M50FW040", ST_ID, ST_M50FW040, 512, 64 * 1024, {}, TEST_OK_PREW, probe_82802ab, erase_82802ab, NULL, write_82802ab},
- {"ST", "M50FW080", ST_ID, ST_M50FW080, 1024, 64 * 1024, {}, TEST_UNTESTED, probe_82802ab, erase_82802ab, NULL, write_82802ab},
- {"ST", "M50LPW116", ST_ID, ST_M50LPW116, 2048, 64 * 1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"SyncMOS", "S29C31004T", SYNCMOS_ID, S29C31004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"SyncMOS", "S29C51004T", SYNCMOS_ID, S29C51004T, 512, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"Winbond", "W25x10", WINBOND_NEX_ID, W_25X10, 128, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, {}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, {}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
- {"Winbond", "W29C011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"Winbond", "W29C020C", WINBOND_ID, W_29C020C, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_jedec},
- {"Winbond", "W29EE011", WINBOND_ID, W_29C011, 128, 128, {}, TEST_OK_PREW, probe_w29ee011, erase_chip_jedec, NULL, write_jedec},
- {"Winbond", "W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"Winbond", "W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"Winbond", "W39V040C", WINBOND_ID, 0x50, 512, 64*1024, {}, TEST_OK_PREW, probe_w39v040c, erase_w39v040c, NULL, write_w39v040c},
- {"Winbond", "W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"Winbond", "W39V080A", WINBOND_ID, W_39V080A, 1024, 64*1024, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_39sf020},
- {"Winbond", "W49F002U", WINBOND_ID, W_49F002U, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"Winbond", "W49V002A", WINBOND_ID, W_49V002A, 256, 128, {}, TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"Winbond", "W49V002FA", WINBOND_ID, W_49V002FA, 256, 128, {}, TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_49f002},
- {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, {}, TEST_OK_PREW, probe_winbond_fwhub, erase_winbond_fwhub, NULL, write_winbond_fwhub},
- {"Winbond", "W39V080FA (dual mode)",WINBOND_ID, W_39V080FA_DM, 512, 64*1024, {}, TEST_UNTESTED, probe_winbond_fwhub, erase_winbond_fwhub, NULL, write_winbond_fwhub},
- {"Atmel", "unknown Atmel SPI chip",ATMEL_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
- {"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
- {"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
- {"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
- {"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
- {"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{"Atmel", "unknown Atmel SPI chip",ATMEL_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{"EON", "unknown EON SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{"Macronix", "unknown Macronix SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{"PMC", "unknown PMC SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{"SST", "unknown SST SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{"ST", "unknown ST SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 256, {}, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{NULL,}
}; Index: flashrom-eraseblocks/flashrom.c =================================================================== --- flashrom-eraseblocks/flashrom.c (Revision 3776) +++ flashrom-eraseblocks/flashrom.c (Arbeitskopie) @@ -534,11 +534,33 @@
if (erase_it) { printf("Erasing flash chip.\n");
if (!flash->erase) {
fprintf(stderr, "Error: flashrom has no erase function for this flash chip.\n");
if (!flash->block_erase && flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom knows the eraseblock "
"layout, but there is no blockwise erase "
"function for this flash chip. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && !flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom has a blockwise erase "
"function for this flash chip, but the "
"eraseblock layout is unknown. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && flash->eraseblocks[0].count) {
unsigned long done = 0;
int i, j;
for (i = 0; done < flash->total_size * 1024; i++) {
for (j = 0; j < flash->eraseblocks[i].count; j++) {
flash->block_erase(flash, done + flash->eraseblocks[i].size * j);
}
done += flash->eraseblocks[i].count * flash->eraseblocks[i].size;
}
} else if (flash->erase) {
flash->erase(flash);
} else {
}fprintf(stderr, "Error: flashrom has no chip erase function for this flash chip.\n"); return 1;
exit(0); } else if (read_it) { if ((image = fopen(filename, "w")) == NULL) {flash->erase(flash);
-- coreboot mailing list: coreboot@coreboot.org http://www.coreboot.org/mailman/listinfo/coreboot
On Sat, Nov 29, 2008 at 9:15 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
This is a patch which stores eraseblock sizes in struct flashchip. I decided to fill in the info for a few chips to illustrate how this works both for uniform and non-uniform sector sizes.
This is to unify different kinds of things.
Index: flashrom-eraseblocks/flashchips.c
...
{"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
{"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_29f002, erase_29f002, NULL, write_29f002},
...
{"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
{"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
{"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL},
{"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL},
{"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt},
{"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt},
...
{"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, {{4096,16}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, {{4096,32}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, {{4096,64}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, {{4096,128}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, {{4096,256}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, {{4096,512}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, {{4096,1024}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, {{4096,2048}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
{"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
...
From the flash chip names, I guess the chips with uniform erase block
size are serial flash chips, and the ones with non-uniform size are parallel flash chips. I propose a new design the 'flashchip' structure. In this new design, serial and parallel flash chip information is stored in 'serial_flashchip' and 'parallel_flashchip' seperately, with a common 'flashchip_common' internal struct as their first field.
serial_flashchip +------------------+------------------------------+ | flashchip_common | sector_size, block_size, ... | +------------------+------------------------------+
parallel_flashchip +------------------+------------------------------+ | flashchip_common | erase_block | +------------------+------------------------------+
'flashchip_common' contains names, id's and common operation functions.
The design above looks clearer. And There is another advantage.
I guess(confirm and disproof welcome) one chipset only provides one of the two flash interface. When a chipset is detected, we can probe only one kind of them, (hopefully) faster and safer. It is ok if we want to probe the other kind.
Index: flashrom-eraseblocks/flashrom.c
--- flashrom-eraseblocks/flashrom.c (Revision 3776) +++ flashrom-eraseblocks/flashrom.c (Arbeitskopie) @@ -534,11 +534,33 @@
if (erase_it) { printf("Erasing flash chip.\n");
if (!flash->erase) {
fprintf(stderr, "Error: flashrom has no erase function for this flash chip.\n");
if (!flash->block_erase && flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom knows the eraseblock "
"layout, but there is no blockwise erase "
"function for this flash chip. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && !flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom has a blockwise erase "
"function for this flash chip, but the "
"eraseblock layout is unknown. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && flash->eraseblocks[0].count) {
unsigned long done = 0;
int i, j;
for (i = 0; done < flash->total_size * 1024; i++) {
for (j = 0; j < flash->eraseblocks[i].count; j++) {
flash->block_erase(flash, done + flash->eraseblocks[i].size * j);
}
done += flash->eraseblocks[i].count * flash->eraseblocks[i].size;
}
} else if (flash->erase) {
flash->erase(flash);
} else {
fprintf(stderr, "Error: flashrom has no chip erase function for this flash chip.\n"); return 1; }
flash->erase(flash); exit(0); } else if (read_it) { if ((image = fopen(filename, "w")) == NULL) {
No comment to the logic. But the new code has a different degree of detail compared to other 'if (do_it)' blocks(i.e., the for loop).
yu ning
On 29.11.2008 13:23, FENG Yu Ning wrote:
On Sat, Nov 29, 2008 at 9:15 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
This is a patch which stores eraseblock sizes in struct flashchip. I decided to fill in the info for a few chips to illustrate how this works both for uniform and non-uniform sector sizes.
This is to unify different kinds of things.
Yes.
Index: flashrom-eraseblocks/flashchips.c
...
{"AMIC", "A29002B", AMIC_ID_NOPREFIX, AMIC_A29002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
{"AMIC", "A29002T", AMIC_ID_NOPREFIX, AMIC_A29002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_29f002, erase_29f002, NULL, write_29f002},
...
{"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
{"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_OK_PREW, probe_jedec, erase_chip_jedec, NULL, write_en29f002a},
{"Fujitsu", "MBM29F004BC", FUJITSU_ID, MBM29F004BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL},
{"Fujitsu", "MBM29F004TC", FUJITSU_ID, MBM29F004TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_jedec, NULL, NULL, NULL},
{"Fujitsu", "MBM29F400BC", FUJITSU_ID, MBM29F400BC, 512, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,7}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt},
{"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC, 512, 64 * 1024, {{65536,7},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, NULL, write_coreboot_m29f400bt},
...
{"Macronix", "MX25L512", MX_ID, MX_25L512, 64, 256, {{4096,16}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L1005", MX_ID, MX_25L1005, 128, 256, {{4096,32}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L2005", MX_ID, MX_25L2005, 256, 256, {{4096,64}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, {{4096,128}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, {{4096,256}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L1605", MX_ID, MX_25L1605, 2048, 256, {{4096,512}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, {{4096,1024}}, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX25L6405", MX_ID, MX_25L6405, 8192, 256, {{4096,2048}}, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, NULL, spi_chip_write, spi_chip_read},
{"Macronix", "MX29F002B", MX_ID, MX_29F002B, 256, 64 * 1024, {{16384,1},{8192,2},{32768,1},{65536,3}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
{"Macronix", "MX29F002T", MX_ID, MX_29F002T, 256, 64 * 1024, {{65536,3},{32768,1},{8192,2},{16384,1}},TEST_UNTESTED, probe_29f002, erase_29f002, NULL, write_29f002},
...
From the flash chip names, I guess the chips with uniform erase block
size are serial flash chips, and the ones with non-uniform size are parallel flash chips.
We have serial flash chips with non-uniform sector size and parallel flash chips with uniform sector size. We even have some flash chips which have uniform sector size for one erase command and non-uniform sector size for another erase command.
I propose a new design the 'flashchip' structure. In this new design, serial and parallel flash chip information is stored in 'serial_flashchip' and 'parallel_flashchip' seperately, with a common 'flashchip_common' internal struct as their first field.
serial_flashchip +------------------+------------------------------+ | flashchip_common | sector_size, block_size, ... | +------------------+------------------------------+
parallel_flashchip +------------------+------------------------------+ | flashchip_common | erase_block | +------------------+------------------------------+
'flashchip_common' contains names, id's and common operation functions.
The design above looks clearer.
Sorry, this will not work. See above.
And There is another advantage.
I guess(confirm and disproof welcome) one chipset only provides one of the two flash interface. When a chipset is detected, we can probe only one kind of them, (hopefully) faster and safer. It is ok if we want to probe the other kind.
ICH7,ICH8,ICH9,ICH10 and some VIA chipsets can provide SPI and LPC at the same time. (ICH7 has some problems if SPI and FWH are attached, but the other chipsets can do it.)
Index: flashrom-eraseblocks/flashrom.c
--- flashrom-eraseblocks/flashrom.c (Revision 3776) +++ flashrom-eraseblocks/flashrom.c (Arbeitskopie) @@ -534,11 +534,33 @@
if (erase_it) { printf("Erasing flash chip.\n");
if (!flash->erase) {
fprintf(stderr, "Error: flashrom has no erase function for this flash chip.\n");
if (!flash->block_erase && flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom knows the eraseblock "
"layout, but there is no blockwise erase "
"function for this flash chip. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && !flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom has a blockwise erase "
"function for this flash chip, but the "
"eraseblock layout is unknown. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && flash->eraseblocks[0].count) {
unsigned long done = 0;
int i, j;
for (i = 0; done < flash->total_size * 1024; i++) {
for (j = 0; j < flash->eraseblocks[i].count; j++) {
flash->block_erase(flash, done + flash->eraseblocks[i].size * j);
}
done += flash->eraseblocks[i].count * flash->eraseblocks[i].size;
}
} else if (flash->erase) {
flash->erase(flash);
} else {
fprintf(stderr, "Error: flashrom has no chip erase function for this flash chip.\n"); return 1; }
flash->erase(flash); exit(0); } else if (read_it) { if ((image = fopen(filename, "w")) == NULL) {
No comment to the logic. But the new code has a different degree of detail compared to other 'if (do_it)' blocks(i.e., the for loop).
Yes, I can move that out to a separate function.
Regards, Carl-Daniel
On Sat, Nov 29, 2008 at 8:23 PM, FENG Yu Ning fengyuning1984@gmail.com wrote:
On Sat, Nov 29, 2008 at 9:15 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Index: flashrom-eraseblocks/flashrom.c
--- flashrom-eraseblocks/flashrom.c (Revision 3776) +++ flashrom-eraseblocks/flashrom.c (Arbeitskopie) @@ -534,11 +534,33 @@
if (erase_it) { printf("Erasing flash chip.\n");
if (!flash->erase) {
fprintf(stderr, "Error: flashrom has no erase function for this flash chip.\n");
if (!flash->block_erase && flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom knows the eraseblock "
"layout, but there is no blockwise erase "
"function for this flash chip. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && !flash->eraseblocks[0].count) {
fprintf(stderr, "Hint: flashrom has a blockwise erase "
"function for this flash chip, but the "
"eraseblock layout is unknown. "
"Using whole-chip erase.\n");
}
if (flash->block_erase && flash->eraseblocks[0].count) {
unsigned long done = 0;
int i, j;
for (i = 0; done < flash->total_size * 1024; i++) {
for (j = 0; j < flash->eraseblocks[i].count; j++) {
flash->block_erase(flash, done + flash->eraseblocks[i].size * j);
}
done += flash->eraseblocks[i].count * flash->eraseblocks[i].size;
}
} else if (flash->erase) {
flash->erase(flash);
} else {
fprintf(stderr, "Error: flashrom has no chip erase function for this flash chip.\n"); return 1; }
flash->erase(flash); exit(0); } else if (read_it) { if ((image = fopen(filename, "w")) == NULL) {
No comment to the logic. But the new code has a different degree of detail compared to other 'if (do_it)' blocks(i.e., the for loop).
I do have a comment to the logic now. If we want to erase a whole chip, we shall try 'flash->erase' first.
yu ning