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.
$ 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!
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;
}
--
http://www.hailfinger.org/
_______________________________________________
flashrom mailing list
flashrom@flashrom.org
http://www.flashrom.org/mailman/listinfo/flashrom