Patches by David Snowdon, 07 Sep 2004:
- add u-boot.hex target in the top level Makefile
- add support for the UNSW/NICTA PLEB 2 board (pleb2)
- use -mtune=xscale and -march=armv5 options for PXA
diff --git a/board/pleb2/Makefile b/board/pleb2/Makefile
new file mode 100644
index 0000000..5fdc874
--- /dev/null
+++ b/board/pleb2/Makefile
@@ -0,0 +1,48 @@
+
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	:= pleb2.o flash.o
+SOBJS	:= memsetup.o
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
diff --git a/board/pleb2/config.mk b/board/pleb2/config.mk
new file mode 100644
index 0000000..6958a63
--- /dev/null
+++ b/board/pleb2/config.mk
@@ -0,0 +1,3 @@
+TEXT_BASE =  0xa1F80000
+#TEXT_BASE = 0xa3080000
+#TEXT_BASE = 0
diff --git a/board/pleb2/flash.c b/board/pleb2/flash.c
new file mode 100644
index 0000000..97271d9
--- /dev/null
+++ b/board/pleb2/flash.c
@@ -0,0 +1,814 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+/* environment.h defines the various CFG_ENV_... values in terms
+ * of whichever ones are given in the configuration file.
+ */
+#include <environment.h>
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips        */
+
+/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
+ *        has nothing to do with the flash chip being 8-bit or 16-bit.
+ */
+#ifdef CONFIG_FLASH_16BIT
+typedef unsigned short FLASH_PORT_WIDTH;
+typedef volatile unsigned short FLASH_PORT_WIDTHV;
+
+#define	FLASH_ID_MASK	0xFFFF
+#else
+typedef unsigned long FLASH_PORT_WIDTH;
+typedef volatile unsigned long FLASH_PORT_WIDTHV;
+
+#define	FLASH_ID_MASK	0xFFFFFFFF
+#endif
+
+#define FPW	FLASH_PORT_WIDTH
+#define FPWV	FLASH_PORT_WIDTHV
+
+#define ORMASK(size) ((-size) & OR_AM_MSK)
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (FPWV * addr, flash_info_t * info);
+static void flash_reset (flash_info_t * info);
+static int write_word_intel (flash_info_t * info, FPWV * dest, FPW data);
+static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
+static void flash_get_offsets (ulong base, flash_info_t * info);
+
+#ifdef CFG_FLASH_PROTECTION
+static void flash_sync_real_protect (flash_info_t * info);
+#endif
+
+/*-----------------------------------------------------------------------
+ * flash_init()
+ *
+ * sets up flash_info and returns size of FLASH (bytes)
+ */
+unsigned long flash_init (void)
+{
+	unsigned long size_b;
+	int i;
+
+	/* Init: no FLASHes known */
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+	}
+
+	size_b = flash_get_size ((FPW *) CFG_FLASH_BASE, &flash_info[0]);
+
+	flash_info[0].size = size_b;
+
+	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx\n",
+			size_b);
+	}
+
+	/* Do this again (was done already in flast_get_size), just
+	 * in case we move it when remap the FLASH.
+	 */
+	flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+
+#ifdef CFG_FLASH_PROTECTION
+	/* read the hardware protection status (if any) into the
+	 * protection array in flash_info.
+	 */
+	flash_sync_real_protect (&flash_info[0]);
+#endif
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+	/* monitor protection ON by default */
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_MONITOR_BASE,
+		       CFG_MONITOR_BASE + monitor_flash_len - 1,
+		       &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_ADDR
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_ENV_ADDR,
+		       CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_ADDR_REDUND
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_ENV_ADDR_REDUND,
+		       CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
+		       &flash_info[0]);
+#endif
+
+	return (size_b);
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_reset (flash_info_t * info)
+{
+	FPWV *base = (FPWV *) (info->start[0]);
+
+	/* Put FLASH back in read mode */
+	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
+		*base = (FPW) 0x00FF00FF;	/* Intel Read Mode */
+	else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
+		*base = (FPW) 0x00F000F0;	/* AMD Read Mode */
+}
+
+/*-----------------------------------------------------------------------
+ */
+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_INTEL
+	    && (info->flash_id & FLASH_BTYPE)) {
+		int bootsect_size;	/* number of bytes/boot sector  */
+		int sect_size;	/* number of bytes/regular sector */
+
+		bootsect_size = 0x00002000 * (sizeof (FPW) / 2);
+		sect_size = 0x00010000 * (sizeof (FPW) / 2);
+
+		/* set sector offsets for bottom boot block type        */
+		for (i = 0; i < 8; ++i) {
+			info->start[i] = base + (i * bootsect_size);
+		}
+		for (i = 8; i < info->sector_count; i++) {
+			info->start[i] = base + ((i - 7) * sect_size);
+		}
+	} else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
+		   && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
+
+		int sect_size;	/* number of bytes/sector */
+
+		sect_size = 0x00010000 * (sizeof (FPW) / 2);
+
+		/* set up sector start address table (uniform sector type) */
+		for (i = 0; i < info->sector_count; i++)
+			info->start[i] = base + (i * sect_size);
+	} else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
+		   && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM800T) {
+
+		int sect_size;	/* number of bytes/sector */
+
+		sect_size = 0x00010000 * (sizeof (FPW) / 2);
+
+		/* set up sector start address table (top boot sector type) */
+		for (i = 0; i < info->sector_count - 3; i++)
+			info->start[i] = base + (i * sect_size);
+		i = info->sector_count - 1;
+		info->start[i--] =
+			base + (info->size - 0x00004000) * (sizeof (FPW) / 2);
+		info->start[i--] =
+			base + (info->size - 0x00006000) * (sizeof (FPW) / 2);
+		info->start[i--] =
+			base + (info->size - 0x00008000) * (sizeof (FPW) / 2);
+	}
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_print_info (flash_info_t * info)
+{
+	int i;
+	uchar *boottype;
+	uchar *bootletter;
+	uchar *fmt;
+	uchar botbootletter[] = "B";
+	uchar topbootletter[] = "T";
+	uchar botboottype[] = "bottom boot sector";
+	uchar topboottype[] = "top boot sector";
+
+	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_BM:
+		printf ("BRIGHT MICRO ");
+		break;
+	case FLASH_MAN_FUJ:
+		printf ("FUJITSU ");
+		break;
+	case FLASH_MAN_SST:
+		printf ("SST ");
+		break;
+	case FLASH_MAN_STM:
+		printf ("STM ");
+		break;
+	case FLASH_MAN_INTEL:
+		printf ("INTEL ");
+		break;
+	default:
+		printf ("Unknown Vendor ");
+		break;
+	}
+
+	/* check for top or bottom boot, if it applies */
+	if (info->flash_id & FLASH_BTYPE) {
+		boottype = botboottype;
+		bootletter = botbootletter;
+	} else {
+		boottype = topboottype;
+		bootletter = topbootletter;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_AM800T:
+		fmt = "29LV800B%s (8 Mbit, %s)\n";
+		break;
+	case FLASH_AM640U:
+		fmt = "29LV641D (64 Mbit, uniform sectors)\n";
+		break;
+	case FLASH_28F800C3B:
+	case FLASH_28F800C3T:
+		fmt = "28F800C3%s (8 Mbit, %s)\n";
+		break;
+	case FLASH_INTEL800B:
+	case FLASH_INTEL800T:
+		fmt = "28F800B3%s (8 Mbit, %s)\n";
+		break;
+	case FLASH_28F160C3B:
+	case FLASH_28F160C3T:
+		fmt = "28F160C3%s (16 Mbit, %s)\n";
+		break;
+	case FLASH_INTEL160B:
+	case FLASH_INTEL160T:
+		fmt = "28F160B3%s (16 Mbit, %s)\n";
+		break;
+	case FLASH_28F320C3B:
+	case FLASH_28F320C3T:
+		fmt = "28F320C3%s (32 Mbit, %s)\n";
+		break;
+	case FLASH_INTEL320B:
+	case FLASH_INTEL320T:
+		fmt = "28F320B3%s (32 Mbit, %s)\n";
+		break;
+	case FLASH_28F640C3B:
+	case FLASH_28F640C3T:
+		fmt = "28F640C3%s (64 Mbit, %s)\n";
+		break;
+	case FLASH_INTEL640B:
+	case FLASH_INTEL640T:
+		fmt = "28F640B3%s (64 Mbit, %s)\n";
+		break;
+	default:
+		fmt = "Unknown Chip Type\n";
+		break;
+	}
+
+	printf (fmt, bootletter, boottype);
+
+	printf ("  Size: %ld MB in %d Sectors\n",
+		info->size >> 20, info->sector_count);
+
+	printf ("  Sector Start Addresses:");
+
+	for (i = 0; i < info->sector_count; ++i) {
+		if ((i % 5) == 0) {
+			printf ("\n   ");
+		}
+
+		printf (" %08lX%s", info->start[i],
+			info->protect[i] ? " (RO)" : "     ");
+	}
+
+	printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+ulong flash_get_size (FPWV * addr, flash_info_t * info)
+{
+	/* Write auto select command: read Manufacturer ID */
+
+	/* Write auto select command sequence and test FLASH answer */
+	addr[0x0555] = (FPW) 0x00AA00AA;	/* for AMD, Intel ignores this */
+	addr[0x02AA] = (FPW) 0x00550055;	/* for AMD, Intel ignores this */
+	addr[0x0555] = (FPW) 0x00900090;	/* selects Intel or AMD */
+
+	/* The manufacturer codes are only 1 byte, so just use 1 byte.
+	 * This works for any bus width and any FLASH device width.
+	 */
+	switch (addr[0] & 0xff) {
+
+	case (uchar) AMD_MANUFACT:
+		info->flash_id = FLASH_MAN_AMD;
+		break;
+
+	case (uchar) INTEL_MANUFACT:
+		info->flash_id = FLASH_MAN_INTEL;
+		break;
+
+	default:
+		info->flash_id = FLASH_UNKNOWN;
+		info->sector_count = 0;
+		info->size = 0;
+		break;
+	}
+
+	/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
+	if (info->flash_id != FLASH_UNKNOWN)
+		switch (addr[1]) {
+
+		case (FPW) AMD_ID_LV800T:
+			info->flash_id += FLASH_AM800T;
+			info->sector_count = 19;
+			info->size = 0x00100000 * (sizeof (FPW) / 2);
+			break;	/* => 1 or 2 MiB        */
+
+		case (FPW) AMD_ID_LV640U:	/* 29LV640 and 29LV641 have same ID */
+			info->flash_id += FLASH_AM640U;
+			info->sector_count = 128;
+			info->size = 0x00800000 * (sizeof (FPW) / 2);
+			break;	/* => 8 or 16 MB        */
+
+		case (FPW) INTEL_ID_28F800C3B:
+			info->flash_id += FLASH_28F800C3B;
+			info->sector_count = 23;
+			info->size = 0x00100000 * (sizeof (FPW) / 2);
+			break;	/* => 1 or 2 MB         */
+
+		case (FPW) INTEL_ID_28F800B3B:
+			info->flash_id += FLASH_INTEL800B;
+			info->sector_count = 23;
+			info->size = 0x00100000 * (sizeof (FPW) / 2);
+			break;	/* => 1 or 2 MB         */
+
+		case (FPW) INTEL_ID_28F160C3B:
+			info->flash_id += FLASH_28F160C3B;
+			info->sector_count = 39;
+			info->size = 0x00200000 * (sizeof (FPW) / 2);
+			break;	/* => 2 or 4 MB         */
+
+		case (FPW) INTEL_ID_28F160B3B:
+			info->flash_id += FLASH_INTEL160B;
+			info->sector_count = 39;
+			info->size = 0x00200000 * (sizeof (FPW) / 2);
+			break;	/* => 2 or 4 MB         */
+
+		case (FPW) INTEL_ID_28F320C3B:
+			info->flash_id += FLASH_28F320C3B;
+			info->sector_count = 71;
+			info->size = 0x00400000 * (sizeof (FPW) / 2);
+			break;	/* => 4 or 8 MB         */
+
+		case (FPW) INTEL_ID_28F320B3B:
+			info->flash_id += FLASH_INTEL320B;
+			info->sector_count = 71;
+			info->size = 0x00400000 * (sizeof (FPW) / 2);
+			break;	/* => 4 or 8 MB         */
+
+		case (FPW) INTEL_ID_28F640C3B:
+			info->flash_id += FLASH_28F640C3B;
+			info->sector_count = 135;
+			info->size = 0x00800000 * (sizeof (FPW) / 2);
+			break;	/* => 8 or 16 MB        */
+
+		case (FPW) INTEL_ID_28F640B3B:
+			info->flash_id += FLASH_INTEL640B;
+			info->sector_count = 135;
+			info->size = 0x00800000 * (sizeof (FPW) / 2);
+			break;	/* => 8 or 16 MB        */
+
+		default:
+			info->flash_id = FLASH_UNKNOWN;
+			info->sector_count = 0;
+			info->size = 0;
+			return (0);	/* => no or unknown flash */
+		}
+
+	flash_get_offsets ((ulong) addr, info);
+
+	/* Put FLASH back in read mode */
+	flash_reset (info);
+
+	return (info->size);
+}
+
+#ifdef CFG_FLASH_PROTECTION
+/*-----------------------------------------------------------------------
+ */
+
+static void flash_sync_real_protect (flash_info_t * info)
+{
+	FPWV *addr = (FPWV *) (info->start[0]);
+	FPWV *sect;
+	int i;
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_28F800C3B:
+	case FLASH_28F800C3T:
+	case FLASH_28F160C3B:
+	case FLASH_28F160C3T:
+	case FLASH_28F320C3B:
+	case FLASH_28F320C3T:
+	case FLASH_28F640C3B:
+	case FLASH_28F640C3T:
+		/* check for protected sectors */
+		*addr = (FPW) 0x00900090;
+		for (i = 0; i < info->sector_count; i++) {
+			/* read sector protection at sector address, (A7 .. A0) = 0x02.
+			 * D0 = 1 for each device if protected.
+			 * If at least one device is protected the sector is marked
+			 * protected, but mixed protected and  unprotected devices
+			 * within a sector should never happen.
+			 */
+			sect = (FPWV *) (info->start[i]);
+			info->protect[i] =
+				(sect[2] & (FPW) (0x00010001)) ? 1 : 0;
+		}
+
+		/* Put FLASH back in read mode */
+		flash_reset (info);
+		break;
+
+	case FLASH_AM640U:
+	case FLASH_AM800T:
+	default:
+		/* no hardware protect that we support */
+		break;
+	}
+}
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+	FPWV *addr;
+	int flag, prot, sect;
+	int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
+	ulong now, last;
+	int rcode = 0;
+
+	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;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_INTEL800B:
+	case FLASH_INTEL160B:
+	case FLASH_INTEL320B:
+	case FLASH_INTEL640B:
+	case FLASH_28F800C3B:
+	case FLASH_28F160C3B:
+	case FLASH_28F320C3B:
+	case FLASH_28F640C3B:
+	case FLASH_AM640U:
+	case FLASH_AM800T:
+		break;
+	case FLASH_UNKNOWN:
+	default:
+		printf ("Can't erase unknown flash type %08lx - aborted\n",
+			info->flash_id);
+		return 1;
+	}
+
+	prot = 0;
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+
+	if (prot) {
+		printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+	} else {
+		printf ("\n");
+	}
+
+	reset_timer_masked ();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last && rcode == 0; sect++) {
+
+		if (info->protect[sect] != 0)	/* protected, skip it */
+			continue;
+
+		/* Disable interrupts which might cause a timeout here */
+		flag = disable_interrupts ();
+
+		reset_timer_masked ();
+		last = 0;
+
+		addr = (FPWV *) (info->start[sect]);
+		if (intel) {
+			*addr = (FPW) 0x00500050;	/* clear status register */
+			*addr = (FPW) 0x00200020;	/* erase setup */
+			*addr = (FPW) 0x00D000D0;	/* erase confirm */
+		} else {
+			/* must be AMD style if not Intel */
+			FPWV *base;	/* first address in bank */
+
+			base = (FPWV *) (info->start[0]);
+			base[0x0555] = (FPW) 0x00AA00AA;	/* unlock */
+			base[0x02AA] = (FPW) 0x00550055;	/* unlock */
+			base[0x0555] = (FPW) 0x00800080;	/* erase mode */
+			base[0x0555] = (FPW) 0x00AA00AA;	/* unlock */
+			base[0x02AA] = (FPW) 0x00550055;	/* unlock */
+			*addr = (FPW) 0x00300030;	/* erase sector */
+		}
+
+		/* re-enable interrupts if necessary */
+		if (flag)
+			enable_interrupts ();
+
+		/* wait at least 50us for AMD, 80us for Intel.
+		 * Let's wait 1 ms.
+		 */
+		udelay (1000);
+
+		while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
+			if ((now =
+			     get_timer_masked ()) > CFG_FLASH_ERASE_TOUT) {
+				printf ("Timeout\n");
+
+				if (intel) {
+					/* suspend erase        */
+					*addr = (FPW) 0x00B000B0;
+				}
+
+				flash_reset (info);	/* reset to read mode */
+				rcode = 1;	/* failed */
+				break;
+			}
+
+			/* show that we're waiting */
+			if ((now - last) > 1 * CFG_HZ) {	/* every second */
+				putc ('.');
+				last = now;
+			}
+		}
+
+		flash_reset (info);	/* reset to read mode   */
+	}
+
+	printf (" done\n");
+	return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * 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)
+{
+	FPW data = 0;		/* 16 or 32 bit word, matches flash bus width on MPC8XX */
+	int bytes;		/* number of bytes to program in current word         */
+	int left;		/* number of bytes left to program                    */
+	int i, res;
+
+	for (left = cnt, res = 0;
+	     left > 0 && res == 0;
+	     addr += sizeof (data), left -= sizeof (data) - bytes) {
+
+		bytes = addr & (sizeof (data) - 1);
+		addr &= ~(sizeof (data) - 1);
+
+		/* combine source and destination data so can program
+		 * an entire word of 16 or 32 bits
+		 */
+#ifdef CFG_LITTLE_ENDIAN
+		for (i = 0; i < sizeof (data); i++) {
+			data >>= 8;
+			if (i < bytes || i - bytes >= left)
+				data += (*((uchar *) addr + i)) << 24;
+			else
+				data += (*src++) << 24;
+		}
+#else
+		for (i = 0; i < sizeof (data); i++) {
+			data <<= 8;
+			if (i < bytes || i - bytes >= left)
+				data += *((uchar *) addr + i);
+			else
+				data += *src++;
+		}
+#endif
+
+		/* write one word to the flash */
+		switch (info->flash_id & FLASH_VENDMASK) {
+		case FLASH_MAN_AMD:
+			res = write_word_amd (info, (FPWV *) addr, data);
+			break;
+		case FLASH_MAN_INTEL:
+			res = write_word_intel (info, (FPWV *) addr, data);
+			break;
+		default:
+			/* unknown flash type, error! */
+			printf ("missing or unknown FLASH type\n");
+			res = 1;	/* not really a timeout, but gives error */
+			break;
+		}
+	}
+
+	return (res);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash for AMD FLASH
+ * A word is 16 or 32 bits, whichever the bus width of the flash bank
+ * (not an individual chip) is.
+ *
+ * returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
+{
+	int flag;
+	int res = 0;		/* result, assume success       */
+	FPWV *base;		/* first address in flash bank  */
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*dest & data) != data) {
+		return (2);
+	}
+
+
+	base = (FPWV *) (info->start[0]);
+
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts ();
+
+	base[0x0555] = (FPW) 0x00AA00AA;	/* unlock */
+	base[0x02AA] = (FPW) 0x00550055;	/* unlock */
+	base[0x0555] = (FPW) 0x00A000A0;	/* selects program mode */
+
+	*dest = data;		/* start programming the data   */
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts ();
+
+	reset_timer_masked ();
+
+	/* data polling for D7 */
+	while (res == 0
+	       && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
+		if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+			*dest = (FPW) 0x00F000F0;	/* reset bank */
+			res = 1;
+		}
+	}
+
+	return (res);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash for Intel FLASH
+ * A word is 16 or 32 bits, whichever the bus width of the flash bank
+ * (not an individual chip) is.
+ *
+ * returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word_intel (flash_info_t * info, FPWV * dest, FPW data)
+{
+	int flag;
+	int res = 0;		/* result, assume success       */
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*dest & data) != data) {
+		return (2);
+	}
+
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts ();
+
+	*dest = (FPW) 0x00500050;	/* clear status register        */
+	*dest = (FPW) 0x00FF00FF;	/* make sure in read mode       */
+	*dest = (FPW) 0x00400040;	/* program setup                */
+
+	*dest = data;		/* start programming the data   */
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts ();
+
+	reset_timer_masked ();
+
+	while (res == 0 && (*dest & (FPW) 0x00800080) != (FPW) 0x00800080) {
+		if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+			*dest = (FPW) 0x00B000B0;	/* Suspend program      */
+			res = 1;
+		}
+	}
+
+	if (res == 0 && (*dest & (FPW) 0x00100010))
+		res = 1;	/* write failed, time out error is close enough */
+
+	*dest = (FPW) 0x00500050;	/* clear status register        */
+	*dest = (FPW) 0x00FF00FF;	/* make sure in read mode       */
+
+	return (res);
+}
+
+#ifdef CFG_FLASH_PROTECTION
+/*-----------------------------------------------------------------------
+ */
+int flash_real_protect (flash_info_t * info, long sector, int prot)
+{
+	int rcode = 0;		/* assume success */
+	FPWV *addr;		/* address of sector */
+	FPW value;
+
+	addr = (FPWV *) (info->start[sector]);
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_28F800C3B:
+	case FLASH_28F800C3T:
+	case FLASH_28F160C3B:
+	case FLASH_28F160C3T:
+	case FLASH_28F320C3B:
+	case FLASH_28F320C3T:
+	case FLASH_28F640C3B:
+	case FLASH_28F640C3T:
+		flash_reset (info);	/* make sure in read mode */
+		*addr = (FPW) 0x00600060L;	/* lock command setup */
+		if (prot)
+			*addr = (FPW) 0x00010001L;	/* lock sector */
+		else
+			*addr = (FPW) 0x00D000D0L;	/* unlock sector */
+		flash_reset (info);	/* reset to read mode */
+
+		/* now see if it really is locked/unlocked as requested */
+		*addr = (FPW) 0x00900090;
+		/* read sector protection at sector address, (A7 .. A0) = 0x02.
+		 * D0 = 1 for each device if protected.
+		 * If at least one device is protected the sector is marked
+		 * protected, but return failure. Mixed protected and
+		 * unprotected devices within a sector should never happen.
+		 */
+		value = addr[2] & (FPW) 0x00010001;
+		if (value == 0)
+			info->protect[sector] = 0;
+		else if (value == (FPW) 0x00010001)
+			info->protect[sector] = 1;
+		else {
+			/* error, mixed protected and unprotected */
+			rcode = 1;
+			info->protect[sector] = 1;
+		}
+		if (info->protect[sector] != prot)
+			rcode = 1;	/* failed to protect/unprotect as requested */
+
+		/* reload all protection bits from hardware for now */
+		flash_sync_real_protect (info);
+		break;
+
+	case FLASH_AM640U:
+	case FLASH_AM800T:
+	default:
+		/* no hardware protect that we support */
+		info->protect[sector] = prot;
+		break;
+	}
+
+	return rcode;
+}
+#endif
diff --git a/board/pleb2/memsetup.S b/board/pleb2/memsetup.S
new file mode 100644
index 0000000..f2e1ce9
--- /dev/null
+++ b/board/pleb2/memsetup.S
@@ -0,0 +1,488 @@
+/*
+ * Most of this taken from Redboot hal_platform_setup.h with cleanup
+ *
+ * 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 <config.h>
+#include <version.h>
+#include <asm/arch/pxa-regs.h>
+
+DRAM_SIZE:  .long   CFG_DRAM_SIZE
+
+/* wait for coprocessor write complete */
+	.macro CPWAIT reg
+	mrc	p15,0,\reg,c2,c0,0
+	mov	\reg,\reg
+	sub	pc,pc,#4
+	.endm
+
+.globl memsetup
+memsetup:
+
+	mov	r10, lr
+
+	/* Set up GPIO pins first */
+
+	ldr	r0,   =GPSR0
+	ldr	r1,   =CFG_GPSR0_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPSR1
+	ldr	r1,   =CFG_GPSR1_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPSR2
+	ldr	r1,   =CFG_GPSR2_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPCR0
+	ldr	r1,   =CFG_GPCR0_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPCR1
+	ldr	r1,   =CFG_GPCR1_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPCR2
+	ldr	r1,   =CFG_GPCR2_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GRER0
+	ldr	r1,   =CFG_GRER0_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GRER1
+	ldr	r1,   =CFG_GRER1_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GRER2
+	ldr	r1,   =CFG_GRER2_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GFER0
+	ldr	r1,   =CFG_GFER0_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GFER1
+	ldr	r1,   =CFG_GFER1_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GFER2
+	ldr	r1,   =CFG_GFER2_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPDR0
+	ldr	r1,   =CFG_GPDR0_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPDR1
+	ldr	r1,   =CFG_GPDR1_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GPDR2
+	ldr	r1,   =CFG_GPDR2_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GAFR0_L
+	ldr	r1,   =CFG_GAFR0_L_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GAFR0_U
+	ldr	r1,   =CFG_GAFR0_U_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GAFR1_L
+	ldr	r1,   =CFG_GAFR1_L_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GAFR1_U
+	ldr	r1,   =CFG_GAFR1_U_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GAFR2_L
+	ldr	r1,   =CFG_GAFR2_L_VAL
+	str	r1,   [r0]
+
+	ldr	r0,   =GAFR2_U
+	ldr	r1,   =CFG_GAFR2_U_VAL
+	str	r1,   [r0]
+
+	/* enable GPIO pins */
+	ldr	r0,   =PSSR
+	ldr	r1,   =CFG_PSSR_VAL
+	str	r1,   [r0]
+
+
+/*********************************************************************
+    Initlialize Memory Controller
+
+    See PXA250 Operating System Developer's Guide
+
+    pause for 200 uSecs- allow internal clocks to settle
+    *Note: only need this if hard reset... doing it anyway for now
+*/
+
+	@ Step 1
+	@ ---- Wait 200 usec
+	ldr	r3, =OSCR	@ reset the OS Timer Count to zero
+	mov	r2, #0
+	str	r2, [r3]
+	ldr	r4, =0x300	@ really 0x2E1 is about 200usec, so 0x300 should be plenty
+1:
+	ldr	r2, [r3]
+	cmp	r4, r2
+	bgt	1b
+
+mem_init:
+	@ get memory controller base address
+	ldr	r1,  =MEMC_BASE
+
+@****************************************************************************
+@  Step 2
+@
+
+	@ Step 2a
+	@ write msc0, read back to ensure data latches
+	@
+	ldr	r2,   =CFG_MSC0_VAL
+	str	r2,   [r1, #MSC0_OFFSET]
+	ldr	r2,   [r1, #MSC0_OFFSET]
+
+	@ write msc1
+	ldr	r2,  =CFG_MSC1_VAL
+	str	r2,  [r1, #MSC1_OFFSET]
+	ldr	r2,  [r1, #MSC1_OFFSET]
+
+	@ write msc2
+	ldr	r2,  =CFG_MSC2_VAL
+	str	r2,  [r1, #MSC2_OFFSET]
+	ldr	r2,  [r1, #MSC2_OFFSET]
+
+
+@ Step 2b
+	@ write mecr
+	ldr	r2,  =CFG_MECR_VAL
+	str	r2,  [r1, #MECR_OFFSET]
+
+	@ write mcmem0
+	ldr	r2,  =CFG_MCMEM0_VAL
+	str	r2,  [r1, #MCMEM0_OFFSET]
+
+	@ write mcmem1
+	ldr	r2,  =CFG_MCMEM1_VAL
+	str	r2,  [r1, #MCMEM1_OFFSET]
+
+	@ write mcatt0
+	ldr	r2,  =CFG_MCATT0_VAL
+	str	r2,  [r1, #MCATT0_OFFSET]
+
+	@ write mcatt1
+	ldr	r2,  =CFG_MCATT1_VAL
+	str	r2,  [r1, #MCATT1_OFFSET]
+
+	@ write mcio0
+	ldr	r2,  =CFG_MCIO0_VAL
+	str	r2,  [r1, #MCIO0_OFFSET]
+
+	@ write mcio1
+	ldr	r2,  =CFG_MCIO1_VAL
+	str	r2,  [r1, #MCIO1_OFFSET]
+
+@ Step 2c
+	@ fly-by-dma is defeatured on this part
+	@ write flycnfg
+	@ldr	r2,  =CFG_FLYCNFG_VAL
+	@str	r2,  [r1, #FLYCNFG_OFFSET]
+
+/* FIXME Does this sequence really make sense */
+#ifdef REDBOOT_WAY
+	@ Step 2d
+	@ get the mdrefr settings
+	ldr	r3,  =CFG_MDREFR_VAL
+
+	@ extract DRI field (we need a valid DRI field)
+	@
+	ldr	r2,  =0xFFF
+
+	@ valid DRI field in r3
+	@
+	and	r3,  r3,  r2
+
+	@ get the reset state of MDREFR
+	@
+	ldr	r4,  [r1, #MDREFR_OFFSET]
+
+	@ clear the DRI field
+	@
+	bic	r4,  r4,  r2
+
+	@ insert the valid DRI field loaded above
+	@
+	orr	r4,  r4,  r3
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+
+	@ *Note: preserve the mdrefr value in r4 *
+
+@****************************************************************************
+@  Step 3
+@
+@ NO SRAM
+
+	mov	pc, r10
+
+
+@****************************************************************************
+@  Step 4
+@
+
+	@ Assumes previous mdrefr value in r4, if not then read current mdrefr
+
+	@ clear the free-running clock bits
+	@ (clear K0Free, K1Free, K2Free
+	@
+	bic	r4,  r4,  #(0x00800000 | 0x01000000 | 0x02000000)
+
+	@ set K0RUN for CPLD clock
+	@
+	orr	r4,  r4,  #0x00002000
+
+	@ set K1RUN if bank 0 installed
+	@
+	orr	r4,  r4,  #0x00010000
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+	ldr	r4,  [r1, #MDREFR_OFFSET]
+
+	@ deassert SLFRSH
+	@
+	bic	r4,  r4,  #0x00400000
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+
+	@ assert E1PIN
+	@
+	orr	r4,  r4,  #0x00008000
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+	ldr	r4,  [r1, #MDREFR_OFFSET]
+	nop
+	nop
+#else
+	@ Step 2d
+	@ get the mdrefr settings
+	ldr	r3,  =CFG_MDREFR_VAL
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+
+	@  Step 4
+
+	@ set K0RUN for CPLD clock
+	@
+	orr	r4,  r4,  #0x00002000
+
+	@ set K1RUN for bank 0
+	@
+	orr	r4,  r4,  #0x00010000
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+	ldr	r4,  [r1, #MDREFR_OFFSET]
+
+	@ deassert SLFRSH
+	@
+	bic	r4,  r4,  #0x00400000
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+
+	@ assert E1PIN
+	@
+	orr	r4,  r4,  #0x00008000
+
+	@ write back mdrefr
+	@
+	str	r4,  [r1, #MDREFR_OFFSET]
+	ldr	r4,  [r1, #MDREFR_OFFSET]
+	nop
+	nop
+#endif
+
+	@ Step 4d
+	@ fetch platform value of mdcnfg
+	@
+	ldr	r2,  =CFG_MDCNFG_VAL
+
+	@ disable all sdram banks
+	@
+	bic	r2,  r2,  #(MDCNFG_DE0 | MDCNFG_DE1)
+	bic	r2,  r2,  #(MDCNFG_DE2 | MDCNFG_DE3)
+
+	@ program banks 0/1 for bus width
+	@
+	bic	r2,  r2,  #MDCNFG_DWID0	     @0=32-bit
+
+	@ write initial value of mdcnfg, w/o enabling sdram banks
+	@
+	str	r2,  [r1, #MDCNFG_OFFSET]
+
+	@ Step 4e
+	@ pause for 200 uSecs
+	@
+	ldr	r3, =OSCR	@ reset the OS Timer Count to zero
+	mov	r2, #0
+	str	r2, [r3]
+	ldr	r4, =0x300			@ really 0x2E1 is about 200usec, so 0x300 should be plenty
+	1:
+	ldr	r2, [r3]
+	cmp	r4, r2
+	bgt	1b
+
+	/* Why is this here??? */
+	mov	r0, #0x78		 @turn everything off
+	mcr	p15, 0, r0, c1, c0, 0	   @(caches off, MMU off, etc.)
+
+	@ Step 4f
+	@ Access memory *not yet enabled* for CBR refresh cycles (8)
+	@ - CBR is generated for all banks
+
+	ldr	r2, =CFG_DRAM_BASE
+	str	r2, [r2]
+	str	r2, [r2]
+	str	r2, [r2]
+	str	r2, [r2]
+	str	r2, [r2]
+	str	r2, [r2]
+	str	r2, [r2]
+	str	r2, [r2]
+
+	@ Step 4g
+	@get memory controller base address
+	@
+	ldr	r1,  =MEMC_BASE
+
+	@fetch current mdcnfg value
+	@
+	ldr	r3,  [r1, #MDCNFG_OFFSET]
+
+	@enable sdram bank 0 if installed (must do for any populated bank)
+	@
+	orr	r3,  r3,  #MDCNFG_DE0
+
+	@write back mdcnfg, enabling the sdram bank(s)
+	@
+	str	r3,  [r1, #MDCNFG_OFFSET]
+
+	@ Step 4h
+	@ write mdmrs
+	@
+	ldr	r2,  =CFG_MDMRS_VAL
+	str	r2,  [r1, #MDMRS_OFFSET]
+
+	@ Done Memory Init
+
+	/*SET_LED 6 */
+
+	@********************************************************************
+	@ Disable (mask) all interrupts at the interrupt controller
+	@
+
+	@ clear the interrupt level register (use IRQ, not FIQ)
+	@
+	mov	r1, #0
+	ldr	r2,  =ICLR
+	str	r1,  [r2]
+
+	@ Set interrupt mask register
+	@
+	ldr	r1,  =CFG_ICMR_VAL
+	ldr	r2,  =ICMR
+	str	r1,  [r2]
+
+	@ ********************************************************************
+	@ Disable the peripheral clocks, and set the core clock
+	@
+
+	@ Turn Off ALL on-chip peripheral clocks for re-configuration
+	@
+	ldr	r1,  =CKEN
+	mov	r2,  #0
+	str	r2,  [r1]
+
+	@ set core clocks
+	@
+	ldr	r2,  =CFG_CCCR_VAL
+	ldr	r1,  =CCCR
+	str	r2,  [r1]
+
+	#ifdef ENABLE32KHZ
+	@ enable the 32Khz oscillator for RTC and PowerManager
+	@
+	ldr	r1,  =OSCC
+	mov	r2,  #OSCC_OON
+	str	r2,  [r1]
+
+	@ NOTE:	 spin here until OSCC.OOK get set,
+	@	 meaning the PLL has settled.
+	@
+60:
+	ldr	r2, [r1]
+	ands	r2, r2, #1
+	beq	60b
+#endif
+
+	@ Turn on needed clocks
+	@
+	ldr	r1,  =CKEN
+	ldr	r2,  =CFG_CKEN_VAL
+	str	r2,  [r1]
+
+	/*SET_LED 7 */
+
+/* Is this needed???? */
+#define NODEBUG
+#ifdef NODEBUG
+   /*Disable software and data breakpoints */
+	mov	r0,#0
+	mcr	p15,0,r0,c14,c8,0  /* ibcr0 */
+	mcr	p15,0,r0,c14,c9,0  /* ibcr1 */
+	mcr	p15,0,r0,c14,c4,0  /* dbcon */
+
+	/*Enable all debug functionality */
+	mov	r0,#0x80000000
+	mcr	p14,0,r0,c10,c0,0  /* dcsr */
+
+#endif
+
+	mov	pc, r10
+
+@ End memsetup
diff --git a/board/pleb2/pleb2.c b/board/pleb2/pleb2.c
new file mode 100644
index 0000000..ce9245c
--- /dev/null
+++ b/board/pleb2/pleb2.c
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2002
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm-arm/mach-types.h>
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* memory and cpu-speed are setup before relocation */
+	/* so we do _nothing_ here */
+
+	/* arch number of Lubbock-Board */
+	gd->bd->bi_arch_number = MACH_TYPE_PLEB2;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = 0xa0000100;
+
+	return 0;
+}
+
+int board_late_init(void)
+{
+	setenv("stdout", "serial");
+	setenv("stderr", "serial");
+	return 0;
+}
+
+
+int dram_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+	gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+	gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
+	gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
+	gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
+	gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
+
+	return 0;
+}
diff --git a/board/pleb2/u-boot.lds b/board/pleb2/u-boot.lds
new file mode 100644
index 0000000..58c371d
--- /dev/null
+++ b/board/pleb2/u-boot.lds
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  cpu/pxa/start.o	(.text)
+	  *(.text)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(.rodata) }
+
+	. = ALIGN(4);
+	.data : { *(.data) }
+
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}