summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebastian.rasmussen@stericsson.com>2010-11-03 11:14:06 +0100
committerMichael BRANDT <michael.brandt@stericsson.com>2010-11-08 09:15:05 +0100
commit134afc5596a7d270923c65e09129d63c39caecfe (patch)
tree4bb70e9c9377c1f3efe2f5191c024d21028f26c9 /common
parent7fdd2b6f38c6dda80bfc9862b59523933f825390 (diff)
Rework env_emmc
Use TOC functionality instead of hardcoded environment addresses to make it easier to move the U-boot environment configuration to other locations in the flash memory. ST-Ericsson ID: 270847 ST-Ericsson FOSS-OUT ID: STETL-FOSS-OUT-10009 Change-Id: If70d56587d47afdc60a2e50e85d0de13cdf556cc Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> Signed-off-by: Sebastian Rasmussen <sebastian.rasmussen@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/7761 Reviewed-by: Simon SJOLANDER <simon.sjolander@stericsson.com> Reviewed-by: Michael BRANDT <michael.brandt@stericsson.com> Reviewed-by: Patrik RYD <patrik.ryd@stericsson.com> Reviewed-by: Mikael GULLBERG <mikael.xx.gullberg@stericsson.com> Tested-by: Patrik RYD <patrik.ryd@stericsson.com>
Diffstat (limited to 'common')
-rwxr-xr-xcommon/env_emmc.c310
1 files changed, 90 insertions, 220 deletions
diff --git a/common/env_emmc.c b/common/env_emmc.c
index 0d0c1c3e1..76adcb831 100755
--- a/common/env_emmc.c
+++ b/common/env_emmc.c
@@ -1,267 +1,137 @@
/*
- * Copyright (C) ST-Ericsson SA 2009
+ * Copyright (C) ST-Ericsson SA 2010
*
- * See file CREDITS for list of people who contributed to this
- * project.
+ * Author: Ulf Hansson <ulf.hansson@stericsson.com> for
+ * ST-Ericsson
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * License terms: GNU General Public License (GPL), version 2.
*/
-/* #define DEBUG */
#include <common.h>
-
-#if defined(CONFIG_ENV_IS_IN_EMMC) /* Environment is in EMMC Flash */
-
-#include <command.h>
#include <environment.h>
-#include <linux/stddef.h>
-#include <malloc.h>
+#include <part.h>
#include <mmc.h>
-#if defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_EMMC)
-#define CMD_SAVEENV
-#elif defined(CONFIG_ENV_OFFSET_REDUND)
-#error Cannot use CONFIG_ENV_OFFSET_REDUND without CONFIG_CMD_ENV & CONFIG_CMD_EMMC
-#endif
-
-#if defined(CONFIG_ENV_SIZE_REDUND) && (CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
-#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
-#endif
-
-#ifdef CONFIG_INFERNO
-#error CONFIG_INFERNO not supported yet
-#endif
-
-/* references to names in env_common.c */
-extern uchar default_environment[];
-extern int default_environment_size;
-
-char * env_name_spec = "EMMC";
-
+DECLARE_GLOBAL_DATA_PTR;
-#ifdef ENV_IS_EMBEDDED
-extern uchar environment[];
-env_t *env_ptr = (env_t *)(&environment[0]);
-#else /* ! ENV_IS_EMBEDDED */
+/* global var allocated in env_common when doing env_relocate */
env_t *env_ptr = 0;
-#endif /* ENV_IS_EMBEDDED */
+/* global var used from cmd_nvedit when saveenv */
+char *env_name_spec = "EMMC";
-DECLARE_GLOBAL_DATA_PTR;
-
-uchar env_get_char_spec (int index)
+/* global funtion used from env_common */
+uchar env_get_char_spec(int index)
{
return ( *((uchar *)(gd->env_addr + index)) );
}
-static int emmc_read_write(u32 byte_offset, void *read_buffer,
- u32 size, u32 write)
+/* global function called before mmc_initialize */
+int env_init(void)
{
- int i;
- u32 xferred_bytes;
- struct mmc *boot_dev = NULL;
- u32 blkcnt;
-
- for (i = 0;; i++) {
- boot_dev = find_mmc_device(i);
- if (!boot_dev)
- return -1;
- if (!strcmp(boot_dev->name, env_name_spec))
- break;
- }
-
- if (write) {
- blkcnt = size/boot_dev->write_bl_len;
- if (size && !blkcnt)
- blkcnt++;
- xferred_bytes =
- boot_dev->block_dev.block_write(i,
- byte_offset/boot_dev->write_bl_len,
- blkcnt,
- (u_char *)read_buffer);
- xferred_bytes *= boot_dev->write_bl_len;
- } else {
- blkcnt = size/boot_dev->read_bl_len;
- if (size && !blkcnt)
- blkcnt++;
- xferred_bytes =
- boot_dev->block_dev.block_read(i,
- byte_offset/boot_dev->read_bl_len,
- blkcnt,
- (u_char *)read_buffer);
- xferred_bytes *= boot_dev->read_bl_len;
- }
- debug("emmc read write:requested:0x%x,done:0x%x", size, xferred_bytes);
- return xferred_bytes;
+ set_default_env();
+ return 0;
}
-
-/* this is called before nand_init()
- * so we can't read Nand to validate env data.
- * Mark it OK for now. env_relocate() in env_common.c
- * will call our relocate function which will does
- * the real validation.
- *
- * When using a eMMC boot image (like sequoia_nand), the environment
- * can be embedded or attached to the U-Boot image in eMMC flash. This way
- * the SPL loads not only the U-Boot image from eMMC but also the
- * environment.
- */
-int env_init(void)
+/* global function called from cmd_nvedit */
+#ifdef CONFIG_CMD_SAVEENV
+int saveenv(void)
{
-#if defined(ENV_IS_EMBEDDED)
- ulong total;
- int crc1_ok = 0, crc2_ok = 0;
- env_t *tmp_env1, *tmp_env2;
-
- total = CONFIG_ENV_SIZE;
-
- tmp_env1 = env_ptr;
- tmp_env2 = (env_t *)((ulong)env_ptr + CONFIG_ENV_SIZE);
+ int ret;
+ struct mmc *mmc_dev;
+ u32 offset;
+ u32 size;
+ u32 loadaddr;
+ u32 blkcnt;
- crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
- crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
+ printf("Writing to EMMC... ");
- if (!crc1_ok && !crc2_ok)
- gd->env_valid = 0;
- else if(crc1_ok && !crc2_ok)
- gd->env_valid = 1;
- else if(!crc1_ok && crc2_ok)
- gd->env_valid = 2;
- else {
- #ifdef CONFIG_REDUNDAND_ENVIRONMENT
- /* 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 */
- #endif
- gd->env_valid = 1;
+ mmc_dev = find_mmc_device(CONFIG_EMMC_DEV_NUM);
+ if (!mmc_dev) {
+ printf("emmc device not found, so env not saved!\n");
+ return 1;
}
- if (gd->env_valid == 1)
- env_ptr = tmp_env1;
- else if (gd->env_valid == 2)
- env_ptr = tmp_env2;
-#else /* ENV_IS_EMBEDDED */
- gd->env_addr = (ulong)&default_environment[0];
- gd->env_valid = 1;
-#endif /* ENV_IS_EMBEDDED */
-
- return (0);
-}
+ ret = get_entry_info_toc(&mmc_dev->block_dev,
+ CONFIG_ENV_TOC_NAME,
+ &offset,
+ &size,
+ &loadaddr);
+ if (ret) {
+ printf("env address not found, so env not saved!\n");
+ return 1;
+ }
-#ifdef CMD_SAVEENV
-int saveenv(void)
-{
- int ret = 0;
+ if (size != CONFIG_ENV_SIZE) {
+ printf("env size mismatch, so env not saved!\n");
+ return 1;
+ }
- puts ("Writing to EMMC... ");
env_crc_update();
- ret = emmc_read_write(CONFIG_ENV_OFFSET_START, (void *) env_ptr,
- CONFIG_ENV_SIZE, 1);
- if (ret != CONFIG_ENV_SIZE)
- puts("error in saving environment\n");
- else
- puts("done\n");
+ blkcnt = (size + mmc_dev->write_bl_len - 1) / mmc_dev->write_bl_len;
+ ret = mmc_dev->block_dev.block_write(mmc_dev->block_dev.dev,
+ offset / mmc_dev->write_bl_len,
+ blkcnt,
+ (void *)env_ptr);
+ if (ret != blkcnt) {
+ printf("env write failed, so env not saved!\n");
+ return 1;
+ }
- return ret;
+ printf("done\n");
+ return 0;
}
-#endif /* CMD_SAVEENV */
-#ifdef CONFIG_ENV_OFFSET_REDUND
+#endif
+
+/* global function called from env_common when doing env_relocate */
void env_relocate_spec (void)
{
-#if !defined(ENV_IS_EMBEDDED)
- ulong total;
- int crc1_ok = 0, crc2_ok = 0;
- env_t *tmp_env1, *tmp_env2;
-
- total = CONFIG_ENV_SIZE;
-
- tmp_env1 = (env_t *) malloc(CONFIG_ENV_SIZE);
- tmp_env2 = (env_t *) malloc(CONFIG_ENV_SIZE);
-
- emmc_read_write(CONFIG_ENV_OFFSET_START, (void *) tmp_env1, total, 0);
- emmc_read_write(CONFIG_ENV_OFFSET_START, (void *) tmp_env2, total, 0);
-
- 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)
- return set_default_env();
- 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;
+ int ret;
+ struct mmc *mmc_dev;
+ u32 offset;
+ u32 size;
+ u32 loadaddr;
+ u32 blkcnt;
+ mmc_dev = find_mmc_device(CONFIG_EMMC_DEV_NUM);
+ if (!mmc_dev) {
+ printf("env emmc device not found, so setting default env!\n");
+ goto err;
}
- free(env_ptr);
- if(gd->env_valid == 1) {
- env_ptr = tmp_env1;
- free(tmp_env2);
- } else {
- env_ptr = tmp_env2;
- free(tmp_env1);
+ ret = get_entry_info_toc(&mmc_dev->block_dev,
+ CONFIG_ENV_TOC_NAME,
+ &offset,
+ &size,
+ &loadaddr);
+ if (ret) {
+ printf("env not found, so setting default env!\n");
+ goto err;
}
-#endif /* ! ENV_IS_EMBEDDED */
-}
-#else /* ! CONFIG_ENV_OFFSET_REDUND */
-void env_relocate_spec (void)
-{
-#if !defined(ENV_IS_EMBEDDED)
- int ret;
-
- ret = emmc_read_write(CONFIG_ENV_OFFSET_START,
- (void *)env_ptr, CONFIG_ENV_SIZE, 0);
+ if (size != CONFIG_ENV_SIZE) {
+ printf("env size mismatch, so setting default env!\n");
+ goto err;
+ }
- if (ret != CONFIG_ENV_SIZE) {
- printf("env read failed so setting default env\n");
- goto misc;
+ blkcnt = (size + mmc_dev->read_bl_len - 1) / mmc_dev->read_bl_len;
+ ret = mmc_dev->block_dev.block_read(mmc_dev->block_dev.dev,
+ offset / mmc_dev->read_bl_len,
+ blkcnt,
+ (void *)env_ptr);
+ if (ret != blkcnt) {
+ printf("env read failed, so setting default env!\n");
+ goto err;
}
if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) {
- printf("env crc failed so setting default env\n");
- goto misc;
+ printf("env crc failed, so setting default env!\n");
+ goto err;
}
return;
-misc:
- return set_default_env();
-#endif /* ! ENV_IS_EMBEDDED */
+err:
+ set_default_env();
}
-#endif /* CONFIG_ENV_OFFSET_REDUND */
-#endif /* CONFIG_ENV_IS_IN_EMMC */