[flashrom] SPI Flashing via Bus-Pirate to DFI T3H6

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Wed Jun 16 16:05:29 CEST 2010


Hi Daniel,

On 16.06.2010 12:41, Daniel Flinkmann wrote:
> I am trying to use the current flashrom together with a Bus-Pirate to re-flash my 
> DFI T3H6 BIOS as it was broken by the official bios update. 
>
> I am using a second computer running Linux and connected the Bus-Pirate to the 
> SPI-Flash Header (DFI call it Bios Download). 
>
> I can only offer the first part, as I had to stop the flashing and will restart it tonight. 
> The erasing of the 8Mbit Flash needed around 60-70 minutes.

Ouch! That should be a lot faster, maybe ~15 minutes or so. The erasing
itself is pretty fast (total maybe 1 second), but we verify if the erase
was successful and for that we have to read the whole chip. That takes time.


> After that I can't see 
> any progress, as -V is pretty silent when writing the flash and -VV dumps far too much 
> to have an overview. 
>   

Yes. Progress bar printing is on our list of useful things to do, but
some parts of the current flashrom architecture don't really fit, and
thus this will require quite some refactoring. I can hack up a progress
printing patch which outputs a dot every time 1024 bytes are
read/written. That would give you some progress indicator for now, and
we can continue fixing flashrom to eventually support something like
that natively.


> I would like to have a block-wise info when writing or verifying the flash, as it will be done when erasing 
> the flash. It would help to have a feeling about the aprox. time it needs and if the flashing is still ongoing.
>
> What is you typical experience with erasing and writing a flash. How many time longer do the writing of the 
> flash need when comparing it with the erasing ?
>   

It depends on the flash chip. Please see the timing discussion at the
end of my mail.


> Flashrom-Log (had to stop flashing, as I had to leave the home to get to work).
>
> # flashrom -p buspirate_spi:dev=/dev/ttyUSB0 -w JX58D422.BIN -V
> flashrom v0.9.2-r1048 on Linux 2.6.32-22-server (x86_64), built with libpci 3.0.0, GCC 4.4.3, little endian
> flashrom is free software, get the source code at http://www.flashrom.org
>
> Calibrating delay loop... OS timer resolution is 1 usecs, 299M loops per second, 10 myus = 11 us, 100 myus = 101 us, 1000 myus = 999 us, 10000 myus = 10113 us, 4 myus = 5 us, OK.
> Initializing buspirate_spi programmer
> SPI speed is 8MHz
> Raw bitbang mode version 1
> Raw SPI mode version 1
> Probing for Atmel AT25DF021, 256 KB: RDID byte 0 parity violation. probe_spi_rdid_generic: id1 0x00, id2 0x00
>   

WTF?!? This looks like data corruption. Such a response is absolutely
unacceptable. Can you run

flashrom -p buspirate_spi:dev=/dev/ttyUSB0 -V

a few times (should be a matter of a few seconds) and check if any
probe_spi_rdid_generic complains about a parity violation? If yes, there
is a bug somewhere which needs to be fixed.


