Yey, it worked - well, partially at least. I just tested it against 0.9.3 sources, and since it patched with only two slight offsets, I gave it a go. The SST chip got written and verified correctly, though erasing failed. Unfortunately my coreboot rom image seems not fully functional, so I'll have to dig that problem - tomorrow :)
Many thanks, jankes
2011/3/3 Michael Karcher flashrom@mkarcher.dialup.fu-berlin.de:
Reported by: Michal Janke jankeso@gmail.com
flashrom -V: http://paste.flashrom.org/view.php?id=370 lspci: http://paste.flashrom.org/view.php?id=371 superiotool: http://paste.flashrom.org/view.php?id=372 and http://www.flashrom.org/pipermail/flashrom/2011-March/005878.html
Signed-off-by: Michael Karcher flashrom@mkarcher.dialup.fu-berlin.de
board_enable.c | 29 +++++++++++++++++++++++------ 1 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/board_enable.c b/board_enable.c index 5776bf5..26c5fbc 100644 --- a/board_enable.c +++ b/board_enable.c @@ -543,7 +543,10 @@ static int it8707f_write_enable_2e(void) return it8707f_write_enable(0x2e); }
-static int pc87360_gpio_set(uint8_t gpio, int raise) +#define PC87360_ID 0xE1 +#define PC87364_ID 0xE4
+static int pc8736x_gpio_set(uint8_t chipid, uint8_t gpio, int raise) { static const int bankbase[] = {0, 4, 8, 10, 12}; int gpio_bank = gpio / 8; @@ -552,13 +555,13 @@ static int pc87360_gpio_set(uint8_t gpio, int raise) uint8_t id, val;
if (gpio_bank > 4) {
- msg_perr("PC87360: Invalid GPIO %d\n", gpio);
- msg_perr("PC8736x: Invalid GPIO %d\n", gpio);
return -1; }
id = sio_read(0x2E, 0x20);
- if (id != 0xE1) {
- msg_perr("PC87360: unexpected ID %02x\n", id);
- if (id != chipid) {
- msg_perr("PC8736x: unexpected ID %02x (expected %02x)\n", id, chipid);
return -1; }
@@ -1483,9 +1486,22 @@ static int board_hp_vl400(void) int ret; ret = intel_ich_gpio_set(25, 1); /* Master write enable ? */ if (!ret)
- ret = pc87360_gpio_set(0x09, 1); /* #WP ? */
- ret = pc8736x_gpio_set(PC87360_ID, 0x09, 1); /* #WP ? */
- if (!ret)
- ret = pc8736x_gpio_set(PC87360_ID, 0x27, 1); /* #TBL */
- return ret;
+}
+/*
- Suited for:
- - HP e-Vectra P2706T: 810E + ICH + PC87364
- */
+static int board_hp_p2706t(void) +{
- int ret;
- ret = pc8736x_gpio_set(PC87364_ID, 0x25, 1);
if (!ret)
- ret = pc87360_gpio_set(0x27, 1); /* #TBL */
- ret = pc8736x_gpio_set(PC87364_ID, 0x26, 1);
return ret; }
@@ -1940,6 +1956,7 @@ const struct board_pciid_enable board_pciid_enables[] = { {0x8086, 0x24c3, 0x1458, 0x24c2, 0x8086, 0x24cd, 0x1458, 0x5004, NULL, NULL, NULL, "GIGABYTE", "GA-8PE667 Ultra 2", 0, OK, intel_ich_gpio32_raise}, {0x10DE, 0x026C, 0x1458, 0xA102, 0x10DE, 0x0260, 0x1458, 0x5001, NULL, NULL, NULL, "GIGABYTE", "GA-K8N51GMF-9", 0, OK, nvidia_mcp_gpio3b_raise}, {0x10DE, 0x0050, 0x1458, 0x0C11, 0x10DE, 0x005e, 0x1458, 0x5000, NULL, NULL, NULL, "GIGABYTE", "GA-K8N-SLI", 0, OK, nvidia_mcp_gpio21_raise},
- {0x8086, 0x2415, 0x103c, 0x1250, 0x10b7, 0x9200, 0x103c, 0x1247, NULL, NULL, NULL, "HP", "e-Vectra P2706T", 0, OK, board_hp_p2706t},
{0x1166, 0x0223, 0x103c, 0x320d, 0x14e4, 0x1678, 0x103c, 0x703e, NULL, "hp", "dl145_g3", "HP", "ProLiant DL145 G3", 0, OK, board_hp_dl145_g3_enable}, {0x1166, 0x0223, 0x103c, 0x320d, 0x14e4, 0x1648, 0x103c, 0x310f, NULL, "hp", "dl165_g6", "HP", "ProLiant DL165 G6", 0, OK, board_hp_dl165_g6_enable}, {0x8086, 0x2580, 0x103c, 0x2a08, 0x8086, 0x2640, 0x103c, 0x2a0a, NULL, NULL, NULL, "HP", "Puffer2-UL8E", 0, OK, intel_ich_gpio18_raise}, -- 1.7.2.3
Am Freitag, den 04.03.2011, 00:59 +0100 schrieb Michał Janke:
two slight offsets, I gave it a go. The SST chip got written and verified correctly, though erasing failed.
That sounds quite strange to me as successful erasing is a prerequisite for writing. Maybe flashrom had to fall back on an alternate erase method. Can you provide verbose logs of what you describe here, please?
Regards, Michael Karcher
2011/3/4 Michael Karcher flashrom@mkarcher.dialup.fu-berlin.de:
Am Freitag, den 04.03.2011, 00:59 +0100 schrieb Michał Janke:
two slight offsets, I gave it a go. The SST chip got written and verified correctly, though erasing failed.
That sounds quite strange to me as successful erasing is a prerequisite for writing. Maybe flashrom had to fall back on an alternate erase method. Can you provide verbose logs of what you describe here, please?
Well, it IS strange - sometimes the chip gets flashed ok in spite of an error during erease and sometimes there is either no such error or the error causes writing to fail. I attach a console script log showing how it looks like (a series ofnon-verbose flashing attempts) and one verbose log.
Regards, Michael Karcher
Am Freitag, den 04.03.2011, 22:45 +0100 schrieb Michał Janke:
Well, it IS strange - sometimes the chip gets flashed ok in spite of an error during erease and sometimes there is either no such error or the error causes writing to fail. I attach a console script log showing how it looks like (a series ofnon-verbose flashing attempts) and one verbose log.
It looks like sometimes the erase command doesn't get through to the chip. We try two different erase methods, first erasing 4K blocks and then we try erasing 64K blocks. The whole process only fails of both erase methods fail (i.e. you get "ERASE FAILED at 0x...." twice). Thanks for the logs, we have to check what we can find in flashrom. Some thing you could try is: Do you get the random failures also in single user mode? There might be something performing concurrent access to the flash chip (like some ACPI stuff) or interrupts causing too high delays between flash access cycles make write commands not recognize. Having no background tasks mitigates the latency problem.
Regards, Michael Karcher
Am Freitag, den 04.03.2011, 22:45 +0100 schrieb Michał Janke:
Well, it IS strange - sometimes the chip gets flashed ok in spite of an error during erease and sometimes there is either no such error or the error causes writing to fail. I attach a console script log showing how it looks like (a series ofnon-verbose flashing attempts) and one verbose log.
[This is a HP board with i810 chipset and an SST49LF004A flash chip that randomly ignores erase instructions, both sector or block erase]
As we found out in a private IRC discussion, the observed random failure of erase commands (command seems to get ignored by the chip) disappear on either of - using current flashrom with interleaved erase/write - removing the programmer_delay(10) calls from erase_sector_jedec_common
But they are still present on current flashrom in erase-only mode (flashrom -E), so it's no general change in flashrom behaviour. Also switching to single user mode did not help.
If I understand it correctly, the delays in erase_sector_jedec_common are mostly for chips that need commands to be written so slowly - these chips should require a probe delay, too. So would there be a problem to put these delays into a "probe timing not zero" test?
Regards, Michael Karcher
Auf 05.03.2011 00:30, Michael Karcher schrieb:
Am Freitag, den 04.03.2011, 22:45 +0100 schrieb Michał Janke:
Well, it IS strange - sometimes the chip gets flashed ok in spite of an error during erease and sometimes there is either no such error or the error causes writing to fail. I attach a console script log showing how it looks like (a series ofnon-verbose flashing attempts) and one verbose log.
[This is a HP board with i810 chipset and an SST49LF004A flash chip that randomly ignores erase instructions, both sector or block erase]
As we found out in a private IRC discussion, the observed random failure of erase commands (command seems to get ignored by the chip) disappear on either of
- using current flashrom with interleaved erase/write
- removing the programmer_delay(10) calls from
erase_sector_jedec_common
But they are still present on current flashrom in erase-only mode (flashrom -E), so it's no general change in flashrom behaviour. Also switching to single user mode did not help.
If I understand it correctly, the delays in erase_sector_jedec_common are mostly for chips that need commands to be written so slowly - these chips should require a probe delay, too. So would there be a problem to put these delays into a "probe timing not zero" test?
AFAIK the erase delay is used on chips which need the probe delay anyway, so your test would indeed cover those problems. However, there is one exception: Winbond W39V040C. See the mail at http://www.flashrom.org/pipermail/flashrom/2009-December/001330.html We could add a new feature bit for this...
I strongly support your approach, but we should handle W39V040C as corner case.
Regards, Carl-Daniel
Hello Carl-Daniel,
Am Samstag, den 05.03.2011, 22:30 +0100 schrieb Carl-Daniel Hailfinger:
If I understand it correctly, the delays in erase_sector_jedec_common are mostly for chips that need commands to be written so slowly - these chips should require a probe delay, too. So would there be a problem to put these delays into a "probe timing not zero" test?
AFAIK the erase delay is used on chips which need the probe delay anyway, so your test would indeed cover those problems. However, there is one exception: Winbond W39V040C. See the mail at http://www.flashrom.org/pipermail/flashrom/2009-December/001330.html We could add a new feature bit for this...
I don't see how that is related, except for also covering some erase problems. My idea was about removing the delays between the command bytes, while that patch slows down the toggle bit detection. I did not intent to change the toggle bit stuff or use the non-slow call. Do I miss something?
Regards, Michael Karcher
Auf 05.03.2011 23:57, Michael Karcher schrieb:
Hello Carl-Daniel,
Am Samstag, den 05.03.2011, 22:30 +0100 schrieb Carl-Daniel Hailfinger:
If I understand it correctly, the delays in erase_sector_jedec_common are mostly for chips that need commands to be written so slowly - these chips should require a probe delay, too. So would there be a problem to put these delays into a "probe timing not zero" test?
AFAIK the erase delay is used on chips which need the probe delay anyway, so your test would indeed cover those problems. However, there is one exception: Winbond W39V040C. See the mail at http://www.flashrom.org/pipermail/flashrom/2009-December/001330.html We could add a new feature bit for this...
I don't see how that is related, except for also covering some erase problems. My idea was about removing the delays between the command bytes, while that patch slows down the toggle bit detection. I did not intent to change the toggle bit stuff or use the non-slow call. Do I miss something?
Ah OK, misunderstanding on my side. Please go ahead.
Regards, Carl-Daniel
It is extremely unlikely that a chip not requiring delays in probe does require them in erase. We observed unreliable erasing with a SST49LF004A with these delays, so remove them if the are not required.
Signed-off-by: Michael Karcher flashrom@mkarcher.dialup.fu-berlin.de --- jedec.c | 33 +++++++++++++++++++++------------ 1 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/jedec.c b/jedec.c index 199c64d..822de88 100644 --- a/jedec.c +++ b/jedec.c @@ -242,21 +242,24 @@ static int erase_sector_jedec_common(struct flashchip *flash, unsigned int page, unsigned int pagesize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int delay_us = 10; + if(flash->probe_timing != TIMING_ZERO) + delay_us = 0;
/* Issue the Sector Erase command */ chip_writeb(0xAA, bios + (0x5555 & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x55, bios + (0x2AAA & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x80, bios + (0x5555 & mask)); - programmer_delay(10); + programmer_delay(delay_us);
chip_writeb(0xAA, bios + (0x5555 & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x55, bios + (0x2AAA & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x30, bios + page); - programmer_delay(10); + programmer_delay(delay_us);
/* wait for Toggle bit ready */ toggle_ready_jedec_slow(bios); @@ -272,6 +275,9 @@ static int erase_block_jedec_common(struct flashchip *flash, unsigned int block, unsigned int blocksize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int delay_us = 10; + if(flash->probe_timing != TIMING_ZERO) + delay_us = 0;
/* Issue the Sector Erase command */ chip_writeb(0xAA, bios + (0x5555 & mask)); @@ -302,21 +308,24 @@ static int erase_chip_jedec_common(struct flashchip *flash, unsigned int mask) { int total_size = flash->total_size * 1024; chipaddr bios = flash->virtual_memory; + int delay_us = 10; + if(flash->probe_timing != TIMING_ZERO) + delay_us = 0;
/* Issue the JEDEC Chip Erase command */ chip_writeb(0xAA, bios + (0x5555 & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x55, bios + (0x2AAA & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x80, bios + (0x5555 & mask)); - programmer_delay(10); + programmer_delay(delay_us);
chip_writeb(0xAA, bios + (0x5555 & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x55, bios + (0x2AAA & mask)); - programmer_delay(10); + programmer_delay(delay_us); chip_writeb(0x10, bios + (0x5555 & mask)); - programmer_delay(10); + programmer_delay(delay_us);
toggle_ready_jedec_slow(bios);