Hi Fredrik,
On 29.03.2008 23:17, Carl-Daniel Hailfinger wrote:
On 29.03.2008 22:58, Fredrik Tolf wrote:
On Sat, 2008-03-29 at 22:17 +0100, Carl-Daniel Hailfinger wrote:
I'm attaching my patch to fix the problem. I would imagine that the other M25Pxx chips would be affected by the same problem, but since I can neither verify nor test what IDs they would have, they are excluded from my patch.
Thanks for investigating and coding this. However, I have to veto the patch in its current form. I know at least 4 flash chips with different sizes from different manufacturers which have the same RES code. Can you post the RDID output for your device? Maybe we can figure out a way to identify it safely with the help of RDID and RES and possibly READ.
The RDID output was just FF FF FF, so I'm pretty sure it just doesn't recognize the command at all.
Good. That means we can probably use RDID in combination with RES to identify this special ST M25P40 variant.
Can you test the patch below? It should have a lower error probability and work fine for you. If you are OK with my changes to your patch, please re-add your Signed-off-by line.
It would be interesting to try the REMS (0x90) instruction as well and match on that one if possible, but this patch is good enough for now.
Regards, Carl-Daniel
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-res/flash.h =================================================================== --- flashrom-res/flash.h (Revision 3296) +++ flashrom-res/flash.h (Arbeitskopie) @@ -249,6 +249,7 @@ #define ST_M25P10A 0x2011 #define ST_M25P20 0x2012 #define ST_M25P40 0x2013 +#define ST_M25P40_RES 0x12 #define ST_M25P80 0x2014 #define ST_M25P16 0x2015 #define ST_M25P32 0x2016 @@ -347,7 +348,8 @@ extern char *lb_part, *lb_vendor;
/* spi.c */ -int probe_spi(struct flashchip *flash); +int probe_spi_rdid(struct flashchip *flash); +int probe_spi_res(struct flashchip *flash); int it87xx_probe_spi_flash(const char *name); int spi_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); void spi_write_enable(); Index: flashrom-res/flashchips.c =================================================================== --- flashrom-res/flashchips.c (Revision 3296) +++ flashrom-res/flashchips.c (Arbeitskopie) @@ -49,25 +49,25 @@ {"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_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, TEST_UNTESTED, probe_82802ab, erase_82802ab, write_82802ab}, - {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L4005", MX_ID, MX_25L4005, 512, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L3205", MX_ID, MX_25L3205, 4096, 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_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Macronix", "MX25L8005", MX_ID, MX_25L8005, 1024, 256, TEST_UNTESTED, 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}, #ifndef DISABLE_DOC {"M-Systems", "MD-2802", MSYSTEMS_ID, MSYSTEMS_MD2802, 8, 8 * 1024, TEST_UNTESTED, probe_md2802, erase_md2802, write_md2802, read_md2802}, #endif - {"PMC", "Pm25LV010", PMC_ID, PMC_25LV010, 128, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV016B", PMC_ID, PMC_25LV016B, 2048, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV020", PMC_ID, PMC_25LV020, 256, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV040", PMC_ID, PMC_25LV040, 512, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV080B", PMC_ID, PMC_25LV080B, 1024, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"PMC", "Pm25LV512", PMC_ID, PMC_25LV512, 64, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, 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_UNTESTED, probe_jedec, erase_chip_jedec, write_49fl004}, {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49fl004}, {"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_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, TEST_UNTESTED, 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", "SST29EE020A", SST_ID, SST_29EE020A, 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}, @@ -87,15 +87,16 @@ {"SST", "SST49LF040B", SST_ID, SST_49LF040B, 512, 64 * 1024, TEST_UNTESTED, probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub}, {"SST", "SST49LF080A", SST_ID, SST_49LF080A, 1024, 4096, TEST_UNTESTED, probe_jedec, erase_49lf040, write_49lf040}, {"SST", "SST49LF160C", SST_ID, SST_49LF160C, 2048, 4 * 1024, TEST_UNTESTED, probe_49lfxxxc, erase_49lfxxxc, write_49lfxxxc}, - {"ST", "M25P05-A", ST_ID, ST_M25P05A, 64, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P10-A", ST_ID, ST_M25P10A, 128, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P128", ST_ID, ST_M25P128, 16384, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P16", ST_ID, ST_M25P16, 2048, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P20", ST_ID, ST_M25P20, 256, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P32", ST_ID, ST_M25P32, 4096, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P40", ST_ID, ST_M25P40, 512, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P64", ST_ID, ST_M25P64, 8192, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"ST", "M25P80", ST_ID, ST_M25P80, 1024, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"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", "M25P128", ST_ID, ST_M25P128, 16384, 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", "M25P20", ST_ID, ST_M25P20, 256, 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_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", "M25P64", ST_ID, ST_M25P64, 8192, 256, TEST_UNTESTED, probe_spi_rdid, 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", "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_UNTESTED, probe_29f040b, erase_29f040b, write_29f040b}, @@ -114,10 +115,10 @@ {"SyncMOS", "S29C51001T", SYNCMOS_ID, S29C51001T, 128, 128, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, {"SyncMOS", "S29C51002T", SYNCMOS_ID, S29C51002T, 256, 128, TEST_UNTESTED, 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, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x20", WINBOND_NEX_ID, W_25X20, 256, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x40", WINBOND_NEX_ID, W_25X40, 512, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, - {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, TEST_UNTESTED, probe_spi, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"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_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"Winbond", "W25x80", WINBOND_NEX_ID, W_25X80, 1024, 256, TEST_UNTESTED, 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_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, {"Winbond", "W29C040P", WINBOND_ID, W_29C040P, 512, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, @@ -132,11 +133,11 @@ {"Winbond", "W39V080FA", WINBOND_ID, W_39V080FA, 1024, 64*1024, TEST_UNTESTED, 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 SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi, NULL, NULL}, - {"Macronix", "unknown SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi, NULL, NULL}, - {"PMC", "unknown SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi, NULL, NULL}, - {"SST", "unknown SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi, NULL, NULL}, - {"ST", "unknown SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi, NULL, NULL}, + {"EON", "unknown SPI chip", EON_ID_NOPREFIX,GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"Macronix", "unknown SPI chip", MX_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"PMC", "unknown SPI chip", PMC_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"SST", "unknown SPI chip", SST_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi_rdid, NULL, NULL}, + {"ST", "unknown SPI chip", ST_ID, GENERIC_DEVICE_ID, 0, 0, TEST_UNTESTED, probe_spi_rdid, NULL, NULL},
{NULL,} }; Index: flashrom-res/spi.c =================================================================== --- flashrom-res/spi.c (Revision 3296) +++ flashrom-res/spi.c (Arbeitskopie) @@ -36,6 +36,11 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
+/* Read Electronic Signature */ +#define JEDEC_RES 0xab +#define JEDEC_RES_OUTSIZE 0x04 +#define JEDEC_RES_INSIZE 0x01 + /* Write Enable */ #define JEDEC_WREN {0x06} #define JEDEC_WREN_OUTSIZE 0x01 @@ -259,6 +264,16 @@ return 0; }
+static int spi_res(unsigned char *readarr) +{ + const unsigned char cmd[] = {JEDEC_RES, 0, 0, 0}; + + if (spi_command(JEDEC_RES_OUTSIZE, JEDEC_RES_INSIZE, cmd, readarr)) + return 1; + printf_debug("RES returned %02x.\n", readarr[0]); + return 0; +} + void spi_write_enable() { const unsigned char cmd[] = JEDEC_WREN; @@ -275,7 +290,7 @@ spi_command(JEDEC_WRDI_OUTSIZE, JEDEC_WRDI_INSIZE, cmd, NULL); }
-int probe_spi(struct flashchip *flash) +int probe_spi_rdid(struct flashchip *flash) { unsigned char readarr[3]; uint32_t manuf_id; @@ -308,6 +323,35 @@ return 0; }
+int probe_spi_res(struct flashchip *flash) +{ + unsigned char readarr[3]; + uint32_t model_id; + if (!spi_rdid(readarr)) { + /* Check if RDID returns 0xff 0xff 0xff, then we use RES. */ + if ((readarr[0] != 0xff) || (readarr[1] != 0xff) || + (readarr[2] != 0xff)) + return 0; + } else { + /* We couldn't issue RDID, it's pointless to try RES. */ + return 0; + } + if (!spi_res(readarr)) { + model_id = readarr[0]; + printf_debug("%s: id 0x%x\n", __FUNCTION__, model_id); + if (model_id == flash->model_id) { + /* Print the status register to tell the + * user about possible write protection. + */ + spi_prettyprint_status_register(flash); + + return 1; + } + } + + return 0; +} + uint8_t spi_read_status_register() { const unsigned char cmd[] = JEDEC_RDSR;