1
2
3
4
5
6#ifndef _BOOTCOUNT_H__
7#define _BOOTCOUNT_H__
8
9#include <common.h>
10#include <asm/io.h>
11#include <asm/byteorder.h>
12#include <env.h>
13
14#ifdef CONFIG_DM_BOOTCOUNT
15
16struct bootcount_ops {
17
18
19
20
21
22
23
24
25
26 int (*get)(struct udevice *dev, u32 *bootcount);
27
28
29
30
31
32
33
34
35
36 int (*set)(struct udevice *dev, const u32 bootcount);
37};
38
39
40#define bootcount_get_ops(dev) ((struct bootcount_ops *)(dev)->driver->ops)
41
42
43
44
45
46
47
48
49int dm_bootcount_get(struct udevice *dev, u32 *bootcount);
50
51
52
53
54
55
56
57
58int dm_bootcount_set(struct udevice *dev, u32 bootcount);
59
60#endif
61
62
63void bootcount_store(ulong);
64
65
66
67
68
69
70ulong bootcount_load(void);
71
72#if defined(CONFIG_SPL_BOOTCOUNT_LIMIT) || defined(CONFIG_BOOTCOUNT_LIMIT)
73
74#if !defined(CONFIG_SYS_BOOTCOUNT_LE) && !defined(CONFIG_SYS_BOOTCOUNT_BE)
75# if __BYTE_ORDER == __LITTLE_ENDIAN
76# define CONFIG_SYS_BOOTCOUNT_LE
77# else
78# define CONFIG_SYS_BOOTCOUNT_BE
79# endif
80#endif
81
82#ifdef CONFIG_SYS_BOOTCOUNT_LE
83static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
84{
85 out_le32(addr, data);
86}
87
88static inline u32 raw_bootcount_load(volatile u32 *addr)
89{
90 return in_le32(addr);
91}
92#else
93static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
94{
95 out_be32(addr, data);
96}
97
98static inline u32 raw_bootcount_load(volatile u32 *addr)
99{
100 return in_be32(addr);
101}
102#endif
103
104DECLARE_GLOBAL_DATA_PTR;
105static inline int bootcount_error(void)
106{
107 unsigned long bootcount = bootcount_load();
108 unsigned long bootlimit = env_get_ulong("bootlimit", 10, 0);
109
110 if (bootlimit && bootcount > bootlimit) {
111 printf("Warning: Bootlimit (%lu) exceeded.", bootlimit);
112 if (!(gd->flags & GD_FLG_SPL_INIT))
113 printf(" Using altbootcmd.");
114 printf("\n");
115
116 return 1;
117 }
118
119 return 0;
120}
121
122static inline void bootcount_inc(void)
123{
124 unsigned long bootcount = bootcount_load();
125
126 if (gd->flags & GD_FLG_SPL_INIT) {
127 bootcount_store(++bootcount);
128 return;
129 }
130
131#ifndef CONFIG_SPL_BUILD
132
133#ifndef CONFIG_SPL_BOOTCOUNT_LIMIT
134 bootcount_store(++bootcount);
135#endif
136 env_set_ulong("bootcount", bootcount);
137#endif
138}
139
140#else
141static inline int bootcount_error(void) { return 0; }
142static inline void bootcount_inc(void) {}
143#endif
144#endif
145