diff options
author | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2012-08-25 01:17:58 +0000 |
---|---|---|
committer | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2012-08-25 01:17:58 +0000 |
commit | 5a7cb847f096dacb0bf96b3aa909f79d76ae8204 (patch) | |
tree | da511e990c1fdded61ee5dcefae38314c3a5a6cc | |
parent | dd73d830f7370b5f0bbdaa0780b0ff8d6ff1776a (diff) | |
download | flashrom-5a7cb847f096dacb0bf96b3aa909f79d76ae8204.tar.gz flashrom-5a7cb847f096dacb0bf96b3aa909f79d76ae8204.tar.bz2 flashrom-5a7cb847f096dacb0bf96b3aa909f79d76ae8204.zip |
Make struct flashchip a field in struct flashctx instead of a complete copy
All the driver conversion work and cleanup has been done by Stefan.
flashrom.c and cli_classic.c are a joint work of Stefan and Carl-Daniel.
Corresponding to flashrom svn r1579.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
-rw-r--r-- | 82802ab.c | 12 | ||||
-rw-r--r-- | cli_classic.c | 44 | ||||
-rw-r--r-- | dediprog.c | 2 | ||||
-rw-r--r-- | en29lv640b.c | 4 | ||||
-rw-r--r-- | flash.h | 26 | ||||
-rw-r--r-- | flashrom.c | 190 | ||||
-rw-r--r-- | ichspi.c | 12 | ||||
-rw-r--r-- | it87spi.c | 20 | ||||
-rw-r--r-- | jedec.c | 45 | ||||
-rw-r--r-- | layout.c | 4 | ||||
-rw-r--r-- | m29f400bt.c | 4 | ||||
-rw-r--r-- | pm49fl00x.c | 8 | ||||
-rw-r--r-- | print.c | 58 | ||||
-rw-r--r-- | programmer.h | 2 | ||||
-rw-r--r-- | sfdp.c | 32 | ||||
-rw-r--r-- | spi.c | 6 | ||||
-rw-r--r-- | spi25.c | 43 | ||||
-rw-r--r-- | sst28sf040.c | 2 | ||||
-rw-r--r-- | sst49lfxxxc.c | 2 | ||||
-rw-r--r-- | sst_fwhub.c | 6 | ||||
-rw-r--r-- | stm50flw0x0x.c | 4 | ||||
-rw-r--r-- | w29ee011.c | 6 | ||||
-rw-r--r-- | w39.c | 8 |
23 files changed, 263 insertions, 277 deletions
@@ -44,7 +44,7 @@ int probe_82802ab(struct flashctx *flash) { chipaddr bios = flash->virtual_memory; uint8_t id1, id2, flashcontent1, flashcontent2; - int shifted = (flash->feature_bits & FEATURE_ADDR_SHIFTED) != 0; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) != 0; /* Reset to get a clean state */ chip_writeb(flash, 0xFF, bios); @@ -80,10 +80,10 @@ int probe_82802ab(struct flashctx *flash) msg_cdbg(", id2 is normal flash content"); msg_cdbg("\n"); - if (id1 != flash->manufacture_id || id2 != flash->model_id) + if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id) return 0; - if (flash->feature_bits & FEATURE_REGISTERMAP) + if (flash->chip->feature_bits & FEATURE_REGISTERMAP) map_flash_registers(flash); return 1; @@ -112,7 +112,7 @@ int unlock_82802ab(struct flashctx *flash) int i; //chipaddr wrprotect = flash->virtual_registers + page + 2; - for (i = 0; i < flash->total_size * 1024; i+= flash->page_size) + for (i = 0; i < flash->chip->total_size * 1024; i+= flash->chip->page_size) chip_writeb(flash, 0, flash->virtual_registers + i + 2); return 0; @@ -181,7 +181,7 @@ int unlock_28f004s5(struct flashctx *flash) } /* Read block lock-bits */ - for (i = 0; i < flash->total_size * 1024; i+= (64 * 1024)) { + for (i = 0; i < flash->chip->total_size * 1024; i+= (64 * 1024)) { bcfg = chip_readb(flash, bios + i + 2); // read block lock config msg_cdbg("block lock at %06x is %slocked!\n", i, bcfg ? "" : "un"); if (bcfg) { @@ -234,7 +234,7 @@ int unlock_lh28f008bjt(struct flashctx *flash) } /* Read block lock-bits, 8 * 8 KB + 15 * 64 KB */ - for (i = 0; i < flash->total_size * 1024; + for (i = 0; i < flash->chip->total_size * 1024; i += (i >= (64 * 1024) ? 64 * 1024 : 8 * 1024)) { bcfg = chip_readb(flash, bios + i + 2); /* read block lock config */ msg_cdbg("block lock at %06x is %slocked!\n", i, diff --git a/cli_classic.c b/cli_classic.c index cf3874c80..58696adf9 100644 --- a/cli_classic.c +++ b/cli_classic.c @@ -109,8 +109,8 @@ int main(int argc, char *argv[]) { unsigned long size; /* Probe for up to three flash chips. */ - const struct flashchip *flash; - struct flashctx flashes[3]; + const struct flashchip *chip = NULL; + struct flashctx flashes[3] = {{0}}; struct flashctx *fill_flash; const char *name; int namelen, opt, i, j; @@ -389,17 +389,16 @@ int main(int argc, char *argv[]) } /* Does a chip with the requested name exist in the flashchips array? */ if (chip_to_probe) { - for (flash = flashchips; flash && flash->name; flash++) - if (!strcmp(flash->name, chip_to_probe)) + for (chip = flashchips; chip && chip->name; chip++) + if (!strcmp(chip->name, chip_to_probe)) break; - if (!flash || !flash->name) { + if (!chip || !chip->name) { msg_cerr("Error: Unknown chip '%s' specified.\n", chip_to_probe); msg_gerr("Run flashrom -L to view the hardware supported in this flashrom version.\n"); ret = 1; goto out; } - /* Clean up after the check. */ - flash = NULL; + /* Keep chip around for later usage in case a forced read is requested. */ } if (prog == PROGRAMMER_INVALID) { @@ -419,16 +418,13 @@ int main(int argc, char *argv[]) goto out_shutdown; } tempstr = flashbuses_to_text(get_buses_supported()); - msg_pdbg("The following protocols are supported: %s.\n", - tempstr); + msg_pdbg("The following protocols are supported: %s.\n", tempstr); free(tempstr); for (j = 0; j < registered_programmer_count; j++) { startchip = 0; while (chipcount < ARRAY_SIZE(flashes)) { - startchip = probe_flash(®istered_programmers[j], - startchip, - &flashes[chipcount], 0); + startchip = probe_flash(®istered_programmers[j], startchip, &flashes[chipcount], 0); if (startchip == -1) break; chipcount++; @@ -437,9 +433,9 @@ int main(int argc, char *argv[]) } if (chipcount > 1) { - msg_cinfo("Multiple flash chips were detected: \"%s\"", flashes[0].name); + msg_cinfo("Multiple flash chips were detected: \"%s\"", flashes[0].chip->name); for (i = 1; i < chipcount; i++) - msg_cinfo(", \"%s\"", flashes[i].name); + msg_cinfo(", \"%s\"", flashes[i].chip->name); msg_cinfo("\nPlease specify which chip to use with the -c <chipname> option.\n"); ret = 1; goto out_shutdown; @@ -456,9 +452,15 @@ int main(int argc, char *argv[]) /* This loop just counts compatible controllers. */ for (j = 0; j < registered_programmer_count; j++) { pgm = ®istered_programmers[j]; - if (pgm->buses_supported & flashes[0].bustype) + /* chip is still set from the chip_to_probe earlier in this function. */ + if (pgm->buses_supported & chip->bustype) compatible_programmers++; } + if (!compatible_programmers) { + msg_cinfo("No compatible controller found for the requested flash chip.\n"); + ret = 1; + goto out_shutdown; + } if (compatible_programmers > 1) msg_cinfo("More than one compatible controller found for the requested flash " "chip, using the first one.\n"); @@ -469,6 +471,7 @@ int main(int argc, char *argv[]) break; } if (startchip == -1) { + // FIXME: This should never happen! Ask for a bug report? msg_cinfo("Probing for flash chip '%s' failed.\n", chip_to_probe); ret = 1; goto out_shutdown; @@ -481,19 +484,18 @@ int main(int argc, char *argv[]) goto out_shutdown; } else if (!chip_to_probe) { /* repeat for convenience when looking at foreign logs */ - tempstr = flashbuses_to_text(flashes[0].bustype); + tempstr = flashbuses_to_text(flashes[0].chip->bustype); msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n", - flashes[0].vendor, flashes[0].name, - flashes[0].total_size, tempstr); + flashes[0].chip->vendor, flashes[0].chip->name, flashes[0].chip->total_size, tempstr); free(tempstr); } fill_flash = &flashes[0]; - check_chip_supported(fill_flash); + check_chip_supported(fill_flash->chip); - size = fill_flash->total_size * 1024; - if (check_max_decode(fill_flash->pgm->buses_supported & fill_flash->bustype, size) && (!force)) { + size = fill_flash->chip->total_size * 1024; + if (check_max_decode(fill_flash->pgm->buses_supported & fill_flash->chip->bustype, size) && (!force)) { msg_cerr("Chip is too big for this programmer (-V gives details). Use --force to override.\n"); ret = 1; goto out_shutdown; diff --git a/dediprog.c b/dediprog.c index 9559eed41..a81cf8386 100644 --- a/dediprog.c +++ b/dediprog.c @@ -381,7 +381,7 @@ static int dediprog_spi_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, uint8_t dedi_spi_cmd) { int ret; - const unsigned int chunksize = flash->page_size; + const unsigned int chunksize = flash->chip->page_size; unsigned int residue = start % chunksize ? chunksize - start % chunksize : 0; unsigned int bulklen; diff --git a/en29lv640b.c b/en29lv640b.c index 0dff2d149..e79415afb 100644 --- a/en29lv640b.c +++ b/en29lv640b.c @@ -81,7 +81,7 @@ int probe_en29lv640b(struct flashctx *flash) msg_cdbg("%s: id1 0x%04x, id2 0x%04x\n", __func__, id1, id2); - if (id1 == flash->manufacture_id && id2 == flash->model_id) + if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id) return 1; return 0; @@ -130,7 +130,7 @@ int block_erase_en29lv640b(struct flashctx *flash, unsigned int start, int block_erase_chip_en29lv640b(struct flashctx *flash, unsigned int address, unsigned int blocklen) { - if ((address != 0) || (blocklen != flash->total_size * 1024)) { + if ((address != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; } @@ -87,6 +87,7 @@ enum chipbustype { #define FEATURE_WRSR_EITHER (FEATURE_WRSR_EWSR | FEATURE_WRSR_WREN) struct flashctx; +typedef int (erasefunc_t)(struct flashctx *flash, unsigned int addr, unsigned int blocklen); struct flashchip { const char *vendor; @@ -148,35 +149,14 @@ struct flashchip { } voltage; }; -/* struct flashctx must always contain struct flashchip at the beginning. */ struct flashctx { - const char *vendor; - const char *name; - enum chipbustype bustype; - uint32_t manufacture_id; - uint32_t model_id; - int total_size; - int page_size; - int feature_bits; - uint32_t tested; - int (*probe) (struct flashctx *flash); - int probe_timing; - struct block_eraser block_erasers[NUM_ERASEFUNCTIONS]; - int (*printlock) (struct flashctx *flash); - int (*unlock) (struct flashctx *flash); - int (*write) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); - int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); - struct voltage voltage; - /* struct flashchip ends here. */ - + struct flashchip *chip; chipaddr virtual_memory; /* Some flash devices have an additional register space. */ chipaddr virtual_registers; struct registered_programmer *pgm; }; -typedef int (erasefunc_t)(struct flashctx *flash, unsigned int addr, unsigned int blocklen); - #define TEST_UNTESTED 0 #define TEST_OK_PROBE (1 << 0) @@ -307,7 +287,7 @@ int print(enum msglevel level, const char *fmt, ...) __attribute__((format(print int register_include_arg(char *name); int process_include_args(void); int read_romlayout(char *name); -int handle_romentries(struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents); +int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents); /* spi.c */ struct spi_command { diff --git a/flashrom.c b/flashrom.c index ee01e60c2..44a3eba26 100644 --- a/flashrom.c +++ b/flashrom.c @@ -416,7 +416,7 @@ void programmer_delay(int usecs) void map_flash_registers(struct flashctx *flash) { - size_t size = flash->total_size * 1024; + size_t size = flash->chip->total_size * 1024; /* Flash registers live 4 MByte below the flash. */ /* FIXME: This is incorrect for nonstandard flashbase. */ flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size); @@ -580,7 +580,7 @@ int verify_range(struct flashctx *flash, uint8_t *cmpbuf, unsigned int start, if (!len) goto out_free; - if (!flash->read) { + if (!flash->chip->read) { msg_cerr("ERROR: flashrom has no read function for this flash chip.\n"); return 1; } @@ -589,17 +589,17 @@ int verify_range(struct flashctx *flash, uint8_t *cmpbuf, unsigned int start, exit(1); } - if (start + len > flash->total_size * 1024) { + if (start + len > flash->chip->total_size * 1024) { msg_gerr("Error: %s called with start 0x%x + len 0x%x >" " total_size 0x%x\n", __func__, start, len, - flash->total_size * 1024); + flash->chip->total_size * 1024); ret = -1; goto out_free; } if (!message) message = "VERIFY"; - ret = flash->read(flash, readbuf, start, len); + ret = flash->chip->read(flash, readbuf, start, len); if (ret) { msg_gerr("Verification impossible because read failed " "at 0x%x (len 0x%x)\n", start, len); @@ -950,44 +950,49 @@ int check_max_decode(enum chipbustype buses, uint32_t size) return 1; } -int probe_flash(struct registered_programmer *pgm, int startchip, - struct flashctx *fill_flash, int force) +int probe_flash(struct registered_programmer *pgm, int startchip, struct flashctx *flash, int force) { - const struct flashchip *flash; + const struct flashchip *chip; unsigned long base = 0; char location[64]; uint32_t size; enum chipbustype buses_common; char *tmp; - for (flash = flashchips + startchip; flash && flash->name; flash++) { - if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0) + for (chip = flashchips + startchip; chip && chip->name; chip++) { + if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0) continue; - buses_common = pgm->buses_supported & flash->bustype; + buses_common = pgm->buses_supported & chip->bustype; if (!buses_common) continue; - msg_gdbg("Probing for %s %s, %d kB: ", - flash->vendor, flash->name, flash->total_size); - if (!flash->probe && !force) { - msg_gdbg("failed! flashrom has no probe function for " - "this flash chip.\n"); + msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size); + if (!chip->probe && !force) { + msg_gdbg("failed! flashrom has no probe function for this flash chip.\n"); continue; } - size = flash->total_size * 1024; + size = chip->total_size * 1024; check_max_decode(buses_common, size); /* Start filling in the dynamic data. */ - memcpy(fill_flash, flash, sizeof(struct flashchip)); - fill_flash->pgm = pgm; + flash->chip = calloc(1, sizeof(struct flashchip)); + if (!flash->chip) { + msg_gerr("Out of memory!\n"); + exit(1); + } + memcpy(flash->chip, chip, sizeof(struct flashchip)); + flash->pgm = pgm; base = flashbase ? flashbase : (0xffffffff - size + 1); - fill_flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size); + flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size); + /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash() + * is only called with force=1 after normal probing failed. + */ if (force) break; - if (fill_flash->probe(fill_flash) != 1) + if (flash->chip->probe(flash) != 1) goto notfound; /* If this is the first chip found, accept it. @@ -997,11 +1002,11 @@ int probe_flash(struct registered_programmer *pgm, int startchip, * one for this programmer interface and thus no other chip has * been found on this interface. */ - if (startchip == 0 && fill_flash->model_id == SFDP_DEVICE_ID) { + if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) { msg_cinfo("===\n" "SFDP has autodetected a flash chip which is " "not natively supported by flashrom yet.\n"); - if (count_usable_erasers(fill_flash) == 0) + if (count_usable_erasers(flash) == 0) msg_cinfo("The standard operations read and " "verify should work, but to support " "erase, write and all other " @@ -1020,16 +1025,21 @@ int probe_flash(struct registered_programmer *pgm, int startchip, "===\n"); } - if (startchip == 0 || - ((fill_flash->model_id != GENERIC_DEVICE_ID) && - (fill_flash->model_id != SFDP_DEVICE_ID))) + /* First flash chip detected on this bus. */ + if (startchip == 0) break; - + /* Not the first flash chip detected on this bus, but not a generic match either. */ + if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID)) + break; + /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */ notfound: - programmer_unmap_flash_region((void *)fill_flash->virtual_memory, size); + programmer_unmap_flash_region((void *)flash->virtual_memory, size); + flash->virtual_memory = (chipaddr)NULL; + free(flash->chip); + flash->chip = NULL; } - if (!flash || !flash->name) + if (!flash->chip) return -1; #if CONFIG_INTERNAL == 1 @@ -1039,27 +1049,26 @@ notfound: #endif snprintf(location, sizeof(location), "on %s", programmer_table[programmer].name); - tmp = flashbuses_to_text(flash->bustype); - msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) %s.\n", - force ? "Assuming" : "Found", fill_flash->vendor, - fill_flash->name, fill_flash->total_size, tmp, location); + tmp = flashbuses_to_text(flash->chip->bustype); + msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) %s.\n", force ? "Assuming" : "Found", + flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp, location); free(tmp); /* Flash registers will not be mapped if the chip was forced. Lock info * may be stored in registers, so avoid lock info printing. */ if (!force) - if (fill_flash->printlock) - fill_flash->printlock(fill_flash); + if (flash->chip->printlock) + flash->chip->printlock(flash); /* Return position of matching chip. */ - return flash - flashchips; + return chip - flashchips; } int verify_flash(struct flashctx *flash, uint8_t *buf) { int ret; - unsigned int total_size = flash->total_size * 1024; + unsigned int total_size = flash->chip->total_size * 1024; msg_cinfo("Verifying flash... "); @@ -1132,7 +1141,7 @@ int write_buf_to_file(unsigned char *buf, unsigned long size, int read_flash_to_file(struct flashctx *flash, const char *filename) { - unsigned long size = flash->total_size * 1024; + unsigned long size = flash->chip->total_size * 1024; unsigned char *buf = calloc(size, sizeof(char)); int ret = 0; @@ -1142,12 +1151,12 @@ int read_flash_to_file(struct flashctx *flash, const char *filename) msg_cinfo("FAILED.\n"); return 1; } - if (!flash->read) { + if (!flash->chip->read) { msg_cerr("No read function available for this flash chip.\n"); ret = 1; goto out_free; } - if (flash->read(flash, buf, 0, size)) { + if (flash->chip->read(flash, buf, 0, size)) { msg_cerr("Read operation failed!\n"); ret = 1; goto out_free; @@ -1164,14 +1173,14 @@ out_free: * walk_eraseregions(). * Even if an error is found, the function will keep going and check the rest. */ -static int selfcheck_eraseblocks(const struct flashchip *flash) +static int selfcheck_eraseblocks(const struct flashchip *chip) { int i, j, k; int ret = 0; for (k = 0; k < NUM_ERASEFUNCTIONS; k++) { unsigned int done = 0; - struct block_eraser eraser = flash->block_erasers[k]; + struct block_eraser eraser = chip->block_erasers[k]; for (i = 0; i < NUM_ERASEREGIONS; i++) { /* Blocks with zero size are bugs in flashchips.c. */ @@ -1180,7 +1189,7 @@ static int selfcheck_eraseblocks(const struct flashchip *flash) msg_gerr("ERROR: Flash chip %s erase function " "%i region %i has size 0. Please report" " a bug at flashrom@flashrom.org\n", - flash->name, k, i); + chip->name, k, i); ret = 1; } /* Blocks with zero count are bugs in flashchips.c. */ @@ -1189,7 +1198,7 @@ static int selfcheck_eraseblocks(const struct flashchip *flash) msg_gerr("ERROR: Flash chip %s erase function " "%i region %i has count 0. Please report" " a bug at flashrom@flashrom.org\n", - flash->name, k, i); + chip->name, k, i); ret = 1; } done += eraser.eraseblocks[i].count * @@ -1201,12 +1210,12 @@ static int selfcheck_eraseblocks(const struct flashchip *flash) "non-empty erase function. Not an error.\n"); if (!done) continue; - if (done != flash->total_size * 1024) { + if (done != chip->total_size * 1024) { msg_gerr("ERROR: Flash chip %s erase function %i " "region walking resulted in 0x%06x bytes total," " expected 0x%06x bytes. Please report a bug at" - " flashrom@flashrom.org\n", flash->name, k, - done, flash->total_size * 1024); + " flashrom@flashrom.org\n", chip->name, k, + done, chip->total_size * 1024); ret = 1; } if (!eraser.block_erase) @@ -1217,11 +1226,11 @@ static int selfcheck_eraseblocks(const struct flashchip *flash) */ for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) { if (eraser.block_erase == - flash->block_erasers[j].block_erase) { + chip->block_erasers[j].block_erase) { msg_gerr("ERROR: Flash chip %s erase function " "%i and %i are identical. Please report" " a bug at flashrom@flashrom.org\n", - flash->name, k, j); + chip->name, k, j); ret = 1; } } @@ -1268,7 +1277,7 @@ static int erase_and_write_block_helper(struct flashctx *flash, if (!writecount++) msg_cdbg("W"); /* Needs the partial write function signature. */ - ret = flash->write(flash, newcontents + starthere, + ret = flash->chip->write(flash, newcontents + starthere, start + starthere, lenhere); if (ret) return ret; @@ -1295,7 +1304,7 @@ static int walk_eraseregions(struct flashctx *flash, int erasefunction, int i, j; unsigned int start = 0; unsigned int len; - struct block_eraser eraser = flash->block_erasers[erasefunction]; + struct block_eraser eraser = flash->chip->block_erasers[erasefunction]; for (i = 0; i < NUM_ERASEREGIONS; i++) { /* count==0 for all automatically initialized array @@ -1321,7 +1330,7 @@ static int walk_eraseregions(struct flashctx *flash, int erasefunction, static int check_block_eraser(const struct flashctx *flash, int k, int log) { - struct block_eraser eraser = flash->block_erasers[k]; + struct block_eraser eraser = flash->chip->block_erasers[k]; if (!eraser.block_erase && !eraser.eraseblocks[0].count) { if (log) @@ -1340,6 +1349,7 @@ static int check_block_eraser(const struct flashctx *flash, int k, int log) "eraseblock layout is not defined. "); return 1; } + // TODO: Once erase functions are annotated with allowed buses, check that as well. return 0; } @@ -1348,7 +1358,7 @@ int erase_and_write_flash(struct flashctx *flash, uint8_t *oldcontents, { int k, ret = 1; uint8_t *curcontents; - unsigned long size = flash->total_size * 1024; + unsigned long size = flash->chip->total_size * 1024; unsigned int usable_erasefunctions = count_usable_erasers(flash); msg_cinfo("Erasing and writing flash chip... "); @@ -1386,7 +1396,7 @@ int erase_and_write_flash(struct flashctx *flash, uint8_t *oldcontents, * in non-verbose mode. */ msg_cinfo("Reading current flash chip contents... "); - if (flash->read(flash, curcontents, 0, size)) { + if (flash->chip->read(flash, curcontents, 0, size)) { /* Now we are truly screwed. Read failed as well. */ msg_cerr("Can't read anymore! Aborting.\n"); /* We have no idea about the flash chip contents, so @@ -1575,7 +1585,7 @@ void print_banner(void) int selfcheck(void) { int ret = 0; - const struct flashchip *flash; + const struct flashchip *chip; /* Safety check. Instead of aborting after the first error, check * if more errors exist. @@ -1593,16 +1603,8 @@ int selfcheck(void) msg_gerr("Flashchips table miscompilation!\n"); ret = 1; } - /* Check that virtual_memory in struct flashctx is placed directly - * after the members copied from struct flashchip. - */ - if (sizeof(struct flashchip) != - offsetof(struct flashctx, virtual_memory)) { - msg_gerr("struct flashctx broken!\n"); - ret = 1; - } - for (flash = flashchips; flash && flash->name; flash++) - if (selfcheck_eraseblocks(flash)) + for (chip = flashchips; chip && chip->name; chip++) + if (selfcheck_eraseblocks(chip)) ret = 1; #if CONFIG_INTERNAL == 1 @@ -1626,41 +1628,41 @@ int selfcheck(void) return ret; } -void check_chip_supported(const struct flashctx *flash) +void check_chip_supported(const struct flashchip *chip) { - if (flash->feature_bits & FEATURE_OTP) { + if (chip->feature_bits & FEATURE_OTP) { msg_cdbg("This chip may contain one-time programmable memory. " "flashrom cannot read\nand may never be able to write " "it, hence it may not be able to completely\n" "clone the contents of this chip (see man page for " "details).\n"); } - if (TEST_OK_MASK != (flash->tested & TEST_OK_MASK)) { + if (TEST_OK_MASK != (chip->tested & TEST_OK_MASK)) { msg_cinfo("===\n"); - if (flash->tested & TEST_BAD_MASK) { + if (chip->tested & TEST_BAD_MASK) { msg_cinfo("This flash part has status NOT WORKING for operations:"); - if (flash->tested & TEST_BAD_PROBE) + if (chip->tested & TEST_BAD_PROBE) msg_cinfo(" PROBE"); - if (flash->tested & TEST_BAD_READ) + if (chip->tested & TEST_BAD_READ) msg_cinfo(" READ"); - if (flash->tested & TEST_BAD_ERASE) + if (chip->tested & TEST_BAD_ERASE) msg_cinfo(" ERASE"); - if (flash->tested & TEST_BAD_WRITE) + if (chip->tested & TEST_BAD_WRITE) msg_cinfo(" WRITE"); msg_cinfo("\n"); } - if ((!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE)) || - (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ)) || - (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE)) || - (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE))) { + if ((!(chip->tested & TEST_BAD_PROBE) && !(chip->tested & TEST_OK_PROBE)) || + (!(chip->tested & TEST_BAD_READ) && !(chip->tested & TEST_OK_READ)) || + (!(chip->tested & TEST_BAD_ERASE) && !(chip->tested & TEST_OK_ERASE)) || + (!(chip->tested & TEST_BAD_WRITE) && !(chip->tested & TEST_OK_WRITE))) { msg_cinfo("This flash part has status UNTESTED for operations:"); - if (!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE)) + if (!(chip->tested & TEST_BAD_PROBE) && !(chip->tested & TEST_OK_PROBE)) msg_cinfo(" PROBE"); - if (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ)) + if (!(chip->tested & TEST_BAD_READ) && !(chip->tested & TEST_OK_READ)) msg_cinfo(" READ"); - if (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE)) + if (!(chip->tested & TEST_BAD_ERASE) && !(chip->tested & TEST_OK_ERASE)) msg_cinfo(" ERASE"); - if (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE)) + if (!(chip->tested & TEST_BAD_WRITE) && !(chip->tested & TEST_OK_WRITE)) msg_cinfo(" WRITE"); msg_cinfo("\n"); } @@ -1685,9 +1687,11 @@ void check_chip_supported(const struct flashctx *flash) /* FIXME: This function signature needs to be improved once doit() has a better * function signature. */ -int chip_safety_check(struct flashctx *flash, int force, int read_it, - int write_it, int erase_it, int verify_it) +int chip_safety_check(const struct flashctx *flash, int force, int read_it, int write_it, int erase_it, + int verify_it) { + const struct flashchip *chip = flash->chip; + if (!programmer_may_write && (write_it || erase_it)) { msg_perr("Write/erase is not working yet on your programmer in " "its current configuration.\n"); @@ -1701,13 +1705,13 @@ int chip_safety_check(struct flashctx *flash, int force, int read_it, if (read_it || erase_it || write_it || verify_it) { /* Everything needs read. */ - if (flash->tested & TEST_BAD_READ) { + if (chip->tested & TEST_BAD_READ) { msg_cerr("Read is not working on this chip. "); if (!force) return 1; msg_cerr("Continuing anyway.\n"); } - if (!flash->read) { + if (!chip->read) { msg_cerr("flashrom has no read function for this " "flash chip.\n"); return 1; @@ -1715,7 +1719,7 @@ int chip_safety_check(struct flashctx *flash, int force, int read_it, } if (erase_it || write_it) { /* Write needs erase. */ - if (flash->tested & TEST_BAD_ERASE) { + if (chip->tested & TEST_BAD_ERASE) { msg_cerr("Erase is not working on this chip. "); if (!force) return 1; @@ -1728,13 +1732,13 @@ int chip_safety_check(struct flashctx *flash, int force, int read_it, } } if (write_it) { - if (flash->tested & TEST_BAD_WRITE) { + if (chip->tested & TEST_BAD_WRITE) { msg_cerr("Write is not working on this chip. "); if (!force) return 1; msg_cerr("Continuing anyway.\n"); } - if (!flash->write) { + if (!chip->write) { msg_cerr("flashrom has no write function for this " "flash chip.\n"); return 1; @@ -1753,7 +1757,7 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, uint8_t *oldcontents; uint8_t *newcontents; int ret = 0; - unsigned long size = flash->total_size * 1024; + unsigned long size = flash->chip->total_size * 1024; if (chip_safety_check(flash, force, read_it, write_it, erase_it, verify_it)) { msg_cerr("Aborting.\n"); @@ -1764,8 +1768,8 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, /* Given the existence of read locks, we want to unlock for read, * erase and write. */ - if (flash->unlock) - flash->unlock(flash); + if (flash->chip->unlock) + flash->chip->unlock(flash); if (read_it) { ret = read_flash_to_file(flash, filename); @@ -1833,7 +1837,7 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, * takes time as well. */ msg_cinfo("Reading old flash chip contents... "); - if (flash->read(flash, oldcontents, 0, size)) { + if (flash->chip->read(flash, oldcontents, 0, size)) { ret = 1; msg_cinfo("FAILED.\n"); goto out; @@ -1850,7 +1854,7 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, if (erase_and_write_flash(flash, oldcontents, newcontents)) { msg_cerr("Uh oh. Erase/write failed. Checking if " "anything changed.\n"); - if (!flash->read(flash, newcontents, 0, size)) { + if (!flash->chip->read(flash, newcontents, 0, size)) { if (!memcmp(oldcontents, newcontents, size)) { msg_cinfo("Good. It seems nothing was " "changed.\n"); @@ -1193,9 +1193,9 @@ static int ich_hwseq_probe(struct flashctx *flash) else msg_cdbg(" with a"); msg_cdbg(" density of %d kB.\n", total_size / 1024); - flash->total_size = total_size / 1024; + flash->chip->total_size = total_size / 1024; - eraser = &(flash->block_erasers[0]); + eraser = &(flash->chip->block_erasers[0]); boundary = (REGREAD32(ICH9_REG_FPB) & FPB_FPBA) << 12; size_high = total_size - boundary; erase_size_high = ich_hwseq_get_erase_block_size(boundary); @@ -1228,7 +1228,7 @@ static int ich_hwseq_probe(struct flashctx *flash) msg_cdbg("In that range are %d erase blocks with %d B each.\n", size_high / erase_size_high, erase_size_high); } - flash->tested = TEST_OK_PREW; + flash->chip->tested = TEST_OK_PREW; return 1; } @@ -1256,7 +1256,7 @@ static int ich_hwseq_block_erase(struct flashctx *flash, unsigned int addr, return -1; } - if (addr + len > flash->total_size * 1024) { + if (addr + len > flash->chip->total_size * 1024) { msg_perr("Request to erase some inaccessible memory address(es)" " (addr=0x%x, len=%d). " "Not erasing anything.\n", addr, len); @@ -1288,7 +1288,7 @@ static int ich_hwseq_read(struct flashctx *flash, uint8_t *buf, uint16_t timeout = 100 * 60; uint8_t block_len; - if (addr + len > flash->total_size * 1024) { + if (addr + len > flash->chip->total_size * 1024) { msg_perr("Request to read from an inaccessible memory address " "(addr=0x%x, len=%d).\n", addr, len); return -1; @@ -1326,7 +1326,7 @@ static int ich_hwseq_write(struct flashctx *flash, uint8_t *buf, uint16_t timeout = 100 * 60; uint8_t block_len; - if (addr + len > flash->total_size * 1024) { + if (addr + len > flash->chip->total_size * 1024) { msg_perr("Request to write to an inaccessible memory address " "(addr=0x%x, len=%d).\n", addr, len); return -1; @@ -331,7 +331,7 @@ static int it8716f_spi_page_program(struct flashctx *flash, uint8_t *buf, /* FIXME: The command below seems to be redundant or wrong. */ OUTB(0x06, it8716f_flashport + 1); OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport); - for (i = 0; i < flash->page_size; i++) + for (i = 0; i < flash->chip->page_size; i++) mmio_writeb(buf[i], (void *)(bios + start + i)); OUTB(0, it8716f_flashport); /* Wait until the Write-In-Progress bit is cleared. @@ -355,7 +355,7 @@ static int it8716f_spi_chip_read(struct flashctx *flash, uint8_t *buf, * the mainboard does not use IT87 SPI translation. This should be done * via a programmer parameter for the internal programmer. */ - if ((flash->total_size * 1024 > 512 * 1024)) { + if ((flash->chip->total_size * 1024 > 512 * 1024)) { spi_read_chunked(flash, buf, start, len, 3); } else { mmio_readn((void *)(flash->virtual_memory + start), buf, len); @@ -367,6 +367,7 @@ static int it8716f_spi_chip_read(struct flashctx *flash, uint8_t *buf, static int it8716f_spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) { + const struct flashchip *chip = flash->chip; /* * IT8716F only allows maximum of 512 kb SPI chip size for memory * mapped access. It also can't write more than 1+3+256 bytes at once, @@ -377,28 +378,27 @@ static int it8716f_spi_chip_write_256(struct flashctx *flash, uint8_t *buf, * the mainboard does not use IT87 SPI translation. This should be done * via a programmer parameter for the internal programmer. */ - if ((flash->total_size * 1024 > 512 * 1024) || - (flash->page_size > 256)) { + if ((chip->total_size * 1024 > 512 * 1024) || (chip->page_size > 256)) { spi_chip_write_1(flash, buf, start, len); } else { unsigned int lenhere; - if (start % flash->page_size) { + if (start % chip->page_size) { /* start to the end of the page or to start + len, * whichever is smaller. */ - lenhere = min(len, flash->page_size - start % flash->page_size); + lenhere = min(len, chip->page_size - start % chip->page_size); spi_chip_write_1(flash, buf, start, lenhere); start += lenhere; len -= lenhere; buf += lenhere; } - while (len >= flash->page_size) { + while (len >= chip->page_size) { it8716f_spi_page_program(flash, buf, start); - start += flash->page_size; - len -= flash->page_size; - buf += flash->page_size; + start += chip->page_size; + len -= chip->page_size; + buf += chip->page_size; } if (len) spi_chip_write_1(flash, buf, start, len); @@ -93,9 +93,9 @@ void data_polling_jedec(const struct flashctx *flash, chipaddr dst, msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i); } -static unsigned int getaddrmask(struct flashctx *flash) +static unsigned int getaddrmask(const struct flashchip *chip) { - switch (flash->feature_bits & FEATURE_ADDR_MASK) { + switch (chip->feature_bits & FEATURE_ADDR_MASK) { case FEATURE_ADDR_FULL: return MASK_FULL; break; @@ -124,16 +124,17 @@ static void start_program_jedec_common(struct flashctx *flash, static int probe_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; + const struct flashchip *chip = flash->chip; uint8_t id1, id2; uint32_t largeid1, largeid2; uint32_t flashcontent1, flashcontent2; int probe_timing_enter, probe_timing_exit; - if (flash->probe_timing > 0) - probe_timing_enter = probe_timing_exit = flash->probe_timing; - else if (flash->probe_timing == TIMING_ZERO) { /* No delay. */ + if (chip->probe_timing > 0) + probe_timing_enter = probe_timing_exit = chip->probe_timing; + else if (chip->probe_timing == TIMING_ZERO) { /* No delay. */ probe_timing_enter = probe_timing_exit = 0; - } else if (flash->probe_timing == TIMING_FIXME) { /* == _IGNORED */ + } else if (chip->probe_timing == TIMING_FIXME) { /* == _IGNORED */ msg_cdbg("Chip lacks correct probe timing information, " "using default 10mS/40uS. "); probe_timing_enter = 10000; @@ -151,7 +152,7 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask) if (probe_timing_enter) programmer_delay(probe_timing_enter); /* Reset chip to a clean slate */ - if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) + if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); if (probe_timing_exit) @@ -194,7 +195,7 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask) } /* Issue JEDEC Product ID Exit command */ - if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) + if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); if (probe_timing_exit) @@ -231,10 +232,10 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask) msg_cdbg(", id2 is normal flash content"); msg_cdbg("\n"); - if (largeid1 != flash->manufacture_id || largeid2 != flash->model_id) + if (largeid1 != chip->manufacture_id || largeid2 != chip->model_id) return 0; - if (flash->feature_bits & FEATURE_REGISTERMAP) + if (chip->feature_bits & FEATURE_REGISTERMAP) map_flash_registers(flash); return 1; @@ -245,7 +246,7 @@ static int erase_sector_jedec_common(struct flashctx *flash, unsigned int page, { chipaddr bios = flash->virtual_memory; int delay_us = 0; - if(flash->probe_timing != TIMING_ZERO) + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10; /* Issue the Sector Erase command */ @@ -275,7 +276,7 @@ static int erase_block_jedec_common(struct flashctx *flash, unsigned int block, { chipaddr bios = flash->virtual_memory; int delay_us = 0; - if(flash->probe_timing != TIMING_ZERO) + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10; /* Issue the Sector Erase command */ @@ -304,7 +305,7 @@ static int erase_chip_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; int delay_us = 0; - if(flash->probe_timing != TIMING_ZERO) + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10; /* Issue the JEDEC Chip Erase command */ @@ -366,7 +367,7 @@ int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start, chipaddr olddst; unsigned int mask; - mask = getaddrmask(flash); + mask = getaddrmask(flash->chip); olddst = dst; for (i = 0; i < len; i++) { @@ -390,7 +391,7 @@ int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src, chipaddr d = dst; unsigned int mask; - mask = getaddrmask(flash); + mask = getaddrmask(flash->chip); retry: /* Issue JEDEC Start Program command */ @@ -438,7 +439,7 @@ int write_jedec(struct flashctx *flash, uint8_t *buf, unsigned int start, * write_jedec have page_size set to max_writechunk_size, so * we're OK for now. */ - unsigned int page_size = flash->page_size; + unsigned int page_size = flash->chip->page_size; /* Warning: This loop has a very unusual condition and body. * The loop needs to go through each page with at least one affected @@ -469,8 +470,8 @@ int erase_chip_block_jedec(struct flashctx *flash, unsigned int addr, { unsigned int mask; - mask = getaddrmask(flash); - if ((addr != 0) || (blocksize != flash->total_size * 1024)) { + mask = getaddrmask(flash->chip); + if ((addr != 0) || (blocksize != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; @@ -482,7 +483,7 @@ int probe_jedec(struct flashctx *flash) { unsigned int mask; - mask = getaddrmask(flash); + mask = getaddrmask(flash->chip); return probe_jedec_common(flash, mask); } @@ -491,7 +492,7 @@ int erase_sector_jedec(struct flashctx *flash, unsigned int page, { unsigned int mask; - mask = getaddrmask(flash); + mask = getaddrmask(flash->chip); return erase_sector_jedec_common(flash, page, size, mask); } @@ -500,7 +501,7 @@ int erase_block_jedec(struct flashctx *flash, unsigned int page, { unsigned int mask; - mask = getaddrmask(flash); + mask = getaddrmask(flash->chip); return erase_block_jedec_common(flash, page, size, mask); } @@ -508,6 +509,6 @@ int erase_chip_jedec(struct flashctx *flash) { unsigned int mask; - mask = getaddrmask(flash); + mask = getaddrmask(flash->chip); return erase_chip_jedec_common(flash, mask); } @@ -217,11 +217,11 @@ romlayout_t *get_next_included_romentry(unsigned int start) return best_entry; } -int handle_romentries(struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents) +int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents) { unsigned int start = 0; romlayout_t *entry; - unsigned int size = flash->total_size * 1024; + unsigned int size = flash->chip->total_size * 1024; /* If no regions were specified for inclusion, assume * that the user wants to write the complete new image. diff --git a/m29f400bt.c b/m29f400bt.c index c9d8a40eb..8f0329ecd 100644 --- a/m29f400bt.c +++ b/m29f400bt.c @@ -81,7 +81,7 @@ int probe_m29f400bt(struct flashctx *flash) msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); - if (id1 == flash->manufacture_id && id2 == flash->model_id) + if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id) return 1; return 0; @@ -130,7 +130,7 @@ int block_erase_m29f400bt(struct flashctx *flash, unsigned int start, int block_erase_chip_m29f400bt(struct flashctx *flash, unsigned int address, unsigned int blocklen) { - if ((address != 0) || (blocklen != flash->total_size * 1024)) { + if ((address != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; diff --git a/pm49fl00x.c b/pm49fl00x.c index 42db2aa96..fe28d2b8e 100644 --- a/pm49fl00x.c +++ b/pm49fl00x.c @@ -40,14 +40,14 @@ static void write_lockbits_49fl00x(const struct flashctx *flash, int unlock_49fl00x(struct flashctx *flash) { - write_lockbits_49fl00x(flash, flash->total_size * 1024, 0, - flash->page_size); + write_lockbits_49fl00x(flash, flash->chip->total_size * 1024, 0, + flash->chip->page_size); return 0; } int lock_49fl00x(struct flashctx *flash) { - write_lockbits_49fl00x(flash, flash->total_size * 1024, 1, - flash->page_size); + write_lockbits_49fl00x(flash, flash->chip->total_size * 1024, 1, + flash->chip->page_size); return 0; } @@ -67,22 +67,22 @@ static void print_supported_chips(void) int maxvendorlen = strlen("Vendor") + 1; int maxchiplen = strlen("Device") + 1; int maxtypelen = strlen("Type") + 1; - const struct flashchip *f; + const struct flashchip *chip; char *s; char *tmpven, *tmpdev; int tmpvenlen, tmpdevlen, curvenlen, curdevlen; /* calculate maximum column widths and by iterating over all chips */ - for (f = flashchips; f->name != NULL; f++) { + for (chip = flashchips; chip->name != NULL; chip++) { /* Ignore generic entries. */ - if (!strncmp(f->vendor, "Unknown", 7) || - !strncmp(f->vendor, "Programmer", 10) || - !strncmp(f->name, "unknown", 7)) + if (!strncmp(chip->vendor, "Unknown", 7) || + !strncmp(chip->vendor, "Programmer", 10) || + !strncmp(chip->name, "unknown", 7)) continue; chipcount++; /* Find maximum vendor length (respecting line splitting). */ - tmpven = (char *)f->vendor; + tmpven = (char *)chip->vendor; do { /* and take minimum token lengths into account */ tmpvenlen = 0; @@ -100,7 +100,7 @@ static void print_supported_chips(void) } while (1); /* same for device name */ - tmpdev = (char *)f->name; + tmpdev = (char *)chip->name; do { tmpdevlen = 0; do { @@ -115,7 +115,7 @@ static void print_supported_chips(void) break; } while (1); - s = flashbuses_to_text(f->bustype); + s = flashbuses_to_text(chip->bustype); maxtypelen = max(maxtypelen, strlen(s)); free(s); } @@ -162,11 +162,11 @@ static void print_supported_chips(void) msg_ginfo("\n\n"); msg_ginfo("(P = PROBE, R = READ, E = ERASE, W = WRITE)\n\n"); - for (f = flashchips; f->name != NULL; f++) { + for (chip = flashchips; chip->name != NULL; chip++) { /* Don't print generic entries. */ - if (!strncmp(f->vendor, "Unknown", 7) || - !strncmp(f->vendor, "Programmer", 10) || - !strncmp(f->name, "unknown", 7)) + if (!strncmp(chip->vendor, "Unknown", 7) || + !strncmp(chip->vendor, "Programmer", 10) || + !strncmp(chip->name, "unknown", 7)) continue; /* support for multiline vendor names: @@ -179,12 +179,12 @@ static void print_supported_chips(void) * - after all other values are printed print the surplus tokens * on fresh lines */ - tmpven = malloc(strlen(f->vendor) + 1); + tmpven = malloc(strlen(chip->vendor) + 1); if (tmpven == NULL) { msg_gerr("Out of memory!\n"); exit(1); } - strcpy(tmpven, f->vendor); + strcpy(tmpven, chip->vendor); tmpven = strtok(tmpven, delim); msg_ginfo("%s", tmpven); @@ -203,12 +203,12 @@ static void print_supported_chips(void) msg_ginfo(" "); /* support for multiline device names as above */ - tmpdev = malloc(strlen(f->name) + 1); + tmpdev = malloc(strlen(chip->name) + 1); if (tmpdev == NULL) { msg_gerr("Out of memory!\n"); exit(1); } - strcpy(tmpdev, f->name); + strcpy(tmpdev, chip->name); tmpdev = strtok(tmpdev, delim); msg_ginfo("%s", tmpdev); @@ -226,60 +226,60 @@ static void print_supported_chips(void) for (i = curdevlen; i < maxchiplen; i++) msg_ginfo(" "); - if ((f->tested & TEST_OK_PROBE)) + if ((chip->tested & TEST_OK_PROBE)) msg_ginfo("P"); else msg_ginfo(" "); - if ((f->tested & TEST_OK_READ)) + if ((chip->tested & TEST_OK_READ)) msg_ginfo("R"); else msg_ginfo(" "); - if ((f->tested & TEST_OK_ERASE)) + if ((chip->tested & TEST_OK_ERASE)) msg_ginfo("E"); else msg_ginfo(" "); - if ((f->tested & TEST_OK_WRITE)) + if ((chip->tested & TEST_OK_WRITE)) msg_ginfo("W"); else msg_ginfo(" "); for (i = 0; i < border; i++) msg_ginfo(" "); - if ((f->tested & TEST_BAD_PROBE)) + if ((chip->tested & TEST_BAD_PROBE)) msg_ginfo("P"); else msg_ginfo(" "); - if ((f->tested & TEST_BAD_READ)) + if ((chip->tested & TEST_BAD_READ)) msg_ginfo("R"); else msg_ginfo(" "); - if ((f->tested & TEST_BAD_ERASE)) + if ((chip->tested & TEST_BAD_ERASE)) msg_ginfo("E"); else msg_ginfo(" "); - if ((f->tested & TEST_BAD_WRITE)) + if ((chip->tested & TEST_BAD_WRITE)) msg_ginfo("W"); else msg_ginfo(" "); for (i = 0; i < border + 1; i++) msg_ginfo(" "); - msg_ginfo("%5d", f->total_size); + msg_ginfo("%5d", chip->total_size); for (i = 0; i < border; i++) msg_ginfo(" "); - s = flashbuses_to_text(f->bustype); + s = flashbuses_to_text(chip->bustype); msg_ginfo("%s", s); for (i = strlen(s); i < maxtypelen; i++) msg_ginfo(" "); free(s); - if (f->voltage.min == 0 && f->voltage.max == 0) + if (chip->voltage.min == 0 && chip->voltage.max == 0) msg_gdbg("no info"); else msg_gdbg("%0.02f;%0.02f", - f->voltage.min/(double)1000, - f->voltage.max/(double)1000); + chip->voltage.min/(double)1000, + chip->voltage.max/(double)1000); /* print surplus vendor and device name tokens */ while (tmpven != NULL || tmpdev != NULL) { diff --git a/programmer.h b/programmer.h index 7a301f372..303fbc458 100644 --- a/programmer.h +++ b/programmer.h @@ -473,7 +473,7 @@ struct decode_sizes { extern struct decode_sizes max_rom_decode; extern int programmer_may_write; extern unsigned long flashbase; -void check_chip_supported(const struct flashctx *flash); +void check_chip_supported(const struct flashchip *chip); int check_max_decode(enum chipbustype buses, uint32_t size); char *extract_programmer_param(const char *param_name); @@ -81,10 +81,10 @@ struct sfdp_tbl_hdr { uint32_t ptp; /* 24b pointer */ }; -static int sfdp_add_uniform_eraser(struct flashctx *flash, uint8_t opcode, uint32_t block_size) +static int sfdp_add_uniform_eraser(struct flashchip *chip, uint8_t opcode, uint32_t block_size) { int i; - uint32_t total_size = flash->total_size * 1024; + uint32_t total_size = chip->total_size * 1024; erasefunc_t *erasefn = spi_get_erasefn_from_opcode(opcode); if (erasefn == NULL || total_size == 0 || block_size == 0 || @@ -95,7 +95,7 @@ static int sfdp_add_uniform_eraser(struct flashctx *flash, uint8_t opcode, uint3 } for (i = 0; i < NUM_ERASEFUNCTIONS; i++) { - struct block_eraser *eraser = &flash->block_erasers[i]; + struct block_eraser *eraser = &chip->block_erasers[i]; /* Check for duplicates (including (some) non-uniform ones). */ if (eraser->eraseblocks[0].size == block_size && eraser->block_erase == erasefn) { @@ -125,7 +125,7 @@ static int sfdp_add_uniform_eraser(struct flashctx *flash, uint8_t opcode, uint3 return 1; } -static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len) +static int sfdp_fill_flash(struct flashchip *chip, uint8_t *buf, uint16_t len) { uint8_t opcode_4k_erase = 0xFF; uint32_t tmp32; @@ -170,28 +170,28 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len) msg_cdbg2("volatile and writes to the status register have to " "be enabled with "); if (tmp32 & (1 << 4)) { - flash->feature_bits = FEATURE_WRSR_WREN; + chip->feature_bits = FEATURE_WRSR_WREN; msg_cdbg2("WREN (0x06).\n"); } else { - flash->feature_bits = FEATURE_WRSR_EWSR; + chip->feature_bits = FEATURE_WRSR_EWSR; msg_cdbg2("EWSR (0x50).\n"); } } else { msg_cdbg2("non-volatile and the standard does not allow " "vendors to tell us whether EWSR/WREN is needed for " "status register writes - assuming EWSR.\n"); - flash->feature_bits = FEATURE_WRSR_EWSR; + chip->feature_bits = FEATURE_WRSR_EWSR; } msg_cdbg2(" Write chunk size is "); if (tmp32 & (1 << 2)) { msg_cdbg2("at least 64 B.\n"); - flash->page_size = 64; - flash->write = spi_chip_write_256; + chip->page_size = 64; + chip->write = spi_chip_write_256; } else { msg_cdbg2("1 B only.\n"); - flash->page_size = 256; - flash->write = spi_chip_write_1; + chip->page_size = 256; + chip->write = spi_chip_write_1; } if ((tmp32 & 0x3) == 0x1) { @@ -212,8 +212,8 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len) return 1; } total_size = ((tmp32 & 0x7FFFFFFF) + 1) / 8; - flash->total_size = total_size / 1024; - msg_cdbg2(" Flash chip size is %d kB.\n", flash->total_size); + chip->total_size = total_size / 1024; + msg_cdbg2(" Flash chip size is %d kB.\n", chip->total_size); if (total_size > (1 << 24)) { msg_cdbg("Flash chip size is bigger than what 3-Byte addressing " "can access.\n"); @@ -221,7 +221,7 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len) } if (opcode_4k_erase != 0xFF) - sfdp_add_uniform_eraser(flash, opcode_4k_erase, 4 * 1024); + sfdp_add_uniform_eraser(chip, opcode_4k_erase, 4 * 1024); /* FIXME: double words 3-7 contain unused fast read information */ @@ -252,7 +252,7 @@ static int sfdp_fill_flash(struct flashctx *flash, uint8_t *buf, uint16_t len) tmp8 = buf[(4 * 7) + (j * 2) + 1]; msg_cspew(" Erase Sector Type %d Opcode: 0x%02x\n", j + 1, tmp8); - sfdp_add_uniform_eraser(flash, tmp8, block_size); + sfdp_add_uniform_eraser(chip, tmp8, block_size); } done: @@ -381,7 +381,7 @@ int probe_spi_sfdp(struct flashctx *flash) msg_cdbg("Length of the mandatory JEDEC SFDP " "parameter table is wrong (%d B), " "skipping it.\n", len); - } else if (sfdp_fill_flash(flash, tbuf, len) == 0) + } else if (sfdp_fill_flash(flash->chip, tbuf, len) == 0) ret = 1; } free(tbuf); @@ -111,16 +111,16 @@ int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, * means 0xffffff, the highest unsigned 24bit number. */ addrbase = spi_get_valid_read_addr(flash); - if (addrbase + flash->total_size * 1024 > (1 << 24)) { + if (addrbase + flash->chip->total_size * 1024 > (1 << 24)) { msg_perr("Flash chip size exceeds the allowed access window. "); msg_perr("Read will probably fail.\n"); /* Try to get the best alignment subject to constraints. */ - addrbase = (1 << 24) - flash->total_size * 1024; + addrbase = (1 << 24) - flash->chip->total_size * 1024; } /* Check if alignment is native (at least the largest power of two which * is a factor of the mapped size of the chip). */ - if (ffs(flash->total_size * 1024) > (ffs(addrbase) ? : 33)) { + if (ffs(flash->chip->total_size * 1024) > (ffs(addrbase) ? : 33)) { msg_perr("Flash chip is not aligned natively in the allowed " "access window.\n"); msg_perr("Read will probably return garbage.\n"); @@ -117,6 +117,7 @@ int spi_write_disable(struct flashctx *flash) static int probe_spi_rdid_generic(struct flashctx *flash, int bytes) { + const struct flashchip *chip = flash->chip; unsigned char readarr[4]; uint32_t id1; uint32_t id2; @@ -147,7 +148,7 @@ static int probe_spi_rdid_generic(struct flashctx *flash, int bytes) msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); - if (id1 == flash->manufacture_id && id2 == flash->model_id) { + if (id1 == chip->manufacture_id && id2 == chip->model_id) { /* Print the status register to tell the * user about possible write protection. */ @@ -157,13 +158,11 @@ static int probe_spi_rdid_generic(struct flashctx *flash, int bytes) } /* Test if this is a pure vendor match. */ - if (id1 == flash->manufacture_id && - GENERIC_DEVICE_ID == flash->model_id) + if (id1 == chip->manufacture_id && GENERIC_DEVICE_ID == chip->model_id) return 1; /* Test if there is any vendor ID. */ - if (GENERIC_MANUF_ID == flash->manufacture_id && - id1 != 0xff) + if (GENERIC_MANUF_ID == chip->manufacture_id && id1 != 0xff) return 1; return 0; @@ -198,6 +197,7 @@ int probe_spi_rdid4(struct flashctx *flash) int probe_spi_rems(struct flashctx *flash) { + const struct flashchip *chip = flash->chip; unsigned char readarr[JEDEC_REMS_INSIZE]; uint32_t id1, id2; @@ -210,7 +210,7 @@ int probe_spi_rems(struct flashctx *flash) msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2); - if (id1 == flash->manufacture_id && id2 == flash->model_id) { + if (id1 == chip->manufacture_id && id2 == chip->model_id) { /* Print the status register to tell the * user about possible write protection. */ @@ -220,13 +220,11 @@ int probe_spi_rems(struct flashctx *flash) } /* Test if this is a pure vendor match. */ - if (id1 == flash->manufacture_id && - GENERIC_DEVICE_ID == flash->model_id) + if (id1 == chip->manufacture_id && GENERIC_DEVICE_ID == chip->model_id) return 1; /* Test if there is any vendor ID. */ - if (GENERIC_MANUF_ID == flash->manufacture_id && - id1 != 0xff) + if (GENERIC_MANUF_ID == chip->manufacture_id && id1 != 0xff) return 1; return 0; @@ -267,7 +265,7 @@ int probe_spi_res1(struct flashctx *flash) msg_cdbg("%s: id 0x%x\n", __func__, id2); - if (id2 != flash->model_id) + if (id2 != flash->chip->model_id) return 0; /* Print the status register to tell the @@ -291,7 +289,7 @@ int probe_spi_res2(struct flashctx *flash) msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2); - if (id1 != flash->manufacture_id || id2 != flash->model_id) + if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id) return 0; /* Print the status register to tell the @@ -419,22 +417,23 @@ void spi_prettyprint_status_register_sst25vf040b(uint8_t status) int spi_prettyprint_status_register(struct flashctx *flash) { + const struct flashchip *chip = flash->chip; uint8_t status; status = spi_read_status_register(flash); msg_cdbg("Chip status register is %02x\n", status); - switch (flash->manufacture_id) { + switch (chip->manufacture_id) { case ST_ID: - if (((flash->model_id & 0xff00) == 0x2000) || - ((flash->model_id & 0xff00) == 0x2500)) + if (((chip->model_id & 0xff00) == 0x2000) || + ((chip->model_id & 0xff00) == 0x2500)) spi_prettyprint_status_register_st_m25p(status); break; case MACRONIX_ID: - if ((flash->model_id & 0xff00) == 0x2000) + if ((chip->model_id & 0xff00) == 0x2000) spi_prettyprint_status_register_st_m25p(status); break; case SST_ID: - switch (flash->model_id) { + switch (chip->model_id) { case 0x2541: spi_prettyprint_status_register_sst25vf016(status); break; @@ -704,7 +703,7 @@ int spi_block_erase_20(struct flashctx *flash, unsigned int addr, int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { - if ((addr != 0) || (blocklen != flash->total_size * 1024)) { + if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; @@ -715,7 +714,7 @@ int spi_block_erase_60(struct flashctx *flash, unsigned int addr, int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { - if ((addr != 0) || (blocklen != flash->total_size * 1024)) { + if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; @@ -820,7 +819,7 @@ static int spi_write_status_register_flag(struct flashctx *flash, int status, co int spi_write_status_register(struct flashctx *flash, int status) { - int feature_bits = flash->feature_bits; + int feature_bits = flash->chip->feature_bits; int ret = 1; if (!(feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) { @@ -972,7 +971,7 @@ int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, { int rc = 0; unsigned int i, j, starthere, lenhere, toread; - unsigned int page_size = flash->page_size; + unsigned int page_size = flash->chip->page_size; /* Warning: This loop has a very unusual condition and body. * The loop needs to go through each page with at least one affected @@ -1017,7 +1016,7 @@ int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, * spi_chip_write_256 have page_size set to max_writechunk_size, so * we're OK for now. */ - unsigned int page_size = flash->page_size; + unsigned int page_size = flash->chip->page_size; /* Warning: This loop has a very unusual condition and body. * The loop needs to go through each page with at least one affected diff --git a/sst28sf040.c b/sst28sf040.c index a9a740cda..52e4256ea 100644 --- a/sst28sf040.c +++ b/sst28sf040.c @@ -119,7 +119,7 @@ static int erase_28sf040(struct flashctx *flash) int erase_chip_28sf040(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { - if ((addr != 0) || (blocklen != flash->total_size * 1024)) { + if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; diff --git a/sst49lfxxxc.c b/sst49lfxxxc.c index 37f0628f0..bb2155914 100644 --- a/sst49lfxxxc.c +++ b/sst49lfxxxc.c @@ -38,7 +38,7 @@ static int write_lockbits_block_49lfxxxc(struct flashctx *flash, static int write_lockbits_49lfxxxc(struct flashctx *flash, unsigned char bits) { chipaddr registers = flash->virtual_registers; - unsigned int i, left = flash->total_size * 1024; + unsigned int i, left = flash->chip->total_size * 1024; unsigned long address; msg_cdbg("\nbios=0x%08lx\n", registers); diff --git a/sst_fwhub.c b/sst_fwhub.c index c802a33bb..a440a2032 100644 --- a/sst_fwhub.c +++ b/sst_fwhub.c @@ -31,7 +31,7 @@ static int check_sst_fwhub_block_lock(struct flashctx *flash, int offset) blockstatus = chip_readb(flash, registers + offset + 2); msg_cdbg("Lock status for 0x%06x (size 0x%06x) is %02x, ", - offset, flash->page_size, blockstatus); + offset, flash->chip->page_size, blockstatus); switch (blockstatus & 0x3) { case 0x0: msg_cdbg("full access\n"); @@ -72,7 +72,7 @@ int printlock_sst_fwhub(struct flashctx *flash) { int i; - for (i = 0; i < flash->total_size * 1024; i += flash->page_size) + for (i = 0; i < flash->chip->total_size * 1024; i += flash->chip->page_size) check_sst_fwhub_block_lock(flash, i); return 0; @@ -82,7 +82,7 @@ int unlock_sst_fwhub(struct flashctx *flash) { int i, ret=0; - for (i = 0; i < flash->total_size * 1024; i += flash->page_size) + for (i = 0; i < flash->chip->total_size * 1024; i += flash->chip->page_size) { if (clear_sst_fwhub_block_lock(flash, i)) { diff --git a/stm50flw0x0x.c b/stm50flw0x0x.c index 9b6443e50..e6c7c0546 100644 --- a/stm50flw0x0x.c +++ b/stm50flw0x0x.c @@ -54,7 +54,7 @@ static int unlock_block_stm50flw0x0x(struct flashctx *flash, int offset) /* Check, if it's is a top/bottom-block with 4k-sectors. */ /* TODO: What about the other types? */ if ((offset == 0) || - (offset == (flash->model_id == ST_M50FLW080A ? 0xE0000 : 0x10000)) + (offset == (flash->chip->model_id == ST_M50FLW080A ? 0xE0000 : 0x10000)) || (offset == 0xF0000)) { // unlock each 4k-sector @@ -85,7 +85,7 @@ int unlock_stm50flw0x0x(struct flashctx *flash) { int i; - for (i = 0; i < flash->total_size * 1024; i+= flash->page_size) { + for (i = 0; i < flash->chip->total_size * 1024; i+= flash->chip->page_size) { if(unlock_block_stm50flw0x0x(flash, i)) { msg_cerr("UNLOCK FAILED!\n"); return -1; diff --git a/w29ee011.c b/w29ee011.c index d2af23dc8..4df4687b3 100644 --- a/w29ee011.c +++ b/w29ee011.c @@ -29,11 +29,11 @@ int probe_w29ee011(struct flashctx *flash) chipaddr bios = flash->virtual_memory; uint8_t id1, id2; - if (!chip_to_probe || strcmp(chip_to_probe, flash->name)) { + if (!chip_to_probe || strcmp(chip_to_probe, flash->chip->name)) { msg_cdbg("Old Winbond W29* probe method disabled because " "the probing sequence puts the AMIC A49LF040A in " "a funky state. Use 'flashrom -c %s' if you " - "have a board with such a chip.\n", flash->name); + "have a board with such a chip.\n", flash->chip->name); return 0; } @@ -65,7 +65,7 @@ int probe_w29ee011(struct flashctx *flash) msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); - if (id1 == flash->manufacture_id && id2 == flash->model_id) + if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id) return 1; return 0; @@ -138,11 +138,11 @@ static int printlock_w39_common(struct flashctx *flash, unsigned int offset) static int printlock_w39_fwh(struct flashctx *flash) { - unsigned int i, total_size = flash->total_size * 1024; + unsigned int i, total_size = flash->chip->total_size * 1024; int ret = 0; /* Print lock status of the complete chip */ - for (i = 0; i < total_size; i += flash->page_size) + for (i = 0; i < total_size; i += flash->chip->page_size) ret |= printlock_w39_fwh_block(flash, i); return ret; @@ -150,10 +150,10 @@ static int printlock_w39_fwh(struct flashctx *flash) static int unlock_w39_fwh(struct flashctx *flash) { - unsigned int i, total_size = flash->total_size * 1024; + unsigned int i, total_size = flash->chip->total_size * 1024; /* Unlock the complete chip */ - for (i = 0; i < total_size; i += flash->page_size) + for (i = 0; i < total_size; i += flash->chip->page_size) if (unlock_w39_fwh_block(flash, i)) return -1; |