blob: 6d0f622262d7de5d41e5415a4febfa7c68083116 [file] [log] [blame]
Simon Glassc2213082025-01-26 11:43:29 -07001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Verified Boot for Embedded (VBE) 'simple' method
4 *
5 * Copyright 2024 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
9#define LOG_CATEGORY LOGC_BOOT
10
11#include <dm.h>
12#include <memalign.h>
13#include <mmc.h>
14#include <dm/ofnode.h>
15#include "vbe_abrec.h"
16
17int abrec_read_priv(ofnode node, struct abrec_priv *priv)
18{
19 memset(priv, '\0', sizeof(*priv));
20 if (ofnode_read_u32(node, "area-start", &priv->area_start) ||
21 ofnode_read_u32(node, "area-size", &priv->area_size) ||
22 ofnode_read_u32(node, "version-offset", &priv->version_offset) ||
23 ofnode_read_u32(node, "version-size", &priv->version_size) ||
24 ofnode_read_u32(node, "state-offset", &priv->state_offset) ||
25 ofnode_read_u32(node, "state-size", &priv->state_size))
26 return log_msg_ret("read", -EINVAL);
27 ofnode_read_u32(node, "skip-offset", &priv->skip_offset);
28 priv->storage = strdup(ofnode_read_string(node, "storage"));
29 if (!priv->storage)
30 return log_msg_ret("str", -EINVAL);
31
32 return 0;
33}
34
35int abrec_read_nvdata(struct abrec_priv *priv, struct udevice *blk,
36 struct abrec_state *state)
37{
38 ALLOC_CACHE_ALIGN_BUFFER(u8, buf, MMC_MAX_BLOCK_LEN);
39 const struct vbe_nvdata *nvd = (struct vbe_nvdata *)buf;
40 uint flags;
41 int ret;
42
43 ret = vbe_read_nvdata(blk, priv->area_start + priv->state_offset,
44 priv->state_size, buf);
45 if (ret == -EPERM) {
46 memset(buf, '\0', MMC_MAX_BLOCK_LEN);
47 log_warning("Starting with empty state\n");
48 } else if (ret) {
49 return log_msg_ret("nv", ret);
50 }
51
52 state->fw_vernum = nvd->fw_vernum;
53 flags = nvd->flags;
54 state->try_count = flags & VBEF_TRY_COUNT_MASK;
55 state->try_b = flags & VBEF_TRY_B;
56 state->recovery = flags & VBEF_RECOVERY;
57 state->pick = (flags & VBEF_PICK_MASK) >> VBEF_PICK_SHIFT;
58
59 return 0;
60}
61
62int abrec_read_state(struct udevice *dev, struct abrec_state *state)
63{
64 struct abrec_priv *priv = dev_get_priv(dev);
65 struct udevice *blk;
66 int ret;
67
68 ret = vbe_get_blk(priv->storage, &blk);
69 if (ret)
70 return log_msg_ret("blk", ret);
71
72 ret = vbe_read_version(blk, priv->area_start + priv->version_offset,
73 state->fw_version, MAX_VERSION_LEN);
74 if (ret)
75 return log_msg_ret("ver", ret);
76 log_debug("version=%s\n", state->fw_version);
77
78 ret = abrec_read_nvdata(priv, blk, state);
79 if (ret)
80 return log_msg_ret("nvd", ret);
81
82 return 0;
83}