Nico Huber has submitted this change and it was merged. ( https://review.coreboot.org/23258 )
Change subject: Add support for selecting the erased bit value with a flag ......................................................................
Add support for selecting the erased bit value with a flag
Most flash chips are erased to ones and programmed to zeros. However, some other chips, such as the ENE KB9012 internal flash, work the opposite way.
Change-Id: Ia7b0de8568e31f9bf263ba0ad6b051e837477b6b Signed-off-by: Mike Banon mikebdp2@gmail.com Signed-off-by: Paul Kocialkowski contact@paulk.fr Reviewed-on: https://review.coreboot.org/23258 Reviewed-by: Nico Huber nico.h@gmx.de Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M flash.h M flashrom.c 2 files changed, 26 insertions(+), 15 deletions(-)
Approvals: Nico Huber: Looks good to me, approved build bot (Jenkins): Verified Paul Kocialkowski: Looks good to me, approved
diff --git a/flash.h b/flash.h index a71fec1..f2c6cbe 100644 --- a/flash.h +++ b/flash.h @@ -130,6 +130,13 @@ #define FEATURE_4BA_NATIVE (FEATURE_4BA_READ | FEATURE_4BA_FAST_READ | FEATURE_4BA_WRITE) #define FEATURE_4BA (FEATURE_4BA_ENTER | FEATURE_4BA_EXT_ADDR | FEATURE_4BA_NATIVE) #define FEATURE_4BA_WREN (FEATURE_4BA_ENTER_WREN | FEATURE_4BA_EXT_ADDR | FEATURE_4BA_NATIVE) +/* + * Most flash chips are erased to ones and programmed to zeros. However, some + * other flash chips, such as the ENE KB9012 internal flash, work the opposite way. + */ +#define FEATURE_ERASED_ZERO (1 << 16) + +#define ERASED_VALUE(flash) (((flash)->chip->feature_bits & FEATURE_ERASED_ZERO) ? 0x00 : 0xff)
enum test_state { OK = 0, @@ -309,7 +316,7 @@ int read_flash_to_file(struct flashctx *flash, const char *filename); char *extract_param(const char *const *haystack, const char *needle, const char *delim); int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len); -int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len, enum write_granularity gran); +int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len, enum write_granularity gran, const uint8_t erased_value); void print_version(void); void print_buildinfo(void); void print_banner(void); diff --git a/flashrom.c b/flashrom.c index a7de995..26b9863 100644 --- a/flashrom.c +++ b/flashrom.c @@ -700,12 +700,13 @@ { int ret; uint8_t *cmpbuf = malloc(len); + const uint8_t erased_value = ERASED_VALUE(flash);
if (!cmpbuf) { msg_gerr("Could not allocate memory!\n"); exit(1); } - memset(cmpbuf, 0xff, len); + memset(cmpbuf, erased_value, len); ret = verify_range(flash, cmpbuf, start, len); free(cmpbuf); return ret; @@ -758,7 +759,8 @@ }
/* Helper function for need_erase() that focuses on granularities of gran bytes. */ -static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len, unsigned int gran) +static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len, + unsigned int gran, const uint8_t erased_value) { unsigned int i, j, limit; for (j = 0; j < len / gran; j++) { @@ -768,7 +770,7 @@ continue; /* have needs to be in erased state. */ for (i = 0; i < limit; i++) - if (have[j * gran + i] != 0xff) + if (have[j * gran + i] != erased_value) return 1; } return 0; @@ -788,7 +790,8 @@ * @gran write granularity (enum, not count) * @return 0 if no erase is needed, 1 otherwise */ -int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len, enum write_granularity gran) +int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len, + enum write_granularity gran, const uint8_t erased_value) { int result = 0; unsigned int i; @@ -803,31 +806,31 @@ break; case write_gran_1byte: for (i = 0; i < len; i++) - if ((have[i] != want[i]) && (have[i] != 0xff)) { + if ((have[i] != want[i]) && (have[i] != erased_value)) { result = 1; break; } break; case write_gran_128bytes: - result = need_erase_gran_bytes(have, want, len, 128); + result = need_erase_gran_bytes(have, want, len, 128, erased_value); break; case write_gran_256bytes: - result = need_erase_gran_bytes(have, want, len, 256); + result = need_erase_gran_bytes(have, want, len, 256, erased_value); break; case write_gran_264bytes: - result = need_erase_gran_bytes(have, want, len, 264); + result = need_erase_gran_bytes(have, want, len, 264, erased_value); break; case write_gran_512bytes: - result = need_erase_gran_bytes(have, want, len, 512); + result = need_erase_gran_bytes(have, want, len, 512, erased_value); break; case write_gran_528bytes: - result = need_erase_gran_bytes(have, want, len, 528); + result = need_erase_gran_bytes(have, want, len, 528, erased_value); break; case write_gran_1024bytes: - result = need_erase_gran_bytes(have, want, len, 1024); + result = need_erase_gran_bytes(have, want, len, 1024, erased_value); break; case write_gran_1056bytes: - result = need_erase_gran_bytes(have, want, len, 1056); + result = need_erase_gran_bytes(have, want, len, 1056, erased_value); break; case write_gran_1byte_implicit_erase: /* Do not erase, handle content changes from anything->0xff by writing 0xff. */ @@ -1772,11 +1775,12 @@ ret = 1; bool skipped = true; uint8_t *const curcontents = info->curcontents + info->erase_start; - if (need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran)) { + const uint8_t erased_value = ERASED_VALUE(flashctx); + if (need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran, erased_value)) { if (erase_block(flashctx, info, erasefn)) goto _free_ret; /* Erase was successful. Adjust curcontents. */ - memset(curcontents, 0xff, erase_len); + memset(curcontents, erased_value, erase_len); skipped = false; }