flashrom had an implicit erase-on-write for most flash chip and programmer drivers, but it was not entirely consistent. Some drivers had their own hand-rolled partial update functionality which made handling partial updates from generic code impossible.
Move implicit erase out of chip drivers, clean up the chip write functions at the same time. A full chip erase is now performed in the generic code for all flash chips on write, and after that the whole chip is written. This is needed before we can change write function signature of the write functions to take start+len.
Side note: With this patch and one or two followup patches, more functions will be easily recognizable as duplicates and can be eliminated.
Compile tested and proofread, but that's it. The patch may cause flashrom to eat your dog or it may cause your dog to eat burned flash chips. Please test on real hardware. Thanks!
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-partial_write_no_autoerase/flash.h =================================================================== --- flashrom-partial_write_no_autoerase/flash.h (Revision 1005) +++ flashrom-partial_write_no_autoerase/flash.h (Arbeitskopie) @@ -676,7 +676,7 @@ int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); 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); +int sb600_spi_write_256(struct flashchip *flash, uint8_t *buf); extern uint8_t *sb600_spibar;
/* wbsio_spi.c */ Index: flashrom-partial_write_no_autoerase/spi25.c =================================================================== --- flashrom-partial_write_no_autoerase/spi25.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/spi25.c (Arbeitskopie) @@ -875,6 +875,7 @@
/* * Read a part of the flash chip. + * FIXME: Use the chunk code from Michael Karcher instead. * Each page is read separately in chunks with a maximum size of chunksize. */ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize) @@ -914,6 +915,7 @@
/* * Write a part of the flash chip. + * FIXME: Use the chunk code from Michael Karcher instead. * Each page is written separately in chunks with a maximum size of chunksize. */ int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize) @@ -964,20 +966,13 @@ * and for chips where memory mapped programming is impossible * (e.g. due to size constraints in IT87* for over 512 kB) */ +/* real chunksize is 1, logical chunksize is 1 */ int spi_chip_write_1(struct flashchip *flash, uint8_t *buf) { - int total_size = 1024 * flash->total_size; int i, result = 0;
spi_disable_blockprotect(); - /* Erase first */ - msg_cinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("done.\n"); - for (i = 0; i < total_size; i++) { + for (i = 0; i < flash->total_size * 1024; i++) { result = spi_byte_program(i, buf[i]); if (result) return 1; @@ -988,6 +983,7 @@ return 0; }
+/* FIXME: Unused function, not easily convertable to partial write. */ int spi_aai_write(struct flashchip *flash, uint8_t *buf) { uint32_t pos = 2, size = flash->total_size * 1024; @@ -1004,10 +1000,6 @@ default: break; } - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } /* FIXME: This will fail on ICH/VIA SPI. */ result = spi_write_enable(); if (result) Index: flashrom-partial_write_no_autoerase/it87spi.c =================================================================== --- flashrom-partial_write_no_autoerase/it87spi.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/it87spi.c (Arbeitskopie) @@ -326,25 +326,19 @@
int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf) { - int total_size = 1024 * flash->total_size; int i;
/* * IT8716F only allows maximum of 512 kb SPI chip size for memory * mapped access. */ - if ((programmer == PROGRAMMER_IT87SPI) || (total_size > 512 * 1024)) { + if ((programmer == PROGRAMMER_IT87SPI) || (flash->total_size * 1024 > 512 * 1024)) { spi_chip_write_1(flash, buf); } else { 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"); - for (i = 0; i < total_size / 256; i++) { + + /* FIXME: Handle chips which have max writechunk size >1 and <256. */ + for (i = 0; i < flash->total_size * 1024 / 256; i++) { it8716f_spi_page_program(flash, i, buf); } } Index: flashrom-partial_write_no_autoerase/buspirate_spi.c =================================================================== --- flashrom-partial_write_no_autoerase/buspirate_spi.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/buspirate_spi.c (Arbeitskopie) @@ -318,16 +318,6 @@
int buspirate_spi_write_256(struct flashchip *flash, uint8_t *buf) { - int total_size = 1024 * flash->total_size; - 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"); - - return spi_write_chunked(flash, buf, 0, total_size, 12); + return spi_write_chunked(flash, buf, 0, flash->total_size * 1024, 12); } Index: flashrom-partial_write_no_autoerase/jedec.c =================================================================== --- flashrom-partial_write_no_autoerase/jedec.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/jedec.c (Arbeitskopie) @@ -393,6 +393,7 @@ } }
+/* real chunksize is page_size, logical chunksize is page_size */ int write_jedec(struct flashchip *flash, uint8_t *buf) { int mask; @@ -402,52 +403,23 @@
mask = getaddrmask(flash);
- 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)) + if (write_page_write_jedec_common(flash, buf + i * page_size, i * page_size, page_size, mask)) failed = 1; - 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");
return failed; }
+/* real chunksize is 1, logical chunksize is 1 */ int write_jedec_1(struct flashchip *flash, uint8_t * buf) { - int i; - chipaddr bios = flash->virtual_memory; - chipaddr dst = bios; + chipaddr dst = flash->virtual_memory; int mask;
mask = getaddrmask(flash);
- programmer_delay(10); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - - msg_cinfo("Programming page: "); - for (i = 0; i < flash->total_size; i++) { - if ((i & 0x3) == 0) - 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) - 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; + return write_sector_jedec_common(flash, buf, dst, flash->total_size * 1024, mask); }
/* erase chip with block_erase() prototype */ Index: flashrom-partial_write_no_autoerase/bitbang_spi.c =================================================================== --- flashrom-partial_write_no_autoerase/bitbang_spi.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/bitbang_spi.c (Arbeitskopie) @@ -141,8 +141,5 @@
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf) { - int total_size = 1024 * flash->total_size; - - msg_pdbg("total_size is %d\n", total_size); - return spi_write_chunked(flash, buf, 0, total_size, 256); + return spi_write_chunked(flash, buf, 0, flash->total_size * 1024, 256); } Index: flashrom-partial_write_no_autoerase/sst49lfxxxc.c =================================================================== --- flashrom-partial_write_no_autoerase/sst49lfxxxc.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/sst49lfxxxc.c (Arbeitskopie) @@ -92,6 +92,7 @@ return 0; }
+/* real chunksize is 1, logical chunksize is page_size */ int write_49lfxxxc(struct flashchip *flash, uint8_t *buf) { int i; @@ -100,21 +101,10 @@ chipaddr bios = flash->virtual_memory;
write_lockbits_49lfxxxc(flash, 0); - 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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - }
- /* write to the sector */ - 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); - 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"); + write_page_82802ab(bios, buf + i * page_size, bios + i * page_size, page_size); } - msg_cinfo("\n");
chip_writeb(0xFF, bios);
Index: flashrom-partial_write_no_autoerase/spi.c =================================================================== --- flashrom-partial_write_no_autoerase/spi.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/spi.c (Arbeitskopie) @@ -67,7 +67,7 @@ .command = sb600_spi_send_command, .multicommand = default_spi_send_multicommand, .read = sb600_spi_read, - .write_256 = sb600_spi_write_1, + .write_256 = sb600_spi_write_256, },
{ /* SPI_CONTROLLER_VIA */ @@ -194,6 +194,7 @@ * Program chip using page (256 bytes) programming. * Some SPI masters can't do this, they use single byte programming instead. */ +/* real chunksize is up to 256, logical chunksize is 256 */ int spi_chip_write_256(struct flashchip *flash, uint8_t *buf) { if (!spi_programmer[spi_controller].write_256) { Index: flashrom-partial_write_no_autoerase/ft2232_spi.c =================================================================== --- flashrom-partial_write_no_autoerase/ft2232_spi.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/ft2232_spi.c (Arbeitskopie) @@ -287,18 +287,8 @@
int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf) { - int total_size = 1024 * flash->total_size; - 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"); - msg_pdbg("total_size is %d\n", total_size); - return spi_write_chunked(flash, buf, 0, total_size, 256); + return spi_write_chunked(flash, buf, 0, flash->total_size * 1024, 256); }
#endif Index: flashrom-partial_write_no_autoerase/sst28sf040.c =================================================================== --- flashrom-partial_write_no_autoerase/sst28sf040.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/sst28sf040.c (Arbeitskopie) @@ -111,6 +111,7 @@ return 0; }
+/* real chunksize is 1, logical chunksize is page_size */ int write_28sf040(struct flashchip *flash, uint8_t *buf) { int i; @@ -120,21 +121,9 @@
unprotect_28sf040(bios);
- 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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - - /* write to the sector */ - 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); - 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"); + write_sector_28sf040(bios, buf + i * page_size, bios + i * page_size, page_size); } - msg_cinfo("\n");
protect_28sf040(bios);
Index: flashrom-partial_write_no_autoerase/sb600spi.c =================================================================== --- flashrom-partial_write_no_autoerase/sb600spi.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/sb600spi.c (Arbeitskopie) @@ -47,25 +47,10 @@ return spi_read_chunked(flash, buf, start, len, 8); }
-/* FIXME: SB600 can write 5 bytes per transaction. */ -int sb600_spi_write_1(struct flashchip *flash, uint8_t *buf) +int sb600_spi_write_256(struct flashchip *flash, uint8_t *buf) { - int total_size = flash->total_size * 1024; - int result = 0; - 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"); - - msg_pinfo("Programming flash"); - result = spi_write_chunked(flash, buf, 0, total_size, 5); - msg_pinfo(" done.\n"); - return result; + return spi_write_chunked(flash, buf, 0, flash->total_size * 1024, 5); }
static void reset_internal_fifo_pointer(void) Index: flashrom-partial_write_no_autoerase/flashrom.c =================================================================== --- flashrom-partial_write_no_autoerase/flashrom.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/flashrom.c (Arbeitskopie) @@ -1319,6 +1319,7 @@
/* This function signature is horrible. We need to design a better interface, * but right now it allows us to split off the CLI code. + * Besides that, the function itself is a textbook example of abysmal code flow. */ int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it) { @@ -1358,12 +1359,7 @@ programmer_shutdown(); return 1; } - } else { - struct stat image_stat; - - if (flash->unlock) - flash->unlock(flash); - + } else if (write_it) { if (flash->tested & TEST_BAD_ERASE) { msg_cerr("Erase is not working on this chip " "and erase is needed for write. "); @@ -1385,6 +1381,18 @@ msg_cerr("Continuing anyway.\n"); } } + if (!flash->write) { + msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + programmer_shutdown(); + return 1; + } + if (flash->unlock) + flash->unlock(flash); + + } + if (write_it || verify_it) { + struct stat image_stat; + if ((image = fopen(filename, "rb")) == NULL) { perror(filename); programmer_shutdown(); @@ -1420,12 +1428,12 @@ // ////////////////////////////////////////////////////////////
if (write_it) { - msg_cinfo("Writing flash chip... "); - if (!flash->write) { - msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + if (erase_flash(flash)) { + emergency_help_message(); programmer_shutdown(); return 1; } + msg_cinfo("Writing flash chip... "); ret = flash->write(flash, buf); if (ret) { msg_cerr("FAILED!\n"); Index: flashrom-partial_write_no_autoerase/ichspi.c =================================================================== --- flashrom-partial_write_no_autoerase/ichspi.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/ichspi.c (Arbeitskopie) @@ -646,34 +646,13 @@
int ich_spi_write_256(struct flashchip *flash, uint8_t * buf) { - int i, ret = 0; - int total_size = flash->total_size * 1024; - int erase_size = 64 * 1024; int maxdata = 64;
if (spi_controller == SPI_CONTROLLER_VIA) maxdata = 16;
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"); - - msg_pinfo("Programming page: \n"); - for (i = 0; i < total_size / erase_size; i++) { - ret = spi_write_chunked(flash, buf + (i * erase_size), - i * erase_size, erase_size, maxdata); - if (ret) - break; - } - - msg_pinfo("\n"); - - return ret; + return spi_write_chunked(flash, buf, 0, flash->total_size * 1024, maxdata); }
int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt, Index: flashrom-partial_write_no_autoerase/82802ab.c =================================================================== --- flashrom-partial_write_no_autoerase/82802ab.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/82802ab.c (Arbeitskopie) @@ -176,28 +176,16 @@ } }
+/* real chunksize is 1, logical chunksize is 1024 */ int write_82802ab(struct flashchip *flash, uint8_t *buf) { int i; chipaddr bios = flash->virtual_memory;
- if (erase_flash(flash)) { - msg_cerr("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; }
Index: flashrom-partial_write_no_autoerase/m29f400bt.c =================================================================== --- flashrom-partial_write_no_autoerase/m29f400bt.c (Revision 1005) +++ flashrom-partial_write_no_autoerase/m29f400bt.c (Arbeitskopie) @@ -39,8 +39,6 @@
/* transfer data from source to destination */ chip_writeb(*src, dst); - //chip_writeb(0xF0, bios); - //programmer_delay(5); toggle_ready_jedec(dst); msg_cerr("Value in the flash at address 0x%lx = %#x, want %#x\n", (dst - bios), chip_readb(dst), *src); @@ -113,7 +111,6 @@
chip_writeb(0xAA, bios + 0xAAA); chip_writeb(0x55, bios + 0x555); - //chip_writeb(0x10, bios + 0xAAA); chip_writeb(0x30, dst);
programmer_delay(10); @@ -136,6 +133,7 @@ return erase_m29f400bt(flash); }
+/* real chunksize is 1, logical chunksize is 8k-64k */ int write_m29f400bt(struct flashchip *flash, uint8_t *buf) { int i; @@ -143,117 +141,27 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- //erase_m29f400bt (flash); - msg_cinfo("Programming page:\n "); - /********************************* - *Pages for M29F400BT: - * 16 0x7c000 0x7ffff TOP - * 8 0x7a000 0x7bfff - * 8 0x78000 0x79fff - * 32 0x70000 0x77fff - * 64 0x60000 0x6ffff - * 64 0x50000 0x5ffff - * 64 0x40000 0x4ffff - *--------------------------------- - * 64 0x30000 0x3ffff - * 64 0x20000 0x2ffff - * 64 0x10000 0x1ffff - * 64 0x00000 0x0ffff BOTTOM - *********************************/ - msg_cinfo("total_size/page_size = %d\n", total_size / page_size); for (i = 0; i < (total_size / page_size) - 1; i++) { - msg_cinfo("%04d at address: 0x%08x\n", i, i * page_size); - if (block_erase_m29f400bt(flash, i * page_size, page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - write_page_m29f400bt(bios, buf + i * page_size, - bios + i * page_size, page_size); - 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"); + write_page_m29f400bt(bios, buf + i * page_size, bios + i * page_size, page_size); }
- msg_cinfo("%04d at address: 0x%08x\n", 7, 0x70000); - if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024); - - msg_cinfo("%04d at address: 0x%08x\n", 8, 0x78000); - if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024); - - msg_cinfo("%04d at address: 0x%08x\n", 9, 0x7a000); - if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024); - - msg_cinfo("%04d at address: 0x%08x\n", 10, 0x7c000); - if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
- msg_cinfo("\n"); - return 0; }
+/* real chunksize is 1, logical chunksize is 64k */ int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf) { chipaddr bios = flash->virtual_memory;
- msg_cinfo("Programming page:\n "); - /********************************* - *Pages for M29F400BT: - * 16 0x7c000 0x7ffff TOP - * 8 0x7a000 0x7bfff - * 8 0x78000 0x79fff - * 32 0x70000 0x77fff - * 64 0x60000 0x6ffff - * 64 0x50000 0x5ffff - * 64 0x40000 0x4ffff - *--------------------------------- - * 64 0x30000 0x3ffff - * 64 0x20000 0x2ffff - * 64 0x10000 0x1ffff - * 64 0x00000 0x0ffff BOTTOM - *********************************/ - msg_cinfo("%04d at address: 0x%08x\n", 7, 0x00000); - if (block_erase_m29f400bt(flash, 0x00000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024); - - msg_cinfo("%04d at address: 0x%08x\n", 7, 0x10000); - if (block_erase_m29f400bt(flash, 0x10000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024); - - msg_cinfo("%04d at address: 0x%08x\n", 7, 0x20000); - if (block_erase_m29f400bt(flash, 0x20000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024); - - msg_cinfo("%04d at address: 0x%08x\n", 7, 0x30000); - if (block_erase_m29f400bt(flash, 0x30000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024);
- msg_cinfo("\n"); - return 0; }
Am Samstag, den 22.05.2010, 03:26 +0200 schrieb Carl-Daniel Hailfinger:
[as requested on IRC, this is not a full review, but two things not directly related to the patch stand out I don't want to leave uncommented]
int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf) {
int total_size = 1024 * flash->total_size; int i;
/*
- IT8716F only allows maximum of 512 kb SPI chip size for memory
- mapped access.
*/
if ((programmer == PROGRAMMER_IT87SPI) || (total_size > 512 * 1024)) {
- if ((programmer == PROGRAMMER_IT87SPI) || (flash->total_size * 1024 > 512 * 1024)) {
why do you have to test for the programmer type here? It seems like it8716f* functions are only ever called if programmer is PROGRAMMER_IT87SPI.
+/* real chunksize is 1, logical chunksize is 64k */ int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf) { chipaddr bios = flash->virtual_memory;
The M29F400 stuff is completely broken. We use write_coreboot_m29f400bt everywhere and write_m29f400bt is dead code. But write_coreboot_m29f400bt does just write the lower half of the chip (below the dashed line in the diagram).
Regards, Michael Karcher
On 10.07.2010 20:16, Michael Karcher wrote:
Am Samstag, den 22.05.2010, 03:26 +0200 schrieb Carl-Daniel Hailfinger:
[as requested on IRC, this is not a full review, but two things not directly related to the patch stand out I don't want to leave uncommented]
int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf) {
int total_size = 1024 * flash->total_size; int i;
/*
- IT8716F only allows maximum of 512 kb SPI chip size for memory
- mapped access.
*/
if ((programmer == PROGRAMMER_IT87SPI) || (total_size > 512 * 1024)) {
- if ((programmer == PROGRAMMER_IT87SPI) || (flash->total_size * 1024 > 512 * 1024)) {
why do you have to test for the programmer type here? It seems like it8716f* functions are only ever called if programmer is PROGRAMMER_IT87SPI.
Historical baggage, and a corner case. PROGRAMMER_IT87SPI means someone used "-p it87_spi" instead of "-p internal". That's for machines which used it87_spi before we had autodetection (and used board enabled instead), and it also is for machines where the IT87* Super I/O does not perform flash translation, but where someone hooked up a flash chip anyway and wants to use IT87 in pure command mode and avoid memmapped mode. To be honest, I think we can kill that special case. I don't know of anyone who actually uses it nowadays.
+/* real chunksize is 1, logical chunksize is 64k */ int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf) { chipaddr bios = flash->virtual_memory;
The M29F400 stuff is completely broken. We use write_coreboot_m29f400bt everywhere and write_m29f400bt is dead code. But write_coreboot_m29f400bt does just write the lower half of the chip (below the dashed line in the diagram).
I think I'll just kill that function.
Regards, Carl-Daniel
On 10.07.2010 21:25, Carl-Daniel Hailfinger wrote:
On 10.07.2010 20:16, Michael Karcher wrote:
The M29F400 stuff is completely broken. We use write_coreboot_m29f400bt everywhere and write_m29f400bt is dead code. But write_coreboot_m29f400bt does just write the lower half of the chip (below the dashed line in the diagram).
I think I'll just kill that function.
My flashrom-partial_write_cleanupontop tree does exactly that, but it also marks three chips as TEST_BAD_WRITE because they used the killed function. OTOH, they were already broken, so the annotation makes sense. Will send that one once the implicit erase is killed everywhere.
Regards, Carl-Daniel
flashrom had an implicit erase-on-write for most flash chip and programmer drivers, but it was not entirely consistent. Some drivers had their own hand-rolled partial update functionality which made handling partial updates from generic code impossible.
Move implicit erase out of chip drivers, and kill some dead erase functions at the same time. A full chip erase is now performed in the generic code for all flash chips on write, and after that the whole chip is written. This is needed before we can change write function signature of the write functions to take start+len.
Compile tested and proofread, but that's it. The patch may cause flashrom to eat your dog or it may cause your dog to eat burned flash chips. Please test on real hardware. Thanks!
I have a cleanup patch for the write functions which will apply on top of this, but I wanted to keep this patch readable and self-contained.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-no_implicit_erase_inside_write/spi25.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi25.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/spi25.c (Arbeitskopie) @@ -976,14 +976,6 @@
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf) { - /* Erase first */ - msg_cinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("done.\n"); - return spi_chip_write_1_new(flash, buf, 0, flash->total_size * 1024); }
Index: flashrom-no_implicit_erase_inside_write/jedec.c =================================================================== --- flashrom-no_implicit_erase_inside_write/jedec.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/jedec.c (Arbeitskopie) @@ -402,11 +402,6 @@
mask = getaddrmask(flash);
- 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); @@ -429,12 +424,6 @@
mask = getaddrmask(flash);
- programmer_delay(10); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming page: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Arbeitskopie) @@ -86,11 +86,6 @@ write_lockbits_49lfxxxc(flash, 0); 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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - }
/* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); Index: flashrom-no_implicit_erase_inside_write/sharplhf00l04.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Arbeitskopie) @@ -65,10 +65,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- if (erase_flash(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); Index: flashrom-no_implicit_erase_inside_write/spi.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/spi.c (Arbeitskopie) @@ -217,12 +217,6 @@ { int ret;
- msg_pinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_perr("ERASE FAILED!\n"); - return -1; - } - msg_pinfo("done.\n"); msg_pinfo("Programming flash... "); ret = spi_chip_write_256_new(flash, buf, 0, flash->total_size * 1024); if (!ret) Index: flashrom-no_implicit_erase_inside_write/sst28sf040.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst28sf040.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/sst28sf040.c (Arbeitskopie) @@ -122,12 +122,6 @@
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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - /* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); write_sector_28sf040(bios, buf + i * page_size, Index: flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c =================================================================== --- flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Arbeitskopie) @@ -93,6 +93,7 @@ return 0; }
+/* This function is unused. */ int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize) { chipaddr bios = flash->virtual_memory + sector; @@ -116,6 +117,7 @@ return 0; }
+/* FIXME: This function is not a real chip erase function. */ int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen) { int i; Index: flashrom-no_implicit_erase_inside_write/flashrom.c =================================================================== --- flashrom-no_implicit_erase_inside_write/flashrom.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/flashrom.c (Arbeitskopie) @@ -1421,6 +1421,7 @@
/* This function signature is horrible. We need to design a better interface, * but right now it allows us to split off the CLI code. + * Besides that, the function itself is a textbook example of abysmal code flow. */ int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it) { @@ -1475,12 +1476,7 @@ programmer_shutdown(); return 1; } - } else { - struct stat image_stat; - - if (flash->unlock) - flash->unlock(flash); - + } else if (write_it) { if (flash->tested & TEST_BAD_ERASE) { msg_cerr("Erase is not working on this chip " "and erase is needed for write. "); @@ -1502,6 +1498,18 @@ msg_cerr("Continuing anyway.\n"); } } + if (!flash->write) { + msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + programmer_shutdown(); + return 1; + } + if (flash->unlock) + flash->unlock(flash); + + } + if (write_it || verify_it) { + struct stat image_stat; + if ((image = fopen(filename, "rb")) == NULL) { perror(filename); programmer_shutdown(); @@ -1537,12 +1545,12 @@ // ////////////////////////////////////////////////////////////
if (write_it) { - msg_cinfo("Writing flash chip... "); - if (!flash->write) { - msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + if (erase_flash(flash)) { + emergency_help_message(); programmer_shutdown(); return 1; } + msg_cinfo("Writing flash chip... "); ret = flash->write(flash, buf); if (ret) { msg_cerr("FAILED!\n"); Index: flashrom-no_implicit_erase_inside_write/82802ab.c =================================================================== --- flashrom-no_implicit_erase_inside_write/82802ab.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/82802ab.c (Arbeitskopie) @@ -144,23 +144,6 @@ return 0; }
-int erase_82802ab(struct flashchip *flash) -{ - int i; - unsigned int total_size = flash->total_size * 1024; - - 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_block_82802ab(flash, i, flash->page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("DONE ERASE\n"); - - return 0; -} - void write_page_82802ab(chipaddr bios, uint8_t *src, chipaddr dst, int page_size) { @@ -179,11 +162,6 @@ int i; chipaddr bios = flash->virtual_memory;
- if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming at: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/chipdrivers.h =================================================================== --- flashrom-no_implicit_erase_inside_write/chipdrivers.h (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/chipdrivers.h (Arbeitskopie) @@ -33,8 +33,6 @@ int probe_spi_res2(struct flashchip *flash); int spi_write_enable(void); int spi_write_disable(void); -int spi_chip_erase_60(struct flashchip *flash); -int spi_chip_erase_c7(struct flashchip *flash); int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen); @@ -58,7 +56,6 @@ /* 82802ab.c */ uint8_t wait_82802ab(chipaddr bios); int probe_82802ab(struct flashchip *flash); -int erase_82802ab(struct flashchip *flash); 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); @@ -73,7 +70,6 @@ int write_byte_program_jedec(chipaddr bios, uint8_t *src, chipaddr dst); int probe_jedec(struct flashchip *flash); -int erase_chip_jedec(struct flashchip *flash); int write_jedec(struct flashchip *flash, uint8_t *buf); int write_jedec_1(struct flashchip *flash, uint8_t *buf); int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned int pagesize); @@ -83,7 +79,6 @@
/* m29f400bt.c */ int probe_m29f400bt(struct flashchip *flash); -int erase_m29f400bt(struct flashchip *flash); int block_erase_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int block_erase_chip_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int write_m29f400bt(struct flashchip *flash, uint8_t *buf); Index: flashrom-no_implicit_erase_inside_write/m29f400bt.c =================================================================== --- flashrom-no_implicit_erase_inside_write/m29f400bt.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/m29f400bt.c (Arbeitskopie) @@ -143,7 +143,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- //erase_m29f400bt (flash); msg_cinfo("Programming page:\n "); /********************************* *Pages for M29F400BT: @@ -163,41 +162,21 @@ msg_cinfo("total_size/page_size = %d\n", total_size / page_size); for (i = 0; i < (total_size / page_size) - 1; i++) { msg_cinfo("%04d at address: 0x%08x\n", i, i * page_size); - if (block_erase_m29f400bt(flash, i * page_size, page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + i * page_size, bios + i * page_size, page_size); 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\n", 7, 0x70000); - if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 8, 0x78000); - if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 9, 0x7a000); - if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 10, 0x7c000); - if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
msg_cinfo("\n"); @@ -226,31 +205,15 @@ * 64 0x00000 0x0ffff BOTTOM *********************************/ msg_cinfo("%04d at address: 0x%08x\n", 7, 0x00000); - if (block_erase_m29f400bt(flash, 0x00000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 7, 0x10000); - if (block_erase_m29f400bt(flash, 0x10000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 7, 0x20000); - if (block_erase_m29f400bt(flash, 0x20000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 7, 0x30000); - if (block_erase_m29f400bt(flash, 0x30000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024);
msg_cinfo("\n");
New version, this time write is marked as untested for all chips.
flashrom had an implicit erase-on-write for most flash chip and programmer drivers, but it was not entirely consistent. Some drivers had their own hand-rolled partial update functionality which made handling partial updates from generic code impossible.
Move implicit erase out of chip drivers, and kill some dead erase functions at the same time. A full chip erase is now performed in the generic code for all flash chips on write, and after that the whole chip is written. This is needed before we can change write function signature of the write functions to take start+len.
Compile tested and proofread, but that's it. The patch may cause flashrom to eat your dog or it may cause your dog to eat burned flash chips. Please test on real hardware. Thanks!
I have a cleanup patch for the write functions which will apply on top of this, but I wanted to keep this patch readable and self-contained.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-no_implicit_erase_inside_write/spi25.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi25.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/spi25.c (Arbeitskopie) @@ -976,14 +976,6 @@
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf) { - /* Erase first */ - msg_cinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("done.\n"); - return spi_chip_write_1_new(flash, buf, 0, flash->total_size * 1024); }
Index: flashrom-no_implicit_erase_inside_write/jedec.c =================================================================== --- flashrom-no_implicit_erase_inside_write/jedec.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/jedec.c (Arbeitskopie) @@ -402,11 +402,6 @@
mask = getaddrmask(flash);
- 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); @@ -429,12 +424,6 @@
mask = getaddrmask(flash);
- programmer_delay(10); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming page: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Arbeitskopie) @@ -86,11 +86,6 @@ write_lockbits_49lfxxxc(flash, 0); 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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - }
/* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); Index: flashrom-no_implicit_erase_inside_write/flashchips.c =================================================================== --- flashrom-no_implicit_erase_inside_write/flashchips.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/flashchips.c (Arbeitskopie) @@ -453,7 +453,7 @@ .model_id = AT_25DF321, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -866,7 +866,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10000, /* 10mS, Enter=Exec */ .block_erasers = @@ -1093,7 +1093,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -1147,7 +1147,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -1179,7 +1179,7 @@ .model_id = AMIC_A25L40P, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -1211,7 +1211,7 @@ .model_id = AMIC_A25L40P, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -1243,7 +1243,7 @@ .model_id = AMIC_A25L80P, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -1307,7 +1307,7 @@ .total_size = 256, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ .block_erasers = @@ -1364,7 +1364,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -2230,7 +2230,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2257,7 +2257,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2288,7 +2288,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2444,7 +2444,7 @@ .total_size = 256, .page_size = 256 * 1024, .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */ - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2840,7 +2840,7 @@ .model_id = MX_25L4005, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -2875,7 +2875,7 @@ .model_id = MX_25L8005, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -2910,7 +2910,7 @@ .model_id = MX_25L1605, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -2977,7 +2977,7 @@ .model_id = MX_25L3205, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3201,7 +3201,7 @@ .total_size = 256, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ .block_erasers = @@ -3344,7 +3344,7 @@ .model_id = ST_M25PE80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3651,7 +3651,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -3738,7 +3738,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -3768,7 +3768,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -3855,7 +3855,7 @@ .model_id = SPANSION_S25FL008A, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3881,7 +3881,7 @@ .model_id = SPANSION_S25FL016A, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3907,7 +3907,7 @@ .model_id = SST_25VF016B, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3942,7 +3942,7 @@ .model_id = SST_25VF032B, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4105,7 +4105,7 @@ .model_id = SST_25VF080B, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4167,7 +4167,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -4213,7 +4213,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -4236,7 +4236,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -4285,7 +4285,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4311,7 +4311,7 @@ .total_size = 256, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4389,7 +4389,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4496,7 +4496,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4561,7 +4561,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4624,7 +4624,7 @@ .total_size = 1024, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4687,7 +4687,7 @@ .total_size = 2048, .page_size = 4 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ .block_erasers = @@ -4719,7 +4719,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4748,7 +4748,7 @@ .total_size = 256, .page_size = 4 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4835,7 +4835,7 @@ .total_size = 1024, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_FIXME, .block_erasers = @@ -4864,7 +4864,7 @@ .total_size = 2048, .page_size = 4 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ .block_erasers = @@ -5031,7 +5031,7 @@ .model_id = ST_M25P40, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5083,7 +5083,7 @@ .model_id = ST_M25P80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5109,7 +5109,7 @@ .model_id = ST_M25P16, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5135,7 +5135,7 @@ .model_id = ST_M25P32, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5386,7 +5386,7 @@ .total_size = 64, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5747,7 +5747,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -5965,7 +5965,7 @@ .model_id = W_25Q64, .total_size = 8192, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6058,7 +6058,7 @@ .model_id = W_25X40, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6087,7 +6087,7 @@ .model_id = W_25X80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6222,7 +6222,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, /* used datasheet for the W29C011A */ .block_erasers = @@ -6245,7 +6245,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6291,7 +6291,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_w29ee011, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (w29ee011.c) */ .block_erasers = @@ -6314,7 +6314,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6340,7 +6340,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6393,7 +6393,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6450,7 +6450,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6512,7 +6512,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6543,7 +6543,7 @@ .total_size = 1024, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_FIXME, .block_erasers = Index: flashrom-no_implicit_erase_inside_write/sharplhf00l04.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Arbeitskopie) @@ -65,10 +65,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- if (erase_flash(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); Index: flashrom-no_implicit_erase_inside_write/spi.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/spi.c (Arbeitskopie) @@ -217,12 +217,6 @@ { int ret;
- msg_pinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_perr("ERASE FAILED!\n"); - return -1; - } - msg_pinfo("done.\n"); msg_pinfo("Programming flash... "); ret = spi_chip_write_256_new(flash, buf, 0, flash->total_size * 1024); if (!ret) Index: flashrom-no_implicit_erase_inside_write/sst28sf040.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst28sf040.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/sst28sf040.c (Arbeitskopie) @@ -122,12 +122,6 @@
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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - /* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); write_sector_28sf040(bios, buf + i * page_size, Index: flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c =================================================================== --- flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Arbeitskopie) @@ -93,6 +93,7 @@ return 0; }
+/* This function is unused. */ int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize) { chipaddr bios = flash->virtual_memory + sector; @@ -116,6 +117,7 @@ return 0; }
+/* FIXME: This function is not a real chip erase function. */ int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen) { int i; Index: flashrom-no_implicit_erase_inside_write/flashrom.c =================================================================== --- flashrom-no_implicit_erase_inside_write/flashrom.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/flashrom.c (Arbeitskopie) @@ -1421,6 +1421,7 @@
/* This function signature is horrible. We need to design a better interface, * but right now it allows us to split off the CLI code. + * Besides that, the function itself is a textbook example of abysmal code flow. */ int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it) { @@ -1475,12 +1476,7 @@ programmer_shutdown(); return 1; } - } else { - struct stat image_stat; - - if (flash->unlock) - flash->unlock(flash); - + } else if (write_it) { if (flash->tested & TEST_BAD_ERASE) { msg_cerr("Erase is not working on this chip " "and erase is needed for write. "); @@ -1502,6 +1498,18 @@ msg_cerr("Continuing anyway.\n"); } } + if (!flash->write) { + msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + programmer_shutdown(); + return 1; + } + if (flash->unlock) + flash->unlock(flash); + + } + if (write_it || verify_it) { + struct stat image_stat; + if ((image = fopen(filename, "rb")) == NULL) { perror(filename); programmer_shutdown(); @@ -1537,12 +1545,12 @@ // ////////////////////////////////////////////////////////////
if (write_it) { - msg_cinfo("Writing flash chip... "); - if (!flash->write) { - msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + if (erase_flash(flash)) { + emergency_help_message(); programmer_shutdown(); return 1; } + msg_cinfo("Writing flash chip... "); ret = flash->write(flash, buf); if (ret) { msg_cerr("FAILED!\n"); Index: flashrom-no_implicit_erase_inside_write/82802ab.c =================================================================== --- flashrom-no_implicit_erase_inside_write/82802ab.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/82802ab.c (Arbeitskopie) @@ -144,23 +144,6 @@ return 0; }
-int erase_82802ab(struct flashchip *flash) -{ - int i; - unsigned int total_size = flash->total_size * 1024; - - 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_block_82802ab(flash, i, flash->page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("DONE ERASE\n"); - - return 0; -} - void write_page_82802ab(chipaddr bios, uint8_t *src, chipaddr dst, int page_size) { @@ -179,11 +162,6 @@ int i; chipaddr bios = flash->virtual_memory;
- if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming at: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/chipdrivers.h =================================================================== --- flashrom-no_implicit_erase_inside_write/chipdrivers.h (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/chipdrivers.h (Arbeitskopie) @@ -33,8 +33,6 @@ int probe_spi_res2(struct flashchip *flash); int spi_write_enable(void); int spi_write_disable(void); -int spi_chip_erase_60(struct flashchip *flash); -int spi_chip_erase_c7(struct flashchip *flash); int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen); @@ -58,7 +56,6 @@ /* 82802ab.c */ uint8_t wait_82802ab(chipaddr bios); int probe_82802ab(struct flashchip *flash); -int erase_82802ab(struct flashchip *flash); 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); @@ -73,7 +70,6 @@ int write_byte_program_jedec(chipaddr bios, uint8_t *src, chipaddr dst); int probe_jedec(struct flashchip *flash); -int erase_chip_jedec(struct flashchip *flash); int write_jedec(struct flashchip *flash, uint8_t *buf); int write_jedec_1(struct flashchip *flash, uint8_t *buf); int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned int pagesize); @@ -83,7 +79,6 @@
/* m29f400bt.c */ int probe_m29f400bt(struct flashchip *flash); -int erase_m29f400bt(struct flashchip *flash); int block_erase_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int block_erase_chip_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int write_m29f400bt(struct flashchip *flash, uint8_t *buf); Index: flashrom-no_implicit_erase_inside_write/m29f400bt.c =================================================================== --- flashrom-no_implicit_erase_inside_write/m29f400bt.c (Revision 1082) +++ flashrom-no_implicit_erase_inside_write/m29f400bt.c (Arbeitskopie) @@ -143,7 +143,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- //erase_m29f400bt (flash); msg_cinfo("Programming page:\n "); /********************************* *Pages for M29F400BT: @@ -163,41 +162,21 @@ msg_cinfo("total_size/page_size = %d\n", total_size / page_size); for (i = 0; i < (total_size / page_size) - 1; i++) { msg_cinfo("%04d at address: 0x%08x\n", i, i * page_size); - if (block_erase_m29f400bt(flash, i * page_size, page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + i * page_size, bios + i * page_size, page_size); 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\n", 7, 0x70000); - if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 8, 0x78000); - if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 9, 0x7a000); - if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 10, 0x7c000); - if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
msg_cinfo("\n"); @@ -226,31 +205,15 @@ * 64 0x00000 0x0ffff BOTTOM *********************************/ msg_cinfo("%04d at address: 0x%08x\n", 7, 0x00000); - if (block_erase_m29f400bt(flash, 0x00000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 7, 0x10000); - if (block_erase_m29f400bt(flash, 0x10000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 7, 0x20000); - if (block_erase_m29f400bt(flash, 0x20000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 7, 0x30000); - if (block_erase_m29f400bt(flash, 0x30000, 64 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024);
msg_cinfo("\n");
New version, updated to apply against current svn.
flashrom had an implicit erase-on-write for most flash chip and programmer drivers, but it was not entirely consistent. Some drivers had their own hand-rolled partial update functionality which made handling partial updates from generic code impossible.
Move implicit erase out of chip drivers, and kill some dead erase functions at the same time. A full chip erase is now performed in the generic code for all flash chips on write, and after that the whole chip is written. This is needed before we can change write function signature of the write functions to take start+len.
Compile tested and proofread, but that's it. The patch may cause flashrom to eat your dog or it may cause your dog to eat burned flash chips. Please test on real hardware. Thanks!
I have a cleanup patch for the write functions which will apply on top of this, but I wanted to keep this patch readable and self-contained.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-no_implicit_erase_inside_write/spi25.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi25.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/spi25.c (Arbeitskopie) @@ -976,14 +976,6 @@
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf) { - /* Erase first */ - msg_cinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("done.\n"); - return spi_chip_write_1_new(flash, buf, 0, flash->total_size * 1024); }
Index: flashrom-no_implicit_erase_inside_write/jedec.c =================================================================== --- flashrom-no_implicit_erase_inside_write/jedec.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/jedec.c (Arbeitskopie) @@ -402,11 +402,6 @@
mask = getaddrmask(flash);
- 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); @@ -429,12 +424,6 @@
mask = getaddrmask(flash);
- programmer_delay(10); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming page: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Arbeitskopie) @@ -86,11 +86,6 @@ write_lockbits_49lfxxxc(flash, 0); 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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - }
/* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); Index: flashrom-no_implicit_erase_inside_write/flashchips.c =================================================================== --- flashrom-no_implicit_erase_inside_write/flashchips.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/flashchips.c (Arbeitskopie) @@ -453,7 +453,7 @@ .model_id = AT_25DF321, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -866,7 +866,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10000, /* 10mS, Enter=Exec */ .block_erasers = @@ -1093,7 +1093,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -1147,7 +1147,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -1179,7 +1179,7 @@ .model_id = AMIC_A25L40P, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -1211,7 +1211,7 @@ .model_id = AMIC_A25L40P, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -1243,7 +1243,7 @@ .model_id = AMIC_A25L80P, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -1307,7 +1307,7 @@ .total_size = 256, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ .block_erasers = @@ -1364,7 +1364,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -2230,7 +2230,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2257,7 +2257,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2288,7 +2288,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2444,7 +2444,7 @@ .total_size = 256, .page_size = 256 * 1024, .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */ - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2840,7 +2840,7 @@ .model_id = MX_25L4005, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -2875,7 +2875,7 @@ .model_id = MX_25L8005, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -2910,7 +2910,7 @@ .model_id = MX_25L1605, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -2977,7 +2977,7 @@ .model_id = MX_25L3205, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3201,7 +3201,7 @@ .total_size = 256, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ .block_erasers = @@ -3344,7 +3344,7 @@ .model_id = ST_M25PE80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3651,7 +3651,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -3738,7 +3738,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -3768,7 +3768,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -3855,7 +3855,7 @@ .model_id = SPANSION_S25FL008A, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3881,7 +3881,7 @@ .model_id = SPANSION_S25FL016A, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3907,7 +3907,7 @@ .model_id = SST_25VF016B, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3942,7 +3942,7 @@ .model_id = SST_25VF032B, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4105,7 +4105,7 @@ .model_id = SST_25VF080B, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4167,7 +4167,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -4213,7 +4213,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -4236,7 +4236,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -4285,7 +4285,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4311,7 +4311,7 @@ .total_size = 256, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4389,7 +4389,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4496,7 +4496,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4561,7 +4561,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4624,7 +4624,7 @@ .total_size = 1024, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4687,7 +4687,7 @@ .total_size = 2048, .page_size = 4 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ .block_erasers = @@ -4719,7 +4719,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4748,7 +4748,7 @@ .total_size = 256, .page_size = 4 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -4835,7 +4835,7 @@ .total_size = 1024, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_FIXME, .block_erasers = @@ -4864,7 +4864,7 @@ .total_size = 2048, .page_size = 4 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ .block_erasers = @@ -5031,7 +5031,7 @@ .model_id = ST_M25P40, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5083,7 +5083,7 @@ .model_id = ST_M25P80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5109,7 +5109,7 @@ .model_id = ST_M25P16, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5135,7 +5135,7 @@ .model_id = ST_M25P32, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5417,7 +5417,7 @@ .total_size = 64, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5778,7 +5778,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -5996,7 +5996,7 @@ .model_id = W_25Q64, .total_size = 8192, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6089,7 +6089,7 @@ .model_id = W_25X40, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6118,7 +6118,7 @@ .model_id = W_25X80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6253,7 +6253,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, /* used datasheet for the W29C011A */ .block_erasers = @@ -6276,7 +6276,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6322,7 +6322,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_w29ee011, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (w29ee011.c) */ .block_erasers = @@ -6345,7 +6345,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6371,7 +6371,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6424,7 +6424,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6481,7 +6481,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6543,7 +6543,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -6574,7 +6574,7 @@ .total_size = 1024, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_FIXME, .block_erasers = Index: flashrom-no_implicit_erase_inside_write/sharplhf00l04.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Arbeitskopie) @@ -65,10 +65,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- if (erase_flash(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); Index: flashrom-no_implicit_erase_inside_write/spi.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/spi.c (Arbeitskopie) @@ -217,12 +217,6 @@ { int ret;
- msg_pinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_perr("ERASE FAILED!\n"); - return -1; - } - msg_pinfo("done.\n"); msg_pinfo("Programming flash... "); ret = spi_chip_write_256_new(flash, buf, 0, flash->total_size * 1024); if (!ret) Index: flashrom-no_implicit_erase_inside_write/sst28sf040.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst28sf040.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/sst28sf040.c (Arbeitskopie) @@ -122,12 +122,6 @@
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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - /* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); write_sector_28sf040(bios, buf + i * page_size, Index: flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c =================================================================== --- flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Arbeitskopie) @@ -93,6 +93,7 @@ return 0; }
+/* This function is unused. */ int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize) { chipaddr bios = flash->virtual_memory + sector; @@ -116,6 +117,7 @@ return 0; }
+/* FIXME: This function is not a real chip erase function. */ int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen) { int i; Index: flashrom-no_implicit_erase_inside_write/flashrom.c =================================================================== --- flashrom-no_implicit_erase_inside_write/flashrom.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/flashrom.c (Arbeitskopie) @@ -1421,6 +1421,7 @@
/* This function signature is horrible. We need to design a better interface, * but right now it allows us to split off the CLI code. + * Besides that, the function itself is a textbook example of abysmal code flow. */ int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it) { @@ -1475,12 +1476,7 @@ programmer_shutdown(); return 1; } - } else { - struct stat image_stat; - - if (flash->unlock) - flash->unlock(flash); - + } else if (write_it) { if (flash->tested & TEST_BAD_ERASE) { msg_cerr("Erase is not working on this chip " "and erase is needed for write. "); @@ -1502,6 +1498,18 @@ msg_cerr("Continuing anyway.\n"); } } + if (!flash->write) { + msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + programmer_shutdown(); + return 1; + } + if (flash->unlock) + flash->unlock(flash); + + } + if (write_it || verify_it) { + struct stat image_stat; + if ((image = fopen(filename, "rb")) == NULL) { perror(filename); programmer_shutdown(); @@ -1537,12 +1545,12 @@ // ////////////////////////////////////////////////////////////
if (write_it) { - msg_cinfo("Writing flash chip... "); - if (!flash->write) { - msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + if (erase_flash(flash)) { + emergency_help_message(); programmer_shutdown(); return 1; } + msg_cinfo("Writing flash chip... "); ret = flash->write(flash, buf); if (ret) { msg_cerr("FAILED!\n"); Index: flashrom-no_implicit_erase_inside_write/82802ab.c =================================================================== --- flashrom-no_implicit_erase_inside_write/82802ab.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/82802ab.c (Arbeitskopie) @@ -144,23 +144,6 @@ return 0; }
-int erase_82802ab(struct flashchip *flash) -{ - int i; - unsigned int total_size = flash->total_size * 1024; - - 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_block_82802ab(flash, i, flash->page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("DONE ERASE\n"); - - return 0; -} - void write_page_82802ab(chipaddr bios, uint8_t *src, chipaddr dst, int page_size) { @@ -179,11 +162,6 @@ int i; chipaddr bios = flash->virtual_memory;
- if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming at: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/chipdrivers.h =================================================================== --- flashrom-no_implicit_erase_inside_write/chipdrivers.h (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/chipdrivers.h (Arbeitskopie) @@ -33,8 +33,6 @@ int probe_spi_res2(struct flashchip *flash); int spi_write_enable(void); int spi_write_disable(void); -int spi_chip_erase_60(struct flashchip *flash); -int spi_chip_erase_c7(struct flashchip *flash); int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen); @@ -58,7 +56,6 @@ /* 82802ab.c */ uint8_t wait_82802ab(chipaddr bios); int probe_82802ab(struct flashchip *flash); -int erase_82802ab(struct flashchip *flash); 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); @@ -73,7 +70,6 @@ int write_byte_program_jedec(chipaddr bios, uint8_t *src, chipaddr dst); int probe_jedec(struct flashchip *flash); -int erase_chip_jedec(struct flashchip *flash); int write_jedec(struct flashchip *flash, uint8_t *buf); int write_jedec_1(struct flashchip *flash, uint8_t *buf); int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned int pagesize); @@ -83,7 +79,6 @@
/* m29f400bt.c */ int probe_m29f400bt(struct flashchip *flash); -int erase_m29f400bt(struct flashchip *flash); int block_erase_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int block_erase_chip_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int write_m29f400bt(struct flashchip *flash, uint8_t *buf); Index: flashrom-no_implicit_erase_inside_write/m29f400bt.c =================================================================== --- flashrom-no_implicit_erase_inside_write/m29f400bt.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/m29f400bt.c (Arbeitskopie) @@ -143,7 +143,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- //erase_m29f400bt (flash); msg_cinfo("Programming page:\n "); /********************************* *Pages for M29F400BT: @@ -163,41 +162,21 @@ msg_cinfo("total_size/page_size = %d\n", total_size / page_size); for (i = 0; i < (total_size / page_size) - 1; i++) { msg_cinfo("%04d at address: 0x%08x\n", i, i * page_size); - if (block_erase_m29f400bt(flash, i * page_size, page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + i * page_size, bios + i * page_size, page_size); 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\n", 7, 0x70000); - if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 8, 0x78000); - if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 9, 0x7a000); - if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 10, 0x7c000); - if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
msg_cinfo("\n");
On Sat, Jul 17, 2010 at 12:18:49AM +0200, Carl-Daniel Hailfinger wrote:
New version, updated to apply against current svn.
flashrom had an implicit erase-on-write for most flash chip and
^ s
Compile tested and proofread, but that's it. The patch may cause flashrom to eat your dog or it may cause your dog to eat burned flash chips. Please test on real hardware. Thanks!
I have a cleanup patch for the write functions which will apply on top of this, but I wanted to keep this patch readable and self-contained.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Uwe Hermann uwe@hermann-uwe.de
Tested on ASUS A8NE-FM with "SST SST49LF004A/B" (512 KB, FWH) and on a Dr. Kaiser PCI card with a "Macronix MX29F001B" (128 KB, Parallel).
Tested all operations including erase/write multiple times for good measure.
Index: flashrom-no_implicit_erase_inside_write/flashchips.c
--- flashrom-no_implicit_erase_inside_write/flashchips.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/flashchips.c (Arbeitskopie) @@ -453,7 +453,7 @@ .model_id = AT_25DF321, .total_size = 4096, .page_size = 256,
.tested = TEST_OK_PRW,
.probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers =.tested = TEST_OK_PR,
Didn't check whether any new chips were added since this patch which would also need their W bit removed. Feel free to merge that into the patch and re-use my ack.
Index: flashrom-no_implicit_erase_inside_write/82802ab.c
--- flashrom-no_implicit_erase_inside_write/82802ab.c (Revision 1083) +++ flashrom-no_implicit_erase_inside_write/82802ab.c (Arbeitskopie) @@ -144,23 +144,6 @@ return 0; }
-int erase_82802ab(struct flashchip *flash) -{
- int i;
- unsigned int total_size = flash->total_size * 1024;
- 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_block_82802ab(flash, i, flash->page_size)) {
msg_cerr("ERASE FAILED!\n");
return -1;
}
- msg_cinfo("DONE ERASE\n");
- return 0;
-}
No longer needed? Not used currently anywhere, it seems.
Uwe.
On 28.07.2010 02:23, Uwe Hermann wrote:
Acked-by: Uwe Hermann uwe@hermann-uwe.de
Tested on ASUS A8NE-FM with "SST SST49LF004A/B" (512 KB, FWH) and on a Dr. Kaiser PCI card with a "Macronix MX29F001B" (128 KB, Parallel).
Tested all operations including erase/write multiple times for good measure.
Updated against current svn.
flashrom had an implicit erase-on-write for most flash chip and programmer drivers, but it was not entirely consistent. Some drivers had their own hand-rolled partial update functionality which made handling partial updates from generic code impossible.
Move implicit erase out of chip drivers, and kill some dead erase functions at the same time. A full chip erase is now performed in the generic code for all flash chips on write, and after that the whole chip is written. This is needed before we can change write function signature of the write functions to take start+len.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-by: Uwe Hermann uwe@hermann-uwe.de
Index: flashrom-no_implicit_erase_inside_write/jedec.c =================================================================== --- flashrom-no_implicit_erase_inside_write/jedec.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/jedec.c (Arbeitskopie) @@ -402,11 +402,6 @@
mask = getaddrmask(flash);
- 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); @@ -429,12 +424,6 @@
mask = getaddrmask(flash);
- programmer_delay(10); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming page: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/sst49lfxxxc.c (Arbeitskopie) @@ -86,11 +86,6 @@ write_lockbits_49lfxxxc(flash, 0); 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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - }
/* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); Index: flashrom-no_implicit_erase_inside_write/sharplhf00l04.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/sharplhf00l04.c (Arbeitskopie) @@ -65,10 +65,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- if (erase_flash(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); Index: flashrom-no_implicit_erase_inside_write/82802ab.c =================================================================== --- flashrom-no_implicit_erase_inside_write/82802ab.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/82802ab.c (Arbeitskopie) @@ -144,23 +144,6 @@ return 0; }
-int erase_82802ab(struct flashchip *flash) -{ - int i; - unsigned int total_size = flash->total_size * 1024; - - 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_block_82802ab(flash, i, flash->page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("DONE ERASE\n"); - - return 0; -} - void write_page_82802ab(chipaddr bios, uint8_t *src, chipaddr dst, int page_size) { @@ -179,11 +162,6 @@ int i; chipaddr bios = flash->virtual_memory;
- if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("Programming at: "); for (i = 0; i < flash->total_size; i++) { if ((i & 0x3) == 0) Index: flashrom-no_implicit_erase_inside_write/spi25.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi25.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/spi25.c (Arbeitskopie) @@ -1321,14 +1321,6 @@
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf) { - /* Erase first */ - msg_cinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("done.\n"); - return spi_chip_write_1_new(flash, buf, 0, flash->total_size * 1024); }
@@ -1426,14 +1418,6 @@
int spi_aai_write(struct flashchip *flash, uint8_t *buf) { - /* Erase first */ - msg_cinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - msg_cinfo("done.\n"); - return spi_aai_write_new(flash, buf, 0, flash->total_size * 1024); }
Index: flashrom-no_implicit_erase_inside_write/flashchips.c =================================================================== --- flashrom-no_implicit_erase_inside_write/flashchips.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/flashchips.c (Arbeitskopie) @@ -65,7 +65,7 @@ .total_size = 128, .page_size = 16 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, .block_erasers = @@ -231,7 +231,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */ .block_erasers = @@ -477,7 +477,7 @@ .model_id = AMIC_A25L40PT, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -509,7 +509,7 @@ .model_id = AMIC_A25L40PU, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -541,7 +541,7 @@ .model_id = AMIC_A25L80P, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -608,7 +608,7 @@ .model_id = AMIC_A25L16PU, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid4, .probe_timing = TIMING_ZERO, .block_erasers = @@ -927,7 +927,7 @@ .total_size = 256, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ .block_erasers = @@ -984,7 +984,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -1196,7 +1196,7 @@ .total_size = 4096, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -1658,7 +1658,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10000, /* 10mS, Enter=Exec */ .block_erasers = @@ -1885,7 +1885,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -1939,7 +1939,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2744,7 +2744,7 @@ .total_size = 1024, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -2843,7 +2843,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2870,7 +2870,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -2901,7 +2901,7 @@ .total_size = 256, .page_size = 256, .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -3057,7 +3057,7 @@ .total_size = 256, .page_size = 256 * 1024, .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */ - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -3196,7 +3196,7 @@ .model_id = INTEL_28F002T, .total_size = 256, .page_size = 256 * 1024, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_82802ab, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -3510,7 +3510,7 @@ .total_size = 512, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3546,7 +3546,7 @@ .total_size = 1024, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3582,7 +3582,7 @@ .total_size = 2048, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3684,7 +3684,7 @@ .total_size = 4096, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -3911,7 +3911,7 @@ .total_size = 256, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */ .block_erasers = @@ -4262,7 +4262,7 @@ .model_id = ST_M25PE80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4507,7 +4507,7 @@ .total_size = 256, .page_size = 8 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_FIXME, .block_erasers = @@ -4569,7 +4569,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -4656,7 +4656,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -4686,7 +4686,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */ .block_erasers = @@ -4773,7 +4773,7 @@ .model_id = SPANSION_S25FL008A, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4799,7 +4799,7 @@ .model_id = SPANSION_S25FL016A, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4825,7 +4825,7 @@ .model_id = SST_SST25VF016B, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4860,7 +4860,7 @@ .model_id = SST_SST25VF032B, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -4895,7 +4895,7 @@ .model_id = SST_SST25VF064C, .total_size = 8192, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5058,7 +5058,7 @@ .model_id = SST_SST25VF080B, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5120,7 +5120,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -5166,7 +5166,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -5189,7 +5189,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -5238,7 +5238,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5264,7 +5264,7 @@ .total_size = 256, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5290,7 +5290,7 @@ .total_size = 512, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5316,7 +5316,7 @@ .total_size = 64, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5342,7 +5342,7 @@ .total_size = 128, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5449,7 +5449,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5514,7 +5514,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5577,7 +5577,7 @@ .total_size = 1024, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5640,7 +5640,7 @@ .total_size = 2048, .page_size = 4 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ .block_erasers = @@ -5672,7 +5672,7 @@ .total_size = 256, .page_size = 16 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5701,7 +5701,7 @@ .total_size = 256, .page_size = 4 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5730,7 +5730,7 @@ .total_size = 512, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150 ns */ .block_erasers = @@ -5759,7 +5759,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 1, /* 150ns */ .block_erasers = @@ -5789,7 +5789,7 @@ .total_size = 1024, .page_size = 4096, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_FIXME, .block_erasers = @@ -5818,7 +5818,7 @@ .total_size = 2048, .page_size = 4 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_82802ab, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */ .block_erasers = @@ -5906,7 +5906,7 @@ .model_id = ST_M25P10A, .total_size = 128, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -5985,7 +5985,7 @@ .model_id = ST_M25P40, .total_size = 512, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6037,7 +6037,7 @@ .model_id = ST_M25P80, .total_size = 1024, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6063,7 +6063,7 @@ .model_id = ST_M25P16, .total_size = 2048, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6089,7 +6089,7 @@ .model_id = ST_M25P32, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6167,7 +6167,7 @@ .model_id = ST_M25PX32, .total_size = 4096, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6196,7 +6196,7 @@ .model_id = ST_M25PX64, .total_size = 8192, .page_size = 256, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6429,7 +6429,7 @@ .total_size = 64, .page_size = 64 * 1024, .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, .block_erasers = @@ -6522,7 +6522,7 @@ .total_size = 1024, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_82802ab, .probe_timing = TIMING_FIXME, .block_erasers = @@ -6816,7 +6816,7 @@ .total_size = 256, .page_size = 512, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = @@ -7008,7 +7008,7 @@ .total_size = 1024, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -7080,7 +7080,7 @@ .total_size = 4096, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -7116,7 +7116,7 @@ .total_size = 8192, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -7212,7 +7212,7 @@ .total_size = 512, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -7242,7 +7242,7 @@ .total_size = 1024, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -7272,7 +7272,7 @@ .total_size = 2048, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = @@ -7380,7 +7380,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, /* used datasheet for the W29C011A */ .block_erasers = @@ -7403,7 +7403,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -7449,7 +7449,7 @@ .total_size = 128, .page_size = 128, .feature_bits = FEATURE_LONG_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_w29ee011, .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (w29ee011.c) */ .block_erasers = @@ -7472,7 +7472,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -7498,7 +7498,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -7551,7 +7551,7 @@ .total_size = 512, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -7608,7 +7608,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -7662,7 +7662,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -7693,7 +7693,7 @@ .total_size = 256, .page_size = 128, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRW, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = 10, .block_erasers = @@ -7724,7 +7724,7 @@ .total_size = 1024, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, - .tested = TEST_OK_PREW, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_FIXME, .block_erasers = Index: flashrom-no_implicit_erase_inside_write/spi.c =================================================================== --- flashrom-no_implicit_erase_inside_write/spi.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/spi.c (Arbeitskopie) @@ -262,12 +262,6 @@ { int ret;
- msg_pinfo("Erasing flash before programming... "); - if (erase_flash(flash)) { - msg_perr("ERASE FAILED!\n"); - return -1; - } - msg_pinfo("done.\n"); msg_pinfo("Programming flash... "); ret = spi_chip_write_256_new(flash, buf, 0, flash->total_size * 1024); if (!ret) Index: flashrom-no_implicit_erase_inside_write/sst28sf040.c =================================================================== --- flashrom-no_implicit_erase_inside_write/sst28sf040.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/sst28sf040.c (Arbeitskopie) @@ -122,12 +122,6 @@
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)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } - /* write to the sector */ msg_cinfo("%04d at address: 0x%08x", i, i * page_size); write_sector_28sf040(bios, buf + i * page_size, Index: flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c =================================================================== --- flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/stm50flw0x0x.c (Arbeitskopie) @@ -93,6 +93,7 @@ return 0; }
+/* This function is unused. */ int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize) { chipaddr bios = flash->virtual_memory + sector; @@ -116,6 +117,7 @@ return 0; }
+/* FIXME: This function is not a real chip erase function. */ int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen) { int i; Index: flashrom-no_implicit_erase_inside_write/flashrom.c =================================================================== --- flashrom-no_implicit_erase_inside_write/flashrom.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/flashrom.c (Arbeitskopie) @@ -1509,6 +1509,7 @@
/* This function signature is horrible. We need to design a better interface, * but right now it allows us to split off the CLI code. + * Besides that, the function itself is a textbook example of abysmal code flow. */ int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it) { @@ -1563,12 +1564,7 @@ programmer_shutdown(); return 1; } - } else { - struct stat image_stat; - - if (flash->unlock) - flash->unlock(flash); - + } else if (write_it) { if (flash->tested & TEST_BAD_ERASE) { msg_cerr("Erase is not working on this chip " "and erase is needed for write. "); @@ -1590,6 +1586,18 @@ msg_cerr("Continuing anyway.\n"); } } + if (!flash->write) { + msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + programmer_shutdown(); + return 1; + } + if (flash->unlock) + flash->unlock(flash); + + } + if (write_it || verify_it) { + struct stat image_stat; + if ((image = fopen(filename, "rb")) == NULL) { perror(filename); programmer_shutdown(); @@ -1625,12 +1633,12 @@ // ////////////////////////////////////////////////////////////
if (write_it) { - msg_cinfo("Writing flash chip... "); - if (!flash->write) { - msg_cerr("Error: flashrom has no write function for this flash chip.\n"); + if (erase_flash(flash)) { + emergency_help_message(); programmer_shutdown(); return 1; } + msg_cinfo("Writing flash chip... "); ret = flash->write(flash, buf); if (ret) { msg_cerr("FAILED!\n"); Index: flashrom-no_implicit_erase_inside_write/m29f400bt.c =================================================================== --- flashrom-no_implicit_erase_inside_write/m29f400bt.c (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/m29f400bt.c (Arbeitskopie) @@ -143,7 +143,6 @@ int page_size = flash->page_size; chipaddr bios = flash->virtual_memory;
- //erase_m29f400bt (flash); msg_cinfo("Programming page:\n "); /********************************* *Pages for M29F400BT: @@ -163,41 +162,21 @@ msg_cinfo("total_size/page_size = %d\n", total_size / page_size); for (i = 0; i < (total_size / page_size) - 1; i++) { msg_cinfo("%04d at address: 0x%08x\n", i, i * page_size); - if (block_erase_m29f400bt(flash, i * page_size, page_size)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + i * page_size, bios + i * page_size, page_size); 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\n", 7, 0x70000); - if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 8, 0x78000); - if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 9, 0x7a000); - if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
msg_cinfo("%04d at address: 0x%08x\n", 10, 0x7c000); - if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) { - msg_cerr("ERASE FAILED!\n"); - return -1; - } write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
msg_cinfo("\n"); Index: flashrom-no_implicit_erase_inside_write/chipdrivers.h =================================================================== --- flashrom-no_implicit_erase_inside_write/chipdrivers.h (Revision 1205) +++ flashrom-no_implicit_erase_inside_write/chipdrivers.h (Arbeitskopie) @@ -33,8 +33,6 @@ int probe_spi_res2(struct flashchip *flash); int spi_write_enable(void); int spi_write_disable(void); -int spi_chip_erase_60(struct flashchip *flash); -int spi_chip_erase_c7(struct flashchip *flash); int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen); @@ -69,7 +67,6 @@ /* 82802ab.c */ uint8_t wait_82802ab(chipaddr bios); int probe_82802ab(struct flashchip *flash); -int erase_82802ab(struct flashchip *flash); 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); @@ -84,7 +81,6 @@ int write_byte_program_jedec(chipaddr bios, uint8_t *src, chipaddr dst); int probe_jedec(struct flashchip *flash); -int erase_chip_jedec(struct flashchip *flash); int write_jedec(struct flashchip *flash, uint8_t *buf); int write_jedec_1(struct flashchip *flash, uint8_t *buf); int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned int pagesize); @@ -94,7 +90,6 @@
/* m29f400bt.c */ int probe_m29f400bt(struct flashchip *flash); -int erase_m29f400bt(struct flashchip *flash); int block_erase_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int block_erase_chip_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len); int write_m29f400bt(struct flashchip *flash, uint8_t *buf);
On 08.10.2010 19:11, Carl-Daniel Hailfinger wrote:
flashrom had an implicit erase-on-write for most flash chip and programmer drivers, but it was not entirely consistent. Some drivers had their own hand-rolled partial update functionality which made handling partial updates from generic code impossible.
Move implicit erase out of chip drivers, and kill some dead erase functions at the same time. A full chip erase is now performed in the generic code for all flash chips on write, and after that the whole chip is written. This is needed before we can change write function signature of the write functions to take start+len.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-by: Uwe Hermann uwe@hermann-uwe.de
Committed in r1206.
Regards, Carl-Daniel