diff options
| author | Stephen Warren <swarren@nvidia.com> | 2012-07-30 10:55:44 +0000 | 
|---|---|---|
| committer | Andy Fleming <afleming@freescale.com> | 2012-09-05 17:32:41 -0500 | 
| commit | 9404a5fc7cb58bc56152dfd7d355902dfb666f8b (patch) | |
| tree | 161d64baeb1a02953f7900fd9818c359a719a427 /common/env_mmc.c | |
| parent | 8948ea830275afaa7c91fe7e13dd3c4b894a453f (diff) | |
| download | olio-uboot-2014.01-9404a5fc7cb58bc56152dfd7d355902dfb666f8b.tar.xz olio-uboot-2014.01-9404a5fc7cb58bc56152dfd7d355902dfb666f8b.zip | |
env_mmc: allow environment to be in an eMMC partition
eMMC devices may have hardware-level partitions: 2 boot partitions,
up to 4 general partitions, plus the user area. This change introduces
optional config variable CONFIG_SYS_MMC_ENV_PART to indicate which
partition the environment should be stored in: 0=user, 1=boot0, 2=boot1,
4..7=general0..3. This allows the environment to be kept out of the user
area, which simplifies the management of OS-/user-level (MBR/GPT)
partitions within the user area.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Diffstat (limited to 'common/env_mmc.c')
| -rw-r--r-- | common/env_mmc.c | 64 | 
1 files changed, 56 insertions, 8 deletions
| diff --git a/common/env_mmc.c b/common/env_mmc.c index be2f2be20..a2ff90bf4 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -75,9 +75,28 @@ static int init_mmc_for_env(struct mmc *mmc)  		return -1;  	} +#ifdef CONFIG_SYS_MMC_ENV_PART +	if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) { +		if (mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, +				    CONFIG_SYS_MMC_ENV_PART)) { +			puts("MMC partition switch failed\n"); +			return -1; +		} +	} +#endif +  	return 0;  } +static void fini_mmc_for_env(struct mmc *mmc) +{ +#ifdef CONFIG_SYS_MMC_ENV_PART +	if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) +		mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, +				mmc->part_num); +#endif +} +  #ifdef CONFIG_CMD_SAVEENV  static inline int write_env(struct mmc *mmc, unsigned long size,  			    unsigned long offset, const void *buffer) @@ -100,26 +119,38 @@ int saveenv(void)  	char	*res;  	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);  	u32	offset; +	int	ret; -	if (init_mmc_for_env(mmc) || mmc_get_env_addr(mmc, &offset)) +	if (init_mmc_for_env(mmc))  		return 1; +	if (mmc_get_env_addr(mmc, &offset)) { +		ret = 1; +		goto fini; +	} +  	res = (char *)&env_new->data;  	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);  	if (len < 0) {  		error("Cannot export environment: errno = %d\n", errno); -		return 1; +		ret = 1; +		goto fini;  	}  	env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);  	printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV);  	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {  		puts("failed\n"); -		return 1; +		ret = 1; +		goto fini;  	}  	puts("done\n"); -	return 0; +	ret = 0; + +fini: +	fini_mmc_for_env(mmc); +	return ret;  }  #endif /* CONFIG_CMD_SAVEENV */ @@ -143,13 +174,30 @@ void env_relocate_spec(void)  	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);  	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);  	u32 offset; +	int ret; -	if (init_mmc_for_env(mmc) || mmc_get_env_addr(mmc, &offset)) -		return set_default_env(NULL); +	if (init_mmc_for_env(mmc)) { +		ret = 1; +		goto err; +	} -	if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) -		return set_default_env(NULL); +	if (mmc_get_env_addr(mmc, &offset)) { +		ret = 1; +		goto fini; +	} + +	if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) { +		ret = 1; +		goto fini; +	}  	env_import(buf, 1); +	ret = 0; + +fini: +	fini_mmc_for_env(mmc); +err: +	if (ret) +		set_default_env(NULL);  #endif  } |