aboutsummaryrefslogtreecommitdiff
path: root/env
diff options
context:
space:
mode:
Diffstat (limited to 'env')
-rw-r--r--env/Kconfig5
-rw-r--r--env/mmc.c47
2 files changed, 47 insertions, 5 deletions
diff --git a/env/Kconfig b/env/Kconfig
index f75f2b1..06d72ba 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -200,6 +200,11 @@ config ENV_IS_IN_MMC
This value may also be positive or negative; this is handled in the
same way as CONFIG_ENV_OFFSET.
+ In case CONFIG_SYS_MMC_ENV_PART is 1 (i.e. environment in eMMC boot
+ partition) then setting CONFIG_ENV_OFFSET_REDUND to the same value
+ as CONFIG_ENV_OFFSET makes use of the second eMMC boot partition for
+ the redundant environment copy.
+
This value is also in units of bytes, but must also be aligned to
an MMC sector boundary.
diff --git a/env/mmc.c b/env/mmc.c
index e111d8e..465b104 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -26,6 +26,18 @@
DECLARE_GLOBAL_DATA_PTR;
+/*
+ * In case the environment is redundant, stored in eMMC hardware boot
+ * partition and the environment and redundant environment offsets are
+ * identical, store the environment and redundant environment in both
+ * eMMC boot partitions, one copy in each.
+ * */
+#if (defined(CONFIG_SYS_REDUNDAND_ENVIRONMENT) && \
+ (CONFIG_SYS_MMC_ENV_PART == 1) && \
+ (CONFIG_ENV_OFFSET == CONFIG_ENV_OFFSET_REDUND))
+#define ENV_MMC_HWPART_REDUND
+#endif
+
#if CONFIG_IS_ENABLED(OF_CONTROL)
static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val)
{
@@ -126,13 +138,11 @@ __weak uint mmc_get_env_part(struct mmc *mmc)
static unsigned char env_mmc_orig_hwpart;
-static int mmc_set_env_part(struct mmc *mmc)
+static int mmc_set_env_part(struct mmc *mmc, uint part)
{
- uint part = mmc_get_env_part(mmc);
int dev = mmc_get_env_dev();
int ret = 0;
- env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
if (ret)
puts("MMC partition switch failed\n");
@@ -140,7 +150,7 @@ static int mmc_set_env_part(struct mmc *mmc)
return ret;
}
#else
-static inline int mmc_set_env_part(struct mmc *mmc) {return 0; };
+static inline int mmc_set_env_part(struct mmc *mmc, uint part) {return 0; };
#endif
static const char *init_mmc_for_env(struct mmc *mmc)
@@ -157,7 +167,8 @@ static const char *init_mmc_for_env(struct mmc *mmc)
if (mmc_init(mmc))
return "MMC init failed";
#endif
- if (mmc_set_env_part(mmc))
+ env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
+ if (mmc_set_env_part(mmc, mmc_get_env_part(mmc)))
return "MMC partition switch failed";
return NULL;
@@ -209,6 +220,13 @@ static int env_mmc_save(void)
#ifdef CONFIG_ENV_OFFSET_REDUND
if (gd->env_valid == ENV_VALID)
copy = 1;
+
+#ifdef ENV_MMC_HWPART_REDUND
+ ret = mmc_set_env_part(mmc, copy + 1);
+ if (ret)
+ goto fini;
+#endif
+
#endif
if (mmc_get_env_addr(mmc, copy, &offset)) {
@@ -273,6 +291,12 @@ static int env_mmc_erase(void)
#ifdef CONFIG_ENV_OFFSET_REDUND
copy = 1;
+#ifdef ENV_MMC_HWPART_REDUND
+ ret = mmc_set_env_part(mmc, copy + 1);
+ if (ret)
+ goto fini;
+#endif
+
if (mmc_get_env_addr(mmc, copy, &offset)) {
ret = CMD_RET_FAILURE;
goto fini;
@@ -331,7 +355,20 @@ static int env_mmc_load(void)
goto fini;
}
+#ifdef ENV_MMC_HWPART_REDUND
+ ret = mmc_set_env_part(mmc, 1);
+ if (ret)
+ goto fini;
+#endif
+
read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1);
+
+#ifdef ENV_MMC_HWPART_REDUND
+ ret = mmc_set_env_part(mmc, 2);
+ if (ret)
+ goto fini;
+#endif
+
read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2);
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,