coreboot-libre-fam15h-rdimm/3rdparty/chromeec/common/nvmem_vars.c

172 lines
4.6 KiB
C
Raw Normal View History

2024-03-04 11:14:53 +01:00
/*
* 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.
*/
#include "common.h"
#include "console.h"
#include "nvmem.h"
#include "new_nvmem.h"
#include "printf.h"
#include "shared_mem.h"
#include "util.h"
/****************************************************************************/
/* Pointer to the RAM copy of the persistent variable store */
test_mockable_static uint8_t *rbuf;
int set_local_copy(void)
{
if (rbuf)
return EC_ERROR_UNKNOWN;
rbuf = nvmem_cache_base(NVMEM_CR50);
return EC_SUCCESS;
}
/****************************************************************************/
/* Implementation notes
*
* The data_ member of struct tuple is simply the key and val blobs
* concatenated together.
*
* We store the variable entries in flash (and RAM) using the struct tuple
* defined in nvmem_vars.h. The entries are written sequentially with no
* padding, starting at offset 0 of the CONFIG_FLASH_NVMEM_VARS_USER_NUM user
* region. A single uint8_t zero byte will ALWAYS follow the valid entries.
* Since valid entries have nonzero key_len, we can always detect the presence
* of valid entries.
*
* A valid entry has both key_len and val_len between 1 and 255. The following
* bytes represent these tuples: <"A","ab">, <"B","cde">:
*
* Offset Content Meaning
* 0 0x01 length of key
* 1 0x02 length of val
* 2 0x00 variable flags (unused at present)
* 3 0x41 'A' (key)
* 4 0x61 'a' (val byte 1)
* 5 0x62 'b' (val byte 2)
* 6 0x01 length of key
* 7 0x03 length of val
* 8 0x00 variable flags (unused at present)
* 9 0x42 'B' (key)
* 10 0x63 'c' (val byte 1)
* 11 0x64 'd' (val byte 2)
* 12 0x65 'e' (val byte 3)
* 13 0x00 End of variables
*
* Note that the keys and values are not null-terminated since they're not
* strings, just binary blobs. The length of each entry is the size of the
* struct tuple header, plus the length of its key and value blobs.
*
* The .flags field is not currently used (and so is set to zero). It could be
* used in the future to for per-variable attributes, such as read-only,
* clear-on-reset, extended-length value, etc.
*/
/****************************************************************************/
/* API functions */
const struct tuple *legacy_getnextvar(const struct tuple *prev_var)
{
const struct tuple *var;
uintptr_t idx;
if (!prev_var) {
/*
* The caller is just starting, let's get the first var, if
* any.
*/
if (!rbuf[0])
return NULL;
return (const struct tuple *)rbuf;
}
/* Let's try to get the next one. */
idx = (uintptr_t)prev_var;
idx += prev_var->key_len + prev_var->val_len + sizeof(struct tuple);
var = (const struct tuple *)idx;
if (var->key_len)
return var;
return NULL;
}
const uint8_t *tuple_key(const struct tuple *t) { return t->data_; }
const uint8_t *tuple_val(const struct tuple *t)
{
return t->data_ + t->key_len;
}
/****************************************************************************/
#if defined(TEST_BUILD) && !defined(TEST_FUZZ)
#include "console.h"
static void print_blob(const uint8_t *blob, int blob_len)
{
int i;
for (i = 0; i < blob_len; i++)
ccprintf("%c", isprint(blob[i]) ? blob[i] : '.');
}
static int command_get(int argc, char **argv)
{
const struct tuple *tuple;
if (argc != 2)
return EC_ERROR_PARAM_COUNT;
tuple = getvar(argv[1], strlen(argv[1]));
if (!tuple)
return EC_SUCCESS;
print_blob(tuple_val(tuple), tuple->val_len);
ccprintf("\n");
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(get, command_get,
"VARIABLE",
"Show the value of the specified variable");
static int command_set(int argc, char **argv)
{
int rc;
if (argc != 2 && argc != 3)
return EC_ERROR_PARAM_COUNT;
if (argc == 2)
rc = setvar(argv[1], strlen(argv[1]), 0, 0);
else
rc = setvar(argv[1], strlen(argv[1]), argv[2], strlen(argv[2]));
return rc;
}
DECLARE_CONSOLE_COMMAND(set, command_set, "VARIABLE [VALUE]",
"Set/clear the value of the specified variable");
static int command_print(int argc, char **argv)
{
ccprintf("Print all vars is not yet implemented\n");
return EC_ERROR_INVAL;
}
DECLARE_CONSOLE_COMMAND(print, command_print, "",
"Print all defined variables");
static int command_clear_nvmem_vars(int argc, char **argv)
{
ccprintf("Nvmem clear vars has not yet been implemented\n");
return EC_ERROR_INVAL;
}
DECLARE_CONSOLE_COMMAND(clr_nvmem_vars, command_clear_nvmem_vars, "",
"Clear the NvMem variables.");
#endif