3 * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
27 /* imports from fetch.c */
28 extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
30 /* imports from input.c */
31 extern int hymod_get_serno (const char *);
33 /* this is relative to the root of the server's tftp directory */
34 static char *def_bddb_cfgdir = "/hymod/bddb";
37 hymod_eeprom_load (int which, hymod_eeprom_t *ep)
39 unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \
40 (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
42 uchar data[HYMOD_EEPROM_SIZE], *dp, *edp;
46 memset (ep, 0, sizeof *ep);
47 memset (data, 0, HYMOD_EEPROM_SIZE);
50 hp = (hymod_eehdr_t *)data;
51 eeprom_read (dev_addr, offset, (uchar *)hp, sizeof (*hp));
52 offset += sizeof (*hp);
54 if (hp->id != HYMOD_EEPROM_ID || hp->ver > HYMOD_EEPROM_VER ||
55 (len = hp->len) > HYMOD_EEPROM_MAXLEN)
58 dp = (uchar *)(hp + 1); edp = dp + len;
59 eeprom_read (dev_addr, offset, dp, len);
62 eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong));
64 if (crc32 (0, data, edp - data) != crc)
70 hymod_eerec_t *rp = (hymod_eerec_t *)dp;
75 if (rp->small.topbit == 0) {
76 rtyp = rp->small.type;
78 rdat = rp->small.data;
79 rsiz = offsetof (hymod_eerec_t, small.data) + rlen;
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;
88 rtyp = rp->large.type;
90 rdat = rp->large.data;
91 rsiz = offsetof (hymod_eerec_t, large.data) + rlen;
98 if (dp > edp) /* error? */
103 case HYMOD_EEREC_SERNO: /* serial number */
104 if (rlen == sizeof (ulong))
105 memcpy (&ep->serno, rdat, sizeof (ulong));
108 case HYMOD_EEREC_DATE: /* date */
109 if (rlen == sizeof (hymod_date_t))
110 memcpy (&ep->date, rdat, sizeof (hymod_date_t));
113 case HYMOD_EEREC_BATCH: /* batch */
114 if (rlen <= HYMOD_MAX_BATCH)
115 memcpy (ep->batch, rdat, ep->batchlen = rlen);
118 case HYMOD_EEREC_TYPE: /* board type */
123 case HYMOD_EEREC_REV: /* board revision */
128 case HYMOD_EEREC_SDRAM: /* sdram size(s) */
129 if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) {
132 for (i = 0; i < rlen; i++)
133 ep->sdramsz[i] = rdat[i];
138 case HYMOD_EEREC_FLASH: /* flash size(s) */
139 if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) {
142 for (i = 0; i < rlen; i++)
143 ep->flashsz[i] = rdat[i];
148 case HYMOD_EEREC_ZBT: /* zbt ram size(s) */
149 if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) {
152 for (i = 0; i < rlen; i++)
153 ep->zbtsz[i] = rdat[i];
158 case HYMOD_EEREC_XLXTYP: /* xilinx fpga type(s) */
159 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
162 for (i = 0; i < rlen; i++)
163 ep->xlx[i].type = rdat[i];
168 case HYMOD_EEREC_XLXSPD: /* xilinx fpga speed(s) */
169 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
172 for (i = 0; i < rlen; i++)
173 ep->xlx[i].speed = rdat[i];
177 case HYMOD_EEREC_XLXTMP: /* xilinx fpga temperature(s) */
178 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
181 for (i = 0; i < rlen; i++)
182 ep->xlx[i].temp = rdat[i];
186 case HYMOD_EEREC_XLXGRD: /* xilinx fpga grade(s) */
187 if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
190 for (i = 0; i < rlen; i++)
191 ep->xlx[i].grade = rdat[i];
195 case HYMOD_EEREC_CPUTYP: /* CPU type */
197 ep->mpc.type = *rdat;
200 case HYMOD_EEREC_CPUSPD: /* CPU speed */
202 ep->mpc.cpuspd = *rdat;
205 case HYMOD_EEREC_CPMSPD: /* CPM speed */
207 ep->mpc.cpmspd = *rdat;
210 case HYMOD_EEREC_BUSSPD: /* bus speed */
212 ep->mpc.busspd = *rdat;
215 case HYMOD_EEREC_HSTYPE: /* hs-serial chip type */
217 ep->hss.type = *rdat;
220 case HYMOD_EEREC_HSCHIN: /* num hs-serial input chans */
222 ep->hss.nchin = *rdat;
225 case HYMOD_EEREC_HSCHOUT: /* num hs-serial output chans */
227 ep->hss.nchout = *rdat;
230 default: /* ignore */
238 /* maps an ascii "name=value" into a binary eeprom data record */
244 (struct _eerec_map *, uchar *, uchar *, uchar *);
251 uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
260 rdata.lval = simple_strtol (val, (char **)&eval, 10);
262 if (eval == val || *eval != '\0') {
263 printf ("%s rec (%s) is not a valid uint\n",
268 if (dp + 2 + rp->length > edp) {
269 printf ("can't fit %s rec into eeprom\n", rp->name);
276 switch (rp->length) {
279 if (rdata.lval >= 256) {
280 printf ("%s rec value (%lu) out of range (0-255)\n",
281 rp->name, rdata.lval);
284 *dp++ = rdata.cval[3];
288 if (rdata.lval >= 65536) {
289 printf ("%s rec value (%lu) out of range (0-65535)\n",
290 rp->name, rdata.lval);
293 memcpy (dp, &rdata.sval[1], 2);
298 memcpy (dp, &rdata.lval, 4);
303 printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length);
311 date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
316 date.year = simple_strtol (p, (char **)&ep, 10);
317 if (ep == p || *ep++ != '-') {
319 printf ("%s rec (%s) is not a valid date\n", rp->name, val);
323 date.month = simple_strtol (p = ep, (char **)&ep, 10);
324 if (ep == p || *ep++ != '-' || date.month == 0 || date.month > 12)
327 date.day = simple_strtol (p = ep, (char **)&ep, 10);
328 if (ep == p || *ep != '\0' || date.day == 0 || date.day > 31)
331 if (dp + 2 + sizeof (hymod_date_t) > edp) {
332 printf ("can't fit %s rec into eeprom\n", rp->name);
337 *dp++ = sizeof (hymod_date_t);
338 memcpy (dp, &date, sizeof (hymod_date_t));
339 dp += sizeof (hymod_date_t);
345 string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
349 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);
355 if (dp + 2 + len > edp) {
356 printf ("can't fit %s rec into eeprom\n", rp->name);
362 memcpy (dp, val, len);
369 bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
371 uchar bytes[HYMOD_MAX_BYTES], nbytes = 0;
376 if (nbytes >= HYMOD_MAX_BYTES) {
377 printf ("%s rec (%s) byte array too long\n",
382 bytes[nbytes++] = simple_strtol (p, (char **)&ep, 10);
384 if (ep == p || (*ep != '\0' && *ep != ',')) {
385 printf ("%s rec (%s) byte array has invalid uint\n",
396 if (dp + 2 + nbytes > edp) {
397 printf ("can't fit %s rec into eeprom\n", rp->name);
403 memcpy (dp, bytes, nbytes);
409 static eerec_map_t eerec_map[] = {
410 /* 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 },
432 static int neerecs = sizeof eerec_map / sizeof eerec_map[0];
434 static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp;
437 eerec_callback (uchar *name, uchar *val)
441 for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++)
442 if (strcmp (name, rp->name) == 0)
445 if (rp >= &eerec_map[neerecs])
448 if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL)
455 hymod_eeprom_fetch(int which, char *filename, ulong addr)
457 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];
462 hp->id = HYMOD_EEPROM_ID;
463 hp->ver = HYMOD_EEPROM_VER;
465 dp = sdp = (uchar *)(hp + 1);
466 edp = dp + HYMOD_EEPROM_MAXLEN;
468 if (fetch_and_parse (filename, addr, eerec_callback) == 0)
473 crc = crc32 (0, data, dp - data);
474 memcpy (dp, &crc, sizeof (ulong));
475 dp += sizeof (ulong);
477 eeprom_write (dev_addr, 0, data, dp - data);
482 static char *type_vals[] = {
483 "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY"
486 static char *xlxtyp_vals[] = {
487 "NONE", "XCV300E", "XCV400E", "XCV600E"
490 static char *xlxspd_vals[] = {
491 "NONE", "6", "7", "8"
494 static char *xlxtmp_vals[] = {
498 static char *xlxgrd_vals[] = {
499 "NONE", "NORMAL", "ENGSAMP"
502 static char *cputyp_vals[] = {
506 static char *clk_vals[] = {
507 "NONE", "33", "66", "100", "133", "166", "200"
510 static char *hstype_vals[] = {
511 "NONE", "AMCC-S2064A"
515 print_mem (char *l, char *s, uchar n, uchar a[])
519 printf ("%s%dMB %s", s, 1 << (a[0] - 20), l);
524 for (i = 0; i < n; i++)
525 t += 1 << (a[i] - 20);
527 printf ("%s%luMB %s (%d banks:", s, t, l, n);
529 for (i = 0; i < n; i++)
532 (i == n - 1) ? ")" : ",");
536 printf ("%sNO %s", s, l);
540 hymod_eeprom_print (hymod_eeprom_t *ep)
544 printf (" Hymod %s board, rev %03d\n",
545 type_vals[ep->bdtype], ep->bdrev);
547 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);
553 switch (ep->bdtype) {
555 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]);
562 print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz);
564 print_mem ("FLASH", ", ", ep->nflash, ep->flashsz);
568 print_mem ("ZBT", " ", ep->nzbt, ep->zbtsz);
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]);
582 printf (", %d Xilinx FPGAs (", ep->nxlx);
583 for (i = 0; i < ep->nxlx; 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) ? ")" : ", ");
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],
604 (ep->hss.nchin == 1 ? "" : "s"),
606 (ep->hss.nchout == 1 ? "" : "s"));
609 case HYMOD_BDTYPE_INPUT:
610 case HYMOD_BDTYPE_ALTINPUT:
611 case HYMOD_BDTYPE_DISPLAY:
616 printf (" UNKNOWN BOARD TYPE: %d\n", ep->bdtype);
622 hymod_eeprom_read (int which, hymod_eeprom_t *ep)
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;
630 rc = eeprom_probe (dev_addr, 0);
633 printf ("*** probe for eeprom failed with code %d\n", rc);
640 sprintf (prompt, "Enter %s board serial number: ", label);
642 if ((dir = getenv ("bddb_cfgdir")) == NULL)
643 dir = def_bddb_cfgdir;
648 if (hymod_eeprom_load (which, ep))
651 printf ("*** %s board EEPROM contents are %sinvalid\n",
652 label, count == 0 ? "" : "STILL ");
654 puts ("*** will fetch from server (Ctrl-C to abort)\n");
656 serno = hymod_get_serno (prompt);
660 puts ("\n*** interrupted!");
662 puts ("\n*** timeout!");
663 puts (" - ignoring eeprom contents\n");
667 sprintf (filename, "%s/%010d.cfg", dir, serno);
669 printf ("*** fetching %s board EEPROM contents from server\n",
672 rc = hymod_eeprom_fetch (which, filename, CFG_LOAD_ADDR);
675 puts ("*** fetch failed - ignoring eeprom contents\n");