⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 env.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    t_env_var_info *info;
    UINT32	   index;
    UINT32	   index_flash;
    UINT32	   rc;
    char	   old_data[SYS_USER_ENVIRONMENT_DATA_SIZE];
	
    if( strlen(name) > ENV_VAR_MAXLEN_NAME )
    {
        return ERROR_ENV_VAR_NAME_LEN;   
    }
	
    /* Check length of data for buffer (name + value + 2 * '\0') */
    if( strlen(name) + strlen(*value) + 2 > SYS_USER_ENVIRONMENT_DATA_SIZE )
    {
        return ERROR_ENV_VAR_VAL_LEN;
    }
	
    if( lookup_env( name, &index ) )
    {
        /* Found */
		env_var = &env_vars[index];
		info    = &env_var_info[index];
		
		switch( info->attr )
		{
		case ENV_ATTR_RO :
			if( !ext_priviliges ) 
				return ERROR_ENV_VAR_RO;
			
			/**** Fall through ****/
			
		case ENV_ATTR_RW :
		case ENV_ATTR_USER :
			
			if( strcmp( env_var->val, *value ) != 0 )
			{
				/* new value, check validity of data */
				if( info->decode &&
					!info->decode( *value, NULL, 0 ) )
				{
					return ERROR_ENV_VAR_VALUE;
				}
				
				/* Store old value */
				strcpy( old_data, env_var->val );
				
				/* Generate new data */
				strcpy( env_var->val, *value );
				
				/* Write to flash */
				rc = env_to_flash( index, &index_flash );
				
				if( rc != OK )
				{
					/* Could not write, restore old data */
					strcpy( env_var->val, old_data );
					return rc;
				}
			}
			
			if( info->attr == ENV_ATTR_USER )
			{
				info->default_value = default_value;
				info->decode        = decode;
				info->attr          = attr;
			}
			
			break;
			
		default :
			/* Ignore */
			break;
        }
    }
    else
    {
        /* Not found, so create it */
		if( env_var_count == SYS_USER_ENVIRONMENT_MAX_INDEX + 1 )
		{
			/* Too many */
			return ERROR_ENV_VAR_OVERFLOW;
        }
		else
		{
			/* Allocate variable */
			index   = env_var_count;
			env_var = &env_vars[index];
			info    = &env_var_info[index];
			
			strcpy( info->data, name );
			
			set_env_var( env_var, info );
			
			if( *value )
				strcpy( env_var->val, *value );
			else
				*env_var->val = '\0';
			
			info->index	        = INDEX_NONE;
			info->default_value	= default_value;
			info->decode	= decode;
			info->attr		= attr;
			
			/* Write to flash */
			rc = env_to_flash( index, &index_flash );
			
			if( rc != OK )
			{
				/* Could not write */
				return rc; 
			}
			else if( index_flash != INDEX_REARRANGED )
			{
				/* Write OK, store index */
				env_var_info[index].index = index_flash;
				
				env_var_count++;	
                
				/* New NULL var */
				env_vars[env_var_count].name = NULL;
				env_vars[env_var_count].val  = NULL;
			}
		}
    }
	
    return OK;
}


/************************************************************************
*                          set_env_var
************************************************************************/
static void
set_env_var(
			t_env_var      *env_var,
			t_env_var_info *info )
{
    env_var->name = info->data;
    env_var->val  = &info->data[strlen(env_var->name) + 1];
}


/************************************************************************
*                          lookup_env
************************************************************************/
static bool
lookup_env(
		   char   *name,
		   UINT32 *index )
{
    /* Find variable */
    for( *index = 0; 
	(*index < env_var_count) &&
		(strcmp( env_vars[*index].name, name ) != 0); 
	(*index)++ );
	
    return ( *index == env_var_count ) ? FALSE : TRUE;
}


/************************************************************************
*                          compare
************************************************************************/
static int
compare(
		UINT32 *x,
		UINT32 *y )
{
    return strcmp( env_vars[*x].name, env_vars[*y].name );
}


