hello! i'm new to the list and my first post will tell something about adding the second bios chip to that board.
first of all some informations on my mainboard, because i haven't read this informations on the mailinglist until now.
i always read about SST25LF040A and MX25L4005A chips which are used for bios on that mainboard. my mainboard which is also revision 2.0 has a different bios chip, which a device from winbond called 25X40VSIG. here's the link to the datasheet of this chip: www.winbond-usa.com/products/Nexflash/pdfs/datasheets/W25X10_20_40_80g.pdf this is just a statement, that there are also boards with that bios-chips out there.
linuxbios will not be tested by me on the 25X40VSIG chip, because i want to remain that chip in it's original state.
i've got two MX25L4005A chips, and i *want* to test linuxbios on my mainboard. so yesterday i bought some soldering equipment, and the things i need to do the job.
Peter Stuge has posted an introduction to add another chip to the second "bios-port" on the mainboard (http://linuxbios.org/pipermail/linuxbios/2007-September/024395.html; http://stuge.se/lb/m57sli/). after studing the datasheet's of the chips, i was certain that it'll be correct what he told just a few weeks before.
what you'll need to get the stuff working: * 2 resistors, i took 100k ohm with 0.25Watt * a SPDT switch * an serial eeprom in an soic case with about 200mil. * equipment to solder * some time to do the job
first i wanted to boot the machine with the "hardware hack" on it, the fans started to move, but i got no response from my monitor. but, after changing the position of the switch, it just worked like usual! (on that point i knew, that i've soldered everything correct. because when the empty chip is activated, there is no data sent from the bios chip to the superio.)
after booting the machine, i made a svn co of the linuxbios flashrom util, compiled it and had a look if it will work. so, here are my output results from the flashrom util:
original bios chip: %<--------------------------------------------------------- benchvice flashrom # ./flashrom --mainboard gigabyte:m57sli Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned ef 30 13 No EEPROM/flash device found. benchvice flashrom # %<--------------------------------------------------------
after changing the position of the spdt switch: %<-------------------------------------------------------- benchvice flashrom # ./flashrom --mainboard gigabyte:m57sli Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0 xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned c2 20 13 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) No operations were specified. benchvice flashrom # %<----------------------------------------------------------------
after all that information i made for sure some pictures, and following the topic here they are: http://illmeyer.com/hg87/LICENSE http://illmeyer.com/hg87/dscf1597.jpg http://illmeyer.com/hg87/dscf1608.jpg http://illmeyer.com/hg87/dscf1617.jpg http://illmeyer.com/hg87/dscf1621.jpg http://illmeyer.com/hg87/dscf1624.jpg http://illmeyer.com/hg87/dscf1628.jpg http://illmeyer.com/hg87/dscf1629.jpg http://illmeyer.com/hg87/dscf1630.jpg http://illmeyer.com/hg87/dscf1631.jpg
at the and i want to thank j0hn for the chip.
regards, harald gutmann
trying to flash the new chip with flashrom fails right now, but i don't know why.
here is the output from flashrom, when i try to flash the linuxbios.rom file: ./flashrom -V --mainboard gigabyte:m57sli -w /home/hg87/src/linuxbios/buildrom-devel/linuxbios.rom Calibrating delay loop... 291M loops per second. ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. Probing for Am29F040B, 512 KB probe_29f040b: id1 0xff, id2 0xff Probing for Am29F016D, 2048 KB probe_29f040b: id1 0xff, id2 0xff Probing for AE49F2008, 256 KB probe_jedec: id1 0xff, id2 0xff Probing for At29C040A, 512 KB probe_jedec: id1 0xff, id2 0xff Probing for At29C020, 256 KB probe_jedec: id1 0xff, id2 0xff Probing for Mx29f002, 256 KB probe_29f002: id1 0xff, id2 0xff Probing for MX25L4005, 512 KB RDID returned c2 20 13 probe_spi: id1 0xc2, id2 0x2013 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) LinuxBIOS last image size (not rom size) is 4096 bytes. MANUFACTURER: GIGABYTE MAINBOARD ID: m57sli This firmware image matches this motherboard. Segmentation fault. benchvice flashrom # ls -lh /home/hg87/src/linuxbios/buildrom-devel/linuxbios.rom -rw-r--r-- 1 hg87 hg87 512K 12. Okt 22:59 /home/hg87/src/linuxbios/buildrom-devel/linuxbios.rom benchvice flashrom #
tomorrow i'll have a more detailed look on that problem, because i've to leave now.
regards, harald
just talking to myselv, but here are some more detailed informations including a backtrace of flashrom: i removed stripping and optimisation, but added the debug flag in makefile.
benchvice flashrom # file flashrom flashrom: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, statically linked, not stripped benchvice flashrom # gdb ./flashrom GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu"... Using host libthread_db library "/lib/libthread_db.so.1". (gdb) run --mainboard gigabyte:m57sli -V -w /home/hg87/src/linuxbios/buildrom-devel/linuxbios.rom Starting program: /home/hg87/src/linuxbios/LinuxBIOSv3/util/flashrom/flashrom --mainboard gigabyte:m57sli -V -w /home/hg87/src/linuxbios/buildrom-devel/linuxbios.rom Calibrating delay loop... 348M loops per second. ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. Probing for Am29F040B, 512 KB probe_29f040b: id1 0xff, id2 0xff Probing for Am29F016D, 2048 KB probe_29f040b: id1 0xff, id2 0xff Probing for AE49F2008, 256 KB probe_jedec: id1 0xff, id2 0xff Probing for At29C040A, 512 KB probe_jedec: id1 0xff, id2 0xff Probing for At29C020, 256 KB probe_jedec: id1 0xff, id2 0xff Probing for Mx29f002, 256 KB probe_29f002: id1 0xff, id2 0xff Probing for MX25L4005, 512 KB RDID returned c2 20 13 probe_spi: id1 0xc2, id2 0x2013 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) LinuxBIOS last image size (not rom size) is 4096 bytes. MANUFACTURER: GIGABYTE MAINBOARD ID: m57sli This firmware image matches this motherboard.
Program received signal SIGSEGV, Segmentation fault. 0x0000000000000000 in ?? () (gdb) bt #0 0x0000000000000000 in ?? () #1 0x00000000004068f4 in main (argc=6, argv=0x7fff7540a148) at flashrom.c:460 (gdb) c Continuing.
Program terminated with signal SIGSEGV, Segmentation fault. The program no longer exists. (gdb) quit benchvice flashrom #
On 13.10.2007 15:59, Harald Gutmann wrote:
just talking to myselv, but here are some more detailed informations including a backtrace of flashrom: i removed stripping and optimisation, but added the debug flag in makefile.
benchvice flashrom # file flashrom flashrom: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, statically linked, not stripped benchvice flashrom # gdb ./flashrom GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu"... Using host libthread_db library "/lib/libthread_db.so.1". (gdb) run --mainboard gigabyte:m57sli -V -w /home/hg87/src/linuxbios/buildrom-devel/linuxbios.rom Starting program: /home/hg87/src/linuxbios/LinuxBIOSv3/util/flashrom/flashrom --mainboard gigabyte:m57sli -V -w /home/hg87/src/linuxbios/buildrom-devel/linuxbios.rom Calibrating delay loop... 348M loops per second. ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. Probing for Am29F040B, 512 KB probe_29f040b: id1 0xff, id2 0xff Probing for Am29F016D, 2048 KB probe_29f040b: id1 0xff, id2 0xff Probing for AE49F2008, 256 KB probe_jedec: id1 0xff, id2 0xff Probing for At29C040A, 512 KB probe_jedec: id1 0xff, id2 0xff Probing for At29C020, 256 KB probe_jedec: id1 0xff, id2 0xff Probing for Mx29f002, 256 KB probe_29f002: id1 0xff, id2 0xff Probing for MX25L4005, 512 KB RDID returned c2 20 13 probe_spi: id1 0xc2, id2 0x2013 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) LinuxBIOS last image size (not rom size) is 4096 bytes. MANUFACTURER: GIGABYTE MAINBOARD ID: m57sli This firmware image matches this motherboard.
Program received signal SIGSEGV, Segmentation fault. 0x0000000000000000 in ?? () (gdb) bt #0 0x0000000000000000 in ?? () #1 0x00000000004068f4 in main (argc=6, argv=0x7fff7540a148) at flashrom.c:460 (gdb) c Continuing.
Program terminated with signal SIGSEGV, Segmentation fault. The program no longer exists. (gdb) quit benchvice flashrom #
That's a NULL pointer dereference because SPI erase/write suppport is not enabled yet. I have patches pending.
Carl-Daniel
On Fri, Oct 12, 2007 at 08:40:02PM +0200, Harald Gutmann wrote:
first i wanted to boot the machine with the "hardware hack" on it, the fans started to move, but i got no response from my monitor. but, after changing the position of the switch, it just worked like usual! (on that point i knew, that i've soldered everything correct. because when the empty chip is activated, there is no data sent from the bios chip to the superio.)
Excellent job! The soldering looks great - very impressive if this was the first time you soldered electronics. :)
Also great to have confirmation that the hardware hack works!
Thank you very much.
after booting the machine, i made a svn co of the linuxbios flashrom util, compiled it and had a look if it will work.
I'm not sure if flashrom actually works with the SPI chips yet.
Carl-Daniel was working on it but I don't remember what the status is.
//Peter
Am Samstag, 13. Oktober 2007 17:17:15 schrieb Peter Stuge:
Excellent job! The soldering looks great - very impressive if this was the first time you soldered electronics. :)
no, it wasn't the first time that i soldered, but i don't often solder.
Also great to have confirmation that the hardware hack works!
according to the flashrom probing output, it works. also the response of the computer on trying to boot with the emtpy bios-chip is a good sign, that it works how it should.
Thank you very much.
no prob.
after booting the machine, i made a svn co of the linuxbios flashrom util, compiled it and had a look if it will work.
I'm not sure if flashrom actually works with the SPI chips yet.
Carl-Daniel was working on it but I don't remember what the status is.
according to Uwe Hermann the write function in current svn version is a NULL function, and not implemented right now. i've to less knowledge in programming and c, to implement that function, but if testers were needed, i'll do it, because i can switch back to the original bios chip easily.
//Peter
On Sat, Oct 13, 2007 at 05:39:51PM +0200, Harald Gutmann wrote:
according to Uwe Hermann the write function in current svn version is a NULL function, and not implemented right now.
Correct - Carl-Daniel did the SPI detection work, but we don't have read/write support yet.
I have updated the M57SLI build tutorial to indicate that the SOIC hardware hack has been confirmed. I really need to get the components so I can do it too on my board.
Thanks! Ward.
Am Samstag, 13. Oktober 2007 18:32:28 schrieb Ward Vandewege:
I have updated the M57SLI build tutorial to indicate that the SOIC hardware hack has been confirmed. I really need to get the components so I can do it too on my board.
thanks for adding it to the wiki, because i've no account right now. getting these chips is quite hard, here in europe, but i'd recommend you, to try to get a serial eeprom, with more capacity, because with the mx25l4005 you just have 512kb space, and linuxbios with LAB as payload would require 1024kb.
as reported here (http://linuxbios.org/pipermail/linuxbios/2007-September/024494.html), it is no problem to use an eeprom with more capacity. also documented (here http://linuxbios.org/pipermail/linuxbios/2007-September/024189.html and here http://linuxbios.org/pipermail/linuxbios/2007-September/024196.html) is, that the clock signal is either 16mhz or 25mhz, but not the 85mhz wich are documented in the 85mhz wich the MX25L4005A has. so i think, that it should be no problem to add an s.eeprom with more capacity and lower clock rate. (and also the manufacturer shouldn't mind. when the technical specifications are the same/nearly the same).
Thanks! Ward.
regards, harald
On Sat, Oct 13, 2007 at 07:30:29PM +0200, Harald Gutmann wrote:
thanks for adding it to the wiki, because i've no account right now.
I would've put my description on the wiki but haven't had time. If anyone wants to use my text or pictures please go ahead.
getting these chips is quite hard, here in europe,
I have a couple of 8Mbit SST25VF080B sample chips that I can pass on. I can't sell them but if you pay for postage I'll send you one or two. They are in WSON package which is footprint compatible with SOIC but not quite as easy to work with because no pins are exposed.
I can probably also get hold of chips for resale if there is need.
but i'd recommend you, to try to get a serial eeprom,
An important clarification here. If you buy a "serial EEPROM" you'll get something quite different from the SPI flash that is needed for the Gigabyte board. (They also come in SOIC but have an I2C interface and sizes are rarely in the megabits, usually they're only a few kbytes.) Please don't confuse the two since they are not compatible.
with more capacity, because with the mx25l4005 you just have 512kb space, and linuxbios with LAB as payload would require 1024kb.
Indeed - 8Mbit or more is the way to go.
no problem to use an eeprom with more capacity.
Again important to note that none of the suitable chips will be EEPROM, only flash ROM. Depending on who you purchase your chips from, confusing the two terms may cause a big problem. (Ie. you getting unusable chips.)
//Peter
Peter Stuge wrote:
getting these chips is quite hard, here in europe,
I have a couple of 8Mbit SST25VF080B sample chips that I can pass on. I can't sell them but if you pay for postage I'll send you one or two. They are in WSON package which is footprint compatible with SOIC but not quite as easy to work with because no pins are exposed.
I can probably also get hold of chips for resale if there is need.
Yes please, I got a M57SLI months ago, but it is series 2. I got the "wrong series 1 chips", and have not made any progress since. I have tried to order the needed BIOS chip, but will no success. I have a local computer shop who will do the soldering, (I am a programmer and would not have a clue on engineering).
Please contact me if you can get the chip required to modify a recent series 2 mother board.
Chris Lingard
Am Sonntag, 14. Oktober 2007 03:45:10 schrieb Peter Stuge:
I have a couple of 8Mbit SST25VF080B sample chips that I can pass on. I can't sell them but if you pay for postage I'll send you one or two. They are in WSON package which is footprint compatible with SOIC but not quite as easy to work with because no pins are exposed.
i think to do that circuit with wson packaged chips will be quite hard, because you can't "lift" the CS# pin that easy like with the sop packaged chips. and i contacted a few people i know, which maybe can get these chips a little easyer than me, over ther company/employers.
//Peter
regards, harald
On Sun, Oct 14, 2007 at 01:22:37PM +0200, Harald Gutmann wrote:
I can't sell them but if you pay for postage I'll send you one or two. They are in WSON package which is footprint compatible with SOIC but not quite as easy to work with because no pins are exposed.
i think to do that circuit with wson packaged chips will be quite hard, because you can't "lift" the CS# pin that easy like with the sop packaged chips.
Hehe, that's true. :) One way to get around it is to just cut the trace on the board and solder the chip down to all pads.
and i contacted a few people i know, which maybe can get these chips a little easyer than me, over ther company/employers.
I'll get in touch with the distributors here. Will get back when I know more.
//Peter
Peter Stuge wrote:
and i contacted a few people i know, which maybe can get these chips a little easyer than me, over ther company/employers.
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go? Smaller quantities like 3 or 4 come pre-programmed here
Chris Lingard
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
Smaller quantities like 3 or 4 come pre-programmed here
That's not a problem per se, you can always erase and reprogram, but usually there is a rather high cost for the service. :\
//Peter
Am Donnerstag, 18. Oktober 2007 01:10:03 schrieb Peter Stuge:
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
the chips go up to 32mbit with 50mhz to 75/85mhz and 8 pins, but i wasn't able to find them in europe until now. 64mbit are only available with 16 pins.
farnell has an sst chip with right pin position, speed (50mhz) and 16mb in its store. which cost's about 3€. farnell has also sockels for that chips in his store, but they cost much more. (about 22€).
i've an second MX25L4005 here, if someone would like to have it, i can send it. (the chip will be for free, and shipping costs maybe to, depends on how much this will be.)
regards, harald
On Thu, Oct 18, 2007 at 04:59:36PM +0200, Harald Gutmann wrote:
Am Donnerstag, 18. Oktober 2007 01:10:03 schrieb Peter Stuge:
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
the chips go up to 32mbit with 50mhz to 75/85mhz and 8 pins, but i wasn't able to find them in europe until now. 64mbit are only available with 16 pins.
farnell has an sst chip with right pin position, speed (50mhz) and 16mb in its store. which cost's about 3€.
What type number is that?
Thanks, Ward.
Am Donnerstag, 18. Oktober 2007 17:05:30 schrieb Ward Vandewege:
On Thu, Oct 18, 2007 at 04:59:36PM +0200, Harald Gutmann wrote:
Am Donnerstag, 18. Oktober 2007 01:10:03 schrieb Peter Stuge:
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
the chips go up to 32mbit with 50mhz to 75/85mhz and 8 pins, but i wasn't able to find them in europe until now. 64mbit are only available with 16 pins.
farnell has an sst chip with right pin position, speed (50mhz) and 16mb in its store. which cost's about 3€.
16Mbit Chip: SST25VF016B-50-4I-S2AF
SOIC 8Pin Sockel: 652B0082215-002
What type number is that?
Thanks, Ward.
-- Ward Vandewege ward@fsf.org Free Software Foundation - Senior System Administrator
On 18.10.2007 17:13, Harald Gutmann wrote:
Am Donnerstag, 18. Oktober 2007 17:05:30 schrieb Ward Vandewege:
On Thu, Oct 18, 2007 at 04:59:36PM +0200, Harald Gutmann wrote:
Am Donnerstag, 18. Oktober 2007 01:10:03 schrieb Peter Stuge:
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
the chips go up to 32mbit with 50mhz to 75/85mhz and 8 pins, but i wasn't able to find them in europe until now. 64mbit are only available with 16 pins.
farnell has an sst chip with right pin position, speed (50mhz) and 16mb in its store. which cost's about 3€.
16Mbit Chip: SST25VF016B-50-4I-S2AF
Do not order a lot of SST chips, they are much more difficult to support with the current flashrom architecture. You could order one and check if they support the RDID instruction (data sheet is silent about RDID), but I have no idea if they do. EON chips have other pitfalls, but they should theoretically still be easier to support.
Regards, Carl-Daniel
On 18.10.2007 22:58, Carl-Daniel Hailfinger wrote:
On 18.10.2007 17:13, Harald Gutmann wrote:
Am Donnerstag, 18. Oktober 2007 17:05:30 schrieb Ward Vandewege:
On Thu, Oct 18, 2007 at 04:59:36PM +0200, Harald Gutmann wrote:
Am Donnerstag, 18. Oktober 2007 01:10:03 schrieb Peter Stuge:
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
> I'll get in touch with the distributors here. Will get back when > I know more. > > I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
the chips go up to 32mbit with 50mhz to 75/85mhz and 8 pins, but i wasn't able to find them in europe until now. 64mbit are only available with 16 pins.
farnell has an sst chip with right pin position, speed (50mhz) and 16mb in its store. which cost's about 3€.
16Mbit Chip: SST25VF016B-50-4I-S2AF
Do not order a lot of SST chips, they are much more difficult to support with the current flashrom architecture. You could order one and check if they support the RDID instruction (data sheet is silent about RDID), but I have no idea if they do.
I now found a SST data sheet (not easily found on the official web site) that talks about RDID, so adding support for it should be possible.
Regards, Carl-Daniel
Peter Stuge wrote:
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
Sorry more dumb questions. Do I want SLTSST25LF040A-33-4C-S2AE ---5.4mm Body or SLTSST25LF040A-33-4C-S2E ------4mm Body
My BIOS chip appears over 5mm
Also flashrom does not detect the BIOS chip, there is no code for this type. So how will flashrom be able to write to the BIOS?
Chris Lingard
Am Montag, 22. Oktober 2007 21:56:32 schrieb Chris Lingard:
Peter Stuge wrote:
On Wed, Oct 17, 2007 at 08:47:41PM +0100, Chris Lingard wrote:
I'll get in touch with the distributors here. Will get back when I know more.
I have been trying to get my M57SLI Rev2.0 SPI running LinuxBios for a while, but could not get the chip
Sorry, no news from me yet, I hardly have time to check my email this week.
I have been offered a batch of SST25LF040A brand new unprogrammed for US $3 each. If this a good price and a way to go?
Fairly good price, depending on how many a batch is? 30-or so pieces could go for $3, but you probably want to look for 25LF080A instead then to get more room. Maybe there's a 16Mbit version too.
Sorry more dumb questions. Do I want SLTSST25LF040A-33-4C-S2AE ---5.4mm Body or SLTSST25LF040A-33-4C-S2E ------4mm Body
My BIOS chip appears over 5mm
Also flashrom does not detect the BIOS chip, there is no code for this type. So how will flashrom be able to write to the BIOS?
without a modification in the flashrom source code it will not be possible to write to this chip.
Chris Lingard
Harald
On 22.10.2007 22:31, Harald Gutmann wrote:
Am Montag, 22. Oktober 2007 21:56:32 schrieb Chris Lingard:
Also flashrom does not detect the BIOS chip, there is no code for this type. So how will flashrom be able to write to the BIOS?
without a modification in the flashrom source code it will not be possible to write to this chip.
The problem is that this specific chip does not appear to support the RDID instruction (at least the data sheet is silent about it). If it supports RDID, adding support for it is easy once somebody has run flashrom -V on that chip. Ask your seller/distributor about JEDEC-RDID instruction support before you buy.
I have no idea about the correct form factor, though.
Regards, Carl-Daniel
Harald Gutmann wrote:
Am Montag, 22. Oktober 2007 21:56:32 schrieb Chris Lingard:
without a modification in the flashrom source code it will not be possible to write to this chip.
Is there an idiots guide to writing sst25lf040a.c, like modifying one of the other sst*.c files. I have a data sheet :-)
On 22.10.2007 22:56, Chris Lingard wrote:
Harald Gutmann wrote:
Am Montag, 22. Oktober 2007 21:56:32 schrieb Chris Lingard:
without a modification in the flashrom source code it will not be possible to write to this chip.
Is there an idiots guide to writing sst25lf040a.c, like modifying one of the other sst*.c files. I have a data sheet :-)
The problem is with probing, not with writing. Look at my other mail.
Regards, Carl-Daniel
after a friend of mine (wolfgang illmeyer) implemented the code to write to the spi chip, i can finally give you the following output:
%<-------------------------------------------------------------------- benchvice flashrom # ./flashrom -m gigabyte:m57sli -w /home/hg87/src/linuxbios/buildrom-devel/linuxbios_onchip.rom Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned c2 20 13 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) benchvice flashrom # ./flashrom -m gigabyte:m57sli -v /home/hg87/src/linuxbios/buildrom-devel/linuxbios_onchip.rom Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned c2 20 13 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) Verifying flash - VERIFIED benchvice flashrom # %<------------------------------------------------------------------------------
i didn't try to boot the linuxbios until now, and the code is quite ugly and not cleaned up these times.
i'll try to get the code cleaned up in the next few days, and poste the code to the list. but now, i try to boot the linuxbios.
regards, harald
On 15.10.2007 00:41, Harald Gutmann wrote:
after a friend of mine (wolfgang illmeyer) implemented the code to write to the spi chip, i can finally give you the following output:
Great!
%<-------------------------------------------------------------------- benchvice flashrom # ./flashrom -m gigabyte:m57sli -w /home/hg87/src/linuxbios/buildrom-devel/linuxbios_onchip.rom Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned c2 20 13 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) benchvice flashrom # ./flashrom -m gigabyte:m57sli -v /home/hg87/src/linuxbios/buildrom-devel/linuxbios_onchip.rom Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned c2 20 13 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) Verifying flash - VERIFIED benchvice flashrom # %<------------------------------------------------------------------------------
i didn't try to boot the linuxbios until now, and the code is quite ugly and not cleaned up these times.
i'll try to get the code cleaned up in the next few days, and poste the code to the list.
Great, thanks! The code I have also is not polished, so even if your code is ugly, it is better than no code. We can clean up that stuff together.
I have a few patches pending to flashrom which restructure the SPI code, but they don't change function prototypes, so your code is likely to work fine even after my changes.
but now, i try to boot the linuxbios.
Good luck!
Regards, Carl-Daniel
Am Montag, 15. Oktober 2007 01:06:00 schrieb Carl-Daniel Hailfinger:
Great, thanks! The code I have also is not polished, so even if your code is ugly, it is better than no code. We can clean up that stuff together.
yes, that's right! here it is.
the patch is done with: hg87@benchvice ~/src/linuxbios/LinuxBIOSv3/util/flashrom $ svn info Pfad: . URL: svn://linuxbios.org/repos/trunk/util/flashrom Basis des Projektarchivs: svn://linuxbios.org/repos UUID des Projektarchivs: 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 Revision: 2850 Knotentyp: Verzeichnis Plan: normal Letzter Autor: rminnich Letzte geänderte Rev: 2850 Letztes Änderungsdatum: 2007-10-12 23:22:40 +0200 (Fr, 12 Okt 2007) hg87@benchvice ~/src/linuxbios/LinuxBIOSv3/util/flashrom $
have fun with it, or just shrug because of the "dirty" hacks. ;)
regards, harald
On 15.10.2007 01:28, Harald Gutmann wrote:
Am Montag, 15. Oktober 2007 01:06:00 schrieb Carl-Daniel Hailfinger:
Great, thanks! The code I have also is not polished, so even if your code is ugly, it is better than no code. We can clean up that stuff together.
yes, that's right! here it is.
Nice!
the patch is done with: hg87@benchvice ~/src/linuxbios/LinuxBIOSv3/util/flashrom $ svn info Pfad: . URL: svn://linuxbios.org/repos/trunk/util/flashrom Basis des Projektarchivs: svn://linuxbios.org/repos UUID des Projektarchivs: 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 Revision: 2850 Knotentyp: Verzeichnis Plan: normal Letzter Autor: rminnich Letzte geänderte Rev: 2850 Letztes Änderungsdatum: 2007-10-12 23:22:40 +0200 (Fr, 12 Okt 2007) hg87@benchvice ~/src/linuxbios/LinuxBIOSv3/util/flashrom $
have fun with it, or just shrug because of the "dirty" hacks. ;)
I'll review later this week, but from a first glance at the code it looks nice.
regards, harald
Regards, Carl-Daniel
diff -ubrN ../../flashrom.original/board_enable.c flashrom.new/board_enable.c --- ../../flashrom.original/board_enable.c 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/board_enable.c 2007-10-14 20:28:41.000000000 +0200 @@ -37,7 +37,7 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +uint16_t it8716f_flashport = 0;
/* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg) @@ -111,7 +111,7 @@ whereas the IT8716F splits commands internally into address and non-address commands with the address in inverse wire order. That's why the register ordering in case 4 and 5 may seem strange. */ -static int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { uint8_t busy, writeenc; do { diff -ubrN ../../flashrom.original/board_enable.h flashrom.new/board_enable.h --- ../../flashrom.original/board_enable.h 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/board_enable.h 2007-10-14 21:09:18.000000000 +0200 @@ -0,0 +1,7 @@ +#ifndef boardenableh +#define boardenableh +uint16_t it8716f_flashport; +uint8_t regval(uint16_t port, uint8_t reg); +void regwrite(uint16_t port, uint8_t reg, uint8_t val); +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +#endif diff -ubrN ../../flashrom.original/flashchips.c flashrom.new/flashchips.c --- ../../flashrom.original/flashchips.c 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flashchips.c 2007-10-15 01:24:58.000000000 +0200 @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024,
probe_spi, NULL, NULL},
{"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256,probe_spi, erase_25l4005, write_25l4005},
diff -ubrN ../../flashrom.original/flash.h flashrom.new/flash.h --- ../../flashrom.original/flash.h 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flash.h 2007-10-14 19:13:52.000000000 +0200 @@ -294,4 +294,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe +int write_25l4005(struct flashchip *flash, uint8_t *buf); +int erase_25l4005(struct flashchip *flash); +int read_25l4005(struct flashchip *flash, uint8_t *buf);
#endif /* !__FLASH_H__ */ diff -ubrN ../../flashrom.original/Makefile flashrom.new/Makefile --- ../../flashrom.original/Makefile 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/Makefile 2007-10-15 01:20:16.000000000 +0200 @@ -24,7 +24,7 @@ am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \ 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \ sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
- sharplhf00l04.o w29ee011.o
- sharplhf00l04.o w29ee011.o mx25l4005.o
all: pciutils dep $(PROGRAM)
@@ -33,7 +33,7 @@ $(STRIP) $(STRIP_ARGS) $(PROGRAM)
clean:
- rm -f *.o *~
- rm -f *.o *~ flashrom
distclean: clean rm -f $(PROGRAM) .dependencies diff -ubrN ../../flashrom.original/mx25l4005.c flashrom.new/mx25l4005.c --- ../../flashrom.original/mx25l4005.c 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/mx25l4005.c 2007-10-15 01:17:56.000000000 +0200 @@ -0,0 +1,57 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "flash.h" +#include "board_enable.h"
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
+static void write_disable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x04, 0, 0, 0, 0};
- // Send WRDI (Write Disable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg&=~(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
- check_n_write_enable();
- outb(0x06,it8716f_flashport+1);
- outb((3<<4),it8716f_flashport);
- int i;
- for (i=0;i<256;++i) {
bios[256*block+i]=buf[256*block+i];
- }
- outb(0,it8716f_flashport);
- write_disable();
- usleep (100000);
+}
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
- int total_size=1024*flash->total_size;
- int i;
- for (i=0;i<total_size/256;++i) {
write256b(i, buf, (uint8_t*)flash->virtual_memory);
- }
+return 0; +}
+int erase_25l4005(struct flashchip *flash) { +check_n_write_enable(); +uint8_t result[3]={0, 0, 0}; +uint8_t command[5]={0xc7, 0, 0, 0, 0}; +it8716f_spi_command(it8716f_flashport, 1, 0, command, result); +write_disable(); +return 0; +}
Am Montag, 15. Oktober 2007 01:45:51 schrieb Carl-Daniel Hailfinger:
Nice!
it works, and that's the main thing! :)
I'll review later this week, but from a first glance at the code it looks nice.
some dirty hacks are in the code, but how i told it works. and now writing from a booted linuxbios! the bootup time is only great. - but i've to correct someting in filo because the sleep until the kernel is loaded is just too much. (here about 10 seconds, but i'll try to correct it in the Config of file first.)
just a few comment's on the code:
diff -ubrN ../../flashrom.original/board_enable.c flashrom.new/board_enable.c --- ../../flashrom.original/board_enable.c 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/board_enable.c 2007-10-14 20:28:41.000000000 +0200 @@ -37,7 +37,7 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +uint16_t it8716f_flashport = 0;
/* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg)
sould be fine.
@@ -111,7 +111,7 @@ whereas the IT8716F splits commands internally into address and non-address commands with the address in inverse wire order. That's why the register ordering in case 4 and 5 may seem strange. */ -static int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { uint8_t busy, writeenc; do {
same here.
diff -ubrN ../../flashrom.original/board_enable.h flashrom.new/board_enable.h --- ../../flashrom.original/board_enable.h 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/board_enable.h 2007-10-14 21:09:18.000000000 +0200 @@ -0,0 +1,7 @@ +#ifndef boardenableh +#define boardenableh +uint16_t it8716f_flashport; +uint8_t regval(uint16_t port, uint8_t reg); +void regwrite(uint16_t port, uint8_t reg, uint8_t val); +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +#endif
here too.
diff -ubrN ../../flashrom.original/flashchips.c flashrom.new/flashchips.c --- ../../flashrom.original/flashchips.c 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flashchips.c 2007-10-15 01:24:58.000000000 +0200 @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024,
probe_spi, NULL, NULL},
{"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256,probe_spi, erase_25l4005, write_25l4005},
diff -ubrN ../../flashrom.original/flash.h flashrom.new/flash.h --- ../../flashrom.original/flash.h 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flash.h 2007-10-14 19:13:52.000000000 +0200
also okay.
@@ -294,4 +294,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe
maybe remove that comment.
+int write_25l4005(struct flashchip *flash, uint8_t *buf); +int erase_25l4005(struct flashchip *flash); +int read_25l4005(struct flashchip *flash, uint8_t *buf);
#endif /* !__FLASH_H__ */ diff -ubrN ../../flashrom.original/Makefile flashrom.new/Makefile --- ../../flashrom.original/Makefile 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/Makefile 2007-10-15 01:20:16.000000000 +0200 @@ -24,7 +24,7 @@ am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \ 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \ sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
- sharplhf00l04.o w29ee011.o
- sharplhf00l04.o w29ee011.o mx25l4005.o
all: pciutils dep $(PROGRAM)
@@ -33,7 +33,7 @@ $(STRIP) $(STRIP_ARGS) $(PROGRAM)
clean:
- rm -f *.o *~
- rm -f *.o *~ flashrom
is in distclean, not necessary.
distclean: clean rm -f $(PROGRAM) .dependencies diff -ubrN ../../flashrom.original/mx25l4005.c flashrom.new/mx25l4005.c --- ../../flashrom.original/mx25l4005.c 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/mx25l4005.c 2007-10-15 01:17:56.000000000 +0200 @@ -0,0 +1,57 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "flash.h" +#include "board_enable.h"
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
i think some parts here could be done easyer with outb.
+static void write_disable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x04, 0, 0, 0, 0};
- // Send WRDI (Write Disable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg&=~(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
here too.
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
- check_n_write_enable();
- outb(0x06,it8716f_flashport+1);
- outb((3<<4),it8716f_flashport);
- int i;
- for (i=0;i<256;++i) {
bios[256*block+i]=buf[256*block+i];
- }
- outb(0,it8716f_flashport);
- write_disable();
- usleep (100000);
that sleep is just a dirty hack. (but i had no patience any more.)
+}
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
- int total_size=1024*flash->total_size;
- int i;
- for (i=0;i<total_size/256;++i) {
write256b(i, buf, (uint8_t*)flash->virtual_memory);
- }
+return 0; +}
sould be okay.
+int erase_25l4005(struct flashchip *flash) { +check_n_write_enable(); +uint8_t result[3]={0, 0, 0}; +uint8_t command[5]={0xc7, 0, 0, 0, 0}; +it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
could also be done with outb
+write_disable(); +return 0; +}
regards, harald
* Harald Gutmann harald.gutmann@gmx.net [071015 02:16]:
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
i think some parts here could be done easyer with outb.
This implementation of the MX25L4005 relies heavily on the chip being attached to an IT8716F SuperIO. I think we should create an abstraction layer (spi_command()? read_spi_status()?) that can be implemented by a SuperIO or southbridge that has an SPI bus attached. This way we could have fairly generic SPI flash chip drivers (most SPI chips are pretty similar too, I think), and they could be used on a new system by just implementing the southbridge/SuperIO specific part in some other place.
Stefan
On Mon, Oct 15, 2007 at 02:57:00AM +0200, Stefan Reinauer wrote:
i think some parts here could be done easyer with outb.
This implementation of the MX25L4005 relies heavily on the chip being attached to an IT8716F SuperIO. I think we should create an abstraction layer (spi_command()? read_spi_status()?) that can be implemented by a SuperIO or southbridge that has an SPI bus attached.
Yes.
//Peter
Am Montag, 15. Oktober 2007 02:57:00 schrieb Stefan Reinauer:
- Harald Gutmann harald.gutmann@gmx.net [071015 02:16]:
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
i think some parts here could be done easyer with outb.
This implementation of the MX25L4005 relies heavily on the chip being attached to an IT8716F SuperIO.
yes, it does!
I think we should create an abstraction
would be good.
layer (spi_command()? read_spi_status()?) that can be implemented by a SuperIO or southbridge that has an SPI bus attached. This way we could have fairly generic SPI flash chip drivers (most SPI chips are pretty similar too, I think), and they could be used on a new system by just implementing the southbridge/SuperIO specific part in some other place.
i also think that the spi programming is fairly generic on SPI flash devices.
Stefan
regards, Harald
On Mon, Oct 15, 2007 at 02:57:00AM +0200, Stefan Reinauer wrote:
- Harald Gutmann harald.gutmann@gmx.net [071015 02:16]:
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
i think some parts here could be done easyer with outb.
This implementation of the MX25L4005 relies heavily on the chip being attached to an IT8716F SuperIO. I think we should create an abstraction layer (spi_command()? read_spi_status()?) that can be implemented by a SuperIO or southbridge that has an SPI bus attached. This way we could have fairly generic SPI flash chip drivers (most SPI chips are pretty similar too, I think), and they could be used on a new system by just implementing the southbridge/SuperIO specific part in some other place.
Full ack.
Uwe.
diff -ubrN ../../flashrom.original/board_enable.c flashrom.new/board_enable.c --- ../../flashrom.original/board_enable.c 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/board_enable.c 2007-10-14 20:28:41.000000000 +0200 @@ -37,7 +37,7 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +uint16_t it8716f_flashport = 0;
/* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg) @@ -111,7 +111,7 @@ whereas the IT8716F splits commands internally into address and non-address commands with the address in inverse wire order. That's why the register ordering in case 4 and 5 may seem strange. */ -static int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { uint8_t busy, writeenc; do { diff -ubrN ../../flashrom.original/board_enable.h flashrom.new/board_enable.h --- ../../flashrom.original/board_enable.h 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/board_enable.h 2007-10-14 21:09:18.000000000 +0200 @@ -0,0 +1,7 @@ +#ifndef boardenableh +#define boardenableh +uint16_t it8716f_flashport; +uint8_t regval(uint16_t port, uint8_t reg); +void regwrite(uint16_t port, uint8_t reg, uint8_t val); +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +#endif diff -ubrN ../../flashrom.original/flashchips.c flashrom.new/flashchips.c --- ../../flashrom.original/flashchips.c 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flashchips.c 2007-10-15 01:24:58.000000000 +0200 @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024,
probe_spi, NULL, NULL},
{"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256,probe_spi, erase_25l4005, write_25l4005},
diff -ubrN ../../flashrom.original/flash.h flashrom.new/flash.h --- ../../flashrom.original/flash.h 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flash.h 2007-10-14 19:13:52.000000000 +0200 @@ -294,4 +294,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe +int write_25l4005(struct flashchip *flash, uint8_t *buf); +int erase_25l4005(struct flashchip *flash); +int read_25l4005(struct flashchip *flash, uint8_t *buf);
#endif /* !__FLASH_H__ */ diff -ubrN ../../flashrom.original/Makefile flashrom.new/Makefile --- ../../flashrom.original/Makefile 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/Makefile 2007-10-15 01:20:16.000000000 +0200 @@ -24,7 +24,7 @@ am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \ 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \ sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
- sharplhf00l04.o w29ee011.o
- sharplhf00l04.o w29ee011.o mx25l4005.o
all: pciutils dep $(PROGRAM)
@@ -33,7 +33,7 @@ $(STRIP) $(STRIP_ARGS) $(PROGRAM)
clean:
- rm -f *.o *~
- rm -f *.o *~ flashrom
distclean: clean rm -f $(PROGRAM) .dependencies diff -ubrN ../../flashrom.original/mx25l4005.c flashrom.new/mx25l4005.c --- ../../flashrom.original/mx25l4005.c 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/mx25l4005.c 2007-10-15 01:17:56.000000000 +0200 @@ -0,0 +1,57 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "flash.h" +#include "board_enable.h"
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
+static void write_disable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x04, 0, 0, 0, 0};
- // Send WRDI (Write Disable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg&=~(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
+}
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
- check_n_write_enable();
- outb(0x06,it8716f_flashport+1);
- outb((3<<4),it8716f_flashport);
- int i;
- for (i=0;i<256;++i) {
bios[256*block+i]=buf[256*block+i];
- }
- outb(0,it8716f_flashport);
- write_disable();
- usleep (100000);
-usleep (100000); +usleep (1000); //also works fine with a value of 1000, and is much faster with that.
+}
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
- int total_size=1024*flash->total_size;
- int i;
- for (i=0;i<total_size/256;++i) {
write256b(i, buf, (uint8_t*)flash->virtual_memory);
- }
+return 0; +}
+int erase_25l4005(struct flashchip *flash) { +check_n_write_enable(); +uint8_t result[3]={0, 0, 0}; +uint8_t command[5]={0xc7, 0, 0, 0, 0}; +it8716f_spi_command(it8716f_flashport, 1, 0, command, result); +write_disable();
+sleep (3); // the chip needs some time, until it responses again.
+return 0; +}
On 15.10.2007 01:28, Harald Gutmann wrote:
Am Montag, 15. Oktober 2007 01:06:00 schrieb Carl-Daniel Hailfinger:
Great, thanks! The code I have also is not polished, so even if your code is ugly, it is better than no code. We can clean up that stuff together.
yes, that's right! here it is.
the patch is done with: Revision: 2850
I have rearranged some code, so your patch does no longer apply, but it should be easy to fix.
diff -ubrN ../../flashrom.original/board_enable.c flashrom.new/board_enable.c --- ../../flashrom.original/board_enable.c 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/board_enable.c 2007-10-14 20:28:41.000000000 +0200
This is now in spi.c
@@ -37,7 +37,7 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +uint16_t it8716f_flashport = 0;
/* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg) @@ -111,7 +111,7 @@ whereas the IT8716F splits commands internally into address and non-address commands with the address in inverse wire order. That's why the register ordering in case 4 and 5 may seem strange. */ -static int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { uint8_t busy, writeenc; do { diff -ubrN ../../flashrom.original/board_enable.h flashrom.new/board_enable.h --- ../../flashrom.original/board_enable.h 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/board_enable.h 2007-10-14 21:09:18.000000000 +0200
Perhaps move to spi.h?
@@ -0,0 +1,7 @@ +#ifndef boardenableh +#define boardenableh +uint16_t it8716f_flashport; +uint8_t regval(uint16_t port, uint8_t reg); +void regwrite(uint16_t port, uint8_t reg, uint8_t val); +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +#endif diff -ubrN ../../flashrom.original/flashchips.c flashrom.new/flashchips.c --- ../../flashrom.original/flashchips.c 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flashchips.c 2007-10-15 01:24:58.000000000 +0200 @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024,
probe_spi, NULL, NULL},
{"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256,probe_spi, erase_25l4005, write_25l4005},
OK
diff -ubrN ../../flashrom.original/flash.h flashrom.new/flash.h --- ../../flashrom.original/flash.h 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flash.h 2007-10-14 19:13:52.000000000 +0200 @@ -294,4 +294,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe +int write_25l4005(struct flashchip *flash, uint8_t *buf); +int erase_25l4005(struct flashchip *flash); +int read_25l4005(struct flashchip *flash, uint8_t *buf);
#endif /* !__FLASH_H__ */
OK
diff -ubrN ../../flashrom.original/Makefile flashrom.new/Makefile --- ../../flashrom.original/Makefile 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/Makefile 2007-10-15 01:20:16.000000000 +0200 @@ -24,7 +24,7 @@ am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \ 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \ sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
- sharplhf00l04.o w29ee011.o
- sharplhf00l04.o w29ee011.o mx25l4005.o
all: pciutils dep $(PROGRAM)
@@ -33,7 +33,7 @@ $(STRIP) $(STRIP_ARGS) $(PROGRAM)
clean:
- rm -f *.o *~
- rm -f *.o *~ flashrom
distclean: clean rm -f $(PROGRAM) .dependencies
Skip the make clean changes. We have make distclean.
diff -ubrN ../../flashrom.original/mx25l4005.c flashrom.new/mx25l4005.c --- ../../flashrom.original/mx25l4005.c 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/mx25l4005.c 2007-10-15 01:17:56.000000000 +0200 @@ -0,0 +1,57 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "flash.h" +#include "board_enable.h"
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
generic_spi_command
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
I have absolutely no idea what you are trying to do here. According to my data sheet, your code does the following: * Enable multiple byte mode, set clock to 33/2 MHz, read the last JEDEC command sent to the flash chip * Set bit 4 of the last JEDEC command * Enable multiple byte mode, set clock to 33/2 MHz, write the modified JEDEC command
Please note that none of these three lines send or receive anything from/to the chip.
+}
+static void write_disable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x04, 0, 0, 0, 0};
- // Send WRDI (Write Disable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
generic_spi_command
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg&=~(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
Same as above: What are you trying to do?
+}
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
- check_n_write_enable();
- outb(0x06,it8716f_flashport+1);
- outb((3<<4),it8716f_flashport);
- int i;
- for (i=0;i<256;++i) {
bios[256*block+i]=buf[256*block+i];
- }
- outb(0,it8716f_flashport);
- write_disable();
- usleep (1000);
Check the chip status register instead fo waiting.
+}
OK, but we probably need a generic_spi_command_prepare and generic_spi_command_stop
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
- int total_size=1024*flash->total_size;
- int i;
- for (i=0;i<total_size/256;++i) {
write256b(i, buf, (uint8_t*)flash->virtual_memory);
- }
+return 0; +}
OK
+int erase_25l4005(struct flashchip *flash) { +check_n_write_enable(); +uint8_t result[3]={0, 0, 0}; +uint8_t command[5]={0xc7, 0, 0, 0, 0}; +it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
generic_spi_command
+write_disable(); +sleep (3); +// the chip needs some time, until it responses again. +return 0;
Can you instead read the flash chip status register in a loop? That way, you don't have to hardcode the sleep duration.
+}
Overall, I like it.
My version of the write patch follows. Please test.
Index: flash.h =================================================================== --- flash.h (Revision 2864) +++ flash.h (Arbeitskopie) @@ -296,4 +296,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe +int write_25l4005(struct flashchip *flash, uint8_t *buf); +int erase_25l4005(struct flashchip *flash); +int read_25l4005(struct flashchip *flash, uint8_t *buf); + #endif /* !__FLASH_H__ */ Index: flashchips.c =================================================================== --- flashchips.c (Revision 2864) +++ flashchips.c (Arbeitskopie) @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024, - probe_spi, NULL, NULL}, + probe_spi, erase_25l4005, write_25l4005}, {"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256, Index: spi.c =================================================================== --- spi.c (Revision 2864) +++ spi.c (Arbeitskopie) @@ -34,8 +34,16 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +#define JEDEC_WREN {0x06} +#define JEDEC_WREN_OUTSIZE 0x01 +#define JEDEC_WREN_INSIZE 0x00
+#define JEDEC_WRDI {0x04} +#define JEDEC_WRDI_OUTSIZE 0x01 +#define JEDEC_WRDI_INSIZE 0x00 + +uint16_t it8716f_flashport = 0; + /* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg) { @@ -170,7 +178,7 @@ return 0; }
-static int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { if (it8716f_flashport) return it8716f_spi_command(it8716f_flashport, writecnt, readcnt, writearr, readarr); @@ -188,6 +196,25 @@ return 0; }
+void generic_spi_write_enable() +{ + const unsigned char cmd[] = JEDEC_WREN; + unsigned char result[] = {0, 0, 0}; + + // Send WREN (Write Enable) + generic_spi_command(JEDEC_WREN_OUTSIZE, JEDEC_WREN_INSIZE, cmd, result); + +} + +void generic_spi_write_disable() +{ + const unsigned char cmd[] = JEDEC_WRDI; + unsigned char result[] = {0, 0, 0}; + + // Send WRDI (Write Disable) + generic_spi_command(JEDEC_WRDI_OUTSIZE, JEDEC_WRDI_INSIZE, cmd, result); +} + int probe_spi(struct flashchip *flash) { unsigned char readarr[3]; Index: Makefile =================================================================== --- Makefile (Revision 2864) +++ Makefile (Arbeitskopie) @@ -24,7 +24,7 @@ am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \ 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \ sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \ - sharplhf00l04.o w29ee011.o spi.o + sharplhf00l04.o w29ee011.o spi.o mx25l4005.o
all: pciutils dep $(PROGRAM)
Index: spi.h =================================================================== --- spi.h (Revision 0) +++ spi.h (Revision 0) @@ -0,0 +1,9 @@ +#ifndef __SPI_H__ +#define __SPI_H__ 1 + +uint16_t it8716f_flashport; +int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +void generic_spi_write_enable(); +void generic_spi_write_disable(); + +#endif Index: mx25l4005.c =================================================================== --- mx25l4005.c (Revision 0) +++ mx25l4005.c (Revision 0) @@ -0,0 +1,39 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "flash.h" +#include "spi.h" + + +void write256b(int block, uint8_t *buf, uint8_t *bios ) { + generic_spi_write_enable(); + outb(0x06,it8716f_flashport+1); + outb((3<<4),it8716f_flashport); + int i; + for (i=0;i<256;++i) { + bios[256*block+i]=buf[256*block+i]; + } + outb(0,it8716f_flashport); + generic_spi_write_disable(); + usleep (1000); +} + +int write_25l4005(struct flashchip *flash, uint8_t *buf) { + int total_size=1024*flash->total_size; + int i; + for (i=0;i<total_size/256;++i) { + write256b(i, buf, (uint8_t*)flash->virtual_memory); + } +return 0; +} + +int erase_25l4005(struct flashchip *flash) { + generic_spi_write_enable(); + uint8_t result[3]={0, 0, 0}; + uint8_t command[5]={0xc7, 0, 0, 0, 0}; + generic_spi_command(1, 0, command, result); + generic_spi_write_disable(); + // the chip needs some time, until it responses again. + sleep (3); + return 0; +}
On Wed, Oct 17, 2007 at 02:14:17PM +0200, Carl-Daniel Hailfinger wrote:
distclean: clean rm -f $(PROGRAM) .dependencies
Skip the make clean changes. We have make distclean.
Yep.
diff -ubrN ../../flashrom.original/mx25l4005.c flashrom.new/mx25l4005.c --- ../../flashrom.original/mx25l4005.c 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/mx25l4005.c 2007-10-15 01:17:56.000000000 +0200 @@ -0,0 +1,57 @@
No license header?
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
- int total_size=1024*flash->total_size;
- int i;
- for (i=0;i<total_size/256;++i) {
write256b(i, buf, (uint8_t*)flash->virtual_memory);
- }
+return 0; +}
OK
Yes, but the coding style if broken (in several places). Please fix that.
My version of the write patch follows. Please test.
Missing Signed-off-by. May be per design, but please always add it, even if the patch is not (yet) meant to be committed. In such a case just mention that it's WIP and shouldn't be commited (but always add the Signed-off-by).
Index: flash.h
--- flash.h (Revision 2864) +++ flash.h (Arbeitskopie) @@ -296,4 +296,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe
What's the "// probe" for?
+void generic_spi_write_enable() +{
- const unsigned char cmd[] = JEDEC_WREN;
Why does JEDEC_WREN contain the braces and not do this?
const unsigned char cmd[] = { JEDEC_WREN };
Is there a technical reason for that? The version without braces in the #define is preferrable IMO.
- unsigned char result[] = {0, 0, 0};
uint8_t ?
Index: spi.h
--- spi.h (Revision 0) +++ spi.h (Revision 0) @@ -0,0 +1,9 @@
Missing license header.
Do we need this file at all? I'd rather merge it into an existing header file, especially since it's almost empty anyway.
+#ifndef __SPI_H__ +#define __SPI_H__ 1
+uint16_t it8716f_flashport;
Missing "extern"?
+int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +void generic_spi_write_enable(); +void generic_spi_write_disable();
+#endif Index: mx25l4005.c =================================================================== --- mx25l4005.c (Revision 0) +++ mx25l4005.c (Revision 0)
Missing license header?
Uwe.
Am Mittwoch, 17. Oktober 2007 14:14:17 schrieb Carl-Daniel Hailfinger:
On 15.10.2007 01:28, Harald Gutmann wrote:
Am Montag, 15. Oktober 2007 01:06:00 schrieb Carl-Daniel Hailfinger:
Great, thanks! The code I have also is not polished, so even if your code is ugly, it is better than no code. We can clean up that stuff together.
yes, that's right! here it is.
the patch is done with: Revision: 2850
I have rearranged some code, so your patch does no longer apply, but it should be easy to fix.
fine!
diff -ubrN ../../flashrom.original/board_enable.c flashrom.new/board_enable.c --- ../../flashrom.original/board_enable.c 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/board_enable.c 2007-10-14 20:28:41.000000000 +0200
This is now in spi.c
@@ -37,7 +37,7 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +uint16_t it8716f_flashport = 0;
/* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg) @@ -111,7 +111,7 @@ whereas the IT8716F splits commands internally into address and non-address commands with the address in inverse wire order. That's why the register ordering in case 4 and 5 may seem strange. */ -static int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { uint8_t busy, writeenc; do { diff -ubrN ../../flashrom.original/board_enable.h flashrom.new/board_enable.h --- ../../flashrom.original/board_enable.h 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/board_enable.h 2007-10-14 21:09:18.000000000 +0200
Perhaps move to spi.h?
@@ -0,0 +1,7 @@ +#ifndef boardenableh +#define boardenableh +uint16_t it8716f_flashport; +uint8_t regval(uint16_t port, uint8_t reg); +void regwrite(uint16_t port, uint8_t reg, uint8_t val); +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +#endif diff -ubrN ../../flashrom.original/flashchips.c flashrom.new/flashchips.c --- ../../flashrom.original/flashchips.c 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flashchips.c 2007-10-15 01:24:58.000000000 +0200 @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024,
probe_spi, NULL, NULL},
{"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256,probe_spi, erase_25l4005, write_25l4005},
OK
diff -ubrN ../../flashrom.original/flash.h flashrom.new/flash.h --- ../../flashrom.original/flash.h 2007-10-15 01:14:28.000000000 +0200 +++ flashrom.new/flash.h 2007-10-14 19:13:52.000000000 +0200 @@ -294,4 +294,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe
the "//probe" could be deleted.
+int write_25l4005(struct flashchip *flash, uint8_t *buf); +int erase_25l4005(struct flashchip *flash); +int read_25l4005(struct flashchip *flash, uint8_t *buf);
#endif /* !__FLASH_H__ */
OK
diff -ubrN ../../flashrom.original/Makefile flashrom.new/Makefile --- ../../flashrom.original/Makefile 2007-10-15 01:14:29.000000000 +0200 +++ flashrom.new/Makefile 2007-10-15 01:20:16.000000000 +0200 @@ -24,7 +24,7 @@ am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \ 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \ sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
- sharplhf00l04.o w29ee011.o
- sharplhf00l04.o w29ee011.o mx25l4005.o
all: pciutils dep $(PROGRAM)
@@ -33,7 +33,7 @@ $(STRIP) $(STRIP_ARGS) $(PROGRAM)
clean:
- rm -f *.o *~
- rm -f *.o *~ flashrom
distclean: clean rm -f $(PROGRAM) .dependencies
Skip the make clean changes. We have make distclean.
like mentioned it's in distclean.
diff -ubrN ../../flashrom.original/mx25l4005.c flashrom.new/mx25l4005.c --- ../../flashrom.original/mx25l4005.c 1970-01-01 01:00:00.000000000 +0100 +++ flashrom.new/mx25l4005.c 2007-10-15 01:17:56.000000000 +0200 @@ -0,0 +1,57 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "flash.h" +#include "board_enable.h"
+static void check_n_write_enable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x06, 0, 0, 0, 0};
- // Send WREN (Write Enable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
generic_spi_command
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg|=(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
I have absolutely no idea what you are trying to do here. According to my data sheet, your code does the following:
- Enable multiple byte mode, set clock to 33/2 MHz, read the last JEDEC
command sent to the flash chip
- Set bit 4 of the last JEDEC command
- Enable multiple byte mode, set clock to 33/2 MHz, write the modified
JEDEC command
sry, i also don't know exactly, a friend of mine hacked that (and i just have started to learn c.) and like told the code was hacked in little time, but worked.
Please note that none of these three lines send or receive anything from/to the chip.
+}
+static void write_disable() {
- uint8_t result[3] = {0, 0, 0};
- uint8_t command[5] = {0x04, 0, 0, 0, 0};
- // Send WRDI (Write Disable)
- it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
generic_spi_command
- uint8_t reg=regval(it8716f_flashport,0x24);
- reg&=~(1<<4);
- regwrite(it8716f_flashport,0x24,reg);
Same as above: What are you trying to do?
same as above: i don't know.
+}
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
- check_n_write_enable();
- outb(0x06,it8716f_flashport+1);
- outb((3<<4),it8716f_flashport);
- int i;
- for (i=0;i<256;++i) {
bios[256*block+i]=buf[256*block+i];
- }
this splitting is because of the superIO and not of the spi chip programmend. look at the end of the message. (*)
- outb(0,it8716f_flashport);
- write_disable();
- usleep (1000);
Check the chip status register instead fo waiting.
we tried that before, but it didn't work for any reason, but i don't know what the problem was, but the first working result was with the hardcoded sleep.
+}
OK, but we probably need a generic_spi_command_prepare and generic_spi_command_stop
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
- int total_size=1024*flash->total_size;
- int i;
- for (i=0;i<total_size/256;++i) {
write256b(i, buf, (uint8_t*)flash->virtual_memory);
- }
+return 0; +}
OK
+int erase_25l4005(struct flashchip *flash) { +check_n_write_enable(); +uint8_t result[3]={0, 0, 0}; +uint8_t command[5]={0xc7, 0, 0, 0, 0}; +it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
generic_spi_command
+write_disable(); +sleep (3); +// the chip needs some time, until it responses again. +return 0;
Can you instead read the flash chip status register in a loop? That way, you don't have to hardcode the sleep duration.
would be better.
+}
Overall, I like it.
My version of the write patch follows. Please test.
tested and approved to work!
(*) but just another thing: it would be good not to fix that code just for the MX25L4005 chip, because there are much more other chips out which can be programmed the same way. for the chip it was originally written, it works and that's really fine!
regards, harald
Index: flash.h
--- flash.h (Revision 2864) +++ flash.h (Arbeitskopie) @@ -296,4 +296,10 @@ /* w49f002u.c */ int write_49f002(struct flashchip *flash, uint8_t *buf);
+/* mx25l4005.c */ +// probe +int write_25l4005(struct flashchip *flash, uint8_t *buf); +int erase_25l4005(struct flashchip *flash); +int read_25l4005(struct flashchip *flash, uint8_t *buf);
#endif /* !__FLASH_H__ */ Index: flashchips.c =================================================================== --- flashchips.c (Revision 2864) +++ flashchips.c (Arbeitskopie) @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024,
probe_spi, NULL, NULL},
{"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256,probe_spi, erase_25l4005, write_25l4005},
Index: spi.c
--- spi.c (Revision 2864) +++ spi.c (Arbeitskopie) @@ -34,8 +34,16 @@ #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +#define JEDEC_WREN {0x06} +#define JEDEC_WREN_OUTSIZE 0x01 +#define JEDEC_WREN_INSIZE 0x00
+#define JEDEC_WRDI {0x04} +#define JEDEC_WRDI_OUTSIZE 0x01 +#define JEDEC_WRDI_INSIZE 0x00
+uint16_t it8716f_flashport = 0;
/* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg) { @@ -170,7 +178,7 @@ return 0; }
-static int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { if (it8716f_flashport) return it8716f_spi_command(it8716f_flashport, writecnt, readcnt, writearr, readarr); @@ -188,6 +196,25 @@ return 0; }
+void generic_spi_write_enable() +{
- const unsigned char cmd[] = JEDEC_WREN;
- unsigned char result[] = {0, 0, 0};
- // Send WREN (Write Enable)
- generic_spi_command(JEDEC_WREN_OUTSIZE, JEDEC_WREN_INSIZE, cmd, result);
+}
+void generic_spi_write_disable() +{
- const unsigned char cmd[] = JEDEC_WRDI;
- unsigned char result[] = {0, 0, 0};
- // Send WRDI (Write Disable)
- generic_spi_command(JEDEC_WRDI_OUTSIZE, JEDEC_WRDI_INSIZE, cmd, result);
+}
int probe_spi(struct flashchip *flash) { unsigned char readarr[3]; Index: Makefile =================================================================== --- Makefile (Revision 2864) +++ Makefile (Arbeitskopie) @@ -24,7 +24,7 @@ am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \ 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \ sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
- sharplhf00l04.o w29ee011.o spi.o
- sharplhf00l04.o w29ee011.o spi.o mx25l4005.o
all: pciutils dep $(PROGRAM)
Index: spi.h
--- spi.h (Revision 0) +++ spi.h (Revision 0) @@ -0,0 +1,9 @@ +#ifndef __SPI_H__ +#define __SPI_H__ 1
+uint16_t it8716f_flashport; +int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +void generic_spi_write_enable(); +void generic_spi_write_disable();
+#endif Index: mx25l4005.c =================================================================== --- mx25l4005.c (Revision 0) +++ mx25l4005.c (Revision 0) @@ -0,0 +1,39 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "flash.h" +#include "spi.h"
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
- generic_spi_write_enable();
- outb(0x06,it8716f_flashport+1);
- outb((3<<4),it8716f_flashport);
- int i;
- for (i=0;i<256;++i) {
bios[256*block+i]=buf[256*block+i];
- }
- outb(0,it8716f_flashport);
- generic_spi_write_disable();
- usleep (1000);
+}
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
- int total_size=1024*flash->total_size;
- int i;
- for (i=0;i<total_size/256;++i) {
write256b(i, buf, (uint8_t*)flash->virtual_memory);
- }
+return 0; +}
+int erase_25l4005(struct flashchip *flash) {
- generic_spi_write_enable();
- uint8_t result[3]={0, 0, 0};
- uint8_t command[5]={0xc7, 0, 0, 0, 0};
- generic_spi_command(1, 0, command, result);
- generic_spi_write_disable();
- // the chip needs some time, until it responses again.
- sleep (3);
- return 0;
+}
On 17.10.2007 20:22, Harald Gutmann wrote:
Am Mittwoch, 17. Oktober 2007 14:14:17 schrieb Carl-Daniel Hailfinger:
+}
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
- check_n_write_enable();
- outb(0x06,it8716f_flashport+1);
- outb((3<<4),it8716f_flashport);
- int i;
- for (i=0;i<256;++i) {
bios[256*block+i]=buf[256*block+i];
- }
this splitting is because of the superIO and not of the spi chip programmend. look at the end of the message. (*)
Yes, but the chip supports only 256 bytes in one go as well. This is a documented "feature" of the page program command.
- outb(0,it8716f_flashport);
- write_disable();
- usleep (1000);
Check the chip status register instead fo waiting.
we tried that before, but it didn't work for any reason, but i don't know what the problem was, but the first working result was with the hardcoded sleep.
OK, I will leave the hardcoded sleep in there and the status register check is commented out.
Overall, I like it.
My version of the write patch follows. Please test.
tested and approved to work!
Great!
(*) but just another thing: it would be good not to fix that code just for the MX25L4005 chip, because there are much more other chips out which can be programmed the same way. for the chip it was originally written, it works and that's really fine!
My new version is way more generic and hopefully works as well. Can you test and give me an Acked-by: line?
Regards, Carl-Daniel
Add generic SPI flash erase and write support to flashrom. The first chip the code was tested and verified with is the Macronix MX25L4005, but other chips should work as well. Timeouts are still hardcoded to data sheet maxima, but the status register checking code is already there. Thanks to Harald Gutmann for the initial code on which this is loosely based.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net ---
Index: util/flashrom/flash.h =================================================================== --- util/flashrom/flash.h (Revision 2867) +++ util/flashrom/flash.h (Arbeitskopie) @@ -210,6 +210,11 @@ /* spi.c */ int probe_spi(struct flashchip *flash); int it87xx_probe_spi_flash(const char *name); +int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr); +void generic_spi_write_enable(); +void generic_spi_write_disable(); +int generic_spi_chip_erase(struct flashchip *flash); +int generic_spi_chip_write(struct flashchip *flash, uint8_t *buf);
/* 82802ab.c */ int probe_82802ab(struct flashchip *flash); Index: util/flashrom/flashchips.c =================================================================== --- util/flashrom/flashchips.c (Revision 2867) +++ util/flashrom/flashchips.c (Arbeitskopie) @@ -39,7 +39,7 @@ {"Mx29f002", MX_ID, MX_29F002, 256, 64 * 1024, probe_29f002, erase_29f002, write_29f002}, {"MX25L4005", MX_ID, MX_25L4005, 512, 4 * 1024, - probe_spi, NULL, NULL}, + probe_spi, generic_spi_chip_erase, generic_spi_chip_write}, {"SST29EE020A", SST_ID, SST_29EE020A, 256, 128, probe_jedec, erase_chip_jedec, write_jedec}, {"SST28SF040A", SST_ID, SST_28SF040, 512, 256, Index: util/flashrom/spi.c =================================================================== --- util/flashrom/spi.c (Revision 2867) +++ util/flashrom/spi.c (Arbeitskopie) @@ -30,12 +30,40 @@ #define ITE_SUPERIO_PORT1 0x2e #define ITE_SUPERIO_PORT2 0x4e
+/* Read Electronic ID */ #define JEDEC_RDID {0x9f} #define JEDEC_RDID_OUTSIZE 0x01 #define JEDEC_RDID_INSIZE 0x03
-static uint16_t it8716f_flashport = 0; +/* Write Enable */ +#define JEDEC_WREN {0x06} +#define JEDEC_WREN_OUTSIZE 0x01 +#define JEDEC_WREN_INSIZE 0x00
+/* Write Disable */ +#define JEDEC_WRDI {0x04} +#define JEDEC_WRDI_OUTSIZE 0x01 +#define JEDEC_WRDI_INSIZE 0x00 + +/* Both Chip Erase commands below should work */ +/* Chip Erase 0x60 */ +#define JEDEC_CE_1 {0x60}; +#define JEDEC_CE_1_OUTSIZE 0x01 +#define JEDEC_CE_1_INSIZE 0x00 + +/* Chip Erase 0xc7 */ +#define JEDEC_CE_2 {0xc7}; +#define JEDEC_CE_2_OUTSIZE 0x01 +#define JEDEC_CE_2_INSIZE 0x00 + +/* Read Status Register */ +#define JEDEC_RDSR {0x05}; +#define JEDEC_RDSR_OUTSIZE 0x01 +#define JEDEC_RDSR_INSIZE 0x01 +#define JEDEC_RDSR_BIT_WIP (0x01 << 0) + +uint16_t it8716f_flashport = 0; + /* Generic Super I/O helper functions */ uint8_t regval(uint16_t port, uint8_t reg) { @@ -119,6 +147,8 @@ static int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { uint8_t busy, writeenc; + int i; + do { busy = inb(port) & 0x80; } while (busy); @@ -164,13 +194,15 @@ do { busy = inb(port) & 0x80; } while (busy); - readarr[0] = inb(port + 5); - readarr[1] = inb(port + 6); - readarr[2] = inb(port + 7); + + for (i = 0; i < readcnt; i++) { + readarr[i] = inb(port + 5 + i); + } + return 0; }
-static int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) +int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr) { if (it8716f_flashport) return it8716f_spi_command(it8716f_flashport, writecnt, readcnt, writearr, readarr); @@ -188,6 +220,23 @@ return 0; }
+void generic_spi_write_enable() +{ + const unsigned char cmd[] = JEDEC_WREN; + + /* Send WREN (Write Enable) */ + generic_spi_command(JEDEC_WREN_OUTSIZE, JEDEC_WREN_INSIZE, cmd, NULL); + +} + +void generic_spi_write_disable() +{ + const unsigned char cmd[] = JEDEC_WRDI; + + /* Send WRDI (Write Disable) */ + generic_spi_command(JEDEC_WRDI_OUTSIZE, JEDEC_WRDI_INSIZE, cmd, NULL); +} + int probe_spi(struct flashchip *flash) { unsigned char readarr[3]; @@ -204,3 +253,72 @@ return 0; }
+uint8_t generic_spi_read_status_register() +{ + const unsigned char cmd[] = JEDEC_RDSR; + unsigned char readarr[1]; + + /* Read Status Register */ + generic_spi_command(JEDEC_RDSR_OUTSIZE, JEDEC_RDSR_INSIZE, cmd, readarr); + return readarr[0]; +} + +int generic_spi_chip_erase(struct flashchip *flash) +{ + const unsigned char cmd[] = JEDEC_CE_2; + + generic_spi_write_enable(); + /* Send CE (Chip Erase) */ + generic_spi_command(1, 0, cmd, NULL); + /* The chip needs some time for erasing, the MX25L4005A has a maximum + * time of 7.5 seconds. + * FIXME: Check the status register instead + * Do we have to check the status register before calling + * write_disable()? The data sheet suggests we don't have to call + * write_disable() at all because WEL is reset automatically. + while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + sleep(1); + */ + generic_spi_write_disable(); + sleep(8); + return 0; +} + +void it8716f_spi_page_program(int block, uint8_t *buf, uint8_t *bios) { + int i; + + generic_spi_write_enable(); + outb(0x06 , it8716f_flashport + 1); + outb((3 << 4), it8716f_flashport); + for (i = 0; i < 256; i++) { + bios[256 * block + i] = buf[256 * block + i]; + } + outb(0, it8716f_flashport); + /* The chip needs some time for page program, the MX25L4005A has a + * maximum time of 5 ms. + * FIXME: Check the status register instead. + * Do we have to check the status register before calling + * write_disable()? The data sheet suggests we don't have to call + * write_disable() at all because WEL is reset automatically. + while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + usleep(1000); + */ + generic_spi_write_disable(); + usleep(5000); +} + +void generic_spi_page_program(int block, uint8_t *buf, uint8_t *bios) +{ + if (it8716f_flashport) + it8716f_spi_page_program(block, buf, bios); +} + +int generic_spi_chip_write(struct flashchip *flash, uint8_t *buf) { + int total_size = 1024 * flash->total_size; + int i; + for (i = 0; i < total_size / 256; i++) { + generic_spi_page_program(i, buf, (uint8_t *)flash->virtual_memory); + } + return 0; +} +
* Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [071018 01:59]:
My new version is way more generic and hopefully works as well. Can you test and give me an Acked-by: line?
I did not test, but please check this in. We can and will fix and improve this later as problems or ideas occur...
Add generic SPI flash erase and write support to flashrom. The first chip the code was tested and verified with is the Macronix MX25L4005, but other chips should work as well. Timeouts are still hardcoded to data sheet maxima, but the status register checking code is already there. Thanks to Harald Gutmann for the initial code on which this is loosely based.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Stefan Reinauer stepan@coresystems.de
On 18.10.2007 02:08, Stefan Reinauer wrote:
- Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [071018 01:59]:
My new version is way more generic and hopefully works as well. Can you test and give me an Acked-by: line?
I did not test, but please check this in. We can and will fix and improve this later as problems or ideas occur...
OK. Harald, please check out the code currently in svn and test if it works for you.
Add generic SPI flash erase and write support to flashrom. The first chip the code was tested and verified with is the Macronix MX25L4005, but other chips should work as well. Timeouts are still hardcoded to data sheet maxima, but the status register checking code is already there. Thanks to Harald Gutmann for the initial code on which this is loosely based.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Stefan Reinauer stepan@coresystems.de
Thanks, r2874.
Carl-Daniel
On 18.10.2007 02:28, Carl-Daniel Hailfinger wrote:
On 18.10.2007 02:08, Stefan Reinauer wrote:
- Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [071018 01:59]:
My new version is way more generic and hopefully works as well. Can you test and give me an Acked-by: line?
I did not test, but please check this in. We can and will fix and improve this later as problems or ideas occur...
OK. Harald, please check out the code currently in svn and test if it works for you.
And if that works, can you also try the following patch against current svn?
Index: spi.c =================================================================== --- spi.c (Revision 2874) +++ spi.c (Arbeitskopie) @@ -270,17 +270,9 @@ generic_spi_write_enable(); /* Send CE (Chip Erase) */ generic_spi_command(1, 0, cmd, NULL); - /* The chip needs some time for erasing, the MX25L4005A has a maximum - * time of 7.5 seconds. - * FIXME: Check the status register instead - * Do we have to check the status register before calling - * write_disable()? The data sheet suggests we don't have to call - * write_disable() at all because WEL is reset automatically. + /* Wait until the Write-In-Progress bit is cleared */ while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) sleep(1); - */ - generic_spi_write_disable(); - sleep(8); return 0; }
@@ -294,17 +286,9 @@ bios[256 * block + i] = buf[256 * block + i]; } outb(0, it8716f_flashport); - /* The chip needs some time for page program, the MX25L4005A has a - * maximum time of 5 ms. - * FIXME: Check the status register instead. - * Do we have to check the status register before calling - * write_disable()? The data sheet suggests we don't have to call - * write_disable() at all because WEL is reset automatically. + /* Wait until the Write-In-Progress bit is cleared */ while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) usleep(1000); - */ - generic_spi_write_disable(); - usleep(5000); }
void generic_spi_page_program(int block, uint8_t *buf, uint8_t *bios)
Am Donnerstag, 18. Oktober 2007 02:33:36 schrieb Carl-Daniel Hailfinger:
On 18.10.2007 02:28, Carl-Daniel Hailfinger wrote:
On 18.10.2007 02:08, Stefan Reinauer wrote:
- Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [071018
01:59]:
My new version is way more generic and hopefully works as well. Can you test and give me an Acked-by: line?
I did not test, but please check this in. We can and will fix and improve this later as problems or ideas occur...
OK. Harald, please check out the code currently in svn and test if it works for you.
svn rev2875 works.
And if that works, can you also try the following patch against current svn?
this patch is also working. (seems that something else went wrong when we tried to do it with testing the busy state of the chip.)
regards, Harald
Index: spi.c
--- spi.c (Revision 2874) +++ spi.c (Arbeitskopie) @@ -270,17 +270,9 @@ generic_spi_write_enable(); /* Send CE (Chip Erase) */ generic_spi_command(1, 0, cmd, NULL);
- /* The chip needs some time for erasing, the MX25L4005A has a maximum
* time of 7.5 seconds.
* FIXME: Check the status register instead
* Do we have to check the status register before calling
* write_disable()? The data sheet suggests we don't have to call
* write_disable() at all because WEL is reset automatically.
- /* Wait until the Write-In-Progress bit is cleared */ while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) sleep(1);
*/
- generic_spi_write_disable();
- sleep(8); return 0;
}
@@ -294,17 +286,9 @@ bios[256 * block + i] = buf[256 * block + i]; } outb(0, it8716f_flashport);
- /* The chip needs some time for page program, the MX25L4005A has a
* maximum time of 5 ms.
* FIXME: Check the status register instead.
* Do we have to check the status register before calling
* write_disable()? The data sheet suggests we don't have to call
* write_disable() at all because WEL is reset automatically.
- /* Wait until the Write-In-Progress bit is cleared */ while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) usleep(1000);
*/
- generic_spi_write_disable();
- usleep(5000);
}
void generic_spi_page_program(int block, uint8_t *buf, uint8_t *bios)
* Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [071018 02:33]:
OK. Harald, please check out the code currently in svn and test if it works for you.
And if that works, can you also try the following patch against current svn?
If you sign-off this patch: Acked-by: Stefan Reinauer stepan@coresystems.de
Index: spi.c
--- spi.c (Revision 2874) +++ spi.c (Arbeitskopie) @@ -270,17 +270,9 @@ generic_spi_write_enable(); /* Send CE (Chip Erase) */ generic_spi_command(1, 0, cmd, NULL);
- /* The chip needs some time for erasing, the MX25L4005A has a maximum
* time of 7.5 seconds.
* FIXME: Check the status register instead
* Do we have to check the status register before calling
* write_disable()? The data sheet suggests we don't have to call
* write_disable() at all because WEL is reset automatically.
- /* Wait until the Write-In-Progress bit is cleared */ while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) sleep(1);
*/
- generic_spi_write_disable();
- sleep(8); return 0;
}
@@ -294,17 +286,9 @@ bios[256 * block + i] = buf[256 * block + i]; } outb(0, it8716f_flashport);
- /* The chip needs some time for page program, the MX25L4005A has a
* maximum time of 5 ms.
* FIXME: Check the status register instead.
* Do we have to check the status register before calling
* write_disable()? The data sheet suggests we don't have to call
* write_disable() at all because WEL is reset automatically.
- /* Wait until the Write-In-Progress bit is cleared */ while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP) usleep(1000);
*/
- generic_spi_write_disable();
- usleep(5000);
}
void generic_spi_page_program(int block, uint8_t *buf, uint8_t *bios)
-- linuxbios mailing list linuxbios@linuxbios.org http://www.linuxbios.org/mailman/listinfo/linuxbios
On 18.10.2007 16:28, Stefan Reinauer wrote:
- Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [071018 02:33]:
OK. Harald, please check out the code currently in svn and test if it works for you.
And if that works, can you also try the following patch against current svn?
If you sign-off this patch: Acked-by: Stefan Reinauer stepan@coresystems.de
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
r2876.
Carl-Daniel
On 12.10.2007 20:40, Harald Gutmann wrote:
i always read about SST25LF040A and MX25L4005A chips which are used for bios on that mainboard. my mainboard which is also revision 2.0 has a different bios chip, which a device from winbond called 25X40VSIG. here's the link to the datasheet of this chip: www.winbond-usa.com/products/Nexflash/pdfs/datasheets/W25X10_20_40_80g.pdf this is just a statement, that there are also boards with that bios-chips out there.
original bios chip: %<--------------------------------------------------------- benchvice flashrom # ./flashrom --mainboard gigabyte:m57sli Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned ef 30 13 No EEPROM/flash device found.
Yes, limitation of the current code, I have patches pending and will send once I'm healthy again.
benchvice flashrom # %<--------------------------------------------------------
after changing the position of the spdt switch: %<-------------------------------------------------------- benchvice flashrom # ./flashrom --mainboard gigabyte:m57sli Calibrating delay loop... ok No LinuxBIOS table found. Found chipset "NVIDIA MCP55": Enabling flash write... OK. Found board "GIGABYTE GA-M57SLI": Enabling flash write... Serial flash segment 0 xfffe0000-0xffffffff enabled Serial flash segment 0x000e0000-0x000fffff enabled Serial flash segment 0xffee0000-0xffefffff disabled Serial flash segment 0xfff80000-0xfffeffff enabled LPC write to serial flash enabled serial flash pin 29 OK. RDID returned c2 20 13 MX25L4005 found at physical address: 0xfff80000 Flash part is MX25L4005 (512 KB) No operations were specified
Expected output.
Carl-Daniel