Patches by Murray Jensen, 17 Jun 2003:
authorwdenk <wdenk>
Thu, 19 Jun 2003 23:40:20 +0000 (23:40 +0000)
committerwdenk <wdenk>
Thu, 19 Jun 2003 23:40:20 +0000 (23:40 +0000)
- 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

45 files changed:
CHANGELOG
board/hymod/Makefile
board/hymod/bsp.c
board/hymod/config.mk
board/hymod/eeprom.c
board/hymod/env.c [new file with mode: 0644]
board/hymod/fetch.c
board/hymod/flash.c
board/hymod/flash.h
board/hymod/global_env
board/hymod/hymod.c
board/hymod/hymod.h [new file with mode: 0644]
board/hymod/input.c [new file with mode: 0644]
common/cmd_eeprom.c
common/console.c
common/main.c
config.mk
cpu/mpc8260/cpu_init.c
cpu/mpc8260/ether_fcc.c
cpu/mpc8260/i2c.c
cpu/mpc8260/interrupts.c
dtt/Makefile
dtt/adm1021.c [new file with mode: 0644]
include/cmd_bsp.h
include/common.h
include/configs/hymod.h
include/dtt.h
include/flash.h
include/mpc8260_irq.h
lib_generic/vsprintf.c
lib_ppc/board.c
tools/bddb/brlog.php
tools/bddb/defs.php
tools/bddb/doedlog.php
tools/bddb/donewlog.php
tools/bddb/edlog.php
tools/bddb/newlog.php
tools/gdb/astest.c
tools/gdb/error.c
tools/gdb/error.h
tools/gdb/gdbcont.c
tools/gdb/gdbsend.c
tools/gdb/remote.h
tools/gdb/serial.c
tools/gdb/serial.h

index 1a39bb5..a0fc00f 100644 (file)
--- 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
index 1804b3c..4d3097c 100644 (file)
@@ -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 $@ $^
index 2ceaeb5..02b6421 100644 (file)
  * 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 <common.h>
 #include <command.h>
 #include <net.h>
-#include <i2c.h>
 #include <asm/iopin_8260.h>
 #include <cmd_bsp.h>
 
  *     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;
+
+       eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE);
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+#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;
        }
 
-       return rcode;
+       /* 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 */
+#endif /* CFG_CMD_BSP */
 
 /* ------------------------------------------------------------------------- */
index 52c3183..ccc7f38 100644 (file)
@@ -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
index 9d50646..01e1453 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * (C) Copyright 2001
- * Murray Jensen, CSIRO Manufacturing Science and Technology,
- * <Murray.Jensen@cmst.csiro.au>
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
 #include <mpc8260.h>
 
 /* 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)
-{
-    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;
-
-    hp = (hymod_eehdr_t *)data;
-    eeprom_read(CFG_DEF_EEPROM_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);
-
-    dp = (uchar *)(hp + 1); edp = dp + len;
-    eeprom_read(CFG_DEF_EEPROM_ADDR, offset, dp, len);
-    offset += len;
-
-    eeprom_read(CFG_DEF_EEPROM_ADDR, offset, (uchar *)&crc, sizeof (ulong));
-
-    if (crc32(0, data, edp - data) != crc)
-       return (0);
-
-    ep->ver = hp->ver;
+/* imports from input.c */
+extern int hymod_get_serno (const char *);
 
-    for (;;) {
-       hymod_eerec_t *rp = (hymod_eerec_t *)dp;
-       ulong rtyp;
-       uchar rlen, *rdat;
-       uint rsiz;
+/* this is relative to the root of the server's tftp directory */
+static char *def_bddb_cfgdir = "/hymod/bddb";
 
-       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;
-       }
+static int
+hymod_eeprom_load (int which, hymod_eeprom_t *ep)
+{
+       unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \
+               (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
+       unsigned offset = 0;
+       uchar data[HYMOD_EEPROM_SIZE], *dp, *edp;
+       hymod_eehdr_t *hp;
+       ulong len, crc;
+
+       memset (ep, 0, sizeof *ep);
+       memset (data, 0, HYMOD_EEPROM_SIZE);
+       crc = 0;
+
+       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);
+
+       dp = (uchar *)(hp + 1); edp = dp + len;
+       eeprom_read (dev_addr, offset, dp, len);
+       offset += len;
+
+       eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong));
+
+       if (crc32 (0, data, edp - data) != crc)
+               return (0);
+
+       ep->ver = hp->ver;
+
+       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 (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;
+               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;
+               }
        }
