*/
#include <common.h>
+#include <bootstage.h>
#include <command.h>
#include <env.h>
-#include <environment.h>
+#include <env_internal.h>
+#include <log.h>
+#include <sort.h>
#include <linux/stddef.h>
#include <search.h>
#include <errno.h>
#include <malloc.h>
+#include <u-boot/crc.h>
DECLARE_GLOBAL_DATA_PTR;
#include <env_default.h>
struct hsearch_data env_htab = {
-#if CONFIG_IS_ENABLED(ENV_SUPPORT)
- /* defined in flags.c, only compile with ENV_SUPPORT */
.change_ok = env_flags_validate,
-#endif
};
/*
return ret_val;
}
-void set_default_env(const char *s, int flags)
+void env_set_default(const char *s, int flags)
{
if (sizeof(default_environment) > ENV_SIZE) {
puts("*** Error - default environment is too large\n\n");
debug("Using default environment\n");
}
+ flags |= H_DEFAULT;
if (himport_r(&env_htab, (char *)default_environment,
sizeof(default_environment), '\0', flags, 0,
0, NULL) == 0)
* Special use-case: import from default environment
* (and use \0 as a separator)
*/
- flags |= H_NOCLEAR;
+ flags |= H_NOCLEAR | H_DEFAULT;
return himport_r(&env_htab, (const char *)default_environment,
sizeof(default_environment), '\0',
flags, 0, nvars, vars);
* Check if CRC is valid and (if yes) import the environment.
* Note that "buf" may or may not be aligned.
*/
-int env_import(const char *buf, int check)
+int env_import(const char *buf, int check, int flags)
{
env_t *ep = (env_t *)buf;
memcpy(&crc, &ep->crc, sizeof(crc));
if (crc32(0, ep->data, ENV_SIZE) != crc) {
- set_default_env("bad CRC", 0);
+ env_set_default("bad CRC", 0);
return -ENOMSG; /* needed for env_load() */
}
}
- if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0,
+ if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', flags, 0,
0, NULL)) {
gd->flags |= GD_FLG_ENV_READY;
return 0;
pr_err("Cannot import environment: errno = %d\n", errno);
- set_default_env("import failed", 0);
+ env_set_default("import failed", 0);
return -EIO;
}
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
static unsigned char env_flags;
-int env_import_redund(const char *buf1, int buf1_read_fail,
- const char *buf2, int buf2_read_fail)
+int env_check_redund(const char *buf1, int buf1_read_fail,
+ const char *buf2, int buf2_read_fail)
{
int crc1_ok, crc2_ok;
- env_t *ep, *tmp_env1, *tmp_env2;
+ env_t *tmp_env1, *tmp_env2;
tmp_env1 = (env_t *)buf1;
tmp_env2 = (env_t *)buf2;
}
if (buf1_read_fail && buf2_read_fail) {
- set_default_env("bad env area", 0);
return -EIO;
} else if (!buf1_read_fail && buf2_read_fail) {
gd->env_valid = ENV_VALID;
- return env_import((char *)tmp_env1, 1);
+ return -EINVAL;
} else if (buf1_read_fail && !buf2_read_fail) {
gd->env_valid = ENV_REDUND;
- return env_import((char *)tmp_env2, 1);
+ return -ENOENT;
}
crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) ==
tmp_env2->crc;
if (!crc1_ok && !crc2_ok) {
- set_default_env("bad CRC", 0);
return -ENOMSG; /* needed for env_load() */
} else if (crc1_ok && !crc2_ok) {
gd->env_valid = ENV_VALID;
gd->env_valid = ENV_VALID;
}
+ return 0;
+}
+
+int env_import_redund(const char *buf1, int buf1_read_fail,
+ const char *buf2, int buf2_read_fail,
+ int flags)
+{
+ env_t *ep;
+ int ret;
+
+ ret = env_check_redund(buf1, buf1_read_fail, buf2, buf2_read_fail);
+
+ if (ret == -EIO) {
+ env_set_default("bad env area", 0);
+ return -EIO;
+ } else if (ret == -EINVAL) {
+ return env_import((char *)buf1, 1, flags);
+ } else if (ret == -ENOENT) {
+ return env_import((char *)buf2, 1, flags);
+ } else if (ret == -ENOMSG) {
+ env_set_default("bad CRC", 0);
+ return -ENOMSG;
+ }
+
if (gd->env_valid == ENV_VALID)
- ep = tmp_env1;
+ ep = (env_t *)buf1;
else
- ep = tmp_env2;
+ ep = (env_t *)buf2;
env_flags = ep->flags;
- return env_import((char *)ep, 0);
+
+ return env_import((char *)ep, 0, flags);
}
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
env_reloc();
env_fix_drivers();
-
- if (env_htab.change_ok)
- env_htab.change_ok += gd->reloc_off;
+ env_htab.change_ok += gd->reloc_off;
#endif
if (gd->env_valid == ENV_INVALID) {
#if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD)
/* Environment not changable */
- set_default_env(NULL, 0);
+ env_set_default(NULL, 0);
#else
bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM);
- set_default_env("bad CRC", 0);
+ env_set_default("bad CRC", 0);
#endif
} else {
env_load();
int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf,
bool dollar_comp)
{
- ENTRY *match;
+ struct env_entry *match;
int found, idx;
if (dollar_comp) {