diff options
Diffstat (limited to 'board')
| -rw-r--r-- | board/jse/Makefile | 44 | ||||
| -rw-r--r-- | board/jse/README.txt | 48 | ||||
| -rw-r--r-- | board/jse/config.mk | 24 | ||||
| -rw-r--r-- | board/jse/flash.c | 671 | ||||
| -rw-r--r-- | board/jse/host_bridge.c | 89 | ||||
| -rw-r--r-- | board/jse/init.S | 105 | ||||
| -rw-r--r-- | board/jse/jse.c | 160 | ||||
| -rw-r--r-- | board/jse/jse_priv.h | 25 | ||||
| -rw-r--r-- | board/jse/sdram.c | 182 | ||||
| -rw-r--r-- | board/jse/u-boot.lds | 140 | 
10 files changed, 1488 insertions, 0 deletions
| diff --git a/board/jse/Makefile b/board/jse/Makefile new file mode 100644 index 000000000..0da27b696 --- /dev/null +++ b/board/jse/Makefile @@ -0,0 +1,44 @@ +# +# Copyright 2004 Picture Elements, Inc. +# Stephen Williams <steve@icarus.com> +# +# 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 sdram.o flash.o host_bridge.o +SOBJS	= init.o + +$(LIB):	$(OBJS) $(SOBJS) +	$(AR) crv $@ $(OBJS) + +clean: +	rm -f $(SOBJS) $(OBJS) + +distclean:	clean +	rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/jse/README.txt b/board/jse/README.txt new file mode 100644 index 000000000..84497db70 --- /dev/null +++ b/board/jse/README.txt @@ -0,0 +1,48 @@ +JSE Configuration Details + +Memory Bank 0 -- Flash chip +--------------------------- + +0xfff00000 - 0xffffffff + +The flash chip is really only 512Kbytes, but the high address bit of +the 1Meg region is ignored, so the flash is replicated through the +region. Thus, this is consistent with a flash base address 0xfff80000. + +The placement at the end is to be consistent with reset behavior, +where the processor itself initially uses this bus to load the branch +vector and start running. + +On-Chip Memory +-------------- + +0xf4000000 - 0xf4000fff + +The 405GPr includes a 4K on-chip memory that can be placed however +software chooses. I choose to place the memory at this address, to +keep it out of the cachable areas. + + +Memory Bank 1 -- SystemACE Controller +------------------------------------- + +0xf0000000 - 0xf00fffff + +The SystemACE chip is along on peripheral bank CS#1. We don't need +much space, but 1Meg is the smallest we can configure the chip to +allocate. We need it far away from the flash region, because this +region is set to be non-cached. + + +Internal Peripherals +-------------------- + +0xef600300 - 0xef6008ff + +These are scattered various peripherals internal to the PPC405GPr +chip. + +SDRAM +----- + +0x00000000 - 0x07ffffff  (128 MBytes) diff --git a/board/jse/config.mk b/board/jse/config.mk new file mode 100644 index 000000000..03ec08501 --- /dev/null +++ b/board/jse/config.mk @@ -0,0 +1,24 @@ +# +# (C) Copyright 2003 Picture Elements, Inc. +# +# 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 +# + +# +# Picture Elements, Inc. JSE boards +# + +TEXT_BASE = 0xFFF80000 diff --git a/board/jse/flash.c b/board/jse/flash.c new file mode 100644 index 000000000..a86ac1a4c --- /dev/null +++ b/board/jse/flash.c @@ -0,0 +1,671 @@ +/* + * (C) Copyright 2000-2004 + * 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 + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + +#if CFG_MAX_FLASH_BANKS != 1 +#error "CFG_MAX_FLASH_BANKS must be 1" +#endif +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); + +#define ADDR0           0x5555 +#define ADDR1           0x2aaa +#define FLASH_WORD_SIZE unsigned char + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ +	unsigned long size_b0; +	unsigned long base_b0; + +	/* Init: no FLASHes known */ +	flash_info[0].flash_id = FLASH_UNKNOWN; + +	/* Static FLASH Bank configuration here - FIXME XXX */ + +	size_b0 = +		flash_get_size ((vu_long *) FLASH_BASE0_PRELIM, +				&flash_info[0]); + +	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); +	} + +	/* Only one bank */ +	/* Setup offsets */ +	flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); + +	/* Monitor protection ON by default */ +	(void) flash_protect (FLAG_PROTECT_SET, +			      FLASH_BASE0_PRELIM, +			      FLASH_BASE0_PRELIM + monitor_flash_len - 1, +			      &flash_info[0]); +	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_VENDMASK) == FLASH_MAN_SST) || +	    (info->flash_id == FLASH_AM040)) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00010000); +	} else { +		if (info->flash_id & FLASH_BTYPE) { +			/* set sector offsets for bottom boot block type        */ +			info->start[0] = base + 0x00000000; +			info->start[1] = base + 0x00004000; +			info->start[2] = base + 0x00006000; +			info->start[3] = base + 0x00008000; +			for (i = 4; i < info->sector_count; i++) { +				info->start[i] = +					base + (i * 0x00010000) - 0x00030000; +			} +		} else { +			/* set sector offsets for top boot block type           */ +			i = info->sector_count - 1; +			info->start[i--] = base + info->size - 0x00004000; +			info->start[i--] = base + info->size - 0x00006000; +			info->start[i--] = base + info->size - 0x00008000; +			for (; i >= 0; i--) { +				info->start[i] = base + i * 0x00010000; +			} +		} +	} +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ +	int i; +	int k; +	int size; +	int erased; +	volatile unsigned long *flash; + +	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; +	case FLASH_MAN_SST: +		printf ("SST "); +		break; +	default: +		printf ("Unknown Vendor "); +		break; +	} + +	switch (info->flash_id & FLASH_TYPEMASK) { +	case FLASH_AM040: +		printf ("AM29F040 (512 Kbit, uniform sector size)\n"); +		break; +	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; +	case FLASH_SST800A: +		printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n"); +		break; +	case FLASH_SST160A: +		printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n"); +		break; +	default: +		printf ("Unknown Chip Type\n"); +		break; +	} + +	printf ("  Size: %ld KB in %d Sectors\n", +		info->size >> 10, info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i = 0; i < info->sector_count; ++i) { +		/* +		 * Check if whole sector is erased +		 */ +		if (i != (info->sector_count - 1)) +			size = info->start[i + 1] - info->start[i]; +		else +			size = info->start[0] + info->size - info->start[i]; +		erased = 1; +		flash = (volatile unsigned long *) info->start[i]; +		size = size >> 2;	/* divide by 4 for longword access */ +		for (k = 0; k < size; k++) { +			if (*flash++ != 0xffffffff) { +				erased = 0; +				break; +			} +		} + +		if ((i % 5) == 0) +			printf ("\n   "); +#if 0				/* test-only */ +		printf (" %08lX%s", +			info->start[i], info->protect[i] ? " (RO)" : "     " +#else +		printf (" %08lX%s%s", +			info->start[i], +			erased ? " E" : "  ", info->protect[i] ? "RO " : "   " +#endif +			); +	} +	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; +	FLASH_WORD_SIZE value; +	ulong base = (ulong) addr; +	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr; + +	/* Write auto select command: read Manufacturer ID */ +	addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; +	addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; +	addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090; + +#ifdef CONFIG_ADCIOP +	value = addr2[2]; +#else +	value = addr2[0]; +#endif + +	switch (value) { +	case (FLASH_WORD_SIZE) AMD_MANUFACT: +		info->flash_id = FLASH_MAN_AMD; +		break; +	case (FLASH_WORD_SIZE) FUJ_MANUFACT: +		info->flash_id = FLASH_MAN_FUJ; +		break; +	case (FLASH_WORD_SIZE) SST_MANUFACT: +		info->flash_id = FLASH_MAN_SST; +		break; +	default: +		info->flash_id = FLASH_UNKNOWN; +		info->sector_count = 0; +		info->size = 0; +		return (0);	/* no or unknown flash  */ +	} + +#ifdef CONFIG_ADCIOP +	value = addr2[0];	/* device ID            */ +	/*        printf("\ndev_code=%x\n", value); */ +#else +	value = addr2[1];	/* device ID            */ +#endif + +	switch (value) { +	case (FLASH_WORD_SIZE) AMD_ID_F040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; +	case (FLASH_WORD_SIZE) AMD_ID_LV040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; +	case (FLASH_WORD_SIZE) AMD_ID_LV400T: +		info->flash_id += FLASH_AM400T; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;		/* => 0.5 MB            */ + +	case (FLASH_WORD_SIZE) AMD_ID_LV400B: +		info->flash_id += FLASH_AM400B; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;		/* => 0.5 MB            */ + +	case (FLASH_WORD_SIZE) AMD_ID_LV800T: +		info->flash_id += FLASH_AM800T; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;		/* => 1 MB              */ + +	case (FLASH_WORD_SIZE) AMD_ID_LV800B: +		info->flash_id += FLASH_AM800B; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;		/* => 1 MB              */ + +	case (FLASH_WORD_SIZE) AMD_ID_LV160T: +		info->flash_id += FLASH_AM160T; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;		/* => 2 MB              */ + +	case (FLASH_WORD_SIZE) AMD_ID_LV160B: +		info->flash_id += FLASH_AM160B; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;		/* => 2 MB              */ +#if 0				/* enable when device IDs are available */ +	case (FLASH_WORD_SIZE) AMD_ID_LV320T: +		info->flash_id += FLASH_AM320T; +		info->sector_count = 67; +		info->size = 0x00400000; +		break;		/* => 4 MB              */ + +	case (FLASH_WORD_SIZE) AMD_ID_LV320B: +		info->flash_id += FLASH_AM320B; +		info->sector_count = 67; +		info->size = 0x00400000; +		break;		/* => 4 MB              */ +#endif +	case (FLASH_WORD_SIZE) SST_ID_xF800A: +		info->flash_id += FLASH_SST800A; +		info->sector_count = 16; +		info->size = 0x00100000; +		break;		/* => 1 MB              */ + +	case (FLASH_WORD_SIZE) SST_ID_xF160A: +		info->flash_id += FLASH_SST160A; +		info->sector_count = 32; +		info->size = 0x00200000; +		break;		/* => 2 MB              */ + +	default: +		info->flash_id = FLASH_UNKNOWN; +		return (0);	/* => no or unknown flash */ + +	} + +	/* set up sector start address table */ +	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || +	    (info->flash_id == FLASH_AM040)) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00010000); +	} else { +		if (info->flash_id & FLASH_BTYPE) { +			/* set sector offsets for bottom boot block type        */ +			info->start[0] = base + 0x00000000; +			info->start[1] = base + 0x00004000; +			info->start[2] = base + 0x00006000; +			info->start[3] = base + 0x00008000; +			for (i = 4; i < info->sector_count; i++) { +				info->start[i] = +					base + (i * 0x00010000) - 0x00030000; +			} +		} else { +			/* set sector offsets for top boot block type           */ +			i = info->sector_count - 1; +			info->start[i--] = base + info->size - 0x00004000; +			info->start[i--] = base + info->size - 0x00006000; +			info->start[i--] = base + info->size - 0x00008000; +			for (; i >= 0; i--) { +				info->start[i] = base + i * 0x00010000; +			} +		} +	} + +	/* 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 */ +#ifdef CONFIG_ADCIOP +		addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]); +		info->protect[i] = addr2[4] & 1; +#else +		addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]); +		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) +			info->protect[i] = 0; +		else +			info->protect[i] = addr2[2] & 1; +#endif +	} + +	/* +	 * Prevent writes to uninitialized FLASH. +	 */ +	if (info->flash_id != FLASH_UNKNOWN) { +#if 0				/* test-only */ +#ifdef CONFIG_ADCIOP +		addr2 = (volatile unsigned char *) info->start[0]; +		addr2[ADDR0] = 0xAA; +		addr2[ADDR1] = 0x55; +		addr2[ADDR0] = 0xF0;	/* reset bank */ +#else +		addr2 = (FLASH_WORD_SIZE *) info->start[0]; +		*addr2 = (FLASH_WORD_SIZE) 0x00F000F0;	/* reset bank */ +#endif +#else  /* test-only */ +		addr2 = (FLASH_WORD_SIZE *) info->start[0]; +		*addr2 = (FLASH_WORD_SIZE) 0x00F000F0;	/* reset bank */ +#endif /* test-only */ +	} + +	return (info->size); +} + +int wait_for_DQ7 (flash_info_t * info, int sect) +{ +	ulong start, now, last; +	volatile FLASH_WORD_SIZE *addr = +		(FLASH_WORD_SIZE *) (info->start[sect]); + +	start = get_timer (0); +	last = start; +	while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) != +	       (FLASH_WORD_SIZE) 0x00800080) { +		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; +		} +	} +	return 0; +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ +	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]); +	volatile FLASH_WORD_SIZE *addr2; +	int flag, prot, sect, l_sect; +	int i; + +	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) { +		printf ("Can't erase unknown flash type - aborted\n"); +		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 (); + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect <= s_last; sect++) { +		if (info->protect[sect] == 0) {	/* not protected */ +			addr2 = (FLASH_WORD_SIZE *) (info->start[sect]); +			printf ("Erasing sector %p\n", addr2);	/* CLH */ + +			if ((info->flash_id & FLASH_VENDMASK) == +			    FLASH_MAN_SST) { +				addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; +				addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; +				addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080; +				addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; +				addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; +				addr2[0] = (FLASH_WORD_SIZE) 0x00500050;	/* block erase */ +				for (i = 0; i < 50; i++) +					udelay (1000);	/* wait 1 ms */ +			} else { +				addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; +				addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; +				addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080; +				addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; +				addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; +				addr2[0] = (FLASH_WORD_SIZE) 0x00300030;	/* sector erase */ +			} +			l_sect = sect; +			/* +			 * Wait for each sector to complete, it's more +			 * reliable.  According to AMD Spec, you must +			 * issue all erase commands within a specified +			 * timeout.  This has been seen to fail, especially +			 * if printf()s are included (for debug)!! +			 */ +			wait_for_DQ7 (info, sect); +		} +	} + +	/* re-enable interrupts if necessary */ +	if (flag) +		enable_interrupts (); + +	/* wait at least 80us - let's wait 1 ms */ +	udelay (1000); + +#if 0 +	/* +	 * We wait for the last triggered sector +	 */ +	if (l_sect < 0) +		goto DONE; +	wait_for_DQ7 (info, l_sect); + +      DONE: +#endif +	/* reset to read mode */ +	addr = (FLASH_WORD_SIZE *) info->start[0]; +	addr[0] = (FLASH_WORD_SIZE) 0x00F000F0;	/* 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; i < l; ++i, ++cp) { +			data = (data << 8) | (*(uchar *) cp); +		} +		for (; i < 4 && cnt > 0; ++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) +{ +	volatile FLASH_WORD_SIZE *addr2 = +		(FLASH_WORD_SIZE *) (info->start[0]); +	volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest; +	volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data; +	ulong start; +	int i; + +	/* Check if Flash is (sufficiently) erased */ +	if ((*((volatile FLASH_WORD_SIZE *) dest) & +	     (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) { +		return (2); +	} + +	for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) { +		int flag; + +		/* Disable interrupts which might cause a timeout here */ +		flag = disable_interrupts (); + +		addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; +		addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; +		addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0; + +		dest2[i] = data2[i]; + +		/* re-enable interrupts if necessary */ +		if (flag) +			enable_interrupts (); + +		/* data polling for D7 */ +		start = get_timer (0); +		while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) != +		       (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) { + +			if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { +				return (1); +			} +		} +	} + +	return (0); +} diff --git a/board/jse/host_bridge.c b/board/jse/host_bridge.c new file mode 100644 index 000000000..d68744518 --- /dev/null +++ b/board/jse/host_bridge.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004 Picture Elements, Inc. + *    Stephen Williams (steve@icarus.com) + * + *    This source code is free software; you can redistribute it + *    and/or modify it in source code form 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 + */ +#ident "$Id:$" + +# include  <common.h> +# include  <pci.h> +# include  "jse_priv.h" + +/* + * The JSE board has an Intel 21555 non-transparent bridge for + * communication with the host. We need to render it harmless on the + * JSE side, but leave it alone on the host (primary) side. Normally, + * this will all be done before the host BIOS can gain access to the + * board, due to the Primary Access Lockout bit. + * + * The host_bridge_init function is called as a late initialization + * function, after most of the board is set up, including a PCI scan. + */ + +void host_bridge_init (void) +{ +	/* The bridge chip is at a fixed location. */ +	pci_dev_t dev = PCI_BDF (0, 10, 0); + +	int rc; +	u32 val32; + +	rc = pci_read_config_dword (dev, 0, &val32); + +	/* Set subsystem ID -- +	   The primary side sees this value at 0x2c. We set it here so +	   that the host can tell what sort of device this is: +	   We are a Picture Elements [0x12c5] JSE [0x008a]. */ +	pci_write_config_dword (dev, 0x6c, 0x008a12c5); + +	/* Downstream (Primary-to-Secondary) BARs are set up mostly +	   off. We need only the Memory-0 Bar so that the host can get +	   at the CSR region to set up tables and the lot. */ + +	/* Downstream Memory 0 setup (4K for CSR) */ +	pci_write_config_dword (dev, 0xac, 0xfffff000); +	/* Downstream Memory 1 setup (off) */ +	pci_write_config_dword (dev, 0xb0, 0x00000000); +	/* Downstream Memory 2 setup (off) */ +	pci_write_config_dword (dev, 0xb4, 0x00000000); +	/* Downstream Memory 3 setup (off) */ +	pci_write_config_dword (dev, 0xb8, 0x00000000); + +	/* Upstream (Secondary-to-Primary) BARs are used to get at +	   host memory from the JSE card. Create two regions: a small +	   one to manage individual word reads/writes, and a larger +	   one for doing bulk frame moves. */ + +	/* Upstream Memory 0 Setup -- (BAR2) 4K non-prefetchable */ +	pci_write_config_dword (dev, 0xc4, 0xfffff000); +	/* Upstream Memory 1 setup -- (BAR3) 4K non-prefetchable */ +	pci_write_config_dword (dev, 0xc8, 0xfffff000); + +	/* Upstream Memory 2 (BAR4) uses page translation, and is set +	   up in CCR1. Configure for 4K pages. */ + +	/* Set CCR1,0 reigsters. This clears the Primary PCI Lockout +	   bit as well, so we are done configuring after this +	   point. Therefore, this must be the last step. + +	   CC1[15:12]= 0  (disable I2O message unit) +	   CC1[11:8] = 0x5 (4K page size) +	   CC0[11]   = 1  (Secondary Clock Disable: disable clock) +	   CC0[10]   = 0  (Primary Access Lockout: allow primary access) +	 */ +	pci_write_config_dword (dev, 0xcc, 0x05000800); +} diff --git a/board/jse/init.S b/board/jse/init.S new file mode 100644 index 000000000..231cd1caf --- /dev/null +++ b/board/jse/init.S @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------+ */ +/* */ +/*       This source code has been made available to you by IBM on an AS-IS */ +/*       basis.  Anyone receiving this source is licensed under IBM */ +/*       copyrights to use it in any way he or she deems fit, including */ +/*       copying it, modifying it, compiling it, and redistributing it either */ +/*       with or without modifications.  No license under IBM patents or */ +/*       patent applications is to be implied by the copyright license. */ +/* */ +/*       Any user of this software should understand that IBM cannot provide */ +/*       technical support for this software and will not be responsible for */ +/*       any consequences resulting from the use of this software. */ +/* */ +/*       Any person who transfers this source code or any derivative work */ +/*       must include the IBM copyright notice, this paragraph, and the */ +/*       preceding two paragraphs in the transferred software. */ +/* */ +/*       COPYRIGHT   I B M   CORPORATION 1995 */ +/*       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M */ +/*------------------------------------------------------------------------- */ + +/*------------------------------------------------------------------------- */ +/* Function:     ext_bus_cntlr_init */ +/* Description:  Initializes the External Bus Controller for the external */ +/*		peripherals. IMPORTANT: For pass1 this code must run from */ +/*		cache since you can not reliably change a peripheral banks */ +/*		timing register (pbxap) while running code from that bank. */ +/*		For ex., since we are running from ROM on bank 0, we can NOT */ +/*		execute the code that modifies bank 0 timings from ROM, so */ +/*		we run it from cache. */ +/*                                    */ +/*                                    */ +/* The layout for the PEI JSE board:  */ +/*	Bank 0 - Flash and SRAM       */ +/*	Bank 1 - SystemACE            */ +/*	Bank 2 - not used             */ +/*	Bank 3 - not used             */ +/*	Bank 4 - not used             */ +/*	Bank 5 - not used             */ +/*	Bank 6 - not used             */ +/*	Bank 7 - not used             */ +/*------------------------------------------------------------------------- */ +#include <ppc4xx.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#define cpc0_cr0 0xB1 + +	.globl	ext_bus_cntlr_init +ext_bus_cntlr_init: +	mflr    r4                      /* save link register */ +	bl      ..getAddr +..getAddr: +	mflr    r3                      /* get address of ..getAddr */ +	mtlr    r4                      /* restore link register */ +	addi    r4,0,14                 /* set ctr to 10; used to prefetch */ +	mtctr   r4                      /* 10 cache lines to fit this function */ +					/* in cache (gives us 8x10=80 instrctns) */ +..ebcloop: +	icbt    r0,r3                   /* prefetch cache line for addr in r3 */ +	addi    r3,r3,32		/* move to next cache line */ +	bdnz    ..ebcloop               /* continue for 10 cache lines */ + +	/*----------------------------------------------------------------- */ +	/* Delay to ensure all accesses to ROM are complete before changing */ +	/* bank 0 timings. 200usec should be enough. */ +	/*   200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */ +	/*----------------------------------------------------------------- */ +	addis	r3,0,0x0 +	ori     r3,r3,0xA000          /* ensure 200usec have passed since reset */ +	mtctr   r3 +..spinlp: +	bdnz    ..spinlp                /* spin loop */ + +	/*----------------------------------------------------------------- */ +	/* Memory Bank 0 (Flash) initialization */ +	/*----------------------------------------------------------------- */ + +	addi    r4,0,pb0ap +	mtdcr   ebccfga,r4 +	addis   r4,0,0x9B01 +	ori     r4,r4,0x5480 +	mtdcr   ebccfgd,r4 + +	addi    r4,0,pb0cr +	mtdcr   ebccfga,r4 +	addis   r4,0,0xFFF1           /* BAS=0xFFF,BS=0x0(1MB),BU=0x3(R/W), */ +	ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */ +	mtdcr   ebccfgd,r4 + +	blr + + +/*----------------------------------------------------------------------- */ +/* Function:     sdram_init                                               */ +/* Description:  This function is called by cpu/ppc4xx/start.S code       */ +/*               to get the SDRAM initialized.                            */ +/*----------------------------------------------------------------------- */ +	.globl  sdram_init +sdram_init: +	blr diff --git a/board/jse/jse.c b/board/jse/jse.c new file mode 100644 index 000000000..929081468 --- /dev/null +++ b/board/jse/jse.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2004 Picture Elements, Inc. + *    Stephen Williams (steve@icarus.com) + * + *    This source code is free software; you can redistribute it + *    and/or modify it in source code form 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  <ppc4xx.h> +# include  <asm/processor.h> +# include  <asm/io.h> +# include  "jse_priv.h" + +/* + * This function is run very early, out of flash, and before devices are + * initialized. It is called by lib_ppc/board.c:board_init_f by virtue + * of being in the init_sequence array. + * + * The SDRAM has been initialized already -- start.S:start called + * init.S:init_sdram early on -- but it is not yet being used for + * anything, not even stack. So be careful. + */ +int board_early_init_f (void) +{ +   /*-------------------------------------------------------------------------+ +   | Interrupt controller setup for the JSE board. +   | Note: IRQ 0-15  405GP internally generated; active high; level sensitive +   |       IRQ 16    405GP internally generated; active low; level sensitive +   |       IRQ 17-24 RESERVED/UNUSED +   |       IRQ 25 (EXT IRQ 0) PCI SLOT 0; active low; level sensitive +   |       IRQ 26 (EXT IRQ 1) PCI SLOT 1; active low; level sensitive +   |       IRQ 27 (EXT IRQ 2) JP2C CHIP ; active low; level sensitive +   |       IRQ 28 (EXT IRQ 3) PCI bridge; active low; level sensitive +   |       IRQ 29 (EXT IRQ 4) SystemACE IRQ; active high +   |       IRQ 30 (EXT IRQ 5) SystemACE BRdy (unused) +   |       IRQ 31 (EXT IRQ 6) (unused) +   +-------------------------------------------------------------------------*/ +	mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */ +	mtdcr (uicer, 0x00000000);	/* disable all ints */ +	mtdcr (uiccr, 0x00000000);	/* set all to be non-critical */ +	mtdcr (uicpr, 0xFFFFFF87);	/* set int polarities */ +	mtdcr (uictr, 0x10000000);	/* set int trigger levels */ +	mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */ + +	/* Configure the interface to the SystemACE MCU port. +	   The SystemACE is fast, but there is no reason to have +	   excessivly tight timings. So the settings are slightly +	   generous. */ + +	/* EBC0_B1AP: BME=1, TWT=2, CSN=0, OEN=1, +	   WBN=0, WBF=1, TH=0,  RE=0,  SOR=0, BEM=0, PEN=0 */ +	mtdcr (ebccfga, pb1ap); +	mtdcr (ebccfgd, 0x01011000); + +	/* EBC0_B1CR: BAS=x, BS=0(1MB), BU=3(R/W), BW=0(8bits) */ +	mtdcr (ebccfga, pb1cr); +	mtdcr (ebccfgd, CFG_SYSTEMACE_BASE | 0x00018000); + +	/* Enable the /PerWE output as /PerWE, instead of /PCIINT. */ +	/* CPC0_CR1 |= PCIPW */ +	mtdcr (0xb2, mfdcr (0xb2) | 0x00004000); + +	return 0; +} + +#ifdef CONFIG_BOARD_PRE_INIT +int board_pre_init (void) +{ +	return board_early_init_f (); +} + +#endif + +/* + * This function is also called by lib_ppc/board.c:board_init_f (it is + * also in the init_sequence array) but later. Many more things are + * configured, but we are still running from flash. + */ +int checkboard (void) +{ +	unsigned vers, status; + +	/* check that the SystemACE chip is alive. */ +	printf ("ACE:   "); +	vers = readw (CFG_SYSTEMACE_BASE + 0x16); +	printf ("SystemACE %u.%u (build %u)", +		(vers >> 12) & 0x0f, (vers >> 8) & 0x0f, vers & 0xff); + +	status = readl (CFG_SYSTEMACE_BASE + 0x04); +#ifdef DEBUG +	printf (" STATUS=0x%08x", status); +#endif +	/* If the flash card is present and there is an initial error, +	   then force a restart of the program. */ +	if (status & 0x00000010) { +		printf (" CFDETECT"); + +		if (status & 0x04) { +			/* CONTROLREG = CFGPROG */ +			writew (0x1000, CFG_SYSTEMACE_BASE + 0x18); +			udelay (500); +			/* CONTROLREG = CFGRESET */ +			writew (0x0080, CFG_SYSTEMACE_BASE + 0x18); +			udelay (500); +			writew (0x0000, CFG_SYSTEMACE_BASE + 0x18); +			/* CONTROLREG = CFGSTART */ +			writew (0x0020, CFG_SYSTEMACE_BASE + 0x18); + +			status = readl (CFG_SYSTEMACE_BASE + 0x04); +		} +	} + +	/* Wait for the SystemACE to program its chain of devices. */ +	while ((status & 0x84) == 0x00) { +		udelay (500); +		status = readl (CFG_SYSTEMACE_BASE + 0x04); +	} + +	if (status & 0x04) +		printf (" CFG-ERROR"); +	if (status & 0x80) +		printf (" CFGDONE"); + +	printf ("\n"); + +	/* Force /RTS to active. The board it not wired quite +	   correctly to use cts/rtc flow control, so just force the +	   /RST active and forget about it. */ +	writeb (readb (0xef600404) | 0x03, 0xef600404); + +	printf ("JSE:   ready\n"); + +	return 0; +} + +/* **** No more functions called by board_init_f. **** */ + +/* + * This function is called by lib_ppc/board.c:board_init_r. At this + * point, basic setup is done, U-Boot has been moved into SDRAM and + * PCI has been set up. From here we done late setup. + */ +int misc_init_r (void) +{ +	host_bridge_init (); +	return 0; +} diff --git a/board/jse/jse_priv.h b/board/jse/jse_priv.h new file mode 100644 index 000000000..ed4894b93 --- /dev/null +++ b/board/jse/jse_priv.h @@ -0,0 +1,25 @@ +#ifndef __jse_priv_H +#define __jse_prov_H +/* + * Copyright (c) 2004 Picture Elements, Inc. + *    Stephen Williams (steve@icarus.com) + * + *    This source code is free software; you can redistribute it + *    and/or modify it in source code form 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 + */ + +extern void host_bridge_init(void); + +#endif diff --git a/board/jse/sdram.c b/board/jse/sdram.c new file mode 100644 index 000000000..9060d979d --- /dev/null +++ b/board/jse/sdram.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2004 Picture Elements, Inc. + *    Stephen Williams (steve@icarus.com) + * + *    This source code is free software; you can redistribute it + *    and/or modify it in source code form 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 <ppc4xx.h> +#include <asm/processor.h> + +# define SDRAM_LEN 0x08000000 + +/* + * this is even after checkboard. It returns the size of the SDRAM + * that we have installed. This function is called by board_init_f + * in lib_ppc/board.c to initialize the memory and return what I + * found. + */ +long int initdram (int board_type) +{ +	/* Configure the SDRAMS */ + +	/* disable memory controller */ +	mtdcr (memcfga, mem_mcopt1); +	mtdcr (memcfgd, 0x00000000); + +	udelay (500); + +	/* Clear SDRAM0_BESR0 (Bus Error Syndrome Register) */ +	mtdcr (memcfga, mem_besra); +	mtdcr (memcfgd, 0xffffffff); + +	/* Clear SDRAM0_BESR1 (Bus Error Syndrome Register) */ +	mtdcr (memcfga, mem_besrb); +	mtdcr (memcfgd, 0xffffffff); + +	/* Clear SDRAM0_ECCCFG (disable ECC) */ +	mtdcr (memcfga, mem_ecccf); +	mtdcr (memcfgd, 0x00000000); + +	/* Clear SDRAM0_ECCESR (ECC Error Syndrome Register) */ +	mtdcr (memcfga, mem_eccerr); +	mtdcr (memcfgd, 0xffffffff); + +	/* Timing register: CASL=2, PTA=2, CTP=2, LDF=1, RFTA=5, RCD=2 */ +	mtdcr (memcfga, mem_sdtr1); +	mtdcr (memcfgd, 0x010a4016); + +	/* Memory Bank 0 Config == BA=0x00000000, SZ=64M, AM=3, BE=1 */ +	mtdcr (memcfga, mem_mb0cf); +	mtdcr (memcfgd, 0x00084001); + +	/* Memory Bank 1 Config == BA=0x04000000, SZ=64M, AM=3, BE=1 */ +	mtdcr (memcfga, mem_mb1cf); +	mtdcr (memcfgd, 0x04084001); + +	/* Memory Bank 2 Config ==  BE=0 */ +	mtdcr (memcfga, mem_mb2cf); +	mtdcr (memcfgd, 0x00000000); + +	/* Memory Bank 3 Config ==  BE=0 */ +	mtdcr (memcfga, mem_mb3cf); +	mtdcr (memcfgd, 0x00000000); + +	/* refresh timer = 0x400  */ +	mtdcr (memcfga, mem_rtr); +	mtdcr (memcfgd, 0x04000000); + +	/* Power management idle timer set to the default. */ +	mtdcr (memcfga, mem_pmit); +	mtdcr (memcfgd, 0x07c00000); + +	udelay (500); + +	/* Enable banks (DCE=1, BPRF=1, ECCDD=1, EMDUL=1) */ +	mtdcr (memcfga, mem_mcopt1); +	mtdcr (memcfgd, 0x80e00000); + +	return SDRAM_LEN; +} + +/* + * The U-Boot core, as part of the initialization to prepare for + * loading the monitor into SDRAM, requests of this function that the + * memory be tested. Return 0 if the memory tests OK. + */ +int testdram (void) +{ +	unsigned long idx; +	unsigned val; +	unsigned errors; +	volatile unsigned long *sdram; + +#ifdef DEBUG +	printf ("SDRAM Controller Registers --\n"); + +	mtdcr (memcfga, mem_mcopt1); +	val = mfdcr (memcfgd); +	printf ("    SDRAM0_CFG   : 0x%08x\n", val); + +	mtdcr (memcfga, 0x24); +	val = mfdcr (memcfgd); +	printf ("    SDRAM0_STATUS: 0x%08x\n", val); + +	mtdcr (memcfga, mem_mb0cf); +	val = mfdcr (memcfgd); +	printf ("    SDRAM0_B0CR  : 0x%08x\n", val); + +	mtdcr (memcfga, mem_mb1cf); +	val = mfdcr (memcfgd); +	printf ("    SDRAM0_B1CR  : 0x%08x\n", val); + +	mtdcr (memcfga, mem_sdtr1); +	val = mfdcr (memcfgd); +	printf ("    SDRAM0_TR    : 0x%08x\n", val); + +	mtdcr (memcfga, mem_rtr); +	val = mfdcr (memcfgd); +	printf ("    SDRAM0_RTR   : 0x%08x\n", val); +#endif + +	/* Wait for memory to be ready by testing MRSCMPbit +	   bit. Really, there should already have been plenty of time, +	   given it was started long ago. But, best to check. */ +	for (idx = 0; idx < 1000000; idx += 1) { +		mtdcr (memcfga, 0x24); +		val = mfdcr (memcfgd); +		if (val & 0x80000000) +			break; +	} + +	if (!(val & 0x80000000)) { +		printf ("SDRAM ERROR: SDRAM0_STATUS never set!\n"); +		return 1; +	} + +	/* Start memory test. */ +	printf ("test: %u MB - ", SDRAM_LEN / 1048576); + +	sdram = (unsigned long *) CFG_SDRAM_BASE; + +	printf ("write - "); +	for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) { +		sdram[idx + 0] = idx; +		sdram[idx + 1] = ~idx; +	} + +	printf ("read - "); +	errors = 0; +	for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) { +		if (sdram[idx + 0] != idx) +			errors += 1; +		if (sdram[idx + 1] != ~idx) +			errors += 1; +		if (errors > 0) +			break; +	} + +	if (errors > 0) { +		printf ("NOT OK\n"); +		printf ("FIRST ERROR at %p: 0x%08lx:0x%08lx != 0x%08lx:0x%08lx\n", +			sdram + idx, sdram[idx + 0], sdram[idx + 1], idx, ~idx); +		return 1; +	} + +	printf ("ok\n"); +	return 0; +} diff --git a/board/jse/u-boot.lds b/board/jse/u-boot.lds new file mode 100644 index 000000000..3e54af7d0 --- /dev/null +++ b/board/jse/u-boot.lds @@ -0,0 +1,140 @@ +/* + * (C) Copyright 2000-2004 + * 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 +{ +  .resetvec 0xFFFFFFFC : +  { +    *(.resetvec) +  } = 0xffff + +  /* 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          : { +    /* The start.o file includes the initial jump vector that +       must be located in the beginning. It is the basic run- +       time function that calls all other functions. */ +    cpu/ppc4xx/start.o	(.text) + +    board/jse/init.o	(.text) +    cpu/ppc4xx/kgdb.o	(.text) + +/*    . = env_offset;*/ +/*    common/environment.o(.text)*/ + +    *(.text) +    *(.fixup) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +    *(.rodata.str1.4) +  } +  .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 = .); + +  __u_boot_cmd_start = .; +  .u_boot_cmd : { *(.u_boot_cmd) } +  __u_boot_cmd_end = .; + + +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(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 = .); +} |