[flashrom] [PATCH] Check if an erase is needed to write

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Mon Nov 23 15:33:27 CET 2009


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 <c-d.hailfinger.devel.2006 at gmx.net>

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."





More information about the flashrom mailing list