diff options
Diffstat (limited to 'env')
-rw-r--r-- | env/common.c | 180 | ||||
-rw-r--r-- | env/eeprom.c | 18 | ||||
-rw-r--r-- | env/env.c | 13 | ||||
-rw-r--r-- | env/nowhere.c | 5 | ||||
-rw-r--r-- | env/nvram.c | 14 |
5 files changed, 182 insertions, 48 deletions
diff --git a/env/common.c b/env/common.c index 81e9e0b2aaf..db213b77483 100644 --- a/env/common.c +++ b/env/common.c @@ -21,6 +21,8 @@ #include <malloc.h> #include <u-boot/crc.h> #include <dm/ofnode.h> +#include <net.h> +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; @@ -34,6 +36,184 @@ struct hsearch_data env_htab = { }; /* + * This env_set() function is defined in cmd/nvedit.c, since it calls + * _do_env_set(), whis is a static function in that file. + * + * int env_set(const char *varname, const char *varvalue); + */ + +/** + * Set an environment variable to an integer value + * + * @param varname Environment variable to set + * @param value Value to set it to + * @return 0 if ok, 1 on error + */ +int env_set_ulong(const char *varname, ulong value) +{ + /* TODO: this should be unsigned */ + char *str = simple_itoa(value); + + return env_set(varname, str); +} + +/** + * Set an environment variable to an value in hex + * + * @param varname Environment variable to set + * @param value Value to set it to + * @return 0 if ok, 1 on error + */ +int env_set_hex(const char *varname, ulong value) +{ + char str[17]; + + sprintf(str, "%lx", value); + return env_set(varname, str); +} + +ulong env_get_hex(const char *varname, ulong default_val) +{ + const char *s; + ulong value; + char *endp; + + s = env_get(varname); + if (s) + value = hextoul(s, &endp); + if (!s || endp == s) + return default_val; + + return value; +} + +int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr) +{ + string_to_enetaddr(env_get(name), enetaddr); + return is_valid_ethaddr(enetaddr); +} + +int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr) +{ + char buf[ARP_HLEN_ASCII + 1]; + + if (eth_env_get_enetaddr(name, (uint8_t *)buf)) + return -EEXIST; + + sprintf(buf, "%pM", enetaddr); + + return env_set(name, buf); +} + +/* + * Look up variable from environment, + * return address of storage for that variable, + * or NULL if not found + */ +char *env_get(const char *name) +{ + if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ + struct env_entry e, *ep; + + WATCHDOG_RESET(); + + e.key = name; + e.data = NULL; + hsearch_r(e, ENV_FIND, &ep, &env_htab, 0); + + return ep ? ep->data : NULL; + } + + /* restricted capabilities before import */ + if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0) + return (char *)(gd->env_buf); + + return NULL; +} + +/* + * Like env_get, but prints an error if envvar isn't defined in the + * environment. It always returns what env_get does, so it can be used in + * place of env_get without changing error handling otherwise. + */ +char *from_env(const char *envvar) +{ + char *ret; + + ret = env_get(envvar); + + if (!ret) + printf("missing environment variable: %s\n", envvar); + + return ret; +} + +/* + * Look up variable from environment for restricted C runtime env. + */ +int env_get_f(const char *name, char *buf, unsigned len) +{ + const char *env, *p, *end; + size_t name_len; + + if (name == NULL || *name == '\0') + return -1; + + name_len = strlen(name); + + if (gd->env_valid == ENV_INVALID) + env = (const char *)default_environment; + else + env = (const char *)gd->env_addr; + + for (p = env; *p != '\0'; p = end + 1) { + const char *value; + unsigned res; + + for (end = p; *end != '\0'; ++end) + if (end - env >= CONFIG_ENV_SIZE) + return -1; + + if (strncmp(name, p, name_len) || p[name_len] != '=') + continue; + value = &p[name_len + 1]; + + res = end - value; + memcpy(buf, value, min(len, res + 1)); + + if (len <= res) { + buf[len - 1] = '\0'; + printf("env_buf [%u bytes] too small for value of \"%s\"\n", + len, name); + } + + return res; + } + + return -1; +} + +/** + * Decode the integer value of an environment variable and return it. + * + * @param name Name of environment variable + * @param base Number base to use (normally 10, or 16 for hex) + * @param default_val Default value to return if the variable is not + * found + * @return the decoded value, or default_val if not found + */ +ulong env_get_ulong(const char *name, int base, ulong default_val) +{ + /* + * We can use env_get() here, even before relocation, since the + * environment variable value is an integer and thus short. + */ + const char *str = env_get(name); + + return str ? simple_strtoul(str, NULL, base) : default_val; +} + +/* * Read an environment variable as a boolean * Return -1 if variable does not exist (default to true) */ diff --git a/env/eeprom.c b/env/eeprom.c index 253bdf14284..f8556a47213 100644 --- a/env/eeprom.c +++ b/env/eeprom.c @@ -64,24 +64,6 @@ static int eeprom_bus_write(unsigned dev_addr, unsigned offset, return rcode; } -/** Call this function from overridden env_get_char_spec() if you need - * this functionality. - */ -int env_eeprom_get_char(int index) -{ - uchar c; - unsigned int off = CONFIG_ENV_OFFSET; - -#ifdef CONFIG_ENV_OFFSET_REDUND - if (gd->env_valid == ENV_REDUND) - off = CONFIG_ENV_OFFSET_REDUND; -#endif - eeprom_bus_read(CONFIG_SYS_I2C_EEPROM_ADDR, - off + index + offsetof(env_t, data), &c, 1); - - return c; -} - static int env_eeprom_load(void) { char buf_env[CONFIG_ENV_SIZE]; diff --git a/env/env.c b/env/env.c index e5340080060..e4dfb92e154 100644 --- a/env/env.c +++ b/env/env.c @@ -166,19 +166,6 @@ static struct env_driver *env_driver_lookup(enum env_operation op, int prio) return drv; } -__weak int env_get_char_spec(int index) -{ - return *(uchar *)(gd->env_addr + index); -} - -int env_get_char(int index) -{ - if (gd->env_valid == ENV_INVALID) - return default_environment[index]; - else - return env_get_char_spec(index); -} - int env_load(void) { struct env_driver *drv; diff --git a/env/nowhere.c b/env/nowhere.c index 41557f5ce44..1fcf5034535 100644 --- a/env/nowhere.c +++ b/env/nowhere.c @@ -31,9 +31,8 @@ static int env_nowhere_init(void) static int env_nowhere_load(void) { /* - * for SPL, set env_valid = ENV_INVALID is enough as env_get_char() - * return the default env if env_get is used - * and SPL don't used env_import to reduce its size + * For SPL, setting env_valid = ENV_INVALID is enough, as env_get() + * searches default_environment array in that case. * For U-Boot proper, import the default environment to allow reload. */ if (!IS_ENABLED(CONFIG_SPL_BUILD)) diff --git a/env/nvram.c b/env/nvram.c index f4126858b5b..261b31edfbb 100644 --- a/env/nvram.c +++ b/env/nvram.c @@ -42,20 +42,6 @@ extern void nvram_write(long dest, const void *src, size_t count); static env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR; #endif -#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE -/** Call this function from overridden env_get_char_spec() if you need - * this functionality. - */ -int env_nvram_get_char(int index) -{ - uchar c; - - nvram_read(&c, CONFIG_ENV_ADDR + index, 1); - - return c; -} -#endif - static int env_nvram_load(void) { char buf[CONFIG_ENV_SIZE]; |