123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /* SPDX-License-Identifier: GPL-2.0+ */
- /*
- * (C) Copyright 2012
- * Stefan Roese, DENX Software Engineering, sr@denx.de.
- */
- #ifndef _BOOTCOUNT_H__
- #define _BOOTCOUNT_H__
- #include <common.h>
- #include <asm/global_data.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
- #include <env.h>
- #ifdef CONFIG_DM_BOOTCOUNT
- struct bootcount_ops {
- /**
- * get() - get the current bootcount value
- *
- * Returns the current counter value of the bootcount backing
- * store.
- *
- * @dev: Device to read from
- * @bootcount: Address to put the current bootcount value
- */
- int (*get)(struct udevice *dev, u32 *bootcount);
- /**
- * set() - set a bootcount value (e.g. to reset or increment)
- *
- * Sets the value in the bootcount backing store.
- *
- * @dev: Device to read from
- * @bootcount: New bootcount value to store
- */
- int (*set)(struct udevice *dev, const u32 bootcount);
- };
- /* Access the operations for a bootcount device */
- #define bootcount_get_ops(dev) ((struct bootcount_ops *)(dev)->driver->ops)
- /**
- * dm_bootcount_get() - Read the current value from a bootcount storage
- *
- * @dev: Device to read from
- * @bootcount: Place to put the current bootcount
- * @return 0 if OK, -ve on error
- */
- int dm_bootcount_get(struct udevice *dev, u32 *bootcount);
- /**
- * dm_bootcount_set() - Write a value to a bootcount storage
- *
- * @dev: Device to read from
- * @bootcount: Value to be written to the backing storage
- * @return 0 if OK, -ve on error
- */
- int dm_bootcount_set(struct udevice *dev, u32 bootcount);
- #endif
- /** bootcount_store() - store the current bootcount */
- void bootcount_store(ulong);
- /**
- * bootcount_load() - load the current bootcount
- *
- * @return bootcount, read from the appropriate location
- */
- ulong bootcount_load(void);
- #if defined(CONFIG_SPL_BOOTCOUNT_LIMIT) || defined(CONFIG_TPL_BOOTCOUNT_LIMIT) || defined(CONFIG_BOOTCOUNT_LIMIT)
- #if !defined(CONFIG_SYS_BOOTCOUNT_LE) && !defined(CONFIG_SYS_BOOTCOUNT_BE)
- # if __BYTE_ORDER == __LITTLE_ENDIAN
- # define CONFIG_SYS_BOOTCOUNT_LE
- # else
- # define CONFIG_SYS_BOOTCOUNT_BE
- # endif
- #endif
- #ifdef CONFIG_SYS_BOOTCOUNT_LE
- static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
- {
- out_le32(addr, data);
- }
- static inline u32 raw_bootcount_load(volatile u32 *addr)
- {
- return in_le32(addr);
- }
- #else
- static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
- {
- out_be32(addr, data);
- }
- static inline u32 raw_bootcount_load(volatile u32 *addr)
- {
- return in_be32(addr);
- }
- #endif
- DECLARE_GLOBAL_DATA_PTR;
- static inline int bootcount_error(void)
- {
- unsigned long bootcount = bootcount_load();
- unsigned long bootlimit = env_get_ulong("bootlimit", 10, 0);
- if (bootlimit && bootcount > bootlimit) {
- printf("Warning: Bootlimit (%lu) exceeded.", bootlimit);
- if (!(gd->flags & GD_FLG_SPL_INIT))
- printf(" Using altbootcmd.");
- printf("\n");
- return 1;
- }
- return 0;
- }
- static inline void bootcount_inc(void)
- {
- unsigned long bootcount = bootcount_load();
- if (gd->flags & GD_FLG_SPL_INIT) {
- bootcount_store(++bootcount);
- return;
- }
- #ifndef CONFIG_SPL_BUILD
- /* Only increment bootcount when no bootcount support in SPL */
- #if !defined(CONFIG_SPL_BOOTCOUNT_LIMIT) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)
- bootcount_store(++bootcount);
- #endif
- env_set_ulong("bootcount", bootcount);
- #endif /* !CONFIG_SPL_BUILD */
- }
- #else
- static inline int bootcount_error(void) { return 0; }
- static inline void bootcount_inc(void) {}
- #endif /* CONFIG_SPL_BOOTCOUNT_LIMIT || CONFIG_TPL_BOOTCOUNT_LIMIT || CONFIG_BOOTCOUNT_LIMIT */
- #endif /* _BOOTCOUNT_H__ */
|