From 67c4f48a49bb428bca409b1f6b6ca03f448c3645 Mon Sep 17 00:00:00 2001 From: wdenk Date: Mon, 26 Aug 2002 22:23:10 +0000 Subject: [PATCH] Initial revision --- board/mpc8260ads/mpc8260ads.c | 272 ++++++++++++++++ board/mpl/common/memtst.c | 568 ++++++++++++++++++++++++++++++++++ 2 files changed, 840 insertions(+) create mode 100644 board/mpc8260ads/mpc8260ads.c create mode 100644 board/mpl/common/memtst.c diff --git a/board/mpc8260ads/mpc8260ads.c b/board/mpc8260ads/mpc8260ads.c new file mode 100644 index 0000000000..1d920fe934 --- /dev/null +++ b/board/mpc8260ads/mpc8260ads.c @@ -0,0 +1,272 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Modified during 2001 by + * Advanced Communications Technologies (Australia) Pty. Ltd. + * Howard Walker, Tuong Vu-Dinh + * + * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com + * Added support for the 16M dram simm on the 8260ads boards + * + * 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 + +/* + * 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 */ + { /* conf ppar psor pdir podr pdat */ + /* PA31 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxENB */ + /* PA30 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 TxClav */ + /* PA29 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 TxSOC */ + /* PA28 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 RxENB */ + /* PA27 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxSOC */ + /* PA26 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 RxClav */ + /* PA25 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */ + /* PA24 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */ + /* PA23 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */ + /* PA22 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */ + /* PA21 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */ + /* PA20 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */ + /* PA19 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */ + /* PA18 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */ + /* PA17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */ + /* PA16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */ + /* PA15 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */ + /* PA14 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */ + /* PA13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */ + /* PA12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */ + /* PA11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */ + /* PA10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */ + /* PA9 */ { 0, 1, 1, 1, 0, 0 }, /* FCC1 L1TXD */ + /* PA8 */ { 0, 1, 1, 0, 0, 0 }, /* FCC1 L1RXD */ + /* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */ + /* PA6 */ { 1, 1, 1, 1, 0, 0 }, /* TDM A1 L1RSYNC */ + /* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */ + /* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */ + /* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */ + /* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */ + /* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* FREERUN */ + /* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */ + }, + + /* Port B configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */ + /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */ + /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */ + /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */ + /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */ + /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */ + /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */ + /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */ + /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */ + /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */ + /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */ + /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */ + /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */ + /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */ + /* PB17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_DIV */ + /* PB16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RX_ERR */ + /* PB15 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_ERR */ + /* PB14 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TX_EN */ + /* PB13 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:COL */ + /* PB12 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:CRS */ + /* PB11 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB10 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB9 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB8 */ { 0, 1, 0, 0, 0, 0 }, /* FCC3:RXD */ + /* PB7 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB6 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB5 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB4 */ { 0, 1, 0, 1, 0, 0 }, /* FCC3:TXD */ + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + }, + + /* Port C */ + { /* conf ppar psor pdir podr pdat */ + /* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */ + /* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */ + /* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */ + /* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */ + /* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* UART Clock in */ + /* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */ + /* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */ + /* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */ + /* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* ATMTFCLK */ + /* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */ + /* PC21 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */ + /* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */ + /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK CLK13 */ + /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK14) */ + /* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */ + /* PC16 */ { 0, 1, 0, 0, 0, 0 }, /* FCC Tx Clock (CLK16) */ + /* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */ + /* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */ + /* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */ + /* PC12 */ { 0, 1, 0, 1, 0, 0 }, /* PC12 */ + /* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* LXT971 transmit control */ + /* PC10 */ { 1, 1, 0, 0, 0, 0 }, /* LXT970 FETHMDC */ + /* PC9 */ { 1, 1, 0, 0, 0, 0 }, /* LXT970 FETHMDIO */ + /* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */ + /* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */ + /* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */ + /* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */ + /* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */ + /* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */ + /* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */ + /* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */ + /* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */ + }, + + /* Port D */ + { /* conf ppar psor pdir podr pdat */ + /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */ + /* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */ + /* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */ + /* PD28 */ { 0, 1, 0, 0, 0, 0 }, /* PD28 */ + /* PD27 */ { 0, 1, 1, 1, 0, 0 }, /* PD27 */ + /* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */ + /* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */ + /* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */ + /* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */ + /* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */ + /* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */ + /* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */ + /* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */ + /* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */ + /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ + /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */ + /* PD15 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 0, 0, 1, 0, 0 }, /* LED */ + /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */ + /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */ + /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */ + /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */ + /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */ + /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */ + /* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */ + /* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */ + /* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */ + /* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */ + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + } +}; + +typedef struct bscr_ { + unsigned long bcsr0; + unsigned long bcsr1; + unsigned long bcsr2; + unsigned long bcsr3; + unsigned long bcsr4; + unsigned long bcsr5; + unsigned long bcsr6; + unsigned long bcsr7; +} bcsr_t; + +void reset_phy(void) +{ + volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR; + + /* reset the FEC port */ + bcsr->bcsr1 &= ~FETH_RST; + bcsr->bcsr1 |= FETH_RST; +} + + +int board_pre_init (void) +{ + volatile bcsr_t *bcsr = (bcsr_t *)CFG_BCSR; + bcsr->bcsr1 = ~FETHIEN & ~RS232EN_1; + + return 0; +} + +long int initdram(int board_type) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + volatile uchar *ramaddr, + c = 0xff; + int i; + +#ifndef CFG_RAMBOOT + immap->im_siu_conf.sc_ppc_acr = 0x00000002; + immap->im_siu_conf.sc_ppc_alrh = 0x01267893; + immap->im_siu_conf.sc_tescr1 = 0x00004000; + + /* init local sdram, bank 4 */ + memctl->memc_lsrt = 0x00000010; + memctl->memc_or4 = 0xFFC01480; + memctl->memc_br4 = 0x04001861; + memctl->memc_lsdmr = 0x2886A522; + ramaddr = (uchar *)CFG_LSDRAM_BASE; + *ramaddr = c; + memctl->memc_lsdmr = 0x0886A522; + for( i = 0; i < 8; i++ ) { + *ramaddr = c; + } + memctl->memc_lsdmr = 0x1886A522; + *ramaddr = c; + memctl->memc_lsdmr = 0x4086A522; + + /* init sdram dimm */ + ramaddr = (uchar *)CFG_SDRAM_BASE; + memctl->memc_psrt = 0x00000010; + immap->im_memctl.memc_or2 = 0xFF000CA0; + immap->im_memctl.memc_br2 = 0x00000041; + memctl->memc_psdmr = 0x296EB452; + *ramaddr = c; + memctl->memc_psdmr = 0x096EB452; + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_psdmr = 0x196EB452; + *ramaddr = c; + memctl->memc_psdmr = 0x416EB452; + *ramaddr = c; +#endif + + /* return total ram size of simm */ + return (16 * 1024 * 1024); +} + +int checkboard(void) +{ + puts ("Board: Motorola MPC8260ADS\n"); + return 0; +} + diff --git a/board/mpl/common/memtst.c b/board/mpl/common/memtst.c new file mode 100644 index 0000000000..f0ace2a760 --- /dev/null +++ b/board/mpl/common/memtst.c @@ -0,0 +1,568 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * 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 + * + */ + +/* NOT Used yet... + add following code to PIP405.c : +int testdram (void) +{ + unsigned char s[32]; + int i; + + i = getenv_r ("testmem", s, 32); + if (i != 0) { + i = (int) simple_strtoul (s, NULL, 10); + if ((i > 0) && (i < 0xf)) { + printf ("testing "); + i = mem_test (0, ramsize, i); + if (i > 0) + printf ("ERROR "); + else + printf ("Ok "); + } + } + return (1); +} +*/ + + +#include +#include +#include <405gp_i2c.h> + +#define FALSE 0 +#define TRUE 1 + +#define TEST_QUIET 8 +#define TEST_SHOW_PROG 4 +#define TEST_SHOW_ERR 2 +#define TEST_SHOW_ALL 1 + +#define TESTPAT1 0xAA55AA55 +#define TESTPAT2 0x55AA55AA +#define TEST_PASSED 0 +#define TEST_FAILED 1 +#define MEGABYTE (1024*1024) + + + + + +typedef struct { + volatile unsigned long pat1; + volatile unsigned long pat2; +} RAM_MEMTEST_PATTERN2; + +typedef struct { + volatile unsigned long addr; +} RAM_MEMTEST_ADDRLINE; + +static __inline unsigned long Swap_32 (unsigned long val) +{ + return (((val << 16) & 0xFFFF0000) | ((val >> 16) & 0x0000FFFF)); +} + +void testm_puts (int quiet, char *buf) +{ + if ((quiet & TEST_SHOW_ALL) == TEST_SHOW_ALL) + puts (buf); +} + + +void Write_Error (int mode, unsigned long addr, unsigned long expected, + unsigned long actual) +{ + + char dispbuf[64]; + + sprintf (dispbuf, "\n ERROR @ 0x%08lX: (exp: 0x%08lX act: 0x%08lX) ", + addr, expected, actual); + testm_puts (((mode & TEST_SHOW_ERR) == + TEST_SHOW_ERR) ? TEST_SHOW_ALL : mode, dispbuf); +} + + +/* + * fills the memblock of bytes from with pat1 and pat2 + */ + + +void RAM_MemTest_WritePattern2 (unsigned long startaddr, + unsigned long size, unsigned long pat1, + unsigned long pat2) +{ + RAM_MEMTEST_PATTERN2 *p, *pe; + + p = (RAM_MEMTEST_PATTERN2 *) startaddr; + pe = (RAM_MEMTEST_PATTERN2 *) (startaddr + size); + + while (p < pe) { + p->pat1 = pat1; + p->pat2 = pat2; + p++; + } /* endwhile */ +} + +/* + * checks the memblock of bytes from with pat1 and pat2 + * returns the address of the first error or NULL if all is well + */ + +void *RAM_MemTest_CheckPattern2 (int mode, unsigned long startaddr, + unsigned long size, unsigned long pat1, + unsigned long pat2) +{ + RAM_MEMTEST_PATTERN2 *p, *pe; + unsigned long actual1, actual2; + + p = (RAM_MEMTEST_PATTERN2 *) startaddr; + pe = (RAM_MEMTEST_PATTERN2 *) (startaddr + size); + + while (p < pe) { + actual1 = p->pat1; + actual2 = p->pat2; + + if (actual1 != pat1) { + Write_Error (mode, (unsigned long) &(p->pat1), pat1, actual1); + return ((void *) &(p->pat1)); + } + /* endif */ + if (actual2 != pat2) { + Write_Error (mode, (unsigned long) &(p->pat2), pat2, actual2); + return ((void *) &(p->pat2)); + } + /* endif */ + p++; + } /* endwhile */ + + return (NULL); +} + +/* + * fills the memblock of bytes from with the address + */ + +void RAM_MemTest_WriteAddrLine (unsigned long startaddr, + unsigned long size, int swapped) +{ + RAM_MEMTEST_ADDRLINE *p, *pe; + + p = (RAM_MEMTEST_ADDRLINE *) startaddr; + pe = (RAM_MEMTEST_ADDRLINE *) (startaddr + size); + + if (!swapped) { + while (p < pe) { + p->addr = (unsigned long) p; + p++; + } /* endwhile */ + } else { + while (p < pe) { + p->addr = Swap_32 ((unsigned long) p); + p++; + } /* endwhile */ + } /* endif */ +} + +/* + * checks the memblock of bytes from + * returns the address of the error or NULL if all is well + */ + +void *RAM_MemTest_CheckAddrLine (int mode, unsigned long startaddr, + unsigned long size, int swapped) +{ + RAM_MEMTEST_ADDRLINE *p, *pe; + unsigned long actual, expected; + + p = (RAM_MEMTEST_ADDRLINE *) startaddr; + pe = (RAM_MEMTEST_ADDRLINE *) (startaddr + size); + + if (!swapped) { + while (p < pe) { + actual = p->addr; + expected = (unsigned long) p; + if (actual != expected) { + Write_Error (mode, (unsigned long) &(p->addr), expected, + actual); + return ((void *) &(p->addr)); + } /* endif */ + p++; + } /* endwhile */ + } else { + while (p < pe) { + actual = p->addr; + expected = Swap_32 ((unsigned long) p); + if (actual != expected) { + Write_Error (mode, (unsigned long) &(p->addr), expected, + actual); + return ((void *) &(p->addr)); + } /* endif */ + p++; + } /* endwhile */ + } /* endif */ + + return (NULL); +} + +/* + * checks the memblock of bytes from + * returns the address of the error or NULL if all is well + */ + +void *RAM_MemTest_CheckAddrLineReverse (int mode, unsigned long startaddr, + unsigned long size, int swapped) +{ + RAM_MEMTEST_ADDRLINE *p, *pe; + unsigned long actual, expected; + + p = (RAM_MEMTEST_ADDRLINE *) (startaddr + size - sizeof (p->addr)); + pe = (RAM_MEMTEST_ADDRLINE *) startaddr; + + if (!swapped) { + while (p > pe) { + actual = p->addr; + expected = (unsigned long) p; + if (actual != expected) { + Write_Error (mode, (unsigned long) &(p->addr), expected, + actual); + return ((void *) &(p->addr)); + } /* endif */ + p--; + } /* endwhile */ + } else { + while (p > pe) { + actual = p->addr; + expected = Swap_32 ((unsigned long) p); + if (actual != expected) { + Write_Error (mode, (unsigned long) &(p->addr), expected, + actual); + return ((void *) &(p->addr)); + } /* endif */ + p--; + } /* endwhile */ + } /* endif */ + + return (NULL); +} + +/* + * fills the memblock of bytes from with walking bit pattern + */ + +void RAM_MemTest_WriteWalkBit (unsigned long startaddr, unsigned long size) +{ + volatile unsigned long *p, *pe; + unsigned long i; + + p = (unsigned long *) startaddr; + pe = (unsigned long *) (startaddr + size); + i = 0; + + while (p < pe) { + *p = 1UL << i; + i = (i + 1 + (((unsigned long) p) >> 7)) % 32; + p++; + } /* endwhile */ +} + +/* + * checks the memblock of bytes from + * returns the address of the error or NULL if all is well + */ + +void *RAM_MemTest_CheckWalkBit (int mode, unsigned long startaddr, + unsigned long size) +{ + volatile unsigned long *p, *pe; + unsigned long actual, expected; + unsigned long i; + + p = (unsigned long *) startaddr; + pe = (unsigned long *) (startaddr + size); + i = 0; + + while (p < pe) { + actual = *p; + expected = (1UL << i); + if (actual != expected) { + Write_Error (mode, (unsigned long) p, expected, actual); + return ((void *) p); + } /* endif */ + i = (i + 1 + (((unsigned long) p) >> 7)) % 32; + p++; + } /* endwhile */ + + return (NULL); +} + +/* + * fills the memblock of bytes from with "random" pattern + */ + +void RAM_MemTest_WriteRandomPattern (unsigned long startaddr, + unsigned long size, + unsigned long *pat) +{ + unsigned long i, p; + + p = *pat; + + for (i = 0; i < (size / 4); i++) { + *(unsigned long *) (startaddr + i * 4) = p; + if ((p % 2) > 0) { + p ^= i; + p >>= 1; + p |= 0x80000000; + } else { + p ^= ~i; + p >>= 1; + } /* endif */ + } /* endfor */ + *pat = p; +} + +/* + * checks the memblock of bytes from + * returns the address of the error or NULL if all is well + */ + +void *RAM_MemTest_CheckRandomPattern (int mode, unsigned long startaddr, + unsigned long size, + unsigned long *pat) +{ + void *perr = NULL; + unsigned long i, p, p1; + + p = *pat; + + for (i = 0; i < (size / 4); i++) { + p1 = *(unsigned long *) (startaddr + i * 4); + if (p1 != p) { + if (perr == NULL) { + Write_Error (mode, startaddr + i * 4, p, p1); + perr = (void *) (startaddr + i * 4); + } /* endif */ + } + /* endif */ + if ((p % 2) > 0) { + p ^= i; + p >>= 1; + p |= 0x80000000; + } else { + p ^= ~i; + p >>= 1; + } /* endif */ + } /* endfor */ + + *pat = p; + return (perr); +} + + +void RAM_MemTest_WriteData1 (unsigned long startaddr, unsigned long size, + unsigned long *pat) +{ + RAM_MemTest_WritePattern2 (startaddr, size, TESTPAT1, TESTPAT2); +} + +void *RAM_MemTest_CheckData1 (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat) +{ + return (RAM_MemTest_CheckPattern2 + (mode, startaddr, size, TESTPAT1, TESTPAT2)); +} + +void RAM_MemTest_WriteData2 (unsigned long startaddr, unsigned long size, + unsigned long *pat) +{ + RAM_MemTest_WritePattern2 (startaddr, size, TESTPAT2, TESTPAT1); +} + +void *RAM_MemTest_CheckData2 (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat) +{ + return (RAM_MemTest_CheckPattern2 + (mode, startaddr, size, TESTPAT2, TESTPAT1)); +} + +void RAM_MemTest_WriteAddr1 (unsigned long startaddr, unsigned long size, + unsigned long *pat) +{ + RAM_MemTest_WriteAddrLine (startaddr, size, FALSE); +} + +void *RAM_MemTest_Check1Addr1 (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat) +{ + return (RAM_MemTest_CheckAddrLine (mode, startaddr, size, FALSE)); +} + +void *RAM_MemTest_Check2Addr1 (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat) +{ + return (RAM_MemTest_CheckAddrLineReverse + (mode, startaddr, size, FALSE)); +} + +void RAM_MemTest_WriteAddr2 (unsigned long startaddr, unsigned long size, + unsigned long *pat) +{ + RAM_MemTest_WriteAddrLine (startaddr, size, TRUE); +} + +void *RAM_MemTest_Check1Addr2 (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat) +{ + return (RAM_MemTest_CheckAddrLine (mode, startaddr, size, TRUE)); +} + +void *RAM_MemTest_Check2Addr2 (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat) +{ + return (RAM_MemTest_CheckAddrLineReverse + (mode, startaddr, size, TRUE)); +} + + + +typedef struct { + void (*test_write) (unsigned long startaddr, unsigned long size, + unsigned long *pat); + char *test_write_desc; + void *(*test_check1) (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat); + void *(*test_check2) (int mode, unsigned long startaddr, + unsigned long size, unsigned long *pat); +} RAM_MEMTEST_FUNC; + + +#define TEST_STAGES 5 +const RAM_MEMTEST_FUNC test_stage[TEST_STAGES] = { + {RAM_MemTest_WriteData1, "data test 1...\n", RAM_MemTest_CheckData1, + NULL}, + {RAM_MemTest_WriteData2, "data test 2...\n", RAM_MemTest_CheckData2, + NULL}, + {RAM_MemTest_WriteAddr1, "address line test...\n", + RAM_MemTest_Check1Addr1, RAM_MemTest_Check2Addr1}, + {RAM_MemTest_WriteAddr2, "address line test (swapped)...\n", + RAM_MemTest_Check1Addr2, RAM_MemTest_Check2Addr2}, + {RAM_MemTest_WriteRandomPattern, "random data test...\n", + RAM_MemTest_CheckRandomPattern, NULL} +}; + + + +int mem_test (unsigned long start, unsigned long ramsize, int quiet) +{ + unsigned long errors, stage; + unsigned long startaddr, size, i; + const unsigned long blocksize = 0x80000; /* check in 512KB blocks */ + unsigned long *perr; + unsigned long rdatapat; + char dispbuf[80]; + int status = TEST_PASSED; + int prog = 0; + + errors = 0; + startaddr = start; + size = ramsize; + if ((quiet & TEST_SHOW_PROG) == TEST_SHOW_PROG) { + prog++; + printf ("."); + } + sprintf (dispbuf, "\nMemory Test: addr = 0x%lx size = 0x%lx\n", + startaddr, size); + testm_puts (quiet, dispbuf); + for (stage = 0; stage < TEST_STAGES; stage++) { + sprintf (dispbuf, test_stage[stage].test_write_desc); + testm_puts (quiet, dispbuf); + /* fill SDRAM */ + rdatapat = 0x12345678; + sprintf (dispbuf, "writing block: "); + testm_puts (quiet, dispbuf); + for (i = 0; i < size; i += blocksize) { + sprintf (dispbuf, "%04lX\b\b\b\b", i / blocksize); + testm_puts (quiet, dispbuf); + test_stage[stage].test_write (startaddr + i, blocksize, + &rdatapat); + } /* endfor */ + sprintf (dispbuf, "\n"); + testm_puts (quiet, dispbuf); + if ((quiet & TEST_SHOW_PROG) == TEST_SHOW_PROG) { + prog++; + printf ("."); + } + /* check SDRAM */ + rdatapat = 0x12345678; + sprintf (dispbuf, "checking block: "); + testm_puts (quiet, dispbuf); + for (i = 0; i < size; i += blocksize) { + sprintf (dispbuf, "%04lX\b\b\b\b", i / blocksize); + testm_puts (quiet, dispbuf); + if ((perr = + test_stage[stage].test_check1 (quiet, startaddr + i, + blocksize, + &rdatapat)) != NULL) { + status = TEST_FAILED; + } /* endif */ + } /* endfor */ + sprintf (dispbuf, "\n"); + testm_puts (quiet, dispbuf); + if ((quiet & TEST_SHOW_PROG) == TEST_SHOW_PROG) { + prog++; + printf ("."); + } + if (test_stage[stage].test_check2 != NULL) { + /* check2 SDRAM */ + sprintf (dispbuf, "2nd checking block: "); + rdatapat = 0x12345678; + testm_puts (quiet, dispbuf); + for (i = 0; i < size; i += blocksize) { + sprintf (dispbuf, "%04lX\b\b\b\b", i / blocksize); + testm_puts (quiet, dispbuf); + if ((perr = + test_stage[stage].test_check2 (quiet, startaddr + i, + blocksize, + &rdatapat)) != NULL) { + status = TEST_FAILED; + } /* endif */ + } /* endfor */ + sprintf (dispbuf, "\n"); + testm_puts (quiet, dispbuf); + if ((quiet & TEST_SHOW_PROG) == TEST_SHOW_PROG) { + prog++; + printf ("."); + } + } + + } /* next stage */ + if ((quiet & TEST_SHOW_PROG) == TEST_SHOW_PROG) { + while (prog-- > 0) + printf ("\b \b"); + } + + if (status == TEST_FAILED) + errors++; + + return (errors); +}