From 6dd652fa4d8591a32e2707a91f4582ed13011b17 Mon Sep 17 00:00:00 2001 From: wdenk Date: Thu, 19 Jun 2003 23:40:20 +0000 Subject: [PATCH] Patches by Murray Jensen, 17 Jun 2003: - Hymod board database mods: add "who" field and new xilinx chip types - provide new "init_cmd_timeout()" function so code external to "common/main.c" can use the "reset_cmd_timeout()" function before entering the main loop - add DTT support for adm1021 (new file dtt/adm1021.c; config slightly different. see include/configs/hymod.h for an example (requires CONFIG_DTT_ADM1021, CONFIG_DTT_SENSORS, and CFG_DTT_ADM1021 defined) - add new "eeprom_probe()" function which has similar args and behaves in a similar way to "eeprom_read()" etc. - add 8260 FCC ethernet loopback code (new "eth_loopback_test()" function which is enabled by defining CONFIG_ETHER_LOOPBACK_TEST) - gdbtools copyright update - ensure that set_msr() executes the "sync" and "isync" instructions after the "mtmsr" instruction in cpu/mpc8260/interrupts.c - 8260 I/O ports fix: Open Drain should be set last when configuring - add SIU IRQ defines for 8260 - allow LDSCRIPT override and OBJCFLAGS initialization: change to config.mk to allow board configurations to override the GNU linker script, selected via the LDSCRIPT, make variable, and to give an initial value to the OBJCFLAGS make variable - 8260 i2c enhancement: o correctly extends the timeout depending on the size of all queued messages for both transmit and receive o will not continue with receive if transmit times out o ensures that the error callback is done for all queued tx and rx messages o correctly detects both tx and rx timeouts, only delivers one to the callback, and does not overwrite an earlier error o logic in i2c_probe now correct - add "vprintf()" function so that "panic()" function can be technically correct - many Hymod board changes --- CHANGELOG | 35 ++ board/hymod/Makefile | 2 +- board/hymod/bsp.c | 176 +++++-- board/hymod/config.mk | 2 +- board/hymod/eeprom.c | 960 +++++++++++++++++++++------------------ board/hymod/env.c | 236 ++++++++++ board/hymod/fetch.c | 159 +++---- board/hymod/flash.c | 521 ++++++--------------- board/hymod/flash.h | 245 +++++----- board/hymod/global_env | 133 +++++- board/hymod/hymod.c | 777 ++++++++++--------------------- board/hymod/hymod.h | 322 +++++++++++++ board/hymod/input.c | 113 +++++ common/cmd_eeprom.c | 20 + common/console.c | 14 + common/main.c | 26 +- config.mk | 4 +- cpu/mpc8260/cpu_init.c | 2 +- cpu/mpc8260/ether_fcc.c | 757 ++++++++++++++++++++++++++++++ cpu/mpc8260/i2c.c | 158 ++++--- cpu/mpc8260/interrupts.c | 10 +- dtt/Makefile | 2 +- dtt/adm1021.c | 171 +++++++ include/cmd_bsp.h | 8 +- include/common.h | 7 +- include/configs/hymod.h | 110 ++++- include/dtt.h | 40 +- include/flash.h | 9 +- include/mpc8260_irq.h | 7 + lib_generic/vsprintf.c | 2 +- lib_ppc/board.c | 1 - tools/bddb/brlog.php | 2 + tools/bddb/defs.php | 12 +- tools/bddb/doedlog.php | 3 + tools/bddb/donewlog.php | 3 + tools/bddb/edlog.php | 3 + tools/bddb/newlog.php | 3 + tools/gdb/astest.c | 23 + tools/gdb/error.c | 23 + tools/gdb/error.h | 23 + tools/gdb/gdbcont.c | 23 + tools/gdb/gdbsend.c | 23 + tools/gdb/remote.h | 23 + tools/gdb/serial.c | 23 + tools/gdb/serial.h | 23 + 45 files changed, 3492 insertions(+), 1747 deletions(-) create mode 100644 board/hymod/env.c create mode 100644 board/hymod/hymod.h create mode 100644 board/hymod/input.c create mode 100644 dtt/adm1021.c diff --git a/CHANGELOG b/CHANGELOG index 1a39bb5931..a0fc00f61c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,41 @@ Changes since U-Boot 0.3.1: ====================================================================== +* Patches by Murray Jensen, 17 Jun 2003: + - Hymod board database mods: add "who" field and new xilinx chip types + - provide new "init_cmd_timeout()" function so code external to + "common/main.c" can use the "reset_cmd_timeout()" function before + entering the main loop + - add DTT support for adm1021 (new file dtt/adm1021.c; config + slightly different. see include/configs/hymod.h for an example + (requires CONFIG_DTT_ADM1021, CONFIG_DTT_SENSORS, and + CFG_DTT_ADM1021 defined) + - add new "eeprom_probe()" function which has similar args and + behaves in a similar way to "eeprom_read()" etc. + - add 8260 FCC ethernet loopback code (new "eth_loopback_test()" + function which is enabled by defining CONFIG_ETHER_LOOPBACK_TEST) + - gdbtools copyright update + - ensure that set_msr() executes the "sync" and "isync" instructions + after the "mtmsr" instruction in cpu/mpc8260/interrupts.c + - 8260 I/O ports fix: Open Drain should be set last when configuring + - add SIU IRQ defines for 8260 + - allow LDSCRIPT override and OBJCFLAGS initialization: change to + config.mk to allow board configurations to override the GNU + linker script, selected via the LDSCRIPT, make variable, and to + give an initial value to the OBJCFLAGS make variable + - 8260 i2c enhancement: + o correctly extends the timeout depending on the size of all + queued messages for both transmit and receive + o will not continue with receive if transmit times out + o ensures that the error callback is done for all queued tx + and rx messages + o correctly detects both tx and rx timeouts, only delivers one to + the callback, and does not overwrite an earlier error + o logic in i2c_probe now correct + - add "vprintf()" function so that "panic()" function can be + technically correct + - many Hymod board changes + * Patches by Robert Schwebel, 14 Jun 2003: - add support for Logotronic DL datalogger board - cleanup serial line after kermit binary download diff --git a/board/hymod/Makefile b/board/hymod/Makefile index 1804b3c1e9..4d3097ce72 100644 --- a/board/hymod/Makefile +++ b/board/hymod/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = lib$(BOARD).a -OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o +OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o input.o env.o $(LIB): .depend $(OBJS) $(AR) crv $@ $^ diff --git a/board/hymod/bsp.c b/board/hymod/bsp.c index 2ceaeb5159..02b6421b89 100644 --- a/board/hymod/bsp.c +++ b/board/hymod/bsp.c @@ -20,13 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * hacked for Hymod FPGA support by Murray.Jensen@cmst.csiro.au, 29-Jan-01 + * hacked for Hymod FPGA support by Murray.Jensen@csiro.au, 29-Jan-01 */ #include #include #include -#include #include #include @@ -74,28 +73,29 @@ * has not worked (wait several ms?) */ -int fpga_load (int mezz, uchar * addr, ulong size) +int +fpga_load (int mezz, uchar *addr, ulong size) { DECLARE_GLOBAL_DATA_PTR; hymod_conf_t *cp = &gd->bd->bi_hymod_conf; + xlx_info_t *fp; xlx_iopins_t *fpgaio; volatile uchar *fpgabase; volatile uint cnt; uchar *eaddr = addr + size; int result; - if (mezz) { - if (!cp->mezz.mmap[0].prog.exists) - return (LOAD_FAIL_NOCONF); - fpgabase = (uchar *) cp->mezz.mmap[0].prog.base; - fpgaio = &cp->mezz.iopins[0]; - } else { - if (!cp->main.mmap[0].prog.exists) - return (LOAD_FAIL_NOCONF); - fpgabase = (uchar *) cp->main.mmap[0].prog.base; - fpgaio = &cp->main.iopins[0]; - } + if (mezz) + fp = &cp->mezz.xlx[0]; + else + fp = &cp->main.xlx[0]; + + if (!fp->mmap.prog.exists) + return (LOAD_FAIL_NOCONF); + + fpgabase = (uchar *)fp->mmap.prog.base; + fpgaio = &fp->iopins; /* set enable HIGH if required */ if (fpgaio->enable_pin.flag) @@ -106,7 +106,7 @@ int fpga_load (int mezz, uchar * addr, ulong size) /* toggle PROG Low then High (will already be Low after Power-On) */ iopin_set_low (&fpgaio->prog_pin); - udelay (1); /* minimum 300ns - 1usec should do it */ + udelay (1); /* minimum 300ns - 1usec should do it */ iopin_set_high (&fpgaio->prog_pin); /* wait for INIT High */ @@ -157,15 +157,15 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) case 2: if (strcmp (argv[1], "info") == 0) { printf ("\nHymod FPGA Info...\n"); - printf (" Address Size\n"); - printf (" Main Configuration: 0x%08x %d\n", - FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE); - printf (" Main Register: 0x%08x %d\n", - FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE); - printf (" Main Port: 0x%08x %d\n", - FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE); - printf (" Mezz Configuration: 0x%08x %d\n", - FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE); + printf ("\t\t\t\tAddress\t\tSize\n"); + printf ("\tMain Configuration:\t0x%08x\t%d\n", + FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE); + printf ("\tMain Register:\t\t0x%08x\t%d\n", + FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE); + printf ("\tMain Port:\t\t0x%08x\t%d\n", + FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE); + printf ("\tMezz Configuration:\t0x%08x\t%d\n", + FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE); return 0; } break; @@ -176,18 +176,21 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) save_addr = addr; #if 0 - /* reading config data unimplemented */ - while VM - :more config data * addr++ = *fpga; - result = VM:? ? ? + /* fpga readback unimplemented */ + while (more readback data) + *addr++ = *fpga; + result = error ? STORE_FAIL_XXX : STORE_SUCCESS; #else - result = 0; + result = STORE_SUCCESS; #endif + if (result == STORE_SUCCESS) { - printf ("SUCCEEDED (%d bytes)\n", addr - save_addr); + printf ("SUCCEEDED (%d bytes)\n", + addr - save_addr); return 0; } else - printf ("FAILED (%d bytes)\n", addr - save_addr); + printf ("FAILED (%d bytes)\n", + addr - save_addr); return 1; } break; @@ -196,25 +199,32 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strcmp (argv[1], "tftp") == 0) { copy_filename (BootFile, argv[2], sizeof (BootFile)); load_addr = simple_strtoul (argv[3], NULL, 16); + NetBootFileXferSize = 0; if (NetLoop (TFTP) <= 0) { - printf ("tftp transfer failed - aborting fgpa load\n"); + printf ("tftp transfer failed - aborting " + "fgpa load\n"); return 1; } if (NetBootFileXferSize == 0) { - printf ("can't determine file size - aborting fpga load\n"); + printf ("can't determine file size - " + "aborting fpga load\n"); return 1; } - printf ("File transfer succeeded - beginning fpga load..."); + printf ("File transfer succeeded - " + "beginning fpga load..."); result = fpga_load (0, (uchar *) load_addr, - NetBootFileXferSize); + NetBootFileXferSize); + if (result == LOAD_SUCCESS) { printf ("SUCCEEDED\n"); return 0; - } else if (result == LOAD_FAIL_NOINIT) + } else if (result == LOAD_FAIL_NOCONF) + printf ("FAILED (no CONF)\n"); + else if (result == LOAD_FAIL_NOINIT) printf ("FAILED (no INIT)\n"); else printf ("FAILED (no DONE)\n"); @@ -231,7 +241,8 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else if (strcmp (argv[2], "mezz") == 0) mezz = 1; else { - printf ("FPGA type must be either `main' or `mezz'\n"); + printf ("FPGA type must be either " + "`main' or `mezz'\n"); return 1; } arg = 3; @@ -239,14 +250,18 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) mezz = 0; arg = 2; } + addr = (uchar *) simple_strtoul (argv[arg++], NULL, 16); size = (ulong) simple_strtoul (argv[arg], NULL, 16); result = fpga_load (mezz, addr, size); + if (result == LOAD_SUCCESS) { printf ("SUCCEEDED\n"); return 0; - } else if (result == LOAD_FAIL_NOINIT) + } else if (result == LOAD_FAIL_NOCONF) + printf ("FAILED (no CONF)\n"); + else if (result == LOAD_FAIL_NOINIT) printf ("FAILED (no INIT)\n"); else printf ("FAILED (no DONE)\n"); @@ -267,22 +282,21 @@ int do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { uchar data[HYMOD_EEPROM_SIZE]; - uint offset; - int rcode = 0; + uint addr = CFG_I2C_EEPROM_ADDR; switch (argc) { case 1: - offset = HYMOD_EEOFF_MAIN; + addr |= HYMOD_EEOFF_MAIN; break; case 2: if (strcmp (argv[1], "main") == 0) { - offset = HYMOD_EEOFF_MAIN; + addr |= HYMOD_EEOFF_MAIN; break; } if (strcmp (argv[1], "mezz") == 0) { - offset = HYMOD_EEOFF_MEZZ; + addr |= HYMOD_EEOFF_MEZZ; break; } /* fall through ... */ @@ -293,15 +307,77 @@ do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } memset (data, 0, HYMOD_EEPROM_SIZE); - if (i2c_write - (CFG_I2C_EEPROM_ADDR | offset, 0, CFG_I2C_EEPROM_ADDR_LEN, data, - HYMOD_EEPROM_SIZE)) { - rcode = 1; - } - return rcode; + eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE); + + return 0; } -#endif /* CFG_CMD_BSP */ +/* ------------------------------------------------------------------------- */ + +#if 0 +static uchar test_bitfile[] = { + /* one day ... */ +}; +#endif + +int +do_htest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +#if 0 + int rc; +#endif +#ifdef CONFIG_ETHER_LOOPBACK_TEST + extern void eth_loopback_test (void); +#endif /* CONFIG_ETHER_LOOPBACK_TEST */ + + printf ("HYMOD tests - ensure loopbacks etc. are connected\n\n"); + +#if 0 + /* Load FPGA with test program */ + + printf ("Loading test FPGA program ..."); + + rc = fpga_load (0, test_bitfile, sizeof (test_bitfile)); + + switch (rc) { + + case LOAD_SUCCESS: + printf (" SUCCEEDED\n"); + break; + + case LOAD_FAIL_NOCONF: + printf (" FAILED (no configuration space defined)\n"); + return 1; + + case LOAD_FAIL_NOINIT: + printf (" FAILED (timeout - no INIT signal seen)\n"); + return 1; + + case LOAD_FAIL_NODONE: + printf (" FAILED (timeout - no DONE signal seen)\n"); + return 1; + + default: + printf (" FAILED (unknown return code from fpga_load\n"); + return 1; + } + + /* run Local Bus <=> Xilinx tests */ + + /* tell Xilinx to run ZBT Ram, High Speed serial and Mezzanine tests */ + + /* run SDRAM test */ +#endif + +#ifdef CONFIG_ETHER_LOOPBACK_TEST + /* run Ethernet test */ + eth_loopback_test (); +#endif /* CONFIG_ETHER_LOOPBACK_TEST */ + + return 0; +} + +#endif /* CFG_CMD_BSP */ /* ------------------------------------------------------------------------- */ diff --git a/board/hymod/config.mk b/board/hymod/config.mk index 52c31832a8..ccc7f3820c 100644 --- a/board/hymod/config.mk +++ b/board/hymod/config.mk @@ -29,4 +29,4 @@ TEXT_BASE = 0x40000000 PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR) -OBJCFLAGS = --set-section-flags=.ppcenv=contents,alloc,load,data +OBJCFLAGS = --remove-section=.ppcenv diff --git a/board/hymod/eeprom.c b/board/hymod/eeprom.c index 9d506467c2..01e145398e 100644 --- a/board/hymod/eeprom.c +++ b/board/hymod/eeprom.c @@ -1,7 +1,6 @@ /* * (C) Copyright 2001 - * Murray Jensen, CSIRO Manufacturing Science and Technology, - * + * Murray Jensen, CSIRO-MIT, * * See file CREDITS for list of people who contributed to this * project. @@ -26,396 +25,408 @@ #include /* imports from fetch.c */ -extern int fetch_and_parse(bd_t *, char *, ulong, int (*)(uchar *, uchar *)); +extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); -int -eeprom_load(unsigned offset, hymod_eeprom_t *ep) +/* 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) { - uchar data[HYMOD_EEPROM_SIZE], *dp, *edp; - hymod_eehdr_t *hp; - ulong len, crc; + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + unsigned offset = 0; + uchar data[HYMOD_EEPROM_SIZE], *dp, *edp; + hymod_eehdr_t *hp; + ulong len, crc; - memset(ep, 0, sizeof *ep); - memset(data, 0, HYMOD_EEPROM_SIZE); - crc = 0; + memset (ep, 0, sizeof *ep); + memset (data, 0, HYMOD_EEPROM_SIZE); + crc = 0; - hp = (hymod_eehdr_t *)data; - eeprom_read(CFG_DEF_EEPROM_ADDR, offset, (uchar *)hp, sizeof (*hp)); - offset += sizeof (*hp); + hp = (hymod_eehdr_t *)data; + eeprom_read (dev_addr, offset, (uchar *)hp, sizeof (*hp)); + offset += sizeof (*hp); - if (hp->id != HYMOD_EEPROM_ID || hp->ver > HYMOD_EEPROM_VER || - (len = hp->len) > HYMOD_EEPROM_MAXLEN) - return (0); + if (hp->id != HYMOD_EEPROM_ID || hp->ver > HYMOD_EEPROM_VER || + (len = hp->len) > HYMOD_EEPROM_MAXLEN) + return (0); - dp = (uchar *)(hp + 1); edp = dp + len; - eeprom_read(CFG_DEF_EEPROM_ADDR, offset, dp, len); - offset += len; + dp = (uchar *)(hp + 1); edp = dp + len; + eeprom_read (dev_addr, offset, dp, len); + offset += len; - eeprom_read(CFG_DEF_EEPROM_ADDR, offset, (uchar *)&crc, sizeof (ulong)); + eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong)); - if (crc32(0, data, edp - data) != crc) - return (0); + if (crc32 (0, data, edp - data) != crc) + return (0); - ep->ver = hp->ver; + ep->ver = hp->ver; - for (;;) { - hymod_eerec_t *rp = (hymod_eerec_t *)dp; - ulong rtyp; - uchar rlen, *rdat; - uint rsiz; + for (;;) { + hymod_eerec_t *rp = (hymod_eerec_t *)dp; + ulong rtyp; + uchar rlen, *rdat; + uint rsiz; - if (rp->small.topbit == 0) { - rtyp = rp->small.type; - rlen = rp->small.len; - rdat = rp->small.data; - rsiz = offsetof(hymod_eerec_t, small.data) + rlen; - } - else if (rp->medium.nxtbit == 0) { - rtyp = rp->medium.type; - rlen = rp->medium.len; - rdat = rp->medium.data; - rsiz = offsetof(hymod_eerec_t, medium.data) + rlen; - } - else { - rtyp = rp->large.type; - rlen = rp->large.len; - rdat = rp->large.data; - rsiz = offsetof(hymod_eerec_t, large.data) + rlen; + if (rp->small.topbit == 0) { + rtyp = rp->small.type; + rlen = rp->small.len; + rdat = rp->small.data; + rsiz = offsetof (hymod_eerec_t, small.data) + rlen; + } + else if (rp->medium.nxtbit == 0) { + rtyp = rp->medium.type; + rlen = rp->medium.len; + rdat = rp->medium.data; + rsiz = offsetof (hymod_eerec_t, medium.data) + rlen; + } + else { + rtyp = rp->large.type; + rlen = rp->large.len; + rdat = rp->large.data; + rsiz = offsetof (hymod_eerec_t, large.data) + rlen; + } + + if (rtyp == 0) + break; + + dp += rsiz; + if (dp > edp) /* error? */ + break; + + switch (rtyp) { + + case HYMOD_EEREC_SERNO: /* serial number */ + if (rlen == sizeof (ulong)) + memcpy (&ep->serno, rdat, sizeof (ulong)); + break; + + case HYMOD_EEREC_DATE: /* date */ + if (rlen == sizeof (hymod_date_t)) + memcpy (&ep->date, rdat, sizeof (hymod_date_t)); + 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; + } } - if (rtyp == 0) - break; - - dp += rsiz; - if (dp > edp) /* error? */ - break; - - switch (rtyp) { - - case HYMOD_EEREC_SERNO: /* serial number */ - if (rlen == sizeof (ulong)) - memcpy(&ep->serno, rdat, sizeof (ulong)); - break; - - case HYMOD_EEREC_DATE: /* date */ - if (rlen == sizeof (hymod_date_t)) - memcpy(&ep->date, rdat, sizeof (hymod_date_t)); - 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: /* high-speed serial chip type */ - if (rlen == 1) - ep->hss.type = *rdat; - break; - - case HYMOD_EEREC_HSCHIN: /* high-speed serial input channels */ - if (rlen == 1) - ep->hss.nchin = *rdat; - break; - - case HYMOD_EEREC_HSCHOUT: /* high-speed serial output channels */ - if (rlen == 1) - ep->hss.nchout = *rdat; - break; - - default: /* ignore */ - break; - } - } - - return (1); + 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; - } + 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 *value, uchar *dp, uchar *edp) +uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - uchar *eval; - union { - uchar cval[4]; - ushort sval[2]; - ulong lval; - } rdata; + uchar *eval; + union { + uchar cval[4]; + ushort sval[2]; + ulong lval; + } rdata; - rdata.lval = simple_strtol(value, (char **)&eval, 10); + rdata.lval = simple_strtol (val, (char **)&eval, 10); - if (eval == value || *eval != '\0') { - printf("%s record (%s) is not a valid uint\n", rp->name, value); - return (NULL); - } - - if (dp + 2 + rp->length > edp) { - printf("can't fit %s record into eeprom\n", rp->name); - return (NULL); - } - - *dp++ = rp->type; - *dp++ = rp->length; - - switch (rp->length) { - - case 1: - if (rdata.lval >= 256) { - printf("%s record value (%lu) out of range (0-255)\n", - rp->name, rdata.lval); - return (NULL); + if (eval == val || *eval != '\0') { + printf ("%s rec (%s) is not a valid uint\n", + rp->name, val); + return (NULL); } - *dp++ = rdata.cval[3]; - break; - case 2: - if (rdata.lval >= 65536) { - printf("%s record value (%lu) out of range (0-65535)\n", - rp->name, rdata.lval); - return (NULL); + if (dp + 2 + rp->length > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); } - memcpy(dp, &rdata.sval[1], 2); - dp += 2; - break; - case 4: - memcpy(dp, &rdata.lval, 4); - dp += 4; - break; + *dp++ = rp->type; + *dp++ = rp->length; - default: - printf("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length); - return (NULL); - } + switch (rp->length) { - return (dp); + case 1: + if (rdata.lval >= 256) { + printf ("%s rec value (%lu) out of range (0-255)\n", + rp->name, rdata.lval); + return (NULL); + } + *dp++ = rdata.cval[3]; + break; + + case 2: + if (rdata.lval >= 65536) { + printf ("%s rec value (%lu) out of range (0-65535)\n", + rp->name, rdata.lval); + return (NULL); + } + memcpy (dp, &rdata.sval[1], 2); + dp += 2; + break; + + case 4: + memcpy (dp, &rdata.lval, 4); + dp += 4; + 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 *value, uchar *dp, uchar *edp) +date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - hymod_date_t date; - uchar *p = value, *ep; + hymod_date_t date; + uchar *p = val, *ep; - date.year = simple_strtol(p, (char **)&ep, 10); - if (ep == p || *ep++ != '-') { + date.year = simple_strtol (p, (char **)&ep, 10); + if (ep == p || *ep++ != '-') { bad_date: - printf("%s record (%s) is not a valid date\n", rp->name, value); - return (NULL); - } + printf ("%s rec (%s) is not a valid date\n", rp->name, val); + return (NULL); + } - date.month = simple_strtol(p = ep, (char **)&ep, 10); - if (ep == p || *ep++ != '-' || date.month == 0 || date.month > 12) - goto bad_date; + date.month = simple_strtol (p = ep, (char **)&ep, 10); + if (ep == p || *ep++ != '-' || date.month == 0 || date.month > 12) + goto bad_date; - date.day = simple_strtol(p = ep, (char **)&ep, 10); - if (ep == p || *ep != '\0' || date.day == 0 || date.day > 31) - goto bad_date; + date.day = simple_strtol (p = ep, (char **)&ep, 10); + if (ep == p || *ep != '\0' || date.day == 0 || date.day > 31) + goto bad_date; - if (dp + 2 + sizeof (hymod_date_t) > edp) { - printf("can't fit %s record into eeprom\n", rp->name); - return (NULL); - } + if (dp + 2 + sizeof (hymod_date_t) > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } - *dp++ = rp->type; - *dp++ = sizeof (hymod_date_t); - memcpy(dp, &date, sizeof (hymod_date_t)); - dp += sizeof (hymod_date_t); + *dp++ = rp->type; + *dp++ = sizeof (hymod_date_t); + memcpy (dp, &date, sizeof (hymod_date_t)); + dp += sizeof (hymod_date_t); - return (dp); + return (dp); } static uchar * -string_handler(eerec_map_t *rp, uchar *value, uchar *dp, uchar *edp) +string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - uint len; + uint len; - if ((len = strlen(value)) > rp->maxlen) { - printf("%s record (%s) string is too long (%d>%d)\n", - rp->name, value, len, rp->maxlen); - return (NULL); - } + if ((len = strlen (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 record into eeprom\n", rp->name); - 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, value, len); - dp += len; + *dp++ = rp->type; + *dp++ = len; + memcpy (dp, val, len); + dp += len; - return (dp); + return (dp); } static uchar * -bytes_handler(eerec_map_t *rp, uchar *value, uchar *dp, uchar *edp) +bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - uchar bytes[HYMOD_MAX_BYTES], nbytes = 0; - uchar *p = value, *ep; + uchar bytes[HYMOD_MAX_BYTES], nbytes = 0; + uchar *p = val, *ep; - for (;;) { + for (;;) { - if (nbytes >= HYMOD_MAX_BYTES) { - printf("%s record (%s) byte array too long\n", rp->name, value); - return (NULL); + if (nbytes >= HYMOD_MAX_BYTES) { + printf ("%s rec (%s) byte array too long\n", + rp->name, val); + return (NULL); + } + + bytes[nbytes++] = simple_strtol (p, (char **)&ep, 10); + + if (ep == p || (*ep != '\0' && *ep != ',')) { + printf ("%s rec (%s) byte array has invalid uint\n", + rp->name, val); + return (NULL); + } + + if (*ep++ == '\0') + break; + + p = ep; } - bytes[nbytes++] = simple_strtol(p, (char **)&ep, 10); - - if (ep == p || (*ep != '\0' && *ep != ',')) { - printf("%s record (%s) byte array has invalid uint\n", - rp->name, value); - return (NULL); + if (dp + 2 + nbytes > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); } - if (*ep++ == '\0') - break; + *dp++ = rp->type; + *dp++ = nbytes; + memcpy (dp, bytes, nbytes); + dp += nbytes; - p = ep; - } - - if (dp + 2 + nbytes > edp) { - printf("can't fit %s record into eeprom\n", rp->name); - return (NULL); - } - - *dp++ = rp->type; - *dp++ = nbytes; - memcpy(dp, bytes, nbytes); - dp += nbytes; - - return (dp); + 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 }, + /* 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]; @@ -423,175 +434,248 @@ static int neerecs = sizeof eerec_map / sizeof eerec_map[0]; static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp; static int -eeprom_fetch_callback(uchar *name, uchar *value) +eerec_callback (uchar *name, uchar *val) { - eerec_map_t *rp; + eerec_map_t *rp; - for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++) - if (strcmp(name, rp->name) == 0) - break; + for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++) + if (strcmp (name, rp->name) == 0) + break; - if (rp >= &eerec_map[neerecs]) - return (0); + if (rp >= &eerec_map[neerecs]) + return (0); - if ((dp = (*rp->handler)(rp, value, dp, edp)) == NULL) - return (0); + if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL) + return (0); - return (1); + return (1); } -int -eeprom_fetch(unsigned offset, bd_t *bd, char *filename, ulong addr) +static int +hymod_eeprom_fetch(int which, char *filename, ulong addr) { - hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0]; - ulong crc; + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0]; + ulong crc; - hp->id = HYMOD_EEPROM_ID; - hp->ver = HYMOD_EEPROM_VER; + hp->id = HYMOD_EEPROM_ID; + hp->ver = HYMOD_EEPROM_VER; - dp = sdp = (uchar *)(hp + 1); - edp = dp + HYMOD_EEPROM_MAXLEN; + dp = sdp = (uchar *)(hp + 1); + edp = dp + HYMOD_EEPROM_MAXLEN; - if (fetch_and_parse(bd, filename, addr, eeprom_fetch_callback) == 0) - return (0); + if (fetch_and_parse (filename, addr, eerec_callback) == 0) + return (0); - hp->len = dp - sdp; + hp->len = dp - sdp; - crc = crc32(0, data, dp - data); - memcpy(dp, &crc, sizeof (ulong)); - dp += sizeof (ulong); + crc = crc32 (0, data, dp - data); + memcpy (dp, &crc, sizeof (ulong)); + dp += sizeof (ulong); - eeprom_write(CFG_DEF_EEPROM_ADDR, offset, data, dp - data); + eeprom_write (dev_addr, 0, data, dp - data); - return (1); + return (1); } static char *type_vals[] = { - "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY" + "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY" }; static char *xlxtyp_vals[] = { - "NONE", "XCV300E", "XCV400E", "XCV600E" + "NONE", "XCV300E", "XCV400E", "XCV600E" }; static char *xlxspd_vals[] = { - "NONE", "6", "7", "8" + "NONE", "6", "7", "8" }; static char *xlxtmp_vals[] = { - "NONE", "COM", "IND" + "NONE", "COM", "IND" }; static char *xlxgrd_vals[] = { - "NONE", "NORMAL", "ENGSAMP" + "NONE", "NORMAL", "ENGSAMP" }; static char *cputyp_vals[] = { - "NONE", "MPC8260" + "NONE", "MPC8260" }; static char *clk_vals[] = { - "NONE", "33", "66", "100", "133", "166", "200" + "NONE", "33", "66", "100", "133", "166", "200" }; static char *hstype_vals[] = { - "NONE", "AMCC-S2064A" + "NONE", "AMCC-S2064A" }; static void -print_mem(char *l, char *s, uchar n, uchar a[]) +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; + 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); + for (i = 0; i < n; i++) + t += 1 << (a[i] - 20); - printf("%s%luMB %s (%d banks:", s, t, l, n); + 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) ? ")" : ","); + for (i = 0; i < n; i++) + printf ("%dMB%s", + 1 << (a[i] - 20), + (i == n - 1) ? ")" : ","); + } } - } - else - printf("%sNO %s", s, l); + else + printf ("%sNO %s", s, l); } void -eeprom_print(hymod_eeprom_t *ep) +hymod_eeprom_print (hymod_eeprom_t *ep) { - int i; + int i; - printf(" Hymod %s board, rev %03d\n", - type_vals[ep->bdtype], ep->bdrev); + 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"); + 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) { + 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]); + 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 ("SDRAM", ", ", ep->nsdram, ep->sdramsz); - print_mem("FLASH", ", ", ep->nflash, ep->flashsz); + print_mem ("FLASH", ", ", ep->nflash, ep->flashsz); - puts("\n"); + puts ("\n"); - print_mem("ZBT", " ", ep->nzbt, ep->zbtsz); + print_mem ("ZBT", " ", ep->nzbt, ep->zbtsz); - if (ep->nxlx > 0) { - hymod_xlx_t *xp; + 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) ? ")" : ", "); + 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 = CFG_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, CFG_LOAD_ADDR); + + if (rc == 0) { + puts ("*** fetch failed - ignoring eeprom contents\n"); + return (0); + } + + count++; } - 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; - } } diff --git a/board/hymod/env.c b/board/hymod/env.c new file mode 100644 index 0000000000..f58aec2570 --- /dev/null +++ b/board/hymod/env.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2003 + * Murray Jensen, CSIRO-MIT, + * + * 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 + +/* imports from fetch.c */ +extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); + +/* this is relative to the root of the server's tftp directory */ +static char *def_global_env_path = "/hymod/global_env"; + +static int +env_callback (uchar *name, uchar *value) +{ + DECLARE_GLOBAL_DATA_PTR; + + hymod_conf_t *cp = &gd->bd->bi_hymod_conf; + char ov[CFG_CBSIZE], nv[CFG_CBSIZE], *p, *q, *nn, c, *curver, *newver; + int override = 1, append = 0, remove = 0, nnl, ovl, nvl; + + nn = name; + + if (*nn == '-') { + override = 0; + nn++; + } + + while (*nn == ' ' || *nn == '\t') + nn++; + + if ((nnl = strlen (nn)) == 0) { + printf ("Empty name in global env file\n"); + return (0); + } + + if ((c = nn[nnl - 1]) == '+' || c == '-') { + if (c == '+') + append = 1; + else + remove = 1; + nn[--nnl] = '\0'; + } + + while (nnl > 0 && ((c = nn[nnl - 1]) == ' ' || c == '\t')) + nn[--nnl] = '\0'; + if (nnl == 0) { + printf ("Empty name in global env file\n"); + return (0); + } + + p = value; + q = nv; + + while ((c = *p) == ' ' || c == '\t') + p++; + + nvl = strlen (p); + while (nvl > 0 && ((c = p[nvl - 1]) == ' ' || c == '\t')) + p[--nvl] = '\0'; + + while ((*q = *p++) != '\0') { + if (*q == '%') { + switch (*p++) { + + case '\0': /* whoops - back up */ + p--; + break; + + case '%': /* a single percent character */ + q++; + break; + + case 's': /* main board serial number as string */ + q += sprintf (q, "%010lu", + cp->main.eeprom.serno); + break; + + case 'S': /* main board serial number as number */ + q += sprintf (q, "%lu", cp->main.eeprom.serno); + break; + + default: /* ignore any others */ + break; + } + } + else + q++; + } + + if ((nvl = q - nv) == 0) { + setenv (nn, NULL); + return (1); + } + + if ((curver = getenv ("global_env_version")) == NULL) + curver = "unknown"; + + if ((newver = getenv ("new_genv_version")) == NULL || \ + strcmp (curver, newver) == 0) { + if (strcmp (nn, "version") == 0) + setenv ("new_genv_version", nv); + return (1); + } + + if ((p = getenv (nn)) != NULL) { + + strcpy (ov, p); + ovl = strlen (ov); + + if (append) { + + if (strstr (ov, nv) == NULL) { + + printf ("Appending '%s' to env var '%s'\n", + nv, nn); + + while (nvl >= 0) { + nv[ovl + 1 + nvl] = nv[nvl]; + nvl--; + } + + nv[ovl] = ' '; + + while (--ovl >= 0) + nv[ovl] = ov[ovl]; + + setenv (nn, nv); + } + + return (1); + } + + if (remove) { + + if (strstr (ov, nv) != NULL) { + + printf ("Removing '%s' from env var '%s'\n", + nv, nn); + + while ((p = strstr (ov, nv)) != NULL) { + q = p + nvl; + if (*q == ' ') + q++; + strcpy(p, q); + } + + setenv (nn, ov); + } + + return (1); + } + + if (!override || strcmp (ov, nv) == 0) + return (1); + + printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", + nn, ov, nv); + } + else + printf ("Setting env cmd '%s' to '%s'\n", nn, nv); + + setenv (nn, nv); + return (1); +} + +void +hymod_check_env (void) +{ + char *p, *path, *curver, *newver; + int firsttime = 0, needsave = 0; + + if (getenv ("global_env_loaded") == NULL) { + puts ("*** global environment has never been loaded\n"); + puts ("*** fetching from server"); + firsttime = 1; + } + else if ((p = getenv ("always_check_env")) != NULL && + strcmp (p, "yes") == 0) + puts ("*** checking for updated global environment"); + else + return; + + puts (" (Control-C to Abort)\n"); + + if ((path = getenv ("global_env_path")) == NULL || *path == '\0') + path = def_global_env_path; + + if (fetch_and_parse (path, CFG_LOAD_ADDR, env_callback) == 0) { + puts ("*** Fetch of global environment failed!\n"); + return; + } + + if ((newver = getenv ("new_genv_version")) == NULL) { + puts ("*** Version number not set - contents ignored!\n"); + return; + } + + if ((curver = getenv ("global_env_version")) == NULL || \ + strcmp (curver, newver) != 0) { + setenv ("global_env_version", newver); + needsave = 1; + } + else + printf ("*** Global environment up-to-date (ver %s)\n", curver); + + setenv ("new_genv_version", NULL); + + if (firsttime) { + setenv ("global_env_loaded", "yes"); + needsave = 1; + } + + if (needsave) + puts ("\n*** Remember to run the 'saveenv' " + "command to save the changes\n\n"); +} diff --git a/board/hymod/fetch.c b/board/hymod/fetch.c index dcbda3174a..e121d5565e 100644 --- a/board/hymod/fetch.c +++ b/board/hymod/fetch.c @@ -1,7 +1,6 @@ /* * (C) Copyright 2001 - * Murray Jensen, CSIRO Manufacturing Science and Technology, - * + * Murray Jensen, CSIRO-MIT, * * See file CREDITS for list of people who contributed to this * project. @@ -25,118 +24,84 @@ #include #include -/* imports from common/main.c */ -extern char console_buffer[CFG_CBSIZE]; +/* imports from input.c */ +extern int hymod_get_ethaddr (void); int -fetch_and_parse(bd_t *bd, char *fn, ulong addr, int (*cback)(uchar *, uchar *)) +fetch_and_parse (char *fn, ulong addr, int (*cback)(uchar *, uchar *)) { - char *ethaddr; - uchar *fp, *efp; + char *ethaddr; + uchar *fp, *efp; + int rc, count = 0; - while ((ethaddr = getenv("ethaddr")) == NULL || *ethaddr == '\0') { + while ((ethaddr = getenv ("ethaddr")) == NULL || *ethaddr == '\0') { - puts("*** Ethernet address is not set\n"); + printf ("*** Ethernet address is%s not set\n", + count == 0 ? "" : " STILL"); - for (;;) { - int n; + if ((rc = hymod_get_ethaddr ()) < 0) { + if (rc == -1) + puts ("\n*** interrupted!"); + else + puts ("\n*** timeout!"); + printf (" - fetch of '%s' aborted\n", fn); + return (0); + } - n = readline("Enter board ethernet address: "); + count++; + } - if (n < 0) { - puts("\n"); + copy_filename (BootFile, fn, sizeof (BootFile)); + load_addr = addr; + NetBootFileXferSize = 0; + + if (NetLoop (TFTP) == 0) { + printf ("tftp transfer of file '%s' failed\n", fn); return (0); - } - - if (n == 0) - continue; - - if (n == 17) { - int i; - char *p, *q; - uchar ea[6]; - - /* see if it looks like an ethernet address */ - - p = console_buffer; - - for (i = 0; i < 6; i++) { - char term = (i == 5 ? '\0' : ':'); - - ea[i] = simple_strtol(p, &q, 16); - - if ((q - p) != 2 || *q++ != term) - break; - - p = q; - } - - if (i == 6) { - /* it looks ok - set it */ - printf("Setting ethernet address to %s\n", console_buffer); - setenv("ethaddr", console_buffer); - - puts("Remember to do a 'saveenv' to make it permanent\n"); - break; - } - } - - printf("Invalid ethernet address (%s) - please re-enter\n", - console_buffer); - } - } - - copy_filename(BootFile, fn, sizeof (BootFile)); - load_addr = addr; - - if (NetLoop(TFTP) <= 0) { - printf("tftp transfer of file '%s' failed\n", fn); - return (0); - } - - if (NetBootFileXferSize == 0) { - printf("can't determine size of file '%s'\n", fn); - return (0); - } - - fp = (uchar *)load_addr; - efp = fp + NetBootFileXferSize; - - do { - uchar *name, *value; - - if (*fp == '#' || *fp == '\n') { - while (fp < efp && *fp++ != '\n') - ; - continue; } - name = fp; + if (NetBootFileXferSize == 0) { + printf ("can't determine size of file '%s'\n", fn); + return (0); + } + + fp = (uchar *)load_addr; + efp = fp + NetBootFileXferSize; + + do { + uchar *name, *value; + + if (*fp == '#' || *fp == '\n') { + /* skip this line */ + while (fp < efp && *fp++ != '\n') + ; + continue; + } - while (fp < efp && *fp != '=') - if (*fp++ == '\n') name = fp; - if (fp >= efp) - break; + while (fp < efp && *fp != '=' && *fp != '\n') + fp++; + if (fp >= efp) + break; + if (*fp == '\n') { + fp++; + continue; + } + *fp++ = '\0'; - *fp++ = '\0'; + value = fp; - value = fp; + while (fp < efp && *fp != '\n') + fp++; + if (fp[-1] == '\r') + fp[-1] = '\0'; + *fp++ = '\0'; /* ok if we go off the end here */ - while (fp < efp && *fp != '\n') - fp++; + if ((*cback)(name, value) == 0) + return (0); - /* ok if we go off the end here */ + } while (fp < efp); - if (fp[-1] == '\r') - fp[-1] = '\0'; - *fp++ = '\0'; - - if ((*cback)(name, value) == 0) - return (0); - - } while (fp < efp); - - return (1); + return (1); } diff --git a/board/hymod/flash.c b/board/hymod/flash.c index 0a09b4a70e..7d1ae30e48 100644 --- a/board/hymod/flash.c +++ b/board/hymod/flash.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00 + * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00 */ #include @@ -35,235 +35,155 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ #define FLAG_PROTECT_SET 0x01 #define FLAG_PROTECT_CLEAR 0x02 -/*----------------------------------------------------------------------- - * Functions - */ -#if 0 -static ulong flash_get_size (vu_long *addr, flash_info_t *info); -static void flash_get_offsets (ulong base, flash_info_t *info); -#endif -static int write_word (flash_info_t *info, ulong dest, ulong data); - /*----------------------------------------------------------------------- */ /* - * probe for the existence of flash at bank word address "addr" - * 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id + * probe for flash bank at address "base" and store info about it + * in the flash_info entry "fip". Fatal error if nothing there. */ -static int -bank_probe_word(bank_addr_t addr) +static void +bank_probe (flash_info_t *fip, bank_addr_t base) { - int retval; + bank_addr_t addr; + bank_word_t word; + int i; /* reset the flash */ - *addr = BANK_CMD_RST; + *base = BANK_CMD_RST; - /* check the manufacturer id */ - *addr = BANK_CMD_RD_ID; - if (*BANK_ADDR_REG_MAN(addr) != BANK_RD_ID_MAN) { - retval = -1; - goto out; - } + /* check the manufacturer id - must be intel */ + *base = BANK_CMD_RD_ID; + word = *BANK_REG_MAN_CODE (base); + *base = BANK_CMD_RST; + + if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff)) + panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx", + (unsigned long)word, (unsigned long)base); /* check the device id */ - *addr = BANK_CMD_RD_ID; - if (*BANK_ADDR_REG_DEV(addr) != BANK_RD_ID_DEV) { - retval = -2; - goto out; + *base = BANK_CMD_RD_ID; + word = *BANK_REG_DEV_CODE (base); + *base = BANK_CMD_RST; + + switch (word) { + + case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5; + fip->sector_count = 32; + break; + + case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5; + fip->sector_count = 64; + break; + + case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A; + fip->sector_count = 32; + break; + + case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A; + fip->sector_count = 64; + break; + + case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A; + fip->sector_count = 128; + break; + + default: + panic ("\nbad device code (0x%08lx) at addr 0x%08lx", + (unsigned long)word, (unsigned long)base); } - retval = CFG_FLASH_TYPE; - -out: - /* reset the flash again */ - *addr = BANK_CMD_RST; - - return retval; -} - -/* - * probe for flash banks at address "base" and store info for any found - * into flash_info entry "fip". Must find at least one bank. - */ -static void -bank_probe(flash_info_t *fip, bank_addr_t base) -{ - bank_addr_t addr, eaddr; - int nbanks; - - fip->flash_id = FLASH_UNKNOWN; - fip->size = 0L; - fip->sector_count = 0; + if (fip->sector_count >= CFG_MAX_FLASH_SECT) + panic ("\ntoo many sectors (%d) in flash at address 0x%08lx", + fip->sector_count, (unsigned long)base); addr = base; - eaddr = BANK_ADDR_BASE(addr, MAX_BANKS); - nbanks = 0; - - while (addr < eaddr) { - bank_addr_t addrw, eaddrw, addrb; - int i, osc, nsc, curtype = -1; - - addrw = addr; - eaddrw = BANK_ADDR_NEXT_WORD(addrw); - - while (addrw < eaddrw) { - int thistype; - -#ifdef FLASH_DEBUG - printf(" probing for flash at addr 0x%08lx\n", - (unsigned long)addrw); -#endif - if ((thistype = bank_probe_word(addrw++)) < 0) - goto out; - - if (curtype < 0) - curtype = thistype; - else { - if (thistype != curtype) { - printf("Differing flash type found!\n"); - goto out; - } - } - } - - if (curtype < 0) - goto out; - - /* bank exists - append info for this bank to *fip */ - fip->flash_id = FLASH_MAN_INTEL|curtype; - fip->size += BANK_SIZE; - osc = fip->sector_count; - fip->sector_count += BANK_NBLOCKS; - if ((nsc = fip->sector_count) >= CFG_MAX_FLASH_SECT) - panic("Too many sectors in flash at address 0x%08lx\n", - (unsigned long)base); - - addrb = addr; - for (i = osc; i < nsc; i++) { - fip->start[i] = (ulong)addrb; - fip->protect[i] = 0; - addrb = BANK_ADDR_NEXT_BLK(addrb); - } - - addr = BANK_ADDR_NEXT_BANK(addr); - nbanks++; + for (i = 0; i < fip->sector_count; i++) { + fip->start[i] = (unsigned long)addr; + fip->protect[i] = 0; + addr = BANK_ADDR_NEXT_BLK (addr); } -out: - if (nbanks == 0) - panic("ERROR: no flash found at address 0x%08lx\n", - (unsigned long)base); + fip->size = (bank_size_t)addr - (bank_size_t)base; } static void -bank_reset(flash_info_t *info, int sect) +bank_reset (flash_info_t *info, int sect) { - bank_addr_t addrw, eaddrw; + bank_addr_t addr = (bank_addr_t)info->start[sect]; - addrw = (bank_addr_t)info->start[sect]; - eaddrw = BANK_ADDR_NEXT_WORD(addrw); - - while (addrw < eaddrw) { #ifdef FLASH_DEBUG - printf(" writing reset cmd to addr 0x%08lx\n", - (unsigned long)addrw); + printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr); #endif - *addrw = BANK_CMD_RST; - addrw++; - } + + *addr = BANK_CMD_RST; } static void -bank_erase_init(flash_info_t *info, int sect) +bank_erase_init (flash_info_t *info, int sect) { - bank_addr_t addrw, saddrw, eaddrw; + bank_addr_t addr = (bank_addr_t)info->start[sect]; int flag; #ifdef FLASH_DEBUG - printf("0x%08lx BANK_CMD_PROG\n", BANK_CMD_PROG); - printf("0x%08lx BANK_CMD_ERASE1\n", BANK_CMD_ERASE1); - printf("0x%08lx BANK_CMD_ERASE2\n", BANK_CMD_ERASE2); - printf("0x%08lx BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT); - printf("0x%08lx BANK_CMD_RST\n", BANK_CMD_RST); - printf("0x%08lx BANK_STAT_RDY\n", BANK_STAT_RDY); - printf("0x%08lx BANK_STAT_ERR\n", BANK_STAT_ERR); -#endif - - saddrw = (bank_addr_t)info->start[sect]; - eaddrw = BANK_ADDR_NEXT_WORD(saddrw); - -#ifdef FLASH_DEBUG - printf("erasing sector %d, start addr = 0x%08lx " - "(bank next word addr = 0x%08lx)\n", sect, - (unsigned long)saddrw, (unsigned long)eaddrw); + printf ("erasing sector %d, addr = 0x%08lx\n", + sect, (unsigned long)addr); #endif /* Disable intrs which might cause a timeout here */ - flag = disable_interrupts(); + flag = disable_interrupts (); - for (addrw = saddrw; addrw < eaddrw; addrw++) { #ifdef FLASH_DEBUG - printf(" writing erase cmd to addr 0x%08lx\n", - (unsigned long)addrw); + printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr); #endif - *addrw = BANK_CMD_ERASE1; - *addrw = BANK_CMD_ERASE2; - } + *addr = BANK_CMD_ERASE1; + *addr = BANK_CMD_ERASE2; /* re-enable interrupts if necessary */ if (flag) - enable_interrupts(); + enable_interrupts (); } static int -bank_erase_poll(flash_info_t *info, int sect) +bank_erase_poll (flash_info_t *info, int sect) { - bank_addr_t addrw, saddrw, eaddrw; - int sectdone, haderr; - - saddrw = (bank_addr_t)info->start[sect]; - eaddrw = BANK_ADDR_NEXT_WORD(saddrw); - - sectdone = 1; - haderr = 0; - - for (addrw = saddrw; addrw < eaddrw; addrw++) { - bank_word_t stat = *addrw; + bank_addr_t addr = (bank_addr_t)info->start[sect]; + bank_word_t stat = *addr; #ifdef FLASH_DEBUG - printf(" checking status at addr " - "0x%08lx [0x%08lx]\n", - (unsigned long)addrw, stat); + printf ("checking status at addr 0x%08lx [0x%08lx]\n", + (unsigned long)addr, (unsigned long)stat); #endif - if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY) - sectdone = 0; - else if ((stat & BANK_STAT_ERR) != 0) { - printf(" failed on sector %d " - "(stat = 0x%08lx) at " - "address 0x%08lx\n", - sect, stat, - (unsigned long)addrw); - *addrw = BANK_CMD_CLR_STAT; - haderr = 1; - } - } - if (haderr) - return (-1); + if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) { + if ((stat & BANK_STAT_ERR) != 0) { + printf ("failed on sector %d [0x%08lx] at " + "address 0x%08lx\n", sect, + (unsigned long)stat, (unsigned long)addr); + *addr = BANK_CMD_CLR_STAT; + return (-1); + } + else + return (1); + } else - return (sectdone); + return (0); } static int -bank_write_word(bank_addr_t addr, bank_word_t value) +bank_write_word (bank_addr_t addr, bank_word_t value) { bank_word_t stat; ulong start; int flag, retval; /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts(); + flag = disable_interrupts (); *addr = BANK_CMD_PROG; @@ -271,14 +191,14 @@ bank_write_word(bank_addr_t addr, bank_word_t value) /* re-enable interrupts if necessary */ if (flag) - enable_interrupts(); + enable_interrupts (); retval = 0; /* data polling for D7 */ start = get_timer (0); do { - if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { retval = 1; goto done; } @@ -286,8 +206,8 @@ bank_write_word(bank_addr_t addr, bank_word_t value) } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY); if ((stat & BANK_STAT_ERR) != 0) { - printf("flash program failed (stat = 0x%08lx) " - "at address 0x%08lx\n", (ulong)stat, (ulong)addr); + printf ("flash program failed [0x%08lx] at address 0x%08lx\n", + (unsigned long)stat, (unsigned long)addr); *addr = BANK_CMD_CLR_STAT; retval = 3; } @@ -303,7 +223,7 @@ done: */ unsigned long -flash_init(void) +flash_init (void) { int i; @@ -312,21 +232,21 @@ flash_init(void) flash_info[i].flash_id = FLASH_UNKNOWN; } - bank_probe(&flash_info[0], (bank_addr_t)CFG_FLASH_BASE); + bank_probe (&flash_info[0], (bank_addr_t)CFG_FLASH_BASE); /* * protect monitor and environment sectors */ #if CFG_MONITOR_BASE == CFG_FLASH_BASE - (void)flash_protect(FLAG_PROTECT_SET, + (void)flash_protect (FLAG_PROTECT_SET, CFG_MONITOR_BASE, CFG_MONITOR_BASE+monitor_flash_len-1, &flash_info[0]); #endif #if defined(CFG_FLASH_ENV_ADDR) - (void)flash_protect(FLAG_PROTECT_SET, + (void)flash_protect (FLAG_PROTECT_SET, CFG_FLASH_ENV_ADDR, #if defined(CFG_FLASH_ENV_BUF) CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1, @@ -339,42 +259,10 @@ flash_init(void) return flash_info[0].size; } -/*----------------------------------------------------------------------- - */ -#if 0 -static void -flash_get_offsets(ulong base, flash_info_t *info) -{ - int i; - - /* set up sector start adress table */ - if (info->flash_id & FLASH_BTYPE) { - /* set sector offsets for bottom boot block type */ - info->start[0] = base + 0x00000000; - info->start[1] = base + 0x00008000; - info->start[2] = base + 0x0000C000; - info->start[3] = base + 0x00010000; - for (i = 4; i < info->sector_count; i++) { - info->start[i] = base + (i * 0x00020000) - 0x00060000; - } - } else { - /* set sector offsets for top boot block type */ - i = info->sector_count - 1; - info->start[i--] = base + info->size - 0x00008000; - info->start[i--] = base + info->size - 0x0000C000; - info->start[i--] = base + info->size - 0x00010000; - for (; i >= 0; i--) { - info->start[i] = base + i * 0x00020000; - } - } - -} -#endif /* 0 */ - /*----------------------------------------------------------------------- */ void -flash_print_info(flash_info_t *info) +flash_print_info (flash_info_t *info) { int i; @@ -391,6 +279,14 @@ flash_print_info(flash_info_t *info) switch (info->flash_id & FLASH_TYPEMASK) { case FLASH_28F320J5: printf ("28F320J5 (32 Mbit, 2 x 16bit)\n"); break; + case FLASH_28F640J5: printf ("28F640J5 (64 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F320J3A: printf ("28F320J3A (32 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F128J3A: printf ("28F320J3A (128 Mbit, 2 x 16bit)\n"); + break; default: printf ("Unknown Chip Type\n"); break; } @@ -411,157 +307,25 @@ flash_print_info(flash_info_t *info) return; } -/*----------------------------------------------------------------------- - */ - /* * The following code cannot be run from FLASH! */ -#if 0 -static ulong -flash_get_size(vu_long *addr, flash_info_t *info) -{ - short i; - ulong value; - ulong base = (ulong)addr; - - - /* Write auto select command: read Manufacturer ID */ - addr[0x0555] = 0x00AA00AA; - addr[0x02AA] = 0x00550055; - addr[0x0555] = 0x00900090; - - value = addr[0]; - - switch (value) { - case AMD_MANUFACT: - info->flash_id = FLASH_MAN_AMD; - break; - case FUJ_MANUFACT: - info->flash_id = FLASH_MAN_FUJ; - break; - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - return (0); /* no or unknown flash */ - } - - value = addr[1]; /* device ID */ - - switch (value) { - case AMD_ID_LV400T: - info->flash_id += FLASH_AM400T; - info->sector_count = 11; - info->size = 0x00100000; - break; /* => 1 MB */ - - case AMD_ID_LV400B: - info->flash_id += FLASH_AM400B; - info->sector_count = 11; - info->size = 0x00100000; - break; /* => 1 MB */ - - case AMD_ID_LV800T: - info->flash_id += FLASH_AM800T; - info->sector_count = 19; - info->size = 0x00200000; - break; /* => 2 MB */ - - case AMD_ID_LV800B: - info->flash_id += FLASH_AM800B; - info->sector_count = 19; - info->size = 0x00200000; - break; /* => 2 MB */ - - case AMD_ID_LV160T: - info->flash_id += FLASH_AM160T; - info->sector_count = 35; - info->size = 0x00400000; - break; /* => 4 MB */ - - case AMD_ID_LV160B: - info->flash_id += FLASH_AM160B; - info->sector_count = 35; - info->size = 0x00400000; - break; /* => 4 MB */ -#if 0 /* enable when device IDs are available */ - case AMD_ID_LV320T: - info->flash_id += FLASH_AM320T; - info->sector_count = 67; - info->size = 0x00800000; - break; /* => 8 MB */ - - case AMD_ID_LV320B: - info->flash_id += FLASH_AM320B; - info->sector_count = 67; - info->size = 0x00800000; - break; /* => 8 MB */ -#endif - default: - info->flash_id = FLASH_UNKNOWN; - return (0); /* => no or unknown flash */ - - } - - /* set up sector start adress table */ - if (info->flash_id & FLASH_BTYPE) { - /* set sector offsets for bottom boot block type */ - info->start[0] = base + 0x00000000; - info->start[1] = base + 0x00008000; - info->start[2] = base + 0x0000C000; - info->start[3] = base + 0x00010000; - for (i = 4; i < info->sector_count; i++) { - info->start[i] = base + (i * 0x00020000) - 0x00060000; - } - } else { - /* set sector offsets for top boot block type */ - i = info->sector_count - 1; - info->start[i--] = base + info->size - 0x00008000; - info->start[i--] = base + info->size - 0x0000C000; - info->start[i--] = base + info->size - 0x00010000; - for (; i >= 0; i--) { - info->start[i] = base + i * 0x00020000; - } - } - - /* check for protected sectors */ - for (i = 0; i < info->sector_count; i++) { - /* read sector protection at sector address, (A7 .. A0) = 0x02 */ - /* D0 = 1 if protected */ - addr = (volatile unsigned long *)(info->start[i]); - info->protect[i] = addr[2] & 1; - } - - /* - * Prevent writes to uninitialized FLASH. - */ - if (info->flash_id != FLASH_UNKNOWN) { - addr = (volatile unsigned long *)info->start[0]; - - *addr = 0x00F000F0; /* reset bank */ - } - - return (info->size); -} -#endif /* 0 */ - /*----------------------------------------------------------------------- */ int -flash_erase(flash_info_t *info, int s_first, int s_last) +flash_erase (flash_info_t *info, int s_first, int s_last) { int prot, sect, haderr; ulong start, now, last; int rcode = 0; #ifdef FLASH_DEBUG - printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" + printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" " Bank # %d: ", s_last - s_first + 1, s_first, s_last, (info - flash_info) + 1); - flash_print_info(info); + flash_print_info (info); #endif if ((s_first < 0) || (s_first > s_last)) { @@ -574,14 +338,14 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } prot = 0; - for (sect=s_first; sect<=s_last; ++sect) { + for (sect = s_first; sect <= s_last; ++sect) { if (info->protect[sect]) { prot++; } } if (prot) { - printf("- Warning: %d protected sector%s will not be erased!\n", + printf ("- Warning: %d protected sector%s will not be erased\n", prot, (prot > 1 ? "s" : "")); } @@ -594,15 +358,15 @@ flash_erase(flash_info_t *info, int s_first, int s_last) ulong estart; int sectdone; - bank_erase_init(info, sect); + bank_erase_init (info, sect); /* wait at least 80us - let's wait 1 ms */ udelay (1000); - estart = get_timer(start); + estart = get_timer (start); do { - now = get_timer(start); + now = get_timer (start); if (now - estart > CFG_FLASH_ERASE_TOUT) { printf ("Timeout (sect %d)\n", sect); @@ -619,7 +383,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } #endif - sectdone = bank_erase_poll(info, sect); + sectdone = bank_erase_poll (info, sect); if (sectdone < 0) { haderr = 1; @@ -642,21 +406,39 @@ flash_erase(flash_info_t *info, int s_first, int s_last) /* reset to read mode */ for (sect = s_first; sect <= s_last; sect++) { if (info->protect[sect] == 0) { /* not protected */ - bank_reset(info, sect); + bank_reset (info, sect); } } return rcode; } +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 3 - Program failed + */ +static int +write_word (flash_info_t *info, ulong dest, ulong data) +{ + /* Check if Flash is (sufficiently) erased */ + if ((*(ulong *)dest & data) != data) + return (2); + + return (bank_write_word ((bank_addr_t)dest, (bank_word_t)data)); +} + /*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased + * 3 - Program failed */ int -write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) { ulong cp, wp, data; int i, l, rc; @@ -680,7 +462,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) data = (data << 8) | (*(uchar *)cp); } - if ((rc = write_word(info, wp, data)) != 0) { + if ((rc = write_word (info, wp, data)) != 0) { return (rc); } wp += 4; @@ -694,7 +476,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) for (i=0; i<4; ++i) { data = (data << 8) | *src++; } - if ((rc = write_word(info, wp, data)) != 0) { + if ((rc = write_word (info, wp, data)) != 0) { return (rc); } wp += 4; @@ -717,28 +499,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) data = (data << 8) | (*(uchar *)cp); } - return (write_word(info, wp, data)); -} - -/*----------------------------------------------------------------------- - * Write a word to Flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - */ -static int -write_word(flash_info_t *info, ulong dest, ulong data) -{ - int retval; - - /* Check if Flash is (sufficiently) erased */ - if ((*(ulong *)dest & data) != data) { - return (2); - } - - retval = bank_write_word((bank_addr_t)dest, (bank_word_t)data); - - return (retval); + return (write_word (info, wp, data)); } /*----------------------------------------------------------------------- diff --git a/board/hymod/flash.h b/board/hymod/flash.h index 3bccbc97aa..10db7fcacf 100644 --- a/board/hymod/flash.h +++ b/board/hymod/flash.h @@ -1,163 +1,156 @@ -/*************** DEFINES for Intel StrataFlash FLASH chip ********************/ - /* - * acceptable chips types are: + * (C) Copyright 2000 + * Murray Jensen, CSIRO-MIT, * - * 28F320J5, 28F640J5, 28F320J3A, 28F640J3A and 28F128J3A + * 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 */ -/* register addresses, valid only following an CHIP_CMD_RD_ID command */ -#define CHIP_ADDR_REG_MAN 0x000000 /* manufacturer's id */ -#define CHIP_ADDR_REG_DEV 0x000001 /* device id */ -#define CHIP_ADDR_REG_CFGM 0x000003 /* master lock config */ -#define CHIP_ADDR_REG_CFG(b) (((b)<<16)|2) /* lock config for block b */ +/*************** DEFINES for Intel StrataFlash FLASH chip ********************/ /* Commands */ -#define CHIP_CMD_RST 0xFF /* reset flash */ -#define CHIP_CMD_RD_ID 0x90 /* read the id and lock bits */ -#define CHIP_CMD_RD_QUERY 0x98 /* read device capabilities */ -#define CHIP_CMD_RD_STAT 0x70 /* read the status register */ -#define CHIP_CMD_CLR_STAT 0x50 /* clear the staus register */ -#define CHIP_CMD_WR_BUF 0xE8 /* clear the staus register */ -#define CHIP_CMD_PROG 0x40 /* program word command */ -#define CHIP_CMD_ERASE1 0x20 /* 1st word for block erase */ -#define CHIP_CMD_ERASE2 0xD0 /* 2nd word for block erase */ -#define CHIP_CMD_ERASE_SUSP 0xB0 /* suspend block erase */ -#define CHIP_CMD_LOCK 0x60 /* 1st word for all lock cmds */ -#define CHIP_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */ -#define CHIP_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */ -#define CHIP_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */ +#define ISF_CMD_RST 0xFF /* reset flash */ +#define ISF_CMD_RD_ID 0x90 /* read the id and lock bits */ +#define ISF_CMD_RD_QUERY 0x98 /* read device capabilities */ +#define ISF_CMD_RD_STAT 0x70 /* read the status register */ +#define ISF_CMD_CLR_STAT 0x50 /* clear the staus register */ +#define ISF_CMD_WR_BUF 0xE8 /* clear the staus register */ +#define ISF_CMD_PROG 0x40 /* program word command */ +#define ISF_CMD_ERASE1 0x20 /* 1st word for block erase */ +#define ISF_CMD_ERASE2 0xD0 /* 2nd word for block erase */ +#define ISF_CMD_ERASE_SUSP 0xB0 /* suspend block erase */ +#define ISF_CMD_LOCK 0x60 /* 1st word for all lock cmds */ +#define ISF_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */ +#define ISF_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */ +#define ISF_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */ /* status register bits */ -#define CHIP_STAT_DPS 0x02 /* Device Protect Status */ -#define CHIP_STAT_VPPS 0x08 /* VPP Status */ -#define CHIP_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */ -#define CHIP_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */ -#define CHIP_STAT_ESS 0x40 /* Erase Suspend Status */ -#define CHIP_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */ +#define ISF_STAT_DPS 0x02 /* Device Protect Status */ +#define ISF_STAT_VPPS 0x08 /* VPP Status */ +#define ISF_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */ +#define ISF_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */ +#define ISF_STAT_ESS 0x40 /* Erase Suspend Status */ +#define ISF_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */ -#define CHIP_STAT_ERR (CHIP_STAT_VPPS | CHIP_STAT_DPS | \ - CHIP_STAT_ECLBS | CHIP_STAT_PSLBS) +#define ISF_STAT_ERR (ISF_STAT_VPPS | ISF_STAT_DPS | \ + ISF_STAT_ECLBS | ISF_STAT_PSLBS) -/* ID and Lock Configuration */ -#define CHIP_RD_ID_LOCK 0x01 /* Bit 0 of each byte */ -#define CHIP_RD_ID_MAN 0x89 /* Manufacturer code = 0x89 */ -#define CHIP_RD_ID_DEV CFG_FLASH_ID - -/* dimensions */ -#define CHIP_WIDTH 2 /* chips are in 16 bit mode */ -#define CHIP_WSHIFT 1 /* (log2 of CHIP_WIDTH) */ -#define CHIP_NBLOCKS CFG_FLASH_NBLOCKS -#define CHIP_BLKSZ (128 * 1024) /* of 128Kbytes each */ -#define CHIP_SIZE (CHIP_BLKSZ * CHIP_NBLOCKS) +/* register addresses, valid only following an ISF_CMD_RD_ID command */ +#define ISF_REG_MAN_CODE 0x00 /* manufacturer code */ +#define ISF_REG_DEV_CODE 0x01 /* device code */ +#define ISF_REG_BLK_LCK 0x02 /* block lock configuration */ +#define ISF_REG_MST_LCK 0x03 /* master lock configuration */ /********************** DEFINES for Hymod Flash ******************************/ /* - * The hymod board has 2 x 28F320J5 chips running in - * 16 bit mode, for a 32 bit wide bank. + * this code requires that the flash on any Hymod board appear as a bank + * of two (identical) 16bit Intel StrataFlash chips with 64Kword erase + * sectors (or blocks), running in x16 bit mode and connected side-by-side + * to make a 32-bit wide bus. */ -typedef unsigned long bank_word_t; /* 8/16/32/64bit unsigned int */ +typedef unsigned long bank_word_t; +typedef bank_word_t bank_blk_t[64 * 1024]; + +#define BANK_FILL_WORD(b) (((bank_word_t)(b) << 16) | (bank_word_t)(b)) + +#ifdef EXAMPLE + +/* theoretically the following examples should also work */ + +/* one flash chip in x8 mode with 128Kword sectors and 8bit bus */ +typedef unsigned char bank_word_t; +typedef bank_word_t bank_blk_t[128 * 1024]; +#define BANK_FILL_WORD(b) ((bank_word_t)(b)) + +/* four flash chips in x16 mode with 32Kword sectors and 64bit bus */ +typedef unsigned long long bank_word_t; +typedef bank_word_t bank_blk_t[32 * 1024]; +#define BANK_FILL_WORD(b) ( \ + ((bank_word_t)(b) << 48) \ + ((bank_word_t)(b) << 32) \ + ((bank_word_t)(b) << 16) \ + ((bank_word_t)(b) << 0) \ + ) + +#endif /* EXAMPLE */ + +/* the sizes of these two types should probably be the same */ typedef volatile bank_word_t *bank_addr_t; -typedef unsigned long bank_size_t; /* want this big - >= 32 bit */ - -#define BANK_CHIP_WIDTH 2 /* each bank is 2 chips wide */ -#define BANK_CHIP_WSHIFT 1 /* (log2 of BANK_CHIP_WIDTH) */ - -#define BANK_WIDTH (CHIP_WIDTH * BANK_CHIP_WIDTH) -#define BANK_WSHIFT (CHIP_WSHIFT + BANK_CHIP_WSHIFT) -#define BANK_NBLOCKS CHIP_NBLOCKS -#define BANK_BLKSZ (CHIP_BLKSZ * BANK_CHIP_WIDTH) -#define BANK_SIZE (CHIP_SIZE * BANK_CHIP_WIDTH) - -#define MAX_BANKS 1 /* only one bank possible */ +typedef unsigned long bank_size_t; /* align bank addresses and sizes to bank word boundaries */ #define BANK_ADDR_WORD_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ - & ~(BANK_WIDTH - 1))) -#define BANK_SIZE_WORD_ALIGN(s) ((bank_size_t)BANK_ADDR_WORD_ALIGN( \ - (bank_size_t)(s) + (BANK_WIDTH - 1))) + & ~(sizeof (bank_word_t) - 1))) +#define BANK_SIZE_WORD_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_word_t) - 1) \ + & ~(sizeof (bank_word_t) - 1)) /* align bank addresses and sizes to bank block boundaries */ #define BANK_ADDR_BLK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ - & ~(BANK_BLKSZ - 1))) -#define BANK_SIZE_BLK_ALIGN(s) ((bank_size_t)BANK_ADDR_BLK_ALIGN( \ - (bank_size_t)(s) + (BANK_BLKSZ - 1))) - -/* align bank addresses and sizes to bank boundaries */ -#define BANK_ADDR_BANK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ - & ~(BANK_SIZE - 1))) -#define BANK_SIZE_BANK_ALIGN(s) ((bank_size_t)BANK_ADDR_BANK_ALIGN( \ - (bank_size_t)(s) + (BANK_SIZE - 1))) + & ~(sizeof (bank_blk_t) - 1))) +#define BANK_SIZE_BLK_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_blk_t) - 1) \ + & ~(sizeof (bank_blk_t) - 1)) /* add an offset to a bank address */ -#define BANK_ADDR_OFFSET(a, o) (bank_addr_t)((bank_size_t)(a) + \ - (bank_size_t)(o)) - -/* get base address of bank b, given flash base address a */ -#define BANK_ADDR_BASE(a, b) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \ - (bank_size_t)(b) * BANK_SIZE) +#define BANK_ADDR_OFFSET(a, o) ((bank_addr_t)((bank_size_t)(a) + \ + (bank_size_t)(o))) /* adjust a bank address to start of next word, block or bank */ #define BANK_ADDR_NEXT_WORD(a) BANK_ADDR_OFFSET(BANK_ADDR_WORD_ALIGN(a), \ - BANK_WIDTH) + sizeof (bank_word_t)) #define BANK_ADDR_NEXT_BLK(a) BANK_ADDR_OFFSET(BANK_ADDR_BLK_ALIGN(a), \ - BANK_BLKSZ) -#define BANK_ADDR_NEXT_BANK(a) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \ - BANK_SIZE) + sizeof (bank_blk_t)) -/* get bank address of chip register r given a bank base address a */ -#define BANK_ADDR_REG(a, r) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \ - ((bank_size_t)(r) << BANK_WSHIFT)) +/* get bank address of register r given a bank base address a and block num b */ +#define BANK_ADDR_REG(a, b, r) BANK_ADDR_OFFSET(BANK_ADDR_OFFSET((a), \ + (bank_size_t)(b) * sizeof (bank_blk_t)), \ + (bank_size_t)(r) * sizeof (bank_word_t)) -/* make a bank address for each chip register address */ - -#define BANK_ADDR_REG_MAN(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_MAN) -#define BANK_ADDR_REG_DEV(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_DEV) -#define BANK_ADDR_REG_CFGM(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFGM) -#define BANK_ADDR_REG_CFG(b,a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFG(b)) - -/* - * replicate a chip cmd/stat/rd value into each byte position within a word - * so that multiple chips are accessed in a single word i/o operation - * - * this must be as wide as the bank_word_t type, and take into account the - * chip width and bank layout - */ - -#define BANK_FILL_WORD(o) ((bank_word_t)( \ - ((unsigned long)(o) << 16) | \ - ((unsigned long)(o) << 0) \ - )) - -/* make a bank word value for each chip cmd/stat/rd value */ +/* make a bank word value for each StrataFlash value */ /* Commands */ -#define BANK_CMD_RST BANK_FILL_WORD(CHIP_CMD_RST) -#define BANK_CMD_RD_ID BANK_FILL_WORD(CHIP_CMD_RD_ID) -#define BANK_CMD_RD_STAT BANK_FILL_WORD(CHIP_CMD_RD_STAT) -#define BANK_CMD_CLR_STAT BANK_FILL_WORD(CHIP_CMD_CLR_STAT) -#define BANK_CMD_ERASE1 BANK_FILL_WORD(CHIP_CMD_ERASE1) -#define BANK_CMD_ERASE2 BANK_FILL_WORD(CHIP_CMD_ERASE2) -#define BANK_CMD_PROG BANK_FILL_WORD(CHIP_CMD_PROG) -#define BANK_CMD_LOCK BANK_FILL_WORD(CHIP_CMD_LOCK) -#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_SET_LOCK_BLK) -#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(CHIP_CMD_SET_LOCK_MSTR) -#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_CLR_LOCK_BLK) +#define BANK_CMD_RST BANK_FILL_WORD(ISF_CMD_RST) +#define BANK_CMD_RD_ID BANK_FILL_WORD(ISF_CMD_RD_ID) +#define BANK_CMD_RD_STAT BANK_FILL_WORD(ISF_CMD_RD_STAT) +#define BANK_CMD_CLR_STAT BANK_FILL_WORD(ISF_CMD_CLR_STAT) +#define BANK_CMD_ERASE1 BANK_FILL_WORD(ISF_CMD_ERASE1) +#define BANK_CMD_ERASE2 BANK_FILL_WORD(ISF_CMD_ERASE2) +#define BANK_CMD_PROG BANK_FILL_WORD(ISF_CMD_PROG) +#define BANK_CMD_LOCK BANK_FILL_WORD(ISF_CMD_LOCK) +#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(ISF_CMD_SET_LOCK_BLK) +#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(ISF_CMD_SET_LOCK_MSTR) +#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(ISF_CMD_CLR_LOCK_BLK) /* status register bits */ -#define BANK_STAT_DPS BANK_FILL_WORD(CHIP_STAT_DPS) -#define BANK_STAT_PSS BANK_FILL_WORD(CHIP_STAT_PSS) -#define BANK_STAT_VPPS BANK_FILL_WORD(CHIP_STAT_VPPS) -#define BANK_STAT_PSLBS BANK_FILL_WORD(CHIP_STAT_PSLBS) -#define BANK_STAT_ECLBS BANK_FILL_WORD(CHIP_STAT_ECLBS) -#define BANK_STAT_ESS BANK_FILL_WORD(CHIP_STAT_ESS) -#define BANK_STAT_RDY BANK_FILL_WORD(CHIP_STAT_RDY) +#define BANK_STAT_DPS BANK_FILL_WORD(ISF_STAT_DPS) +#define BANK_STAT_PSS BANK_FILL_WORD(ISF_STAT_PSS) +#define BANK_STAT_VPPS BANK_FILL_WORD(ISF_STAT_VPPS) +#define BANK_STAT_PSLBS BANK_FILL_WORD(ISF_STAT_PSLBS) +#define BANK_STAT_ECLBS BANK_FILL_WORD(ISF_STAT_ECLBS) +#define BANK_STAT_ESS BANK_FILL_WORD(ISF_STAT_ESS) +#define BANK_STAT_RDY BANK_FILL_WORD(ISF_STAT_RDY) -#define BANK_STAT_ERR BANK_FILL_WORD(CHIP_STAT_ERR) +#define BANK_STAT_ERR BANK_FILL_WORD(ISF_STAT_ERR) -/* ID and Lock Configuration */ -#define BANK_RD_ID_LOCK BANK_FILL_WORD(CHIP_RD_ID_LOCK) -#define BANK_RD_ID_MAN BANK_FILL_WORD(CHIP_RD_ID_MAN) -#define BANK_RD_ID_DEV BANK_FILL_WORD(CHIP_RD_ID_DEV) +/* make a bank register address for each StrataFlash register address */ + +#define BANK_REG_MAN_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_MAN_CODE) +#define BANK_REG_DEV_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_DEV_CODE) +#define BANK_REG_BLK_LCK(a, b) BANK_ADDR_REG((a), (b), ISF_REG_BLK_LCK) +#define BANK_REG_MST_LCK(a) BANK_ADDR_REG((a), 0, ISF_REG_MST_LCK) diff --git a/board/hymod/global_env b/board/hymod/global_env index 913f82db08..16def241dd 100644 --- a/board/hymod/global_env +++ b/board/hymod/global_env @@ -1,3 +1,33 @@ +# DONT FORGET TO CHANGE THE "version" VAR BELOW IF YOU MAKE CHANGES TO THIS FILE + +# (C) Copyright 2001 +# Murray Jensen, CSIRO-MIT, +# +# 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 + +# +# global_env +# +# file used by Hymod boards to initialise the u-boot non-volatile +# environment when u-boot is first run (it determines this by the +# absence of the environment variable "global_env_loaded") +# # format of this file is: # # 1. blank lines and lines beginning with '#' are ignored @@ -7,32 +37,94 @@ # %s serial number of the main board (10 digit zero filled) # %S serial number of the main board (plain number) # %% a percentage character -# -# no whitespace is removed in either or +# ... otherwise the %x is discarded # # if first character in is a dash ('-'), then an existing env var -# will not be overwritten (the dash is removed). +# will not be overwritten (the dash is removed). i.e. it is only set if +# it does not exist # # if last character in is a plus ('+'), then will be appended -# to any existing env var (the plus is removed). Duplicates of are +# to any existing env var (the plus is ignored). Duplicates of are # removed. # +# similarly, if the last character in is a minus ('-'), then any +# occurences of in the current value of will removed (the +# minus is ignored). +# +# leading and trailing whitespace is removed in both and +# (after processing any initial or final plus/minus in ). +# + +# MISCELLANEOUS PARAMETERS + +# version must always come first +version=3 # set the ip address based on the main board serial number ipaddr=192.168.1.%S serverip=192.168.1.254 -# stop auto execute after tftp +# stop auto execute after tftp (not a very good name really) autostart=no +# setting this to "yes" forces the global_env file to be loaded and processed +# if the current version is different to the version in the file +always_check_env=no + +# BOOTING COMMANDS AND PARAMETERS + +# command to run when "auto-booting" +bootcmd=bootm 40080000 40200000 + +# how long the "countdown" to automatically running "bootcmd" is +bootdelay=2 + +# how long before it "times out" console input and attempts to run "bootcmd" +bootretry=5 + +# arguments passed to the boot program (i.e. linux kernel) via register 6 +# the linux kernel (v2.4) uses the following registers: +# r3 - address of board information structure +# r4 - address of initial ramdisk image (0 means no initrd) +# r5 - size of initial ramdisk image +# r6 - address of command line string +-bootargs=root=/dev/ram rw + +# these four are for hymod linux intergrated into our Sun network +bootargs+=serialno=%S +bootargs+=nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4 +bootargs+=nfsclient +bootargs+=automount + +# start a web server by default +bootargs+=webserver + +# give negotiation time to finish +bootargs+=netsleep=5 + +# then our ciscos don't pass packets for 25-30 secs after that, so +# pinging the server until it responds prevents network connections +# from failing... +bootargs+=netping + +# these are old bootargs - we don't need them anymore +bootargs-=preload=unix,i2c-cpm,i2c-dev +bootargs-=ramdisk_size=32768 +bootargs-=ramdisk_size=24576 + +# FLASH MANIPULATION COMMANDS + # -# 16M flash map, 64 x 256K sectors, mapped at address 0x40000000 +# 16M flash, 64 x 256K sectors, mapped at address 0x40000000 # -# sector 0: boot -# sector 1: non volatile environment -# sectors 2-4: linux kernel image -# sectors 5-7: alternate linux kernel image -# sectors 8-63: linux initial ramdisk image +# Sector(s) Address Size Description +# +# 0 - 0 0x40000000 256K boot code +# 1 - 1 0x40040000 256K non volatile environment +# 2 - 4 0x40080000 768K linux kernel image +# 5 - 7 0x40140000 768K alternate linux kernel image +# 8 - 47 0x40200000 10M linux initial ramdisk image +# 48 - 63 0x40c00000 4M ramdisk image for applications # fetchboot=tftp 100000 /hymod/u-boot.bin @@ -49,21 +141,18 @@ newlinux=run fetchlinux eraselinux copylinux cmplinux fetchaltlinux=tftp 100000 /hymod/altlinux.bin erasealtlinux=erase 1:5-7 -copyaltlinux=cp.b 100000 40080000 $(filesize) -cmpaltlinux=cmp.b 100000 40080000 $(filesize) +copyaltlinux=cp.b 100000 40140000 $(filesize) +cmpaltlinux=cmp.b 100000 40140000 $(filesize) newaltlinux=run fetchaltlinux erasealtlinux copyaltlinux cmpaltlinux fetchird=tftp 100000 /hymod/initrd.bin -eraseird=erase 1:8-63 +eraseird=erase 1:8-47 copyird=cp.b 100000 40200000 $(filesize) cmpird=cmp.b 100000 40200000 $(filesize) newinitrd=run fetchird eraseird copyird cmpird -bootcmd=bootm 40080000 40200000 --bootargs=root=/dev/ram rw -# these are for hymod linux -bootargs+=preload=unix,i2c-cpm,i2c-dev -bootargs+=serialno=%S -bootargs+=ramdisk_size=32768 -bootargs+=automount nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4 -bootdelay=2 +fetchard=tftp 100000 /hymod/apprd.bin +eraseard=erase 1:48-63 +copyard=cp.b 100000 40c00000 $(filesize) +cmpard=cmp.b 100000 40c00000 $(filesize) +newapprd=run fetchard eraseard copyard cmpard diff --git a/board/hymod/hymod.c b/board/hymod/hymod.c index 829f25411d..3611a12977 100644 --- a/board/hymod/hymod.c +++ b/board/hymod/hymod.c @@ -20,11 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00 + * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00 */ #include #include +#include #include #include #include @@ -32,15 +33,11 @@ /* ------------------------------------------------------------------------- */ /* imports from eeprom.c */ -extern int eeprom_load (unsigned, hymod_eeprom_t *); -extern int eeprom_fetch (unsigned, char *, ulong); -extern void eeprom_print (hymod_eeprom_t *); +extern int hymod_eeprom_read (int, hymod_eeprom_t *); +extern void hymod_eeprom_print (hymod_eeprom_t *); -/* imports from fetch.c */ -extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); - -/* imports from common/main.c */ -extern char console_buffer[CFG_CBSIZE]; +/* imports from env.c */ +extern void hymod_check_env (void); /* ------------------------------------------------------------------------- */ @@ -54,274 +51,152 @@ extern char console_buffer[CFG_CBSIZE]; const iop_conf_t iop_conf_tab[4][32] = { /* Port A configuration */ - { /* conf ppar psor pdir podr pdat */ - /* PA31 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII COL */ - /* PA30 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII CRS */ - /* PA29 */ {1, 1, 1, 1, 0, 0}, - /* FCC1 MII TX_ER */ - /* PA28 */ {1, 1, 1, 1, 0, 0}, - /* FCC1 MII TX_EN */ - /* PA27 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII RX_DV */ - /* PA26 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII RX_ER */ - /* PA25 */ {1, 0, 0, 1, 0, 0}, - /* FCC2 MII MDIO */ - /* PA24 */ {1, 0, 0, 1, 0, 0}, - /* FCC2 MII MDC */ - /* PA23 */ {1, 0, 0, 1, 0, 0}, - /* FCC3 MII MDIO */ - /* PA22 */ {1, 0, 0, 1, 0, 0}, - /* FCC3 MII MDC */ - /* PA21 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[3] */ - /* PA20 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[2] */ - /* PA19 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[1] */ - /* PA18 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[0] */ - /* PA17 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[3] */ - /* PA16 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[2] */ - /* PA15 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[1] */ - /* PA14 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[0] */ - /* PA13 */ {1, 0, 0, 1, 0, 0}, - /* FCC1 MII MDIO */ - /* PA12 */ {1, 0, 0, 1, 0, 0}, - /* FCC1 MII MDC */ - /* PA11 */ {1, 0, 0, 1, 0, 0}, - /* SEL_CD */ - /* PA10 */ {1, 0, 0, 0, 0, 0}, - /* FLASH STS1 */ - /* PA9 */ {1, 0, 0, 0, 0, 0}, - /* FLASH STS0 */ - /* PA8 */ {1, 0, 0, 0, 0, 0}, - /* FLASH ~PE */ - /* PA7 */ {1, 0, 0, 0, 0, 0}, - /* WATCH ~HRESET */ - /* PA6 */ {1, 0, 0, 0, 1, 0}, - /* VC DONE */ - /* PA5 */ {1, 0, 0, 1, 1, 0}, - /* VC INIT */ - /* PA4 */ {1, 0, 0, 1, 0, 0}, - /* VC ~PROG */ - /* PA3 */ {1, 0, 0, 1, 0, 0}, - /* VM ENABLE */ - /* PA2 */ {1, 0, 0, 0, 1, 0}, - /* VM DONE */ - /* PA1 */ {1, 0, 0, 1, 1, 0}, - /* VM INIT */ - /* PA0 */ {1, 0, 0, 1, 0, 0} - /* VM ~PROG */ - }, + { + /* cnf par sor dir odr dat */ + { 1, 1, 1, 0, 0, 0 }, /* PA31: FCC1 MII COL */ + { 1, 1, 1, 0, 0, 0 }, /* PA30: FCC1 MII CRS */ + { 1, 1, 1, 1, 0, 0 }, /* PA29: FCC1 MII TX_ER */ + { 1, 1, 1, 1, 0, 0 }, /* PA28: FCC1 MII TX_EN */ + { 1, 1, 1, 0, 0, 0 }, /* PA27: FCC1 MII RX_DV */ + { 1, 1, 1, 0, 0, 0 }, /* PA26: FCC1 MII RX_ER */ + { 1, 0, 0, 1, 0, 0 }, /* PA25: FCC2 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA24: FCC2 MII MDC */ + { 1, 0, 0, 1, 0, 0 }, /* PA23: FCC3 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA22: FCC3 MII MDC */ + { 1, 1, 0, 1, 0, 0 }, /* PA21: FCC1 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PA20: FCC1 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PA19: FCC1 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PA18: FCC1 MII TxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PA17: FCC1 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PA16: FCC1 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PA15: FCC1 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PA14: FCC1 MII RxD[0] */ + { 1, 0, 0, 1, 0, 0 }, /* PA13: FCC1 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA12: FCC1 MII MDC */ + { 1, 0, 0, 1, 0, 0 }, /* PA11: SEL_CD */ + { 1, 0, 0, 0, 0, 0 }, /* PA10: FLASH STS1 */ + { 1, 0, 0, 0, 0, 0 }, /* PA09: FLASH STS0 */ + { 1, 0, 0, 0, 0, 0 }, /* PA08: FLASH ~PE */ + { 1, 0, 0, 0, 0, 0 }, /* PA07: WATCH ~HRESET */ + { 1, 0, 0, 0, 1, 0 }, /* PA06: VC DONE */ + { 1, 0, 0, 1, 1, 0 }, /* PA05: VC INIT */ + { 1, 0, 0, 1, 0, 0 }, /* PA04: VC ~PROG */ + { 1, 0, 0, 1, 0, 0 }, /* PA03: VM ENABLE */ + { 1, 0, 0, 0, 1, 0 }, /* PA02: VM DONE */ + { 1, 0, 0, 1, 1, 0 }, /* PA01: VM INIT */ + { 1, 0, 0, 1, 0, 0 } /* PA00: VM ~PROG */ + }, /* Port B configuration */ - { /* conf ppar psor pdir podr pdat */ - /* PB31 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TX_ER */ - /* PB30 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RX_DV */ - /* PB29 */ {1, 1, 1, 1, 0, 0}, - /* FCC2 MII TX_EN */ - /* PB28 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RX_ER */ - /* PB27 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII COL */ - /* PB26 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII CRS */ - /* PB25 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[3] */ - /* PB24 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[2] */ - /* PB23 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[1] */ - /* PB22 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[0] */ - /* PB21 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[0] */ - /* PB20 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[1] */ - /* PB19 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[2] */ - /* PB18 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[3] */ - /* PB17 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RX_DV */ - /* PB16 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RX_ER */ - /* PB15 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TX_ER */ - /* PB14 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TX_EN */ - /* PB13 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII COL */ - /* PB12 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII CRS */ - /* PB11 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[3] */ - /* PB10 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[2] */ - /* PB9 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[1] */ - /* PB8 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[0] */ - /* PB7 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[3] */ - /* PB6 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[2] */ - /* PB5 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[1] */ - /* PB4 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[0] */ - /* PB3 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PB2 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PB1 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PB0 */ {0, 0, 0, 0, 0, 0} - /* pin doesn't exist */ - }, + { + /* cnf par sor dir odr dat */ + { 1, 1, 0, 1, 0, 0 }, /* PB31: FCC2 MII TX_ER */ + { 1, 1, 0, 0, 0, 0 }, /* PB30: FCC2 MII RX_DV */ + { 1, 1, 1, 1, 0, 0 }, /* PB29: FCC2 MII TX_EN */ + { 1, 1, 0, 0, 0, 0 }, /* PB28: FCC2 MII RX_ER */ + { 1, 1, 0, 0, 0, 0 }, /* PB27: FCC2 MII COL */ + { 1, 1, 0, 0, 0, 0 }, /* PB26: FCC2 MII CRS */ + { 1, 1, 0, 1, 0, 0 }, /* PB25: FCC2 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PB24: FCC2 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PB23: FCC2 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PB22: FCC2 MII TxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PB21: FCC2 MII RxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PB20: FCC2 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PB19: FCC2 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PB18: FCC2 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PB17: FCC3 MII RX_DV */ + { 1, 1, 0, 0, 0, 0 }, /* PB16: FCC3 MII RX_ER */ + { 1, 1, 0, 1, 0, 0 }, /* PB15: FCC3 MII TX_ER */ + { 1, 1, 0, 1, 0, 0 }, /* PB14: FCC3 MII TX_EN */ + { 1, 1, 0, 0, 0, 0 }, /* PB13: FCC3 MII COL */ + { 1, 1, 0, 0, 0, 0 }, /* PB12: FCC3 MII CRS */ + { 1, 1, 0, 0, 0, 0 }, /* PB11: FCC3 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PB10: FCC3 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PB09: FCC3 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PB08: FCC3 MII RxD[0] */ + { 1, 1, 0, 1, 0, 0 }, /* PB07: FCC3 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PB06: FCC3 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PB05: FCC3 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PB04: FCC3 MII TxD[0] */ + { 0, 0, 0, 0, 0, 0 }, /* PB03: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PB02: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PB01: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 } /* PB00: pin doesn't exist */ + }, - /* Port C */ - { /* conf ppar psor pdir podr pdat */ - /* PC31 */ {1, 0, 0, 0, 0, 0}, - /* MEZ ~IACK */ - /* PC30 */ {0, 0, 0, 0, 0, 0}, - /* PC29 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCx */ - /* PC28 */ {1, 1, 0, 0, 0, 0}, - /* CLK4 */ - /* PC27 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCF */ - /* PC26 */ {1, 1, 0, 0, 0, 0}, - /* CLK 32K */ - /* PC25 */ {1, 1, 0, 0, 0, 0}, - /* BRG4/CLK7 */ - /* PC24 */ {0, 0, 0, 0, 0, 0}, - /* PC23 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCx */ - /* PC22 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RX_CLK */ - /* PC21 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII TX_CLK */ - /* PC20 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCF */ - /* PC19 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RX_CLK */ - /* PC18 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII TX_CLK */ - /* PC17 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RX_CLK */ - /* PC16 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII TX_CLK */ - /* PC15 */ {1, 0, 0, 0, 0, 0}, - /* SCC1 UART ~CTS */ - /* PC14 */ {1, 0, 0, 0, 0, 0}, - /* SCC1 UART ~CD */ - /* PC13 */ {1, 0, 0, 0, 0, 0}, - /* SCC2 UART ~CTS */ - /* PC12 */ {1, 0, 0, 0, 0, 0}, - /* SCC2 UART ~CD */ - /* PC11 */ {1, 0, 0, 1, 0, 0}, - /* SCC1 UART ~DTR */ - /* PC10 */ {1, 0, 0, 1, 0, 0}, - /* SCC1 UART ~DSR */ - /* PC9 */ {1, 0, 0, 1, 0, 0}, - /* SCC2 UART ~DTR */ - /* PC8 */ {1, 0, 0, 1, 0, 0}, - /* SCC2 UART ~DSR */ - /* PC7 */ {1, 0, 0, 0, 0, 0}, - /* TEMP ~ALERT */ - /* PC6 */ {1, 0, 0, 0, 0, 0}, - /* FCC3 INT */ - /* PC5 */ {1, 0, 0, 0, 0, 0}, - /* FCC2 INT */ - /* PC4 */ {1, 0, 0, 0, 0, 0}, - /* FCC1 INT */ - /* PC3 */ {1, 1, 1, 1, 0, 0}, - /* SDMA IDMA2 ~DACK */ - /* PC2 */ {1, 1, 1, 0, 0, 0}, - /* SDMA IDMA2 ~DONE */ - /* PC1 */ {1, 1, 0, 0, 0, 0}, - /* SDMA IDMA2 ~DREQ */ - /* PC0 */ {1, 1, 0, 1, 0, 0} - /* BRG7 */ - }, + /* Port C configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 0, 0, 0, 0, 0 }, /* PC31: MEZ ~IACK */ + { 0, 0, 0, 0, 0, 0 }, /* PC30: ? */ + { 1, 1, 0, 0, 0, 0 }, /* PC29: CLK SCCx */ + { 1, 1, 0, 0, 0, 0 }, /* PC28: CLK4 */ + { 1, 1, 0, 0, 0, 0 }, /* PC27: CLK SCCF */ + { 1, 1, 0, 0, 0, 0 }, /* PC26: CLK 32K */ + { 1, 1, 0, 0, 0, 0 }, /* PC25: BRG4/CLK7 */ + { 0, 0, 0, 0, 0, 0 }, /* PC24: ? */ + { 1, 1, 0, 0, 0, 0 }, /* PC23: CLK SCCx */ + { 1, 1, 0, 0, 0, 0 }, /* PC22: FCC1 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC21: FCC1 MII TX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC20: CLK SCCF */ + { 1, 1, 0, 0, 0, 0 }, /* PC19: FCC2 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC18: FCC2 MII TX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC17: FCC3 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC16: FCC3 MII TX_CLK */ + { 1, 0, 0, 0, 0, 0 }, /* PC15: SCC1 UART ~CTS */ + { 1, 0, 0, 0, 0, 0 }, /* PC14: SCC1 UART ~CD */ + { 1, 0, 0, 0, 0, 0 }, /* PC13: SCC2 UART ~CTS */ + { 1, 0, 0, 0, 0, 0 }, /* PC12: SCC2 UART ~CD */ + { 1, 0, 0, 1, 0, 0 }, /* PC11: SCC1 UART ~DTR */ + { 1, 0, 0, 1, 0, 0 }, /* PC10: SCC1 UART ~DSR */ + { 1, 0, 0, 1, 0, 0 }, /* PC09: SCC2 UART ~DTR */ + { 1, 0, 0, 1, 0, 0 }, /* PC08: SCC2 UART ~DSR */ + { 1, 0, 0, 0, 0, 0 }, /* PC07: TEMP ~ALERT */ + { 1, 0, 0, 0, 0, 0 }, /* PC06: FCC3 INT */ + { 1, 0, 0, 0, 0, 0 }, /* PC05: FCC2 INT */ + { 1, 0, 0, 0, 0, 0 }, /* PC04: FCC1 INT */ + { 0, 1, 1, 1, 0, 0 }, /* PC03: SDMA IDMA2 ~DACK */ + { 0, 1, 1, 0, 0, 0 }, /* PC02: SDMA IDMA2 ~DONE */ + { 0, 1, 0, 0, 0, 0 }, /* PC01: SDMA IDMA2 ~DREQ */ + { 1, 1, 0, 1, 0, 0 } /* PC00: BRG7 */ + }, - /* Port D */ - { /* conf ppar psor pdir podr pdat */ - /* PD31 */ {1, 1, 0, 0, 0, 0}, - /* SCC1 UART RxD */ - /* PD30 */ {1, 1, 1, 1, 0, 0}, - /* SCC1 UART TxD */ - /* PD29 */ {1, 0, 0, 1, 0, 0}, - /* SCC1 UART ~RTS */ - /* PD28 */ {1, 1, 0, 0, 0, 0}, - /* SCC2 UART RxD */ - /* PD27 */ {1, 1, 0, 1, 0, 0}, - /* SCC2 UART TxD */ - /* PD26 */ {1, 0, 0, 1, 0, 0}, - /* SCC2 UART ~RTS */ - /* PD25 */ {1, 0, 0, 0, 0, 0}, - /* SCC1 UART ~RI */ - /* PD24 */ {1, 0, 0, 0, 0, 0}, - /* SCC2 UART ~RI */ - /* PD23 */ {1, 0, 0, 1, 0, 0}, - /* CLKGEN PD */ - /* PD22 */ {1, 0, 0, 0, 0, 0}, - /* USER3 */ - /* PD21 */ {1, 0, 0, 0, 0, 0}, - /* USER2 */ - /* PD20 */ {1, 0, 0, 0, 0, 0}, - /* USER1 */ - /* PD19 */ {1, 1, 1, 0, 0, 0}, - /* SPI ~SEL */ - /* PD18 */ {1, 1, 1, 0, 0, 0}, - /* SPI CLK */ - /* PD17 */ {1, 1, 1, 0, 0, 0}, - /* SPI MOSI */ - /* PD16 */ {1, 1, 1, 0, 0, 0}, - /* SPI MISO */ - /* PD15 */ {1, 1, 1, 0, 1, 0}, - /* I2C SDA */ - /* PD14 */ {1, 1, 1, 0, 1, 0}, - /* I2C SCL */ - /* PD13 */ {1, 0, 0, 1, 0, 1}, - /* TEMP ~STDBY */ - /* PD12 */ {1, 0, 0, 1, 0, 1}, - /* FCC3 ~RESET */ - /* PD11 */ {1, 0, 0, 1, 0, 1}, - /* FCC2 ~RESET */ - /* PD10 */ {1, 0, 0, 1, 0, 1}, - /* FCC1 ~RESET */ - /* PD9 */ {1, 0, 0, 0, 0, 0}, - /* PD9 */ - /* PD8 */ {1, 0, 0, 0, 0, 0}, - /* PD8 */ - /* PD7 */ {1, 0, 0, 1, 0, 1}, - /* PD7 */ - /* PD6 */ {1, 0, 0, 1, 0, 1}, - /* PD6 */ - /* PD5 */ {1, 0, 0, 1, 0, 1}, - /* PD5 */ - /* PD4 */ {1, 0, 0, 1, 0, 1}, - /* PD4 */ - /* PD3 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PD2 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PD1 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PD0 */ {0, 0, 0, 0, 0, 0} - /* pin doesn't exist */ - } + /* Port D configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 1, 0, 0, 0, 0 }, /* PD31: SCC1 UART RxD */ + { 1, 1, 1, 1, 0, 0 }, /* PD30: SCC1 UART TxD */ + { 1, 0, 0, 1, 0, 0 }, /* PD29: SCC1 UART ~RTS */ + { 1, 1, 0, 0, 0, 0 }, /* PD28: SCC2 UART RxD */ + { 1, 1, 0, 1, 0, 0 }, /* PD27: SCC2 UART TxD */ + { 1, 0, 0, 1, 0, 0 }, /* PD26: SCC2 UART ~RTS */ + { 1, 0, 0, 0, 0, 0 }, /* PD25: SCC1 UART ~RI */ + { 1, 0, 0, 0, 0, 0 }, /* PD24: SCC2 UART ~RI */ + { 1, 0, 0, 1, 0, 0 }, /* PD23: CLKGEN PD */ + { 1, 0, 0, 0, 0, 0 }, /* PD22: USER3 */ + { 1, 0, 0, 0, 0, 0 }, /* PD21: USER2 */ + { 1, 0, 0, 0, 0, 0 }, /* PD20: USER1 */ + { 1, 1, 1, 0, 0, 0 }, /* PD19: SPI ~SEL */ + { 1, 1, 1, 0, 0, 0 }, /* PD18: SPI CLK */ + { 1, 1, 1, 0, 0, 0 }, /* PD17: SPI MOSI */ + { 1, 1, 1, 0, 0, 0 }, /* PD16: SPI MISO */ + { 1, 1, 1, 0, 1, 0 }, /* PD15: I2C SDA */ + { 1, 1, 1, 0, 1, 0 }, /* PD14: I2C SCL */ + { 1, 0, 0, 1, 0, 1 }, /* PD13: TEMP ~STDBY */ + { 1, 0, 0, 1, 0, 1 }, /* PD12: FCC3 ~RESET */ + { 1, 0, 0, 1, 0, 1 }, /* PD11: FCC2 ~RESET */ + { 1, 0, 0, 1, 0, 1 }, /* PD10: FCC1 ~RESET */ + { 1, 0, 0, 0, 0, 0 }, /* PD09: PD9 */ + { 1, 0, 0, 0, 0, 0 }, /* PD08: PD8 */ + { 1, 0, 0, 1, 0, 1 }, /* PD07: PD7 */ + { 1, 0, 0, 1, 0, 1 }, /* PD06: PD6 */ + { 1, 0, 0, 1, 0, 1 }, /* PD05: PD5 */ + { 1, 0, 0, 1, 0, 1 }, /* PD04: PD4 */ + { 0, 0, 0, 0, 0, 0 }, /* PD03: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PD02: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PD01: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 } /* PD00: pin doesn't exist */ + } }; /* ------------------------------------------------------------------------- */ @@ -334,17 +209,36 @@ const iop_conf_t iop_conf_tab[4][32] = { * * the data is written to the FS6377 via the i2c bus using address in * "fs6377_addr" (address is 7 bits - R/W bit not included). + * + * The fs6377 has four clock outputs: A, B, C and D. + * + * Outputs C and D can each provide two different clock outputs C1/D1 or + * C2/D2 depending on the state of the SEL_CD input which is connected to + * the MPC8260 I/O port pin PA11. PA11 output (SEL_CD input) low (or 0) + * selects C1/D1 and PA11 output (SEL_CD input) high (or 1) selects C2/D2. + * + * PA11 defaults to output low (or 0) in the i/o port config table above. + * + * Output A provides a 100MHz for the High Speed Serial chips. Output B + * provides a 3.6864MHz clock for more accurate asynchronous serial bit + * rates. Output C is routed to the mezzanine connector but is currently + * unused - both C1 and C2 are set to 16MHz. Output D is used by both the + * alt-input and display mezzanine boards for their video chips. The + * alt-input board requires a clock of 24.576MHz and this is available on + * D1 (PA11=SEL_CD=0). The display board requires a clock of 27MHz and this + * is available on D2 (PA11=SEL_CD=1). + * + * So the default is a clock suitable for the alt-input board. PA11 is toggled + * later in misc_init_r(), if a display board is detected. */ uchar fs6377_addr = 0x5c; uchar fs6377_regs[16] = { - 12, 75, 64, 25, 144, 128, 25, 192, - 0, 16, 135, 192, 224, 64, 64, 192 + 12, 75, 64, 25, 144, 128, 25, 192, + 0, 16, 135, 192, 224, 64, 64, 192 }; -iopin_t pa11 = { IOPIN_PORTA, 11, 0 }; - /* ------------------------------------------------------------------------- */ /* @@ -356,7 +250,8 @@ iopin_t pa11 = { IOPIN_PORTA, 11, 0 }; * the timebase, for udelay()) */ -int board_postclk_init (void) +int +board_postclk_init (void) { i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); @@ -371,7 +266,7 @@ int board_postclk_init (void) * if this doesn't work */ (void) i2c_write (fs6377_addr, 0, 1, fs6377_regs, - sizeof (fs6377_regs)); + sizeof (fs6377_regs)); return (0); } @@ -382,7 +277,8 @@ int board_postclk_init (void) * Check Board Identity: Hardwired to HYMOD */ -int checkboard (void) +int +checkboard (void) { puts ("Board: HYMOD\n"); return (0); @@ -446,7 +342,8 @@ uint upmc_table[] = { _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_ }; -int misc_init_f (void) +int +misc_init_f (void) { volatile immap_t *immap = (immap_t *) CFG_IMMR; volatile memctl8260_t *memctl = &immap->im_memctl; @@ -465,7 +362,8 @@ int misc_init_f (void) /* ------------------------------------------------------------------------- */ -long initdram (int board_type) +long +initdram (int board_type) { volatile immap_t *immap = (immap_t *) CFG_IMMR; volatile memctl8260_t *memctl = &immap->im_memctl; @@ -523,280 +421,95 @@ long initdram (int board_type) /* containing information to be stored in the eeprom from the tftp server */ /* (the file name is based on the serial number and a built-in path) */ -/* these are relative to the root of the server's tftp directory */ -static char *bddb_cfgdir = "/hymod/bddb"; -static char *global_env_path = "/hymod/global_env"; - -static ulong get_serno (const char *prompt) -{ - for (;;) { - int n; - char *p; - ulong serno; - - n = readline (prompt); - - if (n < 0) - return (0); - - if (n == 0) - continue; - - serno = simple_strtol (console_buffer, &p, 10); - - if (p > console_buffer && *p == '\0') - return (serno); - - printf ("Invalid number (%s) - please re-enter\n", console_buffer); - } -} - -static int read_eeprom (char *label, unsigned offset, hymod_eeprom_t * ep) -{ - char filename[50], prompt[50]; - ulong serno; - int count = 0; - - sprintf (prompt, "Enter %s board serial number: ", label); - - for (;;) { - - if (eeprom_load (offset, ep)) - return (1); - - printf ("*** %s board EEPROM contents are %sinvalid\n", - label, count == 0 ? "" : "STILL "); - - puts ("*** will attempt to fetch from server (Ctrl-C to abort)\n"); - - if ((serno = get_serno (prompt)) == 0) { - puts ("\n*** interrupted! - ignoring eeprom contents\n"); - return (0); - } - - sprintf (filename, "%s/%010lu.cfg", bddb_cfgdir, serno); - - printf ("*** fetching %s board EEPROM contents from server\n", - label); - - if (eeprom_fetch (offset, filename, 0x100000) == 0) { - puts ("*** fetch failed - ignoring eeprom contents\n"); - return (0); - } - - count++; - } -} - -static ulong main_serno; - -static int env_fetch_callback (uchar * name, uchar * value) -{ - char *ov, nv[CFG_CBSIZE], *p, *q, *nn; - int override = 1, append = 0, nl; - - nn = name; - if (*nn == '-') { - override = 0; - nn++; - } - - if ((nl = strlen (nn)) > 0 && nn[nl - 1] == '+') { - append = 1; - nn[--nl] = '\0'; - } - - p = value; - q = nv; - - while ((*q = *p++) != '\0') - if (*q == '%') { - switch (*p++) { - - case '\0': /* whoops - back up */ - p--; - break; - - case '%': /* a single percent character */ - q++; - break; - - case 's': /* main board serial number as string */ - q += sprintf (q, "%010lu", main_serno); - break; - - case 'S': /* main board serial number as number */ - q += sprintf (q, "%lu", main_serno); - break; - - default: /* ignore any others */ - break; - } - } else - q++; - - if ((ov = getenv (nn)) != NULL) { - - if (append) { - - if (strstr (ov, nv) == NULL) { - int ovl, nvl; - - printf ("Appending '%s' to env cmd '%s'\n", nv, nn); - - ovl = strlen (ov); - nvl = strlen (nv); - - while (nvl >= 0) { - nv[ovl + 1 + nvl] = nv[nvl]; - nvl--; - } - - nv[ovl] = ' '; - - while (--ovl >= 0) - nv[ovl] = ov[ovl]; - - setenv (nn, nv); - } - - return (1); - } - - if (!override || strcmp (ov, nv) == 0) - return (1); - - printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", nn, ov, nv); - } else - printf ("Setting env cmd '%s' to '%s'\n", nn, nv); - - setenv (nn, nv); - return (1); -} - -int misc_init_r (void) +int +last_stage_init (void) { DECLARE_GLOBAL_DATA_PTR; hymod_conf_t *cp = &gd->bd->bi_hymod_conf; int rc; +#ifdef CONFIG_BOOT_RETRY_TIME + /* + * we use the readline () function, but we also want + * command timeout enabled + */ + init_cmd_timeout (); +#endif + memset ((void *) cp, 0, sizeof (*cp)); /* set up main board config info */ - if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MAIN)) { + rc = hymod_eeprom_read (0, &cp->main.eeprom); - if (read_eeprom - ("main", HYMOD_EEOFF_MAIN << 8, &cp->main.eeprom)) - cp->main.eeprom_valid = 1; + puts ("EEPROM:main..."); + if (rc < 0) + puts ("NOT PRESENT\n"); + else if (rc == 0) + puts ("INVALID\n"); + else { + cp->main.eeprom.valid = 1; - puts ("EEPROM:main..."); + printf ("OK (ver %u)\n", cp->main.eeprom.ver); + hymod_eeprom_print (&cp->main.eeprom); - if (cp->main.eeprom_valid) { - printf ("OK (ver %u)\n", cp->main.eeprom.ver); - eeprom_print (&cp->main.eeprom); - main_serno = cp->main.eeprom.serno; - } else - puts ("BAD\n"); + /* + * hard-wired assumption here: all hymod main boards will have + * one xilinx fpga, with the interrupt line connected to IRQ2 + * + * One day, this might be based on the board type + */ - cp->main.mmap[0].prog.exists = 1; - cp->main.mmap[0].prog.size = FPGA_MAIN_CFG_SIZE; - cp->main.mmap[0].prog.base = FPGA_MAIN_CFG_BASE; + cp->main.xlx[0].mmap.prog.exists = 1; + cp->main.xlx[0].mmap.prog.size = FPGA_MAIN_CFG_SIZE; + cp->main.xlx[0].mmap.prog.base = FPGA_MAIN_CFG_BASE; - cp->main.mmap[0].reg.exists = 1; - cp->main.mmap[0].reg.size = FPGA_MAIN_REG_SIZE; - cp->main.mmap[0].reg.base = FPGA_MAIN_REG_BASE; + cp->main.xlx[0].mmap.reg.exists = 1; + cp->main.xlx[0].mmap.reg.size = FPGA_MAIN_REG_SIZE; + cp->main.xlx[0].mmap.reg.base = FPGA_MAIN_REG_BASE; - cp->main.mmap[0].port.exists = 1; - cp->main.mmap[0].port.size = FPGA_MAIN_PORT_SIZE; - cp->main.mmap[0].port.base = FPGA_MAIN_PORT_BASE; + cp->main.xlx[0].mmap.port.exists = 1; + cp->main.xlx[0].mmap.port.size = FPGA_MAIN_PORT_SIZE; + cp->main.xlx[0].mmap.port.base = FPGA_MAIN_PORT_BASE; - cp->main.iopins[0].prog_pin.port = FPGA_MAIN_PROG_PORT; - cp->main.iopins[0].prog_pin.pin = FPGA_MAIN_PROG_PIN; - cp->main.iopins[0].prog_pin.flag = 1; - cp->main.iopins[0].init_pin.port = FPGA_MAIN_INIT_PORT; - cp->main.iopins[0].init_pin.pin = FPGA_MAIN_INIT_PIN; - cp->main.iopins[0].init_pin.flag = 1; - cp->main.iopins[0].done_pin.port = FPGA_MAIN_DONE_PORT; - cp->main.iopins[0].done_pin.pin = FPGA_MAIN_DONE_PIN; - cp->main.iopins[0].done_pin.flag = 1; + cp->main.xlx[0].iopins.prog_pin.port = FPGA_MAIN_PROG_PORT; + cp->main.xlx[0].iopins.prog_pin.pin = FPGA_MAIN_PROG_PIN; + cp->main.xlx[0].iopins.prog_pin.flag = 1; + cp->main.xlx[0].iopins.init_pin.port = FPGA_MAIN_INIT_PORT; + cp->main.xlx[0].iopins.init_pin.pin = FPGA_MAIN_INIT_PIN; + cp->main.xlx[0].iopins.init_pin.flag = 1; + cp->main.xlx[0].iopins.done_pin.port = FPGA_MAIN_DONE_PORT; + cp->main.xlx[0].iopins.done_pin.pin = FPGA_MAIN_DONE_PIN; + cp->main.xlx[0].iopins.done_pin.flag = 1; #ifdef FPGA_MAIN_ENABLE_PORT - cp->main.iopins[0].enable_pin.port = FPGA_MAIN_ENABLE_PORT; - cp->main.iopins[0].enable_pin.pin = FPGA_MAIN_ENABLE_PIN; - cp->main.iopins[0].enable_pin.flag = 1; + cp->main.xlx[0].iopins.enable_pin.port = FPGA_MAIN_ENABLE_PORT; + cp->main.xlx[0].iopins.enable_pin.pin = FPGA_MAIN_ENABLE_PIN; + cp->main.xlx[0].iopins.enable_pin.flag = 1; #endif - } else - puts ("EEPROM:main...NOT PRESENT\n"); + + cp->main.xlx[0].irq = FPGA_MAIN_IRQ; + } /* set up mezzanine board config info */ - if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MEZZ)) { + rc = hymod_eeprom_read (1, &cp->mezz.eeprom); - if (read_eeprom - ("mezz", HYMOD_EEOFF_MEZZ << 8, &cp->mezz.eeprom)) - cp->mezz.eeprom_valid = 1; + puts ("EEPROM:mezz..."); + if (rc < 0) + puts ("NOT PRESENT\n"); + else if (rc == 0) + puts ("INVALID\n"); + else { + cp->main.eeprom.valid = 1; - puts ("EEPROM:mezz..."); - - if (cp->mezz.eeprom_valid) { - printf ("OK (ver %u)\n", cp->mezz.eeprom.ver); - eeprom_print (&cp->mezz.eeprom); - } else - puts ("BAD\n"); - - cp->mezz.mmap[0].prog.exists = 1; - cp->mezz.mmap[0].prog.size = FPGA_MEZZ_CFG_SIZE; - cp->mezz.mmap[0].prog.base = FPGA_MEZZ_CFG_BASE; - - cp->mezz.mmap[0].reg.exists = 0; - - cp->mezz.mmap[0].port.exists = 0; - - cp->mezz.iopins[0].prog_pin.port = FPGA_MEZZ_PROG_PORT; - cp->mezz.iopins[0].prog_pin.pin = FPGA_MEZZ_PROG_PIN; - cp->mezz.iopins[0].prog_pin.flag = 1; - cp->mezz.iopins[0].init_pin.port = FPGA_MEZZ_INIT_PORT; - cp->mezz.iopins[0].init_pin.pin = FPGA_MEZZ_INIT_PIN; - cp->mezz.iopins[0].init_pin.flag = 1; - cp->mezz.iopins[0].done_pin.port = FPGA_MEZZ_DONE_PORT; - cp->mezz.iopins[0].done_pin.pin = FPGA_MEZZ_DONE_PIN; - cp->mezz.iopins[0].done_pin.flag = 1; -#ifdef FPGA_MEZZ_ENABLE_PORT - cp->mezz.iopins[0].enable_pin.port = FPGA_MEZZ_ENABLE_PORT; - cp->mezz.iopins[0].enable_pin.pin = FPGA_MEZZ_ENABLE_PIN; - cp->mezz.iopins[0].enable_pin.flag = 1; -#endif - - if (cp->mezz.eeprom_valid && - cp->mezz.eeprom.bdtype == HYMOD_BDTYPE_DISPLAY) { - /* - * mezzanine board is a display board - switch the SEL_CD - * input of the FS6377 clock generator (via I/O Port Pin PA11) to - * high (or 1) to select the 27MHz required by the display board - */ - iopin_set_high (&pa11); - - puts ("SEL_CD:toggled for display board\n"); - } - } else - puts ("EEPROM:mezz...NOT PRESENT\n"); - - cp->crc = - crc32 (0, (unsigned char *) cp, offsetof (hymod_conf_t, crc)); - - if (getenv ("global_env_loaded") == NULL) { - - puts ("*** global environment has not been loaded\n"); - puts ("*** fetching from server (Control-C to Abort)\n"); - - rc = fetch_and_parse (global_env_path, 0x100000, - env_fetch_callback); - - if (rc == 0) - puts ("*** Fetch of environment failed!\n"); - else - setenv ("global_env_loaded", "yes"); + printf ("OK (ver %u)\n", cp->mezz.eeprom.ver); + hymod_eeprom_print (&cp->mezz.eeprom); } + + cp->crc = crc32 (0, (unsigned char *)cp, offsetof (hymod_conf_t, crc)); + + hymod_check_env (); + return (0); } diff --git a/board/hymod/hymod.h b/board/hymod/hymod.h new file mode 100644 index 0000000000..9d8d66271f --- /dev/null +++ b/board/hymod/hymod.h @@ -0,0 +1,322 @@ +/* + * (C) Copyright 2001 + * Murray Jensen, CSIRO-MIT, + * + * 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 + */ + +#ifndef _HYMOD_H_ +#define _HYMOD_H_ + +#include +#ifdef CONFIG_8260 +#include +#endif + +/* + * hymod configuration data - passed by boot code via the board information + * structure (only U-Boot has support for this at the moment) + * + * there are three types of data passed up from the boot monitor. the first + * (type hymod_eeprom_t) is the eeprom data that was read off both the main + * (or mother) board and the mezzanine board (if any). this data defines how + * many Xilinx fpgas are on each board, and their types (among other things). + * the second type of data (type xlx_mmap_t, one per Xilinx fpga) defines where + * in the physical address space the various Xilinx fpga access regions have + * been mapped by the boot rom. the third type of data (type xlx_iopins_t, + * one per Xilinx fpga) defines which io port pins are connected to the various + * signals required to program a Xilinx fpga. + * + * A ram/flash "bank" refers to memory controlled by the same chip select. + * + * the eeprom contents are defined as in technical note #2 - basically, + * a header, zero or more records in no particular order, and a 32 bit crc + * a record is 1 or more type bytes, a length byte and "length" bytes. + */ + +#define HYMOD_EEPROM_ID 0xAA /* eeprom id byte */ +#define HYMOD_EEPROM_VER 1 /* eeprom contents version (0-127) */ +#define HYMOD_EEPROM_SIZE 256 /* number of bytes in the eeprom */ + +/* eeprom header */ +typedef + struct { + unsigned char id; /* eeprom id byte */ + unsigned char :1; + unsigned char ver:7; /* eeprom contents version number */ + unsigned long len; /* total # of bytes btw hdr and crc */ + } +hymod_eehdr_t; + +/* maximum number of bytes available for eeprom data records */ +#define HYMOD_EEPROM_MAXLEN (HYMOD_EEPROM_SIZE \ + - sizeof (hymod_eehdr_t) \ + - sizeof (unsigned long)) + +/* eeprom data record */ +typedef + union { + struct { + unsigned char topbit:1; + unsigned char type:7; + unsigned char len; + unsigned char data[1]; /* variable length */ + } small; + struct { + unsigned short topbit:1; + unsigned short nxtbit:1; + unsigned short type:14; + unsigned short len; + unsigned char data[1]; /* variable length */ + } medium; + struct { + unsigned long topbit:1; + unsigned long nxtbit:1; + unsigned long type:30; + unsigned long len; + unsigned char data[1]; /* variable length */ + } large; + } +hymod_eerec_t; + +#define HYMOD_EEOFF_MAIN 0x00 /* i2c addr offset for main eeprom */ +#define HYMOD_EEOFF_MEZZ 0x04 /* i2c addr offset for mezz eepomr */ + +/* eeprom record types */ +#define HYMOD_EEREC_SERNO 1 /* serial number */ +#define HYMOD_EEREC_DATE 2 /* date */ +#define HYMOD_EEREC_BATCH 3 /* batch id */ +#define HYMOD_EEREC_TYPE 4 /* board type */ +#define HYMOD_EEREC_REV 5 /* revision number */ +#define HYMOD_EEREC_SDRAM 6 /* sdram sizes */ +#define HYMOD_EEREC_FLASH 7 /* flash sizes */ +#define HYMOD_EEREC_ZBT 8 /* zbt ram sizes */ +#define HYMOD_EEREC_XLXTYP 9 /* Xilinx fpga types */ +#define HYMOD_EEREC_XLXSPD 10 /* Xilinx fpga speeds */ +#define HYMOD_EEREC_XLXTMP 11 /* Xilinx fpga temperatures */ +#define HYMOD_EEREC_XLXGRD 12 /* Xilinx fpga grades */ +#define HYMOD_EEREC_CPUTYP 13 /* Motorola CPU type */ +#define HYMOD_EEREC_CPUSPD 14 /* CPU speed */ +#define HYMOD_EEREC_BUSSPD 15 /* bus speed */ +#define HYMOD_EEREC_CPMSPD 16 /* CPM speed */ +#define HYMOD_EEREC_HSTYPE 17 /* high-speed serial chip type */ +#define HYMOD_EEREC_HSCHIN 18 /* high-speed serial input channels */ +#define HYMOD_EEREC_HSCHOUT 19 /* high-speed serial output channels */ + +/* some dimensions */ +#define HYMOD_MAX_BATCH 32 /* max no. of bytes in batch id */ +#define HYMOD_MAX_SDRAM 4 /* max sdram "banks" on any board */ +#define HYMOD_MAX_FLASH 4 /* max flash "banks" on any board */ +#define HYMOD_MAX_ZBT 16 /* max ZBT rams on any board */ +#define HYMOD_MAX_XLX 4 /* max Xilinx fpgas on any board */ + +#define HYMOD_MAX_BYTES 16 /* enough to store any bytes array */ + +/* board types */ +#define HYMOD_BDTYPE_NONE 0 /* information not present */ +#define HYMOD_BDTYPE_IO 1 /* I/O main board */ +#define HYMOD_BDTYPE_CLP 2 /* CLP main board */ +#define HYMOD_BDTYPE_DSP 3 /* DSP main board */ +#define HYMOD_BDTYPE_INPUT 4 /* video input mezzanine board */ +#define HYMOD_BDTYPE_ALTINPUT 5 /* video input mezzanine board */ +#define HYMOD_BDTYPE_DISPLAY 6 /* video display mezzanine board */ +#define HYMOD_BDTYPE_MAX 7 /* first invalid value */ + +/* Xilinx fpga types */ +#define HYMOD_XTYP_NONE 0 /* information not present */ +#define HYMOD_XTYP_XCV300E 1 /* Xilinx Virtex 300 */ +#define HYMOD_XTYP_XCV400E 2 /* Xilinx Virtex 400 */ +#define HYMOD_XTYP_XCV600E 3 /* Xilinx Virtex 600 */ +#define HYMOD_XTYP_MAX 4 /* first invalid value */ + +/* Xilinx fpga speeds */ +#define HYMOD_XSPD_NONE 0 /* information not present */ +#define HYMOD_XSPD_SIX 1 +#define HYMOD_XSPD_SEVEN 2 +#define HYMOD_XSPD_EIGHT 3 +#define HYMOD_XSPD_MAX 4 /* first invalid value */ + +/* Xilinx fpga temperatures */ +#define HYMOD_XTMP_NONE 0 /* information not present */ +#define HYMOD_XTMP_COM 1 +#define HYMOD_XTMP_IND 2 +#define HYMOD_XTMP_MAX 3 /* first invalid value */ + +/* Xilinx fpga grades */ +#define HYMOD_XTMP_NONE 0 /* information not present */ +#define HYMOD_XTMP_NORMAL 1 +#define HYMOD_XTMP_ENGSAMP 2 +#define HYMOD_XTMP_MAX 3 /* first invalid value */ + +/* CPU types */ +#define HYMOD_CPUTYPE_NONE 0 /* information not present */ +#define HYMOD_CPUTYPE_MPC8260 1 /* Motorola MPC8260 embedded powerpc */ +#define HYMOD_CPUTYPE_MAX 2 /* first invalid value */ + +/* CPU/BUS/CPM clock speeds */ +#define HYMOD_CLKSPD_NONE 0 /* information not present */ +#define HYMOD_CLKSPD_33MHZ 1 +#define HYMOD_CLKSPD_66MHZ 2 +#define HYMOD_CLKSPD_100MHZ 3 +#define HYMOD_CLKSPD_133MHZ 4 +#define HYMOD_CLKSPD_166MHZ 5 +#define HYMOD_CLKSPD_200MHZ 6 +#define HYMOD_CLKSPD_MAX 7 /* first invalid value */ + +/* high speed serial chip types */ +#define HYMOD_HSSTYPE_NONE 0 /* information not present */ +#define HYMOD_HSSTYPE_AMCC52064 1 +#define HYMOD_HSSTYPE_MAX 2 /* first invalid value */ + +/* a date (yyyy-mm-dd) */ +typedef + struct { + unsigned short year; + unsigned char month; + unsigned char day; + } +hymod_date_t; + +/* describes a Xilinx fpga */ +typedef + struct { + unsigned char type; /* chip type */ + unsigned char speed; /* chip speed rating */ + unsigned char temp; /* chip temperature rating */ + unsigned char grade; /* chip grade */ + } +hymod_xlx_t; + +/* describes a Motorola embedded processor */ +typedef + struct { + unsigned char type; /* CPU type */ + unsigned char cpuspd; /* speed of the PowerPC core */ + unsigned char busspd; /* speed of the system and 60x bus */ + unsigned char cpmspd; /* speed of the CPM co-processor */ + } +hymod_mpc_t; + +/* info about high-speed (1Gbit) serial interface */ +typedef + struct { + unsigned char type; /* high-speed serial chip type */ + unsigned char nchin; /* number of input channels mounted */ + unsigned char nchout; /* number of output channels mounted */ + } +hymod_hss_t; + +/* + * this defines the contents of the serial eeprom that exists on every + * hymod board, including mezzanine boards (the serial eeprom will be + * faked for early development boards that don't have one) + */ + +typedef + struct { + unsigned char valid:1; /* contents of this struct is valid */ + unsigned char ver:7; /* eeprom contents version */ + unsigned char bdtype; /* board type */ + unsigned char bdrev; /* board revision */ + unsigned char batchlen; /* length of batch string below */ + unsigned long serno; /* serial number */ + hymod_date_t date; /* manufacture date */ + unsigned char batch[32]; /* manufacturer specific batch id */ + unsigned char nsdram; /* # of ram "banks" */ + unsigned char nflash; /* # of flash "banks" */ + unsigned char nzbt; /* # of ZBT rams */ + unsigned char nxlx; /* # of Xilinx fpgas */ + unsigned char sdramsz[HYMOD_MAX_SDRAM]; /* log2 of sdram size */ + unsigned char flashsz[HYMOD_MAX_FLASH]; /* log2 of flash size */ + unsigned char zbtsz[HYMOD_MAX_ZBT]; /* log2 of ZBT ram size */ + hymod_xlx_t xlx[HYMOD_MAX_XLX]; /* Xilinx fpga info */ + hymod_mpc_t mpc; /* Motorola MPC CPU info */ + hymod_hss_t hss; /* high-speed serial info */ + } +hymod_eeprom_t; + +/* + * this defines a region in the processor's physical address space + */ +typedef + struct { + unsigned long exists:1; /* 1 if the region exists, 0 if not */ + unsigned long size:31; /* size in bytes */ + unsigned long base; /* base address */ + } +xlx_prgn_t; + +/* + * this defines where the various Xilinx fpga access regions are mapped + * into the physical address space of the processor + */ +typedef + struct { + xlx_prgn_t prog; /* program access region */ + xlx_prgn_t reg; /* register access region */ + xlx_prgn_t port; /* port access region */ + } +xlx_mmap_t; + +/* + * this defines which 8260 i/o port pins are connected to the various + * signals required for programming a Xilinx fpga + */ +typedef + struct { + iopin_t prog_pin; /* assert for >= 300ns to program */ + iopin_t init_pin; /* goes high when fpga is cleared */ + iopin_t done_pin; /* goes high when program is done */ + iopin_t enable_pin; /* some fpgas need enabling */ + } +xlx_iopins_t; + +/* all info about one Xilinx chip */ +typedef + struct { + xlx_mmap_t mmap; + xlx_iopins_t iopins; + unsigned long irq:8; /* h/w intr req number for this fpga */ + } +xlx_info_t; + +/* all info about one hymod board */ +typedef + struct { + hymod_eeprom_t eeprom; + xlx_info_t xlx[HYMOD_MAX_XLX]; + } +hymod_board_t; + +/* + * this defines the configuration information of a hymod board-set + * (main board + possible mezzanine board). In future, there may be + * more than one mezzanine board (stackable?) - if so, add a "mezz2" + * field, and so on... or make mezz an array? + */ +typedef + struct { + unsigned long ver:8; /* version control */ + hymod_board_t main; /* main board info */ + hymod_board_t mezz; /* mezzanine board info */ + unsigned long crc; /* ensures kernel and boot prom agree */ + } +hymod_conf_t; + +#endif /* _HYMOD_H_ */ diff --git a/board/hymod/input.c b/board/hymod/input.c new file mode 100644 index 0000000000..63aa13c4a9 --- /dev/null +++ b/board/hymod/input.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2003 + * Murray Jensen, CSIRO-MIT, + * + * 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 + +/* imports from common/main.c */ +extern char console_buffer[CFG_CBSIZE]; + +int +hymod_get_serno (const char *prompt) +{ + for (;;) { + int n, serno; + char *p; + +#ifdef CONFIG_BOOT_RETRY_TIME + reset_cmd_timeout (); +#endif + + n = readline (prompt); + + if (n < 0) + return (n); + + if (n == 0) + continue; + + serno = (int) simple_strtol (console_buffer, &p, 10); + + if (p > console_buffer && *p == '\0' && serno > 0) + return (serno); + + printf ("Invalid number (%s) - please re-enter\n", + console_buffer); + } +} + +int +hymod_get_ethaddr (void) +{ + for (;;) { + int n; + +#ifdef CONFIG_BOOT_RETRY_TIME + reset_cmd_timeout (); +#endif + + n = readline ("Enter board ethernet address: "); + + if (n < 0) + return (n); + + if (n == 0) + continue; + + if (n == 17) { + int i; + char *p, *q; + uchar ea[6]; + + /* see if it looks like an ethernet address */ + + p = console_buffer; + + for (i = 0; i < 6; i++) { + char term = (i == 5 ? '\0' : ':'); + + ea[i] = simple_strtol (p, &q, 16); + + if ((q - p) != 2 || *q++ != term) + break; + + p = q; + } + + if (i == 6) { + /* it looks ok - set it */ + printf ("Setting ethernet addr to %s\n", + console_buffer); + + setenv ("ethaddr", console_buffer); + + puts ("Remember to do a 'saveenv' to " + "make it permanent\n"); + + return (0); + } + } + + printf ("Invalid ethernet addr (%s) - please re-enter\n", + console_buffer); + } +} diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index 32bab1a8c0..3db0bca69d 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -327,6 +327,26 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn return rcode; } +#ifndef CONFIG_SPI +int +eeprom_probe (unsigned dev_addr, unsigned offset) +{ + unsigned char chip; + + /* Probe the chip address + */ +#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) + chip = offset >> 8; /* block number */ +#else + chip = offset >> 16; /* block number */ +#endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */ + + chip |= dev_addr; /* insert device address */ + + return (i2c_probe (chip)); +} +#endif + /*----------------------------------------------------------------------- * Set default values */ diff --git a/common/console.c b/common/console.c index 86ed584211..8c94aa7656 100644 --- a/common/console.c +++ b/common/console.c @@ -232,6 +232,20 @@ void printf (const char *fmt, ...) puts (printbuffer); } +void vprintf (const char *fmt, va_list args) +{ + uint i; + char printbuffer[CFG_PBSIZE]; + + /* For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + i = vsprintf (printbuffer, fmt, args); + + /* Print the string */ + puts (printbuffer); +} + /* test if ctrl-c was pressed */ static int ctrlc_disabled = 0; /* see disable_ctrl() */ static int ctrlc_was_pressed = 0; diff --git a/common/main.c b/common/main.c index 6192dff365..f538870d5c 100644 --- a/common/main.c +++ b/common/main.c @@ -319,13 +319,7 @@ void main_loop (void) debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay); # ifdef CONFIG_BOOT_RETRY_TIME - s = getenv ("bootretry"); - if (s != NULL) - retry_time = (int)simple_strtoul(s, NULL, 10); - else - retry_time = CONFIG_BOOT_RETRY_TIME; - if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN) - retry_time = CONFIG_BOOT_RETRY_MIN; + init_cmd_timeout (); # endif /* CONFIG_BOOT_RETRY_TIME */ s = getenv ("bootcmd"); @@ -422,10 +416,26 @@ void main_loop (void) #endif /*CFG_HUSH_PARSER*/ } +#ifdef CONFIG_BOOT_RETRY_TIME +/*************************************************************************** + * initialise command line timeout + */ +void init_cmd_timeout(void) +{ + char *s = getenv ("bootretry"); + + if (s != NULL) + retry_time = (int)simple_strtoul(s, NULL, 10); + else + retry_time = CONFIG_BOOT_RETRY_TIME; + + if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN) + retry_time = CONFIG_BOOT_RETRY_MIN; +} + /*************************************************************************** * reset command line timeout to retry_time seconds */ -#ifdef CONFIG_BOOT_RETRY_TIME void reset_cmd_timeout(void) { endtime = endtick(retry_time); diff --git a/config.mk b/config.mk index 92844b1f5d..95b7256c54 100644 --- a/config.mk +++ b/config.mk @@ -96,9 +96,11 @@ RANLIB = $(CROSS_COMPILE)RANLIB RELFLAGS= $(PLATFORM_RELFLAGS) DBGFLAGS= -g #-DDEBUG OPTFLAGS= -Os #-fomit-frame-pointer +ifndef LDSCRIPT #LDSCRIPT := board/$(BOARDDIR)/u-boot.lds.debug LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds -OBJCFLAGS := --gap-fill=0xff +endif +OBJCFLAGS += --gap-fill=0xff CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \ -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \ diff --git a/cpu/mpc8260/cpu_init.c b/cpu/mpc8260/cpu_init.c index 46ac97578d..d0545cfcf2 100644 --- a/cpu/mpc8260/cpu_init.c +++ b/cpu/mpc8260/cpu_init.c @@ -80,9 +80,9 @@ static void config_8260_ioports (volatile immap_t * immr) */ iop->ppar &= tpmsk; iop->psor = (iop->psor & tpmsk) | psor; + iop->podr = (iop->podr & tpmsk) | podr; iop->pdat = (iop->pdat & tpmsk) | pdat; iop->pdir = (iop->pdir & tpmsk) | pdir; - iop->podr = (iop->podr & tpmsk) | podr; iop->ppar |= ppar; } } diff --git a/cpu/mpc8260/ether_fcc.c b/cpu/mpc8260/ether_fcc.c index bd2fcc927f..45dca73203 100644 --- a/cpu/mpc8260/ether_fcc.c +++ b/cpu/mpc8260/ether_fcc.c @@ -391,4 +391,761 @@ int fec_initialize(bd_t *bis) return 1; } +#ifdef CONFIG_ETHER_LOOPBACK_TEST + +#define ELBT_BUFSZ 1024 /* must be multiple of 32 */ + +#define ELBT_CRCSZ 4 + +#define ELBT_NRXBD 4 /* must be at least 2 */ +#define ELBT_NTXBD 4 + +#define ELBT_MAXRXERR 32 +#define ELBT_MAXTXERR 32 + +#define ELBT_CLSWAIT 1000 /* msec to wait for further input frames */ + +typedef + struct { + uint off; + char *lab; + } +elbt_prdesc; + +typedef + struct { + uint _l, _f, m, bc, mc, lg, no, sh, cr, ov, cl; + uint badsrc, badtyp, badlen, badbit; + } +elbt_rxeacc; + +static elbt_prdesc rxeacc_descs[] = { + { offsetof(elbt_rxeacc, _l), "Not Last in Frame" }, + { offsetof(elbt_rxeacc, _f), "Not First in Frame" }, + { offsetof(elbt_rxeacc, m), "Address Miss" }, + { offsetof(elbt_rxeacc, bc), "Broadcast Address" }, + { offsetof(elbt_rxeacc, mc), "Multicast Address" }, + { offsetof(elbt_rxeacc, lg), "Frame Length Violation"}, + { offsetof(elbt_rxeacc, no), "Non-Octet Alignment" }, + { offsetof(elbt_rxeacc, sh), "Short Frame" }, + { offsetof(elbt_rxeacc, cr), "CRC Error" }, + { offsetof(elbt_rxeacc, ov), "Overrun" }, + { offsetof(elbt_rxeacc, cl), "Collision" }, + { offsetof(elbt_rxeacc, badsrc), "Bad Src Address" }, + { offsetof(elbt_rxeacc, badtyp), "Bad Frame Type" }, + { offsetof(elbt_rxeacc, badlen), "Bad Frame Length" }, + { offsetof(elbt_rxeacc, badbit), "Data Compare Errors" }, +}; +static int rxeacc_ndesc = sizeof (rxeacc_descs) / sizeof (rxeacc_descs[0]); + +typedef + struct { + uint def, hb, lc, rl, rc, un, csl; + } +elbt_txeacc; + +static elbt_prdesc txeacc_descs[] = { + { offsetof(elbt_txeacc, def), "Defer Indication" }, + { offsetof(elbt_txeacc, hb), "Heartbeat" }, + { offsetof(elbt_txeacc, lc), "Late Collision" }, + { offsetof(elbt_txeacc, rl), "Retransmission Limit" }, + { offsetof(elbt_txeacc, rc), "Retry Count" }, + { offsetof(elbt_txeacc, un), "Underrun" }, + { offsetof(elbt_txeacc, csl), "Carrier Sense Lost" }, +}; +static int txeacc_ndesc = sizeof (txeacc_descs) / sizeof (txeacc_descs[0]); + +typedef + struct { + uchar rxbufs[ELBT_NRXBD][ELBT_BUFSZ]; + uchar txbufs[ELBT_NTXBD][ELBT_BUFSZ]; + cbd_t rxbd[ELBT_NRXBD]; + cbd_t txbd[ELBT_NTXBD]; + enum { Idle, Running, Closing, Closed } state; + int proff, page, sblock; + uint clstime, nsent, ntxerr, nrcvd, nrxerr; + ushort rxerrs[ELBT_MAXRXERR], txerrs[ELBT_MAXTXERR]; + elbt_rxeacc rxeacc; + elbt_txeacc txeacc; + } __attribute__ ((aligned(8))) +elbt_chan; + +static uchar patbytes[ELBT_NTXBD] = { + 0xff, 0xaa, 0x55, 0x00 +}; +static uint patwords[ELBT_NTXBD] = { + 0xffffffff, 0xaaaaaaaa, 0x55555555, 0x00000000 +}; + +#ifdef __GNUC__ +static elbt_chan elbt_chans[3] __attribute__ ((aligned(8))); +#else +#error "elbt_chans must be 64-bit aligned" +#endif + +#define CPM_CR_GRACEFUL_STOP_TX ((ushort)0x0005) + +static elbt_prdesc epram_descs[] = { + { offsetof(fcc_enet_t, fen_crcec), "CRC Errors" }, + { offsetof(fcc_enet_t, fen_alec), "Alignment Errors" }, + { offsetof(fcc_enet_t, fen_disfc), "Discarded Frames" }, + { offsetof(fcc_enet_t, fen_octc), "Octets" }, + { offsetof(fcc_enet_t, fen_colc), "Collisions" }, + { offsetof(fcc_enet_t, fen_broc), "Broadcast Frames" }, + { offsetof(fcc_enet_t, fen_mulc), "Multicast Frames" }, + { offsetof(fcc_enet_t, fen_uspc), "Undersize Frames" }, + { offsetof(fcc_enet_t, fen_frgc), "Fragments" }, + { offsetof(fcc_enet_t, fen_ospc), "Oversize Frames" }, + { offsetof(fcc_enet_t, fen_jbrc), "Jabbers" }, + { offsetof(fcc_enet_t, fen_p64c), "64 Octet Frames" }, + { offsetof(fcc_enet_t, fen_p65c), "65-127 Octet Frames" }, + { offsetof(fcc_enet_t, fen_p128c), "128-255 Octet Frames" }, + { offsetof(fcc_enet_t, fen_p256c), "256-511 Octet Frames" }, + { offsetof(fcc_enet_t, fen_p512c), "512-1023 Octet Frames" }, + { offsetof(fcc_enet_t, fen_p1024c), "1024-1518 Octet Frames"}, +}; +static int epram_ndesc = sizeof (epram_descs) / sizeof (epram_descs[0]); + +/* + * given an elbt_prdesc array and an array of base addresses, print + * each prdesc down the screen with the values fetched from each + * base address across the screen + */ +static void +print_desc (elbt_prdesc descs[], int ndesc, uchar *bases[], int nbase) +{ + elbt_prdesc *dp = descs, *edp = dp + ndesc; + int i; + + printf ("%32s", ""); + + for (i = 0; i < nbase; i++) + printf (" Channel %d", i); + + puts ("\n"); + + while (dp < edp) { + + printf ("%-32s", dp->lab); + + for (i = 0; i < nbase; i++) { + uint val = *(uint *)(bases[i] + dp->off); + + printf (" %10u", val); + } + + puts ("\n"); + + dp++; + } +} + +/* + * return number of bits that are set in a value; value contains + * nbits (right-justified) bits. + */ +static uint __inline__ +nbs (uint value, uint nbits) +{ + uint cnt = 0; +#if 1 + uint pos = sizeof (uint) * 8; + + __asm__ __volatile__ ("\ + mtctr %2\n\ +1: rlwnm. %2,%1,%4,31,31\n\ + beq 2f\n\ + addi %0,%0,1\n\ +2: subi %4,%4,1\n\ + bdnz 1b" + : "=r"(cnt) + : "r"(value), "r"(nbits), "r"(cnt), "r"(pos) + : "ctr", "cc" ); +#else + uint mask = 1; + + do { + if (value & mask) + cnt++; + mask <<= 1; + } while (--nbits); +#endif + + return (cnt); +} + +static ulong +badbits (uchar *bp, int n, ulong pat) +{ + ulong *lp, cnt = 0; + int nl; + + while (n > 0 && ((ulong)bp & (sizeof (ulong) - 1)) != 0) { + uchar diff; + + diff = *bp++ ^ (uchar)pat; + + if (diff) + cnt += nbs ((ulong)diff, 8); + + n--; + } + + lp = (ulong *)bp; + nl = n / sizeof (ulong); + n -= nl * sizeof (ulong); + + while (nl > 0) { + ulong diff; + + diff = *lp++ ^ pat; + + if (diff) + cnt += nbs (diff, 32); + + nl--; + } + + bp = (uchar *)lp; + + while (n > 0) { + uchar diff; + + diff = *bp++ ^ (uchar)pat; + + if (diff) + cnt += nbs ((ulong)diff, 8); + + n--; + } + + return (cnt); +} + +static inline unsigned short +swap16 (unsigned short x) +{ + return (((x & 0xff) << 8) | ((x & 0xff00) >> 8)); +} + +void +eth_loopback_test (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + volatile immap_t *immr = (immap_t *)CFG_IMMR; + volatile cpm8260_t *cp = &(immr->im_cpm); + int c, nclosed; + ulong runtime, nmsec; + uchar *bases[3]; + + puts ("FCC Ethernet External loopback test\n"); + + memcpy (NetOurEther, gd->bd->bi_enetaddr, 6); + + /* + * global initialisations for all FCC channels + */ + + /* 28.9 - (1-2): ioports have been set up already */ + +#if defined(CONFIG_HYMOD) + /* + * Attention: this is board-specific + * - FCC1 Rx-CLK is CLK10 + * - FCC1 Tx-CLK is CLK11 + * - FCC2 Rx-CLK is CLK13 + * - FCC2 Tx-CLK is CLK14 + * - FCC3 Rx-CLK is CLK15 + * - FCC3 Tx-CLK is CLK16 + */ + + /* 28.9 - (3): connect FCC's tx and rx clocks */ + immr->im_cpmux.cmx_uar = 0; + immr->im_cpmux.cmx_fcr = CMXFCR_RF1CS_CLK10|CMXFCR_TF1CS_CLK11|\ + CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14|\ + CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16; +#else +#error "eth_loopback_test not supported on your board" +#endif + + puts ("Initialise FCC channels:"); + + for (c = 0; c < 3; c++) { + elbt_chan *ecp = &elbt_chans[c]; + volatile fcc_t *fcp = &immr->im_fcc[c]; + volatile fcc_enet_t *fpp; + int i; + ulong addr; + + /* + * initialise channel data + */ + + printf (" %d", c); + + memset ((void *)ecp, 0, sizeof (*ecp)); + + ecp->state = Idle; + + switch (c) { + + case 0: /* FCC1 */ + ecp->proff = PROFF_FCC1; + ecp->page = CPM_CR_FCC1_PAGE; + ecp->sblock = CPM_CR_FCC1_SBLOCK; + break; + + case 1: /* FCC2 */ + ecp->proff = PROFF_FCC2; + ecp->page = CPM_CR_FCC2_PAGE; + ecp->sblock = CPM_CR_FCC2_SBLOCK; + break; + + case 2: /* FCC3 */ + ecp->proff = PROFF_FCC3; + ecp->page = CPM_CR_FCC3_PAGE; + ecp->sblock = CPM_CR_FCC3_SBLOCK; + break; + } + + /* + * set up tx buffers and bds + */ + + for (i = 0; i < ELBT_NTXBD; i++) { + cbd_t *bdp = &ecp->txbd[i]; + uchar *bp = &ecp->txbufs[i][0]; + + bdp->cbd_bufaddr = (uint)bp; + /* room for crc */ + bdp->cbd_datlen = ELBT_BUFSZ - ELBT_CRCSZ; + bdp->cbd_sc = BD_ENET_TX_READY | BD_ENET_TX_PAD | \ + BD_ENET_TX_LAST | BD_ENET_TX_TC; + + memset ((void *)bp, patbytes[i], ELBT_BUFSZ); + NetSetEther (bp, NetBcastAddr, 0x8000); + } + ecp->txbd[ELBT_NTXBD - 1].cbd_sc |= BD_ENET_TX_WRAP; + + /* + * set up rx buffers and bds + */ + + for (i = 0; i < ELBT_NRXBD; i++) { + cbd_t *bdp = &ecp->rxbd[i]; + uchar *bp = &ecp->rxbufs[i][0]; + + bdp->cbd_bufaddr = (uint)bp; + bdp->cbd_datlen = 0; + bdp->cbd_sc = BD_ENET_RX_EMPTY; + + memset ((void *)bp, 0, ELBT_BUFSZ); + } + ecp->rxbd[ELBT_NRXBD - 1].cbd_sc |= BD_ENET_RX_WRAP; + + /* + * set up the FCC channel hardware + */ + + /* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */ + fcp->fcc_gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32; + + /* 28.9 - (5): FPSMR: fd, enet CRC, Promis, RMON, Rx SHort */ + fcp->fcc_fpsmr = FCC_PSMR_FDE | FCC_PSMR_LPB | \ + FCC_PSMR_ENCRC | FCC_PSMR_PRO | \ + FCC_PSMR_MON | FCC_PSMR_RSH; + + /* 28.9 - (6): FDSR: Ethernet Syn */ + fcp->fcc_fdsr = 0xD555; + + /* 29.9 - (7): initialise parameter ram */ + fpp = (fcc_enet_t *)&(immr->im_dprambase[ecp->proff]); + + /* clear whole struct to make sure all resv fields are zero */ + memset ((void *)fpp, 0, sizeof (fcc_enet_t)); + + /* + * common Parameter RAM area + * + * Allocate space in the reserved FCC area of DPRAM for the + * internal buffers. No one uses this space (yet), so we + * can do this. Later, we will add resource management for + * this area. + */ + addr = CPM_FCC_SPECIAL_BASE + (c * 64); + fpp->fen_genfcc.fcc_riptr = addr; + fpp->fen_genfcc.fcc_tiptr = addr + 32; + + /* + * Set maximum bytes per receive buffer. + * It must be a multiple of 32. + * buffers are in 60x bus memory. + */ + fpp->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; + fpp->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24; + fpp->fen_genfcc.fcc_rbase = (unsigned int)(&ecp->rxbd[0]); + fpp->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24; + fpp->fen_genfcc.fcc_tbase = (unsigned int)(&ecp->txbd[0]); + + /* protocol-specific area */ + fpp->fen_cmask = 0xdebb20e3; /* CRC mask */ + fpp->fen_cpres = 0xffffffff; /* CRC preset */ + fpp->fen_retlim = 15; /* Retry limit threshold */ + fpp->fen_mflr = PKT_MAXBUF_SIZE;/* max frame length register */ + + /* + * Set Ethernet station address. + * + * This is supplied in the board information structure, so we + * copy that into the controller. + * So, far we have only been given one Ethernet address. We use + * the same address for all channels + */ +#define ea gd->bd->bi_enetaddr + fpp->fen_paddrh = (ea[5] << 8) + ea[4]; + fpp->fen_paddrm = (ea[3] << 8) + ea[2]; + fpp->fen_paddrl = (ea[1] << 8) + ea[0]; +#undef ea + + fpp->fen_minflr = PKT_MINBUF_SIZE; /* min frame len register */ + /* + * pad pointer. use tiptr since we don't need + * a specific padding char + */ + fpp->fen_padptr = fpp->fen_genfcc.fcc_tiptr; + fpp->fen_maxd1 = PKT_MAXDMA_SIZE; /* max DMA1 length */ + fpp->fen_maxd2 = PKT_MAXDMA_SIZE; /* max DMA2 length */ + fpp->fen_rfthr = 1; + fpp->fen_rfcnt = 1; + + /* 28.9 - (8): clear out events in FCCE */ + fcp->fcc_fcce = ~0x0; + + /* 28.9 - (9): FCCM: mask all events */ + fcp->fcc_fccm = 0; + + /* 28.9 - (10-12): we don't use ethernet interrupts */ + + /* 28.9 - (13) + * + * Let's re-initialize the channel now. We have to do it later + * than the manual describes because we have just now finished + * the BD initialization. + */ + cp->cp_cpcr = mk_cr_cmd (ecp->page, ecp->sblock, \ + 0x0c, CPM_CR_INIT_TRX) | CPM_CR_FLG; + do { + __asm__ __volatile__ ("eieio"); + } while (cp->cp_cpcr & CPM_CR_FLG); + } + + puts (" done\nStarting test... (Ctrl-C to Finish)\n"); + + /* + * Note: don't want serial output from here until the end of the + * test - the delays would probably stuff things up. + */ + + clear_ctrlc (); + runtime = get_timer (0); + + do { + nclosed = 0; + + for (c = 0; c < 3; c++) { + volatile fcc_t *fcp = &immr->im_fcc[c]; + elbt_chan *ecp = &elbt_chans[c]; + int i; + + switch (ecp->state) { + + case Idle: + /* + * set the channel Running ... + */ + + /* 28.9 - (14): enable tx/rx in gfmr */ + fcp->fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR; + + ecp->state = Running; + break; + + case Running: + /* + * (while Running only) check for + * termination of the test + */ + + (void)ctrlc (); + + if (had_ctrlc ()) { + /* + * initiate a "graceful stop transmit" + * on the channel + */ + cp->cp_cpcr = mk_cr_cmd (ecp->page, \ + ecp->sblock, 0x0c, \ + CPM_CR_GRACEFUL_STOP_TX) | \ + CPM_CR_FLG; + do { + __asm__ __volatile__ ("eieio"); + } while (cp->cp_cpcr & CPM_CR_FLG); + + ecp->clstime = get_timer (0); + ecp->state = Closing; + } + /* fall through ... */ + + case Closing: + /* + * (while Running or Closing) poll the channel: + * - check for any non-READY tx buffers and + * make them ready + * - check for any non-EMPTY rx buffers and + * check that they were received correctly, + * adjust counters etc, then make empty + */ + + for (i = 0; i < ELBT_NTXBD; i++) { + cbd_t *bdp = &ecp->txbd[i]; + ushort sc = bdp->cbd_sc; + + if ((sc & BD_ENET_TX_READY) != 0) + continue; + + /* + * this frame has finished + * transmitting + */ + ecp->nsent++; + + if (sc & BD_ENET_TX_STATS) { + ulong n; + + /* + * we had an error on + * the transmission + */ + n = ecp->ntxerr++; + if (n < ELBT_MAXTXERR) + ecp->txerrs[n] = sc; + + if (sc & BD_ENET_TX_DEF) + ecp->txeacc.def++; + if (sc & BD_ENET_TX_HB) + ecp->txeacc.hb++; + if (sc & BD_ENET_TX_LC) + ecp->txeacc.lc++; + if (sc & BD_ENET_TX_RL) + ecp->txeacc.rl++; + if (sc & BD_ENET_TX_RCMASK) + ecp->txeacc.rc++; + if (sc & BD_ENET_TX_UN) + ecp->txeacc.un++; + if (sc & BD_ENET_TX_CSL) + ecp->txeacc.csl++; + + bdp->cbd_sc &= \ + ~BD_ENET_TX_STATS; + } + + if (ecp->state == Closing) + ecp->clstime = get_timer (0); + + /* make it ready again */ + bdp->cbd_sc |= BD_ENET_TX_READY; + } + + for (i = 0; i < ELBT_NRXBD; i++) { + cbd_t *bdp = &ecp->rxbd[i]; + ushort sc = bdp->cbd_sc, mask; + + if ((sc & BD_ENET_RX_EMPTY) != 0) + continue; + + /* we have a new frame in this buffer */ + ecp->nrcvd++; + + mask = BD_ENET_RX_LAST|BD_ENET_RX_FIRST; + if ((sc & mask) != mask) { + /* somethings wrong here ... */ + if (!(sc & BD_ENET_RX_LAST)) + ecp->rxeacc._l++; + if (!(sc & BD_ENET_RX_FIRST)) + ecp->rxeacc._f++; + } + + if (sc & BD_ENET_RX_STATS) { + ulong n; + + /* + * we had some sort of error + * on the frame + */ + n = ecp->nrxerr++; + if (n < ELBT_MAXRXERR) + ecp->rxerrs[n] = sc; + + if (sc & BD_ENET_RX_MISS) + ecp->rxeacc.m++; + if (sc & BD_ENET_RX_BC) + ecp->rxeacc.bc++; + if (sc & BD_ENET_RX_MC) + ecp->rxeacc.mc++; + if (sc & BD_ENET_RX_LG) + ecp->rxeacc.lg++; + if (sc & BD_ENET_RX_NO) + ecp->rxeacc.no++; + if (sc & BD_ENET_RX_SH) + ecp->rxeacc.sh++; + if (sc & BD_ENET_RX_CR) + ecp->rxeacc.cr++; + if (sc & BD_ENET_RX_OV) + ecp->rxeacc.ov++; + if (sc & BD_ENET_RX_CL) + ecp->rxeacc.cl++; + + bdp->cbd_sc &= \ + ~BD_ENET_RX_STATS; + } + else { + ushort datlen = bdp->cbd_datlen; + Ethernet_t *ehp; + ushort prot; + int ours, tb, n, nbytes; + + ehp = (Ethernet_t *) \ + &ecp->rxbufs[i][0]; + + ours = memcmp (ehp->et_src, \ + NetOurEther, 6); + + prot = swap16 (ehp->et_protlen); + tb = prot & 0x8000; + n = prot & 0x7fff; + + nbytes = ELBT_BUFSZ - \ + offsetof (Ethernet_t, \ + et_dsap) - \ + ELBT_CRCSZ; + + /* check the frame is correct */ + if (datlen != ELBT_BUFSZ) + ecp->rxeacc.badlen++; + else if (!ours) + ecp->rxeacc.badsrc++; + else if (!tb || n >= ELBT_NTXBD) + ecp->rxeacc.badtyp++; + else { + ulong patword = \ + patwords[n]; + uint nbb; + + nbb = badbits ( \ + &ehp->et_dsap, \ + nbytes, \ + patword); + + ecp->rxeacc.badbit += \ + nbb; + } + } + + if (ecp->state == Closing) + ecp->clstime = get_timer (0); + + /* make it empty again */ + bdp->cbd_sc |= BD_ENET_RX_EMPTY; + } + + if (ecp->state != Closing) + break; + + /* + * (while Closing) check to see if + * waited long enough + */ + + if (get_timer (ecp->clstime) >= ELBT_CLSWAIT) { + /* write GFMR: disable tx/rx */ + fcp->fcc_gfmr &= \ + ~(FCC_GFMR_ENT | FCC_GFMR_ENR); + ecp->state = Closed; + } + + break; + + case Closed: + nclosed++; + break; + } + } + + } while (nclosed < 3); + + runtime = get_timer (runtime); + if (runtime <= ELBT_CLSWAIT) { + printf ("Whoops! somehow elapsed time (%ld) is wrong (<= %d)\n", + runtime, ELBT_CLSWAIT); + return; + } + nmsec = runtime - ELBT_CLSWAIT; + + printf ("Test Finished in %ldms (plus %dms close wait period)!\n\n", + nmsec, ELBT_CLSWAIT); + + /* + * now print stats + */ + + for (c = 0; c < 3; c++) { + elbt_chan *ecp = &elbt_chans[c]; + uint rxpps, txpps, nerr; + + rxpps = (ecp->nrcvd * 1000) / nmsec; + txpps = (ecp->nsent * 1000) / nmsec; + + printf ("Channel %d: %d rcvd (%d pps, %d rxerrs), " + "%d sent (%d pps, %d txerrs)\n\n", c, + ecp->nrcvd, rxpps, ecp->nrxerr, + ecp->nsent, txpps, ecp->ntxerr); + + if ((nerr = ecp->nrxerr) > 0) { + ulong i; + + printf ("\tFirst %d rx errs:", nerr); + for (i = 0; i < nerr; i++) + printf (" %04x", ecp->rxerrs[i]); + puts ("\n"); + } + + if ((nerr = ecp->ntxerr) > 0) { + ulong i; + + printf ("\tFirst %d tx errs:", nerr); + for (i = 0; i < nerr; i++) + printf (" %04x", ecp->txerrs[i]); + puts ("\n"); + } + } + + puts ("Receive Error Counts:\n"); + for (c = 0; c < 3; c++) + bases[c] = (uchar *)&elbt_chans[c].rxeacc; + print_desc (rxeacc_descs, rxeacc_ndesc, bases, 3); + + puts ("\nTransmit Error Counts:\n"); + for (c = 0; c < 3; c++) + bases[c] = (uchar *)&elbt_chans[c].txeacc; + print_desc (txeacc_descs, txeacc_ndesc, bases, 3); + + puts ("\nRMON(-like) Counters:\n"); + for (c = 0; c < 3; c++) + bases[c] = (uchar *)&immr->im_dprambase[elbt_chans[c].proff]; + print_desc (epram_descs, epram_ndesc, bases, 3); +} + +#endif /* CONFIG_ETHER_LOOPBACK_TEST */ + #endif /* CONFIG_ETHER_ON_FCC && CFG_CMD_NET && CONFIG_NET_MULTI */ diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c index 2d65e32734..69ae535ba2 100644 --- a/cpu/mpc8260/i2c.c +++ b/cpu/mpc8260/i2c.c @@ -58,7 +58,7 @@ /*----------------------------------------------------------------------- */ -typedef void (*i2c_ecb_t)(int, int); /* error callback function */ +typedef void (*i2c_ecb_t)(int, int, void *); /* error callback function */ /* This structure keeps track of the bd and buffer space usage. */ typedef struct i2c_state { @@ -69,6 +69,7 @@ typedef struct i2c_state { int tx_space; /* number of Tx bytes left */ unsigned char *tx_buf; /* pointer to free Tx area */ i2c_ecb_t err_cb; /* error callback function */ + void *cb_data; /* private data to be passed */ } i2c_state_t; /* flags for i2c_send() and i2c_receive() */ @@ -77,14 +78,15 @@ typedef struct i2c_state { #define I2CF_STOP_COND 0x04 /* tx: generate stop condition */ /* return codes */ -#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */ -#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */ -#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */ -#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */ +#define I2CERR_NO_BUFFERS 1 /* no more BDs or buffer space */ +#define I2CERR_MSG_TOO_LONG 2 /* tried to send/receive to much data */ +#define I2CERR_TIMEOUT 3 /* timeout in i2c_doio() */ +#define I2CERR_QUEUE_EMPTY 4 /* i2c_doio called without send/receive */ +#define I2CERR_IO_ERROR 5 /* had an error during comms */ /* error callback flags */ #define I2CECB_RX_ERR 0x10 /* this is a receive error */ -#define I2CECB_RX_ERR_OV 0x02 /* receive overrun error */ +#define I2CECB_RX_OV 0x02 /* receive overrun error */ #define I2CECB_RX_MASK 0x0f /* mask for error bits */ #define I2CECB_TX_ERR 0x20 /* this is a transmit error */ #define I2CECB_TX_CL 0x01 /* transmit collision error */ @@ -318,6 +320,7 @@ void i2c_newio(i2c_state_t *state) state->tx_space = MAX_TX_SPACE; state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD); state->err_cb = NULL; + state->cb_data = NULL; PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd)); PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd)); @@ -491,14 +494,11 @@ int i2c_doio(i2c_state_t *state) volatile iic_t *iip; volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; volatile I2C_BD *txbd, *rxbd; - int j; - int timeout; + int n, i, b, rxcnt = 0, rxtimeo = 0, txcnt = 0, txtimeo = 0, rc = 0; uint dpaddr; PRINTD(("[I2C] i2c_doio\n")); - timeout = TOUT_LOOP * 256; /* arbitrarily long */ - if (state->tx_idx <= 0 && state->rx_idx <= 0) { PRINTD(("[I2C] No I/O is queued\n")); return I2CERR_QUEUE_EMPTY; @@ -518,14 +518,20 @@ int i2c_doio(i2c_state_t *state) /* Loop until transmit & receive completed */ - txbd = ((I2C_BD*)state->txbd) - 1; - j = 0; - if (state->tx_idx > 0) { - timeout = TOUT_LOOP * txbd->length; + if ((n = state->tx_idx) > 0) { + + txbd = ((I2C_BD*)state->txbd) - n; + for (i = 0; i < n; i++) { + txtimeo += TOUT_LOOP * txbd->length; + txbd++; + } + + txbd--; /* wait until last in list is done */ PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd)); + udelay(START_DELAY_US); /* give it time to start */ - while((txbd->status & BD_SC_READY) && (j++ < timeout)) { + while((txbd->status & BD_SC_READY) && (++txcnt < txtimeo)) { udelay(DELAY_US); if (ctrlc()) return (-1); @@ -533,13 +539,20 @@ int i2c_doio(i2c_state_t *state) } } - rxbd = ((I2C_BD*)state->rxbd) - 1; - j = 0; - if ((state->rx_idx > 0) && (j < timeout)) { - timeout = TOUT_LOOP * rxbd->length; + if (txcnt < txtimeo && (n = state->rx_idx) > 0) { + + rxbd = ((I2C_BD*)state->rxbd) - n; + for (i = 0; i < n; i++) { + rxtimeo += TOUT_LOOP * rxbd->length; + rxbd++; + } + + rxbd--; /* wait until last in list is done */ + PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd)); + udelay(START_DELAY_US); /* give it time to start */ - while((rxbd->status & BD_SC_EMPTY) && (j++ < timeout)) { + while((rxbd->status & BD_SC_EMPTY) && (++rxcnt < rxtimeo)) { udelay(DELAY_US); if (ctrlc()) return (-1); @@ -550,76 +563,91 @@ int i2c_doio(i2c_state_t *state) /* Turn off I2C */ i2c->i2c_i2mod &= ~0x01; - if (state->err_cb != NULL) { - int n, i, b; - - /* - * if we have an error callback function, look at the - * error bits in the bd status and pass them back - */ - - if ((n = state->tx_idx) > 0) { - for (i = 0; i < n; i++) { - txbd = ((I2C_BD*)state->txbd) - (n - i); - if ((b = txbd->status & BD_I2C_TX_ERR) != 0) - (*state->err_cb)(I2CECB_TX_ERR|b, i); + if ((n = state->tx_idx) > 0) { + for (i = 0; i < n; i++) { + txbd = ((I2C_BD*)state->txbd) - (n - i); + if ((b = txbd->status & BD_I2C_TX_ERR) != 0) { + if (state->err_cb != NULL) + (*state->err_cb)(I2CECB_TX_ERR|b, i, + state->cb_data); + if (rc == 0) + rc = I2CERR_IO_ERROR; } } - - if ((n = state->rx_idx) > 0) { - for (i = 0; i < n; i++) { - rxbd = ((I2C_BD*)state->rxbd) - (n - i); - if ((b = rxbd->status & BD_I2C_RX_ERR) != 0) - (*state->err_cb)(I2CECB_RX_ERR|b, i); - } - } - - if (j >= timeout) - (*state->err_cb)(I2CECB_TIMEOUT, 0); } - /* sort out errors and return appropriate good/error status */ - if(j >= timeout) - return(I2CERR_TIMEOUT); - if((txbd->status & BD_I2C_TX_ERR) != 0) - return(I2CECB_TX_ERR | (txbd->status & I2CECB_TX_MASK)); - if((rxbd->status & BD_I2C_RX_ERR) != 0) - return(I2CECB_RX_ERR | (rxbd->status & I2CECB_RX_MASK)); + if ((n = state->rx_idx) > 0) { + for (i = 0; i < n; i++) { + rxbd = ((I2C_BD*)state->rxbd) - (n - i); + if ((b = rxbd->status & BD_I2C_RX_ERR) != 0) { + if (state->err_cb != NULL) + (*state->err_cb)(I2CECB_RX_ERR|b, i, + state->cb_data); + if (rc == 0) + rc = I2CERR_IO_ERROR; + } + } + } - return(0); + if ((txtimeo > 0 && txcnt >= txtimeo) || \ + (rxtimeo > 0 && rxcnt >= rxtimeo)) { + if (state->err_cb != NULL) + (*state->err_cb)(I2CECB_TIMEOUT, -1, state->cb_data); + if (rc == 0) + rc = I2CERR_TIMEOUT; + } + + return (rc); } -static int had_tx_nak; - static void -i2c_test_callback(int flags, int xnum) +i2c_probe_callback(int flags, int xnum, void *data) { - if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK)) - had_tx_nak = 1; + /* + * the only acceptable errors are a transmit NAK or a receive + * overrun - tx NAK means the device does not exist, rx OV + * means the device must have responded to the slave address + * even though the transfer failed + */ + if (flags == (I2CECB_TX_ERR|I2CECB_TX_NAK)) + *(int *)data |= 1; + if (flags == (I2CECB_RX_ERR|I2CECB_RX_OV)) + *(int *)data |= 2; } -int i2c_probe(uchar chip) +int +i2c_probe(uchar chip) { i2c_state_t state; - int rc; + int rc, err_flag; uchar buf[1]; i2c_newio(&state); - state.err_cb = i2c_test_callback; - had_tx_nak = 0; + state.err_cb = i2c_probe_callback; + state.cb_data = (void *) &err_flag; + err_flag = 0; rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf); if (rc != 0) - return (rc); + return (rc); /* probe failed */ rc = i2c_doio(&state); - if ((rc != 0) && (rc != I2CERR_TIMEOUT)) - return (rc); + if (rc == 0) + return (0); /* device exists - read succeeded */ - return (had_tx_nak); + if (rc == I2CERR_TIMEOUT) + return (-1); /* device does not exist - timeout */ + + if (rc != I2CERR_IO_ERROR || err_flag == 0) + return (rc); /* probe failed */ + + if (err_flag & 1) + return (-1); /* device does not exist - had transmit NAK */ + + return (0); /* device exists - had receive overrun */ } diff --git a/cpu/mpc8260/interrupts.c b/cpu/mpc8260/interrupts.c index 90620849a8..3c5ef7460e 100644 --- a/cpu/mpc8260/interrupts.c +++ b/cpu/mpc8260/interrupts.c @@ -155,7 +155,7 @@ static __inline__ unsigned long get_msr (void) static __inline__ void set_msr (unsigned long msr) { - __asm__ __volatile__ ("mtmsr %0"::"r" (msr)); + __asm__ __volatile__ ("mtmsr %0;sync;isync"::"r" (msr)); } static __inline__ unsigned long get_dec (void) @@ -208,6 +208,14 @@ int interrupt_init (void) immr->im_intctl.ic_sipnrh = 0xffffffff; immr->im_intctl.ic_sipnrl = 0xffffffff; +#ifdef CONFIG_HYMOD + /* + * ensure all external interrupt sources default to trigger on + * high-to-low transition (i.e. edge triggered active low) + */ + immr->im_intctl.ic_siexr = -1; +#endif + set_dec (decrementer_count); set_msr (get_msr () | MSR_EE); diff --git a/dtt/Makefile b/dtt/Makefile index 48a4be6667..6b9d49949a 100644 --- a/dtt/Makefile +++ b/dtt/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = libdtt.a -OBJS = lm75.o ds1621.o +OBJS = lm75.o ds1621.o adm1021.o all: $(LIB) diff --git a/dtt/adm1021.c b/dtt/adm1021.c new file mode 100644 index 0000000000..14c38f0a83 --- /dev/null +++ b/dtt/adm1021.c @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2003 + * Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au + * + * based on dtt/lm75.c which is ... + * + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net + * + * 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 + */ + +/* + * Analog Devices's ADM1021 + * "Low Cost Microprocessor System Temperature Monitor" + */ + +#include + +#ifdef CONFIG_DTT_ADM1021 + +#include +#include + +typedef + struct { + uint i2c_addr:7; /* 7bit i2c chip address */ + uint conv_rate:3; /* conversion rate */ + uint enable_alert:1; /* enable alert output pin */ + uint enable_local:1; /* enable internal temp sensor */ + uint max_local:8; /* internal temp maximum */ + uint min_local:8; /* internal temp minimum */ + uint enable_remote:1; /* enable remote temp sensor */ + uint max_remote:8; /* remote temp maximum */ + uint min_remote:8; /* remote temp minimum */ + } +dtt_cfg_t; + +dtt_cfg_t dttcfg[] = CFG_DTT_ADM1021; + +int +dtt_read (int sensor, int reg) +{ + dtt_cfg_t *dcp = &dttcfg[sensor >> 1]; + uchar data; + + if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0) + return -1; + + return (int)data; +} /* dtt_read() */ + +int +dtt_write (int sensor, int reg, int val) +{ + dtt_cfg_t *dcp = &dttcfg[sensor >> 1]; + uchar data; + + data = (uchar)(val & 0xff); + + if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0) + return 1; + + return 0; +} /* dtt_write() */ + +static int +_dtt_init (int sensor) +{ + dtt_cfg_t *dcp = &dttcfg[sensor >> 1]; + int reg, val; + + if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0) + return 1; /* sensor is disabled (or rather ignored) */ + + /* + * Setup High Limit register + */ + if ((sensor & 1) == 0) { + reg = DTT_WRITE_LOC_HIGHLIM; + val = dcp->max_local; + } + else { + reg = DTT_WRITE_REM_HIGHLIM; + val = dcp->max_remote; + } + if (dtt_write (sensor, reg, val) != 0) + return 1; + + /* + * Setup Low Limit register + */ + if ((sensor & 1) == 0) { + reg = DTT_WRITE_LOC_LOWLIM; + val = dcp->min_local; + } + else { + reg = DTT_WRITE_REM_LOWLIM; + val = dcp->min_remote; + } + if (dtt_write (sensor, reg, val) != 0) + return 1; + + /* shouldn't hurt if the rest gets done twice */ + + /* + * Setup Conversion Rate register + */ + if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0) + return 1; + + /* + * Setup configuraton register + */ + val = 0; /* running */ + if (dcp->enable_alert == 0) + val |= DTT_CONFIG_ALERT_MASKED; /* mask ALERT pin */ + if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0) + return 1; + + return 0; +} /* _dtt_init() */ + +int +dtt_init (void) +{ + int i; + unsigned char sensors[] = CONFIG_DTT_SENSORS; + const char *const header = "DTT: "; + + for (i = 0; i < sizeof(sensors); i++) { + if (_dtt_init(sensors[i]) != 0) + printf ("%s%d FAILED INIT\n", header, i+1); + else + printf ("%s%d is %i C\n", header, i+1, + dtt_get_temp(sensors[i])); + } + + return (0); +} /* dtt_init() */ + +int +dtt_get_temp (int sensor) +{ + signed char val; + + if ((sensor & 1) == 0) + val = dtt_read(sensor, DTT_READ_LOC_VALUE); + else + val = dtt_read(sensor, DTT_READ_REM_VALUE); + + return (int) val; +} /* dtt_get_temp() */ + +#endif /* CONFIG_DTT_ADM1021 */ diff --git a/include/cmd_bsp.h b/include/cmd_bsp.h index 7966ad5bd5..008008a8bf 100644 --- a/include/cmd_bsp.h +++ b/include/cmd_bsp.h @@ -168,14 +168,20 @@ int do_pci9054 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); " address spaces appear in the physical address space\n" \ ), MK_CMD_TBL_ENTRY( \ "eeclear", 4, 1, 0, do_eecl, \ - "eeclear - Clear the eeprom on a Hymod board \n", \ + "eeclear - Clear the eeprom on a Hymod board\n", \ "[type]\n" \ " - write zeroes into the EEPROM on the board of type `type'\n"\ " (`type' is either `main' or `mezz' - default `main')\n" \ " Note: the EEPROM write enable jumper must be installed\n" \ +), MK_CMD_TBL_ENTRY( \ + "htest", 5, 1, 0, do_htest, \ + "htest - run HYMOD tests\n", \ + NULL \ ), + int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); int do_eecl (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int do_htest(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif /* CONFIG_HYMOD */ /* -------------------------------------------------------------------- */ diff --git a/include/common.h b/include/common.h index b0640c63bc..cc5dbe7f89 100644 --- a/include/common.h +++ b/include/common.h @@ -52,7 +52,7 @@ typedef volatile unsigned char vu_char; #include #endif #ifdef CONFIG_HYMOD -#include +#include #endif #ifdef CONFIG_ARM #define asmlinkage /* nothing */ @@ -131,6 +131,7 @@ void print_size (ulong, const char *); void main_loop (void); int run_command (const char *cmd, int flag); int readline (const char *const prompt); +void init_cmd_timeout(void); void reset_cmd_timeout(void); /* common/board.c */ @@ -195,6 +196,9 @@ void fdc_hw_init (void); /* $(BOARD)/eeprom.c */ void eeprom_init (void); +#ifndef CONFIG_SPI +int eeprom_probe (unsigned dev_addr, unsigned offset); +#endif int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt); int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt); #ifdef CONFIG_LWMON @@ -437,6 +441,7 @@ int tstc(void); void putc(const char c); void puts(const char *s); void printf(const char *fmt, ...); +void vprintf(const char *fmt, va_list args); /* stderr */ #define eputc(c) fputc(stderr, c) diff --git a/include/configs/hymod.h b/include/configs/hymod.h index e3a0ee3aeb..dc7de4461d 100644 --- a/include/configs/hymod.h +++ b/include/configs/hymod.h @@ -73,6 +73,9 @@ #define CONFIG_ETHER_ON_FCC /* define if ether on FCC */ #undef CONFIG_ETHER_NONE /* define if ether on something else */ #define CONFIG_ETHER_INDEX 1 /* which channel for ether */ +#define CONFIG_ETHER_LOOPBACK_TEST /* add ether external loopback test */ + +#ifdef CONFIG_ETHER_ON_FCC #if (CONFIG_ETHER_INDEX == 1) @@ -87,6 +90,10 @@ # define CFG_CPMFCR_RAMTYPE 0 # define CFG_FCC_PSMR (FCC_PSMR_FDE|FCC_PSMR_LPB) +# define MDIO_PORT 0 /* Port A */ +# define MDIO_DATA_PINMASK 0x00040000 /* Pin 13 */ +# define MDIO_CLCK_PINMASK 0x00080000 /* Pin 12 */ + #elif (CONFIG_ETHER_INDEX == 2) /* @@ -100,6 +107,10 @@ # define CFG_CPMFCR_RAMTYPE 0 # define CFG_FCC_PSMR (FCC_PSMR_FDE|FCC_PSMR_LPB) +# define MDIO_PORT 0 /* Port A */ +# define MDIO_DATA_PINMASK 0x00000040 /* Pin 25 */ +# define MDIO_CLCK_PINMASK 0x00000080 /* Pin 24 */ + #elif (CONFIG_ETHER_INDEX == 3) /* @@ -113,11 +124,33 @@ # define CFG_CPMFCR_RAMTYPE 0 # define CFG_FCC_PSMR (FCC_PSMR_FDE|FCC_PSMR_LPB) +# define MDIO_PORT 0 /* Port A */ +# define MDIO_DATA_PINMASK 0x00000100 /* Pin 23 */ +# define MDIO_CLCK_PINMASK 0x00000200 /* Pin 22 */ + #endif /* CONFIG_ETHER_INDEX */ +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ + +#define MDIO_ACTIVE (iop->pdir |= MDIO_DATA_PINMASK) +#define MDIO_TRISTATE (iop->pdir &= ~MDIO_DATA_PINMASK) +#define MDIO_READ ((iop->pdat & MDIO_DATA_PINMASK) != 0) + +#define MDIO(bit) if(bit) iop->pdat |= MDIO_DATA_PINMASK; \ + else iop->pdat &= ~MDIO_DATA_PINMASK + +#define MDC(bit) if(bit) iop->pdat |= MDIO_CLCK_PINMASK; \ + else iop->pdat &= ~MDIO_CLCK_PINMASK + +#define MIIDELAY udelay(1) + +#endif /* CONFIG_ETHER_ON_FCC */ + /* other options */ #define CONFIG_HARD_I2C 1 /* To enable I2C hardware support */ +#define CONFIG_DTT_ADM1021 1 /* ADM1021 temp sensor support */ /* system clock rate (CLKIN) - equal to the 60x and local bus speed */ #ifdef DEBUG @@ -129,39 +162,52 @@ #if defined(CONFIG_CONS_USE_EXTC) #define CONFIG_BAUDRATE 115200 #else -#define CONFIG_BAUDRATE 38400 +#define CONFIG_BAUDRATE 9600 #endif /* default ip addresses - these will be overridden */ #define CONFIG_IPADDR 192.168.1.1 /* hymod "boot" address */ #define CONFIG_SERVERIP 192.168.1.254 /* hymod "server" address */ +#define CONFIG_LAST_STAGE_INIT + #define CONFIG_COMMANDS (CFG_CMD_ALL & ~( \ CFG_CMD_BEDBUG | \ CFG_CMD_BMP | \ CFG_CMD_DOC | \ - CFG_CMD_ELF | \ CFG_CMD_FDC | \ CFG_CMD_FDOS | \ + CFG_CMD_FPGA | \ CFG_CMD_HWFLOW | \ CFG_CMD_IDE | \ CFG_CMD_JFFS2 | \ CFG_CMD_NAND | \ - CFG_CMD_MII | \ CFG_CMD_MMC | \ CFG_CMD_PCMCIA | \ CFG_CMD_PCI | \ CFG_CMD_USB | \ CFG_CMD_SCSI | \ CFG_CMD_SPI | \ - CFG_CMD_VFD | \ - CFG_CMD_DTT ) ) + CFG_CMD_VFD ) ) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include #ifdef DEBUG #define CONFIG_BOOTDELAY -1 /* autoboot disabled */ +#else +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ +#define CONFIG_BOOT_RETRY_TIME 30 /* retry autoboot after 30 secs */ +#define CONFIG_BOOT_RETRY_MIN 1 /* can go down to 1 second timeout */ +/* Be selective on what keys can delay or stop the autoboot process + * To stop use: " " + */ +#define CONFIG_AUTOBOOT_KEYED +#define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, " \ + "press to stop\n" +#define CONFIG_AUTOBOOT_STOP_STR " " +#undef CONFIG_AUTOBOOT_DELAY_STR +#define DEBUG_BOOTKEYS 0 #endif #if (CONFIG_COMMANDS & CFG_CMD_KGDB) @@ -173,9 +219,9 @@ #define CONFIG_KGDB_EXTC_RATE 3686400 /* serial ext clk rate in Hz */ #define CONFIG_KGDB_EXTC_PINSEL 0 /* pin select 0=CLK3/CLK9,1=CLK5/CLK15*/ # if defined(CONFIG_KGDB_USE_EXTC) -#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port at */ +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port at */ # else -#define CONFIG_KGDB_BAUDRATE 38400 /* speed to run kgdb serial port at */ +#define CONFIG_KGDB_BAUDRATE 9600 /* speed to run kgdb serial port at */ # endif #endif @@ -205,6 +251,8 @@ #define CFG_MEMTEST_START 0x00400000 /* memtest works on */ #define CFG_MEMTEST_END 0x03c00000 /* 4 ... 60 MB in DRAM */ +#define CFG_CLKS_IN_HZ 1 /* everything, incl board info, in Hz */ + #define CFG_LOAD_ADDR 0x100000 /* default load address */ #define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ @@ -217,8 +265,47 @@ /* these are for the ST M24C02 2kbit serial i2c eeprom */ #define CFG_I2C_EEPROM_ADDR 0x50 /* base address */ #define CFG_I2C_EEPROM_ADDR_LEN 1 /* bytes of address */ +/* mask of address bits that overflow into the "EEPROM chip address" */ +#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07 + +#define CFG_EEPROM_PAGE_WRITE_ENABLE 1 /* write eeprom in pages */ +#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* 16 byte write page size */ +#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */ + +#define CFG_I2C_MULTI_EEPROMS 1 /* hymod has two eeproms */ + #define CFG_I2C_RTC_ADDR 0x51 /* philips PCF8563 RTC address */ +/* + * standard dtt sensor configuration - bottom bit will determine local or + * remote sensor of the ADM1021, the rest determines index into + * CFG_DTT_ADM1021 array below. + * + * On HYMOD board, the remote sensor should be connected to the MPC8260 + * temperature diode thingy, but an errata said this didn't work and + * should be disabled - so it isn't connected. + */ +#if 0 +#define CONFIG_DTT_SENSORS { 0, 1 } +#else +#define CONFIG_DTT_SENSORS { 0 } +#endif + +/* + * ADM1021 temp sensor configuration (see dtt/adm1021.c for details). + * there will be one entry in this array for each two (dummy) sensors in + * CONFIG_DTT_SENSORS. + * + * For HYMOD board: + * - only one ADM1021 + * - i2c addr 0x2a (both ADD0 and ADD1 are N/C) + * - conversion rate 0x02 = 0.25 conversions/second + * - ALERT ouput disabled + * - local temp sensor enabled, min set to 0 deg, max set to 85 deg + * - remote temp sensor disabled (see comment for CONFIG_DTT_SENSORS above) + */ +#define CFG_DTT_ADM1021 { { 0x2a, 0x02, 0, 1, 0, 85, 0, } } + /* * Low Level Configuration Settings * (address mappings, register initial values, etc.) @@ -296,10 +383,6 @@ #define CFG_FLASH_ERASE_TOUT 120000 /* Flash Erase Timeout (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ -#define CFG_FLASH_TYPE FLASH_28F640J3A -#define CFG_FLASH_ID (INTEL_ID_28F640J3A & 0xff) -#define CFG_FLASH_NBLOCKS 64 - #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ #define CFG_ENV_SECT_SIZE 0x40000 /* see README - env sect real size */ @@ -609,6 +692,11 @@ #define FPGA_MEZZ_ENABLE_PORT IOPIN_PORTA #define FPGA_MEZZ_ENABLE_PIN 3 /* PA3 */ +/* + * FPGA Interrupt configuration + */ +#define FPGA_MAIN_IRQ SIU_INT_IRQ2 + /* * Internal Definitions * diff --git a/include/dtt.h b/include/dtt.h index f3d95ff77a..a17aa67703 100644 --- a/include/dtt.h +++ b/include/dtt.h @@ -27,9 +27,13 @@ #ifndef _DTT_H_ #define _DTT_H_ -#if defined(CONFIG_DTT_LM75) || defined(CONFIG_DTT_DS1621) +#if defined(CONFIG_DTT_LM75) || \ + defined(CONFIG_DTT_DS1621) || \ + defined(CONFIG_DTT_ADM1021) + #define CONFIG_DTT /* We have a DTT */ +#ifndef CONFIG_DTT_ADM1021 #define DTT_COMMERCIAL_MAX_TEMP 70 /* 0 - +70 C */ #define DTT_INDUSTRIAL_MAX_TEMP 85 /* -40 - +85 C */ #define DTT_AUTOMOTIVE_MAX_TEMP 105 /* -40 - +105 C */ @@ -39,6 +43,7 @@ #ifndef CFG_DTT_HYSTERESIS #define CFG_DTT_HYSTERESIS 5 /* 5 C */ #endif +#endif /* CONFIG_DTT_ADM1021 */ extern int dtt_init (void); extern int dtt_read(int sensor, int reg); @@ -64,4 +69,37 @@ extern int dtt_get_temp(int sensor); #define DTT_CONFIG 0xAC #endif +#if defined(CONFIG_DTT_ADM1021) +#define DTT_READ_LOC_VALUE 0x00 +#define DTT_READ_REM_VALUE 0x01 +#define DTT_READ_STATUS 0x02 +#define DTT_READ_CONFIG 0x03 +#define DTT_READ_CONVRATE 0x04 +#define DTT_READ_LOC_HIGHLIM 0x05 +#define DTT_READ_LOC_LOWLIM 0x06 +#define DTT_READ_REM_HIGHLIM 0x07 +#define DTT_READ_REM_LOWLIM 0x08 +#define DTT_READ_DEVID 0xfe + +#define DTT_WRITE_CONFIG 0x09 +#define DTT_WRITE_CONVRATE 0x0a +#define DTT_WRITE_LOC_HIGHLIM 0x0b +#define DTT_WRITE_LOC_LOWLIM 0x0c +#define DTT_WRITE_REM_HIGHLIM 0x0d +#define DTT_WRITE_REM_LOWLIM 0x0e +#define DTT_WRITE_ONESHOT 0x0f + +#define DTT_STATUS_BUSY 0x80 /* 1=ADC Converting */ +#define DTT_STATUS_LHIGH 0x40 /* 1=Local High Temp Limit Tripped */ +#define DTT_STATUS_LLOW 0x20 /* 1=Local Low Temp Limit Tripped */ +#define DTT_STATUS_RHIGH 0x10 /* 1=Remote High Temp Limit Tripped */ +#define DTT_STATUS_RLOW 0x08 /* 1=Remote Low Temp Limit Tripped */ +#define DTT_STATUS_OPEN 0x04 /* 1=Remote Sensor Open-Circuit */ + +#define DTT_CONFIG_ALERT_MASKED 0x80 /* 0=ALERT Enabled, 1=ALERT Masked */ +#define DTT_CONFIG_STANDBY 0x40 /* 0=Run, 1=Standby */ + +#define DTT_ADM1021_DEVID 0x41 +#endif + #endif /* _DTT_H_ */ diff --git a/include/flash.h b/include/flash.h index e594788380..7223f59e8d 100644 --- a/include/flash.h +++ b/include/flash.h @@ -204,10 +204,11 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot); #define INTEL_ID_28F640C3B 0x88CD88CD /* 64M = 4M x 16 bottom boot sector */ #define INTEL_ID_28F128J3 0x89189818 /* 16M = 8M x 16 x 128 */ -#define INTEL_ID_28F640J5 0x00150015 /* 64M = 128K x 64 */ -#define INTEL_ID_28F320J3A 0x00160016 /* 32M = 128K x 32 */ -#define INTEL_ID_28F640J3A 0x00170017 /* 64M = 128K x 64 */ -#define INTEL_ID_28F128J3A 0x00180018 /* 128M = 128K x 128 */ +#define INTEL_ID_28F320J5 0x00140014 /* 32M = 128K x 32 */ +#define INTEL_ID_28F640J5 0x00150015 /* 64M = 128K x 64 */ +#define INTEL_ID_28F320J3A 0x00160016 /* 32M = 128K x 32 */ +#define INTEL_ID_28F640J3A 0x00170017 /* 64M = 128K x 64 */ +#define INTEL_ID_28F128J3A 0x00180018 /* 128M = 128K x 128 */ #define INTEL_ID_28F160S3 0x00D000D0 /* 16M = 512K x 32 (64kB x 32) */ #define INTEL_ID_28F320S3 0x00D400D4 /* 32M = 512K x 64 (64kB x 64) */ diff --git a/include/mpc8260_irq.h b/include/mpc8260_irq.h index 046dd32643..9bee9a335f 100644 --- a/include/mpc8260_irq.h +++ b/include/mpc8260_irq.h @@ -28,6 +28,13 @@ */ #define SIU_INT_SMC1 ((uint)0x04) #define SIU_INT_SMC2 ((uint)0x05) +#define SIU_INT_IRQ1 ((uint)0x13) +#define SIU_INT_IRQ2 ((uint)0x14) +#define SIU_INT_IRQ3 ((uint)0x15) +#define SIU_INT_IRQ4 ((uint)0x16) +#define SIU_INT_IRQ5 ((uint)0x17) +#define SIU_INT_IRQ6 ((uint)0x18) +#define SIU_INT_IRQ7 ((uint)0x19) #define SIU_INT_FCC1 ((uint)0x20) #define SIU_INT_FCC2 ((uint)0x21) #define SIU_INT_FCC3 ((uint)0x22) diff --git a/lib_generic/vsprintf.c b/lib_generic/vsprintf.c index d7a7661576..b9e6e1ba92 100644 --- a/lib_generic/vsprintf.c +++ b/lib_generic/vsprintf.c @@ -329,7 +329,7 @@ void panic(const char *fmt, ...) { va_list args; va_start(args, fmt); - printf(fmt); + vprintf(fmt, args); putc('\n'); va_end(args); #if defined (CONFIG_PANIC_HANG) diff --git a/lib_ppc/board.c b/lib_ppc/board.c index 56cbdfe5ee..9bc77b5496 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -820,7 +820,6 @@ void board_init_r (gd_t *id, ulong dest_addr) defined(CONFIG_COGENT) || \ defined(CONFIG_CPCI405) || \ defined(CONFIG_EVB64260) || \ - defined(CONFIG_HYMOD) || \ defined(CONFIG_KUP4K) || \ defined(CONFIG_LWMON) || \ defined(CONFIG_PCU_E) || \ diff --git a/tools/bddb/brlog.php b/tools/bddb/brlog.php index 6e98c9c481..fa651ae02d 100644 --- a/tools/bddb/brlog.php +++ b/tools/bddb/brlog.php @@ -73,6 +73,7 @@ logno / edit date +who details \n"; print_cell("$row[logno]"); print_cell($row['date']); + print_cell($row['who']); print_cell("
" . urldecode($row['details']) . "
"); echo "\n"; } diff --git a/tools/bddb/defs.php b/tools/bddb/defs.php index 0393dbda64..9361419d49 100644 --- a/tools/bddb/defs.php +++ b/tools/bddb/defs.php @@ -58,8 +58,8 @@ $zbt_nbits = array(0,19,20,21,22); // Xilinx attributes - $xlxtyp_vals = array('','XCV300E','XCV400E','XCV600E'); - $xlxspd_vals = array('','6','7','8'); + $xlxtyp_vals = array('','XCV300E','XCV400E','XCV600E','XC2V2000','XC2V3000','XC2V4000','XC2V6000'); + $xlxspd_vals = array('','6','7','8','4','5'); $xlxtmp_vals = array('','COM','IND'); $xlxgrd_vals = array('','NORMAL','ENGSAMP'); @@ -449,7 +449,13 @@ // generate a (possibly not unique) random vendor ethernet address // (setting bit 6 in the ethernet address - motorola wise i.e. bit 0 // is the most significant bit - means it is not an assigned ethernet - // address). Also, make sure it is NOT a multicast ethernet address. + // address - it is a "locally administered" address). Also, make sure + // it is NOT a multicast ethernet address (by setting bit 7 to 0). + // e.g. the first byte of all ethernet addresses generated here will + // have 2 in the bottom two bits (incidentally, these are the first + // two bits transmitted on the wire, since the octets in ethernet + // addresses are transmitted LSB first). + function gen_eth_addr($serno) { $ethaddr_high = (mt_rand(0, 65535) & 0xfeff) | 0x0200; diff --git a/tools/bddb/doedlog.php b/tools/bddb/doedlog.php index db27c37eb9..f80047195b 100644 --- a/tools/bddb/doedlog.php +++ b/tools/bddb/doedlog.php @@ -26,6 +26,9 @@ $query.=" date='$date'"; } + if (isset($who)) + $query.=", who='" . $who . "'"; + if (isset($details)) $query.=", details='" . rawurlencode($details) . "'"; diff --git a/tools/bddb/donewlog.php b/tools/bddb/donewlog.php index b00de955bc..35ba1251f7 100644 --- a/tools/bddb/donewlog.php +++ b/tools/bddb/donewlog.php @@ -23,6 +23,9 @@ die("date is invalid (input '$date', yyyy-mm-dd '$y-$m-$d')"); $query.=", date='$date'"; + if (isset($who)) + $query.=", who='" . $who . "'"; + if (isset($details)) $query.=", details='" . rawurlencode($details) . "'"; diff --git a/tools/bddb/edlog.php b/tools/bddb/edlog.php index f819b46a0d..7f311bfdbb 100644 --- a/tools/bddb/edlog.php +++ b/tools/bddb/edlog.php @@ -41,6 +41,9 @@ // date date print_field("date", $row); + // who char(20) + print_field("who", $row); + // details text print_field_multiline("details", $row, 60, 10, 'text_filter'); diff --git a/tools/bddb/newlog.php b/tools/bddb/newlog.php index 5ec42ac289..3f516391b6 100644 --- a/tools/bddb/newlog.php +++ b/tools/bddb/newlog.php @@ -26,6 +26,9 @@ // date date print_field("date", array('date' => date("Y-m-d"))); + // who char(20) + print_field("who", ""); + // details text print_field_multiline("details", array(), 60, 10, 'text_filter'); diff --git a/tools/gdb/astest.c b/tools/gdb/astest.c index dbe55fe5b1..a791469da1 100644 --- a/tools/gdb/astest.c +++ b/tools/gdb/astest.c @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 #include #include diff --git a/tools/gdb/error.c b/tools/gdb/error.c index aea2901114..276a00a677 100644 --- a/tools/gdb/error.c +++ b/tools/gdb/error.c @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 #include #include diff --git a/tools/gdb/error.h b/tools/gdb/error.h index 907709f767..0698213306 100644 --- a/tools/gdb/error.h +++ b/tools/gdb/error.h @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 extern char *pname; diff --git a/tools/gdb/gdbcont.c b/tools/gdb/gdbcont.c index ee9553cd52..300545d8e1 100644 --- a/tools/gdb/gdbcont.c +++ b/tools/gdb/gdbcont.c @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 #include #include diff --git a/tools/gdb/gdbsend.c b/tools/gdb/gdbsend.c index d46ab48467..8cd8347159 100644 --- a/tools/gdb/gdbsend.c +++ b/tools/gdb/gdbsend.c @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 #include #include diff --git a/tools/gdb/remote.h b/tools/gdb/remote.h index bfc4a1f9b7..f14dacb07a 100644 --- a/tools/gdb/remote.h +++ b/tools/gdb/remote.h @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 + */ + extern int remote_desc, remote_timeout; extern void remote_reset(void); diff --git a/tools/gdb/serial.c b/tools/gdb/serial.c index 88895bb9f8..2f2e5291d9 100644 --- a/tools/gdb/serial.c +++ b/tools/gdb/serial.c @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 #include #include diff --git a/tools/gdb/serial.h b/tools/gdb/serial.h index 60629bd743..3ed509ee78 100644 --- a/tools/gdb/serial.h +++ b/tools/gdb/serial.h @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * 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 #define SERIAL_ERROR -1 /* General error, see errno for details */