bootcount.h 3.5 KB

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