summaryrefslogtreecommitdiff
path: root/src/include/smmstore.h
diff options
context:
space:
mode:
authorPatrick Rudolph <patrick.rudolph@9elements.com>2020-04-17 16:16:49 +0200
committerMichał Żygowski <michal.zygowski@3mdeb.com>2020-10-22 12:29:47 +0000
commitbc744f5893fc4d53275ed26dd8d968011c6a09c1 (patch)
treefb283c9d57431020405a5404db04b425428f7709 /src/include/smmstore.h
parenta693fa06cd32da8239f820d833bb7a1bf55bf351 (diff)
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time. Key features: * Uses a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Gives the caller full control over the used data format. * Splits the store into smaller chunks to allow fault tolerant updates. * Doesn't provide feedback about the actual read/written bytes, just returns error or success in registers. * Returns an error if the requested operation would overflow the communication buffer. Separate the SMMSTORE into 64 KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore. The implementation has been tested against EDK2 master. An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c736dbe2 Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Signed-off-by: Christian Walter <christian.walter@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/40520 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Michał Żygowski <michal.zygowski@3mdeb.com> Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Diffstat (limited to 'src/include/smmstore.h')
-rw-r--r--src/include/smmstore.h94
1 files changed, 90 insertions, 4 deletions
diff --git a/src/include/smmstore.h b/src/include/smmstore.h
index ff0b72001a..2c37ca39b9 100644
--- a/src/include/smmstore.h
+++ b/src/include/smmstore.h
@@ -10,10 +10,18 @@
#define SMMSTORE_RET_FAILURE 1
#define SMMSTORE_RET_UNSUPPORTED 2
+/* Version 1 */
#define SMMSTORE_CMD_CLEAR 1
#define SMMSTORE_CMD_READ 2
#define SMMSTORE_CMD_APPEND 3
+/* Version 2 */
+#define SMMSTORE_CMD_INIT 4
+#define SMMSTORE_CMD_RAW_READ 5
+#define SMMSTORE_CMD_RAW_WRITE 6
+#define SMMSTORE_CMD_RAW_CLEAR 7
+
+/* Version 1 */
struct smmstore_params_read {
void *buf;
ssize_t bufsize;
@@ -26,12 +34,90 @@ struct smmstore_params_append {
size_t valsize;
};
-/* SMM responder */
+/* Version 2 */
+/*
+ * The Version 2 protocol separates the SMMSTORE into 64KiB blocks, each
+ * of which can be read/written/cleared in an independent manner. The
+ * data format isn't specified. See documentation page for more details.
+ */
+
+#define SMM_BLOCK_SIZE (64 * KiB)
+
+/*
+ * Sets the communication buffer to use for read and write operations.
+ */
+struct smmstore_params_init {
+ uint32_t com_buffer;
+ uint32_t com_buffer_size;
+} __packed;
+
+/*
+ * Returns the number of blocks the SMMSTORE supports and their size.
+ * For EDK2 this should be at least two blocks with 64 KiB each.
+ * The mmap_addr is set the memory mapped physical address of the SMMSTORE.
+ */
+struct smmstore_params_info {
+ uint32_t num_blocks;
+ uint32_t block_size;
+ uint32_t mmap_addr;
+} __packed;
+
+/*
+ * Reads a chunk of raw data with size @bufsize from the block specified by
+ * @block_id starting at @bufoffset.
+ * The read data is placed in memory pointed to by @buf.
+ *
+ * @block_id must be less than num_blocks
+ * @bufoffset + @bufsize must be less than block_size
+ */
+struct smmstore_params_raw_write {
+ uint32_t bufsize;
+ uint32_t bufoffset;
+ uint32_t block_id;
+} __packed;
+
+/*
+ * Writes a chunk of raw data with size @bufsize to the block specified by
+ * @block_id starting at @bufoffset.
+ *
+ * @block_id must be less than num_blocks
+ * @bufoffset + @bufsize must be less than block_size
+ */
+struct smmstore_params_raw_read {
+ uint32_t bufsize;
+ uint32_t bufoffset;
+ uint32_t block_id;
+} __packed;
+
+/*
+ * Erases the specified block.
+ *
+ * @block_id must be less than num_blocks
+ */
+struct smmstore_params_raw_clear {
+ uint32_t block_id;
+} __packed;
+
+
+/* SMM handler */
uint32_t smmstore_exec(uint8_t command, void *param);
-/* implementation */
+/* Implementation of Version 1 */
int smmstore_read_region(void *buf, ssize_t *bufsize);
-int smmstore_append_data(void *key, uint32_t key_sz,
- void *value, uint32_t value_sz);
+int smmstore_append_data(void *key, uint32_t key_sz, void *value, uint32_t value_sz);
int smmstore_clear_region(void);
+
+/* Implementation of Version 2 */
+int smmstore_init(void *buf, size_t len);
+int smmstore_rawread_region(uint32_t block_id, uint32_t offset, uint32_t bufsize);
+int smmstore_rawwrite_region(uint32_t block_id, uint32_t offset, uint32_t bufsize);
+int smmstore_rawclear_region(uint32_t block_id);
+#if ENV_RAMSTAGE
+int smmstore_get_info(struct smmstore_params_info *info);
+#endif
+
+/* Advertise SMMSTORE v2 support */
+struct lb_header;
+void lb_smmstorev2(struct lb_header *header);
+
#endif