/************************************************************************
*                          remove_var
************************************************************************/
static UINT32
remove_var(
		   UINT32 index,
		   bool   user,
		   bool   system,
		   bool   error_on_ro )
{
    t_env_var_info *info;
    UINT32	   rc;
	
    info = &env_var_info[index];
	
    switch( env_var_info[index].attr )
    {
	case ENV_ATTR_RW :
        if( system )
		{
			/* Set to default value    */
			rc = access_var( env_vars[index].name, 
				&info->default_value, ENV_ATTR_RW,
				info->default_value, NULL );
			
            if( rc != OK )\
				return rc;
        }
        break;
	case ENV_ATTR_USER :
        if( user )
		{
			/* Remove from flash */
			env_remove_from_flash( env_var_info[index].index );
			
			/* Move last record to the empty position */
			env_var_info[index]  = env_var_info[env_var_count - 1];
			set_env_var( &env_vars[index], &env_var_info[index] );
			
			/* New NULL */
			env_var_count--;
			env_vars[env_var_count].name = NULL;
			env_vars[env_var_count].val  = NULL;
        }
		break;
	case ENV_ATTR_RO :
	default :
		/* Ignore request */
		if( error_on_ro )
		{
			return ERROR_ENV_VAR_RO;
		}
		break;
    }
	
    return OK;
}


/************************************************************************
*                          env_to_flash
************************************************************************/
static UINT32 
env_to_flash(
			 UINT32    index_local,
			 UINT32    *index_flash )
{
    t_user_environment_var disk_env_var;
    char		   s[SYS_USER_ENVIRONMENT_DATA_SIZE];
    UINT32		   len_name;
    UINT32		   i;
    INT32		   rc;
    char		   *val;
    UINT32		   align;
	
    t_env_var      *env_var = &env_vars[index_local]; 
    t_env_var_info *info    = &env_var_info[index_local];
	
    *index_flash = info->index;
    len_name     = strlen(env_var->name);
    val          = env_var->val ? env_var->val : "\0";
	
    disk_env_var.size = len_name + strlen(val) + 2;
	
    if( disk_env_var.size > SYS_USER_ENVIRONMENT_DATA_SIZE )
    {
        *index_flash = INDEX_NONE;
        return ERROR_ENV_VAR_VAL_LEN;
    }
	
    strcpy( s, env_var->name );
    strcpy( &s[len_name + 1], val );
	
#ifdef EB
    convert_endianness( s );
    
    /* Round size up to a whole multiplum of words */
    align = (sizeof(UINT32) - (disk_env_var.size % sizeof(UINT32))) %
		sizeof(UINT32);
    
    disk_env_var.size += align;
#endif
	
    disk_env_var.data_inout = (void *)s;
	
    if( *index_flash == INDEX_NONE )
    {
        /* Find free index */
		*index_flash = 0;
		
		do
		{
			for( i=0; 
			(i<env_var_count) && (env_var_info[i].index != *index_flash);
			i++ );
			
            if( i == env_var_count )	/* Found free index */
				break;
			else			/* Not free	    */
				(*index_flash)++;
			
        }
		while( *index_flash <= SYS_USER_ENVIRONMENT_MAX_INDEX );
		
		if( *index_flash > SYS_USER_ENVIRONMENT_MAX_INDEX )
		{
			/* Should not happen */
			*index_flash = INDEX_NONE;
            return ERROR_ENV_VAR_OVERFLOW;
        }
    }
	
    disk_env_var.index = *index_flash;
	
    rc = SYSCON_write(
		SYSCON_DISK_ENVIRONMENT_ID,
		(void *)&disk_env_var,
		sizeof(t_user_environment_var) );
	
    switch( rc )
    {
	case 0 :
		return OK;
		break;
	case ERROR_SYSENV_UPDATE_READ_REFS :
        /* Flash was rearranged, so re-read */
		re_init();
		*index_flash = INDEX_REARRANGED;
		return OK;
        break;
	default :
        *index_flash = INDEX_NONE;
		return rc;
		break;
    }
}


/************************************************************************
*                          env_remove_from_flash
************************************************************************/
static void 
env_remove_from_flash( 
					  UINT32 index )
{
    t_user_environment_var env_var;
	
    env_var.index      = index;
    env_var.size       = 0;
    env_var.data_inout = NULL;
    
    SYSCON_write(
		SYSCON_DISK_ENVIRONMENT_ID,
		(void *)&env_var,
		sizeof(t_user_environment_var) );
} 


