|
|
|
#include <vxWorks.h>
|
|
|
|
#include <vsbConfig.h>
|
|
|
|
#include <semLib.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "ubootenv/crc32.c"
|
|
|
|
#include "ubootenv/uboot_env.c"
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
IMPORT int lfsLowRawWrite(unsigned long offset, const char *buffer, int size);
|
|
|
|
|
|
|
|
static int env_read(unsigned int offset, void *buf, size_t len)
|
|
|
|
{
|
|
|
|
memcpy(buf, (void *)(offset), len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int env_write(unsigned int offset, const void *buf, size_t size)
|
|
|
|
{
|
|
|
|
lfsLowRawWrite(offset, buf, size);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clang-format off */
|
|
|
|
static struct uboot_env_device __bsp_uenv = {
|
|
|
|
"qspiflash",
|
|
|
|
QSPI_ENV_OFFSET,
|
|
|
|
0x10000,
|
|
|
|
0x1000,
|
|
|
|
0x10,
|
|
|
|
env_read,
|
|
|
|
env_write,
|
|
|
|
};
|
|
|
|
/* clang-format on */
|
|
|
|
static struct uboot_ctx *__ctx = NULL;
|
|
|
|
static SEM_ID __ctx_lock = NULL;
|
|
|
|
|
|
|
|
int uenvInit()
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (__ctx == NULL) {
|
|
|
|
if (!__ctx_lock) {
|
|
|
|
__ctx_lock = semBCreate(SEM_Q_FIFO, SEM_FULL);
|
|
|
|
}
|
|
|
|
semTake(__ctx_lock, WAIT_FOREVER);
|
|
|
|
if (__ctx == NULL) {
|
|
|
|
err = libuboot_initialize(&__ctx, &__bsp_uenv, 1);
|
|
|
|
if (err) {
|
|
|
|
semGive(__ctx_lock);
|
|
|
|
goto skip;
|
|
|
|
}
|
|
|
|
if (libuboot_open(__ctx)) {
|
|
|
|
libuboot_exit(__ctx);
|
|
|
|
err = -101;
|
|
|
|
__ctx = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
semGive(__ctx_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
skip:
|
|
|
|
return (err);
|
|
|
|
}
|
|
|
|
|
|
|
|
int uenvget(const char *varname, char *buf, size_t len)
|
|
|
|
{
|
|
|
|
const char *val = NULL;
|
|
|
|
int r = -1;
|
|
|
|
|
|
|
|
if (__ctx) {
|
|
|
|
semTake(__ctx_lock, WAIT_FOREVER);
|
|
|
|
val = libuboot_get_env(__ctx, varname);
|
|
|
|
if (val) {
|
|
|
|
strncpy(buf, val, len);
|
|
|
|
r = 0;
|
|
|
|
}
|
|
|
|
semGive(__ctx_lock);
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int uenvGetUint(const char *varname)
|
|
|
|
{
|
|
|
|
char value[64] = {0};
|
|
|
|
if (uenvget(varname, value, sizeof value) == 0) {
|
|
|
|
return strtoul(value, NULL, 16);
|
|
|
|
}
|
|
|
|
return (unsigned int)(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int setenv(const char *varname, const char *value)
|
|
|
|
{
|
|
|
|
int err = -1;
|
|
|
|
|
|
|
|
if (__ctx) {
|
|
|
|
semTake(__ctx_lock, WAIT_FOREVER);
|
|
|
|
err = libuboot_set_env(__ctx, varname, value);
|
|
|
|
semGive(__ctx_lock);
|
|
|
|
}
|
|
|
|
return (err);
|
|
|
|
}
|
|
|
|
|
|
|
|
int saveenv()
|
|
|
|
{
|
|
|
|
int err = -1;
|
|
|
|
|
|
|
|
if (__ctx) {
|
|
|
|
semTake(__ctx_lock, WAIT_FOREVER);
|
|
|
|
err = libuboot_env_store(__ctx);
|
|
|
|
semGive(__ctx_lock);
|
|
|
|
}
|
|
|
|
return (err);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *envNext(void *next)
|
|
|
|
{
|
|
|
|
if (__ctx) {
|
|
|
|
return libuboot_iterator(__ctx, next);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *envGetName(void *entry)
|
|
|
|
{
|
|
|
|
return libuboot_getname(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *envGetValue(void *entry)
|
|
|
|
{
|
|
|
|
return libuboot_getvalue(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
int printenv(const char *name)
|
|
|
|
{
|
|
|
|
void *entry;
|
|
|
|
|
|
|
|
if (!__ctx) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
semTake(__ctx_lock, WAIT_FOREVER);
|
|
|
|
if (name) {
|
|
|
|
const char *val;
|
|
|
|
val = libuboot_get_env(__ctx, name);
|
|
|
|
if (val) {
|
|
|
|
printf("%s\r\n", val);
|
|
|
|
} else {
|
|
|
|
printf("%s: not found\r\n", name);
|
|
|
|
}
|
|
|
|
semGive(__ctx_lock);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
entry = envNext(NULL);
|
|
|
|
|
|
|
|
while (entry) {
|
|
|
|
printf("%18s: %s\n", envGetName(entry), envGetValue(entry));
|
|
|
|
entry = envNext(entry);
|
|
|
|
}
|
|
|
|
semGive(__ctx_lock);
|
|
|
|
return 0;
|
|
|
|
}
|