X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fenv_flash.c;h=1674b30e118d57c60d1a44684138555417fe34b6;hb=a5bfa2726bfb3811e18d9d1043a4876a5595eec3;hp=1593d2caac11bd968841ce43fb3c24426d6678dd;hpb=c609719b8d1b2dca590e0ed499016d041203e403;p=u-boot diff --git a/common/env_flash.c b/common/env_flash.c index 1593d2caac..1674b30e11 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -32,8 +32,10 @@ #include #include -#include #include +#include + +DECLARE_GLOBAL_DATA_PTR; #if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) #define CMD_SAVEENV @@ -41,11 +43,6 @@ #error Cannot use CFG_ENV_ADDR_REDUND without CFG_CMD_ENV & CFG_CMD_FLASH #endif -#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE) && \ - defined(CFG_ENV_ADDR_REDUND) -#error CFG_ENV_ADDR_REDUND should not be used when CFG_ENV_SECT_SIZE > CFG_ENV_SIZE -#endif - #if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND < CFG_ENV_SIZE) #error CFG_ENV_SIZE_REDUND should not be less then CFG_ENV_SIZE #endif @@ -80,12 +77,13 @@ static env_t *flash_addr = (env_t *)CFG_ENV_ADDR; #ifdef CFG_ENV_ADDR_REDUND static env_t *flash_addr_new = (env_t *)CFG_ENV_ADDR_REDUND; -static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SIZE - 1; -static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1; +/* CFG_ENV_ADDR is supposed to be on sector boundary */ +static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1; +static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1; -static uchar active_flag = 1; -static uchar obsolete_flag = 0; -#endif +#define ACTIVE_FLAG 1 +#define OBSOLETE_FLAG 0 +#endif /* CFG_ENV_ADDR_REDUND */ extern uchar default_environment[]; extern int default_environment_size; @@ -93,8 +91,6 @@ extern int default_environment_size; uchar env_get_char_spec (int index) { - DECLARE_GLOBAL_DATA_PTR; - return ( *((uchar *)(gd->env_addr + index)) ); } @@ -102,12 +98,7 @@ uchar env_get_char_spec (int index) int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; - - int crc1_ok = - (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc); - int crc2_ok = - (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc); + int crc1_ok = 0, crc2_ok = 0; uchar flag1 = flash_addr->flags; uchar flag2 = flash_addr_new->flags; @@ -116,54 +107,57 @@ int env_init(void) ulong addr1 = (ulong)&(flash_addr->data); ulong addr2 = (ulong)&(flash_addr_new->data); - if (crc1_ok && ! crc2_ok) - { +#ifdef CONFIG_OMAP2420H4 + int flash_probe(void); + + if(flash_probe() == 0) + goto bad_flash; +#endif + + crc1_ok = (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc); + crc2_ok = (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc); + + if (crc1_ok && ! crc2_ok) { gd->env_addr = addr1; gd->env_valid = 1; - } - else if (! crc1_ok && crc2_ok) - { + } else if (! crc1_ok && crc2_ok) { gd->env_addr = addr2; gd->env_valid = 1; - } - else if (! crc1_ok && ! crc2_ok) - { + } else if (! crc1_ok && ! crc2_ok) { gd->env_addr = addr_default; gd->env_valid = 0; - } - else if (flag1 == active_flag && flag2 == obsolete_flag) - { + } else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) { gd->env_addr = addr1; gd->env_valid = 1; - } - else if (flag1 == obsolete_flag && flag2 == active_flag) - { + } else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) { gd->env_addr = addr2; gd->env_valid = 1; - } - else if (flag1 == flag2) - { + } else if (flag1 == flag2) { gd->env_addr = addr1; gd->env_valid = 2; - } - else if (flag1 == 0xFF) - { + } else if (flag1 == 0xFF) { gd->env_addr = addr1; gd->env_valid = 2; - } - else if (flag2 == 0xFF) - { + } else if (flag2 == 0xFF) { gd->env_addr = addr2; gd->env_valid = 2; } +#ifdef CONFIG_OMAP2420H4 +bad_flash: +#endif return (0); } #ifdef CMD_SAVEENV int saveenv(void) { + char *saved_data = NULL; int rc = 1; + char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; +#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE + ulong up_data = 0; +#endif debug ("Protect off %08lX ... %08lX\n", (ulong)flash_addr, end_addr); @@ -179,6 +173,22 @@ int saveenv(void) goto Done; } +#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE + up_data = (end_addr_new + 1 - ((long)flash_addr_new + CFG_ENV_SIZE)); + debug ("Data to save 0x%x\n", up_data); + if (up_data) { + if ((saved_data = malloc(up_data)) == NULL) { + printf("Unable to save the rest of sector (%ld)\n", + up_data); + goto Done; + } + memcpy(saved_data, + (void *)((long)flash_addr_new + CFG_ENV_SIZE), up_data); + debug ("Data (start 0x%x, len 0x%x) saved at 0x%x\n", + (long)flash_addr_new + CFG_ENV_SIZE, + up_data, saved_data); + } +#endif puts ("Erasing Flash..."); debug (" %08lX ... %08lX ...", (ulong)flash_addr_new, end_addr_new); @@ -191,27 +201,36 @@ int saveenv(void) debug (" %08lX ... %08lX ...", (ulong)&(flash_addr_new->data), sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data)); - if (flash_write(env_ptr->data, - (ulong)&(flash_addr_new->data), - sizeof(env_ptr->data)) || - - flash_write((char *)&(env_ptr->crc), - (ulong)&(flash_addr_new->crc), - sizeof(env_ptr->crc)) || - - flash_write((char *)&obsolete_flag, - (ulong)&(flash_addr->flags), - sizeof(flash_addr->flags)) || - - flash_write((char *)&active_flag, - (ulong)&(flash_addr_new->flags), - sizeof(flash_addr_new->flags))) + if ((rc = flash_write((char *)env_ptr->data, + (ulong)&(flash_addr_new->data), + sizeof(env_ptr->data))) || + (rc = flash_write((char *)&(env_ptr->crc), + (ulong)&(flash_addr_new->crc), + sizeof(env_ptr->crc))) || + (rc = flash_write(&flag, + (ulong)&(flash_addr->flags), + sizeof(flash_addr->flags))) || + (rc = flash_write(&new_flag, + (ulong)&(flash_addr_new->flags), + sizeof(flash_addr_new->flags)))) { flash_perror (rc); goto Done; } puts ("done\n"); +#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE + if (up_data) { /* restore the rest of sector */ + debug ("Restoring the rest of data to 0x%x len 0x%x\n", + (long)flash_addr_new + CFG_ENV_SIZE, up_data); + if (flash_write(saved_data, + (long)flash_addr_new + CFG_ENV_SIZE, + up_data)) { + flash_perror(rc); + goto Done; + } + } +#endif { env_t * etmp = flash_addr; ulong ltmp = end_addr; @@ -226,6 +245,8 @@ int saveenv(void) rc = 0; Done: + if (saved_data) + free (saved_data); /* try to re-protect */ (void) flash_sect_protect (1, (ulong)flash_addr, end_addr); (void) flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new); @@ -238,16 +259,22 @@ Done: int env_init(void) { - DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_OMAP2420H4 + int flash_probe(void); + if(flash_probe() == 0) + goto bad_flash; +#endif if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { gd->env_addr = (ulong)&(env_ptr->data); gd->env_valid = 1; - } else { - gd->env_addr = (ulong)&default_environment[0]; - gd->env_valid = 0; + return(0); } - +#ifdef CONFIG_OMAP2420H4 +bad_flash: +#endif + gd->env_addr = (ulong)&default_environment[0]; + gd->env_valid = 0; return (0); } @@ -262,7 +289,7 @@ int saveenv(void) ulong flash_offset; uchar env_buffer[CFG_ENV_SECT_SIZE]; #else - uchar *env_buffer = (char *)env_ptr; + uchar *env_buffer = (uchar *)env_ptr; #endif /* CFG_ENV_SECT_SIZE */ int rcode = 0; @@ -308,7 +335,7 @@ int saveenv(void) return 1; puts ("Writing to Flash... "); - rc = flash_write(env_buffer, flash_sect_addr, len); + rc = flash_write((char *)env_buffer, flash_sect_addr, len); if (rc != 0) { flash_perror (rc); rcode = 1; @@ -329,10 +356,7 @@ void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND) #ifdef CFG_ENV_ADDR_REDUND - DECLARE_GLOBAL_DATA_PTR; - - if (gd->env_addr != (ulong)&(flash_addr->data)) - { + if (gd->env_addr != (ulong)&(flash_addr->data)) { env_t * etmp = flash_addr; ulong ltmp = end_addr; @@ -343,26 +367,28 @@ void env_relocate_spec (void) end_addr_new = ltmp; } - if (flash_addr_new->flags != obsolete_flag && + if (flash_addr_new->flags != OBSOLETE_FLAG && crc32(0, flash_addr_new->data, ENV_SIZE) == - flash_addr_new->crc) - { + flash_addr_new->crc) { + char flag = OBSOLETE_FLAG; + gd->env_valid = 2; flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new); - flash_write((char *)&obsolete_flag, - (ulong)&(flash_addr_new->flags), - sizeof(flash_addr_new->flags)); + flash_write(&flag, + (ulong)&(flash_addr_new->flags), + sizeof(flash_addr_new->flags)); flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new); } - if (flash_addr->flags != active_flag && - (flash_addr->flags & active_flag) == active_flag) - { + if (flash_addr->flags != ACTIVE_FLAG && + (flash_addr->flags & ACTIVE_FLAG) == ACTIVE_FLAG) { + char flag = ACTIVE_FLAG; + gd->env_valid = 2; flash_sect_protect (0, (ulong)flash_addr, end_addr); - flash_write((char *)&active_flag, - (ulong)&(flash_addr->flags), - sizeof(flash_addr->flags)); + flash_write(&flag, + (ulong)&(flash_addr->flags), + sizeof(flash_addr->flags)); flash_sect_protect (1, (ulong)flash_addr, end_addr); } @@ -374,4 +400,4 @@ void env_relocate_spec (void) #endif /* ! ENV_IS_EMBEDDED || CFG_ENV_ADDR_REDUND */ } -#endif /* CFG_ENV_IS_IN_FLASH) */ +#endif /* CFG_ENV_IS_IN_FLASH */