[flashrom] [PATCH] Fix sfdp_add_uniform_eraser and its usage.

Stefan Tauner stefan.tauner at student.tuwien.ac.at
Mon Feb 20 22:29:02 CET 2012


sfdp_add_uniform_eraser checks for existing erasers. Due to a bug it
looked for eraser slots that have no erase functions set instead of
those that have one set.

Postpone adding an erase function for the special 4k block erase
opcode until we know the flash chip size and add an additional check
to sfdp_add_uniform_eraser.
 # This is the 2nd commit message:

Fix the output of the parameter table contents.

This patch fixes the index used to retrieve the eraser types, which
was off one double word.

Refine some messages and add a few further debugging prints.

---
has been tested with the new emulator to be able to write successfully
and also handle some error cases as expected.

-VV output:
Probing for Unknown SFDP-capable chip, 0 kB: SFDP revision = 1.0
SFDP number of parameter headers is 1 (NPH = 0).

SFDP parameter table header 0/0:
  ID 0x00, version 1.0
  Length 36 B, Parameter Table Pointer 0x000014
Parsing JEDEC flash parameter table...
  3-Byte only addressing.
  Status register is non-volatile and the standard does not allow vendors to tell us whether EWSR/WREN is needed for status register writes - assuming EWSR.
  Write chunk size is at least 64 B.
  Flash chip size is 8192 kB.
  Block eraser 0: 2048 x 4096 B with opcode 0x20
  Tried to add a duplicate block eraser: 2048 x 4096 B with opcode 0x20.
  Block eraser 1: 256 x 32768 B with opcode 0x52
  Block eraser 2: 128 x 65536 B with opcode 0xd8
done.

-VVV:
Probing for Unknown SFDP-capable chip, 0 kB: dummy_map: Mapping flash chip, 0x0 bytes at 0x00000000
spi_sfdp_read_sfdp_chunk: addr=0x0, len=4, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x00 0x00 reading 4 bytes: 0x53 0x46 0x44 0x50
 0x53 0x46 0x44 0x50
spi_sfdp_read_sfdp_chunk: addr=0x4, len=3, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x04 0x00 reading 3 bytes: 0x00 0x01 0x00
 0x00 0x01 0x00
SFDP revision = 1.0
SFDP number of parameter headers is 1 (NPH = 0).
spi_sfdp_read_sfdp_chunk: addr=0x8, len=8, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x08 0x00 reading 8 bytes: 0x00 0x00 0x01 0x09 0x14 0x00 0x00 0xff
 0x00 0x00 0x01 0x09 0x14 0x00 0x00 0xff

SFDP parameter table header 0/0:
  ID 0x00, version 1.0
  Length 36 B, Parameter Table Pointer 0x000014
spi_sfdp_read_sfdp_chunk: addr=0x14, len=8, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x14 0x00 reading 8 bytes: 0xe5 0x20 0xf1 0xff 0xff 0xff 0xff 0x03
 0xe5 0x20 0xf1 0xff 0xff 0xff 0xff 0x03
spi_sfdp_read_sfdp_chunk: addr=0x1c, len=8, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x1c 0x00 reading 8 bytes: 0x44 0xeb 0x08 0x6b 0x08 0x3b 0x80 0xbb
 0x44 0xeb 0x08 0x6b 0x08 0x3b 0x80 0xbb
spi_sfdp_read_sfdp_chunk: addr=0x24, len=8, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x24 0x00 reading 8 bytes: 0xee 0xff 0xff 0xff 0xff 0xff 0x00 0x00
 0xee 0xff 0xff 0xff 0xff 0xff 0x00 0x00
spi_sfdp_read_sfdp_chunk: addr=0x2c, len=8, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x2c 0x00 reading 8 bytes: 0xff 0xff 0x00 0x00 0x0c 0x20 0x0f 0x52
 0xff 0xff 0x00 0x00 0x0c 0x20 0x0f 0x52
spi_sfdp_read_sfdp_chunk: addr=0x34, len=4, data:
dummy_spi_send_command: writing 5 bytes: 0x5a 0x00 0x00 0x34 0x00 reading 4 bytes: 0x10 0xd8 0x00 0x00
 0x10 0xd8 0x00 0x00
  Parameter table contents:
    0x0000:  e5 20 f1 ff  ff ff ff 03
    0x0008:  44 eb 08 6b  08 3b 80 bb
    0x0010:  ee ff ff ff  ff ff 00 00
    0x0018:  ff ff 00 00  0c 20 0f 52
    0x0020:  10 d8 00 00
Parsing JEDEC flash parameter table...
  3-Byte only addressing.
  Status register is non-volatile and the standard does not allow vendors to tell us whether EWSR/WREN is needed for status register writes - assuming EWSR.
  Write chunk size is at least 64 B.
  4kB erase opcode is 0x20.
  Flash chip size is 8192 kB.
  Block eraser 0: 2048 x 4096 B with opcode 0x20
   Sector Type 1 Size: 0x0c
   Sector Type 1 Opcode: 0x20
  Tried to add a duplicate block eraser: 2048 x 4096 B with opcode 0x20.
   Sector Type 2 Size: 0x0f
   Sector Type 2 Opcode: 0x52
  Block Eraser 0 is already occupied.
  Block eraser 1: 256 x 32768 B with opcode 0x52
   Sector Type 3 Size: 0x10
   Sector Type 3 Opcode: 0xd8
  Block Eraser 0 is already occupied.
  Block Eraser 1 is already occupied.
  Block eraser 2: 128 x 65536 B with opcode 0xd8
   Sector Type 4 Size: 0x00
  Sector Type 3 is unused.
