[flashrom] [commit] r1493 - trunk

repository service svn at flashrom.org
Thu Feb 16 00:40:23 CET 2012


Author: stefanct
Date: Thu Feb 16 00:40:23 2012
New Revision: 1493
URL: http://flashrom.org/trac/flashrom/changeset/1493

Log:
Warn of one-time programmable (OTP) memory

Some flash chips contain OTP memory that we cannot read or write (yet). This
prohibits us from cloning them, hence warn the user if we detect it. Not all
variations of the tagged chips contain OTP memory. They are often only
enabled on request or have there own ordering numbers. There is usually no
way to distinguish them. Because this is a supposedly seldomly used feature
the warning is shown in with dbg verbosity.

The manpage is extended to describe the backgrounds a bit.

This patch is based on the idea and code of Daniel Lenski.
Signed-off-by: Daniel Lenski <dlenski at gmail.com>
Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

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

Modified: trunk/flash.h
==============================================================================
--- trunk/flash.h	Mon Feb 13 01:35:35 2012	(r1492)
+++ trunk/flash.h	Thu Feb 16 00:40:23 2012	(r1493)
@@ -83,6 +83,7 @@
 #define FEATURE_ADDR_SHIFTED	(1 << 5)
 #define FEATURE_WRSR_EWSR	(1 << 6)
 #define FEATURE_WRSR_WREN	(1 << 7)
+#define FEATURE_OTP		(1 << 8)
 #define FEATURE_WRSR_EITHER	(FEATURE_WRSR_EWSR | FEATURE_WRSR_WREN)
 
 struct flashctx;

Modified: trunk/flashchips.c
==============================================================================
--- trunk/flashchips.c	Mon Feb 13 01:35:35 2012	(r1492)
+++ trunk/flashchips.c	Thu Feb 16 00:40:23 2012	(r1493)
@@ -1120,7 +1120,8 @@
 		.model_id	= AMIC_A25L032,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -1158,7 +1159,8 @@
 		.model_id	= AMIC_A25LQ032,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -1315,7 +1317,8 @@
 		.model_id	= ATMEL_AT25DF021,
 		.total_size	= 256,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -1543,7 +1546,8 @@
 		.model_id	= ATMEL_AT25DF321A,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PROBE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -1619,7 +1623,8 @@
 		.model_id	= ATMEL_AT25DQ161,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -1657,7 +1662,8 @@
 		.model_id	= ATMEL_AT25F512B,
 		.total_size	= 64,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -2168,6 +2174,8 @@
 		.model_id	= ATMEL_AT45DB321D,
 		.total_size	= 4096 /* Size can only be determined from status register */,
 		.page_size	= 512 /* Size can only be determined from status register */,
+		/* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+		.feature_bits	= FEATURE_OTP,
 		.tested		= TEST_BAD_READ,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -3236,8 +3244,8 @@
 		.model_id	= EON_EN25Q40,
 		.total_size	= 512,
 		.page_size	= 256,
-		/* TODO: chip features 256-byte one-time programmable region */
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 256B total; enter 0x3A */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -3271,8 +3279,8 @@
 		.model_id	= EON_EN25Q80,
 		.total_size	= 1024,
 		.page_size	= 256,
-		/* TODO: chip features 256-byte one-time programmable region */
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 256B total; enter 0x3A */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -3308,9 +3316,8 @@
 		.model_id	= EON_EN25Q16,
 		.total_size	= 2048,
 		.page_size	= 256,
-		/* TODO: EN25D16 features 512-byte one-time programmable region,
-		 * EN25Q16 features a 128-byte one-time programmable region */
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: D16 512B/Q16 128B total; enter 0x3A */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -3348,8 +3355,8 @@
 		.model_id	= EON_EN25Q32,
 		.total_size	= 4096,
 		.page_size	= 256,
-		/* TODO: chip features 512-byte one-time programmable region */
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 512B total; enter 0x3A */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -3383,8 +3390,8 @@
 		.model_id	= EON_EN25Q64,
 		.total_size	= 8192,
 		.page_size	= 256,
-		/* TODO: chip features 512-byte one-time programmable region */
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 512B total; enter 0x3A */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -3418,8 +3425,8 @@
 		.model_id	= EON_EN25Q128,
 		.total_size	= 16384,
 		.page_size	= 256,
-		/* TODO: chip features 512-byte one-time programmable region */
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 512B total; enter 0x3A */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -3452,10 +3459,9 @@
 		.model_id	= EON_EN25QH16,
 		.total_size	= 2048,
 		.page_size	= 256,
-		/* TODO: chip features 512-byte one-time programmable region
-		 * and supports SFDP.
-		 */
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* supports SFDP */
+		/* OTP: 512B total; enter 0x3A */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -7092,6 +7098,8 @@
 		.model_id	= ST_M25PX16,
 		.total_size	= 2048,
 		.page_size	= 256,
+		/* OTP: 64B total; read 0x4B; write 0x42 */
+		.feature_bits	= FEATURE_OTP,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -7960,7 +7968,8 @@
 		.model_id	= WINBOND_NEX_W25Q80,
 		.total_size	= 1024,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -7997,7 +8006,8 @@
 		.model_id	= WINBOND_NEX_W25Q16,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -8034,7 +8044,8 @@
 		.model_id	= WINBOND_NEX_W25Q32,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -8071,7 +8082,8 @@
 		.model_id	= WINBOND_NEX_W25Q64,
 		.total_size	= 8192,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -8107,7 +8119,8 @@
 		.model_id	= WINBOND_NEX_W25Q128,
 		.total_size	= 16384,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PROBE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,

Modified: trunk/flashrom.8
==============================================================================
--- trunk/flashrom.8	Mon Feb 13 01:35:35 2012	(r1492)
+++ trunk/flashrom.8	Thu Feb 16 00:40:23 2012	(r1493)
@@ -670,6 +670,19 @@
 More information about flashrom on laptops is available from
 .sp
 .B "  http://www.flashrom.org/Laptops"
+.SS
+One-time programmable (OTP) memory and unique IDs
+.sp
+Some flash chips contain OTP memory often denoted as "security registers".
+They usually have a capacity in the range of some bytes to a few hundred
+bytes and can be used to give devices unique IDs etc. flashrom is not able
+to read or write these memories and may therefore not be able to duplicate a
+chip completely. For chip types known to include OTP memories a warning is
+printed when they are detected.
+.sp
+Similar to OTP memories are unique, factory programmed, unforgeable IDs.
+They are not modifiable by the user at all.
+.RE
 .SH LICENSE
 .B flashrom
 is covered by the GNU General Public License (GPL), version 2. Some files are

Modified: trunk/flashrom.c
==============================================================================
--- trunk/flashrom.c	Mon Feb 13 01:35:35 2012	(r1492)
+++ trunk/flashrom.c	Thu Feb 16 00:40:23 2012	(r1493)
@@ -1560,6 +1560,13 @@
 
 void check_chip_supported(const struct flashctx *flash)
 {
+	if (flash->feature_bits & FEATURE_OTP) {
+		msg_cdbg("This chip may contain one-time programmable memory. "
+			 "flashrom cannot read\nand may never be able to write "
+			 "it, hence it may not be able to completely\n"
+			 "clone the contents of this chip (see man page for "
+			 "details).\n");
+	}
 	if (TEST_OK_MASK != (flash->tested & TEST_OK_MASK)) {
 		msg_cinfo("===\n");
 		if (flash->tested & TEST_BAD_MASK) {




More information about the flashrom mailing list