1
2
3
4
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
20
21
22
23
24
25
26
27 int (*get)(struct udevice *dev, u32 *bootcount);
28
29
30
31
32
33
34
35
36
37 int (*set)(struct udevice *dev, const u32 bootcount);
38};
39
40
41#define bootcount_get_ops(dev) ((struct bootcount_ops *)(dev)->driver->ops)
42
43
44
45
46
47
48
49
50int dm_bootcount_get(struct udevice *dev, u32 *bootcount);
51
52
53
54
55
56
57
58
59int dm_bootcount_set(struct udevice *dev, u32 bootcount);
60
61#endif
62
63
64void bootcount_store(ulong);
65
66
67
68
69
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
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
139}
140
141#else
142static inline int bootcount_error(void) { return 0; }
143static inline void bootcount_inc(void) {}
144#endif
145#endif
146