> Probing for Atmel AT25DF041A, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25DF081, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25DF161, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25DF321, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25DF321A, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25DF641, 8192 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25F512B, 64 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25FS010, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT25FS040, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT26DF041, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT26DF081A, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT26DF161, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT26DF161A, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT26F004, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45CS1282, 16896 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB011D, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB021D, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB041D, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB081D, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB161D, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB321C, 4224 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB321D, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Atmel AT45DB642D, 8192 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for AMIC A25L40PT, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for AMIC A25L40PU, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B05, 64 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B05T, 64 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B10, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B10T, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B20, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B20T, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B40, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B40T, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B80, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B80T, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B16, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B16T, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B32, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B32T, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B64, 8192 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25B64T, 8192 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25D16, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25F05, 64 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25F10, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25F20, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25F40, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25F80, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25F16, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Eon EN25F32, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L512, 64 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L1005, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L2005, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L4005, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L8005, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L1605, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L1635D, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L3205, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L3235D, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L6405, 8192 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Macronix MX25L12805, 16384 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Numonyx M25PE10, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Numonyx M25PE20, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Numonyx M25PE40, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Numonyx M25PE80, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Numonyx M25PE16, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for PMC Pm25LV010, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for PMC Pm25LV016B, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for PMC Pm25LV020, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for PMC Pm25LV040, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for PMC Pm25LV080B, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for PMC Pm25LV512, 64 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Sanyo LF25FW203A, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Spansion S25FL008A, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Spansion S25FL016A, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for SST SST25VF016B, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for SST SST25VF032B, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for SST SST25VF040.REMS, 512 KB: probe_spi_rems: id1 0xbf, id2 0x8e
> Probing for SST SST25VF040B, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for SST SST25LF040A.RES, 512 KB: probe_spi_res2: id1 0xbf, id2 0x8e
> Probing for SST SST25VF040B.REMS, 512 KB: probe_spi_rems: id1 0xbf, id2 0x8e
> Probing for SST SST25VF080B, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Chip status register is 1c
> Chip status register: Block Protect Write Disable (BPL) is not set
> Chip status register: Auto Address Increment Programming (AAI) is not set
> Chip status register: Bit 5 / Block Protect 3 (BP3) is not set
> Chip status register: Bit 4 / Block Protect 2 (BP2) is set
> Chip status register: Bit 3 / Block Protect 1 (BP1) is set
> Chip status register: Bit 2 / Block Protect 0 (BP0) is set
> Chip status register: Write Enable Latch (WEL) is not set
> Chip status register: Write In Progress (WIP/BUSY) is not set
> Found chip "SST SST25VF080B" (1024 KB, SPI) at physical address 0xfff00000.
>   

Ouch! That chip can only write one byte at a time. This will be painful
and slow. We might be able to use a few tricks (e.g. AAI write), but
even with the tricks, your flash chip is one of the worst cases for the
Bus Pirate.


> Probing for ST M25P05-A, 64 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P05.RES, 64 KB: Ignoring RES in favour of RDID.
> Probing for ST M25P10-A, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P10.RES, 128 KB: Ignoring RES in favour of RDID.
> Probing for ST M25P20, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P40, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P40-old, 512 KB: Ignoring RES in favour of RDID.
> Probing for ST M25P80, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P16, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P32, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P64, 8192 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for ST M25P128, 16384 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25Q80, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25Q16, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25Q32, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25x10, 128 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25x20, 256 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25x40, 512 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25x16, 2048 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25x32, 4096 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
> Probing for Winbond W25x64, 8192 KB: probe_spi_rdid_generic: id1 0xbf, id2 0x258e
>
> Flash image seems to be a legacy BIOS. Disabling checks.
> Writing flash chip... Some block protection in effect, disabling
> Erasing flash before programming... Erasing flash chip... Looking at blockwise erase function 0... trying... 0x000000-0x000fff, 0x001000-0x001fff, 0x002000-0x002fff, 0x003000-0x003fff, 0x004000-0x004fff, 0x005000-0x005fff, 0x006000-0x006fff, 0x007000-0x007fff, 0x008000-0x008fff, 0x009000-0x009fff, 0x00a000-0x00afff, 0x00b000-0x00bfff, 0x00c000-0x00cfff, 0x00d000-0x00dfff, 0x00e000-0x00efff, 0x00f000-0x00ffff, 0x010000-0x010fff, 0x011000-0x011fff, 0x012000-0x012fff, 0x013000-0x013fff, 0x014000-0x014fff, 0x015000-0x015fff, 0x016000-0x016fff, 0x017000-0x017fff, 0x018000-0x018fff, 0x019000-0x019fff, 0x01a000-0x01afff, 0x01b000-0x01bfff, 0x01c000-0x01cfff, 0x01d000-0x01dfff, 0x01e000-0x01efff, 0x01f000-0x01ffff, 0x020000-0x020fff, 0x021000-0x021fff, 0x022000-0x022fff, 0x023000-0x023fff, 0x024000-0x024fff, 0x025000-0x025fff, 0x026000-0x026fff, 0x027000-0x027fff, 0x028000-0x028fff, 0x029000-0x029fff, 0x02a000-0x02afff, 0x02b000-0x02bfff, 0x02c000-0x02cfff, 0x02d000-0x02dfff, 0x02e000-0x02efff, 0x02f000-0x02ffff, 0x0
> SUCCESS.
> done.
>   

