bootcount_ram.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. #include <common.h>
  20. #include <asm/io.h>
  21. DECLARE_GLOBAL_DATA_PTR;
  22. const ulong patterns[] = { 0x00000000,
  23. 0xFFFFFFFF,
  24. 0xFF00FF00,
  25. 0x0F0F0F0F,
  26. 0xF0F0F0F0};
  27. const ulong NBR_OF_PATTERNS = sizeof(patterns) / sizeof(*patterns);
  28. const ulong OFFS_PATTERN = 3;
  29. const ulong REPEAT_PATTERN = 1000;
  30. void bootcount_store(ulong a)
  31. {
  32. ulong *save_addr;
  33. ulong size = 0;
  34. int i;
  35. for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
  36. size += gd->bd->bi_dram[i].size;
  37. save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
  38. writel(a, save_addr);
  39. writel(BOOTCOUNT_MAGIC, &save_addr[1]);
  40. for (i = 0; i < REPEAT_PATTERN; i++)
  41. writel(patterns[i % NBR_OF_PATTERNS],
  42. &save_addr[i + OFFS_PATTERN]);
  43. }
  44. ulong bootcount_load(void)
  45. {
  46. ulong *save_addr;
  47. ulong size = 0;
  48. ulong counter = 0;
  49. int i, tmp;
  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. counter = readl(&save_addr[0]);
  54. /* Is the counter reliable, check in the big pattern for bit errors */
  55. for (i = 0; (i < REPEAT_PATTERN) && (counter != 0); i++) {
  56. tmp = readl(&save_addr[i + OFFS_PATTERN]);
  57. if (tmp != patterns[i % NBR_OF_PATTERNS])
  58. counter = 0;
  59. }
  60. return counter;
  61. }