-    }
 
-    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;
-
-    rdata.lval = simple_strtol(value, (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);
+       uchar *eval;
+       union {
+               uchar cval[4];
+               ushort sval[2];
+               ulong lval;
+       } rdata;
+
+       rdata.lval = simple_strtol (val, (char **)&eval, 10);
+
+       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;
+
+       switch (rp->length) {
 
-    default:
-       printf("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length);
-       return (NULL);
-    }
+       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);
+       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);
+               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 (ep == p || (*ep != '\0' && *ep != ',')) {
+                       printf ("%s rec (%s) byte array has invalid uint\n",
+                               rp->name, val);
+                       return (NULL);
+               }
 
-       if (*ep++ == '\0')
-           break;
+               if (*ep++ == '\0')
+                       break;
 
-       p = ep;
-    }
+               p = ep;
+       }
 
-    if (dp + 2 + nbytes > edp) {
-       printf("can't fit %s record into eeprom\n", rp->name);
-       return (NULL);
-    }
+       if (dp + 2 + nbytes > edp) {
+               printf ("can't fit %s rec into eeprom\n", rp->name);
+               return (NULL);
+       }
 
-    *dp++ = rp->type;
-    *dp++ = nbytes;
-    memcpy(dp, bytes, nbytes);
-    dp += nbytes;
+       *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;
-
-           for (i = 0; i < n; i++)
-               t += 1 << (a[i] - 20);
-
-           printf("%s%luMB %s (%d banks:", s, t, l, n);
-
-           for (i = 0; i < n; i++)
-               printf("%dMB%s", 1 << (a[i] - 20), (i == n - 1) ? ")" : ",");
+       if (n > 0) {
+               if (n == 1)
+                       printf ("%s%dMB %s", s, 1 << (a[0] - 20), l);
+               else {
+                       ulong t = 0;
+                       int i;
+
+                       for (i = 0; i < n; i++)
+                               t += 1 << (a[i] - 20);
+
+                       printf ("%s%luMB %s (%d banks:", s, t, l, n);
+
+                       for (i = 0; i < n; i++)
+                               printf ("%dMB%s",
+                                       1 << (a[i] - 20),
+                                       (i == n - 1) ? ")" : ",");
+               }
        }
-    }
-    else
-       printf("%sNO %s", s, l);
+       else
+               printf ("%sNO %s", s, l);
 }
 
 void
