diff options
Diffstat (limited to 'env/mmc.c')
-rw-r--r-- | env/mmc.c | 61 |
1 files changed, 52 insertions, 9 deletions
@@ -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)) { @@ -263,20 +281,32 @@ static int env_mmc_erase(void) return 1; } - if (mmc_get_env_addr(mmc, copy, &offset)) - return CMD_RET_FAILURE; + if (mmc_get_env_addr(mmc, copy, &offset)) { + ret = CMD_RET_FAILURE; + goto fini; + } ret = erase_env(mmc, CONFIG_ENV_SIZE, offset); #ifdef CONFIG_ENV_OFFSET_REDUND copy = 1; - if (mmc_get_env_addr(mmc, copy, &offset)) - return CMD_RET_FAILURE; +#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; + } ret |= erase_env(mmc, CONFIG_ENV_SIZE, offset); #endif +fini: + fini_mmc_for_env(mmc); return ret; } #endif /* CONFIG_CMD_SAVEENV && !CONFIG_SPL_BUILD */ @@ -325,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, |