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