env, eeprom: add redundant environment support
PATCH 2/2 env, eeprom: add redundant environment support
Add redundant environment support for environment lying on a EEPROM.
Tested on uppcoming suen3 support
Signed-off-by Andreas Huber <[email protected]>
--- common/env_eeprom.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 127 insertions(+), 4 deletions(-)
common/env_eeprom.c +127 -4
@@ -32,6 +32,11 @@#include <i2c.h> #endif +#ifdef CONFIG_ENV_OFFSET_REDUND +#define ACTIVE_FLAG 1 +#define OBSOLETE_FLAG 0 +#endif +DECLARE_GLOBAL_DATA_PTR ;env_t *env_ptr =NULL ;
@@ -93,9 +98,15 @@ static int eeprom_bus_write (unsigned dev_addr, unsigned offset, uchar *buffer,uchar env_get_char_spec (int index) {uchar c; +unsigned int off; + off =CONFIG_ENV_OFFSET ; +#ifdef CONFIG_ENV_OFFSET_REDUND +if (gd->env_valid ==2 ) + off =CONFIG_ENV_OFFSET_REDUND ; +#endif eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR , -CONFIG_ENV_OFFSET +index+offsetof(env_t ,data), + off + index + offsetof(env_t ,data), &c,1 );return (c);
@@ -103,18 +114,52 @@ uchar env_get_char_spec (int index)void env_relocate_spec (void ) { +unsigned int off =CONFIG_ENV_OFFSET ; +#ifdef CONFIG_ENV_OFFSET_REDUND +if (gd->env_valid ==2 ) + off =CONFIG_ENV_OFFSET_REDUND ; +#endif eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR , -CONFIG_ENV_OFFSET , + off, (uchar *)env_ptr,CONFIG_ENV_SIZE ); }int saveenv (void ) { -return eeprom_bus_write (CONFIG_SYS_DEF_EEPROM_ADDR , -CONFIG_ENV_OFFSET , +int rc; +unsigned int off =CONFIG_ENV_OFFSET ; +#ifdef CONFIG_ENV_OFFSET_REDUND +unsigned int off_red =CONFIG_ENV_OFFSET_REDUND ; +char flag_obsolete =OBSOLETE_FLAG ; +if (gd->env_valid ==1 ) { + off =CONFIG_ENV_OFFSET_REDUND ; + off_red =CONFIG_ENV_OFFSET ; + } + + env_ptr->flags =ACTIVE_FLAG ; +#endif + + rc =eeprom_bus_write (CONFIG_SYS_DEF_EEPROM_ADDR , + off, (uchar *)env_ptr,CONFIG_ENV_SIZE ); + +#ifdef CONFIG_ENV_OFFSET_REDUND +if (rc ==0 ) { +eeprom_bus_write (CONFIG_SYS_DEF_EEPROM_ADDR , + off_red + offsetof(env_t ,flags), + (uchar *)&flag_obsolete, +1 ); +if (gd->env_valid ==1 ) + gd->env_valid =2 ; +else + gd->env_valid =1 ; + + } +#endif + +return rc; }/************************************************************************
@@ -123,6 +168,82 @@ int saveenv(void)* We are still running from ROM, so data use is limited * Use a (moderately small) buffer on the stack */ + +#ifdef CONFIG_ENV_OFFSET_REDUND +int env_init (void ) +{ +ulong len; +ulong crc[2 ], crc_tmp; +unsigned int off, off_env[2 ]; +uchar buf[64 ]; +int crc_ok[2 ] = {0 ,0 }; +unsigned char flags[2 ]; +int i; + +eeprom_init ();/* prepare for EEPROM read/write */ + + off_env[0 ] =CONFIG_ENV_OFFSET ; + off_env[1 ] =CONFIG_ENV_OFFSET_REDUND ; + +for (i =0 ; i <2 ; i++) { +/* read CRC */ +eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR , + off_env[i] + offsetof(env_t ,crc), + (uchar *)&crc[i],sizeof (ulong)); +/* read FLAGS */ +eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR , + off_env[i] + offsetof(env_t ,flags), + (uchar *)&flags[i],sizeof (uchar)); + + crc_tmp=0 ; + len =ENV_SIZE ; + off = off_env[i] + offsetof(env_t ,data); +while (len >0 ) { +int n = (len >sizeof (buf)) ?sizeof (buf) : len; + +eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR , off, + buf, n); + + crc_tmp =crc32 (crc_tmp, buf, n); + len -= n; + off += n; + } +if (crc_tmp == crc[i]) + crc_ok[i] =1 ; + } + +if (!crc_ok[0 ] && !crc_ok[1 ]) { + gd->env_addr =0 ; + gd->env_valid =0 ; + +return 0 ; + }else if (crc_ok[0 ] && !crc_ok[1 ]) { + gd->env_valid =1 ; + } +else if (!crc_ok[0 ] && crc_ok[1 ]) { + gd->env_valid =2 ; + }else { +/* both ok - check serial */ +if (flags[0 ] ==ACTIVE_FLAG && flags[1 ] ==OBSOLETE_FLAG ) + gd->env_valid =1 ; +else if (flags[0 ] ==OBSOLETE_FLAG && flags[1 ] ==ACTIVE_FLAG ) + gd->env_valid =2 ; +else if (flags[0 ] ==0xFF && flags[1 ] ==0 ) + gd->env_valid =2 ; +else if (flags[1 ] ==0xFF && flags[0 ] ==0 ) + gd->env_valid =1 ; +else /* flags are equal - almost impossible */ + gd->env_valid =1 ; + } + +if (gd->env_valid ==2 ) + gd->env_addr = off_env[1 ] + offsetof(env_t ,data); +else if (gd->env_valid ==1 ) + gd->env_addr = off_env[0 ] + offsetof(env_t ,data); + +return (0 ); +} +#else int env_init (void ) {ulong crc, len, new;
@@ -159,3 +280,5 @@ int env_init(void) return (0); } +#endif +
Signature · 5 lines
1.6.2.5 -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Wolfgang Denk
AppliedPATCH 2/2 env, eeprom: add redundant environment support
Dear Heiko Schocher,
Quoted 8 lines · In message <[email protected]> you wrote:
Add redundant environment support for environment lying on a EEPROM.
Tested on uppcoming suen3 support
Signed-off-by Andreas Huber <[email protected]>--- common/env_eeprom.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 127 insertions(+), 4 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de Life would be so much easier if we could just look at the source code. -- Dave Olson