695 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			695 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * (C) Copyright 2001
 | |
|  * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
 | |
|  *
 | |
|  * See file CREDITS for list of people who contributed to this
 | |
|  * project.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU General Public License as
 | |
|  * published by the Free Software Foundation; either version 2 of
 | |
|  * the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program; if not, write to the Free Software
 | |
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 | |
|  * MA 02111-1307 USA
 | |
|  */
 | |
| 
 | |
| #include <common.h>
 | |
| #include <mpc8260.h>
 | |
| 
 | |
| /* imports from fetch.c */
 | |
| extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
 | |
| 
 | |
| /* imports from input.c */
 | |
| extern int hymod_get_serno (const char *);
 | |
| 
 | |
| /* this is relative to the root of the server's tftp directory */
 | |
| static char *def_bddb_cfgdir = "/hymod/bddb";
 | |
| 
 | |
| static int
 | |
| hymod_eeprom_load (int which, hymod_eeprom_t *ep)
 | |
| {
 | |
| 	unsigned dev_addr = CONFIG_SYS_I2C_EEPROM_ADDR | \
 | |
| 		(which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
 | |
| 	unsigned offset = 0;
 | |
| 	uchar data[HYMOD_EEPROM_MAXLEN], *dp, *edp;
 | |
| 	hymod_eehdr_t hdr;
 | |
| 	ulong len, crc;
 | |
| 
 | |
| 	memset (ep, 0, sizeof *ep);
 | |
| 
 | |
| 	eeprom_read (dev_addr, offset, (uchar *)&hdr, sizeof (hdr));
 | |
| 	offset += sizeof (hdr);
 | |
| 
 | |
| 	if (hdr.id != HYMOD_EEPROM_ID || hdr.ver > HYMOD_EEPROM_VER ||
 | |
| 	  (len = hdr.len) > HYMOD_EEPROM_MAXLEN)
 | |
| 	    return (0);
 | |
| 
 | |
| 	eeprom_read (dev_addr, offset, data, len);
 | |
| 	offset += len;
 | |
| 
 | |
| 	eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong));
 | |
| 	offset += sizeof (ulong);
 | |
| 
 | |
| 	if (crc32 (crc32 (0, (uchar *)&hdr, sizeof hdr), data, len) != crc)
 | |
| 		return (0);
 | |
| 
 | |
| 	ep->ver = hdr.ver;
 | |
| 	dp = data; edp = dp + len;
 | |
| 
 | |
