From d04075478d378d9e15f3e1abfd14b0bd124077d4 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 15 Nov 2014 11:48:36 +0800 Subject: init commit via android 4.4 uboot --- board/hymod/Makefile | 40 +++ board/hymod/bsp.c | 407 +++++++++++++++++++++++++ board/hymod/config.mk | 32 ++ board/hymod/eeprom.c | 694 +++++++++++++++++++++++++++++++++++++++++++ board/hymod/env.c | 236 +++++++++++++++ board/hymod/fetch.c | 107 +++++++ board/hymod/flash.c | 506 +++++++++++++++++++++++++++++++ board/hymod/flash.h | 156 ++++++++++ board/hymod/global_env | 161 ++++++++++ board/hymod/hymod.c | 537 +++++++++++++++++++++++++++++++++ board/hymod/hymod.h | 322 ++++++++++++++++++++ board/hymod/input.c | 113 +++++++ board/hymod/u-boot.lds | 148 +++++++++ board/hymod/u-boot.lds.debug | 137 +++++++++ 14 files changed, 3596 insertions(+) create mode 100755 board/hymod/Makefile create mode 100755 board/hymod/bsp.c create mode 100755 board/hymod/config.mk create mode 100755 board/hymod/eeprom.c create mode 100755 board/hymod/env.c create mode 100755 board/hymod/fetch.c create mode 100755 board/hymod/flash.c create mode 100755 board/hymod/flash.h create mode 100755 board/hymod/global_env create mode 100755 board/hymod/hymod.c create mode 100755 board/hymod/hymod.h create mode 100755 board/hymod/input.c create mode 100755 board/hymod/u-boot.lds create mode 100755 board/hymod/u-boot.lds.debug (limited to 'board/hymod') diff --git a/board/hymod/Makefile b/board/hymod/Makefile new file mode 100755 index 0000000..b52af9a --- /dev/null +++ b/board/hymod/Makefile @@ -0,0 +1,40 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS = $(BOARD).o flash.o bsp.o eeprom.o fetch.o input.o env.o + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/hymod/bsp.c b/board/hymod/bsp.c new file mode 100755 index 0000000..0596fa4 --- /dev/null +++ b/board/hymod/bsp.c @@ -0,0 +1,407 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * hacked for Hymod FPGA support by Murray.Jensen@csiro.au, 29-Jan-01 + */ + +#include +#include +#include +#include + +/*----------------------------------------------------------------------- + * Board Special Commands: FPGA load/store, EEPROM erase + */ + +#if (CONFIG_COMMANDS & CFG_CMD_BSP) + +#define LOAD_SUCCESS 0 +#define LOAD_FAIL_NOCONF 1 +#define LOAD_FAIL_NOINIT 2 +#define LOAD_FAIL_NODONE 3 + +#define STORE_SUCCESS 0 + +/* + * Programming the Hymod FPGAs + * + * The 8260 io port config table is set up so that the INIT pin is + * held Low (Open Drain output 0) - this will delay the automatic + * Power-On config until INIT is released (by making it an input). + * + * If the FPGA has been programmed before, then the assertion of PROGRAM + * will initiate configuration (i.e. it begins clearing the RAM). + * + * When the FPGA is ready to receive configuration data (either after + * releasing INIT after Power-On, or after asserting PROGRAM), it will + * pull INIT high. + * + * Notes from Paul Dunn: + * + * 1. program pin should be forced low for >= 300ns + * (about 20 bus clock cycles minimum). + * + * 2. then wait for init to go high, which signals + * that the FPGA has cleared its internal memory + * and is ready to load + * + * 3. perform load writes of entire config file + * + * 4. wait for done to go high, which should be + * within a few bus clock cycles. If done has not + * gone high after reasonable period, then load + * has not worked (wait several ms?) + */ + +int +fpga_load (int mezz, uchar *addr, ulong size) +{ + DECLARE_GLOBAL_DATA_PTR; + + hymod_conf_t *cp = &gd->bd->bi_hymod_conf; + xlx_info_t *fp; + xlx_iopins_t *fpgaio; + volatile uchar *fpgabase; + volatile uint cnt; + uchar *eaddr = addr + size; + int result; + + if (mezz) + fp = &cp->mezz.xlx[0]; + else + fp = &cp->main.xlx[0]; + + if (!fp->mmap.prog.exists) + return (LOAD_FAIL_NOCONF); + + fpgabase = (uchar *)fp->mmap.prog.base; + fpgaio = &fp->iopins; + + /* set enable HIGH if required */ + if (fpgaio->enable_pin.flag) + iopin_set_high (&fpgaio->enable_pin); + + /* ensure INIT is released (set it to be an input) */ + iopin_set_in (&fpgaio->init_pin); + + /* toggle PROG Low then High (will already be Low after Power-On) */ + iopin_set_low (&fpgaio->prog_pin); + udelay (1); /* minimum 300ns - 1usec should do it */ + iopin_set_high (&fpgaio->prog_pin); + + /* wait for INIT High */ + cnt = 0; + while (!iopin_is_high (&fpgaio->init_pin)) + if (++cnt == 10000000) { + result = LOAD_FAIL_NOINIT; + goto done; + } + + /* write configuration data */ + while (addr < eaddr) + *fpgabase = *addr++; + + /* wait for DONE High */ + cnt = 0; + while (!iopin_is_high (&fpgaio->done_pin)) + if (++cnt == 100000000) { + result = LOAD_FAIL_NODONE; + goto done; + } + + /* success */ + result = LOAD_SUCCESS; + + done: + + if (fpgaio->enable_pin.flag) + iopin_set_low (&fpgaio->enable_pin); + + return (result); +} + +/* ------------------------------------------------------------------------- */ +int +do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + uchar *addr, *save_addr; + ulong size; + int mezz, arg, result; + + switch (argc) { + + case 0: + case 1: + break; + + case 2: + if (strcmp (argv[1], "info") == 0) { + printf ("\nHymod FPGA Info...\n"); + printf ("\t\t\t\tAddress\t\tSize\n"); + printf ("\tMain Configuration:\t0x%08x\t%d\n", + FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE); + printf ("\tMain Register:\t\t0x%08x\t%d\n", + FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE); + printf ("\tMain Port:\t\t0x%08x\t%d\n", + FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE); + printf ("\tMezz Configuration:\t0x%08x\t%d\n", + FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE); + return 0; + } + break; + + case 3: + if (strcmp (argv[1], "store") == 0) { + addr = (uchar *) simple_strtoul (argv[2], NULL, 16); + + save_addr = addr; +#if 0 + /* fpga readback unimplemented */ + while (more readback data) + *addr++ = *fpga; + result = error ? STORE_FAIL_XXX : STORE_SUCCESS; +#else + result = STORE_SUCCESS; +#endif + + if (result == STORE_SUCCESS) { + printf ("SUCCEEDED (%d bytes)\n", + addr - save_addr); + return 0; + } else + printf ("FAILED (%d bytes)\n", + addr - save_addr); + return 1; + } + break; + + case 4: + if (strcmp (argv[1], "tftp") == 0) { + copy_filename (BootFile, argv[2], sizeof (BootFile)); + load_addr = simple_strtoul (argv[3], NULL, 16); + NetBootFileXferSize = 0; + + if (NetLoop (TFTP) <= 0) { + printf ("tftp transfer failed - aborting " + "fgpa load\n"); + return 1; + } + + if (NetBootFileXferSize == 0) { + printf ("can't determine file size - " + "aborting fpga load\n"); + return 1; + } + + printf ("File transfer succeeded - " + "beginning fpga load..."); + + result = fpga_load (0, (uchar *) load_addr, + NetBootFileXferSize); + + if (result == LOAD_SUCCESS) { + printf ("SUCCEEDED\n"); + return 0; + } else if (result == LOAD_FAIL_NOCONF) + printf ("FAILED (no CONF)\n"); + else if (result == LOAD_FAIL_NOINIT) + printf ("FAILED (no INIT)\n"); + else + printf ("FAILED (no DONE)\n"); + return 1; + + } + /* fall through ... */ + + case 5: + if (strcmp (argv[1], "load") == 0) { + if (argc == 5) { + if (strcmp (argv[2], "main") == 0) + mezz = 0; + else if (strcmp (argv[2], "mezz") == 0) + mezz = 1; + else { + printf ("FPGA type must be either " + "`main' or `mezz'\n"); + return 1; + } + arg = 3; + } else { + mezz = 0; + arg = 2; + } + + addr = (uchar *) simple_strtoul (argv[arg++], NULL, 16); + size = (ulong) simple_strtoul (argv[arg], NULL, 16); + + result = fpga_load (mezz, addr, size); + + if (result == LOAD_SUCCESS) { + printf ("SUCCEEDED\n"); + return 0; + } else if (result == LOAD_FAIL_NOCONF) + printf ("FAILED (no CONF)\n"); + else if (result == LOAD_FAIL_NOINIT) + printf ("FAILED (no INIT)\n"); + else + printf ("FAILED (no DONE)\n"); + return 1; + } + break; + + default: + break; + } + + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; +} +U_BOOT_CMD( + fpga, 6, 1, do_fpga, + "fpga - FPGA sub-system\n", + "load [type] addr size\n" + " - write the configuration data at memory address `addr',\n" + " size `size' bytes, into the FPGA of type `type' (either\n" + " `main' or `mezz', default `main'). e.g.\n" + " `fpga load 100000 7d8f'\n" + " loads the main FPGA with config data at address 100000\n" + " HEX, size 7d8f HEX (32143 DEC) bytes\n" + "fpga tftp file addr\n" + " - transfers `file' from the tftp server into memory at\n" + " address `addr', then writes the entire file contents\n" + " into the main FPGA\n" + "fpga store addr\n" + " - read configuration data from the main FPGA (the mezz\n" + " FPGA is write-only), into address `addr'. There must be\n" + " enough memory available at `addr' to hold all the config\n" + " data - the size of which is determined by VC:???\n" + "fpga info\n" + " - print information about the Hymod FPGA, namely the\n" + " memory addresses at which the four FPGA local bus\n" + " address spaces appear in the physical address space\n" +); +/* ------------------------------------------------------------------------- */ +int +do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + uchar data[HYMOD_EEPROM_SIZE]; + uint addr = CFG_I2C_EEPROM_ADDR; + + switch (argc) { + + case 1: + addr |= HYMOD_EEOFF_MAIN; + break; + + case 2: + if (strcmp (argv[1], "main") == 0) { + addr |= HYMOD_EEOFF_MAIN; + break; + } + if (strcmp (argv[1], "mezz") == 0) { + addr |= HYMOD_EEOFF_MEZZ; + break; + } + /* fall through ... */ + + default: + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + memset (data, 0, HYMOD_EEPROM_SIZE); + + eeprom_write (addr, 0, data, HYMOD_EEPROM_SIZE); + + return 0; +} +U_BOOT_CMD( + eeclear, 1, 0, do_eecl, + "eeclear - Clear the eeprom on a Hymod board \n", + "[type]\n" + " - write zeroes into the EEPROM on the board of type `type'\n" + " (`type' is either `main' or `mezz' - default `main')\n" + " Note: the EEPROM write enable jumper must be installed\n" +); + +/* ------------------------------------------------------------------------- */ + +int +do_htest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +#if 0 + int rc; +#endif +#ifdef CONFIG_ETHER_LOOPBACK_TEST + extern void eth_loopback_test (void); +#endif /* CONFIG_ETHER_LOOPBACK_TEST */ + + printf ("HYMOD tests - ensure loopbacks etc. are connected\n\n"); + +#if 0 + /* Load FPGA with test program */ + + printf ("Loading test FPGA program ..."); + + rc = fpga_load (0, test_bitfile, sizeof (test_bitfile)); + + switch (rc) { + + case LOAD_SUCCESS: + printf (" SUCCEEDED\n"); + break; + + case LOAD_FAIL_NOCONF: + printf (" FAILED (no configuration space defined)\n"); + return 1; + + case LOAD_FAIL_NOINIT: + printf (" FAILED (timeout - no INIT signal seen)\n"); + return 1; + + case LOAD_FAIL_NODONE: + printf (" FAILED (timeout - no DONE signal seen)\n"); + return 1; + + default: + printf (" FAILED (unknown return code from fpga_load\n"); + return 1; + } + + /* run Local Bus <=> Xilinx tests */ + + /* tell Xilinx to run ZBT Ram, High Speed serial and Mezzanine tests */ + + /* run SDRAM test */ +#endif + +#ifdef CONFIG_ETHER_LOOPBACK_TEST + /* run Ethernet test */ + eth_loopback_test (); +#endif /* CONFIG_ETHER_LOOPBACK_TEST */ + + return 0; +} + +#endif /* CFG_CMD_BSP */ + +/* ------------------------------------------------------------------------- */ diff --git a/board/hymod/config.mk b/board/hymod/config.mk new file mode 100755 index 0000000..0a9985f --- /dev/null +++ b/board/hymod/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# HYMOD boards +# + +TEXT_BASE = 0x40000000 + +PLATFORM_CPPFLAGS += -I$(TOPDIR) + +OBJCFLAGS = --remove-section=.ppcenv diff --git a/board/hymod/eeprom.c b/board/hymod/eeprom.c new file mode 100755 index 0000000..c9b9b18 --- /dev/null +++ b/board/hymod/eeprom.c @@ -0,0 +1,694 @@ +/* + * (C) Copyright 2001 + * Murray Jensen, CSIRO-MIT, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* imports from fetch.c */ +extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); + +/* imports from input.c */ +extern int hymod_get_serno (const char *); + +/* this is relative to the root of the server's tftp directory */ +static char *def_bddb_cfgdir = "/hymod/bddb"; + +static int +hymod_eeprom_load (int which, hymod_eeprom_t *ep) +{ + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + unsigned offset = 0; + uchar data[HYMOD_EEPROM_MAXLEN], *dp, *edp; + hymod_eehdr_t hdr; + ulong len, crc; + + memset (ep, 0, sizeof *ep); + + eeprom_read (dev_addr, offset, (uchar *)&hdr, sizeof (hdr)); + offset += sizeof (hdr); + + if (hdr.id != HYMOD_EEPROM_ID || hdr.ver > HYMOD_EEPROM_VER || + (len = hdr.len) > HYMOD_EEPROM_MAXLEN) + return (0); + + eeprom_read (dev_addr, offset, data, len); + offset += len; + + eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong)); + offset += sizeof (ulong); + + if (crc32 (crc32 (0, (uchar *)&hdr, sizeof hdr), data, len) != crc) + return (0); + + ep->ver = hdr.ver; + dp = data; edp = dp + len; + + for (;;) { + ulong rtyp; + uchar rlen, *rdat; + + rtyp = *dp++; + if ((rtyp & 0x80) == 0) + rlen = *dp++; + else { + uchar islarge = rtyp & 0x40; + + rtyp = ((rtyp & 0x3f) << 8) | *dp++; + if (islarge) { + rtyp = (rtyp << 8) | *dp++; + rtyp = (rtyp << 8) | *dp++; + } + + rlen = *dp++; + rlen = (rlen << 8) | *dp++; + if (islarge) { + rlen = (rlen << 8) | *dp++; + rlen = (rlen << 8) | *dp++; + } + } + + if (rtyp == 0) + break; + + rdat = dp; + dp += rlen; + + if (dp > edp) /* error? */ + break; + + switch (rtyp) { + + case HYMOD_EEREC_SERNO: /* serial number */ + if (rlen == sizeof (ulong)) + ep->serno = \ + ((ulong)rdat[0] << 24) | \ + ((ulong)rdat[1] << 16) | \ + ((ulong)rdat[2] << 8) | \ + (ulong)rdat[3]; + break; + + case HYMOD_EEREC_DATE: /* date */ + if (rlen == sizeof (hymod_date_t)) { + ep->date.year = ((ushort)rdat[0] << 8) | \ + (ushort)rdat[1]; + ep->date.month = rdat[2]; + ep->date.day = rdat[3]; + } + break; + + case HYMOD_EEREC_BATCH: /* batch */ + if (rlen <= HYMOD_MAX_BATCH) + memcpy (ep->batch, rdat, ep->batchlen = rlen); + break; + + case HYMOD_EEREC_TYPE: /* board type */ + if (rlen == 1) + ep->bdtype = *rdat; + break; + + case HYMOD_EEREC_REV: /* board revision */ + if (rlen == 1) + ep->bdrev = *rdat; + break; + + case HYMOD_EEREC_SDRAM: /* sdram size(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) { + int i; + + for (i = 0; i < rlen; i++) + ep->sdramsz[i] = rdat[i]; + ep->nsdram = rlen; + } + break; + + case HYMOD_EEREC_FLASH: /* flash size(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) { + int i; + + for (i = 0; i < rlen; i++) + ep->flashsz[i] = rdat[i]; + ep->nflash = rlen; + } + break; + + case HYMOD_EEREC_ZBT: /* zbt ram size(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) { + int i; + + for (i = 0; i < rlen; i++) + ep->zbtsz[i] = rdat[i]; + ep->nzbt = rlen; + } + break; + + case HYMOD_EEREC_XLXTYP: /* xilinx fpga type(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].type = rdat[i]; + ep->nxlx = rlen; + } + break; + + case HYMOD_EEREC_XLXSPD: /* xilinx fpga speed(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].speed = rdat[i]; + } + break; + + case HYMOD_EEREC_XLXTMP: /* xilinx fpga temperature(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].temp = rdat[i]; + } + break; + + case HYMOD_EEREC_XLXGRD: /* xilinx fpga grade(s) */ + if (rlen > 0 && rlen <= HYMOD_MAX_XLX) { + int i; + + for (i = 0; i < rlen; i++) + ep->xlx[i].grade = rdat[i]; + } + break; + + case HYMOD_EEREC_CPUTYP: /* CPU type */ + if (rlen == 1) + ep->mpc.type = *rdat; + break; + + case HYMOD_EEREC_CPUSPD: /* CPU speed */ + if (rlen == 1) + ep->mpc.cpuspd = *rdat; + break; + + case HYMOD_EEREC_CPMSPD: /* CPM speed */ + if (rlen == 1) + ep->mpc.cpmspd = *rdat; + break; + + case HYMOD_EEREC_BUSSPD: /* bus speed */ + if (rlen == 1) + ep->mpc.busspd = *rdat; + break; + + case HYMOD_EEREC_HSTYPE: /* hs-serial chip type */ + if (rlen == 1) + ep->hss.type = *rdat; + break; + + case HYMOD_EEREC_HSCHIN: /* num hs-serial input chans */ + if (rlen == 1) + ep->hss.nchin = *rdat; + break; + + case HYMOD_EEREC_HSCHOUT: /* num hs-serial output chans */ + if (rlen == 1) + ep->hss.nchout = *rdat; + break; + + default: /* ignore */ + break; + } + } + + return (1); +} + +/* maps an ascii "name=value" into a binary eeprom data record */ +typedef + struct _eerec_map { + char *name; + uint type; + uchar *(*handler) \ + (struct _eerec_map *, uchar *, uchar *, uchar *); + uint length; + uint maxlen; + } +eerec_map_t; + +static uchar * +uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) +{ + char *eval; + ulong lval; + + lval = simple_strtol ((char *)val, &eval, 10); + + if ((uchar *)eval == val || *eval != '\0') { + printf ("%s rec (%s) is not a valid uint\n", rp->name, val); + return (NULL); + } + + if (dp + 2 + rp->length > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } + + *dp++ = rp->type; + *dp++ = rp->length; + + switch (rp->length) { + + case 1: + if (lval >= 256) { + printf ("%s rec value (%lu) out of range (0-255)\n", + rp->name, lval); + return (NULL); + } + *dp++ = lval; + break; + + case 2: + if (lval >= 65536) { + printf ("%s rec value (%lu) out of range (0-65535)\n", + rp->name, lval); + return (NULL); + } + *dp++ = lval >> 8; + *dp++ = lval; + break; + + case 4: + *dp++ = lval >> 24; + *dp++ = lval >> 16; + *dp++ = lval >> 8; + *dp++ = lval; + break; + + default: + printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length); + return (NULL); + } + + return (dp); +} + +static uchar * +date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) +{ + hymod_date_t date; + char *p = (char *)val; + char *ep; + ulong lval; + + lval = simple_strtol (p, &ep, 10); + if (ep == p || *ep++ != '-') { +bad_date: + printf ("%s rec (%s) is not a valid date\n", rp->name, val); + return (NULL); + } + if (lval >= 65536) + goto bad_date; + date.year = lval; + + lval = simple_strtol (p = ep, &ep, 10); + if (ep == p || *ep++ != '-' || lval == 0 || lval > 12) + goto bad_date; + date.month = lval; + + lval = simple_strtol (p = ep, &ep, 10); + if (ep == p || *ep != '\0' || lval == 0 || lval > 31) + goto bad_date; + date.day = lval; + + if (dp + 2 + rp->length > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } + + *dp++ = rp->type; + *dp++ = rp->length; + *dp++ = date.year >> 8; + *dp++ = date.year; + *dp++ = date.month; + *dp++ = date.day; + + return (dp); +} + +static uchar * +string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) +{ + uint len; + + if ((len = strlen ((char *)val)) > rp->maxlen) { + printf ("%s rec (%s) string is too long (%d>%d)\n", + rp->name, val, len, rp->maxlen); + return (NULL); + } + + if (dp + 2 + len > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } + + *dp++ = rp->type; + *dp++ = len; + memcpy (dp, val, len); + dp += len; + + return (dp); +} + +static uchar * +bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp) +{ + uchar bytes[HYMOD_MAX_BYTES], nbytes, *p; + char *ep; + + for (nbytes = 0, p = val; *p != '\0'; p = (uchar *)ep) { + ulong lval; + + lval = simple_strtol ((char *)p, &ep, 10); + if ((uchar *)ep == p || (*ep != '\0' && *ep != ',') || \ + lval >= 256) { + printf ("%s rec (%s) byte array has invalid uint\n", + rp->name, val); + return (NULL); + } + if (nbytes >= HYMOD_MAX_BYTES) { + printf ("%s rec (%s) byte array too long\n", + rp->name, val); + return (NULL); + } + bytes[nbytes++] = lval; + + if (*ep != '\0') + ep++; + } + + if (dp + 2 + nbytes > edp) { + printf ("can't fit %s rec into eeprom\n", rp->name); + return (NULL); + } + + *dp++ = rp->type; + *dp++ = nbytes; + memcpy (dp, bytes, nbytes); + dp += nbytes; + + return (dp); +} + +static eerec_map_t eerec_map[] = { + /* name type handler len max */ + { "serno", HYMOD_EEREC_SERNO, uint_handler, 4, 0 }, + { "date", HYMOD_EEREC_DATE, date_handler, 4, 0 }, + { "batch", HYMOD_EEREC_BATCH, string_handler, 0, HYMOD_MAX_BATCH }, + { "type", HYMOD_EEREC_TYPE, uint_handler, 1, 0 }, + { "rev", HYMOD_EEREC_REV, uint_handler, 1, 0 }, + { "sdram", HYMOD_EEREC_SDRAM, bytes_handler, 0, HYMOD_MAX_SDRAM }, + { "flash", HYMOD_EEREC_FLASH, bytes_handler, 0, HYMOD_MAX_FLASH }, + { "zbt", HYMOD_EEREC_ZBT, bytes_handler, 0, HYMOD_MAX_ZBT }, + { "xlxtyp", HYMOD_EEREC_XLXTYP, bytes_handler, 0, HYMOD_MAX_XLX }, + { "xlxspd", HYMOD_EEREC_XLXSPD, bytes_handler, 0, HYMOD_MAX_XLX }, + { "xlxtmp", HYMOD_EEREC_XLXTMP, bytes_handler, 0, HYMOD_MAX_XLX }, + { "xlxgrd", HYMOD_EEREC_XLXGRD, bytes_handler, 0, HYMOD_MAX_XLX }, + { "cputyp", HYMOD_EEREC_CPUTYP, uint_handler, 1, 0 }, + { "cpuspd", HYMOD_EEREC_CPUSPD, uint_handler, 1, 0 }, + { "cpmspd", HYMOD_EEREC_CPMSPD, uint_handler, 1, 0 }, + { "busspd", HYMOD_EEREC_BUSSPD, uint_handler, 1, 0 }, + { "hstype", HYMOD_EEREC_HSTYPE, uint_handler, 1, 0 }, + { "hschin", HYMOD_EEREC_HSCHIN, uint_handler, 1, 0 }, + { "hschout", HYMOD_EEREC_HSCHOUT, uint_handler, 1, 0 }, +}; + +static int neerecs = sizeof eerec_map / sizeof eerec_map[0]; + +static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp; + +static int +eerec_callback (uchar *name, uchar *val) +{ + eerec_map_t *rp; + + for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++) + if (strcmp ((char *)name, rp->name) == 0) + break; + + if (rp >= &eerec_map[neerecs]) + return (0); + + if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL) + return (0); + + return (1); +} + +static int +hymod_eeprom_fetch(int which, char *filename, ulong addr) +{ + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0]; + ulong crc; + + memset (hp, 0, sizeof *hp); + hp->id = HYMOD_EEPROM_ID; + hp->ver = HYMOD_EEPROM_VER; + + dp = sdp = (uchar *)(hp + 1); + edp = dp + HYMOD_EEPROM_MAXLEN; + + if (fetch_and_parse (filename, addr, eerec_callback) == 0) + return (0); + + hp->len = dp - sdp; + + crc = crc32 (0, data, dp - data); + memcpy (dp, &crc, sizeof (ulong)); + dp += sizeof (ulong); + + eeprom_write (dev_addr, 0, data, dp - data); + + return (1); +} + +static char *type_vals[] = { + "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY" +}; + +static char *xlxtyp_vals[] = { + "NONE", "XCV300E", "XCV400E", "XCV600E" +}; + +static char *xlxspd_vals[] = { + "NONE", "6", "7", "8" +}; + +static char *xlxtmp_vals[] = { + "NONE", "COM", "IND" +}; + +static char *xlxgrd_vals[] = { + "NONE", "NORMAL", "ENGSAMP" +}; + +static char *cputyp_vals[] = { + "NONE", "MPC8260" +}; + +static char *clk_vals[] = { + "NONE", "33", "66", "100", "133", "166", "200" +}; + +static char *hstype_vals[] = { + "NONE", "AMCC-S2064A" +}; + +static void +print_mem (char *l, char *s, uchar n, uchar a[]) +{ + if (n > 0) { + if (n == 1) + printf ("%s%dMB %s", s, 1 << (a[0] - 20), l); + else { + ulong t = 0; + int i; + + for (i = 0; i < n; i++) + t += 1 << (a[i] - 20); + + printf ("%s%luMB %s (%d banks:", s, t, l, n); + + for (i = 0; i < n; i++) + printf ("%dMB%s", + 1 << (a[i] - 20), + (i == n - 1) ? ")" : ","); + } + } + else + printf ("%sNO %s", s, l); +} + +void +hymod_eeprom_print (hymod_eeprom_t *ep) +{ + int i; + + printf (" Hymod %s board, rev %03d\n", + type_vals[ep->bdtype], ep->bdrev); + + printf (" serial #: %010lu, date %04d-%02d-%02d", + ep->serno, ep->date.year, ep->date.month, ep->date.day); + if (ep->batchlen > 0) + printf (", batch \"%.*s\"", ep->batchlen, ep->batch); + puts ("\n"); + + switch (ep->bdtype) { + + case HYMOD_BDTYPE_IO: + case HYMOD_BDTYPE_CLP: + case HYMOD_BDTYPE_DSP: + printf (" Motorola %s CPU, speeds: %s/%s/%s", + cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd], + clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]); + + print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz); + + print_mem ("FLASH", ", ", ep->nflash, ep->flashsz); + + puts ("\n"); + + print_mem ("ZBT", " ", ep->nzbt, ep->zbtsz); + + if (ep->nxlx > 0) { + hymod_xlx_t *xp; + + if (ep->nxlx == 1) { + xp = &ep->xlx[0]; + printf (", Xilinx %s FPGA (%s/%s/%s)", + xlxtyp_vals[xp->type], + xlxspd_vals[xp->speed], + xlxtmp_vals[xp->temp], + xlxgrd_vals[xp->grade]); + } + else { + printf (", %d Xilinx FPGAs (", ep->nxlx); + for (i = 0; i < ep->nxlx; i++) { + xp = &ep->xlx[i]; + printf ("%s[%s/%s/%s]%s", + xlxtyp_vals[xp->type], + xlxspd_vals[xp->speed], + xlxtmp_vals[xp->temp], + xlxgrd_vals[xp->grade], + (i == ep->nxlx - 1) ? ")" : ", "); + } + } + } + else + puts(", NO FPGAs"); + + puts ("\n"); + + if (ep->hss.type > 0) + printf (" High Speed Serial: " + "%s, %d input%s, %d output%s\n", + hstype_vals[ep->hss.type], + ep->hss.nchin, + (ep->hss.nchin == 1 ? "" : "s"), + ep->hss.nchout, + (ep->hss.nchout == 1 ? "" : "s")); + break; + + case HYMOD_BDTYPE_INPUT: + case HYMOD_BDTYPE_ALTINPUT: + case HYMOD_BDTYPE_DISPLAY: + break; + + default: + /* crap! */ + printf (" UNKNOWN BOARD TYPE: %d\n", ep->bdtype); + break; + } +} + +int +hymod_eeprom_read (int which, hymod_eeprom_t *ep) +{ + char *label = which ? "mezzanine" : "main"; + unsigned dev_addr = CFG_I2C_EEPROM_ADDR | \ + (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN); + char filename[50], prompt[50], *dir; + int serno, count = 0, rc; + + rc = eeprom_probe (dev_addr, 0); + + if (rc > 0) { + printf ("*** probe for eeprom failed with code %d\n", rc); + return (0); + } + + if (rc < 0) + return (rc); + + sprintf (prompt, "Enter %s board serial number: ", label); + + if ((dir = getenv ("bddb_cfgdir")) == NULL) + dir = def_bddb_cfgdir; + + for (;;) { + int rc; + + if (hymod_eeprom_load (which, ep)) + return (1); + + printf ("*** %s board EEPROM contents are %sinvalid\n", + label, count == 0 ? "" : "STILL "); + + puts ("*** will fetch from server (Ctrl-C to abort)\n"); + + serno = hymod_get_serno (prompt); + + if (serno < 0) { + if (serno == -1) + puts ("\n*** interrupted!"); + else + puts ("\n*** timeout!"); + puts (" - ignoring eeprom contents\n"); + return (0); + } + + sprintf (filename, "%s/%010d.cfg", dir, serno); + + printf ("*** fetching %s board EEPROM contents from server\n", + label); + + rc = hymod_eeprom_fetch (which, filename, CFG_LOAD_ADDR); + + if (rc == 0) { + puts ("*** fetch failed - ignoring eeprom contents\n"); + return (0); + } + + count++; + } +} diff --git a/board/hymod/env.c b/board/hymod/env.c new file mode 100755 index 0000000..f9e1421 --- /dev/null +++ b/board/hymod/env.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2003 + * Murray Jensen, CSIRO-MIT, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/* imports from fetch.c */ +extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); + +/* this is relative to the root of the server's tftp directory */ +static char *def_global_env_path = "/hymod/global_env"; + +static int +env_callback (uchar *name, uchar *value) +{ + DECLARE_GLOBAL_DATA_PTR; + + hymod_conf_t *cp = &gd->bd->bi_hymod_conf; + char ov[CFG_CBSIZE], nv[CFG_CBSIZE], *p, *q, *nn, c, *curver, *newver; + int override = 1, append = 0, remove = 0, nnl, ovl, nvl; + + nn = (char *)name; + + if (*nn == '-') { + override = 0; + nn++; + } + + while (*nn == ' ' || *nn == '\t') + nn++; + + if ((nnl = strlen (nn)) == 0) { + printf ("Empty name in global env file\n"); + return (0); + } + + if ((c = nn[nnl - 1]) == '+' || c == '-') { + if (c == '+') + append = 1; + else + remove = 1; + nn[--nnl] = '\0'; + } + + while (nnl > 0 && ((c = nn[nnl - 1]) == ' ' || c == '\t')) + nn[--nnl] = '\0'; + if (nnl == 0) { + printf ("Empty name in global env file\n"); + return (0); + } + + p = (char *)value; + q = nv; + + while ((c = *p) == ' ' || c == '\t') + p++; + + nvl = strlen (p); + while (nvl > 0 && ((c = p[nvl - 1]) == ' ' || c == '\t')) + p[--nvl] = '\0'; + + while ((*q = *p++) != '\0') { + if (*q == '%') { + switch (*p++) { + + case '\0': /* whoops - back up */ + p--; + break; + + case '%': /* a single percent character */ + q++; + break; + + case 's': /* main board serial number as string */ + q += sprintf (q, "%010lu", + cp->main.eeprom.serno); + break; + + case 'S': /* main board serial number as number */ + q += sprintf (q, "%lu", cp->main.eeprom.serno); + break; + + default: /* ignore any others */ + break; + } + } + else + q++; + } + + if ((nvl = q - nv) == 0) { + setenv (nn, NULL); + return (1); + } + + if ((curver = getenv ("global_env_version")) == NULL) + curver = "unknown"; + + if ((newver = getenv ("new_genv_version")) == NULL || \ + strcmp (curver, newver) == 0) { + if (strcmp (nn, "version") == 0) + setenv ("new_genv_version", nv); + return (1); + } + + if ((p = getenv (nn)) != NULL) { + + strcpy (ov, p); + ovl = strlen (ov); + + if (append) { + + if (strstr (ov, nv) == NULL) { + + printf ("Appending '%s' to env var '%s'\n", + nv, nn); + + while (nvl >= 0) { + nv[ovl + 1 + nvl] = nv[nvl]; + nvl--; + } + + nv[ovl] = ' '; + + while (--ovl >= 0) + nv[ovl] = ov[ovl]; + + setenv (nn, nv); + } + + return (1); + } + + if (remove) { + + if (strstr (ov, nv) != NULL) { + + printf ("Removing '%s' from env var '%s'\n", + nv, nn); + + while ((p = strstr (ov, nv)) != NULL) { + q = p + nvl; + if (*q == ' ') + q++; + strcpy(p, q); + } + + setenv (nn, ov); + } + + return (1); + } + + if (!override || strcmp (ov, nv) == 0) + return (1); + + printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", + nn, ov, nv); + } + else + printf ("Setting env cmd '%s' to '%s'\n", nn, nv); + + setenv (nn, nv); + return (1); +} + +void +hymod_check_env (void) +{ + char *p, *path, *curver, *newver; + int firsttime = 0, needsave = 0; + + if (getenv ("global_env_loaded") == NULL) { + puts ("*** global environment has never been loaded\n"); + puts ("*** fetching from server"); + firsttime = 1; + } + else if ((p = getenv ("always_check_env")) != NULL && + strcmp (p, "yes") == 0) + puts ("*** checking for updated global environment"); + else + return; + + puts (" (Control-C to Abort)\n"); + + if ((path = getenv ("global_env_path")) == NULL || *path == '\0') + path = def_global_env_path; + + if (fetch_and_parse (path, CFG_LOAD_ADDR, env_callback) == 0) { + puts ("*** Fetch of global environment failed!\n"); + return; + } + + if ((newver = getenv ("new_genv_version")) == NULL) { + puts ("*** Version number not set - contents ignored!\n"); + return; + } + + if ((curver = getenv ("global_env_version")) == NULL || \ + strcmp (curver, newver) != 0) { + setenv ("global_env_version", newver); + needsave = 1; + } + else + printf ("*** Global environment up-to-date (ver %s)\n", curver); + + setenv ("new_genv_version", NULL); + + if (firsttime) { + setenv ("global_env_loaded", "yes"); + needsave = 1; + } + + if (needsave) + puts ("\n*** Remember to run the 'saveenv' " + "command to save the changes\n\n"); +} diff --git a/board/hymod/fetch.c b/board/hymod/fetch.c new file mode 100755 index 0000000..e121d55 --- /dev/null +++ b/board/hymod/fetch.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2001 + * Murray Jensen, CSIRO-MIT, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* imports from input.c */ +extern int hymod_get_ethaddr (void); + +int +fetch_and_parse (char *fn, ulong addr, int (*cback)(uchar *, uchar *)) +{ + char *ethaddr; + uchar *fp, *efp; + int rc, count = 0; + + while ((ethaddr = getenv ("ethaddr")) == NULL || *ethaddr == '\0') { + + printf ("*** Ethernet address is%s not set\n", + count == 0 ? "" : " STILL"); + + if ((rc = hymod_get_ethaddr ()) < 0) { + if (rc == -1) + puts ("\n*** interrupted!"); + else + puts ("\n*** timeout!"); + printf (" - fetch of '%s' aborted\n", fn); + return (0); + } + + count++; + } + + copy_filename (BootFile, fn, sizeof (BootFile)); + load_addr = addr; + NetBootFileXferSize = 0; + + if (NetLoop (TFTP) == 0) { + printf ("tftp transfer of file '%s' failed\n", fn); + return (0); + } + + if (NetBootFileXferSize == 0) { + printf ("can't determine size of file '%s'\n", fn); + return (0); + } + + fp = (uchar *)load_addr; + efp = fp + NetBootFileXferSize; + + do { + uchar *name, *value; + + if (*fp == '#' || *fp == '\n') { + /* skip this line */ + while (fp < efp && *fp++ != '\n') + ; + continue; + } + + name = fp; + + while (fp < efp && *fp != '=' && *fp != '\n') + fp++; + if (fp >= efp) + break; + if (*fp == '\n') { + fp++; + continue; + } + *fp++ = '\0'; + + value = fp; + + while (fp < efp && *fp != '\n') + fp++; + if (fp[-1] == '\r') + fp[-1] = '\0'; + *fp++ = '\0'; /* ok if we go off the end here */ + + if ((*cback)(name, value) == 0) + return (0); + + } while (fp < efp); + + return (1); +} diff --git a/board/hymod/flash.c b/board/hymod/flash.c new file mode 100755 index 0000000..ad0a229 --- /dev/null +++ b/board/hymod/flash.c @@ -0,0 +1,506 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00 + */ + +#include +#include +#include + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/*----------------------------------------------------------------------- + * Protection Flags: + */ +#define FLAG_PROTECT_SET 0x01 +#define FLAG_PROTECT_CLEAR 0x02 + +/*----------------------------------------------------------------------- + */ + +/* + * probe for flash bank at address "base" and store info about it + * in the flash_info entry "fip". Fatal error if nothing there. + */ +static void +bank_probe (flash_info_t *fip, volatile bank_addr_t base) +{ + volatile bank_addr_t addr; + bank_word_t word; + int i; + + /* reset the flash */ + *base = BANK_CMD_RST; + + /* put flash into read id mode */ + *base = BANK_CMD_RD_ID; + + /* check the manufacturer id - must be intel */ + word = *BANK_REG_MAN_CODE (base); + if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff)) + panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx", + (unsigned long)word, (unsigned long)base); + + /* check the device id */ + word = *BANK_REG_DEV_CODE (base); + switch (word) { + + case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5; + fip->sector_count = 32; + break; + + case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5; + fip->sector_count = 64; + break; + + case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A; + fip->sector_count = 32; + break; + + case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A; + fip->sector_count = 64; + break; + + case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff): + fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A; + fip->sector_count = 128; + break; + + default: + panic ("\nbad device code (0x%08lx) at addr 0x%08lx", + (unsigned long)word, (unsigned long)base); + } + + if (fip->sector_count >= CFG_MAX_FLASH_SECT) + panic ("\ntoo many sectors (%d) in flash at address 0x%08lx", + fip->sector_count, (unsigned long)base); + + addr = base; + for (i = 0; i < fip->sector_count; i++) { + fip->start[i] = (unsigned long)addr; + fip->protect[i] = 0; + addr = BANK_ADDR_NEXT_BLK (addr); + } + + fip->size = (bank_size_t)addr - (bank_size_t)base; + + /* reset the flash */ + *base = BANK_CMD_RST; +} + +static void +bank_reset (flash_info_t *info, int sect) +{ + volatile bank_addr_t addr = (bank_addr_t)info->start[sect]; + +#ifdef FLASH_DEBUG + printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr); +#endif + + *addr = BANK_CMD_RST; +} + +static void +bank_erase_init (flash_info_t *info, int sect) +{ + volatile bank_addr_t addr = (bank_addr_t)info->start[sect]; + int flag; + +#ifdef FLASH_DEBUG + printf ("erasing sector %d, addr = 0x%08lx\n", + sect, (unsigned long)addr); +#endif + + /* Disable intrs which might cause a timeout here */ + flag = disable_interrupts (); + +#ifdef FLASH_DEBUG + printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr); +#endif + *addr = BANK_CMD_ERASE1; + *addr = BANK_CMD_ERASE2; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); +} + +static int +bank_erase_poll (flash_info_t *info, int sect) +{ + volatile bank_addr_t addr = (bank_addr_t)info->start[sect]; + bank_word_t stat = *addr; + +#ifdef FLASH_DEBUG + printf ("checking status at addr 0x%08lx [0x%08lx]\n", + (unsigned long)addr, (unsigned long)stat); +#endif + + if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) { + if ((stat & BANK_STAT_ERR) != 0) { + printf ("failed on sector %d [0x%08lx] at " + "address 0x%08lx\n", sect, + (unsigned long)stat, (unsigned long)addr); + *addr = BANK_CMD_CLR_STAT; + return (-1); + } + else + return (1); + } + else + return (0); +} + +static int +bank_write_word (volatile bank_addr_t addr, bank_word_t value) +{ + bank_word_t stat; + ulong start; + int flag, retval; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = BANK_CMD_PROG; + + *addr = value; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + retval = 0; + + /* data polling for D7 */ + start = get_timer (0); + do { + if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { + retval = 1; + goto done; + } + stat = *addr; + } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY); + + if ((stat & BANK_STAT_ERR) != 0) { + printf ("flash program failed [0x%08lx] at address 0x%08lx\n", + (unsigned long)stat, (unsigned long)addr); + *addr = BANK_CMD_CLR_STAT; + retval = 3; + } + +done: + /* reset to read mode */ + *addr = BANK_CMD_RST; + + return (retval); +} + +/*----------------------------------------------------------------------- + */ + +unsigned long +flash_init (void) +{ + int i; + + /* Init: no FLASHes known */ + for (i=0; iflash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: printf ("INTEL "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F320J5: printf ("28F320J5 (32 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F640J5: printf ("28F640J5 (64 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F320J3A: printf ("28F320J3A (32 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F640J3A: printf ("28F640J3A (64 Mbit, 2 x 16bit)\n"); + break; + case FLASH_28F128J3A: printf ("28F320J3A (128 Mbit, 2 x 16bit)\n"); + break; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; isector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); + return; +} + +/* + * The following code cannot be run from FLASH! + */ + +/*----------------------------------------------------------------------- + */ + +int +flash_erase (flash_info_t *info, int s_first, int s_last) +{ + int prot, sect, haderr; + ulong start, now, last; + int rcode = 0; + +#ifdef FLASH_DEBUG + printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" + " Bank # %d: ", s_last - s_first + 1, s_first, s_last, + (info - flash_info) + 1); + flash_print_info (info); +#endif + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sector%s will not be erased\n", + prot, (prot > 1 ? "s" : "")); + } + + start = get_timer (0); + last = 0; + haderr = 0; + + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + ulong estart; + int sectdone; + + bank_erase_init (info, sect); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + estart = get_timer (start); + + do { + now = get_timer (start); + + if (now - estart > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout (sect %d)\n", sect); + haderr = 1; + rcode = 1; + break; + } + +#ifndef FLASH_DEBUG + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } +#endif + + sectdone = bank_erase_poll (info, sect); + + if (sectdone < 0) { + haderr = 1; + rcode = 1; + break; + } + + } while (!sectdone); + + if (haderr) + break; + } + } + + if (haderr > 0) + printf (" failed\n"); + else + printf (" done\n"); + + /* reset to read mode */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + bank_reset (info, sect); + } + } + return rcode; +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 3 - Program failed + */ +static int +write_word (flash_info_t *info, ulong dest, ulong data) +{ + /* Check if Flash is (sufficiently) erased */ + if ((*(ulong *)dest & data) != data) + return (2); + + return (bank_write_word ((bank_addr_t)dest, (bank_word_t)data)); +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 3 - Program failed + */ + +int +write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word (info, wp, data)); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/hymod/flash.h b/board/hymod/flash.h new file mode 100755 index 0000000..ee047fe --- /dev/null +++ b/board/hymod/flash.h @@ -0,0 +1,156 @@ +/* + * (C) Copyright 2000 + * Murray Jensen, CSIRO-MIT, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/*************** DEFINES for Intel StrataFlash FLASH chip ********************/ + +/* Commands */ +#define ISF_CMD_RST 0xFF /* reset flash */ +#define ISF_CMD_RD_ID 0x90 /* read the id and lock bits */ +#define ISF_CMD_RD_QUERY 0x98 /* read device capabilities */ +#define ISF_CMD_RD_STAT 0x70 /* read the status register */ +#define ISF_CMD_CLR_STAT 0x50 /* clear the staus register */ +#define ISF_CMD_WR_BUF 0xE8 /* clear the staus register */ +#define ISF_CMD_PROG 0x40 /* program word command */ +#define ISF_CMD_ERASE1 0x20 /* 1st word for block erase */ +#define ISF_CMD_ERASE2 0xD0 /* 2nd word for block erase */ +#define ISF_CMD_ERASE_SUSP 0xB0 /* suspend block erase */ +#define ISF_CMD_LOCK 0x60 /* 1st word for all lock cmds */ +#define ISF_CMD_SET_LOCK_BLK 0x01 /* 2nd wrd set block lock bit */ +#define ISF_CMD_SET_LOCK_MSTR 0xF1 /* 2nd wrd set master lck bit */ +#define ISF_CMD_CLR_LOCK_BLK 0xD0 /* 2nd wrd clear blk lck bit */ + +/* status register bits */ +#define ISF_STAT_DPS 0x02 /* Device Protect Status */ +#define ISF_STAT_VPPS 0x08 /* VPP Status */ +#define ISF_STAT_PSLBS 0x10 /* Program+Set Lock Bit Stat */ +#define ISF_STAT_ECLBS 0x20 /* Erase+Clr Lock Bit Stat */ +#define ISF_STAT_ESS 0x40 /* Erase Suspend Status */ +#define ISF_STAT_RDY 0x80 /* WSM Mach Status, 1=rdy */ + +#define ISF_STAT_ERR (ISF_STAT_VPPS | ISF_STAT_DPS | \ + ISF_STAT_ECLBS | ISF_STAT_PSLBS) + +/* register addresses, valid only following an ISF_CMD_RD_ID command */ +#define ISF_REG_MAN_CODE 0x00 /* manufacturer code */ +#define ISF_REG_DEV_CODE 0x01 /* device code */ +#define ISF_REG_BLK_LCK 0x02 /* block lock configuration */ +#define ISF_REG_MST_LCK 0x03 /* master lock configuration */ + +/********************** DEFINES for Hymod Flash ******************************/ + +/* + * this code requires that the flash on any Hymod board appear as a bank + * of two (identical) 16bit Intel StrataFlash chips with 64Kword erase + * sectors (or blocks), running in x16 bit mode and connected side-by-side + * to make a 32-bit wide bus. + */ + +typedef unsigned long bank_word_t; +typedef bank_word_t bank_blk_t[64 * 1024]; + +#define BANK_FILL_WORD(b) (((bank_word_t)(b) << 16) | (bank_word_t)(b)) + +#ifdef EXAMPLE + +/* theoretically the following examples should also work */ + +/* one flash chip in x8 mode with 128Kword sectors and 8bit bus */ +typedef unsigned char bank_word_t; +typedef bank_word_t bank_blk_t[128 * 1024]; +#define BANK_FILL_WORD(b) ((bank_word_t)(b)) + +/* four flash chips in x16 mode with 32Kword sectors and 64bit bus */ +typedef unsigned long long bank_word_t; +typedef bank_word_t bank_blk_t[32 * 1024]; +#define BANK_FILL_WORD(b) ( \ + ((bank_word_t)(b) << 48) \ + ((bank_word_t)(b) << 32) \ + ((bank_word_t)(b) << 16) \ + ((bank_word_t)(b) << 0) \ + ) + +#endif /* EXAMPLE */ + +/* the sizes of these two types should probably be the same */ +typedef bank_word_t *bank_addr_t; +typedef unsigned long bank_size_t; + +/* align bank addresses and sizes to bank word boundaries */ +#define BANK_ADDR_WORD_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ + & ~(sizeof (bank_word_t) - 1))) +#define BANK_SIZE_WORD_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_word_t) - 1) \ + & ~(sizeof (bank_word_t) - 1)) + +/* align bank addresses and sizes to bank block boundaries */ +#define BANK_ADDR_BLK_ALIGN(a) ((bank_addr_t)((bank_size_t)(a) \ + & ~(sizeof (bank_blk_t) - 1))) +#define BANK_SIZE_BLK_ALIGN(s) (((bank_size_t)(s) + sizeof (bank_blk_t) - 1) \ + & ~(sizeof (bank_blk_t) - 1)) + +/* add an offset to a bank address */ +#define BANK_ADDR_OFFSET(a, o) ((bank_addr_t)((bank_size_t)(a) + \ + (bank_size_t)(o))) + +/* adjust a bank address to start of next word, block or bank */ +#define BANK_ADDR_NEXT_WORD(a) BANK_ADDR_OFFSET(BANK_ADDR_WORD_ALIGN(a), \ + sizeof (bank_word_t)) +#define BANK_ADDR_NEXT_BLK(a) BANK_ADDR_OFFSET(BANK_ADDR_BLK_ALIGN(a), \ + sizeof (bank_blk_t)) + +/* get bank address of register r given a bank base address a and block num b */ +#define BANK_ADDR_REG(a, b, r) BANK_ADDR_OFFSET(BANK_ADDR_OFFSET((a), \ + (bank_size_t)(b) * sizeof (bank_blk_t)), \ + (bank_size_t)(r) * sizeof (bank_word_t)) + +/* make a bank word value for each StrataFlash value */ + +/* Commands */ +#define BANK_CMD_RST BANK_FILL_WORD(ISF_CMD_RST) +#define BANK_CMD_RD_ID BANK_FILL_WORD(ISF_CMD_RD_ID) +#define BANK_CMD_RD_STAT BANK_FILL_WORD(ISF_CMD_RD_STAT) +#define BANK_CMD_CLR_STAT BANK_FILL_WORD(ISF_CMD_CLR_STAT) +#define BANK_CMD_ERASE1 BANK_FILL_WORD(ISF_CMD_ERASE1) +#define BANK_CMD_ERASE2 BANK_FILL_WORD(ISF_CMD_ERASE2) +#define BANK_CMD_PROG BANK_FILL_WORD(ISF_CMD_PROG) +#define BANK_CMD_LOCK BANK_FILL_WORD(ISF_CMD_LOCK) +#define BANK_CMD_SET_LOCK_BLK BANK_FILL_WORD(ISF_CMD_SET_LOCK_BLK) +#define BANK_CMD_SET_LOCK_MSTR BANK_FILL_WORD(ISF_CMD_SET_LOCK_MSTR) +#define BANK_CMD_CLR_LOCK_BLK BANK_FILL_WORD(ISF_CMD_CLR_LOCK_BLK) + +/* status register bits */ +#define BANK_STAT_DPS BANK_FILL_WORD(ISF_STAT_DPS) +#define BANK_STAT_PSS BANK_FILL_WORD(ISF_STAT_PSS) +#define BANK_STAT_VPPS BANK_FILL_WORD(ISF_STAT_VPPS) +#define BANK_STAT_PSLBS BANK_FILL_WORD(ISF_STAT_PSLBS) +#define BANK_STAT_ECLBS BANK_FILL_WORD(ISF_STAT_ECLBS) +#define BANK_STAT_ESS BANK_FILL_WORD(ISF_STAT_ESS) +#define BANK_STAT_RDY BANK_FILL_WORD(ISF_STAT_RDY) + +#define BANK_STAT_ERR BANK_FILL_WORD(ISF_STAT_ERR) + +/* make a bank register address for each StrataFlash register address */ + +#define BANK_REG_MAN_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_MAN_CODE) +#define BANK_REG_DEV_CODE(a) BANK_ADDR_REG((a), 0, ISF_REG_DEV_CODE) +#define BANK_REG_BLK_LCK(a, b) BANK_ADDR_REG((a), (b), ISF_REG_BLK_LCK) +#define BANK_REG_MST_LCK(a) BANK_ADDR_REG((a), 0, ISF_REG_MST_LCK) diff --git a/board/hymod/global_env b/board/hymod/global_env new file mode 100755 index 0000000..f61d080 --- /dev/null +++ b/board/hymod/global_env @@ -0,0 +1,161 @@ +# DONT FORGET TO CHANGE THE "version" VAR BELOW IF YOU MAKE CHANGES TO THIS FILE + +# (C) Copyright 2001 +# Murray Jensen, CSIRO-MIT, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA + +# +# global_env +# +# file used by Hymod boards to initialise the u-boot non-volatile +# environment when u-boot is first run (it determines this by the +# absence of the environment variable "global_env_loaded") +# +# format of this file is: +# +# 1. blank lines and lines beginning with '#' are ignored +# 2. all other lines must have the form = +# 3. if a percent appears anywhere, it is replaced like so: +# +# %s serial number of the main board (10 digit zero filled) +# %S serial number of the main board (plain number) +# %% a percentage character +# ... otherwise the %x is discarded +# +# if first character in is a dash ('-'), then an existing env var +# will not be overwritten (the dash is removed). i.e. it is only set if +# it does not exist +# +# if last character in is a plus ('+'), then will be appended +# to any existing env var (the plus is ignored). Duplicates of are +# removed. +# +# similarly, if the last character in is a minus ('-'), then any +# occurences of in the current value of will removed (the +# minus is ignored). +# +# leading and trailing whitespace is removed in both and +# (after processing any initial or final plus/minus in ). +# + +# MISCELLANEOUS PARAMETERS + +# version must always come first +version=4 + +# set the ip address based on the main board serial number +ipaddr=192.168.1.%S +serverip=192.168.1.254 + +# stop auto execute after tftp (not a very good name really) +autostart=no + +# setting this to "yes" forces the global_env file to be loaded and processed +# if the current version is different to the version in the file +always_check_env=no + +# BOOTING COMMANDS AND PARAMETERS + +# command to run when "auto-booting" +bootcmd=bootm 40080000 + +# how long the "countdown" to automatically running "bootcmd" is +bootdelay=2 + +# how long before it "times out" console input and attempts to run "bootcmd" +bootretry=5 + +# arguments passed to the boot program (i.e. linux kernel) via register 6 +# the linux kernel (v2.4) uses the following registers: +# r3 - address of board information structure +# r4 - address of initial ramdisk image (0 means no initrd) +# r5 - size of initial ramdisk image +# r6 - address of command line string +-bootargs=root=/dev/mtdblock5 rootfstype=squashfs ro + +# these four are for hymod linux integrated into our Sun network +bootargs+=serialno=%S +bootargs+=nisclient nisdomain=mlb.dmt.csiro.au nissrvadr=138.194.112.4 +bootargs+=nfsclient +bootargs+=automount + +# start a web server by default +bootargs+=webserver + +# give negotiation time to finish +bootargs+=netsleep=5 + +# then our ciscos don't pass packets for 25-30 secs after that, so +# pinging the server until it responds prevents network connections +# from failing... +bootargs+=netping + +# these are old bootargs - we don't need them anymore +bootargs-=preload=unix,i2c-cpm,i2c-dev +bootargs-=ramdisk_size=32768 +bootargs-=ramdisk_size=24576 + +# FLASH MANIPULATION COMMANDS + +# +# 16M flash, 64 x 256K sectors, mapped at address 0x40000000 +# +# Sector(s) Address Size Description +# +# 0 - 0 0x40000000 256K boot code +# 1 - 1 0x40040000 256K non volatile environment +# 2 - 4 0x40080000 768K linux kernel image +# 5 - 7 0x40140000 768K alternate linux kernel image +# 8 - 47 0x40200000 10M linux initial ramdisk image +# 48 - 63 0x40c00000 4M ramdisk image for applications +# + +fetchboot=tftp 100000 /hymod/u-boot.bin +eraseboot=protect off 1:0 ; erase 1:0 ; protect on 1:0 +copyboot=protect off 1:0 ; cp.b 100000 40000000 40000 ; protect on 1:0 +cmpboot=cmp.b 100000 40000000 40000 +newboot=run fetchboot eraseboot copyboot cmpboot + +fetchlinux=tftp 100000 /hymod/linux.bin +eraselinux=erase 1:2-4 +copylinux=cp.b 100000 40080000 ${filesize} +cmplinux=cmp.b 100000 40080000 ${filesize} +newlinux=run fetchlinux eraselinux copylinux cmplinux + +fetchaltlinux=tftp 100000 /hymod/altlinux.bin +erasealtlinux=erase 1:5-7 +copyaltlinux=cp.b 100000 40140000 ${filesize} +cmpaltlinux=cmp.b 100000 40140000 ${filesize} +newaltlinux=run fetchaltlinux erasealtlinux copyaltlinux cmpaltlinux + +fetchroot=tftp 100000 /hymod/root.bin +eraseroot=erase 1:8-47 +copyroot=cp.b 100000 40200000 ${filesize} +cmproot=cmp.b 100000 40200000 ${filesize} +newroot=run fetchroot eraseroot copyroot cmproot + +fetchard=tftp 100000 /hymod/apprd.bin +eraseard=erase 1:48-63 +copyard=cp.b 100000 40c00000 ${filesize} +cmpard=cmp.b 100000 40c00000 ${filesize} +newapprd=run fetchard eraseard copyard cmpard + +# pass above map to linux mtd driver +bootargs+=mtdparts=phys:256k(u-boot),256k(u-boot-env),768k(linux),768k(altlinux),10m(root),4m(hymod) diff --git a/board/hymod/hymod.c b/board/hymod/hymod.c new file mode 100755 index 0000000..dea0a70 --- /dev/null +++ b/board/hymod/hymod.c @@ -0,0 +1,537 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00 + */ + +#include +#include +#include +#include +#include +#include + +/* ------------------------------------------------------------------------- */ + +/* imports from eeprom.c */ +extern int hymod_eeprom_read (int, hymod_eeprom_t *); +extern void hymod_eeprom_print (hymod_eeprom_t *); + +/* imports from env.c */ +extern void hymod_check_env (void); + +/* ------------------------------------------------------------------------- */ + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ + +const iop_conf_t iop_conf_tab[4][32] = { + + /* Port A configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 1, 1, 0, 0, 0 }, /* PA31: FCC1 MII COL */ + { 1, 1, 1, 0, 0, 0 }, /* PA30: FCC1 MII CRS */ + { 1, 1, 1, 1, 0, 0 }, /* PA29: FCC1 MII TX_ER */ + { 1, 1, 1, 1, 0, 0 }, /* PA28: FCC1 MII TX_EN */ + { 1, 1, 1, 0, 0, 0 }, /* PA27: FCC1 MII RX_DV */ + { 1, 1, 1, 0, 0, 0 }, /* PA26: FCC1 MII RX_ER */ + { 1, 0, 0, 1, 0, 0 }, /* PA25: FCC2 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA24: FCC2 MII MDC */ + { 1, 0, 0, 1, 0, 0 }, /* PA23: FCC3 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA22: FCC3 MII MDC */ + { 1, 1, 0, 1, 0, 0 }, /* PA21: FCC1 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PA20: FCC1 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PA19: FCC1 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PA18: FCC1 MII TxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PA17: FCC1 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PA16: FCC1 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PA15: FCC1 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PA14: FCC1 MII RxD[0] */ + { 1, 0, 0, 1, 0, 0 }, /* PA13: FCC1 MII MDIO */ + { 1, 0, 0, 1, 0, 0 }, /* PA12: FCC1 MII MDC */ + { 1, 0, 0, 1, 0, 0 }, /* PA11: SEL_CD */ + { 1, 0, 0, 0, 0, 0 }, /* PA10: FLASH STS1 */ + { 1, 0, 0, 0, 0, 0 }, /* PA09: FLASH STS0 */ + { 1, 0, 0, 0, 0, 0 }, /* PA08: FLASH ~PE */ + { 1, 0, 0, 0, 0, 0 }, /* PA07: WATCH ~HRESET */ + { 1, 0, 0, 0, 1, 0 }, /* PA06: VC DONE */ + { 1, 0, 0, 1, 1, 0 }, /* PA05: VC INIT */ + { 1, 0, 0, 1, 0, 0 }, /* PA04: VC ~PROG */ + { 1, 0, 0, 1, 0, 0 }, /* PA03: VM ENABLE */ + { 1, 0, 0, 0, 1, 0 }, /* PA02: VM DONE */ + { 1, 0, 0, 1, 1, 0 }, /* PA01: VM INIT */ + { 1, 0, 0, 1, 0, 0 } /* PA00: VM ~PROG */ + }, + + /* Port B configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 1, 0, 1, 0, 0 }, /* PB31: FCC2 MII TX_ER */ + { 1, 1, 0, 0, 0, 0 }, /* PB30: FCC2 MII RX_DV */ + { 1, 1, 1, 1, 0, 0 }, /* PB29: FCC2 MII TX_EN */ + { 1, 1, 0, 0, 0, 0 }, /* PB28: FCC2 MII RX_ER */ + { 1, 1, 0, 0, 0, 0 }, /* PB27: FCC2 MII COL */ + { 1, 1, 0, 0, 0, 0 }, /* PB26: FCC2 MII CRS */ + { 1, 1, 0, 1, 0, 0 }, /* PB25: FCC2 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PB24: FCC2 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PB23: FCC2 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PB22: FCC2 MII TxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PB21: FCC2 MII RxD[0] */ + { 1, 1, 0, 0, 0, 0 }, /* PB20: FCC2 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PB19: FCC2 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PB18: FCC2 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PB17: FCC3 MII RX_DV */ + { 1, 1, 0, 0, 0, 0 }, /* PB16: FCC3 MII RX_ER */ + { 1, 1, 0, 1, 0, 0 }, /* PB15: FCC3 MII TX_ER */ + { 1, 1, 0, 1, 0, 0 }, /* PB14: FCC3 MII TX_EN */ + { 1, 1, 0, 0, 0, 0 }, /* PB13: FCC3 MII COL */ + { 1, 1, 0, 0, 0, 0 }, /* PB12: FCC3 MII CRS */ + { 1, 1, 0, 0, 0, 0 }, /* PB11: FCC3 MII RxD[3] */ + { 1, 1, 0, 0, 0, 0 }, /* PB10: FCC3 MII RxD[2] */ + { 1, 1, 0, 0, 0, 0 }, /* PB09: FCC3 MII RxD[1] */ + { 1, 1, 0, 0, 0, 0 }, /* PB08: FCC3 MII RxD[0] */ + { 1, 1, 0, 1, 0, 0 }, /* PB07: FCC3 MII TxD[3] */ + { 1, 1, 0, 1, 0, 0 }, /* PB06: FCC3 MII TxD[2] */ + { 1, 1, 0, 1, 0, 0 }, /* PB05: FCC3 MII TxD[1] */ + { 1, 1, 0, 1, 0, 0 }, /* PB04: FCC3 MII TxD[0] */ + { 0, 0, 0, 0, 0, 0 }, /* PB03: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PB02: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PB01: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 } /* PB00: pin doesn't exist */ + }, + + /* Port C configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 0, 0, 0, 0, 0 }, /* PC31: MEZ ~IACK */ + { 0, 0, 0, 0, 0, 0 }, /* PC30: ? */ + { 1, 1, 0, 0, 0, 0 }, /* PC29: CLK SCCx */ + { 1, 1, 0, 0, 0, 0 }, /* PC28: CLK4 */ + { 1, 1, 0, 0, 0, 0 }, /* PC27: CLK SCCF */ + { 1, 1, 0, 0, 0, 0 }, /* PC26: CLK 32K */ + { 1, 1, 0, 0, 0, 0 }, /* PC25: BRG4/CLK7 */ + { 0, 0, 0, 0, 0, 0 }, /* PC24: ? */ + { 1, 1, 0, 0, 0, 0 }, /* PC23: CLK SCCx */ + { 1, 1, 0, 0, 0, 0 }, /* PC22: FCC1 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC21: FCC1 MII TX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC20: CLK SCCF */ + { 1, 1, 0, 0, 0, 0 }, /* PC19: FCC2 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC18: FCC2 MII TX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC17: FCC3 MII RX_CLK */ + { 1, 1, 0, 0, 0, 0 }, /* PC16: FCC3 MII TX_CLK */ + { 1, 0, 0, 0, 0, 0 }, /* PC15: SCC1 UART ~CTS */ + { 1, 0, 0, 0, 0, 0 }, /* PC14: SCC1 UART ~CD */ + { 1, 0, 0, 0, 0, 0 }, /* PC13: SCC2 UART ~CTS */ + { 1, 0, 0, 0, 0, 0 }, /* PC12: SCC2 UART ~CD */ + { 1, 0, 0, 1, 0, 0 }, /* PC11: SCC1 UART ~DTR */ + { 1, 0, 0, 1, 0, 0 }, /* PC10: SCC1 UART ~DSR */ + { 1, 0, 0, 1, 0, 0 }, /* PC09: SCC2 UART ~DTR */ + { 1, 0, 0, 1, 0, 0 }, /* PC08: SCC2 UART ~DSR */ + { 1, 0, 0, 0, 0, 0 }, /* PC07: TEMP ~ALERT */ + { 1, 0, 0, 0, 0, 0 }, /* PC06: FCC3 INT */ + { 1, 0, 0, 0, 0, 0 }, /* PC05: FCC2 INT */ + { 1, 0, 0, 0, 0, 0 }, /* PC04: FCC1 INT */ + { 0, 1, 1, 1, 0, 0 }, /* PC03: SDMA IDMA2 ~DACK */ + { 0, 1, 1, 0, 0, 0 }, /* PC02: SDMA IDMA2 ~DONE */ + { 0, 1, 0, 0, 0, 0 }, /* PC01: SDMA IDMA2 ~DREQ */ + { 1, 1, 0, 1, 0, 0 } /* PC00: BRG7 */ + }, + + /* Port D configuration */ + { + /* cnf par sor dir odr dat */ + { 1, 1, 0, 0, 0, 0 }, /* PD31: SCC1 UART RxD */ + { 1, 1, 1, 1, 0, 0 }, /* PD30: SCC1 UART TxD */ + { 1, 0, 0, 1, 0, 0 }, /* PD29: SCC1 UART ~RTS */ + { 1, 1, 0, 0, 0, 0 }, /* PD28: SCC2 UART RxD */ + { 1, 1, 0, 1, 0, 0 }, /* PD27: SCC2 UART TxD */ + { 1, 0, 0, 1, 0, 0 }, /* PD26: SCC2 UART ~RTS */ + { 1, 0, 0, 0, 0, 0 }, /* PD25: SCC1 UART ~RI */ + { 1, 0, 0, 0, 0, 0 }, /* PD24: SCC2 UART ~RI */ + { 1, 0, 0, 1, 0, 0 }, /* PD23: CLKGEN PD */ + { 1, 0, 0, 0, 0, 0 }, /* PD22: USER3 */ + { 1, 0, 0, 0, 0, 0 }, /* PD21: USER2 */ + { 1, 0, 0, 0, 0, 0 }, /* PD20: USER1 */ + { 1, 1, 1, 0, 0, 0 }, /* PD19: SPI ~SEL */ + { 1, 1, 1, 0, 0, 0 }, /* PD18: SPI CLK */ + { 1, 1, 1, 0, 0, 0 }, /* PD17: SPI MOSI */ + { 1, 1, 1, 0, 0, 0 }, /* PD16: SPI MISO */ + { 1, 1, 1, 0, 1, 0 }, /* PD15: I2C SDA */ + { 1, 1, 1, 0, 1, 0 }, /* PD14: I2C SCL */ + { 1, 0, 0, 1, 0, 1 }, /* PD13: TEMP ~STDBY */ + { 1, 0, 0, 1, 0, 1 }, /* PD12: FCC3 ~RESET */ + { 1, 0, 0, 1, 0, 1 }, /* PD11: FCC2 ~RESET */ + { 1, 0, 0, 1, 0, 1 }, /* PD10: FCC1 ~RESET */ + { 1, 0, 0, 0, 0, 0 }, /* PD09: PD9 */ + { 1, 0, 0, 0, 0, 0 }, /* PD08: PD8 */ + { 1, 0, 0, 1, 0, 1 }, /* PD07: PD7 */ + { 1, 0, 0, 1, 0, 1 }, /* PD06: PD6 */ + { 1, 0, 0, 1, 0, 1 }, /* PD05: PD5 */ + { 1, 0, 0, 1, 0, 1 }, /* PD04: PD4 */ + { 0, 0, 0, 0, 0, 0 }, /* PD03: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PD02: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 }, /* PD01: pin doesn't exist */ + { 0, 0, 0, 0, 0, 0 } /* PD00: pin doesn't exist */ + } +}; + +/* ------------------------------------------------------------------------- */ + +/* + * AMI FS6377 Clock Generator configuration table + * + * the "fs6377_regs[]" table entries correspond to FS6377 registers + * 0 - 15 (total of 16 bytes). + * + * the data is written to the FS6377 via the i2c bus using address in + * "fs6377_addr" (address is 7 bits - R/W bit not included). + * + * The fs6377 has four clock outputs: A, B, C and D. + * + * Outputs C and D can each provide two different clock outputs C1/D1 or + * C2/D2 depending on the state of the SEL_CD input which is connected to + * the MPC8260 I/O port pin PA11. PA11 output (SEL_CD input) low (or 0) + * selects C1/D1 and PA11 output (SEL_CD input) high (or 1) selects C2/D2. + * + * PA11 defaults to output low (or 0) in the i/o port config table above. + * + * Output A provides a 100MHz for the High Speed Serial chips. Output B + * provides a 3.6864MHz clock for more accurate asynchronous serial bit + * rates. Output C is routed to the mezzanine connector but is currently + * unused - both C1 and C2 are set to 16MHz. Output D is used by both the + * alt-input and display mezzanine boards for their video chips. The + * alt-input board requires a clock of 24.576MHz and this is available on + * D1 (PA11=SEL_CD=0). The display board requires a clock of 27MHz and this + * is available on D2 (PA11=SEL_CD=1). + * + * So the default is a clock suitable for the alt-input board. PA11 is toggled + * later in misc_init_r(), if a display board is detected. + */ + +uchar fs6377_addr = 0x5c; + +uchar fs6377_regs[16] = { + 12, 75, 64, 25, 144, 128, 25, 192, + 0, 16, 135, 192, 224, 64, 64, 192 +}; + +/* ------------------------------------------------------------------------- */ + +/* + * special board initialisation, after clocks and timebase have been + * set up but before environment and serial are initialised. + * + * added so that very early initialisations can be done using the i2c + * driver (which requires the clocks, to calculate the dividers, and + * the timebase, for udelay()) + */ + +int +board_postclk_init (void) +{ + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + + /* + * Initialise the FS6377 clock chip + * + * the secondary address is the register number from where to + * start the write - I want to write all the registers + * + * don't bother checking return status - we have no console yet + * to print it on, nor any RAM to store it in - it will be obvious + * if this doesn't work + */ + (void) i2c_write (fs6377_addr, 0, 1, fs6377_regs, + sizeof (fs6377_regs)); + + return (0); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: Hardwired to HYMOD + */ + +int +checkboard (void) +{ + puts ("Board: HYMOD\n"); + return (0); +} + +/* ------------------------------------------------------------------------- */ + +/* + * miscellaneous (early - while running in flash) initialisations. + */ + +#define _NOT_USED_ 0xFFFFFFFF + +uint upmb_table[] = { + /* Read Single Beat (RSS) - offset 0x00 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Read Burst (RBS) - offset 0x08 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Write Single Beat (WSS) - offset 0x18 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Write Burst (WSS) - offset 0x20 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Refresh Timer (PTS) - offset 0x30 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Exception Condition (EXS) - offset 0x3c */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_ +}; + +uint upmc_table[] = { + /* Read Single Beat (RSS) - offset 0x00 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Read Burst (RBS) - offset 0x08 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Write Single Beat (WSS) - offset 0x18 */ + 0xF0E00000, 0xF0A00000, 0x00A00000, 0x30A00000, + 0xF0F40007, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Write Burst (WSS) - offset 0x20 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Refresh Timer (PTS) - offset 0x30 */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* Exception Condition (EXS) - offset 0x3c */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_ +}; + +int +misc_init_f (void) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + + printf ("UPMs: "); + + upmconfig (UPMB, upmb_table, sizeof upmb_table / sizeof upmb_table[0]); + memctl->memc_mbmr = CFG_MBMR; + + upmconfig (UPMC, upmc_table, sizeof upmc_table / sizeof upmc_table[0]); + memctl->memc_mcmr = CFG_MCMR; + + printf ("configured\n"); + return (0); +} + +/* ------------------------------------------------------------------------- */ + +long +initdram (int board_type) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + volatile uchar c = 0, *ramaddr = (uchar *) (CFG_SDRAM_BASE + 0x8); + ulong psdmr = CFG_PSDMR; + int i; + + /* + * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): + * + * "At system reset, initialization software must set up the + * programmable parameters in the memory controller banks registers + * (ORx, BRx, P/LSDMR). After all memory parameters are coñgured, + * system software should execute the following initialization sequence + * for each SDRAM device. + * + * 1. Issue a PRECHARGE-ALL-BANKS command + * 2. Issue eight CBR REFRESH commands + * 3. Issue a MODE-SET command to initialize the mode register + * + * The initial commands are executed by setting P/LSDMR[OP] and + * accessing the SDRAM with a single-byte transaction." + * + * The appropriate BRx/ORx registers have already been set when we + * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE. + */ + + memctl->memc_psrt = CFG_PSRT; + memctl->memc_mptpr = CFG_MPTPR; + + memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr = c; + + return (CFG_SDRAM_SIZE << 20); +} + +/* ------------------------------------------------------------------------- */ +/* miscellaneous initialisations after relocation into ram (misc_init_r) */ +/* */ +/* loads the data in the main board and mezzanine board eeproms into */ +/* the hymod configuration struct stored in the board information area. */ +/* */ +/* if the contents of either eeprom is invalid, prompts for a serial */ +/* number (and an ethernet address if required) then fetches a file */ +/* containing information to be stored in the eeprom from the tftp server */ +/* (the file name is based on the serial number and a built-in path) */ + +int +last_stage_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + hymod_conf_t *cp = &gd->bd->bi_hymod_conf; + int rc; + +#ifdef CONFIG_BOOT_RETRY_TIME + /* + * we use the readline () function, but we also want + * command timeout enabled + */ + init_cmd_timeout (); +#endif + + memset ((void *) cp, 0, sizeof (*cp)); + + /* set up main board config info */ + + rc = hymod_eeprom_read (0, &cp->main.eeprom); + + puts ("EEPROM:main..."); + if (rc < 0) + puts ("NOT PRESENT\n"); + else if (rc == 0) + puts ("INVALID\n"); + else { + cp->main.eeprom.valid = 1; + + printf ("OK (ver %u)\n", cp->main.eeprom.ver); + hymod_eeprom_print (&cp->main.eeprom); + + /* + * hard-wired assumption here: all hymod main boards will have + * one xilinx fpga, with the interrupt line connected to IRQ2 + * + * One day, this might be based on the board type + */ + + cp->main.xlx[0].mmap.prog.exists = 1; + cp->main.xlx[0].mmap.prog.size = FPGA_MAIN_CFG_SIZE; + cp->main.xlx[0].mmap.prog.base = FPGA_MAIN_CFG_BASE; + + cp->main.xlx[0].mmap.reg.exists = 1; + cp->main.xlx[0].mmap.reg.size = FPGA_MAIN_REG_SIZE; + cp->main.xlx[0].mmap.reg.base = FPGA_MAIN_REG_BASE; + + cp->main.xlx[0].mmap.port.exists = 1; + cp->main.xlx[0].mmap.port.size = FPGA_MAIN_PORT_SIZE; + cp->main.xlx[0].mmap.port.base = FPGA_MAIN_PORT_BASE; + + cp->main.xlx[0].iopins.prog_pin.port = FPGA_MAIN_PROG_PORT; + cp->main.xlx[0].iopins.prog_pin.pin = FPGA_MAIN_PROG_PIN; + cp->main.xlx[0].iopins.prog_pin.flag = 1; + cp->main.xlx[0].iopins.init_pin.port = FPGA_MAIN_INIT_PORT; + cp->main.xlx[0].iopins.init_pin.pin = FPGA_MAIN_INIT_PIN; + cp->main.xlx[0].iopins.init_pin.flag = 1; + cp->main.xlx[0].iopins.done_pin.port = FPGA_MAIN_DONE_PORT; + cp->main.xlx[0].iopins.done_pin.pin = FPGA_MAIN_DONE_PIN; + cp->main.xlx[0].iopins.done_pin.flag = 1; +#ifdef FPGA_MAIN_ENABLE_PORT + cp->main.xlx[0].iopins.enable_pin.port = FPGA_MAIN_ENABLE_PORT; + cp->main.xlx[0].iopins.enable_pin.pin = FPGA_MAIN_ENABLE_PIN; + cp->main.xlx[0].iopins.enable_pin.flag = 1; +#endif + + cp->main.xlx[0].irq = FPGA_MAIN_IRQ; + } + + /* set up mezzanine board config info */ + + rc = hymod_eeprom_read (1, &cp->mezz.eeprom); + + puts ("EEPROM:mezz..."); + if (rc < 0) + puts ("NOT PRESENT\n"); + else if (rc == 0) + puts ("INVALID\n"); + else { + cp->main.eeprom.valid = 1; + + printf ("OK (ver %u)\n", cp->mezz.eeprom.ver); + hymod_eeprom_print (&cp->mezz.eeprom); + } + + cp->crc = crc32 (0, (unsigned char *)cp, offsetof (hymod_conf_t, crc)); + + hymod_check_env (); + + return (0); +} + +#ifdef CONFIG_SHOW_ACTIVITY +void board_show_activity (ulong timebase) +{ +#ifdef CFG_HYMOD_DBLEDS + volatile immap_t *immr = (immap_t *) CFG_IMMR; + volatile iop8260_t *iop = &immr->im_ioport; + static int shift = 0; + + if ((timestamp % CFG_HZ) == 0) { + if (++shift > 3) + shift = 0; + iop->iop_pdatd = + (iop->iop_pdatd & ~0x0f000000) | (1 << (24 + shift)); + } +#endif /* CFG_HYMOD_DBLEDS */ +} + +void show_activity(int arg) +{ +} +#endif /* CONFIG_SHOW_ACTIVITY */ diff --git a/board/hymod/hymod.h b/board/hymod/hymod.h new file mode 100755 index 0000000..9d8d662 --- /dev/null +++ b/board/hymod/hymod.h @@ -0,0 +1,322 @@ +/* + * (C) Copyright 2001 + * Murray Jensen, CSIRO-MIT, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _HYMOD_H_ +#define _HYMOD_H_ + +#include +#ifdef CONFIG_8260 +#include +#endif + +/* + * hymod configuration data - passed by boot code via the board information + * structure (only U-Boot has support for this at the moment) + * + * there are three types of data passed up from the boot monitor. the first + * (type hymod_eeprom_t) is the eeprom data that was read off both the main + * (or mother) board and the mezzanine board (if any). this data defines how + * many Xilinx fpgas are on each board, and their types (among other things). + * the second type of data (type xlx_mmap_t, one per Xilinx fpga) defines where + * in the physical address space the various Xilinx fpga access regions have + * been mapped by the boot rom. the third type of data (type xlx_iopins_t, + * one per Xilinx fpga) defines which io port pins are connected to the various + * signals required to program a Xilinx fpga. + * + * A ram/flash "bank" refers to memory controlled by the same chip select. + * + * the eeprom contents are defined as in technical note #2 - basically, + * a header, zero or more records in no particular order, and a 32 bit crc + * a record is 1 or more type bytes, a length byte and "length" bytes. + */ + +#define HYMOD_EEPROM_ID 0xAA /* eeprom id byte */ +#define HYMOD_EEPROM_VER 1 /* eeprom contents version (0-127) */ +#define HYMOD_EEPROM_SIZE 256 /* number of bytes in the eeprom */ + +/* eeprom header */ +typedef + struct { + unsigned char id; /* eeprom id byte */ + unsigned char :1; + unsigned char ver:7; /* eeprom contents version number */ + unsigned long len; /* total # of bytes btw hdr and crc */ + } +hymod_eehdr_t; + +/* maximum number of bytes available for eeprom data records */ +#define HYMOD_EEPROM_MAXLEN (HYMOD_EEPROM_SIZE \ + - sizeof (hymod_eehdr_t) \ + - sizeof (unsigned long)) + +/* eeprom data record */ +typedef + union { + struct { + unsigned char topbit:1; + unsigned char type:7; + unsigned char len; + unsigned char data[1]; /* variable length */ + } small; + struct { + unsigned short topbit:1; + unsigned short nxtbit:1; + unsigned short type:14; + unsigned short len; + unsigned char data[1]; /* variable length */ + } medium; + struct { + unsigned long topbit:1; + unsigned long nxtbit:1; + unsigned long type:30; + unsigned long len; + unsigned char data[1]; /* variable length */ + } large; + } +hymod_eerec_t; + +#define HYMOD_EEOFF_MAIN 0x00 /* i2c addr offset for main eeprom */ +#define HYMOD_EEOFF_MEZZ 0x04 /* i2c addr offset for mezz eepomr */ + +/* eeprom record types */ +#define HYMOD_EEREC_SERNO 1 /* serial number */ +#define HYMOD_EEREC_DATE 2 /* date */ +#define HYMOD_EEREC_BATCH 3 /* batch id */ +#define HYMOD_EEREC_TYPE 4 /* board type */ +#define HYMOD_EEREC_REV 5 /* revision number */ +#define HYMOD_EEREC_SDRAM 6 /* sdram sizes */ +#define HYMOD_EEREC_FLASH 7 /* flash sizes */ +#define HYMOD_EEREC_ZBT 8 /* zbt ram sizes */ +#define HYMOD_EEREC_XLXTYP 9 /* Xilinx fpga types */ +#define HYMOD_EEREC_XLXSPD 10 /* Xilinx fpga speeds */ +#define HYMOD_EEREC_XLXTMP 11 /* Xilinx fpga temperatures */ +#define HYMOD_EEREC_XLXGRD 12 /* Xilinx fpga grades */ +#define HYMOD_EEREC_CPUTYP 13 /* Motorola CPU type */ +#define HYMOD_EEREC_CPUSPD 14 /* CPU speed */ +#define HYMOD_EEREC_BUSSPD 15 /* bus speed */ +#define HYMOD_EEREC_CPMSPD 16 /* CPM speed */ +#define HYMOD_EEREC_HSTYPE 17 /* high-speed serial chip type */ +#define HYMOD_EEREC_HSCHIN 18 /* high-speed serial input channels */ +#define HYMOD_EEREC_HSCHOUT 19 /* high-speed serial output channels */ + +/* some dimensions */ +#define HYMOD_MAX_BATCH 32 /* max no. of bytes in batch id */ +#define HYMOD_MAX_SDRAM 4 /* max sdram "banks" on any board */ +#define HYMOD_MAX_FLASH 4 /* max flash "banks" on any board */ +#define HYMOD_MAX_ZBT 16 /* max ZBT rams on any board */ +#define HYMOD_MAX_XLX 4 /* max Xilinx fpgas on any board */ + +#define HYMOD_MAX_BYTES 16 /* enough to store any bytes array */ + +/* board types */ +#define HYMOD_BDTYPE_NONE 0 /* information not present */ +#define HYMOD_BDTYPE_IO 1 /* I/O main board */ +#define HYMOD_BDTYPE_CLP 2 /* CLP main board */ +#define HYMOD_BDTYPE_DSP 3 /* DSP main board */ +#define HYMOD_BDTYPE_INPUT 4 /* video input mezzanine board */ +#define HYMOD_BDTYPE_ALTINPUT 5 /* video input mezzanine board */ +#define HYMOD_BDTYPE_DISPLAY 6 /* video display mezzanine board */ +#define HYMOD_BDTYPE_MAX 7 /* first invalid value */ + +/* Xilinx fpga types */ +#define HYMOD_XTYP_NONE 0 /* information not present */ +#define HYMOD_XTYP_XCV300E 1 /* Xilinx Virtex 300 */ +#define HYMOD_XTYP_XCV400E 2 /* Xilinx Virtex 400 */ +#define HYMOD_XTYP_XCV600E 3 /* Xilinx Virtex 600 */ +#define HYMOD_XTYP_MAX 4 /* first invalid value */ + +/* Xilinx fpga speeds */ +#define HYMOD_XSPD_NONE 0 /* information not present */ +#define HYMOD_XSPD_SIX 1 +#define HYMOD_XSPD_SEVEN 2 +#define HYMOD_XSPD_EIGHT 3 +#define HYMOD_XSPD_MAX 4 /* first invalid value */ + +/* Xilinx fpga temperatures */ +#define HYMOD_XTMP_NONE 0 /* information not present */ +#define HYMOD_XTMP_COM 1 +#define HYMOD_XTMP_IND 2 +#define HYMOD_XTMP_MAX 3 /* first invalid value */ + +/* Xilinx fpga grades */ +#define HYMOD_XTMP_NONE 0 /* information not present */ +#define HYMOD_XTMP_NORMAL 1 +#define HYMOD_XTMP_ENGSAMP 2 +#define HYMOD_XTMP_MAX 3 /* first invalid value */ + +/* CPU types */ +#define HYMOD_CPUTYPE_NONE 0 /* information not present */ +#define HYMOD_CPUTYPE_MPC8260 1 /* Motorola MPC8260 embedded powerpc */ +#define HYMOD_CPUTYPE_MAX 2 /* first invalid value */ + +/* CPU/BUS/CPM clock speeds */ +#define HYMOD_CLKSPD_NONE 0 /* information not present */ +#define HYMOD_CLKSPD_33MHZ 1 +#define HYMOD_CLKSPD_66MHZ 2 +#define HYMOD_CLKSPD_100MHZ 3 +#define HYMOD_CLKSPD_133MHZ 4 +#define HYMOD_CLKSPD_166MHZ 5 +#define HYMOD_CLKSPD_200MHZ 6 +#define HYMOD_CLKSPD_MAX 7 /* first invalid value */ + +/* high speed serial chip types */ +#define HYMOD_HSSTYPE_NONE 0 /* information not present */ +#define HYMOD_HSSTYPE_AMCC52064 1 +#define HYMOD_HSSTYPE_MAX 2 /* first invalid value */ + +/* a date (yyyy-mm-dd) */ +typedef + struct { + unsigned short year; + unsigned char month; + unsigned char day; + } +hymod_date_t; + +/* describes a Xilinx fpga */ +typedef + struct { + unsigned char type; /* chip type */ + unsigned char speed; /* chip speed rating */ + unsigned char temp; /* chip temperature rating */ + unsigned char grade; /* chip grade */ + } +hymod_xlx_t; + +/* describes a Motorola embedded processor */ +typedef + struct { + unsigned char type; /* CPU type */ + unsigned char cpuspd; /* speed of the PowerPC core */ + unsigned char busspd; /* speed of the system and 60x bus */ + unsigned char cpmspd; /* speed of the CPM co-processor */ + } +hymod_mpc_t; + +/* info about high-speed (1Gbit) serial interface */ +typedef + struct { + unsigned char type; /* high-speed serial chip type */ + unsigned char nchin; /* number of input channels mounted */ + unsigned char nchout; /* number of output channels mounted */ + } +hymod_hss_t; + +/* + * this defines the contents of the serial eeprom that exists on every + * hymod board, including mezzanine boards (the serial eeprom will be + * faked for early development boards that don't have one) + */ + +typedef + struct { + unsigned char valid:1; /* contents of this struct is valid */ + unsigned char ver:7; /* eeprom contents version */ + unsigned char bdtype; /* board type */ + unsigned char bdrev; /* board revision */ + unsigned char batchlen; /* length of batch string below */ + unsigned long serno; /* serial number */ + hymod_date_t date; /* manufacture date */ + unsigned char batch[32]; /* manufacturer specific batch id */ + unsigned char nsdram; /* # of ram "banks" */ + unsigned char nflash; /* # of flash "banks" */ + unsigned char nzbt; /* # of ZBT rams */ + unsigned char nxlx; /* # of Xilinx fpgas */ + unsigned char sdramsz[HYMOD_MAX_SDRAM]; /* log2 of sdram size */ + unsigned char flashsz[HYMOD_MAX_FLASH]; /* log2 of flash size */ + unsigned char zbtsz[HYMOD_MAX_ZBT]; /* log2 of ZBT ram size */ + hymod_xlx_t xlx[HYMOD_MAX_XLX]; /* Xilinx fpga info */ + hymod_mpc_t mpc; /* Motorola MPC CPU info */ + hymod_hss_t hss; /* high-speed serial info */ + } +hymod_eeprom_t; + +/* + * this defines a region in the processor's physical address space + */ +typedef + struct { + unsigned long exists:1; /* 1 if the region exists, 0 if not */ + unsigned long size:31; /* size in bytes */ + unsigned long base; /* base address */ + } +xlx_prgn_t; + +/* + * this defines where the various Xilinx fpga access regions are mapped + * into the physical address space of the processor + */ +typedef + struct { + xlx_prgn_t prog; /* program access region */ + xlx_prgn_t reg; /* register access region */ + xlx_prgn_t port; /* port access region */ + } +xlx_mmap_t; + +/* + * this defines which 8260 i/o port pins are connected to the various + * signals required for programming a Xilinx fpga + */ +typedef + struct { + iopin_t prog_pin; /* assert for >= 300ns to program */ + iopin_t init_pin; /* goes high when fpga is cleared */ + iopin_t done_pin; /* goes high when program is done */ + iopin_t enable_pin; /* some fpgas need enabling */ + } +xlx_iopins_t; + +/* all info about one Xilinx chip */ +typedef + struct { + xlx_mmap_t mmap; + xlx_iopins_t iopins; + unsigned long irq:8; /* h/w intr req number for this fpga */ + } +xlx_info_t; + +/* all info about one hymod board */ +typedef + struct { + hymod_eeprom_t eeprom; + xlx_info_t xlx[HYMOD_MAX_XLX]; + } +hymod_board_t; + +/* + * this defines the configuration information of a hymod board-set + * (main board + possible mezzanine board). In future, there may be + * more than one mezzanine board (stackable?) - if so, add a "mezz2" + * field, and so on... or make mezz an array? + */ +typedef + struct { + unsigned long ver:8; /* version control */ + hymod_board_t main; /* main board info */ + hymod_board_t mezz; /* mezzanine board info */ + unsigned long crc; /* ensures kernel and boot prom agree */ + } +hymod_conf_t; + +#endif /* _HYMOD_H_ */ diff --git a/board/hymod/input.c b/board/hymod/input.c new file mode 100755 index 0000000..63aa13c --- /dev/null +++ b/board/hymod/input.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2003 + * Murray Jensen, CSIRO-MIT, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/* imports from common/main.c */ +extern char console_buffer[CFG_CBSIZE]; + +int +hymod_get_serno (const char *prompt) +{ + for (;;) { + int n, serno; + char *p; + +#ifdef CONFIG_BOOT_RETRY_TIME + reset_cmd_timeout (); +#endif + + n = readline (prompt); + + if (n < 0) + return (n); + + if (n == 0) + continue; + + serno = (int) simple_strtol (console_buffer, &p, 10); + + if (p > console_buffer && *p == '\0' && serno > 0) + return (serno); + + printf ("Invalid number (%s) - please re-enter\n", + console_buffer); + } +} + +int +hymod_get_ethaddr (void) +{ + for (;;) { + int n; + +#ifdef CONFIG_BOOT_RETRY_TIME + reset_cmd_timeout (); +#endif + + n = readline ("Enter board ethernet address: "); + + if (n < 0) + return (n); + + if (n == 0) + continue; + + if (n == 17) { + int i; + char *p, *q; + uchar ea[6]; + + /* see if it looks like an ethernet address */ + + p = console_buffer; + + for (i = 0; i < 6; i++) { + char term = (i == 5 ? '\0' : ':'); + + ea[i] = simple_strtol (p, &q, 16); + + if ((q - p) != 2 || *q++ != term) + break; + + p = q; + } + + if (i == 6) { + /* it looks ok - set it */ + printf ("Setting ethernet addr to %s\n", + console_buffer); + + setenv ("ethaddr", console_buffer); + + puts ("Remember to do a 'saveenv' to " + "make it permanent\n"); + + return (0); + } + } + + printf ("Invalid ethernet addr (%s) - please re-enter\n", + console_buffer); + } +} diff --git a/board/hymod/u-boot.lds b/board/hymod/u-boot.lds new file mode 100755 index 0000000..337a395 --- /dev/null +++ b/board/hymod/u-boot.lds @@ -0,0 +1,148 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mpc8260/start.o (.text) +/* + common/dlmalloc.o (.text) + lib_ppc/ppcstring.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + lib_generic/zlib.o (.text) + + . = env_offset; +*/ + common/environment.o(.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(256 * 1024); + .ppcenv : + { + common/environment.o (.ppcenv) + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/hymod/u-boot.lds.debug b/board/hymod/u-boot.lds.debug new file mode 100755 index 0000000..ddd4678 --- /dev/null +++ b/board/hymod/u-boot.lds.debug @@ -0,0 +1,137 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/mpc8xx/start.o (.text) + common/dlmalloc.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + + . = env_offset; + common/environment.o(.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} -- cgit