uboot/drivers/bootcount/bootcount_ram.c
<<
>>
Prefs
   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
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25const ulong patterns[]      = { 0x00000000,
  26                                0xFFFFFFFF,
  27                                0xFF00FF00,
  28                                0x0F0F0F0F,
  29                                0xF0F0F0F0};
  30const ulong NBR_OF_PATTERNS = sizeof(patterns) / sizeof(*patterns);
  31const ulong OFFS_PATTERN    = 3;
  32const ulong REPEAT_PATTERN  = 1000;
  33
  34void 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
  52ulong 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}
  73