]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/bootcount/bootcount_ram.c
Merge branch 'agust@denx.de' of git://git.denx.de/u-boot-staging
[karo-tx-uboot.git] / drivers / bootcount / bootcount_ram.c
1 /*
2  * (C) Copyright 2010
3  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  */
19
20 #include <common.h>
21 #include <asm/io.h>
22
23 DECLARE_GLOBAL_DATA_PTR;
24
25 const ulong patterns[]      = { 0x00000000,
26                                 0xFFFFFFFF,
27                                 0xFF00FF00,
28                                 0x0F0F0F0F,
29                                 0xF0F0F0F0};
30 const ulong NBR_OF_PATTERNS = sizeof(patterns) / sizeof(*patterns);
31 const ulong OFFS_PATTERN    = 3;
32 const ulong REPEAT_PATTERN  = 1000;
33
34 void bootcount_store(ulong a)
35 {
36         ulong *save_addr;
37         ulong size = 0;
38         int i;
39
40         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
41                 size += gd->bd->bi_dram[i].size;
42         save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
43         writel(a, save_addr);
44         writel(BOOTCOUNT_MAGIC, &save_addr[1]);
45
46         for (i = 0; i < REPEAT_PATTERN; i++)
47                 writel(patterns[i % NBR_OF_PATTERNS],
48                         &save_addr[i + OFFS_PATTERN]);
49
50 }
51
52 ulong bootcount_load(void)
53 {
54         ulong *save_addr;
55         ulong size = 0;
56         ulong counter = 0;
57         int i, tmp;
58
59         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
60                 size += gd->bd->bi_dram[i].size;
61         save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
62
63         counter = readl(&save_addr[0]);
64
65         /* Is the counter reliable, check in the big pattern for bit errors */
66         for (i = 0; (i < REPEAT_PATTERN) && (counter != 0); i++) {
67                 tmp = readl(&save_addr[i + OFFS_PATTERN]);
68                 if (tmp != patterns[i % NBR_OF_PATTERNS])
69                         counter = 0;
70         }
71         return counter;
72 }