-eeprom_print(hymod_eeprom_t *ep)
+hymod_eeprom_print (hymod_eeprom_t *ep)
 {
-    int i;
-
-    printf("         Hymod %s board, rev %03d\n",
-       type_vals[ep->bdtype], ep->bdrev);
-
-    printf("         serial #: %010lu, date %04d-%02d-%02d",
-       ep->serno, ep->date.year, ep->date.month, ep->date.day);
-    if (ep->batchlen > 0)
-       printf(", batch \"%.*s\"", ep->batchlen, ep->batch);
-    puts("\n");
-
-    switch (ep->bdtype) {
-
-    case HYMOD_BDTYPE_IO:
-    case HYMOD_BDTYPE_CLP:
-    case HYMOD_BDTYPE_DSP:
-       printf("         Motorola %s CPU, speeds: %s/%s/%s",
-           cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd],
-           clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]);
-
-       print_mem("SDRAM", ", ", ep->nsdram, ep->sdramsz);
-
-       print_mem("FLASH", ", ", ep->nflash, ep->flashsz);
-
-       puts("\n");
-
-       print_mem("ZBT", "         ", ep->nzbt, ep->zbtsz);
-
-       if (ep->nxlx > 0) {
-           hymod_xlx_t *xp;
-
-           if (ep->nxlx == 1) {
-               xp = &ep->xlx[0];
-               printf(", Xilinx %s FPGA (%s/%s/%s)",
-                   xlxtyp_vals[xp->type], xlxspd_vals[xp->speed],
-                   xlxtmp_vals[xp->temp], xlxgrd_vals[xp->grade]);
-           }
-           else {
-               printf(", %d Xilinx FPGAs (", ep->nxlx);
-               for (i = 0; i < ep->nxlx; i++) {
-                   xp = &ep->xlx[i];
-                   printf("%s[%s/%s/%s]%s",
-                       xlxtyp_vals[xp->type], xlxspd_vals[xp->speed],
-                       xlxtmp_vals[xp->temp], xlxgrd_vals[xp->grade],
-                       (i == ep->nxlx - 1) ? ")" : ", ");
+       int i;
+
+       printf ("         Hymod %s board, rev %03d\n",
+               type_vals[ep->bdtype], ep->bdrev);
+
+       printf ("         serial #: %010lu, date %04d-%02d-%02d",
+               ep->serno, ep->date.year, ep->date.month, ep->date.day);
+       if (ep->batchlen > 0)
+               printf (", batch \"%.*s\"", ep->batchlen, ep->batch);
+       puts ("\n");
+
+       switch (ep->bdtype) {
+
+       case HYMOD_BDTYPE_IO:
+       case HYMOD_BDTYPE_CLP:
+       case HYMOD_BDTYPE_DSP:
+               printf ("         Motorola %s CPU, speeds: %s/%s/%s",
+                   cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd],
+                   clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]);
+
+               print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz);
+
+               print_mem ("FLASH", ", ", ep->nflash, ep->flashsz);
+
+               puts ("\n");
+
+               print_mem ("ZBT", "         ", ep->nzbt, ep->zbtsz);
+
+               if (ep->nxlx > 0) {
+                       hymod_xlx_t *xp;
+
+                       if (ep->nxlx == 1) {
+                               xp = &ep->xlx[0];
+                               printf (", Xilinx %s FPGA (%s/%s/%s)",
+                                       xlxtyp_vals[xp->type],
+                                       xlxspd_vals[xp->speed],
+                                       xlxtmp_vals[xp->temp],
+                                       xlxgrd_vals[xp->grade]);
+                       }
+                       else {
+                               printf (", %d Xilinx FPGAs (", ep->nxlx);
+                               for (i = 0; i < ep->nxlx; i++) {
+                                       xp = &ep->xlx[i];
+                                       printf ("%s[%s/%s/%s]%s",
+                                           xlxtyp_vals[xp->type],
+                                           xlxspd_vals[xp->speed],
+                                           xlxtmp_vals[xp->temp],
+                                           xlxgrd_vals[xp->grade],
+                                           (i == ep->nxlx - 1) ? ")" : ", ");
+                               }
+                       }
                }
-           }
+               else
+                       puts(", NO FPGAs");
+
+               puts ("\n");
+
+               if (ep->hss.type > 0)
+                       printf ("         High Speed Serial: "
+                               "%s, %d input%s, %d output%s\n",
+                               hstype_vals[ep->hss.type],
+                               ep->hss.nchin,
+                               (ep->hss.nchin == 1 ? "" : "s"),
+                               ep->hss.nchout,
+                               (ep->hss.nchout == 1 ? "" : "s"));
+               break;
+
+       case HYMOD_BDTYPE_INPUT:
+       case HYMOD_BDTYPE_ALTINPUT:
+       case HYMOD_BDTYPE_DISPLAY:
+               break;
+
+       default:
+               /* crap! */
+               printf ("         UNKNOWN BOARD TYPE: %d\n", ep->bdtype);
+               break;
+       }
+}
+
+int
+hymod_eeprom_read (int which, hymod_eeprom_t *ep)
+{
+       char *label = which ? "mezzanine" : "main";
+       unsigned dev_addr = 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 (file)
index 0000000..f58aec2
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * (C) Copyright 2003
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/* 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");
+}
index dcbda31..e121d55 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * (C) Copyright 2001
- * Murray Jensen, CSIRO Manufacturing Science and Technology,
- * <Murray.Jensen@cmst.csiro.au>
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
 #include <common.h>
 #include <net.h>
 
-/* 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;
-
-    while ((ethaddr = getenv("ethaddr")) == NULL || *ethaddr == '\0') {
-
-       puts("*** Ethernet address is not set\n");
-
-       for (;;) {
-           int n;
-
-           n = readline("Enter board ethernet address: ");
-
-           if (n < 0) {
-               puts("\n");
-               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;
+       char *ethaddr;
+       uchar *fp, *efp;
+       int rc, count = 0;
+
+       while ((ethaddr = getenv ("ethaddr")) == NULL || *ethaddr == '\0') {
+
+               printf ("*** Ethernet address is%s not set\n",
+                       count == 0 ? "" : " STILL");
+
+               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);
                }
 
-               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);
+               count++;
        }
-    }
-
-    copy_filename(BootFile, fn, sizeof (BootFile));
-    load_addr = addr;
 
-    if (NetLoop(TFTP) <= 0) {
-       printf("tftp transfer of file '%s' failed\n", fn);
-       return (0);
-    }
+       copy_filename (BootFile, fn, sizeof (BootFile));
+       load_addr = addr;
+       NetBootFileXferSize = 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;
+       if (NetLoop (TFTP) == 0) {
+               printf ("tftp transfer of file '%s' failed\n", fn);
+               return (0);
        }
 
-       name = fp;
+       if (NetBootFileXferSize == 0) {
+               printf ("can't determine size of file '%s'\n", fn);
+               return (0);
+       }
 
-       while (fp < efp && *fp != '=')
-           if (*fp++ == '\n')
-               name = fp;
+       fp = (uchar *)load_addr;
+       efp = fp + NetBootFileXferSize;
 
-       if (fp >= efp)
-           break;
+       do {
+               uchar *name, *value;
 
-       *fp++ = '\0';
+               if (*fp == '#' || *fp == '\n') {
+                       /* skip this line */
+                       while (fp < efp && *fp++ != '\n')
+                               ;
+                       continue;
+               }
 
