1 /*
2  * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3  *
4  * This software may be freely used, copied, modified, and distributed
5  * provided that the above copyright notice is preserved in all copies of the
6  * software.
7  */
8 
9 /* -*-C-*-
10  *
11  * $Revision: 1.3 $
12  *     $Date: 2004/12/27 14:00:54 $
13  *
14  *
15  *   Project: ANGEL
16  *
17  *     Title: Parameter negotiation utility functions
18  */
19 
20 #include "params.h"
21 
22 #include "angel_endian.h"
23 #include "logging.h"
24 
25 
26 /*
27  * Function: Angel_FindParam
28  *  Purpose: find the value of a given parameter from a config.
29  *
30  * see params.h for details
31  */
Angel_FindParam(ADP_Parameter type,const ParameterConfig * config,unsigned int * value)32 bool Angel_FindParam( ADP_Parameter          type,
33                       const ParameterConfig *config,
34                       unsigned int          *value )
35 {
36     unsigned int i;
37 
38     for ( i = 0; i < config->num_parameters; ++i )
39        if ( config->param[i].type == type )
40        {
41            *value = config->param[i].value;
42            return TRUE;
43        }
44 
45     return FALSE;
46 }
47 
48 
49 #if !defined(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
50 
Angel_FindParamList(const ParameterOptions * options,ADP_Parameter type)51 ParameterList *Angel_FindParamList( const ParameterOptions *options,
52                                     ADP_Parameter           type )
53 {
54     unsigned int i;
55 
56     for ( i = 0; i < options->num_param_lists; ++i )
57        if ( options->param_list[i].type == type )
58           return &options->param_list[i];
59 
60     return NULL;
61 }
62 
63 
64 #if defined(TARGET) || defined(TEST_PARAMS)
65 /*
66  * Function: Angel_MatchParams
67  *  Purpose: find a configuration from the requested options which is
68  *           the best match from the supported options.
69  *
70  * see params.h for details
71  */
Angel_MatchParams(const ParameterOptions * requested,const ParameterOptions * supported)72 const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
73                                           const ParameterOptions *supported )
74 {
75     static Parameter        chosen_params[AP_NUM_PARAMS];
76     static ParameterConfig  chosen_config = {
77         AP_NUM_PARAMS,
78         chosen_params
79     };
80     unsigned int i;
81 
82     ASSERT( requested != NULL, "requested is NULL" );
83     ASSERT( requested != NULL, "requested is NULL" );
84     ASSERT( supported->num_param_lists <= AP_NUM_PARAMS, "supp_num too big" );
85 
86     if ( requested->num_param_lists > supported->num_param_lists )
87     {
88         WARN( "req_num exceeds supp_num" );
89         return NULL;
90     }
91 
92     for ( i = 0; i < requested->num_param_lists; ++i )
93     {
94         bool           match;
95         unsigned int   j;
96 
97         const ParameterList *req_list = &requested->param_list[i];
98         ADP_Parameter        req_type = req_list->type;
99         const ParameterList *sup_list = Angel_FindParamList(
100                                             supported, req_type );
101 
102         if ( sup_list == NULL )
103         {
104 #ifdef ASSERTIONS_ENABLED
105             __rt_warning( "option %x not supported\n", req_type );
106 #endif
107             return NULL;
108         }
109 
110         for ( j = 0, match = FALSE;
111               (j < req_list->num_options) && !match;
112               ++j
113             )
114         {
115             unsigned int k;
116 
117             for ( k = 0;
118                   (k < sup_list->num_options) && !match;
119                   ++k
120                 )
121             {
122                 if ( req_list->option[j] == sup_list->option[k] )
123                 {
124 #ifdef DEBUG
125                     __rt_info( "chose value %d for option %x\n",
126                                req_list->option[j], req_type );
127 #endif
128                     match = TRUE;
129                     chosen_config.param[i].type = req_type;
130                     chosen_config.param[i].value = req_list->option[j];
131                 }
132             }
133         }
134 
135         if ( !match )
136         {
137 #ifdef ASSERTIONS_ENABLED
138             __rt_warning( "no match found for option %x\n", req_type );
139 #endif
140             return NULL;
141         }
142     }
143 
144     chosen_config.num_parameters = i;
145     INFO( "match succeeded" );
146     return &chosen_config;
147 }
148 #endif /* defined(TARGET) || defined(TEST_PARAMS) */
149 
150 
151 #if !defined(TARGET) || defined(TEST_PARAMS)
152 /*
153  * Function: Angel_StoreParam
154  *  Purpose: store the value of a given parameter to a config.
155  *
156  * see params.h for details
157  */
Angel_StoreParam(ParameterConfig * config,ADP_Parameter type,unsigned int value)158 bool Angel_StoreParam( ParameterConfig *config,
159                        ADP_Parameter    type,
160                        unsigned int     value )
161 {
162     unsigned int i;
163 
164     for ( i = 0; i < config->num_parameters; ++i )
165        if ( config->param[i].type == type )
166        {
167            config->param[i].value = value;
168            return TRUE;
169        }
170 
171     return FALSE;
172 }
173 #endif /* !defined(TARGET) || defined(TEST_PARAMS) */
174 
175 
176 #if defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
177 /*
178  * Function: Angel_BuildParamConfigMessage
179  *  Purpose: write a parameter config to a buffer in ADP format.
180  *
181  * see params.h for details
182  */
Angel_BuildParamConfigMessage(unsigned char * buffer,const ParameterConfig * config)183 unsigned int Angel_BuildParamConfigMessage( unsigned char         *buffer,
184                                             const ParameterConfig *config )
185 {
186     unsigned char *start = buffer;
187     unsigned int i;
188 
189     PUT32LE( buffer, config->num_parameters );
190     buffer += sizeof( word );
191 
192     for ( i = 0; i < config->num_parameters; ++i )
193     {
194         PUT32LE( buffer, config->param[i].type );
195         buffer += sizeof( word );
196         PUT32LE( buffer, config->param[i].value );
197         buffer += sizeof( word );
198     }
199 
200     return (buffer - start);
201 }
202 #endif /* defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
203 
204 
205 #if !defined(TARGET) || defined(TEST_PARAMS)
206 /*
207  * Function: Angel_BuildParamOptionsMessage
208  *  Purpose: write a parameter Options to a buffer in ADP format.
209  *
210  * see params.h for details
211  */
Angel_BuildParamOptionsMessage(unsigned char * buffer,const ParameterOptions * options)212 unsigned int Angel_BuildParamOptionsMessage( unsigned char          *buffer,
213                                              const ParameterOptions *options )
214 {
215     unsigned char *start = buffer;
216     unsigned int i, j;
217 
218     PUT32LE( buffer, options->num_param_lists );
219     buffer += sizeof( word );
220 
221     for ( i = 0; i < options->num_param_lists; ++i )
222     {
223         PUT32LE( buffer, options->param_list[i].type );
224         buffer += sizeof( word );
225         PUT32LE( buffer, options->param_list[i].num_options );
226         buffer += sizeof( word );
227         for ( j = 0; j < options->param_list[i].num_options; ++j )
228         {
229             PUT32LE( buffer, options->param_list[i].option[j] );
230             buffer += sizeof( word );
231         }
232     }
233 
234     return (buffer - start);
235 }
236 #endif /* !defined(TARGET) || defined(TEST_PARAMS) */
237 
238 
239 #if !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
240 /*
241  * Function: Angel_ReadParamConfigMessage
242  *  Purpose: read a parameter config from a buffer where it is in ADP format.
243  *
244  * see params.h for details
245  */
Angel_ReadParamConfigMessage(const unsigned char * buffer,ParameterConfig * config)246 bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
247                                    ParameterConfig     *config )
248 {
249     unsigned int word;
250     unsigned int i;
251 
252     word = GET32LE( buffer );
253     buffer += sizeof( word );
254     if ( word > config->num_parameters )
255     {
256         WARN( "not enough space" );
257         return FALSE;
258     }
259     config->num_parameters = word;
260 
261     for ( i = 0; i < config->num_parameters; ++i )
262     {
263         config->param[i].type = (ADP_Parameter)GET32LE( buffer );
264         buffer += sizeof( word );
265         config->param[i].value = GET32LE( buffer );
266         buffer += sizeof( word );
267     }
268 
269     return TRUE;
270 }
271 #endif /* !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
272 
273 
274 #if defined(TARGET) || defined(TEST_PARAMS)
275 /*
276  * Function: Angel_ReadParamOptionsMessage
277  *  Purpose: read a parameter options block from a buffer
278  *             where it is in ADP format.
279  *
280  * see params.h for details
281  */
Angel_ReadParamOptionsMessage(const unsigned char * buffer,ParameterOptions * options)282 bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
283                                     ParameterOptions    *options )
284 {
285     unsigned int word;
286     unsigned int i, j;
287 
288     word = GET32LE( buffer );
289     buffer += sizeof( word );
290     if ( word > options->num_param_lists )
291     {
292         WARN( "not enough space" );
293         return FALSE;
294     }
295     options->num_param_lists = word;
296 
297     for ( i = 0; i < options->num_param_lists; ++i )
298     {
299         ParameterList *list = &options->param_list[i];
300 
301         list->type = (ADP_Parameter)GET32LE( buffer );
302         buffer += sizeof( word );
303         word = GET32LE( buffer );
304         buffer += sizeof( word );
305         if ( word > list->num_options )
306         {
307             WARN( "not enough list space" );
308             return FALSE;
309         }
310         list->num_options = word;
311 
312         for ( j = 0; j < list->num_options; ++j )
313         {
314             list->option[j] = GET32LE( buffer );
315             buffer += sizeof( word );
316         }
317     }
318 
319     return TRUE;
320 }
321 #endif /* defined(TARGET) || defined(TEST_PARAMS) */
322 
323 #endif /* !define(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0 */
324 
325 /* EOF params.c */
326