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_MAXLEN
], *dp
, *edp
;
46 memset (ep
, 0, sizeof *ep
);
48 eeprom_read (dev_addr
, offset
, (uchar
*)&hdr
, sizeof (hdr
));
49 offset
+= sizeof (hdr
);
51 if (hdr
.id
!= HYMOD_EEPROM_ID
|| hdr
.ver
> HYMOD_EEPROM_VER
||
52 (len
= hdr
.len
) > HYMOD_EEPROM_MAXLEN
)
55 eeprom_read (dev_addr
, offset
, data
, len
);
58 eeprom_read (dev_addr
, offset
, (uchar
*)&crc
, sizeof (ulong
));
59 offset
+= sizeof (ulong
);
61 if (crc32 (crc32 (0, (uchar
*)&hdr
, sizeof hdr
), data
, len
) != crc
)
65 dp
= data
; edp
= dp
+ len
;
72 if ((rtyp
& 0x80) == 0)
75 uchar islarge
= rtyp
& 0x40;
77 rtyp
= ((rtyp
& 0x3f) << 8) | *dp
++;
79 rtyp
= (rtyp
<< 8) | *dp
++;
80 rtyp
= (rtyp
<< 8) | *dp
++;
84 rlen
= (rlen
<< 8) | *dp
++;
86 rlen
= (rlen
<< 8) | *dp
++;
87 rlen
= (rlen
<< 8) | *dp
++;
97 if (dp
> edp
) /* error? */
102 case HYMOD_EEREC_SERNO
: /* serial number */
103 if (rlen
== sizeof (ulong
))
105 ((ulong
)rdat
[0] << 24) | \
106 ((ulong
)rdat
[1] << 16) | \
107 ((ulong
)rdat
[2] << 8) | \
111 case HYMOD_EEREC_DATE
: /* date */
112 if (rlen
== sizeof (hymod_date_t
)) {
113 ep
->date
.year
= ((ushort
)rdat
[0] << 8) | \
115 ep
->date
.month
= rdat
[2];
116 ep
->date
.day
= rdat
[3];
120 case HYMOD_EEREC_BATCH
: /* batch */
121 if (rlen
<= HYMOD_MAX_BATCH
)
122 memcpy (ep
->batch
, rdat
, ep
->batchlen
= rlen
);
125 case HYMOD_EEREC_TYPE
: /* board type */
130 case HYMOD_EEREC_REV
: /* board revision */
135 case HYMOD_EEREC_SDRAM
: /* sdram size(s) */
136 if (rlen
> 0 && rlen
<= HYMOD_MAX_SDRAM
) {
139 for (i
= 0; i
< rlen
; i
++)
140 ep
->sdramsz
[i
] = rdat
[i
];
145 case HYMOD_EEREC_FLASH
: /* flash size(s) */
146 if (rlen
> 0 && rlen
<= HYMOD_MAX_FLASH
) {
149 for (i
= 0; i
< rlen
; i
++)
150 ep
->flashsz
[i
] = rdat
[i
];
155 case HYMOD_EEREC_ZBT
: /* zbt ram size(s) */
156 if (rlen
> 0 && rlen
<= HYMOD_MAX_ZBT
) {
159 for (i
= 0; i
< rlen
; i
++)
160 ep
->zbtsz
[i
] = rdat
[i
];
165 case HYMOD_EEREC_XLXTYP
: /* xilinx fpga type(s) */
166 if (rlen
> 0 && rlen
<= HYMOD_MAX_XLX
) {
169 for (i
= 0; i
< rlen
; i
++)
170 ep
->xlx
[i
].type
= rdat
[i
];
175 case HYMOD_EEREC_XLXSPD
: /* xilinx fpga speed(s) */
176 if (rlen
> 0 && rlen
<= HYMOD_MAX_XLX
) {
179 for (i
= 0; i
< rlen
; i
++)
180 ep
->xlx
[i
].speed
= rdat
[i
];
184 case HYMOD_EEREC_XLXTMP
: /* xilinx fpga temperature(s) */
185 if (rlen
> 0 && rlen
<= HYMOD_MAX_XLX
) {
188 for (i
= 0; i
< rlen
; i
++)
189 ep
->xlx
[i
].temp
= rdat
[i
];
193 case HYMOD_EEREC_XLXGRD
: /* xilinx fpga grade(s) */
194 if (rlen
> 0 && rlen
<= HYMOD_MAX_XLX
) {
197 for (i
= 0; i
< rlen
; i
++)
198 ep
->xlx
[i
].grade
= rdat
[i
];
202 case HYMOD_EEREC_CPUTYP
: /* CPU type */
204 ep
->mpc
.type
= *rdat
;
207 case HYMOD_EEREC_CPUSPD
: /* CPU speed */
209 ep
->mpc
.cpuspd
= *rdat
;
212 case HYMOD_EEREC_CPMSPD
: /* CPM speed */
214 ep
->mpc
.cpmspd
= *rdat
;
217 case HYMOD_EEREC_BUSSPD
: /* bus speed */
219 ep
->mpc
.busspd
= *rdat
;
222 case HYMOD_EEREC_HSTYPE
: /* hs-serial chip type */
224 ep
->hss
.type
= *rdat
;
227 case HYMOD_EEREC_HSCHIN
: /* num hs-serial input chans */
229 ep
->hss
.nchin
= *rdat
;
232 case HYMOD_EEREC_HSCHOUT
: /* num hs-serial output chans */
234 ep
->hss
.nchout
= *rdat
;
237 default: /* ignore */
245 /* maps an ascii "name=value" into a binary eeprom data record */
251 (struct _eerec_map
*, uchar
*, uchar
*, uchar
*);
258 uint_handler (eerec_map_t
*rp
, uchar
*val
, uchar
*dp
, uchar
*edp
)
263 lval
= simple_strtol ((char *)val
, &eval
, 10);
265 if ((uchar
*)eval
== val
|| *eval
!= '\0') {
266 printf ("%s rec (%s) is not a valid uint\n", rp
->name
, val
);
270 if (dp
+ 2 + rp
->length
> edp
) {
271 printf ("can't fit %s rec into eeprom\n", rp
->name
);
278 switch (rp
->length
) {
282 printf ("%s rec value (%lu) out of range (0-255)\n",
291 printf ("%s rec value (%lu) out of range (0-65535)\n",
307 printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp
->length
);
315 date_handler (eerec_map_t
*rp
, uchar
*val
, uchar
*dp
, uchar
*edp
)
318 char *p
= (char *)val
;
322 lval
= simple_strtol (p
, &ep
, 10);
323 if (ep
== p
|| *ep
++ != '-') {
325 printf ("%s rec (%s) is not a valid date\n", rp
->name
, val
);
332 lval
= simple_strtol (p
= ep
, &ep
, 10);
333 if (ep
== p
|| *ep
++ != '-' || lval
== 0 || lval
> 12)
337 lval
= simple_strtol (p
= ep
, &ep
, 10);
338 if (ep
== p
|| *ep
!= '\0' || lval
== 0 || lval
> 31)
342 if (dp
+ 2 + rp
->length
> edp
) {
343 printf ("can't fit %s rec into eeprom\n", rp
->name
);
349 *dp
++ = date
.year
>> 8;
358 string_handler (eerec_map_t
*rp
, uchar
*val
, uchar
*dp
, uchar
*edp
)
362 if ((len
= strlen ((char *)val
)) > rp
->maxlen
) {
363 printf ("%s rec (%s) string is too long (%d>%d)\n",
364 rp
->name
, val
, len
, rp
->maxlen
);
368 if (dp
+ 2 + len
> edp
) {
369 printf ("can't fit %s rec into eeprom\n", rp
->name
);
375 memcpy (dp
, val
, len
);
382 bytes_handler (eerec_map_t
*rp
, uchar
*val
, uchar
*dp
, uchar
*edp
)
384 uchar bytes
[HYMOD_MAX_BYTES
], nbytes
, *p
;
387 for (nbytes
= 0, p
= val
; *p
!= '\0'; p
= (uchar
*)ep
) {
390 lval
= simple_strtol ((char *)p
, &ep
, 10);
391 if ((uchar
*)ep
== p
|| (*ep
!= '\0' && *ep
!= ',') || \
393 printf ("%s rec (%s) byte array has invalid uint\n",
397 if (nbytes
>= HYMOD_MAX_BYTES
) {
398 printf ("%s rec (%s) byte array too long\n",
402 bytes
[nbytes
++] = lval
;
408 if (dp
+ 2 + nbytes
> edp
) {
409 printf ("can't fit %s rec into eeprom\n", rp
->name
);
415 memcpy (dp
, bytes
, nbytes
);
421 static eerec_map_t eerec_map
[] = {
422 /* name type handler len max */
423 { "serno", HYMOD_EEREC_SERNO
, uint_handler
, 4, 0 },
424 { "date", HYMOD_EEREC_DATE
, date_handler
, 4, 0 },
425 { "batch", HYMOD_EEREC_BATCH
, string_handler
, 0, HYMOD_MAX_BATCH
},
426 { "type", HYMOD_EEREC_TYPE
, uint_handler
, 1, 0 },
427 { "rev", HYMOD_EEREC_REV
, uint_handler
, 1, 0 },
428 { "sdram", HYMOD_EEREC_SDRAM
, bytes_handler
, 0, HYMOD_MAX_SDRAM
},
429 { "flash", HYMOD_EEREC_FLASH
, bytes_handler
, 0, HYMOD_MAX_FLASH
},
430 { "zbt", HYMOD_EEREC_ZBT
, bytes_handler
, 0, HYMOD_MAX_ZBT
},
431 { "xlxtyp", HYMOD_EEREC_XLXTYP
, bytes_handler
, 0, HYMOD_MAX_XLX
},
432 { "xlxspd", HYMOD_EEREC_XLXSPD
, bytes_handler
, 0, HYMOD_MAX_XLX
},
433 { "xlxtmp", HYMOD_EEREC_XLXTMP
, bytes_handler
, 0, HYMOD_MAX_XLX
},
434 { "xlxgrd", HYMOD_EEREC_XLXGRD
, bytes_handler
, 0, HYMOD_MAX_XLX
},
435 { "cputyp", HYMOD_EEREC_CPUTYP
, uint_handler
, 1, 0 },
436 { "cpuspd", HYMOD_EEREC_CPUSPD
, uint_handler
, 1, 0 },
437 { "cpmspd", HYMOD_EEREC_CPMSPD
, uint_handler
, 1, 0 },
438 { "busspd", HYMOD_EEREC_BUSSPD
, uint_handler
, 1, 0 },
439 { "hstype", HYMOD_EEREC_HSTYPE
, uint_handler
, 1, 0 },
440 { "hschin", HYMOD_EEREC_HSCHIN
, uint_handler
, 1, 0 },
441 { "hschout", HYMOD_EEREC_HSCHOUT
, uint_handler
, 1, 0 },
444 static int neerecs
= sizeof eerec_map
/ sizeof eerec_map
[0];
446 static uchar data
[HYMOD_EEPROM_SIZE
], *sdp
, *dp
, *edp
;
449 eerec_callback (uchar
*name
, uchar
*val
)
453 for (rp
= eerec_map
; rp
< &eerec_map
[neerecs
]; rp
++)
454 if (strcmp ((char *)name
, rp
->name
) == 0)
457 if (rp
>= &eerec_map
[neerecs
])
460 if ((dp
= (*rp
->handler
) (rp
, val
, dp
, edp
)) == NULL
)
467 hymod_eeprom_fetch(int which
, char *filename
, ulong addr
)
469 unsigned dev_addr
= CFG_I2C_EEPROM_ADDR
| \
470 (which
? HYMOD_EEOFF_MEZZ
: HYMOD_EEOFF_MAIN
);
471 hymod_eehdr_t
*hp
= (hymod_eehdr_t
*)&data
[0];
474 memset (hp
, 0, sizeof *hp
);
475 hp
->id
= HYMOD_EEPROM_ID
;
476 hp
->ver
= HYMOD_EEPROM_VER
;
478 dp
= sdp
= (uchar
*)(hp
+ 1);
479 edp
= dp
+ HYMOD_EEPROM_MAXLEN
;
481 if (fetch_and_parse (filename
, addr
, eerec_callback
) == 0)
486 crc
= crc32 (0, data
, dp
- data
);
487 memcpy (dp
, &crc
, sizeof (ulong
));
488 dp
+= sizeof (ulong
);
490 eeprom_write (dev_addr
, 0, data
, dp
- data
);
495 static char *type_vals
[] = {
496 "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY"
499 static char *xlxtyp_vals
[] = {
500 "NONE", "XCV300E", "XCV400E", "XCV600E"
503 static char *xlxspd_vals
[] = {
504 "NONE", "6", "7", "8"
507 static char *xlxtmp_vals
[] = {
511 static char *xlxgrd_vals
[] = {
512 "NONE", "NORMAL", "ENGSAMP"
515 static char *cputyp_vals
[] = {
519 static char *clk_vals
[] = {
520 "NONE", "33", "66", "100", "133", "166", "200"
523 static char *hstype_vals
[] = {
524 "NONE", "AMCC-S2064A"
528 print_mem (char *l
, char *s
, uchar n
, uchar a
[])
532 printf ("%s%dMB %s", s
, 1 << (a
[0] - 20), l
);
537 for (i
= 0; i
< n
; i
++)
538 t
+= 1 << (a
[i
] - 20);
540 printf ("%s%luMB %s (%d banks:", s
, t
, l
, n
);
542 for (i
= 0; i
< n
; i
++)
545 (i
== n
- 1) ? ")" : ",");
549 printf ("%sNO %s", s
, l
);
553 hymod_eeprom_print (hymod_eeprom_t
*ep
)
557 printf (" Hymod %s board, rev %03d\n",
558 type_vals
[ep
->bdtype
], ep
->bdrev
);
560 printf (" serial #: %010lu, date %04d-%02d-%02d",
561 ep
->serno
, ep
->date
.year
, ep
->date
.month
, ep
->date
.day
);
562 if (ep
->batchlen
> 0)
563 printf (", batch \"%.*s\"", ep
->batchlen
, ep
->batch
);
566 switch (ep
->bdtype
) {
568 case HYMOD_BDTYPE_IO
:
569 case HYMOD_BDTYPE_CLP
:
570 case HYMOD_BDTYPE_DSP
:
571 printf (" Motorola %s CPU, speeds: %s/%s/%s",
572 cputyp_vals
[ep
->mpc
.type
], clk_vals
[ep
->mpc
.cpuspd
],
573 clk_vals
[ep
->mpc
.cpmspd
], clk_vals
[ep
->mpc
.busspd
]);
575 print_mem ("SDRAM", ", ", ep
->nsdram
, ep
->sdramsz
);
577 print_mem ("FLASH", ", ", ep
->nflash
, ep
->flashsz
);
581 print_mem ("ZBT", " ", ep
->nzbt
, ep
->zbtsz
);
588 printf (", Xilinx %s FPGA (%s/%s/%s)",
589 xlxtyp_vals
[xp
->type
],
590 xlxspd_vals
[xp
->speed
],
591 xlxtmp_vals
[xp
->temp
],
592 xlxgrd_vals
[xp
->grade
]);
595 printf (", %d Xilinx FPGAs (", ep
->nxlx
);
596 for (i
= 0; i
< ep
->nxlx
; i
++) {
598 printf ("%s[%s/%s/%s]%s",
599 xlxtyp_vals
[xp
->type
],
600 xlxspd_vals
[xp
->speed
],
601 xlxtmp_vals
[xp
->temp
],
602 xlxgrd_vals
[xp
->grade
],
603 (i
== ep
->nxlx
- 1) ? ")" : ", ");
612 if (ep
->hss
.type
> 0)
613 printf (" High Speed Serial: "
614 "%s, %d input%s, %d output%s\n",
615 hstype_vals
[ep
->hss
.type
],
617 (ep
->hss
.nchin
== 1 ? "" : "s"),
619 (ep
->hss
.nchout
== 1 ? "" : "s"));
622 case HYMOD_BDTYPE_INPUT
:
623 case HYMOD_BDTYPE_ALTINPUT
:
624 case HYMOD_BDTYPE_DISPLAY
:
629 printf (" UNKNOWN BOARD TYPE: %d\n", ep
->bdtype
);
635 hymod_eeprom_read (int which
, hymod_eeprom_t
*ep
)
637 char *label
= which
? "mezzanine" : "main";
638 unsigned dev_addr
= CFG_I2C_EEPROM_ADDR
| \
639 (which
? HYMOD_EEOFF_MEZZ
: HYMOD_EEOFF_MAIN
);
640 char filename
[50], prompt
[50], *dir
;
641 int serno
, count
= 0, rc
;
643 rc
= eeprom_probe (dev_addr
, 0);
646 printf ("*** probe for eeprom failed with code %d\n", rc
);
653 sprintf (prompt
, "Enter %s board serial number: ", label
);
655 if ((dir
= getenv ("bddb_cfgdir")) == NULL
)
656 dir
= def_bddb_cfgdir
;
661 if (hymod_eeprom_load (which
, ep
))
664 printf ("*** %s board EEPROM contents are %sinvalid\n",
665 label
, count
== 0 ? "" : "STILL ");
667 puts ("*** will fetch from server (Ctrl-C to abort)\n");
669 serno
= hymod_get_serno (prompt
);
673 puts ("\n*** interrupted!");
675 puts ("\n*** timeout!");
676 puts (" - ignoring eeprom contents\n");
680 sprintf (filename
, "%s/%010d.cfg", dir
, serno
);
682 printf ("*** fetching %s board EEPROM contents from server\n",
685 rc
= hymod_eeprom_fetch (which
, filename
, CFG_LOAD_ADDR
);
688 puts ("*** fetch failed - ignoring eeprom contents\n");