Re: Flashrom extension development

Bus Pirate support for the Flashrom project

Flashrom extension development

Postby biosflasher » Fri Jul 30, 2010 11:39 am

I couldn't find any docs for binmode (specifically SPI) buffering in the wiki. Do you have any pointers?
I'd like to add flashrom support for this feature because it has the potential to speed up some writes by a factor of 4, maybe more.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.
biosflasher
Full Member
Full Member
 
Posts: 118
Joined: Mon Nov 16, 2009 7:14 pm

Re: Flashrom extension development

Postby ian » Fri Jul 30, 2010 12:14 pm

Hey Biosflasher - thanks for posting, I've been looking for you :)

Some reported problems with flashrom and the latest firmware. I tested it but didn't have any problems.

The new bulk mode is for PIC programming, but I want to make you a new SPI command for flashrom too.

How about this:
Two new commands. Long write and long read.
Long write:
Write Command|length H|length L|data0|data1|...|datan|
The long write command, with the length of data to buffer then write out SPI (up to 4096 bytes)
Write all the data at once, max speed. The Bus Pirate buffers it first, then writes it out SPI at max speed.
Bus Pirate responds 0x01 at the end of data transmit.

Long read:
Read Command|length H|length L|
Bus Pirate returns up to 0xffff bytes.

I think that will speed things up a ton :) It speeds up PIC programming from minutes for 18K to 1-2 seconds.
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby biosflasher » Sun Aug 01, 2010 8:45 pm

Hey Ian,

thanks for thinking of me and of the needs flashrom has.

ian wrote:Some reported problems with flashrom and the latest firmware. I tested it but didn't have any problems.


Do you have a link to reports? I only heard rumors, but never saw any logs.

There is a known problem with having to reset the Bus Pirate after a flashrom run. I have diagnosed that problem and it's essentially a side effect of the "send 0x00 twenty times to enter bitbang mode". flashrom exits binary SPI mode and raw bitbang mode on regular shutdown until the Bus Pirate is in regular user terminal mode again, but flashrom can't do this if it is killed by the user. On the next flashrom run flashrom will send 0x00 twenty times again, but it will get boatloads of "BBIO1" responses instead of just one response. flashrom can deal with that as well by running a "flush serial line buffer" command, BUT flushing actually does not work reliably. Parts of the buffer are flushed by the OS, but since the Bus Pirate is slow and the FT232 is slow as well, the remaining response from the Bus Pirate might arrive after flushing. I tried flushing five times, and it was not sufficient. I tried flushing five times with a 1.5 ms delay between flushes and that fixed maybe 80% of the problems, but in the end I gave up and flushed 10 times with an 1.5 ms delay between flushes and with those changes I have been unable to break initialization.

I'm looking for testers of that patch at http://patchwork.coreboot.org/patch/1673/ . It works for me, but I have no idea if the rumors about flashrom problems are related or not.

Note: Never trust a flush command to actually do what you want.

ian wrote:The new bulk mode is for PIC programming, but I want to make you a new SPI command for flashrom too.

How about this:
Two new commands. Long write and long read.
Long write:
Write Command|length H|length L|data0|data1|...|datan|
The long write command, with the length of data to buffer then write out SPI (up to 4096 bytes)
Write all the data at once, max speed. The Bus Pirate buffers it first, then writes it out SPI at max speed.
Bus Pirate responds 0x01 at the end of data transmit.

Long read:
Read Command|length H|length L|
Bus Pirate returns up to 0xffff bytes.

I think that will speed things up a ton :) It speeds up PIC programming from minutes for 18K to 1-2 seconds.


A few days ago I committed a patch to flashrom which resulted in a 3x speedup on the Bus Pirate by violating the protocol a bit. It essentially bundles three commands and sends them off before waiting for a response for the first command. Those three commands are: Lower CS#, Read/Write SPI, Raise CS#.

How can flashrom detect the availability of your proposed new mode? I want to make sure that this feature needs zero user interaction (autodetect is needed) and won't break old flashrom versions. Some people won't be able to upgrade their flashrom version, and others won't be able to upgrade their Bus Pirate firmware. We should take care of both groups.

Now on to the technical details:
For writes it is essential that the buffer is big enough to actually write in one go without stopping the clock in between. While most chips can handle a stopped clock just fine, other chips explicitly require that all clock line states (1 or 0) are not longer than 50 us (lowest allowed frequency is 10 kHz). Due to that, flashrom has to take the buffer size of the Bus Pirate into consideration.
The trick of bundling up commands has to continue working or the new feature will essentially make flashing slower than it is right now, and that would be really sad.
However, there is one additional 2x speedup on some writes we could get by being able to bundle six commands: Lower CS#, Read/Write SPI, Raise CS#, Lower CS#, Read/Write SPI, Raise CS#. Most SPI flash write commands are actually two SPI commands in direct succession, and flashrom is able to send them at once if the hardware supports that.
Your proposed SPI read/write commands look good at a first glance. Now if there is a way to make sure the delay between subsequent write and read commands is less than 50 us, this should work out nicely, and we get the advantage of reducing traffic over the serial line by half.