-       value = fp;
+               name = fp;
 
-       while (fp < efp && *fp != '\n')
-           fp++;
+               while (fp < efp && *fp != '=' && *fp != '\n')
+                       fp++;
+               if (fp >= efp)
+                       break;
+               if (*fp == '\n') {
+                       fp++;
+                       continue;
+               }
+               *fp++ = '\0';
 
-       /* ok if we go off the end here */
+               value = fp;
 
-       if (fp[-1] == '\r')
-           fp[-1] = '\0';
-       *fp++ = '\0';
+               while (fp < efp && *fp != '\n')
+                       fp++;
+               if (fp[-1] == '\r')
+                       fp[-1] = '\0';
+               *fp++ = '\0';   /* ok if we go off the end here */
 
-       if ((*cback)(name, value) == 0)
-           return (0);
+               if ((*cback)(name, value) == 0)
+                       return (0);
 
-    } while (fp < efp);
+       } while (fp < efp);
 
-    return (1);
+       return (1);
 }
index 0a09b4a..7d1ae30 100644 (file)
@@ -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 <common.h>
@@ -36,234 +36,154 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];     /* info for FLASH chips */
 #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 device id */
-       *addr = BANK_CMD_RD_ID;
-       if (*BANK_ADDR_REG_DEV(addr) != BANK_RD_ID_DEV) {
-               retval = -2;
-               goto out;
-       }
+       /* check the manufacturer id - must be intel */
+       *base = BANK_CMD_RD_ID;
+       word = *BANK_REG_MAN_CODE (base);
+       *base = BANK_CMD_RST;
 
-       retval = CFG_FLASH_TYPE;
+       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);
 
-out:
-       /* reset the flash again */
-       *addr = BANK_CMD_RST;
-
-       return retval;
-}
+       /* check the device id */
+       *base = BANK_CMD_RD_ID;
+       word = *BANK_REG_DEV_CODE (base);
+       *base = BANK_CMD_RST;
 
