From: wdenk Date: Thu, 5 Jun 2003 19:27:42 +0000 (+0000) Subject: * Add support for RMU board X-Git-Tag: LABEL_2006_03_12_0025~856 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=73a8b27c574f5ec1c8fdd9d8d065bb845d8743d3;p=u-boot * Add support for RMU board * Add support for TQM862L at 100/50 MHz * Patch by Pantelis Antoniou, 02 Jun 2003: major reconstruction of networking code; add "ping" support (outgoing only!) --- diff --git a/CHANGELOG b/CHANGELOG index 7fba2f4406..b613c19a80 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,14 @@ Changes since U-Boot 0.3.1: - Changed config files of CONFIG_EEPRO100 boards to use the CFG_RX_ETH_BUFFER define. +* Add support for RMU board + +* Add support for TQM862L at 100/50 MHz + +* Patch by Pantelis Antoniou, 02 Jun 2003: + major reconstruction of networking code; + add "ping" support (outgoing only!) + * Patch by Denis Peter, 04 June 2003: add support for the MIP405T board diff --git a/MAINTAINERS b/MAINTAINERS index 87670b4eca..c1e5e138aa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -63,6 +63,9 @@ Wolfgang Denk IVMS8_128 MPC860 IVMS8_256 MPC860 LANTEC MPC850 + LWMON MPC823 + R360MPI MPC823 + RMU MPC850 RRvision MPC823 SM850 MPC850 SPD823TS MPC823 @@ -72,6 +75,7 @@ Wolfgang Denk TQM855L MPC855 TQM860L MPC860 TQM860L_FEC MPC860 + TTTech MPC823 c2mon MPC855 hermes MPC860 lwmon MPC823 diff --git a/MAKEALL b/MAKEALL index b6f636c638..2edab7b1b8 100644 --- a/MAKEALL +++ b/MAKEALL @@ -32,11 +32,11 @@ LIST_8xx=" \ IVMS8 IVMS8_128 IVMS8_256 KUP4K \ LANTEC lwmon MBX MBX860T \ MHPC MVS1 NETVIA NX823 \ - pcu_e R360MPI RBC823 RPXClassic \ - RPXlite RRvision SM850 SPD823TS \ - svm_sc8xx SXNI855T TOP860 TQM823L \ - TQM823L_LCD TQM850L TQM855L TQM860L \ - TTTech v37 \ + pcu_e R360MPI RBC823 rmu \ + RPXClassic RPXlite RRvision SM850 \ + SPD823TS svm_sc8xx SXNI855T TOP860 \ + TQM823L TQM823L_LCD TQM850L TQM855L \ + TQM860L TTTech v37 \ " ######################################################################### diff --git a/Makefile b/Makefile index 8ceaad1d1e..7606b0edb9 100644 --- a/Makefile +++ b/Makefile @@ -323,6 +323,9 @@ RPXClassic_config: unconfig RPXlite_config: unconfig @./mkconfig $(@:_config=) ppc mpc8xx RPXlite +rmu_config: unconfig + @./mkconfig $(@:_config=) ppc mpc8xx rmu + RRvision_config: unconfig @./mkconfig $(@:_config=) ppc mpc8xx RRvision @@ -349,10 +352,10 @@ TOP860_config: unconfig @./mkconfig $(@:_config=) ppc mpc8xx top860 emk # Play some tricks for configuration selection -# All boards can come with 50 MHz (default), 66MHz or 80MHz clock, +# All boards can come with 50 MHz (default), 66MHz, 80MHz or 100 MHz clock, # but only 855 and 860 boards may come with FEC # and 823 boards may have LCD support -xtract_8xx = $(subst _66MHz,,$(subst _80MHz,,$(subst _LCD,,$(subst _config,,$1)))) +xtract_8xx = $(subst _66MHz,,$(subst _80MHz,,$(subst _100MHz,,$(subst _LCD,,$(subst _config,,$1))))) FPS850L_config \ FPS860L_config \ @@ -373,7 +376,8 @@ TQM860L_66MHz_config \ TQM860L_80MHz_config \ TQM862L_config \ TQM862L_66MHz_config \ -TQM862L_80MHz_config: unconfig +TQM862L_80MHz_config \ +TQM862L_100MHz_config: unconfig @ >include/config.h @[ -z "$(findstring _66MHz,$@)" ] || \ { echo "#define CONFIG_66MHz" >>include/config.h ; \ @@ -383,6 +387,10 @@ TQM862L_80MHz_config: unconfig { echo "#define CONFIG_80MHz" >>include/config.h ; \ echo "... with 80MHz system clock" ; \ } + @[ -z "$(findstring _100MHz,$@)" ] || \ + { echo "#define CONFIG_100MHz" >>include/config.h ; \ + echo "... with 100MHz system clock" ; \ + } @[ -z "$(findstring _LCD,$@)" ] || \ { echo "#define CONFIG_LCD" >>include/config.h ; \ echo "#define CONFIG_NEC_NL6648BC20" >>include/config.h ; \ diff --git a/board/rmu/Makefile b/board/rmu/Makefile new file mode 100644 index 0000000000..ef173d0366 --- /dev/null +++ b/board/rmu/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 + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $^ + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/rmu/config.mk b/board/rmu/config.mk new file mode 100644 index 0000000000..7cb374eb85 --- /dev/null +++ b/board/rmu/config.mk @@ -0,0 +1,28 @@ +# +# (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 +# + +# +# RMU boards +# + +TEXT_BASE = 0xfff00000 diff --git a/board/rmu/flash.c b/board/rmu/flash.c new file mode 100644 index 0000000000..c05cf324ff --- /dev/null +++ b/board/rmu/flash.c @@ -0,0 +1,515 @@ +/* + * (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 +#include + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static int write_word (flash_info_t *info, ulong dest, ulong data); +static void flash_get_offsets (ulong base, flash_info_t *info); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + unsigned long size_b0 ; + int i; + + /* Init: no FLASHes known */ + for (i=0; imemc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000); + memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V; + + /* Re-do sizing to get full correct info */ + + size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]); + flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]); + +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + /* monitor protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+monitor_flash_len-1, + &flash_info[0]); +#endif + +#ifdef CFG_ENV_IS_IN_FLASH + /* ENV protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR+CFG_ENV_SIZE-1, + &flash_info[0]); +#endif + + flash_info[0].size = size_b0; + + return (size_b0); +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + /* set up sector start address table */ + if (info->flash_id & FLASH_BTYPE) { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00010000; + info->start[2] = base + 0x00018000; + info->start[3] = base + 0x00020000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + ((i-3) * 0x00040000) ; + } + } else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + info->start[i--] = base + info->size - 0x00010000; + info->start[i--] = base + info->size - 0x00018000; + info->start[i--] = base + info->size - 0x00020000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00040000; + } + } + +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: printf ("AMD "); break; + case FLASH_MAN_FUJ: printf ("FUJITSU "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n"); + break; + case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n"); + break; + case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n"); + break; + case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\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! + */ + +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + ulong value; + ulong base = (ulong)addr; + + /* Write auto select command: read Manufacturer ID */ + addr[0xAAA] = 0xAAAAAAAA ; + addr[0x555] = 0x55555555 ; + addr[0xAAA] = 0x90909090 ; + + value = addr[0] ; + + switch (value & 0x00FF00FF) { + case AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + + value = addr[2] ; /* device ID */ + + switch (value & 0x00FF00FF) { + case (AMD_ID_LV400T & 0x00FF00FF): + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (AMD_ID_LV400B & 0x00FF00FF): + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (AMD_ID_LV800T & 0x00FF00FF): + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (AMD_ID_LV800B & 0x00FF00FF): + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00400000; /*%%% Size doubled by yooth */ + break; /* => 4 MB */ + + case (AMD_ID_LV160T & 0x00FF00FF): + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (AMD_ID_LV160B & 0x00FF00FF): + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00800000; + break; /* => 8 MB */ +#if 0 /* enable when device IDs are available */ + case AMD_ID_LV320T: + info->flash_id += FLASH_AM320T; + info->sector_count = 67; + info->size = 0x00800000; + break; /* => 8 MB */ + + case AMD_ID_LV320B: + info->flash_id += FLASH_AM320B; + info->sector_count = 67; + info->size = 0x01000000; + break; /* => 16 MB */ +#endif + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + + } + /*%%% sector start address modified */ + /* set up sector start address table */ + if (info->flash_id & FLASH_BTYPE) { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00010000; + info->start[2] = base + 0x00018000; + info->start[3] = base + 0x00020000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + ((i-3) * 0x00040000) ; + } + } else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + info->start[i--] = base + info->size - 0x00010000; + info->start[i--] = base + info->size - 0x00018000; + info->start[i--] = base + info->size - 0x00020000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00040000; + } + } + + /* check for protected sectors */ + for (i = 0; i < info->sector_count; i++) { + /* read sector protection at sector address, (A7 .. A0) = 0x02 */ + /* D0 = 1 if protected */ + addr = (volatile unsigned long *)(info->start[i]); + info->protect[i] = addr[4] & 1 ; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr = (volatile unsigned long *)info->start[0]; + + *addr = 0xF0F0F0F0; /* reset bank */ + } + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + vu_long *addr = (vu_long*)(info->start[0]); + int flag, prot, sect, l_sect; + ulong start, now, last; + + 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; + } + + if ((info->flash_id == FLASH_UNKNOWN) || + (info->flash_id > FLASH_AMD_COMP)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[0xAAA] = 0xAAAAAAAA; + addr[0x555] = 0x55555555; + addr[0xAAA] = 0x80808080; + addr[0xAAA] = 0xAAAAAAAA; + addr[0x555] = 0x55555555; + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr = (vu_long *)(info->start[sect]) ; + addr[0] = 0x30303030 ; + l_sect = sect; + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + + start = get_timer (0); + last = start; + addr = (vu_long *)(info->start[l_sect]); + while ((addr[0] & 0x80808080) != 0x80808080) { + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + return 1; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + +DONE: + /* reset to read mode */ + addr = (vu_long *)info->start[0]; + addr[0] = 0xF0F0F0F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +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)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + vu_long *addr = (vu_long *)(info->start[0]); + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*((vu_long *)dest) & data) != data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[0xAAA] = 0xAAAAAAAA; + addr[0x555] = 0x55555555; + addr[0xAAA] = 0xA0A0A0A0; + + *((vu_long *)dest) = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/rmu/rmu.c b/board/rmu/rmu.c new file mode 100644 index 0000000000..c9925d09a3 --- /dev/null +++ b/board/rmu/rmu.c @@ -0,0 +1,184 @@ +/* + * (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 +#include + +/* ------------------------------------------------------------------------- */ + +static long int dram_size (long int, long int *, long int); + +/* ------------------------------------------------------------------------- */ + +#define _NOT_USED_ 0xFFFFCC25 + +const uint sdram_table[] = +{ + /* + * Single Read. (Offset 00h in UPMA RAM) + */ + 0x0F03CC04, 0x00ACCC24, 0x1FF74C20, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + + /* + * Burst Read. (Offset 08h in UPMA RAM) + */ + 0x0F03CC04, 0x00ACCC24, 0x00FFCC20, 0x00FFCC20, + 0x01FFCC20, 0x1FF74C20, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + + /* + * Single Write. (Offset 18h in UPMA RAM) + */ + 0x0F03CC02, 0x00AC0C24, 0x1FF74C25, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + + /* + * Burst Write. (Offset 20h in UPMA RAM) + */ + 0x0F03CC00, 0x00AC0C20, 0x00FFFC20, 0x00FFFC22, + 0x01FFFC24, 0x1FF74C25, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + + /* + * Refresh. (Offset 30h in UPMA RAM) + * (Initialization code at 0x36) + */ + 0x0FF0CC24, 0xFFFFCC24, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, 0xEFFB8C34, 0x0FF74C34, + 0x0FFACCB4, 0x0FF5CC34, 0x0FFCC34, 0x0FFFCCB4, + + /* + * Exception. (Offset 3Ch in UPMA RAM) + */ + 0x0FEA8C34, 0x1FB54C34, 0xFFFFCC34, _NOT_USED_ +}; + +/* ------------------------------------------------------------------------- */ + + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + puts ("Board: RMU\n") ; + return (0) ; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + long int size10 ; + + upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint)); + + /* Refresh clock prescalar */ + memctl->memc_mptpr = CFG_MPTPR ; + + memctl->memc_mar = 0x00000088; + + /* Map controller banks 1 to the SDRAM bank */ + memctl->memc_or1 = CFG_OR1_PRELIM; + memctl->memc_br1 = CFG_BR1_PRELIM; + + memctl->memc_mamr = CFG_MAMR_10COL & (~(MAMR_PTAE)); /* no refresh yet */ + + udelay(200); + + /* perform SDRAM initializsation sequence */ + + memctl->memc_mcr = 0x80002136 ; /* SDRAM bank 0 */ + udelay(1); + + memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */ + + udelay (1000); + + /* Check Bank 0 Memory Size + * try 10 column mode + */ + + size10 = dram_size (CFG_MAMR_10COL, (ulong *)SDRAM_BASE_PRELIM, SDRAM_MAX_SIZE) ; + + return (size10); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check memory range for valid RAM. A simple memory test determines + * the actually available RAM size between addresses `base' and + * `base + maxsize'. Some (not all) hardware errors are detected: + * - short between address lines + * - short between data lines + */ + +static long int dram_size (long int mamr_value, long int *base, long int maxsize) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + volatile long int *addr; + ulong cnt, val; + ulong save[32]; /* to make test non-destructive */ + unsigned char i = 0; + + memctl->memc_mamr = mamr_value; + + for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) { + addr = base + cnt; /* pointer arith! */ + + save[i++] = *addr; + *addr = ~cnt; + } + + /* write 0 to base address */ + addr = base; + save[i] = *addr; + *addr = 0; + + /* check at base address */ + if ((val = *addr) != 0) { + *addr = save[i]; + return (0); + } + + for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) { + addr = base + cnt; /* pointer arith! */ + + val = *addr; + *addr = save[--i]; + + if (val != (~cnt)) { + return (cnt * sizeof(long)); + } + } + return (maxsize); +} diff --git a/board/rmu/u-boot.lds b/board/rmu/u-boot.lds new file mode 100644 index 0000000000..c79a5a0ffa --- /dev/null +++ b/board/rmu/u-boot.lds @@ -0,0 +1,134 @@ +/* + * (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_ppc/ppcstring.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + lib_generic/zlib.o (.text) +/* XXX ? + . = env_offset; +*/ + common/environment.o(.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _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 = .); + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} + diff --git a/board/rmu/u-boot.lds.debug b/board/rmu/u-boot.lds.debug new file mode 100644 index 0000000000..22138f8aad --- /dev/null +++ b/board/rmu/u-boot.lds.debug @@ -0,0 +1,131 @@ +/* + * (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) + } + .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 = .); + + __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 = .); +} + diff --git a/board/tqm8xx/flash.c b/board/tqm8xx/flash.c index 6b4ea7d227..98bea0e005 100644 --- a/board/tqm8xx/flash.c +++ b/board/tqm8xx/flash.c @@ -21,6 +21,8 @@ * MA 02111-1307 USA */ +/* #define DEBUG */ + #include #include @@ -53,8 +55,12 @@ unsigned long flash_init (void) /* Static FLASH Bank configuration here - FIXME XXX */ + debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM); + size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); + debug ("## Get flash bank 2 size @ 0x%08x\n",FLASH_BASE1_PRELIM); + if (flash_info[0].flash_id == FLASH_UNKNOWN) { printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", size_b0, size_b0<<20); @@ -62,6 +68,8 @@ unsigned long flash_init (void) size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]); + debug ("## Prelim. Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1); + if (size_b1 > size_b0) { printf ("## ERROR: " "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n", @@ -77,10 +85,19 @@ unsigned long flash_init (void) return (0); } + debug ("## Before remap: " + "BR0: 0x%08x OR0: 0x%08x " + "BR1: 0x%08x OR1: 0x%08x\n", + memctl->memc_br0, memctl->memc_or0, + memctl->memc_br1, memctl->memc_or1); + /* Remap FLASH according to real size */ memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK); memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V; + debug ("## BR0: 0x%08x OR0: 0x%08x\n", + memctl->memc_br0, memctl->memc_or0); + /* Re-do sizing to get full correct info */ size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]); @@ -105,6 +122,9 @@ unsigned long flash_init (void) memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) | BR_MS_GPCM | BR_V; + debug ("## BR1: 0x%08x OR1: 0x%08x\n", + memctl->memc_br1, memctl->memc_or1); + /* Re-do sizing to get full correct info */ size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0), &flash_info[1]); @@ -129,8 +149,14 @@ unsigned long flash_init (void) flash_info[1].flash_id = FLASH_UNKNOWN; flash_info[1].sector_count = -1; + flash_info[1].size = 0; + + debug ("## DISABLE BR1: 0x%08x OR1: 0x%08x\n", + memctl->memc_br1, memctl->memc_or1); } + debug ("## Final Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1); + flash_info[0].size = size_b0; flash_info[1].size = size_b1; @@ -215,6 +241,8 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) value = addr[0]; + debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value); + switch (value) { case AMD_MANUFACT: info->flash_id = FLASH_MAN_AMD; @@ -231,6 +259,8 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) value = addr[1]; /* device ID */ + debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value); + switch (value) { case AMD_ID_LV400T: info->flash_id += FLASH_AM400T; @@ -278,6 +308,12 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) info->sector_count = 71; info->size = 0x00800000; break; /* => 8 MB */ + case AMD_ID_DL640: +debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n"); + info->flash_id += FLASH_AMDL640; + info->sector_count = 142; + info->size = 0x00800000; + break; default: info->flash_id = FLASH_UNKNOWN; return (0); /* => no or unknown flash */ @@ -368,6 +404,8 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) int flag, prot, sect, l_sect; ulong start, now, last; + debug ("flash_erase: first: %d last: %d\n", s_first, s_last); + if ((s_first < 0) || (s_first > s_last)) { if (info->flash_id == FLASH_UNKNOWN) { printf ("- missing\n"); diff --git a/common/cmd_net.c b/common/cmd_net.c index a1ff2ba9a6..e8bf0ae9f2 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -95,6 +95,10 @@ static void netboot_update_env(void) ip_to_string (NetOurDNSIP, tmp); setenv("dnsip", tmp); } + + if (NetOurNISDomain[0]) + setenv("domain", NetOurNISDomain); + } static int netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) @@ -165,4 +169,27 @@ netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) return rcode; } +#if (CONFIG_COMMANDS & CFG_CMD_PING) +int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + if (argc < 2) + return -1; + + NetPingIP = string_to_ip(argv[1]); + if (NetPingIP == 0) { + printf ("Usage:\n%s\n", cmdtp->usage); + return -1; + } + + if (NetLoop(PING) < 0) { + printf("ping failed; host %s is not alive\n", argv[1]); + return 1; + } + + printf("host %s is alive\n", argv[1]); + + return 0; +} +#endif /* CFG_CMD_PING */ + #endif /* CFG_CMD_NET */ diff --git a/common/command.c b/common/command.c index 9e631f1c5d..d52ddf1c8f 100644 --- a/common/command.c +++ b/common/command.c @@ -316,6 +316,7 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_NANDBOOT CMD_TBL_NEXT CMD_TBL_NM + CMD_TBL_PING CMD_TBL_PORTIO_OUT CMD_TBL_PCI CMD_TBL_PRINTENV diff --git a/include/cmd_confdefs.h b/include/cmd_confdefs.h index 18ce6d8eef..7ab553d317 100644 --- a/include/cmd_confdefs.h +++ b/include/cmd_confdefs.h @@ -81,6 +81,7 @@ #define CFG_CMD_NAND 0x0000800000000000 /* NAND support */ #define CFG_CMD_BMP 0x0001000000000000 /* BMP support */ #define CFG_CMD_PORTIO 0x0002000000000000 /* Port I/O */ +#define CFG_CMD_PING 0x0004000000000000 /* ping support */ #define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFF /* ALL commands */ @@ -113,6 +114,7 @@ CFG_CMD_NAND | \ CFG_CMD_PCI | \ CFG_CMD_PCMCIA | \ + CFG_CMD_PING | \ CFG_CMD_REGINFO | \ CFG_CMD_SAVES | \ CFG_CMD_SCSI | \ diff --git a/include/cmd_net.h b/include/cmd_net.h index e9ca5c5bc8..842cb3e154 100644 --- a/include/cmd_net.h +++ b/include/cmd_net.h @@ -64,11 +64,24 @@ int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #define CMD_TBL_DHCP #endif /* CFG_CMD_DHCP */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) +#define CMD_TBL_PING MK_CMD_TBL_ENTRY( \ + "ping", 4, 2, 1, do_ping, \ + "ping - check if host is reachable\n", \ + "host\n" \ +), + +int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#else +#define CMD_TBL_PING +#endif /* CFG_CMD_PING */ + #else #define CMD_TBL_BOOTP #define CMD_TBL_TFTPB #define CMD_TBL_RARPB #define CMD_TBL_DHCP +#define CMD_TBL_PING #endif /* CFG_CMD_NET */ #endif diff --git a/include/commproc.h b/include/commproc.h index d6cf9baadc..2d9ab5cdb3 100644 --- a/include/commproc.h +++ b/include/commproc.h @@ -1254,7 +1254,11 @@ typedef struct scc_enet { #define PA_ENET_TXD ((ushort)0x0008) #define PA_ENET_TCLK ((ushort)0x0200) #define PA_ENET_RCLK ((ushort)0x0800) +#if defined(CONFIG_RMU) +#define PC_ENET_TENA ((uint)0x00000002) /* PC14 */ +#else #define PB_ENET_TENA ((uint)0x00002000) +#endif #define PC_ENET_CLSN ((ushort)0x0040) #define PC_ENET_RENA ((ushort)0x0080) diff --git a/include/configs/TQM862L.h b/include/configs/TQM862L.h index 653d0c79ae..1d0aea1fec 100644 --- a/include/configs/TQM862L.h +++ b/include/configs/TQM862L.h @@ -251,14 +251,15 @@ * Reset PLL lock status sticky bit, timer expired status bit and timer * interrupt status bit * - * If this is a 80 MHz CPU, set PLL multiplication factor to 5 (5*16=80)! + * If this is a 80 MHz or 100 MHz CPU, + * set PLL multiplication factor to 5 (5 * 16 = 80, 5 * 20 = 100) */ -#ifdef CONFIG_80MHz /* for 80 MHz, we use a 16 MHz clock * 5 */ +#if defined(CONFIG_80MHz) || defined(CONFIG_100MHz) #define CFG_PLPRCR \ ( (5-1)< 50.000.000 / Divider = 98 - * 66 Mhz => 66.000.000 / Divider = 129 - * 80 Mhz => 80.000.000 / Divider = 156 + * 50 MHz => 50.000.000 / Divider = 98 + * 66 Mhz => 66.000.000 / Divider = 129 + * 80 Mhz => 80.000.000 / Divider = 156 + * 100 Mhz => 100.000.000 / Divider = 195 */ -#if defined(CONFIG_80MHz) +#if defined(CONFIG_100MHz) +#define CFG_MAMR_PTA 195 +#elif defined(CONFIG_80MHz) #define CFG_MAMR_PTA 156 #elif defined(CONFIG_66MHz) #define CFG_MAMR_PTA 129 diff --git a/include/configs/rmu.h b/include/configs/rmu.h new file mode 100644 index 0000000000..0a94714f7b --- /dev/null +++ b/include/configs/rmu.h @@ -0,0 +1,379 @@ +/* + * (C) Copyright 2003 + * 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 + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + + +/* + * High Level Configuration Options + * (easy to change) + */ + +#undef CONFIG_MPC860 +#define CONFIG_MPC850 1 /* This is a MPC850 CPU */ +#define CONFIG_RPXLITE 1 /* RMU is the RPXlite clone */ +#define CONFIG_RMU 1 + +#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ +#undef CONFIG_8xx_CONS_SMC2 +#undef CONFIG_8xx_CONS_NONE +#define CONFIG_BAUDRATE 9600 /* console baudrate = 9600bps */ +#if 0 +#define CONFIG_BOOTDELAY -1 /* autoboot disabled */ +#else +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ +#endif + +#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */ + +#undef CONFIG_BOOTARGS +#define CONFIG_BOOTCOMMAND \ + "bootp; " \ + "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \ + "bootm" + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */ + +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x0040000 /* memtest works on */ +#define CFG_MEMTEST_END 0x00C0000 /* 4 ... 12 MB in DRAM */ + +#define CFG_LOAD_ADDR 0x100000 /* default load address */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ +/*----------------------------------------------------------------------- + * Internal Memory Mapped Register + */ +#define CFG_IMMR 0xFA200000 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */ +#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_FLASH_BASE 0xFF800000 +/*%%% #define CFG_FLASH_BASE 0xFFF00000 */ +#if defined(DEBUG) || (CONFIG_COMMANDS & CFG_CMD_IDE) +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#else +#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ +#endif +#define CFG_MONITOR_BASE 0xFFF00000 +/*%%% #define CFG_MONITOR_BASE CFG_FLASH_BASE */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/*----------------------------------------------------------------------- + * FLASH organization + */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 35 /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_OFFSET 0x00740000 /* Offset of Environment Sector */ +#define CFG_ENV_SIZE 0x40000 /* Total Size of Environment Sector */ +#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET) + +/* Address and size of Redundant Environment Sector */ +#define CFG_ENV_OFFSET_REDUND (CFG_ENV_OFFSET+CFG_ENV_SIZE) +#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */ +#endif + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control 11-9 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze + */ +#if defined(CONFIG_WATCHDOG) +#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \ + SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP) +#else +#define CFG_SYPCR (SYPCR_SWTC | 0x00000600 | SYPCR_BME | SYPCR_SWF | SYPCR_SWP) +#endif + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration 11-6 + *----------------------------------------------------------------------- + * PCMCIA config., multi-function pin tri-state + */ +#define CFG_SIUMCR (SIUMCR_MLRC10) + +/*----------------------------------------------------------------------- + * TBSCR - Time Base Status and Control 11-26 + *----------------------------------------------------------------------- + * Clear Reference Interrupt Status, Timebase freezing enabled + */ +#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF | TBSCR_TBE) + +/*----------------------------------------------------------------------- + * RTCSC - Real-Time Clock Status and Control Register 11-27 + *----------------------------------------------------------------------- + */ +/*%%%#define CFG_RTCSC (RTCSC_SEC | RTCSC_ALR | RTCSC_RTF| RTCSC_RTE) */ +#define CFG_RTCSC (RTCSC_SEC | RTCSC_RTE) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 11-31 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled + */ +#define CFG_PISCR (PISCR_PS | PISCR_PITF) + +/*----------------------------------------------------------------------- + * PLPRCR - PLL, Low-Power, and Reset Control Register 15-30 + *----------------------------------------------------------------------- + * Reset PLL lock status sticky bit, timer expired status bit and timer + * interrupt status bit + * + * If this is a 80 MHz CPU, set PLL multiplication factor to 5 (5*16=80)! + */ +/* up to 50 MHz we use a 1:1 clock */ +#define CFG_PLPRCR ( (5 << PLPRCR_MF_SHIFT) | PLPRCR_TEXPS ) + +/*----------------------------------------------------------------------- + * SCCR - System Clock and reset Control Register 15-27 + *----------------------------------------------------------------------- + * Set clock output, timebase and RTC source and divider, + * power management and some other internal clocks + */ +#define SCCR_MASK SCCR_EBDF00 +/* up to 50 MHz we use a 1:1 clock */ +#define CFG_SCCR (SCCR_COM00 | SCCR_TBS) + +/*----------------------------------------------------------------------- + * PCMCIA stuff + *----------------------------------------------------------------------- + * + */ +#define CFG_PCMCIA_MEM_ADDR (0xE0000000) +#define CFG_PCMCIA_MEM_SIZE ( 64 << 20 ) +#define CFG_PCMCIA_DMA_ADDR (0xE4000000) +#define CFG_PCMCIA_DMA_SIZE ( 64 << 20 ) +#define CFG_PCMCIA_ATTRB_ADDR (0xE8000000) +#define CFG_PCMCIA_ATTRB_SIZE ( 64 << 20 ) +#define CFG_PCMCIA_IO_ADDR (0xEC000000) +#define CFG_PCMCIA_IO_SIZE ( 64 << 20 ) + +/*----------------------------------------------------------------------- + * IDE/ATA stuff (Supports IDE harddisk on PCMCIA Adapter) + *----------------------------------------------------------------------- + */ + +#define CONFIG_IDE_8xx_PCCARD 1 /* Use IDE with PC Card Adapter */ + +#undef CONFIG_IDE_8xx_DIRECT /* Direct IDE not supported */ +#undef CONFIG_IDE_LED /* LED for ide not supported */ +#undef CONFIG_IDE_RESET /* reset for ide not supported */ + +#define CFG_IDE_MAXBUS 1 /* max. 1 IDE bus */ +#define CFG_IDE_MAXDEVICE 1 /* max. 1 drive per IDE bus */ + +#define CFG_ATA_IDE0_OFFSET 0x0000 + +#define CFG_ATA_BASE_ADDR CFG_PCMCIA_MEM_ADDR + +/* Offset for data I/O */ +#define CFG_ATA_DATA_OFFSET (CFG_PCMCIA_MEM_SIZE + 0x320) + +/* Offset for normal register accesses */ +#define CFG_ATA_REG_OFFSET (2 * CFG_PCMCIA_MEM_SIZE + 0x320) + +/* Offset for alternate registers */ +#define CFG_ATA_ALT_OFFSET 0x0100 + +/*----------------------------------------------------------------------- + * + *----------------------------------------------------------------------- + * + */ +/*#define CFG_DER 0x2002000F*/ +#define CFG_DER 0 + +/* + * Init Memory Controller: + * + * BR0 and OR0 (FLASH) + */ + +#define FLASH_BASE_PRELIM 0xFE000000 /* FLASH base */ +#define CFG_PRELIM_OR_AM 0xFE000000 /* OR addr mask */ + +/* FLASH timing: ACS = 0, TRLX = 0, CSNT = 0, SCY = 4, ETHR = 0, BIH = 1 */ +#define CFG_OR_TIMING_FLASH (OR_SCY_4_CLK | OR_BI) + +#define CFG_OR0_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH) +#define CFG_BR0_PRELIM ((FLASH_BASE_PRELIM & BR_BA_MSK) | BR_V) + +/* + * BR1 and OR1 (SDRAM) + * + */ +#define SDRAM_BASE_PRELIM 0x00000000 /* SDRAM base */ +#define SDRAM_MAX_SIZE 0x01000000 /* max 16 MB */ + +/* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care) */ +#define CFG_OR_TIMING_SDRAM 0x00000E00 + +#define CFG_OR1_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM ) +#define CFG_BR1_PRELIM ((SDRAM_BASE_PRELIM & BR_BA_MSK) | BR_MS_UPMA | BR_V ) + +/* RPXLITE mem setting */ +#define CFG_BR3_PRELIM 0xFA400001 /* BCSR */ +#define CFG_OR3_PRELIM 0xFFFF8910 +#define CFG_BR4_PRELIM 0xFA000401 /* NVRAM&SRAM */ +#define CFG_OR4_PRELIM 0xFFFE0970 + +/* + * Memory Periodic Timer Prescaler + */ + +/* periodic timer for refresh */ +#define CFG_MAMR_PTA 20 + +/* + * Refresh clock Prescalar + */ +#define CFG_MPTPR MPTPR_PTP_DIV2 + +/* + * MAMR settings for SDRAM + */ + +/* 10 column SDRAM */ +#define CFG_MAMR_10COL ((CFG_MAMR_PTA << MAMR_PTA_SHIFT) | MAMR_PTAE | \ + MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A10 | \ + MAMR_RLFA_16X | MAMR_WLFA_16X | MAMR_TLFA_16X) + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +/* + * BCSRx + * + * Board Status and Control Registers + * + */ + +#define BCSR0 0xFA400000 +#define BCSR1 0xFA400001 +#define BCSR2 0xFA400002 +#define BCSR3 0xFA400003 + +#define BCSR0_ENMONXCVR 0x01 /* Monitor XVCR Control */ +#define BCSR0_ENNVRAM 0x02 /* CS4# Control */ +#define BCSR0_LED5 0x04 /* LED5 control 0='on' 1='off' */ +#define BCSR0_LED4 0x08 /* LED4 control 0='on' 1='off' */ +#define BCSR0_FULLDPLX 0x10 /* Ethernet XCVR Control */ +#define BCSR0_COLTEST 0x20 +#define BCSR0_ETHLPBK 0x40 +#define BCSR0_ETHEN 0x80 + +#define BCSR1_PCVCTL7 0x01 /* PC Slot B Control */ +#define BCSR1_PCVCTL6 0x02 +#define BCSR1_PCVCTL5 0x04 +#define BCSR1_PCVCTL4 0x08 +#define BCSR1_IPB5SEL 0x10 + +#define BCSR2_ENPA5HDR 0x08 /* USB Control */ +#define BCSR2_ENUSBCLK 0x10 +#define BCSR2_USBPWREN 0x20 +#define BCSR2_USBSPD 0x40 +#define BCSR2_USBSUSP 0x80 + +#define BCSR3_BWRTC 0x01 /* Real Time Clock Battery */ +#define BCSR3_BWNVR 0x02 /* NVRAM Battery */ +#define BCSR3_RDY_BSY 0x04 /* Flash Operation */ +#define BCSR3_RPXL 0x08 /* Reserved (reads back '1') */ +#define BCSR3_D27 0x10 /* Dip Switch settings */ +#define BCSR3_D26 0x20 +#define BCSR3_D25 0x40 +#define BCSR3_D24 0x80 + +#endif /* __CONFIG_H */ diff --git a/include/configs/sc520_spunk.h b/include/configs/sc520_spunk.h index 2b5a54d9a0..0a28805fda 100644 --- a/include/configs/sc520_spunk.h +++ b/include/configs/sc520_spunk.h @@ -206,7 +206,7 @@ #define CFG_FIRST_PCI_IRQ 9 #define CFG_SECOND_PCI_IRQ 10 -#define CFG_THIRD_PCI_IRQ 11 +#define CFG_THIRD_PCI_IRQ 11 #define CFG_FORTH_PCI_IRQ 12 diff --git a/include/net.h b/include/net.h index e4f7cbdd22..689a90f6ee 100644 --- a/include/net.h +++ b/include/net.h @@ -200,7 +200,9 @@ typedef struct /* * ICMP stuff (just enough to handle (host) redirect messages) */ +#define ICMP_ECHO_REPLY 0 /* Echo reply */ #define ICMP_REDIRECT 5 /* Redirect (change route) */ +#define ICMP_ECHO_REQUEST 8 /* Echo request */ /* Codes for REDIRECT. */ #define ICMP_REDIR_NET 0 /* Redirect Net */ @@ -292,11 +294,15 @@ extern int NetState; /* Network loop state */ extern int NetRestartWrap; /* Tried all network devices */ #endif -typedef enum { BOOTP, RARP, ARP, TFTP, DHCP } proto_t; +typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS } proto_t; /* from net/net.c */ extern char BootFile[128]; /* Boot File name */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) +extern IPaddr_t NetPingIP; /* the ip address to ping */ +#endif + /* Initialize the network adapter */ extern int NetLoop(proto_t); @@ -323,6 +329,9 @@ extern void NetSetTimeout(int, thand_f *); /* Set timeout handler */ /* Transmit "NetTxPacket" */ extern void NetSendPacket(volatile uchar *, int); +/* Transmit UDP packet, performing ARP request if needed */ +extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len); + /* Processes a received packet */ extern void NetReceive(volatile uchar *, int); @@ -373,6 +382,9 @@ static inline void NetCopyLong(ulong *to, ulong *from) /* Convert an IP address to a string */ extern void ip_to_string (IPaddr_t x, char *s); +/* Convert a string to ip address */ +extern IPaddr_t string_to_ip(char *s); + /* read an IP address from a environment variable */ extern IPaddr_t getenv_IPaddr (char *); diff --git a/net/Makefile b/net/Makefile index db0a69fae0..b899d7b2f2 100644 --- a/net/Makefile +++ b/net/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = libnet.a -OBJS = net.o tftp.o bootp.o rarp.o arp.o eth.o +OBJS = net.o tftp.o bootp.o rarp.o eth.o all: $(LIB) $(LIB): $(START) $(OBJS) diff --git a/net/arp.c b/net/arp.c deleted file mode 100644 index c09dc1aac8..0000000000 --- a/net/arp.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * (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 -#include -#include -#include "bootp.h" -#include "tftp.h" -#include "arp.h" - -#if (CONFIG_COMMANDS & CFG_CMD_NET) - -#define TIMEOUT 5 /* Seconds before trying ARP again */ -#ifndef CONFIG_NET_RETRY_COUNT -# define TIMEOUT_COUNT 5 /* # of timeouts before giving up */ -#else -# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) -#endif - -static void ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len); -static void ArpTimeout(void); - -int ArpTry = 0; - -/* - * Handle a ARP received packet. - */ -static void -ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len) -{ - /* Check if the frame is really an ARP reply */ - if (memcmp (NetServerEther, NetBcastAddr, 6) != 0) { -#ifdef DEBUG - printf("Got good ARP - start TFTP\n"); -#endif - TftpStart (); - } -} - - -/* - * Timeout on ARP request. - */ -static void -ArpTimeout(void) -{ - if (ArpTry >= TIMEOUT_COUNT) { - puts ("\nRetry count exceeded; starting again\n"); - NetStartAgain (); - } else { - NetSetTimeout (TIMEOUT * CFG_HZ, ArpTimeout); - ArpRequest (); - } -} - - -void -ArpRequest (void) -{ - int i; - volatile uchar *pkt; - ARP_t * arp; - - printf("ARP broadcast %d\n", ++ArpTry); - pkt = NetTxPacket; - - NetSetEther(pkt, NetBcastAddr, PROT_ARP); - pkt += ETHER_HDR_SIZE; - - arp = (ARP_t *)pkt; - - arp->ar_hrd = htons(ARP_ETHER); - arp->ar_pro = htons(PROT_IP); - arp->ar_hln = 6; - arp->ar_pln = 4; - arp->ar_op = htons(ARPOP_REQUEST); - - memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ - NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr */ - for (i=10; i<16; ++i) { - arp->ar_data[i] = 0; /* dest ET addr = 0 */ - } - - if((NetServerIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { - if (NetOurGatewayIP == 0) { - puts ("## Warning: gatewayip needed but not set\n"); - } - NetWriteIP((uchar*)&arp->ar_data[16], NetOurGatewayIP); - } else { - NetWriteIP((uchar*)&arp->ar_data[16], NetServerIP); - } - - - NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); - - NetSetTimeout(TIMEOUT * CFG_HZ, ArpTimeout); - NetSetHandler(ArpHandler); -} - -#endif /* CFG_CMD_NET */ diff --git a/net/arp.h b/net/arp.h deleted file mode 100644 index b83533495e..0000000000 --- a/net/arp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * (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 - */ - - -#ifndef __ARP_H__ -#define __ARP_H__ - -/**********************************************************************/ -/* - * Global functions and variables. - */ - -extern int ArpTry; - -extern void ArpRequest (void); /* Send a ARP request */ - -/**********************************************************************/ - -#endif /* __ARP_H__ */ - diff --git a/net/bootp.c b/net/bootp.c index 4be0ad586a..8e0f332466 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -24,7 +24,6 @@ #include #include "bootp.h" #include "tftp.h" -#include "arp.h" #ifdef CONFIG_STATUS_LED #include #endif @@ -336,10 +335,7 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) return; } - /* Send ARP request to get TFTP server ethernet address. - * This automagically starts TFTP, too. - */ - ArpRequest(); + TftpStart(); } #endif /* !CFG_CMD_DHCP */ @@ -866,10 +862,7 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) NetState = NETLOOP_SUCCESS; return; } - /* Send ARP request to get TFTP server ethernet address. - * This automagically starts TFTP, too. - */ - ArpRequest(); + TftpStart(); return; } break; diff --git a/net/net.c b/net/net.c index b9cb67b25c..4758595d1c 100644 --- a/net/net.c +++ b/net/net.c @@ -65,10 +65,16 @@ #include "bootp.h" #include "tftp.h" #include "rarp.h" -#include "arp.h" #if (CONFIG_COMMANDS & CFG_CMD_NET) +#define ARP_TIMEOUT 5 /* Seconds before trying ARP again */ +#ifndef CONFIG_NET_RETRY_COUNT +# define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */ +#else +# define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) +#endif + #if 0 #define ET_DEBUG #endif @@ -88,7 +94,7 @@ ushort NetBootFileSize=0; /* Our bootfile size in blocks */ ulong NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */ uchar NetOurEther[6]; /* Our ethernet address */ uchar NetServerEther[6] = /* Boot server enet address */ - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + { 0, 0, 0, 0, 0, 0 }; IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ volatile uchar *NetRxPkt; /* Current receive packet */ @@ -96,6 +102,8 @@ int NetRxPktLen; /* Current rx packet length */ unsigned NetIPID; /* IP packet ID */ uchar NetBcastAddr[6] = /* Ethernet bcast address */ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +uchar NetEtherNullAddr[6] = + { 0, 0, 0, 0, 0, 0 }; int NetState; /* Network loop state */ #ifdef CONFIG_NET_MULTI int NetRestartWrap = 0; /* Tried all network devices */ @@ -105,6 +113,12 @@ static int NetDevExists = 0; /* At least one device configured */ char BootFile[128]; /* Boot File name */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) +IPaddr_t NetPingIP; /* the ip address to ping */ + +static void PingStart(void); +#endif + volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */ @@ -116,6 +130,81 @@ volatile uchar *NetTxPacket = 0; /* THE transmit packet */ static int net_check_prereq (proto_t protocol); +/**********************************************************************/ + +IPaddr_t NetArpWaitPacketIP; +IPaddr_t NetArpWaitReplyIP; +uchar *NetArpWaitPacketMAC; /* MAC address of waiting packet's destination */ +uchar *NetArpWaitTxPacket; /* THE transmit packet */ +int NetArpWaitTxPacketSize; +uchar NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; +ulong NetArpWaitTimerStart; +int NetArpWaitTry; + +void ArpRequest(void) +{ + int i; + volatile uchar *pkt; + ARP_t * arp; + +#ifdef ET_DEBUG + printf("ARP broadcast %d\n", NetArpWaitTry); +#endif + pkt = NetTxPacket; + + NetSetEther(pkt, NetBcastAddr, PROT_ARP); + pkt += ETHER_HDR_SIZE; + + arp = (ARP_t *)pkt; + + arp->ar_hrd = htons(ARP_ETHER); + arp->ar_pro = htons(PROT_IP); + arp->ar_hln = 6; + arp->ar_pln = 4; + arp->ar_op = htons(ARPOP_REQUEST); + + memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ + NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr */ + for (i=10; i<16; ++i) { + arp->ar_data[i] = 0; /* dest ET addr = 0 */ + } + + if((NetArpWaitPacketIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { + if (NetOurGatewayIP == 0) { + puts ("## Warning: gatewayip needed but not set\n"); + } + NetArpWaitReplyIP = NetOurGatewayIP; + } else + NetArpWaitReplyIP = NetArpWaitPacketIP; + + NetWriteIP((uchar*)&arp->ar_data[16], NetArpWaitReplyIP); + (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); +} + +void ArpTimeoutCheck(void) +{ + ulong t; + + if (!NetArpWaitPacketIP) + return; + + t = get_timer(0); + + /* check for arp timeout */ + if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) { + NetArpWaitTry++; + + if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { + puts ("\nARP Retry count exceeded; starting again\n"); + NetArpWaitTry = 0; + NetStartAgain(); + } else { + NetArpWaitTimerStart = t; + ArpRequest(); + } + } +} + /**********************************************************************/ /* * Main network processing loop. @@ -133,6 +222,14 @@ NetLoop(proto_t protocol) NetDevExists = 0; #endif + /* XXX problem with bss workaround */ + NetArpWaitPacketMAC = NULL; + NetArpWaitTxPacket = NULL; + NetArpWaitPacketIP = 0; + NetArpWaitReplyIP = 0; + NetArpWaitTxPacket = NULL; + NetTxPacket = NULL; + if (!NetTxPacket) { int i; @@ -144,6 +241,13 @@ NetLoop(proto_t protocol) for (i = 0; i < PKTBUFSRX; i++) { NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; } + + } + + if (!NetArpWaitTxPacket) { + NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); + NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; + NetArpWaitTxPacketSize = 0; } eth_halt(); @@ -165,11 +269,27 @@ restart: */ switch (protocol) { +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: +#endif case TFTP: NetCopyIP(&NetOurIP, &bd->bi_ip_addr); - NetServerIP = getenv_IPaddr ("serverip"); NetOurGatewayIP = getenv_IPaddr ("gatewayip"); NetOurSubnetMask= getenv_IPaddr ("netmask"); + + switch (protocol) { + case TFTP: + NetServerIP = getenv_IPaddr ("serverip"); + break; +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: + /* nothing */ + break; +#endif + default: + break; + } + break; case BOOTP: case RARP: @@ -202,8 +322,7 @@ restart: switch (protocol) { case TFTP: /* always use ARP to get server ethernet address */ - ArpTry = 0; - ArpRequest (); + TftpStart(); break; #if (CONFIG_COMMANDS & CFG_CMD_DHCP) @@ -224,6 +343,11 @@ restart: RarpTry = 0; RarpRequest (); break; +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: + PingStart(); + break; +#endif default: break; } @@ -260,6 +384,7 @@ restart: return (-1); } + ArpTimeoutCheck(); /* * Check for a timeout, and run the timeout handler @@ -376,7 +501,138 @@ NetSendPacket(volatile uchar * pkt, int len) (void) eth_send(pkt, len); } +int +NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len) +{ + /* convert to new style broadcast */ + if (dest == 0) + dest = 0xFFFFFFFF; + + /* if broadcast, make the ether address a broadcast and don't do ARP */ + if (dest == 0xFFFFFFFF) + ether = NetBcastAddr; + + /* if MAC address was not discovered yet, save the packet and do an ARP request */ + if (memcmp(ether, NetEtherNullAddr, 6) == 0) { + +#ifdef ET_DEBUG + printf("sending ARP for %08lx\n", dest); +#endif + + NetArpWaitPacketIP = dest; + NetArpWaitPacketMAC = ether; + NetSetEther (NetArpWaitTxPacket, NetArpWaitPacketMAC, PROT_IP); + NetSetIP (NetArpWaitTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); + memcpy(NetArpWaitTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, + (uchar *)NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, len); + + /* size of the waiting packet */ + NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE + len; + + /* and do the ARP request */ + NetArpWaitTry = 1; + NetArpWaitTimerStart = get_timer(0); + ArpRequest(); + return 1; /* waiting */ + } + +#ifdef ET_DEBUG + printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n", + dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); +#endif + + NetSetEther (NetTxPacket, ether, PROT_IP); + NetSetIP (NetTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len); + (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); + + return 0; /* transmited */ +} + +#if (CONFIG_COMMANDS & CFG_CMD_PING) +static ushort PingSeqNo; + +int PingSend(void) +{ + static uchar mac[6]; + volatile IP_t *ip; + volatile ushort *s; + + /* XXX always send arp request */ + + memcpy(mac, NetEtherNullAddr, 6); + +#ifdef ET_DEBUG + printf("sending ARP for %08lx\n", NetPingIP); +#endif + + NetArpWaitPacketIP = NetPingIP; + NetArpWaitPacketMAC = mac; + + NetSetEther(NetArpWaitTxPacket, mac, PROT_IP); + + ip = (volatile IP_t *)(NetArpWaitTxPacket + ETHER_HDR_SIZE); + + /* + * Construct an IP and ICMP header. (need to set no fragment bit - XXX) + */ + ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ + ip->ip_tos = 0; + ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); + ip->ip_id = htons(NetIPID++); + ip->ip_off = htons(0x4000); /* No fragmentation */ + ip->ip_ttl = 255; + ip->ip_p = 0x01; /* ICMP */ + ip->ip_sum = 0; + NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ + NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */ + ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); + + s = &ip->udp_src; /* XXX ICMP starts here */ + s[0] = htons(0x0800); /* echo-request, code */ + s[1] = 0; /* checksum */ + s[2] = 0; /* identifier */ + s[3] = htons(PingSeqNo++); /* sequence number */ + s[1] = ~NetCksum((uchar *)s, 8/2); + + /* size of the waiting packet */ + NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + 8; + + /* and do the ARP request */ + NetArpWaitTry = 1; + NetArpWaitTimerStart = get_timer(0); + ArpRequest(); + return 1; /* waiting */ +} + +static void +PingTimeout (void) +{ + eth_halt(); + NetState = NETLOOP_FAIL; /* we did not get the reply */ +} +static void +PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) +{ + IPaddr_t tmp; + volatile IP_t *ip = (volatile IP_t *)pkt; + + tmp = NetReadIP((void *)&ip->ip_src); + if (tmp != NetPingIP) + return; + + NetState = NETLOOP_SUCCESS; +} + +static void PingStart(void) +{ + NetSetTimeout (10 * CFG_HZ, PingTimeout); + NetSetHandler (PingHandler); + + PingSend(); +} + +#endif void NetReceive(volatile uchar * pkt, int len) @@ -387,7 +643,6 @@ NetReceive(volatile uchar * pkt, int len) IPaddr_t tmp; int x; - NetRxPkt = pkt; NetRxPktLen = len; et = (Ethernet_t *)pkt; @@ -462,14 +717,40 @@ NetReceive(volatile uchar * pkt, int len) NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]); memcpy (&arp->ar_data[ 0], NetOurEther, 6); NetCopyIP(&arp->ar_data[ 6], &NetOurIP); - NetSendPacket((uchar *)et,((uchar *)arp-pkt)+ARP_HDR_SIZE); + (void) eth_send((uchar *)et, ((uchar *)arp-pkt) + ARP_HDR_SIZE); return; - case ARPOP_REPLY: /* set TFTP server eth addr */ + + case ARPOP_REPLY: /* arp reply */ + /* are we waiting for a reply */ + if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC) + break; #ifdef ET_DEBUG - printf("Got ARP REPLY, set server/gtwy eth addr\n"); + printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", + arp->ar_data[0], arp->ar_data[1], + arp->ar_data[2], arp->ar_data[3], + arp->ar_data[4], arp->ar_data[5]); #endif - memcpy (NetServerEther, &arp->ar_data[0], 6); - (*packetHandler)(0,0,0,0); /* start TFTP */ + + tmp = NetReadIP(&arp->ar_data[6]); + + /* matched waiting packet's address */ + if (tmp == NetArpWaitReplyIP) { +#ifdef ET_DEBUG + printf("Got it\n"); +#endif + /* save address for later use */ + memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); + + /* modify header, and transmit it */ + memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6); + (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize); + + /* no arp request pending now */ + NetArpWaitPacketIP = 0; + NetArpWaitTxPacketSize = 0; + NetArpWaitPacketMAC = NULL; + + } return; default: #ifdef ET_DEBUG @@ -553,13 +834,26 @@ NetReceive(volatile uchar * pkt, int len) if (ip->ip_p == IPPROTO_ICMP) { ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); - if (icmph->type != ICMP_REDIRECT) - return; + switch (icmph->type) { + case ICMP_REDIRECT: if (icmph->code != ICMP_REDIR_HOST) return; puts (" ICMP Host Redirect to "); print_IPaddr(icmph->un.gateway); putc(' '); + break; +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case ICMP_ECHO_REPLY: + /* + * IP header OK. Pass the packet to the current handler. + */ + /* XXX point to ip packet */ + (*packetHandler)((uchar *)ip, 0, 0, 0); + break; +#endif + default: + return; + } } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ return; } @@ -582,15 +876,25 @@ NetReceive(volatile uchar * pkt, int len) static int net_check_prereq (proto_t protocol) { switch (protocol) { - case ARP: /* nothing to do */ - break; - + /* Fall through */ +#if (CONFIG_COMMANDS & CFG_CMD_PING) + case PING: + if (NetPingIP == 0) { + puts ("*** ERROR: ping address not given\n"); + return (1); + } + goto common; +#endif case TFTP: if (NetServerIP == 0) { puts ("*** ERROR: `serverip' not set\n"); return (1); } +#if (CONFIG_COMMANDS & CFG_CMD_PING) + common: +#endif + if (NetOurIP == 0) { puts ("*** ERROR: `ipaddr' not set\n"); return (1); @@ -626,6 +930,8 @@ static int net_check_prereq (proto_t protocol) #endif } /* Fall through */ + default: + return(0); } return (0); /* OK */ } @@ -723,22 +1029,14 @@ void ip_to_string (IPaddr_t x, char *s) ); } -void print_IPaddr (IPaddr_t x) -{ - char tmp[16]; - - ip_to_string(x, tmp); - - puts(tmp); -} - -IPaddr_t getenv_IPaddr (char *var) +IPaddr_t string_to_ip(char *s) { IPaddr_t addr; - char *s, *e; + char *e; int i; - s = getenv (var); + if (s == NULL) + return(0); for (addr=0, i=0; i<4; ++i) { ulong val = s ? simple_strtoul(s, &e, 10) : 0; @@ -751,3 +1049,17 @@ IPaddr_t getenv_IPaddr (char *var) return (htonl(addr)); } + +void print_IPaddr (IPaddr_t x) +{ + char tmp[16]; + + ip_to_string(x, tmp); + + puts(tmp); +} + +IPaddr_t getenv_IPaddr (char *var) +{ + return (string_to_ip(getenv(var))); +} diff --git a/net/tftp.c b/net/tftp.c index 0ad244fd97..5598be32f1 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -142,10 +142,7 @@ TftpSend (void) break; } - NetSetEther (NetTxPacket, NetServerEther, PROT_IP); - NetSetIP (NetTxPacket + ETHER_HDR_SIZE, NetServerIP, - TftpServerPort, TftpOurPort, len); - NetSendPacket (NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); + NetSendUDPPacket(NetServerEther, NetServerIP, TftpServerPort, TftpOurPort, len); } @@ -257,17 +254,6 @@ TftpTimeout (void) void TftpStart (void) { -#ifdef ET_DEBUG - printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n", - NetServerEther[0], - NetServerEther[1], - NetServerEther[2], - NetServerEther[3], - NetServerEther[4], - NetServerEther[5] - ); -#endif /* DEBUG */ - if (BootFile[0] == '\0') { IPaddr_t OurIP = ntohl(NetOurIP); @@ -320,6 +306,9 @@ TftpStart (void) TftpState = STATE_RRQ; TftpOurPort = 1024 + (get_timer(0) % 3072); + /* zero out server ether in case the server ip has changed */ + memset(NetServerEther, 0, 6); + TftpSend (); }