Merge from "stable branch", tag LABEL_2003_06_28_1800-stable:
- Allow to call sysmon function interactively
- PIC on LWMON board needs delay after power-on
- Add missing RSR definitions for MPC8xx
- Improve log buffer handling: guarantee clean reset after power-on
- Add support for EXBITGEN board
- Add support for SL8245 board
diff --git a/board/exbitgen/Makefile b/board/exbitgen/Makefile
new file mode 100644
index 0000000..34bd4b2
--- /dev/null
+++ b/board/exbitgen/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o flash.o
+
+SOBJS	= init.o
+
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $^
+
+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/exbitgen/config.mk b/board/exbitgen/config.mk
new file mode 100644
index 0000000..42ea0c6
--- /dev/null
+++ b/board/exbitgen/config.mk
@@ -0,0 +1,33 @@
+#
+# (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
+#
+
+#
+# ExbitGen board
+#
+
+LDFLAGS += $(LINKER_UNDEFS)
+
+TEXT_BASE := 0xFFF80000
+#TEXT_BASE := 0x00100000
+
+PLATFORM_RELFLAGS := $(PLATFORM_RELFLAGS)
diff --git a/board/exbitgen/exbitgen.c b/board/exbitgen/exbitgen.c
new file mode 100644
index 0000000..f2cd8ca
--- /dev/null
+++ b/board/exbitgen/exbitgen.c
@@ -0,0 +1,117 @@
+#include <asm/u-boot.h>
+#include <asm/processor.h>
+#include <common.h>
+#include "exbitgen.h"
+
+/* ************************************************************************ */
+int board_pre_init (void)
+/* ------------------------------------------------------------------------ --
+ * Purpose     :
+ * Remarks     :
+ * Restrictions:
+ * See also    :
+ * Example     :
+ * ************************************************************************ */
+{
+	unsigned long i;
+
+   /*-------------------------------------------------------------------------+
+   | Interrupt controller setup for the Walnut 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
+   |       IRQ 25 (EXT IRQ 0) FPGA; active high; level sensitive
+   |       IRQ 26 (EXT IRQ 1) SMI; active high; level sensitive
+   |       IRQ 27 (EXT IRQ 2) Not Used
+   |       IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
+   |       IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+   |       IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
+   |       IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
+   | Note for Walnut board:
+   |       An interrupt taken for the FPGA (IRQ 25) indicates that either
+   |       the Mouse, Keyboard, IRDA, or External Expansion caused the
+   |       interrupt. The FPGA must be read to determine which device
+   |       caused the interrupt. The default setting of the FPGA clears
+   |
+   +-------------------------------------------------------------------------*/
+
+	mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */
+	mtdcr (uicer, 0x00000000);	/* disable all ints */
+	mtdcr (uiccr, 0x00000020);	/* set all but FPGA SMI to be non-critical */
+	mtdcr (uicpr, 0xFFFFFF90);	/* set int polarities */
+	mtdcr (uictr, 0x10000000);	/* set int trigger levels */
+	mtdcr (uicvcr, 0x00000001);	/* set vect base=0,INT0 highest priority */
+	mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */
+
+	/* Perform reset of PHY connected to PPC via register in CPLD */
+	out8 (PHY_CTRL_ADDR, 0x2e);	/* activate nRESET,FDX,F100,ANEN, enable output */
+	for (i = 0; i < 10000000; i++) {
+		;
+	}
+	out8 (PHY_CTRL_ADDR, 0x2f);	/* deactivate nRESET */
+
+	return 0;
+}
+
+
+/* ************************************************************************ */
+int checkboard (void)
+/* ------------------------------------------------------------------------ --
+ * Purpose     :
+ * Remarks     :
+ * Restrictions:
+ * See also    :
+ * Example     :
+ * ************************************************************************ */
+{
+	printf ("Exbit H/W id: %d\n", in8 (HW_ID_ADDR));
+	return (0);
+}
+
+/* ************************************************************************ */
+long int initdram (int board_type)
+/* ------------------------------------------------------------------------ --
+ * Purpose     : Determines size of mounted DRAM.
+ * Remarks     : Size is determined by reading SDRAM configuration registers as
+ *               set up by sdram_init.
+ * Restrictions:
+ * See also    :
+ * Example     :
+ * ************************************************************************ */
+{
+	ulong tot_size;
+	ulong bank_size;
+	ulong tmp;
+
+	tot_size = 0;
+
+	mtdcr (memcfga, mem_mb0cf);
+	tmp = mfdcr (memcfgd);
+	if (tmp & 0x00000001) {
+		bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+		tot_size += bank_size;
+	}
+
+	mtdcr (memcfga, mem_mb1cf);
+	tmp = mfdcr (memcfgd);
+	if (tmp & 0x00000001) {
+		bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+		tot_size += bank_size;
+	}
+
+	mtdcr (memcfga, mem_mb2cf);
+	tmp = mfdcr (memcfgd);
+	if (tmp & 0x00000001) {
+		bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+		tot_size += bank_size;
+	}
+
+	mtdcr (memcfga, mem_mb3cf);
+	tmp = mfdcr (memcfgd);
+	if (tmp & 0x00000001) {
+		bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+		tot_size += bank_size;
+	}
+
+	return tot_size;
+}
diff --git a/board/exbitgen/exbitgen.h b/board/exbitgen/exbitgen.h
new file mode 100644
index 0000000..058ad48
--- /dev/null
+++ b/board/exbitgen/exbitgen.h
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define GPIO_CPU_LED		GPIO_3
+
+
+#define CPLD_BASE		0x10000000		/* t.b.m. */
+#define DEBUG_LEDS_ADDR 	CPLD_BASE + 0x01
+#define HW_ID_ADDR      	CPLD_BASE + 0x02
+#define DIP_SWITCH_ADDR 	CPLD_BASE + 0x04
+#define PHY_CTRL_ADDR   	CPLD_BASE + 0x05
+#define SPI_OUT_ADDR    	CPLD_BASE + 0x07
+#define SPI_IN_ADDR     	CPLD_BASE + 0x08
+#define MDIO_OUT_ADDR   	CPLD_BASE + 0x09
+#define MDIO_IN_ADDR    	CPLD_BASE + 0x0A
+#define MISC_OUT_ADDR   	CPLD_BASE + 0x0B
+
+/* Addresses used on I2C bus */
+#define LM75_CHIP_ADDR		0x9C
+#define LM75_CPU_ADDR		0x9E
+#define SDRAM_SPD_ADDR		0xA0
+
+#define SDRAM_SPD_WRITE_ADDRESS	(SDRAM_SPD_ADDR)
+#define SDRAM_SPD_READ_ADDRESS	(SDRAM_SPD_ADDR+1)
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
diff --git a/board/exbitgen/flash.c b/board/exbitgen/flash.c
new file mode 100644
index 0000000..f687ea3
--- /dev/null
+++ b/board/exbitgen/flash.c
@@ -0,0 +1,597 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * 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 <asm/u-boot.h>
+#include <asm/processor.h>
+#include <ppc4xx.h>
+#include <common.h>
+
+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);
+
+#ifdef MEIGSBOARD_ONBOARD_FLASH /* onboard = 2MB */
+#  ifdef CONFIG_EXBITGEN
+#     define FLASH_WORD_SIZE unsigned long
+#  endif
+#else /* Meigsboard socket flash = 512KB */
+#  ifdef CONFIG_EXBITGEN
+#    define FLASH_WORD_SIZE unsigned char
+#  endif
+#endif
+
+#ifdef CONFIG_EXBITGEN
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+	unsigned long bank_size;
+	unsigned long tot_size;
+	unsigned long bank_addr;
+	int i;
+
+	/* Init: no FLASHes known */
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+		flash_info[i].size = 0;
+	}
+
+	tot_size = 0;
+
+	/* Detect Boot Flash */
+	bank_addr = CFG_FLASH0_BASE;
+	bank_size = flash_get_size((vu_long *)bank_addr, &flash_info[0]);
+	if (bank_size > 0) {
+		(void)flash_protect(FLAG_PROTECT_CLEAR,
+			bank_addr,
+			bank_addr + bank_size - 1,
+			&flash_info[0]);
+	}
+	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+		printf ("## Unknown FLASH on Boot Flash Bank\n");
+	}
+	flash_info[0].size = bank_size;
+	tot_size += bank_size;
+
+	/* Detect Application Flash */
+	bank_addr = CFG_FLASH1_BASE;
+	for (i = 1; i < CFG_MAX_FLASH_BANKS; ++i) {
+		bank_size = flash_get_size((vu_long *)bank_addr, &flash_info[i]);
+		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+			break;
+		}
+		if (bank_size > 0) {
+			(void)flash_protect(FLAG_PROTECT_CLEAR,
+				bank_addr,
+				bank_addr + bank_size - 1,
+				&flash_info[i]);
+		}
+		flash_info[i].size = bank_size;
+		tot_size += bank_size;
+		bank_addr += bank_size;
+	}
+	if (flash_info[1].flash_id == FLASH_UNKNOWN) {
+		printf ("## Unknown FLASH on Application Flash Bank\n");
+	}
+
+	/* Protect monitor and environment sectors */
+#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
+	flash_protect(FLAG_PROTECT_SET,
+		CFG_MONITOR_BASE,
+		CFG_MONITOR_BASE + monitor_flash_len - 1,
+		&flash_info[0]);
+#if 0xfffffffc >= CFG_FLASH0_BASE
+#if 0xfffffffc <= CFG_FLASH0_BASE + CFG_FLASH0_SIZE - 1
+	flash_protect(FLAG_PROTECT_SET,
+		0xfffffffc, 0xffffffff,
+		&flash_info[0]);
+#endif
+#endif
+#endif
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+	flash_protect(FLAG_PROTECT_SET,
+		CFG_ENV_ADDR,
+		CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+		&flash_info[0]);
+#endif
+
+	return tot_size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+	int i;
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		printf ("missing or unknown FLASH type\n");
+		return;
+	}
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case FLASH_MAN_AMD:	printf ("AMD ");		break;
+	case FLASH_MAN_FUJ:	printf ("FUJITSU ");		break;
+	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_AMDLV033C:	printf ("AM29LV033C (32 Mbit, uniform sector size)\n");
+				break;
+	case FLASH_AMDLV065D:	printf ("AM29LV065D (64 Mbit, uniform sector size)\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;
+	case FLASH_SST040:	printf ("SST39LF/VF040 (4 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) {
+		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!
+ */
+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;
+
+	value = addr2[0];
+
+	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	*/
+	}
+
+	value = addr2[1];			/* device ID		*/
+
+	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_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		*/
+
+	case (FLASH_WORD_SIZE)AMD_ID_LV033C:
+		info->flash_id += FLASH_AMDLV033C;
+		info->sector_count = 64;
+		info->size = 0x00400000;
+		break;				/* => 4 MB		*/
+
+	case (FLASH_WORD_SIZE)AMD_ID_LV065D:
+		info->flash_id += FLASH_AMDLV065D;
+		info->sector_count = 128;
+		info->size = 0x00800000;
+		break;				/* => 8 MB		*/
+
+	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		*/
+
+	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		*/
+	case (FLASH_WORD_SIZE)SST_ID_xF040:
+		info->flash_id += FLASH_SST040;
+		info->sector_count = 128;
+		info->size = 0x00080000;
+		break;				/* => 512KB		*/
+
+	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) ||
+		(info->flash_id == FLASH_AMDLV033C) ||
+		(info->flash_id == FLASH_AMDLV065D)) {
+		ulong sectsize = info->size / info->sector_count;
+		for (i = 0; i < info->sector_count; i++)
+			info->start[i] = base + (i * sectsize);
+        } 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 */
+
+		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;
+	}
+
+	/* switch to the read mode */
+	if (info->flash_id != FLASH_UNKNOWN) {
+		addr2 = (FLASH_WORD_SIZE *)info->start[0];
+		*addr2 = (FLASH_WORD_SIZE)0x00F000F0;	/* reset bank */
+	}
+
+	return (info->size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+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;
+	ulong start, now, last;
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		if (info->flash_id == FLASH_UNKNOWN) {
+			printf ("- missing\n");
+		} else {
+			printf ("- no sectors to erase\n");
+		}
+		return 1;
+	}
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		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");
+	}
+
+	start = get_timer (0);
+	last  = start;
+	/* 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]);
+
+			/* Disable interrupts which might cause a timeout here */
+			flag = disable_interrupts();
+
+			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;
+
+			/* re-enable interrupts if necessary */
+			if (flag)
+				enable_interrupts();
+
+			/* wait at least 80us - let's wait 1 ms */
+			udelay (1000);
+
+			while ((addr2[0] & 0x00800080) !=
+				(FLASH_WORD_SIZE) 0x00800080) {
+				if ((now=get_timer(start)) >
+				           CFG_FLASH_ERASE_TOUT) {
+					printf ("Timeout\n");
+					addr[0] = (FLASH_WORD_SIZE)0x00F000F0;
+					return 1;
+				}
+
+				/* show that we're waiting */
+				if ((now - last) > 1000) {  /* every second  */
+					putc ('.');
+					last = now;
+				}
+			}
+
+			addr[0] = (FLASH_WORD_SIZE)0x00F000F0;
+		}
+	}
+
+	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 flag;
+        int i;
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*((volatile ulong *)dest) & data) != data) {
+		printf("dest = %08lx, *dest = %08lx, data = %08lx\n",
+			dest, *(volatile ulong *)dest, data);
+		return 2;
+	}
+
+        for (i=0; i < 4/sizeof(FLASH_WORD_SIZE); i++) {
+		/* 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] & 0x00800080) != (data2[i] & 0x00800080)) {
+			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+				addr2[0] = (FLASH_WORD_SIZE)0x00F000F0;
+				return (1);
+			}
+		}
+	}
+
+	addr2[0] = (FLASH_WORD_SIZE)0x00F000F0;
+
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/exbitgen/init.S b/board/exbitgen/init.S
new file mode 100644
index 0000000..96b0aba
--- /dev/null
+++ b/board/exbitgen/init.S
@@ -0,0 +1,1009 @@
+/*----------------------------------------------------------------------+
+ *
+ *       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
+ *-----------------------------------------------------------------------
+ */
+
+#include <config.h>
+#include <ppc4xx.h>
+#include "config.h"
+
+#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/
+#define FPGA_BRDC       0xF0300004
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#include "exbitgen.h"
+		
+/* IIC declarations (This is an extract from 405gp_i2c.h, which also contains some */
+/* c-code declarations and consequently can't be included here). */
+/* (Possibly to be solved somehow else). */
+/*--------------------------------------------------------------------- */
+#define	   I2C_REGISTERS_BASE_ADDRESS 0xEF600500
+#define    IIC_MDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICMDBUF)
+#define    IIC_SDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICSDBUF)
+#define    IIC_LMADR	(I2C_REGISTERS_BASE_ADDRESS+IICLMADR)
+#define    IIC_HMADR	(I2C_REGISTERS_BASE_ADDRESS+IICHMADR)
+#define    IIC_CNTL	(I2C_REGISTERS_BASE_ADDRESS+IICCNTL)
+#define    IIC_MDCNTL	(I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL)
+#define    IIC_STS	(I2C_REGISTERS_BASE_ADDRESS+IICSTS)
+#define    IIC_EXTSTS	(I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS)
+#define    IIC_LSADR	(I2C_REGISTERS_BASE_ADDRESS+IICLSADR)
+#define    IIC_HSADR	(I2C_REGISTERS_BASE_ADDRESS+IICHSADR)
+#define    IIC_CLKDIV	(I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV)
+#define    IIC_INTRMSK	(I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK)
+#define    IIC_XFRCNT	(I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT)
+#define    IIC_XTCNTLSS	(I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS)
+#define    IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL)
+
+/* MDCNTL Register Bit definition */
+#define    IIC_MDCNTL_HSCL 0x01
+#define    IIC_MDCNTL_EUBS 0x02
+#define    IIC_MDCNTL_FMDB 0x40
+#define    IIC_MDCNTL_FSDB 0x80
+
+/* CNTL Register Bit definition */
+#define    IIC_CNTL_PT     0x01
+#define    IIC_CNTL_READ   0x02
+#define    IIC_CNTL_CHT    0x04
+
+/* STS Register Bit definition */
+#define    IIC_STS_PT	   0X01
+#define    IIC_STS_ERR	   0X04
+#define    IIC_STS_MDBS    0X20
+
+/* EXTSTS Register Bit definition */
+#define    IIC_EXTSTS_XFRA 0X01
+#define    IIC_EXTSTS_ICT  0X02
+#define    IIC_EXTSTS_LA   0X04
+
+/* LED codes used for inditing progress and errors during read of DIMM SPD.  */
+/*--------------------------------------------------------------------- */
+#define LED_SDRAM_CODE_1  0xef
+#define LED_SDRAM_CODE_2  0xee
+#define LED_SDRAM_CODE_3  0xed
+#define LED_SDRAM_CODE_4  0xec
+#define LED_SDRAM_CODE_5  0xeb
+#define LED_SDRAM_CODE_6  0xea
+#define LED_SDRAM_CODE_7  0xe9
+#define LED_SDRAM_CODE_8  0xe8
+#define LED_SDRAM_CODE_9  0xe7
+#define LED_SDRAM_CODE_10 0xe6
+#define LED_SDRAM_CODE_11 0xe5
+#define LED_SDRAM_CODE_12 0xe4
+#define LED_SDRAM_CODE_13 0xe3
+#define LED_SDRAM_CODE_14 0xe2
+#define LED_SDRAM_CODE_15 0xe1
+#define LED_SDRAM_CODE_16 0xe0
+
+
+#define TIMEBASE_10PS (1000000000 / CONFIG_SYS_CLK_FREQ) * 100
+
+#define FLASH_8bit_AP   0x9B015480
+#define FLASH_8bit_CR   0xFFF18000 /* 1MB(min), 8bit, R/W */ 
+
+#define FLASH_32bit_AP  0x9B015480
+#define FLASH_32bit_CR  0xFFE3C000 /* 2MB, 32bit, R/W */
+
+
+#define WDCR_EBC(reg,val) addi    r4,0,reg;\
+        mtdcr   ebccfga,r4;\
+        addis   r4,0,val@h;\
+        ori     r4,r4,val@l;\
+        mtdcr   ebccfgd,r4
+
+/*---------------------------------------------------------------------
+ * 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.
+ *	Bank 0 - Boot flash
+ *	Bank 1-4 - application flash
+ *	Bank 5 - CPLD
+ *	Bank 6 - not used
+ *	Bank 7 - Heathrow chip
+ *---------------------------------------------------------------------	
+ */
+     	.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 */
+
+	mflr	r31			/* save link register */
+	
+        /*-----------------------------------------------------------
+         * 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 (Boot Flash) initialization
+         *---------------------------------------------------------------
+	 */
+	WDCR_EBC(pb0ap, FLASH_32bit_AP)
+	WDCR_EBC(pb0cr, 0xffe38000)
+/*pnc	WDCR_EBC(pb0cr, FLASH_32bit_CR) */
+	
+        /*---------------------------------------------------------------
+         * Memory Bank 5 (CPLD) initialization
+         *---------------------------------------------------------------
+	 */
+	WDCR_EBC(pb5ap, 0x01010040)
+/*jsa recommendation:		WDCR_EBC(pb5ap, 0x00010040) */
+	WDCR_EBC(pb5cr, 0x10038000)
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 6 (not used) initialization */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb6cr, 0x00000000)
+
+	/* Read HW ID to determine whether old H2 board or new generic CPU board */
+	addis	r3, 0,  HW_ID_ADDR@h
+	ori	r3, r3, HW_ID_ADDR@l
+        lbz     r3,0x0000(r3)
+	cmpi	0, r3, 1          /* if (HW_ID==1) */
+	beq 	setup_h2evalboard /* then jump */
+	cmpi	0, r3, 2          /* if (HW_ID==2) */
+	beq 	setup_genieboard  /* then jump */
+	cmpi	0, r3, 3          /* if (HW_ID==3) */
+	beq 	setup_genieboard  /* then jump */
+
+setup_genieboard:
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 1 (Application Flash) initialization for generic CPU board */
+        /*--------------------------------------------------------------- */
+/*	WDCR_EBC(pb1ap, 0x7b015480)	/###* T.B.M. */
+/*	WDCR_EBC(pb1ap, 0x7F8FFE80)	/###* T.B.M. */
+	WDCR_EBC(pb1ap, 0x9b015480)	/* hlb-20020207: burst 8 bit 6 cycles  */
+
+/*	WDCR_EBC(pb1cr, 0x20098000)	/###* 16 MB */
+	WDCR_EBC(pb1cr, 0x200B8000)	/* 32 MB */
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 4 (Onboard FPGA) initialization for generic CPU board */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb4ap, 0x01010000)	/*  */
+	WDCR_EBC(pb4cr, 0x1021c000)	/*  */
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 7 (Heathrow chip on Reference board) initialization */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb7ap, 0x200ffe80)	/* No Ready, many wait states (let reflections die out) */
+	WDCR_EBC(pb7cr, 0X4001A000)
+
+	bl	setup_continue
+
+	
+setup_h2evalboard:
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 1 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb1ap, 0x7b015480)	/* T.B.M. */
+/*3010	WDCR_EBC(pb1ap, 0x7F8FFE80)	/###* T.B.M. */
+	WDCR_EBC(pb1cr, 0x20058000) 
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 2 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb2ap, 0x7b015480)	/* T.B.M. */
+/*3010	WDCR_EBC(pb2ap, 0x7F8FFE80)	/###* T.B.M. */
+	WDCR_EBC(pb2cr, 0x20458000) 
+
+	/*--------------------------------------------------------------- */
+        /* Memory Bank 3 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb3ap, 0x7b015480)	/* T.B.M. */
+/*3010	WDCR_EBC(pb3ap, 0x7F8FFE80)	/###* T.B.M. */
+	WDCR_EBC(pb3cr, 0x20858000) 
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 4 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb4ap, 0x7b015480)	/* T.B.M. */
+/*3010	WDCR_EBC(pb4ap, 0x7F8FFE80)	/###* T.B.M. */
+	WDCR_EBC(pb4cr, 0x20C58000)
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 7 (Heathrow chip) initialization */
+        /*--------------------------------------------------------------- */
+	WDCR_EBC(pb7ap, 0x02000280)	/* No Ready, 4 wait states */
+	WDCR_EBC(pb7cr, 0X4001A000)
+
+setup_continue:
+
+	
+        mtlr    r31                     /* restore lr	 */
+	nop				/* pass2 DCR errata #8 */
+        blr
+
+/*--------------------------------------------------------------------- */
+/* Function:     sdram_init */
+/* Description:  Configures SDRAM memory banks. */
+/*--------------------------------------------------------------------- */
+        .globl  sdram_init
+
+sdram_init:
+#if CFG_MONITOR_BASE < CFG_FLASH_BASE
+	blr
+#else
+	mflr	r31
+
+	/* output SDRAM code  on LEDs */
+	addi	r4, 0, LED_SDRAM_CODE_1
+	addis	r5, 0, 0x1000
+	ori	r5, r5, 0x0001
+	stb	r4,0(r5)
+	eieio
+
+	/* Read contents of spd */
+	/*--------------------- */
+	bl	read_spd
+
+	/*----------------------------------------------------------- */
+	/* */
+	/* */
+	/* Update SDRAM timing register */
+	/* */
+	/* */
+	/*----------------------------------------------------------- */
+
+	/* Read  PLL feedback divider and calculate clock period of local bus in */
+	/* granularity of 10 ps. Save clock period in r30 */
+	/*-------------------------------------------------------------- */
+	mfdcr	r4, pllmd
+	addi	r9, 0, 25
+	srw	r4, r4, r9
+	andi.	r4, r4, 0x07
+	addis	r5, 0,  TIMEBASE_10PS@h
+	ori	r5, r5, TIMEBASE_10PS@l
+	divwu	r30, r5, r4
+
+	/* Determine CASL */
+	/*--------------- */
+	bl	find_casl	/* Returns CASL in r3 */
+
+	/* Calc trp_clocks = (trp * 100 + (clk - 1)) / clk */
+	/* (trp read from byte 27 in granularity of 1 ns) */
+	/*------------------------------------------------ */
+	mulli	r16, r16, 100
+	add	r16, r16, r30
+	addi	r6, 0, 1
+	subf	r16, r6, r16
+	divwu	r16, r16, r30
+
+	/* Calc trcd_clocks = (trcd * 100 + (clk - 1) ) / clk */
+	/* (trcd read from byte 29 in granularity of 1 ns) */
+	/*--------------------------------------------------- */
+	mulli	r17, r17, 100
+	add	r17, r17, r30
+	addi	r6, 0, 1
+	subf	r17, r6, r17
+	divwu	r17, r17, r30
+
+	/* Calc tras_clocks = (tras * 100 + (clk - 1) ) / clk */
+	/* (tras read from byte 30 in granularity of 1 ns) */
+	/*--------------------------------------------------- */
+	mulli	r18, r18, 100
+	add	r18, r18, r30
+	addi	r6, 0, 1
+	subf	r18, r6, r18
+	divwu	r18, r18, r30
+
+	/* Calc trc_clocks = trp_clocks + tras_clocks */
+	/*------------------------------------------- */
+	add	r18, r18, r16
+
+	/* CASL value */
+	/*----------- */
+	addi	r9, 0, 23
+	slw	r4, r3, r9
+
+	/* PTA = trp_clocks - 1 */
+	/*--------------------- */
+	addi	r6, 0, 1
+	subf	r5, r6, r16
+	addi	r9, 0, 18
+	slw	r5, r5, r9
+	or	r4, r4, r5
+
+	/* CTP = trc_clocks - trp_clocks - trcd_clocks - 1 */
+	/*------------------------------------------------ */
+	addi	r5, r18, 0
+	subf	r5, r16, r5
+	subf	r5, r17, r5
+	addi	r6, 0, 1
+	subf	r5, r6, r5
+	addi	r9, 0, 16
+	slw	r5, r5, r9
+	or	r4, r4, r5
+
+	/* LDF = 1 */
+	/*-------- */
+	ori	r4, r4, 0x4000
+
+	/* RFTA = trc_clocks - 4 */
+	/*---------------------- */
+	addi	r6, 0, 4
+	subf	r5, r6, r18
+	addi	r9, 0, 2
+	slw	r5, r5, r9
+	or	r4, r4, r5
+
+	/* RCD = trcd_clocks - 1 */
+	/*---------------------- */
+	addi	r6, 0, 1
+	subf	r5, r6, r17
+	or	r4, r4, r5
+
+        /*----------------------------------------------------------- */
+        /* Set SDTR1  */
+        /*----------------------------------------------------------- */
+        addi    r5,0,mem_sdtr1
+        mtdcr   memcfga,r5
+        mtdcr   memcfgd,r4
+
+	/*----------------------------------------------------------- */
+	/* */
+	/* */
+	/* Update memory bank 0-3 configuration registers */
+	/* */
+	/* */
+	/*----------------------------------------------------------- */
+
+	/* Build contents of configuration register for bank 0 into r6 */
+	/*------------------------------------------------------------ */
+	bl	find_mode	/* returns addressing mode in r3 */
+	addi	r29, r3, 0	/* save mode temporarily in r29 */
+	bl	find_size_code	/* returns size code in r3 */
+	addi	r9, 0, 17	/* bit offset of size code in configuration register */
+	slw	r3, r3, r9	/* */
+	addi	r9, 0, 13	/* bit offset of addressing mode in configuration register  */
+	slw	r29, r29, r9	/*  */
+	or	r3, r29, r3	/* merge size code and addressing mode */
+	ori	r6, r3, CFG_SDRAM_BASE + 1 /* insert base address and enable bank */
+
+	/* Calculate banksize r15 = (density << 22) / 2 */
+	/*--------------------------------------------- */
+	addi	r9, 0, 21
+	slw	r15, r15, r9
+
+	/* Set SDRAM bank 0 register and adjust r6 for next bank */
+	/*------------------------------------------------------ */
+	addi    r7,0,mem_mb0cf
+	mtdcr   memcfga,r7
+	mtdcr   memcfgd,r6
+
+	add	r6, r6, r15	/* add bank size to base address for next bank */
+
+	/* If two rows/banks then set SDRAM bank 1 register and adjust r6 for next bank */
+	/*---------------------------------------------------------------------------- */
+	cmpi	0, r12, 2
+	bne	b1skip
+
+	addi    r7,0,mem_mb1cf
+	mtdcr   memcfga,r7
+	mtdcr   memcfgd,r6
+
+	add	r6, r6, r15	/* add bank size to base address for next bank */
+
+	/* Set SDRAM bank 2 register and adjust r6 for next bank */
+	/*------------------------------------------------------ */
+b1skip:	addi    r7,0,mem_mb2cf
+	mtdcr   memcfga,r7
+	mtdcr   memcfgd,r6
+
+	add	r6, r6, r15	/* add bank size to base address for next bank */
+
+	/* If two rows/banks then set SDRAM bank 3 register */
+	/*------------------------------------------------ */
+	cmpi	0, r12, 2
+	bne	b3skip
+
+	addi    r7,0,mem_mb3cf
+	mtdcr   memcfga,r7
+	mtdcr   memcfgd,r6
+b3skip:	
+
+        /*----------------------------------------------------------- */
+        /* Set RTR */
+        /*----------------------------------------------------------- */
+	cmpi	0, r30, 1600
+	bge	rtr_1
+        addis   r7, 0, 0x05F0	/* RTR value for 100Mhz */
+	bl	rtr_2
+rtr_1:	addis	r7, 0, 0x03F8
+rtr_2:	addi    r4,0,mem_rtr
+	mtdcr   memcfga,r4
+	mtdcr   memcfgd,r7
+
+        /*----------------------------------------------------------- */
+        /* Delay to ensure 200usec have elapsed since reset. Assume worst */
+        /* case that the core is running 200Mhz: */
+        /*   200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+        /*----------------------------------------------------------- */
+        addis   r3,0,0x0000
+        ori     r3,r3,0xA000          /* ensure 200usec have passed since reset */
+        mtctr   r3
+..spinlp2:
+        bdnz    ..spinlp2               /* spin loop */
+
+        /*----------------------------------------------------------- */
+        /* Set memory controller options reg, MCOPT1. */
+	/* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst  */
+	/* read/prefetch. */
+        /*----------------------------------------------------------- */
+	addi    r4,0,mem_mcopt1
+	mtdcr   memcfga,r4
+	addis   r4,0,0x80C0             /* set DC_EN=1 */
+	ori     r4,r4,0x0000
+	mtdcr   memcfgd,r4
+
+
+        /*----------------------------------------------------------- */
+        /* Delay to ensure 10msec have elapsed since reset. This is */
+        /* required for the MPC952 to stabalize. Assume worst */
+        /* case that the core is running 200Mhz: */
+        /*   200,000,000 (cycles/sec) X .010 (sec) = 0x1E8480 cycles */
+        /* This delay should occur before accessing SDRAM. */
+        /*----------------------------------------------------------- */
+	addis   r3,0,0x001E
+	ori     r3,r3,0x8480          /* ensure 10msec have passed since reset */
+	mtctr   r3
+..spinlp3:
+	bdnz    ..spinlp3                /* spin loop */
+
+	/* output SDRAM code  on LEDs */
+	addi	r4, 0, LED_SDRAM_CODE_16
+	addis	r5, 0, 0x1000
+	ori	r5, r5, 0x0001
+	stb	r4,0(r5)
+	eieio
+
+        mtlr    r31                     /* restore lr */
+        blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    read_spd */
+/* Description: Reads contents of SPD and saves parameters to be used for */
+/*		configuration in dedicated registers (see code below). */
+/*---------------------------------------------------------------------	 */
+
+#define WRITE_I2C(reg,val) \
+	addi    r3,0,val;\
+        addis   r4, 0, 0xef60;\
+        ori     r4, r4, 0x0500 + reg;\
+        stb     r3, 0(r4);\
+        eieio
+
+#define READ_I2C(reg) \
+        addis   r3, 0, 0xef60;\
+        ori     r3, r3, 0x0500 + reg;\
+        lbz     r3, 0x0000(r3);\
+        eieio
+
+read_spd:
+
+	mflr	r5
+	
+	/* Initialize i2c */
+	/*--------------- */
+	WRITE_I2C(IICLMADR, 0x00)	/* clear lo master address */
+	WRITE_I2C(IICHMADR, 0x00)	/* clear hi master address */
+	WRITE_I2C(IICLSADR, 0x00)	/* clear lo slave address */
+	WRITE_I2C(IICHSADR, 0x00)	/* clear hi slave address */
+	WRITE_I2C(IICSTS, 0x08)		/* update status register */
+	WRITE_I2C(IICEXTSTS, 0x8f)
+	WRITE_I2C(IICCLKDIV, 0x05)
+	WRITE_I2C(IICINTRMSK, 0x00)	/* no interrupts */
+	WRITE_I2C(IICXFRCNT, 0x00)	/* clear transfer count */
+	WRITE_I2C(IICXTCNTLSS, 0xf0)	/* clear extended control & stat */
+	WRITE_I2C(IICMDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB)	/* mode control */
+	READ_I2C(IICMDCNTL)
+	ori	r3, r3, IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL
+	WRITE_I2C(IICMDCNTL, r3)	/* mode control */
+	WRITE_I2C(IICCNTL, 0x00)	/* clear control reg */
+
+	/* Wait until initialization completed */
+	/*------------------------------------ */
+	bl	wait_i2c_transfer_done
+
+	WRITE_I2C(IICHMADR, 0x00)	/* 7-bit addressing */
+	WRITE_I2C(IICLMADR, SDRAM_SPD_WRITE_ADDRESS)
+
+	/* Write 0 into buffer(start address) */
+	/*----------------------------------- */
+	WRITE_I2C(IICMDBUF, 0x00);
+
+	/* Wait a little */
+	/*-------------- */
+        addis   r3,0,0x0000
+        ori     r3,r3,0xA000
+        mtctr   r3
+in02:	bdnz    in02
+
+	/* Issue write command */
+	/*-------------------- */
+	WRITE_I2C(IICCNTL, IIC_CNTL_PT)
+	bl	wait_i2c_transfer_done
+
+	/* Read 128 bytes */
+	/*--------------- */
+	addi	r7, 0, 0	/* byte counter in r7 */
+	addi	r8, 0, 0	/* checksum in r8 */
+rdlp:	
+	/* issue read command */
+	/*------------------- */
+	cmpi	0, r7, 127
+	blt	rd01
+	WRITE_I2C(IICCNTL, IIC_CNTL_READ | IIC_CNTL_PT) 
+	bl	rd02
+rd01:	WRITE_I2C(IICCNTL, IIC_CNTL_READ | IIC_CNTL_CHT | IIC_CNTL_PT)
+rd02:	bl	wait_i2c_transfer_done
+
+	/* Fetch byte from buffer */
+	/*----------------------- */
+	READ_I2C(IICMDBUF)
+	
+	/* Retrieve parameters that are going to be used during configuration. */
+	/* Save them in dedicated registers. */
+	/*------------------------------------------------------------ */
+	cmpi	0, r7, 3	/* Save byte 3 in r10 */
+	bne	rd10
+	addi	r10, r3, 0	
+rd10:	cmpi	0, r7, 4	/* Save byte 4 in r11 */
+	bne	rd11
+	addi	r11, r3, 0	
+rd11:	cmpi	0, r7, 5	/* Save byte 5 in r12 */
+	bne	rd12
+	addi	r12, r3, 0	
+rd12:	cmpi	0, r7, 17	/* Save byte 17 in r13 */
+	bne	rd13
+	addi	r13, r3, 0	
+rd13:	cmpi	0, r7, 18	/* Save byte 18 in r14 */
+	bne	rd14
+	addi	r14, r3, 0	
+rd14:	cmpi	0, r7, 31	/* Save byte 31 in r15 */
+	bne	rd15
+	addi	r15, r3, 0	
+rd15:	cmpi	0, r7, 27	/* Save byte 27 in r16 */
+	bne	rd16
+	addi	r16, r3, 0	
+rd16:	cmpi	0, r7, 29	/* Save byte 29 in r17 */
+	bne	rd17
+	addi	r17, r3, 0	
+rd17:	cmpi	0, r7, 30	/* Save byte 30 in r18 */
+	bne	rd18
+	addi	r18, r3, 0	
+rd18:	cmpi	0, r7, 9	/* Save byte 9 in r19 */
+	bne	rd19
+	addi	r19, r3, 0	
+rd19:	cmpi	0, r7, 23	/* Save byte 23 in r20 */
+	bne	rd20
+	addi	r20, r3, 0	
+rd20:	cmpi	0, r7, 25	/* Save byte 25 in r21 */
+	bne	rd21
+	addi	r21, r3, 0	
+rd21:
+
+	/* Calculate checksum of the first 63 bytes */
+	/*----------------------------------------- */
+	cmpi	0, r7, 63
+	bgt	rd31
+	beq	rd30
+	add	r8, r8, r3
+	bl	rd31
+
+	/* Verify checksum at byte 63 */
+	/*--------------------------- */
+rd30:	andi.	r8, r8, 0xff		/* use only 8 bits */
+	cmp	0, r8, r3
+	beq	rd31
+	addi	r4, 0, LED_SDRAM_CODE_8
+	addis	r5, 0, 0x1000
+	ori	r5, r5, 0x0001
+	stb	r4,0(r5)
+	eieio
+rderr:	bl	rderr
+
+rd31:	
+	
+	/* Increment byte counter and check whether all bytes have been read. */
+	/*------------------------------------------------------------------- */
+	addi	r7, r7, 1
+	cmpi	0, r7, 127
+	bgt	rd05
+	bl	rdlp
+rd05:	
+        mtlr    r5                     /* restore lr */
+	blr
+
+wait_i2c_transfer_done:
+	mflr	r6
+wt01:	READ_I2C(IICSTS)
+	andi.	r4, r3, IIC_STS_PT
+	cmpi	0, r4, IIC_STS_PT
+	beq	wt01	
+        mtlr    r6                     /* restore lr */
+	blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    find_mode */
+/* Description: Determines addressing mode to be used dependent on   */
+/*		number of rows (r10 = byte 3 from SPD), number of columns (r11 = */
+/*		byte 4 from SPD) and number of banks (r13 = byte 17 from SPD). */
+/*		mode is returned in r3. */
+/* (It would be nicer having a table, pnc). */
+/*---------------------------------------------------------------------	 */
+find_mode:
+
+	mflr	r5
+
+	cmpi	0, r10, 11
+	bne	fm01
+	cmpi	0, r11, 9
+	bne	fm01
+	cmpi	0, r13, 2
+	bne	fm01
+	addi	r3, 0, 1
+	bl	fmfound
+
+fm01:	cmpi	0, r10, 11
+	bne	fm02
+	cmpi	0, r11, 10
+	bne	fm02
+	cmpi	0, r13, 2
+	bne	fm02
+	addi	r3, 0, 1
+	bl	fmfound	
+
+fm02:	cmpi	0, r10, 12
+	bne	fm03
+	cmpi	0, r11, 9
+	bne	fm03
+	cmpi	0, r13, 4
+	bne	fm03
+	addi	r3, 0, 2
+	bl	fmfound
+
+fm03:	cmpi	0, r10, 12
+	bne	fm04
+	cmpi	0, r11, 10
+	bne	fm04
+	cmpi	0, r13, 4
+	bne	fm04
+	addi	r3, 0, 2
+	bl	fmfound
+
+fm04:	cmpi	0, r10, 13
+	bne	fm05
+	cmpi	0, r11, 9
+	bne	fm05
+	cmpi	0, r13, 4
+	bne	fm05
+	addi	r3, 0, 3
+	bl	fmfound
+
+fm05:	cmpi	0, r10, 13
+	bne	fm06
+	cmpi	0, r11, 10
+	bne	fm06
+	cmpi	0, r13, 4
+	bne	fm06
+	addi	r3, 0, 3
+	bl	fmfound
+
+fm06:	cmpi	0, r10, 13
+	bne	fm07
+	cmpi	0, r11, 11
+	bne	fm07
+	cmpi	0, r13, 4
+	bne	fm07
+	addi	r3, 0, 3
+	bl	fmfound
+
+fm07:	cmpi	0, r10, 12
+	bne	fm08
+	cmpi	0, r11, 8
+	bne	fm08
+	cmpi	0, r13, 2
+	bne	fm08
+	addi	r3, 0, 4
+	bl	fmfound
+
+fm08:	cmpi	0, r10, 12
+	bne	fm09
+	cmpi	0, r11, 8
+	bne	fm09
+	cmpi	0, r13, 4
+	bne	fm09
+	addi	r3, 0, 4
+	bl	fmfound
+
+fm09:	cmpi	0, r10, 11
+	bne	fm10
+	cmpi	0, r11, 8
+	bne	fm10
+	cmpi	0, r13, 2
+	bne	fm10
+	addi	r3, 0, 5
+	bl	fmfound
+
+fm10:	cmpi	0, r10, 11
+	bne	fm11
+	cmpi	0, r11, 8
+	bne	fm11
+	cmpi	0, r13, 4
+	bne	fm11
+	addi	r3, 0, 5
+	bl	fmfound
+
+fm11:	cmpi	0, r10, 13
+	bne	fm12
+	cmpi	0, r11, 8
+	bne	fm12
+	cmpi	0, r13, 2
+	bne	fm12
+	addi	r3, 0, 6
+	bl	fmfound
+
+fm12:	cmpi	0, r10, 13
+	bne	fm13
+	cmpi	0, r11, 8
+	bne	fm13
+	cmpi	0, r13, 4
+	bne	fm13
+	addi	r3, 0, 6
+	bl	fmfound
+
+fm13:	cmpi	0, r10, 13
+	bne	fm14
+	cmpi	0, r11, 9
+	bne	fm14
+	cmpi	0, r13, 2
+	bne	fm14
+	addi	r3, 0, 7
+	bl	fmfound
+
+fm14:	cmpi	0, r10, 13
+	bne	fm15
+	cmpi	0, r11, 10
+	bne	fm15
+	cmpi	0, r13, 2
+	bne	fm15
+	addi	r3, 0, 7
+	bl	fmfound
+
+fm15:	
+	/* not found, error code to be issued on LEDs */
+	addi	r7, 0, LED_SDRAM_CODE_2
+	addis	r6, 0, 0x1000
+	ori	r6, r6, 0x0001
+	stb	r7,0(r6)
+	eieio
+fmerr:	bl	fmerr
+
+fmfound:addi	r6, 0, 1
+	subf	r3, r6, r3
+
+        mtlr    r5                     /* restore lr */
+	blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    find_size_code */
+/* Description: Determines size code to be used in configuring SDRAM controller */
+/*		dependent on density (r15 = byte 31 from SPD) */
+/*--------------------------------------------------------------------- */
+find_size_code:
+
+	mflr	r5
+	
+	addi	r3, r15, 0	/* density */
+	addi	r7, 0, 0
+fs01:	andi.	r6, r3, 0x01
+	cmpi	0, r6, 1
+	beq	fs04
+	
+	addi	r7, r7, 1
+	cmpi	0, r7, 7
+	bge	fs02
+	addi	r9, 0, 1
+	srw	r3, r3, r9
+	bl	fs01
+
+	/* not found, error code to be issued on LEDs */
+fs02:	addi	r4, 0, LED_SDRAM_CODE_3
+	addis	r8, 0, 0x1000
+	ori	r8, r8, 0x0001
+	stb	r4,0(r8)
+	eieio
+fs03:	bl	fs03
+
+fs04:	addi	r3, r7, 0
+	cmpi	0, r3, 0
+	beq	fs05
+	addi	r6, 0, 1
+	subf	r3, r6, r3
+fs05:
+        mtlr    r5                     /* restore lr */
+	blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    find_casl */
+/* Description: Determines CAS latency */
+/*--------------------------------------------------------------------- */
+find_casl:
+
+	mflr	r5
+
+	andi.	r14, r14, 0x7f	/* r14 holds supported CAS latencies */
+	addi	r3, 0, 0xff	/* preset determined CASL */
+	addi	r4, 0, 6	/* Start at bit 6 of supported CAS latencies */
+	addi	r2, 0, 0	/* Start finding highest CAS latency */
+
+fc01:	srw	r6, r14, r4	/*  */
+	andi.	r6, r6, 0x01	/*  */
+	cmpi	0, r6, 1	/* Check bit for current latency */
+	bne	fc06		/* If not supported, go to next */
+
+	cmpi	0, r2, 2	/* Check if third-highest latency */
+	bge	fc04		/* If so, go calculate with another format */
+
+	cmpi	0, r2, 0	/* Check if highest latency */
+	bgt	fc02		/* */
+	addi	r7, r19, 0	/* SDRAM cycle time for highest CAS latenty */
+
+	bl	fc03
+fc02:	
+	addi	r7, r20, 0	/* SDRAM cycle time for next-highest CAS latenty */
+fc03:	
+	addi	r8, r7, 0
+	addi	r9, 0, 4
+	srw	r7, r7, r9
+	andi.	r7, r7, 0x0f
+	mulli	r7, r7, 100
+	andi.	r8, r8, 0x0f
+	mulli	r8, r8, 10
+	add	r7, r7, r8
+	cmp	0, r7, r30
+	bgt	fc05
+	addi	r3, r2, 0
+	bl	fc05
+fc04:	
+	addi	r7, r21, 0	/* SDRAM cycle time for third-highest CAS latenty */
+	addi	r8, r7, 0
+	addi	r9, 0, 2
+	srw	r7, r7, r9
+	andi.	r7, r7, 0x3f
+	mulli	r7, r7, 100
+	andi.	r8, r8, 0x03
+	mulli	r8, r8, 25
+	add	r7, r7, r8
+
+	cmp	0, r7, r30
+	bgt	fc05
+	addi	r3, r2, 0
+
+fc05:	addi	r2, r2, 1	/* next latency */
+	cmpi	0, r2, 3
+	bge	fc07
+fc06:	addi	r6, 0, 1
+	subf	r4, r6, r4
+	cmpi	0, r4, 0
+	bne	fc01
+
+fc07:	
+
+        mtlr    r5		/* restore lr */
+	blr
+#endif
+
+
+/*  Peripheral Bank 1 Access Parameters */
+/*     0	BME = 1	; burstmode enabled */
+/*    " 1:8"	TWT=00110110	;Transfer wait (details below) */
+/*     1:5	FWT=00110	; first wait = 6 cycles */
+/*     6:8	BWT=110	; burst wait = 6 cycles */
+/*     9:11	000	; reserved */
+/*     12:13	CSN=00	; chip select on timing = 0 */
+/*     14:15	OEN=01	; output enable  */
+/*     16:17	WBN=01	; write byte enable on timing 1 cycle */
+/*     18:19	WBF=01	; write byte enable off timing 1 cycle */
+/*     20:22	TH=010	; transfer hold = 2 cycles */
+/*     23	RE=0	; ready enable = disabled */
+/*     24	SOR=1	; sample on ready = same PerClk */
+/*     25	BEM=0	; byte enable mode = only for write cycles */
+/*     26	PEN=0	; parity enable = disable */
+/*     27:31	00000	;reserved */
+/* */
+/* 1 + 00110 + 110 + 000 + 00 + 01 + 01 + 01 + 010 + 0 + 1 + 0 + 0 + 00000 = 0x9b015480 */
+/* */
+/* */
+/*	Code for BDI probe: */
+/* */
+/* WDCR    18      0x00000011      ;Select PB1AP */
+/* WDCR    19      0x1b015480      ;PB1AP: Flash */
+/* */
+/* Peripheral Bank 0 Access Parameters */
+/* 0:11	BAS=0x200	; base address select = 0x200 * 0x100000 (1MB) =  */
+/* 12:14	BS=100	; bank size =  16MB (100) / 32MB (101) */
+/* 15:16	BU=11	; bank usage = read/write */
+/* 17:18	BW=00	; bus width = 8-bit */
+/* 19:31		; reserved */
+/* */
+/* 0x200 + 100 + 11 + 00 + 0 0000 0000 0000 = 0x20098000 */
+/* WDCR    18      0x00000001      ;Select PB1CR */
+/* WDCR    19      0x20098000      ;PB1CR: 1MB at 0x00100000, r/w, 8bit */
+
+/* For CPLD */
+/* 0 + 00000 + 010 + 000 + 00 + 01 + 00 + 00 + 000 + 0 + 0 + 1 + 0 + 00000 */
+/*	WDCR_EBC(pb5ap, 0x01010040) */
+/*jsa recommendation:		WDCR_EBC(pb5ap, 0x00010040) */
+/*	WDCR_EBC(pb5cr, 0X10018000) */
+/* Access parms */
+/*   100   3      8          0    0    0 */
+/* 0x100 + 001 + 11 + 00 + 0 0000 0000 0000 = 0x10038000 */
+/* Address :	0x10000000 */
+/* Size:	2 MB */
+/* Usage:	read/write */
+/* Width:	32 bit */
+
+/* For Genie onboard fpga 32 bit interface */
+/* 0      1      0         1         0         0         0            0 */
+/* 0 + 00000 + 010 + 000 + 00 + 01 + 00 + 00 + 000 + 0 + 0 + 0 + 0 + 00000 */
+/* 0x01010000 */
+/* Access parms */
+/*   102   1      c          0    0    0 */
+/* 0x102 + 000 + 11 + 10 + 0 0000 0000 0000 = 0x1021c000 */
+/* Address :	0x10200000 */
+/* Size:	2 MB */
+/* Usage:	read/write */
+/* Width:	32 bit */
+	
+/* Walnut fpga pb7ap */
+/* 0      1      8         1         5         2         8            0 */
+/* 0 + 00000 + 011 + 000 + 00 + 01 + 01 + 01 + 001 + 0 + 1 + 0 + 0 + 00000 */
+/* Walnut fpga pb7cr */
+/* 0xF0318000 */
+/*  */
diff --git a/board/exbitgen/u-boot.lds b/board/exbitgen/u-boot.lds
new file mode 100644
index 0000000..863a7e4
--- /dev/null
+++ b/board/exbitgen/u-boot.lds
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  .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      :
+  {
+    /* WARNING - the following is hand-optimized to fit within	*/
+    /* the sector layout of our flash chips!	XXX FIXME XXX	*/
+
+    cpu/ppc4xx/start.o	(.text)
+    board/exbitgen/init.o	(.text)
+    cpu/ppc4xx/kgdb.o	(.text)
+    cpu/ppc4xx/traps.o	(.text)
+    cpu/ppc4xx/interrupts.o	(.text)
+    cpu/ppc4xx/serial.o	(.text)
+    cpu/ppc4xx/cpu_init.o	(.text)
+    cpu/ppc4xx/speed.o	(.text)
+    common/dlmalloc.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_ppc/extable.o	(.text)
+    lib_generic/zlib.o		(.text)
+
+/*    . = env_offset;*/
+    common/environment.o(.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got) 
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+  . = ALIGN(4);
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c
index b359ec7..91aa58c 100644
--- a/board/lwmon/lwmon.c
+++ b/board/lwmon/lwmon.c
@@ -513,6 +513,9 @@
 
 	gd->kbd_status = 0;
 
+	/* Forced by PIC. Delays <= 175us loose */
+	udelay(1000);
+
 	/* Read initial keyboard error code */
 	val = KEYBD_CMD_READ_STATUS;
 	i2c_write (kbd_addr, 0, 0, &val, 1);
diff --git a/board/sl8245/Makefile b/board/sl8245/Makefile
new file mode 100644
index 0000000..da60318
--- /dev/null
+++ b/board/sl8245/Makefile
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2001 - 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS 	= $(BOARD).o flash.o
+
+$(LIB):	.depend $(OBJS)
+	$(AR) crv $@ $^
+
+#########################################################################
+
+.depend:	Makefile $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/sl8245/config.mk b/board/sl8245/config.mk
new file mode 100644
index 0000000..299fc6c
--- /dev/null
+++ b/board/sl8245/config.mk
@@ -0,0 +1,30 @@
+#
+# (C) Copyright 2001 - 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# SL8245 board
+#
+
+TEXT_BASE = 0xFFF00000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
diff --git a/board/sl8245/flash.c b/board/sl8245/flash.c
new file mode 100644
index 0000000..553dc98
--- /dev/null
+++ b/board/sl8245/flash.c
@@ -0,0 +1,488 @@
+/*
+ * (C) Copyright 2001 - 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+#include <asm/processor.h>
+
+#if defined(CFG_ENV_IS_IN_FLASH)
+# ifndef  CFG_ENV_ADDR
+#  define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET)
+# endif
+# ifndef  CFG_ENV_SIZE
+#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE
+# endif
+# ifndef  CFG_ENV_SECT_SIZE
+#  define CFG_ENV_SECT_SIZE  CFG_ENV_SIZE
+# endif
+#endif
+
+#define FLASH_BANK_SIZE 0x800000
+#define MAIN_SECT_SIZE  0x40000
+#define PARAM_SECT1_SIZE 0x20000
+#define PARAM_SECT23_SIZE 0x8000
+#define PARAM_SECT4_SIZE 0x10000
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+static int write_data (flash_info_t *info, ulong dest, ulong *data);
+static void write_via_fpu(vu_long *addr, ulong *data);
+static __inline__ unsigned long get_msr(void);
+static __inline__ void set_msr(unsigned long msr);
+
+/*---------------------------------------------------------------------*/
+#undef	DEBUG_FLASH
+
+/*---------------------------------------------------------------------*/
+#ifdef DEBUG_FLASH
+#define DEBUGF(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGF(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#define __align__ __attribute__ ((aligned (8)))
+static __align__ ulong precmd0[2]   = { 0x00aa00aa, 0x00aa00aa };
+static __align__ ulong precmd1[2]   = { 0x00550055, 0x00550055 };
+static __align__ ulong cmdid[2]     = { 0x00900090, 0x00900090 };
+static __align__ ulong cmderase[2]  = { 0x00800080, 0x00800080 };
+static __align__ ulong cmdersusp[2] = { 0x00b000b0, 0x00b000b0 };
+static __align__ ulong cmdsecter[2] = { 0x00300030, 0x00300030 };
+static __align__ ulong cmdprog[2]   = { 0x00a000a0, 0x00a000a0 };
+static __align__ ulong cmdres[2]    = { 0x00f000f0, 0x00f000f0 };
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+	int i, j;
+	ulong size = 0;
+
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+		vu_long *addr = (vu_long *) (CFG_FLASH_BASE + i * FLASH_BANK_SIZE);
+
+		write_via_fpu (&addr[0xaaa], precmd0);
+		write_via_fpu (&addr[0x554], precmd1);
+		write_via_fpu (&addr[0xaaa], cmdid);
+
+		DEBUGF ("Flash bank # %d:\n"
+			"\tManuf. ID @ 0x%08lX: 0x%08lX\n"
+			"\tDevice ID @ 0x%08lX: 0x%08lX\n",
+			i,
+			(ulong) (&addr[0]), addr[0],
+			(ulong) (&addr[2]), addr[2]);
+
+		if ((addr[0] == addr[1]) && (addr[0] == AMD_MANUFACT) &&
+			(addr[2] == addr[3]) && (addr[2] == AMD_ID_LV160T)) {
+			flash_info[i].flash_id = (FLASH_MAN_AMD & FLASH_VENDMASK) |
+					(FLASH_AM160T & FLASH_TYPEMASK);
+		} else {
+			flash_info[i].flash_id = FLASH_UNKNOWN;
+			write_via_fpu (addr, cmdres);
+			goto Done;
+		}
+
+		DEBUGF ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
+
+		write_via_fpu (addr, cmdres);
+
+		flash_info[i].size = FLASH_BANK_SIZE;
+		flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+		memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+		for (j = 0; j < 32; j++) {
+			flash_info[i].start[j] = CFG_FLASH_BASE +
+					i * FLASH_BANK_SIZE + j * MAIN_SECT_SIZE;
+		}
+		flash_info[i].start[32] =
+				flash_info[i].start[31] + PARAM_SECT1_SIZE;
+		flash_info[i].start[33] =
+				flash_info[i].start[32] + PARAM_SECT23_SIZE;
+		flash_info[i].start[34] =
+				flash_info[i].start[33] + PARAM_SECT23_SIZE;
+		size += flash_info[i].size;
+	}
+
+	/* Protect monitor and environment sectors
+	 */
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + FLASH_BANK_SIZE
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_MONITOR_BASE,
+			CFG_MONITOR_BASE + monitor_flash_len - 1,
+			&flash_info[1]);
+#else
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_MONITOR_BASE,
+			CFG_MONITOR_BASE + monitor_flash_len - 1,
+			&flash_info[0]);
+#endif
+#endif
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+#if CFG_ENV_ADDR >= CFG_FLASH_BASE + FLASH_BANK_SIZE
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_ENV_ADDR,
+			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[1]);
+#else
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_ENV_ADDR,
+			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+#endif
+#endif
+
+Done:
+	return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+	int i;
+
+	switch ((i = info->flash_id & FLASH_VENDMASK)) {
+	case (FLASH_MAN_AMD & FLASH_VENDMASK):
+		printf ("Intel: ");
+		break;
+	default:
+		printf ("Unknown Vendor 0x%04x ", i);
+		break;
+	}
+
+	switch ((i = info->flash_id & FLASH_TYPEMASK)) {
+	case (FLASH_AM160T & FLASH_TYPEMASK):
+		printf ("AM29LV160BT (16Mbit)\n");
+		break;
+	default:
+		printf ("Unknown Chip Type 0x%04x\n", i);
+		goto Done;
+		break;
+	}
+
+	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");
+
+  Done:
+	return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+	int flag, prot, sect;
+	ulong start, now, last;
+
+	DEBUGF ("Erase flash bank %d sect %d ... %d\n",
+		info - &flash_info[0], s_first, s_last);
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		if (info->flash_id == FLASH_UNKNOWN) {
+			printf ("- missing\n");
+		} else {
+			printf ("- no sectors to erase\n");
+		}
+		return 1;
+	}
+
+	if ((info->flash_id & FLASH_VENDMASK) !=
+		(FLASH_MAN_AMD & FLASH_VENDMASK)) {
+		printf ("Can erase only AMD flash types - 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");
+	}
+
+	start = get_timer (0);
+	last = start;
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last; sect++) {
+		if (info->protect[sect] == 0) {	/* not protected */
+			vu_long *addr = (vu_long *) (info->start[sect]);
+
+			DEBUGF ("Erase sect %d @ 0x%08lX\n", sect, (ulong) addr);
+
+			/* Disable interrupts which might cause a timeout
+			 * here.
+			 */
+			flag = disable_interrupts ();
+
+			write_via_fpu (&addr[0xaaa], precmd0);
+			write_via_fpu (&addr[0x554], precmd1);
+			write_via_fpu (&addr[0xaaa], cmderase);
+			write_via_fpu (&addr[0xaaa], precmd0);
+			write_via_fpu (&addr[0x554], precmd1);
+			write_via_fpu (&addr[0xaaa], cmdsecter);
+
+			/* re-enable interrupts if necessary */
+			if (flag)
+				enable_interrupts ();
+
+			/* wait at least 80us - let's wait 1 ms */
+			udelay (1000);
+
+			while (((addr[0] & 0x00800080) != 0x00800080) ||
+				   ((addr[1] & 0x00800080) != 0x00800080)) {
+				if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
+					printf ("Timeout\n");
+					write_via_fpu (addr, cmdersusp);
+					write_via_fpu (addr, cmdres);
+					return 1;
+				}
+
+				/* show that we're waiting */
+				if ((now - last) > 1000) {	/* every second  */
+					putc ('.');
+					last = now;
+				}
+			}
+
+			write_via_fpu (addr, cmdres);
+		}
+	}
+	printf (" done\n");
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+
+#define	FLASH_WIDTH	8		/* flash bus width in bytes */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+	ulong wp, cp, msr;
+	int l, rc, i;
+	ulong data[2];
+	ulong *datah = &data[0];
+	ulong *datal = &data[1];
+
+	DEBUGF ("Flash write_buff: @ 0x%08lx, src 0x%08lx len %ld\n",
+		addr, (ulong) src, cnt);
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		return 4;
+	}
+
+	msr = get_msr ();
+	set_msr (msr | MSR_FP);
+
+	wp = (addr & ~(FLASH_WIDTH - 1));	/* get lower aligned address */
+
+	/*
+	 * handle unaligned start bytes
+	 */
+	if ((l = addr - wp) != 0) {
+		*datah = *datal = 0;
+
+		for (i = 0, cp = wp; i < l; i++, cp++) {
+			if (i >= 4) {
+				*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
+			}
+
+			*datal = (*datal << 8) | (*(uchar *) cp);
+		}
+		for (; i < FLASH_WIDTH && cnt > 0; ++i) {
+			char tmp;
+
+			tmp = *src;
+
+			src++;
+
+			if (i >= 4) {
+				*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
+			}
+
+			*datal = (*datal << 8) | tmp;
+
+			--cnt;
+			++cp;
+		}
+
+		for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp) {
+			if (i >= 4) {
+				*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
+			}
+
+			*datal = (*datah << 8) | (*(uchar *) cp);
+		}
+
+		if ((rc = write_data (info, wp, data)) != 0) {
+			set_msr (msr);
+			return (rc);
+		}
+
+		wp += FLASH_WIDTH;
+	}
+
+	/*
+	 * handle FLASH_WIDTH aligned part
+	 */
+	while (cnt >= FLASH_WIDTH) {
+		*datah = *(ulong *) src;
+		*datal = *(ulong *) (src + 4);
+		if ((rc = write_data (info, wp, data)) != 0) {
+			set_msr (msr);
+			return (rc);
+		}
+		wp += FLASH_WIDTH;
+		cnt -= FLASH_WIDTH;
+		src += FLASH_WIDTH;
+	}
+
+	if (cnt == 0) {
+		set_msr (msr);
+		return (0);
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	*datah = *datal = 0;
+	for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) {
+		char tmp;
+
+		tmp = *src;
+
+		src++;
+
+		if (i >= 4) {
+			*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
+		}
+
+		*datal = (*datal << 8) | tmp;
+
+		--cnt;
+	}
+
+	for (; i < FLASH_WIDTH; ++i, ++cp) {
+		if (i >= 4) {
+			*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
+		}
+
+		*datal = (*datal << 8) | (*(uchar *) cp);
+	}
+
+	rc = write_data (info, wp, data);
+	set_msr (msr);
+
+	return (rc);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_data (flash_info_t * info, ulong dest, ulong * data)
+{
+	vu_long *chip = (vu_long *) (info->start[0]);
+	vu_long *addr = (vu_long *) dest;
+	ulong start;
+	int flag;
+
+	/* Check if Flash is (sufficiently) erased */
+	if (((addr[0] & data[0]) != data[0]) ||
+		((addr[1] & data[1]) != data[1])) {
+		return (2);
+	}
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts ();
+
+	write_via_fpu (&chip[0xaaa], precmd0);
+	write_via_fpu (&chip[0x554], precmd1);
+	write_via_fpu (&chip[0xaaa], cmdprog);
+	write_via_fpu (addr, data);
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts ();
+
+	start = get_timer (0);
+
+	while (((addr[0] & 0x00800080) != (data[0] & 0x00800080)) ||
+	       ((addr[1] & 0x00800080) != (data[1] & 0x00800080))) {
+		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+			write_via_fpu (chip, cmdres);
+			return (1);
+		}
+	}
+
+	write_via_fpu (chip, cmdres);
+
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void write_via_fpu (vu_long * addr, ulong * data)
+{
+	__asm__ __volatile__ ("lfd  1, 0(%0)"::"r" (data));
+	__asm__ __volatile__ ("stfd 1, 0(%0)"::"r" (addr));
+}
+
+/*-----------------------------------------------------------------------
+ */
+static __inline__ unsigned long get_msr (void)
+{
+	unsigned long msr;
+
+	__asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
+
+	return msr;
+}
+
+static __inline__ void set_msr (unsigned long msr)
+{
+	__asm__ __volatile__ ("mtmsr %0"::"r" (msr));
+}
diff --git a/board/sl8245/sl8245.c b/board/sl8245/sl8245.c
new file mode 100644
index 0000000..1a30b4c
--- /dev/null
+++ b/board/sl8245/sl8245.c
@@ -0,0 +1,86 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc824x.h>
+
+int checkboard (void)
+{
+	ulong busfreq  = get_bus_freq(0);
+	char  buf[32];
+
+	printf("Board: SL8245, local bus @ %s MHz\n", strmhz(buf, busfreq));
+	return 0;
+}
+
+long int initdram (int board_type)
+{
+#ifndef CFG_RAMBOOT
+	int              i, cnt;
+	volatile uchar * base= CFG_SDRAM_BASE;
+	volatile ulong * addr;
+	ulong            save[32];
+	ulong            val, ret  = 0;
+
+	for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
+		addr = (volatile ulong *)base + cnt;
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	addr = (volatile ulong *)base;
+	save[i] = *addr;
+	*addr = 0;
+
+	if (*addr != 0) {
+		*addr = save[i];
+		goto Done;
+	}
+
+	for (cnt = 1; cnt < CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) {
+		addr = (volatile ulong *)base + cnt;
+		val = *addr;
+		*addr = save[--i];
+		if (val != ~cnt) {
+			ulong new_bank0_end = cnt * sizeof(long) - 1;
+			ulong mear1  = mpc824x_mpc107_getreg(MEAR1);
+			ulong emear1 = mpc824x_mpc107_getreg(EMEAR1);
+			mear1 =  (mear1  & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
+			emear1 = (emear1 & 0xFFFFFF00) |
+			  ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
+			mpc824x_mpc107_setreg(MEAR1,  mear1);
+			mpc824x_mpc107_setreg(EMEAR1, emear1);
+
+			ret = cnt * sizeof(long);
+			goto Done;
+		}
+	}
+
+	ret = CFG_MAX_RAM_SIZE;
+Done:
+	return ret;
+#else
+	return CFG_MAX_RAM_SIZE;
+#endif
+}
diff --git a/board/sl8245/u-boot.lds b/board/sl8245/u-boot.lds
new file mode 100644
index 0000000..627a53b
--- /dev/null
+++ b/board/sl8245/u-boot.lds
@@ -0,0 +1,128 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/mpc824x/start.o		(.text)
+    lib_ppc/board.o		(.text)
+    lib_ppc/ppcstring.o		(.text)
+    lib_generic/vsprintf.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_generic/zlib.o		(.text)
+
+	. = DEFINED(env_offset) ? env_offset : .;
+    common/environment.o (.text)
+
+	*(.text)
+
+    *(.fixup)
+    *(.got1)
+    . = ALIGN(16);
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+
+  _end = . ;
+  PROVIDE (end = .);
+}
+