-/*
- * 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;
+       switch (word) {
 
-       fip->flash_id = FLASH_UNKNOWN;
-       fip->size = 0L;
-       fip->sector_count = 0;
+       case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff):
+               fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5;
+               fip->sector_count = 32;
+               break;
 
-       addr = base;
-       eaddr = BANK_ADDR_BASE(addr, MAX_BANKS);
-       nbanks = 0;
+       case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff):
+               fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5;
+               fip->sector_count = 64;
+               break;
 
-       while (addr < eaddr) {
-               bank_addr_t addrw, eaddrw, addrb;
-               int i, osc, nsc, curtype = -1;
+       case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff):
+               fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A;
+               fip->sector_count = 32;
+               break;
 
-               addrw = addr;
-               eaddrw = BANK_ADDR_NEXT_WORD(addrw);
+       case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff):
+               fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A;
+               fip->sector_count = 64;
+               break;
 
-               while (addrw < eaddrw) {
-                       int thistype;
+       case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff):
+               fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A;
+               fip->sector_count = 128;
+               break;
 
-#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;
-                               }
-                       }
-               }
+       default:
+               panic ("\nbad device code (0x%08lx) at addr 0x%08lx",
+                       (unsigned long)word, (unsigned long)base);
+       }
 
-               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);
-               }
+       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 = BANK_ADDR_NEXT_BANK(addr);
-               nbanks++;
+       addr = base;
+       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 ((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);
        }
-
-       if (haderr)
-               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,
@@ -341,40 +261,8 @@ flash_init(void)
 
 /*-----------------------------------------------------------------------
  */
-#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));
 }
 
 /*-----------------------------------------------------------------------
index 3bccbc9..10db7fc 100644 (file)
-/*************** DEFINES for Intel StrataFlash FLASH chip ********************/
-
 /*
- * acceptable chips types are:
+ * (C) Copyright 2000
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
  *
- *     28F320J5, 28F640J5, 28F320J3A, 28F640J3A and 28F128J3A
+ * 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 CHIP_STAT_ERR          (CHIP_STAT_VPPS | CHIP_STAT_DPS | \
-                                   CHIP_STAT_ECLBS | CHIP_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)
+#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 ISF_STAT_ERR           (ISF_STAT_VPPS | ISF_STAT_DPS | \
+                                   ISF_STAT_ECLBS | ISF_STAT_PSLBS)
+
+/* 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 volatile bank_word_t *bank_addr_t;
-typedef unsigned long bank_size_t;             /* want this big - >= 32 bit */
+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
 
-#define BANK_CHIP_WIDTH                2               /* each bank is 2 chips wide */
-#define BANK_CHIP_WSHIFT       1               /* (log2 of BANK_CHIP_WIDTH) */
+/* theoretically the following examples should also work */
 
-#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)
+/* 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))
 
-#define MAX_BANKS              1               /* only one bank possible */
+/* 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;
 
 /* 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)
-
-/* 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))
-
-/* 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
- */
+                                   sizeof (bank_blk_t))
 
-#define BANK_FILL_WORD(o)      ((bank_word_t)( \
-                                   ((unsigned long)(o) << 16) | \
-                                   ((unsigned long)(o) <<  0) \
-                               ))
+/* 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 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_ERR          BANK_FILL_WORD(CHIP_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)
+#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(ISF_STAT_ERR)
+
+/* 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)
index 913f82d..16def24 100644 (file)
@@ -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, <Murray.Jensen@csiro.au>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+
+#
+# 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
 #              %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 <name> or <value>
+#              ... otherwise the %x is discarded
 #
 # if first character in <name> 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 <name> is a plus ('+'), then <value> will be appended
-# to any existing env var (the plus is removed). Duplicates of <value> are
+# to any existing env var (the plus is ignored). Duplicates of <value> are
 # removed.
 #
+# similarly, if the last character in <name> is a minus ('-'), then any
+# occurences of <value> in the current value of <name> will removed (the
+# minus is ignored).
+#
+# leading and trailing whitespace is removed in both <name> and <value>
+# (after processing any initial or final plus/minus in <name>).
+#
+
+# 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, 64 x 256K sectors, mapped at address 0x40000000
 #
-# 16M flash map, 64 x 256K sectors, mapped at address 0x40000000
+# Sector(s)    Address         Size    Description
 #
-# 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
+#  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
index 829f254..3611a12 100644 (file)
  * 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 <common.h>
 #include <mpc8260.h>
+#include <mpc8260_irq.h>
 #include <ioports.h>
 #include <i2c.h>
 #include <asm/iopin_8260.h>
 /* ------------------------------------------------------------------------- */
 
 /* 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 */
