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