blob: 9639e638e953e4426a6557836a69fe0c62c36153 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Ian Ray542a48e2017-11-08 15:35:13 +00002/*
3 * Copyright (c) 2017 General Electric Company. All rights reserved.
Ian Ray542a48e2017-11-08 15:35:13 +00004 */
5
6#include <bootcount.h>
7#include <fs.h>
8#include <mapmem.h>
9
Frédéric Daniscf01a7e2020-03-17 17:59:09 +010010#define BC_MAGIC 0xbd
11#define BC_VERSION 1
12
13typedef struct {
14 u8 magic;
15 u8 version;
16 u8 bootcount;
17 u8 upgrade_available;
18} bootcount_ext_t;
19
20static u8 upgrade_available = 1;
Ian Ray542a48e2017-11-08 15:35:13 +000021
22void bootcount_store(ulong a)
23{
Frédéric Daniscf01a7e2020-03-17 17:59:09 +010024 bootcount_ext_t *buf;
Ian Ray542a48e2017-11-08 15:35:13 +000025 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
Frédéric Daniscf01a7e2020-03-17 17:59:09 +010034 /* 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;
Ian Ray542a48e2017-11-08 15:35:13 +000043 unmap_sysmem(buf);
44
45 ret = fs_write(CONFIG_SYS_BOOTCOUNT_EXT_NAME,
Frédéric Daniscf01a7e2020-03-17 17:59:09 +010046 CONFIG_SYS_BOOTCOUNT_ADDR, 0, sizeof(bootcount_ext_t),
47 &len);
Ian Ray542a48e2017-11-08 15:35:13 +000048 if (ret != 0)
49 puts("Error storing bootcount\n");
50}
51
52ulong bootcount_load(void)
53{
Frédéric Daniscf01a7e2020-03-17 17:59:09 +010054 bootcount_ext_t *buf;
Ian Ray542a48e2017-11-08 15:35:13 +000055 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,
Frédéric Daniscf01a7e2020-03-17 17:59:09 +010065 0, sizeof(bootcount_ext_t), &len_read);
66 if (ret != 0 || len_read != sizeof(bootcount_ext_t)) {
Ian Ray542a48e2017-11-08 15:35:13 +000067 puts("Error loading bootcount\n");
68 return 0;
69 }
70
Frédéric Daniscf01a7e2020-03-17 17:59:09 +010071 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 }
Ian Ray542a48e2017-11-08 15:35:13 +000079
80 unmap_sysmem(buf);
81
82 return ret;
83}