diff options
author | wdenk <wdenk> | 2003-06-19 23:40:20 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2003-06-19 23:40:20 +0000 |
commit | 6dd652fa4d8591a32e2707a91f4582ed13011b17 (patch) | |
tree | 52d7c375a3a33d634e7c30908a75bf9616d92854 /board | |
parent | 52f52c1494eedaeacccad6e2331f4f638b48f5ab (diff) | |
download | u-boot-imx-6dd652fa4d8591a32e2707a91f4582ed13011b17.zip u-boot-imx-6dd652fa4d8591a32e2707a91f4582ed13011b17.tar.gz u-boot-imx-6dd652fa4d8591a32e2707a91f4582ed13011b17.tar.bz2 |
Patches by Murray Jensen, 17 Jun 2003:
- Hymod board database mods: add "who" field and new xilinx chip types
- provide new "init_cmd_timeout()" function so code external to
"common/main.c" can use the "reset_cmd_timeout()" function before
entering the main loop
- add DTT support for adm1021 (new file dtt/adm1021.c; config
slightly different. see include/configs/hymod.h for an example
(requires CONFIG_DTT_ADM1021, CONFIG_DTT_SENSORS, and
CFG_DTT_ADM1021 defined)
- add new "eeprom_probe()" function which has similar args and
behaves in a similar way to "eeprom_read()" etc.
- add 8260 FCC ethernet loopback code (new "eth_loopback_test()"
function which is enabled by defining CONFIG_ETHER_LOOPBACK_TEST)
- gdbtools copyright update
- ensure that set_msr() executes the "sync" and "isync" instructions
after the "mtmsr" instruction in cpu/mpc8260/interrupts.c
- 8260 I/O ports fix: Open Drain should be set last when configuring
- add SIU IRQ defines for 8260
- allow LDSCRIPT override and OBJCFLAGS initialization: change to
config.mk to allow board configurations to override the GNU
linker script, selected via the LDSCRIPT, make variable, and to
give an initial value to the OBJCFLAGS make variable
- 8260 i2c enhancement:
o correctly extends the timeout depending on the size of all
queued messages for both transmit and receive
o will not continue with receive if transmit times out
o ensures that the error callback is done for all queued tx
and rx messages
o correctly detects both tx and rx timeouts, only delivers one to
the callback, and does not overwrite an earlier error
o logic in i2c_probe now correct
- add "vprintf()" function so that "panic()" function can be
technically correct
- many Hymod board changes
Diffstat (limited to 'board')
-rw-r--r-- | board/hymod/Makefile | 2 | ||||
-rw-r--r-- | board/hymod/bsp.c | 174 | ||||
-rw-r--r-- | board/hymod/config.mk | 2 | ||||
-rw-r--r-- | board/hymod/eeprom.c | 1002 | ||||
-rw-r--r-- | board/hymod/env.c | 236 | ||||
-rw-r--r-- | board/hymod/fetch.c | 157 | ||||
-rw-r--r-- | board/hymod/flash.c | 509 | ||||
-rw-r--r-- | board/hymod/flash.h | 249 | ||||
-rw-r--r-- | board/hymod/global_env | 133 | ||||
-rw-r--r-- | board/hymod/hymod.c | 791 | ||||
-rw-r--r-- | board/hymod/hymod.h | 322 | ||||
-rw-r--r-- | board/hymod/input.c | 113 |
12 files changed, 2021 insertions, 1669 deletions
diff --git a/board/hymod/Makefile b/board/hymod/Makefile index 1804b3c..4d3097c 100644 --- a/board/hymod/Makefile +++ b/board/hymod/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = lib$(BOARD).a -OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o +OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o input.o env.o $(LIB): .depend $(OBJS) $(AR) crv $@ $^ diff --git a/board/hymod/bsp.c b/board/hymod/bsp.c index 2ceaeb5..02b6421 100644 --- a/board/hymod/bsp.c +++ b/board/hymod/bsp.c @@ -20,13 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * hacked for Hymod FPGA support by Murray.Jensen@cmst.csiro.au, 29-Jan-01 + * hacked for Hymod FPGA support by Murray.Jensen@csiro.au, 29-Jan-01 */ #include <common.h> #include <command.h> #include <net.h> -#include <i2c.h> #include <asm/iopin_8260.h> #include <cmd_bsp.h> @@ -74,28 +73,29 @@ * has not worked (wait several ms?) */ -int fpga_load (int mezz, uchar * addr, ulong size) +int +fpga_load (int mezz, uchar *addr, ulong size) { DECLARE_GLOBAL_DATA_PTR; hymod_conf_t *cp = &gd->bd->bi_hymod_conf; + xlx_info_t *fp; xlx_iopins_t *fpgaio; volatile uchar *fpgabase; volatile uint cnt; uchar *eaddr = addr + size; int result; - if (mezz) { - if (!cp->mezz.mmap[0].prog.exists) - return (LOAD_FAIL_NOCONF); - fpgabase = (uchar *) cp->mezz.mmap[0].prog.base; - fpgaio = &cp->mezz.iopins[0]; - } else { - if (!cp->main.mmap[0].prog.exists) - return (LOAD_FAIL_NOCONF); - fpgabase = (uchar *) cp->main.mmap[0].prog.base; - fpgaio = &cp->main.iopins[0]; - } + if (mezz) + fp = &cp->mezz.xlx[0]; + else + fp = &cp->main.xlx[0]; + + if (!fp->mmap.prog.exists) + return (LOAD_FAIL_NOCONF); + + fpgabase = (uchar *)fp->mmap.prog.base; + fpgaio = &fp->iopins; /* set enable HIGH if required */ if (fpgaio->enable_pin.flag) @@ -106,7 +106,7 @@ int fpga_load (int mezz, uchar * addr, ulong size) /* toggle PROG Low then High (will already be Low after Power-On) */ iopin_set_low (&fpgaio->prog_pin); - udelay (1); /* minimum 300ns - 1usec should do it */ + udelay (1); /* minimum 300ns - 1usec should do it */ iopin_set_high (&fpgaio->prog_pin); /* wait for INIT High */ @@ -157,15 +157,15 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) case 2: if (strcmp (argv[1], "info") == 0) { printf ("\nHymod FPGA Info...\n"); - printf (" Address Size\n"); - printf (" Main Configuration: 0x%08x %d\n", - FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE); - printf (" Main Register: 0x%08x %d\n", - FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE); - printf (" Main Port: 0x%08x %d\n", - FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE); - printf (" Mezz Configuration: 0x%08x %d\n", - FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE); + printf ("\t\t\t\tAddress\t\tSize\n"); + printf ("\tMain Configuration:\t0x%08x\t%d\n", + FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE); + printf ("\tMain Register:\t\t0x%08x\t%d\n", + FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE); + printf ("\tMain Port:\t\t0x%08x\t%d\n", + FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE); + printf ("\tMezz Configuration:\t0x%08x\t%d\n", + FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE); return 0; } break; @@ -176,18 +176,21 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) save_addr = addr; #if 0 - /* reading config data unimplemented */ - while VM - :more config data * addr++ = *fpga; - result = VM:? ? ? + /* fpga readback unimplemented */ + while (more readback data) + *addr++ = *fpga; + result = error ? STORE_FAIL_XXX : STORE_SUCCESS; #else - result = 0; + result = STORE_SUCCESS; #endif + if (result == STORE_SUCCESS) { - printf ("SUCCEEDED (%d bytes)\n", addr - save_addr); + printf ("SUCCEEDED (%d bytes)\n", + addr - save_addr); return 0; } else - printf ("FAILED (%d bytes)\n", addr - save_addr); + printf ("FAILED (%d bytes)\n", + addr - save_addr); return 1; } break; @@ -196,25 +199,32 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strcmp (argv[1], "tftp") == 0) { copy_filename (BootFile, argv[2], sizeof (BootFile)); load_addr = simple_strtoul (argv[3], NULL, 16); + NetBootFileXferSize = 0; if (NetLoop (TFTP) <= 0) { - printf ("tftp transfer failed - aborting fgpa load\n"); + printf ("tftp transfer failed - aborting " + "fgpa load\n"); return 1; } if (NetBootFileXferSize == 0) { - printf ("can't determine file size - aborting fpga load\n"); + printf ("can't determine file size - " + "aborting fpga load\n"); return 1; } - printf ("File transfer succeeded - beginning fpga load..."); + printf ("File transfer succeeded - " + "beginning fpga load..."); result = fpga_load (0, (uchar *) load_addr, - NetBootFileXferSize); + NetBootFileXferSize); + if (result == LOAD_SUCCESS) { printf ("SUCCEEDED\n"); return 0; - } else if (result == LOAD_FAIL_NOINIT) + } else if (result == LOAD_FAIL_NOCONF) + printf ("FAILED (no CONF)\n"); + else if (result == LOAD_FAIL_NOINIT) printf ("FAILED (no INIT)\n"); else printf ("FAILED (no DONE)\n"); @@ -231,7 +241,8 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else if (strcmp (argv[2], "mezz") == 0) mezz = 1; else { - printf ("FPGA type must be either `main' or `mezz'\n"); + printf ("FPGA type must be either " + "`main' or `mezz'\n"); return 1; } arg = 3; @@ -239,14 +250,18 @@ do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) mezz = 0; arg = 2; } + addr = (uchar *) simple_strtoul (argv[arg++], NULL, 16); size = (ulong) simple_strtoul (argv[arg], NULL, 16); result = fpga_load (mezz, addr, size); + if (result == LOAD_SUCCESS) { printf ("SUCCEEDED\n"); return 0; - } else if (result == LOAD_FAIL_NOINIT) + } else if (result == LOAD_FAIL_NOCONF) + printf ("FAILED (no CONF)\n"); + else if (result == LOAD_FAIL_NOINIT) printf ("FAILED (no INIT)\n"); else printf ("FAILED (no DONE)\n"); @@ -267,22 +282,21 @@ int do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { uchar data[HYMOD_EEPROM_SIZE]; - uint offset; - int rcode = 0; + uint addr = CFG_I2C_EEPROM_ADDR; switch (argc) { case 1: - offset = HYMOD_EEOFF_MAIN; + addr |= HYMOD_EEOFF_MAIN; break; case 2: if (strcmp (argv[1], "main") == 0) { - offset = HYMOD_EEOFF_MAIN; + addr |= HYMOD_EEOFF_MAIN; break; } if (strcmp (argv[1], "mezz") == 0) { - offset = HYMOD_EEOFF_MEZZ; + addr |= HYMOD_EEOFF_MEZZ; break; } /* fall through ... */ @@ -293,15 +307,77 @@ do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } memset (data, 0, HYMOD_EEPROM_SIZE); - if (i2c_write - (CFG_I2C_EEPROM_ADDR | offset, 0, CFG_I2C_EEPROM_ADDR_LEN, data, - HYMOD_EEPROM_SIZE)) { - rcode = 1; + + eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +#if 0 +static uchar test_bitfile[] = { + /* one day ... */ +}; +#endif + +int +do_htest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +#if 0 + int rc; +#endif +#ifdef CONFIG_ETHER_LOOPBACK_TEST + extern void eth_loopback_test (void); +#endif /* CONFIG_ETHER_LOOPBACK_TEST */ + + printf ("HYMOD tests - ensure loopbacks etc. are connected\n\n"); + +#if 0 + /* Load FPGA with test program */ + + printf ("Loading test FPGA program ..."); + + rc = fpga_load (0, test_bitfile, sizeof (test_bitfile)); + + switch (rc) { + + case LOAD_SUCCESS: + printf (" SUCCEEDED\n"); + break; + + case LOAD_FAIL_NOCONF: + printf (" FAILED (no configuration space defined)\n"); + return 1; + + case LOAD_FAIL_NOINIT: + printf (" FAILED (timeout - no INIT signal seen)\n"); + return 1; + + case LOAD_FAIL_NODONE: + printf (" FAILED (timeout - no DONE signal seen)\n"); + return 1; + + default: + printf (" FAILED (unknown return code from fpga_load\n"); + return 1; } - return rcode; + /* run Local Bus <=> Xilinx tests */ + + /* tell Xilinx to run ZBT Ram, High Speed serial and Mezzanine tests */ + + /* run SDRAM test */ +#endif + +#ifdef CONFIG_ETHER_LOOPBACK_TEST + /* run Ethernet test */ + eth_loopback_test (); +#endif /* CONFIG_ETHER_LOOPBACK_TEST */ + + return 0; } -#endif /* CFG_CMD_BSP */ +#endif /* CFG_CMD_BSP */ /* ------------------------------------------------------------------------- */ diff --git a/board/hymod/config.mk b/board/hymod/config.mk index 52c3183..ccc7f38 100644 --- a/board/hymod/config.mk +++ b/board/hymod/config.mk @@ -29,4 +29,4 @@ TEXT_BASE = 0x40000000 PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR) -OBJCFLAGS = --set-section-flags=.ppcenv=contents,alloc,load,data +OBJCFLAGS = --remove-section=.ppcenv diff --git a/board/hymod/eeprom.c b/board/hymod/eeprom.c index 9d50646..01e1453 100644 --- a/board/hymod/eeprom.c +++ b/board/hymod/eeprom.c @@ -1,7 +1,6 @@ /* * (C) Copyright 2001 - * Murray Jensen, CSIRO Manufacturing Science and Technology, - * <Murray.Jensen@cmst.csiro.au> + * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au> * * See file CREDITS for list of people who contributed to this * project. @@ -26,396 +25,408 @@ #include <mpc8260.h> /* imports from fetch.c */ -extern int fetch_and_parse(bd_t *, char *, ulong, int (*)(uchar *, uchar *)); +extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); -int -eeprom_load(unsigned offset, hymod_eeprom_t *ep) -{ - uchar data[HYMOD_EEPROM_SIZE], *dp, *edp; - hymod_eehdr_t *hp; - ulong len, crc; - - memset(ep, 0, sizeof *ep); - memset(data, 0, HYMOD_EEPROM_SIZE); - crc = 0; - - hp = (hymod_eehdr_t *)data; - eeprom_read(CFG_DEF_EEPROM_ADDR, offset, (uchar *)hp, sizeof (*hp)); - offset += sizeof (*hp); - - if (hp->id != HYMOD_EEPROM_ID || hp->ver > HYMOD_EEPROM_VER || - (len = hp->len) > HYMOD_EEPROM_MAXLEN) - return (0); - - dp = (uchar *)(hp + 1); edp = dp + len; - eeprom_read(CFG_DEF_EEPROM_ADDR, offset, dp, len); - offset += len; - - eeprom_read(CFG_DEF_EEPROM_ADDR, offset, (uchar *)&crc, sizeof (ulong)); - - if (crc32(0, data, edp - data) != crc) - return (0); - - ep->ver = hp->ver; +/* imports from input.c */ +extern int hymod_get_serno (const char *); - for (;;) { - hymod_eerec_t *rp = (hymod_eerec_t *)dp; - ulong rtyp; - uchar rlen, *rdat; - uint rsiz; +/* this is relative to the root of the server's tftp directory */ +static char *def_bddb_cfgdir = "/hymod/bddb"; - if (rp->small.topbit == 0) { - rtyp = rp->small.type; - rlen = rp->small.len; - rdat = rp->small.data; - rsiz = offsetof(hymod_eerec_t, small.data) + rlen; - } - else if (rp->medium.nxtbit == 0) { - rtyp = rp->medium.type; - rlen = rp->medium.len; - rdat = rp->medium.data; - rsiz = offsetof(hymod_eerec_t, medium.data) + rlen; - } - else { - rtyp = rp->large.type; - rlen = rp->large.len; - rdat = rp->large.data; - rsiz = offsetof(hymod_eerec_t, large.data) + rlen; - } +static int +hymod_eeprom_load (int which, hymod_eeprom_t *ep) +{ + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + unsigned offset = 0; + uchar data[HYMOD_EEPROM_SIZE], *dp, *edp; + hymod_eehdr_t *hp; + ulong len, crc; + + memset (ep, 0, sizeof *ep); + memset (data, 0, HYMOD_EEPROM_SIZE); + crc = 0; + + hp = (hymod_eehdr_t *)data; + eeprom_read (dev_addr, offset, (uchar *)hp, sizeof (*hp)); + offset += sizeof (*hp); + + if (hp->id != HYMOD_EEPROM_ID || hp->ver > HYMOD_EEPROM_VER || + (len = hp->len) > HYMOD_EEPROM_MAXLEN) + return (0); + + dp = (uchar *)(hp + 1); edp = dp + len; + eeprom_read (dev_addr, offset, dp, len); + offset += len; + + eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong)); + + if (crc32 (0, data, edp - data) != crc) + return (0); + + ep->ver = hp->ver; + + for (;;) { + hymod_eerec_t *rp = (hymod_eerec_t *)dp; + ulong rtyp; + uchar rlen, *rdat; + uint rsiz; + + if (rp->small.topbit == 0) { + rtyp = rp->small.type; + rlen = rp->small.len; + rdat = rp->small.data; + rsiz = offsetof (hymod_eerec_t, small.data) + rlen; + } + else if (rp->medium.nxtbit == 0) { + rtyp = rp->medium.type; + rlen = rp->medium.len; + rdat = rp->medium.data; + rsiz = offsetof (hymod_eerec_t, medium.data) + rlen; + } + else { + rtyp = rp->large.type; + rlen = rp->large.len; + rdat = rp->large.data; + rsiz = offsetof (hymod_eerec_t, large.data) + rlen; + } - if (rtyp == 0) - break; - - dp += rsiz; - if (dp > edp) /* error? */ - break; - - switch (rtyp) { - - case HYMOD_EEREC_SERNO: /* serial number */ - if (rlen == sizeof (ulong)) - memcpy(&ep->serno, rdat, sizeof (ulong)); - break; - - case HYMOD_EEREC_DATE: /* date */ - if (rlen == sizeof (hymod_date_t)) - memcpy(&ep->date, rdat, sizeof (hymod_date_t)); - break; - - case HYMOD_EEREC_BATCH: /* batch */ - if (rlen <= HYMOD_MAX_BATCH) - memcpy(ep->batch, rdat, ep->batchlen = rlen); - break; - - case HYMOD_EEREC_TYPE: /* board type */ - if (rlen == 1) - ep->bdtype = *rdat; - break; - - case HYMOD_EEREC_REV: /* board revision */ - if (rlen == 1) - ep->bdrev = *rdat; - break; - - case HYMOD_EEREC_SDRAM: /* sdram size(s) */ - if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) { - int i; - - for (i = 0; i < rlen; i++) - ep->sdramsz[i] = rdat[i]; - ep->nsdram = rlen; - } - break; - - case HYMOD_EEREC_FLASH: /* flash size(s) */ - if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) { - int i; - - for (i = 0; i < rlen; i++) - ep->flashsz[i] = rdat[i]; - ep->nflash = rlen; - } - break; - - case HYMOD_EEREC_ZBT: /* zbt ram size(s) */ - if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) { - int i; - - for (i = 0; i < rlen; i++) - ep->zbtsz[i] = rdat[i]; - ep->nzbt = rlen; - } - break; - - case HYMOD_EEREC_XLXTYP: /* xilinx fpga type(s) */ - if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { - int i; - - for (i = 0; i < rlen; i++) - ep->xlx[i].type = rdat[i]; - ep->nxlx = rlen; - } - break; - - case HYMOD_EEREC_XLXSPD: /* xilinx fpga speed(s) */ - if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { - int i; - - for (i = 0; i < rlen; i++) - ep->xlx[i].speed = rdat[i]; - } - break; - - case HYMOD_EEREC_XLXTMP: /* xilinx fpga temperature(s) */ - if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { - int i; - - for (i = 0; i < rlen; i++) - ep->xlx[i].temp = rdat[i]; - } - break; - - case HYMOD_EEREC_XLXGRD: /* xilinx fpga grade(s) */ - if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { - int i; - - for (i = 0; i < rlen; i++) - ep->xlx[i].grade = rdat[i]; - } - break; - - case HYMOD_EEREC_CPUTYP: /* CPU type */ - if (rlen == 1) - ep->mpc.type = *rdat; - break; - - case HYMOD_EEREC_CPUSPD: /* CPU speed */ - if (rlen == 1) - ep->mpc.cpuspd = *rdat; - break; - - case HYMOD_EEREC_CPMSPD: /* CPM speed */ - if (rlen == 1) - ep->mpc.cpmspd = *rdat; - break; - - case HYMOD_EEREC_BUSSPD: /* bus speed */ - if (rlen == 1) - ep->mpc.busspd = *rdat; - break; - - case HYMOD_EEREC_HSTYPE: /* high-speed serial chip type */ - if (rlen == 1) - ep->hss.type = *rdat; - break; - - case HYMOD_EEREC_HSCHIN: /* high-speed serial input channels */ - if (rlen == 1) - ep->hss.nchin = *rdat; - break; - - case HYMOD_EEREC_HSCHOUT: /* high-speed serial output channels */ - if (rlen == 1) - ep->hss.nchout = *rdat; - break; - - default: /* ignore */ - break; + if (rtyp == 0) + break; + + dp += rsiz; + if (dp > edp) /* error? */ + break; + + switch (rtyp) { + + case HYMOD_EEREC_SERNO: /* serial number */ + if (rlen == sizeof (ulong)) + memcpy (&ep->serno, rdat, sizeof (ulong)); + break; + + case HYMOD_EEREC_DATE: /* date */ + if (rlen == sizeof (hymod_date_t)) + memcpy (&ep->date, rdat, sizeof (hymod_date_t)); + break; + + case HYMOD_EEREC_BATCH: /* batch */ + if (rlen <= HYMOD_MAX_BATCH) + memcpy (ep->batch, rdat, ep->batchlen = rlen); + break; + + case HYMOD_EEREC_TYPE: /* board type */ + if (rlen == 1) + ep->bdtype = *rdat; + break; + + case HYMOD_EEREC_REV: /* board revision */ + if (rlen == 1) + ep->bdrev = *rdat; + break; + + case HYMOD_EEREC_SDRAM: /* sdram size(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) { + int i; + + for (i = 0; i < rlen; i++) + ep->sdramsz[i] = rdat[i]; + ep->nsdram = rlen; + } + break; + + case HYMOD_EEREC_FLASH: /* flash size(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) { + int i; + + for (i = 0; i < rlen; i++) + ep->flashsz[i] = rdat[i]; + ep->nflash = rlen; + } + break; + + case HYMOD_EEREC_ZBT: /* zbt ram size(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) { + int i; + + for (i = 0; i < rlen; i++) + ep->zbtsz[i] = rdat[i]; + ep->nzbt = rlen; + } + break; + + case HYMOD_EEREC_XLXTYP: /* xilinx fpga type(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].type = rdat[i]; + ep->nxlx = rlen; + } + break; + + case HYMOD_EEREC_XLXSPD: /* xilinx fpga speed(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].speed = rdat[i]; + } + break; + + case HYMOD_EEREC_XLXTMP: /* xilinx fpga temperature(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].temp = rdat[i]; + } + break; + + case HYMOD_EEREC_XLXGRD: /* xilinx fpga grade(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].grade = rdat[i]; + } + break; + + case HYMOD_EEREC_CPUTYP: /* CPU type */ + if (rlen == 1) + ep->mpc.type = *rdat; + break; + + case HYMOD_EEREC_CPUSPD: /* CPU speed */ + if (rlen == 1) + ep->mpc.cpuspd = *rdat; + break; + + case HYMOD_EEREC_CPMSPD: /* CPM speed */ + if (rlen == 1) + ep->mpc.cpmspd = *rdat; + break; + + case HYMOD_EEREC_BUSSPD: /* bus speed */ + if (rlen == 1) + ep->mpc.busspd = *rdat; + break; + + case HYMOD_EEREC_HSTYPE: /* hs-serial chip type */ + if (rlen == 1) + ep->hss.type = *rdat; + break; + + case HYMOD_EEREC_HSCHIN: /* num hs-serial input chans */ + if (rlen == 1) + ep->hss.nchin = *rdat; + break; + + case HYMOD_EEREC_HSCHOUT: /* num hs-serial output chans */ + if (rlen == 1) + ep->hss.nchout = *rdat; + break; + + default: /* ignore */ + break; + } } - } - return (1); + return (1); } /* maps an ascii "name=value" into a binary eeprom data record */ typedef - struct _eerec_map { - char *name; - uint type; - uchar *(*handler)(struct _eerec_map *, uchar *, uchar *, uchar *); - uint length; - uint maxlen; - } + struct _eerec_map { + char *name; + uint type; + uchar *(*handler) \ + (struct _eerec_map *, uchar *, uchar *, uchar *); + uint length; + uint maxlen; + } eerec_map_t; static uchar * -uint_handler(eerec_map_t *rp, uchar *value, uchar *dp, uchar *edp) +uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - uchar *eval; - union { - uchar cval[4]; - ushort sval[2]; - ulong lval; - } rdata; - - rdata.lval = simple_strtol(value, (char **)&eval, 10); - - if (eval == value || *eval != '\0') { - printf("%s record (%s) is not a valid uint\n", rp->name, value); - return (NULL); - } - - if (dp + 2 + rp->length > edp) { - printf("can't fit %s record into eeprom\n", rp->name); - return (NULL); - } - - *dp++ = rp->type; - *dp++ = rp->length; - - switch (rp->length) { - - case 1: - if (rdata.lval >= 256) { - printf("%s record value (%lu) out of range (0-255)\n", - rp->name, rdata.lval); - return (NULL); + uchar *eval; + union { + uchar cval[4]; + ushort sval[2]; + ulong lval; + } rdata; + + rdata.lval = simple_strtol (val, (char **)&eval, 10); + + if (eval == val || *eval != '\0') { + printf ("%s rec (%s) is not a valid uint\n", + rp->name, val); + return (NULL); } - *dp++ = rdata.cval[3]; - break; - - case 2: - if (rdata.lval >= 65536) { - printf("%s record value (%lu) out of range (0-65535)\n", - rp->name, rdata.lval); - return (NULL); + + if (dp + 2 + rp->length > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); } - memcpy(dp, &rdata.sval[1], 2); - dp += 2; - break; - case 4: - memcpy(dp, &rdata.lval, 4); - dp += 4; - break; + *dp++ = rp->type; + *dp++ = rp->length; + + switch (rp->length) { - default: - printf("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length); - return (NULL); - } + case 1: + if (rdata.lval >= 256) { + printf ("%s rec value (%lu) out of range (0-255)\n", + rp->name, rdata.lval); + return (NULL); + } + *dp++ = rdata.cval[3]; + break; + + case 2: + if (rdata.lval >= 65536) { + printf ("%s rec value (%lu) out of range (0-65535)\n", + rp->name, rdata.lval); + return (NULL); + } + memcpy (dp, &rdata.sval[1], 2); + dp += 2; + break; + + case 4: + memcpy (dp, &rdata.lval, 4); + dp += 4; + break; + + default: + printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length); + return (NULL); + } - return (dp); + return (dp); } static uchar * -date_handler(eerec_map_t *rp, uchar *value, uchar *dp, uchar *edp) +date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - hymod_date_t date; - uchar *p = value, *ep; + hymod_date_t date; + uchar *p = val, *ep; - date.year = simple_strtol(p, (char **)&ep, 10); - if (ep == p || *ep++ != '-') { + date.year = simple_strtol (p, (char **)&ep, 10); + if (ep == p || *ep++ != '-') { bad_date: - printf("%s record (%s) is not a valid date\n", rp->name, value); - return (NULL); - } + printf ("%s rec (%s) is not a valid date\n", rp->name, val); + return (NULL); + } - date.month = simple_strtol(p = ep, (char **)&ep, 10); - if (ep == p || *ep++ != '-' || date.month == 0 || date.month > 12) - goto bad_date; + date.month = simple_strtol (p = ep, (char **)&ep, 10); + if (ep == p || *ep++ != '-' || date.month == 0 || date.month > 12) + goto bad_date; - date.day = simple_strtol(p = ep, (char **)&ep, 10); - if (ep == p || *ep != '\0' || date.day == 0 || date.day > 31) - goto bad_date; + date.day = simple_strtol (p = ep, (char **)&ep, 10); + if (ep == p || *ep != '\0' || date.day == 0 || date.day > 31) + goto bad_date; - if (dp + 2 + sizeof (hymod_date_t) > edp) { - printf("can't fit %s record into eeprom\n", rp->name); - return (NULL); - } + if (dp + 2 + sizeof (hymod_date_t) > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } - *dp++ = rp->type; - *dp++ = sizeof (hymod_date_t); - memcpy(dp, &date, sizeof (hymod_date_t)); - dp += sizeof (hymod_date_t); + *dp++ = rp->type; + *dp++ = sizeof (hymod_date_t); + memcpy (dp, &date, sizeof (hymod_date_t)); + dp += sizeof (hymod_date_t); - return (dp); + return (dp); } static uchar * -string_handler(eerec_map_t *rp, uchar *value, uchar *dp, uchar *edp) +string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - uint len; + uint len; - if ((len = strlen(value)) > rp->maxlen) { - printf("%s record (%s) string is too long (%d>%d)\n", - rp->name, value, len, rp->maxlen); - return (NULL); - } + if ((len = strlen (val)) > rp->maxlen) { + printf ("%s rec (%s) string is too long (%d>%d)\n", + rp->name, val, len, rp->maxlen); + return (NULL); + } - if (dp + 2 + len > edp) { - printf("can't fit %s record into eeprom\n", rp->name); - return (NULL); - } + if (dp + 2 + len > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } - *dp++ = rp->type; - *dp++ = len; - memcpy(dp, value, len); - dp += len; + *dp++ = rp->type; + *dp++ = len; + memcpy (dp, val, len); + dp += len; - return (dp); + return (dp); } static uchar * -bytes_handler(eerec_map_t *rp, uchar *value, uchar *dp, uchar *edp) +bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) { - uchar bytes[HYMOD_MAX_BYTES], nbytes = 0; - uchar *p = value, *ep; + uchar bytes[HYMOD_MAX_BYTES], nbytes = 0; + uchar *p = val, *ep; - for (;;) { + for (;;) { - if (nbytes >= HYMOD_MAX_BYTES) { - printf("%s record (%s) byte array too long\n", rp->name, value); - return (NULL); - } + if (nbytes >= HYMOD_MAX_BYTES) { + printf ("%s rec (%s) byte array too long\n", + rp->name, val); + return (NULL); + } - bytes[nbytes++] = simple_strtol(p, (char **)&ep, 10); + bytes[nbytes++] = simple_strtol (p, (char **)&ep, 10); - if (ep == p || (*ep != '\0' && *ep != ',')) { - printf("%s record (%s) byte array has invalid uint\n", - rp->name, value); - return (NULL); - } + if (ep == p || (*ep != '\0' && *ep != ',')) { + printf ("%s rec (%s) byte array has invalid uint\n", + rp->name, val); + return (NULL); + } - if (*ep++ == '\0') - break; + if (*ep++ == '\0') + break; - p = ep; - } + p = ep; + } - if (dp + 2 + nbytes > edp) { - printf("can't fit %s record into eeprom\n", rp->name); - return (NULL); - } + if (dp + 2 + nbytes > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } - *dp++ = rp->type; - *dp++ = nbytes; - memcpy(dp, bytes, nbytes); - dp += nbytes; + *dp++ = rp->type; + *dp++ = nbytes; + memcpy (dp, bytes, nbytes); + dp += nbytes; - return (dp); + return (dp); } static eerec_map_t eerec_map[] = { - /* name type handler len max */ - { "serno", HYMOD_EEREC_SERNO, uint_handler, 4, 0 }, - { "date", HYMOD_EEREC_DATE, date_handler, 4, 0 }, - { "batch", HYMOD_EEREC_BATCH, string_handler, 0, HYMOD_MAX_BATCH }, - { "type", HYMOD_EEREC_TYPE, uint_handler, 1, 0 }, - { "rev", HYMOD_EEREC_REV, uint_handler, 1, 0 }, - { "sdram", HYMOD_EEREC_SDRAM, bytes_handler, 0, HYMOD_MAX_SDRAM }, - { "flash", HYMOD_EEREC_FLASH, bytes_handler, 0, HYMOD_MAX_FLASH }, - { "zbt", HYMOD_EEREC_ZBT, bytes_handler, 0, HYMOD_MAX_ZBT }, - { "xlxtyp", HYMOD_EEREC_XLXTYP, bytes_handler, 0, HYMOD_MAX_XLX }, - { "xlxspd", HYMOD_EEREC_XLXSPD, bytes_handler, 0, HYMOD_MAX_XLX }, - { "xlxtmp", HYMOD_EEREC_XLXTMP, bytes_handler, 0, HYMOD_MAX_XLX }, - { "xlxgrd", HYMOD_EEREC_XLXGRD, bytes_handler, 0, HYMOD_MAX_XLX }, - { "cputyp", HYMOD_EEREC_CPUTYP, uint_handler, 1, 0 }, - { "cpuspd", HYMOD_EEREC_CPUSPD, uint_handler, 1, 0 }, - { "cpmspd", HYMOD_EEREC_CPMSPD, uint_handler, 1, 0 }, - { "busspd", HYMOD_EEREC_BUSSPD, uint_handler, 1, 0 }, - { "hstype", HYMOD_EEREC_HSTYPE, uint_handler, 1, 0 }, - { "hschin", HYMOD_EEREC_HSCHIN, uint_handler, 1, 0 }, - { "hschout", HYMOD_EEREC_HSCHOUT, uint_handler, 1, 0 }, + /* name type handler len max */ + { "serno", HYMOD_EEREC_SERNO, uint_handler, 4, 0 }, + { "date", HYMOD_EEREC_DATE, date_handler, 4, 0 }, + { "batch", HYMOD_EEREC_BATCH, string_handler, 0, HYMOD_MAX_BATCH }, + { "type", HYMOD_EEREC_TYPE, uint_handler, 1, 0 }, + { "rev", HYMOD_EEREC_REV, uint_handler, 1, 0 }, + { "sdram", HYMOD_EEREC_SDRAM, bytes_handler, 0, HYMOD_MAX_SDRAM }, + { "flash", HYMOD_EEREC_FLASH, bytes_handler, 0, HYMOD_MAX_FLASH }, + { "zbt", HYMOD_EEREC_ZBT, bytes_handler, 0, HYMOD_MAX_ZBT }, + { "xlxtyp", HYMOD_EEREC_XLXTYP, bytes_handler, 0, HYMOD_MAX_XLX }, + { "xlxspd", HYMOD_EEREC_XLXSPD, bytes_handler, 0, HYMOD_MAX_XLX }, + { "xlxtmp", HYMOD_EEREC_XLXTMP, bytes_handler, 0, HYMOD_MAX_XLX }, + { "xlxgrd", HYMOD_EEREC_XLXGRD, bytes_handler, 0, HYMOD_MAX_XLX }, + { "cputyp", HYMOD_EEREC_CPUTYP, uint_handler, 1, 0 }, + { "cpuspd", HYMOD_EEREC_CPUSPD, uint_handler, 1, 0 }, + { "cpmspd", HYMOD_EEREC_CPMSPD, uint_handler, 1, 0 }, + { "busspd", HYMOD_EEREC_BUSSPD, uint_handler, 1, 0 }, + { "hstype", HYMOD_EEREC_HSTYPE, uint_handler, 1, 0 }, + { "hschin", HYMOD_EEREC_HSCHIN, uint_handler, 1, 0 }, + { "hschout", HYMOD_EEREC_HSCHOUT, uint_handler, 1, 0 }, }; static int neerecs = sizeof eerec_map / sizeof eerec_map[0]; @@ -423,175 +434,248 @@ static int neerecs = sizeof eerec_map / sizeof eerec_map[0]; static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp; static int -eeprom_fetch_callback(uchar *name, uchar *value) +eerec_callback (uchar *name, uchar *val) { - eerec_map_t *rp; + eerec_map_t *rp; - for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++) - if (strcmp(name, rp->name) == 0) - break; + for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++) + if (strcmp (name, rp->name) == 0) + break; - if (rp >= &eerec_map[neerecs]) - return (0); + if (rp >= &eerec_map[neerecs]) + return (0); - if ((dp = (*rp->handler)(rp, value, dp, edp)) == NULL) - return (0); + if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL) + return (0); - return (1); + return (1); } -int -eeprom_fetch(unsigned offset, bd_t *bd, char *filename, ulong addr) +static int +hymod_eeprom_fetch(int which, char *filename, ulong addr) { - hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0]; - ulong crc; + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0]; + ulong crc; - hp->id = HYMOD_EEPROM_ID; - hp->ver = HYMOD_EEPROM_VER; + hp->id = HYMOD_EEPROM_ID; + hp->ver = HYMOD_EEPROM_VER; - dp = sdp = (uchar *)(hp + 1); - edp = dp + HYMOD_EEPROM_MAXLEN; + dp = sdp = (uchar *)(hp + 1); + edp = dp + HYMOD_EEPROM_MAXLEN; - if (fetch_and_parse(bd, filename, addr, eeprom_fetch_callback) == 0) - return (0); + if (fetch_and_parse (filename, addr, eerec_callback) == 0) + return (0); - hp->len = dp - sdp; + hp->len = dp - sdp; - crc = crc32(0, data, dp - data); - memcpy(dp, &crc, sizeof (ulong)); - dp += sizeof (ulong); + crc = crc32 (0, data, dp - data); + memcpy (dp, &crc, sizeof (ulong)); + dp += sizeof (ulong); - eeprom_write(CFG_DEF_EEPROM_ADDR, offset, data, dp - data); + eeprom_write (dev_addr, 0, data, dp - data); - return (1); + return (1); } static char *type_vals[] = { - "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY" + "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY" }; static char *xlxtyp_vals[] = { - "NONE", "XCV300E", "XCV400E", "XCV600E" + "NONE", "XCV300E", "XCV400E", "XCV600E" }; static char *xlxspd_vals[] = { - "NONE", "6", "7", "8" + "NONE", "6", "7", "8" }; static char *xlxtmp_vals[] = { - "NONE", "COM", "IND" + "NONE", "COM", "IND" }; static char *xlxgrd_vals[] = { - "NONE", "NORMAL", "ENGSAMP" + "NONE", "NORMAL", "ENGSAMP" }; static char *cputyp_vals[] = { - "NONE", "MPC8260" + "NONE", "MPC8260" }; static char *clk_vals[] = { - "NONE", "33", "66", "100", "133", "166", "200" + "NONE", "33", "66", "100", "133", "166", "200" }; static char *hstype_vals[] = { - "NONE", "AMCC-S2064A" + "NONE", "AMCC-S2064A" }; static void -print_mem(char *l, char *s, uchar n, uchar a[]) +print_mem (char *l, char *s, uchar n, uchar a[]) { - if (n > 0) { - if (n == 1) - printf("%s%dMB %s", s, 1 << (a[0] - 20), l); - else { - ulong t = 0; - int i; - - for (i = 0; i < n; i++) - t += 1 << (a[i] - 20); - - printf("%s%luMB %s (%d banks:", s, t, l, n); - - for (i = 0; i < n; i++) - printf("%dMB%s", 1 << (a[i] - 20), (i == n - 1) ? ")" : ","); + if (n > 0) { + if (n == 1) + printf ("%s%dMB %s", s, 1 << (a[0] - 20), l); + else { + ulong t = 0; + int i; + + for (i = 0; i < n; i++) + t += 1 << (a[i] - 20); + + printf ("%s%luMB %s (%d banks:", s, t, l, n); + + for (i = 0; i < n; i++) + printf ("%dMB%s", + 1 << (a[i] - 20), + (i == n - 1) ? ")" : ","); + } } - } - else - printf("%sNO %s", s, l); + else + printf ("%sNO %s", s, l); } void -eeprom_print(hymod_eeprom_t *ep) +hymod_eeprom_print (hymod_eeprom_t *ep) { - int i; - - printf(" Hymod %s board, rev %03d\n", - type_vals[ep->bdtype], ep->bdrev); - - printf(" serial #: %010lu, date %04d-%02d-%02d", - ep->serno, ep->date.year, ep->date.month, ep->date.day); - if (ep->batchlen > 0) - printf(", batch \"%.*s\"", ep->batchlen, ep->batch); - puts("\n"); - - switch (ep->bdtype) { - - case HYMOD_BDTYPE_IO: - case HYMOD_BDTYPE_CLP: - case HYMOD_BDTYPE_DSP: - printf(" Motorola %s CPU, speeds: %s/%s/%s", - cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd], - clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]); - - print_mem("SDRAM", ", ", ep->nsdram, ep->sdramsz); - - print_mem("FLASH", ", ", ep->nflash, ep->flashsz); - - puts("\n"); - - print_mem("ZBT", " ", ep->nzbt, ep->zbtsz); - - if (ep->nxlx > 0) { - hymod_xlx_t *xp; - - if (ep->nxlx == 1) { - xp = &ep->xlx[0]; - printf(", Xilinx %s FPGA (%s/%s/%s)", - xlxtyp_vals[xp->type], xlxspd_vals[xp->speed], - xlxtmp_vals[xp->temp], xlxgrd_vals[xp->grade]); - } - else { - printf(", %d Xilinx FPGAs (", ep->nxlx); - for (i = 0; i < ep->nxlx; i++) { - xp = &ep->xlx[i]; - printf("%s[%s/%s/%s]%s", - xlxtyp_vals[xp->type], xlxspd_vals[xp->speed], - xlxtmp_vals[xp->temp], xlxgrd_vals[xp->grade], - (i == ep->nxlx - 1) ? ")" : ", "); + int i; + + printf (" Hymod %s board, rev %03d\n", + type_vals[ep->bdtype], ep->bdrev); + + printf (" serial #: %010lu, date %04d-%02d-%02d", + ep->serno, ep->date.year, ep->date.month, ep->date.day); + if (ep->batchlen > 0) + printf (", batch \"%.*s\"", ep->batchlen, ep->batch); + puts ("\n"); + + switch (ep->bdtype) { + + case HYMOD_BDTYPE_IO: + case HYMOD_BDTYPE_CLP: + case HYMOD_BDTYPE_DSP: + printf (" Motorola %s CPU, speeds: %s/%s/%s", + cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd], + clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]); + + print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz); + + print_mem ("FLASH", ", ", ep->nflash, ep->flashsz); + + puts ("\n"); + + print_mem ("ZBT", " ", ep->nzbt, ep->zbtsz); + + if (ep->nxlx > 0) { + hymod_xlx_t *xp; + + if (ep->nxlx == 1) { + xp = &ep->xlx[0]; + printf (", Xilinx %s FPGA (%s/%s/%s)", + xlxtyp_vals[xp->type], + xlxspd_vals[xp->speed], + xlxtmp_vals[xp->temp], + xlxgrd_vals[xp->grade]); + } + else { + printf (", %d Xilinx FPGAs (", ep->nxlx); + for (i = 0; i < ep->nxlx; i++) { + xp = &ep->xlx[i]; + printf ("%s[%s/%s/%s]%s", + xlxtyp_vals[xp->type], + xlxspd_vals[xp->speed], + xlxtmp_vals[xp->temp], + xlxgrd_vals[xp->grade], + (i == ep->nxlx - 1) ? ")" : ", "); + } + } } - } + else + puts(", NO FPGAs"); + + puts ("\n"); + + if (ep->hss.type > 0) + printf (" High Speed Serial: " + "%s, %d input%s, %d output%s\n", + hstype_vals[ep->hss.type], + ep->hss.nchin, + (ep->hss.nchin == 1 ? "" : "s"), + ep->hss.nchout, + (ep->hss.nchout == 1 ? "" : "s")); + break; + + case HYMOD_BDTYPE_INPUT: + case HYMOD_BDTYPE_ALTINPUT: + case HYMOD_BDTYPE_DISPLAY: + break; + + default: + /* crap! */ + printf (" UNKNOWN BOARD TYPE: %d\n", ep->bdtype); + break; + } +} + +int +hymod_eeprom_read (int which, hymod_eeprom_t *ep) +{ + char *label = which ? "mezzanine" : "main"; + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + char filename[50], prompt[50], *dir; + int serno, count = 0, rc; + + rc = eeprom_probe (dev_addr, 0); + + if (rc > 0) { + printf ("*** probe for eeprom failed with code %d\n", rc); + return (0); + } + + if (rc < 0) + return (rc); + + sprintf (prompt, "Enter %s board serial number: ", label); + + if ((dir = getenv ("bddb_cfgdir")) == NULL) + dir = def_bddb_cfgdir; + + for (;;) { + int rc; + + if (hymod_eeprom_load (which, ep)) + return (1); + + printf ("*** %s board EEPROM contents are %sinvalid\n", + label, count == 0 ? "" : "STILL "); + + puts ("*** will fetch from server (Ctrl-C to abort)\n"); + + serno = hymod_get_serno (prompt); + + if (serno < 0) { + if (serno == -1) + puts ("\n*** interrupted!"); + else + puts ("\n*** timeout!"); + puts (" - ignoring eeprom contents\n"); + return (0); + } + + sprintf (filename, "%s/%010d.cfg", dir, serno); + + printf ("*** fetching %s board EEPROM contents from server\n", + label); + + rc = hymod_eeprom_fetch (which, filename, CFG_LOAD_ADDR); + + if (rc == 0) { + puts ("*** fetch failed - ignoring eeprom contents\n"); + return (0); + } + + count++; } - else - puts(", NO FPGAs"); - - puts("\n"); - - if (ep->hss.type > 0) - printf(" High Speed Serial: %s, %d input%s, %d output%s\n", - hstype_vals[ep->hss.type], - ep->hss.nchin, (ep->hss.nchin == 1 ? "" : "s"), - ep->hss.nchout, (ep->hss.nchout == 1 ? "" : "s")); - break; - - case HYMOD_BDTYPE_INPUT: - case HYMOD_BDTYPE_ALTINPUT: - case HYMOD_BDTYPE_DISPLAY: - break; - - default: - /* crap! */ - printf(" UNKNOWN BOARD TYPE: %d\n", ep->bdtype); - break; - } } diff --git a/board/hymod/env.c b/board/hymod/env.c new file mode 100644 index 0000000..f58aec2 --- /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 = name; + + if (*nn == '-') { + override = 0; + nn++; + } + + while (*nn == ' ' || *nn == '\t') + nn++; + + if ((nnl = strlen (nn)) == 0) { + printf ("Empty name in global env file\n"); + return (0); + } + + if ((c = nn[nnl - 1]) == '+' || c == '-') { + if (c == '+') + append = 1; + else + remove = 1; + nn[--nnl] = '\0'; + } + + while (nnl > 0 && ((c = nn[nnl - 1]) == ' ' || c == '\t')) + nn[--nnl] = '\0'; + if (nnl == 0) { + printf ("Empty name in global env file\n"); + return (0); + } + + p = value; + q = nv; + + while ((c = *p) == ' ' || c == '\t') + p++; + + nvl = strlen (p); + while (nvl > 0 && ((c = p[nvl - 1]) == ' ' || c == '\t')) + p[--nvl] = '\0'; + + while ((*q = *p++) != '\0') { + if (*q == '%') { + switch (*p++) { + + case '\0': /* whoops - back up */ + p--; + break; + + case '%': /* a single percent character */ + q++; + break; + + case 's': /* main board serial number as string */ + q += sprintf (q, "%010lu", + cp->main.eeprom.serno); + break; + + case 'S': /* main board serial number as number */ + q += sprintf (q, "%lu", cp->main.eeprom.serno); + break; + + default: /* ignore any others */ + break; + } + } + else + q++; + } + + if ((nvl = q - nv) == 0) { + setenv (nn, NULL); + return (1); + } + + if ((curver = getenv ("global_env_version")) == NULL) + curver = "unknown"; + + if ((newver = getenv ("new_genv_version")) == NULL || \ + strcmp (curver, newver) == 0) { + if (strcmp (nn, "version") == 0) + setenv ("new_genv_version", nv); + return (1); + } + + if ((p = getenv (nn)) != NULL) { + + strcpy (ov, p); + ovl = strlen (ov); + + if (append) { + + if (strstr (ov, nv) == NULL) { + + printf ("Appending '%s' to env var '%s'\n", + nv, nn); + + while (nvl >= 0) { + nv[ovl + 1 + nvl] = nv[nvl]; + nvl--; + } + + nv[ovl] = ' '; + + while (--ovl >= 0) + nv[ovl] = ov[ovl]; + + setenv (nn, nv); + } + + return (1); + } + + if (remove) { + + if (strstr (ov, nv) != NULL) { + + printf ("Removing '%s' from env var '%s'\n", + nv, nn); + + while ((p = strstr (ov, nv)) != NULL) { + q = p + nvl; + if (*q == ' ') + q++; + strcpy(p, q); + } + + setenv (nn, ov); + } + + return (1); + } + + if (!override || strcmp (ov, nv) == 0) + return (1); + + printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", + nn, ov, nv); + } + else + printf ("Setting env cmd '%s' to '%s'\n", nn, nv); + + setenv (nn, nv); + return (1); +} + +void +hymod_check_env (void) +{ + char *p, *path, *curver, *newver; + int firsttime = 0, needsave = 0; + + if (getenv ("global_env_loaded") == NULL) { + puts ("*** global environment has never been loaded\n"); + puts ("*** fetching from server"); + firsttime = 1; + } + else if ((p = getenv ("always_check_env")) != NULL && + strcmp (p, "yes") == 0) + puts ("*** checking for updated global environment"); + else + return; + + puts (" (Control-C to Abort)\n"); + + if ((path = getenv ("global_env_path")) == NULL || *path == '\0') + path = def_global_env_path; + + if (fetch_and_parse (path, CFG_LOAD_ADDR, env_callback) == 0) { + puts ("*** Fetch of global environment failed!\n"); + return; + } + + if ((newver = getenv ("new_genv_version")) == NULL) { + puts ("*** Version number not set - contents ignored!\n"); + return; + } + + if ((curver = getenv ("global_env_version")) == NULL || \ + strcmp (curver, newver) != 0) { + setenv ("global_env_version", newver); + needsave = 1; + } + else + printf ("*** Global environment up-to-date (ver %s)\n", curver); + + setenv ("new_genv_version", NULL); + + if (firsttime) { + setenv ("global_env_loaded", "yes"); + needsave = 1; + } + + if (needsave) + puts ("\n*** Remember to run the 'saveenv' " + "command to save the changes\n\n"); +} diff --git a/board/hymod/fetch.c b/board/hymod/fetch.c index dcbda31..e121d55 100644 --- a/board/hymod/fetch.c +++ b/board/hymod/fetch.c @@ -1,7 +1,6 @@ /* * (C) Copyright 2001 - * Murray Jensen, CSIRO Manufacturing Science and Technology, - * <Murray.Jensen@cmst.csiro.au> + * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au> * * See file CREDITS for list of people who contributed to this * project. @@ -25,118 +24,84 @@ #include <common.h> #include <net.h> -/* imports from common/main.c */ -extern char console_buffer[CFG_CBSIZE]; +/* imports from input.c */ +extern int hymod_get_ethaddr (void); int -fetch_and_parse(bd_t *bd, char *fn, ulong addr, int (*cback)(uchar *, uchar *)) +fetch_and_parse (char *fn, ulong addr, int (*cback)(uchar *, uchar *)) { - char *ethaddr; - uchar *fp, *efp; - - while ((ethaddr = getenv("ethaddr")) == NULL || *ethaddr == '\0') { - - puts("*** Ethernet address is not set\n"); - - for (;;) { - int n; - - n = readline("Enter board ethernet address: "); - - if (n < 0) { - puts("\n"); - return (0); - } - - if (n == 0) - continue; - - if (n == 17) { - int i; - char *p, *q; - uchar ea[6]; - - /* see if it looks like an ethernet address */ - - p = console_buffer; - - for (i = 0; i < 6; i++) { - char term = (i == 5 ? '\0' : ':'); - - ea[i] = simple_strtol(p, &q, 16); - - if ((q - p) != 2 || *q++ != term) - break; - - p = q; + char *ethaddr; + uchar *fp, *efp; + int rc, count = 0; + + while ((ethaddr = getenv ("ethaddr")) == NULL || *ethaddr == '\0') { + + printf ("*** Ethernet address is%s not set\n", + count == 0 ? "" : " STILL"); + + if ((rc = hymod_get_ethaddr ()) < 0) { + if (rc == -1) + puts ("\n*** interrupted!"); + else + puts ("\n*** timeout!"); + printf (" - fetch of '%s' aborted\n", fn); + return (0); } - if (i == 6) { - /* it looks ok - set it */ - printf("Setting ethernet address to %s\n", console_buffer); - setenv("ethaddr", console_buffer); - - puts("Remember to do a 'saveenv' to make it permanent\n"); - break; - } - } - - printf("Invalid ethernet address (%s) - please re-enter\n", - console_buffer); + count++; } - } - - copy_filename(BootFile, fn, sizeof (BootFile)); - load_addr = addr; - if (NetLoop(TFTP) <= 0) { - printf("tftp transfer of file '%s' failed\n", fn); - return (0); - } + copy_filename (BootFile, fn, sizeof (BootFile)); + load_addr = addr; + NetBootFileXferSize = 0; - if (NetBootFileXferSize == 0) { - printf("can't determine size of file '%s'\n", fn); - return (0); - } - - fp = (uchar *)load_addr; - efp = fp + NetBootFileXferSize; - - do { - uchar *name, *value; - - if (*fp == '#' || *fp == '\n') { - while (fp < efp && *fp++ != '\n') - ; - continue; + if (NetLoop (TFTP) == 0) { + printf ("tftp transfer of file '%s' failed\n", fn); + return (0); } - name = fp; + if (NetBootFileXferSize == 0) { + printf ("can't determine size of file '%s'\n", fn); + return (0); + } - while (fp < efp && *fp != '=') - if (*fp++ == '\n') - name = fp; + fp = (uchar *)load_addr; + efp = fp + NetBootFileXferSize; - if (fp >= efp) - break; + do { + uchar *name, *value; - *fp++ = '\0'; + if (*fp == '#' || *fp == '\n') { + /* skip this line */ + while (fp < efp && *fp++ != '\n') + ; + continue; + } - value = fp; + name = fp; - while (fp < efp && *fp != '\n') - fp++; + while (fp < efp && *fp != '=' && *fp != '\n') + fp++; + if (fp >= efp) + break; + if (*fp == '\n') { + fp++; + continue; + } + *fp++ = '\0'; - /* ok if we go off the end here */ + value = fp; - if (fp[-1] == '\r') - fp[-1] = '\0'; - *fp++ = '\0'; + while (fp < efp && *fp != '\n') + fp++; + if (fp[-1] == '\r') + fp[-1] = '\0'; + *fp++ = '\0'; /* ok if we go off the end here */ - if ((*cback)(name, value) == 0) - return (0); + if ((*cback)(name, value) == 0) + return (0); - } while (fp < efp); + } while (fp < efp); - return (1); + return (1); } diff --git a/board/hymod/flash.c b/board/hymod/flash.c index 0a09b4a..7d1ae30 100644 --- a/board/hymod/flash.c +++ b/board/hymod/flash.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00 + * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00 */ #include <common.h> @@ -36,234 +36,154 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ #define FLAG_PROTECT_CLEAR 0x02 /*----------------------------------------------------------------------- - * Functions - */ -#if 0 -static ulong flash_get_size (vu_long *addr, flash_info_t *info); -static void flash_get_offsets (ulong base, flash_info_t *info); -#endif -static int write_word (flash_info_t *info, ulong dest, ulong data); - -/*----------------------------------------------------------------------- */ /* - * probe for the existence of flash at bank word address "addr" - * 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id + * probe for flash bank at address "base" and store info about it + * in the flash_info entry "fip". Fatal error if nothing there. */ -static int -bank_probe_word(bank_addr_t addr) +static void +bank_probe (flash_info_t *fip, bank_addr_t base) { - int retval; + bank_addr_t addr; + bank_word_t word; + int i; /* reset the flash */ - *addr = BANK_CMD_RST; + *base = BANK_CMD_RST; - /* check the manufacturer id */ - *addr = BANK_CMD_RD_ID; - if (*BANK_ADDR_REG_MAN(addr) != BANK_RD_ID_MAN) { - retval = -1; - goto out; - } - - /* check the device id */ - *addr = BANK_CMD_RD_ID; - if (*BANK_ADDR_REG_DEV(addr) != BANK_RD_ID_DEV) { - retval = -2; - goto out; - } + /* check the manufacturer id - must be intel */ + *base = BANK_CMD_RD_ID; + word = *BANK_REG_MAN_CODE (base); + *base = BANK_CMD_RST; - retval = CFG_FLASH_TYPE; + if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff)) + panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx", + (unsigned long)word, (unsigned long)base); -out: - /* reset the flash again */ - *addr = BANK_CMD_RST; - - return retval; -} + /* check the device id */ + *base = BANK_CMD_RD_ID; + word = *BANK_REG_DEV_CODE (base); + *base = BANK_CMD_RST; -/* - * probe for flash banks at address "base" and store info for any found - * into flash_info entry "fip". Must find at least one bank. - */ -static void -bank_probe(flash_info_t *fip, bank_addr_t base) -{ - bank_addr_t addr, eaddr; - int nbanks; + switch (word) { - fip->flash_id = FLASH_UNKNOWN; - fip->size = 0L; - fip->sector_count = 0; + case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5; + fip->sector_count = 32; + break; - addr = base; - eaddr = BANK_ADDR_BASE(addr, MAX_BANKS); - nbanks = 0; + case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5; + fip->sector_count = 64; + break; - while (addr < eaddr) { - bank_addr_t addrw, eaddrw, addrb; - int i, osc, nsc, curtype = -1; + case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A; + fip->sector_count = 32; + break; - addrw = addr; - eaddrw = BANK_ADDR_NEXT_WORD(addrw); + case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A; + fip->sector_count = 64; + break; - while (addrw < eaddrw) { - int thistype; + case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A; + fip->sector_count = 128; + break; -#ifdef FLASH_DEBUG - printf(" probing for flash at addr 0x%08lx\n", - (unsigned long)addrw); -#endif - if ((thistype = bank_probe_word(addrw++)) < 0) - goto out; - - if (curtype < 0) - curtype = thistype; - else { - if (thistype != curtype) { - printf("Differing flash type found!\n"); - goto out; - } - } - } + default: + panic ("\nbad device code (0x%08lx) at addr 0x%08lx", + (unsigned long)word, (unsigned long)base); + } - if (curtype < 0) - goto out; - - /* bank exists - append info for this bank to *fip */ - fip->flash_id = FLASH_MAN_INTEL|curtype; - fip->size += BANK_SIZE; - osc = fip->sector_count; - fip->sector_count += BANK_NBLOCKS; - if ((nsc = fip->sector_count) >= CFG_MAX_FLASH_SECT) - panic("Too many sectors in flash at address 0x%08lx\n", - (unsigned long)base); - - addrb = addr; - for (i = osc; i < nsc; i++) { - fip->start[i] = (ulong)addrb; - fip->protect[i] = 0; - addrb = BANK_ADDR_NEXT_BLK(addrb); - } + if (fip->sector_count >= CFG_MAX_FLASH_SECT) + panic ("\ntoo many sectors (%d) in flash at address 0x%08lx", + fip->sector_count, (unsigned long)base); - addr = BANK_ADDR_NEXT_BANK(addr); - nbanks++; + addr = base; + for (i = 0; i < fip->sector_count; i++) { + fip->start[i] = (unsigned long)addr; + fip->protect[i] = 0; + addr = BANK_ADDR_NEXT_BLK (addr); } -out: - if (nbanks == 0) - panic("ERROR: no flash found at address 0x%08lx\n", - (unsigned long)base); + fip->size = (bank_size_t)addr - (bank_size_t)base; } static void -bank_reset(flash_info_t *info, int sect) +bank_reset (flash_info_t *info, int sect) { - bank_addr_t addrw, eaddrw; + bank_addr_t addr = (bank_addr_t)info->start[sect]; - addrw = (bank_addr_t)info->start[sect]; - eaddrw = BANK_ADDR_NEXT_WORD(addrw); - - while (addrw < eaddrw) { #ifdef FLASH_DEBUG - printf(" writing reset cmd to addr 0x%08lx\n", - (unsigned long)addrw); + printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr); #endif - *addrw = BANK_CMD_RST; - addrw++; - } + + *addr = BANK_CMD_RST; } static void -bank_erase_init(flash_info_t *info, int sect) +bank_erase_init (flash_info_t *info, int sect) { - bank_addr_t addrw, saddrw, eaddrw; + bank_addr_t addr = (bank_addr_t)info->start[sect]; int flag; #ifdef FLASH_DEBUG - printf("0x%08lx BANK_CMD_PROG\n", BANK_CMD_PROG); - printf("0x%08lx BANK_CMD_ERASE1\n", BANK_CMD_ERASE1); - printf("0x%08lx BANK_CMD_ERASE2\n", BANK_CMD_ERASE2); - printf("0x%08lx BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT); - printf("0x%08lx BANK_CMD_RST\n", BANK_CMD_RST); - printf("0x%08lx BANK_STAT_RDY\n", BANK_STAT_RDY); - printf("0x%08lx BANK_STAT_ERR\n", BANK_STAT_ERR); -#endif - - saddrw = (bank_addr_t)info->start[sect]; - eaddrw = BANK_ADDR_NEXT_WORD(saddrw); - -#ifdef FLASH_DEBUG - printf("erasing sector %d, start addr = 0x%08lx " - "(bank next word addr = 0x%08lx)\n", sect, - (unsigned long)saddrw, (unsigned long)eaddrw); + printf ("erasing sector %d, addr = 0x%08lx\n", + sect, (unsigned long)addr); #endif /* Disable intrs which might cause a timeout here */ - flag = disable_interrupts(); + flag = disable_interrupts (); - for (addrw = saddrw; addrw < eaddrw; addrw++) { #ifdef FLASH_DEBUG - printf(" writing erase cmd to addr 0x%08lx\n", - (unsigned long)addrw); + printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr); #endif - *addrw = BANK_CMD_ERASE1; - *addrw = BANK_CMD_ERASE2; - } + *addr = BANK_CMD_ERASE1; + *addr = BANK_CMD_ERASE2; /* re-enable interrupts if necessary */ if (flag) - enable_interrupts(); + enable_interrupts (); } static int -bank_erase_poll(flash_info_t *info, int sect) +bank_erase_poll (flash_info_t *info, int sect) { - bank_addr_t addrw, saddrw, eaddrw; - int sectdone, haderr; - - saddrw = (bank_addr_t)info->start[sect]; - eaddrw = BANK_ADDR_NEXT_WORD(saddrw); - - sectdone = 1; - haderr = 0; - - for (addrw = saddrw; addrw < eaddrw; addrw++) { - bank_word_t stat = *addrw; + bank_addr_t addr = (bank_addr_t)info->start[sect]; + bank_word_t stat = *addr; #ifdef FLASH_DEBUG - printf(" checking status at addr " - "0x%08lx [0x%08lx]\n", - (unsigned long)addrw, stat); + printf ("checking status at addr 0x%08lx [0x%08lx]\n", + (unsigned long)addr, (unsigned long)stat); #endif - if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY) - sectdone = 0; - else if ((stat & BANK_STAT_ERR) != 0) { - printf(" failed on sector %d " - "(stat = 0x%08lx) at " - "address 0x%08lx\n", - sect, stat, - (unsigned long)addrw); - *addrw = BANK_CMD_CLR_STAT; - haderr = 1; + + if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) { + if ((stat & BANK_STAT_ERR) != 0) { + printf ("failed on sector %d [0x%08lx] at " + "address 0x%08lx\n", sect, + (unsigned long)stat, (unsigned long)addr); + *addr = BANK_CMD_CLR_STAT; + return (-1); } + else + return (1); } - - if (haderr) - return (-1); else - return (sectdone); + return (0); } static int -bank_write_word(bank_addr_t addr, bank_word_t value) +bank_write_word (bank_addr_t addr, bank_word_t value) { bank_word_t stat; ulong start; int flag, retval; /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts(); + flag = disable_interrupts (); *addr = BANK_CMD_PROG; @@ -271,14 +191,14 @@ bank_write_word(bank_addr_t addr, bank_word_t value) /* re-enable interrupts if necessary */ if (flag) - enable_interrupts(); + enable_interrupts (); retval = 0; /* data polling for D7 */ start = get_timer (0); do { - if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { retval = 1; goto done; } @@ -286,8 +206,8 @@ bank_write_word(bank_addr_t addr, bank_word_t value) } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY); if ((stat & BANK_STAT_ERR) != 0) { - printf("flash program failed (stat = 0x%08lx) " - "at address 0x%08lx\n", (ulong)stat, (ulong)addr); + printf ("flash program failed [0x%08lx] at address 0x%08lx\n", + (unsigned long)stat, (unsigned long)addr); *addr = BANK_CMD_CLR_STAT; retval = 3; } @@ -303,7 +223,7 @@ done: */ unsigned long -flash_init(void) +flash_init (void) { int i; @@ -312,21 +232,21 @@ flash_init(void) flash_info[i].flash_id = FLASH_UNKNOWN; } - bank_probe(&flash_info[0], (bank_addr_t)CFG_FLASH_BASE); + bank_probe (&flash_info[0], (bank_addr_t)CFG_FLASH_BASE); /* * protect monitor and environment sectors */ #if CFG_MONITOR_BASE == CFG_FLASH_BASE - (void)flash_protect(FLAG_PROTECT_SET, + (void)flash_protect (FLAG_PROTECT_SET, CFG_MONITOR_BASE, CFG_MONITOR_BASE+monitor_flash_len-1, &flash_info[0]); #endif #if defined(CFG_FLASH_ENV_ADDR) - (void)flash_protect(FLAG_PROTECT_SET, + (void)flash_protect (FLAG_PROTECT_SET, CFG_FLASH_ENV_ADDR, #if defined(CFG_FLASH_ENV_BUF) CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1, @@ -341,40 +261,8 @@ flash_init(void) /*----------------------------------------------------------------------- */ -#if 0 -static void -flash_get_offsets(ulong base, flash_info_t *info) -{ - int i; - - /* set up sector start adress table */ - if (info->flash_id & FLASH_BTYPE) { - /* set sector offsets for bottom boot block type */ - info->start[0] = base + 0x00000000; - info->start[1] = base + 0x00008000; - info->start[2] = base + 0x0000C000; - info->start[3] = base + 0x00010000; - for (i = 4; i < info->sector_count; i++) { - info->start[i] = base + (i * 0x00020000) - 0x00060000; - } - } else { - /* set sector offsets for top boot block type */ - i = info->sector_count - 1; - info->start[i--] = base + info->size - 0x00008000; - info->start[i--] = base + info->size - 0x0000C000; - info->start[i--] = base + info->size - 0x00010000; - for (; i >= 0; i--) { - info->start[i] = base + i * 0x00020000; - } - } - -} -#endif /* 0 */ - -/*----------------------------------------------------------------------- - */ void -flash_print_info(flash_info_t *info) +flash_print_info (flash_info_t *info) { int i; @@ -391,6 +279,14 @@ flash_print_info(flash_info_t *info) switch (info->flash_id & FLASH_TYPEMASK) { case FLASH_28F320J5: printf ("28F320J5 (32 Mbit, 2 x 16bit)\n"); break; + case FLASH_28F640J5: printf ("28F640J5 (64 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F320J3A: printf ("28F320J3A (32 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F128J3A: printf ("28F320J3A (128 Mbit, 2 x 16bit)\n"); + break; default: printf ("Unknown Chip Type\n"); break; } @@ -411,157 +307,25 @@ flash_print_info(flash_info_t *info) return; } -/*----------------------------------------------------------------------- - */ - /* * The following code cannot be run from FLASH! */ -#if 0 -static ulong -flash_get_size(vu_long *addr, flash_info_t *info) -{ - short i; - ulong value; - ulong base = (ulong)addr; - - - /* Write auto select command: read Manufacturer ID */ - addr[0x0555] = 0x00AA00AA; - addr[0x02AA] = 0x00550055; - addr[0x0555] = 0x00900090; - - value = addr[0]; - - switch (value) { - case AMD_MANUFACT: - info->flash_id = FLASH_MAN_AMD; - break; - case FUJ_MANUFACT: - info->flash_id = FLASH_MAN_FUJ; - break; - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - return (0); /* no or unknown flash */ - } - - value = addr[1]; /* device ID */ - - switch (value) { - case AMD_ID_LV400T: - info->flash_id += FLASH_AM400T; - info->sector_count = 11; - info->size = 0x00100000; - break; /* => 1 MB */ - - case AMD_ID_LV400B: - info->flash_id += FLASH_AM400B; - info->sector_count = 11; - info->size = 0x00100000; - break; /* => 1 MB */ - - case AMD_ID_LV800T: - info->flash_id += FLASH_AM800T; - info->sector_count = 19; - info->size = 0x00200000; - break; /* => 2 MB */ - - case AMD_ID_LV800B: - info->flash_id += FLASH_AM800B; - info->sector_count = 19; - info->size = 0x00200000; - break; /* => 2 MB */ - - case AMD_ID_LV160T: - info->flash_id += FLASH_AM160T; - info->sector_count = 35; - info->size = 0x00400000; - break; /* => 4 MB */ - - case AMD_ID_LV160B: - info->flash_id += FLASH_AM160B; - info->sector_count = 35; - info->size = 0x00400000; - break; /* => 4 MB */ -#if 0 /* enable when device IDs are available */ - case AMD_ID_LV320T: - info->flash_id += FLASH_AM320T; - info->sector_count = 67; - info->size = 0x00800000; - break; /* => 8 MB */ - - case AMD_ID_LV320B: - info->flash_id += FLASH_AM320B; - info->sector_count = 67; - info->size = 0x00800000; - break; /* => 8 MB */ -#endif - default: - info->flash_id = FLASH_UNKNOWN; - return (0); /* => no or unknown flash */ - - } - - /* set up sector start adress table */ - if (info->flash_id & FLASH_BTYPE) { - /* set sector offsets for bottom boot block type */ - info->start[0] = base + 0x00000000; - info->start[1] = base + 0x00008000; - info->start[2] = base + 0x0000C000; - info->start[3] = base + 0x00010000; - for (i = 4; i < info->sector_count; i++) { - info->start[i] = base + (i * 0x00020000) - 0x00060000; - } - } else { - /* set sector offsets for top boot block type */ - i = info->sector_count - 1; - info->start[i--] = base + info->size - 0x00008000; - info->start[i--] = base + info->size - 0x0000C000; - info->start[i--] = base + info->size - 0x00010000; - for (; i >= 0; i--) { - info->start[i] = base + i * 0x00020000; - } - } - - /* check for protected sectors */ - for (i = 0; i < info->sector_count; i++) { - /* read sector protection at sector address, (A7 .. A0) = 0x02 */ - /* D0 = 1 if protected */ - addr = (volatile unsigned long *)(info->start[i]); - info->protect[i] = addr[2] & 1; - } - - /* - * Prevent writes to uninitialized FLASH. - */ - if (info->flash_id != FLASH_UNKNOWN) { - addr = (volatile unsigned long *)info->start[0]; - - *addr = 0x00F000F0; /* reset bank */ - } - - return (info->size); -} -#endif /* 0 */ - /*----------------------------------------------------------------------- */ int -flash_erase(flash_info_t *info, int s_first, int s_last) +flash_erase (flash_info_t *info, int s_first, int s_last) { int prot, sect, haderr; ulong start, now, last; int rcode = 0; #ifdef FLASH_DEBUG - printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" + printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" " Bank # %d: ", s_last - s_first + 1, s_first, s_last, (info - flash_info) + 1); - flash_print_info(info); + flash_print_info (info); #endif if ((s_first < 0) || (s_first > s_last)) { @@ -574,14 +338,14 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } prot = 0; - for (sect=s_first; sect<=s_last; ++sect) { + for (sect = s_first; sect <= s_last; ++sect) { if (info->protect[sect]) { prot++; } } if (prot) { - printf("- Warning: %d protected sector%s will not be erased!\n", + printf ("- Warning: %d protected sector%s will not be erased\n", prot, (prot > 1 ? "s" : "")); } @@ -594,15 +358,15 @@ flash_erase(flash_info_t *info, int s_first, int s_last) ulong estart; int sectdone; - bank_erase_init(info, sect); + bank_erase_init (info, sect); /* wait at least 80us - let's wait 1 ms */ udelay (1000); - estart = get_timer(start); + estart = get_timer (start); do { - now = get_timer(start); + now = get_timer (start); if (now - estart > CFG_FLASH_ERASE_TOUT) { printf ("Timeout (sect %d)\n", sect); @@ -619,7 +383,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } #endif - sectdone = bank_erase_poll(info, sect); + sectdone = bank_erase_poll (info, sect); if (sectdone < 0) { haderr = 1; @@ -642,21 +406,39 @@ flash_erase(flash_info_t *info, int s_first, int s_last) /* reset to read mode */ for (sect = s_first; sect <= s_last; sect++) { if (info->protect[sect] == 0) { /* not protected */ - bank_reset(info, sect); + bank_reset (info, sect); } } return rcode; } /*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 3 - Program failed + */ +static int +write_word (flash_info_t *info, ulong dest, ulong data) +{ + /* Check if Flash is (sufficiently) erased */ + if ((*(ulong *)dest & data) != data) + return (2); + + return (bank_write_word ((bank_addr_t)dest, (bank_word_t)data)); +} + +/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased + * 3 - Program failed */ int -write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) { ulong cp, wp, data; int i, l, rc; @@ -680,7 +462,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) data = (data << 8) | (*(uchar *)cp); } - if ((rc = write_word(info, wp, data)) != 0) { + if ((rc = write_word (info, wp, data)) != 0) { return (rc); } wp += 4; @@ -694,7 +476,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) for (i=0; i<4; ++i) { data = (data << 8) | *src++; } - if ((rc = write_word(info, wp, data)) != 0) { + if ((rc = write_word (info, wp, data)) != 0) { return (rc); } wp += 4; @@ -717,28 +499,7 @@ write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) data = (data << 8) | (*(uchar *)cp); } - return (write_word(info, wp, data)); -} - -/*----------------------------------------------------------------------- - * Write a word to Flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - */ -static int -write_word(flash_info_t *info, ulong dest, ulong data) -{ - int retval; - - /* Check if Flash is (sufficiently) erased */ - if ((*(ulong *)dest & data) != data) { - return (2); - } - - retval = bank_write_word((bank_addr_t)dest, (bank_word_t)data); - - return (retval); + return (write_word (info, wp, data)); } /*----------------------------------------------------------------------- diff --git a/board/hymod/flash.h b/board/hymod/flash.h index 3bccbc9..10db7fc 100644 --- a/board/hymod/flash.h +++ b/board/hymod/flash.h @@ -1,163 +1,156 @@ -/*************** DEFINES for Intel StrataFlash FLASH chip ********************/ - /* - * acceptable chips types are: + * (C) Copyright 2000 + * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au> + * + * See file CREDITS for list of people who contributed to this + * project. * - * 28F320J5, 28F640J5, 28F320J3A, 28F640J3A and 28F128J3A + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA */ -/* register addresses, valid only following an CHIP_CMD_RD_ID command */ -#define CHIP_ADDR_REG_MAN 0x000000 /* manufacturer's id */ -#define CHIP_ADDR_REG_DEV 0x000001 /* device id */ -#define CHIP_ADDR_REG_CFGM 0x000003 /* master lock config */ -#define CHIP_ADDR_REG_CFG(b) (((b)<<16)|2) /* lock config for block b */ +/*************** DEFINES for Intel StrataFlash FLASH chip ********************/ /* Commands */ -#define CHIP_CMD_RST 0xFF /* reset flash */ -#define CHIP_CMD_RD_ID 0x90 /* read the id and lock bits */ -#define CHIP_CMD_RD_QUERY 0x98 /* read device capabilities */ -#define CHIP_CMD_RD_STAT 0x70 /* read the status register */ -#define CHIP_CMD_CLR_STAT 0x50 /* clear the staus register */ -#define CHIP_CMD_WR_BUF 0xE8 /* clear the staus register */ -#define CHIP_CMD_PROG 0x40 /* program word command */ -#define CHIP_CMD_ERASE1 0x20 /* 1st word for block erase */ -#define CHIP_CMD_ERASE2 0xD0 /* 2nd word for block erase */ -#define CHIP_CMD_ERASE_SUSP 0xB0 /* suspend block erase */ -#define CHIP_CMD_LOCK 0x60 /* 1st word for all lock cmds */ -#define CHIP_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */ -#define CHIP_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */ -#define CHIP_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */ +#define ISF_CMD_RST 0xFF /* reset flash */ +#define ISF_CMD_RD_ID 0x90 /* read the id and lock bits */ +#define ISF_CMD_RD_QUERY 0x98 /* read device capabilities */ +#define ISF_CMD_RD_STAT 0x70 /* read the status register */ +#define ISF_CMD_CLR_STAT 0x50 /* clear the staus register */ +#define ISF_CMD_WR_BUF 0xE8 /* clear the staus register */ +#define ISF_CMD_PROG 0x40 /* program word command */ +#define ISF_CMD_ERASE1 0x20 /* 1st word for block erase */ +#define ISF_CMD_ERASE2 0xD0 /* 2nd word for block erase */ +#define ISF_CMD_ERASE_SUSP 0xB0 /* suspend block erase */ +#define ISF_CMD_LOCK 0x60 /* 1st word for all lock cmds */ +#define ISF_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */ +#define ISF_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */ +#define ISF_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */ /* status register bits */ -#define CHIP_STAT_DPS 0x02 /* Device Protect Status */ -#define CHIP_STAT_VPPS 0x08 /* VPP Status */ -#define CHIP_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */ -#define CHIP_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */ -#define CHIP_STAT_ESS 0x40 /* Erase Suspend Status */ -#define CHIP_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */ - -#define CHIP_STAT_ERR (CHIP_STAT_VPPS | CHIP_STAT_DPS | \ - CHIP_STAT_ECLBS | CHIP_STAT_PSLBS) - -/* ID and Lock Configuration */ -#define CHIP_RD_ID_LOCK 0x01 /* Bit 0 of each byte */ -#define CHIP_RD_ID_MAN 0x89 /* Manufacturer code = 0x89 */ -#define CHIP_RD_ID_DEV CFG_FLASH_ID - -/* dimensions */ -#define CHIP_WIDTH 2 /* chips are in 16 bit mode */ -#define CHIP_WSHIFT 1 /* (log2 of CHIP_WIDTH) */ -#define CHIP_NBLOCKS CFG_FLASH_NBLOCKS -#define CHIP_BLKSZ (128 * 1024) /* of 128Kbytes each */ -#define CHIP_SIZE (CHIP_BLKSZ * CHIP_NBLOCKS) +#define ISF_STAT_DPS 0x02 /* Device Protect Status */ +#define ISF_STAT_VPPS 0x08 /* VPP Status */ +#define ISF_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */ +#define ISF_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */ +#define ISF_STAT_ESS 0x40 /* Erase Suspend Status */ +#define ISF_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */ + +#define ISF_STAT_ERR (ISF_STAT_VPPS | ISF_STAT_DPS | \ + ISF_STAT_ECLBS | ISF_STAT_PSLBS) + +/* register addresses, valid only following an ISF_CMD_RD_ID command */ +#define ISF_REG_MAN_CODE 0x00 /* manufacturer code */ +#define ISF_REG_DEV_CODE 0x01 /* device code */ +#define ISF_REG_BLK_LCK 0x02 /* block lock configuration */ +#define ISF_REG_MST_LCK 0x03 /* master lock configuration */ /********************** DEFINES for Hymod Flash ******************************/ /* - * The hymod board has 2 x 28F320J5 chips running in - * 16 bit mode, for a 32 bit wide bank. + * this code requires that the flash on any Hymod board appear as a bank + * of two (identical) 16bit Intel StrataFlash chips with 64Kword erase + * sectors (or blocks), running in x16 bit mode and connected side-by-side + * to make a 32-bit wide bus. */ -typedef unsigned long bank_word_t; /* 8/16/32/64bit unsigned int */ -typedef volatile bank_word_t *bank_addr_t; -typedef unsigned long bank_size_t; /* want this big - >= 32 bit */ +typedef unsigned long bank_word_t; +typedef bank_word_t bank_blk_t[64 * 1024]; + +#define BANK_FILL_WORD(b) (((bank_word_t)(b) << 16) | (bank_word_t)(b)) + +#ifdef EXAMPLE -#define BANK_CHIP_WIDTH 2 /* each bank is 2 chips wide */ -#define BANK_CHIP_WSHIFT 1 /* (log2 of BANK_CHIP_WIDTH) */ +/* theoretically the following examples should also work */ -#define BANK_WIDTH (CHIP_WIDTH * BANK_CHIP_WIDTH) -#define BANK_WSHIFT (CHIP_WSHIFT + BANK_CHIP_WSHIFT) -#define BANK_NBLOCKS CHIP_NBLOCKS -#define BANK_BLKSZ (CHIP_BLKSZ * BANK_CHIP_WIDTH) -#define BANK_SIZE (CHIP_SIZE * BANK_CHIP_WIDTH) +/* one flash chip in x8 mode with 128Kword sectors and 8bit bus */ +typedef unsigned char bank_word_t; +typedef bank_word_t bank_blk_t[128 * 1024]; +#define BANK_FILL_WORD(b) ((bank_word_t)(b)) -#define MAX_BANKS 1 /* only one bank possible */ +/* four flash chips in x16 mode with 32Kword sectors and 64bit bus */ +typedef unsigned long long bank_word_t; +typedef bank_word_t bank_blk_t[32 * 1024]; +#define BANK_FILL_WORD(b) ( \ + ((bank_word_t)(b) << 48) \ + ((bank_word_t)(b) << 32) \ + ((bank_word_t)(b) << 16) \ + ((bank_word_t)(b) << 0) \ + ) + +#endif /* EXAMPLE */ + +/* the sizes of these two types should probably be the same */ +typedef volatile bank_word_t *bank_addr_t; +typedef unsigned long bank_size_t; /* align bank addresses and sizes to bank word boundaries */ #define BANK_ADDR_WORD_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ - & ~(BANK_WIDTH - 1))) -#define BANK_SIZE_WORD_ALIGN(s) ((bank_size_t)BANK_ADDR_WORD_ALIGN( \ - (bank_size_t)(s) + (BANK_WIDTH - 1))) + & ~(sizeof (bank_word_t) - 1))) +#define BANK_SIZE_WORD_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_word_t) - 1) \ + & ~(sizeof (bank_word_t) - 1)) /* align bank addresses and sizes to bank block boundaries */ #define BANK_ADDR_BLK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ - & ~(BANK_BLKSZ - 1))) -#define BANK_SIZE_BLK_ALIGN(s) ((bank_size_t)BANK_ADDR_BLK_ALIGN( \ - (bank_size_t)(s) + (BANK_BLKSZ - 1))) - -/* align bank addresses and sizes to bank boundaries */ -#define BANK_ADDR_BANK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ - & ~(BANK_SIZE - 1))) -#define BANK_SIZE_BANK_ALIGN(s) ((bank_size_t)BANK_ADDR_BANK_ALIGN( \ - (bank_size_t)(s) + (BANK_SIZE - 1))) + & ~(sizeof (bank_blk_t) - 1))) +#define BANK_SIZE_BLK_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_blk_t) - 1) \ + & ~(sizeof (bank_blk_t) - 1)) /* add an offset to a bank address */ -#define BANK_ADDR_OFFSET(a, o) (bank_addr_t)((bank_size_t)(a) + \ - (bank_size_t)(o)) - -/* get base address of bank b, given flash base address a */ -#define BANK_ADDR_BASE(a, b) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \ - (bank_size_t)(b) * BANK_SIZE) +#define BANK_ADDR_OFFSET(a, o) ((bank_addr_t)((bank_size_t)(a) + \ + (bank_size_t)(o))) /* adjust a bank address to start of next word, block or bank */ #define BANK_ADDR_NEXT_WORD(a) BANK_ADDR_OFFSET(BANK_ADDR_WORD_ALIGN(a), \ - BANK_WIDTH) + sizeof (bank_word_t)) #define BANK_ADDR_NEXT_BLK(a) BANK_ADDR_OFFSET(BANK_ADDR_BLK_ALIGN(a), \ - BANK_BLKSZ) -#define BANK_ADDR_NEXT_BANK(a) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \ - BANK_SIZE) - -/* get bank address of chip register r given a bank base address a */ -#define BANK_ADDR_REG(a, r) BANK_ADDR_OFFSET(BANK_ADDR_BANK_ALIGN(a), \ - ((bank_size_t)(r) << BANK_WSHIFT)) - -/* make a bank address for each chip register address */ - -#define BANK_ADDR_REG_MAN(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_MAN) -#define BANK_ADDR_REG_DEV(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_DEV) -#define BANK_ADDR_REG_CFGM(a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFGM) -#define BANK_ADDR_REG_CFG(b,a) BANK_ADDR_REG((a), CHIP_ADDR_REG_CFG(b)) - -/* - * replicate a chip cmd/stat/rd value into each byte position within a word - * so that multiple chips are accessed in a single word i/o operation - * - * this must be as wide as the bank_word_t type, and take into account the - * chip width and bank layout - */ + sizeof (bank_blk_t)) -#define BANK_FILL_WORD(o) ((bank_word_t)( \ - ((unsigned long)(o) << 16) | \ - ((unsigned long)(o) << 0) \ - )) +/* get bank address of register r given a bank base address a and block num b */ +#define BANK_ADDR_REG(a, b, r) BANK_ADDR_OFFSET(BANK_ADDR_OFFSET((a), \ + (bank_size_t)(b) * sizeof (bank_blk_t)), \ + (bank_size_t)(r) * sizeof (bank_word_t)) -/* make a bank word value for each chip cmd/stat/rd value */ +/* make a bank word value for each StrataFlash value */ /* Commands */ -#define BANK_CMD_RST BANK_FILL_WORD(CHIP_CMD_RST) -#define BANK_CMD_RD_ID BANK_FILL_WORD(CHIP_CMD_RD_ID) -#define BANK_CMD_RD_STAT BANK_FILL_WORD(CHIP_CMD_RD_STAT) -#define BANK_CMD_CLR_STAT BANK_FILL_WORD(CHIP_CMD_CLR_STAT) -#define BANK_CMD_ERASE1 BANK_FILL_WORD(CHIP_CMD_ERASE1) -#define BANK_CMD_ERASE2 BANK_FILL_WORD(CHIP_CMD_ERASE2) -#define BANK_CMD_PROG BANK_FILL_WORD(CHIP_CMD_PROG) -#define BANK_CMD_LOCK BANK_FILL_WORD(CHIP_CMD_LOCK) -#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_SET_LOCK_BLK) -#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(CHIP_CMD_SET_LOCK_MSTR) -#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(CHIP_CMD_CLR_LOCK_BLK) +#define BANK_CMD_RST BANK_FILL_WORD(ISF_CMD_RST) +#define BANK_CMD_RD_ID BANK_FILL_WORD(ISF_CMD_RD_ID) +#define BANK_CMD_RD_STAT BANK_FILL_WORD(ISF_CMD_RD_STAT) +#define BANK_CMD_CLR_STAT BANK_FILL_WORD(ISF_CMD_CLR_STAT) +#define BANK_CMD_ERASE1 BANK_FILL_WORD(ISF_CMD_ERASE1) +#define BANK_CMD_ERASE2 BANK_FILL_WORD(ISF_CMD_ERASE2) +#define BANK_CMD_PROG BANK_FILL_WORD(ISF_CMD_PROG) +#define BANK_CMD_LOCK BANK_FILL_WORD(ISF_CMD_LOCK) +#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(ISF_CMD_SET_LOCK_BLK) +#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(ISF_CMD_SET_LOCK_MSTR) +#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(ISF_CMD_CLR_LOCK_BLK) /* status register bits */ -#define BANK_STAT_DPS BANK_FILL_WORD(CHIP_STAT_DPS) -#define BANK_STAT_PSS BANK_FILL_WORD(CHIP_STAT_PSS) -#define BANK_STAT_VPPS BANK_FILL_WORD(CHIP_STAT_VPPS) -#define BANK_STAT_PSLBS BANK_FILL_WORD(CHIP_STAT_PSLBS) -#define BANK_STAT_ECLBS BANK_FILL_WORD(CHIP_STAT_ECLBS) -#define BANK_STAT_ESS BANK_FILL_WORD(CHIP_STAT_ESS) -#define BANK_STAT_RDY BANK_FILL_WORD(CHIP_STAT_RDY) - -#define BANK_STAT_ERR BANK_FILL_WORD(CHIP_STAT_ERR) - -/* ID and Lock Configuration */ -#define BANK_RD_ID_LOCK BANK_FILL_WORD(CHIP_RD_ID_LOCK) -#define BANK_RD_ID_MAN BANK_FILL_WORD(CHIP_RD_ID_MAN) -#define BANK_RD_ID_DEV BANK_FILL_WORD(CHIP_RD_ID_DEV) +#define BANK_STAT_DPS BANK_FILL_WORD(ISF_STAT_DPS) +#define BANK_STAT_PSS BANK_FILL_WORD(ISF_STAT_PSS) +#define BANK_STAT_VPPS BANK_FILL_WORD(ISF_STAT_VPPS) +#define BANK_STAT_PSLBS BANK_FILL_WORD(ISF_STAT_PSLBS) +#define BANK_STAT_ECLBS BANK_FILL_WORD(ISF_STAT_ECLBS) +#define BANK_STAT_ESS BANK_FILL_WORD(ISF_STAT_ESS) +#define BANK_STAT_RDY BANK_FILL_WORD(ISF_STAT_RDY) + +#define BANK_STAT_ERR BANK_FILL_WORD(ISF_STAT_ERR) + +/* make a bank register address for each StrataFlash register address */ + +#define BANK_REG_MAN_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_MAN_CODE) +#define BANK_REG_DEV_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_DEV_CODE) +#define BANK_REG_BLK_LCK(a, b) BANK_ADDR_REG((a), (b), ISF_REG_BLK_LCK) +#define BANK_REG_MST_LCK(a) BANK_ADDR_REG((a), 0, ISF_REG_MST_LCK) diff --git a/board/hymod/global_env b/board/hymod/global_env index 913f82d..16def24 100644 --- a/board/hymod/global_env +++ b/board/hymod/global_env @@ -1,3 +1,33 @@ +# DONT FORGET TO CHANGE THE "version" VAR BELOW IF YOU MAKE CHANGES TO THIS FILE + +# (C) Copyright 2001 +# Murray Jensen, CSIRO-MIT, <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 @@ -7,32 +37,94 @@ # %s serial number of the main board (10 digit zero filled) # %S serial number of the main board (plain number) # %% a percentage character -# -# no whitespace is removed in either <name> or <value> +# ... otherwise the %x is discarded # # if first character in <name> is a dash ('-'), then an existing env var -# will not be overwritten (the dash is removed). +# will not be overwritten (the dash is removed). i.e. it is only set if +# it does not exist # # if last character in <name> is a plus ('+'), then <value> will be appended -# to any existing env var (the plus is removed). Duplicates of <value> are +# to any existing env var (the plus is ignored). Duplicates of <value> are # removed. # +# similarly, if the last character in <name> is a minus ('-'), then any +# occurences of <value> in the current value of <name> will removed (the +# minus is ignored). +# +# leading and trailing whitespace is removed in both <name> and <value> +# (after processing any initial or final plus/minus in <name>). +# + +# MISCELLANEOUS PARAMETERS + +# version must always come first +version=3 # set the ip address based on the main board serial number ipaddr=192.168.1.%S serverip=192.168.1.254 -# stop auto execute after tftp +# stop auto execute after tftp (not a very good name really) autostart=no +# setting this to "yes" forces the global_env file to be loaded and processed +# if the current version is different to the version in the file +always_check_env=no + +# BOOTING COMMANDS AND PARAMETERS + +# command to run when "auto-booting" +bootcmd=bootm 40080000 40200000 + +# how long the "countdown" to automatically running "bootcmd" is +bootdelay=2 + +# how long before it "times out" console input and attempts to run "bootcmd" +bootretry=5 + +# arguments passed to the boot program (i.e. linux kernel) via register 6 +# the linux kernel (v2.4) uses the following registers: +# r3 - address of board information structure +# r4 - address of initial ramdisk image (0 means no initrd) +# r5 - size of initial ramdisk image +# r6 - address of command line string +-bootargs=root=/dev/ram rw + +# these four are for hymod linux intergrated into our Sun network +bootargs+=serialno=%S +bootargs+=nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4 +bootargs+=nfsclient +bootargs+=automount + +# start a web server by default +bootargs+=webserver + +# give negotiation time to finish +bootargs+=netsleep=5 + +# then our ciscos don't pass packets for 25-30 secs after that, so +# pinging the server until it responds prevents network connections +# from failing... +bootargs+=netping + +# these are old bootargs - we don't need them anymore +bootargs-=preload=unix,i2c-cpm,i2c-dev +bootargs-=ramdisk_size=32768 +bootargs-=ramdisk_size=24576 + +# FLASH MANIPULATION COMMANDS + +# +# 16M flash, 64 x 256K sectors, mapped at address 0x40000000 # -# 16M flash map, 64 x 256K sectors, mapped at address 0x40000000 +# Sector(s) Address Size Description # -# sector 0: boot -# sector 1: non volatile environment -# sectors 2-4: linux kernel image -# sectors 5-7: alternate linux kernel image -# sectors 8-63: linux initial ramdisk image +# 0 - 0 0x40000000 256K boot code +# 1 - 1 0x40040000 256K non volatile environment +# 2 - 4 0x40080000 768K linux kernel image +# 5 - 7 0x40140000 768K alternate linux kernel image +# 8 - 47 0x40200000 10M linux initial ramdisk image +# 48 - 63 0x40c00000 4M ramdisk image for applications # fetchboot=tftp 100000 /hymod/u-boot.bin @@ -49,21 +141,18 @@ newlinux=run fetchlinux eraselinux copylinux cmplinux fetchaltlinux=tftp 100000 /hymod/altlinux.bin erasealtlinux=erase 1:5-7 -copyaltlinux=cp.b 100000 40080000 $(filesize) -cmpaltlinux=cmp.b 100000 40080000 $(filesize) +copyaltlinux=cp.b 100000 40140000 $(filesize) +cmpaltlinux=cmp.b 100000 40140000 $(filesize) newaltlinux=run fetchaltlinux erasealtlinux copyaltlinux cmpaltlinux fetchird=tftp 100000 /hymod/initrd.bin -eraseird=erase 1:8-63 +eraseird=erase 1:8-47 copyird=cp.b 100000 40200000 $(filesize) cmpird=cmp.b 100000 40200000 $(filesize) newinitrd=run fetchird eraseird copyird cmpird -bootcmd=bootm 40080000 40200000 --bootargs=root=/dev/ram rw -# these are for hymod linux -bootargs+=preload=unix,i2c-cpm,i2c-dev -bootargs+=serialno=%S -bootargs+=ramdisk_size=32768 -bootargs+=automount nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4 -bootdelay=2 +fetchard=tftp 100000 /hymod/apprd.bin +eraseard=erase 1:48-63 +copyard=cp.b 100000 40c00000 $(filesize) +cmpard=cmp.b 100000 40c00000 $(filesize) +newapprd=run fetchard eraseard copyard cmpard diff --git a/board/hymod/hymod.c b/board/hymod/hymod.c index 829f254..3611a12 100644 --- a/board/hymod/hymod.c +++ b/board/hymod/hymod.c @@ -20,11 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00 + * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00 */ #include <common.h> #include <mpc8260.h> +#include <mpc8260_irq.h> #include <ioports.h> #include <i2c.h> #include <asm/iopin_8260.h> @@ -32,15 +33,11 @@ /* ------------------------------------------------------------------------- */ /* imports from eeprom.c */ -extern int eeprom_load (unsigned, hymod_eeprom_t *); -extern int eeprom_fetch (unsigned, char *, ulong); -extern void eeprom_print (hymod_eeprom_t *); +extern int hymod_eeprom_read (int, hymod_eeprom_t *); +extern void hymod_eeprom_print (hymod_eeprom_t *); -/* imports from fetch.c */ -extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); - -/* imports from common/main.c */ -extern char console_buffer[CFG_CBSIZE]; +/* imports from env.c */ +extern void hymod_check_env (void); /* ------------------------------------------------------------------------- */ @@ -54,274 +51,152 @@ extern char console_buffer[CFG_CBSIZE]; const iop_conf_t iop_conf_tab[4][32] = { /* Port A configuration */ - { /* conf ppar psor pdir podr pdat */ - /* PA31 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII COL */ - /* PA30 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII CRS */ - /* PA29 */ {1, 1, 1, 1, 0, 0}, - /* FCC1 MII TX_ER */ - /* PA28 */ {1, 1, 1, 1, 0, 0}, - /* FCC1 MII TX_EN */ - /* PA27 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII RX_DV */ - /* PA26 */ {1, 1, 1, 0, 0, 0}, - /* FCC1 MII RX_ER */ - /* PA25 */ {1, 0, 0, 1, 0, 0}, - /* FCC2 MII MDIO */ - /* PA24 */ {1, 0, 0, 1, 0, 0}, - /* FCC2 MII MDC */ - /* PA23 */ {1, 0, 0, 1, 0, 0}, - /* FCC3 MII MDIO */ - /* PA22 */ {1, 0, 0, 1, 0, 0}, - /* FCC3 MII MDC */ - /* PA21 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[3] */ - /* PA20 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[2] */ - /* PA19 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[1] */ - /* PA18 */ {1, 1, 0, 1, 0, 0}, - /* FCC1 MII TxD[0] */ - /* PA17 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[3] */ - /* PA16 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[2] */ - /* PA15 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[1] */ - /* PA14 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RxD[0] */ - /* PA13 */ {1, 0, 0, 1, 0, 0}, - /* FCC1 MII MDIO */ - /* PA12 */ {1, 0, 0, 1, 0, 0}, - /* FCC1 MII MDC */ - /* PA11 */ {1, 0, 0, 1, 0, 0}, - /* SEL_CD */ - /* PA10 */ {1, 0, 0, 0, 0, 0}, - /* FLASH STS1 */ - /* PA9 */ {1, 0, 0, 0, 0, 0}, - /* FLASH STS0 */ - /* PA8 */ {1, 0, 0, 0, 0, 0}, - /* FLASH ~PE */ - /* PA7 */ {1, 0, 0, 0, 0, 0}, - /* WATCH ~HRESET */ - /* PA6 */ {1, 0, 0, 0, 1, 0}, - /* VC DONE */ - /* PA5 */ {1, 0, 0, 1, 1, 0}, - /* VC INIT */ - /* PA4 */ {1, 0, 0, 1, 0, 0}, - /* VC ~PROG */ - /* PA3 */ {1, 0, 0, 1, 0, 0}, - /* VM ENABLE */ - /* PA2 */ {1, 0, 0, 0, 1, 0}, - /* VM DONE */ - /* PA1 */ {1, 0, 0, 1, 1, 0}, - /* VM INIT */ - /* PA0 */ {1, 0, 0, 1, 0, 0} - /* VM ~PROG */ - }, + { + /* cnf par sor dir odr dat */ + { 1, 1, 1, 0, 0, 0 }, /* PA31: FCC1 MII COL */ + { 1, 1, 1, 0, 0, 0 }, /* PA30: FCC1 MII CRS */ + { 1, 1, 1, 1, 0, 0 }, /* PA29: FCC1 MII TX_ER */ + { 1, 1, 1, 1, 0, 0 }, /* PA28: FCC1 MII TX_EN */ + { 1, 1, 1, 0, 0, 0 }, /* PA27: FCC1 MII RX_DV */ + { 1, 1, 1, 0, 0, 0 }, /* PA26: FCC1 MII RX_ER */ + { 1, 0, 0, 1, 0, 0 }, /* PA25: FCC2 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA24: FCC2 MII MDC */ + { 1, 0, 0, 1, 0, 0 }, /* PA23: FCC3 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA22: FCC3 MII MDC */ + { 1, 1, 0, 1, 0, 0 }, /* PA21: FCC1 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PA20: FCC1 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PA19: FCC1 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PA18: FCC1 MII TxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PA17: FCC1 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PA16: FCC1 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PA15: FCC1 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PA14: FCC1 MII RxD[0] */ + { 1, 0, 0, 1, 0, 0 }, /* PA13: FCC1 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA12: FCC1 MII MDC */ + { 1, 0, 0, 1, 0, 0 }, /* PA11: SEL_CD */ + { 1, 0, 0, 0, 0, 0 }, /* PA10: FLASH STS1 */ + { 1, 0, 0, 0, 0, 0 }, /* PA09: FLASH STS0 */ + { 1, 0, 0, 0, 0, 0 }, /* PA08: FLASH ~PE */ + { 1, 0, 0, 0, 0, 0 }, /* PA07: WATCH ~HRESET */ + { 1, 0, 0, 0, 1, 0 }, /* PA06: VC DONE */ + { 1, 0, 0, 1, 1, 0 }, /* PA05: VC INIT */ + { 1, 0, 0, 1, 0, 0 }, /* PA04: VC ~PROG */ + { 1, 0, 0, 1, 0, 0 }, /* PA03: VM ENABLE */ + { 1, 0, 0, 0, 1, 0 }, /* PA02: VM DONE */ + { 1, 0, 0, 1, 1, 0 }, /* PA01: VM INIT */ + { 1, 0, 0, 1, 0, 0 } /* PA00: VM ~PROG */ + }, /* Port B configuration */ - { /* conf ppar psor pdir podr pdat */ - /* PB31 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TX_ER */ - /* PB30 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RX_DV */ - /* PB29 */ {1, 1, 1, 1, 0, 0}, - /* FCC2 MII TX_EN */ - /* PB28 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RX_ER */ - /* PB27 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII COL */ - /* PB26 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII CRS */ - /* PB25 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[3] */ - /* PB24 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[2] */ - /* PB23 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[1] */ - /* PB22 */ {1, 1, 0, 1, 0, 0}, - /* FCC2 MII TxD[0] */ - /* PB21 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[0] */ - /* PB20 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[1] */ - /* PB19 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[2] */ - /* PB18 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RxD[3] */ - /* PB17 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RX_DV */ - /* PB16 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RX_ER */ - /* PB15 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TX_ER */ - /* PB14 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TX_EN */ - /* PB13 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII COL */ - /* PB12 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII CRS */ - /* PB11 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[3] */ - /* PB10 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[2] */ - /* PB9 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[1] */ - /* PB8 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RxD[0] */ - /* PB7 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[3] */ - /* PB6 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[2] */ - /* PB5 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[1] */ - /* PB4 */ {1, 1, 0, 1, 0, 0}, - /* FCC3 MII TxD[0] */ - /* PB3 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PB2 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PB1 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PB0 */ {0, 0, 0, 0, 0, 0} - /* pin doesn't exist */ - }, - - /* Port C */ - { /* conf ppar psor pdir podr pdat */ - /* PC31 */ {1, 0, 0, 0, 0, 0}, - /* MEZ ~IACK */ - /* PC30 */ {0, 0, 0, 0, 0, 0}, - /* PC29 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCx */ - /* PC28 */ {1, 1, 0, 0, 0, 0}, - /* CLK4 */ - /* PC27 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCF */ - /* PC26 */ {1, 1, 0, 0, 0, 0}, - /* CLK 32K */ - /* PC25 */ {1, 1, 0, 0, 0, 0}, - /* BRG4/CLK7 */ - /* PC24 */ {0, 0, 0, 0, 0, 0}, - /* PC23 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCx */ - /* PC22 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII RX_CLK */ - /* PC21 */ {1, 1, 0, 0, 0, 0}, - /* FCC1 MII TX_CLK */ - /* PC20 */ {1, 1, 0, 0, 0, 0}, - /* CLK SCCF */ - /* PC19 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII RX_CLK */ - /* PC18 */ {1, 1, 0, 0, 0, 0}, - /* FCC2 MII TX_CLK */ - /* PC17 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII RX_CLK */ - /* PC16 */ {1, 1, 0, 0, 0, 0}, - /* FCC3 MII TX_CLK */ - /* PC15 */ {1, 0, 0, 0, 0, 0}, - /* SCC1 UART ~CTS */ - /* PC14 */ {1, 0, 0, 0, 0, 0}, - /* SCC1 UART ~CD */ - /* PC13 */ {1, 0, 0, 0, 0, 0}, - /* SCC2 UART ~CTS */ - /* PC12 */ {1, 0, 0, 0, 0, 0}, - /* SCC2 UART ~CD */ - /* PC11 */ {1, 0, 0, 1, 0, 0}, - /* SCC1 UART ~DTR */ - /* PC10 */ {1, 0, 0, 1, 0, 0}, - /* SCC1 UART ~DSR */ - /* PC9 */ {1, 0, 0, 1, 0, 0}, - /* SCC2 UART ~DTR */ - /* PC8 */ {1, 0, 0, 1, 0, 0}, - /* SCC2 UART ~DSR */ - /* PC7 */ {1, 0, 0, 0, 0, 0}, - /* TEMP ~ALERT */ - /* PC6 */ {1, 0, 0, 0, 0, 0}, - /* FCC3 INT */ - /* PC5 */ {1, 0, 0, 0, 0, 0}, - /* FCC2 INT */ - /* PC4 */ {1, 0, 0, 0, 0, 0}, - /* FCC1 INT */ - /* PC3 */ {1, 1, 1, 1, 0, 0}, - /* SDMA IDMA2 ~DACK */ - /* PC2 */ {1, 1, 1, 0, 0, 0}, - /* SDMA IDMA2 ~DONE */ - /* PC1 */ {1, 1, 0, 0, 0, 0}, - /* SDMA IDMA2 ~DREQ */ - /* PC0 */ {1, 1, 0, 1, 0, 0} - /* BRG7 */ - }, - - /* Port D */ - { /* conf ppar psor pdir podr pdat */ - /* PD31 */ {1, 1, 0, 0, 0, 0}, - /* SCC1 UART RxD */ - /* PD30 */ {1, 1, 1, 1, 0, 0}, - /* SCC1 UART TxD */ - /* PD29 */ {1, 0, 0, 1, 0, 0}, - /* SCC1 UART ~RTS */ - /* PD28 */ {1, 1, 0, 0, 0, 0}, - /* SCC2 UART RxD */ - /* PD27 */ {1, 1, 0, 1, 0, 0}, - /* SCC2 UART TxD */ - /* PD26 */ {1, 0, 0, 1, 0, 0}, - /* SCC2 UART ~RTS */ - /* PD25 */ {1, 0, 0, 0, 0, 0}, - /* SCC1 UART ~RI */ - /* PD24 */ {1, 0, 0, 0, 0, 0}, - /* SCC2 UART ~RI */ - /* PD23 */ {1, 0, 0, 1, 0, 0}, - /* CLKGEN PD */ - /* PD22 */ {1, 0, 0, 0, 0, 0}, - /* USER3 */ - /* PD21 */ {1, 0, 0, 0, 0, 0}, - /* USER2 */ - /* PD20 */ {1, 0, 0, 0, 0, 0}, - /* USER1 */ - /* PD19 */ {1, 1, 1, 0, 0, 0}, - /* SPI ~SEL */ - /* PD18 */ {1, 1, 1, 0, 0, 0}, - /* SPI CLK */ - /* PD17 */ {1, 1, 1, 0, 0, 0}, - /* SPI MOSI */ - /* PD16 */ {1, 1, 1, 0, 0, 0}, - /* SPI MISO */ - /* PD15 */ {1, 1, 1, 0, 1, 0}, - /* I2C SDA */ - /* PD14 */ {1, 1, 1, 0, 1, 0}, - /* I2C SCL */ - /* PD13 */ {1, 0, 0, 1, 0, 1}, - /* TEMP ~STDBY */ - /* PD12 */ {1, 0, 0, 1, 0, 1}, - /* FCC3 ~RESET */ - /* PD11 */ {1, 0, 0, 1, 0, 1}, - /* FCC2 ~RESET */ - /* PD10 */ {1, 0, 0, 1, 0, 1}, - /* FCC1 ~RESET */ - /* PD9 */ {1, 0, 0, 0, 0, 0}, - /* PD9 */ - /* PD8 */ {1, 0, 0, 0, 0, 0}, - /* PD8 */ - /* PD7 */ {1, 0, 0, 1, 0, 1}, - /* PD7 */ - /* PD6 */ {1, 0, 0, 1, 0, 1}, - /* PD6 */ - /* PD5 */ {1, 0, 0, 1, 0, 1}, - /* PD5 */ - /* PD4 */ {1, 0, 0, 1, 0, 1}, - /* PD4 */ - /* PD3 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PD2 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PD1 */ {0, 0, 0, 0, 0, 0}, - /* pin doesn't exist */ - /* PD0 */ {0, 0, 0, 0, 0, 0} - /* pin doesn't exist */ - } + { + /* cnf par sor dir odr dat */ + { 1, 1, 0, 1, 0, 0 }, /* PB31: FCC2 MII TX_ER */ + { 1, 1, 0, 0, 0, 0 }, /* PB30: FCC2 MII RX_DV */ + { 1, 1, 1, 1, 0, 0 }, /* PB29: FCC2 MII TX_EN */ + { 1, 1, 0, 0, 0, 0 }, /* PB28: FCC2 MII RX_ER */ + { 1, 1, 0, 0, 0, 0 }, /* PB27: FCC2 MII COL */ + { 1, 1, 0, 0, 0, 0 }, /* PB26: FCC2 MII CRS */ + { 1, 1, 0, 1, 0, 0 }, /* PB25: FCC2 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PB24: FCC2 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PB23: FCC2 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PB22: FCC2 MII TxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PB21: FCC2 MII RxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PB20: FCC2 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PB19: FCC2 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PB18: FCC2 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PB17: FCC3 MII RX_DV */ + { 1, 1, 0, 0, 0, 0 }, /* PB16: FCC3 MII RX_ER */ + { 1, 1, 0, 1, 0, 0 }, /* PB15: FCC3 MII TX_ER */ + { 1, 1, 0, 1, 0, 0 }, /* PB14: FCC3 MII TX_EN */ + { 1, 1, 0, 0, 0, 0 }, /* PB13: FCC3 MII COL */ + { 1, 1, 0, 0, 0, 0 }, /* PB12: FCC3 MII CRS */ + { 1, 1, 0, 0, 0, 0 }, /* PB11: FCC3 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PB10: FCC3 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PB09: FCC3 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PB08: FCC3 MII RxD[0] */ + { 1, 1, 0, 1, 0, 0 }, /* PB07: FCC3 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PB06: FCC3 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PB05: FCC3 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PB04: FCC3 MII TxD[0] */ + { 0, 0, 0, 0, 0, 0 }, /* PB03: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PB02: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PB01: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 } /* PB00: pin doesn't exist */ + }, + + /* Port C configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 0, 0, 0, 0, 0 }, /* PC31: MEZ ~IACK */ + { 0, 0, 0, 0, 0, 0 }, /* PC30: ? */ + { 1, 1, 0, 0, 0, 0 }, /* PC29: CLK SCCx */ + { 1, 1, 0, 0, 0, 0 }, /* PC28: CLK4 */ + { 1, 1, 0, 0, 0, 0 }, /* PC27: CLK SCCF */ + { 1, 1, 0, 0, 0, 0 }, /* PC26: CLK 32K */ + { 1, 1, 0, 0, 0, 0 }, /* PC25: BRG4/CLK7 */ + { 0, 0, 0, 0, 0, 0 }, /* PC24: ? */ + { 1, 1, 0, 0, 0, 0 }, /* PC23: CLK SCCx */ + { 1, 1, 0, 0, 0, 0 }, /* PC22: FCC1 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC21: FCC1 MII TX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC20: CLK SCCF */ + { 1, 1, 0, 0, 0, 0 }, /* PC19: FCC2 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC18: FCC2 MII TX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC17: FCC3 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC16: FCC3 MII TX_CLK */ + { 1, 0, 0, 0, 0, 0 }, /* PC15: SCC1 UART ~CTS */ + { 1, 0, 0, 0, 0, 0 }, /* PC14: SCC1 UART ~CD */ + { 1, 0, 0, 0, 0, 0 }, /* PC13: SCC2 UART ~CTS */ + { 1, 0, 0, 0, 0, 0 }, /* PC12: SCC2 UART ~CD */ + { 1, 0, 0, 1, 0, 0 }, /* PC11: SCC1 UART ~DTR */ + { 1, 0, 0, 1, 0, 0 }, /* PC10: SCC1 UART ~DSR */ + { 1, 0, 0, 1, 0, 0 }, /* PC09: SCC2 UART ~DTR */ + { 1, 0, 0, 1, 0, 0 }, /* PC08: SCC2 UART ~DSR */ + { 1, 0, 0, 0, 0, 0 }, /* PC07: TEMP ~ALERT */ + { 1, 0, 0, 0, 0, 0 }, /* PC06: FCC3 INT */ + { 1, 0, 0, 0, 0, 0 }, /* PC05: FCC2 INT */ + { 1, 0, 0, 0, 0, 0 }, /* PC04: FCC1 INT */ + { 0, 1, 1, 1, 0, 0 }, /* PC03: SDMA IDMA2 ~DACK */ + { 0, 1, 1, 0, 0, 0 }, /* PC02: SDMA IDMA2 ~DONE */ + { 0, 1, 0, 0, 0, 0 }, /* PC01: SDMA IDMA2 ~DREQ */ + { 1, 1, 0, 1, 0, 0 } /* PC00: BRG7 */ + }, + + /* Port D configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 1, 0, 0, 0, 0 }, /* PD31: SCC1 UART RxD */ + { 1, 1, 1, 1, 0, 0 }, /* PD30: SCC1 UART TxD */ + { 1, 0, 0, 1, 0, 0 }, /* PD29: SCC1 UART ~RTS */ + { 1, 1, 0, 0, 0, 0 }, /* PD28: SCC2 UART RxD */ + { 1, 1, 0, 1, 0, 0 }, /* PD27: SCC2 UART TxD */ + { 1, 0, 0, 1, 0, 0 }, /* PD26: SCC2 UART ~RTS */ + { 1, 0, 0, 0, 0, 0 }, /* PD25: SCC1 UART ~RI */ + { 1, 0, 0, 0, 0, 0 }, /* PD24: SCC2 UART ~RI */ + { 1, 0, 0, 1, 0, 0 }, /* PD23: CLKGEN PD */ + { 1, 0, 0, 0, 0, 0 }, /* PD22: USER3 */ + { 1, 0, 0, 0, 0, 0 }, /* PD21: USER2 */ + { 1, 0, 0, 0, 0, 0 }, /* PD20: USER1 */ + { 1, 1, 1, 0, 0, 0 }, /* PD19: SPI ~SEL */ + { 1, 1, 1, 0, 0, 0 }, /* PD18: SPI CLK */ + { 1, 1, 1, 0, 0, 0 }, /* PD17: SPI MOSI */ + { 1, 1, 1, 0, 0, 0 }, /* PD16: SPI MISO */ + { 1, 1, 1, 0, 1, 0 }, /* PD15: I2C SDA */ + { 1, 1, 1, 0, 1, 0 }, /* PD14: I2C SCL */ + { 1, 0, 0, 1, 0, 1 }, /* PD13: TEMP ~STDBY */ + { 1, 0, 0, 1, 0, 1 }, /* PD12: FCC3 ~RESET */ + { 1, 0, 0, 1, 0, 1 }, /* PD11: FCC2 ~RESET */ + { 1, 0, 0, 1, 0, 1 }, /* PD10: FCC1 ~RESET */ + { 1, 0, 0, 0, 0, 0 }, /* PD09: PD9 */ + { 1, 0, 0, 0, 0, 0 }, /* PD08: PD8 */ + { 1, 0, 0, 1, 0, 1 }, /* PD07: PD7 */ + { 1, 0, 0, 1, 0, 1 }, /* PD06: PD6 */ + { 1, 0, 0, 1, 0, 1 }, /* PD05: PD5 */ + { 1, 0, 0, 1, 0, 1 }, /* PD04: PD4 */ + { 0, 0, 0, 0, 0, 0 }, /* PD03: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PD02: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PD01: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 } /* PD00: pin doesn't exist */ + } }; /* ------------------------------------------------------------------------- */ @@ -334,17 +209,36 @@ const iop_conf_t iop_conf_tab[4][32] = { * * the data is written to the FS6377 via the i2c bus using address in * "fs6377_addr" (address is 7 bits - R/W bit not included). + * + * The fs6377 has four clock outputs: A, B, C and D. + * + * Outputs C and D can each provide two different clock outputs C1/D1 or + * C2/D2 depending on the state of the SEL_CD input which is connected to + * the MPC8260 I/O port pin PA11. PA11 output (SEL_CD input) low (or 0) + * selects C1/D1 and PA11 output (SEL_CD input) high (or 1) selects C2/D2. + * + * PA11 defaults to output low (or 0) in the i/o port config table above. + * + * Output A provides a 100MHz for the High Speed Serial chips. Output B + * provides a 3.6864MHz clock for more accurate asynchronous serial bit + * rates. Output C is routed to the mezzanine connector but is currently + * unused - both C1 and C2 are set to 16MHz. Output D is used by both the + * alt-input and display mezzanine boards for their video chips. The + * alt-input board requires a clock of 24.576MHz and this is available on + * D1 (PA11=SEL_CD=0). The display board requires a clock of 27MHz and this + * is available on D2 (PA11=SEL_CD=1). + * + * So the default is a clock suitable for the alt-input board. PA11 is toggled + * later in misc_init_r(), if a display board is detected. */ uchar fs6377_addr = 0x5c; uchar fs6377_regs[16] = { - 12, 75, 64, 25, 144, 128, 25, 192, - 0, 16, 135, 192, 224, 64, 64, 192 + 12, 75, 64, 25, 144, 128, 25, 192, + 0, 16, 135, 192, 224, 64, 64, 192 }; -iopin_t pa11 = { IOPIN_PORTA, 11, 0 }; - /* ------------------------------------------------------------------------- */ /* @@ -356,7 +250,8 @@ iopin_t pa11 = { IOPIN_PORTA, 11, 0 }; * the timebase, for udelay()) */ -int board_postclk_init (void) +int +board_postclk_init (void) { i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); @@ -371,7 +266,7 @@ int board_postclk_init (void) * if this doesn't work */ (void) i2c_write (fs6377_addr, 0, 1, fs6377_regs, - sizeof (fs6377_regs)); + sizeof (fs6377_regs)); return (0); } @@ -382,7 +277,8 @@ int board_postclk_init (void) * Check Board Identity: Hardwired to HYMOD */ -int checkboard (void) +int +checkboard (void) { puts ("Board: HYMOD\n"); return (0); @@ -446,7 +342,8 @@ uint upmc_table[] = { _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_ }; -int misc_init_f (void) +int +misc_init_f (void) { volatile immap_t *immap = (immap_t *) CFG_IMMR; volatile memctl8260_t *memctl = &immap->im_memctl; @@ -465,7 +362,8 @@ int misc_init_f (void) /* ------------------------------------------------------------------------- */ -long initdram (int board_type) +long +initdram (int board_type) { volatile immap_t *immap = (immap_t *) CFG_IMMR; volatile memctl8260_t *memctl = &immap->im_memctl; @@ -523,280 +421,95 @@ long initdram (int board_type) /* containing information to be stored in the eeprom from the tftp server */ /* (the file name is based on the serial number and a built-in path) */ -/* these are relative to the root of the server's tftp directory */ -static char *bddb_cfgdir = "/hymod/bddb"; -static char *global_env_path = "/hymod/global_env"; - -static ulong get_serno (const char *prompt) -{ - for (;;) { - int n; - char *p; - ulong serno; - - n = readline (prompt); - - if (n < 0) - return (0); - - if (n == 0) - continue; - - serno = simple_strtol (console_buffer, &p, 10); - - if (p > console_buffer && *p == '\0') - return (serno); - - printf ("Invalid number (%s) - please re-enter\n", console_buffer); - } -} - -static int read_eeprom (char *label, unsigned offset, hymod_eeprom_t * ep) -{ - char filename[50], prompt[50]; - ulong serno; - int count = 0; - - sprintf (prompt, "Enter %s board serial number: ", label); - - for (;;) { - - if (eeprom_load (offset, ep)) - return (1); - - printf ("*** %s board EEPROM contents are %sinvalid\n", - label, count == 0 ? "" : "STILL "); - - puts ("*** will attempt to fetch from server (Ctrl-C to abort)\n"); - - if ((serno = get_serno (prompt)) == 0) { - puts ("\n*** interrupted! - ignoring eeprom contents\n"); - return (0); - } - - sprintf (filename, "%s/%010lu.cfg", bddb_cfgdir, serno); - - printf ("*** fetching %s board EEPROM contents from server\n", - label); - - if (eeprom_fetch (offset, filename, 0x100000) == 0) { - puts ("*** fetch failed - ignoring eeprom contents\n"); - return (0); - } - - count++; - } -} - -static ulong main_serno; - -static int env_fetch_callback (uchar * name, uchar * value) -{ - char *ov, nv[CFG_CBSIZE], *p, *q, *nn; - int override = 1, append = 0, nl; - - nn = name; - if (*nn == '-') { - override = 0; - nn++; - } - - if ((nl = strlen (nn)) > 0 && nn[nl - 1] == '+') { - append = 1; - nn[--nl] = '\0'; - } - - p = value; - q = nv; - - while ((*q = *p++) != '\0') - if (*q == '%') { - switch (*p++) { - - case '\0': /* whoops - back up */ - p--; - break; - - case '%': /* a single percent character */ - q++; - break; - - case 's': /* main board serial number as string */ - q += sprintf (q, "%010lu", main_serno); - break; - - case 'S': /* main board serial number as number */ - q += sprintf (q, "%lu", main_serno); - break; - - default: /* ignore any others */ - break; - } - } else - q++; - - if ((ov = getenv (nn)) != NULL) { - - if (append) { - - if (strstr (ov, nv) == NULL) { - int ovl, nvl; - - printf ("Appending '%s' to env cmd '%s'\n", nv, nn); - - ovl = strlen (ov); - nvl = strlen (nv); - - while (nvl >= 0) { - nv[ovl + 1 + nvl] = nv[nvl]; - nvl--; - } - - nv[ovl] = ' '; - - while (--ovl >= 0) - nv[ovl] = ov[ovl]; - - setenv (nn, nv); - } - - return (1); - } - - if (!override || strcmp (ov, nv) == 0) - return (1); - - printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", nn, ov, nv); - } else - printf ("Setting env cmd '%s' to '%s'\n", nn, nv); - - setenv (nn, nv); - return (1); -} - -int misc_init_r (void) +int +last_stage_init (void) { DECLARE_GLOBAL_DATA_PTR; hymod_conf_t *cp = &gd->bd->bi_hymod_conf; int rc; +#ifdef CONFIG_BOOT_RETRY_TIME + /* + * we use the readline () function, but we also want + * command timeout enabled + */ + init_cmd_timeout (); +#endif + memset ((void *) cp, 0, sizeof (*cp)); /* set up main board config info */ - if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MAIN)) { - - if (read_eeprom - ("main", HYMOD_EEOFF_MAIN << 8, &cp->main.eeprom)) - cp->main.eeprom_valid = 1; - - puts ("EEPROM:main..."); - - if (cp->main.eeprom_valid) { - printf ("OK (ver %u)\n", cp->main.eeprom.ver); - eeprom_print (&cp->main.eeprom); - main_serno = cp->main.eeprom.serno; - } else - puts ("BAD\n"); - - cp->main.mmap[0].prog.exists = 1; - cp->main.mmap[0].prog.size = FPGA_MAIN_CFG_SIZE; - cp->main.mmap[0].prog.base = FPGA_MAIN_CFG_BASE; - - cp->main.mmap[0].reg.exists = 1; - cp->main.mmap[0].reg.size = FPGA_MAIN_REG_SIZE; - cp->main.mmap[0].reg.base = FPGA_MAIN_REG_BASE; - - cp->main.mmap[0].port.exists = 1; - cp->main.mmap[0].port.size = FPGA_MAIN_PORT_SIZE; - cp->main.mmap[0].port.base = FPGA_MAIN_PORT_BASE; - - cp->main.iopins[0].prog_pin.port = FPGA_MAIN_PROG_PORT; - cp->main.iopins[0].prog_pin.pin = FPGA_MAIN_PROG_PIN; - cp->main.iopins[0].prog_pin.flag = 1; - cp->main.iopins[0].init_pin.port = FPGA_MAIN_INIT_PORT; - cp->main.iopins[0].init_pin.pin = FPGA_MAIN_INIT_PIN; - cp->main.iopins[0].init_pin.flag = 1; - cp->main.iopins[0].done_pin.port = FPGA_MAIN_DONE_PORT; - cp->main.iopins[0].done_pin.pin = FPGA_MAIN_DONE_PIN; - cp->main.iopins[0].done_pin.flag = 1; + rc = hymod_eeprom_read (0, &cp->main.eeprom); + + puts ("EEPROM:main..."); + if (rc < 0) + puts ("NOT PRESENT\n"); + else if (rc == 0) + puts ("INVALID\n"); + else { + cp->main.eeprom.valid = 1; + + printf ("OK (ver %u)\n", cp->main.eeprom.ver); + hymod_eeprom_print (&cp->main.eeprom); + + /* + * hard-wired assumption here: all hymod main boards will have + * one xilinx fpga, with the interrupt line connected to IRQ2 + * + * One day, this might be based on the board type + */ + + cp->main.xlx[0].mmap.prog.exists = 1; + cp->main.xlx[0].mmap.prog.size = FPGA_MAIN_CFG_SIZE; + cp->main.xlx[0].mmap.prog.base = FPGA_MAIN_CFG_BASE; + + cp->main.xlx[0].mmap.reg.exists = 1; + cp->main.xlx[0].mmap.reg.size = FPGA_MAIN_REG_SIZE; + cp->main.xlx[0].mmap.reg.base = FPGA_MAIN_REG_BASE; + + cp->main.xlx[0].mmap.port.exists = 1; + cp->main.xlx[0].mmap.port.size = FPGA_MAIN_PORT_SIZE; + cp->main.xlx[0].mmap.port.base = FPGA_MAIN_PORT_BASE; + + cp->main.xlx[0].iopins.prog_pin.port = FPGA_MAIN_PROG_PORT; + cp->main.xlx[0].iopins.prog_pin.pin = FPGA_MAIN_PROG_PIN; + cp->main.xlx[0].iopins.prog_pin.flag = 1; + cp->main.xlx[0].iopins.init_pin.port = FPGA_MAIN_INIT_PORT; + cp->main.xlx[0].iopins.init_pin.pin = FPGA_MAIN_INIT_PIN; + cp->main.xlx[0].iopins.init_pin.flag = 1; + cp->main.xlx[0].iopins.done_pin.port = FPGA_MAIN_DONE_PORT; + cp->main.xlx[0].iopins.done_pin.pin = FPGA_MAIN_DONE_PIN; + cp->main.xlx[0].iopins.done_pin.flag = 1; #ifdef FPGA_MAIN_ENABLE_PORT - cp->main.iopins[0].enable_pin.port = FPGA_MAIN_ENABLE_PORT; - cp->main.iopins[0].enable_pin.pin = FPGA_MAIN_ENABLE_PIN; - cp->main.iopins[0].enable_pin.flag = 1; + cp->main.xlx[0].iopins.enable_pin.port = FPGA_MAIN_ENABLE_PORT; + cp->main.xlx[0].iopins.enable_pin.pin = FPGA_MAIN_ENABLE_PIN; + cp->main.xlx[0].iopins.enable_pin.flag = 1; #endif - } else - puts ("EEPROM:main...NOT PRESENT\n"); - /* set up mezzanine board config info */ - - if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MEZZ)) { - - if (read_eeprom - ("mezz", HYMOD_EEOFF_MEZZ << 8, &cp->mezz.eeprom)) - cp->mezz.eeprom_valid = 1; - - puts ("EEPROM:mezz..."); - - if (cp->mezz.eeprom_valid) { - printf ("OK (ver %u)\n", cp->mezz.eeprom.ver); - eeprom_print (&cp->mezz.eeprom); - } else - puts ("BAD\n"); - - cp->mezz.mmap[0].prog.exists = 1; - cp->mezz.mmap[0].prog.size = FPGA_MEZZ_CFG_SIZE; - cp->mezz.mmap[0].prog.base = FPGA_MEZZ_CFG_BASE; - - cp->mezz.mmap[0].reg.exists = 0; - - cp->mezz.mmap[0].port.exists = 0; - - cp->mezz.iopins[0].prog_pin.port = FPGA_MEZZ_PROG_PORT; - cp->mezz.iopins[0].prog_pin.pin = FPGA_MEZZ_PROG_PIN; - cp->mezz.iopins[0].prog_pin.flag = 1; - cp->mezz.iopins[0].init_pin.port = FPGA_MEZZ_INIT_PORT; - cp->mezz.iopins[0].init_pin.pin = FPGA_MEZZ_INIT_PIN; - cp->mezz.iopins[0].init_pin.flag = 1; - cp->mezz.iopins[0].done_pin.port = FPGA_MEZZ_DONE_PORT; - cp->mezz.iopins[0].done_pin.pin = FPGA_MEZZ_DONE_PIN; - cp->mezz.iopins[0].done_pin.flag = 1; -#ifdef FPGA_MEZZ_ENABLE_PORT - cp->mezz.iopins[0].enable_pin.port = FPGA_MEZZ_ENABLE_PORT; - cp->mezz.iopins[0].enable_pin.pin = FPGA_MEZZ_ENABLE_PIN; - cp->mezz.iopins[0].enable_pin.flag = 1; -#endif + cp->main.xlx[0].irq = FPGA_MAIN_IRQ; + } - if (cp->mezz.eeprom_valid && - cp->mezz.eeprom.bdtype == HYMOD_BDTYPE_DISPLAY) { - /* - * mezzanine board is a display board - switch the SEL_CD - * input of the FS6377 clock generator (via I/O Port Pin PA11) to - * high (or 1) to select the 27MHz required by the display board - */ - iopin_set_high (&pa11); + /* set up mezzanine board config info */ - puts ("SEL_CD:toggled for display board\n"); - } - } else - puts ("EEPROM:mezz...NOT PRESENT\n"); + rc = hymod_eeprom_read (1, &cp->mezz.eeprom); - cp->crc = - crc32 (0, (unsigned char *) cp, offsetof (hymod_conf_t, crc)); + puts ("EEPROM:mezz..."); + if (rc < 0) + puts ("NOT PRESENT\n"); + else if (rc == 0) + puts ("INVALID\n"); + else { + cp->main.eeprom.valid = 1; - if (getenv ("global_env_loaded") == NULL) { + printf ("OK (ver %u)\n", cp->mezz.eeprom.ver); + hymod_eeprom_print (&cp->mezz.eeprom); + } - puts ("*** global environment has not been loaded\n"); - puts ("*** fetching from server (Control-C to Abort)\n"); + cp->crc = crc32 (0, (unsigned char *)cp, offsetof (hymod_conf_t, crc)); - rc = fetch_and_parse (global_env_path, 0x100000, - env_fetch_callback); + hymod_check_env (); - if (rc == 0) - puts ("*** Fetch of environment failed!\n"); - else - setenv ("global_env_loaded", "yes"); - } return (0); } diff --git a/board/hymod/hymod.h b/board/hymod/hymod.h new file mode 100644 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 100644 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); + } +} |