1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-27 07:02:34 +02:00

Add support for two-byte RES probes

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.

Corresponding to flashrom svn r1017.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Stefan Reinauer <stepan@coresystems.de>
This commit is contained in:
Carl-Daniel Hailfinger 2010-05-28 17:07:57 +00:00
parent 80f3d05e73
commit dc1cda15d4
4 changed files with 43 additions and 14 deletions

View File

@ -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);

View File

@ -4665,19 +4665,19 @@ struct flashchip flashchips[] = {
/* 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 @@ struct flashchip flashchips[] = {
.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 @@ struct flashchip flashchips[] = {
.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 =
{

2
spi.h
View File

@ -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 */

38
spi25.c
View File

@ -67,20 +67,20 @@ static int spi_rems(unsigned char *readarr)
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 @@ int probe_spi_rems(struct flashchip *flash)
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 @@ int probe_spi_res(struct flashchip *flash)
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 @@ int probe_spi_res(struct flashchip *flash)
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 };