Commit | Line | Data |
---|---|---|
c906108c SS |
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$ | |
12 | * $Date$ | |
13 | * | |
14 | * | |
15 | * Project: ANGEL | |
16 | * | |
17 | * Title: Parameter negotiation utility functions | |
18 | */ | |
19 | ||
20 | #include "params.h" | |
21 | ||
5c44784c | 22 | #include "angel_endian.h" |
c906108c SS |
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 | */ | |
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 | ||
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 | */ | |
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 | */ | |
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 | */ | |
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 | */ | |
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 | */ | |
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 | */ | |
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 */ |