Add basic uefi_variable_store implementation
Adds an implementation of the uefi_variable_store that forms
the backend for the smm_variable service provider. Orphan
variable index clean-up is not yet implemented.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I0924475a8819f488703065900d8efd01b48d42cf
diff --git a/components/service/smm_variable/backend/variable_index.h b/components/service/smm_variable/backend/variable_index.h
new file mode 100644
index 0000000..85064a7
--- /dev/null
+++ b/components/service/smm_variable/backend/variable_index.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef VARIABLE_INDEX_H
+#define VARIABLE_INDEX_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <protocols/common/efi/efi_status.h>
+#include <protocols/service/smm_variable/smm_variable_proto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Implementation limits
+ */
+#define VARIABLE_INDEX_MAX_NAME_SIZE (32)
+
+/**
+ * \brief variable_info structure definition
+ *
+ * Holds information about a stored variable.
+ */
+struct variable_info
+{
+ EFI_GUID guid;
+ size_t name_size;
+ int16_t name[VARIABLE_INDEX_MAX_NAME_SIZE];
+ uint32_t attributes;
+ uint64_t uid;
+};
+
+/**
+ * \brief An entry in the index
+ *
+ * Represents a store variable in the variable index.
+ */
+struct variable_entry
+{
+ struct variable_info info;
+
+ bool in_use;
+ bool dirty;
+};
+
+/**
+ * \brief variable_index structure definition
+ *
+ * Provides an index of stored variables to allow the uefi variable store
+ * contents to be enumerated.
+ */
+struct variable_index
+{
+ size_t max_variables;
+ struct variable_entry *entries;
+};
+
+/**
+ * @brief Initialises a variable_index
+ *
+ * @param[in] context variable_index
+ * @param[in] max_variables The maximum number of stored variables
+ *
+ * @return EFI_SUCCESS if initialized successfully
+ */
+efi_status_t variable_index_init(
+ struct variable_index *context,
+ size_t max_variables);
+
+/**
+ * @brief De-initialises a variable_index
+ *
+ * @param[in] context variable_index
+ */
+void variable_index_deinit(
+ struct variable_index *context);
+
+/**
+ * @brief Returns the maximum dump size
+ *
+ * For a given maximum index size, returns the size of the
+ * buffer that is needed to hold all serialized variable_info
+ * objects.
+ *
+ * @param[in] context variable_index
+ */
+size_t variable_index_max_dump_size(
+ struct variable_index *context);
+
+/**
+ * @brief Find info about a variable
+ *
+ * @param[in] context variable_index
+ * @param[in] guid The variable's guid
+ * @param[in] name_size The name parameter's size
+ * @param[in] name The variable's name
+ *
+ * @return Pointer to variable_info or NULL
+ */
+const struct variable_info *variable_index_find(
+ const struct variable_index *context,
+ const EFI_GUID *guid,
+ size_t name_size,
+ const int16_t *name);
+
+/**
+ * @brief Find the next variable in the index
+ *
+ * @param[in] context variable_index
+ * @param[in] guid The variable's guid
+ * @param[in] name_size The name parameter's size
+ * @param[in] name The variable's name
+ *
+ * @return Pointer to variable_info or NULL
+ */
+const struct variable_info *variable_index_find_next(
+ const struct variable_index *context,
+ const EFI_GUID *guid,
+ size_t name_size,
+ const int16_t *name);
+
+/**
+ * @brief Add a new variable to the index
+ *
+ * @param[in] context variable_index
+ * @param[in] guid The variable's guid
+ * @param[in] name_size The name parameter's size
+ * @param[in] name The variable's name
+ * @param[in] attributes The variable's attributes
+ *
+ * @return Pointer to variable_info or NULL
+ */
+const struct variable_info *variable_index_add(
+ struct variable_index *context,
+ const EFI_GUID *guid,
+ size_t name_size,
+ const int16_t *name,
+ uint32_t attributes);
+
+/**
+ * @brief Remove a variable from the index
+ *
+ * Removes a variable from the index if it exists.
+ *
+ * @param[in] context variable_index
+ * @param[in] guid The variable's guid
+ * @param[in] name_size The name parameter's size
+ * @param[in] name The variable's name
+ */
+void variable_index_remove(
+ struct variable_index *context,
+ const EFI_GUID *guid,
+ size_t name_size,
+ const int16_t *name);
+
+/**
+ * @brief Update variable attributes
+ *
+ * @param[in] context variable_index
+ * @param[in] info variable info
+ * @param[in] attributes The variable's attributes
+ */
+void variable_index_update_attributes(
+ struct variable_index *context,
+ const struct variable_info *info,
+ uint32_t attributes);
+
+/**
+ * @brief Dump the serialized index contents for persistent backup
+ *
+ * @param[in] context variable_index
+ * @param[in] buffer_size Size of destination buffer
+ * @param[in] buffer Dump to this buffer
+ * @param[out] data_len Length of serialized data
+ *
+ * @return True if there is unsaved data
+ */
+bool variable_index_dump(
+ struct variable_index *context,
+ size_t buffer_size,
+ uint8_t *buffer,
+ size_t *data_len);
+
+/**
+ * @brief Restore the serialized index contents
+ *
+ * Should be called straight after the variable index is initialized to
+ * restore any NV variable info from persistent storage.
+ *
+ * @param[in] context variable_index
+ * @param[in] data_len The length of the data to load
+ * @param[in] buffer Load from this buffer
+ *
+ * @return Number of bytes loaded
+ */
+size_t variable_index_restore(
+ const struct variable_index *context,
+ size_t data_len,
+ const uint8_t *buffer);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VARIABLE_INDEX_H */