From 76768f5f080316d33c25f96e4aaa50d0144f990a Mon Sep 17 00:00:00 2001 From: Fiach Antaw Date: Wed, 25 Jan 2017 18:53:11 +1000 Subject: env: Add generic redundant environment implementation All current environments that implement redundancy use almost identical implementations. This patch implements the env_nand implementation as a function in env_common, and updates the env_export function to export an env_nand-style 'flags' field by default. Signed-off-by: Fiach Antaw Reviewed-by: Tom Rini diff --git a/common/env_common.c b/common/env_common.c index 6845f8d..d9c0c4e 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -226,6 +226,53 @@ int env_import(const char *buf, int check) return 0; } +#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT +static unsigned char env_flags; + +int env_import_redund(const char *buf1, const char *buf2) +{ + int crc1_ok, crc2_ok; + env_t *ep, *tmp_env1, *tmp_env2; + + tmp_env1 = (env_t *)buf1; + tmp_env2 = (env_t *)buf2; + + crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == + tmp_env1->crc; + crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == + tmp_env2->crc; + + if (!crc1_ok && !crc2_ok) { + set_default_env("!bad CRC"); + return 0; + } else if (crc1_ok && !crc2_ok) { + gd->env_valid = 1; + } else if (!crc1_ok && crc2_ok) { + gd->env_valid = 2; + } else { + /* both ok - check serial */ + if (tmp_env1->flags == 255 && tmp_env2->flags == 0) + gd->env_valid = 2; + else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) + gd->env_valid = 1; + else if (tmp_env1->flags > tmp_env2->flags) + gd->env_valid = 1; + else if (tmp_env2->flags > tmp_env1->flags) + gd->env_valid = 2; + else /* flags are equal - almost impossible */ + gd->env_valid = 1; + } + + if (gd->env_valid == 1) + ep = tmp_env1; + else + ep = tmp_env2; + + env_flags = ep->flags; + return env_import((char *)ep, 0); +} +#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ + /* Export the environment and generate CRC for it. */ int env_export(env_t *env_out) { @@ -247,6 +294,10 @@ int env_export(env_t *env_out) env_out->crc = crc32(0, env_out->data, ENV_SIZE); +#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT + env_out->flags = ++env_flags; /* increase the serial */ +#endif + return 0; } diff --git a/include/environment.h b/include/environment.h index 6f94986..d86230a 100644 --- a/include/environment.h +++ b/include/environment.h @@ -224,6 +224,11 @@ int env_import(const char *buf, int check); /* Export from hash table into binary representation */ int env_export(env_t *env_out); +#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT +/* Select and import one of two redundant environments */ +int env_import_redund(const char *buf1, const char *buf2); +#endif + #endif /* DO_DEPS_ONLY */ #endif /* _ENVIRONMENT_H_ */ -- cgit v0.10.2