Oh, and while I'm outlining a wishlist there are two things which would result in a ~100x speedup for some commands:
A repeat-until-result-mask command which would mask+compare the SPI response for the previous command against some value and repeat until response&mask=value. Usage would be to send read-status-register to the chip and repeat that until the response from the chip has the work-in-progress bit cleared. Having the ability to limit the number of loops even if the condition is not met would be even better since flashrom doesn't want to be stuck on a dead chip without working diagnostics.
As an alternative (or useful extension), a delay-n-microseconds command for that mode would help as well. Many chips offer a choice between waiting for a fixed time or polling the status register to detect end-of-write.
Either solution would be faster than a full flashrom<->Bus Pirate roundtrip to check the status register.

There is another speed problem I'm having with the Bus Pirate, and I was unable to track down the underlying reason. Communication with the BP is roughly 9x slower than it should be. AFAICS it should be possible to use one USB frame to send a command to the BP, and use the next USB frame to read the response. That would give us a roundtrip time of 2 ms per command (1 ms per USB frame). However, the actual roundtrip time is closer to 18 ms which is really devastating for performance. I've seen reports which indicate the problem exists on Windows and Linux, and it apparently is independent of how much data we're reading or writing from/to the BP. Just to give you an idea of the magnitude of problems: MrHijet needed 10 hours to write 1 MB, and that is totally unacceptable if we could manage this in little more than an hour without my speedups, and maybe 20 minutes or less with all possible speedups for the old BP SPI interface.

Do you have any idea what could cause those massive roundtrip delays?
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.
biosflasher
Full Member
Full Member
 
Posts: 118
Joined: Mon Nov 16, 2009 7:14 pm

Re: Flashrom extension development

Postby ian » Mon Aug 02, 2010 3:10 am

Here's a few posts that I replied to when I double checked everything in v5.2:
http://dangerousprototypes.com/forum/in ... 22#msg6522
http://dangerousprototypes.com/forum/in ... 70#msg5970

The binmode replies 0x00 when a command is unknown, and 0x01 when it is known, that is probably the most straight forward way to test.

I'm not sure about the round trip delays, there is a setting in the FTDI driver that determines how frequently it polls for new data. The delay is long enough that programs that use timeouts (SUMP logic analyzer mode, for example) will frequently timeout waiting for the next packet.You can change it under the control pannel in windows.

I'm not sure what to do about bundling. I'd be happy to add extensions, or even a whole flashrom protocol, but we're nearly out of room in the current chip/firmware ( a few hundred words left). When Bus Pirate v4 comes out we could revisit this again because there will be 4x more space (and an internal USB connection for much faster coms).

For now, I've attached a firmware with three new commands to hopefully go some distance towards removing some of the bottleneck and bulk when doing long data transfers.

case 0b0100: //long read
case 0b0101: //long write
case 0b0110: //long pump
about here in the code:
http://code.google.com/p/the-bus-pirate ... /SPI.c#594

the format for all commands is the same:
command|high 8 length|low 8 length|

Read will then return up to 0xffff bytes as fast as SPI will allow.

Write will buffer up to 4096 bytes and then write them all to SPI as fast as it will allow. At the end of the transfer it returns 0x01. If you ask for more than 4096 bytes in this mode it returns 0x00.

Pump does essentially what you're already doing, but has a check for overflow. Pump moves up to 0xffff bytes from the serial port and puts them on SPI. As long as the SPI can keep up with the UART (it is 8MHz? has 4 byte buffer, probably ok) it will moves bytes as fast as it can. If the SPI buffer fills at any time it stops and sends 0x00.

We could add a configuration option to raise and lower CS automagically for each of these new commands.

Just a note - with the new servo mode and these changes the firmware is too big. I removed the easter egg, but that only gives a few hundred extra words.
Attachments
BPv3-Firmware-v5.5.hex.zip
(54.47 KiB) Downloaded 432 times
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby Sjaak » Mon Aug 02, 2010 3:56 am

Not the easteregg!

[me=Sjaak]cries[/me]

Would it be time to adjust the ID string with a higher version number? Please also make the CS selectable (active high/low)
For my projects and failures see my blog: http://SMDprutser.nl/
User avatar
Sjaak
Fellow
Fellow
 
Posts: 3297
Joined: Sun Jan 03, 2010 2:45 pm
Location: Hiero

Re: Flashrom extension development

Postby ian » Mon Aug 02, 2010 4:09 am

