📄 eeprom.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 inthymod_eeprom_load (int which, hymod_eeprom_t *ep){ unsigned dev_addr = CFG_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, (char *)&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 (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; uchar *p = val; char *ep; ulong lval; lval = simple_strtol (p, &ep, 10); if ((uchar *)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 ((uchar *)ep == p || *ep++ != '-' || lval == 0 || lval > 12) goto bad_date; date.month = lval; lval = simple_strtol (p = ep, &ep, 10); if ((uchar *)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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -