Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: sys-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: @(#)sys-seeprom.c 1.7 06/04/27 | |
46 | * purpose: | |
47 | * copyright: Copyright 2006 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 <unistd.h> | |
54 | #include <strings.h> | |
55 | #include <ctype.h> | |
56 | #include <sys/types.h> | |
57 | #include <sys/stat.h> | |
58 | #include <sys/param.h> | |
59 | #include <fcntl.h> | |
60 | #include "gen-seeprom.h" | |
61 | #include "sys-seeprom.h" | |
62 | #include "prototypes.h" | |
63 | ||
64 | #define SYS_DEFAULT_MAGIC 0x5359 | |
65 | ||
66 | #define MAX_TABLE_SIZE 1000 | |
67 | #define OBP_RO_MAX 0x400 | |
68 | ||
69 | extern int system_type; | |
70 | extern struct fixed_seeprom *seeprom_data; | |
71 | ||
72 | struct fixed_seeprom sys_seeprom_data[] = { | |
73 | /* name size type value */ | |
74 | { "id_magic", 2, NUM, 0, NULL }, | |
75 | { "ro-checksum", 1, NUM, 0, NULL }, | |
76 | { "ro-size", 2, NUM, 0, NULL }, | |
77 | { "id_format", 1, NUM, 0, NULL }, | |
78 | { "pad", 2, NUM, 0, NULL }, | |
79 | { "pad", 8, NUM, 0, NULL }, | |
80 | { "sys_speed_max", 1, NUM, 0, NULL }, | |
81 | { "sys_speed_min", 1, NUM, 0, NULL }, | |
82 | { "upa_speed_max", 1, NUM, 0, NULL }, | |
83 | { "upa_speed_min", 1, NUM, 0, NULL }, | |
84 | { "stick_freq", 1, NUM, 0, NULL }, | |
85 | { "memc", 1, NUM, 0, NULL }, | |
86 | { "num_timing_sets", 1, NUM, 0, NULL }, | |
87 | { "pad", 1, NUM, 0, NULL }, | |
88 | { NULL, 0, 0, 0, NULL}, | |
89 | }; | |
90 | ||
91 | struct fixed_seeprom fiesta_sys_data[] = { | |
92 | /* name size type value */ | |
93 | { "id_magic", 2, NUM, 0, NULL }, | |
94 | { "ro-checksum", 1, NUM, 0, NULL }, | |
95 | { "ro-size", 2, NUM, 0, NULL }, | |
96 | { "id_format", 1, NUM, 0, NULL }, | |
97 | { "pad", 2, NUM, 0, NULL }, | |
98 | { "pad", 6, NUM, 0, NULL }, | |
99 | { "sys_ssc", 1, NUM, 0, NULL }, | |
100 | { "pci_ssc", 1, NUM, 0, NULL }, | |
101 | { "sys_speed_max", 1, NUM, 0, NULL }, | |
102 | { "sys_speed_min", 1, NUM, 0, NULL }, | |
103 | { "upa_speed_max", 1, NUM, 0, NULL }, | |
104 | { "upa_speed_min", 1, NUM, 0, NULL }, | |
105 | { "stick_freq", 1, NUM, 0, NULL }, | |
106 | { NULL, 0, 0, 0, NULL}, | |
107 | }; | |
108 | ||
109 | static struct timing_table_entry *timing_table = NULL; | |
110 | static struct timing_table_entry *cur_timing_table; | |
111 | ||
112 | static int processing_timing = 0; | |
113 | ||
114 | void | |
115 | set_byte(int index, int data, unsigned short *byte) | |
116 | { | |
117 | *byte |= data; | |
118 | *byte <<= (4*index); | |
119 | } | |
120 | ||
121 | static int | |
122 | update_timing_table(char *parameter, char *line) | |
123 | { | |
124 | int i = 0, offset = 0; | |
125 | unsigned int input_val; | |
126 | ||
127 | while (strcmp(timing_parameters[i].name, parameter)) { | |
128 | offset += timing_parameters[i++].size; | |
129 | if (timing_parameters[i].name == NULL) { | |
130 | fprintf(stderr, | |
131 | "%s is not a valid timing parameter\n", parameter); | |
132 | return (1); | |
133 | } | |
134 | } | |
135 | ||
136 | if (scan_line(line, &input_val) == ERROR) | |
137 | return (ERROR); | |
138 | ||
139 | write_bytes(input_val, timing_parameters[i].size, offset, | |
140 | cur_timing_table->timing_data); | |
141 | ||
142 | return (NO_ERROR); | |
143 | } | |
144 | ||
145 | int | |
146 | sys_dynamic(char *parameter, char *line) | |
147 | { | |
148 | ||
149 | int retval = NO_ERROR; | |
150 | unsigned long long temp; | |
151 | ||
152 | if (processing_timing) { | |
153 | if (strcmp(parameter, "timing_table_end") == 0) { | |
154 | temp = get_seeprom("num_timing_sets"); | |
155 | update_seeprom("num_timing_sets", temp+1); | |
156 | processing_timing = 0; | |
157 | } else { | |
158 | retval = update_timing_table(parameter, line); | |
159 | } | |
160 | } else { | |
161 | if (strcmp(parameter, "timing_table_start") == 0) { | |
162 | if (timing_table == NULL) { | |
163 | timing_table = malloc( | |
164 | sizeof (struct timing_table_entry)); | |
165 | timing_table->next = NULL; | |
166 | cur_timing_table = timing_table; | |
167 | } else { | |
168 | cur_timing_table->next = malloc( | |
169 | sizeof (struct timing_table_entry)); | |
170 | cur_timing_table = cur_timing_table->next; | |
171 | cur_timing_table->next = NULL; | |
172 | } | |
173 | processing_timing = 1; | |
174 | } else if (strcmp(parameter, "timing_table_end") == 0) { | |
175 | fprintf(stderr, "Missing timing_table_start\n"); | |
176 | retval = 1; | |
177 | } else { | |
178 | retval = UNKNOWN; | |
179 | } | |
180 | } | |
181 | return (retval); | |
182 | } | |
183 | ||
184 | static void | |
185 | free_sys(void) | |
186 | { | |
187 | struct timing_table_entry *table_ptr2, *tmp2; | |
188 | ||
189 | if (timing_table != NULL) { | |
190 | table_ptr2 = timing_table; | |
191 | while (table_ptr2->next != NULL) { | |
192 | tmp2 = table_ptr2->next; | |
193 | free(table_ptr2); | |
194 | table_ptr2 = tmp2; | |
195 | } | |
196 | free(table_ptr2); | |
197 | } | |
198 | } | |
199 | ||
200 | void | |
201 | write_sys(unsigned char **ptr) | |
202 | { | |
203 | struct timing_table_entry *table_ptr2; | |
204 | unsigned char *p; | |
205 | int i, size, len; | |
206 | ||
207 | i = size = 0; | |
208 | while (seeprom_data[i].name != NULL) { | |
209 | size += seeprom_data[i++].size; | |
210 | } | |
211 | ||
212 | table_ptr2 = timing_table; | |
213 | while (table_ptr2 != NULL) { | |
214 | len = TIMING_ENTRY_SIZE; | |
215 | size += len; | |
216 | p = table_ptr2->timing_data; | |
217 | store_chars(TIMING_ENTRY_SIZE, p, ptr); | |
218 | table_ptr2 = table_ptr2->next; | |
219 | } | |
220 | ||
221 | free_sys(); | |
222 | } | |
223 | ||
224 | void | |
225 | dump_sys(void) | |
226 | { | |
227 | } | |
228 | ||
229 | static void | |
230 | sys_checksum(unsigned short *checksum, unsigned int bytes, | |
231 | unsigned char *addr) | |
232 | { | |
233 | while (bytes--) { | |
234 | *checksum ^= *addr++; | |
235 | } | |
236 | } | |
237 | ||
238 | int | |
239 | check_sys(void) | |
240 | { | |
241 | int error = 0; | |
242 | ||
243 | if (get_seeprom("id_magic") != SYS_DEFAULT_MAGIC) { | |
244 | sprintf(err_string, | |
245 | "id_magic must be 0x%4x!", SYS_DEFAULT_MAGIC); | |
246 | print_error(err_string); | |
247 | error = 1; | |
248 | } | |
249 | ||
250 | if (system_type == EXCALIBUR) { | |
251 | if (timing_table == NULL) { | |
252 | print_error("Must specify a timing table!\n"); | |
253 | error = 1; | |
254 | } | |
255 | ||
256 | if (processing_timing) { | |
257 | print_error("Missing timing_table_end!\n"); | |
258 | error = 1; | |
259 | } | |
260 | } | |
261 | ||
262 | if (!error) { | |
263 | int i, size; | |
264 | unsigned short checksum; | |
265 | struct timing_table_entry *table_ptr2; | |
266 | ||
267 | i = checksum = size = 0; | |
268 | while (seeprom_data[i].name != NULL) { | |
269 | if (strcmp(seeprom_data[i].name, "checksum") && | |
270 | strcmp(seeprom_data[i].name, "ro-size")) { | |
271 | sys_checksum(&checksum, | |
272 | seeprom_data[i].size, | |
273 | (uchar_t *)&seeprom_data[i].value + | |
274 | (8-seeprom_data[i].size)); | |
275 | } | |
276 | size += seeprom_data[i].size; | |
277 | i++; | |
278 | } | |
279 | table_ptr2 = timing_table; | |
280 | while (table_ptr2 != NULL) { | |
281 | sys_checksum(&checksum, | |
282 | TIMING_ENTRY_SIZE, table_ptr2->timing_data); | |
283 | size += TIMING_ENTRY_SIZE; | |
284 | table_ptr2 = table_ptr2->next; | |
285 | } | |
286 | ||
287 | sys_checksum(&checksum, 2, (unsigned char *)&size+2); | |
288 | update_seeprom("ro-size", (unsigned long long)size); | |
289 | update_seeprom("ro-checksum", (unsigned long long)checksum); | |
290 | } | |
291 | return (error); | |
292 | } | |
293 | ||
294 | int | |
295 | reg_sys(char *s1, data_reg **reg) | |
296 | { | |
297 | return (0); | |
298 | } |