Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / gen-seeprom / mem-seeprom.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: mem-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: @(#)mem-seeprom.c 1.4 05/11/15
46 * purpose:
47 * copyright: Copyright 2005 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 <sys/param.h>
55#include "gen-seeprom.h"
56#include "mem-seeprom.h"
57#include "prototypes.h"
58
59struct fixed_seeprom mem_seeprom_data[] = {
60 /* name size type value */
61 { NULL, 0, 0, 0, NULL},
62};
63
64static struct dimm_list_entry *dimm_list = NULL;
65static struct dimm_list_entry *cur_dimm;
66
67/* mem_layout is array of pointers to data for each memc */
68static struct mem_data_entry *mem_layout = NULL;
69
70static int max_bits = 0;
71static int max_banks = 0;
72static int num_dimms_per_bank = 0;
73static int num_memc = 1;
74
75static int cur_memc = 0; /* bit_mask to indicate which memc data applies */
76static int force_default_mc = 0; /* support for older cfgs w/out memc_id */
77
78static int max_encode_dimm_bits = 0;
79static int max_dimms = 0;
80static int num_dimms_in_list = 0;
81static int num_bits_in_list = 0;
82static int *bit_to_dimm_map = NULL;
83static int *bit_to_pin_map = NULL;
84
85static int processing_dimm_list = 0;
86static int processing_bit_map = 0;
87static int table_width = 0;
88static int memc_id_init = 0;
89
90static int
91parse_memc_id(char *line)
92{
93 unsigned int input_val;
94
95 if (scan_line(line, &input_val) == ERROR)
96 return (ERROR);
97
98 /* For each memc_id, set the mask bit */
99 if ((input_val >= 0) && (input_val < num_memc)) {
100 cur_memc |= (1 << input_val);
101 memc_id_init = 1;
102 } else {
103 print_error("Invalid memc_id\n");
104 return (ERROR);
105 }
106
107 return (NO_ERROR);
108}
109
110static int
111update_dimm_list(char *parameter, char *line)
112{
113
114 char temp[MAXNAMESIZE], input_str[DIMM_NAME_SIZE+1];
115
116 if (strcmp("memc_id", parameter) == 0) {
117 return (parse_memc_id(line));
118 } else if (strcmp("DIMM", parameter) != 0) {
119 fprintf(stderr, "%s is not a valid DIMM list parameter\n",
120 parameter);
121 return (ERROR);
122 }
123 if (sscanf(line, "%32s %s", temp, input_str) != 2) {
124 fprintf(stderr, "DIMM list entries need 2 strings\n");
125 return (ERROR);
126 }
127 if (strlen(input_str) > (DIMM_NAME_SIZE - 1)) {
128 fprintf(stderr, "DIMM name cannot be greater than %d letters\n",
129 DIMM_NAME_SIZE-1);
130 return (ERROR);
131 }
132
133 if (dimm_list == NULL) {
134 dimm_list = malloc(sizeof (struct dimm_list_entry));
135 dimm_list->next = NULL;
136 cur_dimm = dimm_list;
137 } else {
138 cur_dimm->next = malloc(sizeof (struct dimm_list_entry));
139 cur_dimm = cur_dimm->next;
140 cur_dimm->next = NULL;
141 }
142 num_dimms_in_list += 1;
143 (void) strcpy(cur_dimm->name, input_str);
144 return (NO_ERROR);
145}
146
147int prev_bit_num = 0;
148
149
150static int
151update_bit_map(char *parameter, char *line)
152{
153 int bit_num, dimm, pin_num;
154
155 if (strcmp("memc_id", parameter) == 0) {
156 return (parse_memc_id(line));
157 }
158
159 if (sscanf(line, "%d %d %d", &bit_num, &dimm, &pin_num) != 3) {
160 fprintf(stderr, "bit map entries need 3 numeric values\n");
161 return (ERROR);
162 }
163
164 if ((bit_num >= 0 && (bit_num < (max_bits))) &&
165 (dimm >= 0 && (dimm < (num_dimms_per_bank))) &&
166 (pin_num >= 0)) {
167 bit_to_dimm_map[bit_num] = dimm;
168 bit_to_pin_map[bit_num] = pin_num;
169 } else {
170 fprintf(stderr, "Invalid bit map entry for bit# %d\n", bit_num);
171 fprintf(stderr, "bit#, dimm# and pin# must be >= 0, ");
172 fprintf(stderr, " bit# must be < %d and dimm# < %d\n", max_bits,
173 num_dimms_per_bank);
174 return (ERROR);
175 }
176
177 num_bits_in_list++;
178
179 return (NO_ERROR);
180
181}
182
183static int
184mem_params(char *line, int *mem_data)
185{
186 char temp2[MAXNAMESIZE];
187 int data = 0;
188
189 if ((sscanf(line, "%32s %d", temp2, &data) != 2) || (data <= 0)) {
190 return (ERROR);
191 } else {
192 *mem_data = data;
193 }
194 return (NO_ERROR);
195}
196
197static int
198init_mem_params()
199{
200 int retval = NO_ERROR;
201
202 if (table_width == 0) {
203 print_error("table_width must be initialized!\n");
204 retval = ERROR;
205 }
206 if (max_banks == 0) {
207 print_error("max_banks must be initialized!\n");
208 retval = ERROR;
209 }
210 if (max_bits == 0) {
211 print_error("max_bits must be initialized!\n");
212 retval = ERROR;
213 }
214 if (num_dimms_per_bank == 0) {
215 print_error("num_dimms_per_bank must be initialized!\n");
216 retval = ERROR;
217 }
218 if (mem_layout == NULL) {
219 print_error("num_memc not initialized. Assuming 1\n");
220 mem_layout = malloc(sizeof (struct mem_data_entry));
221 force_default_mc = 1;
222 }
223 return (retval);
224}
225
226int
227mem_dynamic(char *parameter, char *line)
228{
229
230 int retval = NO_ERROR;
231 unsigned long long temp;
232 char temp2[MAXNAMESIZE];
233 int count, i;
234
235 if (strcmp(parameter, "table_width") == 0) {
236 retval = mem_params(line, &table_width);
237 } else if (strcmp(parameter, "max_bits") == 0) {
238 retval = mem_params(line, &max_bits);
239 } else if (strcmp(parameter, "max_banks") == 0) {
240 retval = mem_params(line, &max_banks);
241 } else if (strcmp(parameter, "num_memc") == 0) {
242 retval = mem_params(line, &num_memc);
243 if (mem_layout == NULL) {
244 mem_layout =
245 malloc(sizeof (struct mem_data_entry)*num_memc);
246 } else {
247 printf("ERROR: Already initialized num_memc\n");
248 retval = ERROR;
249 }
250 } else if (strcmp(parameter, "num_dimms_per_bank") == 0) {
251 retval = mem_params(line, &num_dimms_per_bank);
252 if (retval != ERROR) {
253 max_dimms = num_dimms_per_bank * max_banks;
254 max_encode_dimm_bits = 0;
255 count = num_dimms_per_bank;
256 while (count != 1) {
257 count >>= 1;
258 max_encode_dimm_bits++;
259 }
260 }
261 } else if (processing_dimm_list) {
262 if (strcmp(parameter, "dimm_list_end") == 0) {
263 processing_dimm_list = 0;
264 if (num_dimms_in_list !=
265 (num_dimms_per_bank * max_banks)) {
266 sprintf(err_string,
267 "DIMM list must have %d names!\n",
268 num_dimms_per_bank * max_banks);
269 print_error(err_string);
270 retval = ERROR;
271 }
272 if (force_default_mc) {
273 cur_memc = 1;
274 } else if (memc_id_init == 0) {
275 print_error("Must init memc_id in dimm_list\n");
276 retval = ERROR;
277 }
278 for (i = 0; i < num_memc; i++) {
279 if (cur_memc & (1 << i)) {
280 mem_layout[i].dimm_list = dimm_list;
281 }
282 }
283 dimm_list = NULL;
284 } else {
285 retval = update_dimm_list(parameter, line);
286 }
287 } else if (processing_bit_map) {
288 if (strcmp(parameter, "bit_map_end") == 0) {
289 processing_bit_map = 0;
290 if (num_bits_in_list != max_bits) {
291 sprintf(err_string,
292 "Bit map has %d entries, should have %d!\n",
293 num_bits_in_list, max_bits);
294 print_error(err_string);
295 retval = ERROR;
296 }
297 if (force_default_mc) {
298 cur_memc = 1;
299 } else if (memc_id_init == 0) {
300 print_error("Must init memc_id in bitmap\n");
301 retval = ERROR;
302 }
303 for (i = 0; i < num_memc; i++) {
304 if (cur_memc & (1 << i)) {
305 mem_layout[i].bit_to_dimm_map =
306 bit_to_dimm_map;
307 mem_layout[i].bit_to_pin_map =
308 bit_to_pin_map;
309 }
310 }
311 } else {
312 retval = update_bit_map(parameter, line);
313 }
314 } else if (strcmp(parameter, "dimm_list_start") == 0) {
315 if (init_mem_params() == NO_ERROR) {
316 num_dimms_in_list = 0;
317 processing_dimm_list = 1;
318 cur_memc = 0;
319 memc_id_init = 0;
320 } else
321 retval = ERROR;
322 } else if (strcmp(parameter, "dimm_list_end") == 0) {
323 fprintf(stderr, "Missing dimm_list_start\n");
324 retval = ERROR;
325 } else if (strcmp(parameter, "bit_map_start") == 0) {
326 if (init_mem_params() == NO_ERROR) {
327 num_bits_in_list = 0;
328 bit_to_dimm_map = malloc(max_bits * sizeof (int));
329 bit_to_pin_map = malloc(max_bits * sizeof (int));
330 processing_bit_map = 1;
331 cur_memc = 0;
332 memc_id_init = 0;
333 } else
334 retval = ERROR;
335 } else {
336 retval = UNKNOWN;
337 }
338 return (retval);
339}
340
341static void
342free_mem(void)
343{
344 struct dimm_list_entry *dimm_ptr, *tmp1;
345
346 free(bit_to_dimm_map);
347 free(bit_to_pin_map);
348
349 dimm_ptr = dimm_list;
350 while (dimm_ptr->next != NULL) {
351 tmp1 = dimm_ptr->next;
352 free(dimm_ptr);
353 dimm_ptr = tmp1;
354 }
355 free(dimm_ptr);
356}
357
358void
359write_mem(unsigned char **ptr)
360{
361 struct dimm_list_entry *dimm_ptr;
362 unsigned char *p;
363 int bits;
364 int i, j, new_val, size;
365
366 size = (max_dimms * DIMM_NAME_SIZE) + max_bits +
367 (max_bits*max_encode_dimm_bits)/8 + TABLE_WIDTH_LEN + 1;
368 store_bytes(4, (unsigned long long) size, ptr);
369
370 for (j = 0; j < num_memc; j++) {
371 dimm_ptr = mem_layout[j].dimm_list;
372 while (dimm_ptr != NULL) {
373 p = (unsigned char *) dimm_ptr->name;
374 store_chars(DIMM_NAME_SIZE, p, ptr);
375 dimm_ptr = dimm_ptr->next;
376 }
377 store_bytes(1, (unsigned long long) table_width, ptr);
378
379 bits = max_bits - 1;
380 while (bits >= 0) {
381 new_val = 0;
382 for (i = 8-max_encode_dimm_bits; i >= 0;
383 i -= max_encode_dimm_bits) {
384 new_val |=
385 mem_layout[j].bit_to_dimm_map[bits--] << i;
386 }
387 store_bytes(1, (unsigned long long) new_val, ptr);
388 }
389 for (i = 0; i < max_bits; i++) {
390 store_bytes(1,
391 (unsigned long long) mem_layout[j].bit_to_pin_map[i],
392 ptr);
393 }
394 /* last byte ends in 0 */
395 store_bytes(1, 0, ptr);
396 }
397}
398
399void
400dump_mem(void)
401{
402}
403
404int
405check_mem(void)
406{
407 return (0);
408}
409
410int
411reg_mem(char *s1, data_reg **reg)
412{
413 return (0);
414}