-        },
-
-       /* 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 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 */
-        }
+       {
+               /* 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 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 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)) {
-
-               if (read_eeprom
-                       ("main", HYMOD_EEOFF_MAIN << 8, &cp->main.eeprom))
-                       cp->main.eeprom_valid = 1;
-
-               puts ("EEPROM:main...");
-
-               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");
-
-               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.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.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.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;
+       rc = hymod_eeprom_read (0, &cp->main.eeprom);
+
+       puts ("EEPROM:main...");
+       if (rc < 0)
+               puts ("NOT PRESENT\n");
+       else if (rc == 0)
+               puts ("INVALID\n");
+       else {
+               cp->main.eeprom.valid = 1;
+
+               printf ("OK (ver %u)\n", cp->main.eeprom.ver);
+               hymod_eeprom_print (&cp->main.eeprom);
+
+               /*
+                * 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.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.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.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.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");
 
-       /* set up mezzanine board config info */
-
-       if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MEZZ)) {
-
-               if (read_eeprom
-                       ("mezz", HYMOD_EEOFF_MEZZ << 8, &cp->mezz.eeprom))
-                       cp->mezz.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
+               cp->main.xlx[0].irq = FPGA_MAIN_IRQ;
+       }
 
-               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);
+       /* set up mezzanine board config info */
 
-                       puts ("SEL_CD:toggled for display board\n");
-               }
-       } else
-               puts ("EEPROM:mezz...NOT PRESENT\n");
+       rc = hymod_eeprom_read (1, &cp->mezz.eeprom);
 
-       cp->crc =
-                       crc32 (0, (unsigned char *) cp, offsetof (hymod_conf_t, crc));
+       puts ("EEPROM:mezz...");
+       if (rc < 0)
+               puts ("NOT PRESENT\n");
+       else if (rc == 0)
+               puts ("INVALID\n");
+       else {
+               cp->main.eeprom.valid = 1;
 
-       if (getenv ("global_env_loaded") == NULL) {
+               printf ("OK (ver %u)\n", cp->mezz.eeprom.ver);
+               hymod_eeprom_print (&cp->mezz.eeprom);
+       }
 
-               puts ("*** global environment has not been loaded\n");
-               puts ("*** fetching from server (Control-C to Abort)\n");
+       cp->crc = crc32 (0, (unsigned char *)cp, offsetof (hymod_conf_t, crc));
 
-               rc = fetch_and_parse (global_env_path, 0x100000,
-                                                         env_fetch_callback);
+       hymod_check_env ();
 
-               if (rc == 0)
-                       puts ("*** Fetch of environment failed!\n");
-               else
-                       setenv ("global_env_loaded", "yes");
-       }
        return (0);
 }
diff --git a/board/hymod/hymod.h b/board/hymod/hymod.h
new file mode 100644 (file)
index 0000000..9d8d662
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * (C) Copyright 2001
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _HYMOD_H_
+#define _HYMOD_H_
+
+#include <linux/config.h>
+#ifdef CONFIG_8260
+#include <asm/iopin_8260.h>
+#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 (file)
index 0000000..63aa13c
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * (C) Copyright 2003
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/* 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);
+       }
+}
index 32bab1a..3db0bca 100644 (file)
@@ -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
  */
index 86ed584..8c94aa7 100644 (file)
@@ -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;
index 6192dff..f538870 100644 (file)
@@ -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);
index 92844b1..95b7256 100644 (file)
--- 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)           \
index 46ac975..d0545cf 100644 (file)
@@ -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;
                }
        }
index bd2fcc9..45dca73 100644 (file)
@@ -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 */
index 2d65e32..69ae535 100644 (file)
@@ -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 ((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;
                        }
                }
