Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / gen-seeprom / env-seeprom.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: env-seeprom.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * id: @(#)env-seeprom.c 1.3 03/06/11
46 * purpose:
47 * copyright: Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved
48 * copyright: Use is subject to license terms.
49 */
50
51#include <stdio.h>
52#include <stdlib.h>
53#include <strings.h>
54#include "gen-seeprom.h"
55#include "prototypes.h"
56#include "env-seeprom.h"
57
58int processing_env = 0, processing_fan = 0;
59int running_offset = VER_SIZE;
60struct env_table_entry *env_table = NULL;
61struct env_table_entry *cur_env_table;
62struct fan_table_entry *fan_table = NULL;
63struct fan_table_entry *cur_fan_table;
64struct id_header_data id_header;
65int current_correction = 0, current_fan_pair = 0;
66int num_corrections = 0, num_fan_ctl_pairs = 0;
67int id_num = 0, fan_id_num = 0, env_version = 0;
68
69void
70set_env_ver(void *data)
71{
72 env_version = (int)data;
73}
74
75/*
76 * allocate memory for the id-offset block
77 */
78
79void
80set_num_sensors(void *data)
81{
82 id_header.num_sensors = (int)data;
83 running_offset += NUM_SEN_SIZE +
84 (id_header.num_sensors * SENSOR_BLOCK_SIZE);
85 id_header.id_block = malloc(id_header.num_sensors * SENSOR_BLOCK_SIZE);
86}
87
88
89/*
90 * "version" , "num-sensors" , "num-fans" will only show up once in a properly
91 * configured environmental segment
92 */
93
94struct fixed_seeprom env_seeprom_data[] = {
95 /* name size type value */
96 { "version", VER_SIZE, NUM, 0, set_env_ver},
97 { "num-sensors", NUM_SEN_SIZE, NUM, 0, set_num_sensors},
98 { NULL, 0, 0, 0, NULL},
99};
100
101
102int
103not_byte_range(int value)
104{
105 return (value > 255 || value < 0);
106}
107
108int
109not_sbyte_range(int value)
110{
111 return (value > 127 || value < -128);
112}
113
114correction_scan(char *line, unsigned int *input_val)
115{
116 char temp[MAXNAMESIZE];
117 char input_one[MAXNAMESIZE];
118 char input_two[MAXNAMESIZE];
119 unsigned int temp_val;
120 int retval = NO_ERROR;
121
122 if (sscanf(line, "%s %s %s", temp, input_one, input_two) != 3) {
123 retval = ERROR;
124 }
125
126 strip_val(input_one, input_val);
127 strip_val(input_two, &temp_val);
128
129 if (not_sbyte_range(*input_val) || not_sbyte_range(temp_val))
130 retval = ERROR;
131
132 *input_val = (*input_val & 0xff) << 8;
133 *input_val += (temp_val & 0xff);
134
135 if (retval == ERROR) {
136 printf("Correction table entries must be entered as a ");
137 printf("pair of signed bytes\n");
138 }
139 return (retval);
140}
141
142fan_min_range_scan(char *line, unsigned int *input_val)
143{
144 char temp[MAXNAMESIZE];
145 char input_one[MAXNAMESIZE];
146 char input_two[MAXNAMESIZE];
147 unsigned int temp_val;
148 int retval = NO_ERROR;
149
150 if (sscanf(line, "%s %s %s", temp, input_one, input_two) != 3) {
151 retval = ERROR;
152 }
153
154 strip_val(input_one, input_val);
155 strip_val(input_two, &temp_val);
156
157 if (not_sbyte_range(*input_val) || not_byte_range(temp_val))
158 retval = ERROR;
159
160 *input_val = (*input_val & 0xff) << 8;
161 *input_val += (temp_val & 0xff);
162
163 if (retval == ERROR) {
164 printf("Fan min/range table entries must be entered as a ");
165 printf("signed, unsigned byte pair.\n");
166 }
167 return (retval);
168}
169
170int
171update_env_table(char *parameter, char *line)
172{
173 int i = 0, offset = 0;
174 unsigned int input_val;
175 int size;
176 unsigned char *data_ptr;
177
178 while (strcmp(env_parameters[i].name, parameter)) {
179 offset += env_parameters[i++].size;
180 if (env_parameters[i].name == NULL) {
181 fprintf(stderr,
182 "%s is not a valid env parameter\n", parameter);
183 return (ERROR);
184 }
185 }
186 size = env_parameters[i].size;
187 data_ptr = cur_env_table->env_data;
188
189 if (strcmp(parameter, "correction") == 0) {
190 offset = COR_SIZE * current_correction;
191 current_correction++;
192 size = COR_SIZE;
193 data_ptr = cur_env_table->correction_data;
194 if ((correction_scan(line, &input_val) == ERROR))
195 return (ERROR);
196 } else if ((scan_line(line, &input_val) == ERROR))
197 return (ERROR);
198
199
200 if (strcmp(parameter, "num-corrections") == 0) {
201 num_corrections = input_val;
202 cur_env_table->correction_data =
203 (unsigned char *) malloc(COR_SIZE * num_corrections);
204 cur_env_table->correction_size = num_corrections * COR_SIZE;
205 }
206
207 write_bytes(input_val, size, offset, data_ptr);
208
209 return (NO_ERROR);
210}
211
212int
213update_fan_table(char *parameter, char *line)
214{
215 int i = 0, offset = 0;
216 unsigned int input_val;
217 int size;
218 unsigned char *data_ptr;
219
220 while (strcmp(fan_parameters[i].name, parameter)) {
221 offset += fan_parameters[i++].size;
222 if (fan_parameters[i].name == NULL) {
223 fprintf(stderr,
224 "%s is not a valid fan parameter\n", parameter);
225 return (ERROR);
226 }
227 }
228 size = fan_parameters[i].size;
229 data_ptr = cur_fan_table->fan_data;
230
231 if (strcmp(parameter, "fan-min-range") == 0) {
232 offset = FAN_MIN_RANGE_SZ * current_fan_pair;
233 current_fan_pair++;
234 data_ptr = cur_fan_table->fan_ctl_data;
235 if ((fan_min_range_scan(line, &input_val) == ERROR))
236 return (ERROR);
237 } else if ((scan_line(line, &input_val) == ERROR))
238 return (ERROR);
239
240
241 if (strcmp(parameter, "num-ctl-pairs") == 0) {
242 num_fan_ctl_pairs = input_val;
243 cur_fan_table->fan_ctl_data =
244 (unsigned char *) malloc(FAN_MIN_RANGE_SZ *
245 num_fan_ctl_pairs);
246 cur_fan_table->fan_pair_size = num_fan_ctl_pairs *
247 FAN_MIN_RANGE_SZ;
248 }
249
250 write_bytes(input_val, size, offset, data_ptr);
251
252 return (NO_ERROR);
253}
254
255int
256set_num_fans(char *line)
257{
258 unsigned int input_val;
259
260 if (id_header.num_fans == 0) {
261 if (scan_line(line, &input_val) == ERROR)
262 return (ERROR);
263 id_header.num_fans = input_val;
264 running_offset += NUM_FAN_SIZE +
265 (id_header.num_fans * FAN_BLOCK_SIZE);
266 id_header.fan_block = malloc(id_header.num_fans *
267 FAN_BLOCK_SIZE);
268 return (NO_ERROR);
269 } else {
270 printf("ERROR: Already initialized num_fans\n");
271 return (ERROR);
272 }
273}
274
275/*
276 * fill the id-offset block with id numbers and their respective data
277 * offsets as they are presented in the cfg file.
278 */
279
280int
281parse_id(char *line)
282{
283 unsigned int input_val, offset, i;
284
285 offset = id_num * SENSOR_BLOCK_SIZE;
286 id_num++;
287 if (scan_line(line, &input_val) == ERROR)
288 return (ERROR);
289
290 for (i = 0; i < id_num-1; i++) {
291 if (!memcmp(&input_val, &id_header.id_block[i*SENSOR_BLOCK_SIZE],
292 ID_SIZE)) {
293 printf("ERROR: Two sensors with id = %x\n", input_val);
294 return (ERROR);
295 }
296 }
297 write_bytes(input_val, ID_SIZE, offset, id_header.id_block);
298 offset += ID_SIZE;
299 write_bytes(running_offset, OFFSET_SIZE, offset, id_header.id_block);
300
301 return (NO_ERROR);
302}
303
304int
305parse_fan_id(char *line)
306{
307 unsigned int input_val, offset, i;
308
309 offset = fan_id_num * FAN_BLOCK_SIZE;
310 fan_id_num++;
311 if (scan_line(line, &input_val) == ERROR)
312 return (ERROR);
313 for (i = 0; i < fan_id_num-1; i++) {
314 if (!memcmp(&input_val, &id_header.fan_block[i*FAN_BLOCK_SIZE],
315 FAN_ID_SIZE)) {
316 printf("ERROR: Two fans with id = %x\n", input_val);
317 return (ERROR);
318 }
319 }
320 write_bytes(input_val, FAN_ID_SIZE, offset, id_header.fan_block);
321 offset += FAN_ID_SIZE;
322 write_bytes(running_offset, FAN_OFF_SIZE, offset, id_header.fan_block);
323
324 return (NO_ERROR);
325}
326
327/*
328 * The sensor data blocks are marked by sensor-data-start and sensor-data-end
329 * tokens. sensor data blocks should only be presented between these two tokens
330 */
331
332int
333env_dynamic(char *parameter, char *line)
334{
335 int retval = NO_ERROR;
336
337 if (strcmp(parameter, "sensor-data-start") == 0) {
338 if (processing_fan) {
339 printf("ERROR, fan data cannot contain");
340 printf(" sensor-data-start\n");
341 return (ERROR);
342 }
343 if (!processing_env) {
344 if (env_table == NULL) {
345 env_table = malloc(
346 sizeof (struct env_table_entry));
347 cur_env_table = env_table;
348 cur_env_table->next = NULL;
349 } else {
350 cur_env_table->next = malloc(
351 sizeof (struct env_table_entry));
352 cur_env_table = cur_env_table->next;
353 cur_env_table->next = NULL;
354 }
355 processing_env = 1;
356 } else {
357 printf("ERROR, consecutive sensor-data-start tokens");
358 printf(" without sensor-data-end\n");
359 retval = ERROR;
360 }
361 } else if (strcmp(parameter, "sensor-data-end") == 0) {
362 if (processing_fan) {
363 printf("ERROR, fan data cannot contain");
364 printf(" sensor-data-end\n");
365 return (ERROR);
366 }
367 if (!processing_env) {
368 fprintf(stderr, "Missing env_table_start\n");
369 retval = ERROR;
370 } else {
371 if (current_correction != num_corrections) {
372 printf("ERROR, missing correction entries\n");
373 retval = ERROR;
374 }
375 running_offset += ENV_ENTRY_SIZE +
376 (num_corrections * COR_SIZE);
377 processing_env = 0;
378 num_corrections = 0;
379 current_correction = 0;
380 }
381 } else if (strcmp(parameter, "id") == 0) {
382 if (processing_env) {
383 retval = parse_id(line);
384 } else {
385 retval = UNKNOWN;
386 }
387 } else if (strcmp(parameter, "fan-data-start") == 0) {
388 if (processing_env) {
389 printf("ERROR, sensor data cannot contain");
390 printf(" fan-data-start\n");
391 return (ERROR);
392 }
393 if (!processing_fan) {
394 if (fan_table == NULL) {
395 fan_table = malloc(
396 sizeof (struct fan_table_entry));
397 memset(fan_table, 0,
398 sizeof (struct fan_table_entry));
399 cur_fan_table = fan_table;
400 cur_fan_table->next = NULL;
401 } else {
402 cur_fan_table->next = malloc(
403 sizeof (struct fan_table_entry));
404 memset(cur_fan_table->next, 0,
405 sizeof (struct fan_table_entry));
406 cur_fan_table = cur_fan_table->next;
407 cur_fan_table->next = NULL;
408 }
409 processing_fan = 1;
410 } else {
411 printf("ERROR, consecutive fan-data-start tokens");
412 printf(" without fan-data-end\n");
413 retval = ERROR;
414 }
415 } else if (strcmp(parameter, "fan-data-end") == 0) {
416 if (processing_env) {
417 printf("ERROR, sensor data cannot contain");
418 printf(" fan-data-end\n");
419 return (ERROR);
420 }
421 if (!processing_fan) {
422 fprintf(stderr, "Missing fan_table_start\n");
423 retval = ERROR;
424 } else {
425 if (current_fan_pair != num_fan_ctl_pairs) {
426 printf("ERROR, missing fan-min-range");
427 printf(" entries\n");
428 retval = ERROR;
429 }
430 running_offset += ENV_FAN_ENTRY_SIZE +
431 (num_fan_ctl_pairs * FAN_MIN_RANGE_SZ);
432 processing_fan = 0;
433 num_fan_ctl_pairs = 0;
434 current_fan_pair = 0;
435 }
436 } else if (strcmp(parameter, "fan-id") == 0) {
437 if (processing_fan) {
438 retval = parse_fan_id(line);
439 } else {
440 retval = UNKNOWN;
441 }
442 } else if (strcmp(parameter, "num-fans") == 0) {
443 if (env_version == 2) {
444 set_num_fans(line);
445 } else {
446 printf("ERROR, num_fans is not a valid parameter");
447 printf(" for this version of the cfg file\n");
448 retval = ERROR;
449 }
450 } else {
451 if (processing_env) {
452 retval = update_env_table(parameter, line);
453 } else if (processing_fan) {
454 retval = update_fan_table(parameter, line);
455 } else {
456 retval = UNKNOWN;
457 }
458 }
459 return (retval);
460}
461
462/*
463 * the number of sensor ids must match the number-sensors token value
464 */
465
466int
467check_env()
468{
469 int retval = NO_ERROR;
470 if (id_num != id_header.num_sensors) {
471 printf("ERROR, number of id fields does not match number ");
472 printf("of sensors\n");
473 retval = ERROR;
474 }
475 if (fan_id_num != id_header.num_fans) {
476 printf("ERROR, number of fan_id fields does not match number ");
477 printf("of fans\n");
478 retval = ERROR;
479 }
480 return (retval);
481}
482
483int
484reg_env(char *s1, data_reg **reg)
485{
486 return (NO_ERROR);
487}
488
489/*
490 * version and num-sensors have already been added by the gen-seeprom tool.
491 * First add the id-offset table, and then the sensor table data
492 */
493
494void
495write_env(unsigned char **ptr)
496{
497 struct env_table_entry *table_ptr;
498 struct fan_table_entry *fan_table_ptr;
499
500 store_chars((id_header.num_sensors * SENSOR_BLOCK_SIZE),
501 id_header.id_block, ptr);
502 if (env_version > 1) {
503 store_bytes(NUM_FAN_SIZE,
504 (unsigned long long) id_header.num_fans, ptr);
505 store_chars((id_header.num_fans * FAN_BLOCK_SIZE),
506 id_header.fan_block, ptr);
507 }
508
509
510 table_ptr = env_table;
511 while (table_ptr != NULL) {
512 store_chars(ENV_ENTRY_SIZE, table_ptr->env_data, ptr);
513 store_chars(table_ptr->correction_size,
514 table_ptr->correction_data, ptr);
515 table_ptr = table_ptr->next;
516 }
517
518 fan_table_ptr = fan_table;
519 while (fan_table_ptr != NULL) {
520 store_chars(ENV_FAN_ENTRY_SIZE, fan_table_ptr->fan_data, ptr);
521 store_chars(fan_table_ptr->fan_pair_size,
522 fan_table_ptr->fan_ctl_data, ptr);
523 fan_table_ptr = fan_table_ptr->next;
524 }
525
526}
527
528void
529dump_env()
530{
531}