I think we could reclaim a bunch of space if we moved the binary mode to v2 and implemented a consistent interface that doesn't need to have all the stuff repeated for each protocol. I started something like this (new bin) but with all the libraries having different commands it was a lot of trouble and didn't save any space.
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby Sjaak » Mon Aug 02, 2010 5:04 am

It has become trashbin? :D

All the protocols have standard entrypoints for busstart, stop, read , etc. Take a look at the scripting language how to 'binairy' interact with the protocols.
For my projects and failures see my blog: http://SMDprutser.nl/
User avatar
Sjaak
Fellow
Fellow
 
Posts: 3297
Joined: Sun Jan 03, 2010 2:45 pm
Location: Hiero

Re: Flashrom extension development

Postby ian » Mon Aug 02, 2010 5:13 am

It is without a doubt trashbin. It's the binmode protocol that is all over the place. Some of the commands are the same across all binmodes, but some have sniffers, some have bitwise where others have bulk reads, etc.
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby biosflasher » Mon Aug 02, 2010 8:46 am

Hey Ian, thanks a lot for implementing Long Read and Long Write. They look pretty useful to me.

To be honest, I have absolutely no idea what the pump mode does, even after staring at your description and the firmware. A more detailed explanation would be appreciated. Or is the pump mode just a longer variant of the old Read/Write command?

With your new commands, flashrom will get a 2x-21x speedup for reads (UART speed is the limiting factor here), up to a 21x speedup on write for some chips (those supporting page write) and no speedup on write for other chips (those supporting Byte/AAI write).

The new command sequence will be
Lower CS#, Write Long, Read Long, Raise CS# instead of the old
Lower CS#, Write/Read SPI, Raise CS#.
flashrom needs a guarantee that the delay between Write Long and Read Long is not longer than 0.05 ms under any circumstances (e.g. even if the OS is stalling writes over the UART). If that is not possible, flashrom can't use Read Long and will have to fall back to the old method.

Automatic control of CS# looks like a great way to save two Bus Pirate commands per SPI command and would remove the need for the current 3x speedup hack because that 3x speedup would be native.

What happens if flashrom aborts during a Write Long (4096) command because the user killed flashrom? AFAICS on the next flashrom run init will hang because it only sends 20 bytes of 0x00 and waits for a response that won't happen because the Bus Pirate thinks this is still input for the Write Long. Worst case is that flashrom init will hang 205 times before init starts working again. A possible workaround is to send 4096 bytes of 0x00 on init, but that might cause significant startup delays. Would a timeout for Write Long make more sense?

Side note: If firmware space is really that tight, just tell me what the minimum size of the command/UART buffer is, and I will simply bundle up commands until the limit is reached (if the Bus Pirate can handle that). That would probably result in almost the same read speedup (though now write speedup) as the new commands, but without the need for new commands.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.
biosflasher
Full Member
Full Member
 
Posts: 118
Joined: Mon Nov 16, 2009 7:14 pm

Re: Flashrom extension development

Postby ian » Mon Aug 02, 2010 9:03 am

Pump is an alternate write method, instead of storing all the data in a buffer then flushing it out SPI, it just takes from UART and puts it in SPI. This is fine for 10MHZ spi, but at low speeds the SPI buffer (4) will fill and we start to loose data.

Yes, it will just be stuck waiting for the bytes to finish. A timeout could be added eventually.

It seems simple enough to just give you a single flashrom extension, it will take less than the long stuff maybe.

How about this:
command|write H | write L| read H | read L| write data... | read data....

I know we've had this discussion before, but I can't find it... The most common page size is 256bytes as I recall, but many chips can be continuously read from 0 to .... mbits. The OLS flash is 264bytes/page (or something), so it seems to make sense to have more than 256bytes as a write/read minimum, but then one-byte read/write will have a ton of overhead. Are all pages /8 or something? Then we could use a single byte to represent chunks of 256 bytes to read.

This function would have automatic CS. I'll implement it now.
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby ian » Mon Aug 02, 2010 9:24 am

I split this into it's own topic and made a new board for flashrom. It's under BP development right now, but it should probably go up front with the OpenOCD support.

Attached in a new firmware with a command in that format. To ensure that it meets the most stringent timing requirements is gives up some speed and buffers everything:
1. Send any of the old long commands
2. send H/L number of bytes to write (max 4096)
3. send h/l number of bytes to read (max 4096)
4. BP replies 0x01 ok or 0x00 error (too many bytes)
5. Send the write bytes. they are buffered in the Bus Pirate.
6. CS is low, all write bytes are sent at once
7. read starts immediately, all bytes are put into a buffer at max SPI speed (no waiting for UART)
8. ENd of data CS goes high
9. buffered read bytes are returned.

