Some chips implement the RES (0xab) opcode, but they use a non-standard two byte response instead of the usual one byte response. A two-byte response has the accuracy of REMS and RDID, so don't check for REMS/RDID availability before running a two-byte RES.
Side note: The one-byte RES will fail on wbsio, but it did that in old versions as well. This needs to be fixed in wbsio.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-spi_2byte_res/spi25.c =================================================================== --- flashrom-spi_2byte_res/spi25.c (Revision 1016) +++ flashrom-spi_2byte_res/spi25.c (Arbeitskopie) @@ -67,20 +67,20 @@ return 0; }
-static int spi_res(unsigned char *readarr) +static int spi_res(unsigned char *readarr, int bytes) { unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 }; uint32_t readaddr; int ret;
- ret = spi_send_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr); + ret = spi_send_command(sizeof(cmd), bytes, cmd, readarr); if (ret == SPI_INVALID_ADDRESS) { /* Find the lowest even address allowed for reads. */ readaddr = (spi_get_valid_read_addr() + 1) & ~1; cmd[1] = (readaddr >> 16) & 0xff, cmd[2] = (readaddr >> 8) & 0xff, cmd[3] = (readaddr >> 0) & 0xff, - ret = spi_send_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr); + ret = spi_send_command(sizeof(cmd), bytes, cmd, readarr); } if (ret) return ret; @@ -235,13 +235,15 @@ return 0; }
-int probe_spi_res(struct flashchip *flash) +int probe_spi_res1(struct flashchip *flash) { unsigned char readarr[3]; uint32_t id2; const unsigned char allff[] = {0xff, 0xff, 0xff}; const unsigned char all00[] = {0x00, 0x00, 0x00};
+ /* We only want one-byte RES if RDID and REMS are unusable. */ + /* Check if RDID is usable and does not return 0xff 0xff 0xff or * 0x00 0x00 0x00. In that case, RES is pointless. */ @@ -259,12 +261,13 @@ return 0; }
- if (spi_res(readarr)) + if (spi_res(readarr, 1)) return 0;
- /* FIXME: Handle the case where RES gives a 2-byte response. */ id2 = readarr[0]; + msg_cdbg("%s: id 0x%x\n", __func__, id2); + if (id2 != flash->model_id) return 0;
@@ -275,6 +278,29 @@ return 1; }
+int probe_spi_res2(struct flashchip *flash) +{ + unsigned char readarr[2]; + uint32_t id1, id2; + + if (spi_res(readarr, 2)) + return 0; + + id1 = readarr[0]; + id2 = readarr[1]; + + msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2); + + if (id1 != flash->manufacture_id || id2 != flash->model_id) + return 0; + + /* Print the status register to tell the + * user about possible write protection. + */ + spi_prettyprint_status_register(flash); + return 1; +} + uint8_t spi_read_status_register(void) { const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR }; Index: flashrom-spi_2byte_res/flashchips.c =================================================================== --- flashrom-spi_2byte_res/flashchips.c (Revision 1016) +++ flashrom-spi_2byte_res/flashchips.c (Arbeitskopie) @@ -4665,19 +4665,19 @@
/* The ST M25P05 is a bit of a problem. It has the same ID as the * ST M25P05-A in RES mode, but supports only 128 byte writes instead - * of 256 byte writes. We rely heavily on the fact that probe_spi_res + * of 256 byte writes. We rely heavily on the fact that probe_spi_res1 * only is successful if RDID does not work. */ { .vendor = "ST", .name = "M25P05.RES", .bustype = CHIP_BUSTYPE_SPI, - .manufacture_id = ST_ID, + .manufacture_id = 0, /* Not used. */ .model_id = ST_M25P05_RES, .total_size = 64, .page_size = 256, .tested = TEST_UNTESTED, - .probe = probe_spi_res, + .probe = probe_spi_res1, .probe_timing = TIMING_ZERO, .block_erasers = { @@ -4723,12 +4723,12 @@ .vendor = "ST", .name = "M25P10.RES", .bustype = CHIP_BUSTYPE_SPI, - .manufacture_id = ST_ID, + .manufacture_id = 0, /* Not used. */ .model_id = ST_M25P10_RES, .total_size = 128, .page_size = 256, .tested = TEST_UNTESTED, - .probe = probe_spi_res, + .probe = probe_spi_res1, .probe_timing = TIMING_ZERO, .block_erasers = { @@ -4798,12 +4798,12 @@ .vendor = "ST", .name = "M25P40-old", .bustype = CHIP_BUSTYPE_SPI, - .manufacture_id = ST_ID, + .manufacture_id = 0, /* Not used. */ .model_id = ST_M25P40_RES, .total_size = 512, .page_size = 256, .tested = TEST_UNTESTED, - .probe = probe_spi_res, + .probe = probe_spi_res1, .probe_timing = TIMING_ZERO, .block_erasers = { Index: flashrom-spi_2byte_res/spi.h =================================================================== --- flashrom-spi_2byte_res/spi.h (Revision 1016) +++ flashrom-spi_2byte_res/spi.h (Arbeitskopie) @@ -27,6 +27,7 @@ /* Read Electronic ID */ #define JEDEC_RDID 0x9f #define JEDEC_RDID_OUTSIZE 0x01 +/* INSIZE may be 0x04 for some chips*/ #define JEDEC_RDID_INSIZE 0x03
/* AT25F512A has bit 3 as don't care bit in commands */ @@ -42,6 +43,7 @@ /* Read Electronic Signature */ #define JEDEC_RES 0xab #define JEDEC_RES_OUTSIZE 0x04 +/* INSIZE may be 0x02 for some chips*/ #define JEDEC_RES_INSIZE 0x01
/* Write Enable */ Index: flashrom-spi_2byte_res/chipdrivers.h =================================================================== --- flashrom-spi_2byte_res/chipdrivers.h (Revision 1016) +++ flashrom-spi_2byte_res/chipdrivers.h (Arbeitskopie) @@ -29,7 +29,8 @@ int probe_spi_rdid(struct flashchip *flash); int probe_spi_rdid4(struct flashchip *flash); int probe_spi_rems(struct flashchip *flash); -int probe_spi_res(struct flashchip *flash); +int probe_spi_res1(struct flashchip *flash); +int probe_spi_res2(struct flashchip *flash); int spi_write_enable(void); int spi_write_disable(void); int spi_chip_erase_60(struct flashchip *flash);
On 5/28/10 6:50 PM, Carl-Daniel Hailfinger wrote:
Some chips implement the RES (0xab) opcode, but they use a non-standard two byte response instead of the usual one byte response. A two-byte response has the accuracy of REMS and RDID, so don't check for REMS/RDID availability before running a two-byte RES.
Side note: The one-byte RES will fail on wbsio, but it did that in old versions as well. This needs to be fixed in wbsio.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Stefan Reinauer stepan@coresystems.de
flashrom v0.9.2-r1015 on Linux 2.6.32-22-server (x86_64), built with libpci 3.0.0, GCC 4.4.3, little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OK. No coreboot table found. Found chipset "Intel ICH7/ICH7R", enabling flash write... tried to set 0xdc to 0xb on ICH7/ICH7R failed (WARNING ONLY) WARNING: SPI Configuration Lockdown activated. FAILED! This chipset supports the following protocols: SPI. ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff Found chip "SST SST25LF040A" (512 KB, SPI) at physical address 0xfff80000. ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff No operations were specified.
On 28.05.2010 19:04, Stefan Reinauer wrote:
On 5/28/10 6:50 PM, Carl-Daniel Hailfinger wrote:
Some chips implement the RES (0xab) opcode, but they use a non-standard two byte response instead of the usual one byte response. A two-byte response has the accuracy of REMS and RDID, so don't check for REMS/RDID availability before running a two-byte RES.
Acked-by: Stefan Reinauer stepan@coresystems.de
Thanks, committed in r1017.
Found chipset "Intel ICH7/ICH7R", enabling flash write... [...] WARNING: SPI Configuration Lockdown activated. FAILED! This chipset supports the following protocols: SPI. ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff Found chip "SST SST25LF040A" (512 KB, SPI) at physical address 0xfff80000. ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff ich_spi_send_command: Address 0x000000 below allowed range 0xf80000-0xffffff No operations were specified.
Very nice, thanks for the log. I expect reading/writing to fail because those commands don't care about the minim address yet.
Regards, Carl-Daniel