diff options
| author | wdenk <wdenk> | 2002-08-26 22:23:10 +0000 | 
|---|---|---|
| committer | wdenk <wdenk> | 2002-08-26 22:23:10 +0000 | 
| commit | 67c4f48a49bb428bca409b1f6b6ca03f448c3645 (patch) | |
| tree | 21b11066f9e0d807466bf8515b9ee3082f371929 | |
| parent | 16f217049a70da97bc61eff7a95b4b6313850909 (diff) | |
| download | olio-uboot-2014.01-67c4f48a49bb428bca409b1f6b6ca03f448c3645.tar.xz olio-uboot-2014.01-67c4f48a49bb428bca409b1f6b6ca03f448c3645.zip | |
Initial revision
| -rw-r--r-- | board/mpc8260ads/mpc8260ads.c | 272 | ||||
| -rw-r--r-- | board/mpl/common/memtst.c | 568 | 
2 files changed, 840 insertions, 0 deletions
| diff --git a/board/mpc8260ads/mpc8260ads.c b/board/mpc8260ads/mpc8260ads.c new file mode 100644 index 000000000..1d920fe93 --- /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 <common.h> +#include <ioports.h> +#include <mpc8260.h> + +/* + * 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 000000000..f0ace2a76 --- /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 <common.h> +#include <asm/processor.h> +#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 <size> bytes from <startaddr> 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 <size> bytes from <startaddr> 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 <size> bytes from <startaddr> 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 <size> bytes from <startaddr> + * 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 <size> bytes from <startaddr+size> + * 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 <size> bytes from <startaddr> 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 <size> bytes from <startaddr> + * 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 <size> bytes from <startaddr> 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 <size> bytes from <startaddr> + * 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); +} |