diff options
author | Namyoon Woo <namyoon@google.com> | 2020-08-27 16:03:16 -0700 |
---|---|---|
committer | Edward O'Callaghan <quasisec@chromium.org> | 2020-09-07 00:52:34 +0000 |
commit | 3149822cd45cb2e5841e15d648783748ba1b2ec6 (patch) | |
tree | ab0402c097da74a0e2bcc66f44a098349eb78c9c | |
parent | 0e787b2e79ce838031b63666bc3c319788ee6a7e (diff) | |
download | flashrom-3149822cd45cb2e5841e15d648783748ba1b2ec6.tar.gz flashrom-3149822cd45cb2e5841e15d648783748ba1b2ec6.tar.bz2 flashrom-3149822cd45cb2e5841e15d648783748ba1b2ec6.zip |
support variable-size SPI chip for dummy programmer
This is designed for firmware updater to pack firmware image
preserving some specific partitions in any size.
BUG=none
TEST=ran the command line below:
$ flashrom -p dummy:image=${TMP_FILE},size=16777216, \
emulate=VARIABLE_SIZE -w ${IMG} -V -f
$ flashrom -p dummy:image=${TMP_FILE},size=auto, \
emulate=VARIABLE_SIZE -w ${IMG} -V -f
Signed-off-by: Namyoon Woo <namyoon@google.com>
Change-Id: Iff266e151459561b126ecfd1c47420b385be1db2
Reviewed-on: https://review.coreboot.org/c/flashrom/+/44879
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
-rw-r--r-- | chipdrivers.h | 3 | ||||
-rw-r--r-- | dummyflasher.c | 89 | ||||
-rw-r--r-- | flashchips.c | 21 |
3 files changed, 113 insertions, 0 deletions
diff --git a/chipdrivers.h b/chipdrivers.h index 3c7d1466..cf038117 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -196,6 +196,9 @@ int erase_sector_stm50(struct flashctx *flash, unsigned int block, unsigned int int probe_en29lv640b(struct flashctx *flash); int write_en29lv640b(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +/* dummyflasher.c */ +int probe_variable_size(struct flashctx *flash); + /* edi.c */ int edi_chip_block_erase(struct flashctx *flash, unsigned int page, unsigned int size); int edi_chip_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); diff --git a/dummyflasher.c b/dummyflasher.c index e1a1d801..b2b3b54d 100644 --- a/dummyflasher.c +++ b/dummyflasher.c @@ -21,6 +21,7 @@ #include "flash.h" #include "chipdrivers.h" #include "programmer.h" +#include "flashchips.h" /* Remove the #define below if you don't want SPI flash chip emulation. */ #define EMULATE_SPI_CHIP 1 @@ -44,6 +45,7 @@ enum emu_chip { EMULATE_SST_SST25VF032B, EMULATE_MACRONIX_MX25L6436, EMULATE_WINBOND_W25Q128FV, + EMULATE_VARIABLE_SIZE, }; static enum emu_chip emu_chip = EMULATE_NONE; static char *emu_persistent_image = NULL; @@ -154,6 +156,7 @@ int dummy_init(void) unsigned int i; #if EMULATE_SPI_CHIP char *status = NULL; + int size = -1; /* size for VARIOUS_SIZE chip device */ #endif #if EMULATE_CHIP struct stat image_stat; @@ -272,6 +275,23 @@ int dummy_init(void) free(tmp); #if EMULATE_CHIP +#if EMULATE_SPI_CHIP + tmp = extract_programmer_param("size"); + if (tmp) { + size = atoi(tmp); + if (size <= 0 || (size % 1024 != 0)) { + msg_perr("%s: Chip size is not a multipler of 1024: %s\n", + __func__, tmp); + free(tmp); + return 1; + } + free(tmp); + } else { + msg_perr("%s: the size parameter is not given.\n", __func__); + return 1; + } +#endif + tmp = extract_programmer_param("emulate"); if (!tmp) { msg_pdbg("Not emulating any flash chip.\n"); @@ -343,6 +363,23 @@ int dummy_init(void) emu_jedec_ce_c7_size = emu_chip_size; msg_pdbg("Emulating Winbond W25Q128FV SPI flash chip (RDID)\n"); } + + /* The name of variable-size virtual chip. A 4 MiB flash example: + * flashrom -p dummy:emulate=VARIABLE_SIZE,size=4194304 + */ + if (!strcmp(tmp, "VARIABLE_SIZE")) { + emu_chip = EMULATE_VARIABLE_SIZE; + emu_chip_size = size; + emu_max_byteprogram_size = 256; + emu_max_aai_size = 0; + emu_jedec_se_size = 4 * 1024; + emu_jedec_be_52_size = 32 * 1024; + emu_jedec_be_d8_size = 64 * 1024; + emu_jedec_ce_60_size = emu_chip_size; + emu_jedec_ce_c7_size = emu_chip_size; + msg_pdbg("Emulating generic SPI flash chip (size=%d bytes)\n", + emu_chip_size); + } #endif if (emu_chip == EMULATE_NONE) { msg_perr("Invalid chip specified for emulation: %s\n", tmp); @@ -610,6 +647,16 @@ static int emulate_spi_chip_response(unsigned int writecnt, if (readcnt > 2) readarr[2] = 0x18; break; + case EMULATE_VARIABLE_SIZE: + if (readcnt > 0) + readarr[0] = (PROGMANUF_ID >> 8) & 0xff; + if (readcnt > 1) + readarr[1] = PROGMANUF_ID & 0xff; + if (readcnt > 2) + readarr[2] = (PROGDEV_ID >> 8) & 0xff; + if (readcnt > 3) + readarr[3] = PROGDEV_ID & 0xff; + break; default: /* ignore */ break; } @@ -840,6 +887,7 @@ static int dummy_spi_send_command(const struct flashctx *flash, unsigned int wri case EMULATE_SST_SST25VF032B: case EMULATE_MACRONIX_MX25L6436: case EMULATE_WINBOND_W25Q128FV: + case EMULATE_VARIABLE_SIZE: if (emulate_spi_chip_response(writecnt, readcnt, writearr, readarr)) { msg_pdbg("Invalid command sent to flash chip!\n"); @@ -862,3 +910,44 @@ static int dummy_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsig return spi_write_chunked(flash, buf, start, len, spi_write_256_chunksize); } + +#if EMULATE_CHIP && EMULATE_SPI_CHIP +int probe_variable_size(struct flashctx *flash) +{ + unsigned int i; + + /* Skip the probing if we don't emulate this chip. */ + if (emu_chip != EMULATE_VARIABLE_SIZE) + return 0; + + /* + * This will break if one day flashctx becomes read-only. + * Once that happens, we need to have special hacks in functions: + * + * erase_and_write_flash() in flashrom.c + * read_flash_to_file() + * handle_romentries() + * ... + * + * Search "total_size * 1024" in code. + */ + flash->chip->total_size = emu_chip_size / 1024; + msg_cdbg("%s: set flash->total_size to %dK bytes.\n", __func__, + flash->chip->total_size); + + /* Update the first count of each of the block_erasers. */ + for (i = 0; i < NUM_ERASEFUNCTIONS; i++) { + struct block_eraser *eraser = &flash->chip->block_erasers[i]; + if (!eraser->block_erase) + break; + + eraser->eraseblocks[0].count = emu_chip_size / + eraser->eraseblocks[0].size; + msg_cdbg("%s: eraser.size=%d, .count=%d\n", + __func__, eraser->eraseblocks[0].size, + eraser->eraseblocks[0].count); + } + + return 1; +} +#endif diff --git a/flashchips.c b/flashchips.c index 8b5b5ccb..6fced9ee 100644 --- a/flashchips.c +++ b/flashchips.c @@ -18759,6 +18759,27 @@ const struct flashchip flashchips[] = { { .vendor = "Generic", + .name = "Variable Size SPI chip", + .bustype = BUS_SPI, + .manufacture_id = PROGMANUF_ID, + .model_id = PROGDEV_ID, + .total_size = 64, /* This size is set temporarily */ + .page_size = 256, + .tested = TEST_OK_PREW, + .probe = probe_variable_size, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 1} }, + .block_erase = spi_block_erase_d8, + } + }, + .write = spi_chip_write_256, + .read = spi_chip_read, + }, + + { + .vendor = "Generic", .name = "unknown SPI chip (RDID)", .bustype = BUS_SPI, .manufacture_id = GENERIC_MANUF_ID, |