diff --git a/flashrom-r710-r931.diff b/flashrom-r710-r995.diff similarity index 85% rename from flashrom-r710-r931.diff rename to flashrom-r710-r995.diff index 044c6e4..602dca0 100644 --- a/flashrom-r710-r931.diff +++ b/flashrom-r710-r995.diff @@ -1,15 +1,16 @@ diff --git a/82802ab.c b/82802ab.c -index 28fa177..e63dc10 100644 +index 28fa177..c9d1a75 100644 --- a/82802ab.c +++ b/82802ab.c -@@ -29,17 +29,18 @@ +@@ -29,51 +29,63 @@ #include #include #include "flash.h" +#include "chipdrivers.h" // I need that Berkeley bit-map printer - void print_82802ab_status(uint8_t status) +-void print_82802ab_status(uint8_t status) ++void print_status_82802ab(uint8_t status) { - printf("%s", status & 0x80 ? "Ready:" : "Busy:"); - printf("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:"); @@ -18,19 +19,21 @@ index 28fa177..e63dc10 100644 - printf("%s", status & 0x8 ? "VP ERR:" : "VPP OK:"); - printf("%s", status & 0x4 ? "PROG SUSPEND:" : "PROG RUN/FINISH:"); - printf("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:"); -+ printf_debug("%s", status & 0x80 ? "Ready:" : "Busy:"); -+ printf_debug("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:"); -+ printf_debug("%s", status & 0x20 ? "BE ERROR:" : "BE OK:"); -+ printf_debug("%s", status & 0x10 ? "PROG ERR:" : "PROG OK:"); -+ printf_debug("%s", status & 0x8 ? "VP ERR:" : "VPP OK:"); -+ printf_debug("%s", status & 0x4 ? "PROG SUSPEND:" : "PROG RUN/FINISH:"); -+ printf_debug("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:"); ++ msg_cdbg("%s", status & 0x80 ? "Ready:" : "Busy:"); ++ msg_cdbg("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:"); ++ msg_cdbg("%s", status & 0x20 ? "BE ERROR:" : "BE OK:"); ++ msg_cdbg("%s", status & 0x10 ? "PROG ERR:" : "PROG OK:"); ++ msg_cdbg("%s", status & 0x8 ? "VP ERR:" : "VPP OK:"); ++ msg_cdbg("%s", status & 0x4 ? "PROG SUSPEND:" : "PROG RUN/FINISH:"); ++ msg_cdbg("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:"); } int probe_82802ab(struct flashchip *flash) -@@ -47,14 +48,11 @@ int probe_82802ab(struct flashchip *flash) + { chipaddr bios = flash->virtual_memory; uint8_t id1, id2; ++ uint8_t flashcontent1, flashcontent2; ++ int shifted = (flash->feature_bits & FEATURE_ADDR_SHIFTED) != 0; -#if 0 - chip_writeb(0xAA, bios + 0x5555); @@ -47,8 +50,10 @@ index 28fa177..e63dc10 100644 chip_writeb(0x90, bios); programmer_delay(10); -@@ -62,13 +60,11 @@ int probe_82802ab(struct flashchip *flash) - id2 = chip_readb(bios + 0x01); +- id1 = chip_readb(bios); +- id2 = chip_readb(bios + 0x01); ++ id1 = chip_readb(bios + (0x00 << shifted)); ++ id2 = chip_readb(bios + (0x01 << shifted)); /* Leave ID mode */ - chip_writeb(0xAA, bios + 0x5555); @@ -59,11 +64,31 @@ index 28fa177..e63dc10 100644 programmer_delay(10); - printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2); -+ printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); ++ msg_cdbg("%s: id1 0x%02x, id2 0x%02x", __func__, id1, id2); ++ ++ if (!oddparity(id1)) ++ msg_cdbg(", id1 parity violation"); ++ /* Read the product ID location again. We should now see normal flash contents. */ ++ flashcontent1 = chip_readb(bios + (0x00 << shifted)); ++ flashcontent2 = chip_readb(bios + (0x01 << shifted)); ++ ++ if (id1 == flashcontent1) ++ msg_cdbg(", id1 is normal flash content"); ++ if (id2 == flashcontent2) ++ msg_cdbg(", id2 is normal flash content"); ++ ++ msg_cdbg("\n"); if (id1 != flash->manufacture_id || id2 != flash->model_id) return 0; -@@ -81,7 +77,6 @@ int probe_82802ab(struct flashchip *flash) + +- map_flash_registers(flash); ++ if (flash->feature_bits & FEATURE_REGISTERMAP) ++ map_flash_registers(flash); + + return 1; + } +@@ -81,7 +93,6 @@ int probe_82802ab(struct flashchip *flash) uint8_t wait_82802ab(chipaddr bios) { uint8_t status; @@ -71,47 +96,56 @@ index 28fa177..e63dc10 100644 chip_writeb(0x70, bios); if ((chip_readb(bios) & 0x80) == 0) { // it's busy -@@ -90,49 +85,38 @@ uint8_t wait_82802ab(chipaddr bios) +@@ -90,49 +101,47 @@ uint8_t wait_82802ab(chipaddr bios) status = chip_readb(bios); - // put another command to get out of status register mode -- ++ /* Reset to get a clean state */ ++ chip_writeb(0xFF, bios); + - chip_writeb(0x90, bios); - programmer_delay(10); -- ++ return status; ++} + - id1 = chip_readb(bios); - id2 = chip_readb(bios + 0x01); -- ++int unlock_82802ab(struct flashchip *flash) ++{ ++ int i; ++ //chipaddr wrprotect = flash->virtual_registers + page + 2; + - // this is needed to jam it out of "read id" mode - chip_writeb(0xAA, bios + 0x5555); - chip_writeb(0x55, bios + 0x2AAA); - chip_writeb(0xF0, bios + 0x5555); -+ /* Reset to get a clean state */ -+ chip_writeb(0xFF, bios); ++ for (i = 0; i < flash->total_size * 1024; i+= flash->page_size) ++ { ++ chip_writeb(0, flash->virtual_registers + i + 2); ++ } - return status; +- return status; ++ return 0; } -int erase_82802ab_block(struct flashchip *flash, int offset) -+int erase_82802ab_block(struct flashchip *flash, unsigned int page, unsigned int pagesize) ++int erase_block_82802ab(struct flashchip *flash, unsigned int page, unsigned int pagesize) { - chipaddr bios = flash->virtual_memory + offset; - chipaddr wrprotect = flash->virtual_registers + offset + 2; + chipaddr bios = flash->virtual_memory; -+ chipaddr wrprotect = flash->virtual_registers + page + 2; uint8_t status; // clear status register - chip_writeb(0x50, bios); - //printf("Erase at %p\n", bios); -+ chip_writeb(0x50, bios + page); -+ - // clear write protect +- // clear write protect - //printf("write protect is at %p\n", (wrprotect)); - //printf("write protect is 0x%x\n", *(wrprotect)); - chip_writeb(0, wrprotect); +- chip_writeb(0, wrprotect); - //printf("write protect is 0x%x\n", *(wrprotect)); ++ chip_writeb(0x50, bios + page); // now start it - chip_writeb(0x20, bios); @@ -124,58 +158,184 @@ index 28fa177..e63dc10 100644 - status = wait_82802ab(flash->virtual_memory); - //print_82802ab_status(status); - if (check_erased_range(flash, offset, flash->page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); + status = wait_82802ab(bios); -+ print_82802ab_status(status); ++ print_status_82802ab(status); + + if (check_erased_range(flash, page, pagesize)) { - fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); return -1; } - printf("DONE BLOCK 0x%x\n", offset); -+ printf("DONE BLOCK 0x%x\n", page); ++ msg_cinfo("DONE BLOCK 0x%x\n", page); return 0; } -@@ -145,7 +129,7 @@ int erase_82802ab(struct flashchip *flash) - printf("total_size is %d; flash->page_size is %d\n", +@@ -142,14 +151,14 @@ int erase_82802ab(struct flashchip *flash) + int i; + unsigned int total_size = flash->total_size * 1024; + +- printf("total_size is %d; flash->page_size is %d\n", ++ msg_cspew("total_size is %d; flash->page_size is %d\n", total_size, flash->page_size); for (i = 0; i < total_size; i += flash->page_size) - if (erase_82802ab_block(flash, i)) { -+ if (erase_82802ab_block(flash, i, flash->page_size)) { - fprintf(stderr, "ERASE FAILED!\n"); +- fprintf(stderr, "ERASE FAILED!\n"); ++ if (erase_block_82802ab(flash, i, flash->page_size)) { ++ msg_cerr("ERASE FAILED!\n"); return -1; } -@@ -199,7 +183,7 @@ int write_82802ab(struct flashchip *flash, uint8_t *buf) - } - - /* erase block by block and write block by block; this is the most secure way */ -- if (erase_82802ab_block(flash, i * page_size)) { -+ if (erase_82802ab_block(flash, i * page_size, page_size)) { - fprintf(stderr, "ERASE FAILED!\n"); - return -1; - } -@@ -207,7 +191,6 @@ int write_82802ab(struct flashchip *flash, uint8_t *buf) - bios + i * page_size, page_size); - } - printf("\n"); -- protect_jedec(bios); - free(tmpbuf); +- printf("DONE ERASE\n"); ++ msg_cinfo("DONE ERASE\n"); return 0; + } +@@ -170,45 +179,76 @@ void write_page_82802ab(chipaddr bios, uint8_t *src, + int write_82802ab(struct flashchip *flash, uint8_t *buf) + { + int i; +- int total_size = flash->total_size * 1024; +- int page_size = flash->page_size; + chipaddr bios = flash->virtual_memory; +- uint8_t *tmpbuf = malloc(page_size); + +- if (!tmpbuf) { +- printf("Could not allocate memory!\n"); +- exit(1); ++ if (erase_flash(flash)) { ++ msg_cerr("ERASE FAILED!\n"); ++ return -1; + } +- printf("Programming page: \n"); +- for (i = 0; i < total_size / page_size; i++) { +- printf +- ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- printf("%04d at address: 0x%08x", i, i * page_size); +- +- /* Auto Skip Blocks, which already contain the desired data +- * Faster, because we only write, what has changed +- * More secure, because blocks, which are excluded +- * (with the exclude or layout feature) +- * or not erased and rewritten; their data is retained also in +- * sudden power off situations +- */ +- chip_readn(tmpbuf, bios + i * page_size, page_size); +- if (!memcmp((void *)(buf + i * page_size), tmpbuf, page_size)) { +- printf("SKIPPED\n"); +- continue; +- } + +- /* erase block by block and write block by block; this is the most secure way */ +- if (erase_82802ab_block(flash, i * page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; ++ msg_cinfo("Programming at: "); ++ for (i = 0; i < flash->total_size; i++) { ++ if ((i & 0x3) == 0) ++ msg_cinfo("address: 0x%08lx", (unsigned long)i * 1024); ++ ++ write_page_82802ab(bios, buf + i * 1024, bios + i * 1024, 1024); ++ ++ if ((i & 0x3) == 0) ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ } ++ ++ msg_cinfo("DONE!\n"); ++ return 0; ++} ++ ++int unlock_28f004s5(struct flashchip *flash) ++{ ++ chipaddr bios = flash->virtual_memory; ++ uint8_t mcfg, bcfg, need_unlock = 0, can_unlock = 0; ++ int i; ++ ++ /* Clear status register */ ++ chip_writeb(0x50, bios); ++ ++ /* Read identifier codes */ ++ chip_writeb(0x90, bios); ++ ++ /* Read master lock-bit */ ++ mcfg = chip_readb(bios + 0x3); ++ msg_cdbg("master lock is "); ++ if (mcfg) { ++ msg_cdbg("locked!\n"); ++ } else { ++ msg_cdbg("unlocked!\n"); ++ can_unlock = 1; ++ } ++ ++ /* Read block lock-bits */ ++ for (i = 0; i < flash->total_size * 1024; i+= (64 * 1024)) { ++ bcfg = chip_readb(bios + i + 2); // read block lock config ++ msg_cdbg("block lock at %06x is %slocked!\n", i, bcfg ? "" : "un"); ++ if (bcfg) { ++ need_unlock = 1; + } +- write_page_82802ab(bios, buf + i * page_size, +- bios + i * page_size, page_size); + } +- printf("\n"); +- protect_jedec(bios); +- free(tmpbuf); ++ ++ /* Reset chip */ ++ chip_writeb(0xFF, bios); ++ ++ /* Unlock: clear block lock-bits, if needed */ ++ if (can_unlock && need_unlock) { ++ msg_cdbg("Unlock: "); ++ chip_writeb(0x60, bios); ++ chip_writeb(0xD0, bios); ++ chip_writeb(0xFF, bios); ++ msg_cdbg("Done!\n"); ++ } ++ ++ /* Error: master locked or a block is locked */ ++ if (!can_unlock && need_unlock) { ++ msg_cerr("At least one block is locked and lockdown is active!\n"); ++ return -1; ++ } + + return 0; + } diff --git a/Makefile b/Makefile -index 881c8f2..9245624 100644 +index 881c8f2..31fc858 100644 --- a/Makefile +++ b/Makefile -@@ -25,7 +25,7 @@ INSTALL = install +@@ -2,6 +2,7 @@ + # This file is part of the flashrom project. + # + # Copyright (C) 2005 coresystems GmbH ++# Copyright (C) 2009,2010 Carl-Daniel Hailfinger + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -20,37 +21,49 @@ + PROGRAM = flashrom + + CC ?= gcc +-STRIP = strip ++STRIP ?= strip + INSTALL = install DIFF = diff PREFIX ?= /usr/local MANDIR ?= $(PREFIX)/share/man -CFLAGS ?= -Os -Wall -Werror -+CFLAGS ?= -Os -Wall -Werror -Wshadow ++CFLAGS ?= -Os -Wall -Wshadow EXPORTDIR ?= . - OS_ARCH = $(shell uname) -@@ -33,24 +33,23 @@ ifneq ($(OS_ARCH), SunOS) +-OS_ARCH = $(shell uname) ++WARNERROR ?= yes ++ ++ifeq ($(WARNERROR), yes) ++CFLAGS += -Werror ++endif ++ ++# FIXME We have to differentiate between host and target arch. ++OS_ARCH ?= $(shell uname) + ifneq ($(OS_ARCH), SunOS) STRIP_ARGS = -s endif ifeq ($(OS_ARCH), Darwin) @@ -189,12 +349,20 @@ index 881c8f2..9245624 100644 +CPPFLAGS += -I/usr/local/include LDFLAGS += -L/usr/local/lib endif - --LIBS += -lpci -lz -+CHIP_OBJS = jedec.o stm50flw0x0x.o w39v040c.o w39v080fa.o sharplhf00l04.o w29ee011.o \ ++ifeq ($(OS_ARCH), DOS) ++CPPFLAGS += -I../libgetopt -I../libpci/include ++# Bus Pirate and Serprog are not supported under DOS. ++CONFIG_BUSPIRATESPI = no ++CONFIG_SERPROG = no ++endif ++ ++CHIP_OBJS = jedec.o stm50flw0x0x.o w39v040c.o w39v080fa.o w29ee011.o \ + sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \ + sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o +-LIBS += -lpci -lz ++LIB_OBJS = layout.o + -OBJS = chipset_enable.o board_enable.o udelay.o jedec.o stm50flw0x0x.o \ - sst28sf040.o am29f040b.o mx29f002.o m29f400bt.o pm29f002.o \ - w49f002u.o 82802ab.o pm49fl00x.o sst49lf040.o en29f002a.o \ @@ -203,24 +371,22 @@ index 881c8f2..9245624 100644 - ichspi.o w39v040c.o sb600spi.o wbsio_spi.o m29f002.o internal.o \ - dummyflasher.o pcidev.o nic3com.o satasii.o ft2232_spi.o \ - print.o -+LIB_OBJS = layout.o -+ +CLI_OBJS = flashrom.o cli_classic.o cli_output.o print.o + +PROGRAMMER_OBJS = udelay.o programmer.o all: pciutils features dep $(PROGRAM) -@@ -58,7 +57,7 @@ all: pciutils features dep $(PROGRAM) +@@ -58,7 +71,7 @@ all: pciutils features dep $(PROGRAM) # of the checked out flashrom files. # Note to packagers: Any tree exported with "make export" or "make tarball" # will not require subversion. The downloadable snapshots are already exported. -SVNVERSION := 710 -+SVNVERSION := 931 ++SVNVERSION := 995 RELEASE := 0.9.1 VERSION := $(RELEASE)-r$(SVNVERSION) -@@ -66,23 +65,150 @@ RELEASENAME ?= $(VERSION) +@@ -66,23 +79,162 @@ RELEASENAME ?= $(VERSION) SVNDEF := -D'FLASHROM_VERSION="$(VERSION)"' @@ -350,12 +516,22 @@ index 881c8f2..9245624 100644 +endif + +ifeq ($(NEED_PCI), yes) -+LIBS += -lpci ++CHECK_LIBPCI = yes ++endif ++ ++ifeq ($(NEED_PCI), yes) +FEATURE_CFLAGS += -D'NEED_PCI=1' +PROGRAMMER_OBJS += pcidev.o physmap.o hwaccess.o +ifeq ($(OS_ARCH), NetBSD) +LIBS += -lpciutils # The libpci we want. +LIBS += -l$(shell uname -p) # For (i386|x86_64)_iopl(2). ++else ++ifeq ($(OS_ARCH), DOS) ++# FIXME There needs to be a better way to do this ++LIBS += ../libpci/lib/libpci.a ../libgetopt/libgetopt.a ++else ++LIBS += -lpci ++endif +endif +endif + @@ -364,6 +540,8 @@ index 881c8f2..9245624 100644 +CLI_OBJS += print_wiki.o +endif + ++FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "UTSNAME := yes" .features && printf "%s" "-D'HAVE_UTSNAME=1'") ++ +# We could use PULLED_IN_LIBS, but that would be ugly. +FEATURE_LIBS += $(shell LC_ALL=C grep -q "NEEDLIBZ := yes" .libdeps && printf "%s" "-lz") + @@ -375,7 +553,7 @@ index 881c8f2..9245624 100644 # TAROPTIONS reduces information leakage from the packager's system. # If other tar programs support command line arguments for setting uid/gid of -@@ -96,7 +222,7 @@ clean: +@@ -96,7 +248,7 @@ clean: rm -f $(PROGRAM) *.o distclean: clean @@ -384,7 +562,7 @@ index 881c8f2..9245624 100644 dep: @$(CC) $(CPPFLAGS) $(SVNDEF) -MM *.c > .dependencies -@@ -108,26 +234,51 @@ compiler: +@@ -108,26 +260,42 @@ compiler: @printf "Checking for a C compiler... " @$(shell ( echo "int main(int argc, char **argv)"; \ echo "{ return 0; }"; ) > .test.c ) @@ -394,7 +572,7 @@ index 881c8f2..9245624 100644 rm -f .test.c .test; exit 1) @rm -f .test.c .test -+ifeq ($(NEED_PCI), yes) ++ifeq ($(CHECK_LIBPCI), yes) pciutils: compiler - @printf "Checking for pciutils and zlib... " + @printf "Checking for libpci headers... " @@ -413,26 +591,17 @@ index 881c8f2..9245624 100644 + echo "Please install libpci headers (package pciutils-devel)."; \ + echo "See README for more information."; echo; \ + rm -f .test.c .test.o; exit 1) -+ @printf "Checking for libpci... " -+ @$(shell ( echo "#include "; \ -+ echo "int main(int argc, char **argv)"; \ -+ echo "{ return 0; }"; ) > .test1.c ) -+ @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .test1.c -o .test1 -lpci $(LIBS) >/dev/null 2>&1 && \ -+ echo "found." || ( echo "not found."; echo; \ -+ echo "Please install libpci (package pciutils)."; \ -+ echo "See README for more information."; echo; \ -+ rm -f .test1.c .test1; exit 1) -+ @printf "Checking if libpci is sufficient... " ++ @printf "Checking if libpci is present and sufficient... " + @printf "" > .libdeps -+ @$(CC) $(LDFLAGS) .test.o -o .test -lpci $(LIBS) >/dev/null 2>&1 && \ ++ @$(CC) $(LDFLAGS) .test.o -o .test $(LIBS) >/dev/null 2>&1 && \ + echo "yes." || ( echo "no."; \ -+ printf "Checking if libz is present and supplies all needed symbols..."; \ -+ $(CC) $(LDFLAGS) .test.o -o .test -lpci -lz $(LIBS) >/dev/null 2>&1 && \ ++ printf "Checking if libz+libpci are present and sufficient..."; \ ++ $(CC) $(LDFLAGS) .test.o -o .test $(LIBS) -lz >/dev/null 2>&1 && \ + ( echo "yes."; echo "NEEDLIBZ := yes" > .libdeps ) || ( echo "no."; echo; \ -+ echo "Please install libz."; \ ++ echo "Please install libpci (package pciutils) and/or libz."; \ + echo "See README for more information."; echo; \ + rm -f .test.c .test.o .test; exit 1) ) -+ @rm -f .test.c .test.o .test .test1.c .test1 ++ @rm -f .test.c .test.o .test +else +pciutils: compiler + @printf "" > .libdeps @@ -444,7 +613,7 @@ index 881c8f2..9245624 100644 features: compiler @echo "FEATURES := yes" > .features.tmp @printf "Checking for FTDI support... " -@@ -135,11 +286,16 @@ features: compiler +@@ -135,11 +303,33 @@ features: compiler echo "struct ftdi_context *ftdic = NULL;"; \ echo "int main(int argc, char **argv)"; \ echo "{ return ftdi_init(ftdic); }"; ) > .featuretest.c ) @@ -452,18 +621,46 @@ index 881c8f2..9245624 100644 + @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest $(FTDILIBS) $(LIBS) >/dev/null 2>&1 && \ ( echo "found."; echo "FTDISUPPORT := yes" >> .features.tmp ) || \ ( echo "not found."; echo "FTDISUPPORT := no" >> .features.tmp ) - @$(DIFF) -q .features.tmp .features >/dev/null 2>&1 && rm .features.tmp || mv .features.tmp .features - @rm -f .featuretest.c .featuretest ++ @printf "Checking for utsname support... " ++ @$(shell ( echo "#include "; \ ++ echo "struct utsname osinfo;"; \ ++ echo "int main(int argc, char **argv)"; \ ++ echo "{ uname (&osinfo); return 0; }"; ) > .featuretest.c ) ++ @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest >/dev/null 2>&1 && \ ++ ( echo "found."; echo "UTSNAME := yes" >> .features.tmp ) || \ ++ ( echo "not found."; echo "UTSNAME := no" >> .features.tmp ) ++ @$(DIFF) -q .features.tmp .features >/dev/null 2>&1 && rm .features.tmp || mv .features.tmp .features ++ @rm -f .featuretest.c .featuretest +else +features: compiler + @echo "FEATURES := yes" > .features.tmp -+ @$(DIFF) -q .features.tmp .features >/dev/null 2>&1 && rm .features.tmp || mv .features.tmp .features ++ @printf "Checking for utsname support... " ++ @$(shell ( echo "#include "; \ ++ echo "struct utsname osinfo;"; \ ++ echo "int main(int argc, char **argv)"; \ ++ echo "{ uname (&osinfo); return 0; }"; ) > .featuretest.c ) ++ @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest >/dev/null 2>&1 && \ ++ ( echo "found."; echo "UTSNAME := yes" >> .features.tmp ) || \ ++ ( echo "not found."; echo "UTSNAME := no" >> .features.tmp ) + @$(DIFF) -q .features.tmp .features >/dev/null 2>&1 && rm .features.tmp || mv .features.tmp .features + @rm -f .featuretest.c .featuretest +endif install: $(PROGRAM) mkdir -p $(DESTDIR)$(PREFIX)/sbin +@@ -159,6 +349,9 @@ tarball: export + @rm -rf $(EXPORTDIR)/flashrom-$(RELEASENAME) + @echo Created $(EXPORTDIR)/flashrom-$(RELEASENAME).tar.bz2 + +-.PHONY: all clean distclean dep compiler pciutils features export tarball ++djgpp-dos: clean ++ make CC=i586-pc-msdosdjgpp-gcc STRIP=i586-pc-msdosdjgpp-strip WARNERROR=no OS_ARCH=DOS ++ ++.PHONY: all clean distclean dep compiler pciutils features export tarball dos + + -include .dependencies diff --git a/README b/README -index b6a0792..0150e90 100644 +index b6a0792..8ccfc2f 100644 --- a/README +++ b/README @@ -11,6 +11,8 @@ program flash chips. @@ -475,16 +672,19 @@ index b6a0792..0150e90 100644 Packaging --------- -@@ -38,7 +40,7 @@ To build flashrom you need to install the following packages or ports: +@@ -38,9 +40,9 @@ To build flashrom you need to install the following packages or ports: Linux et al: - * pciutils + * pciutils / libpci * pciutils-devel / pciutils-dev / libpci-dev - * zlib-devel / zlib1g-dev (only needed if libpci is static) +- * zlib-devel / zlib1g-dev (only needed if libpci is static) ++ * zlib-devel / zlib1g-dev (needed if libpci was compiled with libz support) -@@ -63,10 +65,10 @@ To compile on Solaris, use: + On FreeBSD, you need the following ports: + +@@ -63,58 +65,49 @@ To compile on Solaris, use: gmake LDFLAGS="-L$pathtolibpci" CC="gcc -I$pathtopciheaders" CFLAGS=-O2 @@ -497,7 +697,31 @@ index b6a0792..0150e90 100644 To compile and run on Darwin/Mac OS X: -@@ -79,42 +81,14 @@ Installation + Install DirectIO from coresystems GmbH. + DirectIO is available at http://www.coresystems.de/en/directio. + ++To cross-compile on Linux for DOS: ++ ++ Get RPMs of the cross compiler from the DJGPP site and install them: ++ djcross-binutils-2.19.1-10ap.i386.rpm ++ djcross-gcc-tools-4.4.1-1ap.i686.rpm ++ djcross-gcc-4.3.2-8ap.i686.rpm ++ Download pciutils 3.1.5 and apply http://assembler.cz/flashrom/pciutils.patch ++ Download and compile http://assembler.cz/flashrom/libgetopt/ ++ Compile pciutils, see README.DJGPP for instructions. ++ Enter the flashrom directory. ++ ../libpci should contain pciutils source and binaries. ++ ../libgetopt should contain getopt.a from libgetopt. ++ Run either (change settings where appropriate) ++ make CC=i586-pc-msdosdjgpp-gcc STRIP=i586-pc-msdosdjgpp-strip OS_ARCH=DOS ++ or (above settings hardcoded) ++ make djgpp-dos ++ You might have to add WARNERROR=no to the make command line. ++ To run flashrom.exe, download http://clio.rice.edu/djgpp/csdpmi7b.zip and ++ make sure CWSDPMI.EXE is in the current directory. + + Installation + ------------ In order to install flashrom and the manpage into /usr/local, type: @@ -544,6 +768,14 @@ index b6a0792..0150e90 100644 Contact +@@ -128,6 +121,6 @@ The IRC channel is + + #flashrom at irc.freenode.net + +-The Mailing list addess is ++The mailing list address is + + flashrom@flashrom.org diff --git a/am29f040b.c b/am29f040b.c deleted file mode 100644 index 7f1269c..0000000 @@ -953,7 +1185,7 @@ index 0000000..8d6a9a1 + return 0; +} diff --git a/board_enable.c b/board_enable.c -index c87e782..0e89137 100644 +index c87e782..f1f7953 100644 --- a/board_enable.c +++ b/board_enable.c @@ -66,6 +66,35 @@ void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask) @@ -973,7 +1205,7 @@ index c87e782..0e89137 100644 + break; + case SUPERIO_VENDOR_ITE: + enter_conf_mode_ite(superio.port); -+ /* Enable flash mapping. Works for most old ITE style SuperI/O. */ ++ /* Enable flash mapping. Works for most old ITE style Super I/O. */ + tmp = sio_read(superio.port, 0x24); + tmp |= 0xfc; + sio_write(superio.port, 0x24, tmp); @@ -981,7 +1213,7 @@ index c87e782..0e89137 100644 + ret = 0; + break; + default: -+ printf_debug("Unhandled SuperI/O type!\n"); ++ printf_debug("Unhandled Super I/O type!\n"); + ret = -1; + break; + } @@ -992,7 +1224,7 @@ index c87e782..0e89137 100644 /** * Winbond W83627HF: Raise GPIO24. * -@@ -162,25 +191,111 @@ static void w836xx_memw_enable(uint16_t port) +@@ -162,25 +191,118 @@ static void w836xx_memw_enable(uint16_t port) } /** @@ -1009,6 +1241,21 @@ index c87e782..0e89137 100644 { - uint8_t val; + w836xx_memw_enable(0x2E); + +- /* All memory cycles, not just ROM ones, go to LPC. */ +- val = pci_read_byte(dev, 0x59); +- val &= ~0x80; +- pci_write_byte(dev, 0x59, val); ++ return 0; ++} ++ ++/** ++ * Suited for: ++ * - Termtek TK-3370 (rev. 2.5b) ++ */ ++static int w836xx_memw_enable_4e(const char *name) ++{ ++ w836xx_memw_enable(0x4E); + + return 0; +} @@ -1034,53 +1281,45 @@ index c87e782..0e89137 100644 + * - GIGABYTE GA-7VT600: VIA KT600 + VT8237 + IT8705 + * - Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F + * -+ * SIS950 superio probably requires the same flash write enable. ++ * The SIS950 Super I/O probably requires the same flash write enable. + */ +static int it8705f_write_enable_2e(const char *name) +{ + return it8705f_write_enable(0x2e, name); +} - -- /* All memory cycles, not just ROM ones, go to LPC. */ -- val = pci_read_byte(dev, 0x59); -- val &= ~0x80; -- pci_write_byte(dev, 0x59, val); ++ +static int pc87360_gpio_set(uint8_t gpio, int raise) +{ + static const int bankbase[] = {0, 4, 8, 10, 12}; + int gpio_bank = gpio / 8; + int gpio_pin = gpio % 8; + uint16_t baseport; -+ uint8_t id; -+ uint8_t val; ++ uint8_t id, val; + -+ if (gpio_bank > 4) -+ { ++ if (gpio_bank > 4) { + fprintf(stderr, "PC87360: Invalid GPIO %d\n", gpio); + return -1; + } + + id = sio_read(0x2E, 0x20); -+ if (id != 0xE1) -+ { ++ if (id != 0xE1) { + fprintf(stderr, "PC87360: unexpected ID %02x\n", id); + return -1; + } + -+ sio_write(0x2E, 0x07, 0x07); /* select GPIO device */ ++ sio_write(0x2E, 0x07, 0x07); /* Select GPIO device */ + baseport = (sio_read(0x2E, 0x60) << 8) | sio_read(0x2E, 0x61); -+ if((baseport & 0xFFF0) == 0xFFF0 || baseport == 0) -+ { ++ if ((baseport & 0xFFF0) == 0xFFF0 || baseport == 0) { + fprintf (stderr, "PC87360: invalid GPIO base address %04x\n", + baseport); + return -1; + } + sio_mask (0x2E, 0x30, 0x01, 0x01); /* Enable logical device */ -+ sio_write(0x2E, 0xF0, gpio_bank*16 + gpio_pin); ++ sio_write(0x2E, 0xF0, gpio_bank * 16 + gpio_pin); + sio_mask (0x2E, 0xF1, 0x01, 0x01); /* Make pin output */ + + val = INB(baseport + bankbase[gpio_bank]); -+ if(raise) ++ if (raise) + val |= 1 << gpio_pin; + else + val &= ~(1 << gpio_pin); @@ -1113,7 +1352,7 @@ index c87e782..0e89137 100644 if ((gpio >= 12) && (gpio <= 15)) { /* GPIO12-15 -> output */ -@@ -192,126 +307,75 @@ static void vt823x_gpio_set(struct pci_dev *dev, uint8_t gpio, int raise) +@@ -192,126 +314,75 @@ static void vt823x_gpio_set(struct pci_dev *dev, uint8_t gpio, int raise) val = pci_read_byte(dev, 0xE4); val |= 0x20; pci_write_byte(dev, 0xE4, val); @@ -1172,7 +1411,7 @@ index c87e782..0e89137 100644 - * Suited for: - * - ASUS A7V8X-MX SE and A7V400-MX: AMD K7 + VIA KM400A + VT8235 - * - Tyan S2498 (Tomcat K7M): AMD Geode NX + VIA KM400 + VT8237. -+ * Suited for Asus M2V-MX: VIA K8M890 + VT8237A + IT8716F ++ * Suited for ASUS M2V-MX: VIA K8M890 + VT8237A + IT8716F */ -static int board_asus_a7v8x_mx(const char *name) +static int via_vt823x_gpio5_raise(const char *name) @@ -1197,7 +1436,7 @@ index c87e782..0e89137 100644 /** - * Suited for VIAs EPIA SP and EPIA CN. -+ * Suited for VIAs EPIA N & NL. ++ * Suited for VIA EPIA N & NL. */ -static int board_via_epia_sp(const char *name) +static int via_vt823x_gpio9_raise(const char *name) @@ -1218,7 +1457,7 @@ index c87e782..0e89137 100644 /** - * Suited for VIAs EPIA N & NL. -+ * Suited for VIAs EPIA M and MII, and maybe other CLE266 based EPIAs. ++ * Suited for VIA EPIA M and MII, and maybe other CLE266 based EPIAs. + * + * We don't need to do this for EPIA M when using coreboot, GPIO15 is never + * lowered there. @@ -1272,7 +1511,7 @@ index c87e782..0e89137 100644 } /** -@@ -390,94 +454,135 @@ static int board_asus_p5a(const char *name) +@@ -390,94 +461,152 @@ static int board_asus_p5a(const char *name) return 0; } @@ -1302,7 +1541,7 @@ index c87e782..0e89137 100644 /** - * Suited for the Gigabyte GA-K8N-SLI: CK804 southbridge. -+ * Suited for Shuttle FN25 (SN25P): AMD S939 + Nvidia CK804 (nForce4). ++ * Suited for Shuttle FN25 (SN25P): AMD S939 + NVIDIA CK804 (nForce4). */ -static int board_ga_k8n_sli(const char *name) +static int board_shuttle_fn25(const char *name) @@ -1361,8 +1600,7 @@ index c87e782..0e89137 100644 + fprintf(stderr, "\nERROR: unsupported GPIO: %d.\n", gpio); + return -1; + } - -- tmp |= 0x40; ++ + /* First, check the ISA Bridge */ + dev = pci_dev_find_vendorclass(0x10DE, 0x0601); + switch (dev->device_id) { @@ -1378,12 +1616,13 @@ index c87e782..0e89137 100644 + break; + default: + fprintf(stderr, -+ "\nERROR: no nVidia LPC/SMBus controller found.\n"); ++ "\nERROR: no NVIDIA LPC/SMBus controller found.\n"); + return -1; + } + break; + } -+ + +- tmp |= 0x40; + base = pci_read_long(dev, 0x64) & 0x0000FF00; /* System control area */ + base += 0xC0; @@ -1401,7 +1640,8 @@ index c87e782..0e89137 100644 /** - * Suited for Acorp 6A815EPD. -+ * Suited for ASUS M2NBP-VM CSM: nVidia MCP51. ++ * Suited for ASUS A8N-LA: nVidia MCP51. ++ * Suited for ASUS M2NBP-VM CSM: NVIDIA MCP51. */ -static int board_acorp_6a815epd(const char *name) +static int nvidia_mcp_gpio0_raise(const char *name) @@ -1418,22 +1658,22 @@ index c87e782..0e89137 100644 - return -1; - } +/** -+ * Suited for MSI K8N Neo4: nVidia CK804. -+ * Suited for MSI K8N GM2-L: nVidia MCP51. ++ * Suited for Abit KN8 Ultra: nVidia CK804. + */ -+static int nvidia_mcp_gpio2_raise(const char *name) ++static int nvidia_mcp_gpio2_lower(const char *name) +{ -+ return nvidia_mcp_gpio_set(0x02, 1); ++ return nvidia_mcp_gpio_set(0x02, 0); +} - /* Use GPIOBASE register to find where the GPIO is mapped. */ - port = (pci_read_word(dev, 0x58) & 0xFFC0) + 0xE; +/** -+ * Suited for ASUS P5ND2-SLI Deluxe: LGA775 + nForce4 SLI + MCP04. ++ * Suited for MSI K8N Neo4: NVIDIA CK804. ++ * Suited for MSI K8N GM2-L: NVIDIA MCP51. + */ -+static int nvidia_mcp_gpio10_raise(const char *name) ++static int nvidia_mcp_gpio2_raise(const char *name) +{ -+ return nvidia_mcp_gpio_set(0x10, 1); ++ return nvidia_mcp_gpio_set(0x02, 1); +} - val = INB(port); @@ -1441,14 +1681,30 @@ index c87e782..0e89137 100644 - val |= 0x40; /* Lower Blocks Lock -- pin 7 of PLCC32 */ - OUTB(val, port); +/** ++ * Suited for Abit NF7-S: NVIDIA CK804. ++ */ ++static int nvidia_mcp_gpio8_raise(const char *name) ++{ ++ return nvidia_mcp_gpio_set(0x08, 1); ++} + +- return 0; ++/** ++ * Suited for ASUS P5ND2-SLI Deluxe: LGA775 + nForce4 SLI + MCP04. ++ */ ++static int nvidia_mcp_gpio10_raise(const char *name) ++{ ++ return nvidia_mcp_gpio_set(0x10, 1); ++} ++ ++/** + * Suited for the Gigabyte GA-K8N-SLI: CK804 southbridge. + */ +static int nvidia_mcp_gpio21_raise(const char *name) +{ + return nvidia_mcp_gpio_set(0x21, 0x01); +} - -- return 0; ++ +/** + * Suited for EPoX EP-8RDA3+: Socket A + nForce2 Ultra 400 + MCP2. + */ @@ -1458,7 +1714,7 @@ index c87e782..0e89137 100644 } /** -@@ -522,165 +627,366 @@ static int board_artecgroup_dbe6x(const char *name) +@@ -522,175 +651,402 @@ static int board_artecgroup_dbe6x(const char *name) } /** @@ -1472,7 +1728,7 @@ index c87e782..0e89137 100644 - * @param gp_lvl_bitmask GP_LVL bitmask (set GPIO bits to 1, all others to 0). - * @param gpio_bit The bit (GPIO) which shall be set to high. - * @return If the write-enable was successful return 0, otherwise return -1. -+ * Helper function to raise/drop a given gpo line on intel PIIX4{,E,M} ++ * Helper function to raise/drop a given gpo line on Intel PIIX4{,E,M}. */ -static int ich_gpio_raise(const char *name, uint16_t ich_vendor, - uint16_t ich_device, uint8_t gpiobase_reg, @@ -1485,9 +1741,12 @@ index c87e782..0e89137 100644 - uint16_t gpiobar; - uint32_t reg32; + uint32_t tmp, base; -+ + +- dev = pci_dev_find(ich_vendor, ich_device); /* Intel ICHx LPC */ + dev = pci_dev_find(0x8086, 0x7110); /* Intel PIIX4 ISA bridge */ -+ if (!dev) { + if (!dev) { +- fprintf(stderr, "\nERROR: ICHx LPC dev %4x:%4x not found.\n", +- ich_vendor, ich_device); + fprintf(stderr, "\nERROR: Intel PIIX4 ISA bridge not found.\n"); + return -1; + } @@ -1495,16 +1754,22 @@ index c87e782..0e89137 100644 + /* sanity check */ + if (gpo > 30) { + fprintf(stderr, "\nERROR: Intel PIIX4 has no GPO%d.\n", gpo); -+ return -1; -+ } -+ + return -1; + } + +- /* Use GPIOBASE register to find the I/O space for GPIO. */ +- gpiobar = pci_read_word(dev, gpiobase_reg) & gp_lvl_bitmask; + /* these are dual function pins which are most likely in use already */ + if (((gpo >= 1) && (gpo <= 7)) || + ((gpo >= 9) && (gpo <= 21)) || (gpo == 29)) { + fprintf(stderr, "\nERROR: Unsupported PIIX4 GPO%d.\n", gpo); + return -1; + } -+ + +- /* Set specified GPIO to high. */ +- reg32 = INL(gpiobar + gp_lvl); +- reg32 |= (1 << gpio_bit); +- OUTL(reg32, gpiobar + gp_lvl); + /* dual function that need special enable. */ + if ((gpo >= 22) && (gpo <= 26)) { + tmp = pci_read_long(dev, 0xB0); /* GENCFG */ @@ -1525,27 +1790,18 @@ index c87e782..0e89137 100644 + } + pci_write_long(dev, 0xB0, tmp); + } - -- dev = pci_dev_find(ich_vendor, ich_device); /* Intel ICHx LPC */ ++ + /* GPO {0,8,27,28,30} are always available. */ + + dev = pci_dev_find(0x8086, 0x7113); /* Intel PIIX4 PM */ - if (!dev) { -- fprintf(stderr, "\nERROR: ICHx LPC dev %4x:%4x not found.\n", -- ich_vendor, ich_device); ++ if (!dev) { + fprintf(stderr, "\nERROR: Intel PIIX4 PM not found.\n"); - return -1; - } - -- /* Use GPIOBASE register to find the I/O space for GPIO. */ -- gpiobar = pci_read_word(dev, gpiobase_reg) & gp_lvl_bitmask; ++ return -1; ++ } ++ + /* PM IO base */ + base = pci_read_long(dev, 0x40) & 0x0000FFC0; - -- /* Set specified GPIO to high. */ -- reg32 = INL(gpiobar + gp_lvl); -- reg32 |= (1 << gpio_bit); -- OUTL(reg32, gpiobar + gp_lvl); ++ + gpo_byte = gpo >> 3; + gpo_bit = gpo & 7; + tmp = INB(base + 0x34 + gpo_byte); /* GPO register */ @@ -1571,14 +1827,25 @@ index c87e782..0e89137 100644 /** - * Suited for MSI MS-7046. -+ * Set a GPIO line on a given intel ICH LPC controller. ++ * Suited for Intel SE440BX-2 */ -static int ich6_gpio19_raise(const char *name) -+static int intel_ich_gpio_set(int gpio, int raise) ++static int intel_piix4_gpo27_lower(const char *name) { - return ich_gpio_raise(name, 0x8086, 0x2640, 0x48, 0x0c, 0xffc0, 19); --} -+ /* table mapping the different intel ICH LPC chipsets. */ ++ return intel_piix4_gpo_set(27, 0); + } + +-static int board_kontron_986lcd_m(const char *name) ++/** ++ * Set a GPIO line on a given Intel ICH LPC controller. ++ */ ++static int intel_ich_gpio_set(int gpio, int raise) + { +- struct pci_dev *dev; +- uint16_t gpiobar; +- uint32_t val; ++ /* Table mapping the different Intel ICH LPC chipsets. */ + static struct { + uint16_t id; + uint8_t base_reg; @@ -1619,13 +1886,8 @@ index c87e782..0e89137 100644 + {0, 0, 0, 0, 0} /* end marker */ + }; --static int board_kontron_986lcd_m(const char *name) --{ - struct pci_dev *dev; -- uint16_t gpiobar; -- uint32_t val; -- -#define ICH7_GPIO_LVL2 0x38 ++ struct pci_dev *dev; + uint16_t base; + uint32_t tmp; + int i, allowed; @@ -1650,13 +1912,11 @@ index c87e782..0e89137 100644 - // This will never happen on this board - fprintf(stderr, "\nERROR: ICH7 LPC bridge not found.\n"); + fprintf(stderr, "\nERROR: No Known Intel LPC Bridge found.\n"); - return -1; - } - -- /* Use GPIOBASE register to find where the GPIO is mapped. */ -- gpiobar = pci_read_word(dev, 0x48) & 0xfffc; -+ /* According to the datasheets, all intel ICHs have the gpio bar 5:1 -+ strapped to zero. From some mobile ich9 version on, this becomes ++ return -1; ++ } ++ ++ /* According to the datasheets, all Intel ICHs have the GPIO bar 5:1 ++ strapped to zero. From some mobile ICH9 version on, this becomes + 6:1. The mask below catches all. */ + base = pci_read_word(dev, intel_ich_gpio_table[i].base_reg) & 0xFFC0; + @@ -1671,9 +1931,11 @@ index c87e782..0e89137 100644 + if (!allowed) { + fprintf(stderr, "\nERROR: This Intel LPC Bridge does not allow" + " setting GPIO%02d\n", gpio); -+ return -1; -+ } -+ + return -1; + } + +- /* Use GPIOBASE register to find where the GPIO is mapped. */ +- gpiobar = pci_read_word(dev, 0x48) & 0xfffc; + printf("\nIntel ICH LPC Bridge: %sing GPIO%02d.\n", + raise ? "Rais" : "Dropp", gpio); + @@ -1704,9 +1966,7 @@ index c87e782..0e89137 100644 + tmp = INL(base + 0x04); + tmp &= ~(1 << gpio); + OUTL(tmp, base + 0x04); - -- val = INL(gpiobar + ICH7_GPIO_LVL2); /* GP_LVL2 */ -- printf_debug("\nGPIOBAR=0x%04x GP_LVL: 0x%08x\n", gpiobar, val); ++ + /* Raise GPIO line */ + tmp = INL(base + 0x0C); + if (raise) @@ -1733,22 +1993,14 @@ index c87e782..0e89137 100644 + return -1; + } + } - -- /* bit 2 (0x04) = 0 #TBL --> bootblock locking = 1 -- * bit 2 (0x04) = 1 #TBL --> bootblock locking = 0 -- * bit 3 (0x08) = 0 #WP --> block locking = 1 -- * bit 3 (0x08) = 1 #WP --> block locking = 0 -- * -- * To enable full block locking, you would do: -- * val &= ~ ((1 << 2) | (1 << 3)); -- */ -- val |= (1 << 2) | (1 << 3); ++ + /* Set GPIO to OUTPUT */ + tmp = INL(base + 0x34); + tmp &= ~(1 << gpio); + OUTL(tmp, base + 0x34); -- OUTL(val, gpiobar + ICH7_GPIO_LVL2); +- val = INL(gpiobar + ICH7_GPIO_LVL2); /* GP_LVL2 */ +- printf_debug("\nGPIOBAR=0x%04x GP_LVL: 0x%08x\n", gpiobar, val); + /* Raise GPIO line */ + tmp = INL(base + 0x38); + if (raise) @@ -1770,12 +2022,22 @@ index c87e782..0e89137 100644 + "not allow setting GPIO%02d\n", gpio + 64); + return -1; + } -+ + +- /* bit 2 (0x04) = 0 #TBL --> bootblock locking = 1 +- * bit 2 (0x04) = 1 #TBL --> bootblock locking = 0 +- * bit 3 (0x08) = 0 #WP --> block locking = 1 +- * bit 3 (0x08) = 1 #WP --> block locking = 0 +- * +- * To enable full block locking, you would do: +- * val &= ~ ((1 << 2) | (1 << 3)); +- */ +- val |= (1 << 2) | (1 << 3); + /* Set GPIO to OUTPUT */ + tmp = INL(base + 0x44); + tmp &= ~(1 << gpio); + OUTL(tmp, base + 0x44); -+ + +- OUTL(val, gpiobar + ICH7_GPIO_LVL2); + /* Raise GPIO line */ + tmp = INL(base + 0x48); + if (raise) @@ -1808,10 +2070,17 @@ index c87e782..0e89137 100644 - * bit 7: map flash chip at 1MB-128K (why though? ignoring this.) - */ - sio_mask(0x2e, 0x24, 0x04, 0x04); -- ++ return intel_ich_gpio_set(16, 1); ++} + - /* exit IT87xx conf mode */ - exit_conf_mode_ite(0x2e); -+ return intel_ich_gpio_set(16, 1); ++/** ++ * Suited for ASUS A8JM: Intel 945 + ICH7 ++ */ ++static int intel_ich_gpio34_raise(const char *name) ++{ ++ return intel_ich_gpio_set(34, 1); +} - return 0; @@ -1826,8 +2095,9 @@ index c87e782..0e89137 100644 /** - * Suited for AOpen vKM400Am-S: VIA KM400 + VT8237 + IT8705F. + * Suited for: -+ * - Asus P4B266LM (Sony Vaio PCV-RX650): socket478 + 845D + ICH2. -+ * - Asus P4P800-E Deluxe: Intel socket478 + 865PE + ICH5R. ++ * - ASUS P4B266LM (Sony Vaio PCV-RX650): socket478 + 845D + ICH2. ++ * - ASUS P4C800-E Deluxe: socket478 + 875P + ICH5. ++ * - ASUS P4P800-E Deluxe: Intel socket478 + 865PE + ICH5R. */ -static int board_aopen_vkm400(const char *name) +static int intel_ich_gpio21_raise(const char *name) @@ -1843,8 +2113,9 @@ index c87e782..0e89137 100644 - } +/** + * Suited for: -+ * - Asus P4B266: socket478 + intel 845D + ICH2. -+ * - Asus P4B-MX variant in HP Vectra VL420 SFF: socket478 + 845D + ICH2 ++ * - ASUS P4B266: socket478 + Intel 845D + ICH2. ++ * - ASUS P4B533-E: socket478 + 845E + ICH4 ++ * - ASUS P4B-MX variant in HP Vectra VL420 SFF: socket478 + 845D + ICH2 + */ +static int intel_ich_gpio22_raise(const char *name) +{ @@ -1875,7 +2146,7 @@ index c87e782..0e89137 100644 - * - MSI KT4V and KT4V-L: AMD K7 + VIA KT400 + VT8235 - * - MSI KT4 Ultra: AMD K7 + VIA KT400 + VT8235 - * - MSI KT3 Ultra2: AMD K7 + VIA KT333 + VT8235 -+ * - Dell Poweredge 1850: Intel PPGA604 + E7520 + ICH5R. ++ * - Dell PowerEdge 1850: Intel PPGA604 + E7520 + ICH5R. + * - ASRock P4i65GV: Intel Socket478 + 865GV + ICH5R. */ -static int board_msi_kt4v(const char *name) @@ -1892,26 +2163,34 @@ index c87e782..0e89137 100644 - return -1; - } +/** ++ * Suited for IBase MB899: i945GM + ICH7. ++ */ ++static int intel_ich_gpio26_raise(const char *name) ++{ ++ return intel_ich_gpio_set(26, 1); ++} + +- val = pci_read_byte(dev, 0x59); +- val &= 0x0c; +- pci_write_byte(dev, 0x59, val); ++/** + * Suited for Acorp 6A815EPD: socket 370 + intel 815 + ICH2. + */ +static int board_acorp_6a815epd(const char *name) +{ + int ret; -- val = pci_read_byte(dev, 0x59); -- val &= 0x0c; -- pci_write_byte(dev, 0x59, val); +- vt823x_gpio_set(dev, 12, 1); +- w836xx_memw_enable(0x2E); + /* Lower Blocks Lock -- pin 7 of PLCC32 */ + ret = intel_ich_gpio_set(22, 1); + if (!ret) /* Top Block Lock -- pin 8 of PLCC32 */ + ret = intel_ich_gpio_set(23, 1); -- vt823x_gpio_set(dev, 12, 1); -- w836xx_memw_enable(0x2E); +- return 0; + return ret; +} - -- return 0; ++ +/** + * Suited for Kontron 986LCD-M: socket478 + 915GM + ICH7R. + */ @@ -1927,19 +2206,85 @@ index c87e782..0e89137 100644 } /** -@@ -715,23 +1021,35 @@ static int board_soyo_sy_7vca(const char *name) + * Suited for Soyo SY-7VCA: Pro133A + VT82C686. + */ +-static int board_soyo_sy_7vca(const char *name) ++static int via_apollo_gpo_set(int gpio, int raise) + { +- struct pci_dev *dev; ++ struct pci_dev *dev; + uint32_t base; +- uint8_t tmp; ++ uint32_t tmp; + + /* VT82C686 Power management */ + dev = pci_dev_find(0x1106, 0x3057); +@@ -699,39 +1055,86 @@ static int board_soyo_sy_7vca(const char *name) + return -1; + } + +- /* GPO0 output from PM IO base + 0x4C */ ++ printf("\nVIA Apollo ACPI: %sing GPIO%02d.\n", ++ raise ? "Rais" : "Dropp", gpio); ++ ++ /* select GPO function on multiplexed pins */ + tmp = pci_read_byte(dev, 0x54); +- tmp &= ~0x03; ++ switch(gpio) ++ { ++ case 0: ++ tmp &= ~0x03; ++ break; ++ case 1: ++ tmp |= 0x04; ++ break; ++ case 2: ++ tmp |= 0x08; ++ break; ++ case 3: ++ tmp |= 0x10; ++ break; ++ } + pci_write_byte(dev, 0x54, tmp); + + /* PM IO base */ + base = pci_read_long(dev, 0x48) & 0x0000FF00; + + /* Drop GPO0 */ +- tmp = INB(base + 0x4C); +- tmp &= ~0x01; +- OUTB(tmp, base + 0x4C); ++ tmp = INL(base + 0x4C); ++ if (raise) ++ tmp |= 1U << gpio; ++ else ++ tmp &= ~(1U << gpio); ++ OUTL(tmp, base + 0x4C); + return 0; } -static int it8705f_write_enable(uint8_t port, const char *name) --{ ++/** ++ * Suited for Abit VT6X4: Pro133x + VT82C686A ++ */ ++static int via_apollo_gpo4_lower(const char *name) + { - enter_conf_mode_ite(port); - sio_mask(port, 0x24, 0x04, 0x04); /* Flash ROM I/F Writes Enable */ - exit_conf_mode_ite(port); -- ++ return via_apollo_gpo_set(4, 0); ++} + - return 0; --} -- ++/** ++ * Suited for Soyo SY-7VCA: Pro133A + VT82C686. ++ */ ++static int via_apollo_gpo0_lower(const char *name) ++{ ++ return via_apollo_gpo_set(0, 0); + } + /** - * Suited for: - * - Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F @@ -1952,8 +2297,7 @@ index c87e782..0e89137 100644 { - return it8705f_write_enable(0x2e, name); + struct pci_dev *dev; -+ uint16_t base; -+ uint16_t temp; ++ uint16_t base, temp; + + dev = pci_dev_find(0x1039, 0x0962); + if (!dev) { @@ -1977,7 +2321,7 @@ index c87e782..0e89137 100644 } /** -@@ -802,32 +1120,6 @@ static int board_mitac_6513wu(const char *name) +@@ -802,33 +1205,7 @@ static int board_mitac_6513wu(const char *name) } /** @@ -2007,17 +2351,65 @@ index c87e782..0e89137 100644 -} - -/** - * Suited for Asus A7V8X: VIA KT400 + VT8235 + IT8703F-A +- * Suited for Asus A7V8X: VIA KT400 + VT8235 + IT8703F-A ++ * Suited for ASUS A7V8X: VIA KT400 + VT8235 + IT8703F-A */ static int board_asus_a7v8x(const char *name) -@@ -922,49 +1214,44 @@ it8712f_gpio_set(unsigned int line, int raise) + { +@@ -841,7 +1218,7 @@ static int board_asus_a7v8x(const char *name) + w836xx_ext_leave(0x2E); + + if (id != 0x8701) { +- fprintf(stderr, "\nERROR: IT8703F SuperIO not found.\n"); ++ fprintf(stderr, "\nERROR: IT8703F Super I/O not found.\n"); + return -1; + } + +@@ -852,7 +1229,7 @@ static int board_asus_a7v8x(const char *name) + w836xx_ext_leave(0x2E); + + if (!base) { +- fprintf(stderr, "\nERROR: Failed to read IT8703F SuperIO GPIO" ++ fprintf(stderr, "\nERROR: Failed to read IT8703F Super I/O GPIO" + " Base.\n"); + return -1; + } +@@ -869,8 +1246,7 @@ static int board_asus_a7v8x(const char *name) + * General routine for raising/dropping GPIO lines on the ITE IT8712F. + * There is only some limited checking on the port numbers. + */ +-static int +-it8712f_gpio_set(unsigned int line, int raise) ++static int it8712f_gpio_set(unsigned int line, int raise) + { + unsigned int port; + uint16_t id, base; +@@ -894,7 +1270,7 @@ it8712f_gpio_set(unsigned int line, int raise) + exit_conf_mode_ite(0x2E); + + if (id != 0x8712) { +- fprintf(stderr, "\nERROR: IT8712F SuperIO not found.\n"); ++ fprintf(stderr, "\nERROR: IT8712F Super I/O not found.\n"); + return -1; + } + +@@ -905,7 +1281,7 @@ it8712f_gpio_set(unsigned int line, int raise) + exit_conf_mode_ite(0x2E); + + if (!base) { +- fprintf(stderr, "\nERROR: Failed to read IT8712F SuperIO GPIO" ++ fprintf(stderr, "\nERROR: Failed to read IT8712F Super I/O GPIO" + " Base.\n"); + return -1; + } +@@ -922,49 +1298,44 @@ it8712f_gpio_set(unsigned int line, int raise) } /** - * Suited for Asus A7V600-X: VIA KT600 + VT8237 + IT8712F + * Suited for: -+ * - Asus A7V600-X: VIA KT600 + VT8237 + IT8712F -+ * - Asus A7V8X-X: VIA KT400 + VT8235 + IT8712F ++ * - ASUS A7V600-X: VIA KT600 + VT8237 + IT8712F ++ * - ASUS A7V8X-X: VIA KT400 + VT8235 + IT8712F */ -static int board_asus_a7v600x(const char *name) +static int it8712f_gpio3_1_raise(const char *name) @@ -2074,7 +2466,7 @@ index c87e782..0e89137 100644 + * + * If PCI IDs are not sufficient for board matching, the match can be further + * constrained by a string that has to be present in the DMI database for -+ * the baseboard or the system entry. The pattern is matched by case sensitve ++ * the baseboard or the system entry. The pattern is matched by case sensitive + * substring match, unless it is anchored to the beginning (with a ^ in front) + * or the end (with a $ at the end). Both anchors may be specified at the + * same time to match the full field. @@ -2086,7 +2478,7 @@ index c87e782..0e89137 100644 * * The coreboot ids are used two fold. When running with a coreboot firmware, * the ids uniquely matches the coreboot board identification string. When a -@@ -977,195 +1264,71 @@ static int board_asus_p4p800(const char *name) +@@ -977,195 +1348,76 @@ static int board_asus_p4p800(const char *name) /* Please keep this list alphabetically ordered by vendor/board name. */ struct board_pciid_enable board_pciid_enables[] = { @@ -2141,7 +2533,7 @@ index c87e782..0e89137 100644 - - { 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}, /* end marker */ -}; - +- -/* Please keep this list alphabetically ordered by vendor/board. */ -const struct board_info boards_ok[] = { - /* Verified working boards that don't need write-enables. */ @@ -2264,7 +2656,7 @@ index c87e782..0e89137 100644 -const struct board_info laptops_ok[] = { - /* Verified working laptops. */ - { "Lenovo", "3000 V100 TF05Cxx", }, -- + - {}, -}; - @@ -2280,8 +2672,12 @@ index c87e782..0e89137 100644 - - {}, + /* first pci-id set [4], second pci-id set [4], dmi identifier coreboot id [2], vendor name board name max_rom_... OK? flash enable */ ++ {0x10DE, 0x0547, 0x147B, 0x1C2F, 0x10DE, 0x0548, 0x147B, 0x1C2F, NULL, NULL, NULL, "Abit", "AN-M2", 0, NT, nvidia_mcp_gpio2_raise}, + {0x8086, 0x2926, 0x147b, 0x1084, 0x11ab, 0x4364, 0x147b, 0x1084, NULL, NULL, NULL, "Abit", "IP35", 0, OK, intel_ich_gpio16_raise}, + {0x8086, 0x2930, 0x147b, 0x1083, 0x10ec, 0x8167, 0x147b, 0x1083, NULL, NULL, NULL, "Abit", "IP35 Pro", 0, OK, intel_ich_gpio16_raise}, ++ {0x10de, 0x0050, 0x147b, 0x1c1a, 0, 0, 0, 0, NULL, NULL, NULL, "Abit", "KN8 Ultra", 0, NT, nvidia_mcp_gpio2_lower}, ++ {0x10de, 0x01e0, 0x147b, 0x1c00, 0x10de, 0x0060, 0x147B, 0x1c00, NULL, NULL, NULL, "Abit", "NF7-S", 0, OK, nvidia_mcp_gpio8_raise}, ++ {0x1106, 0x0691, 0, 0, 0x1106, 0x3057, 0, 0, NULL, "abit", "vt6x4", "Abit", "VT6X4", 0, OK, via_apollo_gpo4_lower}, + {0x105a, 0x0d30, 0x105a, 0x4d33, 0x8086, 0x1130, 0x8086, 0, NULL, NULL, NULL, "Acorp", "6A815EPD", 0, OK, board_acorp_6a815epd}, + {0x8086, 0x24D4, 0x1849, 0x24D0, 0x8086, 0x24D5, 0x1849, 0x9739, NULL, NULL, NULL, "ASRock", "P4i65GV", 0, OK, intel_ich_gpio23_raise}, + {0x1022, 0x746B, 0, 0, 0, 0, 0, 0, NULL, "AGAMI", "ARUMA", "agami", "Aruma", 0, OK, w83627hf_gpio24_raise_2e}, @@ -2293,10 +2689,15 @@ index c87e782..0e89137 100644 + {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3177, 0x1043, 0x808C, NULL, NULL, NULL, "ASUS", "A7V8X", 0, OK, board_asus_a7v8x}, + {0x1106, 0x3189, 0x1043, 0x807F, 0x1106, 0x3177, 0x1043, 0x80A1, NULL, NULL, NULL, "ASUS", "A7V8X-X", 0, OK, it8712f_gpio3_1_raise}, + {0x1106, 0x3177, 0x1043, 0x80A1, 0x1106, 0x3205, 0x1043, 0x8118, NULL, NULL, NULL, "ASUS", "A7V8X-MX SE", 0, OK, w836xx_memw_enable_2e}, ++ {0x8086, 0x27A0, 0x1043, 0x1287, 0x8086, 0x27DF, 0x1043, 0x1287, "^A8J", NULL, NULL, "ASUS", "A8JM", 0, NT, intel_ich_gpio34_raise}, ++ {0x10DE, 0x005E, 0x1043, 0x815A, 0x10DE, 0x0054, 0x1043, 0x815A, NULL, NULL, NULL, "ASUS", "A8N", 0, NT, board_shuttle_fn25}, ++ {0x10DE, 0x0260, 0x103c, 0x2a3e, 0x10DE, 0x0264, 0x103c, 0x2a3e, "NAGAMI", NULL, NULL, "ASUS", "A8N-LA", 0, NT, nvidia_mcp_gpio0_raise}, + {0x10DE, 0x0264, 0x1043, 0x81C0, 0x10DE, 0x0260, 0x1043, 0x81C0, NULL, NULL, NULL, "ASUS", "M2NBP-VM CSM", 0, OK, nvidia_mcp_gpio0_raise}, + {0x1106, 0x1336, 0x1043, 0x80ed, 0x1106, 0x3288, 0x1043, 0x8249, NULL, NULL, NULL, "ASUS", "M2V-MX", 0, OK, via_vt823x_gpio5_raise}, + {0x8086, 0x1a30, 0x1043, 0x8070, 0x8086, 0x244b, 0x1043, 0x8028, NULL, NULL, NULL, "ASUS", "P4B266", 0, OK, intel_ich_gpio22_raise}, + {0x8086, 0x1A30, 0x1043, 0x8025, 0x8086, 0x244B, 0x104D, 0x80F0, NULL, NULL, NULL, "ASUS", "P4B266-LM", 0, OK, intel_ich_gpio21_raise}, ++ {0x8086, 0x1A30, 0x1043, 0x8088, 0x8086, 0x24C3, 0x1043, 0x8089, NULL, NULL, NULL, "ASUS", "P4B533-E", 0, NT, intel_ich_gpio22_raise}, ++ {0x8086, 0x24D3, 0x1043, 0x80A6, 0x8086, 0x2578, 0x1043, 0x80F6, NULL, NULL, NULL, "ASUS", "P4C800-E Deluxe", 0, OK, intel_ich_gpio21_raise}, + {0x8086, 0x2570, 0x1043, 0x80F2, 0x105A, 0x3373, 0x1043, 0x80F5, NULL, NULL, NULL, "ASUS", "P4P800-E Deluxe", 0, OK, intel_ich_gpio21_raise}, + {0x10B9, 0x1541, 0, 0, 0x10B9, 0x1533, 0, 0, "^P5A$", "asus", "p5a", "ASUS", "P5A", 0, OK, board_asus_p5a}, + {0x10DE, 0x0030, 0x1043, 0x818a, 0x8086, 0x100E, 0x1043, 0x80EE, NULL, NULL, NULL, "ASUS", "P5ND2-SLI Deluxe", 0, OK, nvidia_mcp_gpio10_raise}, @@ -2308,21 +2709,17 @@ index c87e782..0e89137 100644 + {0x10EC, 0x8139, 0x1695, 0x9001, 0x11C1, 0x5811, 0x1695, 0x9015, NULL, NULL, NULL, "EPoX", "EP-8RDA3+", 0, OK, nvidia_mcp_gpio31_raise}, + {0x8086, 0x7110, 0, 0, 0x8086, 0x7190, 0, 0, NULL, "epox", "ep-bx3", "EPoX", "EP-BX3", 0, OK, board_epox_ep_bx3}, + {0x1106, 0x0686, 0x1106, 0x0686, 0x1106, 0x3058, 0x1458, 0xa000, NULL, NULL, NULL, "GIGABYTE", "GA-7ZM", 512, OK, NULL}, -+ {0x1039, 0x0761, 0, 0, 0x10EC, 0x8168, 0, 0, NULL, "gigabyte", "2761gxdk", "GIGABYTE", "GA-2761GXDK", 0, OK, it87xx_probe_spi_flash}, + {0x1106, 0x3227, 0x1458, 0x5001, 0x10ec, 0x8139, 0x1458, 0xe000, NULL, NULL, NULL, "GIGABYTE", "GA-7VT600", 0, OK, it8705f_write_enable_2e}, + {0x10DE, 0x0050, 0x1458, 0x0C11, 0x10DE, 0x005e, 0x1458, 0x5000, NULL, NULL, NULL, "GIGABYTE", "GA-K8N-SLI", 0, OK, nvidia_mcp_gpio21_raise}, -+ {0x10DE, 0x0360, 0x1458, 0x0C11, 0x10DE, 0x0369, 0x1458, 0x5001, NULL, "gigabyte", "m57sli", "GIGABYTE", "GA-M57SLI-S4", 0, OK, it87xx_probe_spi_flash}, -+ {0x10de, 0x03e0, 0, 0, 0x10DE, 0x03D0, 0, 0, NULL, NULL, NULL, "GIGABYTE", "GA-M61P-S3", 0, OK, it87xx_probe_spi_flash}, -+ {0x1002, 0x4398, 0x1458, 0x5004, 0x1002, 0x4391, 0x1458, 0xb000, NULL, NULL, NULL, "GIGABYTE", "GA-MA78G-DS3H", 0, OK, it87xx_probe_spi_flash}, -+ {0x1002, 0x4398, 0x1458, 0x5004, 0x1002, 0x4391, 0x1458, 0xb002, NULL, NULL, NULL, "GIGABYTE", "GA-MA78GM-S2H", 0, OK, it87xx_probe_spi_flash}, -+ {0x1002, 0x438d, 0x1458, 0x5001, 0x1002, 0x5956, 0x1002, 0x5956, NULL, NULL, NULL, "GIGABYTE", "GA-MA790FX-DQ6", 0, OK, it87xx_probe_spi_flash}, + {0x1166, 0x0223, 0x103c, 0x320d, 0x102b, 0x0522, 0x103c, 0x31fa, NULL, "hp", "dl145_g3", "HP", "DL145 G3", 0, OK, board_hp_dl145_g3_enable}, + {0x8086, 0x2415, 0x103c, 0x1249, 0x10b7, 0x9200, 0x103c, 0x1246, NULL, NULL, NULL, "HP", "Vectra VL400", 0, OK, board_hp_vl400}, + {0x8086, 0x1a30, 0x103c, 0x1a30, 0x8086, 0x2443, 0x103c, 0x2440, "^VL420$", NULL, NULL, "HP", "VL420 SFF", 0, OK, intel_ich_gpio22_raise}, ++ {0x8086, 0x27A0, 0, 0, 0x8086, 0x27B9, 0, 0, NULL, "ibase", "mb899", "iBASE", "MB899", 0, NT, intel_ich_gpio26_raise}, + {0x1166, 0x0205, 0x1014, 0x0347, 0x1002, 0x515E, 0x1014, 0x0325, NULL, NULL, NULL, "IBM", "x3455", 0, OK, board_ibm_x3455}, + {0x1039, 0x5513, 0x8086, 0xd61f, 0x1039, 0x6330, 0x8086, 0xd61f, NULL, NULL, NULL, "Intel", "D201GLY", 0, OK, wbsio_check_for_spi}, ++ {0x8086, 0x7190, 0, 0, 0x8086, 0x7110, 0, 0, "^SE440BX-2$", NULL, NULL, "Intel", "SE440BX-2", 0, NT, intel_piix4_gpo27_lower}, + {0x1022, 0x7468, 0, 0, 0, 0, 0, 0, NULL, "iwill", "dk8_htx", "IWILL", "DK8-HTX", 0, OK, w83627hf_gpio24_raise_2e}, -+ {0x8086, 0x27A0, 0, 0, 0x8086, 0x27b8, 0, 0, NULL, "kontron", "986lcd-m", "Kontron", "986LCD-M", 0, OK, board_kontron_986lcd_m}, ++ {0x8086, 0x27A0, 0x8086, 0x27a0, 0x8086, 0x27b8, 0x8086, 0x27b8, NULL, "kontron", "986lcd-m", "Kontron", "986LCD-M", 0, OK, board_kontron_986lcd_m}, + {0x8086, 0x2411, 0x8086, 0x2411, 0x8086, 0x7125, 0x0e11, 0xb165, NULL, NULL, NULL, "Mitac", "6513WU", 0, OK, board_mitac_6513wu}, + {0x13f6, 0x0111, 0x1462, 0x5900, 0x1106, 0x3177, 0x1106, 0, NULL, NULL, NULL, "MSI", "MS-6590 (KT4 Ultra)", 0, OK, board_msi_kt4v}, + {0x1106, 0x3149, 0x1462, 0x7094, 0x10ec, 0x8167, 0x1462, 0x094c, NULL, NULL, NULL, "MSI", "MS-6702E (K8T Neo2-F)", 0, OK, w83627thf_gpio4_4_raise_2e}, @@ -2335,18 +2732,18 @@ index c87e782..0e89137 100644 + {0x1106, 0x3099, 0, 0, 0x1106, 0x3074, 0, 0, NULL, "shuttle", "ak31", "Shuttle", "AK31", 0, OK, w836xx_memw_enable_2e}, + {0x1106, 0x3104, 0x1297, 0xa238, 0x1106, 0x3059, 0x1297, 0xc063, NULL, NULL, NULL, "Shuttle", "AK38N", 256, OK, it8705f_write_enable_2e}, + {0x10DE, 0x0050, 0x1297, 0x5036, 0x1412, 0x1724, 0x1297, 0x5036, NULL, NULL, NULL, "Shuttle", "FN25", 0, OK, board_shuttle_fn25}, -+ {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x3058, 0x15DD, 0x7609, NULL, NULL, NULL, "Soyo", "SY-7VCA", 0, OK, board_soyo_sy_7vca}, ++ {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x3058, 0x15DD, 0x7609, NULL, NULL, NULL, "Soyo", "SY-7VCA", 0, OK, via_apollo_gpo0_lower}, + {0x8086, 0x1076, 0x8086, 0x1176, 0x1106, 0x3059, 0x10f1, 0x2498, NULL, NULL, NULL, "Tyan", "S2498 (Tomcat K7M)", 0, OK, w836xx_memw_enable_2e}, + {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x0596, 0x1106, 0, NULL, NULL, NULL, "Tekram", "P6Pro-A5", 256, OK, NULL}, ++ {0x1106, 0x3123, 0x1106, 0x3123, 0x1106, 0x3059, 0x1106, 0x4161, NULL, NULL, NULL, "Termtek", "TK-3370 (Rev:2.5B)", 0, OK, w836xx_memw_enable_4e}, + {0x1106, 0x3177, 0x1106, 0xAA01, 0x1106, 0x3123, 0x1106, 0xAA01, NULL, NULL, NULL, "VIA", "EPIA M/MII/...", 0, OK, via_vt823x_gpio15_raise}, + {0x1106, 0x0259, 0x1106, 0x3227, 0x1106, 0x3065, 0x1106, 0x3149, NULL, NULL, NULL, "VIA", "EPIA-N/NL", 0, OK, via_vt823x_gpio9_raise}, -+ {0x1106, 0x5337, 0x1458, 0xb003, 0x1106, 0x287e, 0x1106, 0x337e, NULL, NULL, NULL, "VIA", "PC3500G", 0, OK, it87xx_probe_spi_flash}, + + { 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0, NT, NULL}, /* end marker */ }; /** -@@ -1230,7 +1393,8 @@ static struct board_pciid_enable *board_match_pci_card_ids(void) +@@ -1230,7 +1482,8 @@ static struct board_pciid_enable *board_match_pci_card_ids(void) struct board_pciid_enable *board = board_pciid_enables; for (; board->vendor_name; board++) { @@ -2356,7 +2753,7 @@ index c87e782..0e89137 100644 continue; if (!pci_card_find(board->first_vendor, board->first_device, -@@ -1252,6 +1416,18 @@ static struct board_pciid_enable *board_match_pci_card_ids(void) +@@ -1252,6 +1505,18 @@ static struct board_pciid_enable *board_match_pci_card_ids(void) } } @@ -2375,7 +2772,7 @@ index c87e782..0e89137 100644 return board; } -@@ -1269,15 +1445,39 @@ int board_flash_enable(const char *vendor, const char *part) +@@ -1269,15 +1534,38 @@ int board_flash_enable(const char *vendor, const char *part) if (!board) board = board_match_pci_card_ids(); @@ -2383,20 +2780,19 @@ index c87e782..0e89137 100644 - printf("Disabling flash write protection for board \"%s %s\"... ", - board->vendor_name, board->board_name); + if (board && board->status == NT) { -+ if (!force_boardenable) -+ { ++ if (!force_boardenable) { + printf("WARNING: Your mainboard is %s %s, but the mainboard-specific\n" + "code has not been tested, and thus will not not be executed by default.\n" + "Depending on your hardware environment, erasing, writing or even probing\n" + "can fail without running the board specific code.\n\n" + "Please see the man page (section PROGRAMMER SPECIFIC INFO, subsection\n" -+ "\"internal programmer\") for details\n", ++ "\"internal programmer\") for details.\n", + board->vendor_name, board->board_name); + board = NULL; -+ } -+ else ++ } else { + printf("NOTE: Running an untested board enable procedure.\n" -+ "Please report success/failure to flashrom@flashrom.org\n"); ++ "Please report success/failure to flashrom@flashrom.org.\n"); ++ } + } - ret = board->enable(board->vendor_name); @@ -2425,10 +2821,10 @@ index c87e782..0e89137 100644 return ret; diff --git a/buspirate_spi.c b/buspirate_spi.c new file mode 100644 -index 0000000..f1a0be1 +index 0000000..dc491e2 --- /dev/null +++ b/buspirate_spi.c -@@ -0,0 +1,319 @@ +@@ -0,0 +1,354 @@ +/* + * This file is part of the flashrom project. + * @@ -2747,7 +3143,42 @@ index 0000000..f1a0be1 + return spi_read_chunked(flash, buf, start, len, 12); +} + -+/* We could do 12-byte writes, but for now we use the generic 1-byte code. */ ++int buspirate_spi_write_256(struct flashchip *flash, uint8_t *buf) ++{ ++ int total_size = 1024 * flash->total_size; ++ int i; ++ ++ spi_disable_blockprotect(); ++ /* Erase first. */ ++ msg_pinfo("Erasing flash before programming... "); ++ if (erase_flash(flash)) { ++ msg_perr("ERASE FAILED!\n"); ++ return -1; ++ } ++ msg_pinfo("done.\n"); ++ ++ /* FIXME: We could do 12 byte writes, but then we'd have to make sure ++ * not to cross a 256 byte page boundary. This problem only applies to ++ * writes, reads can cross page boundaries just fine. ++ */ ++ for (i = 0; i < total_size; i += 8) { ++ int l, r; ++ if (i + 8 <= total_size) ++ l = 8; ++ else ++ l = total_size - i; ++ ++ if ((r = spi_nbyte_program(i, &buf[i], l))) { ++ msg_perr("%s: write fail %d\n", __func__, r); ++ return 1; ++ } ++ ++ while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) ++ /* loop */; ++ } ++ ++ return 0; ++} diff --git a/cbtable.c b/cbtable.c index 9d7e758..c12354c 100644 --- a/cbtable.c @@ -2837,10 +3268,10 @@ index 9d7e758..c12354c 100644 } diff --git a/chipdrivers.h b/chipdrivers.h new file mode 100644 -index 0000000..a378803 +index 0000000..6d5cef0 --- /dev/null +++ b/chipdrivers.h -@@ -0,0 +1,144 @@ +@@ -0,0 +1,125 @@ +/* + * This file is part of the flashrom project. + * @@ -2900,8 +3331,12 @@ index 0000000..a378803 +uint8_t wait_82802ab(chipaddr bios); +int probe_82802ab(struct flashchip *flash); +int erase_82802ab(struct flashchip *flash); -+int erase_82802ab_block(struct flashchip *flash, unsigned int page, unsigned int pagesize); ++int erase_block_82802ab(struct flashchip *flash, unsigned int page, unsigned int pagesize); +int write_82802ab(struct flashchip *flash, uint8_t *buf); ++void print_status_82802ab(uint8_t status); ++void write_page_82802ab(chipaddr bios, uint8_t *src, chipaddr dst, int page_size); ++int unlock_82802ab(struct flashchip *flash); ++int unlock_28f004s5(struct flashchip *flash); + +/* jedec.c */ +uint8_t oddparity(uint8_t val); @@ -2933,56 +3368,33 @@ index 0000000..a378803 +int unlock_49fl00x(struct flashchip *flash); +int lock_49fl00x(struct flashchip *flash); + -+/* sharplhf00l04.c */ -+int probe_lhf00l04(struct flashchip *flash); -+int erase_lhf00l04_block(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen); -+int write_lhf00l04(struct flashchip *flash, uint8_t *buf); -+void protect_lhf00l04(chipaddr bios); -+ +/* sst28sf040.c */ -+int probe_28sf040(struct flashchip *flash); +int erase_chip_28sf040(struct flashchip *flash, unsigned int addr, unsigned int blocklen); +int erase_sector_28sf040(struct flashchip *flash, unsigned int address, unsigned int sector_size); +int write_28sf040(struct flashchip *flash, uint8_t *buf); + +/* sst49lfxxxc.c */ -+int probe_49lfxxxc(struct flashchip *flash); -+int erase_49lfxxxc(struct flashchip *flash); +int erase_sector_49lfxxxc(struct flashchip *flash, unsigned int address, unsigned int sector_size); -+int erase_block_49lfxxxc(struct flashchip *flash, unsigned int address, unsigned int sector_size); -+int erase_chip_49lfxxxc(struct flashchip *flash, unsigned int addr, unsigned int blocksize); +int write_49lfxxxc(struct flashchip *flash, uint8_t *buf); +int unlock_49lfxxxc(struct flashchip *flash); + +/* sst_fwhub.c */ -+int probe_sst_fwhub(struct flashchip *flash); -+int erase_sst_fwhub(struct flashchip *flash); -+int erase_sst_fwhub_block(struct flashchip *flash, unsigned int offset, unsigned int page_size); -+int erase_sst_fwhub_sector(struct flashchip *flash, unsigned int offset, unsigned int page_size); -+int write_sst_fwhub(struct flashchip *flash, uint8_t *buf); ++int printlock_sst_fwhub(struct flashchip *flash); ++int unlock_sst_fwhub(struct flashchip *flash); + +/* w39v040c.c */ -+int probe_w39v040c(struct flashchip *flash); -+int erase_w39v040c(struct flashchip *flash); -+int write_w39v040c(struct flashchip *flash, uint8_t *buf); +int printlock_w39v040c(struct flashchip *flash); + +/* w39V080fa.c */ -+int probe_winbond_fwhub(struct flashchip *flash); -+int erase_winbond_fwhub(struct flashchip *flash); -+int write_winbond_fwhub(struct flashchip *flash, uint8_t *buf); +int unlock_winbond_fwhub(struct flashchip *flash); + +/* w29ee011.c */ +int probe_w29ee011(struct flashchip *flash); + +/* stm50flw0x0x.c */ -+int probe_stm50flw0x0x(struct flashchip *flash); -+int erase_stm50flw0x0x(struct flashchip *flash); -+int erase_block_stm50flw0x0x(struct flashchip *flash, unsigned int block, unsigned int blocksize); +int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int block, unsigned int blocksize); +int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen); -+int write_stm50flw0x0x(struct flashchip *flash, uint8_t *buf); ++int unlock_stm50flw0x0x(struct flashchip *flash); + +#endif /* !__CHIPDRIVERS_H__ */ diff --git a/chipset_enable.c b/chipset_enable.c @@ -4210,7 +4622,7 @@ index 0000000..6cb0578 +} diff --git a/cli_output.c b/cli_output.c new file mode 100644 -index 0000000..2ced043 +index 0000000..b3d4e04 --- /dev/null +++ b/cli_output.c @@ -0,0 +1,51 @@ @@ -4243,28 +4655,68 @@ index 0000000..2ced043 + va_list ap; + int ret; + FILE *output_type; -+ -+ switch (type) -+ { ++ ++ switch (type) { + case MSG_ERROR: + output_type = stderr; + break; + case MSG_BARF: -+ if (verbose < 2) return 0; ++ if (verbose < 2) ++ return 0; + case MSG_DEBUG: -+ if (verbose < 1) return 0; ++ if (verbose < 1) ++ return 0; + case MSG_INFO: + default: + output_type = stdout; + break; + } -+ ++ + va_start(ap, fmt); + ret = vfprintf(output_type, fmt, ap); + va_end(ap); + return ret; +} -+ +diff --git a/coreboot_tables.h b/coreboot_tables.h +index 6944559..2e96526 100644 +--- a/coreboot_tables.h ++++ b/coreboot_tables.h +@@ -27,11 +27,11 @@ + /* The coreboot table information is for conveying information + * from the firmware to the loaded OS image. Primarily this + * is expected to be information that cannot be discovered by +- * other means, such as quering the hardware directly. ++ * other means, such as querying the hardware directly. + * + * All of the information should be Position Independent Data. + * That is it should be safe to relocated any of the information +- * without it's meaning/correctnes changing. For table that ++ * without it's meaning/correctness changing. For table that + * can reasonably be used on multiple architectures the data + * size should be fixed. This should ease the transition between + * 32 bit and 64 bit architectures etc. +@@ -48,7 +48,7 @@ + * table entry is required or not. This should remove much of the + * long term compatibility burden as table entries which are + * irrelevant or have been replaced by better alternatives may be +- * dropped. Of course it is polite and expidite to include extra ++ * dropped. Of course it is polite and expedite to include extra + * table entries and be backwards compatible, but it is not required. + */ + +@@ -78,10 +78,10 @@ struct lb_header { + uint32_t table_entries; + }; + +-/* Every entry in the boot enviroment list will correspond to a boot ++/* Every entry in the boot environment list will correspond to a boot + * info record. Encoding both type and size. The type is obviously + * so you can tell what it is. The size allows you to skip that +- * boot enviroment record if you don't know what it easy. This allows ++ * boot environment record if you don't know what it easy. This allows + * forward compatibility with records not yet defined. + */ + struct lb_record { diff --git a/dediprog.c b/dediprog.c new file mode 100644 index 0000000..2d0d060 @@ -4668,10 +5120,10 @@ index 0000000..2d0d060 +} diff --git a/dmi.c b/dmi.c new file mode 100644 -index 0000000..30a4670 +index 0000000..d9f307f --- /dev/null +++ b/dmi.c -@@ -0,0 +1,177 @@ +@@ -0,0 +1,172 @@ +/* + * This file is part of the flashrom project. + * @@ -4698,34 +5150,22 @@ index 0000000..30a4670 + +#include "flash.h" + -+enum dmi_strings { -+ DMI_SYS_MANUFACTURER, -+ DMI_SYS_PRODUCT, -+ DMI_SYS_VERSION, -+ DMI_BB_MANUFACTURER, -+ DMI_BB_PRODUCT, -+ DMI_BB_VERSION, -+ DMI_ID_INVALID /* This must always be the last entry */ -+}; -+ -+/* The short_id for baseboard starts with "m" as in mainboard to leave -+ "b" available for BIOS */ -+const char *dmidecode_names[DMI_ID_INVALID] = { ++const char *dmidecode_names[] = { + "system-manufacturer", + "system-product-name", + "system-version", + "baseboard-manufacturer", + "baseboard-product-name", -+ "baseboard-version" ++ "baseboard-version", +}; + +#define DMI_COMMAND_LEN_MAX 260 +const char *dmidecode_command = "dmidecode"; + +int has_dmi_support = 0; -+char *dmistrings[DMI_ID_INVALID]; ++char *dmistrings[ARRAY_SIZE(dmidecode_names)]; + -+/* strings longer than 4096 in DMI are just insane */ ++/* Strings longer than 4096 in DMI are just insane. */ +#define DMI_MAX_ANSWER_LEN 4096 + +static char *get_dmi_string(const char *string_name) @@ -4733,7 +5173,8 @@ index 0000000..30a4670 + FILE *dmidecode_pipe; + char *result; + char answerbuf[DMI_MAX_ANSWER_LEN]; -+ char commandline[DMI_COMMAND_LEN_MAX+40]; ++ char commandline[DMI_COMMAND_LEN_MAX + 40]; ++ + snprintf(commandline, sizeof(commandline), + "%s -s %s", dmidecode_command, string_name); + dmidecode_pipe = popen(commandline, "r"); @@ -4741,11 +5182,14 @@ index 0000000..30a4670 + printf_debug("DMI pipe open error\n"); + return NULL; + } -+ if (!fgets(answerbuf, DMI_MAX_ANSWER_LEN, dmidecode_pipe) && -+ ferror(dmidecode_pipe)) { -+ printf_debug("DMI pipe read error\n"); -+ pclose(dmidecode_pipe); -+ return NULL; ++ if (!fgets(answerbuf, DMI_MAX_ANSWER_LEN, dmidecode_pipe)) { ++ if(ferror(dmidecode_pipe)) { ++ printf_debug("DMI pipe read error\n"); ++ pclose(dmidecode_pipe); ++ return NULL; ++ } else { ++ answerbuf[0] = 0; /* Hit EOF */ ++ } + } + /* Toss all output above DMI_MAX_ANSWER_LEN away to prevent + deadlock on pclose. */ @@ -4756,7 +5200,7 @@ index 0000000..30a4670 + return NULL; + } + -+ /* chomp trailing newline */ ++ /* Chomp trailing newline. */ + if (answerbuf[0] != 0 && + answerbuf[strlen(answerbuf) - 1] == '\n') + answerbuf[strlen(answerbuf) - 1] = 0; @@ -4773,18 +5217,19 @@ index 0000000..30a4670 +{ + int i; + char *chassis_type; ++ + has_dmi_support = 1; -+ for (i = 0; i < DMI_ID_INVALID; i++) { ++ for (i = 0; i < ARRAY_SIZE(dmidecode_names); i++) { + dmistrings[i] = get_dmi_string(dmidecode_names[i]); + if (!dmistrings[i]) { + has_dmi_support = 0; -+ break; ++ return; + } + } + + chassis_type = get_dmi_string("chassis-type"); + if (chassis_type && !strcmp(chassis_type, "Notebook")) { -+ printf_debug("Laptop detected via DMI"); ++ printf_debug("Laptop detected via DMI\n"); + is_laptop = 1; + } + free(chassis_type); @@ -4805,8 +5250,9 @@ index 0000000..30a4670 +{ + int anchored = 0; + int patternlen; ++ + printf_debug("matching %s against %s\n", value, pattern); -+ /* The empty string is part of all strings */ ++ /* The empty string is part of all strings! */ + if (pattern[0] == 0) + return 1; + @@ -4819,11 +5265,11 @@ index 0000000..30a4670 + if (pattern[patternlen - 1] == '$') { + int valuelen = strlen(value); + patternlen--; -+ if(patternlen > valuelen) ++ if (patternlen > valuelen) + return 0; + + /* full string match: require same length */ -+ if(anchored && (valuelen != patternlen)) ++ if (anchored && (valuelen != patternlen)) + return 0; + + /* start character to make ends match */ @@ -4840,11 +5286,12 @@ index 0000000..30a4670 +int dmi_match(const char *pattern) +{ + int i; ++ + if (!has_dmi_support) + return 0; + -+ for (i = 0;i < DMI_ID_INVALID; i++) -+ if(dmi_compare(dmistrings[i], pattern)) ++ for (i = 0; i < ARRAY_SIZE(dmidecode_names); i++) ++ if (dmi_compare(dmistrings[i], pattern)) + return 1; + + return 0; @@ -5229,7 +5676,7 @@ index b89eb31..0000000 - return 0; -} diff --git a/flash.h b/flash.h -index d3e2e30..34b04e6 100644 +index d3e2e30..0a74363 100644 --- a/flash.h +++ b/flash.h @@ -24,74 +24,55 @@ @@ -5392,7 +5839,7 @@ index d3e2e30..34b04e6 100644 +#define FEATURE_ADDR_MASK (3 << 2) +#define FEATURE_ADDR_2AA (1 << 2) +#define FEATURE_ADDR_AAA (2 << 2) -+#define FEATURE_ADDR_SHIFTED 0 ++#define FEATURE_ADDR_SHIFTED (1 << 5) + struct flashchip { const char *vendor; @@ -5665,7 +6112,7 @@ index d3e2e30..34b04e6 100644 /* ft2232_spi.c */ #define FTDI_FT2232H 0x6010 -@@ -402,46 +487,122 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt, const u +@@ -402,46 +487,123 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt, const u int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf); @@ -5686,6 +6133,7 @@ index d3e2e30..34b04e6 100644 +int buspirate_spi_shutdown(void); +int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); +int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); ++int buspirate_spi_write_256(struct flashchip *flash, uint8_t *buf); + +/* dediprog.c */ +int dediprog_init(void); @@ -5793,7 +6241,7 @@ index d3e2e30..34b04e6 100644 SPI_CONTROLLER_INVALID /* This must always be the last entry. */ }; extern const int spi_programmer_count; -@@ -454,7 +615,7 @@ struct spi_command { +@@ -454,7 +616,7 @@ struct spi_command { struct spi_programmer { int (*command)(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); @@ -5802,7 +6250,7 @@ index d3e2e30..34b04e6 100644 /* Optimized functions for this programmer */ int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len); -@@ -464,56 +625,13 @@ struct spi_programmer { +@@ -464,56 +626,13 @@ struct spi_programmer { extern enum spi_controller spi_controller; extern const struct spi_programmer spi_programmer[]; extern void *spibar; @@ -5862,7 +6310,7 @@ index d3e2e30..34b04e6 100644 /* ichspi.c */ int ich_init_opcodes(void); -@@ -521,12 +639,13 @@ int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt, +@@ -521,12 +640,13 @@ int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ich_spi_write_256(struct flashchip *flash, uint8_t * buf); @@ -5877,7 +6325,7 @@ index d3e2e30..34b04e6 100644 int it87spi_init(void); int it87xx_probe_spi_flash(const char *name); int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt, -@@ -541,96 +660,6 @@ int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); +@@ -541,96 +661,6 @@ int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int sb600_spi_write_1(struct flashchip *flash, uint8_t *buf); extern uint8_t *sb600_spibar; @@ -5974,7 +6422,7 @@ index d3e2e30..34b04e6 100644 /* wbsio_spi.c */ int wbsio_check_for_spi(const char *name); int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt, -@@ -638,11 +667,6 @@ int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt, +@@ -638,11 +668,6 @@ int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt, int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf); @@ -5986,7 +6434,7 @@ index d3e2e30..34b04e6 100644 /* serprog.c */ int serprog_init(void); int serprog_shutdown(void); -@@ -651,4 +675,19 @@ uint8_t serprog_chip_readb(const chipaddr addr); +@@ -651,4 +676,19 @@ uint8_t serprog_chip_readb(const chipaddr addr); void serprog_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); void serprog_delay(int delay); @@ -6007,7 +6455,7 @@ index d3e2e30..34b04e6 100644 + #endif /* !__FLASH_H__ */ diff --git a/flashchips.c b/flashchips.c -index 5fd78f2..24736d4 100644 +index 5fd78f2..10c0989 100644 --- a/flashchips.c +++ b/flashchips.c @@ -5,6 +5,7 @@ @@ -6717,7 +7165,7 @@ index 5fd78f2..24736d4 100644 .page_size = 128, - .tested = TEST_OK_PRE, + .feature_bits = FEATURE_LONG_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PREW, .probe = probe_jedec, .probe_timing = 10000, /* 10mS, Enter=Exec */ - .erase = erase_chip_jedec, @@ -6901,7 +7349,7 @@ index 5fd78f2..24736d4 100644 .page_size = 256, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, /* doc1008.pdf dont says anything about probe timing */ - .erase = erase_chip_jedec, @@ -6927,7 +7375,7 @@ index 5fd78f2..24736d4 100644 }, + /* The next two chip definitions have top/bottom boot blocks, but has no -+ device differenciation between the two */ ++ device differentiation between the two */ { .vendor = "AMIC", - .name = "A25L40P", @@ -6939,8 +7387,9 @@ index 5fd78f2..24736d4 100644 .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRW, -+ .probe = probe_spi_rdid4, -+ .probe_timing = TIMING_ZERO, + .probe = probe_spi_rdid4, + .probe_timing = TIMING_ZERO, +- .erase = spi_chip_erase_c7, + .block_erasers = + { + { @@ -6970,9 +7419,8 @@ index 5fd78f2..24736d4 100644 + .total_size = 512, + .page_size = 256, + .tested = TEST_OK_PRW, - .probe = probe_spi_rdid4, - .probe_timing = TIMING_ZERO, -- .erase = spi_chip_erase_c7, ++ .probe = probe_spi_rdid4, ++ .probe_timing = TIMING_ZERO, + .block_erasers = + { + { @@ -7029,7 +7477,7 @@ index 5fd78f2..24736d4 100644 - .tested = TEST_OK_PREW, - .probe = probe_29f002, + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, + .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ - .erase = erase_29f002, @@ -7813,8 +8261,9 @@ index 5fd78f2..24736d4 100644 .model_id = EN_29F002B, .total_size = 256, .page_size = 256, +- .tested = TEST_UNTESTED, + .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, - .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -7824,10 +8273,10 @@ index 5fd78f2..24736d4 100644 + { + { + .eraseblocks = { -+ {64 * 1024, 3}, -+ {32 * 1024, 1}, -+ {8 * 1024, 2}, + {16 * 1024, 1}, ++ {8 * 1024, 2}, ++ {32 * 1024, 1}, ++ {64 * 1024, 3}, + }, + .block_erase = erase_sector_jedec, + }, { @@ -7845,7 +8294,7 @@ index 5fd78f2..24736d4 100644 .page_size = 256, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -7855,10 +8304,10 @@ index 5fd78f2..24736d4 100644 + { + { + .eraseblocks = { -+ {16 * 1024, 1}, -+ {8 * 1024, 2}, -+ {32 * 1024, 1}, + {64 * 1024, 3}, ++ {32 * 1024, 1}, ++ {8 * 1024, 2}, ++ {16 * 1024, 1}, + }, + .block_erase = erase_sector_jedec, + }, { @@ -7986,16 +8435,16 @@ index 5fd78f2..24736d4 100644 .write = write_coreboot_m29f400bt, .read = read_memmapped, }, -@@ -1162,10 +2316,21 @@ struct flashchip flashchips[] = { +@@ -1162,11 +2316,21 @@ struct flashchip flashchips[] = { .model_id = P28F001BXB, .total_size = 128, .page_size = 128 * 1024, /* 8k + 2x4k + 112k */ - .tested = TEST_BAD_ERASE|TEST_BAD_WRITE, -+ .feature_bits = 0, -+ .tested = TEST_BAD_WRITE, ++ .tested = TEST_UNTESTED, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = NULL, +- .write = NULL, + .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ + .block_erasers = + { @@ -8005,22 +8454,23 @@ index 5fd78f2..24736d4 100644 + {4 * 1024, 2}, + {112 * 1024, 1}, + }, -+ .block_erase = erase_82802ab_block, ++ .block_erase = erase_block_82802ab, + }, + }, - .write = NULL, ++ .write = write_82802ab, .read = read_memmapped, }, -@@ -1178,26 +2343,66 @@ struct flashchip flashchips[] = { + +@@ -1178,11 +2342,154 @@ struct flashchip flashchips[] = { .model_id = P28F001BXT, .total_size = 128, .page_size = 128 * 1024, /* 112k + 2x4k + 8k */ - .tested = TEST_OK_PR|TEST_BAD_ERASE|TEST_BAD_WRITE, -+ .feature_bits = 0, -+ .tested = TEST_BAD_WRITE, ++ .tested = TEST_UNTESTED, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = NULL, +- .write = NULL, + .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ + .block_erasers = + { @@ -8030,15 +8480,15 @@ index 5fd78f2..24736d4 100644 + {4 * 1024, 2}, + {8 * 1024, 1}, + }, -+ .block_erase = erase_82802ab_block, ++ .block_erase = erase_block_82802ab, + }, + }, - .write = NULL, - .read = read_memmapped, - }, - - { - .vendor = "Intel", ++ .write = write_82802ab, ++ .read = read_memmapped, ++ }, ++ ++ { ++ .vendor = "Intel", + .name = "28F004S5", + .bustype = CHIP_BUSTYPE_PARALLEL, + .manufacture_id = INTEL_ID, @@ -8052,7 +8502,35 @@ index 5fd78f2..24736d4 100644 + { + { + .eraseblocks = { {64 * 1024, 8} }, -+ .block_erase = erase_82802ab_block, ++ .block_erase = erase_block_82802ab, ++ }, ++ }, ++ .unlock = unlock_28f004s5, ++ .write = write_82802ab, ++ .read = read_memmapped, ++ }, ++ ++ { ++ .vendor = "Intel", ++ .name = "28F004BV/BE-B", ++ .bustype = CHIP_BUSTYPE_PARALLEL, ++ .manufacture_id = INTEL_ID, ++ .model_id = P28F004BB, ++ .total_size = 512, ++ .page_size = 128 * 1024, /* maximal block size */ ++ .tested = TEST_UNTESTED, ++ .probe = probe_82802ab, ++ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { ++ {16 * 1024, 1}, ++ {8 * 1024, 2}, ++ {96 * 1024, 1}, ++ {128 * 1024, 3}, ++ }, ++ .block_erase = erase_block_82802ab, + }, + }, + .write = write_82802ab, @@ -8061,15 +8539,94 @@ index 5fd78f2..24736d4 100644 + + { + .vendor = "Intel", - .name = "82802AB", - .bustype = CHIP_BUSTYPE_FWH, - .manufacture_id = INTEL_ID, ++ .name = "28F004BV/BE-T", ++ .bustype = CHIP_BUSTYPE_PARALLEL, ++ .manufacture_id = INTEL_ID, ++ .model_id = P28F004BT, ++ .total_size = 512, ++ .page_size = 128 * 1024, /* maximal block size */ ++ .tested = TEST_UNTESTED, ++ .probe = probe_82802ab, ++ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { ++ {128 * 1024, 3}, ++ {96 * 1024, 1}, ++ {8 * 1024, 2}, ++ {16 * 1024, 1}, ++ }, ++ .block_erase = erase_block_82802ab, ++ }, ++ }, ++ .write = write_82802ab, ++ .read = read_memmapped, ++ }, ++ ++ { ++ .vendor = "Intel", ++ .name = "28F400BV/CV/CE-B", ++ .bustype = CHIP_BUSTYPE_PARALLEL, ++ .manufacture_id = INTEL_ID, ++ .model_id = P28F400BB, ++ .total_size = 512, ++ .page_size = 128 * 1024, /* maximal block size */ ++ .feature_bits = FEATURE_ADDR_SHIFTED, ++ .tested = TEST_UNTESTED, ++ .probe = probe_82802ab, ++ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { ++ {16 * 1024, 1}, ++ {8 * 1024, 2}, ++ {96 * 1024, 1}, ++ {128 * 1024, 3}, ++ }, ++ .block_erase = erase_block_82802ab, ++ }, ++ }, ++ .write = write_82802ab, ++ .read = read_memmapped, ++ }, ++ ++ { ++ .vendor = "Intel", ++ .name = "28F400BV/CV/CE-T", ++ .bustype = CHIP_BUSTYPE_PARALLEL, ++ .manufacture_id = INTEL_ID, ++ .model_id = P28F400BT, ++ .total_size = 512, ++ .page_size = 128 * 1024, /* maximal block size */ ++ .feature_bits = FEATURE_ADDR_SHIFTED, ++ .tested = TEST_UNTESTED, ++ .probe = probe_82802ab, ++ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { ++ {128 * 1024, 3}, ++ {96 * 1024, 1}, ++ {8 * 1024, 2}, ++ {16 * 1024, 1}, ++ }, ++ .block_erase = erase_block_82802ab, ++ }, ++ }, ++ .write = write_82802ab, + .read = read_memmapped, + }, + +@@ -1194,10 +2501,18 @@ struct flashchip flashchips[] = { .model_id = I_82802AB, .total_size = 512, .page_size = 64 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = 0, -+ .tested = TEST_OK_PRW, ++ .feature_bits = FEATURE_REGISTERMAP, ++ .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */ - .erase = erase_82802ab, @@ -8077,19 +8634,20 @@ index 5fd78f2..24736d4 100644 + { + { + .eraseblocks = { {64 * 1024, 8} }, -+ .block_erase = erase_82802ab_block, ++ .block_erase = erase_block_82802ab, + }, + }, ++ .unlock = unlock_82802ab, .write = write_82802ab, .read = read_memmapped, }, -@@ -1210,10 +2415,17 @@ struct flashchip flashchips[] = { +@@ -1210,10 +2525,18 @@ struct flashchip flashchips[] = { .model_id = I_82802AC, .total_size = 1024, .page_size = 64 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = 0, -+ .tested = TEST_OK_PRW, ++ .feature_bits = FEATURE_REGISTERMAP, ++ .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */ - .erase = erase_82802ab, @@ -8097,13 +8655,14 @@ index 5fd78f2..24736d4 100644 + { + { + .eraseblocks = { {64 * 1024, 16} }, -+ .block_erase = erase_82802ab_block, ++ .block_erase = erase_block_82802ab, + }, + }, ++ .unlock = unlock_82802ab, .write = write_82802ab, .read = read_memmapped, }, -@@ -1229,7 +2441,25 @@ struct flashchip flashchips[] = { +@@ -1229,7 +2552,25 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8130,7 +8689,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1245,7 +2475,22 @@ struct flashchip flashchips[] = { +@@ -1245,7 +2586,22 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8154,7 +8713,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1261,7 +2506,25 @@ struct flashchip flashchips[] = { +@@ -1261,7 +2617,25 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8181,7 +8740,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1274,10 +2537,28 @@ struct flashchip flashchips[] = { +@@ -1274,10 +2648,28 @@ struct flashchip flashchips[] = { .model_id = MX_25L4005, .total_size = 512, .page_size = 256, @@ -8212,7 +8771,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1290,10 +2571,28 @@ struct flashchip flashchips[] = { +@@ -1290,10 +2682,28 @@ struct flashchip flashchips[] = { .model_id = MX_25L8005, .total_size = 1024, .page_size = 256, @@ -8243,7 +8802,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1306,10 +2605,28 @@ struct flashchip flashchips[] = { +@@ -1306,10 +2716,28 @@ struct flashchip flashchips[] = { .model_id = MX_25L1605, .total_size = 2048, .page_size = 256, @@ -8274,7 +8833,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1325,7 +2642,22 @@ struct flashchip flashchips[] = { +@@ -1325,7 +2753,22 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8298,7 +8857,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1338,10 +2670,25 @@ struct flashchip flashchips[] = { +@@ -1338,10 +2781,25 @@ struct flashchip flashchips[] = { .model_id = MX_25L3205, .total_size = 4096, .page_size = 256, @@ -8326,7 +8885,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1357,7 +2704,22 @@ struct flashchip flashchips[] = { +@@ -1357,7 +2815,22 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8350,7 +8909,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1373,7 +2735,22 @@ struct flashchip flashchips[] = { +@@ -1373,7 +2846,22 @@ struct flashchip flashchips[] = { .tested = TEST_OK_PROBE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8374,7 +8933,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1389,7 +2766,22 @@ struct flashchip flashchips[] = { +@@ -1389,7 +2877,22 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8398,7 +8957,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1402,11 +2794,27 @@ struct flashchip flashchips[] = { +@@ -1402,11 +2905,27 @@ struct flashchip flashchips[] = { .model_id = MX_29F001B, .total_size = 128, .page_size = 32 * 1024, @@ -8429,7 +8988,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1418,11 +2826,27 @@ struct flashchip flashchips[] = { +@@ -1418,11 +2937,27 @@ struct flashchip flashchips[] = { .model_id = MX_29F001T, .total_size = 128, .page_size = 32 * 1024, @@ -8461,7 +9020,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1434,11 +2858,26 @@ struct flashchip flashchips[] = { +@@ -1434,11 +2969,26 @@ struct flashchip flashchips[] = { .model_id = MX_29F002B, .total_size = 256, .page_size = 64 * 1024, @@ -8491,14 +9050,14 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1450,11 +2889,26 @@ struct flashchip flashchips[] = { +@@ -1450,11 +3000,26 @@ struct flashchip flashchips[] = { .model_id = MX_29F002T, .total_size = 256, .page_size = 64 * 1024, - .tested = TEST_OK_PREW, - .probe = probe_29f002, + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, + .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ - .erase = erase_29f002, @@ -8522,7 +9081,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1466,11 +2920,21 @@ struct flashchip flashchips[] = { +@@ -1466,11 +3031,21 @@ struct flashchip flashchips[] = { .model_id = MX_29LV040, .total_size = 512, .page_size = 64 * 1024, @@ -8548,7 +9107,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1485,7 +2949,19 @@ struct flashchip flashchips[] = { +@@ -1485,7 +3060,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8569,7 +9128,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1501,7 +2977,19 @@ struct flashchip flashchips[] = { +@@ -1501,7 +3088,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8590,7 +9149,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1512,12 +3000,24 @@ struct flashchip flashchips[] = { +@@ -1512,12 +3111,24 @@ struct flashchip flashchips[] = { .bustype = CHIP_BUSTYPE_SPI, .manufacture_id = ST_ID, .model_id = ST_M25PE40, @@ -8617,7 +9176,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1533,7 +3033,19 @@ struct flashchip flashchips[] = { +@@ -1533,7 +3144,19 @@ struct flashchip flashchips[] = { .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8638,7 +9197,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1549,7 +3061,19 @@ struct flashchip flashchips[] = { +@@ -1549,7 +3172,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8659,7 +9218,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1565,7 +3089,19 @@ struct flashchip flashchips[] = { +@@ -1565,7 +3200,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8680,7 +9239,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1581,7 +3117,25 @@ struct flashchip flashchips[] = { +@@ -1581,7 +3228,25 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8707,7 +9266,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1597,7 +3151,19 @@ struct flashchip flashchips[] = { +@@ -1597,7 +3262,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8728,7 +9287,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1613,7 +3179,19 @@ struct flashchip flashchips[] = { +@@ -1613,7 +3290,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8749,7 +9308,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1629,7 +3207,25 @@ struct flashchip flashchips[] = { +@@ -1629,7 +3318,25 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8776,7 +9335,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1645,40 +3241,82 @@ struct flashchip flashchips[] = { +@@ -1645,40 +3352,82 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -8871,13 +9430,17 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1690,47 +3328,113 @@ struct flashchip flashchips[] = { - .model_id = PMC_39F010, +@@ -1687,50 +3436,174 @@ struct flashchip flashchips[] = { + .name = "Pm39LV010", + .bustype = CHIP_BUSTYPE_PARALLEL, + .manufacture_id = PMC_ID_NOPREFIX, +- .model_id = PMC_39F010, ++ .model_id = PMC_39F010, /* Pm39LV010 and Pm39F010 have identical IDs but different voltage */ .total_size = 128, .page_size = 4096, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -8902,6 +9465,64 @@ index 5fd78f2..24736d4 100644 { .vendor = "PMC", ++ .name = "Pm39LV020", ++ .bustype = CHIP_BUSTYPE_PARALLEL, ++ .manufacture_id = PMC_ID_NOPREFIX, ++ .model_id = PMC_39LV020, ++ .total_size = 256, ++ .page_size = 4096, ++ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, ++ .tested = TEST_UNTESTED, ++ .probe = probe_jedec, ++ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { {4 * 1024, 64} }, ++ .block_erase = erase_sector_jedec, ++ }, { ++ .eraseblocks = { {64 * 1024, 4} }, ++ .block_erase = erase_block_jedec, ++ }, { ++ .eraseblocks = { {256 * 1024, 1} }, ++ .block_erase = erase_chip_block_jedec, ++ } ++ }, ++ .write = write_jedec_1, ++ .read = read_memmapped, ++ }, ++ ++ { ++ .vendor = "PMC", ++ .name = "Pm39LV040", ++ .bustype = CHIP_BUSTYPE_PARALLEL, ++ .manufacture_id = PMC_ID_NOPREFIX, ++ .model_id = PMC_39LV040, ++ .total_size = 512, ++ .page_size = 4096, ++ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, ++ .tested = TEST_UNTESTED, ++ .probe = probe_jedec, ++ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { {4 * 1024, 128} }, ++ .block_erase = erase_sector_jedec, ++ }, { ++ .eraseblocks = { {64 * 1024, 8} }, ++ .block_erase = erase_block_jedec, ++ }, { ++ .eraseblocks = { {512 * 1024, 1} }, ++ .block_erase = erase_chip_block_jedec, ++ } ++ }, ++ .write = write_jedec_1, ++ .read = read_memmapped, ++ }, ++ ++ { ++ .vendor = "PMC", .name = "Pm49FL002", - .bustype = CHIP_BUSTYPE_LPC|CHIP_BUSTYPE_FWH, /* A/A Mux*/ + .bustype = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH, /* A/A Mux*/ @@ -9000,16 +9621,17 @@ index 5fd78f2..24736d4 100644 .vendor = "Sharp", .name = "LHF00L04", .bustype = CHIP_BUSTYPE_FWH, /* A/A Mux */ -@@ -1738,26 +3442,75 @@ struct flashchip flashchips[] = { +@@ -1738,26 +3611,76 @@ struct flashchip flashchips[] = { .model_id = SHARP_LHF00L04, .total_size = 1024, .page_size = 64 * 1024, -+ .feature_bits = FEATURE_EITHER_RESET, ++ .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_lhf00l04, - .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sharplhf00l04.c) */ - .erase = erase_lhf00l04, -+ .probe = probe_49lfxxxc, +- .write = write_lhf00l04, ++ .probe = probe_82802ab, + .probe_timing = TIMING_ZERO, + .block_erasers = + { @@ -9018,7 +9640,7 @@ index 5fd78f2..24736d4 100644 + {64 * 1024, 15}, + {8 * 1024, 8} + }, -+ .block_erase = erase_lhf00l04_block, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { + {1024 * 1024, 1} @@ -9026,7 +9648,8 @@ index 5fd78f2..24736d4 100644 + .block_erase = NULL, /* 30 D0, only in A/A mux mode */ + }, + }, - .write = write_lhf00l04, ++ .unlock = unlock_82802ab, ++ .write = write_82802ab, .read = read_memmapped, }, @@ -9081,7 +9704,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -1770,10 +3523,28 @@ struct flashchip flashchips[] = { +@@ -1770,10 +3693,28 @@ struct flashchip flashchips[] = { .model_id = SST_25VF016B, .total_size = 2048, .page_size = 256, @@ -9112,7 +9735,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_1, .read = spi_chip_read, }, -@@ -1786,42 +3557,90 @@ struct flashchip flashchips[] = { +@@ -1786,42 +3727,90 @@ struct flashchip flashchips[] = { .model_id = SST_25VF032B, .total_size = 4096, .page_size = 256, @@ -9216,7 +9839,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_1, .read = spi_chip_read, }, -@@ -1833,11 +3652,29 @@ struct flashchip flashchips[] = { +@@ -1833,11 +3822,29 @@ struct flashchip flashchips[] = { .manufacture_id = SST_ID, .model_id = SST_25VF040B_REMS, .total_size = 512, @@ -9248,7 +9871,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_1, .read = spi_chip_read, }, -@@ -1850,10 +3687,28 @@ struct flashchip flashchips[] = { +@@ -1850,10 +3857,28 @@ struct flashchip flashchips[] = { .model_id = SST_25VF080B, .total_size = 1024, .page_size = 256, @@ -9279,13 +9902,14 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_1, .read = spi_chip_read, }, -@@ -1866,10 +3721,20 @@ struct flashchip flashchips[] = { +@@ -1866,10 +3891,20 @@ struct flashchip flashchips[] = { .model_id = SST_28SF040, .total_size = 512, .page_size = 256, + .feature_bits = 0, .tested = TEST_UNTESTED, - .probe = probe_28sf040, +- .probe = probe_28sf040, ++ .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst28sf040.c) */ - .erase = erase_28sf040, + .block_erasers = @@ -9301,13 +9925,13 @@ index 5fd78f2..24736d4 100644 .write = write_28sf040, .read = read_memmapped, }, -@@ -1882,10 +3747,17 @@ struct flashchip flashchips[] = { +@@ -1882,10 +3917,17 @@ struct flashchip flashchips[] = { .model_id = SST_29EE010, .total_size = 128, .page_size = 128, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_LONG_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = 10, - .erase = erase_chip_jedec, @@ -9321,7 +9945,7 @@ index 5fd78f2..24736d4 100644 .write = write_jedec, .read = read_memmapped, }, -@@ -1898,10 +3770,17 @@ struct flashchip flashchips[] = { +@@ -1898,10 +3940,17 @@ struct flashchip flashchips[] = { .model_id = SST_29LE010, .total_size = 128, .page_size = 128, @@ -9340,13 +9964,13 @@ index 5fd78f2..24736d4 100644 .write = write_jedec, .read = read_memmapped, }, -@@ -1914,10 +3793,17 @@ struct flashchip flashchips[] = { +@@ -1914,10 +3963,17 @@ struct flashchip flashchips[] = { .model_id = SST_29EE020A, .total_size = 256, .page_size = 128, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_LONG_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PR, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -9361,12 +9985,13 @@ index 5fd78f2..24736d4 100644 .write = write_jedec, .read = read_memmapped, }, -@@ -1930,27 +3816,70 @@ struct flashchip flashchips[] = { +@@ -1930,27 +3986,70 @@ struct flashchip flashchips[] = { .model_id = SST_29LE020, .total_size = 256, .page_size = 128, +- .tested = TEST_UNTESTED, + .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PREW, .probe = probe_jedec, .probe_timing = 10, - .erase = erase_chip_jedec, @@ -9417,7 +10042,7 @@ index 5fd78f2..24736d4 100644 .page_size = 4096, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ - .erase = erase_chip_jedec, @@ -9436,13 +10061,13 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1962,11 +3891,21 @@ struct flashchip flashchips[] = { +@@ -1962,11 +4061,21 @@ struct flashchip flashchips[] = { .model_id = SST_39SF020, .total_size = 256, .page_size = 4096, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ - .erase = erase_chip_jedec, @@ -9461,7 +10086,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1978,11 +3917,21 @@ struct flashchip flashchips[] = { +@@ -1978,11 +4087,21 @@ struct flashchip flashchips[] = { .model_id = SST_39SF040, .total_size = 512, .page_size = 4096, @@ -9486,7 +10111,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -1994,11 +3943,21 @@ struct flashchip flashchips[] = { +@@ -1994,11 +4113,21 @@ struct flashchip flashchips[] = { .model_id = SST_39VF512, .total_size = 64, .page_size = 4096, @@ -9511,7 +10136,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2010,11 +3969,21 @@ struct flashchip flashchips[] = { +@@ -2010,11 +4139,21 @@ struct flashchip flashchips[] = { .model_id = SST_39VF010, .total_size = 128, .page_size = 4096, @@ -9536,7 +10161,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2026,11 +3995,21 @@ struct flashchip flashchips[] = { +@@ -2026,11 +4165,21 @@ struct flashchip flashchips[] = { .model_id = SST_39VF020, .total_size = 256, .page_size = 4096, @@ -9561,7 +10186,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2042,11 +4021,21 @@ struct flashchip flashchips[] = { +@@ -2042,11 +4191,21 @@ struct flashchip flashchips[] = { .model_id = SST_39VF040, .total_size = 512, .page_size = 4096, @@ -9586,7 +10211,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2058,11 +4047,24 @@ struct flashchip flashchips[] = { +@@ -2058,11 +4217,24 @@ struct flashchip flashchips[] = { .model_id = SST_39VF080, .total_size = 1024, .page_size = 4096, @@ -9613,58 +10238,67 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2074,10 +4076,23 @@ struct flashchip flashchips[] = { +@@ -2074,11 +4246,26 @@ struct flashchip flashchips[] = { .model_id = SST_49LF002A, .total_size = 256, .page_size = 16 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, -+ .tested = TEST_OK_PRW, - .probe = probe_sst_fwhub, +- .probe = probe_sst_fwhub, - .probe_timing = TIMING_FIXME, /* routine is wrapper to probe_jedec (sst_fwhub.c) */ - .erase = erase_sst_fwhub, -+ .probe_timing = 1, /* 150 ns | routine is wrapper to probe_jedec (sst_fwhub.c) */ +- .write = write_sst_fwhub, ++ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, ++ .tested = TEST_OK_PRW, ++ .probe = probe_jedec, ++ .probe_timing = 1, /* 150 ns */ + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 64} }, -+ .block_erase = erase_sst_fwhub_sector, ++ .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {16 * 1024, 16} }, -+ .block_erase = erase_sst_fwhub_block, ++ .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */ + } + }, - .write = write_sst_fwhub, ++ .printlock = printlock_sst_fwhub, ++ .unlock = unlock_sst_fwhub, ++ .write = write_jedec_1, .read = read_memmapped, }, -@@ -2090,15 +4105,31 @@ struct flashchip flashchips[] = { + +@@ -2090,15 +4277,33 @@ struct flashchip flashchips[] = { .model_id = SST_49LF003A, .total_size = 384, .page_size = 64 * 1024, - .tested = TEST_OK_PROBE, -+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, -+ .tested = TEST_OK_PR, - .probe = probe_sst_fwhub, +- .probe = probe_sst_fwhub, - .probe_timing = TIMING_FIXME, /* routine is wrapper to probe_jedec (sst_fwhub.c) */ - .erase = erase_sst_fwhub, -+ .probe_timing = 1, /* 150 ns | routine is wrapper to probe_jedec (sst_fwhub.c) */ +- .write = write_sst_fwhub, ++ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, ++ .tested = TEST_OK_PR, ++ .probe = probe_jedec, ++ .probe_timing = 1, /* 150 ns */ + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 96} }, -+ .block_erase = erase_sst_fwhub_sector, ++ .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {64 * 1024, 6} }, -+ .block_erase = erase_sst_fwhub_block, ++ .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {384 * 1024, 1} }, + .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */ + } + }, - .write = write_sst_fwhub, ++ .printlock = printlock_sst_fwhub, ++ .unlock = unlock_sst_fwhub, ++ .write = write_jedec_1, .read = read_memmapped, }, @@ -9675,39 +10309,45 @@ index 5fd78f2..24736d4 100644 .vendor = "SST", .name = "SST49LF004A/B", .bustype = CHIP_BUSTYPE_FWH, /* A/A Mux */ -@@ -2106,10 +4137,23 @@ struct flashchip flashchips[] = { +@@ -2106,11 +4311,26 @@ struct flashchip flashchips[] = { .model_id = SST_49LF004A, .total_size = 512, .page_size = 64 * 1024, + .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, .tested = TEST_OK_PREW, - .probe = probe_sst_fwhub, +- .probe = probe_sst_fwhub, - .probe_timing = TIMING_FIXME, /* routine is wrapper to probe_jedec (sst_fwhub.c) */ - .erase = erase_sst_fwhub, -+ .probe_timing = 1, /* 150 ns | routine is wrapper to probe_jedec (sst_fwhub.c) */ +- .write = write_sst_fwhub, ++ .probe = probe_jedec, ++ .probe_timing = 1, /* 150 ns */ + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 128} }, -+ .block_erase = erase_sector_jedec, /* missing unlock */ ++ .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {64 * 1024, 8} }, -+ .block_erase = erase_sst_fwhub_block, /* same as erase_block_jedec, but with unlock */ ++ .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */ + }, + }, - .write = write_sst_fwhub, ++ .printlock = printlock_sst_fwhub, ++ .unlock = unlock_sst_fwhub, ++ .write = write_jedec_1, .read = read_memmapped, }, -@@ -2122,10 +4166,25 @@ struct flashchip flashchips[] = { + +@@ -2122,10 +4342,26 @@ struct flashchip flashchips[] = { .model_id = SST_49LF004C, .total_size = 512, .page_size = 4 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_49lfxxxc, +- .probe = probe_49lfxxxc, ++ .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ - .erase = erase_49lfxxxc, + .block_erasers = @@ -9722,46 +10362,53 @@ index 5fd78f2..24736d4 100644 + {8 * 1024, 2}, + {16 * 1024, 1}, + }, -+ .block_erase = erase_block_49lfxxxc, ++ .block_erase = erase_block_82802ab, + } + }, ++ .unlock = unlock_49lfxxxc, .write = write_49lfxxxc, .read = read_memmapped, }, -@@ -2138,10 +4197,23 @@ struct flashchip flashchips[] = { +@@ -2138,11 +4374,26 @@ struct flashchip flashchips[] = { .model_id = SST_49LF008A, .total_size = 1024, .page_size = 64 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, -+ .tested = TEST_OK_PRW, - .probe = probe_sst_fwhub, +- .probe = probe_sst_fwhub, - .probe_timing = TIMING_FIXME, /* routine is wrapper to probe_jedec (sst_fwhub.c) */ - .erase = erase_sst_fwhub, -+ .probe_timing = 1, /* 150 ns | routine is wrapper to probe_jedec (sst_fwhub.c) */ +- .write = write_sst_fwhub, ++ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, ++ .tested = TEST_OK_PRW, ++ .probe = probe_jedec, ++ .probe_timing = 1, /* 150 ns */ + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 256} }, -+ .block_erase = erase_sst_fwhub_sector, ++ .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {64 * 1024, 16} }, -+ .block_erase = erase_sst_fwhub_block, ++ .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {1024 * 1024, 1} }, + .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */ + } + }, - .write = write_sst_fwhub, ++ .printlock = printlock_sst_fwhub, ++ .unlock = unlock_sst_fwhub, ++ .write = write_jedec_1, .read = read_memmapped, }, -@@ -2154,10 +4226,25 @@ struct flashchip flashchips[] = { + +@@ -2154,10 +4405,26 @@ struct flashchip flashchips[] = { .model_id = SST_49LF008C, .total_size = 1024, .page_size = 4 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_49lfxxxc, +- .probe = probe_49lfxxxc, ++ .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ - .erase = erase_49lfxxxc, + .block_erasers = @@ -9776,20 +10423,22 @@ index 5fd78f2..24736d4 100644 + {8 * 1024, 2}, + {16 * 1024, 1}, + }, -+ .block_erase = erase_block_49lfxxxc, ++ .block_erase = erase_block_82802ab, + } + }, ++ .unlock = unlock_49lfxxxc, .write = write_49lfxxxc, .read = read_memmapped, }, -@@ -2170,10 +4257,25 @@ struct flashchip flashchips[] = { +@@ -2170,10 +4437,26 @@ struct flashchip flashchips[] = { .model_id = SST_49LF016C, .total_size = 2048, .page_size = 4 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = 0, +- .probe = probe_49lfxxxc, ++ .feature_bits = FEATURE_REGISTERMAP, + .tested = TEST_OK_PRW, - .probe = probe_49lfxxxc, ++ .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ - .erase = erase_49lfxxxc, + .block_erasers = @@ -9804,13 +10453,14 @@ index 5fd78f2..24736d4 100644 + {8 * 1024, 2}, + {16 * 1024, 1}, + }, -+ .block_erase = erase_block_49lfxxxc, ++ .block_erase = erase_block_82802ab, + } + }, ++ .unlock = unlock_49lfxxxc, .write = write_49lfxxxc, .read = read_memmapped, }, -@@ -2186,11 +4288,24 @@ struct flashchip flashchips[] = { +@@ -2186,11 +4469,24 @@ struct flashchip flashchips[] = { .model_id = SST_49LF020, .total_size = 256, .page_size = 16 * 1024, @@ -9838,7 +10488,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2202,11 +4317,24 @@ struct flashchip flashchips[] = { +@@ -2202,11 +4498,24 @@ struct flashchip flashchips[] = { .model_id = SST_49LF020A, .total_size = 256, .page_size = 4 * 1024, @@ -9865,7 +10515,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2218,11 +4346,24 @@ struct flashchip flashchips[] = { +@@ -2218,11 +4527,24 @@ struct flashchip flashchips[] = { .model_id = SST_49LF040, .total_size = 512, .page_size = 4096, @@ -9893,7 +10543,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2234,11 +4375,24 @@ struct flashchip flashchips[] = { +@@ -2234,11 +4556,24 @@ struct flashchip flashchips[] = { .model_id = SST_49LF040B, .total_size = 512, .page_size = 64 * 1024, @@ -9905,7 +10555,7 @@ index 5fd78f2..24736d4 100644 + .feature_bits = FEATURE_EITHER_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec, -+ .probe_timing = 1, /* 150ns | routine is wrapper to probe_jedec (sst_fwhub.c) */ ++ .probe_timing = 1, /* 150ns */ + .block_erasers = + { + { @@ -9923,13 +10573,13 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2250,11 +4404,24 @@ struct flashchip flashchips[] = { +@@ -2250,11 +4585,24 @@ struct flashchip flashchips[] = { .model_id = SST_49LF080A, .total_size = 1024, .page_size = 4096, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_FIXME, - .erase = erase_49lf040, @@ -9951,14 +10601,15 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2266,10 +4433,26 @@ struct flashchip flashchips[] = { +@@ -2266,10 +4614,26 @@ struct flashchip flashchips[] = { .model_id = SST_49LF160C, .total_size = 2048, .page_size = 4 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = 0, +- .probe = probe_49lfxxxc, ++ .feature_bits = FEATURE_REGISTERMAP, + .tested = TEST_OK_PRW, - .probe = probe_49lfxxxc, ++ .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ - .erase = erase_49lfxxxc, + .block_erasers = @@ -9973,14 +10624,14 @@ index 5fd78f2..24736d4 100644 + {8 * 1024, 2}, + {16 * 1024, 1}, + }, -+ .block_erase = erase_block_49lfxxxc, ++ .block_erase = erase_block_82802ab, + } + }, + .unlock = unlock_49lfxxxc, .write = write_49lfxxxc, .read = read_memmapped, }, -@@ -2285,7 +4468,16 @@ struct flashchip flashchips[] = { +@@ -2285,7 +4649,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -9998,7 +10649,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2306,7 +4498,16 @@ struct flashchip flashchips[] = { +@@ -2306,7 +4679,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_res, .probe_timing = TIMING_ZERO, @@ -10016,7 +10667,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_1, /* 128 */ .read = spi_chip_read, }, -@@ -2322,7 +4523,16 @@ struct flashchip flashchips[] = { +@@ -2322,7 +4704,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -10034,7 +10685,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2339,7 +4549,16 @@ struct flashchip flashchips[] = { +@@ -2339,7 +4730,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_res, .probe_timing = TIMING_ZERO, @@ -10052,7 +10703,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_1, /* 128 */ .read = spi_chip_read, }, -@@ -2355,7 +4574,16 @@ struct flashchip flashchips[] = { +@@ -2355,7 +4755,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -10070,7 +10721,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2368,10 +4596,19 @@ struct flashchip flashchips[] = { +@@ -2368,10 +4777,19 @@ struct flashchip flashchips[] = { .model_id = ST_M25P40, .total_size = 512, .page_size = 256, @@ -10092,7 +10743,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2387,7 +4624,16 @@ struct flashchip flashchips[] = { +@@ -2387,7 +4805,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_res, .probe_timing = TIMING_ZERO, @@ -10110,7 +10761,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2400,10 +4646,19 @@ struct flashchip flashchips[] = { +@@ -2400,10 +4827,19 @@ struct flashchip flashchips[] = { .model_id = ST_M25P80, .total_size = 1024, .page_size = 256, @@ -10132,7 +10783,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2416,10 +4671,19 @@ struct flashchip flashchips[] = { +@@ -2416,10 +4852,19 @@ struct flashchip flashchips[] = { .model_id = ST_M25P16, .total_size = 2048, .page_size = 256, @@ -10154,7 +10805,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2432,10 +4696,19 @@ struct flashchip flashchips[] = { +@@ -2432,10 +4877,19 @@ struct flashchip flashchips[] = { .model_id = ST_M25P32, .total_size = 4096, .page_size = 256, @@ -10176,7 +10827,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2451,7 +4724,16 @@ struct flashchip flashchips[] = { +@@ -2451,7 +4905,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -10194,7 +10845,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2467,7 +4749,16 @@ struct flashchip flashchips[] = { +@@ -2467,7 +4930,16 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -10212,7 +10863,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2480,11 +4771,26 @@ struct flashchip flashchips[] = { +@@ -2480,11 +4952,26 @@ struct flashchip flashchips[] = { .model_id = ST_M29F002B, .total_size = 256, .page_size = 64 * 1024, @@ -10242,7 +10893,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2496,11 +4802,26 @@ struct flashchip flashchips[] = { +@@ -2496,11 +4983,26 @@ struct flashchip flashchips[] = { .model_id = ST_M29F002T, .total_size = 256, .page_size = 64 * 1024, @@ -10273,7 +10924,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2512,15 +4833,26 @@ struct flashchip flashchips[] = { +@@ -2512,15 +5014,26 @@ struct flashchip flashchips[] = { .model_id = ST_M29F040B, .total_size = 512, .page_size = 64 * 1024, @@ -10304,7 +10955,7 @@ index 5fd78f2..24736d4 100644 .vendor = "ST", .name = "M29F400BT", .bustype = CHIP_BUSTYPE_PARALLEL, -@@ -2528,10 +4860,25 @@ struct flashchip flashchips[] = { +@@ -2528,10 +5041,25 @@ struct flashchip flashchips[] = { .model_id = ST_M29F400BT, .total_size = 512, .page_size = 64 * 1024, @@ -10331,7 +10982,7 @@ index 5fd78f2..24736d4 100644 .write = write_coreboot_m29f400bt, .read = read_memmapped, }, -@@ -2544,11 +4891,21 @@ struct flashchip flashchips[] = { +@@ -2544,11 +5072,21 @@ struct flashchip flashchips[] = { .model_id = ST_M29W010B, .total_size = 128, .page_size = 16 * 1024, @@ -10356,7 +11007,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2560,26 +4917,77 @@ struct flashchip flashchips[] = { +@@ -2560,75 +5098,184 @@ struct flashchip flashchips[] = { .model_id = ST_M29W040B, .total_size = 512, .page_size = 64 * 1024, @@ -10413,11 +11064,12 @@ index 5fd78f2..24736d4 100644 .model_id = ST_M50FLW040A, .total_size = 512, .page_size = 64 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_stm50flw0x0x, - .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (stm50flw0x0x.c) */ - .erase = erase_stm50flw0x0x, +- .write = write_stm50flw0x0x, + .probe = probe_82802ab, + .probe_timing = TIMING_FIXME, + .block_erasers = @@ -10432,16 +11084,17 @@ index 5fd78f2..24736d4 100644 + .block_erase = NULL, + }, { + .eraseblocks = { {64 * 1024, 8}, }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, - .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, ++ .write = write_82802ab, .read = read_memmapped, }, -@@ -2587,15 +4995,33 @@ struct flashchip flashchips[] = { + { .vendor = "ST", .name = "M50FLW040B", @@ -10451,11 +11104,12 @@ index 5fd78f2..24736d4 100644 .model_id = ST_M50FLW040B, .total_size = 512, .page_size = 64 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_stm50flw0x0x, - .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (stm50flw0x0x.c) */ - .erase = erase_stm50flw0x0x, +- .write = write_stm50flw0x0x, + .probe = probe_82802ab, + .probe_timing = TIMING_FIXME, + .block_erasers = @@ -10470,16 +11124,17 @@ index 5fd78f2..24736d4 100644 + .block_erase = NULL, + }, { + .eraseblocks = { {64 * 1024, 8}, }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, - .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, ++ .write = write_82802ab, .read = read_memmapped, }, -@@ -2603,15 +5029,33 @@ struct flashchip flashchips[] = { + { .vendor = "ST", .name = "M50FLW080A", @@ -10493,7 +11148,8 @@ index 5fd78f2..24736d4 100644 - .probe = probe_stm50flw0x0x, - .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (stm50flw0x0x.c) */ - .erase = erase_stm50flw0x0x, -+ .feature_bits = 0, +- .write = write_stm50flw0x0x, ++ .feature_bits = FEATURE_REGISTERMAP, + .tested = TEST_UNTESTED, + .probe = probe_82802ab, + .probe_timing = TIMING_FIXME, @@ -10509,16 +11165,17 @@ index 5fd78f2..24736d4 100644 + .block_erase = NULL, + }, { + .eraseblocks = { {64 * 1024, 16}, }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {1024 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, - .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, ++ .write = write_82802ab, .read = read_memmapped, }, -@@ -2619,15 +5063,33 @@ struct flashchip flashchips[] = { + { .vendor = "ST", .name = "M50FLW080B", @@ -10528,11 +11185,12 @@ index 5fd78f2..24736d4 100644 .model_id = ST_M50FLW080B, .total_size = 1024, .page_size = 64 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_stm50flw0x0x, - .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (stm50flw0x0x.c) */ - .erase = erase_stm50flw0x0x, +- .write = write_stm50flw0x0x, + .probe = probe_82802ab, + .probe_timing = TIMING_FIXME, + .block_erasers = @@ -10547,20 +11205,22 @@ index 5fd78f2..24736d4 100644 + .block_erase = NULL, + }, { + .eraseblocks = { {64 * 1024, 16}, }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {1024 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, - .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, ++ .write = write_82802ab, .read = read_memmapped, }, -@@ -2640,11 +5102,26 @@ struct flashchip flashchips[] = { + +@@ -2640,11 +5287,27 @@ struct flashchip flashchips[] = { .model_id = ST_M50FW002, .total_size = 256, .page_size = 64 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_49lfxxxc, + .probe = probe_82802ab, @@ -10576,95 +11236,93 @@ index 5fd78f2..24736d4 100644 + {8 * 1024, 2}, + {16 * 1024, 1}, + }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, -+ .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, ++ .write = write_82802ab, .read = read_memmapped, }, -@@ -2656,11 +5133,21 @@ struct flashchip flashchips[] = { +@@ -2656,10 +5319,21 @@ struct flashchip flashchips[] = { .model_id = ST_M50FW016, .total_size = 2048, .page_size = 64 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (82802ab.c) */ - .erase = erase_82802ab, -- .write = write_82802ab, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 32}, }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {2 * 1024 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, -+ .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, + .write = write_82802ab, .read = read_memmapped, }, - -@@ -2672,11 +5159,21 @@ struct flashchip flashchips[] = { +@@ -2672,10 +5346,21 @@ struct flashchip flashchips[] = { .model_id = ST_M50FW040, .total_size = 512, .page_size = 64 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = 0, -+ .tested = TEST_OK_PRW, ++ .feature_bits = FEATURE_REGISTERMAP, ++ .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (82802ab.c) */ - .erase = erase_82802ab, -- .write = write_82802ab, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 8}, }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, -+ .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, + .write = write_82802ab, .read = read_memmapped, }, - -@@ -2688,11 +5185,21 @@ struct flashchip flashchips[] = { +@@ -2688,10 +5373,21 @@ struct flashchip flashchips[] = { .model_id = ST_M50FW080, .total_size = 1024, .page_size = 64 * 1024, - .tested = TEST_OK_PREW, -+ .feature_bits = 0, -+ .tested = TEST_OK_PRW, ++ .feature_bits = FEATURE_REGISTERMAP, ++ .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (82802ab.c) */ - .erase = erase_82802ab, -- .write = write_82802ab, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 16}, }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {1024 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, -+ .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, + .write = write_82802ab, .read = read_memmapped, }, - -@@ -2704,11 +5211,27 @@ struct flashchip flashchips[] = { +@@ -2704,11 +5400,28 @@ struct flashchip flashchips[] = { .model_id = ST_M50LPW116, .total_size = 2048, .page_size = 64 * 1024, -+ .feature_bits = 0, ++ .feature_bits = FEATURE_REGISTERMAP, .tested = TEST_UNTESTED, - .probe = probe_jedec, - .probe_timing = TIMING_FIXME, @@ -10682,17 +11340,18 @@ index 5fd78f2..24736d4 100644 + {8 * 1024, 2}, + {16 * 1024, 1}, + }, -+ .block_erase = erase_block_stm50flw0x0x, ++ .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {2 * 1024 * 1024, 1} }, + .block_erase = erase_chip_stm50flw0x0x, + } + }, -+ .write = write_stm50flw0x0x, ++ .unlock = unlock_stm50flw0x0x, ++ .write = write_82802ab, .read = read_memmapped, }, -@@ -2720,11 +5243,21 @@ struct flashchip flashchips[] = { +@@ -2720,11 +5433,21 @@ struct flashchip flashchips[] = { .model_id = S29C31004T, .total_size = 512, .page_size = 128, @@ -10717,7 +11376,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2736,11 +5269,21 @@ struct flashchip flashchips[] = { +@@ -2736,11 +5459,21 @@ struct flashchip flashchips[] = { .model_id = S29C51001T, .total_size = 128, .page_size = 128, @@ -10742,13 +11401,13 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2752,11 +5295,21 @@ struct flashchip flashchips[] = { +@@ -2752,11 +5485,21 @@ struct flashchip flashchips[] = { .model_id = S29C51002T, .total_size = 256, .page_size = 128, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -10768,7 +11427,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2768,11 +5321,21 @@ struct flashchip flashchips[] = { +@@ -2768,11 +5511,21 @@ struct flashchip flashchips[] = { .model_id = S29C51004T, .total_size = 512, .page_size = 128, @@ -10793,7 +11452,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2784,11 +5347,26 @@ struct flashchip flashchips[] = { +@@ -2784,11 +5537,26 @@ struct flashchip flashchips[] = { .model_id = TI_TMS29F002RB, .total_size = 256, .page_size = 16384, /* Non-uniform sectors */ @@ -10823,7 +11482,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2800,11 +5378,26 @@ struct flashchip flashchips[] = { +@@ -2800,16 +5568,133 @@ struct flashchip flashchips[] = { .model_id = TI_TMS29F002RT, .total_size = 256, .page_size = 16384, /* Non-uniform sectors */ @@ -10853,7 +11512,114 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2819,7 +5412,19 @@ struct flashchip flashchips[] = { + { + .vendor = "Winbond", ++ .name = "W25Q80", ++ .bustype = CHIP_BUSTYPE_SPI, ++ .manufacture_id = WINBOND_NEX_ID, ++ .model_id = W_25Q80, ++ .total_size = 1024, ++ .page_size = 256, ++ .tested = TEST_UNTESTED, ++ .probe = probe_spi_rdid, ++ .probe_timing = TIMING_ZERO, ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { {4 * 1024, 256} }, ++ .block_erase = spi_block_erase_20, ++ }, { ++ .eraseblocks = { {32 * 1024, 32} }, ++ .block_erase = spi_block_erase_52, ++ }, { ++ .eraseblocks = { {64 * 1024, 16} }, ++ .block_erase = spi_block_erase_d8, ++ }, { ++ .eraseblocks = { {1024 * 1024, 1} }, ++ .block_erase = spi_block_erase_60, ++ }, { ++ .eraseblocks = { {1024 * 1024, 1} }, ++ .block_erase = spi_block_erase_c7, ++ } ++ }, ++ .write = spi_chip_write_256, ++ .read = spi_chip_read, ++ }, ++ ++ { ++ .vendor = "Winbond", ++ .name = "W25Q16", ++ .bustype = CHIP_BUSTYPE_SPI, ++ .manufacture_id = WINBOND_NEX_ID, ++ .model_id = W_25Q16, ++ .total_size = 2048, ++ .page_size = 256, ++ .tested = TEST_UNTESTED, ++ .probe = probe_spi_rdid, ++ .probe_timing = TIMING_ZERO, ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { {4 * 1024, 512} }, ++ .block_erase = spi_block_erase_20, ++ }, { ++ .eraseblocks = { {32 * 1024, 64} }, ++ .block_erase = spi_block_erase_52, ++ }, { ++ .eraseblocks = { {64 * 1024, 32} }, ++ .block_erase = spi_block_erase_d8, ++ }, { ++ .eraseblocks = { {2 * 1024 * 1024, 1} }, ++ .block_erase = spi_block_erase_60, ++ }, { ++ .eraseblocks = { {2 * 1024 * 1024, 1} }, ++ .block_erase = spi_block_erase_c7, ++ } ++ }, ++ .write = spi_chip_write_256, ++ .read = spi_chip_read, ++ }, ++ ++ { ++ .vendor = "Winbond", ++ .name = "W25Q32", ++ .bustype = CHIP_BUSTYPE_SPI, ++ .manufacture_id = WINBOND_NEX_ID, ++ .model_id = W_25Q32, ++ .total_size = 4096, ++ .page_size = 256, ++ .tested = TEST_UNTESTED, ++ .probe = probe_spi_rdid, ++ .probe_timing = TIMING_ZERO, ++ .block_erasers = ++ { ++ { ++ .eraseblocks = { {4 * 1024, 1024} }, ++ .block_erase = spi_block_erase_20, ++ }, { ++ .eraseblocks = { {32 * 1024, 128} }, ++ .block_erase = spi_block_erase_52, ++ }, { ++ .eraseblocks = { {64 * 1024, 64} }, ++ .block_erase = spi_block_erase_d8, ++ }, { ++ .eraseblocks = { {4 * 1024 * 1024, 1} }, ++ .block_erase = spi_block_erase_60, ++ }, { ++ .eraseblocks = { {4 * 1024 * 1024, 1} }, ++ .block_erase = spi_block_erase_c7, ++ } ++ }, ++ .write = spi_chip_write_256, ++ .read = spi_chip_read, ++ }, ++ ++ { ++ .vendor = "Winbond", + .name = "W25x10", + .bustype = CHIP_BUSTYPE_SPI, + .manufacture_id = WINBOND_NEX_ID, +@@ -2819,7 +5704,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -10874,7 +11640,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2835,7 +5440,19 @@ struct flashchip flashchips[] = { +@@ -2835,7 +5732,19 @@ struct flashchip flashchips[] = { .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -10895,7 +11661,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2848,10 +5465,22 @@ struct flashchip flashchips[] = { +@@ -2848,10 +5757,22 @@ struct flashchip flashchips[] = { .model_id = W_25X40, .total_size = 512, .page_size = 256, @@ -10920,7 +11686,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2864,10 +5493,22 @@ struct flashchip flashchips[] = { +@@ -2864,10 +5785,22 @@ struct flashchip flashchips[] = { .model_id = W_25X80, .total_size = 1024, .page_size = 256, @@ -10945,7 +11711,7 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2883,7 +5524,93 @@ struct flashchip flashchips[] = { +@@ -2883,7 +5816,93 @@ struct flashchip flashchips[] = { .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -11040,13 +11806,13 @@ index 5fd78f2..24736d4 100644 .write = spi_chip_write_256, .read = spi_chip_read, }, -@@ -2896,10 +5623,17 @@ struct flashchip flashchips[] = { +@@ -2896,10 +5915,17 @@ struct flashchip flashchips[] = { .model_id = W_29C011, .total_size = 128, .page_size = 128, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_LONG_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -11061,13 +11827,13 @@ index 5fd78f2..24736d4 100644 .write = write_jedec, .read = read_memmapped, }, -@@ -2912,10 +5646,17 @@ struct flashchip flashchips[] = { +@@ -2912,10 +5938,17 @@ struct flashchip flashchips[] = { .model_id = W_29C020C, .total_size = 256, .page_size = 128, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_LONG_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = 10, - .erase = erase_chip_jedec, @@ -11081,7 +11847,7 @@ index 5fd78f2..24736d4 100644 .write = write_jedec, .read = read_memmapped, }, -@@ -2928,10 +5669,17 @@ struct flashchip flashchips[] = { +@@ -2928,10 +5961,17 @@ struct flashchip flashchips[] = { .model_id = W_29C040P, .total_size = 512, .page_size = 256, @@ -11100,7 +11866,7 @@ index 5fd78f2..24736d4 100644 .write = write_jedec, .read = read_memmapped, }, -@@ -2944,10 +5692,17 @@ struct flashchip flashchips[] = { +@@ -2944,10 +5984,17 @@ struct flashchip flashchips[] = { .model_id = W_29C011, .total_size = 128, .page_size = 128, @@ -11120,7 +11886,7 @@ index 5fd78f2..24736d4 100644 .write = write_jedec, .read = read_memmapped, }, -@@ -2959,12 +5714,22 @@ struct flashchip flashchips[] = { +@@ -2959,12 +6006,22 @@ struct flashchip flashchips[] = { .manufacture_id = WINBOND_ID, .model_id = W_39V040A, .total_size = 512, @@ -11128,7 +11894,7 @@ index 5fd78f2..24736d4 100644 - .tested = TEST_OK_PREW, + .page_size = 64 * 1024, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = 10, - .erase = erase_chip_jedec, @@ -11147,7 +11913,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2975,12 +5740,22 @@ struct flashchip flashchips[] = { +@@ -2975,12 +6032,22 @@ struct flashchip flashchips[] = { .manufacture_id = WINBOND_ID, .model_id = W_39V040B, .total_size = 512, @@ -11155,7 +11921,7 @@ index 5fd78f2..24736d4 100644 - .tested = TEST_OK_PR | TEST_BAD_ERASE | TEST_BAD_WRITE, + .page_size = 64 * 1024, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, .probe_timing = 10, - .erase = erase_chip_jedec, @@ -11174,7 +11940,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -2991,12 +5766,23 @@ struct flashchip flashchips[] = { +@@ -2991,12 +6058,23 @@ struct flashchip flashchips[] = { .manufacture_id = WINBOND_ID, .model_id = W_39V040C, .total_size = 512, @@ -11204,7 +11970,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3007,12 +5793,25 @@ struct flashchip flashchips[] = { +@@ -3007,12 +6085,25 @@ struct flashchip flashchips[] = { .manufacture_id = WINBOND_ID, .model_id = W_39V040FA, .total_size = 512, @@ -11234,7 +12000,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3023,12 +5822,22 @@ struct flashchip flashchips[] = { +@@ -3023,12 +6114,22 @@ struct flashchip flashchips[] = { .manufacture_id = WINBOND_ID, .model_id = W_39V080A, .total_size = 1024, @@ -11261,13 +12027,13 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3040,11 +5849,26 @@ struct flashchip flashchips[] = { +@@ -3040,11 +6141,26 @@ struct flashchip flashchips[] = { .model_id = W_49F002U, .total_size = 256, .page_size = 128, - .tested = TEST_OK_PREW, + .feature_bits = FEATURE_EITHER_RESET, -+ .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -11292,7 +12058,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3056,11 +5880,26 @@ struct flashchip flashchips[] = { +@@ -3056,11 +6172,26 @@ struct flashchip flashchips[] = { .model_id = W_49V002A, .total_size = 256, .page_size = 128, @@ -11322,12 +12088,13 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3072,11 +5911,26 @@ struct flashchip flashchips[] = { +@@ -3072,11 +6203,26 @@ struct flashchip flashchips[] = { .model_id = W_49V002FA, .total_size = 256, .page_size = 128, +- .tested = TEST_UNTESTED, + .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_UNTESTED, ++ .tested = TEST_OK_PRW, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, - .erase = erase_chip_jedec, @@ -11352,7 +12119,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3087,12 +5941,23 @@ struct flashchip flashchips[] = { +@@ -3087,12 +6233,23 @@ struct flashchip flashchips[] = { .manufacture_id = WINBOND_ID, .model_id = W_39V080FA, .total_size = 1024, @@ -11382,7 +12149,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3103,12 +5968,23 @@ struct flashchip flashchips[] = { +@@ -3103,12 +6260,23 @@ struct flashchip flashchips[] = { .manufacture_id = WINBOND_ID, .model_id = W_39V080FA_DM, .total_size = 512, @@ -11411,7 +12178,7 @@ index 5fd78f2..24736d4 100644 .read = read_memmapped, }, -@@ -3123,7 +5999,6 @@ struct flashchip flashchips[] = { +@@ -3123,7 +6291,6 @@ struct flashchip flashchips[] = { .tested = TEST_BAD_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -11419,7 +12186,7 @@ index 5fd78f2..24736d4 100644 .write = NULL, .read = NULL, }, -@@ -3139,7 +6014,6 @@ struct flashchip flashchips[] = { +@@ -3139,7 +6306,6 @@ struct flashchip flashchips[] = { .tested = TEST_BAD_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -11427,7 +12194,7 @@ index 5fd78f2..24736d4 100644 .write = NULL, .read = NULL, }, -@@ -3155,7 +6029,6 @@ struct flashchip flashchips[] = { +@@ -3155,7 +6321,6 @@ struct flashchip flashchips[] = { .tested = TEST_BAD_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -11435,7 +12202,7 @@ index 5fd78f2..24736d4 100644 .write = NULL, .read = NULL, }, -@@ -3171,7 +6044,6 @@ struct flashchip flashchips[] = { +@@ -3171,7 +6336,6 @@ struct flashchip flashchips[] = { .tested = TEST_BAD_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -11443,7 +12210,7 @@ index 5fd78f2..24736d4 100644 .write = NULL, .read = NULL, }, -@@ -3187,7 +6059,6 @@ struct flashchip flashchips[] = { +@@ -3187,7 +6351,6 @@ struct flashchip flashchips[] = { .tested = TEST_BAD_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -11451,7 +12218,7 @@ index 5fd78f2..24736d4 100644 .write = NULL, .read = NULL, }, -@@ -3203,10 +6074,49 @@ struct flashchip flashchips[] = { +@@ -3203,10 +6366,49 @@ struct flashchip flashchips[] = { .tested = TEST_BAD_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -11503,7 +12270,7 @@ index 5fd78f2..24736d4 100644 { NULL } }; diff --git a/flashchips.h b/flashchips.h -index 40edbbb..4337e52 100644 +index 40edbbb..bfd8145 100644 --- a/flashchips.h +++ b/flashchips.h @@ -34,6 +34,7 @@ @@ -11553,7 +12320,7 @@ index 40edbbb..4337e52 100644 #define EN_29F040A 0x7F04 #define EN_29LV010 0x7F6E #define EN_29LV040A 0x7F4F /* EN_29LV040(A) */ -@@ -237,6 +254,9 @@ +@@ -237,8 +254,15 @@ #define INTEL_ID 0x89 /* Intel */ #define I_82802AB 0xAD #define I_82802AC 0xAC @@ -11562,8 +12329,14 @@ index 40edbbb..4337e52 100644 +#define E_28F016S5 0xAA #define P28F001BXT 0x94 /* 28F001BX-T */ #define P28F001BXB 0x95 /* 28F001BX-B */ ++#define P28F004BT 0x78 /* 28F004BV/BE-T */ ++#define P28F004BB 0x79 /* 28F004BV/BE-B */ ++#define P28F400BT 0x70 /* 28F400BV/CV/CE-T */ ++#define P28F400BB 0x71 /* 28F400BV/CV/CE-B */ #define SHARP_LH28F008SA 0xA2 /* Sharp chip, Intel Vendor ID */ -@@ -251,11 +271,11 @@ + #define SHARP_LH28F008SC 0xA6 /* Sharp chip, Intel Vendor ID */ + +@@ -251,11 +275,11 @@ * and use the same set of IDs. */ #define MX_ID 0xC2 /* Macronix (MX) */ @@ -11577,7 +12350,7 @@ index 40edbbb..4337e52 100644 #define MX_25L1605 0x2015 /* MX25L1605{,A,D} */ #define MX_25L3205 0x2016 /* MX25L3205{,A} */ #define MX_25L6405 0x2017 /* MX25L3205{,D} */ -@@ -325,6 +345,14 @@ +@@ -325,6 +349,14 @@ #define PMC_49FL002 0x6D #define PMC_49FL004 0x6E @@ -11592,7 +12365,7 @@ index 40edbbb..4337e52 100644 #define SHARP_ID 0xB0 /* Sharp */ #define SHARP_LH28F008BJxxPT 0xEC #define SHARP_LH28F008BJxxPB 0xED -@@ -340,6 +368,7 @@ +@@ -340,6 +372,7 @@ * the second device ID byte is memory capacity. */ #define SPANSION_ID 0x01 /* Spansion, same ID as AMD */ @@ -11600,7 +12373,7 @@ index 40edbbb..4337e52 100644 #define SPANSION_S25FL016A 0x0214 /* -@@ -380,6 +409,7 @@ +@@ -380,6 +413,7 @@ #define SST_29VF020 0x25 #define SST_29SF040 0x13 #define SST_29VF040 0x14 @@ -11608,7 +12381,7 @@ index 40edbbb..4337e52 100644 #define SST_39SF010 0xB5 #define SST_39SF020 0xB6 /* Same as 39SF020A */ #define SST_39SF040 0xB7 -@@ -446,6 +476,7 @@ +@@ -446,6 +480,7 @@ #define ST_M29F800DT 0xEC #define ST_M29W010B 0x23 #define ST_M29W040B 0xE3 @@ -11616,8 +12389,18 @@ index 40edbbb..4337e52 100644 #define SYNCMOS_ID 0x40 /* SyncMOS and Mosel Vitelic */ #define S29C51001T 0x01 +@@ -471,6 +506,9 @@ + #define W_25X16 0x3015 + #define W_25X32 0x3016 + #define W_25X64 0x3017 ++#define W_25Q80 0x4014 ++#define W_25Q16 0x4015 ++#define W_25Q32 0x4016 + #define W_29C011 0xC1 + #define W_29C020C 0x45 /* Same as W29C020 and ASD AE29F2008 */ + #define W_29C040P 0x46 /* Same as W29C040 */ diff --git a/flashrom.8 b/flashrom.8 -index 1324854..25f4a1e 100644 +index 1324854..47e77d6 100644 --- a/flashrom.8 +++ b/flashrom.8 @@ -22,7 +22,11 @@ checking that your flashrom version won't interpret options in a different way. @@ -11633,6 +12416,68 @@ index 1324854..25f4a1e 100644 .TP .B "\-r, \-\-read " Read flash ROM contents and save them into the given +@@ -58,6 +62,30 @@ More verbose output. + .TP + .B "\-c, \-\-chip" + Probe only for specified flash ROM chip. ++.TP ++.B "\-m, \-\-mainboard" <[vendor:]part> ++Override mainboard settings. ++.sp ++flashrom reads the coreboot table to determine the current mainboard. If no ++coreboot table could be read or if you want to override these values, you can ++specify \-m, e.g.: ++.sp ++.B " flashrom -w --mainboard AGAMI:ARUMA agami_aruma.rom" ++.sp ++See the 'Supported mainboards' section in the output of 'flashrom \-L' for ++a list of boards which require the specification of the board name, if no ++coreboot table is found. ++.TP ++.B "\-f, \-\-force" ++Force write without checking whether the ROM image file is really meant ++to be used on this board. ++.sp ++Note: This check only works while coreboot is running, and only for those ++boards where the coreboot code supports it. ++.TP ++.B "\-l, \-\-layout " ++Read ROM layout from ++.BR . + .sp + flashrom supports ROM layouts. This allows you to flash certain parts of + the flash chip only. A ROM layout file looks like follows: +@@ -86,30 +114,6 @@ ROM layouts should replace the \-s and \-e option since they are more + flexible and they should lead to a ROM update file format with the + ROM layout and the ROM image in one file (cpio, zip or something?). + .TP +-.B "\-m, \-\-mainboard" <[vendor:]part> +-Override mainboard settings. +-.sp +-flashrom reads the coreboot table to determine the current mainboard. If no +-coreboot table could be read or if you want to override these values, you can +-specify \-m, e.g.: +-.sp +-.B " flashrom -w --mainboard AGAMI:ARUMA agami_aruma.rom" +-.sp +-See the 'Supported mainboards' section in the output of 'flashrom \-L' for +-a list of boards which require the specification of the board name, if no +-coreboot table is found. +-.TP +-.B "\-f, \-\-force" +-Force write without checking whether the ROM image file is really meant +-to be used on this board. +-.sp +-Note: This check only works while coreboot is running, and only for those +-boards where the coreboot code supports it. +-.TP +-.B "\-l, \-\-layout " +-Read ROM layout from +-.BR . +-.TP + .B "\-i, \-\-image " + Only flash image + .B @@ -131,7 +135,7 @@ Same as but outputs the supported hardware in MediaWiki syntax, so that it can be easily pasted into the wiki page at http://www.flashrom.org/. @@ -11642,7 +12487,7 @@ index 1324854..25f4a1e 100644 Specify the programmer device. Currently supported are: .sp .BR "* internal" " (default, for in-system flashing in the mainboard)" -@@ -140,15 +144,84 @@ Specify the programmer device. Currently supported are: +@@ -140,15 +144,93 @@ Specify the programmer device. Currently supported are: .sp .BR "* nic3com" " (for flash ROMs on 3COM network cards)" .sp @@ -11677,7 +12522,7 @@ index 1324854..25f4a1e 100644 +Show version information and exit. +.SH PROGRAMMER SPECIFIC INFO +Some programmer drivers accept further parameters to set programmer-specific -+parameters. These parameters are seperated from the programmer name by a ++parameters. These parameters are separated from the programmer name by a +colon. While some programmers take arguments at fixed positions, other +programmers use a key/value interface in which the key and value is separated +by an equal sign and different pairs are separated by a comma or a colon. @@ -11723,12 +12568,21 @@ index 1324854..25f4a1e 100644 +enable is going to fail. In any case (success or failure), please report to +the flashrom mailing list, see below. +.sp ++If your mainboard uses an ITE IT87 series Super I/O for LPC<->SPI flash bus ++translation, flashrom should autodetect that configuration. You can use ++.B "flashrom -p internal:it87spiport=portnum" ++syntax as explained in the ++.B it87spi ++programmer section to use a non-default port for controlling the IT87 series ++Super I/O. In the unlikely case flashrom doesn't detect an active IT87 LPC<->SPI ++bridge, you can try to force recognition by using the it87spi programmer. ++.TP +.BR "dummy " programmer +An optional parameter specifies the bus types it should support. For that you have to use the .B "flashrom -p dummy:type" syntax where -@@ -159,11 +232,13 @@ in any order. +@@ -159,11 +241,13 @@ in any order. .sp Example: .B "flashrom -p dummy:lpc,fwh" @@ -11736,7 +12590,7 @@ index 1324854..25f4a1e 100644 -If you have multiple supported PCI cards which can program flash chips -(NICs, SATA/IDE controllers, etc.) in your system, you must use the +.TP -+.BR "nic3com" , " gfxnvidia" , " satasii" and " atahpt " programmers ++.BR "nic3com" , " gfxnvidia" , " satasii " and " atahpt " programmers +These programmers have an option to specify the PCI address of the card +your want to use, which must be specified if more than one card supported +by the selected programmer is installed in your system. The syntax is @@ -11746,7 +12600,7 @@ index 1324854..25f4a1e 100644 .B xxxx is the name of the programmer .B bb -@@ -175,20 +250,18 @@ is the PCI function number of the desired NIC. +@@ -175,20 +259,18 @@ is the PCI function number of the desired NIC. .sp Example: .B "flashrom -p nic3com:05:04.0" @@ -11758,12 +12612,13 @@ index 1324854..25f4a1e 100644 -The it87spi programmer has an optional parameter which will set the I/O base -port of the IT87* SPI controller interface to the port specified in the -parameter. For that you have to use the +-.B "flashrom -p it87spi:port=portnum" +.TP +.BR "it87spi " programmer +An optional parameter sets the I/O base port of the IT87* SPI controller +interface to the port specified in the parameter instead of using the port +address set by the BIOS. For that you have to use the - .B "flashrom -p it87spi:port=portnum" ++.B "flashrom -p it87spi:it87spiport=portnum" syntax where .B portnum is an I/O port number which must be a multiple of 8. @@ -11775,7 +12630,7 @@ index 1324854..25f4a1e 100644 type and interface/port it should support. For that you have to use the .B "flashrom -p ft2232spi:model,port=interface" syntax where -@@ -198,31 +271,35 @@ can be any of +@@ -198,31 +280,35 @@ can be any of and .B interface can be any of @@ -11804,15 +12659,15 @@ index 1324854..25f4a1e 100644 -Support for some programmers can be disabled at compile time. -.B "flashrom -h" -lists all supported programmers. - .TP +-.TP -.B "\-h, \-\-help" -Show a help text and exit. --.TP + .TP -.B "\-R, \-\-version" -Show version information and exit. +.BR "buspiratespi " programmer -+A required dev parameter specifyies the Bus Pirate device node and an optional -+spispeed parameter specifyies the frequency of the SPI bus. The parameter ++A required dev parameter specifies the Bus Pirate device node and an optional ++spispeed parameter specifies the frequency of the SPI bus. The parameter +delimiter is a comma. Syntax is +.sp +.B "flashrom -p buspiratespi:dev=/dev/device,spispeed=frequency" @@ -11825,7 +12680,7 @@ index 1324854..25f4a1e 100644 .SH EXIT STATUS flashrom exits with 0 on success, 1 on most failures but with 2 if /dev/mem (/dev/xsvc on Solaris) can not be opened and with 3 if a call to mmap() fails. -@@ -245,7 +322,7 @@ Claus Gindhart +@@ -245,7 +331,7 @@ Claus Gindhart .br Dominik Geyer .br @@ -11834,7 +12689,7 @@ index 1324854..25f4a1e 100644 .br Giampiero Giancipoli .br -@@ -275,9 +352,9 @@ Steven James +@@ -275,9 +361,9 @@ Steven James .br Uwe Hermann .br @@ -11847,10 +12702,19 @@ index 1324854..25f4a1e 100644 some others .PP diff --git a/flashrom.c b/flashrom.c -index fc80301..6a91089 100644 +index fc80301..2450dee 100644 --- a/flashrom.c +++ b/flashrom.c -@@ -33,10 +33,73 @@ +@@ -27,16 +27,82 @@ + #include + #include + #include ++#if HAVE_UTSNAME == 1 ++#include ++#endif + #include "flash.h" + #include "flashchips.h" + const char *flashrom_version = FLASHROM_VERSION; char *chip_to_probe = NULL; int verbose = 0; @@ -11924,7 +12788,7 @@ index fc80301..6a91089 100644 { .name = "internal", .init = internal_init, -@@ -53,7 +116,9 @@ const struct programmer_entry programmer_table[] = { +@@ -53,7 +119,9 @@ const struct programmer_entry programmer_table[] = { .chip_writen = fallback_chip_writen, .delay = internal_delay, }, @@ -11934,7 +12798,7 @@ index fc80301..6a91089 100644 { .name = "dummy", .init = dummy_init, -@@ -70,7 +135,9 @@ const struct programmer_entry programmer_table[] = { +@@ -70,7 +138,9 @@ const struct programmer_entry programmer_table[] = { .chip_writen = dummy_chip_writen, .delay = internal_delay, }, @@ -11944,7 +12808,7 @@ index fc80301..6a91089 100644 { .name = "nic3com", .init = nic3com_init, -@@ -87,7 +154,47 @@ const struct programmer_entry programmer_table[] = { +@@ -87,7 +157,47 @@ const struct programmer_entry programmer_table[] = { .chip_writen = fallback_chip_writen, .delay = internal_delay, }, @@ -11992,12 +12856,12 @@ index fc80301..6a91089 100644 { .name = "satasii", .init = satasii_init, -@@ -104,36 +211,58 @@ const struct programmer_entry programmer_table[] = { +@@ -104,36 +214,58 @@ const struct programmer_entry programmer_table[] = { .chip_writen = fallback_chip_writen, .delay = internal_delay, }, +#endif -+ + +#if ATAHPT_SUPPORT == 1 + { + .name = "atahpt", @@ -12016,7 +12880,7 @@ index fc80301..6a91089 100644 + .delay = internal_delay, + }, +#endif - ++ +#if INTERNAL_SUPPORT == 1 { .name = "it87spi", @@ -12057,7 +12921,7 @@ index fc80301..6a91089 100644 .chip_writew = fallback_chip_writew, .chip_writel = fallback_chip_writel, .chip_writen = fallback_chip_writen, -@@ -160,9 +289,76 @@ const struct programmer_entry programmer_table[] = { +@@ -160,9 +292,76 @@ const struct programmer_entry programmer_table[] = { }, #endif @@ -12134,7 +12998,7 @@ index fc80301..6a91089 100644 int programmer_init(void) { return programmer_table[programmer].init(); -@@ -170,6 +366,10 @@ int programmer_init(void) +@@ -170,6 +369,10 @@ int programmer_init(void) int programmer_shutdown(void) { @@ -12145,7 +13009,7 @@ index fc80301..6a91089 100644 return programmer_table[programmer].shutdown(); } -@@ -245,6 +445,8 @@ int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len) +@@ -245,6 +448,8 @@ int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len) return 0; } @@ -12154,7 +13018,7 @@ index fc80301..6a91089 100644 int min(int a, int b) { return (a < b) ? a : b; -@@ -255,6 +457,15 @@ int max(int a, int b) +@@ -255,6 +460,15 @@ int max(int a, int b) return (a > b) ? a : b; } @@ -12170,7 +13034,7 @@ index fc80301..6a91089 100644 char *strcat_realloc(char *dest, const char *src) { dest = realloc(dest, strlen(dest) + strlen(src) + 1); -@@ -264,6 +475,60 @@ char *strcat_realloc(char *dest, const char *src) +@@ -264,6 +478,60 @@ char *strcat_realloc(char *dest, const char *src) return dest; } @@ -12231,7 +13095,7 @@ index fc80301..6a91089 100644 /* start is an offset to the base address of the flash chip */ int check_erased_range(struct flashchip *flash, int start, int len) { -@@ -281,7 +546,8 @@ int check_erased_range(struct flashchip *flash, int start, int len) +@@ -281,7 +549,8 @@ int check_erased_range(struct flashchip *flash, int start, int len) } /** @@ -12241,7 +13105,7 @@ index fc80301..6a91089 100644 * @start offset to the base address of the flash chip * @len length of the verified area * @message string to print in the "FAILED" message -@@ -354,10 +620,258 @@ out_free: +@@ -354,32 +623,286 @@ out_free: return ret; } @@ -12289,7 +13153,7 @@ index fc80301..6a91089 100644 + case write_gran_256bytes: + for (j = 0; j < len / 256; j++) { + limit = min (256, len - j * 256); -+ /* Are have and want identical? */ ++ /* Are 'have' and 'want' identical? */ + if (!memcmp(have + j * 256, want + j * 256, limit)) + continue; + /* have needs to be in erased state. */ @@ -12501,17 +13365,32 @@ index fc80301..6a91089 100644 char *tmp; for (flash = first_flash; flash && flash->name; flash++) { -@@ -369,7 +883,8 @@ struct flashchip *probe_flash(struct flashchip *first_flash, int force) - printf_debug("failed! flashrom has no probe function for this flash chip.\n"); + if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0) + continue; +- printf_debug("Probing for %s %s, %d KB: ", ++ msg_gdbg("Probing for %s %s, %d KB: ", + flash->vendor, flash->name, flash->total_size); + if (!flash->probe && !force) { +- printf_debug("failed! flashrom has no probe function for this flash chip.\n"); ++ msg_gdbg("failed! flashrom has no probe function for " ++ "this flash chip.\n"); continue; } - if (!(buses_supported & flash->bustype)) { + buses_common = buses_supported & flash->bustype; + if (!buses_common) { tmp = flashbuses_to_text(buses_supported); - printf_debug("skipped. Host bus type %s ", tmp); +- printf_debug("skipped. Host bus type %s ", tmp); ++ msg_gdbg("skipped."); ++ msg_gspew(" Host bus type %s ", tmp); free(tmp); -@@ -380,6 +895,7 @@ struct flashchip *probe_flash(struct flashchip *first_flash, int force) + tmp = flashbuses_to_text(flash->bustype); +- printf_debug("and chip bus type %s are incompatible.\n", tmp); ++ msg_gspew("and chip bus type %s are incompatible.", ++ tmp); + free(tmp); ++ msg_gdbg("\n"); + continue; } size = flash->total_size * 1024; @@ -12519,7 +13398,7 @@ index fc80301..6a91089 100644 base = flashbase ? flashbase : (0xffffffff - size + 1); flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size); -@@ -405,6 +921,9 @@ notfound: +@@ -405,6 +928,9 @@ notfound: flash->vendor, flash->name, flash->total_size, flashbuses_to_text(flash->bustype), base); @@ -12529,7 +13408,7 @@ index fc80301..6a91089 100644 return flash; } -@@ -434,7 +953,7 @@ int read_flash(struct flashchip *flash, char *filename) +@@ -434,7 +960,7 @@ int read_flash(struct flashchip *flash, char *filename) printf("Error: No filename specified.\n"); return 1; } @@ -12538,7 +13417,7 @@ index fc80301..6a91089 100644 perror(filename); exit(1); } -@@ -455,110 +974,158 @@ int read_flash(struct flashchip *flash, char *filename) +@@ -455,362 +981,231 @@ int read_flash(struct flashchip *flash, char *filename) return 0; } @@ -12596,7 +13475,7 @@ index fc80301..6a91089 100644 + * layouts. That would imply "magic" erase functions. The + * easiest way to check this is with function pointers. + */ -+ for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) ++ for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) { + if (eraser.block_erase == + flash->block_erasers[j].block_erase) { + msg_gerr("ERROR: Flash chip %s erase function " @@ -12605,6 +13484,7 @@ index fc80301..6a91089 100644 + flash->name, k, j); + ret = 1; + } ++ } + } + return ret; +} @@ -12780,11 +13660,47 @@ index fc80301..6a91089 100644 - "specified, then all that happens is that flash info is dumped.\n\n"); - exit(1); + printf("\n"); ++} ++ ++void print_sysinfo(void) ++{ ++#if HAVE_UTSNAME == 1 ++ struct utsname osinfo; ++ uname(&osinfo); ++ ++ msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release, ++ osinfo.machine); ++#else ++ msg_ginfo(" on unknown machine"); ++#endif ++ msg_ginfo(", built with"); ++#if NEED_PCI == 1 ++#ifdef PCILIB_VERSION ++ msg_ginfo(" libpci %s,", PCILIB_VERSION); ++#else ++ msg_ginfo(" unknown PCI library,"); ++#endif ++#endif ++#ifdef __clang__ ++ msg_ginfo(" LLVM %i/clang %i", __llvm__, __clang__); ++#elif defined(__GNUC__) ++ msg_ginfo(" GCC"); ++#ifdef __VERSION__ ++ msg_ginfo(" %s", __VERSION__); ++#else ++ msg_ginfo(" unknown version"); ++#endif ++#else ++ msg_ginfo(" unknown compiler"); ++#endif ++ msg_ginfo("\n"); } void print_version(void) -@@ -566,251 +1133,36 @@ void print_version(void) - printf("flashrom v%s\n", flashrom_version); + { +- printf("flashrom v%s\n", flashrom_version); ++ printf("flashrom v%s", flashrom_version); ++ print_sysinfo(); } -int main(int argc, char *argv[]) @@ -12853,7 +13769,8 @@ index fc80301..6a91089 100644 if (spi_programmer_count - 1 != SPI_CONTROLLER_INVALID) { fprintf(stderr, "SPI programmer table miscompilation!\n"); - exit(1); -- } ++ ret = 1; + } - - setbuf(stdout, NULL); - while ((opt = getopt_long(argc, argv, "rRwvnVEfc:m:l:i:p:Lzh", @@ -12995,8 +13912,7 @@ index fc80301..6a91089 100644 - if (programmer_init()) { - fprintf(stderr, "Error: Programmer initialization failed.\n"); - exit(1); -+ ret = 1; - } +- } - - myusec_calibrate_delay(); - @@ -13006,18 +13922,8 @@ index fc80301..6a91089 100644 - if (!flashes[i]) - for (i++; i < ARRAY_SIZE(flashes); i++) - flashes[i] = NULL; -+#if BITBANG_SPI_SUPPORT == 1 -+ if (bitbang_spi_master_count - 1 != BITBANG_SPI_INVALID) { -+ fprintf(stderr, "Bitbanging SPI master table miscompilation!\n"); -+ ret = 1; - } -+#endif -+ for (flash = flashchips; flash && flash->name; flash++) -+ if (selfcheck_eraseblocks(flash)) -+ ret = 1; -+ return ret; -+} - +- } +- - if (flashes[1]) { - printf("Multiple flash chips were detected:"); - for (i = 0; i < ARRAY_SIZE(flashes) && flashes[i]; i++) @@ -13046,8 +13952,18 @@ index fc80301..6a91089 100644 - } - // FIXME: flash writes stay enabled! - exit(1); -- } -- ++#if BITBANG_SPI_SUPPORT == 1 ++ if (bitbang_spi_master_count - 1 != BITBANG_SPI_INVALID) { ++ fprintf(stderr, "Bitbanging SPI master table miscompilation!\n"); ++ ret = 1; + } ++#endif ++ for (flash = flashchips; flash && flash->name; flash++) ++ if (selfcheck_eraseblocks(flash)) ++ ret = 1; ++ return ret; ++} + - flash = flashes[0]; - +void check_chip_supported(struct flashchip *flash) @@ -13055,7 +13971,7 @@ index fc80301..6a91089 100644 if (TEST_OK_MASK != (flash->tested & TEST_OK_MASK)) { printf("===\n"); if (flash->tested & TEST_BAD_MASK) { -@@ -840,29 +1192,32 @@ int main(int argc, char *argv[]) +@@ -840,29 +1235,32 @@ int main(int argc, char *argv[]) printf(" WRITE"); printf("\n"); } @@ -13072,7 +13988,7 @@ index fc80301..6a91089 100644 - printf("No operations were specified.\n"); - // FIXME: flash writes stay enabled! - exit(1); -+ "mainboard or programmer you tested. Thanks for your " ++ "mainboard or programmer you tested.\nThanks for your " + "help!\n===\n"); } +} @@ -13103,7 +14019,7 @@ index fc80301..6a91089 100644 size = flash->total_size * 1024; buf = (uint8_t *) calloc(size, sizeof(char)); -@@ -872,26 +1227,40 @@ int main(int argc, char *argv[]) +@@ -872,26 +1270,40 @@ int main(int argc, char *argv[]) fprintf(stderr, "Erase is not working on this chip. "); if (!force) { fprintf(stderr, "Aborting.\n"); @@ -13145,7 +14061,7 @@ index fc80301..6a91089 100644 return 1; } else { fprintf(stderr, "Continuing anyway.\n"); -@@ -901,29 +1270,36 @@ int main(int argc, char *argv[]) +@@ -901,29 +1313,36 @@ int main(int argc, char *argv[]) fprintf(stderr, "Write is not working on this chip. "); if (!force) { fprintf(stderr, "Aborting.\n"); @@ -13183,7 +14099,7 @@ index fc80301..6a91089 100644 return 1; } } -@@ -938,12 +1314,14 @@ int main(int argc, char *argv[]) +@@ -938,12 +1357,14 @@ int main(int argc, char *argv[]) printf("Writing flash chip... "); if (!flash->write) { fprintf(stderr, "Error: flashrom has no write function for this flash chip.\n"); @@ -13198,7 +14114,7 @@ index fc80301..6a91089 100644 return 1; } else { printf("COMPLETE.\n"); -@@ -955,7 +1333,7 @@ int main(int argc, char *argv[]) +@@ -955,7 +1376,7 @@ int main(int argc, char *argv[]) if (write_it) programmer_delay(1000*1000); ret = verify_flash(flash, buf); @@ -13650,10 +14566,10 @@ index 0000000..ec41279 +} diff --git a/hwaccess.c b/hwaccess.c new file mode 100644 -index 0000000..7f7b805 +index 0000000..36ea6f4 --- /dev/null +++ b/hwaccess.c -@@ -0,0 +1,83 @@ +@@ -0,0 +1,85 @@ +/* + * This file is part of the flashrom project. + * @@ -13692,7 +14608,9 @@ index 0000000..7f7b805 + if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) != 0) { +#elif defined(__FreeBSD__) || defined (__DragonFly__) + if ((io_fd = open("/dev/io", O_RDWR)) < 0) { -+#else ++#elif __DJGPP__ ++ if (0) { ++#else + if (iopl(3) != 0) { +#endif + fprintf(stderr, "ERROR: Could not get I/O privileges (%s).\n" @@ -13739,10 +14657,10 @@ index 0000000..7f7b805 +} diff --git a/hwaccess.h b/hwaccess.h new file mode 100644 -index 0000000..89469b0 +index 0000000..7a76925 --- /dev/null +++ b/hwaccess.h -@@ -0,0 +1,152 @@ +@@ -0,0 +1,165 @@ +/* + * This file is part of the flashrom project. + * @@ -13760,8 +14678,9 @@ index 0000000..89469b0 + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * ++ */ ++ ++/* + * Header file for hardware access and OS abstraction. Included from flash.h. + */ + @@ -13812,12 +14731,30 @@ index 0000000..89469b0 + #define INW inw + #define INL inl +#else ++ ++#ifdef __DJGPP__ ++ ++#include ++ ++ #define OUTB(x,y) outportb(y, x) ++ #define OUTW(x,y) outportw(y, x) ++ #define OUTL(x,y) outportl(y, x) ++ ++ #define INB inportb ++ #define INW inportw ++ #define INL inportl ++ ++#else ++ + #define OUTB outb + #define OUTW outw + #define OUTL outl + #define INB inb + #define INW inw + #define INL inl ++ ++#endif ++ +#endif +#endif + @@ -13834,42 +14771,36 @@ index 0000000..89469b0 + #endif + #include + -+static inline void -+outb(uint8_t value, uint16_t port) ++static inline void outb(uint8_t value, uint16_t port) +{ + asm volatile ("outb %b0,%w1": :"a" (value), "Nd" (port)); +} + -+static inline uint8_t -+inb(uint16_t port) ++static inline uint8_t inb(uint16_t port) +{ + uint8_t value; + asm volatile ("inb %w1,%0":"=a" (value):"Nd" (port)); + return value; +} + -+static inline void -+outw(uint16_t value, uint16_t port) ++static inline void outw(uint16_t value, uint16_t port) +{ + asm volatile ("outw %w0,%w1": :"a" (value), "Nd" (port)); +} + -+static inline uint16_t -+inw(uint16_t port) ++static inline uint16_t inw(uint16_t port) +{ + uint16_t value; + asm volatile ("inw %w1,%0":"=a" (value):"Nd" (port)); + return value; +} + -+static inline void -+outl(uint32_t value, uint16_t port) ++static inline void outl(uint32_t value, uint16_t port) +{ + asm volatile ("outl %0,%w1": :"a" (value), "Nd" (port)); +} + -+static inline uint32_t -+inl(uint16_t port) ++static inline uint32_t inl(uint16_t port) +{ + uint32_t value; + asm volatile ("inl %1,%0":"=a" (value):"Nd" (port)); @@ -13896,7 +14827,7 @@ index 0000000..89469b0 + +#endif /* !__HWACCESS_H__ */ diff --git a/ichspi.c b/ichspi.c -index 831dd9d..9ab61ff 100644 +index 831dd9d..35b9dbd 100644 --- a/ichspi.c +++ b/ichspi.c @@ -5,6 +5,7 @@ @@ -14070,6 +15001,15 @@ index 831dd9d..9ab61ff 100644 } /* Start */ +@@ -521,7 +536,7 @@ static int ich9_run_opcode(OPCODE op, uint32_t offset, + + /* clear error status registers */ + temp32 |= (SSFS_CDS + SSFS_FCERR); +- /* USE 20 MhZ */ ++ /* Use 20 MHz */ + temp32 |= SSFC_SCF_20MHZ; + + if (datalength != 0) { @@ -548,14 +563,15 @@ static int ich9_run_opcode(OPCODE op, uint32_t offset, temp32 |= ((uint32_t) (opcode_index & 0x07)) << (8 + 4); @@ -14324,7 +15264,7 @@ index 831dd9d..9ab61ff 100644 return ret; } diff --git a/internal.c b/internal.c -index a3b2ae5..0afed72 100644 +index a3b2ae5..39edd10 100644 --- a/internal.c +++ b/internal.c @@ -27,10 +27,7 @@ @@ -14366,7 +15306,7 @@ index a3b2ae5..0afed72 100644 struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device) { struct pci_dev *temp; -@@ -79,33 +96,46 @@ struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device, +@@ -79,33 +96,47 @@ struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device, return NULL; } @@ -14396,7 +15336,8 @@ index a3b2ae5..0afed72 100644 -#if defined(__FreeBSD__) || defined(__DragonFly__) - close(io_fd); + superio = probe_superio_ite(); -+#if 0 /* Winbond SuperI/O code is not yet available. */ ++#if 0 ++ /* Winbond Super I/O code is not yet available. */ + if (superio.vendor == SUPERIO_VENDOR_NONE) + superio = probe_superio_winbond(); #endif @@ -14430,28 +15371,38 @@ index a3b2ae5..0afed72 100644 get_io_perms(); /* Initialize PCI access for flash enables */ -@@ -118,6 +148,20 @@ int internal_init(void) +@@ -118,6 +149,20 @@ int internal_init(void) * mainboard specific flash enable sequence. */ coreboot_init(); + dmi_init(); + -+ /* Probe for the SuperI/O chip and fill global struct superio. */ ++ /* Probe for the Super I/O chip and fill global struct superio. */ + probe_superio(); + -+ /* Warn if a laptop is detected */ ++ /* Warn if a laptop is detected. */ + if (is_laptop) + printf("========================================================================\n" + "WARNING! You seem to be running flashrom on a laptop.\n" + "Laptops, notebooks and netbooks are difficult to support and we recommend\n" + "to use the vendor flashing utility. The embedded controller (EC) in these\n" -+ "machines often interacts badly with flashing\n" -+ "See http://www.flashrom.org/Laptops\n" ++ "machines often interacts badly with flashing.\n" ++ "See http://www.flashrom.org/Laptops for details.\n" + "========================================================================\n"); /* try to enable it. Failure IS an option, since not all motherboards * really need this to be done, etc., etc. -@@ -143,6 +187,7 @@ int internal_shutdown(void) +@@ -128,6 +173,9 @@ int internal_init(void) + "will most likely fail.\n"); + } + ++ /* Probe for IT87* LPC->SPI translation unconditionally. */ ++ it87xx_probe_spi_flash(NULL); ++ + board_flash_enable(lb_vendor, lb_part); + + /* Even if chipset init returns an error code, we don't want to abort. +@@ -143,6 +191,7 @@ int internal_shutdown(void) return 0; } @@ -14459,7 +15410,7 @@ index a3b2ae5..0afed72 100644 void internal_chip_writeb(uint8_t val, chipaddr addr) { -@@ -179,115 +224,3 @@ void internal_chip_readn(uint8_t *buf, const chipaddr addr, size_t len) +@@ -179,115 +228,3 @@ void internal_chip_readn(uint8_t *buf, const chipaddr addr, size_t len) memcpy(buf, (void *)addr, len); return; } @@ -14576,7 +15527,7 @@ index a3b2ae5..0afed72 100644 - return; -} diff --git a/it87spi.c b/it87spi.c -index 299725c..ed72c90 100644 +index 299725c..0ee7d12 100644 --- a/it87spi.c +++ b/it87spi.c @@ -26,6 +26,7 @@ @@ -14587,7 +15538,7 @@ index 299725c..ed72c90 100644 #include "spi.h" #define ITE_SUPERIO_PORT1 0x2e -@@ -54,46 +55,82 @@ void exit_conf_mode_ite(uint16_t port) +@@ -54,68 +55,122 @@ void exit_conf_mode_ite(uint16_t port) sio_write(port, 0x02, 0x02); } @@ -14624,7 +15575,7 @@ index 299725c..ed72c90 100644 + case 0x82: + case 0x86: + case 0x87: -+ msg_pinfo("Found ITE SuperI/O, id %04hx\n", ++ msg_pinfo("Found ITE Super I/O, id %04hx\n", + ret.model); + return ret; + } @@ -14646,10 +15597,19 @@ index 299725c..ed72c90 100644 + switch (id) { + case 0x8716: + case 0x8718: ++ case 0x8720: + enter_conf_mode_ite(port); /* NOLDN, reg 0x24, mask out lowest bit (suspend) */ tmp = sio_read(port, 0x24) & 0xFE; - printf("Serial flash segment 0x%08x-0x%08x %sabled\n", ++ /* If IT87SPI was not explicitly selected, we want to check ++ * quickly if LPC->SPI translation is active. ++ */ ++ if ((programmer == PROGRAMMER_INTERNAL) && !(tmp & (0x0E))) { ++ msg_pdbg("No IT87* serial flash segment enabled.\n"); ++ exit_conf_mode_ite(port); ++ break; ++ } + msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n", 0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis"); - printf("Serial flash segment 0x%08x-0x%08x %sabled\n", @@ -14685,20 +15645,30 @@ index 299725c..ed72c90 100644 if (programmer_param && !strlen(programmer_param)) { free(programmer_param); programmer_param = NULL; -@@ -101,21 +138,25 @@ static uint16_t find_ite_spi_flash_port(uint16_t port) - if (programmer_param && (portpos = strstr(programmer_param, "port="))) { - portpos += 5; - flashport = strtol(portpos, (char **)NULL, 0); + } +- if (programmer_param && (portpos = strstr(programmer_param, "port="))) { +- portpos += 5; +- flashport = strtol(portpos, (char **)NULL, 0); - printf("Forcing serial flash port 0x%04x\n", flashport); -+ msg_pinfo("Forcing serial flash port 0x%04x\n", flashport); - sio_write(port, 0x64, (flashport >> 8)); - sio_write(port, 0x65, (flashport & 0xff)); +- sio_write(port, 0x64, (flashport >> 8)); +- sio_write(port, 0x65, (flashport & 0xff)); ++ if (programmer_param) { ++ portpos = extract_param(&programmer_param, ++ "it87spiport=", ",:"); ++ if (portpos) { ++ flashport = strtol(portpos, (char **)NULL, 0); ++ msg_pinfo("Forcing serial flash port 0x%04x\n", ++ flashport); ++ sio_write(port, 0x64, (flashport >> 8)); ++ sio_write(port, 0x65, (flashport & 0xff)); ++ free(portpos); ++ } } + exit_conf_mode_ite(port); + break; + /* TODO: Handle more IT87xx if they support flash translation */ + default: -+ msg_pinfo("SuperI/O ID %04hx is not on the controller list.\n", id); ++ msg_pdbg("SuperI/O ID %04hx is not on the controller list.\n", id); } - exit_conf_mode_ite(port); return flashport; @@ -14716,16 +15686,29 @@ index 299725c..ed72c90 100644 if (it8716f_flashport) spi_controller = SPI_CONTROLLER_IT87XX; -@@ -129,6 +170,8 @@ int it87spi_init(void) +@@ -129,6 +184,8 @@ int it87spi_init(void) int ret; get_io_perms(); -+ /* Probe for the SuperI/O chip and fill global struct superio. */ ++ /* Probe for the Super I/O chip and fill global struct superio. */ + probe_superio(); ret = it87spi_common_init(); if (!ret) { buses_supported = CHIP_BUSTYPE_SPI; -@@ -167,8 +210,8 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt, +@@ -143,8 +200,11 @@ int it87xx_probe_spi_flash(const char *name) + int ret; + + ret = it87spi_common_init(); +- if (!ret) ++ if (!ret) { ++ if (buses_supported & CHIP_BUSTYPE_SPI) ++ msg_pdbg("Overriding chipset SPI with IT87 SPI.\n"); + buses_supported |= CHIP_BUSTYPE_SPI; ++ } + return ret; + } + +@@ -167,8 +227,8 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt, busy = INB(it8716f_flashport) & 0x80; } while (busy); if (readcnt > 3) { @@ -14736,7 +15719,7 @@ index 299725c..ed72c90 100644 return SPI_INVALID_LENGTH; } switch (writecnt) { -@@ -197,8 +240,8 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt, +@@ -197,8 +257,8 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt, writeenc = 0x3; break; default: @@ -14747,7 +15730,7 @@ index 299725c..ed72c90 100644 return SPI_INVALID_LENGTH; } /* -@@ -278,12 +321,12 @@ int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf) +@@ -278,12 +338,12 @@ int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf) } else { spi_disable_blockprotect(); /* Erase first */ @@ -14765,7 +15748,7 @@ index 299725c..ed72c90 100644 it8716f_spi_page_program(flash, i, buf); } diff --git a/jedec.c b/jedec.c -index 0e426d6..fee7302 100644 +index 0e426d6..30c343f 100644 --- a/jedec.c +++ b/jedec.c @@ -5,6 +5,7 @@ @@ -14811,7 +15794,7 @@ index 0e426d6..fee7302 100644 tmp1 = tmp2; } + if (i > 0x100000) -+ printf_debug("%s: excessive loops, i=0x%x\n", __func__, i); ++ msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i); +} + +void toggle_ready_jedec(chipaddr dst) @@ -14837,12 +15820,11 @@ index 0e426d6..fee7302 100644 } } + if (i > 0x100000) -+ printf_debug("%s: excessive loops, i=0x%x\n", __func__, i); ++ msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i); } -void unprotect_jedec(chipaddr bios) -+void start_program_jedec_common(struct flashchip *flash, unsigned int mask) - { +-{ - chip_writeb(0xAA, bios + 0x5555); - chip_writeb(0x55, bios + 0x2AAA); - chip_writeb(0x80, bios + 0x5555); @@ -14854,7 +15836,8 @@ index 0e426d6..fee7302 100644 -} - -void protect_jedec(chipaddr bios) --{ ++void start_program_jedec_common(struct flashchip *flash, unsigned int mask) + { - chip_writeb(0xAA, bios + 0x5555); - chip_writeb(0x55, bios + 0x2AAA); - chip_writeb(0xA0, bios + 0x5555); @@ -14871,7 +15854,20 @@ index 0e426d6..fee7302 100644 { chipaddr bios = flash->virtual_memory; uint8_t id1, id2; -@@ -109,15 +124,15 @@ int probe_jedec(struct flashchip *flash) +@@ -98,26 +113,26 @@ int probe_jedec(struct flashchip *flash) + else if (flash->probe_timing == TIMING_ZERO) { /* No delay. */ + probe_timing_enter = probe_timing_exit = 0; + } else if (flash->probe_timing == TIMING_FIXME) { /* == _IGNORED */ +- printf_debug("Chip lacks correct probe timing information, " ++ msg_cdbg("Chip lacks correct probe timing information, " + "using default 10mS/40uS. "); + probe_timing_enter = 10000; + probe_timing_exit = 40; + } else { +- printf("Chip has negative value in probe_timing, failing " ++ msg_cerr("Chip has negative value in probe_timing, failing " + "without chip access\n"); + return 0; } /* Issue JEDEC Product ID Entry command */ @@ -14896,7 +15892,7 @@ index 0e426d6..fee7302 100644 /* Read product ID */ id1 = chip_readb(bios); -@@ -138,14 +153,20 @@ int probe_jedec(struct flashchip *flash) +@@ -138,16 +153,22 @@ int probe_jedec(struct flashchip *flash) } /* Issue JEDEC Product ID Exit command */ @@ -14920,23 +15916,34 @@ index 0e426d6..fee7302 100644 + programmer_delay(probe_timing_exit); - printf_debug("%s: id1 0x%02x, id2 0x%02x", __FUNCTION__, largeid1, largeid2); -+ printf_debug("%s: id1 0x%02x, id2 0x%02x", __func__, largeid1, largeid2); ++ msg_cdbg("%s: id1 0x%02x, id2 0x%02x", __func__, largeid1, largeid2); if (!oddparity(id1)) - printf_debug(", id1 parity violation"); +- printf_debug(", id1 parity violation"); ++ msg_cdbg(", id1 parity violation"); -@@ -169,33 +190,37 @@ int probe_jedec(struct flashchip *flash) - printf_debug(", id2 is normal flash content"); + /* Read the product ID location again. We should now see normal flash contents. */ + flashcontent1 = chip_readb(bios); +@@ -164,121 +185,171 @@ int probe_jedec(struct flashchip *flash) + } - printf_debug("\n"); -- if (largeid1 == flash->manufacture_id && largeid2 == flash->model_id) -- return 1; + if (largeid1 == flashcontent1) +- printf_debug(", id1 is normal flash content"); ++ msg_cdbg(", id1 is normal flash content"); + if (largeid2 == flashcontent2) +- printf_debug(", id2 is normal flash content"); ++ msg_cdbg(", id2 is normal flash content"); ++ ++ msg_cdbg("\n"); + if (largeid1 != flash->manufacture_id || largeid2 != flash->model_id) + return 0; -- return 0; +- printf_debug("\n"); +- if (largeid1 == flash->manufacture_id && largeid2 == flash->model_id) +- return 1; + if (flash->feature_bits & FEATURE_REGISTERMAP) + map_flash_registers(flash); -+ + +- return 0; + return 1; } @@ -14971,8 +15978,10 @@ index 0e426d6..fee7302 100644 + toggle_ready_jedec_slow(bios); if (check_erased_range(flash, page, pagesize)) { - fprintf(stderr,"ERASE FAILED!\n"); -@@ -204,27 +229,28 @@ int erase_sector_jedec(struct flashchip *flash, unsigned int page, int pagesize) +- fprintf(stderr,"ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } return 0; } @@ -15007,8 +16016,10 @@ index 0e426d6..fee7302 100644 + toggle_ready_jedec_slow(bios); if (check_erased_range(flash, block, blocksize)) { - fprintf(stderr,"ERASE FAILED!\n"); -@@ -233,27 +259,27 @@ int erase_block_jedec(struct flashchip *flash, unsigned int block, int blocksize +- fprintf(stderr,"ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } return 0; } @@ -15043,8 +16054,10 @@ index 0e426d6..fee7302 100644 + toggle_ready_jedec_slow(bios); if (check_erased_range(flash, 0, total_size)) { - fprintf(stderr,"ERASE FAILED!\n"); -@@ -262,23 +288,68 @@ int erase_chip_jedec(struct flashchip *flash) +- fprintf(stderr,"ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } return 0; } @@ -15093,7 +16106,7 @@ index 0e426d6..fee7302 100644 + dst++, src++; + } + if (failed) -+ fprintf(stderr, " writing sector at 0x%lx failed!\n", olddst); ++ msg_cerr(" writing sector at 0x%lx failed!\n", olddst); + + return failed; +} @@ -15112,7 +16125,7 @@ index 0e426d6..fee7302 100644 - chip_writeb(0xAA, bios + 0x5555); - chip_writeb(0x55, bios + 0x2AAA); - chip_writeb(0xA0, bios + 0x5555); -+ /* Issue JEDEC Start Program comand */ ++ /* Issue JEDEC Start Program command */ + start_program_jedec_common(flash, mask); /* transfer data from source to destination */ @@ -15121,7 +16134,7 @@ index 0e426d6..fee7302 100644 /* If the data is 0xFF, don't program it */ if (*src != 0xFF) chip_writeb(*src, dst); -@@ -290,68 +361,46 @@ retry: +@@ -290,83 +361,138 @@ retry: dst = d; src = s; @@ -15131,57 +16144,28 @@ index 0e426d6..fee7302 100644 - if (!ok && tried++ < MAX_REFLASH_TRIES) { - start_index = i; + if (failed && tried++ < MAX_REFLASH_TRIES) { -+ fprintf(stderr, "retrying.\n"); ++ msg_cerr("retrying.\n"); goto retry; } - if (!ok) { +- fprintf(stderr, " page 0x%lx failed!\n", + if (failed) { - fprintf(stderr, " page 0x%lx failed!\n", ++ msg_cerr(" page 0x%lx failed!\n", (d - bios) / page_size); } - return !ok; --} -- ++ return failed; + } + -int write_byte_program_jedec(chipaddr bios, uint8_t *src, - chipaddr dst) --{ ++int getaddrmask(struct flashchip *flash) + { - int tried = 0, ok = 1; - - /* If the data is 0xFF, don't program it */ - if (*src == 0xFF) { - return -1; -- } -- --retry: -- /* Issue JEDEC Byte Program command */ -- chip_writeb(0xAA, bios + 0x5555); -- chip_writeb(0x55, bios + 0x2AAA); -- chip_writeb(0xA0, bios + 0x5555); -- -- /* transfer data from source to destination */ -- chip_writeb(*src, dst); -- toggle_ready_jedec(bios); -- -- if (chip_readb(dst) != *src && tried++ < MAX_REFLASH_TRIES) { -- goto retry; -- } -- -- if (tried >= MAX_REFLASH_TRIES) -- ok = 0; -- -- return !ok; -+ return failed; - } - --int write_sector_jedec(chipaddr bios, uint8_t *src, -- chipaddr dst, unsigned int page_size) -+int getaddrmask(struct flashchip *flash) - { -- int i; -- -- for (i = 0; i < page_size; i++) { -- write_byte_program_jedec(bios, src, dst); -- dst++, src++; + switch (flash->feature_bits & FEATURE_ADDR_MASK) { + case FEATURE_ADDR_FULL: + return MASK_FULL; @@ -15193,89 +16177,121 @@ index 0e426d6..fee7302 100644 + return MASK_AAA; + break; + default: -+ fprintf(stderr, "%s called with unknown mask\n", __func__); ++ msg_cerr("%s called with unknown mask\n", __func__); + return 0; + break; } -- -- return 0; - } ++} - int write_jedec(struct flashchip *flash, uint8_t *buf) - { -- int i; +-retry: +- /* Issue JEDEC Byte Program command */ +- chip_writeb(0xAA, bios + 0x5555); +- chip_writeb(0x55, bios + 0x2AAA); +- chip_writeb(0xA0, bios + 0x5555); ++int write_jedec(struct flashchip *flash, uint8_t *buf) ++{ + int mask; + int i, failed = 0; - int total_size = flash->total_size * 1024; - int page_size = flash->page_size; -- chipaddr bios = flash->virtual_memory; -+ ++ int total_size = flash->total_size * 1024; ++ int page_size = flash->page_size; + +- /* transfer data from source to destination */ +- chip_writeb(*src, dst); +- toggle_ready_jedec(bios); + mask = getaddrmask(flash); - if (erase_chip_jedec(flash)) { - fprintf(stderr,"ERASE FAILED!\n"); -@@ -361,12 +410,89 @@ int write_jedec(struct flashchip *flash, uint8_t *buf) - printf("Programming page: "); - for (i = 0; i < total_size / page_size; i++) { - printf("%04d at address: 0x%08x", i, i * page_size); -- write_page_write_jedec(flash, buf + i * page_size, -- i * page_size, page_size); +- if (chip_readb(dst) != *src && tried++ < MAX_REFLASH_TRIES) { +- goto retry; ++ if (erase_chip_jedec(flash)) { ++ msg_cerr("ERASE FAILED!\n"); ++ return -1; + } ++ ++ msg_cinfo("Programming page: "); ++ for (i = 0; i < total_size / page_size; i++) { ++ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); + if (write_page_write_jedec_common(flash, buf + i * page_size, + i * page_size, page_size, mask)) + failed = 1; - printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); - } - printf("\n"); -- protect_jedec(bios); ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ } ++ msg_cinfo("DONE!\n"); +- if (tried >= MAX_REFLASH_TRIES) +- ok = 0; +- +- return !ok; + return failed; -+} -+ + } + +-int write_sector_jedec(chipaddr bios, uint8_t *src, +- chipaddr dst, unsigned int page_size) +int write_jedec_1(struct flashchip *flash, uint8_t * buf) -+{ -+ int i; + { + int i; + chipaddr bios = flash->virtual_memory; + chipaddr dst = bios; + int mask; -+ + +- for (i = 0; i < page_size; i++) { +- write_byte_program_jedec(bios, src, dst); +- dst++, src++; + mask = getaddrmask(flash); + + programmer_delay(10); + if (erase_flash(flash)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; -+ } -+ -+ printf("Programming page: "); + } + ++ msg_cinfo("Programming page: "); + for (i = 0; i < flash->total_size; i++) { + if ((i & 0x3) == 0) -+ printf("address: 0x%08lx", (unsigned long)i * 1024); ++ msg_cinfo("address: 0x%08lx", (unsigned long)i * 1024); + + write_sector_jedec_common(flash, buf + i * 1024, dst + i * 1024, 1024, mask); + + if ((i & 0x3) == 0) -+ printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); + } + -+ printf("\n"); ++ msg_cinfo("DONE!\n"); return 0; } -+ + +-int write_jedec(struct flashchip *flash, uint8_t *buf) +/* erase chip with block_erase() prototype */ +int erase_chip_block_jedec(struct flashchip *flash, unsigned int addr, + unsigned int blocksize) -+{ + { +- int i; +- int total_size = flash->total_size * 1024; +- int page_size = flash->page_size; +- chipaddr bios = flash->virtual_memory; + int mask; -+ + +- if (erase_chip_jedec(flash)) { +- fprintf(stderr,"ERASE FAILED!\n"); + mask = getaddrmask(flash); + if ((addr != 0) || (blocksize != flash->total_size * 1024)) { -+ fprintf(stderr, "%s called with incorrect arguments\n", ++ msg_cerr("%s called with incorrect arguments\n", + __func__); -+ return -1; -+ } + return -1; + } +- +- printf("Programming page: "); +- for (i = 0; i < total_size / page_size; i++) { +- printf("%04d at address: 0x%08x", i, i * page_size); +- write_page_write_jedec(flash, buf + i * page_size, +- i * page_size, page_size); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- } +- printf("\n"); +- protect_jedec(bios); + return erase_chip_jedec_common(flash, mask); +} -+ + +- return 0; +int probe_jedec(struct flashchip *flash) +{ + int mask; @@ -15306,7 +16322,7 @@ index 0e426d6..fee7302 100644 + + mask = getaddrmask(flash); + return erase_chip_jedec_common(flash, mask); -+} + } diff --git a/layout.c b/layout.c index c432ebe..26b7c6a 100644 --- a/layout.c @@ -15471,7 +16487,7 @@ index 00cbbc1..0000000 - return 0; -} diff --git a/m29f400bt.c b/m29f400bt.c -index ace6dae..c394074 100644 +index ace6dae..c8ed5d8 100644 --- a/m29f400bt.c +++ b/m29f400bt.c @@ -19,15 +19,13 @@ @@ -15496,16 +16512,33 @@ index ace6dae..c394074 100644 void write_page_m29f400bt(chipaddr bios, uint8_t *src, chipaddr dst, int page_size) -@@ -75,7 +73,7 @@ int probe_m29f400bt(struct flashchip *flash) +@@ -44,8 +42,7 @@ void write_page_m29f400bt(chipaddr bios, uint8_t *src, + //chip_writeb(0xF0, bios); + //programmer_delay(5); + toggle_ready_jedec(dst); +- printf +- ("Value in the flash at address 0x%lx = %#x, want %#x\n", ++ msg_cerr("Value in the flash at address 0x%lx = %#x, want %#x\n", + (dst - bios), chip_readb(dst), *src); + dst++; + src++; +@@ -75,7 +72,7 @@ int probe_m29f400bt(struct flashchip *flash) programmer_delay(10); - printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2); -+ printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); ++ msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); if (id1 == flash->manufacture_id && id2 == flash->model_id) return 1; -@@ -105,7 +103,7 @@ int erase_m29f400bt(struct flashchip *flash) +@@ -99,13 +96,13 @@ int erase_m29f400bt(struct flashchip *flash) + toggle_ready_jedec(bios); + + if (check_erased_range(flash, 0, flash->total_size * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } return 0; } @@ -15514,14 +16547,21 @@ index ace6dae..c394074 100644 { chipaddr bios = flash->virtual_memory; chipaddr dst = bios + start; -@@ -129,6 +127,16 @@ int block_erase_m29f400bt(struct flashchip *flash, int start, int len) +@@ -123,12 +120,22 @@ int block_erase_m29f400bt(struct flashchip *flash, int start, int len) + toggle_ready_jedec(bios); + + if (check_erased_range(flash, start, len)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } return 0; } +int block_erase_chip_m29f400bt(struct flashchip *flash, unsigned int address, unsigned int blocklen) +{ + if ((address != 0) || (blocklen != flash->total_size * 1024)) { -+ fprintf(stderr, "%s called with incorrect arguments\n", ++ msg_cerr("%s called with incorrect arguments\n", + __func__); + return -1; + } @@ -15531,19 +16571,129 @@ index ace6dae..c394074 100644 int write_m29f400bt(struct flashchip *flash, uint8_t *buf) { int i; -@@ -194,7 +202,6 @@ int write_m29f400bt(struct flashchip *flash, uint8_t *buf) +@@ -137,7 +144,7 @@ int write_m29f400bt(struct flashchip *flash, uint8_t *buf) + chipaddr bios = flash->virtual_memory; + + //erase_m29f400bt (flash); +- printf("Programming page:\n "); ++ msg_cinfo("Programming page:\n "); + /********************************* + *Pages for M29F400BT: + * 16 0x7c000 0x7ffff TOP +@@ -153,48 +160,47 @@ int write_m29f400bt(struct flashchip *flash, uint8_t *buf) + * 64 0x10000 0x1ffff + * 64 0x00000 0x0ffff BOTTOM + *********************************/ +- printf("total_size/page_size = %d\n", total_size / page_size); ++ msg_cinfo("total_size/page_size = %d\n", total_size / page_size); + for (i = 0; i < (total_size / page_size) - 1; i++) { +- printf("%04d at address: 0x%08x\n", i, i * page_size); ++ msg_cinfo("%04d at address: 0x%08x\n", i, i * page_size); + if (block_erase_m29f400bt(flash, i * page_size, page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + write_page_m29f400bt(bios, buf + i * page_size, + bios + i * page_size, page_size); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); + } + +- printf("%04d at address: 0x%08x\n", 7, 0x70000); ++ msg_cinfo("%04d at address: 0x%08x\n", 7, 0x70000); + if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024); + +- printf("%04d at address: 0x%08x\n", 8, 0x78000); ++ msg_cinfo("%04d at address: 0x%08x\n", 8, 0x78000); + if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024); + +- printf("%04d at address: 0x%08x\n", 9, 0x7a000); ++ msg_cinfo("%04d at address: 0x%08x\n", 9, 0x7a000); + if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024); + +- printf("%04d at address: 0x%08x\n", 10, 0x7c000); ++ msg_cinfo("%04d at address: 0x%08x\n", 10, 0x7c000); + if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024); - printf("\n"); +- printf("\n"); - //protect_m29f400bt (bios); ++ msg_cinfo("\n"); return 0; } -@@ -248,7 +255,6 @@ int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf) +@@ -203,7 +209,7 @@ int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf) + { + chipaddr bios = flash->virtual_memory; + +- printf("Programming page:\n "); ++ msg_cinfo("Programming page:\n "); + /********************************* + *Pages for M29F400BT: + * 16 0x7c000 0x7ffff TOP +@@ -219,36 +225,35 @@ int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf) + * 64 0x10000 0x1ffff + * 64 0x00000 0x0ffff BOTTOM + *********************************/ +- printf("%04d at address: 0x%08x\n", 7, 0x00000); ++ msg_cinfo("%04d at address: 0x%08x\n", 7, 0x00000); + if (block_erase_m29f400bt(flash, 0x00000, 64 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024); + +- printf("%04d at address: 0x%08x\n", 7, 0x10000); ++ msg_cinfo("%04d at address: 0x%08x\n", 7, 0x10000); + if (block_erase_m29f400bt(flash, 0x10000, 64 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024); + +- printf("%04d at address: 0x%08x\n", 7, 0x20000); ++ msg_cinfo("%04d at address: 0x%08x\n", 7, 0x20000); + if (block_erase_m29f400bt(flash, 0x20000, 64 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024); + +- printf("%04d at address: 0x%08x\n", 7, 0x30000); ++ msg_cinfo("%04d at address: 0x%08x\n", 7, 0x30000); + if (block_erase_m29f400bt(flash, 0x30000, 64 * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024); - printf("\n"); +- printf("\n"); - //protect_m29f400bt (bios); ++ msg_cinfo("\n"); return 0; } @@ -15699,10 +16849,10 @@ index 075e760..d3dcce5 100644 /* 3COM 3C90xB cards need a special fixup. */ diff --git a/pcidev.c b/pcidev.c -index 580ebae..fcb04e6 100644 +index 580ebae..818819a 100644 --- a/pcidev.c +++ b/pcidev.c -@@ -28,7 +28,8 @@ struct pci_access *pacc; +@@ -28,23 +28,44 @@ struct pci_access *pacc; struct pci_filter filter; struct pci_dev *pcidev_dev = NULL; @@ -15711,8 +16861,10 @@ index 580ebae..fcb04e6 100644 + struct pcidev_status *devs) { int i; ++ /* FIXME: 64 bit memory BARs need a 64 bit addr. */ uint32_t addr; -@@ -37,14 +38,18 @@ uint32_t pcidev_validate(struct pci_dev *dev, struct pcidev_status *devs) + + for (i = 0; devs[i].device_name != NULL; i++) { if (dev->device_id != devs[i].device_id) continue; @@ -15723,7 +16875,7 @@ index 580ebae..fcb04e6 100644 + * Don't use dev->base_addr[x] (as value for 'bar'), won't + * work on older libpci. + */ -+ addr = pci_read_long(dev, bar) & ~0x03; ++ addr = pci_read_long(dev, bar); + printf("Found \"%s %s\" (%04x:%04x, BDF %02x:%02x.%x).\n", - devs[i].vendor_name, devs[i].device_name, dev->vendor_id, @@ -15731,13 +16883,28 @@ index 580ebae..fcb04e6 100644 + devs[i].vendor_name, devs[i].device_name, + dev->vendor_id, dev->device_id, dev->bus, dev->dev, + dev->func); ++ msg_pdbg("Requested BAR is %s", (addr & 0x1) ? "IO" : "MEM"); ++ if (addr & 0x1) { ++ /* Mask off IO space indicator and reserved bit. */ ++ msg_pdbg("\n"); ++ addr &= ~0x3; ++ } else { ++ msg_pdbg(", %sbit, %sprefetchable\n", ++ ((addr & 0x6) == 0x0) ? "32" : ++ (((addr & 0x6) == 0x4) ? "64" : "reserved"), ++ (addr & 0x8) ? "" : "not "); ++ /* Mask off Mem space indicator, 32/64bit type indicator ++ * and Prefetchable indicator. ++ */ ++ addr &= ~0xf; ++ } - if (devs[i].status == PCI_NT) { + if (devs[i].status == NT) { printf("===\nThis PCI device is UNTESTED. Please " "report the 'flashrom -p xxxx' output \n" "to flashrom@flashrom.org if it works " -@@ -57,7 +62,8 @@ uint32_t pcidev_validate(struct pci_dev *dev, struct pcidev_status *devs) +@@ -57,7 +78,8 @@ uint32_t pcidev_validate(struct pci_dev *dev, struct pcidev_status *devs) return 0; } @@ -15747,7 +16914,7 @@ index 580ebae..fcb04e6 100644 { struct pci_dev *dev; char *msg = NULL; -@@ -80,7 +86,7 @@ uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs, char *pcide +@@ -80,7 +102,7 @@ uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs, char *pcide for (dev = pacc->devices; dev; dev = dev->next) { if (pci_filter_match(&filter, dev)) { @@ -15756,7 +16923,7 @@ index 580ebae..fcb04e6 100644 curaddr = addr; pcidev_dev = dev; found++; -@@ -94,7 +100,7 @@ uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs, char *pcide +@@ -94,7 +116,7 @@ uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs, char *pcide exit(1); } else if (found > 1) { fprintf(stderr, "Error: Multiple supported PCI devices found. " @@ -15765,7 +16932,7 @@ index 580ebae..fcb04e6 100644 "to explicitly select the card with the given BDF " "(PCI bus, device, function).\n"); exit(1); -@@ -111,6 +117,6 @@ void print_supported_pcidevs(struct pcidev_status *devs) +@@ -111,6 +133,6 @@ void print_supported_pcidevs(struct pcidev_status *devs) printf("%s %s [%02x:%02x]%s\n", devs[i].vendor_name, devs[i].device_name, devs[i].vendor_id, devs[i].device_id, @@ -15774,18 +16941,99 @@ index 580ebae..fcb04e6 100644 } } diff --git a/physmap.c b/physmap.c -index 778a783..fba7a53 100644 +index 778a783..0e3ce60 100644 --- a/physmap.c +++ b/physmap.c -@@ -3,6 +3,7 @@ +@@ -3,6 +3,8 @@ * * Copyright (C) 2009 Peter Stuge * Copyright (C) 2009 coresystems GmbH + * Copyright (C) 2010 Carl-Daniel Hailfinger ++ * Copyright (C) 2010 Rudolf Marek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -@@ -36,6 +37,10 @@ void *sys_physmap(unsigned long phys_addr, size_t len) +@@ -26,7 +28,78 @@ + #include + #include "flash.h" + +-#ifdef __DARWIN__ ++#ifdef __DJGPP__ ++#include ++#include ++ ++#define MEM_DEV "dpmi" ++ ++static void *realmem_map; ++ ++static void *map_first_meg(unsigned long phys_addr, size_t len) ++{ ++ ++ if (realmem_map) { ++ return realmem_map + phys_addr; ++ } ++ ++ realmem_map = valloc(1024 * 1024); ++ ++ if (!realmem_map) { ++ return NULL; ++ } ++ ++ if (__djgpp_map_physical_memory(realmem_map, (1024 * 1024), 0)) { ++ return NULL; ++ } ++ ++ return realmem_map + phys_addr; ++} ++ ++void *sys_physmap(unsigned long phys_addr, size_t len) ++{ ++ int ret; ++ __dpmi_meminfo mi; ++ ++ /* enable 4GB limit on DS descriptor */ ++ if (!__djgpp_nearptr_enable()) { ++ return NULL; ++ } ++ ++ if ((phys_addr + len - 1) < (1024 * 1024)) { ++ /* we need to use another method to map first 1MB */ ++ return map_first_meg(phys_addr, len); ++ } ++ ++ mi.address = phys_addr; ++ mi.size = len; ++ ret = __dpmi_physical_address_mapping (&mi); ++ ++ if (ret != 0) { ++ return NULL; ++ } ++ ++ return (void *) mi.address + __djgpp_conventional_base; ++} ++ ++#define sys_physmap_rw_uncached sys_physmap ++#define sys_physmap_ro_cached sys_physmap ++ ++void physunmap(void *virt_addr, size_t len) ++{ ++ __dpmi_meminfo mi; ++ ++ /* we ignore unmaps for our first 1MB */ ++ if ((virt_addr >= realmem_map) && ((virt_addr + len) <= (realmem_map + (1024 * 1024)))) { ++ return; ++ } ++ ++ mi.address = (unsigned long) virt_addr; ++ __dpmi_free_physical_address_mapping(&mi); ++} ++ ++#elif defined(__DARWIN__) ++ + #include + + #define MEM_DEV "DirectIO" +@@ -36,6 +109,10 @@ void *sys_physmap(unsigned long phys_addr, size_t len) return map_physical(phys_addr, len); } @@ -15796,7 +17044,7 @@ index 778a783..fba7a53 100644 void physunmap(void *virt_addr, size_t len) { unmap_physical(virt_addr, len); -@@ -51,8 +56,10 @@ void physunmap(void *virt_addr, size_t len) +@@ -51,8 +128,10 @@ void physunmap(void *virt_addr, size_t len) #endif static int fd_mem = -1; @@ -15808,7 +17056,7 @@ index 778a783..fba7a53 100644 { void *virt_addr; -@@ -69,6 +76,26 @@ void *sys_physmap(unsigned long phys_addr, size_t len) +@@ -69,6 +148,26 @@ void *sys_physmap(unsigned long phys_addr, size_t len) return MAP_FAILED == virt_addr ? NULL : virt_addr; } @@ -15835,7 +17083,7 @@ index 778a783..fba7a53 100644 void physunmap(void *virt_addr, size_t len) { if (len == 0) { -@@ -80,7 +107,12 @@ void physunmap(void *virt_addr, size_t len) +@@ -80,7 +179,12 @@ void physunmap(void *virt_addr, size_t len) } #endif @@ -15849,7 +17097,7 @@ index 778a783..fba7a53 100644 { void *virt_addr; -@@ -100,7 +132,11 @@ void *physmap(const char *descr, unsigned long phys_addr, size_t len) +@@ -100,7 +204,11 @@ void *physmap(const char *descr, unsigned long phys_addr, size_t len) descr, (unsigned long)len, phys_addr); } @@ -15862,7 +17110,7 @@ index 778a783..fba7a53 100644 if (NULL == virt_addr) { if (NULL == descr) -@@ -114,12 +150,23 @@ void *physmap(const char *descr, unsigned long phys_addr, size_t len) +@@ -114,12 +222,23 @@ void *physmap(const char *descr, unsigned long phys_addr, size_t len) fprintf(stderr, "You can override CONFIG_X86_PAT at boot with the nopat kernel parameter but\n"); fprintf(stderr, "disabling the other option unfortunately requires a kernel recompile. Sorry!\n"); } @@ -15887,7 +17135,7 @@ index 778a783..fba7a53 100644 #ifdef __linux__ /* * Reading and writing to MSRs, however requires instructions rdmsr/wrmsr, -@@ -133,7 +180,7 @@ static int fd_msr = -1; +@@ -133,7 +252,7 @@ static int fd_msr = -1; msr_t rdmsr(int addr) { @@ -15896,7 +17144,7 @@ index 778a783..fba7a53 100644 msr_t msr = { 0xffffffff, 0xffffffff }; if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) { -@@ -143,8 +190,8 @@ msr_t rdmsr(int addr) +@@ -143,8 +262,8 @@ msr_t rdmsr(int addr) } if (read(fd_msr, buf, 8) == 8) { @@ -15970,7 +17218,7 @@ index a01df88..0000000 - return 0; -} diff --git a/pm49fl00x.c b/pm49fl00x.c -index 27a1163..5e5eec8 100644 +index 27a1163..fd93ef6 100644 --- a/pm49fl00x.c +++ b/pm49fl00x.c @@ -21,6 +21,7 @@ @@ -15981,7 +17229,7 @@ index 27a1163..5e5eec8 100644 void write_lockbits_49fl00x(chipaddr bios, int size, unsigned char bits, int block_size) -@@ -36,14 +37,16 @@ void write_lockbits_49fl00x(chipaddr bios, int size, +@@ -36,81 +37,14 @@ void write_lockbits_49fl00x(chipaddr bios, int size, } } @@ -15992,31 +17240,83 @@ index 27a1163..5e5eec8 100644 - - if (ret == 1) - map_flash_registers(flash); -+ write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 0, flash->page_size); -+ return 0; -+} - +- - return ret; -+int lock_49fl00x(struct flashchip *flash) -+{ -+ write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 1, flash->page_size); -+ return 0; +-} +- +-int erase_49fl00x(struct flashchip *flash) +-{ +- int i; +- int total_size = flash->total_size * 1024; +- int page_size = flash->page_size; +- +- /* unprotected */ +- write_lockbits_49fl00x(flash->virtual_registers, +- total_size, 0, page_size); +- +- /* +- * erase_chip_jedec() will not work... Datasheet says +- * "Chip erase is available in A/A Mux Mode only". +- */ +- printf("Erasing page: "); +- for (i = 0; i < total_size / page_size; i++) { +- /* erase the page */ +- if (erase_block_jedec(flash, i * page_size, page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- printf("%04d at address: 0x%08x", i, i * page_size); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- fflush(stdout); +- } +- printf("\n"); +- +- /* protected */ +- write_lockbits_49fl00x(flash->virtual_registers, +- total_size, 1, page_size); +- ++ write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 0, flash->page_size); + return 0; } - int erase_49fl00x(struct flashchip *flash) -@@ -101,8 +104,8 @@ int write_49fl00x(struct flashchip *flash, uint8_t *buf) - - /* write to the sector */ - printf("%04d at address: 0x%08x", i, i * page_size); +-int write_49fl00x(struct flashchip *flash, uint8_t *buf) ++int lock_49fl00x(struct flashchip *flash) + { +- int i; +- int total_size = flash->total_size * 1024; +- int page_size = flash->page_size; +- chipaddr bios = flash->virtual_memory; +- +- /* unprotected */ +- write_lockbits_49fl00x(flash->virtual_registers, total_size, 0, +- page_size); +- +- printf("Programming page: "); +- for (i = 0; i < total_size / page_size; i++) { +- /* erase the page before programming */ +- if (erase_block_jedec(flash, i * page_size, page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- +- /* write to the sector */ +- printf("%04d at address: 0x%08x", i, i * page_size); - write_sector_jedec(bios, buf + i * page_size, - bios + i * page_size, page_size); -+ write_sector_jedec_common(flash, buf + i * page_size, -+ bios + i * page_size, page_size, 0xffff); - printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); - fflush(stdout); - } +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- fflush(stdout); +- } +- printf("\n"); +- +- /* protected */ +- write_lockbits_49fl00x(flash->virtual_registers, total_size, 1, +- page_size); +- ++ write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 1, flash->page_size); + return 0; + } diff --git a/print.c b/print.c -index ce46e1b..2208dca 100644 +index ce46e1b..2a2c81b 100644 --- a/print.c +++ b/print.c @@ -21,22 +21,9 @@ @@ -16077,7 +17377,7 @@ index ce46e1b..2208dca 100644 printf(" "); if (b[i].lb_vendor != NULL) printf("-m %s:%s\n", b[i].lb_vendor, b[i].lb_part); -@@ -234,505 +222,188 @@ void print_supported_boards(void) +@@ -234,505 +222,206 @@ void print_supported_boards(void) print_supported_boards_helper(laptops_bad, "Laptops which have been verified to NOT work yet"); } @@ -16357,9 +17657,9 @@ index ce46e1b..2208dca 100644 + { "ASRock", "M3A790GXH/128M" }, + { "ASUS", "A7N8X Deluxe", }, + { "ASUS", "A7N8X-E Deluxe", }, ++ { "ASUS", "A7V133", }, + { "ASUS", "A7V400-MX", }, + { "ASUS", "A7V8X-MX", }, -+ { "ASUS", "A7V8X-X", }, + { "ASUS", "A8N-E", }, + { "ASUS", "A8NE-FM/S", }, + { "ASUS", "A8N-SLI", }, @@ -16380,44 +17680,60 @@ index ce46e1b..2208dca 100644 + { "ASUS", "P2B-DS", }, + { "ASUS", "P2B-F", }, + { "ASUS", "P2L97-S", }, ++ { "ASUS", "P5B", }, + { "ASUS", "P5B-Deluxe", }, + { "ASUS", "P5KC", }, + { "ASUS", "P5L-MX", }, ++ { "ASUS", "P6T Deluxe", }, + { "ASUS", "P6T Deluxe V2", }, + { "A-Trend", "ATC-6220", }, + { "BCOM", "WinNET100", }, + { "DFI", "Blood-Iron P35 T2RL", }, + { "Elitegroup", "K7S5A", }, + { "Elitegroup", "P6VAP-A+", }, ++ { "GIGABYTE", "GA-2761GXDK", }, + { "GIGABYTE", "GA-6BXC", }, + { "GIGABYTE", "GA-6BXDU", }, + { "GIGABYTE", "GA-6ZMA", }, + { "GIGABYTE", "GA-7ZM", }, ++ { "GIGABYTE", "GA-965P-DS4", }, + { "GIGABYTE", "GA-EP35-DS3L", }, + { "GIGABYTE", "GA-EX58-UD4P", }, -+ { "GIGABYTE", "GA-MA78GPM-DS2H", }, -+ { "GIGABYTE", "GA-MA790GP-DS4H", }, ++ { "GIGABYTE", "GA-M57SLI-S4", }, ++ { "GIGABYTE", "GA-M61P-S3", }, ++ { "GIGABYTE", "GA-MA69VM-S2", }, + { "GIGABYTE", "GA-MA770T-UD3P", }, ++ { "GIGABYTE", "GA-MA78G-DS3H", }, ++ { "GIGABYTE", "GA-MA78GM-S2H", }, ++ { "GIGABYTE", "GA-MA78GPM-DS2H", }, ++ { "GIGABYTE", "GA-MA790FX-DQ6", }, ++ { "GIGABYTE", "GA-MA790GP-DS4H", }, + { "Intel", "EP80759", }, + { "Jetway", "J7F4K1G5D-PB", }, + { "MSI", "MS-6153", }, + { "MSI", "MS-6156", }, ++ { "MSI", "MS-6330 (K7T Turbo)", }, + { "MSI", "MS-6570 (K7N2)", }, + { "MSI", "MS-7065", }, + { "MSI", "MS-7168 (Orion)", }, + { "MSI", "MS-7236 (945PL Neo3)", }, + { "MSI", "MS-7255 (P4M890M)", }, ++ { "MSI", "MS-7312 (K9MM-V)", }, + { "MSI", "MS-7345 (P35 Neo2-FIR)", }, + { "MSI", "MS-7368 (K9AG Neo2-Digital)", }, ++ { "MSI", "MS-7376 (K9A2 Platinum)", }, + { "NEC", "PowerMate 2000", }, + { "PC Engines", "Alix.1c", }, + { "PC Engines", "Alix.2c2", }, + { "PC Engines", "Alix.2c3", }, + { "PC Engines", "Alix.3c3", }, + { "PC Engines", "Alix.3d3", }, ++ { "PC Engines", "WRAP.2E", }, + { "RCA", "RM4100", }, ++ { "Shuttle", "FD37", }, + { "Sun", "Blade x6250", }, + { "Supermicro", "H8QC8", }, ++ { "Supermicro", "X8DTT-F", }, + { "Thomson", "IP1000", }, + { "TriGem", "Lomita", }, + { "T-Online", "S-100", }, @@ -16440,6 +17756,7 @@ index ce46e1b..2208dca 100644 + { "Tyan", "S5375", }, + { "Tyan", "S5376G2NR/S5376WAG2NR", }, + { "Tyan", "S5377", }, ++ { "Tyan", "S5382 (Tempest i5000PW)", }, + { "Tyan", "S5397", }, + { "VIA", "EPIA-CN", }, + { "VIA", "EPIA-EX15000G", }, @@ -16449,6 +17766,7 @@ index ce46e1b..2208dca 100644 + { "VIA", "EPIA-SP", }, + { "VIA", "NAB74X0", }, + { "VIA", "pc2500e", }, ++ { "VIA", "PC3500G", }, + { "VIA", "VB700X", }, + + {}, @@ -16464,7 +17782,6 @@ index ce46e1b..2208dca 100644 + { "ASUS", "MEW-AM", }, + { "ASUS", "MEW-VM", }, + { "ASUS", "P3B-F", }, -+ { "ASUS", "P5B", }, + { "ASUS", "P5BV-M", }, + { "Biostar", "M6TBA", }, + { "Boser", "HS-6637", }, @@ -16493,6 +17810,7 @@ index ce46e1b..2208dca 100644 - { "HP/Compaq", "nx9010", "Hangs upon '''flashrom -V''' (needs hard power-cycle then)." }, - { "IBM/Lenovo", "Thinkpad T40p", "Seems to (partially) work at first, but one block/sector cannot be written which then leaves you with a bricked laptop. Maybe this can be investigated and fixed in software later." }, + { "Lenovo", "3000 V100 TF05Cxx", }, ++ { "Acer", "Aspire 1520", }, - { NULL, NULL, 0 }, + {}, @@ -16758,10 +18076,10 @@ index ce46e1b..2208dca 100644 diff --git a/print_wiki.c b/print_wiki.c new file mode 100644 -index 0000000..4156c3e +index 0000000..87adf4d --- /dev/null +++ b/print_wiki.c -@@ -0,0 +1,575 @@ +@@ -0,0 +1,600 @@ +/* + * This file is part of the flashrom project. + * @@ -16870,67 +18188,78 @@ index 0000000..4156c3e + { "ASRock", "A770CrossFire", "http://www.asrock.com/mb/overview.asp?Model=A770CrossFire&s=AM2\%2b" }, + { "ASRock", "K8S8X", "http://www.asrock.com/mb/overview.asp?Model=K8S8X" }, + { "ASRock", "M3A790GXH/128M" "http://www.asrock.com/MB/overview.asp?Model=M3A790GXH/128M" }, -+ { "ASUS", "A7N8X Deluxe", "http://www.asus.com/Product.aspx?P_ID=wAsRYm41KTp78MFC" }, -+ { "ASUS", "A7N8X-E Deluxe", "http://www.asus.com/products.aspx?l1=3&l2=13&l3=56&l4=0&model=217&modelmenu=1" }, -+ { "ASUS", "A7V400-MX", "http://www.asus.com.tw/products.aspx?l1=3&l2=13&l3=63&l4=0&model=228&modelmenu=1" }, -+ { "ASUS", "A7V8X-MX", "http://www.asus.com.tw/products.aspx?l1=3&l2=13&l3=64&l4=0&model=229&modelmenu=1" }, -+ { "ASUS", "A8N-E", "http://www.asus.com.tw/products.aspx?l1=3&l2=15&l3=171&l4=0&model=455&modelmenu=2" }, ++ { "ASUS", "A7N8X Deluxe", "http://www.asus.com/product.aspx?P_ID=wAsRYm41KTp78MFC" }, ++ { "ASUS", "A7N8X-E Deluxe", "http://www.asus.com/product.aspx?P_ID=TmQtPJv4jIxmL9C2" }, ++ { "ASUS", "A7V133", "ftp://ftp.asus.com.tw/pub/ASUS/mb/socka/kt133a/a7v133/" }, ++ { "ASUS", "A7V400-MX", "http://www.asus.com/product.aspx?P_ID=hORgEHRBDLMfwAwx" }, ++ { "ASUS", "A7V8X-MX", "http://www.asus.com/product.aspx?P_ID=SEJOOYqfuQPitx2H" }, ++ { "ASUS", "A8N-E", "http://www.asus.com/product.aspx?P_ID=DzbA8hgqchMBOVRz" }, + { "ASUS", "A8NE-FM/S", "http://www.hardwareschotte.de/hardware/preise/proid_1266090/preis_ASUS+A8NE-FM" }, -+ { "ASUS", "A8N-SLI", "http://asus.com/product.aspx?P_ID=J9FKa8z2xVId3pDK" }, -+ { "ASUS", "A8N-SLI Premium", "http://www.asus.com.tw/products.aspx?l1=3&l2=15&l3=148&l4=0&model=539&modelmenu=1" }, ++ { "ASUS", "A8N-SLI", "http://www.asus.com/product.aspx?P_ID=J9FKa8z2xVId3pDK" }, ++ { "ASUS", "A8N-SLI Premium", "http://www.asus.com/product.aspx?P_ID=nbulqxniNmzf0mH1" }, + { "ASUS", "A8V Deluxe", "http://www.asus.com/product.aspx?P_ID=tvpdgPNCPaABZRVU" }, -+ { "ASUS", "A8V-E Deluxe", "http://www.asus.com.tw/products.aspx?l1=3&l2=15&l3=143&l4=0&model=376&modelmenu=1" }, -+ { "ASUS", "A8V-E SE", "http://www.asus.com.tw/products.aspx?l1=3&l2=15&l3=143&l4=0&model=576&modelmenu=1" }, ++ { "ASUS", "A8V-E Deluxe", "http://www.asus.com/product.aspx?P_ID=hQBPIJWEZnnGAZEh" }, ++ { "ASUS", "A8V-E SE", "http://www.asus.com/product.aspx?P_ID=VMfiJJRYTHM4gXIi" }, + { "ASUS", "K8V", "http://www.asus.com/product.aspx?P_ID=fG2KZOWF7v6MRFRm" }, + { "ASUS", "K8V SE Deluxe", "http://www.asus.com/product.aspx?P_ID=65HeDI8XM1u6Uy6o" }, -+ { "ASUS", "K8V-X SE", "http://asus.com/product.aspx?P_ID=lzDXlbBVHkdckHVr" }, -+ { "ASUS", "M2A-MX", "http://www.asus.com/products.aspx?l1=3&l2=101&l3=583&l4=0&model=1909&modelmenu=1" }, -+ { "ASUS", "M2A-VM", "http://www.asus.com.tw/products.aspx?l1=3&l2=101&l3=496&l4=0&model=1568&modelmenu=1" }, -+ { "ASUS", "M2N-E", "http://www.asus.com/products.aspx?l1=3&l2=101&l3=308&l4=0&model=1181&modelmenu=1" }, -+ { "ASUS", "M2V", "http://asus.com/Product.aspx?P_ID=OqYlEDFfF6ZqZGvp" }, ++ { "ASUS", "K8V-X SE", "http://www.asus.com/product.aspx?P_ID=lzDXlbBVHkdckHVr" }, ++ { "ASUS", "M2A-MX", "http://www.asus.com/product.aspx?P_ID=BmaOnPewi1JgltOZ" }, ++ { "ASUS", "M2A-VM", "http://www.asus.com/product.aspx?P_ID=St3pWpym8xXpROQS" }, ++ { "ASUS", "M2N-E", "http://www.asus.com/product.aspx?P_ID=NFlvt10av3F7ayQ9" }, ++ { "ASUS", "M2V", "http://www.asus.com/product.aspx?P_ID=OqYlEDFfF6ZqZGvp" }, + { "ASUS", "M3A78-EM", "http://www.asus.com/product.aspx?P_ID=KjpYqzmAd9vsTM2D" }, -+ { "ASUS", "P2B", "http://www.motherboard.cz/mb/asus/P2B.htm" }, ++ { "ASUS", "P2B", "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b/" }, + { "ASUS", "P2B-D", "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b-d/" }, + { "ASUS", "P2B-DS", "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b-ds/" }, -+ { "ASUS", "P2B-F", "http://www.motherboard.cz/mb/asus/P2B-F.htm" }, -+ { "ASUS", "P2L97-S", "http://www.motherboard.cz/mb/asus/P2L97-S.htm" }, -+ { "ASUS", "P5B-Deluxe", "ftp://ftp.asus.com.tw/pub/ASUS/mb/socket775/P5B-Deluxe/" }, ++ { "ASUS", "P2B-F", "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b-d/" }, ++ { "ASUS", "P2L97-S", "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440lx/p2l97-s/" }, ++ { "ASUS", "P5B", "ftp://ftp.asus.com.tw/pub/ASUS/mb/socket775/P5B/" }, ++ { "ASUS", "P5B-Deluxe", "http://www.asus.com/product.aspx?P_ID=bswT66IBSb2rEWNa" }, + { "ASUS", "P5KC", "http://www.asus.com/product.aspx?P_ID=fFZ8oUIGmLpwNMjj" }, + { "ASUS", "P5L-MX", "http://www.asus.com/product.aspx?P_ID=X70d3NCzH2DE9vWH" }, ++ { "ASUS", "P6T Deluxe", "http://www.asus.com/product.aspx?P_ID=vXixf82co6Q5v0BZ" }, + { "ASUS", "P6T Deluxe V2", "http://www.asus.com/product.aspx?P_ID=iRlP8RG9han6saZx" }, + { "A-Trend", "ATC-6220", "http://www.motherboard.cz/mb/atrend/atc6220.htm" }, + { "BCOM", "WinNET100", "http://www.coreboot.org/BCOM_WINNET100" }, + { "DFI", "Blood-Iron P35 T2RL", "http://lp.lanparty.com.tw/portal/CM/cmproduct/XX_cmproddetail/XX_WbProdsWindow?itemId=516&downloadFlag=false&action=1" }, + { "Elitegroup", "K7S5A", "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=279&CategoryID=1&DetailName=Specification&MenuID=1&LanID=0" }, + { "Elitegroup", "P6VAP-A+", "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=117&CategoryID=1&DetailName=Specification&MenuID=1&LanID=0" }, -+ { "GIGABYTE", "GA-6BXC", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ClassValue=Motherboard&ProductID=1445&ProductName=GA-6BXC" }, ++ { "GIGABYTE", "GA-6BXC", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=1445" }, + { "GIGABYTE", "GA-6BXDU", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=1429" }, -+ { "GIGABYTE", "GA-6ZMA", "http://www.gigabyte.de/Support/Motherboard/BIOS_Model.aspx?ProductID=3289" }, -+ { "GIGABYTE", "GA-EX58-UD4P", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Overview.aspx?ProductID=2986" }, -+ { "GIGABYTE", "GA-EP35-DS3L", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Overview.aspx?ProductID=2778" }, ++ { "GIGABYTE", "GA-6ZMA", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=1541" }, ++ { "GIGABYTE", "GA-965P-DS4", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2288" }, ++ { "GIGABYTE", "GA-EX58-UD4P", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2986" }, ++ { "GIGABYTE", "GA-EP35-DS3L", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2778" }, ++ { "GIGABYTE", "GA-MA69VM-S2", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2500" }, + { "GIGABYTE", "GA-MA790GP-DS4H", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2887" }, + { "GIGABYTE", "GA-MA78GPM-DS2H", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2859" }, + { "GIGABYTE", "GA-MA770T-UD3P", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=3096" }, + { "Intel", "EP80759", NULL }, + { "Jetway", "J7F4K1G5D-PB", "http://www.jetway.com.tw/jetway/system/productshow2.asp?id=389&proname=J7F4K1G5D-P" }, -+ { "MSI", "MS-6153", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&cat2_no=&cat3_no=&prod_no=336" }, ++ { "MSI", "MS-6153", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=336" }, + { "MSI", "MS-6156", "http://uk.ts.fujitsu.com/rl/servicesupport/techsupport/boards/Motherboards/MicroStar/Ms6156/MS6156.htm" }, -+ { "MSI", "MS-6570 (K7N2)", "http://www.msi-computer.de/index.php?func=proddesc&prod_no=519&maincat_no=1" }, ++ { "MSI", "MS-6330 (K7T Turbo)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=327" }, ++ { "MSI", "MS-6570 (K7N2)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=519" }, + { "MSI", "MS-7065", "http://browse.geekbench.ca/geekbench2/view/53114" }, + { "MSI", "MS-7168 (Orion)", "http://support.packardbell.co.uk/uk/item/index.php?i=spec_orion&pi=platform_honeymoon_istart" }, + { "MSI", "MS-7236 (945PL Neo3)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=1173" }, -+ { "MSI", "MS-7255 (P4M890M)", "http://www.tcsbahamas.com/P4M89.htm" }, -+ { "MSI", "MS-7345 (P35 Neo2-FIR)","http://www.msi.com/index.php?func=prodcpusupport&maincat_no=1&cat2_no=170&cat3_no=&prod_no=1261" }, ++ { "MSI", "MS-7255 (P4M890M)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=1082" }, ++ { "MSI", "MS-7345 (P35 Neo2-FIR)","http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=1261" }, ++ { "MSI", "MS-7312 (K9MM-V)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=1104" }, + { "MSI", "MS-7368 (K9AG Neo2-Digital)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=1241" }, ++ { "MSI", "MS-7376 (K9A2 Platinum)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=1332" }, + { "NEC", "PowerMate 2000", "http://support.necam.com/mobilesolutions/hardware/Desktops/pm2000/celeron/" }, + { "PC Engines", "Alix.1c", "http://pcengines.ch/alix1c.htm" }, + { "PC Engines", "Alix.2c2", "http://pcengines.ch/alix2c2.htm" }, + { "PC Engines", "Alix.2c3", "http://pcengines.ch/alix2c3.htm" }, + { "PC Engines", "Alix.3c3", "http://pcengines.ch/alix3c3.htm" }, + { "PC Engines", "Alix.3d3", "http://pcengines.ch/alix3d3.htm" }, ++ { "PC Engines", "WRAP.2E", "http://pcengines.ch/wrap2e1.htm" }, + { "RCA", "RM4100", "http://www.settoplinux.org/index.php?title=RCA_RM4100" }, ++ { "Shuttle", "FD37", "http://www.shuttle.eu/products/discontinued/barebones/sd37p2/" }, + { "Sun", "Blade x6250", "http://www.sun.com/servers/blades/x6250/" }, + { "Supermicro", "H8QC8", "http://www.supermicro.com/Aplus/motherboard/Opteron/nforce/H8QC8.cfm" }, ++ { "Supermicro", "X8DTT-F", "http://www.supermicro.com/products/motherboard/QPI/5500/X8DTT-F.cfm" }, + { "Tekram", "P6Pro-A5", "http://www.motherboard.cz/mb/tekram/P6Pro-A5.htm" }, + { "Thomson", "IP1000", "http://www.settoplinux.org/index.php?title=Thomson_IP1000" }, + { "TriGem", "Lomita", "http://www.e4allupgraders.info/dir1/motherboards/socket370/lomita.shtml" }, @@ -16954,6 +18283,7 @@ index 0000000..4156c3e + { "Tyan", "S5375", "http://www.tyan.com/product_board_detail.aspx?pid=566" }, + { "Tyan", "S5376G2NR/S5376WAG2NR","http://www.tyan.com/product_board_detail.aspx?pid=605" }, + { "Tyan", "S5377", "http://www.tyan.com/product_SKU_spec.aspx?ProductType=MB&pid=642&SKU=600000017" }, ++ { "Tyan", "S5382 (Tempest i5000PW)", "http://www.tyan.com/product_board_detail.aspx?pid=439" }, + { "Tyan", "S5397", "http://www.tyan.com/product_board_detail.aspx?pid=560" }, + { "VIA", "EPIA-EX15000G", "http://www.via.com.tw/en/products/embedded/ProductDetail.jsp?productLine=1&motherboard_id=450" }, + { "VIA", "EPIA-LN", "http://www.via.com.tw/en/products/mainboards/motherboards.jsp?motherboard_id=473" }, @@ -16964,7 +18294,10 @@ index 0000000..4156c3e + { "VIA", "VB700X", "http://www.via.com.tw/en/products/mainboards/motherboards.jsp?motherboard_id=490" }, + + /* Verified working boards that DO need write-enables. */ ++ { "Abit", "VT6X4", "http://www.abit.com.tw/page/en/motherboard/motherboard_detail.php?fMTYPE=Slot%201&pMODEL_NAME=VT6X4" }, + { "Abit", "IP35", "http://www.abit.com.tw/page/en/motherboard/motherboard_detail.php?fMTYPE=LGA775&pMODEL_NAME=IP35" }, ++ { "Abit", "IP35 Pro", "http://www.abit.com.tw/page/de/motherboard/motherboard_detail.php?fMTYPE=LGA775&pMODEL_NAME=IP35%20Pro" }, ++ { "Abit", "NF7-S", "http://www.abit.com.tw/page/en/motherboard/motherboard_detail.php?fMTYPE=Socket%20A&pMODEL_NAME=NF7-S"}, + { "Acorp", "6A815EPD", "http://web.archive.org/web/20021206163652/www.acorp.com.tw/English/default.asp" }, + { "agami", "Aruma", "http://web.archive.org/web/20080212111524/http://www.agami.com/site/ais-6000-series" }, + { "Albatron", "PM266A Pro", "http://www.albatron.com.tw/English/Product/MB/pro_detail.asp?rlink=Overview&no=56" }, /* FIXME */ @@ -16975,12 +18308,17 @@ index 0000000..4156c3e + { "ASUS", "A7V8X", "http://www.asus.com/product.aspx?P_ID=qfpaGrAy2kLVo0f2" }, + { "ASUS", "A7V8X-MX SE", "http://www.asus.com/product.aspx?P_ID=1guVBT1qV5oqhHyZ" }, + { "ASUS", "A7V8X-X", "http://www.asus.com/product.aspx?P_ID=YcXfRrWHZ9RKoVmw" }, -+ { "ASUS", "P4B266", "http://www.ciao.co.uk/ASUS_Intel_845D_Chipset_P4B266__5409807#productdetail" }, ++ { "ASUS", "M2NBP-VM CSM", "http://www.asus.com/product.aspx?P_ID=MnOfzTGd2KkwG0rF" }, ++ { "ASUS", "M2V-MX", "http://www.asus.com/product.aspx?P_ID=7grf8Ci4yxnqzt3z" }, ++ { "ASUS", "P4B266", "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock478/p4b266/" }, ++ { "ASUS", "P4C800-E Deluxe", "http://www.asus.com/product.aspx?P_ID=cFuVCr9bXXCckmcK" }, ++ { "ASUS", "P4B266-LM", "http://esupport.sony.com/US/perl/swu-list.pl?mdl=PCVRX650" }, + { "ASUS", "P4P800-E Deluxe", "http://www.asus.com/product.aspx?P_ID=INIJUvLlif7LHp3g" }, + { "ASUS", "P5ND2-SLI Deluxe", "http://www.asus.com/product.aspx?P_ID=WY7XroDuUImVbgp5" }, + { "ASUS", "P5A", "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock7/ali/p5a/" }, + { "Biostar", "P4M80-M4", "http://www.biostar-usa.com/mbdetails.asp?model=p4m80-m4" }, + { "Dell", "PowerEdge 1850", "http://support.dell.com/support/edocs/systems/pe1850/en/index.htm" }, ++ { "Elitegroup", "K7S6A", "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=77&CategoryID=1&DetailName=Specification&MenuID=52&LanID=0" }, + { "Elitegroup", "K7VTA3", "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=264&CategoryID=1&DetailName=Specification&MenuID=52&LanID=0" }, + { "EPoX", "EP-8K5A2", "http://www.epox.com/product.asp?ID=EP-8K5A2" }, + { "EPoX", "EP-8RDA3+", "http://www.epox.com/product.asp?ID=EP-8RDA3plus" }, @@ -16989,23 +18327,28 @@ index 0000000..4156c3e + { "GIGABYTE", "GA-7VT600", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=1666" }, + { "GIGABYTE", "GA-7ZM", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=1366" }, + { "GIGABYTE", "GA-K8N-SLI", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=1928" }, -+ { "GIGABYTE", "GA-M57SLI-S4", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Overview.aspx?ProductID=2287&ModelName=GA-M57SLI-S4" }, ++ { "GIGABYTE", "GA-M57SLI-S4", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2287" }, + { "GIGABYTE", "GA-M61P-S3", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2434" }, + { "GIGABYTE", "GA-MA78G-DS3H", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2800" }, /* TODO: Rev 1.x or 2.x? */ + { "GIGABYTE", "GA-MA78GM-S2H", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2758" }, /* TODO: Rev. 1.0, 1.1, or 2.x? */ + { "GIGABYTE", "GA-MA790FX-DQ6", "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2690" }, + { "HP", "DL145 G3", "http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c00816835&lang=en&cc=us&taskId=101&prodSeriesId=3219755&prodTypeId=15351" }, ++ { "HP", "Vectra VL400 PC", "http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c00060658&lang=en&cc=us" }, ++ { "HP", "Vectra VL420 SFF PC", "http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c00060661&lang=en&cc=us" }, + { "IBM", "x3455", "http://www-03.ibm.com/systems/x/hardware/rack/x3455/index.html" }, + { "Intel", "D201GLY", "http://www.intel.com/support/motherboards/desktop/d201gly/index.htm" }, + { "IWILL", "DK8-HTX", "http://web.archive.org/web/20060507170150/http://www.iwill.net/product_2.asp?p_id=98" }, + { "Kontron", "986LCD-M", "http://de.kontron.com/products/boards+and+mezzanines/embedded+motherboards/miniitx+motherboards/986lcdmmitx.html" }, + { "Mitac", "6513WU", "http://web.archive.org/web/20050313054828/http://www.mitac.com/micweb/products/tyan/6513wu/6513wu.htm" }, -+ { "MSI", "MS-6590 (KT4 Ultra)", "http://www.msicomputer.com/product/p_spec.asp?model=KT4_Ultra&class=mb" }, -+ { "MSI", "MS-6702E (K8T Neo2-F)","http://www.msicomputer.com/product/p_spec.asp?model=K8T_Neo2-F&class=mb" }, -+ { "MSI", "MS-6712 (KT4V)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&cat2_no=&cat3_no=&prod_no=505" }, ++ { "MSI", "MS-6590 (KT4 Ultra)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=502" }, ++ { "MSI", "MS-6702E (K8T Neo2-F)","http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=588" }, ++ { "MSI", "MS-6712 (KT4V)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=505" }, ++ { "MSI", "MS-7005 (651M-L)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=559" }, + { "MSI", "MS-7046", "http://www.heimir.de/ms7046/" }, -+ { "MSI", "MS-7135 (K8N Neo3)", "http://www.msi-computer.de/index.php?func=proddesc&prod_no=170&maincat_no=1" }, ++ { "MSI", "MS-7135 (K8N Neo3)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=170" }, ++ { "Shuttle", "AK31", "http://www.motherboard.cz/mb/shuttle/AK31.htm" }, + { "Shuttle", "AK38N", "http://eu.shuttle.com/en/desktopdefault.aspx/tabid-36/558_read-9889/" }, ++ { "Shuttle", "FN25", "http://www.shuttle.eu/products/discontinued/barebones/sn25p/?0=" }, + { "Soyo", "SY-7VCA", "http://www.tomshardware.com/reviews/12-socket-370-motherboards,196-15.html" }, + { "Tyan", "S2498 (Tomcat K7M)", "http://www.tyan.com/archive/products/html/tomcatk7m.html" }, + { "VIA", "EPIA-CN", "http://www.via.com.tw/en/products/mainboards/motherboards.jsp?motherboard_id=400" }, @@ -17020,13 +18363,12 @@ index 0000000..4156c3e + { "ASUS", "MEW-AM", "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock370/810/mew-am/" }, + { "ASUS", "MEW-VM", "http://www.elhvb.com/mboards/OEM/HP/manual/ASUS%20MEW-VM.htm" }, + { "ASUS", "P3B-F", "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p3b-f/" }, -+ { "ASUS", "P5B", "ftp://ftp.asus.com.tw/pub/ASUS/mb/socket775/P5B/" }, + { "ASUS", "P5BV-M", "ftp://ftp.asus.com.tw/pub/ASUS/mb/socket775/P5B-VM/" }, + { "Biostar", "M6TBA", "ftp://ftp.biostar-usa.com/manuals/M6TBA/" }, + { "Boser", "HS-6637", "http://www.boser.com.tw/manual/HS-62376637v3.4.pdf" }, + { "DFI", "855GME-MGF", "http://www.dfi.com.tw/portal/CM/cmproduct/XX_cmproddetail/XX_WbProdsWindow?action=e&downloadType=&windowstate=normal&mode=view&downloadFlag=false&itemId=433" }, + { "FIC", "VA-502", "ftp://ftp.fic.com.tw/motherboard/manual/socket7/va-502/" }, -+ { "MSI", "MS-6178", "http://www.msi-technology.de/index.php?func=proddesc&prod_no=343&maincat_no=1" }, ++ { "MSI", "MS-6178", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=343" }, + { "MSI", "MS-7260 (K9N Neo)", "http://www.msi.com/index.php?func=proddesc&maincat_no=1&prod_no=255" }, + { "Soyo", "SY-5VD", "http://www.soyo.com/content/Downloads/163/&c=80&p=464&l=English" }, + { "Sun", "Fire x4540", "http://www.sun.com/servers/x64/x4540/" }, @@ -17035,6 +18377,7 @@ index 0000000..4156c3e + { "Sun", "Fire x4600", "http://www.sun.com/servers/x64/x4600/" }, + + /* Verified working laptops. */ ++ { "Acer", "Aspire 1520", "http://support.acer.com/us/en/acerpanam/notebook/0000/Acer/Aspire1520/Aspire1520nv.shtml" }, + { "Lenovo", "3000 V100 TF05Cxx", "http://www5.pc.ibm.com/europe/products.nsf/products?openagent&brand=Lenovo3000Notebook&series=Lenovo+3000+V+Series#viewallmodelstop" }, + + /* Verified non-working laptops (for now). */ @@ -17611,10 +18954,10 @@ index c853f42..0cf797c 100644 } diff --git a/serial.c b/serial.c new file mode 100644 -index 0000000..4d49e08 +index 0000000..37f2549 --- /dev/null +++ b/serial.c -@@ -0,0 +1,231 @@ +@@ -0,0 +1,232 @@ +/* + * This file is part of the flashrom project. + * @@ -17722,13 +19065,15 @@ index 0000000..4d49e08 +{ +#ifdef _WIN32 + HANDLE fd; -+ char* dev2 = dev; -+ if ((strlen(dev) > 3) && (tolower(dev[0])=='c') && (tolower(dev[1])=='o') && (tolower(dev[2])=='m')) { -+ dev2 = malloc(strlen(dev)+5); ++ char *dev2 = dev; ++ if ((strlen(dev) > 3) && (tolower(dev[0]) == 'c') ++ && (tolower(dev[1]) == 'o') && (tolower(dev[2]) == 'm')) { ++ dev2 = malloc(strlen(dev) + 5); + strcpy(dev2, "\\\\.\\"); -+ strcpy(dev2+4, dev); ++ strcpy(dev2 + 4, dev); + } -+ fd = CreateFile(dev2, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); ++ fd = CreateFile(dev2, GENERIC_READ | GENERIC_WRITE, 0, NULL, ++ OPEN_EXISTING, 0, NULL); + if (dev2 != dev) + free(dev2); + if (fd == INVALID_HANDLE_VALUE) { @@ -17746,9 +19091,9 @@ index 0000000..4d49e08 + case 115200: dcb.BaudRate = CBR_115200; break; + default: sp_die("Error: Could not set baud rate"); + } -+ dcb.ByteSize=8; -+ dcb.Parity=NOPARITY; -+ dcb.StopBits=ONESTOPBIT; ++ dcb.ByteSize = 8; ++ dcb.Parity = NOPARITY; ++ dcb.StopBits = ONESTOPBIT; + if (!SetCommState(fd, &dcb)) { + sp_die("Error: Could not change serial port configuration"); + } @@ -17764,9 +19109,8 @@ index 0000000..4d49e08 + for (i = 0;; i++) { + if (sp_baudtable[i].baud == 0) { + close(fd); -+ msg_perr( -+ "Error: cannot configure for baudrate %d\n", -+ baud); ++ msg_perr("Error: cannot configure for baudrate %d\n", ++ baud); + exit(1); + } + if (sp_baudtable[i].baud == baud) { @@ -17846,11 +19190,32 @@ index 0000000..4d49e08 + + return 0; +} +diff --git a/serprog-protocol.txt b/serprog-protocol.txt +index 0d389e6..c5464a4 100644 +--- a/serprog-protocol.txt ++++ b/serprog-protocol.txt +@@ -46,14 +46,14 @@ Additional information of the above commands: + cmd 7 support: byte 0 bit 7 + cmd 8 support: byte 1 bit 0, and so on. + 0x04 (Q_SERBUF): +- If the programmer has guaranteedly working flow control, ++ If the programmer has a guaranteed working flow control, + it should return a big bogus value - eg 0xFFFF. + 0x05 (Q_BUSTYPE): + The bit's are defined as follows: + bit 0: PARALLEL, bit 1: LPC, bit 2: FWH, bit 3: SPI (if ever supported). + 0x06 (Q_CHIPSIZE): + Only applicable to parallel programmers. +- An LPC/FHW/SPI-programmer can report this as not supported in the command bitmap. ++ An LPC/FWH/SPI-programmer can report this as not supported in the command bitmap. + 0x08 (Q_WRNMAXLEN): + If a programmer reports a bigger maximum write-n length than the serial buffer size, + it is assumed that the programmer can process the data fast enough to take in the diff --git a/serprog.c b/serprog.c -index 23e1a0c..0035e9a 100644 +index 23e1a0c..efcf9d8 100644 --- a/serprog.c +++ b/serprog.c -@@ -61,8 +61,6 @@ +@@ -61,14 +61,12 @@ #define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */ #define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */ @@ -17859,6 +19224,13 @@ index 23e1a0c..0035e9a 100644 static uint16_t sp_device_serbuf_size = 16; static uint16_t sp_device_opbuf_size = 300; /* Bitmap of supported commands */ + static uint8_t sp_cmdmap[32]; + +-/* sp_prev_was_write used to detect writes with continouous addresses ++/* sp_prev_was_write used to detect writes with contiguous addresses + and combine them to write-n's */ + static int sp_prev_was_write = 0; + /* sp_write_n_addr used as the starting addr of the currently @@ -95,19 +93,13 @@ static int sp_opbuf_usage = 0; whether the command is supported before doing it */ static int sp_check_avail_automatic = 0; @@ -18010,6 +19382,15 @@ index 23e1a0c..0035e9a 100644 static int sp_sync_read_timeout(int loops) { int i; +@@ -253,7 +138,7 @@ static int sp_sync_read_timeout(int loops) + return -1; + } + +-/* Synchronize: a bit tricky algorhytm that tries to (and in my tests has * ++/* Synchronize: a bit tricky algorithm that tries to (and in my tests has * + * always succeeded in) bring the serial protocol to known waiting-for- * + * command state - uses nonblocking read - rest of the driver uses * + * blocking read - TODO: add an alarm() timer for the rest of the app on * @@ -285,7 +170,7 @@ static void sp_synchronize(void) unsigned char c = S_CMD_SYNCNOP; if (write(sp_fd, &c, 1) != 1) @@ -18274,12 +19655,14 @@ index 23e1a0c..0035e9a 100644 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) sp_execute_opbuf(); close(sp_fd); -@@ -662,14 +535,13 @@ static void sp_check_opbuf_usage(int bytes_to_be_added) +@@ -661,15 +534,14 @@ static void sp_check_opbuf_usage(int bytes_to_be_added) + if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) { sp_execute_opbuf(); /* If this happens in the mid of an page load the page load * - * will propably fail. */ +- * will propably fail. */ - printf_debug(MSGHEADER - "Warning: executed operation buffer due to size reasons\n"); ++ * will probably fail. */ + msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n"); } } @@ -18291,7 +19674,7 @@ index 23e1a0c..0035e9a 100644 if (sp_max_write_n) { if ((sp_prev_was_write) && (addr == (sp_write_n_addr + sp_write_n_bytes))) { -@@ -713,7 +585,7 @@ uint8_t serprog_chip_readb(const chipaddr addr) +@@ -713,16 +585,16 @@ uint8_t serprog_chip_readb(const chipaddr addr) sp_flush_stream(); if (read(sp_fd, &c, 1) != 1) sp_die("readb byteread"); @@ -18300,7 +19683,9 @@ index 23e1a0c..0035e9a 100644 return c; } -@@ -722,7 +594,7 @@ static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len) +-/* Local version that really does the job, doesnt care of max_read_n. */ ++/* Local version that really does the job, doesn't care of max_read_n. */ + static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len) { int rd_bytes = 0; unsigned char sbuf[6]; @@ -18319,21 +19704,27 @@ index 23e1a0c..0035e9a 100644 sp_pass_writen(); sp_check_opbuf_usage(5); diff --git a/sharplhf00l04.c b/sharplhf00l04.c -index 53b9931..d5ab38c 100644 +index 53b9931..70b8135 100644 --- a/sharplhf00l04.c +++ b/sharplhf00l04.c -@@ -20,6 +20,7 @@ +@@ -20,147 +20,45 @@ #include #include "flash.h" +#include "chipdrivers.h" - // I need that Berkeley bit-map printer - void print_lhf00l04_status(uint8_t status) -@@ -33,81 +34,20 @@ void print_lhf00l04_status(uint8_t status) - printf("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:"); - } - +-// I need that Berkeley bit-map printer +-void print_lhf00l04_status(uint8_t status) +-{ +- printf("%s", status & 0x80 ? "Ready:" : "Busy:"); +- printf("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:"); +- printf("%s", status & 0x20 ? "BE ERROR:" : "BE OK:"); +- printf("%s", status & 0x10 ? "PROG ERR:" : "PROG OK:"); +- printf("%s", status & 0x8 ? "VP ERR:" : "VPP OK:"); +- printf("%s", status & 0x4 ? "PROG SUSPEND:" : "PROG RUN/FINISH:"); +- printf("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:"); +-} +- -int probe_lhf00l04(struct flashchip *flash) -{ - chipaddr bios = flash->virtual_memory; @@ -18413,25 +19804,37 @@ index 53b9931..d5ab38c 100644 // clear status register chip_writeb(0x50, bios); - printf("Erase at 0x%lx\n", bios); +- printf("Erase at 0x%lx\n", bios); - status = wait_lhf00l04(flash->virtual_memory); +- print_lhf00l04_status(status); ++ msg_cdbg("Erase at 0x%lx\n", bios); + status = wait_82802ab(flash->virtual_memory); - print_lhf00l04_status(status); ++ print_status_82802ab(status); // clear write protect - printf("write protect is at 0x%lx\n", (wrprotect)); -@@ -120,34 +60,17 @@ int erase_lhf00l04_block(struct flashchip *flash, int offset) +- printf("write protect is at 0x%lx\n", (wrprotect)); +- printf("write protect is 0x%x\n", chip_readb(wrprotect)); ++ msg_cspew("write protect is at 0x%lx\n", (wrprotect)); ++ msg_cspew("write protect is 0x%x\n", chip_readb(wrprotect)); + chip_writeb(0, wrprotect); +- printf("write protect is 0x%x\n", chip_readb(wrprotect)); ++ msg_cspew("write protect is 0x%x\n", chip_readb(wrprotect)); + + // now start it + chip_writeb(0x20, bios); chip_writeb(0xd0, bios); programmer_delay(10); // now let's see what the register is - status = wait_lhf00l04(flash->virtual_memory); -+ status = wait_82802ab(flash->virtual_memory); - print_lhf00l04_status(status); +- print_lhf00l04_status(status); - printf("DONE BLOCK 0x%x\n", offset); -+ printf("DONE BLOCK 0x%x\n", blockaddr); ++ status = wait_82802ab(flash->virtual_memory); ++ print_status_82802ab(status); ++ msg_cinfo("DONE BLOCK 0x%x\n", blockaddr); - if (check_erased_range(flash, offset, flash->page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); + if (check_erased_range(flash, blockaddr, blocklen)) { - fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); return -1; } return 0; @@ -18454,37 +19857,51 @@ index 53b9931..d5ab38c 100644 - return 0; -} - - void write_page_lhf00l04(chipaddr bios, uint8_t *src, - chipaddr dst, int page_size) - { -@@ -157,7 +80,7 @@ void write_page_lhf00l04(chipaddr bios, uint8_t *src, - /* transfer data from source to destination */ - chip_writeb(0x40, dst); - chip_writeb(*src++, dst++); +-void write_page_lhf00l04(chipaddr bios, uint8_t *src, +- chipaddr dst, int page_size) +-{ +- int i; +- +- for (i = 0; i < page_size; i++) { +- /* transfer data from source to destination */ +- chip_writeb(0x40, dst); +- chip_writeb(*src++, dst++); - wait_lhf00l04(bios); -+ wait_82802ab(bios); - } - } - -@@ -168,7 +91,7 @@ int write_lhf00l04(struct flashchip *flash, uint8_t *buf) +- } +-} +- + int write_lhf00l04(struct flashchip *flash, uint8_t *buf) + { + int i; +@@ -168,19 +66,18 @@ int write_lhf00l04(struct flashchip *flash, uint8_t *buf) int page_size = flash->page_size; chipaddr bios = flash->virtual_memory; - if (erase_lhf00l04(flash)) { +- fprintf(stderr, "ERASE FAILED!\n"); + if (erase_flash(flash)) { - fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); return -1; } -@@ -180,7 +103,6 @@ int write_lhf00l04(struct flashchip *flash, uint8_t *buf) - printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- printf("Programming page: "); ++ msg_cinfo("Programming page: "); + for (i = 0; i < total_size / page_size; i++) { +- printf("%04d at address: 0x%08x", i, i * page_size); +- write_page_lhf00l04(bios, buf + i * page_size, ++ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); ++ write_page_82802ab(bios, buf + i * page_size, + bios + i * page_size, page_size); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); } - printf("\n"); +- printf("\n"); - protect_jedec(bios); ++ msg_cinfo("\n"); return 0; } diff --git a/spi.c b/spi.c -index 7f678a1..41bb8f3 100644 +index 7f678a1..8bbbe6e 100644 --- a/spi.c +++ b/spi.c @@ -25,6 +25,7 @@ @@ -18529,7 +19946,7 @@ index 7f678a1..41bb8f3 100644 + .command = buspirate_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = buspirate_spi_read, -+ .write_256 = spi_chip_write_1, ++ .write_256 = buspirate_spi_write_256, + }, +#endif + @@ -19474,10 +20891,10 @@ index 3050ccf..1b49d59 100644 #define SPI_INVALID_LENGTH -4 diff --git a/spi25.c b/spi25.c new file mode 100644 -index 0000000..54121b0 +index 0000000..c6d1b65 --- /dev/null +++ b/spi25.c -@@ -0,0 +1,992 @@ +@@ -0,0 +1,981 @@ +/* + * This file is part of the flashrom project. + * @@ -19519,10 +20936,10 @@ index 0000000..54121b0 + ret = spi_send_command(sizeof(cmd), bytes, cmd, readarr); + if (ret) + return ret; -+ printf_debug("RDID returned"); ++ msg_cspew("RDID returned"); + for (i = 0; i < bytes; i++) -+ printf_debug(" 0x%02x", readarr[i]); -+ printf_debug(". "); ++ msg_cspew(" 0x%02x", readarr[i]); ++ msg_cspew(". "); + return 0; +} + @@ -19543,7 +20960,7 @@ index 0000000..54121b0 + } + if (ret) + return ret; -+ printf_debug("REMS returned %02x %02x. ", readarr[0], readarr[1]); ++ msg_cspew("REMS returned %02x %02x. ", readarr[0], readarr[1]); + return 0; +} + @@ -19564,7 +20981,7 @@ index 0000000..54121b0 + } + if (ret) + return ret; -+ printf_debug("RES returned %02x. ", readarr[0]); ++ msg_cspew("RES returned %02x. ", readarr[0]); + return 0; +} + @@ -19577,7 +20994,7 @@ index 0000000..54121b0 + result = spi_send_command(sizeof(cmd), 0, cmd, NULL); + + if (result) -+ fprintf(stderr, "%s failed\n", __func__); ++ msg_cerr("%s failed\n", __func__); + + return result; +} @@ -19600,12 +21017,12 @@ index 0000000..54121b0 + return 0; + + if (!oddparity(readarr[0])) -+ printf_debug("RDID byte 0 parity violation. "); ++ msg_cdbg("RDID byte 0 parity violation. "); + + /* Check if this is a continuation vendor ID */ + if (readarr[0] == 0x7f) { + if (!oddparity(readarr[1])) -+ printf_debug("RDID byte 1 parity violation. "); ++ msg_cdbg("RDID byte 1 parity violation. "); + id1 = (readarr[0] << 8) | readarr[1]; + id2 = readarr[2]; + if (bytes > 3) { @@ -19617,7 +21034,7 @@ index 0000000..54121b0 + id2 = (readarr[1] << 8) | readarr[2]; + } + -+ printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); ++ msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); + + if (id1 == flash->manufacture_id && id2 == flash->model_id) { + /* Print the status register to tell the @@ -19672,7 +21089,7 @@ index 0000000..54121b0 +#endif + return probe_spi_rdid_generic(flash, 4); + default: -+ printf_debug("4b ID not supported on this SPI controller\n"); ++ msg_cinfo("4b ID not supported on this SPI controller\n"); + } + + return 0; @@ -19689,7 +21106,7 @@ index 0000000..54121b0 + id1 = readarr[0]; + id2 = readarr[1]; + -+ printf_debug("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2); ++ msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2); + + if (id1 == flash->manufacture_id && id2 == flash->model_id) { + /* Print the status register to tell the @@ -19742,7 +21159,7 @@ index 0000000..54121b0 + + /* FIXME: Handle the case where RES gives a 2-byte response. */ + id2 = readarr[0]; -+ printf_debug("%s: id 0x%x\n", __func__, id2); ++ msg_cdbg("%s: id 0x%x\n", __func__, id2); + if (id2 != flash->model_id) + return 0; + @@ -19763,7 +21180,7 @@ index 0000000..54121b0 + /* Read Status Register */ + ret = spi_send_command(sizeof(cmd), sizeof(readarr), cmd, readarr); + if (ret) -+ fprintf(stderr, "RDSR failed!\n"); ++ msg_cerr("RDSR failed!\n"); + + return readarr[0]; +} @@ -19771,17 +21188,17 @@ index 0000000..54121b0 +/* Prettyprint the status register. Common definitions. */ +void spi_prettyprint_status_register_common(uint8_t status) +{ -+ printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is " ++ msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is " + "%sset\n", (status & (1 << 5)) ? "" : "not "); -+ printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is " ++ msg_cdbg("Chip status register: Bit 4 / Block Protect 2 (BP2) is " + "%sset\n", (status & (1 << 4)) ? "" : "not "); -+ printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is " ++ msg_cdbg("Chip status register: Bit 3 / Block Protect 1 (BP1) is " + "%sset\n", (status & (1 << 3)) ? "" : "not "); -+ printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is " ++ msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is " + "%sset\n", (status & (1 << 2)) ? "" : "not "); -+ printf_debug("Chip status register: Write Enable Latch (WEL) is " ++ msg_cdbg("Chip status register: Write Enable Latch (WEL) is " + "%sset\n", (status & (1 << 1)) ? "" : "not "); -+ printf_debug("Chip status register: Write In Progress (WIP/BUSY) is " ++ msg_cdbg("Chip status register: Write In Progress (WIP/BUSY) is " + "%sset\n", (status & (1 << 0)) ? "" : "not "); +} + @@ -19791,18 +21208,18 @@ index 0000000..54121b0 + */ +void spi_prettyprint_status_register_st_m25p(uint8_t status) +{ -+ printf_debug("Chip status register: Status Register Write Disable " ++ msg_cdbg("Chip status register: Status Register Write Disable " + "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not "); -+ printf_debug("Chip status register: Bit 6 is " ++ msg_cdbg("Chip status register: Bit 6 is " + "%sset\n", (status & (1 << 6)) ? "" : "not "); + spi_prettyprint_status_register_common(status); +} + +void spi_prettyprint_status_register_sst25(uint8_t status) +{ -+ printf_debug("Chip status register: Block Protect Write Disable " ++ msg_cdbg("Chip status register: Block Protect Write Disable " + "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not "); -+ printf_debug("Chip status register: Auto Address Increment Programming " ++ msg_cdbg("Chip status register: Auto Address Increment Programming " + "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not "); + spi_prettyprint_status_register_common(status); +} @@ -19822,7 +21239,7 @@ index 0000000..54121b0 + "all", "all" + }; + spi_prettyprint_status_register_sst25(status); -+ printf_debug("Resulting block protection : %s\n", ++ msg_cdbg("Resulting block protection : %s\n", + bpt[(status & 0x1c) >> 2]); +} + @@ -19836,7 +21253,7 @@ index 0000000..54121b0 + "all blocks", "all blocks", "all blocks", "all blocks" + }; + spi_prettyprint_status_register_sst25(status); -+ printf_debug("Resulting block protection : %s\n", ++ msg_cdbg("Resulting block protection : %s\n", + bpt[(status & 0x1c) >> 2]); +} + @@ -19845,7 +21262,7 @@ index 0000000..54121b0 + uint8_t status; + + status = spi_read_status_register(); -+ printf_debug("Chip status register is %02x\n", status); ++ msg_cdbg("Chip status register is %02x\n", status); + switch (flash->manufacture_id) { + case ST_ID: + if (((flash->model_id & 0xff00) == 0x2000) || @@ -19896,13 +21313,13 @@ index 0000000..54121b0 + + result = spi_disable_blockprotect(); + if (result) { -+ fprintf(stderr, "spi_disable_blockprotect failed\n"); ++ msg_cerr("spi_disable_blockprotect failed\n"); + return result; + } + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution\n", ++ msg_cerr("%s failed during command execution\n", + __func__); + return result; + } @@ -19913,7 +21330,7 @@ index 0000000..54121b0 + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(1000 * 1000); + if (check_erased_range(flash, 0, flash->total_size * 1024)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + return 0; @@ -19942,13 +21359,13 @@ index 0000000..54121b0 + + result = spi_disable_blockprotect(); + if (result) { -+ fprintf(stderr, "spi_disable_blockprotect failed\n"); ++ msg_cerr("spi_disable_blockprotect failed\n"); + return result; + } + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution\n", __func__); ++ msg_cerr("%s failed during command execution\n", __func__); + return result; + } + /* Wait until the Write-In-Progress bit is cleared. @@ -19958,23 +21375,12 @@ index 0000000..54121b0 + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(1000 * 1000); + if (check_erased_range(flash, 0, flash->total_size * 1024)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + return 0; +} + -+int spi_chip_erase_60_c7(struct flashchip *flash) -+{ -+ int result; -+ result = spi_chip_erase_60(flash); -+ if (result) { -+ printf_debug("spi_chip_erase_60 failed, trying c7\n"); -+ result = spi_chip_erase_c7(flash); -+ } -+ return result; -+} -+ +int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen) +{ + int result; @@ -20003,7 +21409,7 @@ index 0000000..54121b0 + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution at address 0x%x\n", ++ msg_cerr("%s failed during command execution at address 0x%x\n", + __func__, addr); + return result; + } @@ -20013,7 +21419,7 @@ index 0000000..54121b0 + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(100 * 1000); + if (check_erased_range(flash, addr, blocklen)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + return 0; @@ -20052,7 +21458,7 @@ index 0000000..54121b0 + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution at address 0x%x\n", ++ msg_cerr("%s failed during command execution at address 0x%x\n", + __func__, addr); + return result; + } @@ -20062,7 +21468,7 @@ index 0000000..54121b0 + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(100 * 1000); + if (check_erased_range(flash, addr, blocklen)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + return 0; @@ -20099,7 +21505,7 @@ index 0000000..54121b0 + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution at address 0x%x\n", ++ msg_cerr("%s failed during command execution at address 0x%x\n", + __func__, addr); + return result; + } @@ -20109,7 +21515,7 @@ index 0000000..54121b0 + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(100 * 1000); + if (check_erased_range(flash, addr, blocklen)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + return 0; @@ -20123,17 +21529,17 @@ index 0000000..54121b0 + + spi_disable_blockprotect(); + -+ printf("Erasing chip: \n"); ++ msg_cinfo("Erasing chip: \n"); + + for (i = 0; i < total_size / erase_size; i++) { + rc = spi_block_erase_d8(flash, i * erase_size, erase_size); + if (rc) { -+ fprintf(stderr, "Error erasing block at 0x%x\n", i); ++ msg_cerr("Error erasing block at 0x%x\n", i); + break; + } + } + -+ printf("\n"); ++ msg_cinfo("\n"); + + return rc; +} @@ -20167,7 +21573,7 @@ index 0000000..54121b0 + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution at address 0x%x\n", ++ msg_cerr("%s failed during command execution at address 0x%x\n", + __func__, addr); + return result; + } @@ -20177,7 +21583,7 @@ index 0000000..54121b0 + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(10 * 1000); + if (check_erased_range(flash, addr, blocklen)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + return 0; @@ -20186,7 +21592,7 @@ index 0000000..54121b0 +int spi_block_erase_60(struct flashchip *flash, unsigned int addr, unsigned int blocklen) +{ + if ((addr != 0) || (blocklen != flash->total_size * 1024)) { -+ fprintf(stderr, "%s called with incorrect arguments\n", ++ msg_cerr("%s called with incorrect arguments\n", + __func__); + return -1; + } @@ -20196,7 +21602,7 @@ index 0000000..54121b0 +int spi_block_erase_c7(struct flashchip *flash, unsigned int addr, unsigned int blocklen) +{ + if ((addr != 0) || (blocklen != flash->total_size * 1024)) { -+ fprintf(stderr, "%s called with incorrect arguments\n", ++ msg_cerr("%s called with incorrect arguments\n", + __func__); + return -1; + } @@ -20212,7 +21618,7 @@ index 0000000..54121b0 + result = spi_send_command(sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL); + + if (result) -+ fprintf(stderr, "%s failed\n", __func__); ++ msg_cerr("%s failed\n", __func__); + + return result; +} @@ -20245,7 +21651,7 @@ index 0000000..54121b0 + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution\n", ++ msg_cerr("%s failed during command execution\n", + __func__); + } + return result; @@ -20280,7 +21686,7 @@ index 0000000..54121b0 + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution at address 0x%x\n", ++ msg_cerr("%s failed during command execution at address 0x%x\n", + __func__, addr); + } + return result; @@ -20315,11 +21721,11 @@ index 0000000..54121b0 + }}; + + if (!len) { -+ fprintf(stderr, "%s called for zero-length write\n", __func__); ++ msg_cerr("%s called for zero-length write\n", __func__); + return 1; + } + if (len > 256) { -+ fprintf(stderr, "%s called for too long a write\n", __func__); ++ msg_cerr("%s called for too long a write\n", __func__); + return 1; + } + @@ -20327,7 +21733,7 @@ index 0000000..54121b0 + + result = spi_send_multicommand(cmds); + if (result) { -+ fprintf(stderr, "%s failed during command execution at address 0x%x\n", ++ msg_cerr("%s failed during command execution at address 0x%x\n", + __func__, addr); + } + return result; @@ -20341,10 +21747,10 @@ index 0000000..54121b0 + status = spi_read_status_register(); + /* If there is block protection in effect, unprotect it first. */ + if ((status & 0x3c) != 0) { -+ printf_debug("Some block protection in effect, disabling\n"); ++ msg_cdbg("Some block protection in effect, disabling\n"); + result = spi_write_status_register(status & ~0x3c); + if (result) { -+ fprintf(stderr, "spi_write_status_register failed\n"); ++ msg_cerr("spi_write_status_register failed\n"); + return result; + } + } @@ -20416,12 +21822,12 @@ index 0000000..54121b0 + + spi_disable_blockprotect(); + /* Erase first */ -+ printf("Erasing flash before programming... "); ++ msg_cinfo("Erasing flash before programming... "); + if (erase_flash(flash)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } -+ printf("done.\n"); ++ msg_cinfo("done.\n"); + for (i = 0; i < total_size; i++) { + result = spi_byte_program(i, buf[i]); + if (result) @@ -20442,7 +21848,7 @@ index 0000000..54121b0 + switch (spi_controller) { +#if INTERNAL_SUPPORT == 1 + case SPI_CONTROLLER_WBSIO: -+ fprintf(stderr, "%s: impossible with Winbond SPI masters," ++ msg_cerr("%s: impossible with Winbond SPI masters," + " degrading to byte program\n", __func__); + return spi_chip_write_1(flash, buf); +#endif @@ -20450,7 +21856,7 @@ index 0000000..54121b0 + break; + } + if (erase_flash(flash)) { -+ fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + /* FIXME: This will fail on ICH/VIA SPI. */ @@ -20471,7 +21877,7 @@ index 0000000..54121b0 + return 0; +} diff --git a/sst28sf040.c b/sst28sf040.c -index 35f8c27..bbb9d56 100644 +index 35f8c27..b9e33ab 100644 --- a/sst28sf040.c +++ b/sst28sf040.c @@ -3,6 +3,7 @@ @@ -20537,7 +21943,14 @@ index 35f8c27..bbb9d56 100644 { chipaddr bios = flash->virtual_memory; -@@ -71,7 +69,7 @@ static int erase_sector_28sf040(struct flashchip *flash, unsigned long address, +@@ -65,13 +63,13 @@ static int erase_sector_28sf040(struct flashchip *flash, unsigned long address, + toggle_ready_jedec(bios); + + if (check_erased_range(flash, address, sector_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } return 0; } @@ -20546,16 +21959,72 @@ index 35f8c27..bbb9d56 100644 unsigned int page_size) { int i; -@@ -111,7 +109,7 @@ int probe_28sf040(struct flashchip *flash) - chip_writeb(RESET, bios); - programmer_delay(10); +@@ -94,30 +92,6 @@ static int write_sector_28sf040(chipaddr bios, uint8_t *src, chipaddr dst, + return 0; + } +-int probe_28sf040(struct flashchip *flash) +-{ +- chipaddr bios = flash->virtual_memory; +- uint8_t id1, id2; +- +- chip_writeb(RESET, bios); +- programmer_delay(10); +- +- chip_writeb(READ_ID, bios); +- programmer_delay(10); +- id1 = chip_readb(bios); +- programmer_delay(10); +- id2 = chip_readb(bios + 0x01); +- +- chip_writeb(RESET, bios); +- programmer_delay(10); +- - printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2); -+ printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); - if (id1 == flash->manufacture_id && id2 == flash->model_id) - return 1; +- if (id1 == flash->manufacture_id && id2 == flash->model_id) +- return 1; +- +- return 0; +-} +- + int erase_28sf040(struct flashchip *flash) + { + chipaddr bios = flash->virtual_memory; +@@ -131,7 +105,7 @@ int erase_28sf040(struct flashchip *flash) + toggle_ready_jedec(bios); -@@ -166,3 +164,13 @@ int write_28sf040(struct flashchip *flash, uint8_t *buf) + if (check_erased_range(flash, 0, flash->total_size * 1024)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + return 0; +@@ -146,23 +120,33 @@ int write_28sf040(struct flashchip *flash, uint8_t *buf) + + unprotect_28sf040(bios); + +- printf("Programming page: "); ++ msg_cinfo("Programming page: "); + for (i = 0; i < total_size / page_size; i++) { + /* erase the page before programming */ + if (erase_sector_28sf040(flash, i * page_size, page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } + + /* write to the sector */ +- printf("%04d at address: 0x%08x", i, i * page_size); ++ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); + write_sector_28sf040(bios, buf + i * page_size, + bios + i * page_size, page_size); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); + } +- printf("\n"); ++ msg_cinfo("\n"); + + protect_28sf040(bios); return 0; } @@ -20563,7 +22032,7 @@ index 35f8c27..bbb9d56 100644 +int erase_chip_28sf040(struct flashchip *flash, unsigned int addr, unsigned int blocklen) +{ + if ((addr != 0) || (blocklen != flash->total_size * 1024)) { -+ fprintf(stderr, "%s called with incorrect arguments\n", ++ msg_cerr("%s called with incorrect arguments\n", + __func__); + return -1; + } @@ -20648,7 +22117,7 @@ index ab1c918..0000000 - return 0; -} diff --git a/sst49lfxxxc.c b/sst49lfxxxc.c -index 848ccde..9f9ee30 100644 +index 848ccde..1331cda 100644 --- a/sst49lfxxxc.c +++ b/sst49lfxxxc.c @@ -3,6 +3,7 @@ @@ -20659,87 +22128,214 @@ index 848ccde..9f9ee30 100644 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -@@ -21,6 +22,7 @@ +@@ -21,19 +22,16 @@ #include #include "flash.h" +#include "chipdrivers.h" - #define SECTOR_ERASE 0x30 - #define BLOCK_ERASE 0x20 -@@ -35,6 +37,15 @@ - #define STATUS_ESS (1 << 6) - #define STATUS_WSMS (1 << 7) - +-#define SECTOR_ERASE 0x30 +-#define BLOCK_ERASE 0x20 +-#define ERASE 0xD0 +-#define AUTO_PGRM 0x10 +-#define RESET 0xFF +-#define READ_ID 0x90 +-#define READ_STATUS 0x70 +-#define CLEAR_STATUS 0x50 +int unlock_block_49lfxxxc(struct flashchip *flash, unsigned long address, unsigned char bits) +{ + unsigned long lock = flash->virtual_registers + address + 2; -+ printf_debug("lockbits at address=0x%08lx is 0x%01x\n", lock, chip_readb(lock)); ++ msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", lock, chip_readb(lock)); + chip_writeb(bits, lock); -+ + +-#define STATUS_BPS (1 << 1) +-#define STATUS_ESS (1 << 6) +-#define STATUS_WSMS (1 << 7) + return 0; +} -+ + static int write_lockbits_49lfxxxc(struct flashchip *flash, unsigned char bits) { - chipaddr registers = flash->virtual_registers; -@@ -72,7 +83,12 @@ static int write_lockbits_49lfxxxc(struct flashchip *flash, unsigned char bits) +@@ -41,30 +39,30 @@ static int write_lockbits_49lfxxxc(struct flashchip *flash, unsigned char bits) + int i, left = flash->total_size * 1024; + unsigned long address; + +- printf_debug("\nbios=0x%08lx\n", registers); ++ msg_cdbg("\nbios=0x%08lx\n", registers); + for (i = 0; left > 65536; i++, left -= 65536) { +- printf_debug("lockbits at address=0x%08lx is 0x%01x\n", ++ msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", + registers + (i * 65536) + 2, + chip_readb(registers + (i * 65536) + 2)); + chip_writeb(bits, registers + (i * 65536) + 2); + } + address = i * 65536; +- printf_debug("lockbits at address=0x%08lx is 0x%01x\n", ++ msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", + registers + address + 2, + chip_readb(registers + address + 2)); + chip_writeb(bits, registers + address + 2); + address += 32768; +- printf_debug("lockbits at address=0x%08lx is 0x%01x\n", ++ msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", + registers + address + 2, + chip_readb(registers + address + 2)); + chip_writeb(bits, registers + address + 2); + address += 8192; +- printf_debug("lockbits at address=0x%08lx is 0x%01x\n", ++ msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", + registers + address + 2, + chip_readb(registers + address + 2)); + chip_writeb(bits, registers + address + 2); + address += 8192; +- printf_debug("lockbits at address=0x%08lx is 0x%01x\n", ++ msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", + registers + address + 2, + chip_readb(registers + address + 2)); + chip_writeb(bits, registers + address + 2); +@@ -72,98 +70,25 @@ static int write_lockbits_49lfxxxc(struct flashchip *flash, unsigned char bits) return 0; } -static int erase_sector_49lfxxxc(struct flashchip *flash, unsigned long address, int sector_size) +-{ +- unsigned char status; +- chipaddr bios = flash->virtual_memory; +- +- chip_writeb(SECTOR_ERASE, bios); +- chip_writeb(ERASE, bios + address); +- +- do { +- status = chip_readb(bios); +- if (status & (STATUS_ESS | STATUS_BPS)) { +- printf("sector erase FAILED at address=0x%08lx status=0x%01x\n", bios + address, status); +- chip_writeb(CLEAR_STATUS, bios); +- return (-1); +- } +- } while (!(status & STATUS_WSMS)); +- chip_writeb(RESET, bios); +- +- if (check_erased_range(flash, address, sector_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- return 0; +-} +- +-static int write_sector_49lfxxxc(chipaddr bios, uint8_t *src, chipaddr dst, +- unsigned int page_size) +-{ +- int i; +- unsigned char status; +- +- chip_writeb(CLEAR_STATUS, bios); +- for (i = 0; i < page_size; i++) { +- /* transfer data from source to destination */ +- if (*src == 0xFF) { +- dst++, src++; +- /* If the data is 0xFF, don't program it */ +- continue; +- } +- /*issue AUTO PROGRAM command */ +- chip_writeb(AUTO_PGRM, bios); +- chip_writeb(*src++, dst++); +- +- do { +- status = chip_readb(bios); +- if (status & (STATUS_ESS | STATUS_BPS)) { +- printf("sector write FAILED at address=0x%08lx status=0x%01x\n", dst, status); +- chip_writeb(CLEAR_STATUS, bios); +- return (-1); +- } +- } while (!(status & STATUS_WSMS)); +- } +- +- return 0; +-} +- +-int probe_49lfxxxc(struct flashchip *flash) +int unlock_49lfxxxc(struct flashchip *flash) -+{ + { +- chipaddr bios = flash->virtual_memory; +- uint8_t id1, id2; +- +- chip_writeb(RESET, bios); +- +- chip_writeb(READ_ID, bios); +- id1 = chip_readb(bios); +- id2 = chip_readb(bios + 0x01); +- +- chip_writeb(RESET, bios); +- +- printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2); +- +- if (!(id1 == flash->manufacture_id && id2 == flash->model_id)) +- return 0; +- +- map_flash_registers(flash); +- +- return 1; + return write_lockbits_49lfxxxc(flash, 0); -+} -+ + } + +-int erase_49lfxxxc(struct flashchip *flash) +int erase_sector_49lfxxxc(struct flashchip *flash, unsigned int address, unsigned int sector_size) { - unsigned char status; ++ uint8_t status; chipaddr bios = flash->virtual_memory; -@@ -97,6 +113,31 @@ static int erase_sector_49lfxxxc(struct flashchip *flash, unsigned long address, +- int i; +- unsigned int total_size = flash->total_size * 1024; + +- write_lockbits_49lfxxxc(flash, 0); +- for (i = 0; i < total_size; i += flash->page_size) +- if (erase_sector_49lfxxxc(flash, i, flash->page_size)) +- return (-1); ++ chip_writeb(0x30, bios); ++ chip_writeb(0xD0, bios + address); + +- chip_writeb(RESET, bios); ++ status = wait_82802ab(bios); + ++ if (check_erased_range(flash, address, sector_size)) { ++ msg_cerr("ERASE FAILED!\n"); ++ return -1; ++ } return 0; } -+int erase_block_49lfxxxc(struct flashchip *flash, unsigned int address, unsigned int block_size) -+{ -+ unsigned char status; -+ chipaddr bios = flash->virtual_memory; -+ -+ chip_writeb(BLOCK_ERASE, bios); -+ chip_writeb(ERASE, bios + address); -+ -+ do { -+ status = chip_readb(bios); -+ if (status & (STATUS_ESS | STATUS_BPS)) { -+ printf("block erase FAILED at address=0x%08lx status=0x%01x\n", bios + address, status); -+ chip_writeb(CLEAR_STATUS, bios); -+ return (-1); -+ } -+ } while (!(status & STATUS_WSMS)); -+ chip_writeb(RESET, bios); -+ -+ if (check_erased_range(flash, address, block_size)) { -+ fprintf(stderr, "ERASE FAILED!\n"); -+ return -1; -+ } -+ return 0; -+} -+ - static int write_sector_49lfxxxc(chipaddr bios, uint8_t *src, chipaddr dst, - unsigned int page_size) - { -@@ -141,7 +182,7 @@ int probe_49lfxxxc(struct flashchip *flash) +@@ -175,23 +100,23 @@ int write_49lfxxxc(struct flashchip *flash, uint8_t *buf) + chipaddr bios = flash->virtual_memory; - chip_writeb(RESET, bios); + write_lockbits_49lfxxxc(flash, 0); +- printf("Programming page: "); ++ msg_cinfo("Programming page: "); + for (i = 0; i < total_size / page_size; i++) { + /* erase the page before programming */ + if (erase_sector_49lfxxxc(flash, i * page_size, flash->page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } -- printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2); -+ printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); + /* write to the sector */ +- printf("%04d at address: 0x%08x", i, i * page_size); +- write_sector_49lfxxxc(bios, buf + i * page_size, ++ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); ++ write_page_82802ab(bios, buf + i * page_size, + bios + i * page_size, page_size); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); + } +- printf("\n"); ++ msg_cinfo("\n"); - if (!(id1 == flash->manufacture_id && id2 == flash->model_id)) - return 0; +- chip_writeb(RESET, bios); ++ chip_writeb(0xFF, bios); + + return 0; + } diff --git a/sst_fwhub.c b/sst_fwhub.c -index e7ae9e9..9819cee 100644 +index e7ae9e9..2b867c8 100644 --- a/sst_fwhub.c +++ b/sst_fwhub.c @@ -2,6 +2,8 @@ @@ -20751,69 +22347,137 @@ index e7ae9e9..9819cee 100644 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -@@ -20,7 +22,10 @@ +@@ -20,19 +22,10 @@ /* Adapted from the Intel FW hub stuff for 82802ax parts. */ +#include +#include #include "flash.h" +- +-// I need that Berkeley bit-map printer +-void print_sst_fwhub_status(uint8_t status) +-{ +- printf("%s", status & 0x80 ? "Ready:" : "Busy:"); +- printf("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:"); +- printf("%s", status & 0x20 ? "BE ERROR:" : "BE OK:"); +- printf("%s", status & 0x10 ? "PROG ERR:" : "PROG OK:"); +- printf("%s", status & 0x8 ? "VP ERR:" : "VPP OK:"); +- printf("%s", status & 0x4 ? "PROG SUSPEND:" : "PROG RUN/FINISH:"); +- printf("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:"); +-} +#include "chipdrivers.h" - // I need that Berkeley bit-map printer - void print_sst_fwhub_status(uint8_t status) -@@ -86,15 +91,13 @@ int probe_sst_fwhub(struct flashchip *flash) - if (probe_jedec(flash) == 0) - return 0; + int check_sst_fwhub_block_lock(struct flashchip *flash, int offset) + { +@@ -40,20 +33,20 @@ int check_sst_fwhub_block_lock(struct flashchip *flash, int offset) + uint8_t blockstatus; + blockstatus = chip_readb(registers + offset + 2); +- printf_debug("Lock status for 0x%06x (size 0x%06x) is %02x, ", ++ msg_cdbg("Lock status for 0x%06x (size 0x%06x) is %02x, ", + offset, flash->page_size, blockstatus); + switch (blockstatus & 0x3) { + case 0x0: +- printf_debug("full access\n"); ++ msg_cdbg("full access\n"); + break; + case 0x1: +- printf_debug("write locked\n"); ++ msg_cdbg("write locked\n"); + break; + case 0x2: +- printf_debug("locked open\n"); ++ msg_cdbg("locked open\n"); + break; + case 0x3: +- printf_debug("write locked down\n"); ++ msg_cdbg("write locked down\n"); + break; + } + /* Return content of the write_locked bit */ +@@ -68,93 +61,38 @@ int clear_sst_fwhub_block_lock(struct flashchip *flash, int offset) + blockstatus = check_sst_fwhub_block_lock(flash, offset); + + if (blockstatus) { +- printf_debug("Trying to clear lock for 0x%06x... ", offset) ++ msg_cdbg("Trying to clear lock for 0x%06x... ", offset); + chip_writeb(0, registers + offset + 2); + + blockstatus = check_sst_fwhub_block_lock(flash, offset); +- printf_debug("%s\n", (blockstatus) ? "failed" : "OK"); ++ msg_cdbg("%s\n", (blockstatus) ? "failed" : "OK"); + } + + return blockstatus; + } + +-/* probe_jedec works fine for probing */ +-int probe_sst_fwhub(struct flashchip *flash) ++int printlock_sst_fwhub(struct flashchip *flash) + { + int i; + +- if (probe_jedec(flash) == 0) +- return 0; +- - map_flash_registers(flash); - for (i = 0; i < flash->total_size * 1024; i += flash->page_size) check_sst_fwhub_block_lock(flash, i); - return 1; - } - +- return 1; +-} +- -int erase_sst_fwhub_block(struct flashchip *flash, int offset, int page_size) -+int erase_sst_fwhub_block(struct flashchip *flash, unsigned int offset, unsigned int page_size) - { - uint8_t blockstatus = clear_sst_fwhub_block_lock(flash, offset); - -@@ -113,6 +116,25 @@ int erase_sst_fwhub_block(struct flashchip *flash, int offset, int page_size) +-{ +- uint8_t blockstatus = clear_sst_fwhub_block_lock(flash, offset); +- +- if (blockstatus) { +- printf("Block lock clearing failed, not erasing block " +- "at 0x%06x\n", offset); +- return 1; +- } +- +- if (erase_block_jedec(flash, offset, page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- toggle_ready_jedec(flash->virtual_memory); +- return 0; } -+int erase_sst_fwhub_sector(struct flashchip *flash, unsigned int offset, unsigned int page_size) -+{ -+ uint8_t blockstatus = clear_sst_fwhub_block_lock(flash, offset); -+ -+ if (blockstatus) { -+ printf("Sector lock clearing failed, not erasing sector " -+ "at 0x%06x\n", offset); -+ return 1; -+ } -+ -+ if (erase_sector_jedec(flash, offset, page_size)) { -+ fprintf(stderr, "ERASE FAILED!\n"); -+ return -1; -+ } -+ toggle_ready_jedec(flash->virtual_memory); -+ -+ return 0; -+} -+ - int erase_sst_fwhub(struct flashchip *flash) - { - int i; -@@ -130,28 +152,33 @@ int erase_sst_fwhub(struct flashchip *flash) - - int write_sst_fwhub(struct flashchip *flash, uint8_t *buf) +-int erase_sst_fwhub(struct flashchip *flash) ++int unlock_sst_fwhub(struct flashchip *flash) { - int i; -+ int i, rc; - int total_size = flash->total_size * 1024; - int page_size = flash->page_size; - chipaddr bios = flash->virtual_memory; +- unsigned int total_size = flash->total_size * 1024; ++ int i, ret=0; + +- for (i = 0; i < total_size; i += flash->page_size) { +- if (erase_sst_fwhub_block(flash, i, flash->page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; ++ for (i = 0; i < flash->total_size * 1024; i += flash->page_size) ++ { ++ if (clear_sst_fwhub_block_lock(flash, i)) ++ { ++ msg_cdbg("Warning: Unlock Failed for block 0x%06x\n", i); ++ ret++; + } + } +- +- return 0; ++ return ret; + } + +-int write_sst_fwhub(struct flashchip *flash, uint8_t *buf) +-{ +- int i; +- int total_size = flash->total_size * 1024; +- int page_size = flash->page_size; +- chipaddr bios = flash->virtual_memory; - uint8_t blockstatus; - - // FIXME: We want block wide erase instead of ironing the whole chip @@ -20822,40 +22486,24 @@ index e7ae9e9..9819cee 100644 - return -1; - } - -+ uint8_t *readbuf = malloc(page_size); -+ - printf("Programming page: "); - for (i = 0; i < total_size / page_size; i++) { - printf("%04d at address: 0x%08x", i, i * page_size); +- printf("Programming page: "); +- for (i = 0; i < total_size / page_size; i++) { +- printf("%04d at address: 0x%08x", i, i * page_size); - blockstatus = clear_sst_fwhub_block_lock(flash, i * page_size); - if (blockstatus) { - printf(" is locked down permanently, aborting\n"); - return 1; -+ -+ /* Auto Skip Blocks, which already contain the desired data: -+ * Faster, because we only write, what has changed -+ * More secure, because blocks, which are excluded -+ * (with the exclude or layout feature) -+ * are not erased and rewritten; data is retained also -+ * in sudden power off situations -+ */ -+ flash->read(flash, readbuf, i * page_size, page_size); -+ if (memcmp((void *)(buf + i * page_size), -+ (void *)(readbuf), page_size)) { -+ rc = erase_sst_fwhub_block(flash, i * page_size, -+ page_size); -+ if (rc) -+ return 1; -+ write_sector_jedec_common(flash, buf + i * page_size, -+ bios + i * page_size, page_size, 0xffff); - } +- } - write_sector_jedec(bios, buf + i * page_size, - bios + i * page_size, page_size); - printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); - } - printf("\n"); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- } +- printf("\n"); +- +- return 0; +-} diff --git a/stm50flw0x0x.c b/stm50flw0x0x.c -index 30b7d50..7095aec 100644 +index 30b7d50..3539395 100644 --- a/stm50flw0x0x.c +++ b/stm50flw0x0x.c @@ -2,6 +2,7 @@ @@ -20866,7 +22514,7 @@ index 30b7d50..7095aec 100644 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -@@ -30,82 +31,21 @@ +@@ -30,88 +31,7 @@ #include #include "flash.h" #include "flashchips.h" @@ -20930,135 +22578,377 @@ index 30b7d50..7095aec 100644 - - return 1; -} -+#include "chipdrivers.h" - - static void wait_stm50flw0x0x(chipaddr bios) - { +- +-static void wait_stm50flw0x0x(chipaddr bios) +-{ - uint8_t id1; - // id2; - - chip_writeb(0x70, bios); - if ((chip_readb(bios) & 0x80) == 0) { // it's busy - while ((chip_readb(bios) & 0x80) == 0) ; - } -+ - // put another command to get out of status register mode - - chip_writeb(0x90, bios); - programmer_delay(10); - +- chip_writeb(0x70, bios); +- if ((chip_readb(bios) & 0x80) == 0) { // it's busy +- while ((chip_readb(bios) & 0x80) == 0) ; +- } +- // put another command to get out of status register mode +- +- chip_writeb(0x90, bios); +- programmer_delay(10); +- - id1 = chip_readb(bios); -+ chip_readb(bios); // Read device ID (to make sure?) +- +- // this is needed to jam it out of "read id" mode +- chip_writeb(0xAA, bios + 0x5555); +- chip_writeb(0x55, bios + 0x2AAA); +- chip_writeb(0xF0, bios + 0x5555); +-} ++#include "chipdrivers.h" - // this is needed to jam it out of "read id" mode - chip_writeb(0xAA, bios + 0x5555); -@@ -161,9 +101,9 @@ int unlock_block_stm50flw0x0x(struct flashchip *flash, int offset) + /* + * claus.gindhart@kontron.com +@@ -129,7 +49,7 @@ int unlock_block_stm50flw0x0x(struct flashchip *flash, int offset) + * to them. The size of the locking sectors depends on the type + * of chip. + * +- * Sometimes, the BIOS does this for you; so you propably ++ * Sometimes, the BIOS does this for you; so you probably + * don't need to worry about that. + */ + +@@ -141,19 +61,19 @@ int unlock_block_stm50flw0x0x(struct flashchip *flash, int offset) + + // unlock each 4k-sector + for (j = 0; j < 0x10000; j += 0x1000) { +- printf_debug("unlocking at 0x%x\n", offset + j); ++ msg_cdbg("unlocking at 0x%x\n", offset + j); + chip_writeb(unlock_sector, wrprotect + offset + j); + if (chip_readb(wrprotect + offset + j) != unlock_sector) { +- printf("Cannot unlock sector @ 0x%x\n", ++ msg_cerr("Cannot unlock sector @ 0x%x\n", + offset + j); + return -1; + } + } + } else { +- printf_debug("unlocking at 0x%x\n", offset); ++ msg_cdbg("unlocking at 0x%x\n", offset); + chip_writeb(unlock_sector, wrprotect + offset); + if (chip_readb(wrprotect + offset) != unlock_sector) { +- printf("Cannot unlock sector @ 0x%x\n", offset); ++ msg_cerr("Cannot unlock sector @ 0x%x\n", offset); + return -1; + } + } +@@ -161,138 +81,69 @@ int unlock_block_stm50flw0x0x(struct flashchip *flash, int offset) return 0; } -int erase_block_stm50flw0x0x(struct flashchip *flash, int offset) -+int erase_block_stm50flw0x0x(struct flashchip *flash, unsigned int block, unsigned int blocksize) ++int unlock_stm50flw0x0x(struct flashchip *flash) { - chipaddr bios = flash->virtual_memory + offset; -+ chipaddr bios = flash->virtual_memory + block; - - // clear status register - chip_writeb(0x50, bios); -@@ -175,11 +115,34 @@ int erase_block_stm50flw0x0x(struct flashchip *flash, int offset) - - wait_stm50flw0x0x(flash->virtual_memory); +- +- // clear status register +- chip_writeb(0x50, bios); +- printf_debug("Erase at 0x%lx\n", bios); +- // now start it +- chip_writeb(0x20, bios); +- chip_writeb(0xd0, bios); +- programmer_delay(10); +- +- wait_stm50flw0x0x(flash->virtual_memory); ++ int i; - if (check_erased_range(flash, offset, flash->page_size)) { -+ if (check_erased_range(flash, block, blocksize)) { -+ fprintf(stderr, "ERASE FAILED!\n"); -+ return -1; -+ } -+ printf("DONE BLOCK 0x%x\n", block); -+ -+ return 0; -+} -+ +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; ++ for (i = 0; i < flash->total_size * 1024; i+= flash->page_size) { ++ if(unlock_block_stm50flw0x0x(flash, i)) { ++ msg_cerr("UNLOCK FAILED!\n"); ++ return -1; ++ } + } +- printf("DONE BLOCK 0x%x\n", offset); + + return 0; + } + +-int write_page_stm50flw0x0x(chipaddr bios, uint8_t *src, +- chipaddr dst, int page_size) +int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize) -+{ + { +- int i, rc = 0; +- chipaddr d = dst; +- uint8_t *s = src; + chipaddr bios = flash->virtual_memory + sector; -+ + +- /* transfer data from source to destination */ +- for (i = 0; i < page_size; i++) { +- chip_writeb(0x40, dst); +- chip_writeb(*src++, dst++); +- wait_stm50flw0x0x(bios); +- } + // clear status register + chip_writeb(0x50, bios); -+ printf_debug("Erase at 0x%lx\n", bios); ++ msg_cdbg("Erase at 0x%lx\n", bios); + // now start it + chip_writeb(0x32, bios); + chip_writeb(0xd0, bios); + programmer_delay(10); -+ -+ wait_stm50flw0x0x(flash->virtual_memory); -+ -+ if (check_erased_range(flash, sector, sectorsize)) { - fprintf(stderr, "ERASE FAILED!\n"); - return -1; - } -- printf("DONE BLOCK 0x%x\n", offset); -+ printf("DONE BLOCK 0x%x\n", sector); - return 0; +-/* claus.gindhart@kontron.com +- * TODO +- * I think, that verification is not required, but +- * i leave it in anyway +- */ +- dst = d; +- src = s; +- for (i = 0; i < page_size; i++) { +- if (chip_readb(dst) != *src) { +- rc = -1; +- break; +- } +- dst++; +- src++; +- } ++ wait_82802ab(flash->virtual_memory); + +- if (rc) { +- fprintf(stderr, " page 0x%lx failed!\n", +- (d - bios) / page_size); ++ if (check_erased_range(flash, sector, sectorsize)) { ++ msg_cerr("ERASE FAILED!\n"); ++ return -1; + } ++ msg_cinfo("DONE BLOCK 0x%x\n", sector); + +- return rc; ++ return 0; } -@@ -230,7 +193,6 @@ int erase_stm50flw0x0x(struct flashchip *flash) + +-/* I simply erase block by block +- * I Chip This is not the fastest way, but it works +- */ +-int erase_stm50flw0x0x(struct flashchip *flash) ++int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen) + { int i; int total_size = flash->total_size * 1024; int page_size = flash->page_size; - chipaddr bios = flash->virtual_memory; - printf("Erasing page:\n"); - for (i = 0; i < total_size / page_size; i++) { -@@ -241,17 +203,26 @@ int erase_stm50flw0x0x(struct flashchip *flash) - fprintf(stderr, "UNLOCK FAILED!\n"); - return -1; - } -- if (erase_block_stm50flw0x0x(flash, i * page_size)) { -+ if (erase_block_stm50flw0x0x(flash, i * page_size, page_size)) { - fprintf(stderr, "ERASE FAILED!\n"); - return -1; - } - } - printf("\n"); -- protect_stm50flw0x0x(bios); - - return 0; - } - -+int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen) -+{ +- printf("Erasing page:\n"); + if ((addr != 0) || (blocklen != flash->total_size * 1024)) { + msg_cerr("%s called with incorrect arguments\n", + __func__); + return -1; + } -+ return erase_stm50flw0x0x(flash); -+} + - int write_stm50flw0x0x(struct flashchip *flash, uint8_t * buf) - { - int i, rc = 0; -@@ -285,13 +256,12 @@ int write_stm50flw0x0x(struct flashchip *flash, uint8_t * buf) - - rc = unlock_block_stm50flw0x0x(flash, i * page_size); - if (!rc) -- rc = erase_block_stm50flw0x0x(flash, i * page_size); -+ rc = erase_block_stm50flw0x0x(flash, i * page_size, page_size); - if (!rc) - write_page_stm50flw0x0x(bios, buf + i * page_size, - bios + i * page_size, page_size); ++ msg_cinfo("Erasing page:\n"); + for (i = 0; i < total_size / page_size; i++) { +- printf +- ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- printf("%04d at address: 0x%08x ", i, i * page_size); +- if (unlock_block_stm50flw0x0x(flash, i * page_size)) { +- fprintf(stderr, "UNLOCK FAILED!\n"); +- return -1; +- } +- if (erase_block_stm50flw0x0x(flash, i * page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); ++ msg_cinfo("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); ++ msg_cinfo("%04d at address: 0x%08x ", i, i * page_size); ++ //if (unlock_block_stm50flw0x0x(flash, i * page_size)) { ++ // msg_cerr("UNLOCK FAILED!\n"); ++ // return -1; ++ //} ++ if (erase_block_82802ab(flash, i * page_size, page_size)) { ++ msg_cerr("ERASE FAILED!\n"); + return -1; + } } - printf("\n"); +- printf("\n"); - protect_stm50flw0x0x(bios); - free(tmpbuf); ++ msg_cinfo("\n"); - return rc; + return 0; + } +- +-int write_stm50flw0x0x(struct flashchip *flash, uint8_t * buf) +-{ +- int i, rc = 0; +- int total_size = flash->total_size * 1024; +- int page_size = flash->page_size; +- chipaddr bios = flash->virtual_memory; +- uint8_t *tmpbuf = malloc(page_size); +- +- if (!tmpbuf) { +- printf("Could not allocate memory!\n"); +- exit(1); +- } +- printf("Programming page: \n"); +- for (i = 0; (i < total_size / page_size) && (rc == 0); i++) { +- printf +- ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- printf("%04d at address: 0x%08x ", i, i * page_size); +- +- /* Auto Skip Blocks, which already contain the desired data +- * Faster, because we only write, what has changed +- * More secure, because blocks, which are excluded +- * (with the exclude or layout feature) +- * are not erased and rewritten; data is retained also +- * in sudden power off situations +- */ +- chip_readn(tmpbuf, bios + i * page_size, page_size); +- if (!memcmp((void *)(buf + i * page_size), tmpbuf, page_size)) { +- printf("SKIPPED\n"); +- continue; +- } +- +- rc = unlock_block_stm50flw0x0x(flash, i * page_size); +- if (!rc) +- rc = erase_block_stm50flw0x0x(flash, i * page_size); +- if (!rc) +- write_page_stm50flw0x0x(bios, buf + i * page_size, +- bios + i * page_size, page_size); +- } +- printf("\n"); +- protect_stm50flw0x0x(bios); +- free(tmpbuf); +- +- return rc; +-} diff --git a/udelay.c b/udelay.c -index 9a0ab36..f61d793 100644 +index 9a0ab36..bae6467 100644 --- a/udelay.c +++ b/udelay.c -@@ -63,3 +63,16 @@ void myusec_calibrate_delay(void) - (unsigned long)micro, timeusec); +@@ -2,6 +2,7 @@ + * This file is part of the flashrom project. + * + * Copyright (C) 2000 Silicon Integrated System Corporation ++ * Copyright (C) 2009,2010 Carl-Daniel Hailfinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -19,47 +20,111 @@ + */ + + #include ++#include ++#include + #include "flash.h" + +-// count to a billion. Time it. If it's < 1 sec, count to 10B, etc. ++/* loops per microsecond */ + unsigned long micro = 1; + +-void myusec_delay(int usecs) ++__attribute__ ((noinline)) void myusec_delay(int usecs) + { +- volatile unsigned long i; +- for (i = 0; i < usecs * micro; i++) ; ++ unsigned long i; ++ for (i = 0; i < usecs * micro; i++) { ++ /* Make sure the compiler doesn't optimize the loop away. */ ++ asm volatile ("" : : "rm" (i) ); ++ } + } + +-void myusec_calibrate_delay(void) ++unsigned long measure_delay(int usecs) + { +- int count = 1000; + unsigned long timeusec; + struct timeval start, end; +- int ok = 0; ++ ++ gettimeofday(&start, 0); ++ myusec_delay(usecs); ++ gettimeofday(&end, 0); ++ timeusec = 1000000 * (end.tv_sec - start.tv_sec) + ++ (end.tv_usec - start.tv_usec); ++ /* Protect against time going forward too much. */ ++ if ((end.tv_sec > start.tv_sec) && ++ ((end.tv_sec - start.tv_sec) >= LONG_MAX / 1000000 - 1)) ++ timeusec = LONG_MAX; ++ /* Protect against time going backwards during leap seconds. */ ++ if ((end.tv_sec < start.tv_sec) || (timeusec > LONG_MAX)) ++ timeusec = 1; ++ ++ return timeusec; ++} ++ ++void myusec_calibrate_delay(void) ++{ ++ unsigned long count = 1000; ++ unsigned long timeusec; ++ int i, tries = 0; + + printf("Calibrating delay loop... "); + +- while (!ok) { +- gettimeofday(&start, 0); +- myusec_delay(count); +- gettimeofday(&end, 0); +- timeusec = 1000000 * (end.tv_sec - start.tv_sec) + +- (end.tv_usec - start.tv_usec); ++recalibrate: ++ count = 1000; ++ while (1) { ++ timeusec = measure_delay(count); ++ if (timeusec > 1000000 / 4) ++ break; ++ if (count >= ULONG_MAX / 2) { ++ msg_pinfo("timer loop overflow, reduced precision. "); ++ break; ++ } + count *= 2; +- if (timeusec < 1000000 / 4) +- continue; +- ok = 1; + } ++ tries ++; + +- // compute one microsecond. That will be count / time +- micro = count / timeusec; ++ /* Avoid division by zero, but in that case the loop is shot anyway. */ ++ if (!timeusec) ++ timeusec = 1; ++ ++ /* Compute rounded up number of loops per microsecond. */ ++ micro = (count * micro) / timeusec + 1; ++ msg_pdbg("%luM loops per second, ", micro); ++ ++ /* Did we try to recalibrate less than 5 times? */ ++ if (tries < 5) { ++ /* Recheck our timing to make sure we weren't just hitting ++ * a scheduler delay or something similar. ++ */ ++ for (i = 0; i < 4; i++) { ++ if (measure_delay(100) < 90) { ++ msg_pdbg("delay more than 10%% too short, " ++ "recalculating... "); ++ goto recalibrate; ++ } ++ } ++ } else { ++ msg_perr("delay loop is unreliable, trying to continue "); ++ } ++ ++ /* We're interested in the actual precision. */ ++ timeusec = measure_delay(10); ++ msg_pdbg("10 myus = %ld us, ", timeusec); ++ timeusec = measure_delay(100); ++ msg_pdbg("100 myus = %ld us, ", timeusec); ++ timeusec = measure_delay(1000); ++ msg_pdbg("1000 myus = %ld us, ", timeusec); ++ timeusec = measure_delay(10000); ++ msg_pdbg("10000 myus = %ld us, ", timeusec); + +- gettimeofday(&start, 0); +- myusec_delay(100); +- gettimeofday(&end, 0); +- timeusec = 1000000 * (end.tv_sec - start.tv_sec) + +- (end.tv_usec - start.tv_usec); +- printf_debug("%ldM loops per second, 100 myus = %ld us. ", +- (unsigned long)micro, timeusec); printf("OK.\n"); } + @@ -21075,7 +22965,7 @@ index 9a0ab36..f61d793 100644 +} + diff --git a/w29ee011.c b/w29ee011.c -index a26cd80..63cf4fc 100644 +index a26cd80..6b88a1c 100644 --- a/w29ee011.c +++ b/w29ee011.c @@ -20,6 +20,7 @@ @@ -21086,38 +22976,44 @@ index a26cd80..63cf4fc 100644 int probe_w29ee011(struct flashchip *flash) { +@@ -28,7 +29,7 @@ int probe_w29ee011(struct flashchip *flash) + extern char *chip_to_probe; + + if (!chip_to_probe || strcmp(chip_to_probe, "W29EE011")) { +- printf_debug("Probing disabled for Winbond W29EE011 because " ++ msg_cdbg("Probing disabled for Winbond W29EE011 because " + "the probing sequence puts the AMIC A49LF040A in " + "a funky state. Use 'flashrom -c W29EE011' if you " + "have a board with this chip.\n"); @@ -61,7 +62,7 @@ int probe_w29ee011(struct flashchip *flash) chip_writeb(0xF0, bios + 0x5555); programmer_delay(10); - printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2); -+ printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); ++ msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); if (id1 == flash->manufacture_id && id2 == flash->model_id) return 1; diff --git a/w39v040c.c b/w39v040c.c -index 7fccd53..20e53fa 100644 +index 7fccd53..dc4de1c 100644 --- a/w39v040c.c +++ b/w39v040c.c -@@ -19,11 +19,16 @@ +@@ -19,11 +19,12 @@ */ #include "flash.h" +#include "chipdrivers.h" - int probe_w39v040c(struct flashchip *flash) +-int probe_w39v040c(struct flashchip *flash) ++int printlock_w39v040c(struct flashchip *flash) { chipaddr bios = flash->virtual_memory; - uint8_t id1, id2, lock; -+ int result = probe_jedec(flash); + uint8_t lock; -+ -+ if (!result) -+ return result; chip_writeb(0xAA, bios + 0x5555); programmer_delay(10); -@@ -32,8 +37,6 @@ int probe_w39v040c(struct flashchip *flash) +@@ -32,8 +33,6 @@ int probe_w39v040c(struct flashchip *flash) chip_writeb(0x90, bios + 0x5555); programmer_delay(10); @@ -21126,7 +23022,7 @@ index 7fccd53..20e53fa 100644 lock = chip_readb(bios + 0xfff2); chip_writeb(0xAA, bios + 0x5555); -@@ -43,16 +46,34 @@ int probe_w39v040c(struct flashchip *flash) +@@ -43,54 +42,7 @@ int probe_w39v040c(struct flashchip *flash) chip_writeb(0xF0, bios + 0x5555); programmer_delay(40); @@ -21139,62 +23035,55 @@ index 7fccd53..20e53fa 100644 - __func__, lock & 0x4 ? "" : "un", lock & 0x8 ? "" : "un"); - return 1; - } -+ printf("%s: Boot block #TBL is %slocked, rest of chip #WP is %slocked.\n", -+ __func__, lock & 0x4 ? "" : "un", lock & 0x8 ? "" : "un"); -+ return 1; -+} -+ -+int printlock_w39v040c(struct flashchip *flash) -+{ -+ chipaddr bios = flash->virtual_memory; -+ uint8_t lock; -+ -+ chip_writeb(0xAA, bios + 0x5555); -+ programmer_delay(10); -+ chip_writeb(0x55, bios + 0x2AAA); -+ programmer_delay(10); -+ chip_writeb(0x90, bios + 0x5555); -+ programmer_delay(10); -+ -+ lock = chip_readb(bios + 0xfff2); -+ -+ chip_writeb(0xAA, bios + 0x5555); -+ programmer_delay(10); -+ chip_writeb(0x55, bios + 0x2AAA); -+ programmer_delay(10); -+ chip_writeb(0xF0, bios + 0x5555); -+ programmer_delay(40); - -+ printf("%s: Boot block #TBL is %slocked, rest of chip #WP is %slocked.\n", +- +- return 0; +-} +- +-int erase_w39v040c(struct flashchip *flash) +-{ +- int i; +- unsigned int total_size = flash->total_size * 1024; +- +- for (i = 0; i < total_size; i += flash->page_size) { +- if (erase_sector_jedec(flash, i, flash->page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- } +- +- return 0; +-} +- +-int write_w39v040c(struct flashchip *flash, uint8_t *buf) +-{ +- int i; +- int total_size = flash->total_size * 1024; +- int page_size = flash->page_size; +- chipaddr bios = flash->virtual_memory; +- +- if (flash->erase(flash)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- +- printf("Programming page: "); +- for (i = 0; i < total_size / page_size; i++) { +- printf("%04d at address: 0x%08x", i, i * page_size); +- write_sector_jedec(bios, buf + i * page_size, +- bios + i * page_size, page_size); +- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +- } +- printf("\n"); +- ++ msg_cdbg("%s: Boot block #TBL is %slocked, rest of chip #WP is %slocked.\n", + __func__, lock & 0x4 ? "" : "un", lock & 0x8 ? "" : "un"); return 0; } - -@@ -78,7 +99,7 @@ int write_w39v040c(struct flashchip *flash, uint8_t *buf) - int page_size = flash->page_size; - chipaddr bios = flash->virtual_memory; - -- if (flash->erase(flash)) { -+ if (erase_flash(flash)) { - fprintf(stderr, "ERASE FAILED!\n"); - return -1; - } -@@ -86,8 +107,8 @@ int write_w39v040c(struct flashchip *flash, uint8_t *buf) - printf("Programming page: "); - for (i = 0; i < total_size / page_size; i++) { - printf("%04d at address: 0x%08x", i, i * page_size); -- write_sector_jedec(bios, buf + i * page_size, -- bios + i * page_size, page_size); -+ write_sector_jedec_common(flash, buf + i * page_size, -+ bios + i * page_size, page_size, 0xffff); - printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); - } - printf("\n"); diff --git a/w39v080fa.c b/w39v080fa.c -index 31ef15f..0163766 100644 +index 31ef15f..62c55f4 100644 --- a/w39v080fa.c +++ b/w39v080fa.c -@@ -19,37 +19,7 @@ +@@ -19,74 +19,44 @@ */ #include "flash.h" @@ -21233,15 +23122,145 @@ index 31ef15f..0163766 100644 static int unlock_block_winbond_fwhub(struct flashchip *flash, int offset) { -@@ -201,7 +171,7 @@ int write_winbond_fwhub(struct flashchip *flash, uint8_t *buf) - printf("Programming: "); - for (i = 0; i < total_size; i += flash->page_size) { - printf("0x%08x\b\b\b\b\b\b\b\b\b\b", i); -- write_sector_jedec(bios, buf + i, bios + i, flash->page_size); -+ write_sector_jedec_common(flash, buf + i, bios + i, flash->page_size, 0xffff); - } - printf("\n"); + chipaddr wrprotect = flash->virtual_registers + offset + 2; + uint8_t locking; +- printf_debug("Trying to unlock block @0x%08x = 0x%02x\n", offset, ++ msg_cdbg("Trying to unlock block @0x%08x = 0x%02x\n", offset, + chip_readb(wrprotect)); + + locking = chip_readb(wrprotect); + switch (locking & 0x7) { + case 0: +- printf_debug("Full Access.\n"); ++ msg_cdbg("Full Access.\n"); + return 0; + case 1: +- printf_debug("Write Lock (Default State).\n"); ++ msg_cdbg("Write Lock (Default State).\n"); + chip_writeb(0, wrprotect); + return 0; + case 2: +- printf_debug("Locked Open (Full Access, Lock Down).\n"); ++ msg_cdbg("Locked Open (Full Access, Lock Down).\n"); + return 0; + case 3: +- fprintf(stderr, "Error: Write Lock, Locked Down.\n"); ++ msg_cerr("Error: Write Lock, Locked Down.\n"); + return -1; + case 4: +- printf_debug("Read Lock.\n"); ++ msg_cdbg("Read Lock.\n"); + chip_writeb(0, wrprotect); + return 0; + case 5: +- printf_debug("Read/Write Lock.\n"); ++ msg_cdbg("Read/Write Lock.\n"); + chip_writeb(0, wrprotect); + return 0; + case 6: +- fprintf(stderr, "Error: Read Lock, Locked Down.\n"); ++ msg_cerr("Error: Read Lock, Locked Down.\n"); + return -1; + case 7: +- fprintf(stderr, "Error: Read/Write Lock, Locked Down.\n"); ++ msg_cerr("Error: Read/Write Lock, Locked Down.\n"); + return -1; + } + +@@ -119,17 +89,17 @@ int unlock_winbond_fwhub(struct flashchip *flash) + chip_writeb(0xF0, bios + 0x5555); + programmer_delay(10); + +- printf_debug("Lockout bits:\n"); ++ msg_cdbg("Lockout bits:\n"); + + if (locking & (1 << 2)) +- fprintf(stderr, "Error: hardware bootblock locking (#TBL).\n"); ++ msg_cerr("Error: hardware bootblock locking (#TBL).\n"); + else +- printf_debug("No hardware bootblock locking (good!)\n"); ++ msg_cdbg("No hardware bootblock locking (good!)\n"); + + if (locking & (1 << 3)) +- fprintf(stderr, "Error: hardware block locking (#WP).\n"); ++ msg_cerr("Error: hardware block locking (#WP).\n"); + else +- printf_debug("No hardware block locking (good!)\n"); ++ msg_cdbg("No hardware block locking (good!)\n"); + + if (locking & ((1 << 2) | (1 << 3))) + return -1; +@@ -141,69 +111,3 @@ int unlock_winbond_fwhub(struct flashchip *flash) + + return 0; + } +- +-static int erase_sector_winbond_fwhub(struct flashchip *flash, +- unsigned int sector) +-{ +- chipaddr bios = flash->virtual_memory; +- /* Remember: too much sleep can waste your day. */ +- +- printf("0x%08x\b\b\b\b\b\b\b\b\b\b", sector); +- +- /* Sector Erase */ +- chip_writeb(0xAA, bios + 0x5555); +- chip_writeb(0x55, bios + 0x2AAA); +- chip_writeb(0x80, bios + 0x5555); +- +- chip_writeb(0xAA, bios + 0x5555); +- chip_writeb(0x55, bios + 0x2AAA); +- chip_writeb(0x30, bios + sector); +- +- /* wait for Toggle bit ready */ +- toggle_ready_jedec(bios); +- +- if (check_erased_range(flash, sector, flash->page_size)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- return 0; +-} +- +-int erase_winbond_fwhub(struct flashchip *flash) +-{ +- int i, total_size = flash->total_size * 1024; +- +- unlock_winbond_fwhub(flash); +- +- printf("Erasing: "); +- +- for (i = 0; i < total_size; i += flash->page_size) { +- if (erase_sector_winbond_fwhub(flash, i)) { +- fprintf(stderr, "ERASE FAILED!\n"); +- return -1; +- } +- } +- +- printf("\n"); +- +- return 0; +-} +- +-int write_winbond_fwhub(struct flashchip *flash, uint8_t *buf) +-{ +- int i; +- int total_size = flash->total_size * 1024; +- chipaddr bios = flash->virtual_memory; +- +- if (erase_winbond_fwhub(flash)) +- return -1; +- +- printf("Programming: "); +- for (i = 0; i < total_size; i += flash->page_size) { +- printf("0x%08x\b\b\b\b\b\b\b\b\b\b", i); +- write_sector_jedec(bios, buf + i, bios + i, flash->page_size); +- } +- printf("\n"); +- +- return 0; +-} diff --git a/w49f002u.c b/w49f002u.c deleted file mode 100644 index d12bc72..0000000 diff --git a/flashrom.spec b/flashrom.spec index 4cfb70a..e43692b 100644 --- a/flashrom.spec +++ b/flashrom.spec @@ -1,15 +1,15 @@ -%global svnrev 931 +%global svnrev 995 Summary: Simple program for reading/writing BIOS chips content Name: flashrom Version: 0.9.1 -Release: 3.svn%{svnrev}%{?dist} +Release: 4.svn%{svnrev}%{?dist} License: GPLv2 Group: Applications/System URL: http://flashrom.org Source0: http://qa.coreboot.org/releases/%{name}-%{version}.tar.bz2 Source1: http://qa.coreboot.org/releases/%{name}-%{version}.tar.bz2.asc -Patch0: flashrom-r710-r931.diff +Patch0: flashrom-r710-r%{svnrev}.diff BuildRequires: pciutils-devel BuildRequires: zlib-devel BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -42,6 +42,10 @@ CFLAGS="%{optflags}" %{__make} %{?_smp_mflags} %{_mandir}/man8/%{name}.* %changelog +* Wed Apr 28 2010 Peter Lemenkov 0.9.1-4.svn995 +- Updated to latest svn ver. 995 +- Lots of new chips and m/b + * Fri Mar 12 2010 Peter Lemenkov 0.9.1-3.svn931 - Updated to latest svn ver. 931 - ASUS A7V8X-X board diff --git a/import.log b/import.log index 9ff21f0..d5f8041 100644 --- a/import.log +++ b/import.log @@ -8,3 +8,4 @@ flashrom-0_9_0-1_fc10:HEAD:flashrom-0.9.0-1.fc10.src.rpm:1241503535 flashrom-0_9_1-1_fc11:HEAD:flashrom-0.9.1-1.fc11.src.rpm:1252055642 flashrom-0_9_1-2_svn893_fc12:HEAD:flashrom-0.9.1-2.svn893.fc12.src.rpm:1265623249 flashrom-0_9_1-3_svn931_fc12:HEAD:flashrom-0.9.1-3.svn931.fc12.src.rpm:1268395198 +flashrom-0_9_1-4_svn995_fc12:HEAD:flashrom-0.9.1-4.svn995.fc12.src.rpm:1272467717