This wiki is retired
All wiki content available in read-only mode at wiki.flashrom.org
Feel free to cut-n-paste from mails and IRC into this page. Grammar and spelling are not so important.
What numbers do FWH/LPC chips tend to start with?
39/49/50 with 49 being the most common. I've seen 39/49 chips which are parallel but that's ususual. 50 is not very common as model number.
Dirty little secrets why chips are not found although the chipset and the chip are supported
There are a few dirty little secrets about probing for flash EEPROMs:
1. old parallel flash chips often need a special board enable or the flash chip will ignore any commands (get ID, erase, write)
(that's the case with most boards of PIIX4 or older era, flash chip model names are usually *29*) Also, many *28* chips require high voltage to respond to any identification routines.
2. modern chipsets usually have more than one flash bus, and some boards even have additional bus translation chips
so for modern boards you have to check the LPC/FWH bus of the chipset, then you check the SPI bus of the chipset (if supported by the chipset and supported by flashrom), then you check the SPI bus of any LPC-to-SPI bus translation chip
on the M2N68, we only probe for LPC chips, but the chip on the board is SPI
that means the SPI chip is either attached to the SPI bus of the chipset (and we don't have a driver for that due to lack of docs) or it is behind some LPC/SPI translation chip (some of which we support)
the translation test is performed with -p it87spi
As you can see, it's complicated. Worst of all, autodetection is basically impossible.
3. To top it off, on some boards the BIOS disables all chip writes (which are needed for ID) and then it locks the chipset and unlocking is only possible by resetting (after reset, the BIOS runs and locks everything down again).
Command set secrets
This is only mentioned in very few datasheets, but it applies to most parallel (and some LPC) chips I saw: Upper address bits of commands are ignored if they are not mentioned explicitly. If a datasheet specifies the following sequence:
chip_writeb(0xAA, bios + 0x555); chip_writeb(0x55, bios + 0x2AA); chip_writeb(0x90, bios + 0x555);
then it is quite likely the following sequence will work as well
chip_writeb(0xAA, bios + 0x5555); chip_writeb(0x55, bios + 0x2AAA); chip_writeb(0x90, bios + 0x5555);
However, if the chip datasheet specifies addresses like 0x5555, you can't shorten them to 0x555.
To summarize, replacing short addresses with long addresses usually works, but the other way round usually fails.
Writing or reusing a probe function
If you have a chip with id1 0xc2, id2 0x18, first run
to get an overview of the probe results for the existing probe functions. There's a good chance you'll find a probe function (or even many of them) that works for you. To automate this, run
flashrom -V|grep "0xc2.*0x18"|sed "s/.*probe/probe/"|sort|uniq
and you get a neat list of probe function names and their results, looking roughly like this:
probe_29f002: id1 0xc2, id2 0x18 probe_29f040b: id1 0xc2, id2 0x18 probe_jedec: id1 0xc2, id2 0x18 probe_stm50flw0x0x: id1 0xc2, id2 0x18 probe_w39v040c: id1 0xc2, id2 0x18 probe_winbond_fwhub: id1 0xc2, id2 0x18
As you can see, there are quite a lot of probe functions which seem to work fine (and that's mostly because of the ignored address bits). probe_jedec is the most-used function in our tree, so if the sequence looks ok, please use that one.
In general, you should try to fill in the probe timing info even if the current probe function ignores it. Someone may later try to unify your probe function with another one, possibly with probe_jedec and you help this person a lot if he/she doesn't have to look up the timing info. To sumarize,
.probe_timing = TIMING_IGNORED,
is not liked that much. If the datasheet doesn't say anything useful about timing (such a phrase is "standard microporocessor timing"), you can use
.probe_timing = TIMING_FIXME,
and if the datasheet says there should be no delays (or doesn't mention delays at all), you should use
.probe_timing = TIMING_ZERO,
There's a special case:
.probe_timing = 0,
will give an error because flashrom assumes you just forgot to fill it in.
If you didn't test the chip, use
.tested = TEST_UNTESTED,
If you tested and everything (probe, read, erase, write) worked, use
.tested = TEST_OK_PREW,
If you only tested parts (e.g. probe and read) of the functionality, use
.tested = TEST_OK_PR,
If you tested and some things work and others failed (e.g. probe worked, erase failed), use
.tested = TEST_OK_PROBE|TEST_BAD_ERASE,
All TEST_* definitions are in flash.h.
Shadowing the ROM is either happening below 1 MB (old 16bit address space), and we don't care about that area, regardless of how much you shadow. Or it is happening close to 4 GB, but for that you either need a processor which can handle non-contiguous RAM (basically, AMD, but only if you don't use onboard video) or if you have 4 GB installed in the machine and don't mind very very weird problems on bootup so basically it is very very extremely unlikely that shadowing can bite us.
But, other features like bios flashing protection set in bios are affecting flashrom.
Bios content changes between reboots
Many BIOSes out there change a few bytes in the ROM on each boot. They store boot date/time and some configuration data. Such changes are expected. As long as the readback doesn't change between subsequent reads (without any boot in between), you're in the clear.
And if you are patient enough you can figure what bios change and where.
Writing a chip driver
For parallel/LPC/FWH chips:
- Check if you can use the stuff in jedec.c . If yes, use the functions directly instead of copying them.
- If jedec.c is not compatible with your chip, try to find a chip driver file which works for your chip. Use these functions directly instead of copying them.
For SPI chips:
- spi.c contains both chip-specific command functions and SPI general infrastructure. Try to find compatible functions in there and use them directly instead of copying. spi.c will be split into infrastructure and chip commands in the future, so check if this note still applies.
For all chips:
- Hook up the driver functions in flashchips.c . Easiest way is to copy the entry for a similar chip and modify as needed.
- IDs are defined in flashchips.h which also acts as a database for IDs not yet hooked up and IDs which are aliases for other chips (see the comments in there).
Writing a programmer driver
This task entirely depends on the communication protocol you want to use for talking to the chip. There are two main interface classes: Address-value pairs (Parallel/LPC/FWH protocols) and explicit commands (SPI). Our generic programmer infrastructure can handle both, even in the same programmer.
The easiest way to get started is to hack dummyflasher.c which supports both interface classes. You get immediate results by running
flashrom -p dummy
without having to touch a single line outside dummyflasher.c . Once your hacked up dummyflasher does something useful (that means it differs in a nontrivial way from vanilla dummyflasher), we strongly suggest post it to the mailing list. Then we can help you separate your code from dummyflasher and make it a real driver on its own (some of us have predefined templates for that). You don't have to touch any code or Makefile outside your driver if you don't want to.
A new programmer driver is automatically added to the output of flashrom --help and the only file you have to touch outside your own driver file is the man page. Qualified help is available for that task, so you can get by with supplying the text if you don't know man page syntax.
Generally, we recommend to submit early and often, even if your code is nowhere near ready. Maybe someone else already has unfinished/unreleased code for your favourite programmer.
Programmer drivers can be merged even if they are not completely working yet, but they will be disabled by default in that case. You save yourself the hassle of carring a large patch forward and can contentrate on driver development instead of forward porting your patch every few commits (which is painful to do over large time periods). Plus, your code gets some exposure on the list and interested users may help with development and debugging.
Flash chip locking
(In case you wondered, this is not about concurrent execution.)