summaryrefslogtreecommitdiff
path: root/board/hymod
diff options
context:
space:
mode:
authorKevin2014-11-15 11:48:36 +0800
committerKevin2014-11-15 11:48:36 +0800
commitd04075478d378d9e15f3e1abfd14b0bd124077d4 (patch)
tree733dd964582f388b9e3e367c249946cd32a2851f /board/hymod
downloadFOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.gz
FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.bz2
FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.zip
init commit via android 4.4 uboot
Diffstat (limited to 'board/hymod')
-rwxr-xr-xboard/hymod/Makefile40
-rwxr-xr-xboard/hymod/bsp.c407
-rwxr-xr-xboard/hymod/config.mk32
-rwxr-xr-xboard/hymod/eeprom.c694
-rwxr-xr-xboard/hymod/env.c236
-rwxr-xr-xboard/hymod/fetch.c107
-rwxr-xr-xboard/hymod/flash.c506
-rwxr-xr-xboard/hymod/flash.h156
-rwxr-xr-xboard/hymod/global_env161
-rwxr-xr-xboard/hymod/hymod.c537
-rwxr-xr-xboard/hymod/hymod.h322
-rwxr-xr-xboard/hymod/input.c113
-rwxr-xr-xboard/hymod/u-boot.lds148
-rwxr-xr-xboard/hymod/u-boot.lds.debug137
14 files changed, 3596 insertions, 0 deletions
diff --git a/board/hymod/Makefile b/board/hymod/Makefile
new file mode 100755
index 0000000..b52af9a
--- /dev/null
+++ b/board/hymod/Makefile
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o input.o env.o
+
+$(LIB): .depend $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/hymod/bsp.c b/board/hymod/bsp.c
new file mode 100755
index 0000000..0596fa4
--- /dev/null
+++ b/board/hymod/bsp.c
@@ -0,0 +1,407 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ * hacked for Hymod FPGA support by Murray.Jensen@csiro.au, 29-Jan-01
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <asm/iopin_8260.h>
+
+/*-----------------------------------------------------------------------
+ * Board Special Commands: FPGA load/store, EEPROM erase
+ */
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+#define LOAD_SUCCESS 0
+#define LOAD_FAIL_NOCONF 1
+#define LOAD_FAIL_NOINIT 2
+#define LOAD_FAIL_NODONE 3
+
+#define STORE_SUCCESS 0
+
+/*
+ * Programming the Hymod FPGAs
+ *
+ * The 8260 io port config table is set up so that the INIT pin is
+ * held Low (Open Drain output 0) - this will delay the automatic
+ * Power-On config until INIT is released (by making it an input).
+ *
+ * If the FPGA has been programmed before, then the assertion of PROGRAM
+ * will initiate configuration (i.e. it begins clearing the RAM).
+ *
+ * When the FPGA is ready to receive configuration data (either after
+ * releasing INIT after Power-On, or after asserting PROGRAM), it will
+ * pull INIT high.
+ *
+ * Notes from Paul Dunn:
+ *
+ * 1. program pin should be forced low for >= 300ns
+ * (about 20 bus clock cycles minimum).
+ *
+ * 2. then wait for init to go high, which signals
+ * that the FPGA has cleared its internal memory
+ * and is ready to load
+ *
+ * 3. perform load writes of entire config file
+ *
+ * 4. wait for done to go high, which should be
+ * within a few bus clock cycles. If done has not
+ * gone high after reasonable period, then load
+ * has not worked (wait several ms?)
+ */
+
+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)
+ 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)
+ iopin_set_high (&fpgaio->enable_pin);
+
+ /* ensure INIT is released (set it to be an input) */
+ iopin_set_in (&fpgaio->init_pin);
+
+ /* 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 */
+ iopin_set_high (&fpgaio->prog_pin);
+
+ /* wait for INIT High */
+ cnt = 0;
+ while (!iopin_is_high (&fpgaio->init_pin))
+ if (++cnt == 10000000) {
+ result = LOAD_FAIL_NOINIT;
+ goto done;
+ }
+
+ /* write configuration data */
+ while (addr < eaddr)
+ *fpgabase = *addr++;
+
+ /* wait for DONE High */
+ cnt = 0;
+ while (!iopin_is_high (&fpgaio->done_pin))
+ if (++cnt == 100000000) {
+ result = LOAD_FAIL_NODONE;
+ goto done;
+ }
+
+ /* success */
+ result = LOAD_SUCCESS;
+
+ done:
+
+ if (fpgaio->enable_pin.flag)
+ iopin_set_low (&fpgaio->enable_pin);
+
+ return (result);
+}
+
+/* ------------------------------------------------------------------------- */
+int
+do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ uchar *addr, *save_addr;
+ ulong size;
+ int mezz, arg, result;
+
+ switch (argc) {
+
+ case 0:
+ case 1:
+ break;
+
+ case 2:
+ if (strcmp (argv[1], "info") == 0) {
+ printf ("\nHymod FPGA Info...\n");
+ 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;
+
+ case 3:
+ if (strcmp (argv[1], "store") == 0) {
+ addr = (uchar *) simple_strtoul (argv[2], NULL, 16);
+
+ save_addr = addr;
+#if 0
+ /* fpga readback unimplemented */
+ while (more readback data)
+ *addr++ = *fpga;
+ result = error ? STORE_FAIL_XXX : STORE_SUCCESS;
+#else
+ result = STORE_SUCCESS;
+#endif
+
+ if (result == STORE_SUCCESS) {
+ printf ("SUCCEEDED (%d bytes)\n",
+ addr - save_addr);
+ return 0;
+ } else
+ printf ("FAILED (%d bytes)\n",
+ addr - save_addr);
+ return 1;
+ }
+ break;
+
+ case 4:
+ 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");
+ return 1;
+ }
+
+ if (NetBootFileXferSize == 0) {
+ printf ("can't determine file size - "
+ "aborting fpga load\n");
+ return 1;
+ }
+
+ printf ("File transfer succeeded - "
+ "beginning fpga load...");
+
+ result = fpga_load (0, (uchar *) load_addr,
+ NetBootFileXferSize);
+
+ if (result == LOAD_SUCCESS) {
+ printf ("SUCCEEDED\n");
+ return 0;
+ } 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");
+ return 1;
+
+ }
+ /* fall through ... */
+
+ case 5:
+ if (strcmp (argv[1], "load") == 0) {
+ if (argc == 5) {
+ if (strcmp (argv[2], "main") == 0)
+ mezz = 0;
+ else if (strcmp (argv[2], "mezz") == 0)
+ mezz = 1;
+ else {
+ printf ("FPGA type must be either "
+ "`main' or `mezz'\n");
+ return 1;
+ }
+ arg = 3;
+ } else {
+ 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_NOCONF)
+ printf ("FAILED (no CONF)\n");
+ else if (result == LOAD_FAIL_NOINIT)
+ printf ("FAILED (no INIT)\n");
+ else
+ printf ("FAILED (no DONE)\n");
+ return 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+U_BOOT_CMD(
+ fpga, 6, 1, do_fpga,
+ "fpga - FPGA sub-system\n",
+ "load [type] addr size\n"
+ " - write the configuration data at memory address `addr',\n"
+ " size `size' bytes, into the FPGA of type `type' (either\n"
+ " `main' or `mezz', default `main'). e.g.\n"
+ " `fpga load 100000 7d8f'\n"
+ " loads the main FPGA with config data at address 100000\n"
+ " HEX, size 7d8f HEX (32143 DEC) bytes\n"
+ "fpga tftp file addr\n"
+ " - transfers `file' from the tftp server into memory at\n"
+ " address `addr', then writes the entire file contents\n"
+ " into the main FPGA\n"
+ "fpga store addr\n"
+ " - read configuration data from the main FPGA (the mezz\n"
+ " FPGA is write-only), into address `addr'. There must be\n"
+ " enough memory available at `addr' to hold all the config\n"
+ " data - the size of which is determined by VC:???\n"
+ "fpga info\n"
+ " - print information about the Hymod FPGA, namely the\n"
+ " memory addresses at which the four FPGA local bus\n"
+ " address spaces appear in the physical address space\n"
+);
+/* ------------------------------------------------------------------------- */
+int
+do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ uchar data[HYMOD_EEPROM_SIZE];
+ uint addr = CFG_I2C_EEPROM_ADDR;
+
+ switch (argc) {
+
+ case 1:
+ addr |= HYMOD_EEOFF_MAIN;
+ break;
+
+ case 2:
+ if (strcmp (argv[1], "main") == 0) {
+ addr |= HYMOD_EEOFF_MAIN;
+ break;
+ }
+ if (strcmp (argv[1], "mezz") == 0) {
+ addr |= HYMOD_EEOFF_MEZZ;
+ break;
+ }
+ /* fall through ... */
+
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ memset (data, 0, HYMOD_EEPROM_SIZE);
+
+ eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE);
+
+ return 0;
+}
+U_BOOT_CMD(
+ eeclear, 1, 0, do_eecl,
+ "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"
+);
+
+/* ------------------------------------------------------------------------- */
+
+int
+do_htest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#if 0
+ int rc;
+#endif
+#ifdef CONFIG_ETHER_LOOPBACK_TEST
+ extern void eth_loopback_test (void);
+#endif /* CONFIG_ETHER_LOOPBACK_TEST */
+
+ printf ("HYMOD tests - ensure loopbacks etc. are connected\n\n");
+
+#if 0
+ /* Load FPGA with test program */
+
+ printf ("Loading test FPGA program ...");
+
+ rc = fpga_load (0, test_bitfile, sizeof (test_bitfile));
+
+ switch (rc) {
+
+ case LOAD_SUCCESS:
+ printf (" SUCCEEDED\n");
+ break;
+
+ case LOAD_FAIL_NOCONF:
+ printf (" FAILED (no configuration space defined)\n");
+ return 1;
+
+ case LOAD_FAIL_NOINIT:
+ printf (" FAILED (timeout - no INIT signal seen)\n");
+ return 1;
+
+ case LOAD_FAIL_NODONE:
+ printf (" FAILED (timeout - no DONE signal seen)\n");
+ return 1;
+
+ default:
+ printf (" FAILED (unknown return code from fpga_load\n");
+ return 1;
+ }
+
+ /* run Local Bus <=> Xilinx tests */
+
+ /* tell Xilinx to run ZBT Ram, High Speed serial and Mezzanine tests */
+
+ /* run SDRAM test */
+#endif
+
+#ifdef CONFIG_ETHER_LOOPBACK_TEST
+ /* run Ethernet test */
+ eth_loopback_test ();
+#endif /* CONFIG_ETHER_LOOPBACK_TEST */
+
+ return 0;
+}
+
+#endif /* CFG_CMD_BSP */
+
+/* ------------------------------------------------------------------------- */
diff --git a/board/hymod/config.mk b/board/hymod/config.mk
new file mode 100755
index 0000000..0a9985f
--- /dev/null
+++ b/board/hymod/config.mk
@@ -0,0 +1,32 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# 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
+#
+
+#
+# HYMOD boards
+#
+
+TEXT_BASE = 0x40000000
+
+PLATFORM_CPPFLAGS += -I$(TOPDIR)
+
+OBJCFLAGS = --remove-section=.ppcenv
diff --git a/board/hymod/eeprom.c b/board/hymod/eeprom.c
new file mode 100755
index 0000000..c9b9b18
--- /dev/null
+++ b/board/hymod/eeprom.c
@@ -0,0 +1,694 @@
+/*
+ * (C) Copyright 2001
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8260.h>
+
+/* imports from fetch.c */
+extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
+
+/* imports from input.c */
+extern int hymod_get_serno (const char *);
+
+/* this is relative to the root of the server's tftp directory */
+static char *def_bddb_cfgdir = "/hymod/bddb";
+
+static int
+hymod_eeprom_load (int which, hymod_eeprom_t *ep)
+{
+ unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \
+ (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
+ unsigned offset = 0;
+ uchar data[HYMOD_EEPROM_MAXLEN], *dp, *edp;
+ hymod_eehdr_t hdr;
+ ulong len, crc;
+
+ memset (ep, 0, sizeof *ep);
+
+ eeprom_read (dev_addr, offset, (uchar *)&hdr, sizeof (hdr));
+ offset += sizeof (hdr);
+
+ if (hdr.id != HYMOD_EEPROM_ID || hdr.ver > HYMOD_EEPROM_VER ||
+ (len = hdr.len) > HYMOD_EEPROM_MAXLEN)
+ return (0);
+
+ eeprom_read (dev_addr, offset, data, len);
+ offset += len;
+
+ eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong));
+ offset += sizeof (ulong);
+
+ if (crc32 (crc32 (0, (uchar *)&hdr, sizeof hdr), data, len) != crc)
+ return (0);
+
+ ep->ver = hdr.ver;
+ dp = data; edp = dp + len;
+
+ for (;;) {
+ ulong rtyp;
+ uchar rlen, *rdat;
+
+ rtyp = *dp++;
+ if ((rtyp & 0x80) == 0)
+ rlen = *dp++;
+ else {
+ uchar islarge = rtyp & 0x40;
+
+ rtyp = ((rtyp & 0x3f) << 8) | *dp++;
+ if (islarge) {
+ rtyp = (rtyp << 8) | *dp++;
+ rtyp = (rtyp << 8) | *dp++;
+ }
+
+ rlen = *dp++;
+ rlen = (rlen << 8) | *dp++;
+ if (islarge) {
+ rlen = (rlen << 8) | *dp++;
+ rlen = (rlen << 8) | *dp++;
+ }
+ }
+
+ if (rtyp == 0)
+ break;
+
+ rdat = dp;
+ dp += rlen;
+
+ if (dp > edp) /* error? */
+ break;
+
+ switch (rtyp) {
+
+ case HYMOD_EEREC_SERNO: /* serial number */
+ if (rlen == sizeof (ulong))
+ ep->serno = \
+ ((ulong)rdat[0] << 24) | \
+ ((ulong)rdat[1] << 16) | \
+ ((ulong)rdat[2] << 8) | \
+ (ulong)rdat[3];
+ break;
+
+ case HYMOD_EEREC_DATE: /* date */
+ if (rlen == sizeof (hymod_date_t)) {
+ ep->date.year = ((ushort)rdat[0] << 8) | \
+ (ushort)rdat[1];
+ ep->date.month = rdat[2];
+ ep->date.day = rdat[3];
+ }
+ break;
+
+ case HYMOD_EEREC_BATCH: /* batch */
+ if (rlen <= HYMOD_MAX_BATCH)
+ memcpy (ep->batch, rdat, ep->batchlen = rlen);
+ break;
+
+ case HYMOD_EEREC_TYPE: /* board type */
+ if (rlen == 1)
+ ep->bdtype = *rdat;
+ break;
+
+ case HYMOD_EEREC_REV: /* board revision */
+ if (rlen == 1)
+ ep->bdrev = *rdat;
+ break;
+
+ case HYMOD_EEREC_SDRAM: /* sdram size(s) */
+ if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) {
+ int i;
+
+ for (i = 0; i < rlen; i++)
+ ep->sdramsz[i] = rdat[i];
+ ep->nsdram = rlen;
+ }
+ break;
+
+ case HYMOD_EEREC_FLASH: /* flash size(s) */
+ if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) {
+ int i;
+
+ for (i = 0; i < rlen; i++)
+ ep->flashsz[i] = rdat[i];
+ ep->nflash = rlen;
+ }
+ break;
+
+ case HYMOD_EEREC_ZBT: /* zbt ram size(s) */
+ if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) {
+ int i;
+
+ for (i = 0; i < rlen; i++)
+ ep->zbtsz[i] = rdat[i];
+ ep->nzbt = rlen;
+ }
+ break;
+
+ case HYMOD_EEREC_XLXTYP: /* xilinx fpga type(s) */
+ if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
+ int i;
+
+ for (i = 0; i < rlen; i++)
+ ep->xlx[i].type = rdat[i];
+ ep->nxlx = rlen;
+ }
+ break;
+
+ case HYMOD_EEREC_XLXSPD: /* xilinx fpga speed(s) */
+ if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
+ int i;
+
+ for (i = 0; i < rlen; i++)
+ ep->xlx[i].speed = rdat[i];
+ }
+ break;
+
+ case HYMOD_EEREC_XLXTMP: /* xilinx fpga temperature(s) */
+ if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
+ int i;
+
+ for (i = 0; i < rlen; i++)
+ ep->xlx[i].temp = rdat[i];
+ }
+ break;
+
+ case HYMOD_EEREC_XLXGRD: /* xilinx fpga grade(s) */
+ if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
+ int i;
+
+ for (i = 0; i < rlen; i++)
+ ep->xlx[i].grade = rdat[i];
+ }
+ break;
+
+ case HYMOD_EEREC_CPUTYP: /* CPU type */
+ if (rlen == 1)
+ ep->mpc.type = *rdat;
+ break;
+
+ case HYMOD_EEREC_CPUSPD: /* CPU speed */
+ if (rlen == 1)
+ ep->mpc.cpuspd = *rdat;
+ break;
+
+ case HYMOD_EEREC_CPMSPD: /* CPM speed */
+ if (rlen == 1)
+ ep->mpc.cpmspd = *rdat;
+ break;
+
+ case HYMOD_EEREC_BUSSPD: /* bus speed */
+ if (rlen == 1)
+ ep->mpc.busspd = *rdat;
+ break;
+
+ case HYMOD_EEREC_HSTYPE: /* hs-serial chip type */
+ if (rlen == 1)
+ ep->hss.type = *rdat;
+ break;
+
+ case HYMOD_EEREC_HSCHIN: /* num hs-serial input chans */
+ if (rlen == 1)
+ ep->hss.nchin = *rdat;
+ break;
+
+ case HYMOD_EEREC_HSCHOUT: /* num hs-serial output chans */
+ if (rlen == 1)
+ ep->hss.nchout = *rdat;
+ break;
+
+ default: /* ignore */
+ break;
+ }
+ }
+
+ return (1);
+}
+
+/* maps an ascii "name=value" into a binary eeprom data record */
+typedef
+ struct _eerec_map {
+ char *name;
+ uint type;
+ uchar *(*handler) \
+ (struct _eerec_map *, uchar *, uchar *, uchar *);
+ uint length;
+ uint maxlen;
+ }
+eerec_map_t;
+
+static uchar *
+uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
+{
+ char *eval;
+ ulong lval;
+
+ lval = simple_strtol ((char *)val, &eval, 10);
+
+ if ((uchar *)eval == val || *eval != '\0') {
+ printf ("%s rec (%s) is not a valid uint\n", rp->name, val);
+ return (NULL);
+ }
+
+ if (dp + 2 + rp->length > edp) {
+ printf ("can't fit %s rec into eeprom\n", rp->name);
+ return (NULL);
+ }
+
+ *dp++ = rp->type;
+ *dp++ = rp->length;
+
+ switch (rp->length) {
+
+ case 1:
+ if (lval >= 256) {
+ printf ("%s rec value (%lu) out of range (0-255)\n",
+ rp->name, lval);
+ return (NULL);
+ }
+ *dp++ = lval;
+ break;
+
+ case 2:
+ if (lval >= 65536) {
+ printf ("%s rec value (%lu) out of range (0-65535)\n",
+ rp->name, lval);
+ return (NULL);
+ }
+ *dp++ = lval >> 8;
+ *dp++ = lval;
+ break;
+
+ case 4:
+ *dp++ = lval >> 24;
+ *dp++ = lval >> 16;
+ *dp++ = lval >> 8;
+ *dp++ = lval;
+ break;
+
+ default:
+ printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length);
+ return (NULL);
+ }
+
+ return (dp);
+}
+
+static uchar *
+date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
+{
+ hymod_date_t date;
+ char *p = (char *)val;
+ char *ep;
+ ulong lval;
+
+ lval = simple_strtol (p, &ep, 10);
+ if (ep == p || *ep++ != '-') {
+bad_date:
+ printf ("%s rec (%s) is not a valid date\n", rp->name, val);
+ return (NULL);
+ }
+ if (lval >= 65536)
+ goto bad_date;
+ date.year = lval;
+
+ lval = simple_strtol (p = ep, &ep, 10);
+ if (ep == p || *ep++ != '-' || lval == 0 || lval > 12)
+ goto bad_date;
+ date.month = lval;
+
+ lval = simple_strtol (p = ep, &ep, 10);
+ if (ep == p || *ep != '\0' || lval == 0 || lval > 31)
+ goto bad_date;
+ date.day = lval;
+
+ if (dp + 2 + rp->length > edp) {
+ printf ("can't fit %s rec into eeprom\n", rp->name);
+ return (NULL);
+ }
+
+ *dp++ = rp->type;
+ *dp++ = rp->length;
+ *dp++ = date.year >> 8;
+ *dp++ = date.year;
+ *dp++ = date.month;
+ *dp++ = date.day;
+
+ return (dp);
+}
+
+static uchar *
+string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
+{
+ uint len;
+
+ if ((len = strlen ((char *)val)) > rp->maxlen) {
+ printf ("%s rec (%s) string is too long (%d>%d)\n",
+ rp->name, val, len, rp->maxlen);
+ return (NULL);
+ }
+
+ if (dp + 2 + len > edp) {
+ printf ("can't fit %s rec into eeprom\n", rp->name);
+ return (NULL);
+ }
+
+ *dp++ = rp->type;
+ *dp++ = len;
+ memcpy (dp, val, len);
+ dp += len;
+
+ return (dp);
+}
+
+static uchar *
+bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
+{
+ uchar bytes[HYMOD_MAX_BYTES], nbytes, *p;
+ char *ep;
+
+ for (nbytes = 0, p = val; *p != '\0'; p = (uchar *)ep) {
+ ulong lval;
+
+ lval = simple_strtol ((char *)p, &ep, 10);
+ if ((uchar *)ep == p || (*ep != '\0' && *ep != ',') || \
+ lval >= 256) {
+ printf ("%s rec (%s) byte array has invalid uint\n",
+ rp->name, val);
+ return (NULL);
+ }
+ if (nbytes >= HYMOD_MAX_BYTES) {
+ printf ("%s rec (%s) byte array too long\n",
+ rp->name, val);
+ return (NULL);
+ }
+ bytes[nbytes++] = lval;
+
+ if (*ep != '\0')
+ ep++;
+ }
+
+ if (dp + 2 + nbytes > edp) {
+ printf ("can't fit %s rec into eeprom\n", rp->name);
+ return (NULL);
+ }
+
+ *dp++ = rp->type;
+ *dp++ = nbytes;
+ memcpy (dp, bytes, nbytes);
+ dp += nbytes;
+
+ return (dp);
+}
+
+static eerec_map_t eerec_map[] = {
+ /* name type handler len max */
+ { "serno", HYMOD_EEREC_SERNO, uint_handler, 4, 0 },
+ { "date", HYMOD_EEREC_DATE, date_handler, 4, 0 },
+ { "batch", HYMOD_EEREC_BATCH, string_handler, 0, HYMOD_MAX_BATCH },
+ { "type", HYMOD_EEREC_TYPE, uint_handler, 1, 0 },
+ { "rev", HYMOD_EEREC_REV, uint_handler, 1, 0 },
+ { "sdram", HYMOD_EEREC_SDRAM, bytes_handler, 0, HYMOD_MAX_SDRAM },
+ { "flash", HYMOD_EEREC_FLASH, bytes_handler, 0, HYMOD_MAX_FLASH },
+ { "zbt", HYMOD_EEREC_ZBT, bytes_handler, 0, HYMOD_MAX_ZBT },
+ { "xlxtyp", HYMOD_EEREC_XLXTYP, bytes_handler, 0, HYMOD_MAX_XLX },
+ { "xlxspd", HYMOD_EEREC_XLXSPD, bytes_handler, 0, HYMOD_MAX_XLX },
+ { "xlxtmp", HYMOD_EEREC_XLXTMP, bytes_handler, 0, HYMOD_MAX_XLX },
+ { "xlxgrd", HYMOD_EEREC_XLXGRD, bytes_handler, 0, HYMOD_MAX_XLX },
+ { "cputyp", HYMOD_EEREC_CPUTYP, uint_handler, 1, 0 },
+ { "cpuspd", HYMOD_EEREC_CPUSPD, uint_handler, 1, 0 },
+ { "cpmspd", HYMOD_EEREC_CPMSPD, uint_handler, 1, 0 },
+ { "busspd", HYMOD_EEREC_BUSSPD, uint_handler, 1, 0 },
+ { "hstype", HYMOD_EEREC_HSTYPE, uint_handler, 1, 0 },
+ { "hschin", HYMOD_EEREC_HSCHIN, uint_handler, 1, 0 },
+ { "hschout", HYMOD_EEREC_HSCHOUT, uint_handler, 1, 0 },
+};
+
+static int neerecs = sizeof eerec_map / sizeof eerec_map[0];
+
+static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp;
+
+static int
+eerec_callback (uchar *name, uchar *val)
+{
+ eerec_map_t *rp;
+
+ for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++)
+ if (strcmp ((char *)name, rp->name) == 0)
+ break;
+
+ if (rp >= &eerec_map[neerecs])
+ return (0);
+
+ if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL)
+ return (0);
+
+ return (1);
+}
+
+static int
+hymod_eeprom_fetch(int which, char *filename, ulong addr)
+{
+ unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \
+ (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
+ hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0];
+ ulong crc;
+
+ memset (hp, 0, sizeof *hp);
+ hp->id = HYMOD_EEPROM_ID;
+ hp->ver = HYMOD_EEPROM_VER;
+
+ dp = sdp = (uchar *)(hp + 1);
+ edp = dp + HYMOD_EEPROM_MAXLEN;
+
+ if (fetch_and_parse (filename, addr, eerec_callback) == 0)
+ return (0);
+
+ hp->len = dp - sdp;
+
+ crc = crc32 (0, data, dp - data);
+ memcpy (dp, &crc, sizeof (ulong));
+ dp += sizeof (ulong);
+
+ eeprom_write (dev_addr, 0, data, dp - data);
+
+ return (1);
+}
+
+static char *type_vals[] = {
+ "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY"
+};
+
+static char *xlxtyp_vals[] = {
+ "NONE", "XCV300E", "XCV400E", "XCV600E"
+};
+
+static char *xlxspd_vals[] = {
+ "NONE", "6", "7", "8"
+};
+
+static char *xlxtmp_vals[] = {
+ "NONE", "COM", "IND"
+};
+
+static char *xlxgrd_vals[] = {
+ "NONE", "NORMAL", "ENGSAMP"
+};
+
+static char *cputyp_vals[] = {
+ "NONE", "MPC8260"
+};
+
+static char *clk_vals[] = {
+ "NONE", "33", "66", "100", "133", "166", "200"
+};
+
+static char *hstype_vals[] = {
+ "NONE", "AMCC-S2064A"
+};
+
+static void
+print_mem (char *l, char *s, uchar n, uchar a[])
+{
+ if (n > 0) {
+ if (n == 1)
+ printf ("%s%dMB %s", s, 1 << (a[0] - 20), l);
+ else {
+ ulong t = 0;
+ int i;
+
+ for (i = 0; i < n; i++)
+ t += 1 << (a[i] - 20);
+
+ printf ("%s%luMB %s (%d banks:", s, t, l, n);
+
+ for (i = 0; i < n; i++)
+ printf ("%dMB%s",
+ 1 << (a[i] - 20),
+ (i == n - 1) ? ")" : ",");
+ }
+ }
+ else
+ printf ("%sNO %s", s, l);
+}
+
+void
+hymod_eeprom_print (hymod_eeprom_t *ep)
+{
+ int i;
+
+ printf (" Hymod %s board, rev %03d\n",
+ type_vals[ep->bdtype], ep->bdrev);
+
+ printf (" serial #: %010lu, date %04d-%02d-%02d",
+ ep->serno, ep->date.year, ep->date.month, ep->date.day);
+ if (ep->batchlen > 0)
+ printf (", batch \"%.*s\"", ep->batchlen, ep->batch);
+ puts ("\n");
+
+ switch (ep->bdtype) {
+
+ case HYMOD_BDTYPE_IO:
+ case HYMOD_BDTYPE_CLP:
+ case HYMOD_BDTYPE_DSP:
+ printf (" Motorola %s CPU, speeds: %s/%s/%s",
+ cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd],
+ clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]);
+
+ print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz);
+
+ print_mem ("FLASH", ", ", ep->nflash, ep->flashsz);
+
+ puts ("\n");
+
+ print_mem ("ZBT", " ", ep->nzbt, ep->zbtsz);
+
+ if (ep->nxlx > 0) {
+ hymod_xlx_t *xp;
+
+ if (ep->nxlx == 1) {
+ xp = &ep->xlx[0];
+ printf (", Xilinx %s FPGA (%s/%s/%s)",
+ xlxtyp_vals[xp->type],
+ xlxspd_vals[xp->speed],
+ xlxtmp_vals[xp->temp],
+ xlxgrd_vals[xp->grade]);
+ }
+ else {
+ printf (", %d Xilinx FPGAs (", ep->nxlx);
+ for (i = 0; i < ep->nxlx; i++) {
+ xp = &ep->xlx[i];
+ printf ("%s[%s/%s/%s]%s",
+ xlxtyp_vals[xp->type],
+ xlxspd_vals[xp->speed],
+ xlxtmp_vals[xp->temp],
+ xlxgrd_vals[xp->grade],
+ (i == ep->nxlx - 1) ? ")" : ", ");
+ }
+ }
+ }
+ else
+ puts(", NO FPGAs");
+
+ puts ("\n");
+
+ if (ep->hss.type > 0)
+ printf (" High Speed Serial: "
+ "%s, %d input%s, %d output%s\n",
+ hstype_vals[ep->hss.type],
+ ep->hss.nchin,
+ (ep->hss.nchin == 1 ? "" : "s"),
+ ep->hss.nchout,
+ (ep->hss.nchout == 1 ? "" : "s"));
+ break;
+
+ case HYMOD_BDTYPE_INPUT:
+ case HYMOD_BDTYPE_ALTINPUT:
+ case HYMOD_BDTYPE_DISPLAY:
+ break;
+
+ default:
+ /* crap! */
+ printf (" UNKNOWN BOARD TYPE: %d\n", ep->bdtype);
+ break;
+ }
+}
+
+int
+hymod_eeprom_read (int which, hymod_eeprom_t *ep)
+{
+ char *label = which ? "mezzanine" : "main";
+ unsigned dev_addr = 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++;
+ }
+}
diff --git a/board/hymod/env.c b/board/hymod/env.c
new file mode 100755
index 0000000..f9e1421
--- /dev/null
+++ b/board/hymod/env.c
@@ -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 = (char *)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 = (char *)value;
+ q = nv;
+
+ while ((c = *p) == ' ' || c == '\t')
+ p++;
+
+ nvl = strlen (p);
+ while (nvl > 0 && ((c = p[nvl - 1]) == ' ' || c == '\t'))
+ p[--nvl] = '\0';
+
+ while ((*q = *p++) != '\0') {
+ if (*q == '%') {
+ switch (*p++) {
+
+ case '\0': /* whoops - back up */
+ p--;
+ break;
+
+ case '%': /* a single percent character */
+ q++;
+ break;
+
+ case 's': /* main board serial number as string */
+ q += sprintf (q, "%010lu",
+ cp->main.eeprom.serno);
+ break;
+
+ case 'S': /* main board serial number as number */
+ q += sprintf (q, "%lu", cp->main.eeprom.serno);
+ break;
+
+ default: /* ignore any others */
+ break;
+ }
+ }
+ else
+ q++;
+ }
+
+ if ((nvl = q - nv) == 0) {
+ setenv (nn, NULL);
+ return (1);
+ }
+
+ if ((curver = getenv ("global_env_version")) == NULL)
+ curver = "unknown";
+
+ if ((newver = getenv ("new_genv_version")) == NULL || \
+ strcmp (curver, newver) == 0) {
+ if (strcmp (nn, "version") == 0)
+ setenv ("new_genv_version", nv);
+ return (1);
+ }
+
+ if ((p = getenv (nn)) != NULL) {
+
+ strcpy (ov, p);
+ ovl = strlen (ov);
+
+ if (append) {
+
+ if (strstr (ov, nv) == NULL) {
+
+ printf ("Appending '%s' to env var '%s'\n",
+ nv, nn);
+
+ while (nvl >= 0) {
+ nv[ovl + 1 + nvl] = nv[nvl];
+ nvl--;
+ }
+
+ nv[ovl] = ' ';
+
+ while (--ovl >= 0)
+ nv[ovl] = ov[ovl];
+
+ setenv (nn, nv);
+ }
+
+ return (1);
+ }
+
+ if (remove) {
+
+ if (strstr (ov, nv) != NULL) {
+
+ printf ("Removing '%s' from env var '%s'\n",
+ nv, nn);
+
+ while ((p = strstr (ov, nv)) != NULL) {
+ q = p + nvl;
+ if (*q == ' ')
+ q++;
+ strcpy(p, q);
+ }
+
+ setenv (nn, ov);
+ }
+
+ return (1);
+ }
+
+ if (!override || strcmp (ov, nv) == 0)
+ return (1);
+
+ printf ("Re-setting env cmd '%s' from '%s' to '%s'\n",
+ nn, ov, nv);
+ }
+ else
+ printf ("Setting env cmd '%s' to '%s'\n", nn, nv);
+
+ setenv (nn, nv);
+ return (1);
+}
+
+void
+hymod_check_env (void)
+{
+ char *p, *path, *curver, *newver;
+ int firsttime = 0, needsave = 0;
+
+ if (getenv ("global_env_loaded") == NULL) {
+ puts ("*** global environment has never been loaded\n");
+ puts ("*** fetching from server");
+ firsttime = 1;
+ }
+ else if ((p = getenv ("always_check_env")) != NULL &&
+ strcmp (p, "yes") == 0)
+ puts ("*** checking for updated global environment");
+ else
+ return;
+
+ puts (" (Control-C to Abort)\n");
+
+ if ((path = getenv ("global_env_path")) == NULL || *path == '\0')
+ path = def_global_env_path;
+
+ if (fetch_and_parse (path, CFG_LOAD_ADDR, env_callback) == 0) {
+ puts ("*** Fetch of global environment failed!\n");
+ return;
+ }
+
+ if ((newver = getenv ("new_genv_version")) == NULL) {
+ puts ("*** Version number not set - contents ignored!\n");
+ return;
+ }
+
+ if ((curver = getenv ("global_env_version")) == NULL || \
+ strcmp (curver, newver) != 0) {
+ setenv ("global_env_version", newver);
+ needsave = 1;
+ }
+ else
+ printf ("*** Global environment up-to-date (ver %s)\n", curver);
+
+ setenv ("new_genv_version", NULL);
+
+ if (firsttime) {
+ setenv ("global_env_loaded", "yes");
+ needsave = 1;
+ }
+
+ if (needsave)
+ puts ("\n*** Remember to run the 'saveenv' "
+ "command to save the changes\n\n");
+}
diff --git a/board/hymod/fetch.c b/board/hymod/fetch.c
new file mode 100755
index 0000000..e121d55
--- /dev/null
+++ b/board/hymod/fetch.c
@@ -0,0 +1,107 @@
+/*
+ * (C) Copyright 2001
+ * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <net.h>
+
+/* imports from input.c */
+extern int hymod_get_ethaddr (void);
+
+int
+fetch_and_parse (char *fn, ulong addr, int (*cback)(uchar *, uchar *))
+{
+ 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);
+ }
+
+ count++;
+ }
+
+ copy_filename (BootFile, fn, sizeof (BootFile));
+ load_addr = addr;
+ NetBootFileXferSize = 0;
+
+ if (NetLoop (TFTP) == 0) {
+ printf ("tftp transfer of file '%s' failed\n", fn);
+ return (0);
+ }
+
+ if (NetBootFileXferSize == 0) {
+ printf ("can't determine size of file '%s'\n", fn);
+ return (0);
+ }
+
+ fp = (uchar *)load_addr;
+ efp = fp + NetBootFileXferSize;
+
+ do {
+ uchar *name, *value;
+
+ if (*fp == '#' || *fp == '\n') {
+ /* skip this line */
+ while (fp < efp && *fp++ != '\n')
+ ;
+ continue;
+ }
+
+ name = fp;
+
+ while (fp < efp && *fp != '=' && *fp != '\n')
+ fp++;
+ if (fp >= efp)
+ break;
+ if (*fp == '\n') {
+ fp++;
+ continue;
+ }
+ *fp++ = '\0';
+
+ value = fp;
+
+ while (fp < efp && *fp != '\n')
+ fp++;
+ if (fp[-1] == '\r')
+ fp[-1] = '\0';
+ *fp++ = '\0'; /* ok if we go off the end here */
+
+ if ((*cback)(name, value) == 0)
+ return (0);
+
+ } while (fp < efp);
+
+ return (1);
+}
diff --git a/board/hymod/flash.c b/board/hymod/flash.c
new file mode 100755
index 0000000..ad0a229
--- /dev/null
+++ b/board/hymod/flash.c
@@ -0,0 +1,506 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00
+ */
+
+#include <common.h>
+#include <mpc8260.h>
+#include <board/hymod/flash.h>
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * Protection Flags:
+ */
+#define FLAG_PROTECT_SET 0x01
+#define FLAG_PROTECT_CLEAR 0x02
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * probe for flash bank at address "base" and store info about it
+ * in the flash_info entry "fip". Fatal error if nothing there.
+ */
+static void
+bank_probe (flash_info_t *fip, volatile bank_addr_t base)
+{
+ volatile bank_addr_t addr;
+ bank_word_t word;
+ int i;
+
+ /* reset the flash */
+ *base = BANK_CMD_RST;
+
+ /* put flash into read id mode */
+ *base = BANK_CMD_RD_ID;
+
+ /* check the manufacturer id - must be intel */
+ word = *BANK_REG_MAN_CODE (base);
+ if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff))
+ panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx",
+ (unsigned long)word, (unsigned long)base);
+
+ /* check the device id */
+ word = *BANK_REG_DEV_CODE (base);
+ switch (word) {
+
+ case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff):
+ fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5;
+ fip->sector_count = 32;
+ break;
+
+ case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff):
+ fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5;
+ fip->sector_count = 64;
+ break;
+
+ case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff):
+ fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A;
+ fip->sector_count = 32;
+ break;
+
+ case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff):
+ fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A;
+ fip->sector_count = 64;
+ break;
+
+ case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff):
+ fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A;
+ fip->sector_count = 128;
+ break;
+
+ default:
+ panic ("\nbad device code (0x%08lx) at addr 0x%08lx",
+ (unsigned long)word, (unsigned long)base);
+ }
+
+ if (fip->sector_count >= CFG_MAX_FLASH_SECT)
+ panic ("\ntoo many sectors (%d) in flash at address 0x%08lx",
+ fip->sector_count, (unsigned long)base);
+
+ addr = base;
+ for (i = 0; i < fip->sector_count; i++) {
+ fip->start[i] = (unsigned long)addr;
+ fip->protect[i] = 0;
+ addr = BANK_ADDR_NEXT_BLK (addr);
+ }
+
+ fip->size = (bank_size_t)addr - (bank_size_t)base;
+
+ /* reset the flash */
+ *base = BANK_CMD_RST;
+}
+
+static void
+bank_reset (flash_info_t *info, int sect)
+{
+ volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
+
+#ifdef FLASH_DEBUG
+ printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr);
+#endif
+
+ *addr = BANK_CMD_RST;
+}
+
+static void
+bank_erase_init (flash_info_t *info, int sect)
+{
+ volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
+ int flag;
+
+#ifdef FLASH_DEBUG
+ printf ("erasing sector %d, addr = 0x%08lx\n",
+ sect, (unsigned long)addr);
+#endif
+
+ /* Disable intrs which might cause a timeout here */
+ flag = disable_interrupts ();
+
+#ifdef FLASH_DEBUG
+ printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr);
+#endif
+ *addr = BANK_CMD_ERASE1;
+ *addr = BANK_CMD_ERASE2;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts ();
+}
+
+static int
+bank_erase_poll (flash_info_t *info, int sect)
+{
+ volatile 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)addr, (unsigned long)stat);
+#endif
+
+ if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) {
+ if ((stat & BANK_STAT_ERR) != 0) {
+ printf ("failed on sector %d [0x%08lx] at "
+ "address 0x%08lx\n", sect,
+ (unsigned long)stat, (unsigned long)addr);
+ *addr = BANK_CMD_CLR_STAT;
+ return (-1);
+ }
+ else
+ return (1);
+ }
+ else
+ return (0);
+}
+
+static int
+bank_write_word (volatile 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 ();
+
+ *addr = BANK_CMD_PROG;
+
+ *addr = value;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts ();
+
+ retval = 0;
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ do {
+ if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+ retval = 1;
+ goto done;
+ }
+ stat = *addr;
+ } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
+
+ if ((stat & BANK_STAT_ERR) != 0) {
+ printf ("flash program failed [0x%08lx] at address 0x%08lx\n",
+ (unsigned long)stat, (unsigned long)addr);
+ *addr = BANK_CMD_CLR_STAT;
+ retval = 3;
+ }
+
+done:
+ /* reset to read mode */
+ *addr = BANK_CMD_RST;
+
+ return (retval);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long
+flash_init (void)
+{
+ int i;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ 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,
+ 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,
+ CFG_FLASH_ENV_ADDR,
+#if defined(CFG_FLASH_ENV_BUF)
+ CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1,
+#else
+ CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_SIZE - 1,
+#endif
+ &flash_info[0]);
+#endif
+
+ return flash_info[0].size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void
+flash_print_info (flash_info_t *info)
+{
+ int i;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_INTEL: printf ("INTEL "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ 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;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf ("\n ");
+ printf (" %08lX%s",
+ info->start[i],
+ info->protect[i] ? " (RO)" : " "
+ );
+ }
+ printf ("\n");
+ return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+/*-----------------------------------------------------------------------
+ */
+
+int
+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"
+ " Bank # %d: ", s_last - s_first + 1, s_first, s_last,
+ (info - flash_info) + 1);
+ flash_print_info (info);
+#endif
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("- missing\n");
+ } else {
+ printf ("- no sectors to erase\n");
+ }
+ return 1;
+ }
+
+ prot = 0;
+ 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",
+ prot, (prot > 1 ? "s" : ""));
+ }
+
+ start = get_timer (0);
+ last = 0;
+ haderr = 0;
+
+ for (sect = s_first; sect <= s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ ulong estart;
+ int sectdone;
+
+ bank_erase_init (info, sect);
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ estart = get_timer (start);
+
+ do {
+ now = get_timer (start);
+
+ if (now - estart > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout (sect %d)\n", sect);
+ haderr = 1;
+ rcode = 1;
+ break;
+ }
+
+#ifndef FLASH_DEBUG
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+#endif
+
+ sectdone = bank_erase_poll (info, sect);
+
+ if (sectdone < 0) {
+ haderr = 1;
+ rcode = 1;
+ break;
+ }
+
+ } while (!sectdone);
+
+ if (haderr)
+ break;
+ }
+ }
+
+ if (haderr > 0)
+ printf (" failed\n");
+ else
+ printf (" done\n");
+
+ /* reset to read mode */
+ for (sect = s_first; sect <= s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ 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)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i=0, cp=wp; i<l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word (info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word (info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word (info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/hymod/flash.h b/board/hymod/flash.h
new file mode 100755
index 0000000..ee047fe
--- /dev/null
+++ b/board/hymod/flash.h
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2000
+ * 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
+ */
+
+/*************** DEFINES for Intel StrataFlash FLASH chip ********************/
+
+/* Commands */
+#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 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 ******************************/
+
+/*
+ * 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;
+typedef bank_word_t bank_blk_t[64 * 1024];
+
+#define BANK_FILL_WORD(b) (((bank_word_t)(b) << 16) | (bank_word_t)(b))
+
+#ifdef EXAMPLE
+
+/* theoretically the following examples should also work */
+
+/* one flash chip in x8 mode with 128Kword sectors and 8bit bus */
+typedef unsigned char bank_word_t;
+typedef bank_word_t bank_blk_t[128 * 1024];
+#define BANK_FILL_WORD(b) ((bank_word_t)(b))
+
+/* four flash chips in x16 mode with 32Kword sectors and 64bit bus */
+typedef unsigned long long bank_word_t;
+typedef bank_word_t bank_blk_t[32 * 1024];
+#define BANK_FILL_WORD(b) ( \
+ ((bank_word_t)(b) << 48) \
+ ((bank_word_t)(b) << 32) \
+ ((bank_word_t)(b) << 16) \
+ ((bank_word_t)(b) << 0) \
+ )
+
+#endif /* EXAMPLE */
+
+/* the sizes of these two types should probably be the same */
+typedef 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) \
+ & ~(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) \
+ & ~(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)))
+
+/* 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), \
+ sizeof (bank_word_t))
+#define BANK_ADDR_NEXT_BLK(a) BANK_ADDR_OFFSET(BANK_ADDR_BLK_ALIGN(a), \
+ sizeof (bank_blk_t))
+
+/* 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 StrataFlash value */
+
+/* Commands */
+#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(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)
diff --git a/board/hymod/global_env b/board/hymod/global_env
new file mode 100755
index 0000000..f61d080
--- /dev/null
+++ b/board/hymod/global_env
@@ -0,0 +1,161 @@
+# 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
+# 2. all other lines must have the form <name>=<value>
+# 3. if a percent appears anywhere, it is replaced like so:
+#
+# %s serial number of the main board (10 digit zero filled)
+# %S serial number of the main board (plain number)
+# %% a percentage character
+# ... 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). 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 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=4
+
+# 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 (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
+
+# 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/mtdblock5 rootfstype=squashfs ro
+
+# these four are for hymod linux integrated 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
+#
+# Sector(s) Address Size Description
+#
+# 0 - 0 0x40000000 256K boot code
+# 1 - 1 0x40040000 256K non volatile environment
+# 2 - 4 0x40080000 768K linux kernel image
+# 5 - 7 0x40140000 768K alternate linux kernel image
+# 8 - 47 0x40200000 10M linux initial ramdisk image
+# 48 - 63 0x40c00000 4M ramdisk image for applications
+#
+
+fetchboot=tftp 100000 /hymod/u-boot.bin
+eraseboot=protect off 1:0 ; erase 1:0 ; protect on 1:0
+copyboot=protect off 1:0 ; cp.b 100000 40000000 40000 ; protect on 1:0
+cmpboot=cmp.b 100000 40000000 40000
+newboot=run fetchboot eraseboot copyboot cmpboot
+
+fetchlinux=tftp 100000 /hymod/linux.bin
+eraselinux=erase 1:2-4
+copylinux=cp.b 100000 40080000 ${filesize}
+cmplinux=cmp.b 100000 40080000 ${filesize}
+newlinux=run fetchlinux eraselinux copylinux cmplinux
+
+fetchaltlinux=tftp 100000 /hymod/altlinux.bin
+erasealtlinux=erase 1:5-7
+copyaltlinux=cp.b 100000 40140000 ${filesize}
+cmpaltlinux=cmp.b 100000 40140000 ${filesize}
+newaltlinux=run fetchaltlinux erasealtlinux copyaltlinux cmpaltlinux
+
+fetchroot=tftp 100000 /hymod/root.bin
+eraseroot=erase 1:8-47
+copyroot=cp.b 100000 40200000 ${filesize}
+cmproot=cmp.b 100000 40200000 ${filesize}
+newroot=run fetchroot eraseroot copyroot cmproot
+
+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
+
+# pass above map to linux mtd driver
+bootargs+=mtdparts=phys:256k(u-boot),256k(u-boot-env),768k(linux),768k(altlinux),10m(root),4m(hymod)
diff --git a/board/hymod/hymod.c b/board/hymod/hymod.c
new file mode 100755
index 0000000..dea0a70
--- /dev/null
+++ b/board/hymod/hymod.c
@@ -0,0 +1,537 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ * 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 hymod_eeprom_read (int, hymod_eeprom_t *);
+extern void hymod_eeprom_print (hymod_eeprom_t *);
+
+/* imports from env.c */
+extern void hymod_check_env (void);
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * I/O Port configuration table
+ *
+ * if conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+ /* Port A configuration */
+ {
+ /* 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 */
+ {
+ /* 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 */
+ }
+};
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * AMI FS6377 Clock Generator configuration table
+ *
+ * the "fs6377_regs[]" table entries correspond to FS6377 registers
+ * 0 - 15 (total of 16 bytes).
+ *
+ * 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
+};
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * special board initialisation, after clocks and timebase have been
+ * set up but before environment and serial are initialised.
+ *
+ * added so that very early initialisations can be done using the i2c
+ * driver (which requires the clocks, to calculate the dividers, and
+ * the timebase, for udelay())
+ */
+
+int
+board_postclk_init (void)
+{
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ /*
+ * Initialise the FS6377 clock chip
+ *
+ * the secondary address is the register number from where to
+ * start the write - I want to write all the registers
+ *
+ * don't bother checking return status - we have no console yet
+ * to print it on, nor any RAM to store it in - it will be obvious
+ * if this doesn't work
+ */
+ (void) i2c_write (fs6377_addr, 0, 1, fs6377_regs,
+ sizeof (fs6377_regs));
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity: Hardwired to HYMOD
+ */
+
+int
+checkboard (void)
+{
+ puts ("Board: HYMOD\n");
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * miscellaneous (early - while running in flash) initialisations.
+ */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+uint upmb_table[] = {
+ /* Read Single Beat (RSS) - offset 0x00 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Read Burst (RBS) - offset 0x08 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Single Beat (WSS) - offset 0x18 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Burst (WSS) - offset 0x20 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Refresh Timer (PTS) - offset 0x30 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Exception Condition (EXS) - offset 0x3c */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_
+};
+
+uint upmc_table[] = {
+ /* Read Single Beat (RSS) - offset 0x00 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Read Burst (RBS) - offset 0x08 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Single Beat (WSS) - offset 0x18 */
+ 0xF0E00000, 0xF0A00000, 0x00A00000, 0x30A00000,
+ 0xF0F40007, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Burst (WSS) - offset 0x20 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Refresh Timer (PTS) - offset 0x30 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Exception Condition (EXS) - offset 0x3c */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_
+};
+
+int
+misc_init_f (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+
+ printf ("UPMs: ");
+
+ upmconfig (UPMB, upmb_table, sizeof upmb_table / sizeof upmb_table[0]);
+ memctl->memc_mbmr = CFG_MBMR;
+
+ upmconfig (UPMC, upmc_table, sizeof upmc_table / sizeof upmc_table[0]);
+ memctl->memc_mcmr = CFG_MCMR;
+
+ printf ("configured\n");
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long
+initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+ volatile uchar c = 0, *ramaddr = (uchar *) (CFG_SDRAM_BASE + 0x8);
+ ulong psdmr = CFG_PSDMR;
+ int i;
+
+ /*
+ * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
+ *
+ * "At system reset, initialization software must set up the
+ * programmable parameters in the memory controller banks registers
+ * (ORx, BRx, P/LSDMR). After all memory parameters are coñgured,
+ * system software should execute the following initialization sequence
+ * for each SDRAM device.
+ *
+ * 1. Issue a PRECHARGE-ALL-BANKS command
+ * 2. Issue eight CBR REFRESH commands
+ * 3. Issue a MODE-SET command to initialize the mode register
+ *
+ * The initial commands are executed by setting P/LSDMR[OP] and
+ * accessing the SDRAM with a single-byte transaction."
+ *
+ * The appropriate BRx/ORx registers have already been set when we
+ * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
+ */
+
+ memctl->memc_psrt = CFG_PSRT;
+ memctl->memc_mptpr = CFG_MPTPR;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
+ *ramaddr = c;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
+ for (i = 0; i < 8; i++)
+ *ramaddr = c;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
+ *ramaddr = c;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
+ *ramaddr = c;
+
+ return (CFG_SDRAM_SIZE << 20);
+}
+
+/* ------------------------------------------------------------------------- */
+/* miscellaneous initialisations after relocation into ram (misc_init_r) */
+/* */
+/* loads the data in the main board and mezzanine board eeproms into */
+/* the hymod configuration struct stored in the board information area. */
+/* */
+/* if the contents of either eeprom is invalid, prompts for a serial */
+/* number (and an ethernet address if required) then fetches a file */
+/* 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) */
+
+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 */
+
+ 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.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
+
+ cp->main.xlx[0].irq = FPGA_MAIN_IRQ;
+ }
+
+ /* set up mezzanine board config info */
+
+ rc = hymod_eeprom_read (1, &cp->mezz.eeprom);
+
+ puts ("EEPROM:mezz...");
+ 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->mezz.eeprom.ver);
+ hymod_eeprom_print (&cp->mezz.eeprom);
+ }
+
+ cp->crc = crc32 (0, (unsigned char *)cp, offsetof (hymod_conf_t, crc));
+
+ hymod_check_env ();
+
+ return (0);
+}
+
+#ifdef CONFIG_SHOW_ACTIVITY
+void board_show_activity (ulong timebase)
+{
+#ifdef CFG_HYMOD_DBLEDS
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile iop8260_t *iop = &immr->im_ioport;
+ static int shift = 0;
+
+ if ((timestamp % CFG_HZ) == 0) {
+ if (++shift > 3)
+ shift = 0;
+ iop->iop_pdatd =
+ (iop->iop_pdatd & ~0x0f000000) | (1 << (24 + shift));
+ }
+#endif /* CFG_HYMOD_DBLEDS */
+}
+
+void show_activity(int arg)
+{
+}
+#endif /* CONFIG_SHOW_ACTIVITY */
diff --git a/board/hymod/hymod.h b/board/hymod/hymod.h
new file mode 100755
index 0000000..9d8d662
--- /dev/null
+++ b/board/hymod/hymod.h
@@ -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 100755
index 0000000..63aa13c
--- /dev/null
+++ b/board/hymod/input.c
@@ -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);
+ }
+}
diff --git a/board/hymod/u-boot.lds b/board/hymod/u-boot.lds
new file mode 100755
index 0000000..337a395
--- /dev/null
+++ b/board/hymod/u-boot.lds
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector layout of our flash chips! XXX FIXME XXX */
+
+ cpu/mpc8260/start.o (.text)
+/*
+ common/dlmalloc.o (.text)
+ lib_ppc/ppcstring.o (.text)
+ lib_generic/vsprintf.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_generic/zlib.o (.text)
+
+ . = env_offset;
+*/
+ common/environment.o(.text)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(256 * 1024);
+ .ppcenv :
+ {
+ common/environment.o (.ppcenv)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/hymod/u-boot.lds.debug b/board/hymod/u-boot.lds.debug
new file mode 100755
index 0000000..ddd4678
--- /dev/null
+++ b/board/hymod/u-boot.lds.debug
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector layout of our flash chips! XXX FIXME XXX */
+
+ cpu/mpc8xx/start.o (.text)
+ common/dlmalloc.o (.text)
+ lib_generic/vsprintf.o (.text)
+ lib_generic/crc32.o (.text)
+
+ . = env_offset;
+ common/environment.o(.text)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}