/************************************************************************
*                          convert_endianness
************************************************************************/
static void
convert_endianness( 
				   char *s )
{ 
    UINT32 i;
    UINT32 *data = (UINT32 *)s;
	
    for(i=0; i<SYS_USER_ENVIRONMENT_DATA_SIZE / 4; i++ )
    {
        data[i] = SWAPEND32( data[i] );
    }
}


/************************************************************************
*                          re_init
************************************************************************/
static void 
re_init( void )
{
    /* Flash was rearranged, so indices must be updated */
	
    t_user_environment_var env_var;
    UINT32		   index;
    UINT32		   i;
	
    for( i=0; i<= SYS_USER_ENVIRONMENT_MAX_INDEX; i++ )
    {
        env_var.index = i;
		
        if( SYSCON_read(
			SYSCON_DISK_ENVIRONMENT_ID,
			(void *)&env_var,
			sizeof(t_user_environment_var) ) == OK )
		{
			/* Found variable */
			if( lookup_env(
				(char *)env_var.data_inout,
				&index) )
			{
				/* lookup_env should never fail in this case */
				env_var_info[index].index = env_var.index;
			}
        }	 
    }
}



/************************************************************************
*  Implementation : Public functions
************************************************************************/


/************************************************************************
*
*                          env_init
*  Description :
*  -------------
*
*  Init ENV module (create System environment variables)
*
*  Return values :
*  ---------------
*
*  None
*
************************************************************************/
void 
env_init(void)
{
    t_user_environment_var	     env_var;
    UINT32			     i, t, count;
    char			     *s;
    bool			     default_switch;
    char			     *raw;
    char			     msg[40];
	UINT32				 error;
    t_sys_error_lookup_registration  registration;

    /* Register error handling function */
    registration.prefix = SYSERROR_DOMAIN( ERROR_ENV );
    registration.lookup = error_lookup;
    SYSCON_write( SYSCON_ERROR_REGISTER_LOOKUP_ID,
		&registration,
		sizeof( registration ) );
	
    env_var_count = 0;
    env_corrupted = FALSE;


	
    /* Read environment variables */
    for( i=0; i<= SYS_USER_ENVIRONMENT_MAX_INDEX; i++ )
    {
        env_var.index = i;
		
        if( SYSCON_read(
			SYSCON_DISK_ENVIRONMENT_ID,
			(void *)&env_var,
			sizeof(t_user_environment_var) ) == OK )
		{
			env_var_info[env_var_count].index  = env_var.index;
			env_var_info[env_var_count].attr   = ENV_ATTR_USER;
			env_var_info[env_var_count].decode = NULL;
			
			/* Make local copy of data */
			s = env_var_info[env_var_count].data;
			
			memcpy( s,
				(char *)env_var.data_inout,
				SYS_USER_ENVIRONMENT_DATA_SIZE );
#ifdef EB
            convert_endianness( s );
#endif
			
			/* Check that data contains two \0 terminations */
			for( t=0, count = 0; t< SYS_USER_ENVIRONMENT_DATA_SIZE; t++ )
			{
				if( s[t] == '\0' )
					count++;
			}
			
			if( count >= 2 )
			{
				/* Setup name and value */		
				env_vars[env_var_count].name = s;
				env_vars[env_var_count].val  = &s[strlen(s) + 1];
				env_var_count++;
            }
			else
			{
				env_corrupted = TRUE;
			}
		}
    }
    
    env_vars[env_var_count].name = NULL;
    env_vars[env_var_count].val  = NULL;
	
    /* Setup system environment variables if this was not done
	* at a previous run.
	*/
	


    SYSCON_read( SYSCON_BOARD_USE_DEFAULT_ID,
		(void *)&default_switch,
		sizeof(UINT32) );
	
    SYSCON_read( SYSCON_CPU_CACHE_CONFIGURABLE_ID,
		(void *)&cache_configurable,
		sizeof(UINT32) );
	
    SYSCON_read( SYSCON_CPU_MMU_CONFIGURABLE_ID,
		(void *)&mmu_configurable,
		sizeof(UINT32) );
	
    SYSCON_read( SYSCON_CPU_CP0_CONFIG_RESET_ID,
		(void *)&config_init,
		sizeof(UINT32) );
    
    ext_priviliges = TRUE;

	
    /* Size of RAM */
    sprintf( msg, "0x%08x", sys_ramsize );
    if( (error = env_set( "memsize", msg, ENV_ATTR_RO, NULL, hex_s2num )) != OK )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -