]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
f31dac4e IR |
2 | /* |
3 | * Copyright (c) 2017 General Electric Company. All rights reserved. | |
f31dac4e IR |
4 | */ |
5 | ||
6 | #include <bootcount.h> | |
7 | #include <fs.h> | |
8 | #include <mapmem.h> | |
9 | ||
df928f85 FD |
10 | #define BC_MAGIC 0xbd |
11 | #define BC_VERSION 1 | |
12 | ||
13 | typedef struct { | |
14 | u8 magic; | |
15 | u8 version; | |
16 | u8 bootcount; | |
17 | u8 upgrade_available; | |
18 | } bootcount_ext_t; | |
19 | ||
20 | static u8 upgrade_available = 1; | |
f31dac4e IR |
21 | |
22 | void bootcount_store(ulong a) | |
23 | { | |
df928f85 | 24 | bootcount_ext_t *buf; |
f31dac4e IR |
25 | loff_t len; |
26 | int ret; | |
27 | ||
28 | if (fs_set_blk_dev(CONFIG_SYS_BOOTCOUNT_EXT_INTERFACE, | |
29 | CONFIG_SYS_BOOTCOUNT_EXT_DEVPART, FS_TYPE_EXT)) { | |
30 | puts("Error selecting device\n"); | |
31 | return; | |
32 | } | |
33 | ||
df928f85 FD |
34 | /* Only update bootcount during upgrade process */ |
35 | if (!upgrade_available) | |
36 | return; | |
37 | ||
38 | buf = map_sysmem(CONFIG_SYS_BOOTCOUNT_ADDR, sizeof(bootcount_ext_t)); | |
39 | buf->magic = BC_MAGIC; | |
40 | buf->version = BC_VERSION; | |
41 | buf->bootcount = (a & 0xff); | |
42 | buf->upgrade_available = upgrade_available; | |
f31dac4e IR |
43 | unmap_sysmem(buf); |
44 | ||
45 | ret = fs_write(CONFIG_SYS_BOOTCOUNT_EXT_NAME, | |
df928f85 FD |
46 | CONFIG_SYS_BOOTCOUNT_ADDR, 0, sizeof(bootcount_ext_t), |
47 | &len); | |
f31dac4e IR |
48 | if (ret != 0) |
49 | puts("Error storing bootcount\n"); | |
50 | } | |
51 | ||
52 | ulong bootcount_load(void) | |
53 | { | |
df928f85 | 54 | bootcount_ext_t *buf; |
f31dac4e IR |
55 | loff_t len_read; |
56 | int ret; | |
57 | ||
58 | if (fs_set_blk_dev(CONFIG_SYS_BOOTCOUNT_EXT_INTERFACE, | |
59 | CONFIG_SYS_BOOTCOUNT_EXT_DEVPART, FS_TYPE_EXT)) { | |
60 | puts("Error selecting device\n"); | |
61 | return 0; | |
62 | } | |
63 | ||
64 | ret = fs_read(CONFIG_SYS_BOOTCOUNT_EXT_NAME, CONFIG_SYS_BOOTCOUNT_ADDR, | |
df928f85 FD |
65 | 0, sizeof(bootcount_ext_t), &len_read); |
66 | if (ret != 0 || len_read != sizeof(bootcount_ext_t)) { | |
f31dac4e IR |
67 | puts("Error loading bootcount\n"); |
68 | return 0; | |
69 | } | |
70 | ||
df928f85 FD |
71 | buf = map_sysmem(CONFIG_SYS_BOOTCOUNT_ADDR, sizeof(bootcount_ext_t)); |
72 | if (buf->magic == BC_MAGIC && buf->version == BC_VERSION) { | |
73 | upgrade_available = buf->upgrade_available; | |
74 | if (upgrade_available) | |
75 | ret = buf->bootcount; | |
76 | } else { | |
77 | puts("Incorrect bootcount file\n"); | |
78 | } | |
f31dac4e IR |
79 | |
80 | unmap_sysmem(buf); | |
81 | ||
82 | return ret; | |
83 | } |