[flashrom] [commit] r927 - trunk

repository service svn at flashrom.org
Mon Mar 8 01:42:32 CET 2010


Author: hailfinger
Date: Mon Mar  8 01:42:32 2010
New Revision: 927
URL: http://flashrom.org/trac/coreboot/changeset/927

Log:
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.

Handle 1-bit, 1-byte and 256-byte write granularity.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
Acked-by: Sean Nelson <audiohacked at gmail.com>
Acked-by: David Hendricks <dhendrix at google.com>

Modified:
   trunk/flash.h
   trunk/flashrom.c

Modified: trunk/flash.h
==============================================================================
--- trunk/flash.h	Sun Mar  7 23:29:28 2010	(r926)
+++ trunk/flash.h	Mon Mar  8 01:42:32 2010	(r927)
@@ -512,6 +512,11 @@
 int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 
 /* flashrom.c */
+enum write_granularity {
+	write_gran_1bit,
+	write_gran_1byte,
+	write_gran_256bytes,
+};
 extern enum chipbustype buses_supported;
 struct decode_sizes {
 	uint32_t parallel;
@@ -538,6 +543,7 @@
 char *extract_param(char **haystack, char *needle, char *delim);
 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);
 void print_version(void);
 int selfcheck(void);

Modified: trunk/flashrom.c
==============================================================================
--- trunk/flashrom.c	Sun Mar  7 23:29:28 2010	(r926)
+++ trunk/flashrom.c	Mon Mar  8 01:42:32 2010	(r927)
@@ -620,6 +620,67 @@
 	return ret;
 }
 
+/**
+ * Check if the buffer @have can be programmed to the content of @want without
+ * erasing. This is only possible if all chunks of size @gran are either kept
+ * as-is or changed from an all-ones state to any other state.
+ * The following write granularities (enum @gran) are known:
+ * - 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 and unsupported by
+ *   this function.
+ * - 256 bytes. If less than 256 bytes are written, the contents of the
+ *   unwritten bytes are undefined.
+ *
+ * @have        buffer with current content
+ * @want        buffer with desired content
+ * @len         length of the verified area
+ * @gran	write granularity (enum, not count)
+ * @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.
  *




More information about the flashrom mailing list