bootcount.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * (C) Copyright 2012
  4. * Stefan Roese, DENX Software Engineering, sr@denx.de.
  5. */
  6. #ifndef _BOOTCOUNT_H__
  7. #define _BOOTCOUNT_H__
  8. #include <common.h>
  9. #include <asm/io.h>
  10. #include <asm/byteorder.h>
  11. #ifdef CONFIG_DM_BOOTCOUNT
  12. struct bootcount_ops {
  13. /**
  14. * get() - get the current bootcount value
  15. *
  16. * Returns the current counter value of the bootcount backing
  17. * store.
  18. *
  19. * @dev: Device to read from
  20. * @bootcount: Address to put the current bootcount value
  21. */
  22. int (*get)(struct udevice *dev, u32 *bootcount);
  23. /**
  24. * set() - set a bootcount value (e.g. to reset or increment)
  25. *
  26. * Sets the value in the bootcount backing store.
  27. *
  28. * @dev: Device to read from
  29. * @bootcount: New bootcount value to store
  30. */
  31. int (*set)(struct udevice *dev, const u32 bootcount);
  32. };
  33. /* Access the operations for a bootcount device */
  34. #define bootcount_get_ops(dev) ((struct bootcount_ops *)(dev)->driver->ops)
  35. /**
  36. * dm_bootcount_get() - Read the current value from a bootcount storage
  37. *
  38. * @dev: Device to read from
  39. * @bootcount: Place to put the current bootcount
  40. * @return 0 if OK, -ve on error
  41. */
  42. int dm_bootcount_get(struct udevice *dev, u32 *bootcount);
  43. /**
  44. * dm_bootcount_set() - Write a value to a bootcount storage
  45. *
  46. * @dev: Device to read from
  47. * @bootcount: Value to be written to the backing storage
  48. * @return 0 if OK, -ve on error
  49. */
  50. int dm_bootcount_set(struct udevice *dev, u32 bootcount);
  51. #endif
  52. #if defined(CONFIG_SPL_BOOTCOUNT_LIMIT) || defined(CONFIG_BOOTCOUNT_LIMIT)
  53. #if !defined(CONFIG_SYS_BOOTCOUNT_LE) && !defined(CONFIG_SYS_BOOTCOUNT_BE)
  54. # if __BYTE_ORDER == __LITTLE_ENDIAN
  55. # define CONFIG_SYS_BOOTCOUNT_LE
  56. # else
  57. # define CONFIG_SYS_BOOTCOUNT_BE
  58. # endif
  59. #endif
  60. #ifdef CONFIG_SYS_BOOTCOUNT_LE
  61. static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
  62. {
  63. out_le32(addr, data);
  64. }
  65. static inline u32 raw_bootcount_load(volatile u32 *addr)
  66. {
  67. return in_le32(addr);
  68. }
  69. #else
  70. static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
  71. {
  72. out_be32(addr, data);
  73. }
  74. static inline u32 raw_bootcount_load(volatile u32 *addr)
  75. {
  76. return in_be32(addr);
  77. }
  78. #endif
  79. DECLARE_GLOBAL_DATA_PTR;
  80. static inline int bootcount_error(void)
  81. {
  82. unsigned long bootcount = bootcount_load();
  83. unsigned long bootlimit = env_get_ulong("bootlimit", 10, 0);
  84. if (bootlimit && bootcount > bootlimit) {
  85. printf("Warning: Bootlimit (%lu) exceeded.", bootlimit);
  86. if (!(gd->flags & GD_FLG_SPL_INIT))
  87. printf(" Using altbootcmd.");
  88. printf("\n");
  89. return 1;
  90. }
  91. return 0;
  92. }
  93. static inline void bootcount_inc(void)
  94. {
  95. unsigned long bootcount = bootcount_load();
  96. if (gd->flags & GD_FLG_SPL_INIT) {
  97. bootcount_store(++bootcount);
  98. return;
  99. }
  100. #ifndef CONFIG_SPL_BUILD
  101. /* Only increment bootcount when no bootcount support in SPL */
  102. #ifndef CONFIG_SPL_BOOTCOUNT_LIMIT
  103. bootcount_store(++bootcount);
  104. #endif
  105. env_set_ulong("bootcount", bootcount);
  106. #endif /* !CONFIG_SPL_BUILD */
  107. }
  108. #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)
  109. void bootcount_store(ulong a) {};
  110. ulong bootcount_load(void) { return 0; }
  111. #endif /* CONFIG_SPL_BUILD && !CONFIG_SPL_BOOTCOUNT_LIMIT */
  112. #else
  113. static inline int bootcount_error(void) { return 0; }
  114. static inline void bootcount_inc(void) {}
  115. #endif /* CONFIG_SPL_BOOTCOUNT_LIMIT || CONFIG_BOOTCOUNT_LIMIT */
  116. #endif /* _BOOTCOUNT_H__ */