Fix internal offset calculations for SPI BYTE PROGRAM and SPI AAI PROGRAM. The bug was invisible so far because we always started at offset 0. The pending partial write patch uses nonzero start offsets and trips over this bug.
Clarify a few comments in IT87 SPI.
Thanks to Idwer Vollering for reporting write breakage with my latest partial write patch. This patch should fix the underlying problem.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-partial_write_spi_fix_offset_calc/it87spi.c =================================================================== --- flashrom-partial_write_spi_fix_offset_calc/it87spi.c (Revision 1216) +++ flashrom-partial_write_spi_fix_offset_calc/it87spi.c (Arbeitskopie) @@ -339,7 +339,10 @@ { /* * IT8716F only allows maximum of 512 kb SPI chip size for memory - * mapped access. It also can't write more than 1+3+256 bytes at once. + * mapped access. It also can't write more than 1+3+256 bytes at once, + * so page_size > 256 bytes needs a fallback. + * FIXME: Split too big page writes into chunks IT87* can handle instead + * of degrading to single-byte program. */ if ((programmer == PROGRAMMER_IT87SPI) || (flash->total_size * 1024 > 512 * 1024) || @@ -349,9 +352,8 @@ int lenhere;
if (start % flash->page_size) { - /* start to the end of the page or start + len, - * whichever is smaller. Page length is hardcoded to - * 256 bytes (IT87 SPI hardware limitation). + /* start to the end of the page or to start + len, + * whichever is smaller. */ lenhere = min(len, flash->page_size - start % flash->page_size); spi_chip_write_1(flash, buf, start, lenhere); @@ -360,7 +362,6 @@ buf += lenhere; }
- /* FIXME: Handle chips which have max writechunk size >1 and <256. */ while (len >= flash->page_size) { it8716f_spi_page_program(flash, buf, start); start += flash->page_size; Index: flashrom-partial_write_spi_fix_offset_calc/spi25.c =================================================================== --- flashrom-partial_write_spi_fix_offset_calc/spi25.c (Revision 1216) +++ flashrom-partial_write_spi_fix_offset_calc/spi25.c (Arbeitskopie) @@ -1309,7 +1309,7 @@ int i, result = 0;
for (i = start; i < start + len; i++) { - result = spi_byte_program(i, buf[i]); + result = spi_byte_program(i, buf[i - start]); if (result) return 1; while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) @@ -1377,6 +1377,14 @@ if (spi_chip_write_1(flash, buf, start, start % 2)) return SPI_GENERIC_ERROR; pos += start % 2; + cmds[1].writearr = (const unsigned char[]){ + JEDEC_AAI_WORD_PROGRAM, + (pos >> 16) & 0xff, + (pos >> 8) & 0xff, + (pos & 0xff), + buf[pos - start], + buf[pos - start + 1] + }; /* Do not return an error for now. */ //return SPI_GENERIC_ERROR; } @@ -1406,8 +1414,8 @@
/* Are there at least two more bytes to write? */ while (pos < start + len - 1) { - cmd[1] = buf[pos++]; - cmd[2] = buf[pos++]; + cmd[1] = buf[pos++ - start]; + cmd[2] = buf[pos++ - start]; spi_send_command(JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL); while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) programmer_delay(10); @@ -1420,7 +1428,7 @@
/* Write remaining byte (if any). */ if (pos < start + len) { - if (spi_chip_write_1(flash, buf + pos, pos, pos % 2)) + if (spi_chip_write_1(flash, buf + pos - start, pos, pos % 2)) return SPI_GENERIC_ERROR; pos += pos % 2; }
2010/10/27 Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Fix internal offset calculations for SPI BYTE PROGRAM and SPI AAI PROGRAM. The bug was invisible so far because we always started at offset 0. The pending partial write patch uses nonzero start offsets and trips over this bug.
Clarify a few comments in IT87 SPI.
Thanks to Idwer Vollering for reporting write breakage with my latest partial write patch. This patch should fix the underlying problem.
With this patch applied: http://patchwork.coreboot.org/patch/2160/
$ sudo ./flashrom -p nicintel_spi -V -w nicintel_spi.rom -c M25P10.RES flashrom v0.9.3-r1215 on FreeBSD 8.1-RELEASE (i386), built with libpci 3.1.7, GCC 4.2.1 20070719 [FreeBSD], little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 1 usecs, 1685M loops per second, delay more than 10% too short (got 85% of expected delay), recalculating... 1929M loops per second, 10 myus = 11 us, 100 myus = 115 us, 1000 myus = 1280 us, 10000 myus = 22197 us, 4 myus = 10 us, OK. Initializing nicintel_spi programmer Found "Intel 82541PI Gigabit Ethernet Controller" (8086:107c, BDF 01:03.0). Requested BAR is MEM, 32bit, not prefetchable Probing for ST M25P10.RES, 128 KB: probe_spi_res1: id 0x10 Chip status register is 00 Found chip "ST M25P10.RES" (128 KB, SPI) at physical address 0xfffe0000. === This flash part has status UNTESTED for operations: PROBE READ ERASE WRITE The test status of this chip may have been updated in the latest development version of flashrom. If you are running the latest development version, please email a report to flashrom@flashrom.org if any of the above operations work correctly for you with this flash part. Please include the flashrom output with the additional -V option for all operations you tested (-V, -Vr, -Vw, -VE), and mention which mainboard or programmer you tested. Please mention your board in the subject line. Thanks for your help! Reading old flash chip contents... Erasing and writing flash chip... Looking at blockwise erase function 0... trying... 0x000000-0x007fff:W, 0x008000-0x00ffff:W, 0x010000-0x017fff:W, 0x018000-0x01ffff:S
Done. Verifying flash... VERIFY FAILED at 0x00008000! Expected=0xc6, Read=0x15, failed byte count from 0x00000000-0x0001ffff: 0x8d75 Your flash chip is in an unknown state. Get help on IRC at irc.freenode.net (channel #flashrom) or mail flashrom@flashrom.org with FAILED: your board name in the subject line! ------------------------------------------------------------------------------- DO NOT REBOOT OR POWEROFF!
With http://patchwork.coreboot.org/patch/2188/
$ sudo ./flashrom -p nicintel_spi -V -w nicintel_spi.rom -c M25P10.RES flashrom v0.9.3-r1216 on FreeBSD 8.1-RELEASE (i386), built with libpci 3.1.7, GCC 4.2.1 20070719 [FreeBSD], little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 5 usecs, 1814M loops per second, 10 myus = 11 us, 100 myus = 106 us, 1000 myus = 925 us, 10000 myus = 8902 us, 20 myus = 38 us, OK. Initializing nicintel_spi programmer Found "Intel 82541PI Gigabit Ethernet Controller" (8086:107c, BDF 01:03.0). Requested BAR is MEM, 32bit, not prefetchable Probing for ST M25P10.RES, 128 KB: probe_spi_res1: id 0x10 Chip status register is 00 Found chip "ST M25P10.RES" (128 KB, SPI) at physical address 0xfffe0000. === This flash part has status UNTESTED for operations: PROBE READ ERASE WRITE The test status of this chip may have been updated in the latest development version of flashrom. If you are running the latest development version, please email a report to flashrom@flashrom.org if any of the above operations work correctly for you with this flash part. Please include the flashrom output with the additional -V option for all operations you tested (-V, -Vr, -Vw, -VE), and mention which mainboard or programmer you tested. Please mention your board in the subject line. Thanks for your help! Reading old flash chip contents... Erasing and writing flash chip... Looking at blockwise erase function 0... trying... 0x000000-0x007fff:W, 0x008000-0x00ffff:W, 0x010000-0x017fff:W, 0x018000-0x01ffff:S
Done. Verifying flash... VERIFIED.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Idwer Vollering vidwer@gmail.com
Index: flashrom-partial_write_spi_fix_offset_calc/it87spi.c
--- flashrom-partial_write_spi_fix_offset_calc/it87spi.c (Revision 1216) +++ flashrom-partial_write_spi_fix_offset_calc/it87spi.c (Arbeitskopie) @@ -339,7 +339,10 @@ { /* * IT8716F only allows maximum of 512 kb SPI chip size for memory
* mapped access. It also can't write more than 1+3+256 bytes at
once.
* mapped access. It also can't write more than 1+3+256 bytes at
once,
* so page_size > 256 bytes needs a fallback.
* FIXME: Split too big page writes into chunks IT87* can handle
instead
* of degrading to single-byte program. */ if ((programmer == PROGRAMMER_IT87SPI) || (flash->total_size * 1024 > 512 * 1024) ||
@@ -349,9 +352,8 @@ int lenhere;
if (start % flash->page_size) {
/* start to the end of the page or start + len,
* whichever is smaller. Page length is hardcoded
to
* 256 bytes (IT87 SPI hardware limitation).
/* start to the end of the page or to start + len,
* whichever is smaller. */ lenhere = min(len, flash->page_size - start %
flash->page_size); spi_chip_write_1(flash, buf, start, lenhere); @@ -360,7 +362,6 @@ buf += lenhere; }
/* FIXME: Handle chips which have max writechunk size >1
and <256. */ while (len >= flash->page_size) { it8716f_spi_page_program(flash, buf, start); start += flash->page_size; Index: flashrom-partial_write_spi_fix_offset_calc/spi25.c =================================================================== --- flashrom-partial_write_spi_fix_offset_calc/spi25.c (Revision 1216) +++ flashrom-partial_write_spi_fix_offset_calc/spi25.c (Arbeitskopie) @@ -1309,7 +1309,7 @@ int i, result = 0;
for (i = start; i < start + len; i++) {
result = spi_byte_program(i, buf[i]);
result = spi_byte_program(i, buf[i - start]); if (result) return 1; while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
@@ -1377,6 +1377,14 @@ if (spi_chip_write_1(flash, buf, start, start % 2)) return SPI_GENERIC_ERROR; pos += start % 2;
cmds[1].writearr = (const unsigned char[]){
JEDEC_AAI_WORD_PROGRAM,
(pos >> 16) & 0xff,
(pos >> 8) & 0xff,
(pos & 0xff),
buf[pos - start],
buf[pos - start + 1]
}; /* Do not return an error for now. */ //return SPI_GENERIC_ERROR; }
@@ -1406,8 +1414,8 @@
/* Are there at least two more bytes to write? */ while (pos < start + len - 1) {
cmd[1] = buf[pos++];
cmd[2] = buf[pos++];
cmd[1] = buf[pos++ - start];
cmd[2] = buf[pos++ - start]; spi_send_command(JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0,
cmd, NULL); while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) programmer_delay(10); @@ -1420,7 +1428,7 @@
/* Write remaining byte (if any). */ if (pos < start + len) {
if (spi_chip_write_1(flash, buf + pos, pos, pos % 2))
if (spi_chip_write_1(flash, buf + pos - start, pos, pos %
2)) return SPI_GENERIC_ERROR; pos += pos % 2; }
flashrom mailing list flashrom@flashrom.org http://www.flashrom.org/mailman/listinfo/flashrom
On 27.10.2010 21:06, Idwer Vollering wrote:
With this patch applied: http://patchwork.coreboot.org/patch/2160/
$ sudo ./flashrom -p nicintel_spi -V -w nicintel_spi.rom -c M25P10.RES flashrom v0.9.3-r1215 on FreeBSD 8.1-RELEASE (i386), built with libpci 3.1.7, GCC 4.2.1 20070719 [FreeBSD], little endian Calibrating delay loop... OK. Initializing nicintel_spi programmer Found "Intel 82541PI Gigabit Ethernet Controller" (8086:107c, BDF 01:03.0). Probing for ST M25P10.RES, 128 KB: probe_spi_res1: id 0x10 Chip status register is 00 Found chip "ST M25P10.RES" (128 KB, SPI) at physical address 0xfffe0000. Reading old flash chip contents... Erasing and writing flash chip... Looking at blockwise erase function 0... trying... 0x000000-0x007fff:W, 0x008000-0x00ffff:W, 0x010000-0x017fff:W, 0x018000-0x01ffff:S Done. Verifying flash... VERIFY FAILED at 0x00008000! Expected=0xc6, Read=0x15, failed byte count from 0x00000000-0x0001ffff: 0x8d75 Your flash chip is in an unknown state.
With http://patchwork.coreboot.org/patch/2188/
$ sudo ./flashrom -p nicintel_spi -V -w nicintel_spi.rom -c M25P10.RES flashrom v0.9.3-r1216 on FreeBSD 8.1-RELEASE (i386), built with libpci 3.1.7, GCC 4.2.1 20070719 [FreeBSD], little endian Calibrating delay loop... OK. Initializing nicintel_spi programmer Found "Intel 82541PI Gigabit Ethernet Controller" (8086:107c, BDF 01:03.0). Probing for ST M25P10.RES, 128 KB: probe_spi_res1: id 0x10 Chip status register is 00 Found chip "ST M25P10.RES" (128 KB, SPI) at physical address 0xfffe0000. Reading old flash chip contents... Erasing and writing flash chip... Looking at blockwise erase function 0... trying... 0x000000-0x007fff:W, 0x008000-0x00ffff:W, 0x010000-0x017fff:W, 0x018000-0x01ffff:S
Done. Verifying flash... VERIFIED.
Great, so this patch indeed fixes the bug you were seeing.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Idwer Vollering vidwer@gmail.com
Thanks, committed in r1217.
Regards, Carl-Daniel