| 	for (;;) {
 | |
| 		ulong rtyp;
 | |
| 		uchar rlen, *rdat;
 | |
| 
 | |
| 		rtyp = *dp++;
 | |
| 		if ((rtyp & 0x80) == 0)
 | |
| 			rlen = *dp++;
 | |
| 		else {
 | |
| 			uchar islarge = rtyp & 0x40;
 | |
| 
 | |
| 			rtyp = ((rtyp & 0x3f) << 8) | *dp++;
 | |
| 			if (islarge) {
 | |
| 				rtyp = (rtyp << 8) | *dp++;
 | |
| 				rtyp = (rtyp << 8) | *dp++;
 | |
| 			}
 | |
| 
 | |
| 			rlen = *dp++;
 | |
| 			rlen = (rlen << 8) | *dp++;
 | |
| 			if (islarge) {
 | |
| 				rlen = (rlen << 8) | *dp++;
 | |
| 				rlen = (rlen << 8) | *dp++;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if (rtyp == 0)
 | |
| 			break;
 | |
| 
 | |
| 		rdat = dp;
 | |
| 		dp += rlen;
 | |
| 
 | |
| 		if (dp > edp)	/* error? */
 | |
| 			break;
 | |
| 
 | |
| 		switch (rtyp) {
 | |
| 
 | |
| 		case HYMOD_EEREC_SERNO:		/* serial number */
 | |
| 			if (rlen == sizeof (ulong))
 | |
| 				ep->serno = \
 | |
| 					((ulong)rdat[0] << 24) | \
 | |
| 					((ulong)rdat[1] << 16) | \
 | |
| 					((ulong)rdat[2] << 8) | \
 | |
| 					(ulong)rdat[3];
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_DATE:		/* date */
 | |
| 			if (rlen == sizeof (hymod_date_t)) {
 | |
| 				ep->date.year = ((ushort)rdat[0] << 8) | \
 | |
| 					(ushort)rdat[1];
 | |
| 				ep->date.month = rdat[2];
 | |
| 				ep->date.day = rdat[3];
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_BATCH:		/* batch */
 | |
| 			if (rlen <= HYMOD_MAX_BATCH)
 | |
| 				memcpy (ep->batch, rdat, ep->batchlen = rlen);
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_TYPE:		/* board type */
 | |
| 			if (rlen == 1)
 | |
| 				ep->bdtype = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_REV:		/* board revision */
 | |
| 			if (rlen == 1)
 | |
| 				ep->bdrev = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_SDRAM:		/* sdram size(s) */
 | |
| 			if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) {
 | |
| 				int i;
 | |
| 
 | |
| 				for (i = 0; i < rlen; i++)
 | |
| 					ep->sdramsz[i] = rdat[i];
 | |
| 				ep->nsdram = rlen;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_FLASH:		/* flash size(s) */
 | |
| 			if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) {
 | |
| 				int i;
 | |
| 
 | |
| 				for (i = 0; i < rlen; i++)
 | |
| 					ep->flashsz[i] = rdat[i];
 | |
| 				ep->nflash = rlen;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_ZBT:		/* zbt ram size(s) */
 | |
| 			if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) {
 | |
| 				int i;
 | |
| 
 | |
| 				for (i = 0; i < rlen; i++)
 | |
| 					ep->zbtsz[i] = rdat[i];
 | |
| 				ep->nzbt = rlen;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_XLXTYP:	/* xilinx fpga type(s) */
 | |
| 			if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 | |
| 				int i;
 | |
| 
 | |
| 				for (i = 0; i < rlen; i++)
 | |
| 					ep->xlx[i].type = rdat[i];
 | |
| 				ep->nxlx = rlen;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_XLXSPD:	/* xilinx fpga speed(s) */
 | |
| 			if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 | |
| 				int i;
 | |
| 
 | |
| 				for (i = 0; i < rlen; i++)
 | |
| 					ep->xlx[i].speed = rdat[i];
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_XLXTMP:	/* xilinx fpga temperature(s) */
 | |
| 			if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 | |
| 				int i;
 | |
| 
 | |
| 				for (i = 0; i < rlen; i++)
 | |
| 					ep->xlx[i].temp = rdat[i];
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_XLXGRD:	/* xilinx fpga grade(s) */
 | |
| 			if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 | |
| 				int i;
 | |
| 
 | |
| 				for (i = 0; i < rlen; i++)
 | |
| 					ep->xlx[i].grade = rdat[i];
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_CPUTYP:	/* CPU type */
 | |
| 			if (rlen == 1)
 | |
| 				ep->mpc.type = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_CPUSPD:	/* CPU speed */
 | |
| 			if (rlen == 1)
 | |
| 				ep->mpc.cpuspd = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_CPMSPD:	/* CPM speed */
 | |
| 			if (rlen == 1)
 | |
| 				ep->mpc.cpmspd = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_BUSSPD:	/* bus speed */
 | |
| 			if (rlen == 1)
 | |
| 				ep->mpc.busspd = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_HSTYPE:	/* hs-serial chip type */
 | |
| 			if (rlen == 1)
 | |
| 				ep->hss.type = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_HSCHIN:	/* num hs-serial input chans */
 | |
| 			if (rlen == 1)
 | |
| 				ep->hss.nchin = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		case HYMOD_EEREC_HSCHOUT:	/* num hs-serial output chans */
 | |
| 			if (rlen == 1)
 | |
| 				ep->hss.nchout = *rdat;
 | |
| 			break;
 | |
| 
 | |
| 		default:	/* ignore */
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return (1);
 | |
| }
 | |
| 
 | |
| /* maps an ascii "name=value" into a binary eeprom data record */
 | |
| typedef
 | |
| 	struct _eerec_map {
 | |
| 		char *name;
 | |
| 		uint type;
 | |
| 		uchar *(*handler) \
 | |
| 			(struct _eerec_map *, uchar *, uchar *, uchar *);
 | |
| 		uint length;
 | |
| 		uint maxlen;
 | |
| 	}
 | |
| eerec_map_t;
 | |
| 
 | |
| static uchar *
 | |
| uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 | |
| {
 | |
| 	char *eval;
 | |
| 	ulong lval;
 | |
| 
 | |
| 	lval = simple_strtol ((char *)val, &eval, 10);
 | |
| 
 | |
| 	if ((uchar *)eval == val || *eval != '\0') {
 | |
| 		printf ("%s rec (%s) is not a valid uint\n", rp->name, val);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 
 | |
| 	if (dp + 2 + rp->length > edp) {
 | |
| 		printf ("can't fit %s rec into eeprom\n", rp->name);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 
 | |
| 	*dp++ = rp->type;
 | |
| 	*dp++ = rp->length;
 | |
| 
 | |
| 	switch (rp->length) {
 | |
| 
 | |
| 	case 1:
 | |
| 		if (lval >= 256) {
 | |
| 			printf ("%s rec value (%lu) out of range (0-255)\n",
 | |
| 				rp->name, lval);
 | |
| 			return (NULL);
 | |
| 		}
 | |
| 		*dp++ = lval;
 | |
| 		break;
 | |
| 
 | |
| 	case 2:
 | |
| 		if (lval >= 65536) {
 | |
| 			printf ("%s rec value (%lu) out of range (0-65535)\n",
 | |
| 				rp->name, lval);
 | |
| 			return (NULL);
 | |
| 		}
 | |
| 		*dp++ = lval >> 8;
 | |
| 		*dp++ = lval;
 | |
| 		break;
 | |
| 
 | |
| 	case 4:
 | |
| 		*dp++ = lval >> 24;
 | |
| 		*dp++ = lval >> 16;
 | |
| 		*dp++ = lval >> 8;
 | |
| 		*dp++ = lval;
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 
 | |
| 	return (dp);
 | |
| }
 | |
| 
 | |
| static uchar *
 | |
| date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 | |
| {
 | |
| 	hymod_date_t date;
 | |
| 	char *p = (char *)val;
 | |
| 	char *ep;
 | |
| 	ulong lval;
 | |
| 
 | |
| 	lval = simple_strtol (p, &ep, 10);
 | |
| 	if (ep == p || *ep++ != '-') {
 | |
| bad_date:
 | |
| 		printf ("%s rec (%s) is not a valid date\n", rp->name, val);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 	if (lval >= 65536)
 | |
| 		goto bad_date;
 | |
| 	date.year = lval;
 | |
| 
 | |
| 	lval = simple_strtol (p = ep, &ep, 10);
 | |
| 	if (ep == p || *ep++ != '-' || lval == 0 || lval > 12)
 | |
| 		goto bad_date;
 | |
| 	date.month = lval;
 | |
| 
 | |
| 	lval = simple_strtol (p = ep, &ep, 10);
 | |
| 	if (ep == p || *ep != '\0' || lval == 0 || lval > 31)
 | |
| 		goto bad_date;
 | |
| 	date.day = lval;
 | |
| 
 | |
| 	if (dp + 2 + rp->length > edp) {
 | |
| 		printf ("can't fit %s rec into eeprom\n", rp->name);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 
 | |
| 	*dp++ = rp->type;
 | |
| 	*dp++ = rp->length;
 | |
| 	*dp++ = date.year >> 8;
 | |
| 	*dp++ = date.year;
 | |
| 	*dp++ = date.month;
 | |
| 	*dp++ = date.day;
 | |
| 
 | |
| 	return (dp);
 | |
| }
 | |
| 
 | |
| static uchar *
 | |
| string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 | |
| {
 | |
| 	uint len;
 | |
| 
 | |
| 	if ((len = strlen ((char *)val)) > rp->maxlen) {
 | |
| 		printf ("%s rec (%s) string is too long (%d>%d)\n",
 | |
| 			rp->name, val, len, rp->maxlen);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 
 | |
| 	if (dp + 2 + len > edp) {
 | |
| 		printf ("can't fit %s rec into eeprom\n", rp->name);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 
 | |
| 	*dp++ = rp->type;
 | |
| 	*dp++ = len;
 | |
| 	memcpy (dp, val, len);
 | |
| 	dp += len;
 | |
| 
 | |
| 	return (dp);
 | |
| }
 | |
| 
 | |
| static uchar *
 | |
| bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 | |
| {
 | |
| 	uchar bytes[HYMOD_MAX_BYTES], nbytes, *p;
 | |
| 	char *ep;
 | |
| 
 | |
| 	for (nbytes = 0, p = val; *p != '\0'; p = (uchar *)ep) {
 | |
| 		ulong lval;
 | |
| 
 | |
| 		lval = simple_strtol ((char *)p, &ep, 10);
 | |
| 		if ((uchar *)ep == p || (*ep != '\0' && *ep != ',') || \
 | |
| 		    lval >= 256) {
 | |
| 			printf ("%s rec (%s) byte array has invalid uint\n",
 | |
| 				rp->name, val);
 | |
| 			return (NULL);
 | |
| 		}
 | |
| 		if (nbytes >= HYMOD_MAX_BYTES) {
 | |
| 			printf ("%s rec (%s) byte array too long\n",
 | |
| 				rp->name, val);
 | |
| 			return (NULL);
 | |
| 		}
 | |
| 		bytes[nbytes++] = lval;
 | |
| 
 | |
| 		if (*ep != '\0')
 | |
| 			ep++;
 | |
| 	}
 | |
| 
 | |
| 	if (dp + 2 + nbytes > edp) {
 | |
| 		printf ("can't fit %s rec into eeprom\n", rp->name);
 | |
| 		return (NULL);
 | |
| 	}
 | |
| 
 | |
| 	*dp++ = rp->type;
 | |
| 	*dp++ = nbytes;
 | |
| 	memcpy (dp, bytes, nbytes);
 | |
| 	dp += nbytes;
 | |
| 
 | |
| 	return (dp);
 | |
| }
 | |
| 
 | |
| static eerec_map_t eerec_map[] = {
 | |
| 	/* name      type                 handler         len max             */
 | |
| 	{ "serno",   HYMOD_EEREC_SERNO,   uint_handler,   4,  0               },
 | |
| 	{ "date",    HYMOD_EEREC_DATE,    date_handler,   4,  0               },
 | |
| 	{ "batch",   HYMOD_EEREC_BATCH,   string_handler, 0,  HYMOD_MAX_BATCH },
 | |
| 	{ "type",    HYMOD_EEREC_TYPE,    uint_handler,   1,  0               },
 | |
| 	{ "rev",     HYMOD_EEREC_REV,     uint_handler,   1,  0               },
 | |
| 	{ "sdram",   HYMOD_EEREC_SDRAM,   bytes_handler,  0,  HYMOD_MAX_SDRAM },
 | |
| 	{ "flash",   HYMOD_EEREC_FLASH,   bytes_handler,  0,  HYMOD_MAX_FLASH },
 | |
| 	{ "zbt",     HYMOD_EEREC_ZBT,     bytes_handler,  0,  HYMOD_MAX_ZBT   },
 | |
| 	{ "xlxtyp",  HYMOD_EEREC_XLXTYP,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 | |
| 	{ "xlxspd",  HYMOD_EEREC_XLXSPD,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 | |
| 	{ "xlxtmp",  HYMOD_EEREC_XLXTMP,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 | |
| 	{ "xlxgrd",  HYMOD_EEREC_XLXGRD,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 | |
| 	{ "cputyp",  HYMOD_EEREC_CPUTYP,  uint_handler,   1,  0               },
 | |
| 	{ "cpuspd",  HYMOD_EEREC_CPUSPD,  uint_handler,   1,  0               },
 | |
| 	{ "cpmspd",  HYMOD_EEREC_CPMSPD,  uint_handler,   1,  0               },
 | |
| 	{ "busspd",  HYMOD_EEREC_BUSSPD,  uint_handler,   1,  0               },
 | |
| 	{ "hstype",  HYMOD_EEREC_HSTYPE,  uint_handler,   1,  0               },
 | |
| 	{ "hschin",  HYMOD_EEREC_HSCHIN,  uint_handler,   1,  0               },
 | |
| 	{ "hschout", HYMOD_EEREC_HSCHOUT, uint_handler,   1,  0               },
 | |
| };
 | |
| 
 | |
| static int neerecs = sizeof eerec_map / sizeof eerec_map[0];
 | |
| 
 | |
| static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp;
 | |
| 
 | |
| static int
 | |
| eerec_callback (uchar *name, uchar *val)
 | |
| {
 | |
| 	eerec_map_t *rp;
 | |
| 
 | |
| 	for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++)
 | |
| 		if (strcmp ((char *)name, rp->name) == 0)
 | |
| 			break;
 | |
| 
 | |
| 	if (rp >= &eerec_map[neerecs])
 | |
| 		return (0);
 | |
| 
 | |
| 	if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL)
 | |
| 		return (0);
 | |
| 
 | |
| 	return (1);
 | |
| }
 | |
| 
 | |
| static int
 | |
| hymod_eeprom_fetch(int which, char *filename, ulong addr)
 | |
| {
 | |
| 	unsigned dev_addr = CONFIG_SYS_I2C_EEPROM_ADDR | \
 | |
| 		(which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
 | |
| 	hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0];
 | |
| 	ulong crc;
 | |
| 
 | |
| 	memset (hp, 0, sizeof *hp);
 | |
| 	hp->id = HYMOD_EEPROM_ID;
 | |
| 	hp->ver = HYMOD_EEPROM_VER;
 | |
| 
 | |
| 	dp = sdp = (uchar *)(hp + 1);
 | |
| 	edp = dp + HYMOD_EEPROM_MAXLEN;
 | |
| 
 | |
| 	if (fetch_and_parse (filename, addr, eerec_callback) == 0)
 | |
| 		return (0);
 | |
| 
 | |
| 	hp->len = dp - sdp;
 | |
| 
 | |
| 	crc = crc32 (0, data, dp - data);
 | |
| 	memcpy (dp, &crc, sizeof (ulong));
 | |
| 	dp += sizeof (ulong);
 | |
| 
 | |
| 	eeprom_write (dev_addr, 0, data, dp - data);
 | |
| 
 | |
| 	return (1);
 | |
| }
 | |
| 
 | |
| static char *type_vals[] = {
 | |
| 	"NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY"
 | |
| };
 | |
| 
 | |
| static char *xlxtyp_vals[] = {
 | |
| 	"NONE", "XCV300E", "XCV400E", "XCV600E"
 | |
| };
 | |
| 
 | |
| static char *xlxspd_vals[] = {
 | |
| 	"NONE", "6", "7", "8"
 | |
| };
 | |
| 
 | |
| static char *xlxtmp_vals[] = {
 | |
| 	"NONE", "COM", "IND"
 | |
| };
 | |
| 
 | |
| static char *xlxgrd_vals[] = {
 | |
| 	"NONE", "NORMAL", "ENGSAMP"
 | |
| };
 | |
| 
 | |
| static char *cputyp_vals[] = {
 | |
| 	"NONE", "MPC8260"
 | |
| };
 | |
| 
 | |
| static char *clk_vals[] = {
 | |
| 	"NONE", "33", "66", "100", "133", "166", "200"
 | |
| };
 | |
| 
 | |
| static char *hstype_vals[] = {
 | |
| 	"NONE", "AMCC-S2064A"
 | |
| };
 | |
| 
 | |
| static void
 | |
| print_mem (char *l, char *s, uchar n, uchar a[])
 | |
| {
 | |
| 	if (n > 0) {
 | |
| 		if (n == 1)
 | |
| 			printf ("%s%dMB %s", s, 1 << (a[0] - 20), l);
 | |
| 		else {
 | |
| 			ulong t = 0;
 | |
| 			int i;
 | |
| 
 | |
| 			for (i = 0; i < n; i++)
 | |
| 				t += 1 << (a[i] - 20);
 | |
| 
 | |
| 			printf ("%s%luMB %s (%d banks:", s, t, l, n);
 | |
| 
 | |
| 			for (i = 0; i < n; i++)
 | |
| 				printf ("%dMB%s",
 | |
| 					1 << (a[i] - 20),
 | |
| 					(i == n - 1) ? ")" : ",");
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 		printf ("%sNO %s", s, l);
 | |
| }
 | |
| 
 | |
| void
 | |
| hymod_eeprom_print (hymod_eeprom_t *ep)
 | |
| {
 | |
| 	int i;
 | |
| 
 | |
| 	printf ("         Hymod %s board, rev %03d\n",
 | |
| 		type_vals[ep->bdtype], ep->bdrev);
 | |
| 
 | |
| 	printf ("         serial #: %010lu, date %04d-%02d-%02d",
 | |
| 		ep->serno, ep->date.year, ep->date.month, ep->date.day);
 | |
| 	if (ep->batchlen > 0)
 | |
| 		printf (", batch \"%.*s\"", ep->batchlen, ep->batch);
 | |
| 	puts ("\n");
 | |
| 
 | |
| 	switch (ep->bdtype) {
 | |
| 
 | |
| 	case HYMOD_BDTYPE_IO:
 | |
| 	case HYMOD_BDTYPE_CLP:
 | |
| 	case HYMOD_BDTYPE_DSP:
 | |
| 		printf ("         Motorola %s CPU, speeds: %s/%s/%s",
 | |
| 		    cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd],
 | |
| 		    clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]);
 | |
| 
 | |
| 		print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz);
 | |
| 
 | |
| 		print_mem ("FLASH", ", ", ep->nflash, ep->flashsz);
 | |
| 
 | |
| 		puts ("\n");
 | |
| 
 | |
| 		print_mem ("ZBT", "         ", ep->nzbt, ep->zbtsz);
 | |
| 
 | |
| 		if (ep->nxlx > 0) {
 | |
| 			hymod_xlx_t *xp;
 | |
| 
 | |
| 			if (ep->nxlx == 1) {
 | |
| 				xp = &ep->xlx[0];
 | |
| 				printf (", Xilinx %s FPGA (%s/%s/%s)",
 | |
| 					xlxtyp_vals[xp->type],
 | |
| 					xlxspd_vals[xp->speed],
 | |
| 					xlxtmp_vals[xp->temp],
 | |
| 					xlxgrd_vals[xp->grade]);
 | |
| 			}
 | |
| 			else {
 | |
| 				printf (", %d Xilinx FPGAs (", ep->nxlx);
 | |
| 				for (i = 0; i < ep->nxlx; i++) {
 | |
| 					xp = &ep->xlx[i];
 | |
| 					printf ("%s[%s/%s/%s]%s",
 | |
| 					    xlxtyp_vals[xp->type],
 | |
| 					    xlxspd_vals[xp->speed],
 | |
| 					    xlxtmp_vals[xp->temp],
 | |
| 					    xlxgrd_vals[xp->grade],
 | |
| 					    (i == ep->nxlx - 1) ? ")" : ", ");
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 			puts(", NO FPGAs");
 | |
| 
 | |
| 		puts ("\n");
 | |
| 
 | |
| 		if (ep->hss.type > 0)
 | |
| 			printf ("         High Speed Serial: "
 | |
| 				"%s, %d input%s, %d output%s\n",
 | |
| 				hstype_vals[ep->hss.type],
 | |
| 				ep->hss.nchin,
 | |
| 				(ep->hss.nchin == 1 ? "" : "s"),
 | |
| 				ep->hss.nchout,
 | |
| 				(ep->hss.nchout == 1 ? "" : "s"));
 | |
| 		break;
 | |
| 
 | |
| 	case HYMOD_BDTYPE_INPUT:
 | |
| 	case HYMOD_BDTYPE_ALTINPUT:
 | |
| 	case HYMOD_BDTYPE_DISPLAY:
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		/* crap! */
 | |
| 		printf ("         UNKNOWN BOARD TYPE: %d\n", ep->bdtype);
 | |
| 		break;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int
 | |
| hymod_eeprom_read (int which, hymod_eeprom_t *ep)
 | |
| {
 | |
| 	char *label = which ? "mezzanine" : "main";
 | |
| 	unsigned dev_addr = CONFIG_SYS_I2C_EEPROM_ADDR | \
 | |
| 		(which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
 | |
| 	char filename[50], prompt[50], *dir;
 | |
| 	int serno, count = 0, rc;
 | |
| 
 | |
| 	rc = eeprom_probe (dev_addr, 0);
 | |
| 
 | |
| 	if (rc > 0) {
 | |
| 		printf ("*** probe for eeprom failed with code %d\n", rc);
 | |
| 		return (0);
 | |
| 	}
 | |
| 
 | |
| 	if (rc < 0)
 | |
| 		return (rc);
 | |
| 
 | |
| 	sprintf (prompt, "Enter %s board serial number: ", label);
 | |
| 
 | |
| 	if ((dir = getenv ("bddb_cfgdir")) == NULL)
 | |
| 		dir = def_bddb_cfgdir;
 | |
| 
 | |
| 	for (;;) {
 | |
| 		int rc;
 | |
| 
 | |
| 		if (hymod_eeprom_load (which, ep))
 | |
| 			return (1);
 | |
| 
 | |
| 		printf ("*** %s board EEPROM contents are %sinvalid\n",
 | |
| 			label, count == 0 ? "" : "STILL ");
 | |
| 
 | |
| 		puts ("*** will fetch from server (Ctrl-C to abort)\n");
 | |
| 
 | |
| 		serno = hymod_get_serno (prompt);
 | |
| 
 | |
| 		if (serno < 0) {
 | |
| 			if (serno == -1)
 | |
| 				puts ("\n*** interrupted!");
 | |
| 			else
 | |
| 				puts ("\n*** timeout!");
 | |
| 			puts (" - ignoring eeprom contents\n");
 | |
| 			return (0);
 | |
| 		}
 | |
| 
 | |
| 		sprintf (filename, "%s/%010d.cfg", dir, serno);
 | |
| 
 | |
| 		printf ("*** fetching %s board EEPROM contents from server\n",
 | |
| 			label);
 | |
| 
 | |
| 		rc = hymod_eeprom_fetch (which, filename, CONFIG_SYS_LOAD_ADDR);
 | |
| 
 | |
| 		if (rc == 0) {
 | |
| 			puts ("*** fetch failed - ignoring eeprom contents\n");
 | |
| 			return (0);
 | |
| 		}
 | |
| 
 | |
| 		count++;
 | |
| 	}
 | |
| }
 |