arm/km: adapt bootcounter evaluation

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@keymile.com>
Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com>
cc: Prafulla Wadaskar <prafulla@marvell.com>
This commit is contained in:
Holger Brunck 2011-09-13 22:41:02 +00:00 committed by Albert ARIBAUD
parent c5dd978517
commit 37605c466d

View File

@ -405,6 +405,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;
@ -416,21 +425,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