[flashrom] [PATCH] Fix offset calculation for partial SPI programming

Idwer Vollering vidwer at gmail.com
Wed Oct 27 21:06:31 CEST 2010


2010/10/27 Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at 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 at 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 at 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 at 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 at gmx.net>
>

Acked-by: Idwer Vollering <vidwer at 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;
>        }
>
>
> --
> http://www.hailfinger.org/
>
>
> _______________________________________________
> flashrom mailing list
> flashrom at flashrom.org
> http://www.flashrom.org/mailman/listinfo/flashrom
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.flashrom.org/pipermail/flashrom/attachments/20101027/1d6d7feb/attachment.html>


More information about the flashrom mailing list