Timing with the Bus Pirate can be calculated as follows:

If we assume the usbserial driver of your OS pushes all bytes of a
read/write at once, we have one USB transaction per read and one
transaction per write. Each transaction takes 1 ms (USB standard).
To send a SPI command to the chip, we need:
- one write/read to activate CS#
- one write/read to send/receive SPI command and response
- one write/read to deactivate CS#
This means a total of 6 transactions and 6 ms per SPI command if we have
optimal conditions.
To read a whole chip, we slice it up in pages of 256 bytes each (some
chips need that) and then we slice each page up in chunks of 12 bytes
each (Bus Pirate read length limit). This means we have 22 chunks per page.
Your chip has 1 MByte (1048576 bytes), 4096 pages and thus 4096*22=90112
read chunks. Each chunk has to be read with a separate command, so the
absolute minimum read timing for your chip with the current code is
90112*6=540672 ms or roughly 9 minutes.

Your chip supports two write modes:
- standard one-byte-at-a-time (write_1) write (default)
- auto address increment (AAI) write
and flashrom uses write_1 mode right now (can be changed).

write_1 mode means you have to send at least three SPI commands to the
chip per written byte: write enable, write byte, read status.
Your chip has 1 MByte (1048576 bytes), needs 1048576 byte writes, thus
1048576*3=3145728 SPI commands, and 3145728*6=18874368 ms or roughly 315
minutes to write in the optimal case, plus the time to verify (full chip
read).

AAI write mode means you have to send at least two SPI commands (or one
SPI command and continuous listening on the SO pin) per two written bytes.
Your chip has 1 MByte (1048576 bytes), needs 1048576/2=524288 AAI
writes, thus 524288*2=1048576 SPI commands, and 1048576*6=6291456 ms or
roughly 105 minutes to write in the optimal case, plus the time to
verify (full chip read).

The current flashrom SPI code has some additional delays which shouldn't
have an effect during erase/read, but I sent a patch to remove them a
few minutes ago. Those delays slow down write a lot, though.

Once the delay removal patch is in, the following options remain:
- Use AAI to speed up write by a factor of 3 compared to the default.
- Violate the Bus Pirate communication protocol and batch each
CS/command/CS combination into one write/read. Should result in a
speedup for read/write/erase by a factor of 3. Not sure if it is doable.
- Violate the Bus Pirate communication protocol some more and batch each
flashrom multicommand into one write/read. Speedup by a factor of 2 for
write.

With enough protocol violations and AAI write, the minimum write time
for your chip is roughly 18 minutes plus the time to read the chip. This
write time can only be achieved if your OS has good usbserial drivers
and if the Bus Pirate is fast enough.

The biggest mystery right now is the 60 minutes required to erase.
Unless I'm mistaken, this means all of the time is spent reading for the
verify operation. Given that my calculations result in 9 minutes read
time, I'd like to know what's going wrong here before you attempt to
write. If this is a problem affecting all operations, you would have to
deal with write taking a day or more. That is totally unacceptable.

Can you measure exactly how long a read of the chip takes, preferably
while no other processes are running in the background on the machine
running flashrom?

Regards,
Carl-Daniel

-- 
http://www.hailfinger.org/






More information about the flashrom mailing list