-
-               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 ((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(0);
+       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 */
+
+       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 (had_tx_nak);
+       return (0);     /* device exists - had receive overrun */
 }
 
 
index 9062084..3c5ef74 100644 (file)
@@ -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);
index 48a4be6..6b9d499 100644 (file)
@@ -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 (file)
index 0000000..14c38f0
--- /dev/null
@@ -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 <common.h>
+
+#ifdef CONFIG_DTT_ADM1021
+
+#include <i2c.h>
+#include <dtt.h>
+
+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 */
index 7966ad5..008008a 100644 (file)
@@ -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 */
 /* --------------------------------------------------------------------        */
index b0640c6..cc5dbe7 100644 (file)
@@ -52,7 +52,7 @@ typedef volatile unsigned char        vu_char;
 #include <ppc4xx.h>
 #endif
 #ifdef CONFIG_HYMOD
-#include <asm/hymod.h>
+#include <board/hymod/hymod.h>
 #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)
index e3a0ee3..dc7de44 100644 (file)
@@ -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)
 
 # 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)
 
 /*
 # 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)
 
 /*
 # 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
 #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 <cmd_confdefs.h>
 
 #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 <SPACE> to stop\n"
+#define CONFIG_AUTOBOOT_STOP_STR       " "
+#undef CONFIG_AUTOBOOT_DELAY_STR
+#define DEBUG_BOOTKEYS         0
 #endif
 
 #if (CONFIG_COMMANDS & CFG_CMD_KGDB)
 #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
 
 #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 */
 /* 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.)
  * You should know what you are doing if you make changes here.
 #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 */
 #define FPGA_MEZZ_ENABLE_PIN   3       /* PA3 */
 
 /*
+ * FPGA Interrupt configuration
+ */
+#define FPGA_MAIN_IRQ          SIU_INT_IRQ2
+
+/*
  * Internal Definitions
  *
  * Boot Flags
index f3d95ff..a17aa67 100644 (file)
 #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_ */
index e594788..7223f59 100644 (file)
@@ -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)        */
index 046dd32..9bee9a3 100644 (file)
 */
 #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)
index d7a7661..b9e6e1b 100644 (file)
@@ -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)
index 56cbdfe..9bc77b5 100644 (file)
@@ -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)      || \
index 6e98c9c..fa651ae 100644 (file)
@@ -73,6 +73,7 @@
 <tr valign=top>
 <th>logno / edit</th>
 <th>date</th>
+<th>who</th>
 <th width="70%">details</th>
 </tr>
 <?php
@@ -82,6 +83,7 @@
                echo "<tr>\n";
                print_cell("<a href=\"edlog.php?serno=$row[serno]&logno=$row[logno]\">$row[logno]</a>");
                print_cell($row['date']);
+               print_cell($row['who']);
                print_cell("<pre>" . urldecode($row['details']) . "</pre>");
                echo "</tr>\n";
        }
index 0393dbd..9361419 100644 (file)
@@ -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');
 
        // 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;
index db27c37..f800471 100644 (file)
@@ -26,6 +26,9 @@
                $query.=" date='$date'";
        }
 
+       if (isset($who))
+               $query.=", who='" . $who . "'";
+
        if (isset($details))
                $query.=", details='" . rawurlencode($details) . "'";
 
index b00de95..35ba125 100644 (file)
@@ -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) . "'";
 
index f819b46..7f311bf 100644 (file)
@@ -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');
 
index 5ec42ac..3f51639 100644 (file)
@@ -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');
 
index dbe55fe..a791469 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index aea2901..276a00a 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index 907709f..0698213 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 #include <stdarg.h>
 
 extern char *pname;
index ee9553c..300545d 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index d46ab48..8cd8347 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index bfc4a1f..f14dacb 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 extern int remote_desc, remote_timeout;
 
 extern void remote_reset(void);
index 88895bb..2f2e529 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
index 60629bd..3ed509e 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * (C) Copyright 2000
+ * Murray Jensen <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
 #include <termios.h>
 
 #define SERIAL_ERROR   -1      /* General error, see errno for details */