[U-Boot] [PATCH 1/5] arm/km: adapt bootcounter evaluation

Holger Brunck holger.brunck at keymile.com
Wed Sep 14 10:41:02 CEST 2011


The bootcounter (stored in the RAM) is not enough protected with the 4 Bytes
BOOTCOUNT_MAGIC against bit errors due to short power loss or holding a system
in RESET. It has been seen, that the bootcounter value has been changed due to
a bit flip on a system holding in RESET, but the BOOTCOUNT_MAGIC was still valid.

A bit pattern with 4000 bytes (after BOOTCOUNT_MAGIC) has been implemented,
which should be enough to detect a bit error.

Signed-off-by: Holger Brunck <holger.brunck at keymile.com>
Signed-off-by: Valentin Longchamp <valentin.longchamp at keymile.com>
cc: Prafulla Wadaskar <prafulla at marvell.com>
---
 board/keymile/km_arm/km_arm.c |   32 +++++++++++++++++++++++++++-----
 1 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c
index fb8f79c..cfd0de7 100644
--- a/board/keymile/km_arm/km_arm.c
+++ b/board/keymile/km_arm/km_arm.c
@@ -408,6 +408,15 @@ int hush_init_var(void)
 #endif
 
 #if defined(CONFIG_BOOTCOUNT_LIMIT)
+const ulong patterns[]      = {	0x00000000,
+				0xFFFFFFFF,
+				0xFF00FF00,
+				0x0F0F0F0F,
+				0xF0F0F0F0};
+const ulong NBR_OF_PATTERNS = sizeof(patterns)/sizeof(*patterns);
+const ulong OFFS_PATTERN    = 3;
+const ulong REPEAT_PATTERN  = 1000;
+
 void bootcount_store(ulong a)
 {
 	volatile ulong *save_addr;
@@ -419,21 +428,34 @@ void bootcount_store(ulong a)
 	save_addr = (ulong*)(size - BOOTCOUNT_ADDR);
 	writel(a, save_addr);
 	writel(BOOTCOUNT_MAGIC, &save_addr[1]);
+
+	for (i = 0; i < REPEAT_PATTERN; i++)
+		writel(patterns[i % NBR_OF_PATTERNS],
+			&save_addr[i+OFFS_PATTERN]);
+
 }
 
 ulong bootcount_load(void)
 {
 	volatile ulong *save_addr;
 	volatile ulong size = 0;
-	int i;
+	ulong counter = 0;
+	int i, tmp;
+
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		size += gd->bd->bi_dram[i].size;
 	}
 	save_addr = (ulong*)(size - BOOTCOUNT_ADDR);
-	if (readl(&save_addr[1]) != BOOTCOUNT_MAGIC)
-		return 0;
-	else
-		return readl(save_addr);
+
+	counter = readl(&save_addr[0]);
+
+	/* Is the counter reliable, check in the big pattern for bit errors */
+	for (i = 0; (i < REPEAT_PATTERN) && (counter != 0); i++) {
+		tmp = readl(&save_addr[i+OFFS_PATTERN]);
+		if (tmp != patterns[i % NBR_OF_PATTERNS])
+			counter = 0;
+	}
+	return counter;
 }
 #endif
 
-- 
1.7.1



More information about the U-Boot mailing list