This is the most complex change. Keep this
one as a separate commit for now.
---
 common/env_flash.c |   65 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/common/env_flash.c b/common/env_flash.c
index b860c48..64882d2 100644
--- a/common/env_flash.c
+++ b/common/env_flash.c
@@ -52,27 +52,28 @@ DECLARE_GLOBAL_DATA_PTR;
 
 char * env_name_spec = "Flash";
 
+static int flash_env_swapped;
+
 #ifdef ENV_IS_EMBEDDED
 
 extern uchar environment[];
 env_t *env_ptr = (env_t *)(&environment[0]);
 
 #ifdef CMD_SAVEENV
-/* static env_t *flash_addr = (env_t *)(&environment[0]);-broken on ARM-wd-*/
-static env_t *flash_addr = (env_t *)CONFIG_ENV_ADDR;
+#define flash_addr  f_flash_addr()
 #endif
 
 #else /* ! ENV_IS_EMBEDDED */
 
 env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR;
 #ifdef CMD_SAVEENV
-static env_t *flash_addr = (env_t *)CONFIG_ENV_ADDR;
+#define flash_addr f_flash_addr()
 #endif
 
 #endif /* ENV_IS_EMBEDDED */
 
 #ifdef CONFIG_ENV_ADDR_REDUND
-static env_t *flash_addr_new = (env_t *)CONFIG_ENV_ADDR_REDUND;
+#define flash_addr_new  f_flash_addr_new()
 
 /* CONFIG_ENV_ADDR is supposed to be on sector boundary */
 static ulong end_addr = CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1;
@@ -80,10 +81,35 @@ static ulong end_addr_new = CONFIG_ENV_ADDR_REDUND + 
CONFIG_ENV_SECT_SIZE - 1;
 
 #define ACTIVE_FLAG   1
 #define OBSOLETE_FLAG 0
+
+static void flash_env_swap(void)
+{
+       ulong ltmp = end_addr;
+
+       flash_env_swapped = !flash_env_swapped;
+
+       end_addr = end_addr_new;
+       end_addr_new = ltmp;
+}
+
+static env_t * f_flash_addr_new(void)
+{
+       if (!*(LINK_OFF(&flash_env_swapped)))
+               return (env_t *)CONFIG_ENV_ADDR_REDUND;
+       else
+               return (env_t *)CONFIG_ENV_ADDR;
+}
 #endif /* CONFIG_ENV_ADDR_REDUND */
 
 extern uchar default_environment[];
 
+static env_t * f_flash_addr(void)
+{
+       if (!(*LINK_OFF(&flash_env_swapped)))
+               return (env_t *)CONFIG_ENV_ADDR;
+       else
+               return (env_t *)CONFIG_ENV_ADDR_REDUND;
+}
 
 uchar env_get_char_spec (int index)
 {
@@ -99,7 +125,7 @@ int  env_init(void)
        uchar flag1 = flash_addr->flags;
        uchar flag2 = flash_addr_new->flags;
 
-       ulong addr_default = (ulong)&default_environment[0];
+       ulong addr_default = (ulong)LINK_OFF(default_environment);
        ulong addr1 = (ulong)&(flash_addr->data);
        ulong addr2 = (ulong)&(flash_addr_new->data);
 
@@ -218,14 +244,7 @@ int saveenv(void)
        }
 #endif
        {
-               env_t * etmp = flash_addr;
-               ulong ltmp = end_addr;
-
-               flash_addr = flash_addr_new;
-               flash_addr_new = etmp;
-
-               end_addr = end_addr_new;
-               end_addr_new = ltmp;
+               flash_env_swap();
        }
 
        rc = 0;
@@ -245,13 +264,15 @@ Done:
 
 int  env_init(void)
 {
-       if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
-               gd->env_addr  = (ulong)&(env_ptr->data);
+       env_t *ep = *LINK_OFF(&env_ptr);
+
+       if (crc32(0, ep->data, ENV_SIZE) == ep->crc) {
+               gd->env_addr  = (ulong)&(ep->data);
                gd->env_valid = 1;
                return(0);
        }
 
-       gd->env_addr  = (ulong)&default_environment[0];
+       gd->env_addr  = (ulong)LINK_OFF(default_environment);
        gd->env_valid = 0;
        return (0);
 }
@@ -334,16 +355,8 @@ void env_relocate_spec (void)
 {
 #if !defined(ENV_IS_EMBEDDED) || defined(CONFIG_ENV_ADDR_REDUND)
 #ifdef CONFIG_ENV_ADDR_REDUND
-       if (gd->env_addr != (ulong)&(flash_addr->data)) {
-               env_t * etmp = flash_addr;
-               ulong ltmp = end_addr;
-
-               flash_addr = flash_addr_new;
-               flash_addr_new = etmp;
-
-               end_addr = end_addr_new;
-               end_addr_new = ltmp;
-       }
+       if (gd->env_addr != (ulong)&(flash_addr->data))
+               flash_env_swap();
 
        if (flash_addr_new->flags != OBSOLETE_FLAG &&
            crc32(0, flash_addr_new->data, ENV_SIZE) ==
-- 
1.6.4.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to