blob: 2f0197dae1fed80e3e2606c00ebdbeca3475b10f [file] [log] [blame]
Julian Hall65f7eb42021-11-22 16:06:42 +01001/*
2 * Copyright (c) 2021, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#ifndef VARIABLE_INDEX_H
9#define VARIABLE_INDEX_H
10
11#include <stdbool.h>
12#include <stddef.h>
13#include <stdint.h>
14#include <protocols/common/efi/efi_status.h>
15#include <protocols/service/smm_variable/smm_variable_proto.h>
Julian Hall0a86f762021-11-08 13:31:23 +000016#include "variable_checker.h"
Julian Hall65f7eb42021-11-22 16:06:42 +010017
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22/**
23 * Implementation limits
24 */
25#define VARIABLE_INDEX_MAX_NAME_SIZE (32)
26
27/**
Julian Hall0a86f762021-11-08 13:31:23 +000028 * \brief variable_metadata structure definition
Julian Hall65f7eb42021-11-22 16:06:42 +010029 *
Julian Hall0a86f762021-11-08 13:31:23 +000030 * Holds metadata associated with stored variable.
Julian Hall65f7eb42021-11-22 16:06:42 +010031 */
Julian Hall0a86f762021-11-08 13:31:23 +000032struct variable_metadata
Julian Hall65f7eb42021-11-22 16:06:42 +010033{
34 EFI_GUID guid;
35 size_t name_size;
36 int16_t name[VARIABLE_INDEX_MAX_NAME_SIZE];
37 uint32_t attributes;
38 uint64_t uid;
39};
40
41/**
Julian Hall0a86f762021-11-08 13:31:23 +000042 * \brief variable_info structure definition
43 *
44 * Holds information about a stored variable.
45 */
46struct variable_info
47{
48 struct variable_metadata metadata;
49 struct variable_constraints check_constraints;
50
51 bool is_variable_set;
52 bool is_constraints_set;
53};
54
55/**
Julian Hall65f7eb42021-11-22 16:06:42 +010056 * \brief An entry in the index
57 *
58 * Represents a store variable in the variable index.
59 */
60struct variable_entry
61{
62 struct variable_info info;
63
64 bool in_use;
65 bool dirty;
66};
67
68/**
69 * \brief variable_index structure definition
70 *
71 * Provides an index of stored variables to allow the uefi variable store
72 * contents to be enumerated.
73 */
74struct variable_index
75{
76 size_t max_variables;
77 struct variable_entry *entries;
78};
79
80/**
81 * @brief Initialises a variable_index
82 *
83 * @param[in] context variable_index
84 * @param[in] max_variables The maximum number of stored variables
85 *
86 * @return EFI_SUCCESS if initialized successfully
87 */
88efi_status_t variable_index_init(
89 struct variable_index *context,
90 size_t max_variables);
91
92/**
93 * @brief De-initialises a variable_index
94 *
95 * @param[in] context variable_index
96 */
97void variable_index_deinit(
98 struct variable_index *context);
99
100/**
101 * @brief Returns the maximum dump size
102 *
103 * For a given maximum index size, returns the size of the
104 * buffer that is needed to hold all serialized variable_info
105 * objects.
106 *
107 * @param[in] context variable_index
108 */
109size_t variable_index_max_dump_size(
110 struct variable_index *context);
111
112/**
113 * @brief Find info about a variable
114 *
115 * @param[in] context variable_index
116 * @param[in] guid The variable's guid
117 * @param[in] name_size The name parameter's size
118 * @param[in] name The variable's name
119 *
120 * @return Pointer to variable_info or NULL
121 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000122struct variable_info *variable_index_find(
123 struct variable_index *context,
Julian Hall65f7eb42021-11-22 16:06:42 +0100124 const EFI_GUID *guid,
125 size_t name_size,
126 const int16_t *name);
127
128/**
129 * @brief Find the next variable in the index
130 *
131 * @param[in] context variable_index
132 * @param[in] guid The variable's guid
133 * @param[in] name_size The name parameter's size
134 * @param[in] name The variable's name
Julian Halld8242e62022-01-06 09:44:15 +0000135 * @param[out] status Provides error status
Julian Hall65f7eb42021-11-22 16:06:42 +0100136 *
137 * @return Pointer to variable_info or NULL
138 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000139struct variable_info *variable_index_find_next(
Julian Hall65f7eb42021-11-22 16:06:42 +0100140 const struct variable_index *context,
141 const EFI_GUID *guid,
142 size_t name_size,
Julian Halld8242e62022-01-06 09:44:15 +0000143 const int16_t *name,
144 efi_status_t *status);
Julian Hall65f7eb42021-11-22 16:06:42 +0100145
146/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000147 * @brief Add a new entry to the index
148 *
149 * An entry is needed either when a new variable is created or
150 * when variable constraints are set for a variable that doesn't
151 * yet exist.
Julian Hall65f7eb42021-11-22 16:06:42 +0100152 *
153 * @param[in] context variable_index
154 * @param[in] guid The variable's guid
155 * @param[in] name_size The name parameter's size
156 * @param[in] name The variable's name
Julian Hall65f7eb42021-11-22 16:06:42 +0100157 *
158 * @return Pointer to variable_info or NULL
159 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000160struct variable_info *variable_index_add_entry(
Julian Hall65f7eb42021-11-22 16:06:42 +0100161 struct variable_index *context,
162 const EFI_GUID *guid,
163 size_t name_size,
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000164 const int16_t *name);
Julian Hall65f7eb42021-11-22 16:06:42 +0100165
166/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000167 * @brief Remove an unused entry from the index
Julian Hall65f7eb42021-11-22 16:06:42 +0100168 *
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000169 * Removes an entry if it is not in use.
Julian Hall65f7eb42021-11-22 16:06:42 +0100170 *
171 * @param[in] context variable_index
Julian Hallc0d54dc2021-10-13 15:18:30 +0100172 * @param[in] info The variable info corresponding to the entry to remove
Julian Hall65f7eb42021-11-22 16:06:42 +0100173 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000174void variable_index_remove_unused_entry(
Julian Hall65f7eb42021-11-22 16:06:42 +0100175 struct variable_index *context,
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000176 struct variable_info *info);
Julian Hall65f7eb42021-11-22 16:06:42 +0100177
178/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000179 * @brief Set a variable to the index
180 *
181 * An entry for the variable must already exist.
Julian Hall65f7eb42021-11-22 16:06:42 +0100182 *
Julian Hall65f7eb42021-11-22 16:06:42 +0100183 * @param[in] info variable info
184 * @param[in] attributes The variable's attributes
185 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000186void variable_index_set_variable(
187 struct variable_info *info,
Julian Hall65f7eb42021-11-22 16:06:42 +0100188 uint32_t attributes);
189
190/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000191 * @brief Clear a variable from the index
192 *
193 * Clears a variable from the index
Julian Hall0a86f762021-11-08 13:31:23 +0000194 *
195 * @param[in] context variable_index
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000196 * @param[in] info The variable info corresponding to the variable to clear
Julian Hall0a86f762021-11-08 13:31:23 +0000197 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000198void variable_index_clear_variable(
Julian Hall0a86f762021-11-08 13:31:23 +0000199 struct variable_index *context,
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000200 struct variable_info *info);
Julian Hall0a86f762021-11-08 13:31:23 +0000201
202/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000203 * @brief Set a check constraints object associated with a variavle
Julian Hall0a86f762021-11-08 13:31:23 +0000204 *
205 * @param[in] info variable info
206 * @param[in] constraints The check constraints
207 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000208void variable_index_set_constraints(
209 struct variable_info *info,
Julian Hall0a86f762021-11-08 13:31:23 +0000210 const struct variable_constraints *constraints);
211
212/**
Julian Hall65f7eb42021-11-22 16:06:42 +0100213 * @brief Dump the serialized index contents for persistent backup
214 *
215 * @param[in] context variable_index
216 * @param[in] buffer_size Size of destination buffer
217 * @param[in] buffer Dump to this buffer
218 * @param[out] data_len Length of serialized data
219 *
220 * @return True if there is unsaved data
221 */
222bool variable_index_dump(
223 struct variable_index *context,
224 size_t buffer_size,
225 uint8_t *buffer,
226 size_t *data_len);
227
228/**
229 * @brief Restore the serialized index contents
230 *
231 * Should be called straight after the variable index is initialized to
232 * restore any NV variable info from persistent storage.
233 *
234 * @param[in] context variable_index
235 * @param[in] data_len The length of the data to load
236 * @param[in] buffer Load from this buffer
237 *
238 * @return Number of bytes loaded
239 */
240size_t variable_index_restore(
241 const struct variable_index *context,
242 size_t data_len,
243 const uint8_t *buffer);
244
245
246#ifdef __cplusplus
247}
248#endif
249
250#endif /* VARIABLE_INDEX_H */