@ -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