Subsystem: coreboot-v2/util/flashrom/ Action: activating support for EN29F002(A)(N)[BT]
Fully tested for Probe/Read/Erase/Write on EN29F002NT. Jedec subroutines 'probe_jedec()' and 'erase_chip_jedec()' are still in use, but a tailored 'write_en29f002a()' is needed due to a byte wise writing mechanism for this chip.
Signed-off by: Mats Erik Andersson mats.andersson@gisladisker.se
---
The already existing file "util/flashrom/en29f002a.c" has been activated by including the needed header files, and it has been supplemented with a routine for writing, since the standard jedec routine for writing does not function for this chip. Also the old 'probe_en29f002a()' seems defect in my testing, but is left as it was.
There has formally been incorporated a routine 'erase_en29f002a()' mostly for referencing from "flash.h", but it is never used since some obscure timing condition fails, whereas 'erase_chip_jedec()' indeed does function well for this chip.
Only EN29F002(A)(N)T has been marked TEST_OK_PREW in "flash.c", since I have only checked a physical chip EN29F002NT, and have no further chip in my possession.
Kind regards,
Mats Erik Andersson
Index: util/flashrom/flash.h =================================================================== --- util/flashrom/flash.h (revision 3578) +++ util/flashrom/flash.h (arbetskopia) @@ -435,6 +435,11 @@ int erase_29f040b(struct flashchip *flash); int write_29f040b(struct flashchip *flash, uint8_t *buf);
+/* en29f002a.c */ +int probe_en29f002a(struct flashchip *flash); +int erase_en29f002a(struct flashchip *flash); +int write_en29f002a(struct flashchip *flash, uint8_t *buf); + /* ichspi.c */ int ich_spi_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int ich_spi_read(struct flashchip *flash, uint8_t * buf); Index: util/flashrom/en29f002a.c =================================================================== --- util/flashrom/en29f002a.c (revision 3578) +++ util/flashrom/en29f002a.c (arbetskopia) @@ -25,6 +25,11 @@ EN29LV010 has 1C,6E and uses short F0 reset sequence EN29LV040(A) has 1C,4F and uses short F0 reset sequence */ + +#include <stdio.h> +#include <stdint.h> +#include "flash.h" + int probe_en29f512(struct flashchip *flash) { volatile uint8_t *bios = flash->virtual_memory; @@ -56,6 +61,8 @@ EN29F002AT has 1C,92 EN29F002AB has 1C,97 */ + /* MEA: This does not function properly for EN29F002NT */ + int probe_en29f002a(struct flashchip *flash) { volatile uint8_t *bios = flash->virtual_memory; @@ -83,3 +90,36 @@ return 0; }
+/* The EN29F002 chip needs repeated single byte writing, no block writing. */ + +int write_en29f002a(struct flashchip *flash, uint8_t *buf) +{ + int i; + int total_size = flash->total_size * 1024; + volatile uint8_t *bios = flash->virtual_memory; + volatile uint8_t *dst = bios; + + // *bios = 0xF0; + myusec_delay(10); + erase_chip_jedec(flash); + + printf("Programming page: "); + for (i = 0; i < total_size; i++) { + /* write to the sector */ + if ((i & 0xfff) == 0) + printf("address: 0x%08lx", (unsigned long)i); + *(bios + 0x5555) = 0xAA; + *(bios + 0x2AAA) = 0x55; + *(bios + 0x5555) = 0xA0; + *dst++ = *buf++; + + /* wait for Toggle bit ready */ + toggle_ready_jedec(dst); + + if ((i & 0xfff) == 0) + printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); + } + + printf("\n"); + return 0; +} Index: util/flashrom/flashchips.c =================================================================== --- util/flashrom/flashchips.c (revision 3578) +++ util/flashrom/flashchips.c (arbetskopia) @@ -47,8 +47,8 @@ {"AMIC", "A29040B", AMIC_ID_NOPREFIX, AMIC_A29040B, 512, 64 * 1024, TEST_OK_PR, probe_29f040b, erase_29f040b, write_29f040b}, {"AMIC", "A49LF040A", AMIC_ID_NOPREFIX, AMIC_A49LF040A, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, {"EMST", "F49B002UA", EMST_ID, EMST_F49B002UA, 256, 4096, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_49f002}, - {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, - {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_jedec}, + {"EON", "EN29F002(A)(N)B", EON_ID, EN_29F002B, 256, 256, TEST_UNTESTED, probe_jedec, erase_chip_jedec, write_en29f002a}, + {"EON", "EN29F002(A)(N)T", EON_ID, EN_29F002T, 256, 256, TEST_OK_PREW, probe_jedec, erase_chip_jedec, write_en29f002a}, {"Fujitsu", "MBM29F400TC", FUJITSU_ID, MBM29F400TC_STRANGE, 512, 64 * 1024, TEST_UNTESTED, probe_m29f400bt, erase_m29f400bt, write_coreboot_m29f400bt}, {"Intel", "82802AB", INTEL_ID, 173, 512, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, {"Intel", "82802AC", INTEL_ID, 172, 1024, 64 * 1024, TEST_OK_PREW, probe_82802ab, erase_82802ab, write_82802ab}, Index: util/flashrom/Makefile =================================================================== --- util/flashrom/Makefile (revision 3578) +++ util/flashrom/Makefile (arbetskopia) @@ -26,7 +26,7 @@
OBJS = chipset_enable.o board_enable.o udelay.o jedec.o stm50flw0x0x.o \ sst28sf040.o am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o \ - w49f002u.o 82802ab.o pm49fl00x.o sst49lf040.o \ + w49f002u.o 82802ab.o pm49fl00x.o sst49lf040.o en29f002a.o \ sst49lfxxxc.o sst_fwhub.o layout.o cbtable.o flashchips.o \ flashrom.o w39v080fa.o sharplhf00l04.o w29ee011.o spi.o it87spi.o \ ichspi.o w39v040c.o
On Mon, Sep 22, 2008 at 03:24:25PM +0200, Mats Erik Andersson wrote:
Subsystem: coreboot-v2/util/flashrom/ Action: activating support for EN29F002(A)(N)[BT]
Fully tested for Probe/Read/Erase/Write on EN29F002NT. Jedec subroutines 'probe_jedec()' and 'erase_chip_jedec()' are still in use, but a tailored 'write_en29f002a()' is needed due to a byte wise writing mechanism for this chip.
Signed-off by: Mats Erik Andersson mats.andersson@gisladisker.se
Thanks, r3602.
I tested this with an EN29F002NT and it does work better than the code we had before, but I'm seeing flashrom hang upon writes. Do you experience a similar behavior? Not sure what the problem is, flashrom is at 99% CPU load, but it can be killed with CTRL-C. Maybe it's just that my chip is dead or almost-dead (never worked so far)...
Uwe.
Den 29 september skrev Uwe Hermann uwe@hermann-uwe.de:
On Mon, Sep 22, 2008 at 03:24:25PM +0200, Mats Erik Andersson wrote:
Subsystem: coreboot-v2/util/flashrom/ Action: activating support for EN29F002(A)(N)[BT]
Fully tested for Probe/Read/Erase/Write on EN29F002NT. Jedec subroutines 'probe_jedec()' and 'erase_chip_jedec()' are still in use, but a tailored 'write_en29f002a()' is needed due to a byte wise writing mechanism for this chip.
Signed-off by: Mats Erik Andersson mats.andersson@gisladisker.se
Thanks, r3602.
I tested this with an EN29F002NT and it does work better than the code we had before, but I'm seeing flashrom hang upon writes. Do you experience a similar behavior? Not sure what the problem is, flashrom is at 99% CPU load, but it can be killed with CTRL-C. Maybe it's just that my chip is dead or almost-dead (never worked so far)...
No, after implementing the correct byte wise writing algorithm, I have not experienced any latch ups. I have produced some ten images for a FIC mainboard and no problems at writing. Since I use a uClibc-Busybox target system where flash writes are performed, I can only say that the load figure using top says "0.17" at a busy write to EN29F002NT, but the time to write 256kB is so short that "top" might have difficulties to catch up.
Since this chip needs byte oriented writes and polling, a heavier load than during block write ought to be expected. There is an additional strobe using a value "0xF0" that I outcommented in the code write_en26f002a() since it did not seem to matter. Do test to see if that might awaken your memory chip.
Regards
Mats E Andersson
note to all: we did find, long ago, on one mainboard with one particular chip, that a POST cycle at the wrong time would hang flashrom. The issue is that every POST cycle is a failed cycle, in the sense that no device ever responds. The chipset timeout cycle was long enough to glitch the timing.
Linux does indeed have some POST cycles in the kernel. So, it is possible that on some chipsets, now and in the future, this could be an issue. The best part is that the actual problem can appear or not appear depending on chipset, revision, and bios revision. Isn't that fun?
Just an FYI.
thanks
ron
On Mon, 29 Sep 2008, ron minnich wrote:
note to all: we did find, long ago, on one mainboard with one particular chip, that a POST cycle at the wrong time would hang flashrom. The issue is that every POST cycle is a failed cycle, in the sense that no device ever responds. The chipset timeout cycle was long enough to glitch the timing.
Linux does indeed have some POST cycles in the kernel. So, it is possible that on some chipsets, now and in the future, this could be an issue. The best part is that the actual problem can appear or not appear depending on chipset, revision, and bios revision. Isn't that fun?
Since kernel version 2.6.25 (I believe) it is possible switch off (most of?) the POST cycles in the kernel. In the menuconfig, the option can be found under Kernel Hacking -> IO delay type. Available options are to use port 0x80 (POST), port 0xed, use the kernel's internal udelay function, or to make the delays a NOP since they are generally not necessary anymore on current hardware.
The default for i386 is still to use port 0x80, but that may improve over time (after it has received more testing). And we have a way to try to solve the problem if you suspect being bitten by it now.
Kind regards, Tim.