done.
===
SFDP has autodetected a flash chip which is not natively supported by flashrom yet.
All standard operations (read, verify, erase and write) should work, but to support all possible features we need to add them manually.
You can help us by mailing us the output of the following command to flashrom at flashrom.org:
'flashrom -VV [plus the -p/--programmer parameter (if needed)]'
Thanks for your help!
===
Found Unknown flash chip "SFDP-capable chip" (8192 kB, SPI) on dummy.

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
---
 sfdp.c |   38 ++++++++++++++++++++++++++------------
 1 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/sfdp.c b/sfdp.c
index 75dfb5f..e1897c7 100644
--- a/sfdp.c
+++ b/sfdp.c
@@ -78,8 +78,10 @@ static int sfdp_add_uniform_eraser(struct flashctx *flash, uint8_t opcode, uint3
 	uint32_t total_size = flash->total_size * 1024;
 	erasefunc_t *erasefn = spi_get_erasefn_from_opcode(opcode);
 
-	if (erasefn == NULL || block_size == 0 || total_size % block_size != 0) {
-		msg_cdbg("%s: invalid input\n", __func__);
+	if (erasefn == NULL || total_size == 0 || block_size == 0 ||
+	    total_size % block_size != 0) {
+		msg_cdbg("%s: invalid input, please report to "
+			 "flashrom at flashrom.org\n", __func__);
 		return 1;
 	}
 
@@ -89,11 +91,12 @@ static int sfdp_add_uniform_eraser(struct flashctx *flash, uint8_t opcode, uint3
 		if (eraser->eraseblocks[0].size == block_size &&
 		    eraser->block_erase == erasefn) {
 			msg_cdbg2("  Tried to add a duplicate block eraser: "
-				  "%d x %d B with opcode 0x%02x\n",
+				  "%d x %d B with opcode 0x%02x.\n",
 				  total_size/block_size, block_size, opcode);
 			return 1;
 		}
-		if (eraser->eraseblocks[0].size != 0 || !eraser->block_erase) {
+		if (eraser->eraseblocks[0].size != 0 ||
+		    eraser->block_erase != NULL) {
 			msg_cspew("  Block Eraser %d is already occupied.\n",
 				  i);
 			continue;
@@ -115,6 +118,7 @@ static int sfdp_add_uniform_eraser(struct flashctx *flash, uint8_t opcode, uint3
 
 static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len)
 {
+	uint8_t opcode_4k_erase = 0xFF;
 	uint32_t tmp32;
 	uint8_t tmp8;
 	uint32_t total_size; /* in bytes */
@@ -181,8 +185,11 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len)
 	}
 
 	if ((tmp32 & 0x3) == 0x1) {
-		sfdp_add_uniform_eraser(flash, (tmp32 >> 8) & 0xFF, 4 * 1024);
-	}
+		opcode_4k_erase = (tmp32 >> 8) & 0xFF;
+		msg_cspew("  4kB erase opcode is 0x%02x.\n", opcode_4k_erase);
+		/* add the eraser later, because we don't know total_size yet */
+	} else
+		msg_cspew("  4kB erase opcode is not defined.\n");
 
 	/* 2. double word */
 	dw = 1;
@@ -204,6 +211,9 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len)
 		return 1;
 	}
 
+	if (opcode_4k_erase != 0xFF)
+		sfdp_add_uniform_eraser(flash, opcode_4k_erase, 4 * 1024);
+
 	/* FIXME: double words 3-7 contain unused fast read information */
 
 	if (len == 4 * 4) {
@@ -213,22 +223,25 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len)
 		goto done;
 	}
 
-	dw = 8;
+	/* 8. double word */
+	dw = 7;
 	for (j = 0; j < 4; j++) {
-		/* 8 double words from the start + 2 words for every eraser */
+		/* 8 double words from the start + 2 bytes for every eraser */
 		tmp8 = buf[(4 * dw) + (2 * j)];
+		msg_cspew("   Sector Type %d Size: 0x%02x\n", j + 1, tmp8);
 		if (tmp8 == 0) {
-			msg_cdbg2("  Block eraser %d is unused.\n", j);
+			msg_cspew("  Sector Type %d is unused.\n", j);
 			continue;
 		}
 		if (tmp8 >= 31) {
-			msg_cdbg2("  Block size of eraser %d (2^%d) is too big "
-				  "for flashrom.\n", j, tmp8);
+			msg_cspew("  Block size of Sector Type %d (2^%d) is "
+				  "too big for flashrom.\n", j, tmp8);
 			continue;
 		}
 		block_size = 1 << (tmp8); /* block_size = 2 ^ field */
 
 		tmp8 = buf[(4 * dw) + (2 * j) + 1];
+		msg_cspew("   Sector Type %d Opcode: 0x%02x\n", j + 1, tmp8);
 		sfdp_add_uniform_eraser(flash, tmp8, block_size);
 	}
 
@@ -332,7 +345,7 @@ int probe_spi_sfdp(struct flashctx *flash)
 			if ((tmp32 % 8) == 0) {
 				msg_cspew("    0x%04x: ", tmp32);
 			}
-			msg_cspew(" %02x", buf[tmp32]);
+			msg_cspew(" %02x", tbuf[tmp32]);
 			if ((tmp32 % 8) == 7) {
 				msg_cspew("\n");
 				continue;
@@ -342,6 +355,7 @@ int probe_spi_sfdp(struct flashctx *flash)
 				continue;
 			}
 		}
+		msg_cspew("\n");
 
 		if (i == 0) { /* Mandatory JEDEC SFDP parameter table */
 			if (hdrs[i].id != 0)
-- 
1.7.1





More information about the flashrom mailing list