Browse Source

flash: Add optional verify-after-write feature

Sometimes it might make sense to verify the written data to NOR flash.
This patch adds this feature. To enable this verify-after-write, you
need to define CONFIG_FLASH_VERIFY in your board config header.

Please note that this option is useless in nearly all cases,
since such flash programming errors usually are detected earlier
while unprotecting/erasing/programming. Please only enable
this option if you really know what you are doing.

Signed-off-by: Stefan Roese <sr@denx.de>
Stefan Roese 12 years ago
parent
commit
352ef3f1b6
2 changed files with 20 additions and 0 deletions
  1. 9 0
      README
  2. 11 0
      common/flash.c

+ 9 - 0
README

@@ -3248,6 +3248,15 @@ Configuration Settings:
 		digits and dots.  Recommended value: 45 (9..1) for 80
 		digits and dots.  Recommended value: 45 (9..1) for 80
 		column displays, 15 (3..1) for 40 column displays.
 		column displays, 15 (3..1) for 40 column displays.
 
 
+- CONFIG_FLASH_VERIFY
+		If defined, the content of the flash (destination) is compared
+		against the source after the write operation. An error message
+		will be printed when the contents are not identical.
+		Please note that this option is useless in nearly all cases,
+		since such flash programming errors usually are detected earlier
+		while unprotecting/erasing/programming. Please only enable
+		this option if you really know what you are doing.
+
 - CONFIG_SYS_RX_ETH_BUFFER:
 - CONFIG_SYS_RX_ETH_BUFFER:
 		Defines the number of Ethernet receive buffers. On some
 		Defines the number of Ethernet receive buffers. On some
 		Ethernet controllers it is recommended to set this value
 		Ethernet controllers it is recommended to set this value

+ 11 - 0
common/flash.c

@@ -149,6 +149,9 @@ flash_write (char *src, ulong addr, ulong cnt)
 	flash_info_t *info_first = addr2info (addr);
 	flash_info_t *info_first = addr2info (addr);
 	flash_info_t *info_last  = addr2info (end );
 	flash_info_t *info_last  = addr2info (end );
 	flash_info_t *info;
 	flash_info_t *info;
+	__maybe_unused char *src_orig = src;
+	__maybe_unused char *addr_orig = (char *)addr;
+	__maybe_unused ulong cnt_orig = cnt;
 
 
 	if (cnt == 0) {
 	if (cnt == 0) {
 		return (ERR_OK);
 		return (ERR_OK);
@@ -185,6 +188,14 @@ flash_write (char *src, ulong addr, ulong cnt)
 		addr += len;
 		addr += len;
 		src  += len;
 		src  += len;
 	}
 	}
+
+#if defined(CONFIG_FLASH_VERIFY)
+	if (memcmp(src_orig, addr_orig, cnt_orig)) {
+		printf("\nVerify failed!\n");
+		return ERR_PROG_ERROR;
+	}
+#endif /* CONFIG_SYS_FLASH_VERIFY_AFTER_WRITE */
+
 	return (ERR_OK);
 	return (ERR_OK);
 #endif /* CONFIG_SPD823TS */
 #endif /* CONFIG_SPD823TS */
 }
 }