summaryrefslogtreecommitdiff
path: root/include/nvmem_vars.h
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-11-28 11:38:20 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-12-21 19:42:37 -0800
commit971e758ddec1b04b4a5479d716ec5a53ea48950f (patch)
tree489332a65ce2c781efb1692c53e81cb6fe994a20 /include/nvmem_vars.h
parent0a97a6cf4bbc052e715080a9634078396645b733 (diff)
downloadchrome-ec-971e758ddec1b04b4a5479d716ec5a53ea48950f.tar.gz
Add nvmem-backed key=value variable storage
The CONFIG_FLASH_NVMEM option implements persistent, reliable storage regions in flash. This adds CONFIG_FLASH_NVMEM_VARS, which uses one of those storage regions for free-form variables. Refer to the comments in include/nvmem_vars.h and common/nvmem_vars.c for usage and implementation details. BUG=chrome-os-partner:61107 BRANCH=none TEST=make runtests This CL includes a number of new tests, specifically for this feature. No target boards use this feature yet so there's nothing to test on actual hardware, but the test/nvmem_vars executable includes console commands ("get", "set", "print") to try it out. Change-Id: I8597415dc3b00a1462f5b164eeb5073129030525 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/414194 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'include/nvmem_vars.h')
-rw-r--r--include/nvmem_vars.h87
1 files changed, 87 insertions, 0 deletions
diff --git a/include/nvmem_vars.h b/include/nvmem_vars.h
new file mode 100644
index 0000000000..867ea32018
--- /dev/null
+++ b/include/nvmem_vars.h
@@ -0,0 +1,87 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __EC_INCLUDE_NVMEM_VARS_H
+#define __EC_INCLUDE_NVMEM_VARS_H
+
+/*
+ * CONFIG_FLASH_NVMEM provides persistent, atomic-update storage in
+ * flash. The storage is logically divided into one or more "user regions", as
+ * configured in board.h and board.c
+ *
+ * CONFIG_FLASH_NVMEM_VARS stores a set of <KEY, VALUE> tuples in the nvmem
+ * user region designated by CONFIG_FLASH_NVMEM_VARS_USER_NUM (in board.h)
+ *
+ * Tuples are stored and managed using this struct:
+ */
+
+struct tuple {
+ uint8_t key_len; /* 1 - 255 */
+ uint8_t val_len; /* 1 - 255 */
+ uint8_t flags; /* RESERVED, will be zeroed */
+ uint8_t data_[0]; /* Opaque. Don't look here. */
+};
+
+/*
+ * Both KEY and VALUE can be any binary blob between 1 and 255 bytes (flash
+ * memory is limited, so if you need longer values just use two keys and
+ * concatenate the blobs). Zero-length KEYs or VALUEs are not allowed.
+ * Assigning a zero-length VALUE to a KEY just deletes that tuple (if it
+ * existed).
+ *
+ * The expected usage is:
+ *
+ * 1. At boot, call initvars() to ensure that the variable storage region is
+ * valid. If it isn't, this will initialize it to an empty set.
+ *
+ * 2. Call getenv() or setenv() as needed. The first call to either will copy
+ * the storage regsion from flash into a RAM buffer. Any changes made with
+ * setenv() will affect only that RAM buffer.
+ *
+ * 3. Call writevars() to commit the RAM buffer to flash and free it.
+ *
+ * CAUTION: The underlying CONFIG_FLASH_NVMEM implementation allows access by
+ * multiple tasks, provided each task access only one user region. There is no
+ * support for simultaneous access to the *same* user region by multiple tasks.
+ * CONFIG_FLASH_NVMEM_VARS stores all variables in one user region, so if
+ * variable access by multiple tasks is required, the tasks should establish
+ * their own locks or mutexes to fit their usage. In general that would mean
+ * aquiring a lock before calling getvar() or setvar(), and releasing it after
+ * calling writevars().
+ */
+
+/*
+ * Initialize the persistent storage. This checks the user region to ensure
+ * that all tuples are valid and that there is one additional '\0' at the end.
+ * If any discrepancies are found, it erases all values. This should return
+ * EC_SUCCESS unless there is a problem writing to flash.
+ */
+int initvars(void);
+
+/*
+ * Look up a key, return a pointer to the tuple. If the key is not found,
+ * return NULL. WARNING: The returned pointer is only valid until the next call
+ * to setvar() or writevars(). Use it or lose it.
+ */
+const struct tuple *getvar(const uint8_t *key, uint8_t key_len);
+
+/* Use these to access the data components of a valid struct tuple pointer */
+const uint8_t *tuple_key(const struct tuple *);
+const uint8_t *tuple_val(const struct tuple *);
+
+/*
+ * Save the tuple in the RAM buffer. If val is NULL or val_len is 0, the
+ * tuple is deleted (if it existed). Returns EC_SUCCESS or error code.
+ */
+int setvar(const uint8_t *key, uint8_t key_len,
+ const uint8_t *val, uint8_t val_len);
+
+/*
+ * Commit any changes made with setvar() to persistent memory, and invalidate
+ * the RAM buffer. Return EC_SUCCESS or error code on failure.
+ */
+int writevars(void);
+
+#endif /* __EC_INCLUDE_NVMEM_VARS_H */