blob: 84117815a19c4fbb5fe52c71d6041096444208bd [file] [log] [blame]
Simon Glassfdacd502025-01-15 18:27:03 -07001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Verified Boot for Embedded (VBE) common functions
4 *
5 * Copyright 2024 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
9#ifndef __VBE_COMMON_H
10#define __VBE_COMMON_H
11
12#include <linux/types.h>
13
Simon Glassedd22362025-01-15 18:27:22 -070014struct spl_image_info;
Simon Glassfdacd502025-01-15 18:27:03 -070015struct udevice;
16
Simon Glassedd22362025-01-15 18:27:22 -070017/*
18 * Controls whether we use a full bootmeth driver with VBE in this phase, or
19 * just access the information directly.
20 *
21 * For now VBE-simple uses the full bootmeth, but VBE-abrec does not, to reduce
22 * code size
23 */
24#define USE_BOOTMETH CONFIG_IS_ENABLED(BOOTMETH_VBE_SIMPLE)
25
Simon Glassfdacd502025-01-15 18:27:03 -070026enum {
27 MAX_VERSION_LEN = 256,
28
29 NVD_HDR_VER_SHIFT = 0,
30 NVD_HDR_VER_MASK = 0xf,
31 NVD_HDR_SIZE_SHIFT = 4,
32 NVD_HDR_SIZE_MASK = 0xf << NVD_HDR_SIZE_SHIFT,
33
34 /* Firmware key-version is in the top 16 bits of fw_ver */
35 FWVER_KEY_SHIFT = 16,
36 FWVER_FW_MASK = 0xffff,
37
38 NVD_HDR_VER_CUR = 1, /* current version */
39};
40
41/**
42 * struct vbe_nvdata - basic storage format for non-volatile data
43 *
44 * This is used for all VBE methods
45 *
46 * @crc8: crc8 for the entire record except @crc8 field itself
47 * @hdr: header size and version (NVD_HDR_...)
48 * @spare1: unused, must be 0
49 * @fw_vernum: version and key version (FWVER_...)
50 * @flags: Flags controlling operation (enum vbe_flags)
51 */
52struct vbe_nvdata {
53 u8 crc8;
54 u8 hdr;
55 u16 spare1;
56 u32 fw_vernum;
57 u32 flags;
58 u8 spare2[0x34];
59};
60
Simon Glass15d320d2025-01-15 18:27:07 -070061/**
62 * vbe_get_blk() - Obtain the block device to use for VBE
63 *
64 * Decodes the string to produce a block device
65 *
66 * @storage: String indicating the device to use, e.g. "mmc1"
67 * @blkp: Returns associated block device, on success
68 * Return 0 if OK, -ENODEV if @storage does not end with a number, -E2BIG if
69 * the device name is more than 15 characters, -ENXIO if the block device could
70 * not be found
71 */
72int vbe_get_blk(const char *storage, struct udevice **blkp);
73
Simon Glass9846e5f2025-01-15 18:27:08 -070074/**
75 * vbe_read_version() - Read version-string from a block device
76 *
77 * Reads the VBE version-string from a device. This function reads a single
78 * block from the device, so the string cannot be larger than that. It uses a
79 * temporary buffer for the read, then copies in up to @size bytes
80 *
81 * @blk: Device to read from
82 * @offset: Offset to read, in bytes
83 * @version: Place to put the string
84 * @max_size: Maximum size of @version
85 * Return: 0 if OK, -E2BIG if @max_size > block size, -EBADF if the offset is
86 * not block-aligned, -EIO if an I/O error occurred
87 */
88int vbe_read_version(struct udevice *blk, ulong offset, char *version,
89 int max_size);
90
Simon Glass72424b82025-01-15 18:27:09 -070091/**
92 * vbe_read_nvdata() - Read non-volatile data from a block device
93 *
94 * Reads the VBE nvdata from a device. This function reads a single block from
95 * the device, so the nvdata cannot be larger than that.
96 *
97 * @blk: Device to read from
98 * @offset: Offset to read, in bytes
99 * @size: Number of bytes to read
100 * @buf: Buffer to hold the data
101 * Return: 0 if OK, -E2BIG if @size > block size, -EBADF if the offset is not
102 * block-aligned, -EIO if an I/O error occurred, -EPERM if the header version is
103 * incorrect, the header size is invalid or the data fails its CRC check
104 */
105int vbe_read_nvdata(struct udevice *blk, ulong offset, ulong size, u8 *buf);
106
Simon Glass988f16a2025-01-15 18:27:10 -0700107/**
108 * vbe_read_fit() - Read an image from a FIT
109 *
110 * This handles most of the VBE logic for reading from a FIT. It reads the FIT
111 * metadata, decides which image to load and loads it to a suitable address,
112 * ready for jumping to the next phase of VBE.
113 *
114 * This supports transition from VPL to SPL as well as SPL to U-Boot proper. For
115 * now, TPL->VPL is not supported.
116 *
117 * Both embedded and external data are supported for the FIT
118 *
119 * @blk: Block device containing FIT
120 * @area_offset: Byte offset of the VBE area in @blk containing the FIT
121 * @area_size: Size of the VBE area
Simon Glassedd22362025-01-15 18:27:22 -0700122 * @image: SPL image to fill in with details of the loaded image, or NULL
Simon Glass988f16a2025-01-15 18:27:10 -0700123 * @load_addrp: If non-null, returns the address where the image was loaded
124 * @lenp: If non-null, returns the size of the image loaded, in bytes
125 * @namep: If non-null, returns the name of the FIT-image node that was loaded
126 * (allocated by this function)
127 * Return: 0 if OK, -EINVAL if the area does not contain an FDT (the underlying
128 * format for FIT), -E2BIG if the FIT extends past @area_size, -ENOMEM if there
129 * was not space to allocate the image-node name, other error if a read error
130 * occurred (see blk_read()), or something went wrong with the actually
131 * FIT-parsing (see fit_image_load()).
132 */
133int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
Simon Glassedd22362025-01-15 18:27:22 -0700134 struct spl_image_info *image, ulong *load_addrp, ulong *lenp,
135 char **namep);
Simon Glass988f16a2025-01-15 18:27:10 -0700136
Simon Glassfdacd502025-01-15 18:27:03 -0700137#endif /* __VBE_ABREC_H */