326 lines
8.5 KiB
C
326 lines
8.5 KiB
C
/*
|
|
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
|
|
*
|
|
* This software may be freely used, copied, modified, and distributed
|
|
* provided that the above copyright notice is preserved in all copies of the
|
|
* software.
|
|
*/
|
|
|
|
/* -*-C-*-
|
|
*
|
|
* $Revision$
|
|
* $Date$
|
|
*
|
|
*
|
|
* Project: ANGEL
|
|
*
|
|
* Title: Parameter negotiation utility functions
|
|
*/
|
|
|
|
#include "params.h"
|
|
|
|
#include "angel_endian.h"
|
|
#include "logging.h"
|
|
|
|
|
|
/*
|
|
* Function: Angel_FindParam
|
|
* Purpose: find the value of a given parameter from a config.
|
|
*
|
|
* see params.h for details
|
|
*/
|
|
bool Angel_FindParam( ADP_Parameter type,
|
|
const ParameterConfig *config,
|
|
unsigned int *value )
|
|
{
|
|
unsigned int i;
|
|
|
|
for ( i = 0; i < config->num_parameters; ++i )
|
|
if ( config->param[i].type == type )
|
|
{
|
|
*value = config->param[i].value;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#if !defined(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
|
|
|
|
ParameterList *Angel_FindParamList( const ParameterOptions *options,
|
|
ADP_Parameter type )
|
|
{
|
|
unsigned int i;
|
|
|
|
for ( i = 0; i < options->num_param_lists; ++i )
|
|
if ( options->param_list[i].type == type )
|
|
return &options->param_list[i];
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
#if defined(TARGET) || defined(TEST_PARAMS)
|
|
/*
|
|
* Function: Angel_MatchParams
|
|
* Purpose: find a configuration from the requested options which is
|
|
* the best match from the supported options.
|
|
*
|
|
* see params.h for details
|
|
*/
|
|
const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
|
|
const ParameterOptions *supported )
|
|
{
|
|
static Parameter chosen_params[AP_NUM_PARAMS];
|
|
static ParameterConfig chosen_config = {
|
|
AP_NUM_PARAMS,
|
|
chosen_params
|
|
};
|
|
unsigned int i;
|
|
|
|
ASSERT( requested != NULL, "requested is NULL" );
|
|
ASSERT( requested != NULL, "requested is NULL" );
|
|
ASSERT( supported->num_param_lists <= AP_NUM_PARAMS, "supp_num too big" );
|
|
|
|
if ( requested->num_param_lists > supported->num_param_lists )
|
|
{
|
|
WARN( "req_num exceeds supp_num" );
|
|
return NULL;
|
|
}
|
|
|
|
for ( i = 0; i < requested->num_param_lists; ++i )
|
|
{
|
|
bool match;
|
|
unsigned int j;
|
|
|
|
const ParameterList *req_list = &requested->param_list[i];
|
|
ADP_Parameter req_type = req_list->type;
|
|
const ParameterList *sup_list = Angel_FindParamList(
|
|
supported, req_type );
|
|
|
|
if ( sup_list == NULL )
|
|
{
|
|
#ifdef ASSERTIONS_ENABLED
|
|
__rt_warning( "option %x not supported\n", req_type );
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
for ( j = 0, match = FALSE;
|
|
(j < req_list->num_options) && !match;
|
|
++j
|
|
)
|
|
{
|
|
unsigned int k;
|
|
|
|
for ( k = 0;
|
|
(k < sup_list->num_options) && !match;
|
|
++k
|
|
)
|
|
{
|
|
if ( req_list->option[j] == sup_list->option[k] )
|
|
{
|
|
#ifdef DEBUG
|
|
__rt_info( "chose value %d for option %x\n",
|
|
req_list->option[j], req_type );
|
|
#endif
|
|
match = TRUE;
|
|
chosen_config.param[i].type = req_type;
|
|
chosen_config.param[i].value = req_list->option[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !match )
|
|
{
|
|
#ifdef ASSERTIONS_ENABLED
|
|
__rt_warning( "no match found for option %x\n", req_type );
|
|
#endif
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
chosen_config.num_parameters = i;
|
|
INFO( "match succeeded" );
|
|
return &chosen_config;
|
|
}
|
|
#endif /* defined(TARGET) || defined(TEST_PARAMS) */
|
|
|
|
|
|
#if !defined(TARGET) || defined(TEST_PARAMS)
|
|
/*
|
|
* Function: Angel_StoreParam
|
|
* Purpose: store the value of a given parameter to a config.
|
|
*
|
|
* see params.h for details
|
|
*/
|
|
bool Angel_StoreParam( ParameterConfig *config,
|
|
ADP_Parameter type,
|
|
unsigned int value )
|
|
{
|
|
unsigned int i;
|
|
|
|
for ( i = 0; i < config->num_parameters; ++i )
|
|
if ( config->param[i].type == type )
|
|
{
|
|
config->param[i].value = value;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
|
|
|
|
|
|
#if defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
|
|
/*
|
|
* Function: Angel_BuildParamConfigMessage
|
|
* Purpose: write a parameter config to a buffer in ADP format.
|
|
*
|
|
* see params.h for details
|
|
*/
|
|
unsigned int Angel_BuildParamConfigMessage( unsigned char *buffer,
|
|
const ParameterConfig *config )
|
|
{
|
|
unsigned char *start = buffer;
|
|
unsigned int i;
|
|
|
|
PUT32LE( buffer, config->num_parameters );
|
|
buffer += sizeof( word );
|
|
|
|
for ( i = 0; i < config->num_parameters; ++i )
|
|
{
|
|
PUT32LE( buffer, config->param[i].type );
|
|
buffer += sizeof( word );
|
|
PUT32LE( buffer, config->param[i].value );
|
|
buffer += sizeof( word );
|
|
}
|
|
|
|
return (buffer - start);
|
|
}
|
|
#endif /* defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
|
|
|
|
|
|
#if !defined(TARGET) || defined(TEST_PARAMS)
|
|
/*
|
|
* Function: Angel_BuildParamOptionsMessage
|
|
* Purpose: write a parameter Options to a buffer in ADP format.
|
|
*
|
|
* see params.h for details
|
|
*/
|
|
unsigned int Angel_BuildParamOptionsMessage( unsigned char *buffer,
|
|
const ParameterOptions *options )
|
|
{
|
|
unsigned char *start = buffer;
|
|
unsigned int i, j;
|
|
|
|
PUT32LE( buffer, options->num_param_lists );
|
|
buffer += sizeof( word );
|
|
|
|
for ( i = 0; i < options->num_param_lists; ++i )
|
|
{
|
|
PUT32LE( buffer, options->param_list[i].type );
|
|
buffer += sizeof( word );
|
|
PUT32LE( buffer, options->param_list[i].num_options );
|
|
buffer += sizeof( word );
|
|
for ( j = 0; j < options->param_list[i].num_options; ++j )
|
|
{
|
|
PUT32LE( buffer, options->param_list[i].option[j] );
|
|
buffer += sizeof( word );
|
|
}
|
|
}
|
|
|
|
return (buffer - start);
|
|
}
|
|
#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
|
|
|
|
|
|
#if !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
|
|
/*
|
|
* Function: Angel_ReadParamConfigMessage
|
|
* Purpose: read a parameter config from a buffer where it is in ADP format.
|
|
*
|
|
* see params.h for details
|
|
*/
|
|
bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
|
|
ParameterConfig *config )
|
|
{
|
|
unsigned int word;
|
|
unsigned int i;
|
|
|
|
word = GET32LE( buffer );
|
|
buffer += sizeof( word );
|
|
if ( word > config->num_parameters )
|
|
{
|
|
WARN( "not enough space" );
|
|
return FALSE;
|
|
}
|
|
config->num_parameters = word;
|
|
|
|
for ( i = 0; i < config->num_parameters; ++i )
|
|
{
|
|
config->param[i].type = (ADP_Parameter)GET32LE( buffer );
|
|
buffer += sizeof( word );
|
|
config->param[i].value = GET32LE( buffer );
|
|
buffer += sizeof( word );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
#endif /* !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
|
|
|
|
|
|
#if defined(TARGET) || defined(TEST_PARAMS)
|
|
/*
|
|
* Function: Angel_ReadParamOptionsMessage
|
|
* Purpose: read a parameter options block from a buffer
|
|
* where it is in ADP format.
|
|
*
|
|
* see params.h for details
|
|
*/
|
|
bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
|
|
ParameterOptions *options )
|
|
{
|
|
unsigned int word;
|
|
unsigned int i, j;
|
|
|
|
word = GET32LE( buffer );
|
|
buffer += sizeof( word );
|
|
if ( word > options->num_param_lists )
|
|
{
|
|
WARN( "not enough space" );
|
|
return FALSE;
|
|
}
|
|
options->num_param_lists = word;
|
|
|
|
for ( i = 0; i < options->num_param_lists; ++i )
|
|
{
|
|
ParameterList *list = &options->param_list[i];
|
|
|
|
list->type = (ADP_Parameter)GET32LE( buffer );
|
|
buffer += sizeof( word );
|
|
word = GET32LE( buffer );
|
|
buffer += sizeof( word );
|
|
if ( word > list->num_options )
|
|
{
|
|
WARN( "not enough list space" );
|
|
return FALSE;
|
|
}
|
|
list->num_options = word;
|
|
|
|
for ( j = 0; j < list->num_options; ++j )
|
|
{
|
|
list->option[j] = GET32LE( buffer );
|
|
buffer += sizeof( word );
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
#endif /* defined(TARGET) || defined(TEST_PARAMS) */
|
|
|
|
#endif /* !define(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0 */
|
|
|
|
/* EOF params.c */
|