blob: 01e145398e8e268721f2545cc52c6d01b60d36b1 [file] [log] [blame]
wdenkaffae2b2002-08-17 09:36:01 +00001/*
2 * (C) Copyright 2001
wdenk6dd652f2003-06-19 23:40:20 +00003 * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
wdenkaffae2b2002-08-17 09:36:01 +00004 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <common.h>
25#include <mpc8260.h>
26
27/* imports from fetch.c */
wdenk6dd652f2003-06-19 23:40:20 +000028extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
wdenkaffae2b2002-08-17 09:36:01 +000029
wdenk6dd652f2003-06-19 23:40:20 +000030/* imports from input.c */
31extern int hymod_get_serno (const char *);
32
33/* this is relative to the root of the server's tftp directory */
34static char *def_bddb_cfgdir = "/hymod/bddb";
35
36static int
37hymod_eeprom_load (int which, hymod_eeprom_t *ep)
wdenkaffae2b2002-08-17 09:36:01 +000038{
wdenk6dd652f2003-06-19 23:40:20 +000039 unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \
40 (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
41 unsigned offset = 0;
42 uchar data[HYMOD_EEPROM_SIZE], *dp, *edp;
43 hymod_eehdr_t *hp;
44 ulong len, crc;
wdenkaffae2b2002-08-17 09:36:01 +000045
wdenk6dd652f2003-06-19 23:40:20 +000046 memset (ep, 0, sizeof *ep);
47 memset (data, 0, HYMOD_EEPROM_SIZE);
48 crc = 0;
wdenkaffae2b2002-08-17 09:36:01 +000049
wdenk6dd652f2003-06-19 23:40:20 +000050 hp = (hymod_eehdr_t *)data;
51 eeprom_read (dev_addr, offset, (uchar *)hp, sizeof (*hp));
52 offset += sizeof (*hp);
wdenkaffae2b2002-08-17 09:36:01 +000053
wdenk6dd652f2003-06-19 23:40:20 +000054 if (hp->id != HYMOD_EEPROM_ID || hp->ver > HYMOD_EEPROM_VER ||
55 (len = hp->len) > HYMOD_EEPROM_MAXLEN)
56 return (0);
wdenkaffae2b2002-08-17 09:36:01 +000057
wdenk6dd652f2003-06-19 23:40:20 +000058 dp = (uchar *)(hp + 1); edp = dp + len;
59 eeprom_read (dev_addr, offset, dp, len);
60 offset += len;
wdenkaffae2b2002-08-17 09:36:01 +000061
wdenk6dd652f2003-06-19 23:40:20 +000062 eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong));
wdenkaffae2b2002-08-17 09:36:01 +000063
wdenk6dd652f2003-06-19 23:40:20 +000064 if (crc32 (0, data, edp - data) != crc)
65 return (0);
wdenkaffae2b2002-08-17 09:36:01 +000066
wdenk6dd652f2003-06-19 23:40:20 +000067 ep->ver = hp->ver;
wdenkaffae2b2002-08-17 09:36:01 +000068
wdenk6dd652f2003-06-19 23:40:20 +000069 for (;;) {
70 hymod_eerec_t *rp = (hymod_eerec_t *)dp;
71 ulong rtyp;
72 uchar rlen, *rdat;
73 uint rsiz;
wdenkaffae2b2002-08-17 09:36:01 +000074
wdenk6dd652f2003-06-19 23:40:20 +000075 if (rp->small.topbit == 0) {
76 rtyp = rp->small.type;
77 rlen = rp->small.len;
78 rdat = rp->small.data;
79 rsiz = offsetof (hymod_eerec_t, small.data) + rlen;
80 }
81 else if (rp->medium.nxtbit == 0) {
82 rtyp = rp->medium.type;
83 rlen = rp->medium.len;
84 rdat = rp->medium.data;
85 rsiz = offsetof (hymod_eerec_t, medium.data) + rlen;
86 }
87 else {
88 rtyp = rp->large.type;
89 rlen = rp->large.len;
90 rdat = rp->large.data;
91 rsiz = offsetof (hymod_eerec_t, large.data) + rlen;
92 }
93
94 if (rtyp == 0)
95 break;
96
97 dp += rsiz;
98 if (dp > edp) /* error? */
99 break;
100
101 switch (rtyp) {
102
103 case HYMOD_EEREC_SERNO: /* serial number */
104 if (rlen == sizeof (ulong))
105 memcpy (&ep->serno, rdat, sizeof (ulong));
106 break;
107
108 case HYMOD_EEREC_DATE: /* date */
109 if (rlen == sizeof (hymod_date_t))
110 memcpy (&ep->date, rdat, sizeof (hymod_date_t));
111 break;
112
113 case HYMOD_EEREC_BATCH: /* batch */
114 if (rlen <= HYMOD_MAX_BATCH)
115 memcpy (ep->batch, rdat, ep->batchlen = rlen);
116 break;
117
118 case HYMOD_EEREC_TYPE: /* board type */
119 if (rlen == 1)
120 ep->bdtype = *rdat;
121 break;
122
123 case HYMOD_EEREC_REV: /* board revision */
124 if (rlen == 1)
125 ep->bdrev = *rdat;
126 break;
127
128 case HYMOD_EEREC_SDRAM: /* sdram size(s) */
129 if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) {
130 int i;
131
132 for (i = 0; i < rlen; i++)
133 ep->sdramsz[i] = rdat[i];
134 ep->nsdram = rlen;
135 }
136 break;
137
138 case HYMOD_EEREC_FLASH: /* flash size(s) */
139 if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) {
140 int i;
141
142 for (i = 0; i < rlen; i++)
143 ep->flashsz[i] = rdat[i];
144 ep->nflash = rlen;
145 }
146 break;
147
148 case HYMOD_EEREC_ZBT: /* zbt ram size(s) */
149 if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) {
150 int i;
151
152 for (i = 0; i < rlen; i++)
153 ep->zbtsz[i] = rdat[i];
154 ep->nzbt = rlen;
155 }
156 break;
157
158 case HYMOD_EEREC_XLXTYP: /* xilinx fpga type(s) */
159 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
160 int i;
161
162 for (i = 0; i < rlen; i++)
163 ep->xlx[i].type = rdat[i];
164 ep->nxlx = rlen;
165 }
166 break;
167
168 case HYMOD_EEREC_XLXSPD: /* xilinx fpga speed(s) */
169 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
170 int i;
171
172 for (i = 0; i < rlen; i++)
173 ep->xlx[i].speed = rdat[i];
174 }
175 break;
176
177 case HYMOD_EEREC_XLXTMP: /* xilinx fpga temperature(s) */
178 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
179 int i;
180
181 for (i = 0; i < rlen; i++)
182 ep->xlx[i].temp = rdat[i];
183 }
184 break;
185
186 case HYMOD_EEREC_XLXGRD: /* xilinx fpga grade(s) */
187 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
188 int i;
189
190 for (i = 0; i < rlen; i++)
191 ep->xlx[i].grade = rdat[i];
192 }
193 break;
194
195 case HYMOD_EEREC_CPUTYP: /* CPU type */
196 if (rlen == 1)
197 ep->mpc.type = *rdat;
198 break;
199
200 case HYMOD_EEREC_CPUSPD: /* CPU speed */
201 if (rlen == 1)
202 ep->mpc.cpuspd = *rdat;
203 break;
204
205 case HYMOD_EEREC_CPMSPD: /* CPM speed */
206 if (rlen == 1)
207 ep->mpc.cpmspd = *rdat;
208 break;
209
210 case HYMOD_EEREC_BUSSPD: /* bus speed */
211 if (rlen == 1)
212 ep->mpc.busspd = *rdat;
213 break;
214
215 case HYMOD_EEREC_HSTYPE: /* hs-serial chip type */
216 if (rlen == 1)
217 ep->hss.type = *rdat;
218 break;
219
220 case HYMOD_EEREC_HSCHIN: /* num hs-serial input chans */
221 if (rlen == 1)
222 ep->hss.nchin = *rdat;
223 break;
224
225 case HYMOD_EEREC_HSCHOUT: /* num hs-serial output chans */
226 if (rlen == 1)
227 ep->hss.nchout = *rdat;
228 break;
229
230 default: /* ignore */
231 break;
232 }
wdenkaffae2b2002-08-17 09:36:01 +0000233 }
234
wdenk6dd652f2003-06-19 23:40:20 +0000235 return (1);
wdenkaffae2b2002-08-17 09:36:01 +0000236}
237
238/* maps an ascii "name=value" into a binary eeprom data record */
239typedef
wdenk6dd652f2003-06-19 23:40:20 +0000240 struct _eerec_map {
241 char *name;
242 uint type;
243 uchar *(*handler) \
244 (struct _eerec_map *, uchar *, uchar *, uchar *);
245 uint length;
246 uint maxlen;
247 }
wdenkaffae2b2002-08-17 09:36:01 +0000248eerec_map_t;
249
250static uchar *
wdenk6dd652f2003-06-19 23:40:20 +0000251uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
wdenkaffae2b2002-08-17 09:36:01 +0000252{
wdenk6dd652f2003-06-19 23:40:20 +0000253 uchar *eval;
254 union {
255 uchar cval[4];
256 ushort sval[2];
257 ulong lval;
258 } rdata;
wdenkaffae2b2002-08-17 09:36:01 +0000259
wdenk6dd652f2003-06-19 23:40:20 +0000260 rdata.lval = simple_strtol (val, (char **)&eval, 10);
wdenkaffae2b2002-08-17 09:36:01 +0000261
wdenk6dd652f2003-06-19 23:40:20 +0000262 if (eval == val || *eval != '\0') {
263 printf ("%s rec (%s) is not a valid uint\n",
264 rp->name, val);
265 return (NULL);
wdenkaffae2b2002-08-17 09:36:01 +0000266 }
wdenkaffae2b2002-08-17 09:36:01 +0000267
wdenk6dd652f2003-06-19 23:40:20 +0000268 if (dp + 2 + rp->length > edp) {
269 printf ("can't fit %s rec into eeprom\n", rp->name);
270 return (NULL);
wdenkaffae2b2002-08-17 09:36:01 +0000271 }
wdenkaffae2b2002-08-17 09:36:01 +0000272
wdenk6dd652f2003-06-19 23:40:20 +0000273 *dp++ = rp->type;
274 *dp++ = rp->length;
wdenkaffae2b2002-08-17 09:36:01 +0000275
wdenk6dd652f2003-06-19 23:40:20 +0000276 switch (rp->length) {
wdenkaffae2b2002-08-17 09:36:01 +0000277
wdenk6dd652f2003-06-19 23:40:20 +0000278 case 1:
279 if (rdata.lval >= 256) {
280 printf ("%s rec value (%lu) out of range (0-255)\n",
281 rp->name, rdata.lval);
282 return (NULL);
283 }
284 *dp++ = rdata.cval[3];
285 break;
286
287 case 2:
288 if (rdata.lval >= 65536) {
289 printf ("%s rec value (%lu) out of range (0-65535)\n",
290 rp->name, rdata.lval);
291 return (NULL);
292 }
293 memcpy (dp, &rdata.sval[1], 2);
294 dp += 2;
295 break;
296
297 case 4:
298 memcpy (dp, &rdata.lval, 4);
299 dp += 4;
300 break;
301
302 default:
303 printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length);
304 return (NULL);
305 }
306
307 return (dp);
wdenkaffae2b2002-08-17 09:36:01 +0000308}
309
310static uchar *
wdenk6dd652f2003-06-19 23:40:20 +0000311date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
wdenkaffae2b2002-08-17 09:36:01 +0000312{
wdenk6dd652f2003-06-19 23:40:20 +0000313 hymod_date_t date;
314 uchar *p = val, *ep;
wdenkaffae2b2002-08-17 09:36:01 +0000315
wdenk6dd652f2003-06-19 23:40:20 +0000316 date.year = simple_strtol (p, (char **)&ep, 10);
317 if (ep == p || *ep++ != '-') {
wdenkaffae2b2002-08-17 09:36:01 +0000318bad_date:
wdenk6dd652f2003-06-19 23:40:20 +0000319 printf ("%s rec (%s) is not a valid date\n", rp->name, val);
320 return (NULL);
321 }
wdenkaffae2b2002-08-17 09:36:01 +0000322
wdenk6dd652f2003-06-19 23:40:20 +0000323 date.month = simple_strtol (p = ep, (char **)&ep, 10);
324 if (ep == p || *ep++ != '-' || date.month == 0 || date.month > 12)
325 goto bad_date;
wdenkaffae2b2002-08-17 09:36:01 +0000326
wdenk6dd652f2003-06-19 23:40:20 +0000327 date.day = simple_strtol (p = ep, (char **)&ep, 10);
328 if (ep == p || *ep != '\0' || date.day == 0 || date.day > 31)
329 goto bad_date;
wdenkaffae2b2002-08-17 09:36:01 +0000330
wdenk6dd652f2003-06-19 23:40:20 +0000331 if (dp + 2 + sizeof (hymod_date_t) > edp) {
332 printf ("can't fit %s rec into eeprom\n", rp->name);
333 return (NULL);
334 }
wdenkaffae2b2002-08-17 09:36:01 +0000335
wdenk6dd652f2003-06-19 23:40:20 +0000336 *dp++ = rp->type;
337 *dp++ = sizeof (hymod_date_t);
338 memcpy (dp, &date, sizeof (hymod_date_t));
339 dp += sizeof (hymod_date_t);
wdenkaffae2b2002-08-17 09:36:01 +0000340
wdenk6dd652f2003-06-19 23:40:20 +0000341 return (dp);
wdenkaffae2b2002-08-17 09:36:01 +0000342}
343
344static uchar *
wdenk6dd652f2003-06-19 23:40:20 +0000345string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
wdenkaffae2b2002-08-17 09:36:01 +0000346{
wdenk6dd652f2003-06-19 23:40:20 +0000347 uint len;
wdenkaffae2b2002-08-17 09:36:01 +0000348
wdenk6dd652f2003-06-19 23:40:20 +0000349 if ((len = strlen (val)) > rp->maxlen) {
350 printf ("%s rec (%s) string is too long (%d>%d)\n",
351 rp->name, val, len, rp->maxlen);
352 return (NULL);
353 }
wdenkaffae2b2002-08-17 09:36:01 +0000354
wdenk6dd652f2003-06-19 23:40:20 +0000355 if (dp + 2 + len > edp) {
356 printf ("can't fit %s rec into eeprom\n", rp->name);
357 return (NULL);
358 }
wdenkaffae2b2002-08-17 09:36:01 +0000359
wdenk6dd652f2003-06-19 23:40:20 +0000360 *dp++ = rp->type;
361 *dp++ = len;
362 memcpy (dp, val, len);
363 dp += len;
wdenkaffae2b2002-08-17 09:36:01 +0000364
wdenk6dd652f2003-06-19 23:40:20 +0000365 return (dp);
wdenkaffae2b2002-08-17 09:36:01 +0000366}
367
368static uchar *
wdenk6dd652f2003-06-19 23:40:20 +0000369bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
wdenkaffae2b2002-08-17 09:36:01 +0000370{
wdenk6dd652f2003-06-19 23:40:20 +0000371 uchar bytes[HYMOD_MAX_BYTES], nbytes = 0;
372 uchar *p = val, *ep;
wdenkaffae2b2002-08-17 09:36:01 +0000373
wdenk6dd652f2003-06-19 23:40:20 +0000374 for (;;) {
wdenkaffae2b2002-08-17 09:36:01 +0000375
wdenk6dd652f2003-06-19 23:40:20 +0000376 if (nbytes >= HYMOD_MAX_BYTES) {
377 printf ("%s rec (%s) byte array too long\n",
378 rp->name, val);
379 return (NULL);
380 }
381
382 bytes[nbytes++] = simple_strtol (p, (char **)&ep, 10);
383
384 if (ep == p || (*ep != '\0' && *ep != ',')) {
385 printf ("%s rec (%s) byte array has invalid uint\n",
386 rp->name, val);
387 return (NULL);
388 }
389
390 if (*ep++ == '\0')
391 break;
392
393 p = ep;
wdenkaffae2b2002-08-17 09:36:01 +0000394 }
395
wdenk6dd652f2003-06-19 23:40:20 +0000396 if (dp + 2 + nbytes > edp) {
397 printf ("can't fit %s rec into eeprom\n", rp->name);
398 return (NULL);
wdenkaffae2b2002-08-17 09:36:01 +0000399 }
400
wdenk6dd652f2003-06-19 23:40:20 +0000401 *dp++ = rp->type;
402 *dp++ = nbytes;
403 memcpy (dp, bytes, nbytes);
404 dp += nbytes;
wdenkaffae2b2002-08-17 09:36:01 +0000405
wdenk6dd652f2003-06-19 23:40:20 +0000406 return (dp);
wdenkaffae2b2002-08-17 09:36:01 +0000407}
408
409static eerec_map_t eerec_map[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000410 /* name type handler len max */
411 { "serno", HYMOD_EEREC_SERNO, uint_handler, 4, 0 },
412 { "date", HYMOD_EEREC_DATE, date_handler, 4, 0 },
413 { "batch", HYMOD_EEREC_BATCH, string_handler, 0, HYMOD_MAX_BATCH },
414 { "type", HYMOD_EEREC_TYPE, uint_handler, 1, 0 },
415 { "rev", HYMOD_EEREC_REV, uint_handler, 1, 0 },
416 { "sdram", HYMOD_EEREC_SDRAM, bytes_handler, 0, HYMOD_MAX_SDRAM },
417 { "flash", HYMOD_EEREC_FLASH, bytes_handler, 0, HYMOD_MAX_FLASH },
418 { "zbt", HYMOD_EEREC_ZBT, bytes_handler, 0, HYMOD_MAX_ZBT },
419 { "xlxtyp", HYMOD_EEREC_XLXTYP, bytes_handler, 0, HYMOD_MAX_XLX },
420 { "xlxspd", HYMOD_EEREC_XLXSPD, bytes_handler, 0, HYMOD_MAX_XLX },
421 { "xlxtmp", HYMOD_EEREC_XLXTMP, bytes_handler, 0, HYMOD_MAX_XLX },
422 { "xlxgrd", HYMOD_EEREC_XLXGRD, bytes_handler, 0, HYMOD_MAX_XLX },
423 { "cputyp", HYMOD_EEREC_CPUTYP, uint_handler, 1, 0 },
424 { "cpuspd", HYMOD_EEREC_CPUSPD, uint_handler, 1, 0 },
425 { "cpmspd", HYMOD_EEREC_CPMSPD, uint_handler, 1, 0 },
426 { "busspd", HYMOD_EEREC_BUSSPD, uint_handler, 1, 0 },
427 { "hstype", HYMOD_EEREC_HSTYPE, uint_handler, 1, 0 },
428 { "hschin", HYMOD_EEREC_HSCHIN, uint_handler, 1, 0 },
429 { "hschout", HYMOD_EEREC_HSCHOUT, uint_handler, 1, 0 },
wdenkaffae2b2002-08-17 09:36:01 +0000430};
431
432static int neerecs = sizeof eerec_map / sizeof eerec_map[0];
433
434static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp;
435
436static int
wdenk6dd652f2003-06-19 23:40:20 +0000437eerec_callback (uchar *name, uchar *val)
wdenkaffae2b2002-08-17 09:36:01 +0000438{
wdenk6dd652f2003-06-19 23:40:20 +0000439 eerec_map_t *rp;
wdenkaffae2b2002-08-17 09:36:01 +0000440
wdenk6dd652f2003-06-19 23:40:20 +0000441 for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++)
442 if (strcmp (name, rp->name) == 0)
443 break;
wdenkaffae2b2002-08-17 09:36:01 +0000444
wdenk6dd652f2003-06-19 23:40:20 +0000445 if (rp >= &eerec_map[neerecs])
446 return (0);
wdenkaffae2b2002-08-17 09:36:01 +0000447
wdenk6dd652f2003-06-19 23:40:20 +0000448 if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL)
449 return (0);
wdenkaffae2b2002-08-17 09:36:01 +0000450
wdenk6dd652f2003-06-19 23:40:20 +0000451 return (1);
wdenkaffae2b2002-08-17 09:36:01 +0000452}
453
wdenk6dd652f2003-06-19 23:40:20 +0000454static int
455hymod_eeprom_fetch(int which, char *filename, ulong addr)
wdenkaffae2b2002-08-17 09:36:01 +0000456{
wdenk6dd652f2003-06-19 23:40:20 +0000457 unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \
458 (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
459 hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0];
460 ulong crc;
wdenkaffae2b2002-08-17 09:36:01 +0000461
wdenk6dd652f2003-06-19 23:40:20 +0000462 hp->id = HYMOD_EEPROM_ID;
463 hp->ver = HYMOD_EEPROM_VER;
wdenkaffae2b2002-08-17 09:36:01 +0000464
wdenk6dd652f2003-06-19 23:40:20 +0000465 dp = sdp = (uchar *)(hp + 1);
466 edp = dp + HYMOD_EEPROM_MAXLEN;
wdenkaffae2b2002-08-17 09:36:01 +0000467
wdenk6dd652f2003-06-19 23:40:20 +0000468 if (fetch_and_parse (filename, addr, eerec_callback) == 0)
469 return (0);
wdenkaffae2b2002-08-17 09:36:01 +0000470
wdenk6dd652f2003-06-19 23:40:20 +0000471 hp->len = dp - sdp;
wdenkaffae2b2002-08-17 09:36:01 +0000472
wdenk6dd652f2003-06-19 23:40:20 +0000473 crc = crc32 (0, data, dp - data);
474 memcpy (dp, &crc, sizeof (ulong));
475 dp += sizeof (ulong);
wdenkaffae2b2002-08-17 09:36:01 +0000476
wdenk6dd652f2003-06-19 23:40:20 +0000477 eeprom_write (dev_addr, 0, data, dp - data);
wdenkaffae2b2002-08-17 09:36:01 +0000478
wdenk6dd652f2003-06-19 23:40:20 +0000479 return (1);
wdenkaffae2b2002-08-17 09:36:01 +0000480}
481
482static char *type_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000483 "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY"
wdenkaffae2b2002-08-17 09:36:01 +0000484};
485
486static char *xlxtyp_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000487 "NONE", "XCV300E", "XCV400E", "XCV600E"
wdenkaffae2b2002-08-17 09:36:01 +0000488};
489
490static char *xlxspd_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000491 "NONE", "6", "7", "8"
wdenkaffae2b2002-08-17 09:36:01 +0000492};
493
494static char *xlxtmp_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000495 "NONE", "COM", "IND"
wdenkaffae2b2002-08-17 09:36:01 +0000496};
497
498static char *xlxgrd_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000499 "NONE", "NORMAL", "ENGSAMP"
wdenkaffae2b2002-08-17 09:36:01 +0000500};
501
502static char *cputyp_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000503 "NONE", "MPC8260"
wdenkaffae2b2002-08-17 09:36:01 +0000504};
505
506static char *clk_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000507 "NONE", "33", "66", "100", "133", "166", "200"
wdenkaffae2b2002-08-17 09:36:01 +0000508};
509
510static char *hstype_vals[] = {
wdenk6dd652f2003-06-19 23:40:20 +0000511 "NONE", "AMCC-S2064A"
wdenkaffae2b2002-08-17 09:36:01 +0000512};
513
514static void
wdenk6dd652f2003-06-19 23:40:20 +0000515print_mem (char *l, char *s, uchar n, uchar a[])
wdenkaffae2b2002-08-17 09:36:01 +0000516{
wdenk6dd652f2003-06-19 23:40:20 +0000517 if (n > 0) {
518 if (n == 1)
519 printf ("%s%dMB %s", s, 1 << (a[0] - 20), l);
520 else {
521 ulong t = 0;
522 int i;
wdenkaffae2b2002-08-17 09:36:01 +0000523
wdenk6dd652f2003-06-19 23:40:20 +0000524 for (i = 0; i < n; i++)
525 t += 1 << (a[i] - 20);
wdenkaffae2b2002-08-17 09:36:01 +0000526
wdenk6dd652f2003-06-19 23:40:20 +0000527 printf ("%s%luMB %s (%d banks:", s, t, l, n);
wdenkaffae2b2002-08-17 09:36:01 +0000528
wdenk6dd652f2003-06-19 23:40:20 +0000529 for (i = 0; i < n; i++)
530 printf ("%dMB%s",
531 1 << (a[i] - 20),
532 (i == n - 1) ? ")" : ",");
533 }
wdenkaffae2b2002-08-17 09:36:01 +0000534 }
wdenk6dd652f2003-06-19 23:40:20 +0000535 else
536 printf ("%sNO %s", s, l);
wdenkaffae2b2002-08-17 09:36:01 +0000537}
538
539void
wdenk6dd652f2003-06-19 23:40:20 +0000540hymod_eeprom_print (hymod_eeprom_t *ep)
wdenkaffae2b2002-08-17 09:36:01 +0000541{
wdenk6dd652f2003-06-19 23:40:20 +0000542 int i;
wdenkaffae2b2002-08-17 09:36:01 +0000543
wdenk6dd652f2003-06-19 23:40:20 +0000544 printf (" Hymod %s board, rev %03d\n",
545 type_vals[ep->bdtype], ep->bdrev);
wdenkaffae2b2002-08-17 09:36:01 +0000546
wdenk6dd652f2003-06-19 23:40:20 +0000547 printf (" serial #: %010lu, date %04d-%02d-%02d",
548 ep->serno, ep->date.year, ep->date.month, ep->date.day);
549 if (ep->batchlen > 0)
550 printf (", batch \"%.*s\"", ep->batchlen, ep->batch);
551 puts ("\n");
wdenkaffae2b2002-08-17 09:36:01 +0000552
wdenk6dd652f2003-06-19 23:40:20 +0000553 switch (ep->bdtype) {
wdenkaffae2b2002-08-17 09:36:01 +0000554
wdenk6dd652f2003-06-19 23:40:20 +0000555 case HYMOD_BDTYPE_IO:
556 case HYMOD_BDTYPE_CLP:
557 case HYMOD_BDTYPE_DSP:
558 printf (" Motorola %s CPU, speeds: %s/%s/%s",
559 cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd],
560 clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]);
wdenkaffae2b2002-08-17 09:36:01 +0000561
wdenk6dd652f2003-06-19 23:40:20 +0000562 print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz);
wdenkaffae2b2002-08-17 09:36:01 +0000563
wdenk6dd652f2003-06-19 23:40:20 +0000564 print_mem ("FLASH", ", ", ep->nflash, ep->flashsz);
wdenkaffae2b2002-08-17 09:36:01 +0000565
wdenk6dd652f2003-06-19 23:40:20 +0000566 puts ("\n");
wdenkaffae2b2002-08-17 09:36:01 +0000567
wdenk6dd652f2003-06-19 23:40:20 +0000568 print_mem ("ZBT", " ", ep->nzbt, ep->zbtsz);
wdenkaffae2b2002-08-17 09:36:01 +0000569
wdenk6dd652f2003-06-19 23:40:20 +0000570 if (ep->nxlx > 0) {
571 hymod_xlx_t *xp;
wdenkaffae2b2002-08-17 09:36:01 +0000572
wdenk6dd652f2003-06-19 23:40:20 +0000573 if (ep->nxlx == 1) {
574 xp = &ep->xlx[0];
575 printf (", Xilinx %s FPGA (%s/%s/%s)",
576 xlxtyp_vals[xp->type],
577 xlxspd_vals[xp->speed],
578 xlxtmp_vals[xp->temp],
579 xlxgrd_vals[xp->grade]);
580 }
581 else {
582 printf (", %d Xilinx FPGAs (", ep->nxlx);
583 for (i = 0; i < ep->nxlx; i++) {
584 xp = &ep->xlx[i];
585 printf ("%s[%s/%s/%s]%s",
586 xlxtyp_vals[xp->type],
587 xlxspd_vals[xp->speed],
588 xlxtmp_vals[xp->temp],
589 xlxgrd_vals[xp->grade],
590 (i == ep->nxlx - 1) ? ")" : ", ");
591 }
592 }
wdenkaffae2b2002-08-17 09:36:01 +0000593 }
wdenk6dd652f2003-06-19 23:40:20 +0000594 else
595 puts(", NO FPGAs");
596
597 puts ("\n");
598
599 if (ep->hss.type > 0)
600 printf (" High Speed Serial: "
601 "%s, %d input%s, %d output%s\n",
602 hstype_vals[ep->hss.type],
603 ep->hss.nchin,
604 (ep->hss.nchin == 1 ? "" : "s"),
605 ep->hss.nchout,
606 (ep->hss.nchout == 1 ? "" : "s"));
607 break;
608
609 case HYMOD_BDTYPE_INPUT:
610 case HYMOD_BDTYPE_ALTINPUT:
611 case HYMOD_BDTYPE_DISPLAY:
612 break;
613
614 default:
615 /* crap! */
616 printf (" UNKNOWN BOARD TYPE: %d\n", ep->bdtype);
617 break;
wdenkaffae2b2002-08-17 09:36:01 +0000618 }
wdenk6dd652f2003-06-19 23:40:20 +0000619}
wdenkaffae2b2002-08-17 09:36:01 +0000620
wdenk6dd652f2003-06-19 23:40:20 +0000621int
622hymod_eeprom_read (int which, hymod_eeprom_t *ep)
623{
624 char *label = which ? "mezzanine" : "main";
625 unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \
626 (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
627 char filename[50], prompt[50], *dir;
628 int serno, count = 0, rc;
wdenkaffae2b2002-08-17 09:36:01 +0000629
wdenk6dd652f2003-06-19 23:40:20 +0000630 rc = eeprom_probe (dev_addr, 0);
wdenkaffae2b2002-08-17 09:36:01 +0000631
wdenk6dd652f2003-06-19 23:40:20 +0000632 if (rc > 0) {
633 printf ("*** probe for eeprom failed with code %d\n", rc);
634 return (0);
635 }
wdenkaffae2b2002-08-17 09:36:01 +0000636
wdenk6dd652f2003-06-19 23:40:20 +0000637 if (rc < 0)
638 return (rc);
639
640 sprintf (prompt, "Enter %s board serial number: ", label);
641
642 if ((dir = getenv ("bddb_cfgdir")) == NULL)
643 dir = def_bddb_cfgdir;
644
645 for (;;) {
646 int rc;
647
648 if (hymod_eeprom_load (which, ep))
649 return (1);
650
651 printf ("*** %s board EEPROM contents are %sinvalid\n",
652 label, count == 0 ? "" : "STILL ");
653
654 puts ("*** will fetch from server (Ctrl-C to abort)\n");
655
656 serno = hymod_get_serno (prompt);
657
658 if (serno < 0) {
659 if (serno == -1)
660 puts ("\n*** interrupted!");
661 else
662 puts ("\n*** timeout!");
663 puts (" - ignoring eeprom contents\n");
664 return (0);
665 }
666
667 sprintf (filename, "%s/%010d.cfg", dir, serno);
668
669 printf ("*** fetching %s board EEPROM contents from server\n",
670 label);
671
672 rc = hymod_eeprom_fetch (which, filename, CFG_LOAD_ADDR);
673
674 if (rc == 0) {
675 puts ("*** fetch failed - ignoring eeprom contents\n");
676 return (0);
677 }
678
679 count++;
680 }
wdenkaffae2b2002-08-17 09:36:01 +0000681}