We can optimize how represent the number of read/write bytes for the least overhead and maximum flexibility.
Attachments
BPv3-Firmware-v5.5.hex.zip
(54.51 KiB) Downloaded 426 times
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby biosflasher » Mon Aug 02, 2010 10:15 am

ian wrote:I split this into it's own topic and made a new board for flashrom. It's under BP development right now, but it should probably go up front with the OpenOCD support.

Thanks!

ian wrote:Attached in a new firmware with a command in that format. To ensure that it meets the most stringent timing requirements is gives up some speed and buffers everything:
1. Send any of the old long commands
2. send H/L number of bytes to write (max 4096)
3. send h/l number of bytes to read (max 4096)
4. BP replies 0x01 ok or 0x00 error (too many bytes)
5. Send the write bytes. they are buffered in the Bus Pirate.
6. CS is low, all write bytes are sent at once
7. read starts immediately, all bytes are put into a buffer at max SPI speed (no waiting for UART)
8. ENd of data CS goes high
9. buffered read bytes are returned.

Having dedicated commands for flashrom in the firmware is awesome!
One of the biggest impacts on read/write speed is round trip time. Anything which reduces round trip time is very desirable. One way to avoid the roundtrip at point 4 would be to have a command which queries the buffer size and have flashrom avoid overflows automatically. This would allow us to move point 4 directly before point 9. AFAICS this is worth a 2x speedup.

What do you mean with "old long commands"? The new command you're outlining looks like we should call it flashrom_writeread_spi or something like that, and it would be the only thing flashrom needs.

Side note: The auto-CS# handling might make sense to happen for the really old SPI read/write interface as well, but I'm not sure if there is a point to that. It might have lower overhead for really short writes (no 4 bytes for length needed), but that's pretty much it.

ian wrote:We can optimize how represent the number of read/write bytes for the least overhead and maximum flexibility.

Good point. For starters, flashrom will always write at least 1 byte. This allows us to cram the write size in 12 bits. If we restrict the new command to a read size of 4095 bytes, we can stuff the read size in 12 bits as well. That saves one byte for transmission, but I have no idea if it makes the firmware bigger or smaller. The timing impact is probably negligible for most operations.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.
biosflasher
Full Member
Full Member
 
Posts: 118
Joined: Mon Nov 16, 2009 7:14 pm

Re: Flashrom extension development

Postby ian » Mon Aug 02, 2010 10:27 am

What do you mean with "old long commands"?


It responds to the same command. I just stuck this new command under the same switch as the new commands in the last build.

One way to avoid the roundtrip at point 4 ...


Sorry, that line was accidentally left there when I compiled... It wasn't intended (jsut used it for testing), but in case you tried it I wanted to give you a heads up. I attached a new version without it.

I figure we still need the 0 still if someone wants to do all read or all write in one operation.
Attachments
BPv3-Firmware-v5.5.hex.zip
(54.46 KiB) Downloaded 436 times
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby ian » Mon Aug 02, 2010 10:29 am

1. Send any of the old long commands
2. send H/L number of bytes to write (max 4096)
3. send h/l number of bytes to read (max 4096)
4. Send the write bytes. they are buffered in the Bus Pirate.
5. CS is low, all write bytes are sent at once
6. read starts immediately, all bytes are put into a buffer at max SPI speed (no waiting for UART)
7. ENd of data CS goes high
8. buffered read bytes are returned.
Got a question? Please ask in the forum for the fastest answers.
User avatar
ian
Crew
Crew
 
Posts: 10803
Joined: Mon Jul 06, 2009 6:14 am

Re: Flashrom extension development

Postby biosflasher » Mon Aug 02, 2010 11:47 am

The interface looks really good, and the code is very readable. Thanks!

I'd kill all long commands except one. There is no software out there using them, and they take up valuable space in the firmware. Just tell me which one to use and I'll stick to that.

A getbufsize command (returning OK, hi, lo) would be really appreciated because it has twofold functionality:[list type=decimal]
[*]it allows flashrom to check for the presence of the new command without issuing a SPI command
[*]it allows flashrom to pick the right size for reads/writes on a higher level instead of having to perform error recovery after a too big read/write
[/list]

For most writes, flashrom will send two commands (WRITE_ENABLE and PAGE_WRITE) directly after each other (of course CS# is disabled and enabled in between). WRITE_ENABLE writes 1 byte to SPI and reads 0 bytes. The subsequent PAGE_WRITE writes 5-260 bytes (1 command, 3 address, 1-256 data for classic NOR flash with 256 byte sectors). Can I just send both commands in the same write() to the serial port and wait for their result after both have been sent, or is that a problem with the UART/BP buffer? Such command bundling would result in another 2x speedup.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.
biosflasher
Full Member
Full Member
 
Posts: 118
Joined: Mon Nov 16, 2009 7:14 pm

Next

Return to Flashrom

cron