On 19.11.2009 17:51, Carl-Daniel Hailfinger wrote: > On 17.09.2009 12:41, Carl-Daniel Hailfinger wrote: > >> On 16.09.2009 23:40, Stefan Reinauer wrote: >> >> >>> Carl-Daniel Hailfinger wrote: >>> >>> >>>> On 16.09.2009 19:07, Stefan Reinauer wrote: >>>> >>>> >>>>> Carl-Daniel Hailfinger wrote: >>>>> >>>>> >>>>>> For optimal partial reflashing, we have to find out which parts of the >>>>>> chip can be written without erase. For that, the only criterion (except >>>>>> a limit on the number of writes for very old chips) is whether the write >>>>>> will only clear bits (set them to 0). >>>>>> If (current&new==new) we can skip the erase. >>>>>> If any bit would have to be set to 1, we need to erase. >>>>>> >>>>>> >>>>>> >>>>> Is that sufficient? Ie is it always ok to skip an erase if we're only >>>>> clearing bits? >>>>> >>>>> >>>>> >>>> It depends on the chip, but given that the following appears in the ICH7 >>>> and all later datasheets as absolute flash requirement, I'm positive >>>> most current flash chips support it. >>>> >>>> ----------------- >>>> The system BIOS and IntelĀ® Active Management Technology firmware usage >>>> models >>>> require that the serial flash device support multiple writes (minimum of >>>> 512 writes) to >>>> a page (256 bytes) without requiring a preceding erase command. >>>> ----------------- >>>> >>>> >>>> >>> That means you can theoretically write it twice (2*256 byte writes on an >>> x8 device) without erasing it. >>> I don't think this is something we should rely on. >>> >>> It also says serial flash device, which implies that LPC/FWH might >>> behave differently. >>> >>> >>> >> How should we handle the case where a chip is already erased? Do we >> erase anyway? After all, we can't know if someone already wrote 0xff there. >> >> > > To summarize: Write granularity is chip specific. The following write > granularities exist according to my datasheet survey: > - 1 bit. Each bit can be cleared individually. > - 1 byte. A byte can be written once. Further writes to an already > written byte cause the contents to be either undefined or to stay unchanged. > - 128 bytes. If less than 128 bytes are written, the rest will be > erased. Each write to a 128-byte region will trigger an automatic erase > before anything is written. Very uncommon behaviour. > - 256 bytes. If less than 256 bytes are written, the contents of the > unwritten bytes are undefined. > > Note that chips with default 256-byte writes, which keep the original > contents for unwritten bytes, have a granularity of 1 byte. > > This patch covers the 1-bit granularity variant, and since it is not > hooked up anywhere, I think it is a good starting point for implementing > a check for all variants. We will need an additional field in struct > flashchip for the minimum write granularity, though. >
New patch. Handle 1-bit, 1-byte and 256-byte write granularity. Stefan: I believe this addresses your concerns. Signed-off-by: Carl-Daniel Hailfinger <[email protected]> Index: flashrom-need_erase/flash.h =================================================================== --- flashrom-need_erase/flash.h (Revision 770) +++ flashrom-need_erase/flash.h (Arbeitskopie) @@ -485,6 +485,12 @@ int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); /* flashrom.c */ +enum write_granularity { + write_gran_1bit, + write_gran_1byte, + write_gran_256bytes, +}; + extern char *programmer_param; extern int verbose; extern const char *flashrom_version; @@ -496,6 +502,7 @@ int max(int a, int b); int check_erased_range(struct flashchip *flash, int start, int len); int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message); +int need_erase(uint8_t *have, uint8_t *want, int len, enum write_granularity gran); char *strcat_realloc(char *dest, const char *src); #define OK 0 Index: flashrom-need_erase/flashrom.c =================================================================== --- flashrom-need_erase/flashrom.c (Revision 770) +++ flashrom-need_erase/flashrom.c (Arbeitskopie) @@ -407,6 +407,55 @@ return ret; } +/** + * Check if the buffer have can be programmed to the content of want without + * erasing. This is only possible if no bit has to be set to 1. + * + * @have buffer with current content + * @want buffer with desired content + * @len length of the verified area + * @return 0 if no erase is needed, 1 otherwise + */ +int need_erase(uint8_t *have, uint8_t *want, int len, enum write_granularity gran) +{ + int result = 0; + int i, j, limit; + + switch (gran) { + case write_gran_1bit: + for (i = 0; i < len; i++) + if ((have[i] & want[i]) != want[i]) { + result = 1; + break; + } + break; + case write_gran_1byte: + for (i = 0; i < len; i++) + if ((have[i] != want[i]) && (have[i] != 0xff)) { + result = 1; + break; + } + break; + case write_gran_256bytes: + for (j = 0; j < len / 256; j++) { + limit = min (256, len - j * 256); + /* Are have and want identical? */ + if (!memcmp(have + j * 256, want + j * 256, limit)) + continue; + /* have needs to be in erased state. */ + for (i = 0; i < limit; i++) + if (have[i] != 0xff) { + result = 1; + break; + } + if (result) + break; + } + break; + } + return result; +} + /* This function generates various test patterns useful for testing controller * and chip communication as well as chip behaviour. * -- Developer quote of the month: "We are juggling too many chainsaws and flaming arrows and tigers." _______________________________________________ flashrom mailing list [email protected] http://www.flashrom.org/mailman/listinfo/flashrom
