Am 19.02.2012 20:05 schrieb Stefan Tauner:
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.
Also, the special 4k opcode encoded in the first double word was tried to add with sfdp_add_uniform_eraser
-ENOPARSE
although the total size of the chip was not yet known. This is now postponed and an additional check to sfdp_add_uniform_eraser is added.
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at
this is the last fixup combined with what is described in the second half of the commit log above.
sfdp.c | 18 +++++++++++++----- 1 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/sfdp.c b/sfdp.c index 75dfb5f..80faeca 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 "
return 1; }"flashrom@flashrom.org\n", __func__);
@@ -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 = 0xFF;
rename to opcode_4k_erase?
uint32_t tmp32; uint8_t tmp8; uint32_t total_size; /* in bytes */ @@ -181,7 +185,8 @@ 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);
/* add the eraser later, because we don't know total_size yet */
opcode_4k = (tmp32 >> 8) & 0xFF;
}
/* 2. double word */
@@ -204,6 +209,9 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len) return 1; }
if (opcode_4k != 0xFF)
sfdp_add_uniform_eraser(flash, opcode_4k, 4 * 1024);
/* FIXME: double words 3-7 contain unused fast read information */
if (len == 4 * 4) {
How well-tested is this? I'd rather not have a fixup for the fixup.
Regards, Carl-Daniel
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@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@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@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)