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