uboot/drivers/bootcount/bootcount_ram.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <asm/io.h>
  10
  11DECLARE_GLOBAL_DATA_PTR;
  12
  13const ulong patterns[]      = { 0x00000000,
  14                                0xFFFFFFFF,
  15                                0xFF00FF00,
  16                                0x0F0F0F0F,
  17                                0xF0F0F0F0};
  18const ulong NBR_OF_PATTERNS = sizeof(patterns) / sizeof(*patterns);
  19const ulong OFFS_PATTERN    = 3;
  20const ulong REPEAT_PATTERN  = 1000;
  21
  22void bootcount_store(ulong a)
  23{
  24        ulong *save_addr;
  25        ulong size = 0;
  26        int i;
  27
  28        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
  29                size += gd->bd->bi_dram[i].size;
  30        save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
  31        writel(a, save_addr);
  32        writel(BOOTCOUNT_MAGIC, &save_addr[1]);
  33
  34        for (i = 0; i < REPEAT_PATTERN; i++)
  35                writel(patterns[i % NBR_OF_PATTERNS],
  36                        &save_addr[i + OFFS_PATTERN]);
  37
  38        /* Make sure the data is written to RAM */
  39        flush_dcache_range((ulong)&save_addr[0],
  40                           (ulong)&save_addr[REPEAT_PATTERN + OFFS_PATTERN]);
  41}
  42
  43ulong bootcount_load(void)
  44{
  45        ulong *save_addr;
  46        ulong size = 0;
  47        ulong counter = 0;
  48        int i, tmp;
  49
  50        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
  51                size += gd->bd->bi_dram[i].size;
  52        save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
  53
  54        counter = readl(&save_addr[0]);
  55
  56        /* Is the counter reliable, check in the big pattern for bit errors */
  57        for (i = 0; (i < REPEAT_PATTERN) && (counter != 0); i++) {
  58                tmp = readl(&save_addr[i + OFFS_PATTERN]);
  59                if (tmp != patterns[i % NBR_OF_PATTERNS])
  60                        counter = 0;
  61        }
  62        return counter;
  63}
  64