blob: 63f42ab60191e77cf29881312374b958ec9f0fa0 [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
135 *
136 * @return Pointer to variable_info or NULL
137 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000138struct variable_info *variable_index_find_next(
Julian Hall65f7eb42021-11-22 16:06:42 +0100139 const struct variable_index *context,
140 const EFI_GUID *guid,
141 size_t name_size,
142 const int16_t *name);
143
144/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000145 * @brief Add a new entry to the index
146 *
147 * An entry is needed either when a new variable is created or
148 * when variable constraints are set for a variable that doesn't
149 * yet exist.
Julian Hall65f7eb42021-11-22 16:06:42 +0100150 *
151 * @param[in] context variable_index
152 * @param[in] guid The variable's guid
153 * @param[in] name_size The name parameter's size
154 * @param[in] name The variable's name
Julian Hall65f7eb42021-11-22 16:06:42 +0100155 *
156 * @return Pointer to variable_info or NULL
157 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000158struct variable_info *variable_index_add_entry(
Julian Hall65f7eb42021-11-22 16:06:42 +0100159 struct variable_index *context,
160 const EFI_GUID *guid,
161 size_t name_size,
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000162 const int16_t *name);
Julian Hall65f7eb42021-11-22 16:06:42 +0100163
164/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000165 * @brief Remove an unused entry from the index
Julian Hall65f7eb42021-11-22 16:06:42 +0100166 *
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000167 * Removes an entry if it is not in use.
Julian Hall65f7eb42021-11-22 16:06:42 +0100168 *
169 * @param[in] context variable_index
Julian Hallc0d54dc2021-10-13 15:18:30 +0100170 * @param[in] info The variable info corresponding to the entry to remove
Julian Hall65f7eb42021-11-22 16:06:42 +0100171 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000172void variable_index_remove_unused_entry(
Julian Hall65f7eb42021-11-22 16:06:42 +0100173 struct variable_index *context,
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000174 struct variable_info *info);
Julian Hall65f7eb42021-11-22 16:06:42 +0100175
176/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000177 * @brief Set a variable to the index
178 *
179 * An entry for the variable must already exist.
Julian Hall65f7eb42021-11-22 16:06:42 +0100180 *
Julian Hall65f7eb42021-11-22 16:06:42 +0100181 * @param[in] info variable info
182 * @param[in] attributes The variable's attributes
183 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000184void variable_index_set_variable(
185 struct variable_info *info,
Julian Hall65f7eb42021-11-22 16:06:42 +0100186 uint32_t attributes);
187
188/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000189 * @brief Clear a variable from the index
190 *
191 * Clears a variable from the index
Julian Hall0a86f762021-11-08 13:31:23 +0000192 *
193 * @param[in] context variable_index
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000194 * @param[in] info The variable info corresponding to the variable to clear
Julian Hall0a86f762021-11-08 13:31:23 +0000195 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000196void variable_index_clear_variable(
Julian Hall0a86f762021-11-08 13:31:23 +0000197 struct variable_index *context,
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000198 struct variable_info *info);
Julian Hall0a86f762021-11-08 13:31:23 +0000199
200/**
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000201 * @brief Set a check constraints object associated with a variavle
Julian Hall0a86f762021-11-08 13:31:23 +0000202 *
203 * @param[in] info variable info
204 * @param[in] constraints The check constraints
205 */
Julian Hall4b8dd0a2021-12-02 10:15:54 +0000206void variable_index_set_constraints(
207 struct variable_info *info,
Julian Hall0a86f762021-11-08 13:31:23 +0000208 const struct variable_constraints *constraints);
209
210/**
Julian Hall65f7eb42021-11-22 16:06:42 +0100211 * @brief Dump the serialized index contents for persistent backup
212 *
213 * @param[in] context variable_index
214 * @param[in] buffer_size Size of destination buffer
215 * @param[in] buffer Dump to this buffer
216 * @param[out] data_len Length of serialized data
217 *
218 * @return True if there is unsaved data
219 */
220bool variable_index_dump(
221 struct variable_index *context,
222 size_t buffer_size,
223 uint8_t *buffer,
224 size_t *data_len);
225
226/**
227 * @brief Restore the serialized index contents
228 *
229 * Should be called straight after the variable index is initialized to
230 * restore any NV variable info from persistent storage.
231 *
232 * @param[in] context variable_index
233 * @param[in] data_len The length of the data to load
234 * @param[in] buffer Load from this buffer
235 *
236 * @return Number of bytes loaded
237 */
238size_t variable_index_restore(
239 const struct variable_index *context,
240 size_t data_len,
241 const uint8_t *buffer);
242
243
244#ifdef __cplusplus
245}
246#endif
247
248#endif /* VARIABLE_INDEX_H */