Initial revision
diff --git a/board/cogent/serial.c b/board/cogent/serial.c
new file mode 100644
index 0000000..4c20017
--- /dev/null
+++ b/board/cogent/serial.c
@@ -0,0 +1,190 @@
+/*
+ * Simple serial driver for Cogent motherboard serial ports
+ * for use during boot
+ */
+
+#include <common.h>
+#include <board/cogent/serial.h>
+
+#if (CMA_MB_CAPS & CMA_MB_CAP_SERPAR)
+
+#if (defined(CONFIG_8xx) && defined(CONFIG_8xx_CONS_NONE)) || \
+     (defined(CONFIG_8260) && defined(CONFIG_CONS_NONE))
+
+#if CONFIG_CONS_INDEX == 1
+#define CMA_MB_SERIAL_BASE	CMA_MB_SERIALA_BASE
+#elif CONFIG_CONS_INDEX == 2
+#define CMA_MB_SERIAL_BASE	CMA_MB_SERIALB_BASE
+#elif CONFIG_CONS_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_SERIAL_BASE	CMA_MB_SER2A_BASE
+#elif CONFIG_CONS_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_SERIAL_BASE	CMA_MB_SER2B_BASE
+#else
+#error CONFIG_CONS_INDEX must be configured for Cogent motherboard serial
+#endif
+
+int serial_init (void)
+{
+/*  DECLARE_GLOBAL_DATA_PTR; */
+
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    cma_mb_reg_write(&mbsp->ser_ier, 0x00);	/* turn off interrupts */
+    serial_setbrg ();
+    cma_mb_reg_write(&mbsp->ser_lcr, 0x03);	/* 8 data, 1 stop, no parity */
+    cma_mb_reg_write(&mbsp->ser_mcr, 0x03);	/* RTS/DTR */
+    cma_mb_reg_write(&mbsp->ser_fcr, 0x07);	/* Clear & enable FIFOs */
+
+    return (0);
+}
+
+void
+serial_setbrg (void)
+{
+    DECLARE_GLOBAL_DATA_PTR;
+
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+    unsigned int divisor;
+    unsigned char lcr;
+
+    if ((divisor = br_to_div(gd->baudrate)) == 0)
+	divisor = DEFDIV;
+
+    lcr = cma_mb_reg_read(&mbsp->ser_lcr);
+    cma_mb_reg_write(&mbsp->ser_lcr, lcr|0x80);/* Access baud rate(set DLAB)*/
+    cma_mb_reg_write(&mbsp->ser_brl, divisor & 0xff);
+    cma_mb_reg_write(&mbsp->ser_brh, (divisor >> 8) & 0xff);
+    cma_mb_reg_write(&mbsp->ser_lcr, lcr);	/* unset DLAB */
+}
+
+void
+serial_putc(const char c)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    if (c == '\n')
+	serial_putc('\r');
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_THRE) == 0)
+	;
+
+    cma_mb_reg_write(&mbsp->ser_thr, c);
+}
+
+void
+serial_puts(const char *s)
+{
+    while (*s != '\0')
+	serial_putc(*s++);
+}
+
+int
+serial_getc(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) == 0)
+	;
+
+    return ((int)cma_mb_reg_read(&mbsp->ser_rhr) & 0x7f);
+}
+
+int
+serial_tstc(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_SERIAL_BASE;
+
+    return ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) != 0);
+}
+
+#endif /* CONS_NONE */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && \
+    defined(CONFIG_KGDB_NONE)
+
+#if CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
+#error Console and kgdb are on the same serial port - this is not supported
+#endif
+
+#if CONFIG_KGDB_INDEX == 1
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SERIALA_BASE
+#elif CONFIG_KGDB_INDEX == 2
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SERIALB_BASE
+#elif CONFIG_KGDB_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SER2A_BASE
+#elif CONFIG_KGDB_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
+#define CMA_MB_KGDB_SER_BASE	CMA_MB_SER2B_BASE
+#else
+#error CONFIG_KGDB_INDEX must be configured for Cogent motherboard serial
+#endif
+
+void
+kgdb_serial_init(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+    unsigned int divisor;
+
+    if ((divisor = br_to_div(CONFIG_KGDB_BAUDRATE)) == 0)
+	divisor = DEFDIV;
+
+    cma_mb_reg_write(&mbsp->ser_ier, 0x00);	/* turn off interrupts */
+    cma_mb_reg_write(&mbsp->ser_lcr, 0x80);	/* Access baud rate(set DLAB)*/
+    cma_mb_reg_write(&mbsp->ser_brl, divisor & 0xff);
+    cma_mb_reg_write(&mbsp->ser_brh, (divisor >> 8) & 0xff);
+    cma_mb_reg_write(&mbsp->ser_lcr, 0x03);	/* 8 data, 1 stop, no parity */
+    cma_mb_reg_write(&mbsp->ser_mcr, 0x03);	/* RTS/DTR */
+    cma_mb_reg_write(&mbsp->ser_fcr, 0x07);	/* Clear & enable FIFOs */
+
+    printf("[on cma10x serial port B] ");
+}
+
+void
+putDebugChar(int c)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_THRE) == 0)
+	;
+
+    cma_mb_reg_write(&mbsp->ser_thr, c & 0xff);
+}
+
+void
+putDebugStr(const char *str)
+{
+    while (*str != '\0') {
+	if (*str == '\n')
+	    putDebugChar('\r');
+	putDebugChar(*str++);
+    }
+}
+
+int
+getDebugChar(void)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+    while ((cma_mb_reg_read(&mbsp->ser_lsr) & LSR_DR) == 0)
+	;
+
+    return ((int)cma_mb_reg_read(&mbsp->ser_rhr) & 0x7f);
+}
+
+void
+kgdb_interruptible(int yes)
+{
+    cma_mb_serial *mbsp = (cma_mb_serial *)CMA_MB_KGDB_SER_BASE;
+
+    if (yes == 1) {
+	printf("kgdb: turning serial ints on\n");
+	cma_mb_reg_write(&mbsp->ser_ier, 0xf);
+    }
+    else {
+	printf("kgdb: turning serial ints off\n");
+	cma_mb_reg_write(&mbsp->ser_ier, 0x0);
+    }
+}
+
+#endif /* KGDB && KGDB_NONE */
+
+#endif /* CAPS & SERPAR */
diff --git a/board/cu824/cu824.c b/board/cu824/cu824.c
new file mode 100644
index 0000000..20aaea2
--- /dev/null
+++ b/board/cu824/cu824.c
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2001, 2002
+ * 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>
+#include <pci.h>
+
+#define BOARD_REV_REG 0xFE80002B
+
+int checkboard (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	char  revision = *(volatile char *)(BOARD_REV_REG);
+	char  buf[32];
+
+	puts ("Board: CU824 ");
+	printf("Revision %d ", revision);
+	printf("Local Bus at %s MHz\n", strmhz(buf, gd->bus_clk));
+
+	return 0;
+}
+
+long int initdram(int board_type)
+{
+	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;
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
+	  pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
+				       0,
+				       PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
+	{ }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/dnp1110/u-boot.lds b/board/dnp1110/u-boot.lds
new file mode 100644
index 0000000..f4b0ade
--- /dev/null
+++ b/board/dnp1110/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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/sa1100/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/ebony/ebony.c b/board/ebony/ebony.c
new file mode 100644
index 0000000..723fad3
--- /dev/null
+++ b/board/ebony/ebony.c
@@ -0,0 +1,301 @@
+/*
+ *  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
+ *
+ * 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
+ */
+
+
+extern long int spd_sdram (void);
+
+#include <common.h>
+#include "ebony.h"
+#include <asm/processor.h>
+
+#define BOOT_SMALL_FLASH	32	/* 00100000 */
+#define FLASH_ONBD_N		2	/* 00000010 */
+#define FLASH_SRAM_SEL		1	/* 00000001 */
+
+long int fixed_sdram (void);
+
+int board_pre_init (void)
+{
+	uint reg;
+	unsigned char *fpga_base = (unsigned char *) CFG_FPGA_BASE;
+	unsigned char status;
+
+
+	/*--------------------------------------------------------------------
+	 * Setup the external bus controller/chip selects
+	 *-------------------------------------------------------------------*/
+	mtdcr (ebccfga, xbcfg);
+	reg = mfdcr (ebccfgd);
+	mtdcr (ebccfgd, reg | 0x04000000);	/* Set ATC */
+
+	mtebc (pb1ap, 0x02815480);	/* NVRAM/RTC */
+	mtebc (pb1cr, 0x48018000);	/* BA=0x480 1MB R/W 8-bit */
+	mtebc (pb7ap, 0x01015280);	/* FPGA registers */
+	mtebc (pb7cr, 0x48318000);	/* BA=0x483 1MB R/W 8-bit */
+
+	/* read FPGA_REG0  and set the bus controller */
+	status = *fpga_base;
+	if ((status & BOOT_SMALL_FLASH) && !(status & FLASH_ONBD_N)) {
+		mtebc (pb0ap, 0x9b015480);	/* FLASH/SRAM */
+		mtebc (pb0cr, 0xfff18000);	/* BAS=0xfff 1MB R/W 8-bit */
+		mtebc (pb2ap, 0x9b015480);	/* 4MB FLASH */
+		mtebc (pb2cr, 0xff858000);	/* BAS=0xff8 4MB R/W 8-bit */
+	} else {
+		mtebc (pb0ap, 0x9b015480);	/* 4MB FLASH */
+		mtebc (pb0cr, 0xffc58000);	/* BAS=0xffc 4MB R/W 8-bit */
+
+		/* set CS2 if FLASH_ONBD_N == 0 */
+		if (!(status & FLASH_ONBD_N)) {
+			mtebc (pb2ap, 0x9b015480);	/* FLASH/SRAM */
+			mtebc (pb2cr, 0xff818000);	/* BAS=0xff8 4MB R/W 8-bit */
+		}
+	}
+
+	/*--------------------------------------------------------------------
+	 * Setup the interrupt controller polarities, triggers, etc.
+	 *-------------------------------------------------------------------*/
+	mtdcr (uic0sr, 0xffffffff);	/* clear all */
+	mtdcr (uic0er, 0x00000000);	/* disable all */
+	mtdcr (uic0cr, 0x00000009);	/* SMI & UIC1 crit are critical */
+	mtdcr (uic0pr, 0xfffffe13);	/* per ref-board manual */
+	mtdcr (uic0tr, 0x01c00008);	/* per ref-board manual */
+	mtdcr (uic0vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr (uic0sr, 0xffffffff);	/* clear all */
+
+	mtdcr (uic1sr, 0xffffffff);	/* clear all */
+	mtdcr (uic1er, 0x00000000);	/* disable all */
+	mtdcr (uic1cr, 0x00000000);	/* all non-critical */
+	mtdcr (uic1pr, 0xffffe0ff);	/* per ref-board manual */
+	mtdcr (uic1tr, 0x00ffc000);	/* per ref-board manual */
+	mtdcr (uic1vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr (uic1sr, 0xffffffff);	/* clear all */
+
+	return 0;
+}
+
+
+
+int checkboard (void)
+{
+	sys_info_t sysinfo;
+
+	get_sys_info (&sysinfo);
+
+	printf ("Board: IBM 440GP Evaluation Board (Ebony)\n");
+	printf ("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz / 1000000);
+	printf ("\tCPU: %lu MHz\n", sysinfo.freqProcessor / 1000000);
+	printf ("\tPLB: %lu MHz\n", sysinfo.freqPLB / 1000000);
+	printf ("\tOPB: %lu MHz\n", sysinfo.freqOPB / 1000000);
+	printf ("\tEPB: %lu MHz\n", sysinfo.freqEPB / 1000000);
+	return (0);
+}
+
+
+long int initdram (int board_type)
+{
+	long dram_size = 0;
+	extern long spd_sdram (void);
+
+#if defined(CONFIG_SPD_EEPROM)
+	dram_size = spd_sdram ();
+#else
+	dram_size = fixed_sdram ();
+#endif
+	return dram_size;
+}
+
+
+#if defined(CFG_DRAM_TEST)
+int testdram (void)
+{
+	uint *pstart = (uint *) 0x00000000;
+	uint *pend = (uint *) 0x08000000;
+	uint *p;
+
+	for (p = pstart; p < pend; p++)
+		*p = 0xaaaaaaaa;
+
+	for (p = pstart; p < pend; p++) {
+		if (*p != 0xaaaaaaaa) {
+			printf ("SDRAM test fails at: %08x\n", (uint) p);
+			return 1;
+		}
+	}
+
+	for (p = pstart; p < pend; p++)
+		*p = 0x55555555;
+
+	for (p = pstart; p < pend; p++) {
+		if (*p != 0x55555555) {
+			printf ("SDRAM test fails at: %08x\n", (uint) p);
+			return 1;
+		}
+	}
+	return 0;
+}
+#endif
+
+#if !defined(CONFIG_SPD_EEPROM)
+/*************************************************************************
+ *  fixed sdram init -- doesn't use serial presence detect.
+ *
+ *  Assumes:    128 MB, non-ECC, non-registered
+ *              PLB @ 133 MHz
+ *
+ ************************************************************************/
+long int fixed_sdram (void)
+{
+	uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup some default
+	 *------------------------------------------------------------------*/
+	mtsdram (mem_uabba, 0x00000000);	/* ubba=0 (default)             */
+	mtsdram (mem_slio, 0x00000000);		/* rdre=0 wrre=0 rarw=0         */
+	mtsdram (mem_devopt, 0x00000000);	/* dll=0 ds=0 (normal)          */
+	mtsdram (mem_wddctr, 0x00000000);	/* wrcp=0 dcd=0                 */
+	mtsdram (mem_clktr, 0x40000000);	/* clkp=1 (90 deg wr) dcdt=0    */
+
+	/*--------------------------------------------------------------------
+	 * Setup for board-specific specific mem
+	 *------------------------------------------------------------------*/
+	/*
+	 * Following for CAS Latency = 2.5 @ 133 MHz PLB
+	 */
+	mtsdram (mem_b0cr, 0x000a4001);	/* SDBA=0x000 128MB, Mode 3, enabled */
+	mtsdram (mem_tr0, 0x410a4012);	/* WR=2  WD=1 CL=2.5 PA=3 CP=4 LD=2 */
+	/* RA=10 RD=3                       */
+	mtsdram (mem_tr1, 0x8080082f);	/* SS=T2 SL=STAGE 3 CD=1 CT=0x02f   */
+	mtsdram (mem_rtr, 0x08200000);	/* Rate 15.625 ns @ 133 MHz PLB     */
+	mtsdram (mem_cfg1, 0x00000000);	/* Self-refresh exit, disable PM    */
+	udelay (400);			/* Delay 200 usecs (min)            */
+
+	/*--------------------------------------------------------------------
+	 * Enable the controller, then wait for DCEN to complete
+	 *------------------------------------------------------------------*/
+	mtsdram (mem_cfg0, 0x86000000);	/* DCEN=1, PMUD=1, 64-bit           */
+	for (;;) {
+		mfsdram (mem_mcsts, reg);
+		if (reg & 0x80000000)
+			break;
+	}
+
+	return (128 * 1024 * 1024);	/* 128 MB                           */
+}
+#endif	/* !defined(CONFIG_SPD_EEPROM) */
+
+
+/*************************************************************************
+ *  pci_pre_init
+ *
+ *  This routine is called just prior to registering the hose and gives
+ *  the board the opportunity to check things. Returning a value of zero
+ *  indicates that things are bad & PCI initialization should be aborted.
+ *
+ *	Different boards may wish to customize the pci controller structure
+ *	(add regions, override default access routines, etc) or perform
+ *	certain pre-initialization actions.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)
+int pci_pre_init(struct pci_controller * hose )
+{
+    unsigned long strap;
+
+	/*--------------------------------------------------------------------------+
+     *	The ebony board is always configured as the host & requires the
+     *	PCI arbiter to be enabled.
+	 *--------------------------------------------------------------------------*/
+    strap = mfdcr(cpc0_strp1);
+    if( (strap & 0x00100000) == 0 ){
+        printf("PCI: CPC0_STRP1[PAE] not set.\n");
+        return 0;
+    }
+
+    return 1;
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ *  pci_target_init
+ *
+ *	The bootstrap configuration provides default settings for the pci
+ *	inbound map (PIM). But the bootstrap config choices are limited and
+ *	may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller * hose )
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/*--------------------------------------------------------------------------+
+	 * Disable everything
+	 *--------------------------------------------------------------------------*/
+	out32r( PCIX0_PIM0SA, 0 ); /* disable */
+	out32r( PCIX0_PIM1SA, 0 ); /* disable */
+	out32r( PCIX0_PIM2SA, 0 ); /* disable */
+	out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */
+
+	/*--------------------------------------------------------------------------+
+	 * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 strapping
+     * options to not support sizes such as 128/256 MB.
+	 *--------------------------------------------------------------------------*/
+	out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE );
+	out32r( PCIX0_PIM0LAH, 0 );
+	out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 );
+
+	out32r( PCIX0_BAR0, 0 );
+
+	/*--------------------------------------------------------------------------+
+	 * Program the board's subsystem id/vendor id
+	 *--------------------------------------------------------------------------*/
+    out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+    out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID );
+
+	out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY );
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+
+/*************************************************************************
+ *  is_pci_host
+ *
+ *	This routine is called to determine if a pci scan should be
+ *	performed. With various hardware environments (especially cPCI and
+ *	PPMC) it's insufficient to depend on the state of the arbiter enable
+ *	bit in the strap register, or generic host/adapter assumptions.
+ *
+ *	Rather than hard-code a bad assumption in the general 440 code, the
+ *	440 pci code requires the board to decide at runtime.
+ *
+ *	Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+int is_pci_host(struct pci_controller *hose)
+{
+    /* The ebony board is always configured as host. */
+    return(1);
+}
+#endif /* defined(CONFIG_PCI) */
diff --git a/board/ebony/init.S b/board/ebony/init.S
new file mode 100644
index 0000000..3ae93d6
--- /dev/null
+++ b/board/ebony/init.S
@@ -0,0 +1,98 @@
+/*
+*  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
+*
+* 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 <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID   0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K	    0x00000000
+#define SZ_4K	    0x00000010
+#define SZ_16K	    0x00000020
+#define SZ_64K	    0x00000030
+#define SZ_256K	    0x00000040
+#define SZ_1M	    0x00000050
+#define SZ_16M	    0x00000070
+#define SZ_256M	    0x00000090
+
+/* Storage attributes */
+#define SA_W	    0x00000800	    /* Write-through */
+#define SA_I	    0x00000400	    /* Caching inhibited */
+#define SA_M	    0x00000200	    /* Memory coherence */
+#define SA_G	    0x00000100	    /* Guarded */
+#define SA_E	    0x00000080	    /* Endian */
+
+/* Access control */
+#define AC_X	    0x00000024	    /* Execute */
+#define AC_W	    0x00000012	    /* Write */
+#define AC_R	    0x00000009	    /* Read */
+
+/* Some handy macros */
+
+#define EPN(e)		((e) & 0xfffffc00)
+#define TLB0(epn,sz)	( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn)	( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a)		( (a)&0x00000fbf )
+
+#define tlbtab_start\
+	mflr    r1  ;\
+	bl 0f	    ;
+
+#define tlbtab_end\
+	.long 0, 0, 0	;   \
+0:	mflr    r0	;   \
+	mtlr    r1	;   \
+	blr		;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+	.long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ *  Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+    .section .bootpg,"ax"
+    .globl tlbtab
+
+tlbtab:
+    tlbtab_start
+    tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+    tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+    tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
+    tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I )
+    tlbtab_end
+
+
diff --git a/board/eltec/bab7xx/asm_init.S b/board/eltec/bab7xx/asm_init.S
new file mode 100644
index 0000000..d739b81
--- /dev/null
+++ b/board/eltec/bab7xx/asm_init.S
@@ -0,0 +1,1487 @@
+/*
+ * (C) Copyright 2001 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * ELTEC BAB PPC RAM initialization
+ *
+ * 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 <mpc75x.h>
+#include <mpc106.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+/*
+ * This following contains the entry code for the initialization code
+ * for the MPC 106, a PCI Bridge/Memory Controller.
+ * Register usage:
+ * r0  = ramtest scratch register, toggleError loop counter
+ * r1  = 0xfec0 0cf8 CONFIG_ADDRESS
+ * r2  = 0xfee0 0cfc CONFIG_DATA
+ * r3  = scratch register, subroutine argument and return value, ramtest size
+ * r4  = scratch register, spdRead clock mask, OutHex loop count
+ * r5  = ramtest scratch register
+ * r6  = toggleError 1st value, spdRead port mask
+ * r7  = toggleError 2nd value, ramtest scratch register,
+ *       spdRead scratch register (0x00)
+ * r8  = ramtest scratch register, spdRead scratch register (0x80)
+ * r9  = ramtest scratch register, toggleError loop end, OutHex digit
+ * r10 = ramtest scratch register, spdWriteByte parameter,
+ *        spdReadByte return value, printf pointer to COM1
+ * r11 = startType
+ * r12 = ramtest scratch register, spdRead data mask
+ * r13 = pointer to message block
+ * r14 = pointer to GOT
+ * r15 = scratch register, SPD save
+ * r16 = bank0 size, total memory size
+ * r17 = bank1 size
+ * r18 = bank2 size
+ * r19 = bank3 size
+ * r20 = MCCR1, MSAR1
+ * r21 = MCCR3, MEAR1
+ * r22 = MCCR4, MBER
+ * r23 = EMSAR1
+ * r24 = EMEAR1
+ * r25 = save link register 1st level
+ * r26 = save link register 2nd level
+ * r27 = save link register 3rd level
+ * r30 = pointer to GPIO for spdRead
+ */
+
+
+.globl board_asm_init
+board_asm_init:
+/*
+ * setup pointer to message block
+ */
+    mflr    r25             /* save away link register */
+    bl      get_lnk_reg     /* r3=addr of next instruction */
+    subi    r4, r3, 8       /* r4=board_asm_init addr */
+    addi    r13, r4, (MessageBlock-board_asm_init)
+/*
+ * dcache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, HID0_DCE
+    andc    r3, r3, r4
+    mr      r2, r3
+    ori     r3, r3, HID0_DCI
+    sync
+    mtspr   HID0, r3
+    mtspr   HID0, r2
+    isync
+    sync
+/*
+ * icache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, 0
+    ori     r4, r4, HID0_ICE
+    andc    r3, r3, r4
+    sync
+    mtspr   HID0, r3
+/*
+ * invalidate caches
+ */
+    ori     r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
+    or      r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    andc    r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    isync
+/*
+ * icache_enable
+ */
+    mfspr   r3, HID0
+    ori     r3, r3, (HID0_ICE | HID0_ICFI)
+    sync
+    mtspr   HID0, r3
+
+    lis     r1, 0xfec0
+    ori     r1, r1, 0x0cf8
+    lis     r2, 0xfee0
+    ori     r2, r2, 0xcfc
+
+#ifdef CFG_ADDRESS_MAP_A
+/*
+ * Switch to address map A if necessary.
+ */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, PCI_PICR1
+    stwbrx  r3, 0, r1
+    sync
+    lwbrx   r4, 0, r2
+    sync
+    lis     r0, PICR1_XIO_MODE@h
+    ori     r0, r0, PICR1_XIO_MODE@l
+    andc    r4, r4, r0
+    lis     r0, PICR1_ADDRESS_MAP@h
+    ori     r0, r0, PICR1_ADDRESS_MAP@l
+    or      r4, r4, r0
+    stwbrx  r4, 0, r2
+    sync
+#endif
+
+/*
+ * Do the init for the SIO.
+ */
+    bl      .sioInit
+
+    addi    r3, r13, (MinitLogo-MessageBlock)
+    bl      Printf
+
+    addi    r3, r13, (Mspd01-MessageBlock)
+    bl      Printf
+/*
+ * Memory cofiguration using SPD information stored on the SODIMMs
+ */
+    li      r17, 0
+    li      r18, 0
+    li      r19, 0
+
+    li      r3, 0x0002          /* get RAM type from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    bne     noSpdError
+
+    addi    r3, r13, (Mfail-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x00
+    b       toggleError         /* fail - loop forever */
+
+noSpdError:
+    mr      r15, r3             /* save r3 */
+
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+
+    cmpli   0, 0, r15, 0x0001   /* FPM ? */
+    beq     configFPM
+    cmpli   0, 0, r15, 0x0002   /* EDO ? */
+    beq     configEDO
+    cmpli   0, 0, r15, 0x0004   /* SDRAM ? */
+    beq     configSDRAM
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x01
+    b       toggleError         /* fail - loop forever */
+
+configSDRAM:
+    addi    r3, r13, (MsdRam-MessageBlock)
+    bl      Printf
+/*
+ * set the Memory Configuration Reg. 1
+ */
+    li      r3, 0x001f          /* get bank size from spd bank0/1 */
+    bl      spdRead
+
+    andi.   r3, r3, 0x0038
+    beq     SD16MB2B
+
+    li      r3, 0x0011          /* get number of internal banks */
+                                /* from spd for bank0/1 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x02
+    beq     SD64MB2B
+
+    cmpli   0, 0, r3, 0x04
+    beq     SD64MB4B
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x02
+    b       toggleError         /* fail - loop forever */
+
+SD64MB2B:
+    li      r20, 0x0005         /* 64-Mbit SDRAM 2 banks */
+    b       SDRow2nd
+
+SD64MB4B:
+    li      r20, 0x0000         /* 64-Mbit SDRAM 4 banks */
+    b       SDRow2nd
+
+SD16MB2B:
+    li      r20, 0x000f         /* 16-Mbit SDRAM 2 banks */
+
+SDRow2nd:
+    li      r3, 0x0102          /* get RAM type spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x0004
+    bne     S2D64MB4B           /* bank2/3 isn't present or no SDRAM */
+
+    li      r3, 0x011f          /* get bank size from spd bank2/3 */
+    bl      spdRead
+
+    andi.   r3, r3, 0x0038
+    beq     S2D16MB2B
+/*
+ * set the Memory Configuration Reg. 2
+ */
+    li      r3, 0x0111          /* get number of internal banks */
+                                /* from spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x02
+    beq     S2D64MB2B
+
+    cmpli   0, 0, r3, 0x04
+    beq     S2D64MB4B
+
+    li      r6, 0xe0            /* error codes in r6 and r7 */
+    li      r7, 0x03
+    b       toggleError         /* fail - loop forever */
+
+S2D64MB2B:
+    ori     r20, r20, 0x0050    /* 64-Mbit SDRAM 2 banks */
+    b       S2D64MB4B
+
+S2D16MB2B:
+    ori     r20, r20, 0x00f0    /* 16-Mbit SDRAM 2 banks */
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+S2D64MB4B:
+    lis     r21, 0x8630         /* BSTOPRE = 0x80, REFREC = 6, */
+                                /* RDLAT = 3 */
+
+/*
+ * set the Memory Configuration Reg. 4
+ */
+    lis     r22, 0x2430         /* PRETOACT = 2, ACTOPRE = 4, */
+                                /* WCBUF = 1, RCBUF = 1 */
+    ori     r22, r22, 0x2220    /* SDMODE = 0x022, ACTORW = 2 */
+
+/*
+ * get the size of bank 0-3
+ */
+    li      r3, 0x001f          /* get bank size from spd bank0/1 */
+    bl      spdRead
+
+    rlwinm  r16, r3, 2, 24, 29  /* calculate size in MByte */
+                                /* (128 MB max.) */
+
+    li      r3, 0x0005          /* get number of banks from spd */
+                                /* for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     SDRAMnobank1
+
+    mr      r17, r16
+
+SDRAMnobank1:
+    addi    r3, r13, (Mspd23-MessageBlock)
+    bl      Printf
+
+    li      r3, 0x0102          /* get RAM type spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x0001    /* FPM ? */
+    bne     noFPM23             /* handle as EDO */
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MfpmRam-MessageBlock)
+    bl      Printf
+    b       configRAMcommon
+noFPM23:
+    cmpli   0, 0, r3, 0x0002    /* EDO ? */
+    bne     noEDO23
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MedoRam-MessageBlock)
+    bl      Printf
+    b       configRAMcommon
+noEDO23:
+    cmpli   0, 0, r3, 0x0004    /* SDRAM ? */
+    bne    noSDRAM23
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MsdRam-MessageBlock)
+    bl      Printf
+    b       configSDRAM23
+noSDRAM23:
+    addi    r3, r13, (Mna-MessageBlock)
+    bl      Printf
+    b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
+
+configSDRAM23:
+    li      r3, 0x011f          /* get bank size from spd bank2/3 */
+    bl      spdRead
+
+    rlwinm  r18, r3, 2, 24, 29  /* calculate size in MByte */
+                                /* (128 MB max.) */
+
+    li      r3, 0x0105          /* get number of banks from */
+                                /* spd bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     SDRAMnobank3
+
+    mr    r19, r18
+
+SDRAMnobank3:
+    b       configRAMcommon
+
+configFPM:
+    addi    r3, r13, (MfpmRam-MessageBlock)
+    bl      Printf
+    b       configEDO0
+/*
+ * set the Memory Configuration Reg. 1
+ */
+configEDO:
+    addi    r3, r13, (MedoRam-MessageBlock)
+    bl      Printf
+configEDO0:
+    lis     r20, MCCR1_TYPE_EDO@h
+
+getSpdRowBank01:
+    li      r3, 0x0003          /* get number of row bits from */
+                                /* spd from bank0/1 */
+    bl      spdRead
+    ori     r20, r20, (MCCR1_BK0_9BITS | MCCR1_BK1_9BITS)
+    cmpli   0, 0, r3, 0x0009    /* bank0 -  9 row bits */
+    beq     getSpdRowBank23
+
+    ori     r20, r20, (MCCR1_BK0_10BITS | MCCR1_BK1_10BITS)
+    cmpli   0, 0, r3, 0x000a    /* bank0 -  10 row bits */
+    beq     getSpdRowBank23
+
+    ori     r20, r20, (MCCR1_BK0_11BITS | MCCR1_BK1_11BITS)
+    cmpli   0, 0, r3, 0x000b    /* bank0 -  11 row bits */
+    beq     getSpdRowBank23
+
+    ori     r20, r20, (MCCR1_BK0_12BITS | MCCR1_BK1_12BITS)
+    cmpli   0, 0, r3, 0x000c    /* bank0 -  12 row bits */
+    beq     getSpdRowBank23
+
+    cmpli   0, 0, r3, 0x000d    /* bank0 -  13 row bits */
+    beq     getSpdRowBank23
+
+    li      r6, 0xe0            /* error codes in r6 and r7 */
+    li      r7, 0x10
+    b       toggleError         /* fail - loop forever */
+
+getSpdRowBank23:
+    li     r3, 0x0103           /* get number of row bits from */
+                                /* spd for bank2/3 */
+    bl      spdRead
+
+    ori     r20, r20, (MCCR1_BK2_9BITS | MCCR1_BK3_9BITS)
+    cmpli   0, 0, r3, 0x0009    /* bank0 -  9 row bits */
+    beq     writeRowBits
+
+    ori     r20, r20, (MCCR1_BK2_10BITS | MCCR1_BK3_10BITS)
+    cmpli   0, 0, r3, 0x000a    /* bank0 -  10 row bits */
+    beq     writeRowBits
+
+    ori     r20, r20, (MCCR1_BK2_11BITS | MCCR1_BK3_11BITS)
+    cmpli   0, 0, r3, 0x000b    /* bank0 -  11 row bits */
+    beq     writeRowBits
+
+    ori     r20, r20, (MCCR1_BK2_12BITS | MCCR1_BK3_12BITS)
+
+/*
+ * set the Memory Configuration Reg. 3
+ */
+writeRowBits:
+    lis     r21, 0x000a         /* CPX = 1, RAS6P = 4 */
+    ori     r21, r21, 0x2293    /* CAS5 = 2, CP4 = 1, */
+                                /* CAS3 = 2, RCD2 = 2, RP = 3 */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+    lis     r22, 0x0010         /* all SDRAM parameter 0, */
+                                /* WCBUF flow through, */
+                                /* RCBUF registered */
+/*
+ * get the size of bank 0-3
+ */
+    li      r3, 0x0003          /* get row bits from spd  bank0/1 */
+    bl      spdRead
+
+    li      r16, 0              /* bank size is: */
+                                /* (8*2^row*2^column)/0x100000 MB */
+    ori     r16, r16, 0x8000
+    rlwnm   r16, r16, r3, 0, 31
+
+    li      r3, 0x0004          /* get column bits from spd bank0/1 */
+    bl      spdRead
+
+    rlwnm   r16, r16, r3, 0, 31
+
+    li      r3, 0x0005          /* get number of banks from */
+                                /* spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     EDOnobank1
+
+    mr      r17, r16
+
+EDOnobank1:
+    addi    r3, r13, (Mspd23-MessageBlock)
+    bl      Printf
+
+    li      r3, 0x0102          /* get RAM type spd for bank2/3 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x0001    /* FPM ? */
+    bne     noFPM231            /* handle as EDO */
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MfpmRam-MessageBlock)
+    bl      Printf
+    b       EDObank2
+noFPM231:
+    cmpli   0, 0, r3, 0x0002    /* EDO ? */
+    bne     noEDO231
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MedoRam-MessageBlock)
+    bl      Printf
+    b       EDObank2
+noEDO231:
+    cmpli   0, 0, r3, 0x0004    /* SDRAM ? */
+    bne     noSDRAM231
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+    addi    r3, r13, (MsdRam-MessageBlock)
+    bl      Printf
+    b       configRAMcommon
+noSDRAM231:
+    addi    r3, r13, (Mfail-MessageBlock)
+    bl      Printf
+    b       configRAMcommon     /* bank2/3 isn't present or no SDRAM */
+
+EDObank2:
+    li      r3, 0x0103          /* get row bits from spd for bank2/3 */
+    bl      spdRead
+
+    li      r18, 0              /* bank size is: */
+                                /* (8*2^row*2^column)/0x100000 MB */
+    ori     r18, r18, 0x8000
+    rlwnm   r18, r18, r3, 0, 31
+
+    li      r3, 0x0104          /* get column bits from spd bank2/3 */
+    bl      spdRead
+
+    rlwnm   r18, r18, r3, 0, 31
+
+    li      r3, 0x0105          /* get number of banks from */
+                                /* spd for bank2/3 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     configRAMcommon
+
+    mr      r19, r18
+
+configRAMcommon:
+    lis     r1, MPC106_REG_ADDR@h
+    ori     r1, r1, MPC106_REG_ADDR@l
+    lis     r2, MPC106_REG_DATA@h
+    ori     r2, r2, MPC106_REG_DATA@l
+
+    li      r0, 0
+
+/*
+ * If we are already running in RAM (debug mode), we should
+ * NOT reset the MEMGO flag. Otherwise we will stop all memory
+ * accesses.
+ */
+#ifdef IN_RAM
+    lis     r4, MCCR1_MEMGO@h
+    ori     r4, r4, MCCR1_MEMGO@l
+    or      r20, r20, r4
+#endif
+
+/*
+ * set the Memory Configuration Reg. 1
+ */
+    lis     r3, MPC106_REG@h        /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
+    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+    eieio                           /* make sure mem. access is complete */
+    stwbrx  r20, r0, r2             /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 3
+ */
+    lis     r3, MPC106_REG@h        /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR3    /* register number 0xf8 */
+    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+    eieio                           /* make sure mem. access is complete */
+    stwbrx    r21, r0, r2           /* write data to CONFIG_DATA */
+/*
+ * set the Memory Configuration Reg. 4
+ */
+    lis     r3, MPC106_REG@h        /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR4    /* register number 0xfc */
+    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+    eieio                           /* make sure mem. access is complete */
+    stwbrx  r22, r0, r2             /* write data to CONFIG_DATA */
+/*
+ * set the memory boundary registers for bank 0-3
+ */
+    li      r20, 0
+    li      r23, 0
+    li      r24, 0
+    subi    r21, r16, 1         /* calculate end address bank0 */
+    li      r22, (MBER_BANK0)
+
+    cmpi    0, 0, r17, 0        /* bank1 present ? */
+    beq     nobank1
+
+    rlwinm  r3, r16, 8, 16, 23  /* calculate start address of bank1 */
+    or      r20, r20, r3
+    add     r16, r16, r17       /* add to total memory size */
+    subi    r3, r16, 1          /* calculate end address of bank1 */
+    rlwinm  r3, r3, 8, 16, 23
+    or      r21, r21, r3
+    ori     r22, r22, (MBER_BANK1)      /* enable bank1 */
+    b       bank2
+
+nobank1:
+    ori     r23, r23, 0x0300    /* set bank1 start to unused area */
+    ori     r24, r24, 0x0300    /* set bank1 end to unused area */
+
+bank2:
+    cmpi    0, 0, r18, 0        /* bank2 present ? */
+    beq     nobank2
+
+    andi.   r3, r16, 0x00ff     /* calculate start address of bank2 */
+    andi.   r4, r16, 0x0300
+    rlwinm  r3, r3, 16, 8, 15
+    or      r20, r20, r3
+    rlwinm  r3, r4, 8, 8, 15
+    or      r23, r23, r3
+    add     r16, r16, r18       /* add to total memory size */
+    subi    r3, r16, 1          /* calculate end address of bank2 */
+    andi.   r4, r3, 0x0300
+    andi.   r3, r3, 0x00ff
+    rlwinm  r3, r3, 16, 8, 15
+    or      r21, r21, r3
+    rlwinm  r3, r4, 8, 8, 15
+    or      r24, r24, r3
+    ori     r22, r22, (MBER_BANK2)    /* enable bank2 */
+    b       bank3
+
+nobank2:
+    lis     r3, 0x0003
+    or      r23, r23, r3        /* set bank2 start to unused area */
+    or      r24, r24, r3        /* set bank2 end to unused area */
+
+bank3:
+    cmpi    0, 0, r19, 0        /* bank3 present ? */
+    beq     nobank3
+
+    andi.   r3, r16, 0x00ff     /* calculate start address of bank3 */
+    andi.   r4, r16, 0x0300
+    rlwinm  r3, r3, 24, 0, 7
+    or      r20, r20, r3
+    rlwinm  r3, r4, 16, 0, 7
+    or      r23, r23, r3
+    add     r16, r16, r19       /* add to total memory size */
+    subi    r3, r16, 1          /* calculate end address of bank3 */
+    andi.   r4, r3, 0x0300
+    andi.   r3, r3, 0x00ff
+    rlwinm  r3, r3, 24, 0, 7
+    or      r21, r21, r3
+    rlwinm  r3, r4, 16, 0, 7
+    or      r24, r24, r3
+    ori     r22, r22, (MBER_BANK3)    /* enable bank3 */
+    b       writebound
+
+nobank3:
+    lis     r3, 0x0300
+    or      r23, r23, r3        /* set bank3 start to unused area */
+    or      r24, r24, r3        /* set bank3 end to unused area */
+
+writebound:
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MSAR1    /* register number 0x80 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r20, r0, r2         /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MEAR1    /* register number 0x90 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r21, r0, r2         /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMSAR1    /* register number 0x88 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r23, r0, r2         /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMEAR1    /* register number 0x98 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r24, r0, r2         /* write data to CONFIG_DATA */
+
+/*
+ * set boundaries of unused banks to unused address space
+ */
+    lis     r4, 0x0303
+    ori     r4, r4, 0x0303      /* bank 4-7 start and end adresses */
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMSAR2    /* register number 0x8C */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_EMEAR2    /* register number 0x9C */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */
+
+/*
+ * set the Memory Configuration Reg. 2
+ */
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR2    /* register number 0xf4 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+
+    li      r3, 0x000c          /* get refresh from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    bne     common1
+
+    li      r6, 0xe0            /* error codes in r6 and r7  */
+    li      r7, 0x20
+    b       toggleError         /* fail - loop forever */
+
+common1:
+    andi.   r15, r3, 0x007f     /* mask selfrefresh bit */
+    li      r3, 0x010c          /* get refresh from spd for bank2/3 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    beq     common2
+    andi.   r3, r3, 0x007f      /* mask selfrefresh bit */
+    cmp     0, 0, r3, r15       /* find the lower */
+    blt     common3
+
+common2:
+    mr      r3, r15
+
+common3:
+    li      r4, 0x1010          /* refesh cycle 1028 clocks */
+                                /*  left shifted 2 */
+    cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x0808          /* refesh cycle 514 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x2020          /* refesh cycle 2056 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x4040          /* refesh cycle 4112 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0004    /* 62.5 us ? */
+    beq     writeRefresh
+
+    li      r4, 0
+    ori     r4, r4, 0x8080      /* refesh cycle 8224 clocks */
+                                /* left shifted 2 */
+    cmpli   0, 0, r3, 0x0005    /* 125 us ? */
+    beq     writeRefresh
+
+    li      r6, 0xe0            /* error codes in r6 and r7 */
+    li      r7, 0x21
+    b       toggleError         /* fail - loop forever */
+
+writeRefresh:
+    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */
+
+/*
+ * DRAM BANKS SHOULD BE ENABLED
+ */
+    addi    r3, r13, (Mactivate-MessageBlock)
+    bl      Printf
+    mr      r3, r16
+    bl      OutDec
+    addi    r3, r13, (Mmbyte-MessageBlock)
+    bl      Printf
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MBER /* register number 0xa0 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+    stb     r22, 0(r2)          /* write data to CONFIG_DATA */
+    li      r8, 0x63            /* PGMAX = 99 */
+    stb     r8, 3(r2)           /* write data to CONFIG_DATA */
+
+/*
+ *  DRAM SHOULD NOW BE CONFIGURED AND ENABLED
+ *  MUST WAIT 200us BEFORE ACCESSING
+ */
+    li      r0, 0x7800
+    mtctr   r0
+
+wait200us:
+    bdnz    wait200us
+
+    lis     r3, MPC106_REG@h    /* start building new reg number */
+    ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
+    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
+    eieio                       /* make sure mem. access is complete */
+
+    lwbrx   r4, r0, r2          /* load r4 from CONFIG_DATA */
+
+    lis     r0, MCCR1_MEMGO@h   /* MEMGO=1 */
+    ori     r0, r0, MCCR1_MEMGO@l
+    or      r4, r4, r0          /* set the MEMGO bit */
+    stwbrx  r4, r0, r2          /* write mdfd data to CONFIG_DATA */
+
+    li      r0, 0x7000
+    mtctr   r0
+
+wait8ref:
+    bdnz    wait8ref
+
+    addi    r3, r13, (Mok-MessageBlock)
+    bl      Printf
+
+    mtlr    r25
+    blr
+
+/*
+ * Infinite loop called in case of an error during RAM initialisation.
+ * error codes in r6 and r7.
+ */
+toggleError:
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError1:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError1
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError2:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError2
+    b       toggleError
+
+
+/******************************************************************************
+ * This function performs a basic initialisation of the superio chip
+ * to enable basic console output and SPD access during RAM initialisation.
+ *
+ * Upon completion, SIO resource registers are mapped as follows:
+ * Resource     Enabled         Address
+ * UART1        Yes             3F8-3FF COM1
+ * UART2        Yes             2F8-2FF COM2
+ * GPIO         Yes             220-227
+ */
+.set    SIO_LUNINDEX, 0x07      /* SIO LUN index register */
+.set    SIO_CNFG1, 0x21         /* SIO configuration #1 register */
+.set    SIO_PCSCI, 0x23         /* SIO PCS configuration index reg */
+.set    SIO_PCSCD, 0x24         /* SIO PCS configuration data reg */
+.set    SIO_ACTIVATE, 0x30      /* SIO activate register */
+.set    SIO_IOBASEHI, 0x60      /* SIO I/O port base address, 15:8 */
+.set    SIO_IOBASELO, 0x61      /* SIO I/O port base address, 7:0 */
+.set    SIO_LUNENABLE, 0x01     /* SIO LUN enable */
+
+.sioInit:
+    mfspr   r7, 8               /* save link register */
+
+.sioInit_87308:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+    lis     r6, CFG_ISA_IO@h
+    ori     r6, r6, CFG_ISA_IO@l
+
+/*
+ * Set offset to base address for config registers.
+ */
+#if defined(CFG_NS87308_BADDR_0x)
+    addi    r4, r0, 0x0279
+#elif defined(CFG_NS87308_BADDR_10)
+    addi    r4, r0, 0x015C
+#elif defined(CFG_NS87308_BADDR_11)
+    addi    r4, r0, 0x002E
+#endif
+    add     r6, r6, r4          /* add offset to base */
+    or      r3, r6, r6          /* make a copy */
+
+/*
+ * PMC (LUN 8)
+ */
+    addi    r4, r0, SIO_LUNINDEX    /* select PMC LUN */
+    addi    r5, r0, 0x8
+    bl      .sio_bw
+    addi    r4, r0, SIO_IOBASEHI    /* initialize PMC address to 0x460 */
+    addi    r5, r0, 0x04
+    bl      .sio_bw
+    addi    r4, r0, SIO_IOBASELO
+    addi    r5, r0, 0x60
+    bl      .sio_bw
+    addi    r4, r0, SIO_ACTIVATE    /* enable PMC */
+    addi    r5, r0, SIO_LUNENABLE
+    bl      .sio_bw
+
+    lis     r8, CFG_ISA_IO@h
+    ori     r8, r8, 0x0460
+    li      r9, 0x03
+    stb     r9, 0(r8)               /* select PMC2 register */
+    eieio
+    li      r9, 0x00
+    stb     r9, 1(r8)               /* SuperI/O clock src: 24MHz via X1 */
+    eieio
+
+/*
+ * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
+ */
+    addi    r4, r0, SIO_LUNINDEX    /* select COM1 LUN */
+    addi    r5, r0, 0x6
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASEHI    /* initialize COM1 address to 0x3F8 */
+    addi    r5, r0, 0x03
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASELO
+    addi    r5, r0, 0xF8
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_ACTIVATE    /* enable COM1 */
+    addi    r5, r0, SIO_LUNENABLE
+    bl      .sio_bw
+
+/*
+ * Init COM1 for polled output
+ */
+    lis     r8, CFG_ISA_IO@h
+    ori     r8, r8, 0x03f8
+    li      r9, 0x00
+    stb     r9, 1(r8)           /* int disabled */
+    eieio
+    li      r9, 0x00
+    stb     r9, 4(r8)           /* modem ctrl */
+    eieio
+    li      r9, 0x80
+    stb     r9, 3(r8)           /* link ctrl, bank select */
+    eieio
+    li      r9, 115200/CONFIG_BAUDRATE
+    stb     r9, 0(r8)           /* baud rate (LSB)*/
+    eieio
+    rotrwi  r9, r9, 8
+    stb     r9, 1(r8)           /* baud rate (MSB) */
+    eieio
+    li      r9, 0x03
+    stb     r9, 3(r8)           /* 8 data bits, 1 stop bit, */
+                                /* no parity */
+    eieio
+    li      r9, 0x0b
+    stb     r9, 4(r8)           /* enable the receiver and transmitter */
+    eieio
+
+waitEmpty:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty
+    li      r9, 0x47
+    stb     r9, 3(r8)           /* send break, 8 data bits, */
+                                /* 2 stop bits, no parity */
+    eieio
+
+    lis     r0, 0x0001
+    mtctr   r0
+
+waitCOM1:
+    lwz     r0, 5(r8)           /* load from port for delay */
+    bdnz    waitCOM1
+
+waitEmpty1:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty1
+    li      r9, 0x07
+    stb     r9, 3(r8)           /* 8 data bits, 2 stop bits, */
+                                /* no parity */
+    eieio
+
+/*
+ * GPIO (LUN 7)
+ */
+    addi    r4, r0, SIO_LUNINDEX    /* select GPIO LUN */
+    addi    r5, r0, 0x7
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASEHI    /* initialize GPIO address to 0x220 */
+    addi    r5, r0, 0x02
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_IOBASELO
+    addi    r5, r0, 0x20
+    bl      .sio_bw
+
+    addi    r4, r0, SIO_ACTIVATE    /* enable GPIO */
+    addi    r5, r0, SIO_LUNENABLE
+    bl      .sio_bw
+
+.sioInit_done:
+
+/*
+ * Get base addr of ISA I/O space
+ */
+    lis     r3, CFG_ISA_IO@h
+    ori     r3, r3, CFG_ISA_IO@l
+
+    addi    r3, r3, 0x015C      /* adjust to superI/O 87308 base */
+    or      r6, r3, r3          /* make a copy */
+/*
+ * CS0
+ */
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x01
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x76
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x02
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x40
+    bl      .sio_bw
+/*
+ * CS1
+ */
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x05
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x05
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x70
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x06
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x1C
+    bl      .sio_bw
+/*
+ * CS2
+ */
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x08
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x00
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x09
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x71
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
+    addi    r5, r0, 0x0A
+    bl      .sio_bw
+    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
+    addi    r5, r0, 0x1C
+    bl      .sio_bw
+
+    mtspr   8, r7               /* restore link register */
+    bclr    20, 0               /* return to caller */
+
+/*
+ * this function writes a register to the SIO chip
+ */
+.sio_bw:
+    stb     r4, 0(r3)           /* write index register with register offset */
+    eieio
+    sync
+    stb     r5, 1(r3)           /* 1st write */
+    eieio
+    sync
+    stb     r5, 1(r3)           /* 2nd write */
+    eieio
+    sync
+    bclr    20, 0               /* return to caller */
+/*
+ * this function reads a register from the SIO chip
+ */
+.sio_br:
+    stb     r4, 0(r3)           /* write index register with register offset */
+    eieio
+    sync
+    lbz     r3, 1(r3)           /* retrieve specified reg offset contents */
+    eieio
+    sync
+    bclr    20, 0               /* return to caller */
+
+/*
+ * Print a message to COM1 in polling mode
+ * r10=COM1 port, r3=(char*)string
+ */
+.globl Printf
+Printf:
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+
+WaitChr:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, WaitChr        /* wait till empty */
+    lbzx    r0, r0, r3          /* get char */
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addi    r3, r3, 1           /* next char */
+    lbzx    r0, r0, r3          /* get char */
+    cmpwi   cr1, r0, 0          /* end of string ? */
+    bne     cr1, WaitChr
+    blr
+
+/*
+ * Print 8/4/2 digits hex value to COM1 in polling mode
+ * r10=COM1 port, r3=val
+ */
+OutHex2:
+    li      r9, 4               /* shift reg for 2 digits */
+    b       OHstart
+OutHex4:
+    li      r9, 12              /* shift reg for 4 digits */
+    b       OHstart
+    .globl OutHex
+OutHex:
+    li      r9, 28              /* shift reg for 8 digits */
+OHstart:
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+OutDig:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDig
+    sraw    r0, r3, r9
+    clrlwi  r0, r0, 28
+    cmpwi   cr1, r0, 9
+    ble     cr1, digIsNum
+    addic   r0, r0, 55
+    b       nextDig
+digIsNum:
+    addic   r0, r0, 48
+nextDig:
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addic.  r9, r9, -4
+    bge     OutDig
+    blr
+/*
+ * Print 3 digits hdec value to COM1 in polling mode
+ * r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch
+ */
+.globl OutDec
+OutDec:
+    li      r6, 10
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r9 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r9, r10, r3
+
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r8 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r8, r10, r3
+
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r7 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r7, r10, r3
+
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+
+    or.     r7, r7, r7
+    bne     noblank1
+    li      r3, 0x20
+    b       OutDec4
+
+noblank1:
+    addi    r3, r7, 48          /* convert to ASCII */
+
+OutDec4:
+    lbz     r0, 0(r13)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec4
+    stb     r3, 0(r10)          /* x00 to transmit */
+    eieio
+
+    or.     r7, r7, r8
+    beq     OutDec5
+
+    addi    r3, r8, 48          /* convert to ASCII */
+OutDec5:
+    lbz     r0, 0(r13)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec5
+    stb     r3, 0(r10)          /* x0  to transmit */
+    eieio
+
+    addi    r3, r9, 48          /* convert to ASCII */
+OutDec6:
+    lbz     r0, 0(r13)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec6
+    stb     r3, 0(r10)          /* x   to transmit */
+    eieio
+    blr
+/*
+ * Print a char to COM1 in polling mode
+ * r10=COM1 port, r3=char
+ */
+.globl    OutChr
+OutChr:
+    lis     r10, CFG_ISA_IO@h   /* COM1 port */
+    ori     r10, r10, 0x03f8
+
+OutChr1:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutChr1        /* wait till empty */
+    stb     r3, 0(r10)          /* write to transmit reg */
+    eieio
+    blr
+/*
+ * Input:  r3 adr to read
+ * Output: r3 val or -1 for error
+ */
+spdRead:
+    mfspr   r26, 8              /* save link register */
+
+    lis     r30, CFG_ISA_IO@h
+    ori     r30, r30, 0x220     /* GPIO Port 1 */
+    li      r7, 0x00
+    li      r8, 0x100
+    and.    r5, r3, r8
+    beq     spdbank0
+    li      r12, 0x08
+    li      r4, 0x10
+    li      r6, 0x18
+    b       spdRead1
+
+spdbank0:
+    li      r12, 0x20           /* set I2C data */
+    li      r4, 0x40            /* set I2C clock */
+    li      r6, 0x60            /* set I2C clock and data */
+
+spdRead1:
+    li      r8, 0x80
+
+    bl      spdStart            /* access I2C bus as master */
+    li      r10, 0xa0           /* write to SPD */
+    bl      spdWriteByte
+    bl      spdReadAck          /* ACK returns in r10 */
+    cmpw    cr0, r10, r7
+    bne     AckErr              /* r10 must be 0, if ACK received */
+    mr      r10, r3             /* adr to read */
+    bl      spdWriteByte
+    bl      spdReadAck
+    cmpw    cr0, r10, r7
+    bne     AckErr
+    bl      spdStart
+    li      r10, 0xa1           /* read from SPD */
+    bl      spdWriteByte
+    bl      spdReadAck
+    cmpw    cr0, r10, r7
+    bne     AckErr
+    bl      spdReadByte         /* return val in r10 */
+    bl      spdWriteAck
+    bl      spdStop             /* release I2C bus */
+    mr      r3, r10
+    mtspr   8, r26              /* restore link register */
+    blr
+/*
+ * ACK error occurred
+ */
+AckErr:
+    bl      spdStop
+    orc     r3, r0, r0          /* return -1 */
+    mtspr   8, r26              /* restore link register */
+    blr
+
+/*
+ * Routines to read from RAM spd.
+ * r30 - GPIO Port1 address in all cases.
+ * r4 - clock mask for SPD
+ * r6 - port mask for SPD
+ * r12 - data mask for SPD
+ */
+waitSpd:
+    li      r0, 0x1000
+    mtctr   r0
+wSpd:
+    bdnz    wSpd
+    bclr    20, 0               /* return to caller */
+
+/*
+ * establish START condition on I2C bus
+ */
+spdStart:
+    mfspr   r27, 8              /* save link register */
+    stb     r6, 0(r30)          /* set SDA and SCL */
+    eieio
+    stb     r6, 1(r30)          /* switch GPIO to output */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* reset SDA */
+    eieio
+    bl      waitSpd
+    stb     r7, 0(r30)          /* reset SCL */
+    eieio
+    bl      waitSpd
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+/*
+ * establish STOP condition on I2C bus
+ */
+spdStop:
+    mfspr   r27, 8              /* save link register */
+    stb     r7, 0(r30)          /* reset SCL and SDA */
+    eieio
+    stb     r6, 1(r30)          /* switch GPIO to output */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* set SCL */
+    eieio
+    bl      waitSpd
+    stb     r6, 0(r30)          /* set SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r7, 1(r30)          /* switch GPIO to input */
+    eieio
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+spdReadByte:
+    mfspr   r27, 8
+    stb     r4, 1(r30)          /* set GPIO for SCL output */
+    eieio
+    li      r9, 0x08
+    li      r10, 0x00
+loopRB:
+    stb     r7, 0(r30)          /* reset SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* set SCL */
+    eieio
+    bl      waitSpd
+    lbz     r5, 0(r30)          /* read from GPIO Port1 */
+    rlwinm  r10, r10, 1, 0, 31
+    and.    r5, r5, r12
+    beq     clearBit
+    ori     r10, r10, 0x01      /* append _1_ */
+clearBit:
+    stb     r7, 0(r30)          /* reset SCL */
+    eieio
+    bl      waitSpd
+    addic.  r9, r9, -1
+    bne     loopRB
+    mtspr   8, r27
+    bclr    20, 0               /* return (r10) to caller */
+
+/*
+ * spdWriteByte writes bits 24 - 31 of r10 to I2C.
+ * r8 contains bit mask 0x80
+ */
+spdWriteByte:
+    mfspr   r27, 8              /* save link register */
+    li      r9, 0x08            /* write octet */
+    and.    r5, r10, r8
+    bne     sWB1
+    stb     r7, 0(r30)          /* set SDA to _0_ */
+    eieio
+    b       sWB2
+sWB1:
+    stb     r12, 0(r30)         /* set SDA to _1_ */
+    eieio
+sWB2:
+    stb     r6, 1(r30)          /* set GPIO to output */
+    eieio
+loopWB:
+    and.    r5, r10, r8
+    bne     sWB3
+    stb     r7, 0(r30)          /* set SDA to _0_ */
+    eieio
+    b       sWB4
+sWB3:
+    stb     r12, 0(r30)         /* set SDA to _1_ */
+    eieio
+sWB4:
+    bl      waitSpd
+    and.    r5, r10, r8
+    bne     sWB5
+    stb     r4, 0(r30)          /* set SDA to _0_ and SCL */
+    eieio
+    b       sWB6
+sWB5:
+    stb     r6, 0(r30)          /* set SDA to _1_ and SCL */
+    eieio
+sWB6:
+    bl      waitSpd
+    and.    r5, r10, r8
+    bne     sWB7
+    stb     r7, 0(r30)          /* set SDA to _0_ and reset SCL */
+    eieio
+    b       sWB8
+sWB7:
+    stb     r12, 0(r30)         /* set SDA to _1_ and reset SCL */
+    eieio
+sWB8:
+    bl      waitSpd
+    rlwinm  r10, r10, 1, 0, 31  /* next bit */
+    addic.  r9, r9, -1
+    bne     loopWB
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+/*
+ * Read ACK from SPD, return value in r10
+ */
+spdReadAck:
+    mfspr   r27, 8              /* save link register */
+    stb     r4, 1(r30)          /* set GPIO to output */
+    eieio
+    stb     r7, 0(r30)          /* reset SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r4, 0(r30)          /* set SCL */
+    eieio
+    bl      waitSpd
+    lbz     r10, 0(r30)         /* read GPIO Port 1 and mask SDA */
+    and     r10, r10, r12
+    bl      waitSpd
+    stb     r7, 0(r30)          /* reset SDA and SCL */
+    eieio
+    bl      waitSpd
+    mtspr   8, r27
+    bclr    20, 0               /* return (r10) to caller */
+
+spdWriteAck:
+    mfspr   r27, 8
+    stb     r12, 0(r30)         /* set SCL */
+    eieio
+    stb     r6, 1(r30)          /* set GPIO to output */
+    eieio
+    bl      waitSpd
+    stb     r6, 0(r30)          /* SDA and SCL */
+    eieio
+    bl      waitSpd
+    stb     r12, 0(r30)         /* reset SCL */
+    eieio
+    bl      waitSpd
+    mtspr   8, r27
+    bclr    20, 0               /* return to caller */
+
+get_lnk_reg:
+    mflr    r3                  /* return link reg */
+    blr
+
+/*
+ * Messages for console output
+ */
+.globl MessageBlock
+MessageBlock:
+Mok:
+    .ascii  "OK\015\012\000"
+Mfail:
+    .ascii  "FAILED\015\012\000"
+Mna:
+    .ascii  "NA\015\012\000"
+MinitLogo:
+    .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
+    .ascii  "\015\012Initialising RAM\015\012\000"
+Mspd01:
+    .ascii  "       Reading SPD of bank0/1 ..... \000"
+Mspd23:
+    .ascii  "       Reading SPD of bank2/3 ..... \000"
+MfpmRam:
+    .ascii  "       RAM-Type: FPM \015\012\000"
+MedoRam:
+    .ascii  "       RAM-Type: EDO \015\012\000"
+MsdRam:
+    .ascii  "       RAM-Type: SDRAM \015\012\000"
+Mactivate:
+    .ascii  "       Activating \000"
+Mmbyte:
+    .ascii  " MB .......... \000"
+    .align  4
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/board/eltec/bab7xx/el_srom.c b/board/eltec/bab7xx/el_srom.c
new file mode 100644
index 0000000..56abdc7
--- /dev/null
+++ b/board/eltec/bab7xx/el_srom.c
@@ -0,0 +1,292 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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 "srom.h"
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  START sequence
+ *        _ _________
+ *  SCLK  _>         \____
+ *        _ ____
+ *  SDIO  _>    \_________
+ *         :    :    :
+ */
+static void eepStart (void)
+{
+    out8(I2C_BUS_DAT, 0x60);     /* SCLK = high  SDIO = high */
+    out8(I2C_BUS_DIR, 0x60);     /* set output direction for SCLK/SDIO */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x40);     /* SCLK = high  SDIO = low */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x00);     /* SCLK = low   SDIO = low */
+    udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  STOP sequence
+ *              _______
+ *  SCLK  _____/
+ *        _         ___
+ *  SDIO  _>_______/
+ *         :   :   :
+ */
+static void eepStop (void)
+{
+    out8(I2C_BUS_DAT, 0x00);      /* SCLK = low   SDIO = low */
+    out8(I2C_BUS_DIR, 0x60);      /* set output direction for SCLK/SDIO */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x40);      /* SCLK = high  SDIO = low */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x60);      /* SCLK = high  SDIO = high */
+    udelay(10);
+    out8(I2C_BUS_DIR, 0x00);      /* reset to input direction */
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Read one byte from EEPROM
+ *            ___     ___     ___     ___     ___     ___     ___     ___
+ *  SCLK  ___/   \___/   \___/   \___/   \___/   \___/   \___/   \___/   \
+ *        _________________________________________________________________
+ *  SDIO  >     ^       ^       ^       ^       ^       ^       ^       ^
+ *        :  :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :
+ */
+static unsigned char eepReadByte (void)
+{
+    register unsigned char buf = 0x00;
+    register int i;
+
+    out8(I2C_BUS_DIR, 0x40);
+
+    for (i = 0; i < 8; i++)
+    {
+        out8(I2C_BUS_DAT, 0x00);    /* SCLK = low   SDIO = high */
+        udelay(10);
+        out8(I2C_BUS_DAT, 0x40);    /* SCLK = high  SDIO = high */
+        udelay(15);
+        buf <<= 1;
+        buf = (in8(I2C_BUS_DAT) & 0x20) ? (buf | 0x01) : (buf & 0xFE);
+        out8(I2C_BUS_DAT, 0x00);    /* SCLK = low   SDIO = high */
+        udelay(10);
+    }
+    return(buf);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Write one byte to EEPROM
+ *           ___     ___     ___     ___     ___     ___     ___     ___
+ *  SCLK  __/   \___/   \___/   \___/   \___/   \___/   \___/   \___/   \__
+ *         _______ _______ _______ _______ _______ _______ _______ ________
+ *  SDIO  X_______X_______X_______X_______X_______X_______X_______X________
+ *      :   7   :   6   :   5   :   4   :   3   :   2   :   1   :   0
+ */
+static void eepWriteByte (register unsigned char buf)
+{
+    register int    i;
+
+    (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00);     /* SCLK = low   SDIO = data */
+    out8(I2C_BUS_DIR, 0x60);
+
+    for (i = 7; i >= 0; i--)
+    {
+        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low  SDIO=data */
+        udelay(10);
+        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK=high SDIO=data */
+        udelay(15);
+        (buf & 0x80) ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK=low  SDIO=data */
+        udelay(10);
+        buf <<= 1;
+    }
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Read data acknowledge of EEPROM
+ *             _______
+ *  SCLK  ____/       \___
+ *         _______________
+ *  SDIO  >
+ *        :   :   ^   :
+ */
+static int eepReadAck (void)
+{
+    int retval;
+
+    out8(I2C_BUS_DIR, 0x40);
+    out8(I2C_BUS_DAT, 0x00);            /* SCLK = low   SDIO = high */
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x40);            /* SCLK = high  SDIO = high */
+    udelay(10);
+    retval = (in8(I2C_BUS_DAT) & 0x20) ? ERROR : 0;
+    udelay(10);
+    out8(I2C_BUS_DAT, 0x00);            /* SCLK = low   SDIO = high */
+    udelay(10);
+
+    return(retval);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *  Write data acknowledge to EEPROM
+ *             _______
+ *  SCLK  ____/       \___
+ *
+ *  SDIO  >_______________
+ *        :   :       :
+ */
+static void eepWriteAck (unsigned char ack)
+{
+    ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low   SDIO = ack */
+    out8(I2C_BUS_DIR, 0x60);
+    udelay(10);
+    ack ? out8(I2C_BUS_DAT, 0x60) : out8(I2C_BUS_DAT, 0x40); /* SCLK = high  SDIO = ack */
+    udelay(15);
+    ack ? out8(I2C_BUS_DAT, 0x20) : out8(I2C_BUS_DAT, 0x00); /* SCLK = low   SDIO = ack */
+    udelay(10);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Read bytes from EEPROM
+ */
+int el_srom_load (addr, buf, cnt, device, block)
+unsigned char addr;
+unsigned char *buf;
+int cnt;
+unsigned char device;
+unsigned char block;
+{
+    register int i;
+
+    for (i=0;i<cnt;i++)
+    {
+        eepStart();
+        eepWriteByte(0xA0 | device | block);
+        if (eepReadAck() == ERROR)
+        {
+           eepStop();
+            return(ERROR);
+        }
+        eepWriteByte(addr++);
+        if (eepReadAck() == ERROR)
+        {
+            eepStop();
+            return(ERROR);
+        }
+        eepStart();
+
+        eepWriteByte(0xA1 | device | block);
+        if (eepReadAck() == ERROR)
+        {
+            eepStop();
+            return(ERROR);
+        }
+
+        *buf++ = eepReadByte();
+        eepWriteAck(1);
+        eepStop();
+
+        if ((addr == 0) && (i != (cnt-1)))    /* is it the same block ? */
+        {
+            if (block == FIRST_BLOCK)
+                block = SECOND_BLOCK;
+            else
+                return(ERROR);
+        }
+    }
+    return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ *
+ * Write bytes to EEPROM
+ *
+ */
+int el_srom_store (addr, buf, cnt, device, block)
+unsigned char    addr, *buf, device, block;
+int        cnt;
+{
+    register int i, retVal;
+
+    for (i=0;i<cnt;i++)
+    {
+        retVal = ERROR;
+        do
+        {
+            eepStart();
+            eepWriteByte(0xA0 | device | block);
+            if ((retVal = eepReadAck()) == ERROR)
+                eepStop();
+        } while (retVal == ERROR);
+
+        eepWriteByte(addr++);
+        if (eepReadAck() == ERROR)  return(ERROR);
+
+        if ((addr == 0) && (i != (cnt-1)))    /* is it the same block ? */
+        {
+            if (block == FIRST_BLOCK)
+                block = SECOND_BLOCK;
+            else
+            return(ERROR);
+        }
+
+        eepWriteByte(*buf++);
+        if (eepReadAck() == ERROR)
+            return(ERROR);
+
+        eepStop();
+    }
+    return(cnt);
+}
+
+/*----------------------------------------------------------------------------*/
+/*
+ * calculate checksum for ELTEC revision srom
+ */
+unsigned long el_srom_checksum (ptr, size)
+register unsigned char *ptr;
+unsigned long size;
+{
+    u_long f, accu = 0;
+    u_int  i;
+    u_char byte;
+
+    for (; size; size--)
+    {
+        byte = *ptr++;
+        for (i = 8; i; i--)
+        {
+            f =  ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
+            accu >>= 1; accu ^= f;
+            byte >>= 1;
+        }
+    }
+    return(accu);
+}
+
+/*----------------------------------------------------------------------------*/
diff --git a/board/eltec/bab7xx/u-boot.lds b/board/eltec/bab7xx/u-boot.lds
new file mode 100644
index 0000000..7b10c0d
--- /dev/null
+++ b/board/eltec/bab7xx/u-boot.lds
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+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/74xx_7xx/start.o	(.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/*    . = 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)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/eltec/elppc/asm_init.S b/board/eltec/elppc/asm_init.S
new file mode 100644
index 0000000..a5605b7
--- /dev/null
+++ b/board/eltec/elppc/asm_init.S
@@ -0,0 +1,877 @@
+/*
+ * (C) Copyright 2001 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.de>
+ *
+ * ELTEC ELPPC RAM initialization
+ *
+ * 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 <mpc106.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+.globl board_asm_init
+board_asm_init:
+
+/*
+ * setup pointer to message block
+ */
+    mflr    r13                 /* save away link register */
+    bl      get_lnk_reg         /* r3=addr of next instruction */
+    subi    r4, r3, 8           /* r4=board_asm_init addr */
+    addi    r29, r4, (MessageBlock-board_asm_init)
+
+/*
+ * dcache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, HID0_DCE
+    andc    r3, r3, r4
+    mr      r2, r3
+    ori     r3, r3, HID0_DCI
+    sync
+    mtspr   HID0, r3
+    mtspr   HID0, r2
+    isync
+    sync
+/*
+ * icache_disable
+ */
+    mfspr   r3, HID0
+    li      r4, 0
+    ori     r4, r4, HID0_ICE
+    andc    r3, r3, r4
+    sync
+    mtspr   HID0, r3
+/*
+ * invalidate caches
+ */
+    ori     r3, r3, (HID0_ICE | HID0_ICFI | HID0_DCI | HID0_DCE)
+    or      r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    andc    r4, r4, r3
+    isync
+    mtspr   HID0, r4
+    isync
+/*
+ * icache_enable
+ */
+    mfspr   r3, HID0
+    ori     r3, r3, (HID0_ICE | HID0_ICFI)
+    sync
+    mtspr   HID0, r3
+
+
+/*
+ * setup memory controller
+ */
+    lis     r1, MPC106_REG_ADDR@h
+    ori     r1, r1, MPC106_REG_ADDR@l
+    lis     r2, MPC106_REG_DATA@h
+    ori     r2, r2, MPC106_REG_DATA@l
+
+    /* Configure PICR1 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, PCI_PICR1
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFF14
+    ori     r3, r3, 0x1CC8
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure PICR2 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, PCI_PICR2
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0000
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure EUMBAR */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, 0x0078      /* offest of EUMBAR in PCI config space */
+    stwbrx  r3, 0, r1
+    lis     r3, MPC107_EUMB_ADDR@h
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure Address Map B Option Reg */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, 0x00e0      /* offest of AMBOR in PCI config space */
+    stwbrx  r3, 0, r1
+    lis     r3, 0
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure I2C Controller */
+    lis     r14, MPC107_I2C_ADDR@h  /* base of I2C controller */
+    ori     r14, r14, MPC107_I2C_ADDR@l
+    lis     r3, 0x2b10          /* I2C clock = 100MHz/1024 */
+    stw     r3, 4(r14)
+    li      r3, 0               /* clear arbitration */
+    eieio
+    stw     r3, 12(r14)
+
+    /* Configure MCCR1 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR1
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0660      /* don't set MEMGO now ! */
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure MCCR2 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR2
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0400
+    ori     r3, r3, 0x1800
+    eieio
+    stwbrx  r3, 0, r2
+
+
+    /* Configure MCCR3 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR3
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0230
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    /* Configure MCCR4 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR4
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x2532
+    ori     r3, r3, 0x2220
+    eieio
+    stwbrx  r3, 0, r2
+
+/*
+ * configure memory interface (MICRs)
+ */
+    addis   r3, r0, 0x8000      /* ADDR_80 */
+    ori     r3, r3, 0x0080      /* SMEMADD1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0x4000
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_84 */
+    ori     r3, r3, 0x0084      /* SMEMADD2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0xFFFF
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_88 */
+    ori     r3, r3, 0x0088      /* EXTSMEM1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_8C */
+    ori     r3, r3, 0x008c      /* EXTSMEM2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0303
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_90 */
+    ori     r3, r3, 0x0090      /* EMEMADD1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0x7F3F
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_94 */
+    ori     r3, r3, 0x0094      /* EMEMADD2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0xFFFF
+    ori     r3, r3, 0xFFFF
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_98 */
+    ori     r3, r3, 0x0098      /* EXTEMEM1 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0000
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_9C */
+    ori     r3, r3, 0x009c      /* EXTEMEM2 */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0303
+    ori     r3, r3, 0x0303
+    eieio
+    stwbrx  r3, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_A0 */
+    ori     r3, r3, 0x00a0      /* MEMBNKEN */
+    stwbrx  r3, 0, r1
+    addis   r3, r0, 0x0000
+    ori     r3, r3, 0x0003
+    eieio
+    stwbrx  r3, 0, r2
+
+/*
+ * must wait at least 100us after HRESET to issue a MEMGO
+ */
+    lis     r0, 1
+    mtctr   r0
+memStartWait:
+    bdnz    memStartWait
+
+/*
+ * enable RAM Operations through MCCR1 (MEMGO)
+ */
+    lis     r3, 0x8000
+    ori     r3, r3, 0x00f0
+    stwbrx  r3, r0, r1
+    sync
+    lwbrx   r3, 0, r2
+    lis     r0, 0x0008
+    or      r3, r0, r3
+    stwbrx  r3, 0, r2
+    sync
+
+/*
+ * set LEDs first time
+ */
+    li      r3, 0x1
+    lis     r30, CFG_USR_LED_BASE@h
+    stb     r3, 2(r30)
+    sync
+
+/*
+ * init COM1 for polled output
+ */
+    lis     r8, CFG_NS16550_COM1@h  /* COM1 base address*/
+    ori     r8, r8, CFG_NS16550_COM1@l
+    li      r9, 0x00
+    stb     r9, 1(r8)           /* int disabled */
+    eieio
+    li      r9, 0x00
+    stb     r9, 4(r8)           /* modem ctrl */
+    eieio
+    li      r9, 0x80
+    stb     r9, 3(r8)           /* link ctrl */
+    eieio
+    li      r9, (CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE)
+    stb     r9, 0(r8)           /* baud rate (LSB)*/
+    eieio
+    li      r9, ((CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE) >> 8)
+    stb     r9, 1(r8)           /* baud rate (MSB) */
+    eieio
+    li      r9, 0x07
+    stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */
+    eieio
+    li      r9, 0x0b
+    stb     r9, 4(r8)           /* enable the receiver and transmitter (modem ctrl) */
+    eieio
+waitEmpty:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty
+    li      r9, 0x47
+    stb     r9, 3(r8)           /* send break, 8 data bits, 2 stop bit, no parity */
+    eieio
+
+    lis     r0, 0x0001
+    mtctr   r0
+waitCOM1:
+    lwz     r0, 5(r8)           /* load from port for delay */
+    bdnz    waitCOM1
+
+waitEmpty1:
+    lbz     r9, 5(r8)           /* transmit empty */
+    andi.   r9, r9, 0x40
+    beq     waitEmpty1
+    li      r9, 0x07
+    stb     r9, 3(r8)           /* 8 data bits, 2 stop bit, no parity */
+    eieio
+
+/*
+ * intro message from message block
+ */
+    addi    r3, r29, (MnewLine-MessageBlock)
+    bl      Printf
+    addi    r3, r29, (MinitLogo-MessageBlock)
+    bl      Printf
+
+/*
+ * memory cofiguration using SPD information stored on the SODIMMs
+ */
+    addi    r3, r29, (Mspd01-MessageBlock)
+    bl      Printf
+
+    li      r17, 0
+
+    li      r3, 0x0002          /* get RAM type from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, -1        /* error ? */
+    bne     noSpdError
+
+    addi    r3, r29, (Mfail-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xe             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+
+noSpdError:
+    mr      r15, r3             /* save r3 */
+
+    addi    r3, r29, (Mok-MessageBlock)
+    bl      Printf
+
+    cmpli   0, 0, r15, 0x0004   /* SDRAM ? */
+    beq     isSDRAM
+
+    addi    r3, r29, (MramTyp-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xd             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+
+isSDRAM:
+    li      r3, 0x0012          /* get supported CAS latencies from byte 18 */
+    bl      spdRead
+    mr      r15, r3
+    li      r3, 0x09
+    andi.   r0, r15, 0x04
+    bne     maxCLis3
+    li      r3, 0x17
+maxCLis3:
+    andi.   r0, r15, 0x02
+    bne     CL2
+
+    addi    r3, r29, (MramTyp-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xc             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+CL2:
+    bl      spdRead
+    cmpli   0, 0, r3, 0xa1      /* cycle time must be 10ns max. */
+    blt     speedOk
+
+    addi    r3, r29, (MramTyp-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xb             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+speedOk:
+    lis     r20, 0x06e8         /* preset MCR1 value */
+
+    li      r3, 0x0011          /* get number of internal banks from spd for bank0/1 */
+    bl      spdRead
+
+    cmpli   0, 0, r3, 0x02
+    beq     SD_2B
+    cmpli   0, 0, r3, 0x04
+    beq     SD_4B
+memConfErr:
+    addi    r3, r29, (MramConfErr-MessageBlock)
+    bl      Printf
+
+    li      r6, 0xa             /* error codes in r6 and r7  */
+    li      r7, 0x0
+    b       toggleError         /* fail - loop forever */
+
+SD_2B:
+    li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */
+    bl      spdRead
+    cmpli   0, 0, r3, 0x0b
+    beq     row11x2
+    cmpli   0, 0, r3, 0x0c
+    beq     row12x2or13x2
+    cmpli   0, 0, r3, 0x0d
+    beq     row12x2or13x2
+    b       memConfErr
+SD_4B:
+    li      r3, 0x0003          /* get number of row bits from spd for bank0/1 */
+    bl      spdRead
+    cmpli   0, 0, r3, 0x0b
+    beq     row11x4or12x4
+    cmpli   0, 0, r3, 0x0c
+    beq     row11x4or12x4
+    cmpli   0, 0, r3, 0x0d
+    beq     row13x4
+    b       memConfErr
+row12x2or13x2:
+    ori     r20, r20, 0x05
+    b       row11x4or12x4
+row13x4:
+    ori     r20, r20, 0x0a
+    b       row11x4or12x4
+row11x2:
+    ori     r20, r20, 0x0f
+row11x4or12x4:
+    /* get the size of bank 0-1 */
+
+    li      r3, 0x001f          /* get bank size from spd for bank0/1 */
+    bl      spdRead
+
+    rlwinm  r16, r3, 2, 24, 29  /* calculate size in MByte (128 MB max.) */
+
+    li      r3, 0x0005          /* get number of banks from spd for bank0/1 */
+    bl      spdRead
+
+    cmpi    0, 0, r3, 2         /* 2 banks ? */
+    bne     SDRAMnobank1
+
+    mr      r17, r16
+
+SDRAMnobank1:
+    li      r3, 0x000c          /* get refresh from spd for bank0/1 */
+    bl      spdRead
+    andi.   r3, r3, 0x007f      /* mask selfrefresh bit */
+    li      r4, 0x1800          /* refesh cycle 1536 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x0c00          /* refesh cycle 768 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x3000          /* refesh cycle 3072 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
+    beq     writeRefresh
+
+    li      r4, 0x6000          /* refesh cycle 6144 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0004    /* 62.5 us ? */
+    beq     writeRefresh
+
+    li      r4, 0
+    ori     r4, r4, 0xc000      /* refesh cycle 8224 clocks left shifted 2 */
+    cmpli   0, 0, r3, 0x0005    /* 125 us ? */
+    beq     writeRefresh
+
+    b       memConfErr
+
+writeRefresh:
+    lis     r21, 0x0400         /* preset MCCR2 value */
+    or      r21, r21, r4
+
+    /* Overwrite MCCR1 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR1
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r20, 0, r2
+
+    /* Overwrite MCCR2 */
+    lis     r3, MPC106_REG@h
+    ori     r3, r3, MPC106_MCCR2
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r21, 0, r2
+
+    /* set the memory boundary registers for bank 0-3 */
+    li      r20, 0
+    lis     r23, 0x0303
+    lis     r24, 0x0303
+    subi    r21, r16, 1         /* calculate end address bank0 */
+    li      r22, 1
+
+    cmpi    0, 0, r17, 0        /* bank1 present ? */
+    beq     nobank1
+
+    andi.   r3, r16, 0x00ff     /* calculate start address of bank1 */
+    andi.   r4, r16, 0x0300
+    rlwinm  r3, r3, 8, 16, 23
+    or      r20, r20, r3
+    or      r23, r23, r4
+
+    add     r16, r16, r17       /* add to total memory size */
+
+    subi    r3, r16, 1          /* calculate end address of bank1 */
+    andi.   r4, r3, 0x0300
+    andi.   r3, r3, 0x00ff
+    rlwinm  r3, r3, 8, 16, 23
+    or      r21, r21, r3
+    or      r24, r24, r4
+
+    ori     r22, r22, 2         /* enable bank1 */
+    b       bankOk
+nobank1:
+    ori     r23, r23, 0x0300    /* set bank1 start to unused area */
+    ori     r24, r24, 0x0300    /* set bank1 end to unused area */
+bankOk:
+    addi    r3, r29, (Mactivate-MessageBlock)
+    bl      Printf
+    mr      r3, r16
+    bl      OutDec
+    addi    r3, r29, (Mact0123e-MessageBlock)
+    bl      Printf
+
+/*
+ * overwrite MSAR1, MEAR1, EMSAR1, and EMEAR1
+ */
+    addis   r3, r0, 0x8000      /* ADDR_80 */
+    ori     r3, r3, 0x0080      /* MSAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r20, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_88 */
+    ori     r3, r3, 0x0088      /* EMSAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r23, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_90 */
+    ori     r3, r3, 0x0090      /* MEAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r21, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_98 */
+    ori     r3, r3, 0x0098      /* EMEAR1 */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r24, 0, r2
+
+    addis   r3, r0, 0x8000      /* ADDR_A0 */
+    ori     r3, r3, 0x00a0      /* MBER */
+    stwbrx  r3, 0, r1
+    eieio
+    stwbrx  r22, 0, r2
+
+/*
+ * delay to let SDRAM go through several initialization/refresh cycles
+ */
+    lis     r3, 3
+    mtctr   r3
+memStartWait_1:
+    bdnz    memStartWait_1
+    eieio
+
+/*
+ * set LEDs end
+ */
+    li      r3, 0xf
+    lis     r30, CFG_USR_LED_BASE@h
+    stb     r3, 2(r30)
+    sync
+
+    mtlr    r13
+    blr                         /* EXIT board_asm_init ... */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * print a message to COM1 in polling mode (r10=COM1 port, r3=(char*)string)
+ */
+
+Printf:
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+WaitChr:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, WaitChr        /* wait till empty */
+    lbzx    r0, r0, r3          /* get char */
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addi    r3, r3, 1           /* next char */
+    lbzx    r0, r0, r3          /* get char */
+    cmpwi   cr1, r0, 0          /* end of string ? */
+    bne     cr1, WaitChr
+    blr
+
+/*
+ * print a char to COM1 in polling mode (r10=COM1 port, r3=char)
+ */
+OutChr:
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+OutChr1:
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutChr1        /* wait till empty */
+    stb     r3, 0(r10)          /* write to transmit reg */
+    eieio
+    blr
+
+/*
+ * print 8/4/2 digits hex value to COM1 in polling mode (r10=COM1 port, r3=val)
+ */
+OutHex2:
+    li      r9, 4               /* shift reg for 2 digits */
+    b       OHstart
+OutHex4:
+    li      r9, 12              /* shift reg for 4 digits */
+    b       OHstart
+OutHex:
+    li      r9, 28              /* shift reg for 8 digits */
+OHstart:
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+OutDig:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDig
+    sraw    r0, r3, r9
+    clrlwi  r0, r0, 28
+    cmpwi   cr1, r0, 9
+    ble     cr1, digIsNum
+    addic   r0, r0, 55
+    b       nextDig
+digIsNum:
+    addic   r0, r0, 48
+nextDig:
+    stb     r0, 0(r10)          /* write to transmit reg */
+    eieio
+    addic.  r9, r9, -4
+    bge     OutDig
+    blr
+
+/*
+ * print 3 digits hdec value to COM1 in polling mode
+ * (r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0, r6=scratch)
+ */
+OutDec:
+    li      r6, 10
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r9 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r9, r10, r3
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r8 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r8, r10, r3
+    mr      r3, r0
+    divwu   r0, r3, r6          /* r0 = r3 / 10, r7 = r3 mod 10 */
+    mullw   r10, r0, r6
+    subf    r7, r10, r3
+    lis     r10, CFG_NS16550_COM1@h /* COM1 base address*/
+    ori     r10, r10, CFG_NS16550_COM1@l
+    or.     r7, r7, r7
+    bne     noblank1
+    li      r3, 0x20
+    b       OutDec4
+noblank1:
+    addi    r3, r7, 48          /* convert to ASCII */
+OutDec4:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec4
+    stb     r3, 0(r10)          /* x00 to transmit */
+    eieio
+    or.     r7, r7, r8
+    beq     OutDec5
+    addi    r3, r8, 48          /* convert to ASCII */
+OutDec5:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec5
+    stb     r3, 0(r10)          /* x0  to transmit */
+    eieio
+    addi    r3, r9, 48          /* convert to ASCII */
+OutDec6:
+    lbz     r0, 0(r29)          /* slow down dummy read */
+    lbz     r0, 5(r10)          /* read link status */
+    eieio
+    andi.   r0, r0, 0x40        /* mask transmitter empty bit */
+    beq     cr0, OutDec6
+    stb     r3, 0(r10)          /* x   to transmit */
+    eieio
+    blr
+
+/*
+ * hang endless loop
+ */
+toggleError:                    /* fail type in r6, r7=0xff, toggle LEDs */
+    stb     r7, 2(r30)          /* r7 to LED */
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError1:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError1
+    stb     r6, 2(r30)          /* r6 to LED */
+    li      r0, 0
+    lis     r9, 127
+    ori     r9, r9, 65535
+toggleError2:
+    addic   r0, r0, 1
+    cmpw    cr1, r0, r9
+    ble     cr1, toggleError2
+    b       toggleError
+
+/*
+ * routines to read from ram spd
+ */
+spdWaitIdle:
+    lis     r0, 0x1             /* timeout for about 100us */
+    mtctr   r0
+iSpd:
+    lbz     r10, 12(r14)
+    andi.   r10, r10, 0x20      /* mask and test MBB */
+    beq     idle
+    bdnz    iSpd
+    orc.    r10, r0, r0         /* return -1 to caller */
+idle:
+    bclr    20, 0               /* return to caller */
+
+waitSpd:
+    lis     r0, 0x10            /* timeout for about 1.5ms */
+    mtctr   r0
+wSpd:
+    lbz     r10, 12(r14)
+    andi.   r10, r10, 0x82
+    cmpli   0, 0, r10, 0x82     /* test MCF and MIF set */
+    beq     wend
+    bdnz    wSpd
+    orc.    r10, r0, r0         /* return -1 to caller */
+    bclr    20, 0               /* return to caller */
+
+wend:
+    li      r10, 0
+    stb     r10, 12(r14)        /* clear status */
+    bclr    20, 0               /* return to caller */
+
+/*
+ * spdread
+ * in:  r3 adr to read
+ * out: r3 val or -1 for error
+ * uses r10, assumes that r14 points to I2C controller
+ */
+spdRead:
+    mfspr   r25, 8              /* save link register */
+
+    bl      spdWaitIdle
+    bne     spdErr
+
+    li      r10, 0x80           /* start with MEN */
+    stb     r10, 8(r14)
+    eieio
+
+    li      r10, 0xb0           /* start as master */
+    stb     r10, 8(r14)
+    eieio
+
+    li      r10, 0xa0           /* write device 0xA0 */
+    stb     r10, 16(r14)
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+    lbz     r10, 12(r14)        /* test ACK */
+    andi.   r10, r10, 0x01
+    bne     gotNoAck
+
+    stb     r3, 16(r14)         /* data address */
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+
+    li      r10, 0xb4           /* switch to read - restart */
+    stb     r10, 8(r14)
+    eieio
+
+    li      r10, 0xa1           /* read device 0xA0 */
+    stb     r10, 16(r14)
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+    li      r10, 0xa8           /* no ACK */
+    stb     r10, 8(r14)
+    eieio
+
+    lbz     r10, 16(r14)        /* trigger read next byte */
+    eieio
+    bl      waitSpd
+    bne     spdErr
+
+    li      r10, 0x88           /* generate STOP condition */
+    stb     r10, 8(r14)
+    eieio
+
+    lbz     r3, 16(r14)         /* return read byte */
+
+    mtspr   8, r25              /* restore link register */
+    blr
+
+gotNoAck:
+    li      r10, 0x80           /* generate STOP condition */
+    stb     r10, 8(r14)
+    eieio
+spdErr:
+    orc     r3, r0, r0          /* return -1 */
+    mtspr   8, r25              /* restore link register */
+    blr
+
+get_lnk_reg:
+    mflr    r3                  /* return link reg */
+    blr
+
+MessageBlock:
+
+MinitLogo:
+    .ascii  "\015\012*** ELTEC Elektronik, Mainz ***\015\012"
+    .ascii  "\015\012Initialising RAM\015\012\000"
+Mspd01:
+    .ascii  "       Reading SPD of SODIMM ...... \000"
+MramTyp:
+    .ascii  "\015\012\SDRAM with CL=2 at 100 MHz required!\015\012\000"
+MramConfErr:
+    .ascii  "\015\012\Unsupported SODIMM Configuration!\015\012\000"
+Mactivate:
+    .ascii  "       Activating \000"
+Mact0123e:
+    .ascii  " MByte.\015\012\000"
+Mok:
+    .ascii  "OK \015\012\000"
+Mfail:
+    .ascii  "FAILED \015\012\000"
+MnewLine:
+    .ascii  "\015\012\000"
+    .align 4
diff --git a/board/eltec/elppc/u-boot.lds b/board/eltec/elppc/u-boot.lds
new file mode 100644
index 0000000..7b10c0d
--- /dev/null
+++ b/board/eltec/elppc/u-boot.lds
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+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/74xx_7xx/start.o	(.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/*    . = 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)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/ep7312/flash.c b/board/ep7312/flash.c
new file mode 100644
index 0000000..373d238
--- /dev/null
+++ b/board/ep7312/flash.c
@@ -0,0 +1,341 @@
+/*
+ * (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>
+
+#define FLASH_BANK_SIZE 0x1000000
+#define MAIN_SECT_SIZE  0x20000
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init (void)
+{
+	int i, j;
+	ulong size = 0;
+
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+		ulong flashbase = 0;
+
+		flash_info[i].flash_id =
+				(INTEL_MANUFACT & FLASH_VENDMASK) |
+				(INTEL_ID_28F128J3 & FLASH_TYPEMASK);
+		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);
+		if (i == 0)
+			flashbase = PHYS_FLASH_1;
+		else
+			panic ("configured to many flash banks!\n");
+		for (j = 0; j < flash_info[i].sector_count; j++) {
+			flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;
+		}
+		size += flash_info[i].size;
+	}
+
+	/* Protect monitor and environment sectors
+	 */
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_FLASH_BASE,
+			CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
+			&flash_info[0]);
+
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_ENV_ADDR,
+			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+
+	return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+	int i;
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case (INTEL_MANUFACT & FLASH_VENDMASK):
+		printf ("Intel: ");
+		break;
+	default:
+		printf ("Unknown Vendor ");
+		break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
+		printf ("28F128J3 (128Mbit)\n");
+		break;
+	default:
+		printf ("Unknown Chip Type\n");
+		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:
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+	int flag, prot, sect;
+	int rc = ERR_OK;
+
+	if (info->flash_id == FLASH_UNKNOWN)
+		return ERR_UNKNOWN_FLASH_TYPE;
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		return ERR_INVAL;
+	}
+
+	if ((info->flash_id & FLASH_VENDMASK) !=
+		(INTEL_MANUFACT & FLASH_VENDMASK)) {
+		return ERR_UNKNOWN_FLASH_VENDOR;
+	}
+
+	prot = 0;
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+	if (prot)
+		return ERR_PROTECTED;
+
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	flag = disable_interrupts ();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+
+		printf ("Erasing sector %2d ... ", sect);
+
+		/* arm simple, non interrupt dependent timer */
+		reset_timer_masked ();
+
+		if (info->protect[sect] == 0) {	/* not protected */
+			vu_short *addr = (vu_short *) (info->start[sect]);
+
+			*addr = 0x20;		/* erase setup */
+			*addr = 0xD0;		/* erase confirm */
+
+			while ((*addr & 0x80) != 0x80) {
+				if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+					*addr = 0xB0;	/* suspend erase */
+					*addr = 0xFF;	/* reset to read mode */
+					rc = ERR_TIMOUT;
+					goto outahere;
+				}
+			}
+
+			/* clear status register command */
+			*addr = 0x50;
+			/* reset to read mode */
+			*addr = 0xFF;
+		}
+		printf ("ok.\n");
+	}
+	if (ctrlc ())
+		printf ("User Interrupt!\n");
+
+  outahere:
+
+	/* allow flash to settle - wait 10 ms */
+	udelay_masked (10000);
+
+	if (flag)
+		enable_interrupts ();
+
+	return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_word (flash_info_t * info, ulong dest, ushort data)
+{
+	vu_short *addr = (vu_short *) dest, val;
+	int rc = ERR_OK;
+	int flag;
+
+	/* Check if Flash is (sufficiently) erased
+	 */
+	if ((*addr & data) != data)
+		return ERR_NOT_ERASED;
+
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	flag = disable_interrupts ();
+
+	/* clear status register command */
+	*addr = 0x50;
+
+	/* program set-up command */
+	*addr = 0x40;
+
+	/* latch address/data */
+	*addr = data;
+
+	/* arm simple, non interrupt dependent timer */
+	reset_timer_masked ();
+
+	/* wait while polling the status register */
+	while (((val = *addr) & 0x80) != 0x80) {
+		if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+			rc = ERR_TIMOUT;
+			/* suspend program command */
+			*addr = 0xB0;
+			goto outahere;
+		}
+	}
+
+	if (val & 0x1A) {			/* check for error */
+		printf ("\nFlash write error %02x at address %08lx\n",
+				(int) val, (unsigned long) dest);
+		if (val & (1 << 3)) {
+			printf ("Voltage range error.\n");
+			rc = ERR_PROG_ERROR;
+			goto outahere;
+		}
+		if (val & (1 << 1)) {
+			printf ("Device protect error.\n");
+			rc = ERR_PROTECTED;
+			goto outahere;
+		}
+		if (val & (1 << 4)) {
+			printf ("Programming error.\n");
+			rc = ERR_PROG_ERROR;
+			goto outahere;
+		}
+		rc = ERR_PROG_ERROR;
+		goto outahere;
+	}
+
+  outahere:
+	/* read array command */
+	*addr = 0xFF;
+
+	if (flag)
+		enable_interrupts ();
+
+	return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+	ulong cp, wp;
+	ushort data;
+	int l;
+	int i, rc;
+
+	wp = (addr & ~1);			/* 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 << 8);
+		}
+		for (; i < 2 && cnt > 0; ++i) {
+			data = (data >> 8) | (*src++ << 8);
+			--cnt;
+			++cp;
+		}
+		for (; cnt == 0 && i < 2; ++i, ++cp) {
+			data = (data >> 8) | (*(uchar *) cp << 8);
+		}
+
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += 2;
+	}
+
+	/*
+	 * handle word aligned part
+	 */
+	while (cnt >= 2) {
+		data = *((vu_short *) src);
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		src += 2;
+		wp += 2;
+		cnt -= 2;
+	}
+
+	if (cnt == 0) {
+		return ERR_OK;
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
+		data = (data >> 8) | (*src++ << 8);
+		--cnt;
+	}
+	for (; i < 2; ++i, ++cp) {
+		data = (data >> 8) | (*(uchar *) cp << 8);
+	}
+
+	return write_word (info, wp, data);
+}
diff --git a/board/ep7312/u-boot.lds b/board/ep7312/u-boot.lds
new file mode 100644
index 0000000..0849648
--- /dev/null
+++ b/board/ep7312/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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/arm720t/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/esd/common/fpga.c b/board/esd/common/fpga.c
new file mode 100644
index 0000000..666b490
--- /dev/null
+++ b/board/esd/common/fpga.c
@@ -0,0 +1,262 @@
+/*
+ * (C) Copyright 2001
+ * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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/processor.h>
+#include <command.h>
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef FPGA_DEBUG
+#define DBG(x...) printf(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+#define MAX_ONES               226
+
+#define IBM405GP_GPIO0_OR      0xef600700  /* GPIO Output */
+#define IBM405GP_GPIO0_TCR     0xef600704  /* GPIO Three-State Control */
+#define IBM405GP_GPIO0_ODR     0xef600718  /* GPIO Open Drain */
+#define IBM405GP_GPIO0_IR      0xef60071c  /* GPIO Input */
+
+#ifdef CFG_FPGA_PRG
+# define FPGA_PRG              CFG_FPGA_PRG /* FPGA program pin (ppc output)*/
+# define FPGA_CLK              CFG_FPGA_CLK /* FPGA clk pin (ppc output)    */
+# define FPGA_DATA             CFG_FPGA_DATA /* FPGA data pin (ppc output)  */
+# define FPGA_DONE             CFG_FPGA_DONE /* FPGA done pin (ppc input)   */
+# define FPGA_INIT             CFG_FPGA_INIT /* FPGA init pin (ppc input)   */
+#else
+# define FPGA_PRG              0x04000000  /* FPGA program pin (ppc output) */
+# define FPGA_CLK              0x02000000  /* FPGA clk pin (ppc output)     */
+# define FPGA_DATA             0x01000000  /* FPGA data pin (ppc output)    */
+# define FPGA_DONE             0x00800000  /* FPGA done pin (ppc input)     */
+# define FPGA_INIT             0x00400000  /* FPGA init pin (ppc input)     */
+#endif
+
+#define ERROR_FPGA_PRG_INIT_LOW  -1        /* Timeout after PRG* asserted   */
+#define ERROR_FPGA_PRG_INIT_HIGH -2        /* Timeout after PRG* deasserted */
+#define ERROR_FPGA_PRG_DONE      -3        /* Timeout after programming     */
+
+#define SET_FPGA(data)         out32(IBM405GP_GPIO0_OR, data)
+
+#define FPGA_WRITE_1 {                                                    \
+        SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
+        SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set data to 1  */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* set clock to 1 */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1  */
+
+#define FPGA_WRITE_0 {                                                    \
+        SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
+        SET_FPGA(FPGA_PRG);                         /* set data to 0  */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK);              /* set clock to 1 */  \
+        SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1  */
+
+
+static int fpga_boot(unsigned char *fpgadata, int size)
+{
+  int i,index,len;
+  int count;
+#ifdef CFG_FPGA_SPARTAN2
+  int j;
+#else
+  unsigned char b;
+  int bit;
+#endif
+
+  /* display infos on fpgaimage */
+  index = 15;
+  for (i=0; i<4; i++)
+    {
+      len = fpgadata[index];
+      DBG("FPGA: %s\n", &(fpgadata[index+1]));
+      index += len+3;
+    }
+
+#ifdef CFG_FPGA_SPARTAN2
+  /* search for preamble 0xFFFFFFFF */
+  while (1)
+    {
+      if ((fpgadata[index] == 0xff) && (fpgadata[index+1] == 0xff) &&
+          (fpgadata[index+2] == 0xff) && (fpgadata[index+3] == 0xff))
+        break; /* preamble found */
+      else
+        index++;
+    }
+#else
+  /* search for preamble 0xFF2X */
+  for (index = 0; index < size-1 ; index++)
+    {
+      if ((fpgadata[index] == 0xff) && ((fpgadata[index+1] & 0xf0) == 0x30))
+	break;
+    }
+  index += 2;
+#endif
+
+  DBG("FPGA: configdata starts at position 0x%x\n",index);
+  DBG("FPGA: length of fpga-data %d\n", size-index);
+
+  /*
+   * Setup port pins for fpga programming
+   */
+  out32(IBM405GP_GPIO0_ODR, 0x00000000);                       /* no open drain pins      */
+  out32(IBM405GP_GPIO0_TCR, FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* setup for output        */
+  out32(IBM405GP_GPIO0_OR,  FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* set output pins to high */
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  /*
+   * Init fpga by asserting and deasserting PROGRAM*
+   */
+  SET_FPGA(FPGA_CLK | FPGA_DATA);
+
+  /* Wait for FPGA init line low */
+  count = 0;
+  while (in32(IBM405GP_GPIO0_IR) & FPGA_INIT)
+    {
+      udelay(1000); /* wait 1ms */
+      /* Check for timeout - 100us max, so use 3ms */
+      if (count++ > 3)
+        {
+          DBG("FPGA: Booting failed!\n");
+          return ERROR_FPGA_PRG_INIT_LOW;
+        }
+    }
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  /* deassert PROGRAM* */
+  SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
+
+  /* Wait for FPGA end of init period .  */
+  count = 0;
+  while (!(in32(IBM405GP_GPIO0_IR) & FPGA_INIT))
+    {
+      udelay(1000); /* wait 1ms */
+      /* Check for timeout */
+      if (count++ > 3)
+        {
+          DBG("FPGA: Booting failed!\n");
+          return ERROR_FPGA_PRG_INIT_HIGH;
+        }
+    }
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  DBG("write configuration data into fpga\n");
+  /* write configuration-data into fpga... */
+
+#ifdef CFG_FPGA_SPARTAN2
+  /*
+   * Load uncompressed image into fpga
+   */
+  for (i=index; i<size; i++)
+    {
+      for (j=0; j<8; j++)
+        {
+          if ((fpgadata[i] & 0x80) == 0x80)
+	    {
+              FPGA_WRITE_1;
+	    }
+          else
+	    {
+              FPGA_WRITE_0;
+	    }
+          fpgadata[i] <<= 1;
+        }
+    }
+#else
+  /* send 0xff 0x20 */
+  FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
+  FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
+  FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_1; FPGA_WRITE_0;
+  FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0;
+
+  /*
+  ** Bit_DeCompression
+  **   Code 1           .. maxOnes     : n                 '1's followed by '0'
+  **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0'
+  **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1'
+  **        255                        :                   '1'
+  */
+
+  for (i=index; i<size; i++)
+    {
+      b = fpgadata[i];
+      if ((b >= 1) && (b <= MAX_ONES))
+	{
+	  for(bit=0; bit<b; bit++)
+            {
+              FPGA_WRITE_1;
+            }
+	  FPGA_WRITE_0;
+	}
+      else if (b == (MAX_ONES+1))
+	{
+	  for(bit=1; bit<b; bit++)
+            {
+              FPGA_WRITE_1;
+            }
+	}
+      else if ((b >= (MAX_ONES+2)) && (b <= 254))
+	{
+	  for(bit=0; bit<(b-(MAX_ONES+2)); bit++)
+            {
+              FPGA_WRITE_0;
+            }
+          FPGA_WRITE_1;
+	}
+      else if (b == 255)
+        {
+          FPGA_WRITE_1;
+        }
+    }
+#endif
+
+  DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
+  DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );
+
+  /*
+   * Check if fpga's DONE signal - correctly booted ?
+   */
+
+  /* Wait for FPGA end of programming period .  */
+  count = 0;
+  while (!(in32(IBM405GP_GPIO0_IR) & FPGA_DONE))
+    {
+      udelay(1000); /* wait 1ms */
+      /* Check for timeout */
+      if (count++ > 3)
+        {
+          DBG("FPGA: Booting failed!\n");
+          return ERROR_FPGA_PRG_DONE;
+        }
+    }
+
+  DBG("FPGA: Booting successful!\n");
+  return 0;
+}
diff --git a/board/esd/common/pci.c b/board/esd/common/pci.c
new file mode 100644
index 0000000..f8f180c
--- /dev/null
+++ b/board/esd/common/pci.c
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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 <ppc4xx.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+
+u_long pci9054_iobase;
+
+
+#define PCI_PRIMARY_CAR	(0x500000dc) /* PCI config address reg */
+#define PCI_PRIMARY_CDR	(0x80000000) /* PCI config data    reg */
+
+
+/*-----------------------------------------------------------------------------+
+|  Subroutine:  pci9054_read_config_dword
+|  Description: Read a PCI configuration register
+|  Inputs:
+|               hose            PCI Controller
+|               dev             PCI Bus+Device+Function number
+|               offset          Configuration register number
+|               value           Address of the configuration register value
+|  Return value:
+|               0               Successful
++-----------------------------------------------------------------------------*/
+int pci9054_read_config_dword(struct pci_controller *hose,
+			      pci_dev_t dev, int offset, u32* value)
+{
+  unsigned long      conAdrVal;
+  unsigned long      val;
+
+  /* generate coded value for CON_ADR register */
+  conAdrVal = dev | (offset & 0xfc) | 0x80000000;
+
+  /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
+  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
+
+  /* Note: *pResult comes back as -1 if machine check happened */
+  val = in32r(PCI_PRIMARY_CDR);
+
+  *value = (unsigned long) val;
+
+  out32r(PCI_PRIMARY_CAR, 0);
+
+  if ((*(unsigned long *)0x50000304) & 0x60000000)
+    {
+      /* clear pci master/target abort bits */
+      *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
+    }
+
+  return 0;
+}
+
+/*-----------------------------------------------------------------------------+
+|  Subroutine:  pci9054_write_config_dword
+|  Description: Write a PCI configuration register.
+|  Inputs:
+|               hose            PCI Controller
+|               dev             PCI Bus+Device+Function number
+|               offset          Configuration register number
+|               Value           Configuration register value
+|  Return value:
+|               0               Successful
+| Updated for pass2 errata #6. Need to disable interrupts and clear the
+| PCICFGADR reg after writing the PCICFGDATA reg.
++-----------------------------------------------------------------------------*/
+int pci9054_write_config_dword(struct pci_controller *hose,
+			       pci_dev_t dev, int offset, u32 value)
+{
+  unsigned long      conAdrVal;
+
+  conAdrVal = dev | (offset & 0xfc) | 0x80000000;
+
+  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
+
+  out32r(PCI_PRIMARY_CDR, value);
+
+  out32r(PCI_PRIMARY_CAR, 0);
+
+  /* clear pci master/target abort bits */
+  *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
+
+  return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+#ifdef CONFIG_DASA_SIM
+static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev,
+					struct pci_config_table *_)
+{
+  unsigned int iobase;
+  unsigned short status = 0;
+  unsigned char timer;
+
+  /*
+   * Configure PLX PCI9054
+   */
+  pci_read_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, &status);
+  status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+  pci_write_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, status);
+
+  /* Check the latency timer for values >= 0x60.
+   */
+  pci_read_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer);
+  if (timer < 0x60)
+    {
+      pci_write_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60);
+    }
+
+  /* Set I/O base register.
+   */
+  pci_write_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CFG_PCI9054_IOBASE);
+  pci_read_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase);
+
+  pci9054_iobase = pci_mem_to_phys(CFG_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK);
+
+  if (pci9054_iobase == 0xffffffff)
+    {
+      printf("Error: Can not set I/O base register.\n");
+      return;
+    }
+}
+#endif
+
+static struct pci_config_table pci9054_config_table[] = {
+#ifndef CONFIG_PCI_PNP
+  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+    PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
+    pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
+				 CFG_ETH_IOBASE,
+				 PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
+#ifdef CONFIG_DASA_SIM
+  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+    PCI_BUS(CFG_PCI9054_DEV_FN), PCI_DEV(CFG_PCI9054_DEV_FN), PCI_FUNC(CFG_PCI9054_DEV_FN),
+    pci_dasa_sim_config_pci9054 },
+#endif
+#endif
+  { }
+};
+
+static struct pci_controller pci9054_hose = {
+  config_table: pci9054_config_table,
+};
+
+void pci_init(void)
+{
+  struct pci_controller *hose = &pci9054_hose;
+
+  /*
+   * Register the hose
+   */
+  hose->first_busno = 0;
+  hose->last_busno = 0xff;
+
+  /* System memory space */
+  pci_set_region(hose->regions + 0,
+		 0x00000000, 0x00000000, 0x01000000,
+		 PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+  /* PCI Memory space */
+  pci_set_region(hose->regions + 1,
+		 0x00000000, 0xc0000000, 0x10000000,
+		 PCI_REGION_MEM);
+
+  pci_set_ops(hose,
+	      pci_hose_read_config_byte_via_dword,
+	      pci_hose_read_config_word_via_dword,
+	      pci9054_read_config_dword,
+	      pci_hose_write_config_byte_via_dword,
+	      pci_hose_write_config_word_via_dword,
+	      pci9054_write_config_dword);
+
+  hose->region_count = 2;
+
+  pci_register_hose(hose);
+
+  hose->last_busno = pci_hose_scan(hose);
+}
diff --git a/board/esd/cpci405/cpci405.c b/board/esd/cpci405/cpci405.c
new file mode 100644
index 0000000..2dda8fa
--- /dev/null
+++ b/board/esd/cpci405/cpci405.c
@@ -0,0 +1,451 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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/processor.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <malloc.h>
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+/* fpga configuration data - generated by bin2cc */
+const unsigned char fpgadata[] =
+{
+#ifdef CONFIG_CPCI405_VER2
+# include "fpgadata_cpci4052.c"
+#else
+# include "fpgadata_cpci405.c"
+#endif
+};
+
+/*
+ * include common fpga code (for esd boards)
+ */
+#include "../common/fpga.c"
+
+
+/* Prototypes */
+int version2(void);
+int gunzip(void *, int, unsigned char *, int *);
+
+
+int board_pre_init (void)
+{
+#ifndef CONFIG_CPCI405_VER2
+	int index, len, i;
+	int status;
+#endif
+
+#ifdef FPGA_DEBUG
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* set up serial port with default baudrate */
+	(void) get_clocks ();
+	gd->baudrate = CONFIG_BAUDRATE;
+	serial_init ();
+	console_init_f();
+#endif
+
+	/*
+	 * First pull fpga-prg pin low, to disable fpga logic (on version 2 board)
+	 */
+	out32(IBM405GP_GPIO0_ODR, 0x00000000);        /* no open drain pins      */
+	out32(IBM405GP_GPIO0_TCR, CFG_FPGA_PRG);      /* setup for output        */
+	out32(IBM405GP_GPIO0_OR,  CFG_FPGA_PRG);      /* set output pins to high */
+	out32(IBM405GP_GPIO0_OR, 0);                  /* pull prg low            */
+
+	/*
+	 * Boot onboard FPGA
+	 */
+#ifndef CONFIG_CPCI405_VER2
+	if (!version2()) {
+		status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata));
+		if (status != 0) {
+			/* booting FPGA failed */
+#ifndef FPGA_DEBUG
+			DECLARE_GLOBAL_DATA_PTR;
+
+			/* set up serial port with default baudrate */
+			(void) get_clocks ();
+			gd->baudrate = CONFIG_BAUDRATE;
+			serial_init ();
+			console_init_f();
+#endif
+			printf("\nFPGA: Booting failed ");
+			switch (status) {
+			case ERROR_FPGA_PRG_INIT_LOW:
+				printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_INIT_HIGH:
+				printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_DONE:
+				printf("(Timeout: DONE not high after programming FPGA)\n ");
+				break;
+			}
+
+			/* display infos on fpgaimage */
+			index = 15;
+			for (i=0; i<4; i++) {
+				len = fpgadata[index];
+				printf("FPGA: %s\n", &(fpgadata[index+1]));
+				index += len+3;
+			}
+			putc ('\n');
+			/* delayed reboot */
+			for (i=20; i>0; i--) {
+				printf("Rebooting in %2d seconds \r",i);
+				for (index=0;index<1000;index++)
+					udelay(1000);
+			}
+			putc ('\n');
+			do_reset(NULL, 0, 0, NULL);
+		}
+	}
+#endif /* !CONFIG_CPCI405_VER2 */
+
+	/*
+	 * 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) CAN0; active low; level sensitive
+	 * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052) ; active low; level sensitive
+	 * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
+	 * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
+	 * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+	 * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
+	 * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
+	 */
+	mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
+	mtdcr(uicer, 0x00000000);       /* disable all ints */
+	mtdcr(uiccr, 0x00000000);       /* set all to be non-critical*/
+	mtdcr(uicpr, 0xFFFFFF81);       /* 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 */
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int ctermm2(void)
+{
+#ifdef CONFIG_CPCI405_VER2
+	return 0;                       /* no, board is cpci405 */
+#else
+	if ((*(unsigned char *)0xf0000400 == 0x00) &&
+	    (*(unsigned char *)0xf0000401 == 0x01))
+		return 0;               /* no, board is cpci405 */
+	else
+		return -1;              /* yes, board is cterm-m2 */
+#endif
+}
+
+
+int cpci405_host(void)
+{
+	if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+		return -1;              /* yes, board is cpci405 host */
+	else
+		return 0;               /* no, board is cpci405 adapter */
+}
+
+
+int version2(void)
+{
+	unsigned long cntrl0Reg;
+	unsigned long value;
+
+	/*
+	 * Setup GPIO pins (CS2/GPIO11 as GPIO)
+	 */
+	cntrl0Reg = mfdcr(cntrl0);
+	mtdcr(cntrl0, cntrl0Reg | 0x02000000);
+
+	udelay(1000);                   /* wait some time before reading input */
+	value = in32(IBM405GP_GPIO0_IR) & 0x00100000; /* test GPIO11 */
+
+	/*
+	 * Setup GPIO pins (CS2/GPIO11 as CS again)
+	 */
+	mtdcr(cntrl0, cntrl0Reg);
+
+	if (value)
+		return 0;               /* no, board is version 1.x */
+	else
+		return -1;              /* yes, board is version 2.x */
+}
+
+
+int misc_init_f (void)
+{
+	return 0;  /* dummy implementation */
+}
+
+
+int misc_init_r (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	bd_t *bd = gd->bd;
+	char *	tmp;                    /* Temporary char pointer      */
+
+#ifdef CONFIG_CPCI405_VER2
+	unsigned char *dst;
+	ulong len = sizeof(fpgadata);
+	int status;
+	int index;
+	int i;
+	unsigned long cntrl0Reg;
+
+	/*
+	 * On CPCI-405 version 2 the environment is saved in eeprom!
+	 * FPGA can be gzip compressed (malloc) and booted this late.
+	 */
+
+	if (version2()) {
+		/*
+		 * Setup GPIO pins (CS6+CS7 as GPIO)
+		 */
+		cntrl0Reg = mfdcr(cntrl0);
+		mtdcr(cntrl0, cntrl0Reg | 0x00300000);
+
+		dst = malloc(CFG_FPGA_MAX_SIZE);
+		if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
+			printf ("GUNZIP ERROR - must RESET board to recover\n");
+			do_reset (NULL, 0, 0, NULL);
+		}
+
+		status = fpga_boot(dst, len);
+		if (status != 0) {
+			printf("\nFPGA: Booting failed ");
+			switch (status) {
+			case ERROR_FPGA_PRG_INIT_LOW:
+				printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_INIT_HIGH:
+				printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+				break;
+			case ERROR_FPGA_PRG_DONE:
+				printf("(Timeout: DONE not high after programming FPGA)\n ");
+				break;
+			}
+
+			/* display infos on fpgaimage */
+			index = 15;
+			for (i=0; i<4; i++) {
+				len = dst[index];
+				printf("FPGA: %s\n", &(dst[index+1]));
+				index += len+3;
+			}
+			putc ('\n');
+			/* delayed reboot */
+			for (i=20; i>0; i--) {
+				printf("Rebooting in %2d seconds \r",i);
+				for (index=0;index<1000;index++)
+					udelay(1000);
+			}
+			putc ('\n');
+			do_reset(NULL, 0, 0, NULL);
+		}
+
+		/* restore gpio/cs settings */
+		mtdcr(cntrl0, cntrl0Reg);
+
+		puts("FPGA:  ");
+
+		/* display infos on fpgaimage */
+		index = 15;
+		for (i=0; i<4; i++) {
+			len = dst[index];
+			printf("%s ", &(dst[index+1]));
+			index += len+3;
+		}
+		putc ('\n');
+
+		free(dst);
+	}
+	else {
+		printf("\n*** U-Boot Version does not match Board Version!\n");
+		printf("*** CPCI-405 Version 2.x detected!\n");
+		printf("*** Please use correct U-Boot version (CPCI4052)!\n\n");
+	}
+
+#else /* CONFIG_CPCI405_VER2 */
+
+	/*
+	 * Generate last byte of ip-addr from code-plug @ 0xf0000400
+	 */
+	if (ctermm2()) {
+		char str[32];
+		unsigned char ipbyte = *(unsigned char *)0xf0000400;
+
+		/*
+		 * Only overwrite ip-addr with allowed values
+		 */
+		if ((ipbyte != 0x00) && (ipbyte != 0xff)) {
+			bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte;
+			sprintf(str, "%ld.%ld.%ld.%ld",
+				(bd->bi_ip_addr & 0xff000000) >> 24,
+				(bd->bi_ip_addr & 0x00ff0000) >> 16,
+				(bd->bi_ip_addr & 0x0000ff00) >> 8,
+				(bd->bi_ip_addr & 0x000000ff));
+			setenv("ipaddr", str);
+		}
+	}
+
+	if (version2()) {
+		printf("\n*** U-Boot Version does not match Board Version!\n");
+		printf("*** CPCI-405 Board Version 1.x detected!\n");
+		printf("*** Please use correct U-Boot version (CPCI405)!\n\n");
+	}
+
+#endif /* CONFIG_CPCI405_VER2 */
+
+	/*
+	 * Write ethernet addr in NVRAM for VxWorks
+	 */
+	tmp = (char *)CFG_NVRAM_BASE_ADDR + CFG_NVRAM_VXWORKS_OFFS;
+	memcpy( (char *)tmp, (char *)&bd->bi_enetaddr[0], 6 );
+	return (0);
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+#ifndef CONFIG_CPCI405_VER2
+	int index;
+	int len;
+#endif
+	unsigned char str[64];
+	int i = getenv_r ("serial#", str, sizeof(str));
+
+	puts ("Board: ");
+
+	if (i == -1) {
+		puts ("### No HW ID - assuming CPCI405");
+	} else {
+		puts(str);
+	}
+
+	if (version2())
+		puts (" (Ver 2.x, ");
+	else
+		puts (" (Ver 1.x, ");
+
+#if 0
+	if ((*(unsigned short *)((unsigned long)CFG_FPGA_BASE_ADDR) + CFG_FPGA_STATUS)
+	    & CFG_FPGA_STATUS_FLASH)
+		puts ("FLASH Bank A, ");
+	else
+		puts ("FLASH Bank B, ");
+#endif
+
+	if (ctermm2()) {
+		printf("CTERM-M2 - Id=0x%02x)", *(unsigned char *)0xf0000400);
+	} else {
+		if (cpci405_host()) {
+			puts ("PCI Host Version)");
+		} else {
+			puts ("PCI Adapter Version)");
+		}
+	}
+
+#ifndef CONFIG_CPCI405_VER2
+	puts ("\nFPGA:  ");
+
+	/* display infos on fpgaimage */
+	index = 15;
+	for (i=0; i<4; i++) {
+		len = fpgadata[index];
+		printf("%s ", &(fpgadata[index+1]));
+		index += len+3;
+	}
+#endif
+
+	putc ('\n');
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+	unsigned long val;
+
+	mtdcr(memcfga, mem_mb0cf);
+	val = mfdcr(memcfgd);
+
+#if 0
+	printf("\nmb0cf=%x\n", val); /* test-only */
+	printf("strap=%x\n", mfdcr(strap)); /* test-only */
+#endif
+
+	return (4*1024*1024 << ((val & 0x000e0000) >> 17));
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("test: 16 MB - ok\n");
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_CPCI405_VER2
+#ifdef CONFIG_IDE_RESET
+
+void ide_set_reset(int on)
+{
+	volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
+
+	/*
+	 * Assert or deassert CompactFlash Reset Pin
+	 */
+	if (on) {		/* assert RESET */
+		*fpga_mode &= ~(CFG_FPGA_MODE_CF_RESET);
+	} else {		/* release RESET */
+		*fpga_mode |= CFG_FPGA_MODE_CF_RESET;
+	}
+}
+
+#endif /* CONFIG_IDE_RESET */
+#endif /* CONFIG_CPCI405_VER2 */
+
+/* ------------------------------------------------------------------------- */
diff --git a/board/esd/cpci440/cpci440.c b/board/esd/cpci440/cpci440.c
new file mode 100644
index 0000000..51a5edd
--- /dev/null
+++ b/board/esd/cpci440/cpci440.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2002
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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/processor.h>
+
+
+long int fixed_sdram( void );
+
+int board_pre_init (void)
+{
+	uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup the external bus controller/chip selects
+	 *-------------------------------------------------------------------*/
+	mtdcr( ebccfga, xbcfg );
+	reg = mfdcr( ebccfgd );
+	mtdcr( ebccfgd, reg | 0x04000000 );	/* Set ATC */
+
+	mtebc( pb0ap, 0x92015480 );	/* FLASH/SRAM */
+	mtebc( pb0cr, 0xFF87A000 ); /* BAS=0xff8 8MB R/W 16-bit */
+	/* test-only: other regs still missing... */
+
+	/*--------------------------------------------------------------------
+	 * Setup the interrupt controller polarities, triggers, etc.
+	 *-------------------------------------------------------------------*/
+	mtdcr( uic0sr, 0xffffffff );    /* clear all */
+	mtdcr( uic0er, 0x00000000 );    /* disable all */
+	mtdcr( uic0cr, 0x00000009 );    /* SMI & UIC1 crit are critical */
+	mtdcr( uic0pr, 0xfffffe13 );    /* per ref-board manual */
+	mtdcr( uic0tr, 0x01c00008 );    /* per ref-board manual */
+	mtdcr( uic0vr, 0x00000001 );    /* int31 highest, base=0x000 */
+	mtdcr( uic0sr, 0xffffffff );    /* clear all */
+
+	mtdcr( uic1sr, 0xffffffff );    /* clear all */
+	mtdcr( uic1er, 0x00000000 );    /* disable all */
+	mtdcr( uic1cr, 0x00000000 );    /* all non-critical */
+	mtdcr( uic1pr, 0xffffe0ff );    /* per ref-board manual */
+	mtdcr( uic1tr, 0x00ffc000 );    /* per ref-board manual */
+	mtdcr( uic1vr, 0x00000001 );    /* int31 highest, base=0x000 */
+	mtdcr( uic1sr, 0xffffffff );    /* clear all */
+
+	return 0;
+}
+
+
+
+int checkboard (void)
+{
+	sys_info_t sysinfo;
+	get_sys_info(&sysinfo);
+
+	printf("Board: esd CPCI-440\n");
+	printf("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz/1000000);
+	printf("\tCPU: %lu MHz\n", sysinfo.freqProcessor/1000000);
+	printf("\tPLB: %lu MHz\n", sysinfo.freqPLB/1000000);
+	printf("\tOPB: %lu MHz\n", sysinfo.freqOPB/1000000);
+	printf("\tEPB: %lu MHz\n", sysinfo.freqEPB/1000000);
+	return (0);
+}
+
+
+long int initdram (int board_type)
+{
+	long    dram_size = 0;
+
+	dram_size = fixed_sdram();
+	return dram_size;
+}
+
+
+/*************************************************************************
+ *  fixed sdram init -- doesn't use serial presence detect.
+ *
+ *  Assumes:    64 MB, non-ECC, non-registered
+ *              PLB @ 133 MHz
+ *
+ ************************************************************************/
+long int fixed_sdram( void )
+{
+	uint    reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup some default
+	 *------------------------------------------------------------------*/
+	mtsdram( mem_uabba, 0x00000000 );   /* ubba=0 (default)             */
+	mtsdram( mem_slio,  0x00000000 );   /* rdre=0 wrre=0 rarw=0         */
+	mtsdram( mem_devopt,0x00000000 );   /* dll=0 ds=0 (normal)          */
+	mtsdram( mem_wddctr,0x40000000 );   /* wrcp=0 dcd=0                 */
+	mtsdram( mem_clktr, 0x40000000 );   /* clkp=1 (90 deg wr) dcdt=0    */
+
+	/*--------------------------------------------------------------------
+	 * Setup for board-specific specific mem
+	 *------------------------------------------------------------------*/
+	/*
+	 * Following for CAS Latency = 2.5 @ 133 MHz PLB
+	 */
+	mtsdram( mem_b0cr, 0x00082001 );/* SDBA=0x000, 64MB, Mode 2, enabled*/
+	mtsdram( mem_tr0,  0x410a4012 );/* WR=2  WD=1 CL=2.5 PA=3 CP=4 LD=2 */
+	/* RA=10 RD=3                       */
+	mtsdram( mem_tr1,  0x8080082f );/* SS=T2 SL=STAGE 3 CD=1 CT=0x02f   */
+	mtsdram( mem_rtr,  0x08200000 );/* Rate 15.625 ns @ 133 MHz PLB     */
+	mtsdram( mem_cfg1, 0x00000000 );/* Self-refresh exit, disable PM    */
+	udelay( 400 );                  /* Delay 200 usecs (min)            */
+
+	/*--------------------------------------------------------------------
+	 * Enable the controller, then wait for DCEN to complete
+	 *------------------------------------------------------------------*/
+	mtsdram( mem_cfg0, 0x86000000 );/* DCEN=1, PMUD=1, 64-bit           */
+	for(;;)
+	{
+		mfsdram( mem_mcsts, reg );
+		if( reg & 0x80000000 )
+			break;
+	}
+
+	return( 64 * 1024 * 1024 );      /* 64 MB                           */
+}
diff --git a/board/esd/cpci440/init.S b/board/esd/cpci440/init.S
new file mode 100644
index 0000000..2dab9f9
--- /dev/null
+++ b/board/esd/cpci440/init.S
@@ -0,0 +1,96 @@
+/*
+*  Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
+*
+* 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 <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID   0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K	    0x00000000
+#define SZ_4K	    0x00000010
+#define SZ_16K	    0x00000020
+#define SZ_64K	    0x00000030
+#define SZ_256K	    0x00000040
+#define SZ_1M	    0x00000050
+#define SZ_16M	    0x00000070
+#define SZ_256M	    0x00000090
+
+/* Storage attributes */
+#define SA_W	    0x00000800	    /* Write-through */
+#define SA_I	    0x00000400	    /* Caching inhibited */
+#define SA_M	    0x00000200	    /* Memory coherence */
+#define SA_G	    0x00000100	    /* Guarded */
+#define SA_E	    0x00000080	    /* Endian */
+
+/* Access control */
+#define AC_X	    0x00000024	    /* Execute */
+#define AC_W	    0x00000012	    /* Write */
+#define AC_R	    0x00000009	    /* Read */
+
+/* Some handy macros */
+
+#define EPN(e)		((e) & 0xfffffc00)
+#define TLB0(epn,sz)	( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn)	( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a)		( (a)&0x00000fbf )
+
+#define tlbtab_start\
+	mflr    r1  ;\
+	bl 0f	    ;
+
+#define tlbtab_end\
+	.long 0, 0, 0	;   \
+0:	mflr    r0	;   \
+	mtlr    r1	;   \
+	blr		;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+	.long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ *  Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+    .section .bootpg,"ax"
+    .globl tlbtab
+
+tlbtab:
+    tlbtab_start
+    tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+    tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+    tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
+    tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X )
+    tlbtab_end
+
+
diff --git a/board/esd/pci405/pci405.c b/board/esd/pci405/pci405.c
new file mode 100644
index 0000000..ed86c02
--- /dev/null
+++ b/board/esd/pci405/pci405.c
@@ -0,0 +1,254 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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/processor.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <malloc.h>
+#include <pci.h>
+#include <405gp_pci.h>
+
+/* ------------------------------------------------------------------------- */
+
+#if 0
+#define FPGA_DEBUG
+#endif
+
+#define PCI_RECONFIG_MAGIC       0x07081967
+
+
+struct pci_config_regs {
+	unsigned short  command;
+	unsigned char   latency_timer;
+	unsigned char   int_line;
+	unsigned long   bar1;
+	unsigned long   bar2;
+	unsigned long   magic;
+};
+
+
+/* fpga configuration data - generated by bin2cc */
+const unsigned char fpgadata[] =
+{
+#include "fpgadata.c"
+};
+
+/*
+ * include common fpga code (for esd boards)
+ */
+#include "../common/fpga.c"
+
+
+/* Prototypes */
+int gunzip(void *, int, unsigned char *, int *);
+
+
+int board_pre_init (void)
+{
+	unsigned long cntrl0Reg;
+
+	/*
+	 * 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) CAN0; active low; level sensitive
+	 * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive
+	 * IRQ 27 (EXT IRQ 2) CAN2; active low; level sensitive
+	 * IRQ 28 (EXT IRQ 3) CAN3; active low; level sensitive
+	 * IRQ 29 (EXT IRQ 4) unused; active low; level sensitive
+	 * IRQ 30 (EXT IRQ 5) FPGA Timestamp; active low; level sensitive
+	 * IRQ 31 (EXT IRQ 6) PCI Reset; active low; level sensitive
+	 */
+	mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
+	mtdcr(uicer, 0x00000000);        /* disable all ints */
+	mtdcr(uiccr, 0x00000000);        /* set all to be non-critical*/
+	mtdcr(uicpr, 0xFFFFFF80);        /* 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 */
+
+	/*
+	 * Setup GPIO pins (IRQ4/GPIO21 as GPIO)
+	 */
+	cntrl0Reg = mfdcr(cntrl0);
+	mtdcr(cntrl0, cntrl0Reg | 0x00008000);
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_f (void)
+{
+	return 0;  /* dummy implementation */
+}
+
+
+int misc_init_r (void)
+{
+	unsigned char *dst;
+	ulong len = sizeof(fpgadata);
+	int status;
+	int index;
+	int i;
+	struct pci_config_regs *pci_regs;
+
+	/*
+	 * On PCI-405 the environment is saved in eeprom!
+	 * FPGA can be gzip compressed (malloc) and booted this late.
+	 */
+
+	dst = malloc(CFG_FPGA_MAX_SIZE);
+	if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
+		printf ("GUNZIP ERROR - must RESET board to recover\n");
+		do_reset (NULL, 0, 0, NULL);
+	}
+
+	status = fpga_boot(dst, len);
+	if (status != 0) {
+		printf("\nFPGA: Booting failed ");
+		switch (status) {
+		case ERROR_FPGA_PRG_INIT_LOW:
+			printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
+			break;
+		case ERROR_FPGA_PRG_INIT_HIGH:
+			printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
+			break;
+		case ERROR_FPGA_PRG_DONE:
+			printf("(Timeout: DONE not high after programming FPGA)\n ");
+			break;
+		}
+
+		/* display infos on fpgaimage */
+		index = 15;
+		for (i=0; i<4; i++) {
+			len = dst[index];
+			printf("FPGA: %s\n", &(dst[index+1]));
+			index += len+3;
+		}
+		putc ('\n');
+		/* delayed reboot */
+		for (i=20; i>0; i--) {
+			printf("Rebooting in %2d seconds \r",i);
+			for (index=0;index<1000;index++)
+				udelay(1000);
+		}
+		putc ('\n');
+		do_reset(NULL, 0, 0, NULL);
+	}
+
+	puts("FPGA:  ");
+
+	/* display infos on fpgaimage */
+	index = 15;
+	for (i=0; i<4; i++) {
+		len = dst[index];
+		printf("%s ", &(dst[index+1]));
+		index += len+3;
+	}
+	putc ('\n');
+
+	/*
+	 * Rewrite pci config regs (only after soft-reset with magic set)
+	 */
+	pci_regs = (struct pci_config_regs *)0x10;
+	if (pci_regs->magic == PCI_RECONFIG_MAGIC) {
+		puts("PCI:   Found magic, rewriting config regs...\n");
+		pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND,
+				      pci_regs->command);
+		pci_write_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER,
+				      pci_regs->latency_timer);
+		pci_write_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE,
+				      pci_regs->int_line);
+		pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1,
+				       pci_regs->bar1);
+		pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2,
+				       pci_regs->bar2);
+	}
+	pci_regs->magic = 0; /* clear magic again */
+
+#if 0 /* test-only */
+	pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &(pci_regs->command));
+	pci_read_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER, &(pci_regs->latency_timer));
+	pci_read_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE, &(pci_regs->int_line));
+	pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, &(pci_regs->bar1));
+	pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, &(pci_regs->bar2));
+	pci_regs->magic = PCI_RECONFIG_MAGIC; /* set magic */
+#endif
+
+	free(dst);
+	return (0);
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+	unsigned char str[64];
+	int i = getenv_r ("serial#", str, sizeof(str));
+
+	puts ("Board: ");
+
+	if (i == -1) {
+		puts ("### No HW ID - assuming CPCI405");
+	} else {
+		puts (str);
+	}
+	putc ('\n');
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+	unsigned long val;
+
+	mtdcr(memcfga, mem_mb0cf);
+	val = mfdcr(memcfgd);
+
+#if 0
+	printf("\nmb0cf=%x\n", val); /* test-only */
+	printf("strap=%x\n", mfdcr(strap)); /* test-only */
+#endif
+
+	return (4*1024*1024 << ((val & 0x000e0000) >> 17));
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("test: 16 MB - ok\n");
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/board/evb64260/eth_addrtbl.c b/board/evb64260/eth_addrtbl.c
new file mode 100644
index 0000000..ea4925a
--- /dev/null
+++ b/board/evb64260/eth_addrtbl.c
@@ -0,0 +1,225 @@
+#include <common.h>
+#include <malloc.h>
+#include <galileo/gt64260R.h>
+#include <galileo/core.h>
+#include <asm/cache.h>
+#include "eth.h"
+#include "eth_addrtbl.h"
+
+#define TRUE 1
+#define FALSE 0
+
+#define PRINTF printf
+
+#ifdef CONFIG_GT_USE_MAC_HASH_TABLE
+
+static u32           addressTableHashMode[ GAL_ETH_DEVS ] = { 0, };
+static u32           addressTableHashSize[ GAL_ETH_DEVS ] = { 0, };
+static addrTblEntry *addressTableBase[     GAL_ETH_DEVS ] = { 0, };
+static void         *realAddrTableBase[    GAL_ETH_DEVS ] = { 0, };
+
+static const u32 hashLength[ 2 ] = {
+    (0x8000),             /* 8K * 4 entries */
+    (0x8000/16),          /* 512 * 4 entries */
+};
+
+/* Initialize the address table for a port, if needed */
+unsigned int initAddressTable( u32 port, u32 hashMode, u32 hashSizeSelector)
+{
+    unsigned int tableBase;
+
+    if( port < 0 || port >= GAL_ETH_DEVS ) {
+		printf("%s: Invalid port number %d\n", __FUNCTION__, port );
+		return 0;
+	}
+
+	if (hashMode > 1) {
+		printf("%s: Invalid Hash Mode %d\n", __FUNCTION__, port );
+		return 0;
+	}
+
+	if ( realAddrTableBase[port] &&
+		( addressTableHashSize[port] != hashSizeSelector )) {
+		/* we have been here before,
+		 * but now we want a different sized table
+		 */
+		free( realAddrTableBase[port] );
+		realAddrTableBase[port] = 0;
+		addressTableBase[port] = 0;
+
+	}
+
+	tableBase = (unsigned int)addressTableBase[port];
+	/* we get called for every probe, so only do this once */
+	if ( !tableBase ) {
+    	int bytes = hashLength[hashSizeSelector] * sizeof(addrTblEntry);
+
+		tableBase = (unsigned int)realAddrTableBase[port] = malloc(bytes+64);
+
+	    if(!tableBase)
+		{
+			printf("%s: alloc memory failed \n", __FUNCTION__);
+			return 0;
+		}
+
+    	/* align to octal byte */
+	    if(tableBase&63) tableBase=(tableBase+63) & ~63;
+
+    	addressTableHashMode[port] = hashMode;
+	    addressTableHashSize[port] = hashSizeSelector;
+    	addressTableBase[port] = (addrTblEntry *)tableBase;
+
+	    memset((void *)tableBase,0,bytes);
+	}
+
+    return tableBase;
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will calculate the hash function of the address.
+ * depends on the hash mode and hash size.
+ * Inputs
+ * macH             - the 2 most significant bytes of the MAC address.
+ * macL             - the 4 least significant bytes of the MAC address.
+ * hashMode         - hash mode 0 or hash mode 1.
+ * hashSizeSelector - indicates number of hash table entries (0=0x8000,1=0x800)
+ * Outputs
+ * return the calculated entry.
+ */
+u32
+hashTableFunction( u32 macH, u32 macL, u32 HashSize, u32 hash_mode)
+{
+    u32 hashResult;
+    u32 addrH;
+    u32 addrL;
+    u32 addr0;
+    u32 addr1;
+    u32 addr2;
+    u32 addr3;
+    u32 addrHSwapped;
+    u32 addrLSwapped;
+
+
+    addrH = NIBBLE_SWAPPING_16_BIT( macH );
+    addrL = NIBBLE_SWAPPING_32_BIT( macL );
+
+    addrHSwapped =   FLIP_4_BITS(  addrH        & 0xf )
+                 + ((FLIP_4_BITS( (addrH >>  4) & 0xf)) <<  4)
+                 + ((FLIP_4_BITS( (addrH >>  8) & 0xf)) <<  8)
+                 + ((FLIP_4_BITS( (addrH >> 12) & 0xf)) << 12);
+
+    addrLSwapped =   FLIP_4_BITS(  addrL        & 0xf )
+                 + ((FLIP_4_BITS( (addrL >>  4) & 0xf)) <<  4)
+                 + ((FLIP_4_BITS( (addrL >>  8) & 0xf)) <<  8)
+                 + ((FLIP_4_BITS( (addrL >> 12) & 0xf)) << 12)
+                 + ((FLIP_4_BITS( (addrL >> 16) & 0xf)) << 16)
+                 + ((FLIP_4_BITS( (addrL >> 20) & 0xf)) << 20)
+                 + ((FLIP_4_BITS( (addrL >> 24) & 0xf)) << 24)
+                 + ((FLIP_4_BITS( (addrL >> 28) & 0xf)) << 28);
+
+    addrH = addrHSwapped;
+    addrL = addrLSwapped;
+
+    if( hash_mode == 0 )  {
+        addr0 =  (addrL >>  2) & 0x03f;
+        addr1 =  (addrL        & 0x003) | ((addrL >> 8) & 0x7f) << 2;
+        addr2 =  (addrL >> 15) & 0x1ff;
+        addr3 = ((addrL >> 24) & 0x0ff) | ((addrH &  1)         << 8);
+    } else  {
+        addr0 = FLIP_6_BITS(    addrL        & 0x03f );
+        addr1 = FLIP_9_BITS(  ((addrL >>  6) & 0x1ff));
+        addr2 = FLIP_9_BITS(   (addrL >> 15) & 0x1ff);
+        addr3 = FLIP_9_BITS( (((addrL >> 24) & 0x0ff) | ((addrH & 0x1) << 8)));
+    }
+
+    hashResult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
+
+    if( HashSize == _8K_TABLE )  {
+        hashResult = hashResult & 0xffff;
+    } else  {
+        hashResult = hashResult & 0x07ff;
+    }
+
+    return( hashResult );
+}
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will add an entry to the address table.
+ * depends on the hash mode and hash size that was initialized.
+ * Inputs
+ * port - ETHERNET port number.
+ * macH - the 2 most significant bytes of the MAC address.
+ * macL - the 4 least significant bytes of the MAC address.
+ * skip - if 1, skip this address.
+ * rd   - the RD field in the address table.
+ * Outputs
+ * address table entry is added.
+ * TRUE if success.
+ * FALSE if table full
+ */
+int
+addAddressTableEntry(
+    u32           port,
+    u32           macH,
+    u32           macL,
+    u32           rd,
+    u32           skip         )
+{
+    addrTblEntry *entry;
+    u32           newHi;
+    u32           newLo;
+    u32           i;
+
+    newLo = (((macH >>  4) & 0xf) << 15)
+          | (((macH >>  0) & 0xf) << 11)
+          | (((macH >> 12) & 0xf) <<  7)
+          | (((macH >>  8) & 0xf) <<  3)
+          | (((macL >> 20) & 0x1) << 31)
+          | (((macL >> 16) & 0xf) << 27)
+          | (((macL >> 28) & 0xf) << 23)
+          | (((macL >> 24) & 0xf) << 19)
+          |   (skip << SKIP_BIT)  |  (rd << 2) | VALID;
+
+    newHi = (((macL >>  4) & 0xf) << 15)
+          | (((macL >>  0) & 0xf) << 11)
+          | (((macL >> 12) & 0xf) <<  7)
+          | (((macL >>  8) & 0xf) <<  3)
+          | (((macL >> 21) & 0x7) <<  0);
+
+    /*
+     * Pick the appropriate table, start scanning for free/reusable
+     * entries at the index obtained by hashing the specified MAC address
+     */
+    entry  = addressTableBase[port];
+    entry += hashTableFunction( macH, macL, addressTableHashSize[port],
+                                            addressTableHashMode[port]  );
+    for( i = 0;  i < HOP_NUMBER;  i++, entry++ )  {
+        if( !(entry->lo & VALID)   /*|| (entry->lo & SKIP)*/   )  {
+            break;
+        } else  {                    /* if same address put in same position */
+            if(   ((entry->lo & 0xfffffff8) == (newLo & 0xfffffff8))
+                && (entry->hi               ==  newHi) )
+            {
+                    break;
+            }
+        }
+    }
+
+    if( i == HOP_NUMBER )  {
+        PRINTF( "addGT64260addressTableEntry: table section is full\n" );
+        return( FALSE );
+    }
+
+    /*
+     * Update the selected entry
+     */
+    entry->hi = newHi;
+    entry->lo = newLo;
+    DCACHE_FLUSH_N_SYNC( (u32)entry, MAC_ENTRY_SIZE );
+    return( TRUE );
+}
+
+#endif /* CONFIG_GT_USE_MAC_HASH_TABLE */
diff --git a/board/evb64260/pci.c b/board/evb64260/pci.c
new file mode 100644
index 0000000..8e9178d
--- /dev/null
+++ b/board/evb64260/pci.c
@@ -0,0 +1,691 @@
+/* PCI.c - PCI functions */
+
+/* Copyright - Galileo technology. */
+
+#include <common.h>
+#include <pci.h>
+
+#include <galileo/pci.h>
+
+static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
+#ifdef CONFIG_ZUMA_V2
+    {0,0,0,0,0,0,0,29, [8 ... PCI_MAX_DEVICES-1]=0},
+    {0,0,0,0,0,0,0,28, [8 ... PCI_MAX_DEVICES-1]=0}
+#else	/* EVB??? This is a guess */
+    {0,0,0,0,0,0,0,27,27, [9 ... PCI_MAX_DEVICES-1]=0},
+    {0,0,0,0,0,0,0,29,29, [9 ... PCI_MAX_DEVICES-1]=0}
+#endif
+};
+
+static const unsigned int pci_p2p_configuration_reg[]={
+    PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
+
+static const unsigned int pci_configuration_address[]={
+    PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS};
+
+static const unsigned int pci_configuration_data[]={
+    PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+    PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER};
+
+static const unsigned int pci_error_cause_reg[]={
+    PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE};
+
+static const unsigned int pci_arbiter_control[]={
+    PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL};
+
+static const unsigned int pci_snoop_control_base_0_low[]={
+    PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW};
+static const unsigned int pci_snoop_control_top_0[]={
+    PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0};
+
+static const unsigned int pci_access_control_base_0_low[]={
+    PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW};
+static const unsigned int pci_access_control_top_0[]={
+    PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0};
+
+static const unsigned int pci_scs_bank_size[2][4] = {
+    {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
+     PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
+    {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
+     PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}};
+
+static const unsigned int pci_p2p_configuration[] = {
+    PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
+
+/********************************************************************
+* pciWriteConfigReg - Write to a PCI configuration register
+*                    - Make sure the GT is configured as a master before writing
+*                      to another device on the PCI.
+*                    - The function takes care of Big/Little endian conversion.
+*
+*
+* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec
+*                   (or any other PCI device spec)
+*           pciDevNum: The device number needs to be addressed.
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum,unsigned int data)
+{
+    volatile unsigned int DataForAddrReg;
+    unsigned int functionNum;
+    unsigned int busNum = 0;
+    unsigned int addr;
+
+    if(pciDevNum > 32) /* illegal device Number */
+        return;
+    if(pciDevNum == SELF) /* configure our configuration space. */
+    {
+        pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
+        busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
+    }
+    functionNum =  regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xfc;
+    DataForAddrReg = ( regOffset | pciDevNum | functionNum | busNum) | BIT31;
+    GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
+    GT_REG_READ(pci_configuration_address[host], &addr);
+    if (addr != DataForAddrReg) return;
+    GT_REG_WRITE(pci_configuration_data[host],data);
+}
+
+/********************************************************************
+* pciReadConfigReg  - Read from a PCI0 configuration register
+*                    - Make sure the GT is configured as a master before reading
+*                     from another device on the PCI.
+*                   - The function takes care of Big/Little endian conversion.
+* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+*                        spec)
+*           pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+*                 cause register to make sure the data is valid
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|00|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum)
+{
+    volatile unsigned int DataForAddrReg;
+   	unsigned int data;
+    unsigned int functionNum;
+    unsigned int busNum = 0;
+
+    if(pciDevNum > 32) /* illegal device Number */
+        return 0xffffffff;
+    if(pciDevNum == SELF) /* configure our configuration space. */
+    {
+        pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
+        busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
+    }
+    functionNum = regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xfc;
+    DataForAddrReg = (regOffset | pciDevNum | functionNum | busNum) | BIT31 ;
+    GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
+    GT_REG_READ(pci_configuration_address[host], &data);
+    if (data != DataForAddrReg)
+        return 0xffffffff;
+    GT_REG_READ(pci_configuration_data[host], &data);
+    return data;
+}
+
+/********************************************************************
+* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
+*                               the agent is placed on another Bus. For more
+*                               information read P2P in the PCI spec.
+*
+* Inputs:   unsigned int regOffset - The register offset as it apears in the
+*           GT spec (or any other PCI device spec).
+*           unsigned int pciDevNum - The device number needs to be addressed.
+*           unsigned int busNum - On which bus does the Target agent connect
+*                                 to.
+*           unsigned int data - data to be written.
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|01|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*  The configuration Address is configure as type-I (bits[1:0] = '01') due to
+*   PCI spec referring to P2P.
+*
+*********************************************************************/
+void pciOverBridgeWriteConfigReg(PCI_HOST host,
+				 unsigned int regOffset,
+                                 unsigned int pciDevNum,
+                                 unsigned int busNum,unsigned int data)
+{
+   	unsigned int   DataForReg;
+    unsigned int   functionNum;
+
+   	functionNum =  regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xff;
+    busNum = busNum << 16;
+    if(pciDevNum == SELF) /* This board */
+    {
+        DataForReg = ( regOffset | pciDevNum | functionNum) | BIT0;
+    }
+    else
+    {
+        DataForReg = ( regOffset | pciDevNum | functionNum | busNum) |
+            BIT31 | BIT0;
+    }
+    GT_REG_WRITE(pci_configuration_address[host],DataForReg);
+    if(pciDevNum == SELF) /* This board */
+    {
+        GT_REG_WRITE(pci_configuration_data[host],data);
+    }
+    else /* configuration Transaction over the pci. */
+    {
+        /* The PCI is working in LE Mode So it swap the Data. */
+        GT_REG_WRITE(pci_configuration_data[host],WORD_SWAP(data));
+    }
+}
+
+
+/********************************************************************
+* pciOverBridgeReadConfigReg  - Read from a PCIn configuration register where
+*                               the agent target locate on another PCI bus.
+*                             - Make sure the GT is configured as a master
+*                               before reading from another device on the PCI.
+*                             - The function takes care of Big/Little endian
+*                               conversion.
+* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+*                        spec). (configuration register offset.)
+*           pciDevNum: The device number needs to be addressed.
+*           busNum: the Bus number where the agent is place.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+*                 cause register to make sure the data is valid
+*
+*  Configuration Address 0xCF8:
+*
+*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+*  |congif|Reserved|  Bus |Device|Function|Register|01|
+*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+*
+*********************************************************************/
+unsigned int pciOverBridgeReadConfigReg(PCI_HOST host,
+					unsigned int regOffset,
+                                        unsigned int pciDevNum,
+                                        unsigned int busNum)
+{
+    unsigned int DataForReg;
+    unsigned int data;
+    unsigned int functionNum;
+
+    functionNum = regOffset & 0x00000700;
+    pciDevNum = pciDevNum << 11;
+    regOffset = regOffset & 0xff;
+    busNum = busNum << 16;
+    if (pciDevNum == SELF) /* This board */
+    {
+        DataForReg = (regOffset | pciDevNum | functionNum) | BIT31 ;
+    }
+    else /* agent on another bus */
+    {
+        DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
+        BIT0 | BIT31 ;
+    }
+    GT_REG_WRITE(pci_configuration_address[host],DataForReg);
+    if (pciDevNum == SELF) /* This board */
+   	{
+        GT_REG_READ(pci_configuration_data[host], &data);
+    	return data;
+    }
+    else /* The PCI is working in LE Mode So it swap the Data. */
+    {
+        GT_REG_READ(pci_configuration_data[host], &data);
+    	return WORD_SWAP(data);
+    }
+}
+
+/********************************************************************
+* pciGetRegOffset - Gets the register offset for this region config.
+*
+* INPUT:   Bus, Region - The bus and region we ask for its base address.
+* OUTPUT:   N/A
+* RETURNS: PCI register base address
+*********************************************************************/
+static unsigned int pciGetRegOffset(PCI_HOST host, PCI_REGION region)
+{
+    switch (host)
+    {
+	case PCI_HOST0:
+	    switch(region) {
+		case PCI_IO:		return PCI_0I_O_LOW_DECODE_ADDRESS;
+		case PCI_REGION0:	return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+		case PCI_REGION1:	return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
+		case PCI_REGION2:	return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
+		case PCI_REGION3:	return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
+	    }
+	case PCI_HOST1:
+	    switch(region) {
+		case PCI_IO:		return PCI_1I_O_LOW_DECODE_ADDRESS;
+		case PCI_REGION0:	return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
+		case PCI_REGION1:	return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
+		case PCI_REGION2:	return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
+		case PCI_REGION3:	return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
+	    }
+    }
+    return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+}
+
+static unsigned int pciGetRemapOffset(PCI_HOST host, PCI_REGION region)
+{
+    switch (host)
+    {
+	case PCI_HOST0:
+	    switch(region) {
+		case PCI_IO:		return PCI_0I_O_ADDRESS_REMAP;
+		case PCI_REGION0:	return PCI_0MEMORY0_ADDRESS_REMAP;
+		case PCI_REGION1:	return PCI_0MEMORY1_ADDRESS_REMAP;
+		case PCI_REGION2:	return PCI_0MEMORY2_ADDRESS_REMAP;
+		case PCI_REGION3:	return PCI_0MEMORY3_ADDRESS_REMAP;
+	    }
+	case PCI_HOST1:
+	    switch(region) {
+		case PCI_IO:		return PCI_1I_O_ADDRESS_REMAP;
+		case PCI_REGION0:	return PCI_1MEMORY0_ADDRESS_REMAP;
+		case PCI_REGION1:	return PCI_1MEMORY1_ADDRESS_REMAP;
+		case PCI_REGION2:	return PCI_1MEMORY2_ADDRESS_REMAP;
+		case PCI_REGION3:	return PCI_1MEMORY3_ADDRESS_REMAP;
+	    }
+    }
+    return PCI_0MEMORY0_ADDRESS_REMAP;
+}
+
+bool pciMapSpace(PCI_HOST host, PCI_REGION region, unsigned int remapBase, unsigned int bankBase,unsigned int bankLength)
+{
+    unsigned int low=0xfff;
+    unsigned int high=0x0;
+    unsigned int regOffset=pciGetRegOffset(host, region);
+    unsigned int remapOffset=pciGetRemapOffset(host, region);
+
+    if(bankLength!=0) {
+	low = (bankBase >> 20) & 0xfff;
+	high=((bankBase+bankLength)>>20)-1;
+    }
+
+    GT_REG_WRITE(regOffset, low | (1<<24));	/* no swapping */
+    GT_REG_WRITE(regOffset+8, high);
+
+    if(bankLength!=0) {	/* must do AFTER writing maps */
+	GT_REG_WRITE(remapOffset, remapBase>>20);	/* sorry, 32 bits only.
+							   dont support upper 32
+							   in this driver */
+    }
+    return true;
+}
+
+unsigned int pciGetSpaceBase(PCI_HOST host, PCI_REGION region)
+{
+    unsigned int low;
+    unsigned int regOffset=pciGetRegOffset(host, region);
+    GT_REG_READ(regOffset,&low);
+    return (low&0xfff)<<20;
+}
+
+unsigned int pciGetSpaceSize(PCI_HOST host, PCI_REGION region)
+{
+    unsigned int low,high;
+    unsigned int regOffset=pciGetRegOffset(host, region);
+    GT_REG_READ(regOffset,&low);
+    GT_REG_READ(regOffset+8,&high);
+    high&=0xfff;
+    low&=0xfff;
+    if(high<=low) return 0;
+    return (high+1-low)<<20;
+}
+
+/********************************************************************
+* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
+*
+* Inputs: base and size of PCI SCS
+*********************************************************************/
+void pciMapMemoryBank(PCI_HOST host, MEMORY_BANK bank, unsigned int pciDramBase,unsigned int pciDramSize)
+{
+  	pciDramBase = pciDramBase & 0xfffff000;
+    pciDramBase = pciDramBase | (pciReadConfigReg(host,
+        PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF) & 0x00000fff);
+    pciWriteConfigReg(host,PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF,pciDramBase);
+    if(pciDramSize == 0)
+        pciDramSize ++;
+    GT_REG_WRITE(pci_scs_bank_size[host][bank], pciDramSize-1);
+}
+
+
+/********************************************************************
+* pciSetRegionFeatures - This function modifys one of the 8 regions with
+*                         feature bits given as an input.
+*                       - Be advised to check the spec before modifying them.
+* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
+*         unsigned int features - See file: pci.h there are defintion for those
+*                                 region features.
+*         unsigned int baseAddress - The region base Address.
+*         unsigned int topAddress - The region top Address.
+* Returns: false if one of the parameters is erroneous true otherwise.
+*********************************************************************/
+bool pciSetRegionFeatures(PCI_HOST host, PCI_ACCESS_REGIONS region,unsigned int features,
+                           unsigned int baseAddress,unsigned int regionLength)
+{
+    unsigned int accessLow;
+    unsigned int accessHigh;
+    unsigned int accessTop = baseAddress + regionLength;
+
+    if(regionLength == 0) /* close the region. */
+    {
+        pciDisableAccessRegion(host, region);
+        return true;
+    }
+    /* base Address is store is bits [11:0] */
+    accessLow = (baseAddress & 0xfff00000) >> 20;
+    /* All the features are update according to the defines in pci.h (to be on
+       the safe side we disable bits: [11:0] */
+    accessLow = accessLow | (features & 0xfffff000);
+    /* write to the Low Access Region register */
+    GT_REG_WRITE( pci_access_control_base_0_low[host] + 0x10*region,accessLow);
+
+    accessHigh = (accessTop & 0xfff00000) >> 20;
+
+    /* write to the High Access Region register */
+    GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,accessHigh - 1);
+    return true;
+}
+
+/********************************************************************
+* pciDisableAccessRegion - Disable The given Region by writing MAX size
+*                           to its low Address and MIN size to its high Address.
+*
+* Inputs:   PCI_ACCESS_REGIONS region - The region we to be Disabled.
+* Returns:  N/A.
+*********************************************************************/
+void pciDisableAccessRegion(PCI_HOST host, PCI_ACCESS_REGIONS region)
+{
+    /* writing back the registers default values. */
+    GT_REG_WRITE(pci_access_control_base_0_low[host] + 0x10*region,0x01001fff);
+    GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,0);
+}
+
+/********************************************************************
+* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
+*
+* Inputs:   N/A
+* Returns:  true.
+*********************************************************************/
+bool pciArbiterEnable(PCI_HOST host)
+{
+    unsigned int regData;
+
+    GT_REG_READ(pci_arbiter_control[host],&regData);
+    GT_REG_WRITE(pci_arbiter_control[host],regData | BIT31);
+    return true;
+}
+
+/********************************************************************
+* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
+*
+* Inputs:   N/A
+* Returns:  true
+*********************************************************************/
+bool pciArbiterDisable(PCI_HOST host)
+{
+    unsigned int regData;
+
+    GT_REG_READ(pci_arbiter_control[host],&regData);
+    GT_REG_WRITE(pci_arbiter_control[host],regData & 0x7fffffff);
+    return true;
+}
+
+/********************************************************************
+* pciParkingDisable - Park on last option disable, with this function you can
+*                      disable the park on last mechanism for each agent.
+*                      disabling this option for all agents results parking
+*                      on the internal master.
+*
+* Inputs: PCI_AGENT_PARK internalAgent -  parking Disable for internal agent.
+*         PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
+*         PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
+*         PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
+*         PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
+*         PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
+*         PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
+* Returns:  true
+*********************************************************************/
+bool pciParkingDisable(PCI_HOST host, PCI_AGENT_PARK internalAgent,
+                        PCI_AGENT_PARK externalAgent0,
+                        PCI_AGENT_PARK externalAgent1,
+                        PCI_AGENT_PARK externalAgent2,
+                        PCI_AGENT_PARK externalAgent3,
+                        PCI_AGENT_PARK externalAgent4,
+                        PCI_AGENT_PARK externalAgent5)
+{
+    unsigned int regData;
+    unsigned int writeData;
+
+    GT_REG_READ(pci_arbiter_control[host],&regData);
+    writeData = (internalAgent << 14) + (externalAgent0 << 15) +     \
+                (externalAgent1 << 16) + (externalAgent2 << 17) +    \
+                (externalAgent3 << 18) + (externalAgent4 << 19) +    \
+                (externalAgent5 << 20);
+    regData = (regData & ~(0x7f<<14)) | writeData;
+    GT_REG_WRITE(pci_arbiter_control[host],regData);
+    return true;
+}
+
+/********************************************************************
+* pciSetRegionSnoopMode - This function modifys one of the 4 regions which
+*                          supports Cache Coherency in the PCI_n interface.
+* Inputs: region - One of the four regions.
+*         snoopType - There is four optional Types:
+*                        1. No Snoop.
+*                        2. Snoop to WT region.
+*                        3. Snoop to WB region.
+*                        4. Snoop & Invalidate to WB region.
+*         baseAddress - Base Address of this region.
+*         regionLength - Region length.
+* Returns: false if one of the parameters is wrong otherwise return true.
+*********************************************************************/
+bool pciSetRegionSnoopMode(PCI_HOST host, PCI_SNOOP_REGION region,PCI_SNOOP_TYPE snoopType,
+                            unsigned int baseAddress,
+                            unsigned int regionLength)
+{
+    unsigned int snoopXbaseAddress;
+    unsigned int snoopXtopAddress;
+    unsigned int data;
+    unsigned int snoopHigh = baseAddress + regionLength;
+
+    if( (region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB) )
+        return false;
+    snoopXbaseAddress = pci_snoop_control_base_0_low[host] + 0x10 * region;
+    snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
+    if(regionLength == 0) /* closing the region */
+    {
+        GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
+        GT_REG_WRITE(snoopXtopAddress,0);
+        return true;
+    }
+    baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
+    data = (baseAddress >> 20) | snoopType << 12;
+    GT_REG_WRITE(snoopXbaseAddress,data);
+    snoopHigh = (snoopHigh & 0xfff00000) >> 20;
+    GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
+    return true;
+}
+
+/*
+ *
+ */
+
+static int gt_read_config_dword(struct pci_controller *hose,
+				pci_dev_t dev,
+				int offset, u32* value)
+{
+    *value = pciReadConfigReg((PCI_HOST) hose->cfg_addr, offset, PCI_DEV(dev));
+    return 0;
+}
+
+static int gt_write_config_dword(struct pci_controller *hose,
+				 pci_dev_t dev,
+				 int offset, u32 value)
+{
+    pciWriteConfigReg((PCI_HOST)hose->cfg_addr, offset, PCI_DEV(dev), value);
+    return 0;
+}
+
+/*
+ *
+ */
+
+static void gt_setup_ide(struct pci_controller *hose,
+			 pci_dev_t dev, struct pci_config_table *entry)
+{
+    static const int ide_bar[]={8,4,8,4,0,0};
+    u32 bar_response, bar_value;
+    int bar;
+
+    for (bar=0; bar<6; bar++)
+    {
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, 0x0);
+	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, &bar_response);
+
+	pciauto_region_allocate(bar_response & PCI_BASE_ADDRESS_SPACE_IO ?
+				hose->pci_io : hose->pci_mem, ide_bar[bar], &bar_value);
+
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, bar_value);
+    }
+}
+
+static void gt_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+    unsigned char pin, irq;
+
+    pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+    if(pin == 1) {	/* only allow INT A */
+	irq = pci_irq_swizzle[(PCI_HOST)hose->cfg_addr][PCI_DEV(dev)];
+	if(irq)
+	    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+    }
+}
+
+struct pci_config_table gt_config_table[] = {
+    { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
+      PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
+
+    { }
+};
+
+struct pci_controller pci0_hose = {
+    fixup_irq: gt_fixup_irq,
+    config_table: gt_config_table,
+};
+
+struct pci_controller pci1_hose = {
+    fixup_irq: gt_fixup_irq,
+    config_table: gt_config_table,
+};
+
+void
+pci_init(void)
+{
+    unsigned int command;
+
+    pci0_hose.first_busno = 0;
+    pci0_hose.last_busno = 0xff;
+
+    /* PCI memory space */
+    pci_set_region(pci0_hose.regions + 0,
+		   CFG_PCI0_0_MEM_SPACE,
+		   CFG_PCI0_0_MEM_SPACE,
+		   CFG_PCI0_MEM_SIZE,
+		   PCI_REGION_MEM);
+
+    /* PCI I/O space */
+    pci_set_region(pci0_hose.regions + 1,
+		   CFG_PCI0_IO_SPACE_PCI,
+		   CFG_PCI0_IO_SPACE,
+		   CFG_PCI0_IO_SIZE,
+		   PCI_REGION_IO);
+
+    pci_set_ops(&pci0_hose,
+		pci_hose_read_config_byte_via_dword,
+		pci_hose_read_config_word_via_dword,
+		gt_read_config_dword,
+		pci_hose_write_config_byte_via_dword,
+		pci_hose_write_config_word_via_dword,
+		gt_write_config_dword);
+
+    pci0_hose.region_count = 2;
+
+    pci0_hose.cfg_addr = (unsigned int*) PCI_HOST0;
+
+    pci_register_hose(&pci0_hose);
+
+    pciArbiterEnable(PCI_HOST0);
+    pciParkingDisable(PCI_HOST0,1,1,1,1,1,1,1);
+
+    command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MASTER;
+    pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
+
+    pci0_hose.last_busno = pci_hose_scan(&pci0_hose);
+
+    command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MEMORY;
+    pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
+
+    pci1_hose.first_busno = pci0_hose.last_busno + 1;
+    pci1_hose.last_busno = 0xff;
+
+    /* PCI memory space */
+    pci_set_region(pci1_hose.regions + 0,
+		   CFG_PCI1_0_MEM_SPACE,
+		   CFG_PCI1_0_MEM_SPACE,
+		   CFG_PCI1_MEM_SIZE,
+		   PCI_REGION_MEM);
+
+    /* PCI I/O space */
+    pci_set_region(pci1_hose.regions + 1,
+		   CFG_PCI1_IO_SPACE_PCI,
+		   CFG_PCI1_IO_SPACE,
+		   CFG_PCI1_IO_SIZE,
+		   PCI_REGION_IO);
+
+    pci_set_ops(&pci1_hose,
+		pci_hose_read_config_byte_via_dword,
+		pci_hose_read_config_word_via_dword,
+		gt_read_config_dword,
+		pci_hose_write_config_byte_via_dword,
+		pci_hose_write_config_word_via_dword,
+		gt_write_config_dword);
+
+    pci1_hose.region_count = 2;
+
+    pci1_hose.cfg_addr = (unsigned int*) PCI_HOST1;
+
+    pci_register_hose(&pci1_hose);
+
+    pciArbiterEnable(PCI_HOST1);
+    pciParkingDisable(PCI_HOST1,1,1,1,1,1,1,1);
+
+    command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MASTER;
+    pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
+
+    pci1_hose.last_busno = pci_hose_scan(&pci1_hose);
+
+    command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
+    command |= PCI_COMMAND_MEMORY;
+    pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
+}
diff --git a/board/evb64260/sdram_init.c b/board/evb64260/sdram_init.c
new file mode 100644
index 0000000..ff98e4d
--- /dev/null
+++ b/board/evb64260/sdram_init.c
@@ -0,0 +1,629 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/* sdram_init.c - automatic memory sizing */
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include <galileo/memory.h>
+#include <galileo/pci.h>
+#include <galileo/gt64260R.h>
+#include <net.h>
+
+#include "eth.h"
+#include "mpsc.h"
+#include "i2c.h"
+#include "64260.h"
+
+/* #define	DEBUG */
+#define	MAP_PCI
+
+#ifdef DEBUG
+#define DP(x) x
+#else
+#define DP(x)
+#endif
+
+#define GB         (1 << 30)
+
+/* structure to store the relevant information about an sdram bank */
+typedef struct sdram_info {
+	uchar drb_size;
+	uchar registered, ecc;
+	uchar tpar;
+	uchar tras_clocks;
+	uchar burst_len;
+	uchar banks, slot;
+	int size;	/* detected size, not from I2C but from dram_size() */
+} sdram_info_t;
+
+#ifdef DEBUG
+void dump_dimm_info(struct sdram_info *d)
+{
+    static const char *ecc_legend[]={""," Parity"," ECC"};
+    printf("dimm%s %sDRAM: %dMibytes:\n",
+	    ecc_legend[d->ecc],
+	    d->registered?"R":"",
+	    (d->size>>20));
+    printf("  drb=%d tpar=%d tras=%d burstlen=%d banks=%d slot=%d\n",
+	    d->drb_size, d->tpar, d->tras_clocks, d->burst_len,
+	    d->banks, d->slot);
+}
+#endif
+
+static int
+memory_map_bank(unsigned int bankNo,
+		unsigned int bankBase,
+		unsigned int bankLength)
+{
+#ifdef DEBUG
+	if (bankLength > 0) {
+		printf("mapping bank %d at %08x - %08x\n",
+		       bankNo, bankBase, bankBase + bankLength - 1);
+	} else {
+		printf("unmapping bank %d\n", bankNo);
+	}
+#endif
+
+	memoryMapBank(bankNo, bankBase, bankLength);
+
+	return 0;
+}
+
+#ifdef MAP_PCI
+static int
+memory_map_bank_pci(unsigned int bankNo,
+		unsigned int bankBase,
+		unsigned int bankLength)
+{
+	PCI_HOST host;
+	for (host=PCI_HOST0;host<=PCI_HOST1;host++) {
+		const int features=
+			PREFETCH_ENABLE |
+			DELAYED_READ_ENABLE |
+			AGGRESSIVE_PREFETCH |
+			READ_LINE_AGGRESSIVE_PREFETCH |
+			READ_MULTI_AGGRESSIVE_PREFETCH |
+			MAX_BURST_4 |
+			PCI_NO_SWAP;
+
+		pciMapMemoryBank(host, bankNo, bankBase, bankLength);
+
+		pciSetRegionSnoopMode(host, bankNo, PCI_SNOOP_WB, bankBase,
+				bankLength);
+
+		pciSetRegionFeatures(host, bankNo, features, bankBase, bankLength);
+	}
+	return 0;
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* much of this code is based on (or is) the code in the pip405 port */
+/* thanks go to the authors of said port - Josh */
+
+
+/*
+ * translate ns.ns/10 coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short
+NS10to10PS(unsigned char spd_byte)
+{
+	unsigned short ns, ns10;
+
+	/* isolate upper nibble */
+	ns = (spd_byte >> 4) & 0x0F;
+	/* isolate lower nibble */
+	ns10 = (spd_byte & 0x0F);
+
+	return(ns*100 + ns10*10);
+}
+
+/*
+ * translate ns coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short
+NSto10PS(unsigned char spd_byte)
+{
+	return(spd_byte*100);
+}
+
+#ifdef CONFIG_ZUMA_V2
+static int
+check_dimm(uchar slot, sdram_info_t *info)
+{
+        /* assume 2 dimms, 2 banks each 256M - we dont have an
+	 * dimm i2c so rely on the detection routines later */
+
+	memset(info, 0, sizeof(*info));
+
+	info->slot = slot;
+	info->banks = 2;	/* Detect later */
+	    info->registered = 0;
+	info->drb_size = 32;	/* 16 - 256MBit, 32 - 512MBit
+				   but doesn't matter, both do same
+				   thing in setup_sdram() */
+	    info->tpar = 3;
+	    info->tras_clocks = 5;
+	    info->burst_len = 4;
+#ifdef CONFIG_ECC
+	info->ecc = 0;		/* Detect later */
+#endif /* CONFIG_ECC */
+	return 0;
+}
+
+#else /* ! CONFIG_ZUMA_V2 */
+
+/* This code reads the SPD chip on the sdram and populates
+ * the array which is passed in with the relevant information */
+static int
+check_dimm(uchar slot, sdram_info_t *info)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	uchar addr = slot == 0 ? DIMM0_I2C_ADDR : DIMM1_I2C_ADDR;
+	int ret;
+	uchar rows, cols, sdram_banks, supp_cal, width, cal_val;
+	ulong tmemclk;
+	uchar trp_clocks, trcd_clocks;
+	uchar data[128];
+
+	get_clocks ();
+
+ 	tmemclk = 1000000000 / (gd->bus_clk / 100);  /* in 10 ps units */
+
+#ifdef CONFIG_EVB64260_750CX
+	if (0 != slot) {
+		printf("check_dimm: The EVB-64260-750CX only has 1 DIMM,");
+		printf("            called with slot=%d insetad!\n", slot);
+		return 0;
+	}
+#endif
+	DP(puts("before i2c read\n"));
+
+	ret = i2c_read(addr, 0, 128, data, 0);
+
+	DP(puts("after i2c read\n"));
+
+	/* zero all the values */
+	memset(info, 0, sizeof(*info));
+
+	if (ret) {
+		DP(printf("No DIMM in slot %d [err = %x]\n", slot, ret));
+		return 0;
+	}
+
+	/* first, do some sanity checks */
+	if (data[2] != 0x4) {
+		printf("Not SDRAM in slot %d\n", slot);
+		return 0;
+	}
+
+	/* get various information */
+	rows = data[3];
+	cols = data[4];
+	info->banks = data[5];
+	sdram_banks = data[17];
+	width = data[13] & 0x7f;
+
+	DP(printf("sdram_banks: %d, banks: %d\n", sdram_banks, info->banks));
+
+	/* check if the memory is registered */
+	if (data[21] & (BIT1 | BIT4))
+		info->registered = 1;
+
+#ifdef CONFIG_ECC
+	/* check for ECC/parity [0 = none, 1 = parity, 2 = ecc] */
+	info->ecc = (data[11] & 2) >> 1;
+#endif
+
+	/* bit 1 is CL2, bit 2 is CL3 */
+	supp_cal = (data[18] & 0x6) >> 1;
+
+	/* compute the relevant clock values */
+	trp_clocks = (NSto10PS(data[27])+(tmemclk-1)) / tmemclk;
+	trcd_clocks = (NSto10PS(data[29])+(tmemclk-1)) / tmemclk;
+	info->tras_clocks = (NSto10PS(data[30])+(tmemclk-1)) / tmemclk;
+
+	DP(printf("trp = %d\ntrcd_clocks = %d\ntras_clocks = %d\n",
+		  trp_clocks, trcd_clocks, info->tras_clocks));
+
+	/* try a CAS latency of 3 first... */
+	cal_val = 0;
+	if (supp_cal & 3) {
+		if (NS10to10PS(data[9]) <= tmemclk)
+			cal_val = 3;
+	}
+
+	/* then 2... */
+	if (supp_cal & 2) {
+		if (NS10to10PS(data[23]) <= tmemclk)
+			cal_val = 2;
+	}
+
+	DP(printf("cal_val = %d\n", cal_val));
+
+	/* bummer, did't work... */
+	if (cal_val == 0) {
+		DP(printf("Couldn't find a good CAS latency\n"));
+		return 0;
+	}
+
+	/* get the largest delay -- these values need to all be the same
+	 * see Res#6 */
+	info->tpar = cal_val;
+	if (trp_clocks > info->tpar)
+		info->tpar = trp_clocks;
+	if (trcd_clocks > info->tpar)
+		info->tpar = trcd_clocks;
+
+	DP(printf("tpar set to: %d\n", info->tpar));
+
+#ifdef CFG_BROKEN_CL2
+	if (info->tpar == 2){
+		info->tpar = 3;
+	        DP(printf("tpar fixed-up to: %d\n", info->tpar));
+	}
+#endif
+	/* compute the module DRB size */
+	info->drb_size = (((1 << (rows + cols)) * sdram_banks) * width) / _16M;
+
+	DP(printf("drb_size set to: %d\n", info->drb_size));
+
+	/* find the burst len */
+	info->burst_len = data[16] & 0xf;
+	if ((info->burst_len & 8) == 8) {
+		info->burst_len = 1;
+	} else if ((info->burst_len & 4) == 4) {
+		info->burst_len = 0;
+	} else {
+		return 0;
+	}
+
+	info->slot = slot;
+	return 0;
+}
+#endif /* ! CONFIG_ZUMA_V2 */
+
+static int
+setup_sdram_common(sdram_info_t info[2])
+{
+    	ulong tmp;
+	int tpar=2, tras_clocks=5, registered=1, ecc=2;
+
+	if(!info[0].banks && !info[1].banks) return 0;
+
+	if(info[0].banks) {
+	    if(info[0].tpar>tpar) tpar=info[0].tpar;
+	    if(info[0].tras_clocks>tras_clocks) tras_clocks=info[0].tras_clocks;
+	    if(!info[0].registered) registered=0;
+	    if(info[0].ecc!=2) ecc=0;
+	}
+
+	if(info[1].banks) {
+	    if(info[1].tpar>tpar) tpar=info[1].tpar;
+	    if(info[1].tras_clocks>tras_clocks) tras_clocks=info[1].tras_clocks;
+	    if(!info[1].registered) registered=0;
+	    if(info[1].ecc!=2) ecc=0;
+	}
+
+	/* SDRAM configuration */
+	tmp = GTREGREAD(SDRAM_CONFIGURATION);
+
+	/* Turn on physical interleave if both DIMMs
+	 * have even numbers of banks. */
+	if( (info[0].banks == 0 || info[0].banks == 2) &&
+	    (info[1].banks == 0 || info[1].banks == 2) ) {
+	    /* physical interleave on */
+	    tmp &= ~(1 << 15);
+	} else {
+	    /* physical interleave off */
+	    tmp |= (1 << 15);
+	}
+
+	tmp |= (registered << 17);
+
+	/* Use buffer 1 to return read data to the CPU
+	 * See Res #12 */
+	tmp |= (1 << 26);
+
+	GT_REG_WRITE(SDRAM_CONFIGURATION, tmp);
+	DP(printf("SDRAM config: %08x\n",
+		GTREGREAD(SDRAM_CONFIGURATION)));
+
+	/* SDRAM timing */
+	tmp = (((tpar == 3) ? 2 : 1) |
+	       (((tpar == 3) ? 2 : 1) << 2) |
+	       (((tpar == 3) ? 2 : 1) << 4) |
+	       (tras_clocks << 8));
+
+#ifdef CONFIG_ECC
+	/* Setup ECC */
+	if (ecc == 2) tmp |= 1<<13;
+#endif /* CONFIG_ECC */
+
+	GT_REG_WRITE(SDRAM_TIMING, tmp);
+	DP(printf("SDRAM timing: %08x (%d,%d,%d,%d)\n",
+		GTREGREAD(SDRAM_TIMING), tpar,tpar,tpar,tras_clocks));
+
+	/* SDRAM address decode register */
+	/* program this with the default value */
+	GT_REG_WRITE(SDRAM_ADDRESS_DECODE, 0x2);
+	DP(printf("SDRAM decode: %08x\n",
+		GTREGREAD(SDRAM_ADDRESS_DECODE)));
+
+	return 0;
+}
+
+/* sets up the GT properly with information passed in */
+static int
+setup_sdram(sdram_info_t *info)
+{
+	ulong tmp, check;
+	ulong *addr = 0;
+	int i;
+
+	/* sanity checking */
+	if (! info->banks) return 0;
+
+	/* ---------------------------- */
+	/* Program the GT with the discovered data */
+
+	/* bank parameters */
+	tmp = (0xf<<16);	/* leave all virt bank pages open */
+
+	DP(printf("drb_size: %d\n", info->drb_size));
+	switch (info->drb_size) {
+	case 1:
+		tmp |= (1 << 14);
+		break;
+	case 4:
+	case 8:
+		tmp |= (2 << 14);
+		break;
+	case 16:
+	case 32:
+		tmp |= (3 << 14);
+		break;
+	default:
+		printf("Error in dram size calculation\n");
+		return 1;
+	}
+
+	/* SDRAM bank parameters */
+	/* the param registers for slot 1 (banks 2+3) are offset by 0x8 */
+	GT_REG_WRITE(SDRAM_BANK0PARAMETERS + (info->slot * 0x8), tmp);
+	GT_REG_WRITE(SDRAM_BANK1PARAMETERS + (info->slot * 0x8), tmp);
+	DP(printf("SDRAM bankparam slot %d (bank %d+%d): %08lx\n", info->slot, info->slot*2, (info->slot*2)+1, tmp));
+
+	/* set the SDRAM configuration for each bank */
+	for (i = info->slot * 2; i < ((info->slot * 2) + info->banks); i++) {
+		DP(printf("*** Running a MRS cycle for bank %d ***\n", i));
+
+		/* map the bank */
+		memory_map_bank(i, 0, GB/4);
+
+		/* set SDRAM mode */
+		GT_REG_WRITE(SDRAM_OPERATION_MODE, 0x3);
+		check = GTREGREAD(SDRAM_OPERATION_MODE);
+
+		/* dummy write */
+		*addr = 0;
+
+		/* wait for the command to complete */
+		while ((GTREGREAD(SDRAM_OPERATION_MODE) & (1 << 31)) == 0)
+			;
+
+		/* switch back to normal operation mode */
+		GT_REG_WRITE(SDRAM_OPERATION_MODE, 0);
+		check = GTREGREAD(SDRAM_OPERATION_MODE);
+
+		/* unmap the bank */
+		memory_map_bank(i, 0, 0);
+		DP(printf("*** MRS cycle for bank %d done ***\n", i));
+	}
+
+	return 0;
+}
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+static long int
+dram_size(long int *base, long int maxsize)
+{
+    volatile long int	 *addr, *b=base;
+    long int	 cnt, val, save1, save2;
+
+#define STARTVAL (1<<20)	/* start test at 1M */
+    for (cnt = STARTVAL/sizeof(long); cnt < maxsize/sizeof(long); cnt <<= 1) {
+	    addr = base + cnt;	/* pointer arith! */
+
+	    save1=*addr;	/* save contents of addr */
+	    save2=*b;		/* save contents of base */
+
+	    *addr=cnt;		/* write cnt to addr */
+	    *b=0;		/* put null at base */
+
+	    /* check at base address */
+	    if ((*b) != 0) {
+		*addr=save1;	/* restore *addr */
+		*b=save2;	/* restore *b */
+		return (0);
+	    }
+	    val = *addr;	/* read *addr */
+
+	    *addr=save1;
+	    *b=save2;
+
+	    if (val != cnt) {
+		    /* fix boundary condition.. STARTVAL means zero */
+		    if(cnt==STARTVAL/sizeof(long)) cnt=0;
+		    return (cnt * sizeof(long));
+	    }
+    }
+    return maxsize;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* U-Boot interface function to SDRAM init - this is where all the
+ * controlling logic happens */
+long int
+initdram(int board_type)
+{
+	ulong checkbank[4] = { [0 ... 3] = 0 };
+	int bank_no;
+        ulong total;
+	int nhr;
+	sdram_info_t dimm_info[2];
+
+
+	/* first, use the SPD to get info about the SDRAM */
+
+	/* check the NHR bit and skip mem init if it's already done */
+	nhr = get_hid0() & (1 << 16);
+
+	if (nhr) {
+		printf("Skipping SDRAM setup due to NHR bit being set\n");
+	} else {
+		/* DIMM0 */
+		check_dimm(0, &dimm_info[0]);
+
+		/* DIMM1 */
+#ifndef CONFIG_EVB64260_750CX /* EVB64260_750CX has only 1 DIMM */
+		check_dimm(1, &dimm_info[1]);
+#else /* CONFIG_EVB64260_750CX */
+		memset(&dimm_info[1], 0, sizeof(sdram_info_t));
+#endif
+
+		/* unmap all banks */
+		memory_map_bank(0, 0, 0);
+		memory_map_bank(1, 0, 0);
+		memory_map_bank(2, 0, 0);
+		memory_map_bank(3, 0, 0);
+
+		/* Now, program the GT with the correct values */
+		if (setup_sdram_common(dimm_info)) {
+			printf("Setup common failed.\n");
+		}
+
+		if (setup_sdram(&dimm_info[0])) {
+			printf("Setup for DIMM1 failed.\n");
+		}
+
+		if (setup_sdram(&dimm_info[1])) {
+			printf("Setup for DIMM2 failed.\n");
+		}
+
+		/* set the NHR bit */
+		set_hid0(get_hid0() | (1 << 16));
+	}
+	/* next, size the SDRAM banks */
+
+	total = 0;
+	if (dimm_info[0].banks > 0) checkbank[0] = 1;
+	if (dimm_info[0].banks > 1) checkbank[1] = 1;
+	if (dimm_info[0].banks > 2)
+		printf("Error, SPD claims DIMM1 has >2 banks\n");
+
+	if (dimm_info[1].banks > 0) checkbank[2] = 1;
+	if (dimm_info[1].banks > 1) checkbank[3] = 1;
+	if (dimm_info[1].banks > 2)
+		printf("Error, SPD claims DIMM2 has >2 banks\n");
+
+	/* Generic dram sizer: works even if we don't have i2c DIMMs,
+	 * as long as the timing settings are more or less correct */
+
+	/*
+	 * pass 1: size all the banks, using first bat (0-256M)
+	 * 	   limitation: we only support 256M per bank due to
+	 *  	   us only having 1 BAT for all DRAM
+	 */
+	for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
+		/* skip over banks that are not populated */
+		if (! checkbank[bank_no])
+			continue;
+
+		DP(printf("checking bank %d\n", bank_no));
+
+		memory_map_bank(bank_no, 0, GB/4);
+		checkbank[bank_no] = dram_size(NULL, GB/4);
+		memory_map_bank(bank_no, 0, 0);
+
+		DP(printf("bank %d %08lx\n", bank_no, checkbank[bank_no]));
+	}
+
+	/*
+	 * pass 2: contiguously map each bank into physical address
+	 * 	   space.
+	 */
+	dimm_info[0].banks=dimm_info[1].banks=0;
+	for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
+		if(!checkbank[bank_no]) continue;
+
+		dimm_info[bank_no/2].banks++;
+		dimm_info[bank_no/2].size+=checkbank[bank_no];
+
+		memory_map_bank(bank_no, total, checkbank[bank_no]);
+#ifdef MAP_PCI
+		memory_map_bank_pci(bank_no, total, checkbank[bank_no]);
+#endif
+		total += checkbank[bank_no];
+	}
+
+#ifdef CONFIG_ECC
+#ifdef CONFIG_ZUMA_V2
+	/*
+	 * We always enable ECC when bank 2 and 3 are unpopulated
+	 * If we 2 or 3 are populated, we CAN'T support ECC.
+	 * (Zuma boards only support ECC in banks 0 and 1; assume that
+	 * in that configuration, ECC chips are mounted, even for stacked
+	 * chips)
+	 */
+	if (checkbank[2]==0 && checkbank[3]==0) {
+	    	dimm_info[0].ecc=2;
+		GT_REG_WRITE(SDRAM_TIMING, GTREGREAD(SDRAM_TIMING) | (1 << 13));
+		/* TODO: do we have to run MRS cycles again? */
+	}
+#endif /* CONFIG_ZUMA_V2 */
+
+	if (GTREGREAD(SDRAM_TIMING) & (1 << 13)) {
+		puts("[ECC] ");
+	}
+#endif /* CONFIG_ECC */
+
+#ifdef DEBUG
+	dump_dimm_info(&dimm_info[0]);
+	dump_dimm_info(&dimm_info[1]);
+#endif
+	/* TODO: return at MOST 256M? */
+        /* return total > GB/4 ? GB/4 : total; */
+	return total;
+}
diff --git a/board/evb64260/serial.c b/board/evb64260/serial.c
new file mode 100644
index 0000000..d9c7a15
--- /dev/null
+++ b/board/evb64260/serial.c
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * serial.c - serial support for the gal ev board
+ */
+
+/* supports both the 16650 duart and the MPSC */
+
+#include <common.h>
+#include <command.h>
+#include <galileo/memory.h>
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+#include <ns16550.h>
+#endif
+
+#include "serial.h"
+
+#include "mpsc.h"
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1,
+				(NS16550_t) CFG_NS16550_COM2 };
+#endif
+
+#ifdef CONFIG_MPSC
+
+int serial_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+	int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+#endif
+
+	mpsc_init(gd->baudrate);
+
+	/* init the DUART chans so that KGDB in the kernel can use them */
+#ifdef CFG_INIT_CHAN1
+	NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+	return (0);
+}
+
+void
+serial_putc(const char c)
+{
+	if (c == '\n')
+		mpsc_putchar('\r');
+
+	mpsc_putchar(c);
+}
+
+int
+serial_getc(void)
+{
+	return mpsc_getchar();
+}
+
+int
+serial_tstc(void)
+{
+	return mpsc_test_char();
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	galbrg_set_baudrate(CONFIG_MPSC_PORT, gd->baudrate);
+}
+
+#else /* ! CONFIG_MPSC */
+
+int serial_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+	(void)NS16550_init(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	(void)NS16550_init(COM_PORTS[1], clock_divisor);
+#endif
+
+	return (0);
+}
+
+void
+serial_putc(const char c)
+{
+	if (c == '\n')
+		NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+
+	NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+	return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+	return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+	NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+}
+
+#endif /* CONFIG_MPSC */
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar (int c)
+{
+	serial_putc (c);
+}
+
+void
+putDebugStr (const char *str)
+{
+	serial_puts (str);
+}
+
+int
+getDebugChar (void)
+{
+	return serial_getc();
+}
+
+void
+kgdb_interruptible (int yes)
+{
+	return;
+}
+#endif	/* CFG_CMD_KGDB	*/
diff --git a/board/gen860t/README b/board/gen860t/README
new file mode 100644
index 0000000..761ceed
--- /dev/null
+++ b/board/gen860t/README
@@ -0,0 +1,142 @@
+
+This directory contains board specific code for a generic MPC860T based
+embedded computer, called 'GEN860T'.  The design is generic in the sense that
+common, readily available components are used and that the architecture of the
+system is i(relatively) straightforward:
+
+	One eight bit wide boot (FLASH) memory
+	32 bit main memory using SDRAM
+	DOC 2000+
+	Ethernet PHY
+	Some I2C peripheral devices: Atmel AT24C256 EEPROM, Maxim DS1337 RTC.
+	Some other miscellaneous peripherals
+
+NOTE: There are references to a XIlinx FPGA and Mil-Std 1553 databus in this
+port.  I guess the computer is not as generic as I first said 8)  However,
+these extras can be safely ignored.
+
+Given the GEN860T files, it should be pretty easy to reverse engineer the
+hardware configuration, if that's useful to you.  Hopefully, this code will
+be useful to someone as a basis for a port to a new system or as a head start
+on a custom design.  If you end up using any of this, I would appreciate
+hearing from you, especially if you discover bugs or find ways to improve the
+quality of this U-Boot port.
+
+Here are the salient features of the system:
+Clock						:	33 Mhz oscillator
+Processor core frequency	:	66 Mhz  if in 1:2:1 mode; can also run 1:1
+Bus frequency				:	33 Mhz
+
+Main memory:
+	Type	: SDRAM
+	Width	: 32 bits
+	Size	: 64 megabytes
+	Chip	: Two Micron MT48LC16M16A2TG-7E
+	CS		: MPC860T CS1*/UPMA
+	UPMA CONNECTIONS:
+		SDRAM A10	: GPLA0*
+		SDRAM CAS*	: GPLA2*
+		SDRAM WE*	: GPLA3*
+		SDRAM RAS*	: GPLA4*
+
+Boot memory:
+	Type	: FLASH
+	Width	: 8 bits
+	Size	: 16 megabytes
+	Chip	: One Intel 28F128J3A (StrataFlash)
+	CS		: MPC860T CS0*/GPCM (this is the "boot" chip select)
+
+EEPROM memory:
+	Type	: Serial I2C EEPROM
+	Width	: 8 bits
+	Size	: 32 kibibytes
+	Chip	: One Atmel AT25C256
+	CS		: 0x50 (external I2C address pins on device are tied to GND)
+
+Filesystem memory:
+	Type	: NAND FLASH (Toshiba)
+	Width	: 8 bits (i.e. interface to DOC is 8 bits)
+	Size	: 32 megabytes
+	Chip	: One DiskOnCHip Millenium Plus (DOC 2000+)
+	CS		: MPC860T CS2*/GPCM
+
+Network support:
+	MAC		: MPC86OT FEC (Fast Ethernet Controller)
+	PHY		: Intel LXT971A
+	MII Addr: 0x0 (hardwired on the board)
+	MII IRQ	:
+
+Console:
+	RS-232 on SMC1 (Maxim MAX3232 LVCMOS-RS232 level shifter)
+
+Real Time Clock:
+	Type	: Low power, I2C interface
+	Chip	: Maxim DS1337
+	CS		: Address 0x68 on I2C bus
+
+	The MPC860T's internal RTC has a defect in Mask rev D that increases
+	the current drain on the KAPWR line to 10 mA.  Since this is an
+	unreasonable amount of current draw for a RTC, and Motorola does not
+	plan to fix this in future mask revisions, a serial (I2C) RTC that
+	works has been included instead.  NOTE that the DS1337 can be
+	configured to output a 32768 Hz clock while the main power is on.
+	This clock output has been routed to the MPC860T's EXTAL pin to allow
+	the internal RTC to be used.  NOTE also that due to yet another
+	defect in the rev D mask, the RTC does not operate reliably when the
+	internal RTC divisor is set to use a 32768 Hz reference.  So just use
+	the I2C RTC.
+
+Miscellaneous:
+	Xilinx Virtex FPGA on CS3*/GPCM.
+	Virtex FPGA slave SelectMap interface on cs4*/UPMB.
+	Mil-Std 1553 databus interface on CS5*/GPCM.
+	Audio sounder (beeper) with digital volume control connected to SPKROUT.
+
+Issues:
+	The DOC 2000+ returns 0x40 as its device ID when probed using the method
+	desxribed in the DOC datasheet.  Unfortunately, the U-Boot DOC driver
+	does not recognize this device.  As of this writing, it seems that MTD
+	does not support the DOC 2000+ either.
+
+Status:
+	Everything appears to work except DOC support. As of this writing,
+	David Woodhouse has stated on the MTD mailing list that he has no
+	knowledge of the DOC Millineum Plus and therfore there is no support
+	in MTD for this device.  I wish I had known this sooner :(
+
+The GEN860T board specific files and configuration is based on the work
+of others who have contributed to U-Boot. The copright and license notices
+of these authors have been retained wherever their code has been reused.
+All new code to support the GEN860T board is:
+
+	(C) Copyright 2001-2002
+	Keith Outwater (keith_outwater@mvis.com)
+
+and the following license applies:
+
+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,
+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
+
+Thanks to Wolfgang Denk for a great software package and to everyone
+who contributed to its development.
+
+Keith Outwater
+Sr. Staff Engineer
+Microvision, Inc.
+<keith_outwater@mvis.com>
+<outwater@eskimo.com>
+
+vim: set ts=4 sw=4 tw=78:
+
diff --git a/board/gen860t/beeper.c b/board/gen860t/beeper.c
new file mode 100644
index 0000000..46fe66b
--- /dev/null
+++ b/board/gen860t/beeper.c
@@ -0,0 +1,213 @@
+/*
+ * (C) Copyright 2002
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * 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>
+#include <asm/8xx_immap.h>
+#include <linux/ctype.h>
+
+/*
+ * Basic beeper support for the GEN860T board.  The GEN860T includes
+ * an audio sounder driven by a Phillips TDA8551 amplifier.  The
+ * TDA8551 features a digital volume control which uses a "trinary"
+ * input (high/high-Z/low) to set volume.  The 860's SPKROUT pin
+ * drives the amplifier input.
+ */
+
+
+/*
+ * Initialize beeper-related hardware. Initialize timer 1 for use with
+ * the beeper. Use 66 Mhz internal clock with prescale of 33 to get
+ * 1 uS period per count.
+ * FIXME: we should really compute the prescale based on the reported
+ * core clock frequency.
+ */
+void
+init_beeper(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_RST1 | TGCR_STP1;
+	immap->im_cpmtimer.cpmt_tmr1 = ((33 << TMR_PS_SHIFT) & TMR_PS_MSK)
+								 | TMR_OM | TMR_FRR | TMR_ICLK_IN_GEN;
+	immap->im_cpmtimer.cpmt_tcn1 = 0;
+	immap->im_cpmtimer.cpmt_ter1 = 0xffff;
+	immap->im_cpmtimer.cpmt_tgcr |= TGCR_RST1;
+}
+
+
+/*
+ * Set beeper frequency.  Max allowed frequency is 2.5 KHz.  This limit
+ * is mostly arbitrary, but the beeper isn't really much good beyond this
+ * frequency.
+ */
+void
+set_beeper_frequency(uint frequency)
+{
+#define FREQ_LIMIT	2500
+
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	/*
+	 * Compute timer ticks given desired frequency.  The timer is set up
+	 * to count 0.5 uS per tick and it takes two ticks per cycle (Hz).
+	 */
+	if (frequency > FREQ_LIMIT) frequency = FREQ_LIMIT;
+	frequency = 1000000/frequency;
+	immap->im_cpmtimer.cpmt_trr1 = (ushort)frequency;
+}
+
+
+/*
+ * Turn the beeper on
+ */
+void
+beeper_on(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_STP1;
+}
+
+
+/*
+ * Turn the beeper off
+ */
+void
+beeper_off(void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	immap->im_cpmtimer.cpmt_tgcr |= TGCR_STP1;
+}
+
+
+/*
+ * Increase or decrease the beeper volume.  Volume can be set
+ * from off to full in 64 steps.  To increase volume, the output
+ * pin is actively driven high, then returned to tristate.
+ * To decrease volume, output a low on the port pin (no need to
+ * change pin mode to tristate) then output a high to go back to
+ * tristate.
+ */
+void
+set_beeper_volume(int steps)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+	int i;
+
+	if (steps >= 0) {
+		for (i = 0; i < (steps >= 64 ? 64 : steps); i++) {
+			immap->im_cpm.cp_pbodr &= ~(0x80000000 >> 19);
+			udelay(1);
+			immap->im_cpm.cp_pbodr |= (0x80000000 >> 19);
+			udelay(1);
+		}
+	}
+	else {
+		for (i = 0; i > (steps <= -64 ? -64 : steps); i--) {
+			immap->im_cpm.cp_pbdat &= ~(0x80000000 >> 19);
+			udelay(1);
+			immap->im_cpm.cp_pbdat |= (0x80000000 >> 19);
+			udelay(1);
+		}
+	}
+}
+
+
+/*
+ * Check the environment to see if the beeper needs beeping.
+ * Controlled by a sequence of the form:
+ * freq/delta volume/on time/off time;... where:
+ * freq 		= frequency in Hz (0 - 2500)
+ * delta volume = volume steps up or down (-64 <= vol <= 64)
+ * on time		= time in mS
+ * off time		= time in mS
+ *
+ * Return 1 on success, 0 on failure
+ */
+int
+do_beeper(char *sequence)
+{
+#define DELIMITER	';'
+
+int args[4];
+int i;
+int val;
+char *p = sequence;
+char *tp;
+
+	/*
+	 * Parse the control sequence.  This is a really simple parser
+	 * without any real error checking.  You can probably blow it
+	 * up really easily.
+	 */
+	if (*p == '\0' || !isdigit(*p)) {
+		printf("%s:%d: null or invalid string (%s)\n",
+				__FILE__, __LINE__, p);
+		return 0;
+	}
+
+	i = 0;
+	while (*p != '\0') {
+		while (*p != DELIMITER) {
+			if (i > 3) i = 0;
+			val = (int) simple_strtol(p, &tp, 0);
+			if (tp == p) {
+				printf("%s:%d: no digits or bad format\n",
+								__FILE__,__LINE__);
+				return 0;
+			}
+			else {
+				args[i] = val;
+			}
+
+			i++;
+			if (*tp == DELIMITER)
+				p = tp;
+			else
+				p = ++tp;
+		}
+		p++;
+
+		/*
+		 * Well, we got something that has a chance of being correct
+		 */
+#if 0
+		for (i = 0; i < 4; i++) {
+			printf("%s:%d:arg %d = %d\n", __FILE__, __LINE__, i, args[i]);
+		}
+		printf("\n");
+#endif
+
+		set_beeper_frequency(args[0]);
+		set_beeper_volume(args[1]);
+		beeper_on();
+		udelay(1000 * args[2]);
+		beeper_off();
+		udelay(1000 * args[3]);
+	}
+	return 1;
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/flash.c b/board/gen860t/flash.c
new file mode 100644
index 0000000..902b1b0
--- /dev/null
+++ b/board/gen860t/flash.c
@@ -0,0 +1,644 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvsi.com
+ *
+ * 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>
+
+#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
+
+/*
+ * Use buffered writes to flash by default - they are about 32x faster than
+ * single byte writes.
+ */
+#ifndef  CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#endif
+
+/*
+ * Max time to wait (in mS) for flash device to allocate a write buffer.
+ */
+#ifndef CFG_FLASH_ALLOC_BUFFER_TOUT
+#define CFG_FLASH_ALLOC_BUFFER_TOUT		100
+#endif
+
+/*
+ * These functions support a single Intel StrataFlash device (28F128J3A)
+ * in byte mode only!.  The flash routines are very basic and simple
+ * since there isn't really any remapping necessary.
+ */
+
+/*
+ * Intel SCS (Scalable Command Set) command definitions
+ * (taken from 28F128J3A datasheet)
+ */
+#define SCS_READ_CMD				0xff
+#define SCS_READ_ID_CMD				0x90
+#define SCS_QUERY_CMD				0x98
+#define SCS_READ_STATUS_CMD			0x70
+#define SCS_CLEAR_STATUS_CMD		0x50
+#define SCS_WRITE_BUF_CMD			0xe8
+#define SCS_PROGRAM_CMD				0x40
+#define SCS_BLOCK_ERASE_CMD			0x20
+#define SCS_BLOCK_ERASE_RESUME_CMD	0xd0
+#define SCS_PROGRAM_RESUME_CMD		0xd0
+#define SCS_BLOCK_ERASE_SUSPEND_CMD	0xb0
+#define SCS_SET_BLOCK_LOCK_CMD		0x60
+#define SCS_CLR_BLOCK_LOCK_CMD		0x60
+
+/*
+ * SCS status/extended status register bit definitions
+ */
+#define  SCS_SR7					0x80
+#define  SCS_XSR7					0x80
+
+/*---------------------------------------------------------------------*/
+#if 0
+#define DEBUG_FLASH
+#endif
+
+#ifdef DEBUG_FLASH
+#define PRINTF(fmt,args...) printf(fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+flash_info_t	flash_info[CFG_MAX_FLASH_BANKS];
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_char *addr, flash_info_t *info);
+static int write_data8 (flash_info_t *info, ulong dest, uchar data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ * Initialize the flash memory.
+ */
+unsigned long
+flash_init (void)
+{
+	volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	unsigned long size_b0;
+	int i;
+
+	for (i= 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+	}
+
+	/*
+	 * The gen860t board only has one FLASH memory device, so the
+	 * FLASH Bank configuration is done statically.
+	 */
+	PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM);
+	size_b0 = flash_get_size((vu_char *)FLASH_BASE0_PRELIM, &flash_info[0]);
+	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+		printf ("## Unknown FLASH on Bank 0: "
+				"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
+				flash_info[0].flash_id,size_b0, size_b0 << 20);
+	}
+
+	PRINTF("## Before remap:\n"
+		   "  BR0: 0x%08x    OR0: 0x%08x\n  BR1: 0x%08x    OR1: 0x%08x\n",
+		   memctl->memc_br0, memctl->memc_or0,
+		   memctl->memc_br1, memctl->memc_or1);
+
+	/*
+	 * Remap FLASH according to real size
+	 */
+	memctl->memc_or0 |= (-size_b0 & 0xFFFF8000);
+	memctl->memc_br0 |= (CFG_FLASH_BASE & BR_BA_MSK);
+
+	PRINTF("## After remap:\n"
+		   "  BR0: 0x%08x    OR0: 0x%08x\n", memctl->memc_br0, memctl->memc_or0);
+
+	/*
+	 * Re-do sizing to get full correct info
+	 */
+	size_b0 = flash_get_size ((vu_char *)CFG_FLASH_BASE, &flash_info[0]);
+	flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+	flash_info[0].size = size_b0;
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+	/*
+	 * Monitor protection is ON by default
+	 */
+	flash_protect(FLAG_PROTECT_SET,
+		      	  CFG_MONITOR_BASE,
+		      	  CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
+		      	  &flash_info[0]);
+#endif
+
+#ifdef	CFG_ENV_IS_IN_FLASH
+	/*
+	 * Environment protection ON by default
+	 */
+	flash_protect(FLAG_PROTECT_SET,
+		      	  CFG_ENV_ADDR,
+		      	  CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+		      	  &flash_info[0]);
+#endif
+
+	PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0);
+	return (size_b0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Fill in the FLASH offset table
+ */
+static void
+flash_get_offsets (ulong base, flash_info_t *info)
+{
+	int i;
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		return;
+	}
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+		case FLASH_MAN_INTEL:
+	    	for (i = 0; i < info->sector_count; i++) {
+				info->start[i] = base;
+				base += 1024 * 128;
+	    	}
+	    	return;
+
+		default:
+	   		printf ("Don't know sector offsets for FLASH"
+			        " type 0x%lx\n", info->flash_id);
+	    return;
+	}
+}
+
+
+/*-----------------------------------------------------------------------
+ * Display FLASH device info
+ */
+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_INTEL:
+			printf ("Intel ");
+			break;
+	default:
+			printf ("Unknown Vendor ");
+			break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_28F128J3A:
+			printf ("28F128J3A (128Mbit = 128K x 128)\n");
+			break;
+	default:
+			printf ("Unknown Chip Type\n");
+			break;
+	}
+
+	if (info->size >= (1024 * 1024)) {
+		i = 20;
+	} else {
+		i = 10;
+	}
+	printf ("  Size: %ld %cB in %d Sectors\n",
+			info->size >> i,
+			(i == 20) ? 'M' : 'k',
+			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");
+	return;
+}
+
+
+/*-----------------------------------------------------------------------
+ * Get size and other information for a FLASH device.
+ * NOTE: The following code cannot be run from FLASH!
+ */
+static
+ulong flash_get_size (vu_char *addr, flash_info_t *info)
+{
+#define NO_FLASH	0
+
+	vu_char value[2];
+
+	/*
+	 * Try to read the manufacturer ID
+	 */
+	addr[0] = SCS_READ_CMD;
+	addr[0] = SCS_READ_ID_CMD;
+	value[0] = addr[0];
+	value[1] = addr[2];
+	addr[0] = SCS_READ_CMD;
+
+	PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong)addr, value[0]);
+	switch (value[0]) {
+		case (INTEL_MANUFACT & 0xff):
+			info->flash_id = FLASH_MAN_INTEL;
+			break;
+		default:
+			info->flash_id = FLASH_UNKNOWN;
+			info->sector_count = 0;
+			info->size = 0;
+			return (NO_FLASH);
+	}
+
+	/*
+	 * Read the device ID
+	 */
+	PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong)(&addr[2]), value[1]);
+	switch (value[1]) {
+		case (INTEL_ID_28F128J3A & 0xff):
+			info->flash_id += FLASH_28F128J3A;
+			info->sector_count = 128;
+			info->size = 16 * 1024 * 1024;
+			break;
+
+		default:
+			info->flash_id = FLASH_UNKNOWN;
+			return (NO_FLASH);
+	}
+
+	if (info->sector_count > CFG_MAX_FLASH_SECT) {
+		printf ("** ERROR: sector count %d > max (%d) **\n",
+				info->sector_count, CFG_MAX_FLASH_SECT);
+				info->sector_count = CFG_MAX_FLASH_SECT;
+	}
+	return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Erase the specified sectors in the specified FLASH device
+ */
+int
+flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+	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_VENDMASK) != FLASH_MAN_INTEL) {
+		printf ("Can erase only Intel 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_char *addr = (uchar *)(info->start[sect]);
+			vu_char status;
+
+			/*
+			 * Disable interrupts which might cause a timeout
+			 */
+			flag = disable_interrupts();
+
+			*addr = SCS_CLEAR_STATUS_CMD;
+			*addr = SCS_BLOCK_ERASE_CMD;
+			*addr = SCS_BLOCK_ERASE_RESUME_CMD;
+
+			/*
+			 * Re-enable interrupts if necessary
+			 */
+			if (flag)
+				enable_interrupts();
+
+			/*
+			 * Wait at least 80us - let's wait 1 ms
+			 */
+			udelay (1000);
+
+			while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+				if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+					printf ("Timeout\n");
+					*addr = SCS_BLOCK_ERASE_SUSPEND_CMD;
+					*addr = SCS_READ_CMD;
+					return 1;
+				}
+
+				/*
+				 * Show that we're waiting
+				 */
+				if ((now - last) > 1000) {	/* 1 second */
+					putc ('.');
+					last = now;
+				}
+			}
+			*addr = SCS_READ_CMD;
+		}
+	}
+	printf (" done\n");
+	return 0;
+}
+
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+/*
+ * Allocate a flash buffer, fill it with data and write it to the flash.
+ * 0 - OK
+ * 1 - Timeout on buffer request
+ *
+ * NOTE: After the last call to this function, WSM status needs to be checked!
+ */
+static int
+write_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,
+				    uint count)
+{
+	vu_char *block_addr_p = NULL;
+	vu_char *start_addr_p = NULL;
+	ulong blocksize = info_p->size / (ulong)info_p->sector_count;
+
+	int i;
+	uint time = get_timer(0);
+
+	PRINTF("%s:%d: src: 0x%p dest: 0x%p  count: %d\n",
+		   __FUNCTION__, __LINE__, src_p, dest_p, count);
+
+	/*
+	 * What block are we in? We already know that the source address is
+	 * in the flash address range, but we also can't cross a block boundary.
+	 * We assume that the block does not cross a boundary (we'll check before
+	 * calling this function).
+	 */
+ 	for (i = 0; i < info_p->sector_count; ++i) {
+		if ( ((ulong)dest_p >= info_p->start[i]) &&
+		    ((ulong)dest_p < (info_p->start[i] + blocksize)) ) {
+			PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
+				   __FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);
+			block_addr_p = (vu_char *)info_p->start[i];
+			break;
+		}
+	}
+
+	/*
+	 * Request a buffer
+	 */
+	*block_addr_p = SCS_WRITE_BUF_CMD;
+	while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {
+		if (get_timer(time) >  CFG_FLASH_ALLOC_BUFFER_TOUT) {
+			PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
+				   __FUNCTION__, __LINE__, block_addr_p,
+				   CFG_FLASH_ALLOC_BUFFER_TOUT);
+			return 1;
+		}
+		*block_addr_p = SCS_WRITE_BUF_CMD;
+	}
+
+	/*
+	 * Fill the buffer with data
+	 */
+	start_addr_p = dest_p;
+	*block_addr_p = count - 1; /* flash device wants count - 1 */
+	PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
+		   __FUNCTION__, __LINE__, block_addr_p);
+	for (i = 0; i < count; i++) {
+		*start_addr_p++ = *src_p++;
+	}
+
+	/*
+	 * Flush buffer to flash
+	 */
+	*block_addr_p = SCS_PROGRAM_RESUME_CMD;
+#if 1
+	time = get_timer(0);
+	while ((*block_addr_p & SCS_SR7) != SCS_SR7) {
+		if (get_timer(time) >  CFG_FLASH_WRITE_TOUT) {
+			PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
+				   __FUNCTION__, __LINE__, block_addr_p, CFG_FLASH_WRITE_TOUT);
+			return 1;
+		}
+	}
+
+#endif
+	return 0;
+}
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+int
+write_buff(flash_info_t *info_p, uchar *src_p, ulong addr, ulong count)
+{
+	int rc = 0;
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+#define FLASH_WRITE_BUF_SIZE	0x00000020	/* 32 bytes */
+	int i;
+	uint bufs;
+	ulong buf_count;
+	vu_char *sp;
+	vu_char *dp;
+#else
+	ulong wp;
+#endif
+
+	PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
+		   __FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);
+
+	if (info_p->flash_id == FLASH_UNKNOWN) {
+		return 4;
+	}
+
+#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
+	sp = src_p;
+	dp = (uchar *)addr;
+
+	/*
+	 * For maximum performance, we want to align the start address to
+	 * the beginning of a write buffer boundary (i.e. A4-A0 of the
+	 * start address = 0). See how many bytes are required to get to a
+	 * write-buffer-aligned address.  If that number is non-zero, do
+	 * non buffered writes of the non-aligned data.  By doing non-buffered
+	 * writes, we avoid the problem of crossing a block (sector) boundary
+	 * with buffered writes.
+	 */
+	buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));
+	if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */
+		buf_count = 0;
+	}
+	if (buf_count > count) { /* not a full buffers worth of data to write */
+		buf_count = count;
+	}
+	count -= buf_count;
+
+	PRINTF("%s:%d: Write buffer alignment count = %ld\n",
+		   __FUNCTION__, __LINE__, buf_count);
+	while (buf_count-- >= 1) {
+		if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0)  {
+			return (rc);
+		}
+	}
+
+	PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);
+	if (count == 0) { /* all done */
+		PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
+			   __FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);
+		return (rc);
+	}
+
+	/*
+	 * Now that we are write buffer aligned, write full or partial buffers.
+	 * The fact that we are write buffer aligned automatically avoids
+	 * crossing a block address during a write buffer operation.
+	 */
+	bufs = count / FLASH_WRITE_BUF_SIZE;
+	PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,
+		   bufs, bufs);
+	while (bufs >= 1) {
+		rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);
+		if (rc != 0) {
+			PRINTF("%s:%d: ** Error writing buf %d\n",
+				   __FUNCTION__, __LINE__, bufs);
+			return (rc);
+		}
+		bufs--;
+		sp += FLASH_WRITE_BUF_SIZE;
+		dp += FLASH_WRITE_BUF_SIZE;
+	}
+
+	/*
+	 * Do the leftovers
+	 */
+	i = count % FLASH_WRITE_BUF_SIZE;
+	PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);
+	if (i > 0) {
+		rc = write_flash_buffer8(info_p, sp, dp, i);
+	}
+
+	sp = (vu_char*)info_p->start[0];
+	*sp = SCS_READ_CMD;
+	return (rc);
+
+#else
+	wp = addr;
+	while (count-- >= 1) {
+		if((rc = write_data8(info_p, wp++, *src_p++)) != 0)
+			return (rc);
+	}
+	return 0;
+#endif
+}
+
+
+/*-----------------------------------------------------------------------
+ * Write a byte to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int
+write_data8 (flash_info_t *info, ulong dest, uchar data)
+{
+	vu_char *addr = (vu_char *)dest;
+	vu_char status;
+	ulong start;
+	int flag;
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*addr & data) != data) {
+		return (2);
+	}
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	*addr = SCS_PROGRAM_CMD;
+	*addr = data;
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	start = get_timer (0);
+
+	while (((status = *addr) & SCS_SR7) != SCS_SR7) {
+		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+			*addr = SCS_READ_CMD;
+			return (1);
+		}
+	}
+	*addr = SCS_READ_CMD;
+	return (0);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/fpga.c b/board/gen860t/fpga.c
new file mode 100644
index 0000000..2c4fbf1
--- /dev/null
+++ b/board/gen860t/fpga.c
@@ -0,0 +1,401 @@
+/*
+ * (C) Copyright 2002
+ * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
+ * Keith Outwater, keith_outwater@mvis.com.
+ *
+ * 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
+ *
+ */
+
+/*
+ * Virtex2 FPGA configuration support for the GEN860T computer
+ */
+
+#include <common.h>
+#include <virtex2.h>
+#include <command.h>
+#include "fpga.h"
+
+#if (CONFIG_FPGA)
+
+#if 0
+#define GEN860T_FPGA_DEBUG
+#endif
+
+#ifdef GEN860T_FPGA_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define	PRINTF(fmt,args...)
+#endif
+
+/*
+ * Port bit numbers for the Selectmap controls
+ */
+#define FPGA_INIT_BIT_NUM		22	/* PB22 */
+#define FPGA_RESET_BIT_NUM		11	/* PC11 */
+#define FPGA_DONE_BIT_NUM		16	/* PB16 */
+#define FPGA_PROGRAM_BIT_NUM	7	/* PA7  */
+
+/* Note that these are pointers to code that is in Flash.  They will be
+ * relocated at runtime.
+ */
+Xilinx_Virtex2_Slave_SelectMap_fns fpga_fns = {
+	fpga_pre_config_fn,
+	fpga_pgm_fn,
+	fpga_init_fn,
+	fpga_err_fn,
+	fpga_done_fn,
+	fpga_clk_fn,
+	fpga_cs_fn,
+	fpga_wr_fn,
+	fpga_read_data_fn,
+	fpga_write_data_fn,
+	fpga_busy_fn,
+	fpga_abort_fn,
+	fpga_post_config_fn
+};
+
+Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
+	{ Xilinx_Virtex2,
+	  slave_selectmap,
+	  XILINX_XC2V3000_SIZE,
+	  (void *)&fpga_fns,
+	  0
+	}
+};
+
+/*
+ * Display FPGA revision information
+ */
+void
+print_fpga_revision(void)
+{
+	vu_long *rev_p = (vu_long *)0x60000008;
+
+	printf("FPGA Revision 0x%.8lx"
+		   " (Date %.2lx/%.2lx/%.2lx, Status \"%.1lx\", Version %.3lu)\n",
+		   *rev_p,
+		   ((*rev_p >> 28) & 0xf),
+		   ((*rev_p >> 20) & 0xff),
+		   ((*rev_p >> 12) & 0xff),
+		   ((*rev_p >> 8) & 0xf),
+		   (*rev_p & 0xff));
+}
+
+
+/*
+ * Perform a simple test of the FPGA to processor interface using the FPGA's
+ * inverting bus test register.  The great thing about doing a read/write
+ * test on a register that inverts it's contents is that you avoid any
+ * problems with bus charging.
+ * Return 0 on failure, 1 on success.
+ */
+int
+test_fpga_ibtr(void)
+{
+	vu_long *ibtr_p = (vu_long *)0x60000010;
+	vu_long readback;
+	vu_long compare;
+	int i;
+	int j;
+	int k;
+	int pass = 1;
+
+	static const ulong bitpattern[] = {
+		0xdeadbeef,	/* magic ID pattern for debug	*/
+		0x00000001,	/* single bit					*/
+		0x00000003,	/* two adjacent bits			*/
+		0x00000007,	/* three adjacent bits			*/
+		0x0000000F,	/* four adjacent bits			*/
+		0x00000005,	/* two non-adjacent bits		*/
+		0x00000015,	/* three non-adjacent bits		*/
+		0x00000055,	/* four non-adjacent bits		*/
+		0xaaaaaaaa,	/* alternating 1/0				*/
+	};
+
+	for (i = 0; i < 1024; i++) {
+		for (j = 0; j < 31; j++) {
+			for (k = 0; k < sizeof(bitpattern)/sizeof(bitpattern[0]); k++) {
+				*ibtr_p = compare = (bitpattern[k] << j);
+				readback = *ibtr_p;
+				if (readback != ~compare) {
+					printf("%s:%d: FPGA test fail: expected 0x%.8lx"
+						   " actual 0x%.8lx\n",
+						   __FUNCTION__, __LINE__, ~compare, readback);
+					pass = 0;
+					break;
+				}
+			}
+			if (!pass) break;
+		}
+		if (!pass) break;
+	}
+	if (pass) {
+		printf("FPGA inverting bus test passed\n");
+		print_fpga_revision();
+	}
+	else {
+		printf("** FPGA inverting bus test failed\n");
+	}
+	return pass;
+}
+
+
+/*
+ * Set the active-low FPGA reset signal.
+ */
+void
+fpga_reset(int assert)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: RESET ", __FUNCTION__, __LINE__);
+	if (assert) {
+		immap->im_ioport.iop_pcdat &= ~(0x8000 >> FPGA_RESET_BIT_NUM);
+		PRINTF("asserted\n");
+	}
+	else {
+		immap->im_ioport.iop_pcdat |= (0x8000 >> FPGA_RESET_BIT_NUM);
+		PRINTF("deasserted\n");
+	}
+}
+
+
+/*
+ * Initialize the SelectMap interface.  We assume that the mode and the
+ * initial state of all of the port pins have already been set!
+ */
+void
+fpga_selectmap_init(void)
+{
+	PRINTF("%s:%d: Initialize SelectMap interface\n", __FUNCTION__, __LINE__);
+	fpga_pgm_fn(FALSE, FALSE, 0);   /* make sure program pin is inactive */
+}
+
+
+/*
+ * Initialize the fpga.  Return 1 on success, 0 on failure.
+ */
+int
+gen860t_init_fpga(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int i;
+
+	PRINTF("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n",
+			__FUNCTION__, __LINE__, gd->reloc_off);
+	fpga_init(gd->reloc_off);
+	fpga_selectmap_init();
+
+	for(i=0; i < CONFIG_FPGA_COUNT; i++) {
+		PRINTF("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
+		fpga_add(fpga_xilinx, &fpga[i]);
+	}
+ 	return 1;
+}
+
+
+/*
+ * Set the FPGA's active-low SelectMap program line to the specified level
+ */
+int
+fpga_pgm_fn(int assert, int flush, int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
+
+	if (assert) {
+		immap->im_ioport.iop_padat &= ~(0x8000 >> FPGA_PROGRAM_BIT_NUM);
+		PRINTF("asserted\n");
+	}
+	else {
+		immap->im_ioport.iop_padat |= (0x8000 >> FPGA_PROGRAM_BIT_NUM);
+		PRINTF("deasserted\n");
+	}
+	return assert;
+}
+
+
+/*
+ * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
+ * asserted (low).
+ */
+int
+fpga_init_fn(int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
+	if(immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_INIT_BIT_NUM)) {
+		PRINTF("high\n");
+		return 0;
+	}
+	else {
+		PRINTF("low\n");
+		return 1;
+	}
+}
+
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+int
+fpga_done_fn(int cookie)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+	PRINTF("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
+	if (immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_DONE_BIT_NUM)) {
+		PRINTF("high\n");
+		return FPGA_SUCCESS;
+	}
+	else {
+		PRINTF("low\n");
+		return FPGA_FAIL;
+	}
+}
+
+
+/*
+ * Read FPGA SelectMap data.
+ */
+int
+fpga_read_data_fn(unsigned char *data, int cookie)
+{
+	vu_char *p = (vu_char *)SELECTMAP_BASE;
+
+	*data = *p;
+#if 0
+	PRINTF("%s: Read 0x%x into 0x%p\n", __FUNCTION__, (int)data, data);
+#endif
+	return (int)data;
+}
+
+
+/*
+ * Write data to the FPGA SelectMap port
+ */
+int
+fpga_write_data_fn(unsigned char data, int flush, int cookie)
+{
+	vu_char *p = (vu_char *)SELECTMAP_BASE;
+
+#if 0
+	PRINTF("%s: Write Data 0x%x\n", __FUNCTION__, (int)data);
+#endif
+	*p = data;
+	return (int)data;
+}
+
+
+/*
+ * Abort and FPGA operation
+ */
+int
+fpga_abort_fn(int cookie)
+{
+	PRINTF("%s:%d: FPGA program sequence aborted\n",
+		   __FUNCTION__, __LINE__);
+	return FPGA_FAIL;
+}
+
+
+/*
+ * FPGA pre-configuration function. Just make sure that
+ * FPGA reset is asserted to keep the FPGA from starting up after
+ * configuration.
+ */
+int
+fpga_pre_config_fn(int cookie)
+{
+	PRINTF("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
+	fpga_reset(TRUE);
+	return 0;
+}
+
+
+/*
+ * FPGA post configuration function. Blip the FPGA reset line and then see if
+ * the FPGA appears to be running.
+ */
+int
+fpga_post_config_fn(int cookie)
+{
+	int rc;
+
+	PRINTF("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
+	fpga_reset(TRUE);
+	udelay(1000);
+	fpga_reset(FALSE);
+	udelay (1000);
+
+	/*
+	 * Use the FPGA,s inverting bus test register to do a simple test of the
+	 * processor interface.
+	 */
+	rc = test_fpga_ibtr();
+	return rc;
+}
+
+
+/*
+ * Clock, chip select and write signal assert functions and error check
+ * and busy functions.  These are only stubs because the GEN860T selectmap
+ * interface handles sequencing of control signals automatically (it uses
+ * a memory-mapped interface to the FPGA SelectMap port).  The design of
+ * the interface guarantees that the SelectMap port cannot be overrun so
+ * no busy check is needed.  A configuration error is signalled by INIT
+ * going low during configuration, so there is no need for a separate error
+ * function.
+ */
+int
+fpga_clk_fn(int assert_clk, int flush, int cookie)
+{
+	return assert_clk;
+}
+
+int
+fpga_cs_fn(int assert_cs, int flush, int cookie)
+{
+	return assert_cs;
+}
+
+int
+fpga_wr_fn(int assert_write, int flush, int cookie)
+{
+	return assert_write;
+}
+
+int
+fpga_err_fn(int cookie)
+{
+	return 0;
+}
+
+int
+fpga_busy_fn(int cookie)
+{
+	return 0;
+}
+#endif
+
+/* vim: set ts=4 tw=78 sw=4: */
diff --git a/board/gen860t/gen860t.c b/board/gen860t/gen860t.c
new file mode 100644
index 0000000..16a3262
--- /dev/null
+++ b/board/gen860t/gen860t.c
@@ -0,0 +1,299 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com
+ *
+ * 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 <virtex2.h>
+#include <common.h>
+#include <mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include "beeper.h"
+#include "fpga.h"
+#include "ioport.h"
+
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
+
+#if defined(CFG_CMD_MII) && defined(CONFIG_MII)
+#include <net.h>
+#endif
+
+#if 0
+#define GEN860T_DEBUG
+#endif
+
+#ifdef GEN860T_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define	PRINTF(fmt,args...)
+#endif
+
+/*
+ * The following UPM init tables were generated automatically by
+ * Motorola's MCUINIT program. See the README file for UPM to
+ * SDRAM pin assignments if you want to type this data into
+ * MCUINIT in order to reverse engineer the waveforms.
+ */
+
+/*
+ * UPM initialization tables for MICRON MT48LC16M16A2TG SDRAM devices
+ * (UPMA) and Virtex FPGA SelectMap interface (UPMB).
+ * NOTE that unused areas of the table are used to hold NOP, precharge
+ * and mode register set sequences.
+ *
+ */
+#define	UPMA_NOP_ADDR			0x5
+#define	UPMA_PRECHARGE_ADDR		0x6
+#define UPMA_MRS_ADDR			0x12
+
+#define UPM_SINGLE_READ_ADDR	0x00
+#define UPM_BURST_READ_ADDR		0x08
+#define UPM_SINGLE_WRITE_ADDR	0x18
+#define UPM_BURST_WRITE_ADDR	0x20
+#define	UPM_REFRESH_ADDR		0x30
+
+const uint sdram_upm_table[] = {
+	/* single read   (offset 0x00 in upm ram) */
+	0x0e0fdc04, 0x01adfc04, 0x0fbffc00, 0x1fff5c05,
+	0xffffffff, 0x0fffffcd, 0x0fff0fce, 0xefcfffff,
+	/* burst read    (offset 0x08 in upm ram) */
+	0x0f0fdc04, 0x00fdfc04, 0xf0fffc00, 0xf0fffc00,
+	0xf1fffc00, 0xfffffc00, 0xfffffc05, 0xffffffff,
+	0xffffffff, 0xffffffff, 0x0ffffff4, 0x1f3d5ff4,
+	0xfffffff4, 0xfffffff5, 0xffffffff, 0xffffffff,
+	/* single write  (offset 0x18 in upm ram) */
+	0x0f0fdc04, 0x00ad3c00, 0x1fff5c05, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* burst write   (offset 0x20 in upm ram) */
+	0x0f0fdc00, 0x10fd7c00, 0xf0fffc00, 0xf0fffc00,
+	0xf1fffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xfffff7ff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* refresh       (offset 0x30 in upm ram) */
+	0x1ffddc84, 0xfffffc04, 0xfffffc04, 0xfffffc84,
+	0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* exception     (offset 0x3C in upm ram) */
+   };
+
+const uint selectmap_upm_table[] = {
+	/* single read   (offset 0x00 in upm ram) */
+	0x88fffc06, 0x00fff404, 0x00fffc04, 0x33fffc00,
+	0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* burst read    (offset 0x08 in upm ram) */
+	0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* single write  (offset 0x18 in upm ram) */
+	0x88fffc04, 0x00fff400, 0x77fffc05, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* burst write   (offset 0x20 in upm ram) */
+	0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* refresh       (offset 0x30 in upm ram) */
+	0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	/* exception     (offset 0x3C in upm ram) */
+	0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff
+};
+
+/*
+ * Check board identity.  Always successful (gives information only)
+ */
+int
+checkboard(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    unsigned char *s;
+    unsigned char buf[64];
+    int i;
+
+    i = getenv_r("board_id", buf, sizeof(buf));
+    s = (i>0) ? buf : NULL;
+
+	if (s) {
+		printf("%s ", s);
+	} else {
+		printf("<unknown> ");
+	}
+
+    i = getenv_r("serial#", buf, sizeof(buf));
+    s = (i>0) ? buf : NULL;
+
+	if (s) {
+		printf("S/N %s\n", s);
+	} else {
+		printf("S/N <unknown>\n");
+	}
+
+    printf("CPU at %s MHz, ",strmhz(buf, gd->cpu_clk));
+	printf("local bus at %s MHz\n", strmhz(buf, gd->bus_clk));
+    return (0);
+}
+
+/*
+ * Initialize SDRAM
+ */
+long int
+initdram(int board_type)
+{
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+    upmconfig(UPMA,
+			  (uint *)sdram_upm_table,
+			  sizeof(sdram_upm_table) / sizeof(uint)
+			 );
+
+    /*
+     * Setup MAMR register
+     */
+    memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+    memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+    /*
+     * Map CS1* to SDRAM bank
+     */
+    memctl->memc_or1 = CFG_OR1;
+    memctl->memc_br1 = CFG_BR1;
+
+	/*
+	 * Perform SDRAM initialization sequence:
+	 * 1. Apply at least one NOP command
+	 * 2. 100 uS delay (JEDEC standard says 200 uS)
+	 * 3. Issue 4 precharge commands
+	 * 4. Perform two refresh cycles
+	 * 5. Program mode register
+	 *
+	 * Program SDRAM for standard operation, sequential burst, burst length
+	 * of 4, CAS latency of 2.
+	 */
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(0) | UPMA_NOP_ADDR;
+	udelay(200);
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(4) | UPMA_PRECHARGE_ADDR;
+
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(2) | UPM_REFRESH_ADDR;
+
+    memctl->memc_mar = 0x00000088;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(1) | UPMA_MRS_ADDR;
+
+    memctl->memc_mar = 0x00000000;
+	memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
+					   MCR_MLCF(0) | UPMA_NOP_ADDR;
+	/*
+	 * Enable refresh
+	 */
+    memctl->memc_mamr |= MAMR_PTAE;
+
+    return (SDRAM_SIZE);
+}
+
+/*
+ * Disk On Chip (DOC) Millenium initialization.
+ * The DOC lives in the CS2* space
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void
+doc_probe(ulong physadr);
+
+void
+doc_init(void)
+{
+	printf("Probing at 0x%.8x: ", DOC_BASE);
+	doc_probe(DOC_BASE);
+}
+#endif
+
+/*
+ * Miscellaneous intialization
+ */
+int
+misc_init_r (void)
+{
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+	/*
+	 * Set up UPMB to handle the Virtex FPGA SelectMap interface
+	 */
+	upmconfig(UPMB, (uint *)selectmap_upm_table,
+			  sizeof(selectmap_upm_table) / sizeof(uint));
+
+    memctl->memc_mbmr = 0x0;
+
+	config_mpc8xx_ioports(immr);
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+	mii_init();
+#endif
+
+#if (CONFIG_FPGA)
+	gen860t_init_fpga();
+#endif
+	return 0;
+}
+
+/*
+ * Final init hook before entering command loop.
+ */
+int
+last_stage_init(void)
+{
+	unsigned char buf[256];
+	int i;
+
+	/*
+	 * Set LEDs here since status LED init code has already run
+	 */
+	status_led_set(STATUS_LED_BIT1, STATUS_LED_ON);
+	status_led_set(STATUS_LED_BIT3, STATUS_LED_ON);
+
+	/*
+	 * Turn the beeper volume all the way down in case this is a warm
+	 * boot.
+	 */
+	set_beeper_volume(-64);
+	init_beeper();
+
+	/*
+	 * Read the environment to see what to do with the beeper
+	 */
+    i = getenv_r("beeper", buf, sizeof(buf));
+	if (i > 0) {
+		do_beeper(buf);
+	}
+	return 0;
+}
+/* vim: set ts=4 sw=4 tw=78 : */
diff --git a/board/gen860t/ioport.c b/board/gen860t/ioport.c
new file mode 100644
index 0000000..5d6524d
--- /dev/null
+++ b/board/gen860t/ioport.c
@@ -0,0 +1,276 @@
+/*
+ * (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>
+#include <asm/8xx_immap.h>
+#include "ioport.h"
+
+#if 0
+#define IOPORT_DEBUG
+#endif
+
+#ifdef  IOPORT_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/*
+ * The ioport configuration table.
+ */
+const mpc8xx_iop_conf_t iop_conf_tab[NUM_PORTS][PORT_BITS] = {
+    /*
+	 * Port A configuration
+	 * Pin		Signal				Type	Active		Initial state
+	 * PA7 		fpgaProgramLowOut	Out		Low			High
+	 */
+    {	/*	    conf ppar psor pdir podr pdat pint	   function 		*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /* No pin			*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /* No pin			*/
+	/* PA15 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA12 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA11 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA10 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA9  */ { 1,   0,   0,   1,   0,   0,   0 }, /* grn bicolor LED 1*/
+	/* PA8  */ { 1,   0,   0,   1,   0,   0,   0 }, /* red bicolor LED 1*/
+	/* PA7  */ { 1,   0,   0,   1,   0,   1,   0 }, /* fpgaProgramLow	*/
+	/* PA6  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA5  */ { 1,   0,   0,   1,   0,   0,   0 }, /* grn bicolor LED 0*/
+	/* PA4  */ { 1,   0,   0,   1,   0,   0,   0 }, /* red bicolor LED 0*/
+	/* PA3  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA2  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA1  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PA0  */ { 0,   0,   0,   0,   0,   0,   0 }  /*	*/
+    },
+
+	/*
+	 * Pin		Signal			Type		Active		Initial state
+	 * PB14		docBusyLowIn	In			Low			X
+	 * PB15		gpio1Sig		Out			High		Low
+	 * PB16		fpgaDoneBi		In			High		X
+	 * PB17		swBitOkLowOut	Out			Low			Low
+	 * PB19		speakerVolSig	Out/Hi-Z	High/Low	High (Hi-Z)
+	 * PB22		fpgaInitLowBi	In			Low			X
+	 * PB23		batteryOkSig	In			High		X
+     */
+    {	/*	    conf ppar psor pdir podr pdat pint 	  function			*/
+	/* PB31 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB30 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB29 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB28 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB27 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB26 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB25 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB24 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB23 */ { 1,   0,   0,   0,   0,   0,   0 }, /* batteryOk		*/
+	/* PB22 */ { 1,   0,   0,   0,   0,   0,   0 }, /* fpgaInitLowBi	*/
+	/* PB21 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB20 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB19 */ { 1,   0,   0,   1,   1,   1,   0 }, /* speakerVol		*/
+	/* PB18 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PB17 */ { 1,   0,   0,   1,   0,   0,   0 }, /* swBitOkLow		*/
+	/* PB16 */ { 1,   0,   0,   0,   0,   0,   0 }, /* fpgaDone			*/
+	/* PB15 */ { 1,   0,   0,   1,   0,   0,   0 }, /* gpio1			*/
+	/* PB14 */ { 1,   0,   0,   0,   0,   0,   0 }  /* docBusyLow		*/
+    },
+
+	/*
+	 * Pin		Signal				Type	Active		Initial state
+	 * PC4		i2cBus1EnSig		Out		High		High
+	 * PC5		i2cBus2EnSig		Out		High		High
+	 * PC6		gpio0Sig			Out		High		Low
+	 * PC8		i2cBus3EnSig		Out		High		High
+	 * PC10		i2cBus4EnSig		Out		High		High
+	 * PC11		fpgaResetLowOut		Out		Low			High
+	 * PC12		systemBitOkIn		In		High		X
+	 * PC15		selfDreqLow			In		Low			X
+	 */
+    {	/*	    conf ppar psor pdir podr pdat pint 	  function			*/
+	/* N/A	*/ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A	*/ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC15 */ { 1,   0,   0,   0,   0,   0,   0 }, /* selfDreqLowIn	*/
+	/* PC14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC12 */ { 1,   0,   0,   0,   0,   0,   0 }, /* systemBitOkIn	*/
+	/* PC11 */ { 1,   0,   0,   1,   0,   1,   0 }, /* fpgaResetLowOut	*/
+	/* PC10 */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus4EnSig		*/
+	/* PC9  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC8  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus3EnSig		*/
+	/* PC7  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PC6  */ { 1,   0,   0,   1,   0,   1,   0 }, /* gpio0			*/
+	/* PC5  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus2EnSig		*/
+	/* PC4  */ { 1,   0,   0,   1,   0,   1,   0 }, /* i2cBus1EnSig		*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }  /*	*/
+    },
+
+    /* Port D configuration */
+    {	/*	    conf ppar psor pdir podr pdat pint 	   function			*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD15 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD14 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD13 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD12 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD11 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD10 */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD9  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD8  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD7  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD6  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD5  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD4  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* PD3  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }, /*	*/
+	/* N/A  */ { 0,   0,   0,   0,   0,   0,   0 }  /*	*/
+    }
+};
+
+/*
+ * Configure the MPC8XX I/O ports per the ioport configuration table
+ * (taken from ./cpu/mpc8260/cpu_init.c)
+ */
+void
+config_mpc8xx_ioports(volatile immap_t *immr)
+{
+    int portnum;
+
+    for (portnum = 0; portnum < NUM_PORTS; portnum++) {
+		uint pmsk = 0, ppar = 0, psor = 0, pdir = 0;
+		uint podr = 0, pdat = 0, pint = 0;
+		uint msk = 1;
+		mpc8xx_iop_conf_t *iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][0];
+		mpc8xx_iop_conf_t *eiopc = iopc + PORT_BITS;
+
+		/*
+		 * For all ports except port B, ignore the two don't care entries
+		 * in the configuration tables.
+		 */
+		if (portnum != 1) {
+			iopc = (mpc8xx_iop_conf_t *)&iop_conf_tab[portnum][2];
+		}
+
+		/*
+		 * NOTE: index 0 refers to pin 17, index 17 refers to pin 0
+		 */
+		while (iopc < eiopc) {
+	    	if (iopc->conf) {
+				pmsk |= msk;
+				if (iopc->ppar) ppar |= msk;
+				if (iopc->psor) psor |= msk;
+				if (iopc->pdir) pdir |= msk;
+				if (iopc->podr) podr |= msk;
+				if (iopc->pdat) pdat |= msk;
+				if (iopc->pint) pint |= msk;
+		    }
+		    msk <<= 1;
+	  	  iopc++;
+		}
+
+		PRINTF("%s:%d:\n  portnum=%d ", __FUNCTION__, __LINE__, portnum);
+#ifdef IOPORT_DEBUG
+		switch(portnum) {
+			case 0: printf("(A)\n"); break;
+			case 1: printf("(B)\n"); break;
+			case 2: printf("(C)\n"); break;
+			case 3: printf("(D)\n"); break;
+			default: printf("(?)\n"); break;
+		}
+#endif
+		PRINTF("  ppar=0x%.8x  pdir=0x%.8x  podr=0x%.8x\n"
+			   "  pdat=0x%.8x  psor=0x%.8x  pint=0x%.8x  pmsk=0x%.8x\n",
+			   ppar, pdir, podr, pdat, psor, pint, pmsk);
+
+		/*
+		 * Have to handle the ioports on a port-by-port basis since there
+		 * are three different flavors.
+		 */
+		if (pmsk != 0) {
+		    uint tpmsk = ~pmsk;
+
+			if (0 == portnum) { /* port A */
+		    	immr->im_ioport.iop_papar &= tpmsk;
+		    	immr->im_ioport.iop_padat =
+					(immr->im_ioport.iop_padat & tpmsk) | pdat;
+		    	immr->im_ioport.iop_padir =
+					(immr->im_ioport.iop_padir & tpmsk) | pdir;
+		    	immr->im_ioport.iop_paodr =
+					(immr->im_ioport.iop_paodr & tpmsk) | podr;
+		    	immr->im_ioport.iop_papar |= ppar;
+			}
+			else if (1 == portnum) { /* port B */
+		    	immr->im_cpm.cp_pbpar &= tpmsk;
+		    	immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & tpmsk) | pdat;
+		    	immr->im_cpm.cp_pbdir = (immr->im_cpm.cp_pbdir & tpmsk) | pdir;
+		    	immr->im_cpm.cp_pbodr = (immr->im_cpm.cp_pbodr & tpmsk) | podr;
+		    	immr->im_cpm.cp_pbpar |= ppar;
+			}
+			else if (2 == portnum) { /* port C */
+		    	immr->im_ioport.iop_pcpar &= tpmsk;
+		    	immr->im_ioport.iop_pcdat =
+					(immr->im_ioport.iop_pcdat & tpmsk) | pdat;
+		    	immr->im_ioport.iop_pcdir =
+					(immr->im_ioport.iop_pcdir & tpmsk) | pdir;
+		    	immr->im_ioport.iop_pcint =
+					(immr->im_ioport.iop_pcint & tpmsk) | pint;
+		    	immr->im_ioport.iop_pcso =
+					(immr->im_ioport.iop_pcso & tpmsk) | psor;
+		    	immr->im_ioport.iop_pcpar |= ppar;
+			}
+			else if (3 == portnum) { /* port D */
+		    	immr->im_ioport.iop_pdpar &= tpmsk;
+		    	immr->im_ioport.iop_pddat =
+					(immr->im_ioport.iop_pddat & tpmsk) | pdat;
+		    	immr->im_ioport.iop_pddir =
+					(immr->im_ioport.iop_pddir & tpmsk) | pdir;
+		    	immr->im_ioport.iop_pdpar |= ppar;
+			}
+		}
+    }
+
+	PRINTF("%s:%d: Port A:\n  papar=0x%.4x  padir=0x%.4x"
+		   "  paodr=0x%.4x\n  padat=0x%.4x\n", __FUNCTION__, __LINE__,
+		   immr->im_ioport.iop_papar, immr->im_ioport.iop_padir,
+		   immr->im_ioport.iop_paodr, immr->im_ioport.iop_padat);
+	PRINTF("%s:%d: Port B:\n  pbpar=0x%.8x  pbdir=0x%.8x"
+		   "  pbodr=0x%.8x\n  pbdat=0x%.8x\n", __FUNCTION__, __LINE__,
+		   immr->im_cpm.cp_pbpar, immr->im_cpm.cp_pbdir,
+		   immr->im_cpm.cp_pbodr, immr->im_cpm.cp_pbdat);
+	PRINTF("%s:%d: Port C:\n  pcpar=0x%.4x  pcdir=0x%.4x"
+		   "  pcdat=0x%.4x\n  pcso=0x%.4x  pcint=0x%.4x\n  ",
+		   __FUNCTION__, __LINE__, immr->im_ioport.iop_pcpar,
+		   immr->im_ioport.iop_pcdir, immr->im_ioport.iop_pcdat,
+		   immr->im_ioport.iop_pcso, immr->im_ioport.iop_pcint);
+	PRINTF("%s:%d: Port D:\n  pdpar=0x%.4x  pddir=0x%.4x"
+		   "  pddat=0x%.4x\n", __FUNCTION__, __LINE__,
+		   immr->im_ioport.iop_pdpar, immr->im_ioport.iop_pddir,
+		   immr->im_ioport.iop_pddat);
+}
+
+/* vim: set ts=4 sw=4 tw=78: */
diff --git a/board/gen860t/u-boot.lds b/board/gen860t/u-boot.lds
new file mode 100644
index 0000000..1b53c72
--- /dev/null
+++ b/board/gen860t/u-boot.lds
@@ -0,0 +1,135 @@
+/*
+ * Linker command file for the GEN860T board.
+ *
+ * (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);
+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/mpc8xx/start.o		(.text)
+    common/dlmalloc.o		(.text)
+    lib_ppc/ppcstring.o		(.text)
+    lib_generic/vsprintf.o	(.text)
+    lib_generic/crc32.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)
+   *(.bss)
+   *(COMMON)
+  }
+
+  _end = . ;
+  PROVIDE (end = .);
+}
+
diff --git a/board/impa7/flash.c b/board/impa7/flash.c
new file mode 100644
index 0000000..c59ffb8
--- /dev/null
+++ b/board/impa7/flash.c
@@ -0,0 +1,365 @@
+/*
+ * (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>
+
+#define FLASH_BANK_SIZE 0x800000
+#define MAIN_SECT_SIZE  0x20000
+#define PARAM_SECT_SIZE 0x4000
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init(void)
+{
+    int i, j;
+    ulong size = 0;
+
+    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
+    {
+	ulong flashbase = 0;
+	flash_info[i].flash_id =
+	  (INTEL_MANUFACT & FLASH_VENDMASK) |
+	  (INTEL_ID_28F320B3T & FLASH_TYPEMASK);
+	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);
+	if (i == 0)
+	  flashbase = PHYS_FLASH_1;
+	else if (i == 1)
+	  flashbase = PHYS_FLASH_2;
+	else
+	  panic("configured to many flash banks!\n");
+	for (j = 0; j < flash_info[i].sector_count; j++)
+	{
+	    if (j <= 7)
+	    {
+		flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;
+	    }
+	    else
+	    {
+		flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;
+	    }
+	}
+	size += flash_info[i].size;
+    }
+
+    /* Protect monitor and environment sectors
+     */
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_FLASH_BASE,
+		  CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
+		  &flash_info[0]);
+
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_ENV_ADDR,
+		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+		  &flash_info[0]);
+
+    return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+
+    switch (info->flash_id & FLASH_VENDMASK)
+    {
+    case (INTEL_MANUFACT & FLASH_VENDMASK):
+	printf("Intel: ");
+	break;
+    default:
+	printf("Unknown Vendor ");
+	break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK)
+    {
+    case (INTEL_ID_28F320B3T & FLASH_TYPEMASK):
+	printf("28F320F3B (16Mbit)\n");
+	break;
+    default:
+	printf("Unknown Chip Type\n");
+	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:
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int	flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+    int flag, prot, sect;
+    int rc = ERR_OK;
+
+    if (info->flash_id == FLASH_UNKNOWN)
+	return ERR_UNKNOWN_FLASH_TYPE;
+
+    if ((s_first < 0) || (s_first > s_last)) {
+	return ERR_INVAL;
+    }
+
+    if ((info->flash_id & FLASH_VENDMASK) !=
+	(INTEL_MANUFACT & FLASH_VENDMASK)) {
+	return ERR_UNKNOWN_FLASH_VENDOR;
+    }
+
+    prot = 0;
+    for (sect=s_first; sect<=s_last; ++sect) {
+	if (info->protect[sect]) {
+	    prot++;
+	}
+    }
+    if (prot)
+	return ERR_PROTECTED;
+
+    /*
+     * Disable interrupts which might cause a timeout
+     * here. Remember that our exception vectors are
+     * at address 0 in the flash, and we don't want a
+     * (ticker) exception to happen while the flash
+     * chip is in programming mode.
+     */
+    flag = disable_interrupts();
+
+    /* Start erase on unprotected sectors */
+    for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
+
+	printf("Erasing sector %2d ... ", sect);
+
+	/* arm simple, non interrupt dependent timer */
+	reset_timer_masked();
+
+	if (info->protect[sect] == 0) {	/* not protected */
+	    vu_long *addr = (vu_long *)(info->start[sect]);
+
+	    *addr = 0x00200020;	/* erase setup */
+	    *addr = 0x00D000D0;	/* erase confirm */
+
+	    while ((*addr & 0x00800080) != 0x00800080) {
+		if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
+		    *addr = 0x00B000B0; /* suspend erase */
+		    *addr = 0x00FF00FF;	/* reset to read mode */
+		    rc = ERR_TIMOUT;
+		    goto outahere;
+		}
+	    }
+
+	    *addr = 0x00FF00FF;	/* reset to read mode */
+	}
+	printf("ok.\n");
+    }
+    if (ctrlc())
+      printf("User Interrupt!\n");
+
+outahere:
+
+    /* allow flash to settle - wait 10 ms */
+    udelay_masked(10000);
+
+    if (flag)
+      enable_interrupts();
+
+    return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+    vu_long *addr = (vu_long *)dest;
+    ulong barf;
+    int rc = ERR_OK;
+    int flag;
+
+    /* Check if Flash is (sufficiently) erased
+     */
+    if ((*addr & data) != data)
+        return ERR_NOT_ERASED;
+
+    /*
+     * Disable interrupts which might cause a timeout
+     * here. Remember that our exception vectors are
+     * at address 0 in the flash, and we don't want a
+     * (ticker) exception to happen while the flash
+     * chip is in programming mode.
+     */
+    flag = disable_interrupts();
+
+    /* clear status register command */
+    *addr = 0x00500050;
+
+    /* program set-up command */
+    *addr = 0x00400040;
+
+    /* latch address/data */
+    *addr = data;
+
+    /* arm simple, non interrupt dependent timer */
+    reset_timer_masked();
+
+    /* read status register command */
+    *addr = 0x00700070;
+
+    /* wait while polling the status register */
+    while((*addr & 0x00800080) != 0x00800080)
+    {
+	if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
+	    rc = ERR_TIMOUT;
+	    /* suspend program command */
+	    *addr = 0x00B000B0;
+	    goto outahere;
+	}
+
+	if( *addr & 0x003A003A) {	/* check for error */
+	    barf = *addr;
+	    if( barf & 0x003A0000) {
+		barf >>=16;
+	    } else {
+		barf &= 0x0000003A;
+	    }
+	    printf("\nFlash write error %02lx at address %08lx\n",
+		   barf, (unsigned long)dest);
+	    if(barf & 0x0002) {
+		printf("Block locked, not erased.\n");
+		rc = ERR_NOT_ERASED;
+		goto outahere;
+	    }
+	    if(barf & 0x0010) {
+		printf("Programming error.\n");
+		rc = ERR_PROG_ERROR;
+		goto outahere;
+	    }
+	    if(barf & 0x0008) {
+		printf("Vpp Low error.\n");
+		rc = ERR_PROG_ERROR;
+		goto outahere;
+	    }
+	    rc = ERR_PROG_ERROR;
+	    goto outahere;
+	}
+    }
+
+
+outahere:
+    /* read array command */
+    *addr = 0x00FF00FF;
+
+    if (flag)
+      enable_interrupts();
+
+    return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong cp, wp, data;
+    int l;
+    int i, 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 << 24);
+	}
+	for (; i<4 && cnt>0; ++i) {
+	    data = (data >> 8) | (*src++ << 24);
+	    --cnt;
+	    ++cp;
+	}
+	for (; cnt==0 && i<4; ++i, ++cp) {
+	    data = (data >> 8) | (*(uchar *)cp << 24);
+	}
+
+	if ((rc = write_word(info, wp, data)) != 0) {
+	    return (rc);
+	}
+	wp += 4;
+    }
+
+    /*
+     * handle word aligned part
+     */
+    while (cnt >= 4) {
+	data = *((vu_long*)src);
+	if ((rc = write_word(info, wp, data)) != 0) {
+	    return (rc);
+	}
+	src += 4;
+	wp  += 4;
+	cnt -= 4;
+    }
+
+    if (cnt == 0) {
+	return ERR_OK;
+    }
+
+    /*
+     * handle unaligned tail bytes
+     */
+    data = 0;
+    for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+	data = (data >> 8) | (*src++ << 24);
+	--cnt;
+    }
+    for (; i<4; ++i, ++cp) {
+	data = (data >> 8) | (*(uchar *)cp << 24);
+    }
+
+    return write_word(info, wp, data);
+}
diff --git a/board/impa7/u-boot.lds b/board/impa7/u-boot.lds
new file mode 100644
index 0000000..0849648
--- /dev/null
+++ b/board/impa7/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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/arm720t/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/lart/u-boot.lds b/board/lart/u-boot.lds
new file mode 100644
index 0000000..f4b0ade
--- /dev/null
+++ b/board/lart/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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/sa1100/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/mbx8xx/mbx8xx.c b/board/mbx8xx/mbx8xx.c
new file mode 100644
index 0000000..9a9bf80
--- /dev/null
+++ b/board/mbx8xx/mbx8xx.c
@@ -0,0 +1,379 @@
+/*
+ * (C) Copyright 2000
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Board specific routines for the MBX
+ *
+ * - initialisation
+ * - interface to VPD data (mac address, clock speeds)
+ * - memory controller
+ * - serial io initialisation
+ * - ethernet io initialisation
+ *
+ * -----------------------------------------------------------------
+ * 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 <commproc.h>
+#include <mpc8xx.h>
+#include "dimm.h"
+#include "vpd.h"
+#include "csr.h"
+
+/* ------------------------------------------------------------------------- */
+
+static const uint sdram_table_40[] = {
+	/* DRAM - single read. (offset 0 in upm RAM)
+	 */
+	0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
+	0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst read. (offset 8 in upm RAM)
+	 */
+	0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
+	0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
+	0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - single write. (offset 18 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x33FF4804,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst write. (offset 20 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* refresh  (offset 30 in upm RAM)
+	 */
+	0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+	0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* exception. (offset 3c in upm RAM)
+	 */
+	0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+};
+
+static const uint sdram_table_50[] = {
+	/* DRAM - single read. (offset 0 in upm RAM)
+	 */
+	0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
+	0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst read. (offset 8 in upm RAM)
+	 */
+	0xCFAFC004, 0X0FAFC404, 0X0CAF8C04, 0X00AF0C04,
+  /*	0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C04,	*/
+	0X07AF0C08, 0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08,
+	0X0CAF0C04, 0X01AF0C04, 0X0FAF0C08, 0X0CAF0C04,
+  /*	0X10AF0C04, 0XF0AFC000, 0XF3FF4805, 0XFFFFC005,	*/
+	0X10AF0C04, 0XF0AFC000, 0XF3BF4805, 0XFFFFC005,
+
+	/* DRAM - single write. (offset 18 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
+	0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* DRAM - burst write. (offset 20 in upm RAM)
+	 */
+	0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+	0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* refresh  (offset 30 in upm RAM)
+	 */
+	0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+	0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
+	0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+	/* exception. (offset 3c in upm RAM)
+	 */
+	0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned int get_reffreq(void);
+static unsigned int board_get_cpufreq(void);
+
+void mbx_init (void)
+{
+	volatile immap_t *immr = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immr->im_memctl;
+	ulong speed, refclock, plprcr, sccr;
+	ulong br0_32 = memctl->memc_br0 & 0x400;
+
+	/* real-time clock status and control register */
+	immr->im_sitk.sitk_rtcsck = KAPWR_KEY;
+	immr->im_sit.sit_rtcsc = 0x00C3;
+
+	/* SIEL and SIMASK Registers (see MBX PRG 2-3) */
+	immr->im_siu_conf.sc_simask = 0x00000000;
+	immr->im_siu_conf.sc_siel = 0xAAAA0000;
+	immr->im_siu_conf.sc_tesr = 0xFFFFFFFF;
+
+	/*
+	 * Prepare access to i2c bus. The MBX offers 3 devices on the i2c bus:
+	 * 1. Vital Product Data (contains clock speeds, MAC address etc, see vpd.h)
+	 * 2. RAM  Specs (see dimm.h)
+	 * 2. DIMM Specs (see dimm.h)
+	 */
+	vpd_init ();
+
+	/* system clock and reset control register */
+	immr->im_clkrstk.cark_sccrk = KAPWR_KEY;
+	sccr = immr->im_clkrst.car_sccr;
+	sccr &= SCCR_MASK;
+	sccr |= CFG_SCCR;
+	immr->im_clkrst.car_sccr = sccr;
+
+	speed = board_get_cpufreq ();
+	refclock = get_reffreq ();
+
+#if ((CFG_PLPRCR & PLPRCR_MF_MSK) != 0)
+	plprcr = CFG_PLPRCR;
+#else
+	plprcr = immr->im_clkrst.car_plprcr;
+	plprcr &= PLPRCR_MF_MSK;	/* isolate MF field */
+	plprcr |= CFG_PLPRCR;		/* reset control bits   */
+#endif
+
+#ifdef CFG_USE_OSCCLK			/* See doc/README.MBX ! */
+	plprcr |= ((speed + refclock / 2) / refclock - 1) << 20;
+#endif
+
+	immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
+	immr->im_clkrst.car_plprcr = plprcr;
+
+	/*
+	 * preliminary setup of memory controller:
+	 * - map Flash, otherwise configuration/status
+	 *    registers won't be accessible when read
+	 *    by board_init_f.
+	 * - map NVRAM and configuation/status registers.
+	 * - map pci registers.
+	 * - DON'T map ram yet, this is done in initdram().
+	 */
+	switch (speed / 1000000) {
+	case 40:
+		memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+		memctl->memc_or0 = 0xFF800930;
+		memctl->memc_or4 = CFG_NVRAM_OR | 0x920;
+		memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+		break;
+	case 50:
+		memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+		memctl->memc_or0 = 0xFF800940;
+		memctl->memc_or4 = CFG_NVRAM_OR | 0x930;
+		memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+		break;
+	default:
+		hang ();
+		break;
+	}
+#ifdef CONFIG_USE_PCI
+	memctl->memc_or5 = CFG_PCIMEM_OR;
+	memctl->memc_br5 = CFG_PCIMEM_BASE | 0x001;
+	memctl->memc_or6 = CFG_PCIBRIDGE_OR;
+	memctl->memc_br6 = CFG_PCIBRIDGE_BASE | 0x001;
+#endif
+	/*
+	 * FIXME: I do not understand why I have to call this to
+	 * initialise the control register here before booting from
+	 * the PCMCIA card but if I do not the Linux kernel falls
+	 * over in a big heap. If you can answer this question I
+	 * would like to know about it.
+	 */
+	board_ether_init();
+}
+
+void board_serial_init (void)
+{
+	MBX_CSR1 &= ~(CSR1_COM1EN | CSR1_XCVRDIS);
+}
+
+void board_ether_init (void)
+{
+	MBX_CSR1 &= ~(CSR1_EAEN | CSR1_ELEN);
+	MBX_CSR1 |= CSR1_ETEN | CSR1_TPEN | CSR1_FDDIS;
+}
+
+static unsigned int board_get_cpufreq (void)
+{
+#ifndef CONFIG_8xx_GCLK_FREQ
+	vpd_packet_t *packet;
+
+	packet = vpd_find_packet (VPD_PID_ICS);
+	return *((ulong *) packet->data);
+#else
+	return((unsigned int)CONFIG_8xx_GCLK_FREQ );
+#endif /* CONFIG_8xx_GCLK_FREQ */
+}
+
+static unsigned int get_reffreq (void)
+{
+	vpd_packet_t *packet;
+
+	packet = vpd_find_packet (VPD_PID_RCS);
+	return *((ulong *) packet->data);
+}
+
+void board_get_enetaddr (uchar * addr)
+{
+	int i;
+	vpd_packet_t *packet;
+
+	packet = vpd_find_packet (VPD_PID_EA);
+	for (i = 0; i < 6; i++)
+		addr[i] = packet->data[i];
+}
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+	vpd_packet_t *packet;
+	int i;
+	const char *const fmt =
+		"\n	 *** Warning: Low Battery Status - %s Battery ***";
+
+	puts ("Board: ");
+
+	packet = vpd_find_packet (VPD_PID_PID);
+	for (i = 0; i < packet->size; i++) {
+		serial_putc (packet->data[i]);
+	}
+	packet = vpd_find_packet (VPD_PID_MT);
+	for (i = 0; i < packet->size; i++) {
+		serial_putc (packet->data[i]);
+	}
+	serial_putc ('(');
+	packet = vpd_find_packet (VPD_PID_FAN);
+	for (i = 0; i < packet->size; i++) {
+		serial_putc (packet->data[i]);
+	}
+	serial_putc (')');
+
+	if (!(MBX_CSR2 & SR2_BATGD))
+		printf (fmt, "On-Board");
+	if (!(MBX_CSR2 & SR2_NVBATGD))
+		printf (fmt, "NVRAM");
+
+	serial_putc ('\n');
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static ulong get_ramsize (dimm_t * dimm)
+{
+	ulong size = 0;
+
+	if (dimm->fmt == 1 || dimm->fmt == 2 || dimm->fmt == 3
+		|| dimm->fmt == 4) {
+		size = (1 << (dimm->n_row + dimm->n_col)) * dimm->n_banks *
+			((dimm->data_w_hi << 8 | dimm->data_w_lo) / 8);
+	}
+
+	return size;
+}
+
+long int initdram (int board_type)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	unsigned long ram_sz = 0;
+	unsigned long dimm_sz = 0;
+	dimm_t vpd_dimm, vpd_dram;
+	unsigned int speed = board_get_cpufreq () / 1000000;
+
+	if (vpd_read (0xa2, (uchar *) & vpd_dimm, sizeof (vpd_dimm), 0) > 0) {
+		dimm_sz = get_ramsize (&vpd_dimm);
+	}
+	if (vpd_read (0xa6, (uchar *) & vpd_dram, sizeof (vpd_dram), 0) > 0) {
+		ram_sz = get_ramsize (&vpd_dram);
+	}
+
+	/*
+	 * Only initialize memory controller when running from FLASH.
+	 * When running from RAM, don't touch it.
+	 */
+	if ((ulong) initdram & 0xff000000) {
+		ulong dimm_bank;
+		ulong br0_32 = memctl->memc_br0 & 0x400;
+
+		switch (speed) {
+		case 40:
+			upmconfig (UPMA, (uint *) sdram_table_40,
+					   sizeof (sdram_table_40) / sizeof (uint));
+			memctl->memc_mptpr = 0x0200;
+			memctl->memc_mamr = dimm_sz ? 0x06801000 : 0x13801000;
+			memctl->memc_or7 = 0xff800930;
+			memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+			break;
+		case 50:
+			upmconfig (UPMA, (uint *) sdram_table_50,
+					   sizeof (sdram_table_50) / sizeof (uint));
+			memctl->memc_mptpr = 0x0200;
+			memctl->memc_mamr = dimm_sz ? 0x08801000 : 0x1880100;
+			memctl->memc_or7 = 0xff800940;
+			memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+			break;
+		default:
+			hang ();
+			break;
+		}
+
+		/* now map ram and dimm, largest one first */
+		dimm_bank = dimm_sz / 2;
+		if (!dimm_sz) {
+			memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+			memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+			memctl->memc_br2 = 0;
+			memctl->memc_br3 = 0;
+		} else if (ram_sz > dimm_bank) {
+			memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+			memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+			memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br2 = (CFG_SDRAM_BASE + ram_sz) | 0x81;
+			memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br3 = (CFG_SDRAM_BASE + ram_sz + dimm_bank) \
+								     | 0x81;
+		} else {
+			memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br2 = CFG_SDRAM_BASE | 0x81;
+			memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+			memctl->memc_br3 = (CFG_SDRAM_BASE + dimm_bank) | 0x81;
+			memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+			memctl->memc_br1 = (CFG_SDRAM_BASE + dimm_sz) | 0x81;
+		}
+	}
+
+	return ram_sz + dimm_sz;
+}
diff --git a/board/ml2/serial.c b/board/ml2/serial.c
new file mode 100644
index 0000000..dc9a8ea
--- /dev/null
+++ b/board/ml2/serial.c
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2002
+ * Peter De Schrijver (p2@mind.be), Mind Linux Solutions, NV.
+ *
+ * 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 <asm/u-boot.h>
+#include <asm/processor.h>
+#include <common.h>
+#include <command.h>
+#include <configs/ML2.h>
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+#include <ns16550.h>
+#endif
+
+#if 0
+#include "serial.h"
+#endif
+
+#if (defined CFG_INIT_CHAN1) || (defined CFG_INIT_CHAN2)
+const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1,
+		                (NS16550_t) CFG_NS16550_COM2 };
+#endif
+
+int
+serial_init (void)
+{
+		DECLARE_GLOBAL_DATA_PTR;
+
+	    int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+	    (void)NS16550_init(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+	    (void)NS16550_init(COM_PORTS[1], clock_divisor);
+#endif
+		return 0;
+
+}
+
+void
+serial_putc(const char c)
+{
+    if (c == '\n')
+        NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+
+    NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+    return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+    return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+    NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+    NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar (int c)
+{
+	serial_putc (c);
+}
+
+void
+putDebugStr (const char *str)
+{
+	serial_puts (str);
+}
+
+int
+getDebugChar (void)
+{
+	return serial_getc();
+}
+
+void
+kgdb_interruptible (int yes)
+{
+	return;
+}
+#endif	/* CFG_CMD_KGDB	*/
diff --git a/board/mousse/pci.c b/board/mousse/pci.c
new file mode 100644
index 0000000..89ca235
--- /dev/null
+++ b/board/mousse/pci.c
@@ -0,0 +1,283 @@
+/*
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * James Dougherty (jfd@cs.stanford.edu)
+ *
+ * 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
+ */
+
+/*
+ * PCI Configuration space access support for MPC824x/MPC107 PCI Bridge
+ */
+#include <common.h>
+#include <mpc824x.h>
+#include <pci.h>
+
+#include "mousse.h"
+
+/*
+ * Promise ATA/66 support.
+ */
+#define XFER_PIO_4	0x0C	/* 0000|1100 */
+#define XFER_PIO_3	0x0B	/* 0000|1011 */
+#define XFER_PIO_2	0x0A	/* 0000|1010 */
+#define XFER_PIO_1	0x09	/* 0000|1001 */
+#define XFER_PIO_0	0x08	/* 0000|1000 */
+#define XFER_PIO_SLOW	0x00	/* 0000|0000 */
+
+/* Promise Regs */
+#define REG_A		0x01
+#define REG_B		0x02
+#define REG_C		0x04
+#define REG_D		0x08
+
+void
+pdc202xx_decode_registers (unsigned char registers, unsigned char value)
+{
+	unsigned char	bit = 0, bit1 = 0, bit2 = 0;
+	switch(registers) {
+		case REG_A:
+			bit2 = 0;
+			printf("  A Register ");
+			if (value & 0x80) printf("SYNC_IN ");
+			if (value & 0x40) printf("ERRDY_EN ");
+			if (value & 0x20) printf("IORDY_EN ");
+			if (value & 0x10) printf("PREFETCH_EN ");
+			if (value & 0x08) { printf("PA3 ");bit2 |= 0x08; }
+			if (value & 0x04) { printf("PA2 ");bit2 |= 0x04; }
+			if (value & 0x02) { printf("PA1 ");bit2 |= 0x02; }
+			if (value & 0x01) { printf("PA0 ");bit2 |= 0x01; }
+			printf("PIO(A) = %d ", bit2);
+			break;
+		case REG_B:
+			bit1 = 0;bit2 = 0;
+			printf("  B Register ");
+			if (value & 0x80) { printf("MB2 ");bit1 |= 0x80; }
+			if (value & 0x40) { printf("MB1 ");bit1 |= 0x40; }
+			if (value & 0x20) { printf("MB0 ");bit1 |= 0x20; }
+			printf("DMA(B) = %d ", bit1 >> 5);
+			if (value & 0x10) printf("PIO_FORCED/PB4 ");
+			if (value & 0x08) { printf("PB3 ");bit2 |= 0x08; }
+			if (value & 0x04) { printf("PB2 ");bit2 |= 0x04; }
+			if (value & 0x02) { printf("PB1 ");bit2 |= 0x02; }
+			if (value & 0x01) { printf("PB0 ");bit2 |= 0x01; }
+			printf("PIO(B) = %d ", bit2);
+			break;
+		case REG_C:
+			bit2 = 0;
+			printf("  C Register ");
+			if (value & 0x80) printf("DMARQp ");
+			if (value & 0x40) printf("IORDYp ");
+			if (value & 0x20) printf("DMAR_EN ");
+			if (value & 0x10) printf("DMAW_EN ");
+
+			if (value & 0x08) { printf("MC3 ");bit2 |= 0x08; }
+			if (value & 0x04) { printf("MC2 ");bit2 |= 0x04; }
+			if (value & 0x02) { printf("MC1 ");bit2 |= 0x02; }
+			if (value & 0x01) { printf("MC0 ");bit2 |= 0x01; }
+			printf("DMA(C) = %d ", bit2);
+			break;
+		case REG_D:
+			printf("  D Register ");
+			break;
+		default:
+			return;
+	}
+	printf("\n        %s ", (registers & REG_D) ? "DP" :
+				(registers & REG_C) ? "CP" :
+				(registers & REG_B) ? "BP" :
+				(registers & REG_A) ? "AP" : "ERROR");
+	for (bit=128;bit>0;bit/=2)
+		printf("%s", (value & bit) ? "1" : "0");
+	printf("\n");
+}
+
+/*
+ * Promise ATA/66 Support: configure Promise ATA66 card in specified mode.
+ */
+int
+pdc202xx_tune_chipset (pci_dev_t dev, int drive, unsigned char speed)
+{
+	unsigned short		drive_conf;
+	int			err = 0;
+	unsigned char			drive_pci, AP, BP, CP, DP;
+	unsigned char			TA = 0, TB = 0;
+
+	switch (drive) {
+		case 0: drive_pci = 0x60; break;
+		case 1: drive_pci = 0x64; break;
+		case 2: drive_pci = 0x68; break;
+		case 3: drive_pci = 0x6c; break;
+		default: return -1;
+	}
+
+	pci_read_config_word(dev, drive_pci, &drive_conf);
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+
+	if ((AP & 0x0F) || (BP & 0x07)) {
+	  /* clear PIO modes of lower 8421 bits of A Register */
+	  pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
+	  pci_read_config_byte(dev, (drive_pci), &AP);
+
+	  /* clear PIO modes of lower 421 bits of B Register */
+	  pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
+	  pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+
+	  pci_read_config_byte(dev, (drive_pci), &AP);
+	  pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	}
+
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+
+	switch(speed) {
+		case XFER_PIO_4:	TA = 0x01; TB = 0x04; break;
+		case XFER_PIO_3:	TA = 0x02; TB = 0x06; break;
+		case XFER_PIO_2:	TA = 0x03; TB = 0x08; break;
+		case XFER_PIO_1:	TA = 0x05; TB = 0x0C; break;
+		case XFER_PIO_0:
+		default:		TA = 0x09; TB = 0x13; break;
+	}
+
+	pci_write_config_byte(dev, (drive_pci), AP|TA);
+	pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
+
+	pci_read_config_byte(dev, (drive_pci), &AP);
+	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+
+
+#ifdef PDC202XX_DEBUG
+	pdc202xx_decode_registers(REG_A, AP);
+	pdc202xx_decode_registers(REG_B, BP);
+	pdc202xx_decode_registers(REG_C, CP);
+	pdc202xx_decode_registers(REG_D, DP);
+#endif
+	return err;
+}
+/*
+ * Show/Init PCI devices on the specified bus number.
+ */
+
+void pci_mousse_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	unsigned int line;
+
+	switch(PCI_DEV(dev)) {
+	case 0x0d:
+		line = 0x00000101;
+		break;
+
+	case 0x0e:
+	default:
+		line = 0x00000303;
+		break;
+	}
+
+	pci_write_config_dword(dev, PCI_INTERRUPT_LINE, line);
+}
+
+void pci_mousse_setup_pdc202xx(struct pci_controller *hose, pci_dev_t dev,
+			       struct pci_config_table *_)
+{
+	unsigned short vendorId;
+	unsigned int mbar0, cmd;
+	int bar, a;
+
+	pci_read_config_word(dev, PCI_VENDOR_ID, &vendorId);
+
+	if(vendorId == PCI_VENDOR_ID_PROMISE || vendorId == PCI_VENDOR_ID_CMD){
+		/* PDC 202xx card is handled differently, it is a bootable
+		 * device and needs all 5 MBAR's configured
+		 */
+		for(bar = 0; bar < 5; bar++){
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, ~0);
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+#ifdef DEBUG
+			printf("  ATA_bar[%d] = %dbytes\n", bar,
+			       ~(mbar0 & PCI_BASE_ADDRESS_MEM_MASK) + 1);
+#endif
+		}
+
+		/* Program all BAR's */
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PROMISE_MBAR0);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, PROMISE_MBAR1);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_2,	PROMISE_MBAR2);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_3,	PROMISE_MBAR3);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_4,	PROMISE_MBAR4);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_5,	PROMISE_MBAR5);
+
+		for(bar = 0; bar < 5; bar++){
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0+bar*4, &mbar0);
+#ifdef DEBUG
+			printf("  ATA_bar[%d]@0x%x\n", bar, mbar0);
+#endif
+		}
+
+		/* Enable ROM Expansion base */
+		pci_write_config_dword(dev, PCI_ROM_ADDRESS, PROMISE_MBAR5|1);
+
+		/* Io enable, Memory enable, master enable */
+		pci_read_config_dword(dev, PCI_COMMAND, &cmd);
+		cmd &= ~0xffff0000;
+		cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+		pci_write_config_dword(dev, PCI_COMMAND, cmd);
+
+		/* Breath some life into the controller */
+		for( a = 0; a < 4; a++)
+			pdc202xx_tune_chipset(dev, a, XFER_PIO_0);
+	}
+}
+
+static struct pci_config_table pci_sandpoint_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0e, 0x00,
+	  pci_mousse_setup_pdc202xx },
+#ifndef CONFIG_PCI_PNP
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 0x0d, 0x00,
+	  pci_cfgfunc_config_device, {PCI_ENET_IOADDR,
+				      PCI_ENET_MEMADDR,
+				      PCI_COMMAND_MEMORY |
+				      PCI_COMMAND_MASTER}},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, {PCI_SLOT_IOADDR,
+				      PCI_SLOT_MEMADDR,
+				      PCI_COMMAND_MEMORY |
+				      PCI_COMMAND_MASTER}},
+#endif
+	{ }
+};
+
+struct pci_controller hose = {
+	config_table: pci_sandpoint_config_table,
+	fixup_irq: pci_mousse_fixup_irq,
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c
new file mode 100644
index 0000000..60c49af
--- /dev/null
+++ b/board/mpl/common/common_util.c
@@ -0,0 +1,606 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <video_fb.h>
+#include "common_util.h"
+#include <asm/processor.h>
+#include <i2c.h>
+#include <devices.h>
+#include <pci.h>
+
+extern int  gunzip (void *, int, unsigned char *, int *);
+extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
+
+#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
+#define IMAGE_SIZE 0x80000
+
+extern flash_info_t flash_info[];	/* info for FLASH chips */
+
+image_header_t header;
+
+
+
+int mpl_prg(unsigned long src,unsigned long size)
+{
+	unsigned long start;
+	flash_info_t *info;
+	int i,rc;
+	unsigned long *magic = (unsigned long *)src;
+
+	info = &flash_info[0];
+  	start = 0 - size;
+	for(i=info->sector_count-1;i>0;i--)
+	{
+		info->protect[i] = 0; /* unprotect this sector */
+		if(start>=info->start[i])
+		break;
+	}
+	/* set-up flash location */
+	/* now erase flash */
+	if(magic[0]!=IH_MAGIC) {
+		printf("Bad Magic number\n");
+		return -1;
+	}
+	printf("Erasing at %lx (sector %d) (start %lx)\n",
+				start,i,info->start[i]);
+	flash_erase (info, i, info->sector_count-1);
+	printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
+	if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
+		puts ("ERROR ");
+		flash_perror (rc);
+		return (1);
+	}
+	puts ("OK programming done\n");
+	return 0;
+}
+
+
+int mpl_prg_image(unsigned long ld_addr)
+{
+	unsigned long data,len,checksum;
+	image_header_t *hdr=&header;
+	/* Copy header so we can blank CRC field for re-calculation */
+	memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
+	if (hdr->ih_magic  != IH_MAGIC) {
+		printf ("Bad Magic Number\n");
+		return 1;
+	}
+	print_image_hdr(hdr);
+	if (hdr->ih_os  != IH_OS_U_BOOT) {
+		printf ("No U-Boot Image\n");
+		return 1;
+	}
+	if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
+		printf ("No Firmware Image\n");
+		return 1;
+	}
+	data = (ulong)&header;
+	len  = sizeof(image_header_t);
+	checksum = hdr->ih_hcrc;
+	hdr->ih_hcrc = 0;
+	if (crc32 (0, (char *)data, len) != checksum) {
+		printf ("Bad Header Checksum\n");
+		return 1;
+	}
+	data = ld_addr + sizeof(image_header_t);
+	len  = hdr->ih_size;
+	printf ("Verifying Checksum ... ");
+	if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
+		printf ("Bad Data CRC\n");
+		return 1;
+	}
+	switch (hdr->ih_comp) {
+	case IH_COMP_NONE:
+		break;
+	case IH_COMP_GZIP:
+		printf ("  Uncompressing  ... ");
+		if (gunzip ((void *)(data+0x100000), 0x400000,
+			    (uchar *)data, (int *)&len) != 0) {
+			printf ("GUNZIP ERROR\n");
+			return 1;
+		}
+		data+=0x100000;
+		break;
+	default:
+		printf ("   Unimplemented compression type %d\n", hdr->ih_comp);
+		return 1;
+	}
+
+	printf ("  OK\n");
+	return(mpl_prg(data,len));
+}
+
+
+void get_backup_values(backup_t *buf)
+{
+	i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
+}
+
+void set_backup_values(int overwrite)
+{
+	backup_t back;
+	int i;
+
+	get_backup_values(&back);
+	if(!overwrite) {
+		if(strncmp(back.signature,"MPL\0",4)==0) {
+			printf("Not possible to write Backup\n");
+			return;
+		}
+	}
+	memcpy(back.signature,"MPL\0",4);
+	i=getenv_r("serial#",back.serial_name,16);
+	if(i==0) {
+		printf("Not possible to write Backup\n");
+		return;
+	}
+	back.serial_name[16]=0;
+	i=getenv_r("ethaddr",back.eth_addr,20);
+	if(i==0) {
+		printf("Not possible to write Backup\n");
+		return;
+	}
+	back.eth_addr[20]=0;
+	i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+}
+
+void clear_env_values(void)
+{
+	backup_t back;
+	unsigned char env_crc[4];
+
+	memset(&back,0xff,sizeof(backup_t));
+	memset(env_crc,0x00,4);
+	i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
+	i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
+}
+
+/*
+ * check crc of "older" environment
+ */
+int check_env_old_size(ulong oldsize)
+{
+	ulong crc, len, new;
+	unsigned off;
+	uchar buf[64];
+
+	/* read old CRC */
+	eeprom_read (CFG_DEF_EEPROM_ADDR,
+		     CFG_ENV_OFFSET,
+		     (uchar *)&crc, sizeof(ulong));
+
+	new = 0;
+	len = oldsize;
+	off = sizeof(long);
+	len = oldsize-off;
+	while (len > 0) {
+		int n = (len > sizeof(buf)) ? sizeof(buf) : len;
+
+		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
+		new = crc32 (new, buf, n);
+		len -= n;
+		off += n;
+	}
+
+	return (crc == new);
+}
+
+static ulong oldsizes[] = {
+	0x200,
+	0x800,
+	0
+};
+
+void copy_old_env(ulong size)
+{
+	uchar name_buf[64];
+	uchar value_buf[0x800];
+	uchar c;
+	ulong len;
+	unsigned off;
+	uchar *name, *value;
+
+	name=&name_buf[0];
+	value=&value_buf[0];
+	len=size;
+	off = sizeof(long);
+	while (len > off) {
+		eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
+		if(c != '=') {
+			*name++=c;
+			off++;
+		}
+		else {
+			*name++='\0';
+			off++;
+			do {
+				eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
+				*value++=c;
+				off++;
+				if(c == '\0')
+					break;
+			} while(len > off);
+			name=&name_buf[0];
+			value=&value_buf[0];
+			if(strncmp(name,"baudrate",8)!=0) {
+				setenv(name,value);
+			}
+
+		}
+	}
+}
+
+
+void check_env(void)
+{
+	unsigned char *s;
+	int i=0;
+	char buf[32];
+	backup_t back;
+
+	s=getenv("serial#");
+	if(!s) {
+		while(oldsizes[i]) {
+			if(check_env_old_size(oldsizes[i]))
+				break;
+			i++;
+		}
+		if(!oldsizes[i]) {
+			/* no old environment has been found */
+			get_backup_values (&back);
+			if (strncmp (back.signature, "MPL\0", 4) == 0) {
+				sprintf (buf, "%s", back.serial_name);
+				setenv ("serial#", buf);
+				sprintf (buf, "%s", back.eth_addr);
+				setenv ("ethaddr", buf);
+				printf ("INFO:  serial# and ethaddr recovered, use saveenv\n");
+				return;
+			}
+		}
+		else {
+			copy_old_env(oldsizes[i]);
+			printf ("INFO:  old environment ajusted, use saveenv\n");
+		}
+	}
+	else {
+		/* check if back up is set */
+		get_backup_values(&back);
+		if(strncmp(back.signature,"MPL\0",4)!=0) {
+			set_backup_values(0);
+		}
+	}
+}
+
+
+
+extern device_t *stdio_devices[];
+extern char *stdio_names[];
+
+void show_stdio_dev(void)
+{
+	/* Print informations */
+	printf ("In:    ");
+	if (stdio_devices[stdin] == NULL) {
+		printf ("No input devices available!\n");
+	} else {
+		printf ("%s\n", stdio_devices[stdin]->name);
+	}
+
+	printf ("Out:   ");
+	if (stdio_devices[stdout] == NULL) {
+		printf ("No output devices available!\n");
+	} else {
+		printf ("%s\n", stdio_devices[stdout]->name);
+	}
+
+	printf ("Err:   ");
+	if (stdio_devices[stderr] == NULL) {
+		printf ("No error devices available!\n");
+	} else {
+		printf ("%s\n", stdio_devices[stderr]->name);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+	/* switches the cs0 and the cs1 to the locations.
+	   When boot is TRUE, the the mapping is switched
+	   to the boot configuration, If it is FALSE, the
+	   flash will be switched in the boot area */
+
+#undef SW_CS_DBG
+#ifdef SW_CS_DBG
+#define	SW_CS_PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define SW_CS_PRINTF(fmt,args...)
+#endif
+
+
+int switch_cs(unsigned char boot)
+{
+  	unsigned long pbcr;
+	mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
+	pbcr = mfdcr(ebccfgd);
+	if((pbcr&0x00002000)==0) {
+		/* we need only to switch if boot from MPS */
+		/*printf(" MPS boot mode detected. ");*/
+		/* printf("cs0 cfg: %lx\n",pbcr); */
+		if(boot) {
+			/* switch to boot configuration */
+			/* this is a 8bit boot, switch cs0 to flash location */
+			SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
+			pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+			mtdcr(ebccfga, pb0cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
+			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+			pbcr = mfdcr(ebccfgd);
+			SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
+			pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+			mtdcr(ebccfga, pb1cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
+		}
+		else
+		{
+			/* map flash to boot area, */
+			SW_CS_PRINTF("map Flash to boot area\n");
+			pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+			mtdcr(ebccfga, pb0cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
+			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+			pbcr = mfdcr(ebccfgd);
+			SW_CS_PRINTF("  cs1 cfg: %lx\n",pbcr);
+			pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+			mtdcr(ebccfga, pb1cr);
+			mtdcr(ebccfgd, pbcr);
+			SW_CS_PRINTF("  new cs1 cfg: %lx Flash is on High Address\n",pbcr);
+		}
+		return 1;
+	}
+	else {
+		SW_CS_PRINTF("Normal boot, no switching necessary\n");
+		return 0;
+	}
+}
+
+
+int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ 	ulong size,src,ld_addr;
+	int result;
+	backup_t back;
+	char sw;
+	src = MULTI_PURPOSE_SOCKET_ADDR;
+	size = IMAGE_SIZE;
+
+	if (strcmp(argv[1], "flash") == 0)
+	{
+		sw = switch_cs(0); /* Switch flash to normal location */
+#if (CONFIG_COMMANDS & CFG_CMD_FDC)
+		if (strcmp(argv[2], "floppy") == 0) {
+ 			char *local_args[3];
+			extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
+			printf ("\nupdating bootloader image from floppy\n");
+			local_args[0] = argv[0];
+	    		if(argc==4) {
+				local_args[1] = argv[3];
+				local_args[2] = NULL;
+				ld_addr=simple_strtoul(argv[3], NULL, 16);
+				result=do_fdcboot(cmdtp, 0, 2, local_args);
+			}
+			else {
+				local_args[1] = NULL;
+				ld_addr=CFG_LOAD_ADDR;
+				result=do_fdcboot(cmdtp, 0, 1, local_args);
+			}
+			result=mpl_prg_image(ld_addr);
+			switch_cs(sw); /* Switch flash back */
+			return result;
+		}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
+		if (strcmp(argv[2], "mem") == 0) {
+	    		if(argc==4) {
+				ld_addr=simple_strtoul(argv[3], NULL, 16);
+			}
+			else {
+				ld_addr=load_addr;
+			}
+			printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
+			result=mpl_prg_image(ld_addr);
+			switch_cs(sw); /* Switch flash back */
+			return result;
+		}
+		if (strcmp(argv[2], "mps") == 0) {
+			printf ("\nupdating bootloader image from MSP\n");
+			result=mpl_prg(src,size);
+			switch_cs(sw); /* Switch flash back */
+			return result;
+		}
+		switch_cs(sw); /* Switch flash back */
+
+	}
+	if (strcmp(argv[1], "mem") == 0)
+	{
+		result=0;
+		if(argc==3)
+		{
+			result = (int)simple_strtol(argv[2], NULL, 16);
+	    }
+	    src=(unsigned long)&result;
+	    src-=CFG_MEMTEST_START;
+	    src-=(100*1024); /* - 100k */
+	    src&=0xfff00000;
+	    size=0;
+	    do {
+	    	size++;
+			printf("\n\nPass %ld\n",size);
+			mem_test(CFG_MEMTEST_START,src,1);
+			if(ctrlc())
+				break;
+			if(result>0)
+				result--;
+
+		}while(result);
+		return 0;
+	}
+	if (strcmp(argv[1], "clearenvvalues") == 0)
+	{
+ 		if (strcmp(argv[2], "yes") == 0)
+		{
+			clear_env_values();
+			return 0;
+		}
+	}
+	if (strcmp(argv[1], "getback") == 0) {
+		get_backup_values(&back);
+		back.signature[3]=0;
+		back.serial_name[16]=0;
+		back.eth_addr[20]=0;
+		printf("GetBackUp: signature: %s\n",back.signature);
+		printf("           serial#:   %s\n",back.serial_name);
+		printf("           ethaddr:   %s\n",back.eth_addr);
+		return 0;
+	}
+	if (strcmp(argv[1], "setback") == 0) {
+		set_backup_values(1);
+		return 0;
+	}
+	printf("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void doc_probe(ulong physadr);
+void doc_init (void)
+{
+  doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
+}
+#endif
+
+
+#ifdef CONFIG_VIDEO
+/******************************************************
+ * Routines to display the Board information
+ * to the screen (since the VGA will be initialized as last,
+ * we must resend the infos)
+ */
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern GraphicDevice ctfb;
+
+void video_get_info_str (int line_number, char *info)
+{
+	/* init video info strings for graphic console */
+	DECLARE_GLOBAL_DATA_PTR;
+	PPC405_SYS_INFO sys_info;
+	char rev;
+	int i;
+	unsigned long pvr;
+	char buf[64];
+	char tmp[16];
+	unsigned char *s, *e, bc, sw;
+	switch (line_number)
+	{
+	case 2:
+		/* CPU and board infos */
+		pvr=get_pvr();
+		get_sys_info (&sys_info);
+		switch (pvr) {
+			case PVR_405GP_RB: rev='B'; break;
+			case PVR_405GP_RC: rev='C'; break;
+			case PVR_405GP_RD: rev='D'; break;
+			case PVR_405GP_RE: rev='E'; break;
+			default:           rev='?'; break;
+		}
+		/* Board info */
+		i=0;
+		s=getenv ("serial#");
+#ifdef CONFIG_PIP405
+		if (!s || strncmp (s, "PIP405", 6)) {
+			sprintf(buf,"### No HW ID - assuming PIP405");
+		}
+#endif
+#ifdef CONFIG_MIP405
+		if (!s || strncmp (s, "MIP405", 6)) {
+			sprintf(buf,"### No HW ID - assuming MIP405");
+		}
+#endif
+		else {
+			for (e = s; *e; ++e) {
+				if (*e == ' ')
+					break;
+			}
+			for (; s < e; ++s) {
+				if (*s == '_') {
+					++s;
+					break;
+				}
+				buf[i++]=*s;
+			}
+			sprintf(&buf[i]," SN ");
+			i+=4;
+			for (; s < e; ++s) {
+				buf[i++]=*s;
+			}
+			buf[i++]=0;
+		}
+		sprintf (info," %s PPC405GP %c %s MHz (%lu/%lu/%lu MHz)",
+			buf,rev,
+			strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
+			sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
+			sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
+		return;
+	case 3:
+		/* Memory Info */
+		sw = switch_cs (0);
+		switch_cs (sw);
+		bc = in8 (CONFIG_PORT_ADDR);
+		sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
+			gd->bd->bi_memsize / 0x100000,
+			gd->bd->bi_flashsize / 0x100000,
+			bc,
+			sw ? "MPS boot" : "Flash boot",
+			ctfb.modeIdent);
+		return;
+	case 1:
+		sprintf	(buf, "%s",CONFIG_IDENT_STRING);
+		sprintf (info, " %s", &buf[1]);
+		return;
+    }
+    /* no more info lines */
+    *info = 0;
+    return;
+}
+#endif /* CONFIG_CONSOLE_EXTRA_INFO */
+
+#endif /* CONFIG_VIDEO */
diff --git a/board/mpl/common/pci.c b/board/mpl/common/pci.c
new file mode 100644
index 0000000..d1965f9
--- /dev/null
+++ b/board/mpl/common/pci.c
@@ -0,0 +1,102 @@
+/*-----------------------------------------------------------------------------+
+|
+|       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
++-----------------------------------------------------------------------------*/
+/*
+ * Adapted for PIP405 03.07.01
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * TODO: Clean-up
+ */
+
+#include <common.h>
+#include <pci.h>
+#include "isa.h"
+
+#ifdef CONFIG_405GP
+#ifdef CONFIG_PCI
+
+#undef DEBUG
+
+#include "piix4_pci.h"
+#include "pci_parts.h"
+
+void pci_pip405_write_regs(struct pci_controller *hose, pci_dev_t dev,
+			   struct pci_config_table *entry)
+{
+	struct pci_pip405_config_entry *table;
+	int i;
+
+	table = (struct pci_pip405_config_entry*) entry->priv[0];
+
+	for (i=0; table[i].width; i++)
+	{
+#ifdef DEBUG
+		printf("Reg 0x%02X Value 0x%08lX Width %02d written\n",
+		       table[i].index, table[i].val, table[i].width);
+#endif
+
+		switch(table[i].width)
+		{
+		case 1: pci_hose_write_config_byte(hose, dev, table[i].index, table[i].val); break;
+		case 2: pci_hose_write_config_word(hose, dev, table[i].index, table[i].val); break;
+		case 4: pci_hose_write_config_dword(hose, dev, table[i].index, table[i].val); break;
+		}
+	}
+}
+
+
+static void pci_pip405_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	unsigned char int_line = 0xff;
+	/*
+	 * Write pci interrupt line register
+	 */
+	if(PCI_DEV(dev)==0) /* Device0 = PPC405 -> skip */
+		return;
+	if(PCI_FUNC(dev)==0)
+	{
+		/* assuming all function 0 are using their INTA# Pin*/
+		int_line=PCI_IRQ_VECTOR(dev);
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
+#ifdef DEBUG
+		printf("Fixup IRQ: dev %d (%x) int line %d 0x%x\n",
+		       PCI_DEV(dev),dev,int_line,int_line);
+#endif
+	}
+}
+
+extern void pci_405gp_init(struct pci_controller *hose);
+
+
+static struct pci_controller hose = {
+  config_table: pci_pip405_config_table,
+  fixup_irq: pci_pip405_fixup_irq,
+};
+
+void pci_init(void)
+{
+	/*we want the ptrs to RAM not flash (ie don't use init list)*/
+	hose.fixup_irq    = pci_pip405_fixup_irq;
+	hose.config_table = pci_pip405_config_table;
+	pci_405gp_init(&hose);
+}
+
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_405GP */
diff --git a/board/mpl/common/pci_parts.h b/board/mpl/common/pci_parts.h
new file mode 100644
index 0000000..944585f
--- /dev/null
+++ b/board/mpl/common/pci_parts.h
@@ -0,0 +1,192 @@
+ /*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#ifndef _PCI_PARTS_H_
+#define _PCI_PARTS_H_
+
+
+/* Board specific file containing:
+ * - PCI Memory Mapping
+ * - PCI IO Mapping
+ * - PCI Interrupt Mapping
+ */
+
+/* PIP405 PCI INT Routing:
+ *                      IRQ0  VECTOR
+ * PIXX4 IDSEL  = AD16  INTA#  28 (Function 2 USB is INTD# = 31)
+ * VGA   IDSEL  = AD17  INTB#  29
+ * SCSI  IDSEL  = AD18  INTC#  30
+ * PC104 IDSEL0 = AD20  INTA#  28
+ * PC104 IDSEL1 = AD21  INTB#  29
+ * PC104 IDSEL2 = AD22  INTC#  30
+ * PC104 IDSEL3 = AD23  INTD#  31
+ *
+ * busdevfunc = EXXX XXXX BBBB BBBB DDDD DFFF RRRR RR00
+ *              ^         ^         ^     ^   ^
+ *             31        23        15    10   7
+ * E = Enabled
+ * B = Bussnumber
+ * D = Devicenumber (Device0 = AD10)
+ * F = Functionnumber
+ * R = Registernumber
+ *
+ * Device = (busdevfunc>>11) + 10
+ * Vector = devicenumber % 4 + 28
+ *
+ */
+#define PCI_HIGHEST_ON_BOARD_ID	19
+/*#define PCI_DEV_NUMBER(x)	(((x>>11) & 0x1f) + 10) */
+#define PCI_IRQ_VECTOR(x)	((PCI_DEV(x) + 10) % 4) + 28
+
+
+
+/* PCI Device List for PIP405 */
+
+/* Mapping:
+ * +-------------+------------+------------+--------------------------------+
+ * ¦ PCI MemAddr | PCI IOAddr | Local Addr | Device / Function              |
+ * +-------------+------------+------------+--------------------------------+
+ * |  0x00000000 |            | 0xA0000000 | ISA Memory (hard wired)        |
+ * |  0x00FFFFFF |            | 0xA0FFFFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ * |             | 0x00000000 | 0xE8000000 | ISA IO (hard wired)            |
+ * |             | 0x0000FFFF | 0xE800FFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ * |  0x80000000 |            | 0x80000000 | VGA Controller Memory          |
+ * |  0x80FFFFFF |            | 0x80FFFFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ * |  0x81000000 |            | 0x81000000 | SCSI Controller Memory         |
+ * |  0x81FFFFFF |            | 0x81FFFFFF |                                |
+ * +-------------+------------+------------+--------------------------------+
+ */
+
+struct pci_pip405_config_entry {
+	int 		index; 	/* address */
+	unsigned long 	val;	/* value */
+	int 		width;	/* data size */
+};
+
+extern void pci_pip405_write_regs(struct pci_controller *,
+				  pci_dev_t,
+				  struct pci_config_table *);
+
+/* PIIX4 ISA Bridge Function 0 */
+static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
+	{PCI_CFG_PIIX4_SERIRQ,	0xD0,		1}, /* enable Continous SERIRQ Pin */
+	{PCI_CFG_PIIX4_GENCFG,	0x00010041,	4}, /* enable SERIRQs, ISA, PNP	*/
+	{PCI_CFG_PIIX4_TOM,	0xFE,		1}, /* Top of Memory		*/
+	{PCI_CFG_PIIX4_XBCS,	0x02C4,		2}, /* disable all peri CS	*/
+	{PCI_CFG_PIIX4_RTCCFG,	0x21,		1}, /* enable RTC	   	*/
+#if defined(CONFIG_PIP405)
+	{PCI_CFG_PIIX4_MBDMA,	0x82,		1}, /* set MBDMA0 to DMA 2   	*/
+	{PCI_CFG_PIIX4_MBDMA+1,	0x83,		1}, /* set MBDMA1 to DMA 3   	*/
+#endif
+	{PCI_CFG_PIIX4_DLC,	0x0,		1}, /* disable passive release feature */
+	{ }				    	    /* end of device table	*/
+};
+
+/* PIIX4 IDE Controller Function 1 */
+static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
+	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/
+	{PCI_CFG_PIIX4_IDETIM,	0x80008000,	4}, /* enable Both IDE channels	*/
+	{ }					    /* end of device table 	*/
+};
+
+/* PIIX4 USB Controller Function 2 */
+static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
+	{PCI_INTERRUPT_LINE,	31,		1}, /* Int vector = 31 		*/
+	{PCI_BASE_ADDRESS_4,	0x0000E001,	4}, /* Set IO Address to 0xe000 to 0xe01F */
+	{PCI_LATENCY_TIMER,	0x80,		1}, /* Latency Timer 0x80 	*/
+	{0xC0,			0x2000,		2}, /* Legacy support 		*/
+	{PCI_COMMAND,		0x0005,		2}, /* enable IO access and Master */
+	{ }					    /* end of device table 	*/
+};
+
+/* PIIX4 Power Management Function 3 */
+static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = {
+	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/
+	{PCI_CFG_PIIX4_PMAB,	0x00004000,	4}, /* set PMBA to "valid" value */
+	{PCI_CFG_PIIX4_PMMISC,	0x01,		1}, /* enable PMBA IO access	*/
+	{PCI_CFG_PIIX4_SMBBA,	0x00005000,	4}, /* set SMBBA to "valid" value */
+	{ }					    /* end of device table 	*/
+};
+/* PPC405 Dummy only used to prevent autosetup on this host bridge */
+static struct pci_pip405_config_entry ibm405_dummy[] = {
+	{ }				    	    /* end of device table 	*/
+};
+
+void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
+			 struct pci_config_table *entry);
+
+
+static struct pci_config_table pci_pip405_config_table[]={
+	{PCI_VENDOR_ID_IBM, 			/* 405 dummy */
+	 PCI_DEVICE_ID_IBM_405GP,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 0,
+	 pci_pip405_write_regs, {(unsigned long) ibm405_dummy}},
+
+	{PCI_VENDOR_ID_INTEL, 			/* PIIX4 ISA Bridge Function 0 */
+	 PCI_DEVICE_ID_INTEL_82371AB_0,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 0,
+	 pci_pip405_write_regs, {(unsigned long) piix4_isa_bridge_f0}},
+
+	{PCI_VENDOR_ID_INTEL,			/* PIIX4 IDE Controller Function 1 */
+	 PCI_DEVICE_ID_INTEL_82371AB,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 1,
+	 pci_pip405_write_regs, {(unsigned long) piix4_ide_cntrl_f1}},
+
+	{PCI_VENDOR_ID_INTEL,			/* PIIX4 USB Controller Function 2 */
+	 PCI_DEVICE_ID_INTEL_82371AB_2,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 2,
+	 pci_pip405_write_regs, {(unsigned long) piix4_usb_cntrl_f2}},
+
+	{PCI_VENDOR_ID_INTEL,			/* PIIX4 USB Controller Function 3 */
+	 PCI_DEVICE_ID_INTEL_82371AB_3,
+	 PCI_ANY_ID,
+	 PCI_ANY_ID, PCI_ANY_ID, 3,
+	 pci_pip405_write_regs, {(unsigned long) piix4_pmm_cntrl_f3}},
+
+	{PCI_ANY_ID,
+	 PCI_ANY_ID,
+	 PCI_CLASS_DISPLAY_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	 pci_405gp_setup_vga},
+
+	{PCI_ANY_ID,
+	 PCI_ANY_ID,
+	 PCI_CLASS_NOT_DEFINED_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	 pci_405gp_setup_vga},
+
+	{ }
+};
+#endif /* _PCI_PARTS_H_ */
+
+
+
+
+
diff --git a/board/mpl/mip405/Makefile b/board/mpl/mip405/Makefile
new file mode 100644
index 0000000..839cafe
--- /dev/null
+++ b/board/mpl/mip405/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000, 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o ../common/flash.o cmd_mip405.o ../common/pci.o \
+			../common/usb_uhci.o ../common/memtst.o ../common/common_util.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/mpl/pip405/Makefile b/board/mpl/pip405/Makefile
new file mode 100644
index 0000000..b6cc531
--- /dev/null
+++ b/board/mpl/pip405/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000, 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o \
+	  ../common/flash.o cmd_pip405.o ../common/pci.o \
+	  ../common/isa.o ../common/kbd.o \
+	  ../common/usb_uhci.o \
+	  ../common/memtst.o ../common/common_util.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/musenki/musenki.c b/board/musenki/musenki.c
new file mode 100644
index 0000000..3b02f37
--- /dev/null
+++ b/board/musenki/musenki.c
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * 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 <pci.h>
+
+int checkboard (void)
+{
+	ulong busfreq  = get_bus_freq(0);
+	char  buf[32];
+
+	printf("Board: MUSENKI Local Bus at %s MHz\n", strmhz(buf, busfreq));
+	return 0;
+
+}
+
+#if 0 	/* NOT USED */
+int checkflash (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("## Test not implemented yet ##\n");
+
+	return (0);
+}
+#endif
+
+long int initdram (int board_type)
+{
+	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;
+}
+
+/*
+ * Initialize PCI Devices
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+#if 0
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  0x0, 0x0, 0x0, /* unknown eth0 divice */
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_IO |
+				       PCI_COMMAND_MEMORY |
+				       PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  0x0, 0x0, 0x0, /* unknown eth1 device */
+	  pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+				       PCI_ENET1_MEMADDR,
+				       PCI_COMMAND_IO |
+				       PCI_COMMAND_MEMORY |
+				       PCI_COMMAND_MASTER }},
+#endif
+	{ }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/mvs1/Makefile b/board/mvs1/Makefile
new file mode 100644
index 0000000..ef173d0
--- /dev/null
+++ b/board/mvs1/Makefile
@@ -0,0 +1,40 @@
+#
+# (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
+
+$(LIB):	.depend $(OBJS)
+	$(AR) crv $@ $^
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/netvia/Makefile b/board/netvia/Makefile
new file mode 100644
index 0000000..ef173d0
--- /dev/null
+++ b/board/netvia/Makefile
@@ -0,0 +1,40 @@
+#
+# (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
+
+$(LIB):	.depend $(OBJS)
+	$(AR) crv $@ $^
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/netvia/netvia.c b/board/netvia/netvia.c
new file mode 100644
index 0000000..504593e
--- /dev/null
+++ b/board/netvia/netvia.c
@@ -0,0 +1,374 @@
+/*
+ * (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
+ */
+
+/*
+ * Pantelis Antoniou, Intracom S.A., panto@intracom.gr
+ * U-Boot port on NetVia board
+ */
+
+#include <common.h>
+#include "mpc8xx.h"
+
+/* some sane bit macros */
+#define _BD(_b)				(1U << (31-(_b)))
+#define _BDR(_l, _h)			(((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
+
+#define _BW(_b)				(1U << (15-(_b)))
+#define _BWR(_l, _h)			(((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
+
+#define _BB(_b)				(1U << (7-(_b)))
+#define _BBR(_l, _h)			(((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
+
+#define _B(_b)				_BD(_b)
+#define _BR(_l, _h)			_BDR(_l, _h)
+
+/* ------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_	0xFFFFFFFF
+
+/* ------------------------------------------------------------------------- */
+
+#define CS_0000		0x00000000
+#define CS_0001		0x10000000
+#define CS_0010		0x20000000
+#define CS_0011		0x30000000
+#define CS_0100		0x40000000
+#define CS_0101		0x50000000
+#define CS_0110		0x60000000
+#define CS_0111		0x70000000
+#define CS_1000		0x80000000
+#define CS_1001		0x90000000
+#define CS_1010		0xA0000000
+#define CS_1011		0xB0000000
+#define CS_1100		0xC0000000
+#define CS_1101		0xD0000000
+#define CS_1110		0xE0000000
+#define CS_1111		0xF0000000
+
+#define BS_0000		0x00000000
+#define BS_0001		0x01000000
+#define BS_0010		0x02000000
+#define BS_0011		0x03000000
+#define BS_0100		0x04000000
+#define BS_0101		0x05000000
+#define BS_0110		0x06000000
+#define BS_0111		0x07000000
+#define BS_1000		0x08000000
+#define BS_1001		0x09000000
+#define BS_1010		0x0A000000
+#define BS_1011		0x0B000000
+#define BS_1100		0x0C000000
+#define BS_1101		0x0D000000
+#define BS_1110		0x0E000000
+#define BS_1111		0x0F000000
+
+#define A10_AAAA	0x00000000
+#define A10_AAA0	0x00200000
+#define A10_AAA1	0x00300000
+#define A10_000A	0x00800000
+#define A10_0000	0x00A00000
+#define A10_0001	0x00B00000
+#define A10_111A	0x00C00000
+#define A10_1110	0x00E00000
+#define A10_1111	0x00F00000
+
+#define RAS_0000	0x00000000
+#define RAS_0001	0x00040000
+#define RAS_1110	0x00080000
+#define RAS_1111	0x000C0000
+
+#define CAS_0000	0x00000000
+#define CAS_0001	0x00010000
+#define CAS_1110	0x00020000
+#define CAS_1111	0x00030000
+
+#define WE_0000		0x00000000
+#define WE_0001		0x00004000
+#define WE_1110		0x00008000
+#define WE_1111		0x0000C000
+
+#define GPL4_0000	0x00000000
+#define GPL4_0001	0x00001000
+#define GPL4_1110	0x00002000
+#define GPL4_1111	0x00003000
+
+#define GPL5_0000	0x00000000
+#define GPL5_0001	0x00000400
+#define GPL5_1110	0x00000800
+#define GPL5_1111	0x00000C00
+#define LOOP		0x00000080
+
+#define EXEN		0x00000040
+
+#define AMX_COL		0x00000000
+#define AMX_ROW		0x00000020
+#define AMX_MAR		0x00000030
+
+#define NA		0x00000008
+
+#define UTA		0x00000004
+
+#define TODT		0x00000002
+
+#define LAST		0x00000001
+
+const uint sdram_table[0x40] = {
+	/* RSS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* ACT   */
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_0000 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA,			/* READ  */
+	CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA,			/* PALL  */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST,	/* NOP   */
+	_NOT_USED_, _NOT_USED_,
+
+	/* RBS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* ACT   */
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_0001 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA,			/* READ  */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP	 */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP	 */
+	CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL,				/* PALL  */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST,		/* NOP	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* WSS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+	CS_0000 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL | UTA,
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* WBS */
+	CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* ACT   */
+	CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL,				/* WRITE */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_1111 | BS_0001 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,			/* NOP   */
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA,			/* PALL  */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST,	/* NOP   */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+	/* UPT */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,				/* NOP   */
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_0001 | WE_1111 | AMX_COL | LOOP,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LOOP,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LAST,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_,
+
+	/* EXC */
+	CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL,
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST,
+
+	/* REG */
+	CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1110 | AMX_MAR,
+	CS_0001 | BS_1111 | A10_0001 | RAS_0001 | CAS_0001 | WE_0001 | AMX_MAR | TODT | LAST,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Test ETX ID string (ETX_xxx...)
+ *
+ * Return 1 always.
+ */
+
+int checkboard(void)
+{
+	printf ("NETVIA\n");
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* 0xC8 = 0b11001000 , CAS3, >> 2 = 0b00 11 0 010 */
+#define MAR_SDRAM_INIT		0x000000C8LU
+
+#define MCR_OP(x)		((unsigned long)((x) & 3) << (31-1))
+#define MCR_OP_MASK		MCR_OP(3)
+
+#define MCR_UM(x)		((unsigned long)((x) & 1) << (31 - 8))
+#define MCR_UM_MASK		MCR_UM(1)
+#define MCR_UM_UPMA		MCR_UM(0)
+#define MCR_UM_UPMB		MCR_UM(1)
+
+#define MCR_MB(x)		((unsigned long)((x) & 7) << (31 - 18))
+#define MCR_MB_MASK		MCR_MB(7)
+#define MCR_MB_CS(x)		MCR_MB(x)
+
+#define MCR_MCLF(x)		((unsigned long)((x) & 15) << (31 - 23))
+#define MCR_MCLF_MASK		MCR_MCLF(15)
+
+long int initdram(int board_type)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	long int size;
+
+	upmconfig(UPMA, (uint *) sdram_table, sizeof(sdram_table) / sizeof(uint));
+
+	/*
+	 * Preliminary prescaler for refresh
+	 */
+	memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+
+	memctl->memc_mar = MAR_SDRAM_INIT;	/* 32-bit address to be output on the address bus if AMX = 0b11 */
+
+    /*
+     * Map controller bank 3 to the SDRAM bank at preliminary address.
+     */
+	memctl->memc_or3 = CFG_OR3_PRELIM;
+	memctl->memc_br3 = CFG_BR3_PRELIM;
+
+	memctl->memc_mamr = CFG_MAMR_9COL & ~MAMR_PTAE;	/* no refresh yet */
+
+	udelay(200);
+
+	/* perform SDRAM initialisation sequence */
+	memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3C);	/* precharge all			*/
+	udelay(1);
+	memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(0) | MCR_MAD(0x30); /* refresh 16 times(0)		*/
+	udelay(1);
+	memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3E);	/* exception program (write mar) */
+	udelay(1);
+
+	memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */
+
+	udelay(1000);
+
+	memctl->memc_mamr = CFG_MAMR_9COL;
+
+	size = SDRAM_MAX_SIZE;
+
+	udelay(10000);
+
+	/* do the ram test */
+	{
+		register unsigned long *rp;
+		register unsigned long v;
+
+		/* first fill */
+		for (rp = (unsigned long *)0; rp < (unsigned long *)SDRAM_MAX_SIZE; )
+		    *rp++ = (unsigned long)rp;
+
+		/* now check */
+		for (rp = (unsigned long *)0; rp < (unsigned long *)SDRAM_MAX_SIZE; rp++) {
+		    if ((v = *rp) != (unsigned long)rp) {
+			printf("ERROR at 0x%lx (0x%lx)\n", (unsigned long)rp, v);
+			return -1;
+		    }
+		}
+
+	}
+
+	return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_r(void)
+{
+	return(0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* bits that can have a special purpose or can be configured as inputs/outputs */
+#define PA_MASK		(_BWR(4, 9) | _BWR(12, 15))
+#define PA_ODR_MASK	(_BW(9) | _BW(12) | _BW(14))
+#define PA_ODR_VAL	0
+#define PA_GP_INMASK	0
+#define PA_GP_OUTMASK	(_BW(5) | _BW(14) | _BW(15))
+#define PA_SP_OUTMASK	0
+#define PA_GP_OUTVAL	_BW(5)
+#define PA_SP_OUTVAL	0
+
+#define PB_MASK		(_BR(16, 19) | _BR(22, 31))
+#define PB_ODR_MASK	PB_MASK
+#define PB_ODR_VAL	0
+#define PB_GP_INMASK	0
+#define PB_GP_OUTMASK	(_BR(16, 19) | _BR(26, 27) | _B(31))
+#define PB_SP_OUTMASK	_BR(28, 30)
+#define PB_SP_OUTVAL	_BR(28, 30)
+#define PB_GP_OUTVAL	(_BR(16, 19) | _BR(26, 27) | _B(31))
+
+#define PC_MASK		_BWR(4, 15)
+#define PC_SO_MASK	(_BWR(6, 11) | _BWR(14, 15))
+#define PC_SO_VAL	0
+#define PC_INT_MASK	PC_MASK
+#define PC_INT_VAL	0
+#define PC_GP_INMASK	(_BWR(5, 7) | _BWR(9, 10) | _BW(13))
+#define PC_GP_OUTMASK	_BW(12)
+#define PC_SP_OUTMASK	0
+#define PC_SP_OUTVAL	_BW(12)
+#define PC_GP_OUTVAL	0
+
+#define PD_MASK		_BWR(0, 15)
+#define PD_GP_INMASK	0
+#define PD_GP_OUTMASK	_BWR(3, 15)
+#define PD_SP_OUTMASK	0
+#define PD_GP_OUTVAL	(_BW(3) | _BW(5) | _BW(7) | _BWR(8, 15))
+#define PD_SP_OUTVAL	0
+
+int board_pre_init(void)
+{
+	register volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	register volatile iop8xx_t *ioport = &immap->im_ioport;
+	register volatile cpm8xx_t *cpm = &immap->im_cpm;
+
+	ioport->iop_padat = (ioport->iop_padat & ~PA_MASK)     | PA_SP_OUTVAL | PA_GP_OUTVAL;
+	ioport->iop_paodr = (ioport->iop_paodr & ~PA_ODR_MASK) | PA_ODR_VAL;
+	ioport->iop_padir = (ioport->iop_padir & ~PA_GP_INMASK)| PA_SP_OUTMASK | PA_GP_OUTMASK;
+	ioport->iop_papar = (ioport->iop_papar & ~(PA_GP_INMASK & PA_GP_OUTMASK));
+
+	cpm->cp_pbdat = (ioport->iop_padat & ~PB_MASK)     | PB_SP_OUTVAL | PB_GP_OUTVAL;
+	cpm->cp_pbodr = (ioport->iop_paodr & ~PB_ODR_MASK) | PB_ODR_VAL;
+	cpm->cp_pbdir = (ioport->iop_padir & ~PB_GP_INMASK)| PB_SP_OUTMASK | PB_GP_OUTMASK;
+	cpm->cp_pbpar = (ioport->iop_papar & ~(PB_GP_INMASK & PB_GP_OUTMASK));
+
+	ioport->iop_pcdat = (ioport->iop_pcdat & ~PC_MASK)     | PC_SP_OUTVAL | PC_GP_OUTVAL;
+	ioport->iop_pcdir = (ioport->iop_pcdir & ~PC_GP_INMASK)| PC_SP_OUTMASK | PC_GP_OUTMASK;
+	ioport->iop_pcso  = (ioport->iop_pcso  & ~PC_SO_MASK)  | PC_SO_VAL;
+	ioport->iop_pcint = (ioport->iop_pcint & ~PC_INT_MASK) | PC_INT_VAL;
+	ioport->iop_pcpar = (ioport->iop_pcpar & ~(PC_GP_INMASK & PC_GP_OUTMASK));
+
+	ioport->iop_pddat = (ioport->iop_pddat & ~PD_MASK)     | PD_SP_OUTVAL | PD_GP_OUTVAL;
+	ioport->iop_pddir = (ioport->iop_pddir & ~PD_GP_INMASK)| PD_SP_OUTMASK | PD_GP_OUTMASK;
+	ioport->iop_pdpar = (ioport->iop_pdpar & ~(PD_GP_INMASK & PD_GP_OUTMASK));
+
+	return 0;
+}
+
diff --git a/board/netvia/u-boot.lds b/board/netvia/u-boot.lds
new file mode 100644
index 0000000..e75f12c
--- /dev/null
+++ b/board/netvia/u-boot.lds
@@ -0,0 +1,132 @@
+/*
+ * (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
+{
+  /* 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/mpc8xx/start.o		(.text)
+    cpu/mpc8xx/traps.o		(.text)
+    common/dlmalloc.o		(.text)
+    lib_ppc/ppcstring.o		(.text)
+    lib_generic/vsprintf.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_generic/zlib.o		(.text)
+    lib_ppc/cache.o		(.text)
+    lib_ppc/time.o		(.text)
+
+    . = env_offset;
+    common/environment.o	(.ppcenv)
+
+    *(.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)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/netvia/u-boot.lds.debug b/board/netvia/u-boot.lds.debug
new file mode 100644
index 0000000..fa494fb
--- /dev/null
+++ b/board/netvia/u-boot.lds.debug
@@ -0,0 +1,131 @@
+/*
+ * (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
+{
+  /* 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/mpc8xx/start.o		(.text)
+    common/dlmalloc.o		(.text)
+    lib_generic/vsprintf.o	(.text)
+    lib_generic/crc32.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: */
+  . = (. + 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 = .);
+}
+
diff --git a/board/oxc/flash.c b/board/oxc/flash.c
new file mode 100644
index 0000000..4f0220e
--- /dev/null
+++ b/board/oxc/flash.c
@@ -0,0 +1,372 @@
+/*
+ * (C) Copyright 2000
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Flash Routines for STM29W320DB/STM29W800D flash chips
+ *
+ *--------------------------------------------------------------------
+ * 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>
+
+flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+
+static ulong flash_get_size (vu_char *addr, flash_info_t *info);
+static int write_byte (flash_info_t *info, ulong dest, uchar data);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+    unsigned long size;
+    int i;
+
+    /* Init: no FLASHes known */
+    for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+	flash_info[i].flash_id = FLASH_UNKNOWN;
+    }
+
+    /*
+     * We use the following trick here: since flash is cyclically
+     * mapped in the 0xFF800000-0xFFFFFFFF area, we detect the type
+     * and the size of flash using 0xFF800000 as the base address,
+     * and then call flash_get_size() again to fill flash_info.
+     */
+    size = flash_get_size((vu_char *)CFG_FLASH_PRELIMBASE, &flash_info[0]);
+    if (size)
+    {
+	flash_get_size((vu_char *)(-size), &flash_info[0]);
+    }
+
+#if (CFG_MONITOR_BASE >= CFG_FLASH_PRELIMBASE)
+    /* monitor protection ON by default */
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_MONITOR_BASE,
+		  CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+		  &flash_info[0]);
+#endif
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+# ifndef  CFG_ENV_SIZE
+#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE
+# endif
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_ENV_ADDR,
+		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+		  &flash_info[0]);
+#endif
+
+    return (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_STM:
+	printf ("ST ");
+	break;
+    default:
+	printf ("Unknown Vendor ");
+	break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+    case FLASH_STM320DB:
+	printf ("M29W320DB (32 Mbit)\n");
+	break;
+    case FLASH_STM800DB:
+	printf ("M29W800DB (8 Mbit, bottom boot block)\n");
+	break;
+    case FLASH_STM800DT:
+	printf ("M29W800DT (8 Mbit, top boot block)\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");
+    return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+static ulong flash_get_size (vu_char *addr, flash_info_t *info)
+{
+    short i;
+    uchar vendor, devid;
+    ulong base = (ulong)addr;
+
+    /* Write auto select command: read Manufacturer ID */
+    addr[0x0AAA] = 0xAA;
+    addr[0x0555] = 0x55;
+    addr[0x0AAA] = 0x90;
+
+    udelay(1000);
+
+    vendor = addr[0];
+    devid = addr[2];
+
+    /* only support STM */
+    if ((vendor << 16) != FLASH_MAN_STM) {
+	return 0;
+    }
+
+    if (devid == FLASH_STM320DB) {
+    	/* MPC8240 can address maximum 2Mb of flash, that is why the MSB
+	 * lead is grounded and we can access only 2 first Mb */
+	info->flash_id     = vendor << 16 | devid;
+	info->sector_count = 32;
+	info->size         = info->sector_count * 0x10000;
+	for (i = 0; i < info->sector_count; i++) {
+	    info->start[i] = base + i * 0x10000;
+	}
+    }
+    else if (devid == FLASH_STM800DB) {
+	info->flash_id     = vendor << 16 | devid;
+	info->sector_count = 19;
+	info->size         = 0x100000;
+	info->start[0]     = 0x0000;
+	info->start[1]     = 0x4000;
+	info->start[2]     = 0x6000;
+	info->start[3]     = 0x8000;
+	for (i = 4; i < info->sector_count; i++) {
+	    info->start[i] = base + (i-3) * 0x10000;
+	}
+    }
+    else if (devid == FLASH_STM800DT) {
+	info->flash_id     = vendor << 16 | devid;
+	info->sector_count = 19;
+	info->size         = 0x100000;
+	for (i = 0; i < info->sector_count-4; i++) {
+	    info->start[i] = base + i * 0x10000;
+	}
+	info->start[i]     = base + i * 0x10000;
+	info->start[i+1]   = base + i * 0x10000 + 0x8000;
+	info->start[i+2]   = base + i * 0x10000 + 0xa000;
+	info->start[i+3]   = base + i * 0x10000 + 0xc000;
+    }
+    else {
+	return 0;
+    }
+
+    /* mark all sectors as unprotected */
+    for (i = 0; i < info->sector_count; i++) {
+	info->protect[i] = 0;
+    }
+
+    /* Issue the reset command */
+    if (info->flash_id != FLASH_UNKNOWN) {
+	addr[0] = 0xF0;	/* reset bank */
+    }
+
+    return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int	flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+    vu_char *addr = (vu_char *)(info->start[0]);
+    int flag, prot, sect, l_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;
+    }
+
+    prot = 0;
+    for (sect = s_first; sect <= s_last; sect++) {
+	if (info->protect[sect]) {
+	    prot++;
+	}
+    }
+
+    if (prot) {
+	printf ("- Warning: %d protected sectors will not be erased!\n",
+		prot);
+    } else {
+	printf ("\n");
+    }
+
+    l_sect = -1;
+
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    addr[0x0AAA] = 0xAA;
+    addr[0x0555] = 0x55;
+    addr[0x0AAA] = 0x80;
+    addr[0x0AAA] = 0xAA;
+    addr[0x0555] = 0x55;
+
+    /* wait at least 80us - let's wait 1 ms */
+    udelay (1000);
+
+    /* Start erase on unprotected sectors */
+    for (sect = s_first; sect<=s_last; sect++) {
+	if (info->protect[sect] == 0) {	/* not protected */
+	    addr = (vu_char *)(info->start[sect]);
+	    addr[0] = 0x30;
+	    l_sect = sect;
+	}
+    }
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+      enable_interrupts();
+
+    /* wait at least 80us - let's wait 1 ms */
+    udelay (1000);
+
+    /*
+     * We wait for the last triggered sector
+     */
+    if (l_sect < 0)
+      goto DONE;
+
+    start = get_timer (0);
+    last  = start;
+    addr = (vu_char *)(info->start[l_sect]);
+    while ((addr[0] & 0x80) != 0x80) {
+	if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+	    printf ("Timeout\n");
+	    return 1;
+	}
+	/* show that we're waiting */
+	if ((now - last) > 1000) {	/* every second */
+	    serial_putc ('.');
+	    last = now;
+	}
+    }
+
+    DONE:
+    /* reset to read mode */
+    addr = (volatile unsigned char *)info->start[0];
+    addr[0] = 0xF0;	/* reset bank */
+
+    printf (" done\n");
+    return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    int rc;
+
+    while (cnt > 0) {
+	if ((rc = write_byte(info, addr, *src)) != 0) {
+	    return (rc);
+	}
+	addr++;
+	src++;
+	cnt--;
+    }
+
+    return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a byte to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_byte (flash_info_t *info, ulong dest, uchar data)
+{
+    vu_char *addr = (vu_char *)(info->start[0]);
+    ulong start;
+    int flag;
+
+    /* Check if Flash is (sufficiently) erased */
+    if ((*((vu_char *)dest) & data) != data) {
+	return (2);
+    }
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    addr[0x0AAA] = 0xAA;
+    addr[0x0555] = 0x55;
+    addr[0x0AAA] = 0xA0;
+
+    *((vu_char *)dest) = data;
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+      enable_interrupts();
+
+    /* data polling for D7 */
+    start = get_timer (0);
+    while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) {
+	if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+	    return (1);
+	}
+    }
+    return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/oxc/oxc.c b/board/oxc/oxc.c
new file mode 100644
index 0000000..8aced84
--- /dev/null
+++ b/board/oxc/oxc.c
@@ -0,0 +1,237 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * 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 <pci.h>
+#include <i2c.h>
+
+int checkboard (void)
+{
+	puts (	"Board: OXC8240\n" );
+	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
+	/* if U-Boot starts from RAM, then suppose we have 16Mb of RAM */
+	return (16 << 20);
+#endif
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_oxc_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x14, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x15, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+				       PCI_ENET1_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ }
+};
+#endif
+
+static struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_oxc_config_table,
+#endif
+};
+
+void pci_init (void)
+{
+	pci_mpc824x_init(&hose);
+}
+
+int board_pre_init (void)
+{
+	*(volatile unsigned char *)(CFG_CPLD_RESET) = 0x89;
+	return 0;
+}
+
+#ifdef CONFIG_WATCHDOG
+void oxc_wdt_reset(void)
+{
+	*(volatile unsigned char *)(CFG_CPLD_WATCHDOG) = 0xff;
+}
+
+void watchdog_reset(void)
+{
+	int re_enable = disable_interrupts();
+
+	oxc_wdt_reset();
+	if (re_enable)
+		enable_interrupts();
+}
+#endif
+
+static int oxc_get_expander(unsigned char addr, unsigned char * val)
+{
+	return i2c_read(addr, 0, 0, val, 1);
+}
+
+static int oxc_set_expander(unsigned char addr, unsigned char val)
+{
+	return i2c_write(addr, 0, 0, &val, 1);
+}
+
+static int expander0alive = 0;
+
+#ifdef CONFIG_SHOW_ACTIVITY
+static int ledtoggle = 0;
+static int ledstatus = 1;
+
+void oxc_toggle_activeled(void)
+{
+	ledtoggle++;
+}
+
+void show_activity(int arg)
+{
+	static unsigned char led = 0;
+	unsigned char val;
+
+	if (!expander0alive) return;
+
+	if ((ledtoggle > (2 * arg)) && ledstatus) {
+		led ^= 0x80;
+		oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+		udelay(200);
+		oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, (val & 0x7F) | led);
+		ledtoggle = 0;
+	}
+}
+#endif
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress(int arg)
+{
+	unsigned char val;
+
+	if (!expander0alive) return;
+
+	if (arg > 0 && ledstatus) {
+		ledstatus = 0;
+		oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+		udelay(200);
+		oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, val | 0x80);
+	} else if (arg < 0) {
+		oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val);
+		udelay(200);
+		oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, val & 0x7F);
+		ledstatus = 1;
+	}
+}
+#endif
+
+int misc_init_r (void)
+{
+	/* check whether the i2c expander #0 is accessible */
+	if (!oxc_set_expander(CFG_I2C_EXPANDER0_ADDR, 0x7F)) {
+		udelay(200);
+		expander0alive = 1;
+	}
+
+#ifdef CFG_OXC_GENERATE_IP
+	{
+		DECLARE_GLOBAL_DATA_PTR;
+
+		char str[32];
+		unsigned long ip = CFG_OXC_IPMASK;
+		bd_t *bd = gd->bd;
+
+		if (expander0alive) {
+			unsigned char val;
+
+			if (!oxc_get_expander(CFG_I2C_EXPANDER0_ADDR, &val)) {
+				ip = (ip & 0xffffff00) | ((val & 0x7c) >> 2);
+			}
+		}
+
+		if ((ip & 0xff) < 3) {
+			/* if fail, set x.x.x.254 */
+			ip = (ip & 0xffffff00) | 0xfe;
+		}
+
+		bd->bi_ip_addr = ip;
+		sprintf(str, "%ld.%ld.%ld.%ld",
+			(bd->bi_ip_addr & 0xff000000) >> 24,
+			(bd->bi_ip_addr & 0x00ff0000) >> 16,
+			(bd->bi_ip_addr & 0x0000ff00) >> 8,
+			(bd->bi_ip_addr & 0x000000ff));
+		setenv("ipaddr", str);
+		printf("ip:    %s\n", str);
+	}
+#endif
+	return (0);
+}
diff --git a/board/pcippc2/cpc710_init_ram.c b/board/pcippc2/cpc710_init_ram.c
new file mode 100644
index 0000000..57ed8f0
--- /dev/null
+++ b/board/pcippc2/cpc710_init_ram.c
@@ -0,0 +1,254 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <asm/io.h>
+
+#include "pcippc2.h"
+#include "i2c.h"
+
+typedef struct cpc710_mem_org_s
+{
+  u8		rows;
+  u8		cols;
+  u8		banks2;
+  u8		org;
+} cpc710_mem_org_t;
+
+static int		cpc710_compute_mcer	(u32 *		mcer,
+						 unsigned long *
+								size,
+						 unsigned int	sdram);
+static int		cpc710_eeprom_checksum	(unsigned int	sdram);
+static u8		cpc710_eeprom_read	(unsigned int	sdram,
+						 unsigned int	offset);
+
+static u32		cpc710_mcer_mem [] =
+{
+  0x000003f3,	/* 18 lines,    4 Mb */
+  0x000003e3,	/* 19 lines,    8 Mb */
+  0x000003c3,	/* 20 lines,   16 Mb */
+  0x00000383,	/* 21 lines,   32 Mb */
+  0x00000303,	/* 22 lines,   64 Mb */
+  0x00000203,	/* 23 lines,  128 Mb */
+  0x00000003,	/* 24 lines,  256 Mb */
+  0x00000002,	/* 25 lines,  512 Mb */
+  0x00000001	/* 26 lines, 1024 Mb */
+};
+static cpc710_mem_org_t	cpc710_mem_org [] =
+{
+  { 0x0c, 0x09, 0x02, 0x00 },	/* 0000: 12/ 9/2 */
+  { 0x0d, 0x09, 0x02, 0x00 },	/* 0000: 13/ 9/2 */
+  { 0x0d, 0x0a, 0x02, 0x00 },	/* 0000: 13/10/2 */
+  { 0x0d, 0x0b, 0x02, 0x00 },	/* 0000: 13/11/2 */
+  { 0x0d, 0x0c, 0x02, 0x00 },	/* 0000: 13/12/2 */
+  { 0x0e, 0x0c, 0x02, 0x00 },	/* 0000: 14/12/2 */
+  { 0x0b, 0x08, 0x02, 0x01 },	/* 0001: 11/ 8/2 */
+  { 0x0b, 0x09, 0x01, 0x02 },	/* 0010: 11/ 9/1 */
+  { 0x0b, 0x0a, 0x01, 0x03 },	/* 0011: 11/10/1 */
+  { 0x0c, 0x08, 0x02, 0x04 },	/* 0100: 12/ 8/2 */
+  { 0x0c, 0x0a, 0x02, 0x05 },	/* 0101: 12/10/2 */
+  { 0x0d, 0x08, 0x01, 0x06 },	/* 0110: 13/ 8/1 */
+  { 0x0d, 0x08, 0x02, 0x07 },	/* 0111: 13/ 8/2 */
+  { 0x0d, 0x09, 0x01, 0x08 },	/* 1000: 13/ 9/1 */
+  { 0x0d, 0x0a, 0x01, 0x09 },	/* 1001: 13/10/1 */
+  { 0x0b, 0x08, 0x01, 0x0a },	/* 1010: 11/ 8/1 */
+  { 0x0c, 0x08, 0x01, 0x0b },	/* 1011: 12/ 8/1 */
+  { 0x0c, 0x09, 0x01, 0x0c },	/* 1100: 12/ 9/1 */
+  { 0x0e, 0x09, 0x02, 0x0d },	/* 1101: 14/ 9/2 */
+  { 0x0e, 0x0a, 0x02, 0x0e },	/* 1110: 14/10/2 */
+  { 0x0e, 0x0b, 0x02, 0x0f } 	/* 1111: 14/11/2 */
+};
+
+unsigned long cpc710_ram_init (void)
+{
+  unsigned long 	memsize = 0;
+  unsigned long		bank_size;
+  u32			mcer;
+
+#ifndef CFG_RAMBOOT
+    /* Clear memory banks
+     */
+  out32(REG(SDRAM0, MCER0), 0);
+  out32(REG(SDRAM0, MCER1), 0);
+  out32(REG(SDRAM0, MCER2), 0);
+  out32(REG(SDRAM0, MCER3), 0);
+  out32(REG(SDRAM0, MCER4), 0);
+  out32(REG(SDRAM0, MCER5), 0);
+  out32(REG(SDRAM0, MCER6), 0);
+  out32(REG(SDRAM0, MCER7), 0);
+  iobarrier_rw();
+
+    /* Disable memory
+     */
+  out32(REG(SDRAM0,MCCR), 0x13b06000);
+  iobarrier_rw();
+#endif
+
+    /* Only the first memory bank is initialised now
+     */
+  if (! cpc710_compute_mcer(& mcer, & bank_size, 0))
+  {
+    puts("Unsupported SDRAM type !\n");
+    hang();
+  }
+  memsize += bank_size;
+#ifndef CFG_RAMBOOT
+    /* Enable bank, zero start
+     */
+  out32(REG(SDRAM0, MCER0), mcer | 0x80000000);
+  iobarrier_rw();
+#endif
+
+#ifndef CFG_RAMBOOT
+    /* Enable memory
+     */
+  out32(REG(SDRAM0, MCCR), in32(REG(SDRAM0, MCCR)) | 0x80000000);
+
+    /* Wait until initialisation finished
+     */
+  while (! (in32 (REG(SDRAM0, MCCR)) & 0x20000000))
+  {
+    iobarrier_rw();
+  }
+
+    /* Clear Memory Error Status and Address registers
+     */
+  out32(REG(SDRAM0, MESR), 0);
+  out32(REG(SDRAM0, MEAR), 0);
+  iobarrier_rw();
+
+    /* ECC is not configured now
+     */
+#endif
+
+    /* Memory size counter
+     */
+  out32(REG(CPC0, RGBAN1), memsize);
+
+  return memsize;
+}
+
+static int cpc710_compute_mcer (
+  u32 *			mcer,
+  unsigned long	*	size,
+  unsigned int		sdram)
+{
+  u8			rows;
+  u8			cols;
+  u8			banks2;
+  unsigned int		lines;
+  u32			mc = 0;
+  unsigned int		i;
+  cpc710_mem_org_t *	org = 0;
+
+
+  if (! i2c_reset())
+  {
+    puts("Can't reset I2C!\n");
+    hang();
+  }
+
+  if (! cpc710_eeprom_checksum(sdram))
+  {
+    puts("Invalid EEPROM checksum !\n");
+    hang();
+  }
+
+  rows   = cpc710_eeprom_read(sdram, 3);
+  cols   = cpc710_eeprom_read(sdram, 4);
+    /* Can be 2 or 4 banks; divide by 2
+     */
+  banks2 = cpc710_eeprom_read(sdram, 17) / 2;
+
+  lines = rows + cols + banks2;
+
+  if (lines < 18 || lines > 26)
+  {
+      /* Unsupported configuration
+       */
+    return 0;
+  }
+
+
+  mc |= cpc710_mcer_mem [lines - 18] << 6;
+
+  for (i = 0; i < sizeof(cpc710_mem_org) / sizeof(cpc710_mem_org_t); i++)
+  {
+    cpc710_mem_org_t *	corg = cpc710_mem_org + i;
+
+    if (corg->rows == rows && corg->cols == cols && corg->banks2 == banks2)
+    {
+      org = corg;
+
+      break;
+    }
+  }
+
+  if (! org)
+  {
+      /* Unsupported configuration
+       */
+    return 0;
+  }
+
+  mc |= (u32) org->org << 2;
+
+    /* Supported configuration
+     */
+  *mcer = mc;
+  *size = 1l << (lines + 4);
+
+  return 1;
+}
+
+static int cpc710_eeprom_checksum (
+  unsigned int		sdram)
+{
+  u8			sum = 0;
+  unsigned int		i;
+
+  for (i = 0; i < 63; i++)
+  {
+    sum += cpc710_eeprom_read(sdram, i);
+  }
+
+  return sum == cpc710_eeprom_read(sdram, 63);
+}
+
+static u8 cpc710_eeprom_read (
+  unsigned int		sdram,
+  unsigned int		offset)
+{
+  u8			dev = (sdram << 1) | 0xa0;
+  u8			data;
+
+  if (! i2c_read_byte(& data, dev,offset))
+  {
+    puts("I2C error !\n");
+    hang();
+  }
+
+  return data;
+}
diff --git a/board/pcippc2/cpc710_pci.c b/board/pcippc2/cpc710_pci.c
new file mode 100644
index 0000000..9975cda
--- /dev/null
+++ b/board/pcippc2/cpc710_pci.c
@@ -0,0 +1,309 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#include "hardware.h"
+#include "pcippc2.h"
+
+struct pci_controller local_hose, cpci_hose;
+
+static u32	cpc710_mapped_ram;
+
+  /* Enable PCI retry timeouts
+   */
+void cpc710_pci_enable_timeout (void)
+{
+  out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), 0x32000000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
+  iobarrier_rw();
+}
+
+void cpc710_pci_init (void)
+{
+  u32			sdram_size = pcippc2_sdram_size();
+
+  cpc710_mapped_ram = sdram_size < PCI_MEMORY_MAXSIZE ?
+                      sdram_size : PCI_MEMORY_MAXSIZE;
+
+    /* Select the local PCI
+     */
+  out32(REG(CPC0, PCICNFR), 0x80000002);
+  iobarrier_rw();
+
+  out32(REG(CPC0, PCIBAR), BRIDGE_LOCAL_PHYS);
+  iobarrier_rw();
+
+    /* Enable PCI bridge address decoding
+     */
+  out32(REG(CPC0, PCIENB), 0x80000000);
+  iobarrier_rw();
+
+    /* Select the CPCI bridge
+     */
+  out32(REG(CPC0, PCICNFR), 0x80000003);
+  iobarrier_rw();
+
+  out32(REG(CPC0, PCIBAR), BRIDGE_CPCI_PHYS);
+  iobarrier_rw();
+
+    /* Enable PCI bridge address decoding
+     */
+  out32(REG(CPC0, PCIENB), 0x80000000);
+  iobarrier_rw();
+
+    /* Disable configuration accesses
+     */
+  out32(REG(CPC0, PCICNFR), 0x80000000);
+  iobarrier_rw();
+
+    /* Initialise the local PCI
+     */
+  out32(BRIDGE(LOCAL, CRR), 0x7c000000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PCIDG), 0x40000000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PIBAR), BRIDGE_LOCAL_IO_BUS);
+  out32(BRIDGE(LOCAL, SIBAR), BRIDGE_LOCAL_IO_PHYS);
+  out32(BRIDGE(LOCAL, IOSIZE), -BRIDGE_LOCAL_IO_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PMBAR), BRIDGE_LOCAL_MEM_BUS);
+  out32(BRIDGE(LOCAL, SMBAR), BRIDGE_LOCAL_MEM_PHYS);
+  out32(BRIDGE(LOCAL, MSIZE), -BRIDGE_LOCAL_MEM_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PR), 0x00ffe000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, ACR), 0xfe000000);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, PSBAR), PCI_MEMORY_BUS >> 24);
+  out32(BRIDGE(LOCAL, BARPS), PCI_MEMORY_PHYS >> 24);
+  out32(BRIDGE(LOCAL, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
+  iobarrier_rw();
+
+    /* Initialise the CPCI bridge
+     */
+  out32(BRIDGE(CPCI, CRR), 0x7c000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PCIDG), 0xC0000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PIBAR), BRIDGE_CPCI_IO_BUS);
+  out32(BRIDGE(CPCI, SIBAR), BRIDGE_CPCI_IO_PHYS);
+  out32(BRIDGE(CPCI, IOSIZE), -BRIDGE_CPCI_IO_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PMBAR), BRIDGE_CPCI_MEM_BUS);
+  out32(BRIDGE(CPCI, SMBAR), BRIDGE_CPCI_MEM_PHYS);
+  out32(BRIDGE(CPCI, MSIZE), -BRIDGE_CPCI_MEM_SIZE);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PR), 0x80ffe000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, ACR), 0xdf000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, PSBAR), PCI_MEMORY_BUS >> 24);
+  out32(BRIDGE(CPCI, BARPS), PCI_MEMORY_PHYS >> 24);
+  out32(BRIDGE(CPCI, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
+  iobarrier_rw();
+
+    /* Local PCI
+     */
+
+  out32(BRIDGE(LOCAL, CFGADDR), 0x04000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), 0x56010000);
+  iobarrier_rw();
+
+  out32(BRIDGE(LOCAL, CFGADDR), 0x0c000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
+  iobarrier_rw();
+
+    /* Set bus and subbus numbers
+     */
+  out32(BRIDGE(LOCAL, CFGADDR), 0x40000080);
+  iobarrier_rw();
+  out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
+  iobarrier_rw();
+
+  out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
+  iobarrier_rw();
+    /* PCI retry timeouts will be enabled later
+     */
+  out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
+  iobarrier_rw();
+
+    /* CPCI
+     */
+
+    /* Set bus and subbus numbers
+     */
+  out32(BRIDGE(CPCI, CFGADDR), 0x40000080);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x01010000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x04000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x56010000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x0c000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
+  iobarrier_rw();
+
+    /* Write to the PSBAR */
+  out32(BRIDGE(CPCI, CFGADDR), 0x10000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), cpu_to_le32(PCI_MEMORY_BUS));
+  iobarrier_rw();
+
+    /* Set bus and subbus numbers
+     */
+  out32(BRIDGE(CPCI, CFGADDR), 0x40000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x01ff0000);
+  iobarrier_rw();
+
+  out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
+    /* PCI retry timeouts will be enabled later
+     */
+  out32(BRIDGE(CPCI, CFGDATA), 0x00000000);
+  iobarrier_rw();
+
+    /* Remove reset on the PCI buses
+     */
+  out32(BRIDGE(LOCAL, CRR), 0xfc000000);
+  iobarrier_rw();
+  out32(BRIDGE(CPCI, CRR), 0xfc000000);
+  iobarrier_rw();
+
+  local_hose.first_busno = 0;
+  local_hose.last_busno = 0xff;
+
+  /* System memory space */
+  pci_set_region(local_hose.regions + 0,
+		 PCI_MEMORY_BUS,
+		 PCI_MEMORY_PHYS,
+		 PCI_MEMORY_MAXSIZE,
+		 PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+  /* PCI memory space */
+  pci_set_region(local_hose.regions + 1,
+		 BRIDGE_LOCAL_MEM_BUS,
+		 BRIDGE_LOCAL_MEM_PHYS,
+		 BRIDGE_LOCAL_MEM_SIZE,
+		 PCI_REGION_MEM);
+
+  /* PCI I/O space */
+  pci_set_region(local_hose.regions + 2,
+		 BRIDGE_LOCAL_IO_BUS,
+		 BRIDGE_LOCAL_IO_PHYS,
+		 BRIDGE_LOCAL_IO_SIZE,
+		 PCI_REGION_IO);
+
+  local_hose.region_count = 3;
+
+  pci_setup_indirect(&local_hose,
+		     BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGADDR,
+		     BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGDATA);
+
+  pci_register_hose(&local_hose);
+
+  /* Initialize PCI32 bus registers */
+  pci_hose_write_config_byte(&local_hose,
+			  PCI_BDF(local_hose.first_busno,0,0),
+			  CPC710_BUS_NUMBER,
+			  local_hose.first_busno);
+  pci_hose_write_config_byte(&local_hose,
+			  PCI_BDF(local_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  local_hose.last_busno);
+
+  local_hose.last_busno = pci_hose_scan(&local_hose);
+
+  /* Write out correct max subordinate bus number for local hose */
+  pci_hose_write_config_byte(&local_hose,
+			  PCI_BDF(local_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  local_hose.last_busno);
+
+  cpci_hose.first_busno = local_hose.last_busno + 1;
+  cpci_hose.last_busno = 0xff;
+
+  /* System memory space */
+  pci_set_region(cpci_hose.regions + 0,
+		 PCI_MEMORY_BUS,
+		 PCI_MEMORY_PHYS,
+		 PCI_MEMORY_MAXSIZE,
+		 PCI_REGION_MEMORY);
+
+  /* PCI memory space */
+  pci_set_region(cpci_hose.regions + 1,
+		 BRIDGE_CPCI_MEM_BUS,
+		 BRIDGE_CPCI_MEM_PHYS,
+		 BRIDGE_CPCI_MEM_SIZE,
+		 PCI_REGION_MEM);
+
+  /* PCI I/O space */
+  pci_set_region(cpci_hose.regions + 2,
+		 BRIDGE_CPCI_IO_BUS,
+		 BRIDGE_CPCI_IO_PHYS,
+		 BRIDGE_CPCI_IO_SIZE,
+		 PCI_REGION_IO);
+
+  cpci_hose.region_count = 3;
+
+  pci_setup_indirect(&cpci_hose,
+		     BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGADDR,
+		     BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGDATA);
+
+  pci_register_hose(&cpci_hose);
+
+  /* Initialize PCI64 bus registers */
+  pci_hose_write_config_byte(&cpci_hose,
+			  PCI_BDF(cpci_hose.first_busno,0,0),
+			  CPC710_BUS_NUMBER,
+			  cpci_hose.first_busno);
+  pci_hose_write_config_byte(&cpci_hose,
+			  PCI_BDF(cpci_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  cpci_hose.last_busno);
+
+  cpci_hose.last_busno = pci_hose_scan(&cpci_hose);
+
+  /* Write out correct max subordinate bus number for cpci hose */
+  pci_hose_write_config_byte(&cpci_hose,
+			  PCI_BDF(cpci_hose.first_busno,0,0),
+			  CPC710_SUB_BUS_NUMBER,
+			  cpci_hose.last_busno);
+}
diff --git a/board/pcippc2/i2c.c b/board/pcippc2/i2c.c
new file mode 100644
index 0000000..36b1d0f
--- /dev/null
+++ b/board/pcippc2/i2c.c
@@ -0,0 +1,257 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <asm/io.h>
+
+#include "hardware.h"
+#include "i2c.h"
+
+static void		i2c_start	(void);
+static void		i2c_stop	(void);
+static int		i2c_write	(u8		data);
+static void		i2c_read	(u8 *		data);
+
+static inline void	i2c_port_start  (void);
+static inline void	i2c_clock	(unsigned int	val);
+static inline void	i2c_data	(unsigned int	val);
+static inline unsigned int
+			i2c_in		(void);
+static inline void	i2c_write_bit	(unsigned int	val);
+static inline unsigned int
+			i2c_read_bit	(void);
+
+static inline void	i2c_udelay	(unsigned int	time);
+
+int i2c_read_byte (
+  u8 *			data,
+  u8			dev,
+  u8			offset)
+{
+  int			err = 0;
+
+  i2c_start();
+
+  err = ! i2c_write(dev);
+
+  if (! err)
+  {
+    err = ! i2c_write(offset);
+  }
+
+  if (! err)
+  {
+    i2c_start();
+  }
+
+  if (! err)
+  {
+    err = ! i2c_write(dev | 0x01);
+  }
+
+  if (! err)
+  {
+    i2c_read(data);
+  }
+
+  i2c_stop();
+
+  return ! err;
+}
+
+static inline void i2c_udelay (
+  unsigned int		time)
+{
+  int			v;
+
+  asm volatile("mtdec %0" : : "r" (time * ((CFG_BUS_CLK / 4) / 1000000)));
+
+  do
+  {
+    asm volatile("isync; mfdec %0" : "=r" (v));
+  } while (v >= 0);
+}
+
+  /* Low-level hardware access
+   */
+
+#define BIT_GPDATA		0x80000000
+#define BIT_GPCLK		0x40000000
+
+static inline void i2c_port_start (void)
+{
+  out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~(BIT_GPCLK | BIT_GPDATA));
+  out32(REG(CPC0, GPOUT), in32(REG(CPC0, GPOUT)) & ~(BIT_GPCLK | BIT_GPDATA));
+  iobarrier_rw();
+
+  i2c_udelay(1);
+}
+
+static inline void i2c_clock (
+  unsigned int		val)
+{
+  if (val)
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPCLK);
+  }
+  else
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPCLK);
+  }
+
+  iobarrier_rw();
+
+  i2c_udelay(1);
+}
+
+static inline void i2c_data (
+  unsigned int		val)
+{
+  if (val)
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPDATA);
+  }
+  else
+  {
+    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPDATA);
+  }
+
+  iobarrier_rw();
+
+  i2c_udelay(1);
+}
+
+static inline unsigned int i2c_in (void)
+{
+  unsigned int		val = ((in32(REG(CPC0, GPIN)) & BIT_GPDATA) != 0)?1:0;
+
+  iobarrier_rw();
+
+  return val;
+}
+
+
+  /* Protocol implementation
+   */
+
+static inline void i2c_write_bit (
+  unsigned int		val)
+{
+  i2c_data(val);
+  i2c_udelay(10);
+  i2c_clock(1);
+  i2c_udelay(10);
+  i2c_clock(0);
+  i2c_udelay(10);
+}
+
+static inline unsigned int i2c_read_bit (void)
+{
+  unsigned int		val;
+
+  i2c_data(1);
+  i2c_udelay(10);
+
+  i2c_clock(1);
+  i2c_udelay(10);
+
+  val = i2c_in();
+
+  i2c_clock(0);
+  i2c_udelay(10);
+
+  return val;
+}
+
+unsigned int i2c_reset (void)
+{
+  unsigned int		val;
+  int i;
+
+  i2c_port_start();
+
+  i=0;
+  do {
+    i2c_udelay(10);
+    i2c_clock(0);
+    i2c_udelay(10);
+    i2c_clock(1);
+    i2c_udelay(10);
+    val = i2c_in();
+    i++;
+  }  while ((i<9)&&(val==0));
+  return (val);
+}
+
+
+static void i2c_start (void)
+{
+  i2c_data(1);
+  i2c_clock(1);
+  i2c_udelay(10);
+  i2c_data(0);
+  i2c_udelay(10);
+  i2c_clock(0);
+  i2c_udelay(10);
+}
+
+static void i2c_stop (void)
+{
+  i2c_data(0);
+  i2c_udelay(10);
+  i2c_clock(1);
+  i2c_udelay(10);
+  i2c_data(1);
+  i2c_udelay(10);
+}
+
+static int i2c_write (
+  u8			data)
+{
+  unsigned int		i;
+
+  for (i = 0; i < 8; i++)
+  {
+    i2c_write_bit(data >> 7);
+    data <<= 1;
+  }
+
+  return i2c_read_bit() == 0;
+}
+
+static void i2c_read (
+  u8 *			data)
+{
+  unsigned int		i;
+  u8			val = 0;
+
+  for (i = 0; i < 8; i++)
+  {
+    val <<= 1;
+    val |= i2c_read_bit();
+  }
+
+  *data = val;
+  i2c_write_bit(1); /* NoAck */
+}
diff --git a/board/pcippc2/pcippc2.c b/board/pcippc2/pcippc2.c
new file mode 100644
index 0000000..e1b065b
--- /dev/null
+++ b/board/pcippc2/pcippc2.c
@@ -0,0 +1,214 @@
+/*
+ * (C) Copyright 2002
+ * 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 <config.h>
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+#include <linux/mtd/doc2000.h>
+#include <watchdog.h>
+#include <pci.h>
+
+#include "hardware.h"
+#include "pcippc2.h"
+#include "sconsole.h"
+#include "fpga_serial.h"
+
+#if defined(CONFIG_WATCHDOG)
+
+static int pcippc2_wdt_init_done = 0;
+
+void pcippc2_wdt_init (void);
+
+#endif
+
+  /* Check board identity
+   */
+int checkboard (void)
+{
+#ifdef CONFIG_PCIPPC2
+	puts ("Board: Gespac PCIPPC-2\n");
+#else
+	puts ("Board: Gespac PCIPPC-6\n");
+#endif
+	return 0;
+}
+
+  /* RAM size is stored in CPC0_RGBAN1
+   */
+u32 pcippc2_sdram_size (void)
+{
+	return in32 (REG (CPC0, RGBAN1));
+}
+
+long initdram (int board_type)
+{
+	return cpc710_ram_init ();
+}
+
+void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+	out32 (REG (CPC0, SPOR), 0);
+	iobarrier_rw ();
+	while (1);
+}
+
+int board_pre_init (void)
+{
+	out32 (REG (CPC0, RSTR), 0xC0000000);
+	iobarrier_rw ();
+
+	out32 (REG (CPC0, RSTR), 0xF0000000);
+	iobarrier_rw ();
+
+	out32 (REG (CPC0, UCTL), 0x00F80000);
+
+	out32 (REG (CPC0, SIOC0), 0x30000000);
+
+	out32 (REG (CPC0, ABCNTL), 0x00000000);
+
+	out32 (REG (CPC0, SESR), 0x00000000);
+	out32 (REG (CPC0, SEAR), 0x00000000);
+
+	/* Detect IBM Avignon CPC710 Revision */
+	if ((in32 (REG (CPC0, UCTL)) & 0x000000F0) == CPC710_TYPE_100P)
+		out32 (REG (CPC0, PGCHP), 0xA0000040);
+	else
+		out32 (REG (CPC0, PGCHP), 0x80800040);
+
+
+	out32 (REG (CPC0, ATAS), 0x709C2508);
+
+	iobarrier_rw ();
+
+	return 0;
+}
+
+void after_reloc (ulong dest_addr)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* Jump to the main U-Boot board init code
+	 */
+	board_init_r (gd, dest_addr);
+}
+
+int misc_init_r (void)
+{
+	pcippc2_fpga_init ();
+
+#if defined(CONFIG_WATCHDOG)
+	pcippc2_wdt_init ();
+#endif
+
+	fpga_serial_init (sconsole_get_baudrate ());
+
+	sconsole_putc   = fpga_serial_putc;
+	sconsole_puts   = fpga_serial_puts;
+	sconsole_getc   = fpga_serial_getc;
+	sconsole_tstc   = fpga_serial_tstc;
+	sconsole_setbrg = fpga_serial_setbrg;
+
+	sconsole_flush ();
+	return (0);
+}
+
+void pci_init (void)
+{
+	cpc710_pci_init ();
+
+	/* FPGA requires no retry timeouts to be enabled
+	 */
+	cpc710_pci_enable_timeout ();
+}
+
+void doc_init (void)
+{
+	doc_probe (pcippc2_fpga1_phys + HW_FPGA1_DOC);
+}
+
+#if defined(CONFIG_WATCHDOG)
+
+void pcippc2_wdt_init (void)
+{
+	out16r (FPGA (WDT, PROG), 0xffff);
+	out8 (FPGA (WDT, CTRL), 0x1);
+
+	pcippc2_wdt_init_done = 1;
+}
+
+void pcippc2_wdt_done (void)
+{
+	out8 (FPGA (WDT, CTRL), 0x0);
+
+	pcippc2_wdt_init_done = 0;
+}
+
+void pcippc2_wdt_reset (void)
+{
+	if (pcippc2_wdt_init_done == 1)
+		out8 (FPGA (WDT, REFRESH), 0x56);
+}
+
+void watchdog_reset (void)
+{
+	int re_enable = disable_interrupts ();
+
+	pcippc2_wdt_reset ();
+	if (re_enable)
+		enable_interrupts ();
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+int do_wd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+	switch (argc) {
+	case 1:
+		printf ("Watchdog timer status is %s\n",
+			pcippc2_wdt_init_done == 1 ? "on" : "off");
+
+		return 0;
+	case 2:
+		if (!strcmp(argv[1],"on")) {
+			pcippc2_wdt_init();
+			printf("Watchdog timer now is on\n");
+
+			return 0;
+
+		} else if (!strcmp(argv[1],"off")) {
+			pcippc2_wdt_done();
+			printf("Watchdog timer now is off\n");
+
+			return 0;
+
+		} else
+			break;
+	default:
+		break;
+	}
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+}
+
+#endif	/* CFG_CMD_BSP */
+#endif	/* CONFIG_WATCHDOG */
diff --git a/board/pn62/cmd_pn62.c b/board/pn62/cmd_pn62.c
new file mode 100644
index 0000000..928f6c0
--- /dev/null
+++ b/board/pn62/cmd_pn62.c
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <cmd_autoscript.h>
+#include <cmd_bsp.h>
+
+#include "pn62.h"
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+/*
+ * Command led: controls the various LEDs 0..11 on the PN62 card.
+ */
+int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    unsigned int number, function;
+
+    if (argc != 3) {
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    }
+    number = simple_strtoul(argv[1], NULL, 10);
+    if (number > PN62_LED_MAX)
+	return 1;
+    function = simple_strtoul(argv[2], NULL, 16);
+    set_led (number, function);
+    return 0;
+}
+
+/*
+ * Command loadpci: loads a image over PCI.
+ */
+#define CMD_MOVE_WINDOW 0x1
+#define CMD_BOOT_IMAGE  0x2
+
+int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    char *s;
+    ulong addr = 0, count = 0;
+    u32 off;
+    int cmd, rcode = 0;
+
+    /* pre-set load_addr */
+    if ((s = getenv("loadaddr")) != NULL) {
+	addr = simple_strtoul(s, NULL, 16);
+    }
+
+    switch (argc) {
+    case 1:
+	break;
+    case 2:
+	addr = simple_strtoul(argv[1], NULL, 16);
+	break;
+    default:
+       printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+    }
+
+    printf ("## Ready for image download ...\n");
+
+    show_startup_phase(12);
+
+    while (1) {
+	/* Alive indicator */
+	i2155x_write_scrapad(BOOT_PROTO, BOOT_PROTO_READY);
+
+	/* Toggle status LEDs */
+	cmd = (count / 200) % 4; /* downscale */
+	set_led(4, cmd == 0 ? LED_1 : LED_0);
+	set_led(5, cmd == 1 ? LED_1 : LED_0);
+	set_led(6, cmd == 2 ? LED_1 : LED_0);
+	set_led(7, cmd == 3 ? LED_1 : LED_0);
+	udelay(1000);
+	count++;
+
+	cmd = i2155x_read_scrapad(BOOT_CMD);
+
+	if (cmd == BOOT_CMD_MOVE) {
+	    off = i2155x_read_scrapad(BOOT_DATA);
+	    off += addr;
+	    i2155x_set_bar_base(3, off);
+	    printf ("## BAR3 Addr moved = 0x%08x\n", off);
+	    i2155x_write_scrapad(BOOT_CMD, ~cmd);
+	    show_startup_phase(13);
+	}
+	else if (cmd == BOOT_CMD_BOOT) {
+	    set_led(4, LED_1);
+	    set_led(5, LED_1);
+	    set_led(6, LED_1);
+	    set_led(7, LED_1);
+
+	    i2155x_write_scrapad(BOOT_CMD, ~cmd);
+	    show_startup_phase(14);
+	    break;
+	}
+
+	/* Abort if ctrl-c was pressed */
+	if (ctrlc()) {
+	    printf("\nAbort\n");
+	    return 0;
+	}
+
+    }
+
+    /* Repoint to the default shared memory */
+    i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+    load_addr = addr;
+    printf ("## Start Addr      = 0x%08lx\n", addr);
+
+    show_startup_phase(15);
+
+    /* Loading ok, check if we should attempt an auto-start */
+    if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
+	char *local_args[2];
+	local_args[0] = argv[0];
+	local_args[1] = NULL;
+
+	printf ("Automatic boot of image at addr 0x%08lX ...\n",
+		load_addr);
+	rcode = do_bootm (cmdtp, 0, 1, local_args);
+    }
+
+#ifdef CONFIG_AUTOSCRIPT
+    if (load_addr) {
+	char *s;
+
+	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
+	    printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
+	    rcode = autoscript (bd, load_addr);
+	}
+    }
+#endif
+    return rcode;
+}
+
+#endif
diff --git a/board/pn62/misc.c b/board/pn62/misc.c
new file mode 100644
index 0000000..4f71950
--- /dev/null
+++ b/board/pn62/misc.c
@@ -0,0 +1,235 @@
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@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/io.h>
+#include <pci.h>
+
+#include "pn62.h"
+
+typedef struct {
+    pci_dev_t    devno;
+    volatile u32 *csr;
+
+} i2155x_t;
+
+static i2155x_t i2155x = { 0, NULL };
+
+static struct pci_device_id i2155x_ids[] = {
+    { 0x1011, 0x0046 },		/* i21554 */
+    { 0x8086, 0xb555 }		/* i21555 */
+};
+
+int i2155x_init(void)
+{
+    pci_dev_t devno;
+    u32 val;
+    int i;
+
+    /*
+     * Find the Intel bridge.
+     */
+    if ((devno = pci_find_devices(i2155x_ids, 0)) < 0) {
+	printf("Error: Intel bridge 2155x not found!\n");
+	return -1;
+    }
+    i2155x.devno = devno;
+
+    /*
+     * Get auto-configured base address for CSR access.
+     */
+    pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &val);
+    if (val & PCI_BASE_ADDRESS_SPACE_IO) {
+	val &= PCI_BASE_ADDRESS_IO_MASK;
+	i2155x.csr = (volatile u32 *)(_IO_BASE + val);
+    } else {
+	val &= PCI_BASE_ADDRESS_MEM_MASK;
+	i2155x.csr =  (volatile u32 *)val;
+    }
+
+    /*
+     * Translate downstream memory 2 (bar3) to base of shared memory.
+     */
+    i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
+
+    /*
+     * Enable memory space, I/O space and bus master bits
+     * in both Primary and Secondary command registers.
+     */
+    val = PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+    pci_write_config_word(devno, 0x44, val);
+    pci_write_config_word(devno, 0x04, val);
+
+    /*
+     * Clear scratchpad registers.
+     */
+    for (i = 0; i < (I2155X_SCRAPAD_MAX - 1); i++) {
+	i2155x_write_scrapad(i, 0x0);
+    }
+
+    /*
+     * Set interrupt line for Linux.
+     */
+    pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 3);
+
+    return 0;
+}
+
+/*
+ * Access the Scratchpad registers 0..7 of the Intel bridge.
+ */
+void i2155x_write_scrapad(int idx, u32 val)
+{
+    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+	out_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx, val);
+    else
+	printf("i2155x_write_scrapad: invalid index\n");
+}
+
+u32 i2155x_read_scrapad(int idx)
+{
+    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
+	return in_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx);
+    else
+	printf("i2155x_read_scrapad: invalid index\n");
+    return -1;
+}
+
+void i2155x_set_bar_base(int bar, u32 base)
+{
+    if (bar >= 2 && bar <= 4) {
+	pci_write_config_dword(i2155x.devno,
+			       I2155X_BAR2_BASE + (bar - 2) * 4,
+			       base);
+    }
+}
+
+/*
+ * Read Vital Product Data (VPD) from the Serial EPROM attached
+ * to the Intel bridge.
+ */
+int i2155x_read_vpd(int offset, int size, unsigned char *data)
+{
+    int i, n;
+    u16 val16;
+
+    for (i = 0; i < size; i++) {
+	pci_write_config_word(i2155x.devno, I2155X_VPD_ADDR,
+			      offset + i - I2155X_VPD_START);
+	for (n = 10000; n > 0; n--) {
+	    pci_read_config_word(i2155x.devno, I2155X_VPD_ADDR, &val16);
+	    if ((val16 & 0x8000) != 0) /* wait for completion */
+		break;
+	    udelay(100);
+	}
+	if (n == 0) {
+	    printf("i2155x_read_vpd: TIMEOUT\n");
+	    return -1;
+	}
+
+	pci_read_config_byte(i2155x.devno, I2155X_VPD_DATA, &data[i]);
+    }
+
+    return i;
+}
+
+static struct pci_device_id am79c95x_ids [] = {
+        { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
+        { }
+};
+
+
+/*
+ * Initialize the AMD ethernet controllers.
+ */
+int am79c95x_init(void)
+{
+    pci_dev_t devno;
+    int i;
+
+    /*
+     * Set interrupt line for Linux.
+     */
+    for (i = 0; i < 2; i++) {
+	if ((devno = pci_find_devices(am79c95x_ids, i)) < 0)
+	    break;
+	pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 2+i);
+    }
+    if (i < 2)
+	printf("Error: Only %d AMD Ethernet Controller found!\n", i);
+
+    return 0;
+}
+
+
+void set_led(unsigned int number, unsigned int function)
+{
+    volatile u8 *addr;
+
+    if ((number >= 0) && (number < PN62_LED_MAX) &&
+	(function >= 0) && (function <= LED_LAST_FUNCTION)) {
+	addr = (volatile u8 *)(PN62_LED_BASE + number * 8);
+	out_8(addr, function&0xff);
+    }
+}
+
+/*
+ * Show fatal error indicated by Kinght Rider(tm) effect
+ * in LEDS 0-7. LEDS 8-11 contain 4 bit error code.
+ * Note: this function will not terminate.
+ */
+void fatal_error(unsigned int error_code)
+{
+    int i, d;
+
+    for (i = 0; i < 12; i++) {
+	set_led(i, LED_0);
+    }
+
+    /*
+     * Write error code.
+     */
+    set_led(8,  (error_code & 0x01) ? LED_1 : LED_0);
+    set_led(9,  (error_code & 0x02) ? LED_1 : LED_0);
+    set_led(10, (error_code & 0x04) ? LED_1 : LED_0);
+    set_led(11, (error_code & 0x08) ? LED_1 : LED_0);
+
+    /*
+     * Yay - Knight Rider effect!
+     */
+    while(1) {
+	unsigned int delay = 2000;
+
+	for (i = 0; i < 8; i++) {
+	    set_led(i, LED_1);
+	    for (d = 0; d < delay; d++);
+	    set_led(i, LED_0);
+	}
+
+	for (i = 7; i > 0; i--) {
+	    set_led(i, LED_1);
+	    for (d = 0; d < delay; d++);
+	    set_led(i, LED_0);
+	}
+    }
+}
diff --git a/board/pn62/pn62.c b/board/pn62/pn62.c
new file mode 100644
index 0000000..4d87527
--- /dev/null
+++ b/board/pn62/pn62.c
@@ -0,0 +1,216 @@
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@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 <pci.h>
+
+#include "pn62.h"
+
+
+static int get_serial_number (char *string, int size);
+static int get_mac_address (int id, u8 * mac, char *string, int size);
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+void show_boot_progress (int phase)
+{
+	/*
+	 * Show phases of the bootm command on the front panel
+	 * LEDs and the scratchpad register #3 as well. We use
+	 * blinking LEDs for logical "1".
+	 */
+	if (phase > 0) {
+		set_led (8, (phase & 0x1) ? LED_SLOW_CLOCK : LED_0);
+		set_led (9, (phase & 0x2) ? LED_SLOW_CLOCK : LED_0);
+		set_led (10, (phase & 0x4) ? LED_SLOW_CLOCK : LED_0);
+		set_led (11, (phase & 0x8) ? LED_SLOW_CLOCK : LED_0);
+	}
+	i2155x_write_scrapad (BOOT_STATUS, phase);
+	if (phase < 0)
+		i2155x_write_scrapad (BOOT_DONE, BOOT_DONE_ERROR);
+}
+#endif
+
+void show_startup_phase (int phase)
+{
+	/*
+	 * Show the phase of U-Boot startup on the front panel
+	 * LEDs and the scratchpad register #3 as well.
+	 */
+	if (phase > 0) {
+		set_led (8, (phase & 0x1) ? LED_1 : LED_0);
+		set_led (9, (phase & 0x2) ? LED_1 : LED_0);
+		set_led (10, (phase & 0x4) ? LED_1 : LED_0);
+		set_led (11, (phase & 0x8) ? LED_1 : LED_0);
+	}
+	i2155x_write_scrapad (BOOT_STATUS, phase);
+	if (phase < 0)
+		i2155x_write_scrapad (BOOT_DONE, BOOT_DONE_ERROR);
+}
+
+int checkboard (void)
+{
+	show_startup_phase (1);
+	puts ("Board: PN62\n");
+	return 0;
+}
+
+long int initdram (int board_type)
+{
+	int i, cnt;
+	volatile uchar *base = CFG_SDRAM_BASE;
+	volatile ulong *addr;
+	ulong save[32];
+	ulong val, ret = 0;
+
+	show_startup_phase (2);
+
+	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:
+	show_startup_phase (3);
+	return ret;
+}
+
+/*
+ * Initialize PCI Devices. We rely on auto-configuration.
+ */
+#ifndef CONFIG_PCI_PNP
+#error "CONFIG_PCI_PNP is not defined, please correct!"
+#endif
+
+struct pci_controller hose = {
+};
+
+void pci_init (void)
+{
+	show_startup_phase (4);
+	pci_mpc824x_init (&hose);
+
+	show_startup_phase (5);
+	i2155x_init ();
+	show_startup_phase (6);
+	am79c95x_init ();
+	show_startup_phase (7);
+}
+
+int misc_init_r (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	char str[20];
+	u8 mac[6];
+
+	show_startup_phase (8);
+	/*
+	 * Get serial number and ethernet addresses if not already defined
+	 * and update the board info structure and the environment.
+	 */
+	if (getenv ("serial#") == NULL &&
+		get_serial_number (str, strlen (str)) > 0) {
+		setenv ("serial#", str);
+	}
+	show_startup_phase (9);
+
+	if (getenv ("ethaddr") == NULL &&
+		get_mac_address (0, mac, str, sizeof (str)) > 0) {
+		setenv ("ethaddr", str);
+		memcpy (gd->bd->bi_enetaddr, mac, 6);
+	}
+	show_startup_phase (10);
+
+	if (getenv ("eth1addr") == NULL &&
+		get_mac_address (1, mac, str, sizeof (str)) > 0) {
+		setenv ("eth1addr", str);
+		memcpy (gd->bd->bi_enet1addr, mac, 6);
+	}
+	show_startup_phase (11);
+
+	/* Tell everybody that U-Boot is up and runnig */
+	i2155x_write_scrapad (0, 0x12345678);
+	return (0);
+}
+
+static int get_serial_number (char *string, int size)
+{
+	int i;
+	char c;
+
+	if (size < I2155X_VPD_SN_SIZE)
+		size = I2155X_VPD_SN_SIZE;
+	for (i = 0; i < (size - 1); i++) {
+		i2155x_read_vpd (I2155X_VPD_SN_START + i, 1, &c);
+		if (c == '\0')
+			break;
+		string[i] = c;
+	}
+	string[i] = '\0';			/* make sure it's terminated */
+
+	return i;
+}
+
+static int get_mac_address (int id, u8 * mac, char *string, int size)
+{
+	if (size < 6 * 3)
+		return -1;
+
+	i2155x_read_vpd (I2155X_VPD_MAC0_START + 6 * id, 6, mac);
+	return sprintf (string, "%02x:%02x:%02x:%02x:%02x:%02x",
+				mac[0], mac[1], mac[2],
+				mac[3], mac[4], mac[5]);
+}
diff --git a/board/r360mpi/r360mpi.c b/board/r360mpi/r360mpi.c
new file mode 100644
index 0000000..d7b8873
--- /dev/null
+++ b/board/r360mpi/r360mpi.c
@@ -0,0 +1,423 @@
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <config.h>
+#include <mpc8xx.h>
+#include <i2c.h>
+
+#include <commproc.h>
+#include <command.h>
+#include <cmd_bsp.h>
+#include <malloc.h>
+
+#include <linux/types.h>
+#include <linux/string.h>       /* for strdup */
+
+
+/*
+ *  Memory Controller Using
+ *
+ *  CS0 - Flash memory            (0x40000000)
+ *  CS1 - SDRAM                   (0x00000000}
+ *  CS2 -
+ *  CS3 -
+ *  CS4 -
+ *  CS5 -
+ *  CS6 - PCMCIA device
+ *  CS7 - PCMCIA device
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#define _not_used_	0xffffffff
+
+const uint sdram_table[]=
+{
+        /* single read. (offset 0 in upm RAM) */
+        0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+        0x1ff77c47,
+
+        /* MRS initialization (offset 5) */
+
+        0x1ff77c34, 0xefeabc34, 0x1fb57c35,
+
+        /* burst read. (offset 8 in upm RAM) */
+        0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+        0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* single write. (offset 18 in upm RAM) */
+        0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* burst write. (offset 20 in upm RAM) */
+        0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+        0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* refresh. (offset 30 in upm RAM) */
+        0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+        0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
+        _not_used_, _not_used_, _not_used_, _not_used_,
+
+        /* exception. (offset 3c in upm RAM) */
+        0x7ffffc07, _not_used_, _not_used_, _not_used_ };
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+	puts ("Board: R360 MPI Board\n");
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	long int size8, size9;
+	long int size_b0 = 0;
+	unsigned long reg;
+
+	upmconfig (UPMA, (uint *) sdram_table,
+			   sizeof (sdram_table) / sizeof (uint));
+
+	/*
+	 * Preliminary prescaler for refresh (depends on number of
+	 * banks): This value is selected for four cycles every 62.4 us
+	 * with two SDRAM banks or four cycles every 31.2 us with one
+	 * bank. It will be adjusted after memory sizing.
+	 */
+	memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
+
+	memctl->memc_mar = 0x00000088;
+
+	/*
+	 * Map controller bank 1 to the SDRAM bank at
+	 * preliminary address - these have to be modified after the
+	 * SDRAM size has been determined.
+	 */
+	memctl->memc_or1 = CFG_OR1_PRELIM;
+	memctl->memc_br1 = CFG_BR1_PRELIM;
+
+	memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE));	/* no refresh yet */
+
+	udelay (200);
+
+	/* perform SDRAM initializsation sequence */
+
+	memctl->memc_mcr = 0x80002105;	/* SDRAM bank 0 */
+	udelay (200);
+	memctl->memc_mcr = 0x80002230;	/* SDRAM bank 0 - execute twice */
+	udelay (200);
+
+	memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */
+
+	udelay (1000);
+
+	/*
+	 * Check Bank 0 Memory Size for re-configuration
+	 *
+	 * try 8 column mode
+	 */
+	size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE1_PRELIM,
+					   SDRAM_MAX_SIZE);
+
+	udelay (1000);
+
+	/*
+	 * try 9 column mode
+	 */
+	size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE1_PRELIM,
+					   SDRAM_MAX_SIZE);
+
+	if (size8 < size9) {		/* leave configuration at 9 columns */
+		size_b0 = size9;
+/*	debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);	*/
+	} else {					/* back to 8 columns            */
+		size_b0 = size8;
+		memctl->memc_mamr = CFG_MAMR_8COL;
+		udelay (500);
+/*	debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);	*/
+	}
+
+	udelay (1000);
+
+	/*
+	 * Adjust refresh rate depending on SDRAM type, both banks
+	 * For types > 128 MBit leave it at the current (fast) rate
+	 */
+	if ((size_b0 < 0x02000000)) {
+		/* reduce to 15.6 us (62.4 us / quad) */
+		memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
+		udelay (1000);
+	}
+
+	/*
+	 * Final mapping
+	 */
+
+	memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+	memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+	/* adjust refresh rate depending on SDRAM type, one bank */
+	reg = memctl->memc_mptpr;
+	reg >>= 1;		/* reduce to CFG_MPTPR_1BK_8K / _4K */
+	memctl->memc_mptpr = reg;
+
+	udelay (10000);
+
+	return (size_b0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base,
+						   long int maxsize)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	volatile long int *addr;
+	ulong cnt, val;
+	ulong save[32];			/* to make test non-destructive */
+	unsigned char i = 0;
+
+	memctl->memc_mamr = mamr_value;
+
+	for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+		addr = base + cnt;	/* pointer arith! */
+
+		save[i++] = *addr;
+		*addr = ~cnt;
+	}
+
+	/* write 0 to base address */
+	addr = base;
+	save[i] = *addr;
+	*addr = 0;
+
+	/* check at base address */
+	if ((val = *addr) != 0) {
+		*addr = save[i];
+		return (0);
+	}
+
+	for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+		addr = base + cnt;	/* pointer arith! */
+		val = *addr;
+		*addr = save[--i];
+
+		if (val != (~cnt)) {
+			return (cnt * sizeof (long));
+		}
+	}
+	return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void r360_pwm_write (uchar reg, uchar val)
+{
+	if (i2c_write (CFG_I2C_PWM_ADDR, reg, 1, &val, 1)) {
+		printf ("Can't write PWM register 0x%02X.\n", reg);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+
+/* Number of bytes returned from Keyboard Controller */
+#define KEYBD_KEY_MAX		20				/* maximum key number */
+#define KEYBD_DATALEN		((KEYBD_KEY_MAX + 7) / 8)	/* normal key scan data */
+
+static uchar kbd_addr = CFG_I2C_KBD_ADDR;
+
+static uchar *key_match (uchar *);
+
+int misc_init_r (void)
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	uchar keybd_env[2 * KEYBD_DATALEN + 1];
+	uchar *str;
+	int i;
+
+	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+	for (i = 0; i < KEYBD_DATALEN; ++i) {
+		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+	}
+	setenv ("keybd", keybd_env);
+
+	str = strdup (key_match (kbd_data));	/* decode keys */
+
+#ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */
+	setenv ("preboot", str);	/* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+	if (str != NULL) {
+		free (str);
+	}
+
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Check if pressed key(s) match magic sequence,
+ * and return the command string associated with that key(s).
+ *
+ * If no key press was decoded, NULL is returned.
+ *
+ * Note: the first character of the argument will be overwritten with
+ * the "magic charcter code" of the decoded key(s), or '\0'.
+ *
+ *
+ * Note: the string points to static environment data and must be
+ * saved before you call any function that modifies the environment.
+ */
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static uchar *key_match (uchar * kbd_data)
+{
+	uchar compare[KEYBD_DATALEN];
+	uchar magic[sizeof (kbd_magic_prefix) + 1];
+	uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+	uchar key_mask;
+	uchar *str, *nxt, *suffix;
+	uchar *kbd_magic_keys;
+	char *cmd;
+	int i;
+
+	/*
+	 * The following string defines the characters that can pe appended
+	 * to "key_magic" to form the names of environment variables that
+	 * hold "magic" key codes, i. e. such key codes that can cause
+	 * pre-boot actions. If the string is empty (""), then only
+	 * "key_magic" is checked (old behaviour); the string "125" causes
+	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+	 */
+	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+		kbd_magic_keys = "";
+
+	/* loop over all magic keys;
+	 * use '\0' suffix in case of empty string
+	 */
+	for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix) {
+		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+#if 0
+		printf ("### Check magic \"%s\"\n", magic);
+#endif
+
+		memcpy(compare, kbd_data, KEYBD_DATALEN);
+
+		for (str = getenv(magic); str != NULL; str = (*nxt) ? nxt+1 : nxt) {
+			uchar c;
+
+			c = (uchar) simple_strtoul (str, (char **) (&nxt), 16);
+
+			if (str == nxt)				/* invalid character */
+				break;
+
+			if (c >= KEYBD_KEY_MAX)			/* bad key number */
+				goto next_magic;
+
+			key_mask = 0x80 >> (c % 8);
+
+			if (!(compare[c / 8] & key_mask))	/* key not pressed */
+				goto next_magic;
+
+			compare[c / 8] &= ~key_mask;
+		}
+
+		for (i=0; i<KEYBD_DATALEN; i++)
+			if (compare[i])			/* key(s) not released */
+				goto next_magic;
+
+		sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+
+		cmd = getenv (cmd_name);
+#if 0
+		printf ("### Set PREBOOT to $(%s): \"%s\"\n",
+			cmd_name, cmd ? cmd : "<<NULL>>");
+#endif
+		*kbd_data = *suffix;
+		return (cmd);
+
+	next_magic:;
+	}
+#if 0
+	printf ("### Delete PREBOOT\n");
+#endif
+	*kbd_data = '\0';
+	return (NULL);
+}
+#endif							/* CONFIG_PREBOOT */
+
+/* Read Keyboard status */
+int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	uchar kbd_data[KEYBD_DATALEN];
+	uchar keybd_env[2 * KEYBD_DATALEN + 1];
+	int i;
+
+	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+	/* Read keys */
+	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+	puts ("Keys:");
+	for (i = 0; i < KEYBD_DATALEN; ++i) {
+		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+		printf (" %02x", kbd_data[i]);
+	}
+	putc ('\n');
+	setenv ("keybd", keybd_env);
+	return 0;
+}
diff --git a/board/sacsng/clkinit.c b/board/sacsng/clkinit.c
new file mode 100644
index 0000000..1e851e1
--- /dev/null
+++ b/board/sacsng/clkinit.c
@@ -0,0 +1,884 @@
+/*
+ * (C) Copyright 2002
+ * Custom IDEAS, Inc. <www.cideas.com>
+ * Jon Diekema <diekema@cideas.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc8260.h>
+#include <asm/cpm_8260.h>
+#include <configs/sacsng.h>
+
+#include "clkinit.h"
+
+int Daq64xSampling = 0;
+
+
+void Daq_BRG_Reset(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     volatile uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+     *brg_ptr |=  CPM_BRG_RST;
+     *brg_ptr &= ~CPM_BRG_RST;
+}
+
+void Daq_BRG_Disable(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     volatile uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+     *brg_ptr &= ~CPM_BRG_EN;
+}
+
+void Daq_BRG_Enable(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     volatile uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+     *brg_ptr |= CPM_BRG_EN;
+}
+
+uint Daq_BRG_Get_Div16(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     if (*brg_ptr & CPM_BRG_DIV16) {
+         /* DIV16 active */
+         return (TRUE);
+     }
+     else {
+         /* DIV16 inactive */
+         return (FALSE);
+     }
+}
+
+void Daq_BRG_Set_Div16(uint brg, uint div16)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     if (div16) {
+         /* DIV16 active */
+         *brg_ptr |=  CPM_BRG_DIV16;
+     }
+     else {
+         /* DIV16 inactive */
+         *brg_ptr &= ~CPM_BRG_DIV16;
+     }
+}
+
+uint Daq_BRG_Get_Count(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+     uint brg_cnt;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     /* Get the clock divider
+      *
+      * Note: A clock divider of 0 means divide by 1,
+      *       therefore we need to add 1 to the count.
+      */
+     brg_cnt = (*brg_ptr & CPM_BRG_CD_MASK) >> CPM_BRG_DIV16_SHIFT;
+     brg_cnt++;
+     if (*brg_ptr & CPM_BRG_DIV16) {
+         brg_cnt *= 16;
+     }
+
+    return (brg_cnt);
+}
+
+void Daq_BRG_Set_Count(uint brg, uint brg_cnt)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     /*
+      * Note: A clock divider of 0 means divide by 1,
+      *	 therefore we need to subtract 1 from the count.
+      */
+     if (brg_cnt > 4096) {
+         /* Prescale = Divide by 16 */
+         *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK)   |
+	     (((brg_cnt / 16) - 1) << CPM_BRG_DIV16_SHIFT);
+	 *brg_ptr |= CPM_BRG_DIV16;
+     }
+     else {
+         /* Prescale = Divide by 1 */
+         *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK) |
+	     ((brg_cnt - 1) << CPM_BRG_DIV16_SHIFT);
+	 *brg_ptr &= ~CPM_BRG_DIV16;
+     }
+}
+
+uint Daq_BRG_Get_ExtClk(uint brg)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     return ((*brg_ptr & CPM_BRG_EXTC_MASK) >> CPM_BRG_EXTC_SHIFT);
+}
+
+char* Daq_BRG_Get_ExtClk_Description(uint brg)
+{
+     uint extc;
+
+     extc = Daq_BRG_Get_ExtClk(brg);
+
+     switch (brg + 1) {
+         case 1:
+         case 2:
+         case 5:
+         case 6: {
+             switch (extc) {
+                 case 0: {
+                     return ("BRG_INT");
+                 }
+                 case 1: {
+                     return ("CLK3");
+                 }
+                 case 2: {
+                     return ("CLK5");
+                 }
+             }
+             return ("??1245??");
+         }
+         case 3:
+         case 4:
+         case 7:
+         case 8: {
+             switch (extc) {
+                 case 0: {
+                     return ("BRG_INT");
+                 }
+                 case 1: {
+                     return ("CLK9");
+                 }
+                 case 2: {
+                     return ("CLK15");
+                 }
+             }
+             return ("??3478??");
+         }
+     }
+     return ("??9876??");
+}
+
+void Daq_BRG_Set_ExtClk(uint brg, uint extc)
+{
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg -= 4;
+     }
+     brg_ptr += brg;
+
+     *brg_ptr = (*brg_ptr & ~CPM_BRG_EXTC_MASK) |
+                ((extc << CPM_BRG_EXTC_SHIFT) & CPM_BRG_EXTC_MASK);
+}
+
+uint Daq_BRG_Rate(uint brg)
+{
+     DECLARE_GLOBAL_DATA_PTR;
+     volatile immap_t *immr = (immap_t *)CFG_IMMR;
+     uint *brg_ptr;
+     uint brg_cnt;
+     uint brg_freq = 0;
+
+     brg_ptr = (uint *)&immr->im_brgc1;
+     brg_ptr += brg;
+     if (brg >= 5) {
+         brg_ptr = (uint *)&immr->im_brgc5;
+         brg_ptr += (brg - 4);
+     }
+
+    brg_cnt = Daq_BRG_Get_Count(brg);
+
+    switch (Daq_BRG_Get_ExtClk(brg)) {
+        case CPM_BRG_EXTC_CLK3:
+        case CPM_BRG_EXTC_CLK5: {
+	    brg_freq = brg_cnt;
+	    break;
+	}
+	default: {
+	    brg_freq = (uint)BRG_INT_CLK / brg_cnt;
+	}
+    }
+    return (brg_freq);
+}
+
+uint Daq_Get_SampleRate(void)
+
+{
+     /*
+      * Read the BRG's to return the actual sample rate.
+      */
+     return (Daq_BRG_Rate(MCLK_BRG) / (MCLK_DIVISOR * SCLK_DIVISOR));
+}
+
+uint Daq_Set_SampleRate(uint rate, uint force)
+
+{
+    DECLARE_GLOBAL_DATA_PTR;
+    uint mclk_divisor; /* MCLK divisor */
+    uint rate_curr;    /* Current sample rate */
+
+    /*
+     * Limit the sample rate to some sensible values.
+     */
+    if (Daq64xSampling) {
+      if (rate > MAX_64x_SAMPLE_RATE) {
+	  rate = MAX_64x_SAMPLE_RATE;
+      }
+    }
+    else {
+      if (rate > MAX_128x_SAMPLE_RATE) {
+	  rate = MAX_128x_SAMPLE_RATE;
+      }
+    }
+    if (rate < MIN_SAMPLE_RATE) {
+        rate = MIN_SAMPLE_RATE;
+    }
+
+    /* Check to see if we are really changing rates */
+    rate_curr = Daq_Get_SampleRate();
+    if ((rate != rate_curr) || force) {
+        /*
+	 * Dynamically adjust MCLK based on the new sample rate.
+	 */
+
+        /* Compute the divisors */
+        mclk_divisor = BRG_INT_CLK / (rate * MCLK_DIVISOR * SCLK_DIVISOR);
+
+	/* Setup MCLK */
+	Daq_BRG_Set_Count(MCLK_BRG, mclk_divisor);
+
+	/* Setup SCLK */
+#       ifdef RUN_SCLK_ON_BRG_INT
+	   Daq_BRG_Set_Count(SCLK_BRG, mclk_divisor * MCLK_DIVISOR);
+#       else
+	   Daq_BRG_Set_Count(SCLK_BRG, MCLK_DIVISOR);
+#       endif
+
+#       ifdef RUN_LRCLK_ON_BRG_INT
+	    Daq_BRG_Set_Count(LRCLK_BRG,
+			      mclk_divisor * MCLK_DIVISOR * SCLK_DIVISOR);
+#       else
+	    Daq_BRG_Set_Count(LRCLK_BRG, SCLK_DIVISOR);
+#       endif
+
+	/* Read the BRG's to return the actual sample rate. */
+	rate_curr = Daq_Get_SampleRate();
+    }
+
+    return (rate_curr);
+}
+
+void Daq_Init_Clocks(int sample_rate, int sample_64x)
+
+{
+    volatile ioport_t *iopa = ioport_addr((immap_t *)CFG_IMMR, 0 /* port A */);
+
+    /* Save off the clocking data */
+    Daq64xSampling = sample_64x;
+
+    /*
+     * Limit the sample rate to some sensible values.
+     */
+    if (Daq64xSampling) {
+      if (sample_rate > MAX_64x_SAMPLE_RATE) {
+	  sample_rate = MAX_64x_SAMPLE_RATE;
+      }
+    }
+    else {
+      if (sample_rate > MAX_128x_SAMPLE_RATE) {
+	  sample_rate = MAX_128x_SAMPLE_RATE;
+      }
+    }
+    if (sample_rate < MIN_SAMPLE_RATE) {
+        sample_rate = MIN_SAMPLE_RATE;
+    }
+
+    /*
+     * Initialize the MCLK/SCLK/LRCLK baud rate generators.
+     */
+
+    /* Setup MCLK */
+    Daq_BRG_Set_ExtClk(MCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+
+    /* Setup SCLK */
+#   ifdef RUN_SCLK_ON_BRG_INT
+        Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+#   else
+        Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_CLK9);
+#   endif
+
+    /* Setup LRCLK */
+#   ifdef RUN_LRCLK_ON_BRG_INT
+        Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_BRGCLK);
+#   else
+        Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_CLK5);
+#   endif
+
+    /* Setup the BRG rates */
+    Daq_Set_SampleRate(sample_rate, TRUE);
+
+    /* Enable the clock drivers */
+    iopa->pdat &= ~SLRCLK_EN_MASK;
+}
+
+void Daq_Stop_Clocks(void)
+
+{
+#ifdef TIGHTEN_UP_BRG_TIMING
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#endif
+
+#   ifdef TIGHTEN_UP_BRG_TIMING
+        /*
+         * Reset MCLK BRG
+         */
+#       if (MCLK_BRG == 0)
+            immr->im_brgc1 |=  CPM_BRG_RST;
+            immr->im_brgc1 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 1)
+            immr->im_brgc2 |=  CPM_BRG_RST;
+            immr->im_brgc2 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 2)
+            immr->im_brgc3 |=  CPM_BRG_RST;
+            immr->im_brgc3 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 3)
+            immr->im_brgc4 |=  CPM_BRG_RST;
+            immr->im_brgc4 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 4)
+            immr->im_brgc5 |=  CPM_BRG_RST;
+            immr->im_brgc5 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 5)
+            immr->im_brgc6 |=  CPM_BRG_RST;
+            immr->im_brgc6 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 6)
+            immr->im_brgc7 |=  CPM_BRG_RST;
+            immr->im_brgc7 &= ~CPM_BRG_RST;
+#       endif
+#       if (MCLK_BRG == 7)
+            immr->im_brgc8 |=  CPM_BRG_RST;
+            immr->im_brgc8 &= ~CPM_BRG_RST;
+#       endif
+
+        /*
+         * Reset SCLK BRG
+         */
+#       if (SCLK_BRG == 0)
+            immr->im_brgc1 |=  CPM_BRG_RST;
+            immr->im_brgc1 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 1)
+            immr->im_brgc2 |=  CPM_BRG_RST;
+            immr->im_brgc2 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 2)
+            immr->im_brgc3 |=  CPM_BRG_RST;
+            immr->im_brgc3 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 3)
+            immr->im_brgc4 |=  CPM_BRG_RST;
+            immr->im_brgc4 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 4)
+            immr->im_brgc5 |=  CPM_BRG_RST;
+            immr->im_brgc5 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 5)
+            immr->im_brgc6 |=  CPM_BRG_RST;
+            immr->im_brgc6 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 6)
+            immr->im_brgc7 |=  CPM_BRG_RST;
+            immr->im_brgc7 &= ~CPM_BRG_RST;
+#       endif
+#       if (SCLK_BRG == 7)
+            immr->im_brgc8 |=  CPM_BRG_RST;
+            immr->im_brgc8 &= ~CPM_BRG_RST;
+#       endif
+
+        /*
+         * Reset LRCLK BRG
+         */
+#       if (LRCLK_BRG == 0)
+            immr->im_brgc1 |=  CPM_BRG_RST;
+            immr->im_brgc1 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 1)
+            immr->im_brgc2 |=  CPM_BRG_RST;
+            immr->im_brgc2 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 2)
+            immr->im_brgc3 |=  CPM_BRG_RST;
+            immr->im_brgc3 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 3)
+            immr->im_brgc4 |=  CPM_BRG_RST;
+            immr->im_brgc4 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 4)
+            immr->im_brgc5 |=  CPM_BRG_RST;
+            immr->im_brgc5 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 5)
+            immr->im_brgc6 |=  CPM_BRG_RST;
+            immr->im_brgc6 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 6)
+            immr->im_brgc7 |=  CPM_BRG_RST;
+            immr->im_brgc7 &= ~CPM_BRG_RST;
+#       endif
+#       if (LRCLK_BRG == 7)
+            immr->im_brgc8 |=  CPM_BRG_RST;
+            immr->im_brgc8 &= ~CPM_BRG_RST;
+#       endif
+#   else
+        /*
+         * Reset the clocks
+         */
+        Daq_BRG_Reset(MCLK_BRG);
+        Daq_BRG_Reset(SCLK_BRG);
+        Daq_BRG_Reset(LRCLK_BRG);
+#   endif
+}
+
+void Daq_Start_Clocks(int sample_rate)
+
+{
+#ifdef TIGHTEN_UP_BRG_TIMING
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+    uint          mclk_brg;       /* MCLK  BRG value */
+    uint          sclk_brg;       /* SCLK  BRG value */
+    uint          lrclk_brg;      /* LRCLK BRG value */
+    uint          temp_lrclk_brg; /* Temporary LRCLK BRG value */
+    uint	  real_lrclk_brg; /* Permanent LRCLK BRG value */
+    unsigned long flags;          /* Interrupt flags */
+    uint          sclk_cnt;       /* SCLK count */
+    uint          delay_cnt;      /* Delay count */
+#endif
+
+#   ifdef TIGHTEN_UP_BRG_TIMING
+        /*
+         * Obtain the enabled MCLK BRG value
+         */
+#       if (MCLK_BRG == 0)
+            mclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 1)
+            mclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 2)
+            mclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 3)
+            mclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 4)
+            mclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 5)
+            mclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 6)
+            mclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (MCLK_BRG == 7)
+            mclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+
+        /*
+         * Obtain the enabled SCLK BRG value
+         */
+#       if (SCLK_BRG == 0)
+            sclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 1)
+            sclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 2)
+            sclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 3)
+            sclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 4)
+            sclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 5)
+            sclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 6)
+            sclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (SCLK_BRG == 7)
+            sclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+
+        /*
+         * Obtain the enabled LRCLK BRG value
+         */
+#       if (LRCLK_BRG == 0)
+            lrclk_brg = (immr->im_brgc1 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 1)
+            lrclk_brg = (immr->im_brgc2 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 2)
+            lrclk_brg = (immr->im_brgc3 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 3)
+            lrclk_brg = (immr->im_brgc4 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 4)
+            lrclk_brg = (immr->im_brgc5 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 5)
+            lrclk_brg = (immr->im_brgc6 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 6)
+            lrclk_brg = (immr->im_brgc7 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+#       if (LRCLK_BRG == 7)
+            lrclk_brg = (immr->im_brgc8 & ~CPM_BRG_RST) | CPM_BRG_EN;
+#       endif
+
+	/* Save off the real LRCLK value */
+	real_lrclk_brg = lrclk_brg;
+
+	/* Obtain the current SCLK count */
+	sclk_cnt  = ((sclk_brg & 0x00001FFE) >> 1) + 1;
+
+	/* Compute the delay as a function of SCLK count */
+        delay_cnt = ((sclk_cnt / 4) - 2) * 10 + 6;
+	if (sample_rate == 43402) {
+	  delay_cnt++;
+	}
+
+        /* Clear out the count */
+	temp_lrclk_brg = sclk_brg & ~0x00001FFE;
+
+        /* Insert the count */
+	temp_lrclk_brg |= ((delay_cnt + (sclk_cnt / 2) - 1) << 1) &  0x00001FFE;
+
+        /*
+         * Enable MCLK BRG
+         */
+#       if (MCLK_BRG == 0)
+            immr->im_brgc1 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 1)
+            immr->im_brgc2 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 2)
+            immr->im_brgc3 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 3)
+            immr->im_brgc4 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 4)
+            immr->im_brgc5 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 5)
+            immr->im_brgc6 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 6)
+            immr->im_brgc7 = mclk_brg;
+#       endif
+#       if (MCLK_BRG == 7)
+            immr->im_brgc8 = mclk_brg;
+#       endif
+
+        /*
+         * Enable SCLK BRG
+         */
+#       if (SCLK_BRG == 0)
+            immr->im_brgc1 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 1)
+            immr->im_brgc2 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 2)
+            immr->im_brgc3 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 3)
+            immr->im_brgc4 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 4)
+            immr->im_brgc5 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 5)
+            immr->im_brgc6 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 6)
+            immr->im_brgc7 = sclk_brg;
+#       endif
+#       if (SCLK_BRG == 7)
+            immr->im_brgc8 = sclk_brg;
+#       endif
+
+        /*
+         * Enable LRCLK BRG (1st time - temporary)
+         */
+#       if (LRCLK_BRG == 0)
+             immr->im_brgc1 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 1)
+             immr->im_brgc2 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 2)
+             immr->im_brgc3 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 3)
+             immr->im_brgc4 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 4)
+             immr->im_brgc5 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 5)
+             immr->im_brgc6 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 6)
+             immr->im_brgc7 = temp_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 7)
+             immr->im_brgc8 = temp_lrclk_brg;
+#       endif
+
+        /*
+         * Enable LRCLK BRG (2nd time - permanent)
+         */
+#       if (LRCLK_BRG == 0)
+             immr->im_brgc1 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 1)
+             immr->im_brgc2 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 2)
+             immr->im_brgc3 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 3)
+             immr->im_brgc4 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 4)
+             immr->im_brgc5 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 5)
+             immr->im_brgc6 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 6)
+             immr->im_brgc7 = real_lrclk_brg;
+#       endif
+#       if (LRCLK_BRG == 7)
+             immr->im_brgc8 = real_lrclk_brg;
+#       endif
+#   else
+        /*
+         * Enable the clocks
+         */
+        Daq_BRG_Enable(LRCLK_BRG);
+        Daq_BRG_Enable(SCLK_BRG);
+        Daq_BRG_Enable(MCLK_BRG);
+#   endif
+}
+
+void Daq_Display_Clocks(void)
+
+{
+    volatile immap_t *immr = (immap_t *)CFG_IMMR;
+    uint mclk_divisor; /* Detected MCLK divisor */
+    uint sclk_divisor; /* Detected SCLK divisor */
+
+    printf("\nBRG:\n");
+    if (immr->im_brgc4 != 0) {
+        printf("\tbrgc4\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  MCLK\n",
+	       immr->im_brgc4,
+	       (uint)&(immr->im_brgc4),
+	       Daq_BRG_Get_Count(3),
+	       Daq_BRG_Get_ExtClk(3),
+	       Daq_BRG_Get_ExtClk_Description(3));
+    }
+    if (immr->im_brgc8 != 0) {
+        printf("\tbrgc8\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SCLK\n",
+	       immr->im_brgc8,
+	       (uint)&(immr->im_brgc8),
+	       Daq_BRG_Get_Count(7),
+	       Daq_BRG_Get_ExtClk(7),
+	       Daq_BRG_Get_ExtClk_Description(7));
+    }
+    if (immr->im_brgc6 != 0) {
+        printf("\tbrgc6\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  LRCLK\n",
+	       immr->im_brgc6,
+	       (uint)&(immr->im_brgc6),
+	       Daq_BRG_Get_Count(5),
+	       Daq_BRG_Get_ExtClk(5),
+	       Daq_BRG_Get_ExtClk_Description(5));
+    }
+    if (immr->im_brgc1 != 0) {
+        printf("\tbrgc1\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SMC1\n",
+	       immr->im_brgc1,
+	       (uint)&(immr->im_brgc1),
+	       Daq_BRG_Get_Count(0),
+	       Daq_BRG_Get_ExtClk(0),
+	       Daq_BRG_Get_ExtClk_Description(0));
+    }
+    if (immr->im_brgc2 != 0) {
+        printf("\tbrgc2\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SMC2\n",
+	       immr->im_brgc2,
+	       (uint)&(immr->im_brgc2),
+	       Daq_BRG_Get_Count(1),
+	       Daq_BRG_Get_ExtClk(1),
+	       Daq_BRG_Get_ExtClk_Description(1));
+    }
+    if (immr->im_brgc3 != 0) {
+        printf("\tbrgc3\t0x%08x @ 0x%08x, %5d count, %d extc, %8s,  SCC1\n",
+	       immr->im_brgc3,
+	       (uint)&(immr->im_brgc3),
+	       Daq_BRG_Get_Count(2),
+	       Daq_BRG_Get_ExtClk(2),
+	       Daq_BRG_Get_ExtClk_Description(2));
+    }
+    if (immr->im_brgc5 != 0) {
+        printf("\tbrgc5\t0x%08x @ 0x%08x, %5d count, %d extc, %8s\n",
+	       immr->im_brgc5,
+	       (uint)&(immr->im_brgc5),
+	       Daq_BRG_Get_Count(4),
+	       Daq_BRG_Get_ExtClk(4),
+	       Daq_BRG_Get_ExtClk_Description(4));
+    }
+    if (immr->im_brgc7 != 0) {
+        printf("\tbrgc7\t0x%08x @ 0x%08x, %5d count, %d extc, %8s\n",
+	       immr->im_brgc7,
+	       (uint)&(immr->im_brgc7),
+	       Daq_BRG_Get_Count(6),
+	       Daq_BRG_Get_ExtClk(6),
+	       Daq_BRG_Get_ExtClk_Description(6));
+    }
+
+#   ifdef RUN_SCLK_ON_BRG_INT
+        mclk_divisor = Daq_BRG_Rate(MCLK_BRG) / Daq_BRG_Rate(SCLK_BRG);
+#   else
+        mclk_divisor = Daq_BRG_Get_Count(SCLK_BRG);
+#   endif
+#   ifdef RUN_LRCLK_ON_BRG_INT
+        sclk_divisor = Daq_BRG_Rate(SCLK_BRG) / Daq_BRG_Rate(LRCLK_BRG);
+#   else
+        sclk_divisor = Daq_BRG_Get_Count(LRCLK_BRG);
+#   endif
+
+    printf("\nADC/DAC Clocking (%d/%d):\n", sclk_divisor, mclk_divisor);
+    printf("\tMCLK  %8d Hz, or %3dx SCLK, or %3dx LRCLK\n",
+	   Daq_BRG_Rate(MCLK_BRG),
+	   mclk_divisor,
+	   mclk_divisor * sclk_divisor);
+#   ifdef RUN_SCLK_ON_BRG_INT
+        printf("\tSCLK  %8d Hz, or %3dx LRCLK\n",
+	       Daq_BRG_Rate(SCLK_BRG),
+	       sclk_divisor);
+#   else
+        printf("\tSCLK  %8d Hz, or %3dx LRCLK\n",
+	       Daq_BRG_Rate(MCLK_BRG) / mclk_divisor,
+	       sclk_divisor);
+#   endif
+#   ifdef RUN_LRCLK_ON_BRG_INT
+        printf("\tLRCLK %8d Hz\n",
+	       Daq_BRG_Rate(LRCLK_BRG));
+#   else
+#       ifdef RUN_SCLK_ON_BRG_INT
+            printf("\tLRCLK %8d Hz\n",
+		   Daq_BRG_Rate(SCLK_BRG) / sclk_divisor);
+#       else
+            printf("\tLRCLK %8d Hz\n",
+		   Daq_BRG_Rate(MCLK_BRG) / (mclk_divisor * sclk_divisor));
+#       endif
+#   endif
+    printf("\n");
+}
diff --git a/board/sacsng/ioconfig.h b/board/sacsng/ioconfig.h
new file mode 100644
index 0000000..6857f99
--- /dev/null
+++ b/board/sacsng/ioconfig.h
@@ -0,0 +1,218 @@
+/*
+ * I/O Port configuration table
+ *
+ * If conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ */
+
+#ifdef SKIP
+#undef SKIP
+#endif
+
+#ifdef CONF
+#undef CONF
+#endif
+
+#ifdef DIN
+#undef DIN
+#endif
+
+#ifdef DOUT
+#undef DOUT
+#endif
+
+#ifdef GPIO
+#undef GPIO
+#endif
+
+#ifdef SPEC
+#undef SPEC
+#endif
+
+#ifdef ACTV
+#undef ACTV
+#endif
+
+#ifdef OPEN
+#undef OPEN
+#endif
+
+#define SKIP 0  /* SKIP over this port */
+#define CONF 1  /* CONFiguration the port */
+
+#define DIN  0  /* PDIRx 0: Direction IN  */
+#define DOUT 1  /* PDIRx 1: Direction OUT */
+
+#define GPIO 0  /* PPARx 0: General Purpose I/O */
+#define SPEC 1  /* PPARx 1: dedicated to a peripheral function, */
+                /*          i.e. the port has a SPECial use. */
+
+#define ACTV 0  /* PODRx 0: ACTiVely driven as an output */
+#define OPEN 1  /* PODRx 1: OPEN-drain driver */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+    /* Port A configuration */
+    {	/*	     conf  ppar  psor  pdir  podr  pdat */
+	/* PA31 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS8*        */
+	/* PA30 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS7*        */
+	/* PA29 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS6*        */
+	/* PA28 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS5*        */
+	/* PA27 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS4*        */
+	/* PA26 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS3*        */
+	/* PA25 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS2*        */
+	/* PA24 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* RODIS1*        */
+	/* PA23 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* ODIS_EN*       */
+	/* PA22 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* STLED2_EN*     */
+	/* PA21 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* STLED1_EN*     */
+	/* PA20 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* PLED3_EN*      */
+	/* PA19 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* PLED2_EN*      */
+        /* PA18 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* PLED1_EN*      */
+	/* PA17 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PA16 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* DAC_RST*       */
+	/* PA15 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* CH34SDATA_PU   */
+        /* PA14 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* CH12SDATA_PU   */
+        /* PA13 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* SLRCLK_EN*     */
+	/* PA12 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_4ACDC*    */
+	/* PA11 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_4TEDS*    */
+	/* PA10 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_4XTDS*    */
+	/* PA9  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_3ACDC*    */
+	/* PA8  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_3TEDS*    */
+	/* PA7  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_3XTDS*    */
+	/* PA6  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_2ACDC*    */
+	/* PA5  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_2TEDS*    */
+	/* PA4  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_2XTDS*    */
+	/* PA3  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PA2  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_1ACDC*    */
+	/* PA1  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* MTRX_1TEDS*    */
+	/* PA0  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }  /* MTRX_1XTDS*    */
+    },
+
+    /* Port B configuration */
+    {	/*	     conf  ppar  psor  pdir  podr  pdat */
+	/* PB31 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TX_ER */
+	/* PB30 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RX_DV */
+	/* PB29 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* FCC2 MII_TX_EN */
+	/* PB28 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RX_ER */
+	/* PB27 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_COL   */
+	/* PB26 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_CRS   */
+	/* PB25 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD3  */
+	/* PB24 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD2  */
+	/* PB23 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD1  */
+	/* PB22 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* FCC2 MII_TXD0  */
+	/* PB21 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD0  */
+	/* PB20 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD1  */
+	/* PB19 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD2  */
+	/* PB18 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* FCC2 MII_RXD3  */
+	/* PB17 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB16 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB15 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB14 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RXDC1,   BSDATA_ADC12 */
+	/* PB13 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB12 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RSYNCC1, LRCLK  */
+	/* PB11 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1TXDD1,   RSDATA_DAC12 */
+	/* PB10 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RXDD1,   BSDATA_ADC34 */
+	/* PB9  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB8  */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* L1RSYNCD1, LRCLK  */
+	/* PB7  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PB6  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* XCITE_SHDN     */
+	/* PB5  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* TRIGGER        */
+	/* PB4  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* ARM            */
+	/* PB3  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PB2  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PB1  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PB0  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }  /* pin doesn't exist */
+    },
+
+    /* Port C */
+    {	/*	      conf ppar  psor  pdir  podr  pdat */
+	/* PC31 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC30 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC29 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK3,  MCLK    */
+	/* PC28 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* TOUT2*         */
+#ifdef QQQ
+	/* PC28 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TOUT2*         */
+#endif
+	/* PC27 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK5,  SCLK    */
+	/* PC26 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC25 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK7,  SCLK    */
+	/* PC24 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC23 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK9,  MCLK    */
+	/* PC22 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC21 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* BRGO6 (LRCLK)  */
+	/* PC20 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC19 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK13, MII_RXCLK  */
+	/* PC18 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* CLK14, MII_TXCLK  */
+        /* PC17 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* BRGO8 (SCLK)   */
+	/* PC16 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC15 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* SMC2_TX        */
+	/* PC14 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC13 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC12 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TDM_STRB3      */
+	/* PC11 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC10 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* TDM_STRB4      */
+	/* PC9  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BPDIS_IN3      */
+	/* PC8  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BPDIS_IN2      */
+	/* PC7  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BPDIS_IN1      */
+	/* PC6  */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PC5  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BTST_IN2*      */
+        /* PC4  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* BTST_IN1*      */
+	/* PC3  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* MUSH_STAT      */
+	/* PC2  */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* OUTDRV_STAT    */
+	/* PC1  */ { CONF, GPIO,   0,  DOUT, OPEN,   1   }, /* PHY_MDIO       */
+        /* PC0  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* PHY_MDC        */
+    },
+
+    /* Port D */
+    {	/*	      conf ppar  psor  pdir  podr  pdat */
+	/* PD31 */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* SCC1_RX        */
+	/* PD30 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* SCC1_TX        */
+	/* PD29 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD28 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD27 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD26 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD25 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD24 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD23 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD22 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD21 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD20 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* SPI_ADC_CS*    */
+	/* PD19 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* SPI_DAC_CS*    */
+#if defined(CONFIG_SOFT_SPI)
+	/* PD18 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* SPI_CLK        */
+	/* PD17 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* SPI_MOSI       */
+	/* PD16 */ { CONF, GPIO,   0,  DIN,  ACTV,   0   }, /* SPI_MISO       */
+#else
+	/* PD18 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* SPI_CLK        */
+	/* PD17 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* SPI_MOSI       */
+	/* PD16 */ { CONF, SPEC,   1,  DIN,  ACTV,   0   }, /* SPI_MISO       */
+#endif
+#if defined(CONFIG_SOFT_I2C)
+	/* PD15 */ { CONF, GPIO,   0,  DOUT, OPEN,   1   }, /* I2C_SDA        */
+	/* PD14 */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* I2C_SCL        */
+#else
+#if defined(CONFIG_HARD_I2C)
+	/* PD15 */ { CONF, SPEC,   1,  DIN,  OPEN,   0   }, /* I2C_SDA        */
+	/* PD14 */ { CONF, SPEC,   1,  DIN,  OPEN,   0   }, /* I2C_SCL        */
+#else /* normal I/O port pins */
+	/* PD15 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* I2C_SDA        */
+	/* PD14 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* I2C_SCL        */
+#endif
+#endif
+	/* PD13 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TDM_STRB1      */
+	/* PD12 */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* TDM_STRB2      */
+	/* PD11 */ { CONF, GPIO,   0,  DOUT, ACTV,   0   }, /* N/C            */
+	/* PD10 */ { CONF, SPEC,   1,  DOUT, ACTV,   0   }, /* BRGO4 (MCLK)   */
+	/* PD9  */ { CONF, SPEC,   0,  DOUT, ACTV,   0   }, /* SMC1_TX        */
+	/* PD8  */ { CONF, SPEC,   0,  DIN,  ACTV,   0   }, /* SMC1_RX        */
+	/* PD7  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* N/C            */
+	/* PD6  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* N/C            */
+	/* PD5  */ { CONF, GPIO,   0,  DOUT, ACTV,   1   }, /* N/C            */
+	/* PD4  */ { CONF, SPEC,   1,  DOUT, ACTV,   1   }, /* SMC2_RX        */
+	/* PD3  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PD2  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PD1  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }, /* pin doesn't exist */
+	/* PD0  */ { SKIP, GPIO,   0,  DIN,  ACTV,   0   }  /* pin doesn't exist */
+    }
+};
+
diff --git a/board/sandpoint/sandpoint.c b/board/sandpoint/sandpoint.c
new file mode 100644
index 0000000..8d385f7
--- /dev/null
+++ b/board/sandpoint/sandpoint.c
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * 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 <pci.h>
+
+int checkboard (void)
+{
+	/*TODO: Check processor type */
+
+	puts (	"Board: Sandpoint "
+#ifdef CONFIG_MPC8240
+		"8240"
+#endif
+#ifdef CONFIG_MPC8245
+		"8245"
+#endif
+		" Unity ##Test not implemented yet##\n");
+	return 0;
+}
+
+#if 0 	/* NOT USED */
+int checkflash (void)
+{
+	/* TODO: XXX XXX XXX */
+	printf ("## Test not implemented yet ##\n");
+
+	return (0);
+}
+#endif
+
+long int initdram (int board_type)
+{
+	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;
+}
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_sandpoint_config_table[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x10, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET1_IOADDR,
+				       PCI_ENET1_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ }
+};
+#endif
+
+struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_sandpoint_config_table,
+#endif
+};
+
+void pci_init(void)
+{
+	pci_mpc824x_init(&hose);
+}
diff --git a/board/shannon/u-boot.lds b/board/shannon/u-boot.lds
new file mode 100644
index 0000000..f4b0ade
--- /dev/null
+++ b/board/shannon/u-boot.lds
@@ -0,0 +1,53 @@
+/*
+ * (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/sa1100/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/siemens/CCM/ccm.c b/board/siemens/CCM/ccm.c
new file mode 100644
index 0000000..079f38f
--- /dev/null
+++ b/board/siemens/CCM/ccm.c
@@ -0,0 +1,440 @@
+/*
+ * (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
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <commproc.h>
+#include <command.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+void can_driver_enable (void);
+void can_driver_disable (void);
+
+int fpga_init(void);
+
+/* ------------------------------------------------------------------------- */
+
+#define	_NOT_USED_	0xFFFFFFFF
+
+const uint sdram_table[] =
+{
+	/*
+	 * Single Read. (Offset 0 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
+	0x1FF5FC47, /* last */
+	/*
+	 * SDRAM Initialization (offset 5 in UPMA RAM)
+	 *
+	 * This is no UPM entry point. The following definition uses
+	 * the remaining space to establish an initialization
+	 * sequence, which is executed by a RUN command.
+	 *
+	 */
+		    0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
+	/*
+	 * Burst Read. (Offset 8 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
+	0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Single Write. (Offset 18 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEABBC00, 0x01B27C04, 0x1FF5FC47, /* last */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Burst Write. (Offset 20 in UPMA RAM)
+	 */
+	0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
+	0xF0AFFC00, 0xE1BAFC04, 0x1FF5FC47, /* last */
+					    _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Refresh  (Offset 30 in UPMA RAM)
+	 */
+	0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
+	0xFFFFFC84, 0xFFFFFC07, /* last */
+				_NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Exception. (Offset 3c in UPMA RAM)
+	 */
+	0x7FFFFC07, /* last */
+		    _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Always return 1 (no second DRAM bank since based on TQM8xxL module)
+ */
+
+int checkboard (void)
+{
+    unsigned char *s;
+    unsigned char buf[64];
+
+    s = (getenv_r ("serial#", buf, sizeof(buf)) > 0) ? buf : NULL;
+
+    puts ("Board: Siemens CCM");
+
+    if (s) {
+	    puts (" (");
+
+	    for (; *s; ++s) {
+		if (*s == ' ')
+		    break;
+		putc (*s);
+	    }
+	    putc (')');
+    }
+
+    putc ('\n');
+
+    return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * If Power-On-Reset switch off the Red and Green LED: At reset, the
+ * data direction registers are cleared and must therefore be restored.
+ */
+#define RSR_CSRS	0x08000000
+
+int power_on_reset(void)
+{
+    /* Test Reset Status Register */
+    return ((volatile immap_t *)CFG_IMMR)->im_clkrst.car_rsr & RSR_CSRS ? 0:1;
+}
+
+#define PB_LED_GREEN	0x10000		/* red LED is on PB.15 */
+#define PB_LED_RED	0x20000		/* red LED is on PB.14 */
+#define PB_LEDS		(PB_LED_GREEN | PB_LED_RED);
+
+static void init_leds (void)
+{
+    volatile immap_t *immap  = (immap_t *)CFG_IMMR;
+
+    immap->im_cpm.cp_pbpar &= ~PB_LEDS;
+    immap->im_cpm.cp_pbodr &= ~PB_LEDS;
+    immap->im_cpm.cp_pbdir |=  PB_LEDS;
+    /* Check stop reset status */
+    if (power_on_reset()) {
+	    immap->im_cpm.cp_pbdat &= ~PB_LEDS;
+    }
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+    long int size8, size9;
+    long int size = 0;
+    unsigned long reg;
+
+    upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+    /*
+     * Preliminary prescaler for refresh (depends on number of
+     * banks): This value is selected for four cycles every 62.4 us
+     * with two SDRAM banks or four cycles every 31.2 us with one
+     * bank. It will be adjusted after memory sizing.
+     */
+    memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
+
+    memctl->memc_mar  = 0x00000088;
+
+    /*
+     * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
+     * preliminary addresses - these have to be modified after the
+     * SDRAM size has been determined.
+     */
+    memctl->memc_or2 = CFG_OR2_PRELIM;
+    memctl->memc_br2 = CFG_BR2_PRELIM;
+
+    memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+    udelay(200);
+
+    /* perform SDRAM initializsation sequence */
+
+    memctl->memc_mcr  = 0x80004105;	/* SDRAM bank 0 */
+    udelay(1);
+    memctl->memc_mcr  = 0x80004230;	/* SDRAM bank 0 - execute twice */
+    udelay(1);
+
+    memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */
+
+    udelay (1000);
+
+    /*
+     * Check Bank 0 Memory Size for re-configuration
+     *
+     * try 8 column mode
+     */
+    size8 = dram_size (CFG_MAMR_8COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
+
+    udelay (1000);
+
+    /*
+     * try 9 column mode
+     */
+    size9 = dram_size (CFG_MAMR_9COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
+
+    if (size8 < size9) {		/* leave configuration at 9 columns	*/
+	size = size9;
+/*	debug ("SDRAM in 9 column mode: %ld MB\n", size >> 20);	*/
+    } else {				/* back to 8 columns			*/
+	size = size8;
+	memctl->memc_mamr = CFG_MAMR_8COL;
+	udelay(500);
+/*	debug ("SDRAM in 8 column mode: %ld MB\n", size >> 20);	*/
+    }
+
+    udelay (1000);
+
+    /*
+     * Adjust refresh rate depending on SDRAM type
+     * For types > 128 MBit leave it at the current (fast) rate
+     */
+    if (size < 0x02000000) {
+	/* reduce to 15.6 us (62.4 us / quad) */
+	memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
+	udelay(1000);
+    }
+
+    /*
+     * Final mapping
+     */
+
+    memctl->memc_or2 = ((-size) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+    memctl->memc_br2 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+
+    /* adjust refresh rate depending on SDRAM type, one bank */
+    reg = memctl->memc_mptpr;
+    reg >>= 1;	/* reduce to CFG_MPTPR_1BK_8K / _4K */
+    memctl->memc_mptpr = reg;
+
+    can_driver_enable ();
+    init_leds ();
+
+    udelay(10000);
+
+    return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Warning - both the PUMA load mode and the CAN driver use UPM B,
+ * so make sure only one of both is active.
+ */
+void can_driver_enable (void)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+    /* Initialize MBMR */
+    memctl->memc_mbmr = MAMR_GPL_B4DIS;	/* GPL_B4 ouput line Disable */
+
+    /* Initialize UPMB for CAN: single read */
+    memctl->memc_mdr = 0xFFFFC004;
+    memctl->memc_mcr = 0x0100 | UPMB;
+
+    memctl->memc_mdr = 0x0FFFD004;
+    memctl->memc_mcr = 0x0101 | UPMB;
+
+    memctl->memc_mdr = 0x0FFFC000;
+    memctl->memc_mcr = 0x0102 | UPMB;
+
+    memctl->memc_mdr = 0x3FFFC004;
+    memctl->memc_mcr = 0x0103 | UPMB;
+
+    memctl->memc_mdr = 0xFFFFDC05;
+    memctl->memc_mcr = 0x0104 | UPMB;
+
+    /* Initialize UPMB for CAN: single write */
+    memctl->memc_mdr = 0xFFFCC004;
+    memctl->memc_mcr = 0x0118 | UPMB;
+
+    memctl->memc_mdr = 0xCFFCD004;
+    memctl->memc_mcr = 0x0119 | UPMB;
+
+    memctl->memc_mdr = 0x0FFCC000;
+    memctl->memc_mcr = 0x011A | UPMB;
+
+    memctl->memc_mdr = 0x7FFCC004;
+    memctl->memc_mcr = 0x011B | UPMB;
+
+    memctl->memc_mdr = 0xFFFDCC05;
+    memctl->memc_mcr = 0x011C | UPMB;
+
+    /* Initialize OR3 / BR3 for CAN Bus Controller */
+    memctl->memc_or3 = CFG_OR3_CAN;
+    memctl->memc_br3 = CFG_BR3_CAN;
+}
+
+void can_driver_disable (void)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+    /* Reset OR3 / BR3 to disable  CAN Bus Controller */
+    memctl->memc_br3 = 0;
+    memctl->memc_or3 = 0;
+
+    memctl->memc_mbmr = 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base, long int maxsize)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+    volatile long int	 *addr;
+    ulong		  cnt, val;
+    ulong		  save[32];	/* to make test non-destructive */
+    unsigned char	  i = 0;
+
+    memctl->memc_mamr = mamr_value;
+
+    for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+	addr = base + cnt;	/* pointer arith! */
+
+	save[i++] = *addr;
+	*addr = ~cnt;
+    }
+
+    /* write 0 to base address */
+    addr = base;
+    save[i] = *addr;
+    *addr = 0;
+
+    /* check at base address */
+    if ((val = *addr) != 0) {
+	*addr = save[i];
+	return (0);
+    }
+
+    for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
+	addr = base + cnt;	/* pointer arith! */
+
+	val = *addr;
+	*addr = save[--i];
+
+	if (val != (~cnt)) {
+	    return (cnt * sizeof(long));
+	}
+    }
+    return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define	ETH_CFG_BITS	(CFG_PB_ETH_CFG1 | CFG_PB_ETH_CFG2  | CFG_PB_ETH_CFG3 )
+
+#define ETH_ALL_BITS	(ETH_CFG_BITS | CFG_PB_ETH_POWERDOWN)
+
+void	reset_phy(void)
+{
+	immap_t *immr = (immap_t *)CFG_IMMR;
+	ulong value;
+
+	/* Configure all needed port pins for GPIO */
+#if CFG_ETH_MDDIS_VALUE
+	immr->im_ioport.iop_padat |=   CFG_PA_ETH_MDDIS;
+#else
+	immr->im_ioport.iop_padat &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);	/* Set low */
+#endif
+	immr->im_ioport.iop_papar &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);	/* GPIO */
+	immr->im_ioport.iop_paodr &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);	/* active output */
+	immr->im_ioport.iop_padir |=   CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET;	/* output */
+
+	immr->im_cpm.cp_pbpar &= ~(ETH_ALL_BITS);	/* GPIO */
+	immr->im_cpm.cp_pbodr &= ~(ETH_ALL_BITS);	/* active output */
+
+	value  = immr->im_cpm.cp_pbdat;
+
+	/* Assert Powerdown and Reset signals */
+	value |=  CFG_PB_ETH_POWERDOWN;
+
+	/* PHY configuration includes MDDIS and CFG1 ... CFG3 */
+#if CFG_ETH_CFG1_VALUE
+	value |=   CFG_PB_ETH_CFG1;
+#else
+	value &= ~(CFG_PB_ETH_CFG1);
+#endif
+#if CFG_ETH_CFG2_VALUE
+	value |=   CFG_PB_ETH_CFG2;
+#else
+	value &= ~(CFG_PB_ETH_CFG2);
+#endif
+#if CFG_ETH_CFG3_VALUE
+	value |=   CFG_PB_ETH_CFG3;
+#else
+	value &= ~(CFG_PB_ETH_CFG3);
+#endif
+
+	/* Drive output signals to initial state */
+	immr->im_cpm.cp_pbdat  = value;
+	immr->im_cpm.cp_pbdir |= ETH_ALL_BITS;
+	udelay (10000);
+
+	/* De-assert Ethernet Powerdown */
+	immr->im_cpm.cp_pbdat &= ~(CFG_PB_ETH_POWERDOWN); /* Enable PHY power */
+	udelay (10000);
+
+	/* de-assert RESET signal of PHY */
+	immr->im_ioport.iop_padat |= CFG_PA_ETH_RESET;
+	udelay (1000);
+}
+
+
+int misc_init_r (void)
+{
+	fpga_init();
+	return (0);
+}
+/* ------------------------------------------------------------------------- */
diff --git a/board/siemens/CCM/fpga_ccm.c b/board/siemens/CCM/fpga_ccm.c
new file mode 100644
index 0000000..292387b
--- /dev/null
+++ b/board/siemens/CCM/fpga_ccm.c
@@ -0,0 +1,170 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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>
+#include <commproc.h>
+#include <common.h>
+
+#include "../common/fpga.h"
+
+fpga_t fpga_list[] = {
+    { "PUMA" , PUMA_CONF_BASE ,
+      CFG_PC_PUMA_INIT , CFG_PC_PUMA_PROG , CFG_PC_PUMA_DONE  }
+};
+int fpga_count = sizeof(fpga_list) / sizeof(fpga_t);
+
+void can_driver_enable (void);
+void can_driver_disable (void);
+
+#define	_NOT_USED_	0xFFFFFFFF
+
+/*
+ * PUMA access using UPM B
+ */
+const uint puma_table[] =
+{
+	/*
+	 * Single Read. (Offset 0 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_,
+	/*
+	 * Precharge and MRS
+	 */
+		    _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Burst Read. (Offset 8 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Single Write. (Offset 18 in UPM RAM)
+	 */
+	0x0FFCF804, 0x0FFCF400, 0x3FFDFC47, /* last */
+					    _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Burst Write. (Offset 20 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Refresh  (Offset 30 in UPM RAM)
+	 */
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+	/*
+	 * Exception. (Offset 3c in UPM RAM)
+	 */
+	0x7FFFFC07, /* last */
+		    _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+
+ulong fpga_control (fpga_t* fpga, int cmd)
+{
+    volatile immap_t     *immr  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immr->im_memctl;
+
+    switch (cmd) {
+    case FPGA_INIT_IS_HIGH:
+	immr->im_ioport.iop_pcdir &= ~fpga->init_mask; /* input */
+	return (immr->im_ioport.iop_pcdat & fpga->init_mask) ? 1:0;
+
+    case FPGA_INIT_SET_LOW:
+	immr->im_ioport.iop_pcdir |=  fpga->init_mask; /* output */
+	immr->im_ioport.iop_pcdat &= ~fpga->init_mask;
+	break;
+
+    case FPGA_INIT_SET_HIGH:
+	immr->im_ioport.iop_pcdir |= fpga->init_mask; /* output */
+	immr->im_ioport.iop_pcdat |= fpga->init_mask;
+	break;
+
+    case FPGA_PROG_SET_LOW:
+	immr->im_ioport.iop_pcdat &= ~fpga->prog_mask;
+	break;
+
+    case FPGA_PROG_SET_HIGH:
+	immr->im_ioport.iop_pcdat |= fpga->prog_mask;
+	break;
+
+    case FPGA_DONE_IS_HIGH:
+	return (immr->im_ioport.iop_pcdat & fpga->done_mask) ? 1:0;
+
+    case FPGA_READ_MODE:
+	/* disable FPGA in memory controller */
+	memctl->memc_br4 = 0;
+	memctl->memc_or4 = PUMA_CONF_OR_READ;
+	memctl->memc_br4 = PUMA_CONF_BR_READ;
+
+	/* (re-) enable CAN drivers */
+	can_driver_enable ();
+
+	break;
+
+    case FPGA_LOAD_MODE:
+	/* disable FPGA in memory controller */
+	memctl->memc_br4 = 0;
+	/*
+	 * We must disable the CAN drivers first because
+	 * they use UPM B, too.
+	 */
+	can_driver_disable ();
+	/*
+	 * Configure UPMB for FPGA
+	 */
+	upmconfig(UPMB,(uint *)puma_table,sizeof(puma_table)/sizeof(uint));
+	memctl->memc_or4 = PUMA_CONF_OR_LOAD;
+	memctl->memc_br4 = PUMA_CONF_BR_LOAD;
+	break;
+
+    case FPGA_GET_ID:
+	return *(volatile ulong *)fpga->conf_base;
+
+    case FPGA_INIT_PORTS:
+	immr->im_ioport.iop_pcpar &= ~fpga->init_mask; /* INIT I/O */
+	immr->im_ioport.iop_pcso  &= ~fpga->init_mask;
+	immr->im_ioport.iop_pcdir &= ~fpga->init_mask;
+
+	immr->im_ioport.iop_pcpar &= ~fpga->prog_mask; /* PROG Output */
+	immr->im_ioport.iop_pcso  &= ~fpga->prog_mask;
+	immr->im_ioport.iop_pcdir |=  fpga->prog_mask;
+
+	immr->im_ioport.iop_pcpar &= ~fpga->done_mask; /* DONE Input */
+	immr->im_ioport.iop_pcso  &= ~fpga->done_mask;
+	immr->im_ioport.iop_pcdir &= ~fpga->done_mask;
+
+	break;
+
+    }
+    return 0;
+}
+
diff --git a/board/siemens/SCM/fpga_scm.c b/board/siemens/SCM/fpga_scm.c
new file mode 100644
index 0000000..3b93794
--- /dev/null
+++ b/board/siemens/SCM/fpga_scm.c
@@ -0,0 +1,104 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <mpc8260.h>
+#include <common.h>
+#include "../common/fpga.h"
+
+fpga_t fpga_list[] = {
+    { "FIOX" , CFG_FIOX_BASE ,
+      CFG_PD_FIOX_INIT , CFG_PD_FIOX_PROG , CFG_PD_FIOX_DONE  },
+    { "FDOHM", CFG_FDOHM_BASE,
+      CFG_PD_FDOHM_INIT, CFG_PD_FDOHM_PROG, CFG_PD_FDOHM_DONE }
+};
+int fpga_count = sizeof(fpga_list) / sizeof(fpga_t);
+
+
+ulong fpga_control (fpga_t* fpga, int cmd)
+{
+    volatile immap_t *immr  = (immap_t *)CFG_IMMR;
+
+    switch (cmd) {
+    case FPGA_INIT_IS_HIGH:
+	immr->im_ioport.iop_pdird &= ~fpga->init_mask; /* input */
+	return (immr->im_ioport.iop_pdatd & fpga->init_mask) ? 1:0;
+
+    case FPGA_INIT_SET_LOW:
+	immr->im_ioport.iop_pdird |=  fpga->init_mask; /* output */
+	immr->im_ioport.iop_pdatd &= ~fpga->init_mask;
+	break;
+
+    case FPGA_INIT_SET_HIGH:
+	immr->im_ioport.iop_pdird |= fpga->init_mask; /* output */
+	immr->im_ioport.iop_pdatd |= fpga->init_mask;
+	break;
+
+    case FPGA_PROG_SET_LOW:
+	immr->im_ioport.iop_pdatd &= ~fpga->prog_mask;
+	break;
+
+    case FPGA_PROG_SET_HIGH:
+	immr->im_ioport.iop_pdatd |= fpga->prog_mask;
+	break;
+
+    case FPGA_DONE_IS_HIGH:
+	return (immr->im_ioport.iop_pdatd & fpga->done_mask) ? 1:0;
+
+    case FPGA_READ_MODE:
+	break;
+
+    case FPGA_LOAD_MODE:
+	break;
+
+    case FPGA_GET_ID:
+	if (fpga->conf_base == CFG_FIOX_BASE) {
+	    ulong ver = *(volatile ulong *)(fpga->conf_base + 0x10);
+	    return ((ver >> 10) & 0xf) + ((ver >> 2) & 0xf0);
+	}
+	else if (fpga->conf_base == CFG_FDOHM_BASE) {
+	    return (*(volatile ushort *)fpga->conf_base) & 0xff;
+	}
+	else {
+	    return *(volatile ulong *)fpga->conf_base;
+	}
+
+    case FPGA_INIT_PORTS:
+	immr->im_ioport.iop_ppard &= ~fpga->init_mask; /* INIT I/O */
+	immr->im_ioport.iop_psord &= ~fpga->init_mask;
+	immr->im_ioport.iop_pdird &= ~fpga->init_mask;
+
+	immr->im_ioport.iop_ppard &= ~fpga->prog_mask; /* PROG Output */
+	immr->im_ioport.iop_psord &= ~fpga->prog_mask;
+	immr->im_ioport.iop_pdird |=  fpga->prog_mask;
+
+	immr->im_ioport.iop_ppard &= ~fpga->done_mask; /* DONE Input */
+	immr->im_ioport.iop_psord &= ~fpga->done_mask;
+	immr->im_ioport.iop_pdird &= ~fpga->done_mask;
+
+	break;
+
+    }
+    return 0;
+}
diff --git a/board/siemens/common/README b/board/siemens/common/README
new file mode 100644
index 0000000..d781903
--- /dev/null
+++ b/board/siemens/common/README
@@ -0,0 +1,27 @@
+CCM/SCM-Ergaenzungen fuer U-Boot und Linux:
+-------------------------------------------
+
+Es gibt nun ein gemeinsames Kommando zum Laden der FPGAs:
+
+  => help fpga
+  fpga fpga status [name] - print FPGA status
+  fpga reset  [name] - reset FPGA
+  fpga load [name] addr - load FPGA configuration data
+
+Der Name kann beim CCM-Module auch weggelassen werden.
+Die Laengenangabe und damit "puma_len" ist nicht mehr
+noetig:
+
+  => fpga load puma 40600000
+  FPGA load PUMA: addr 40600000: (00000005)... done
+
+Die MTD-Partitionierung kann nun mittels "bootargs" ueber-
+geben werden:
+
+  => printenv addmtd
+  addmtd=setenv bootargs $(bootargs)
+    mtdparts=0:256k(U-Boot)ro,768k(Kernel),-(Rest)\;1:-(myJFFS2)
+
+Die Portierung auf SMC ist natuerlich noch nicht getestet.
+
+Wolfgang Grandegger (04.06.2002)
diff --git a/board/siemens/common/fpga.c b/board/siemens/common/fpga.c
new file mode 100644
index 0000000..a17de5a
--- /dev/null
+++ b/board/siemens/common/fpga.c
@@ -0,0 +1,358 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Grandegger, DENX Software Engineering, wg@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 <command.h>
+#include <linux/ctype.h>
+#include <common.h>
+#include <cmd_boot.h>
+#include <cmd_bsp.h>
+
+#include "fpga.h"
+
+int  power_on_reset(void);
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+
+static int fpga_get_version(fpga_t* fpga, char* name)
+{
+    char vname[12];
+    /*
+     * Net-list string format:
+     *     "vvvvvvvvddddddddn...".
+     *     Version Date    Name
+     *     "0000000322042002PUMA" = PUMA version 3 from 22.04.2002.
+     */
+    if (strlen(name) < (16 + strlen(fpga->name)))
+	goto failure;
+    /* Check FPGA name */
+    if (strcmp(&name[16], fpga->name) != 0)
+	goto failure;
+    /* Get version number */
+    memcpy(vname, name, 8);
+    vname[8] = '\0';
+    return simple_strtoul(vname, NULL, 16);
+
+ failure:
+    printf("Image name %s is invalid\n", name);
+    return -1;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+static fpga_t* fpga_get(char* fpga_name)
+{
+    char name[FPGA_NAME_LEN];
+    int i;
+
+    if (strlen(fpga_name) >= FPGA_NAME_LEN)
+	goto failure;
+    for (i = 0; i < strlen(fpga_name); i++)
+	name[i] = toupper(fpga_name[i]);
+    name[i] = '\0';
+    for (i = 0; i < fpga_count; i++) {
+	if (strcmp(name, fpga_list[i].name) == 0)
+	    return &fpga_list[i];
+    }
+ failure:
+    printf("FPGA: name %s is invalid\n", fpga_name);
+    return NULL;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+static void fpga_status (fpga_t* fpga)
+{
+    /* Check state */
+    if (fpga_control(fpga, FPGA_DONE_IS_HIGH))
+	printf ("%s is loaded (%08lx)\n",
+		fpga->name, fpga_control(fpga, FPGA_GET_ID));
+    else
+	printf ("%s is NOT loaded\n", fpga->name);
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+#define FPGA_RESET_TIMEOUT 100 /* = 10 ms */
+
+static int fpga_reset (fpga_t* fpga)
+{
+    int i;
+
+    /* Set PROG to low and wait til INIT goes low */
+    fpga_control(fpga, FPGA_PROG_SET_LOW);
+    for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
+	udelay (100);
+	if (!fpga_control(fpga, FPGA_INIT_IS_HIGH))
+	    break;
+    }
+    if (i == FPGA_RESET_TIMEOUT)
+	goto failure;
+
+    /* Set PROG to high and wait til INIT goes high */
+    fpga_control(fpga, FPGA_PROG_SET_HIGH);
+    for (i = 0; i < FPGA_RESET_TIMEOUT; i++) {
+	udelay (100);
+	if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
+	    break;
+    }
+    if (i == FPGA_RESET_TIMEOUT)
+	goto failure;
+
+    return 0;
+ failure:
+    return 1;
+}
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+#define FPGA_LOAD_TIMEOUT 100 /* = 10 ms */
+
+static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
+{
+    volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
+    image_header_t hdr;
+    ulong len, checksum;
+    uchar *data = (uchar *)&hdr;
+    char *s, msg[32];
+    int verify, i;
+
+    /*
+     * Check the image header and data of the net-list
+     */
+    memcpy (&hdr, (char *)addr, sizeof(image_header_t));
+
+    if (hdr.ih_magic != IH_MAGIC) {
+	strcpy (msg, "Bad Image Magic Number");
+        goto failure;
+    }
+
+    len  = sizeof(image_header_t);
+
+    checksum = hdr.ih_hcrc;
+    hdr.ih_hcrc = 0;
+
+    if (crc32 (0, data, len) != checksum) {
+	strcpy (msg, "Bad Image Header CRC");
+	goto failure;
+    }
+
+    data = (uchar*)(addr + sizeof(image_header_t));
+    len  = hdr.ih_size;
+
+    s = getenv ("verify");
+    verify = (s && (*s == 'n')) ? 0 : 1;
+    if (verify) {
+	if (crc32 (0, data, len) != hdr.ih_dcrc) {
+	    strcpy (msg, "Bad Image Data CRC");
+	    goto failure;
+	}
+    }
+
+    if (checkall && fpga_get_version(fpga, hdr.ih_name) < 0)
+	return 1;
+
+    /* align length */
+    if (len & 1)
+	++len;
+
+    /*
+     * Reset FPGA and wait for completion
+     */
+    if (fpga_reset(fpga)) {
+	strcpy (msg, "Reset Timeout");
+	goto failure;
+    }
+
+    printf ("(%s)... ", hdr.ih_name);
+    /*
+     * Copy data to FPGA
+     */
+    fpga_control (fpga, FPGA_LOAD_MODE);
+    while (len--) {
+	*fpga_addr = *data++;
+    }
+    fpga_control (fpga, FPGA_READ_MODE);
+
+    /*
+     * Wait for completion and check error status if timeout
+     */
+    for (i = 0; i < FPGA_LOAD_TIMEOUT; i++) {
+	udelay (100);
+	if (fpga_control (fpga, FPGA_DONE_IS_HIGH))
+	    break;
+    }
+    if (i == FPGA_LOAD_TIMEOUT) {
+	if (fpga_control(fpga, FPGA_INIT_IS_HIGH))
+	    strcpy(msg, "Invalid Size");
+	else
+	    strcpy(msg, "CRC Error");
+	goto failure;
+    }
+
+    printf("done\n");
+    return 0;
+
+ failure:
+
+    printf("ERROR: %s\n", msg);
+    return 1;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+int do_fpga (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    ulong addr = 0;
+    int i;
+    fpga_t* fpga;
+
+    if (argc < 2)
+	goto failure;
+
+    if (strncmp(argv[1], "stat", 4) == 0) {		/* status */
+	if (argc == 2) {
+	    for (i = 0; i < fpga_count; i++) {
+		fpga_status (&fpga_list[i]);
+	    }
+	}
+	else if (argc == 3) {
+	    if ((fpga = fpga_get(argv[2])) == 0)
+		goto failure;
+	    fpga_status (fpga);
+	}
+	else
+	    goto failure;
+    }
+    else if (strcmp(argv[1],"load") == 0) {		/* load */
+	if (argc == 3 && fpga_count == 1) {
+	    fpga = &fpga_list[0];
+	}
+	else if (argc == 4) {
+	    if ((fpga = fpga_get(argv[2])) == 0)
+		goto failure;
+	}
+	else
+	    goto failure;
+
+	addr = simple_strtoul(argv[argc-1], NULL, 16);
+
+	printf ("FPGA load %s: addr %08lx: ",
+		fpga->name, addr);
+	fpga_load (fpga, addr, 1);
+
+    }
+    else if (strncmp(argv[1], "rese", 4) == 0) {	/* reset */
+	if (argc == 2 && fpga_count == 1) {
+	    fpga = &fpga_list[0];
+	}
+	else if (argc == 3) {
+	    if ((fpga = fpga_get(argv[2])) == 0)
+		goto failure;
+	}
+	else
+	    goto failure;
+
+	printf ("FPGA reset %s: ", fpga->name);
+	if (fpga_reset(fpga))
+	    printf ("ERROR: Timeout\n");
+	else
+	    printf ("done\n");
+    }
+    else
+	goto failure;
+
+    return 0;
+
+ failure:
+    printf ("Usage:\n%s\n", cmdtp->usage);
+    return 1;
+}
+
+#endif	/* CONFIG_COMMANDS & CFG_CMD_BSP */
+
+/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
+
+int fpga_init (void)
+{
+    ulong addr;
+    ulong new_id, old_id = 0;
+    image_header_t *hdr;
+    fpga_t* fpga;
+    int do_load, i, j;
+    char name[16], *s;
+
+    /*
+     *  Port setup for FPGA control
+     */
+    for (i = 0; i < fpga_count; i++) {
+	fpga_control(&fpga_list[i], FPGA_INIT_PORTS);
+    }
+
+    /*
+     * Load FPGA(s): a new net-list is loaded if the FPGA is
+     * empty, Power-on-Reset or the old one is not up-to-date
+     */
+    for (i = 0; i < fpga_count; i++) {
+	fpga = &fpga_list[i];
+	printf ("%s:  ", fpga->name);
+
+	for (j = 0; j < strlen(fpga->name); j++)
+	    name[j] = tolower(fpga->name[j]);
+	name[j] = '\0';
+	sprintf(name, "%s_addr", name);
+	addr = 0;
+	if ((s = getenv(name)) != NULL)
+	    addr = simple_strtoul(s, NULL, 16);
+
+	if (!addr) {
+	    printf ("env. variable %s undefined\n", name);
+	    return 1;
+	}
+
+	hdr = (image_header_t *)addr;
+	if ((new_id = fpga_get_version(fpga, hdr->ih_name)) == -1)
+	    return 1;
+
+	do_load = 1;
+
+	if (!power_on_reset() && fpga_control(fpga, FPGA_DONE_IS_HIGH)) {
+	    old_id = fpga_control(fpga, FPGA_GET_ID);
+	    if (new_id == old_id)
+		do_load = 0;
+	}
+
+	if (do_load) {
+	    printf ("loading ");
+	    fpga_load (fpga, addr, 0);
+	} else {
+	    printf ("loaded (%08lx)\n", old_id);
+	}
+    }
+
+    return 0;
+}
diff --git a/board/smdk2400/u-boot.lds b/board/smdk2400/u-boot.lds
new file mode 100644
index 0000000..8c9c218
--- /dev/null
+++ b/board/smdk2400/u-boot.lds
@@ -0,0 +1,54 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm920t/start.o	(.text)
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/smdk2410/smdk2410.c b/board/smdk2410/smdk2410.c
new file mode 100644
index 0000000..7f983ef
--- /dev/null
+++ b/board/smdk2410/smdk2410.c
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <s3c2410.h>
+
+/* ------------------------------------------------------------------------- */
+
+#define FCLK_SPEED 1
+
+#if FCLK_SPEED==0		/* Fout = 203MHz, Fin = 12MHz for Audio */
+#define M_MDIV	0xC3
+#define M_PDIV	0x4
+#define M_SDIV	0x1
+#elif FCLK_SPEED==1		/* Fout = 202.8MHz */
+#define M_MDIV	0xA1
+#define M_PDIV	0x3
+#define M_SDIV	0x1
+#endif
+
+#define USB_CLOCK 1
+
+#if USB_CLOCK==0
+#define U_M_MDIV	0xA1
+#define U_M_PDIV	0x3
+#define U_M_SDIV	0x1
+#elif USB_CLOCK==1
+#define U_M_MDIV	0x48
+#define U_M_PDIV	0x3
+#define U_M_SDIV	0x2
+#endif
+
+static inline void delay (unsigned long loops)
+{
+	__asm__ volatile ("1:\n"
+	  "subs %0, %1, #1\n"
+	  "bne 1b":"=r" (loops):"0" (loops));
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* to reduce PLL lock time, adjust the LOCKTIME register */
+	rLOCKTIME = 0xFFFFFF;
+
+	/* configure MPLL */
+	rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
+
+	/* some delay between MPLL and UPLL */
+	delay (4000);
+
+	/* configure UPLL */
+	rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
+
+	/* some delay between MPLL and UPLL */
+	delay (8000);
+
+	/* set up the I/O ports */
+	rGPACON = 0x007FFFFF;
+	rGPBCON = 0x00044555;
+	rGPBUP = 0x000007FF;
+	rGPCCON = 0xAAAAAAAA;
+	rGPCUP = 0x0000FFFF;
+	rGPDCON = 0xAAAAAAAA;
+	rGPDUP = 0x0000FFFF;
+	rGPECON = 0xAAAAAAAA;
+	rGPEUP = 0x0000FFFF;
+	rGPFCON = 0x000055AA;
+	rGPFUP = 0x000000FF;
+	rGPGCON = 0xFF95FFBA;
+	rGPGUP = 0x0000FFFF;
+	rGPHCON = 0x002AFAAA;
+	rGPHUP = 0x000007FF;
+
+	/* arch number of SMDK2410-Board */
+	gd->bd->bi_arch_number = 193;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = 0x30000100;
+
+	icache_enable();
+	dcache_enable();
+
+	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;
+
+	return 0;
+}
diff --git a/board/tqm8xx/flash.c b/board/tqm8xx/flash.c
new file mode 100644
index 0000000..2f74ccc
--- /dev/null
+++ b/board/tqm8xx/flash.c
@@ -0,0 +1,569 @@
+/*
+ * (C) Copyright 2000-2002
+ * 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>
+
+#ifndef	CFG_ENV_ADDR
+#define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET)
+#endif
+
+flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+	volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+	volatile memctl8xx_t *memctl = &immap->im_memctl;
+	unsigned long size_b0, size_b1;
+	int i;
+
+	/* Init: no FLASHes known */
+	for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+	}
+
+	/* Static FLASH Bank configuration here - FIXME XXX */
+
+	size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+			size_b0, size_b0<<20);
+	}
+
+	size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+
+	if (size_b1 > size_b0) {
+		printf ("## ERROR: "
+			"Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
+			size_b1, size_b1<<20,
+			size_b0, size_b0<<20
+		);
+		flash_info[0].flash_id	= FLASH_UNKNOWN;
+		flash_info[1].flash_id	= FLASH_UNKNOWN;
+		flash_info[0].sector_count	= -1;
+		flash_info[1].sector_count	= -1;
+		flash_info[0].size		= 0;
+		flash_info[1].size		= 0;
+		return (0);
+	}
+
+	/* Remap FLASH according to real size */
+	memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
+	memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
+
+	/* Re-do sizing to get full correct info */
+	size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+	/* monitor protection ON by default */
+	flash_protect(FLAG_PROTECT_SET,
+		      CFG_MONITOR_BASE,
+		      CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+		      &flash_info[0]);
+#endif
+
+#ifdef	CFG_ENV_IS_IN_FLASH
+	/* ENV protection ON by default */
+	flash_protect(FLAG_PROTECT_SET,
+		      CFG_ENV_ADDR,
+		      CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+		      &flash_info[0]);
+#endif
+
+	if (size_b1) {
+		memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
+		memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
+				    BR_MS_GPCM | BR_V;
+
+		/* Re-do sizing to get full correct info */
+		size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
+					  &flash_info[1]);
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+		/* monitor protection ON by default */
+		flash_protect(FLAG_PROTECT_SET,
+			      CFG_MONITOR_BASE,
+			      CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+			      &flash_info[1]);
+#endif
+
+#ifdef	CFG_ENV_IS_IN_FLASH
+		/* ENV protection ON by default */
+		flash_protect(FLAG_PROTECT_SET,
+			      CFG_ENV_ADDR,
+			      CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+			      &flash_info[1]);
+#endif
+	} else {
+		memctl->memc_br1 = 0;		/* invalidate bank */
+
+		flash_info[1].flash_id = FLASH_UNKNOWN;
+		flash_info[1].sector_count = -1;
+	}
+
+	flash_info[0].size = size_b0;
+	flash_info[1].size = size_b1;
+
+	return (size_b0 + size_b1);
+}
+
+/*-----------------------------------------------------------------------
+ */
+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;
+	default:		printf ("Unknown Vendor ");	break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	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;
+	default:		printf ("Unknown Chip Type\n");
+				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");
+	return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+	short i;
+	ulong value;
+	ulong base = (ulong)addr;
+
+	/* Write auto select command: read Manufacturer ID */
+	addr[0x0555] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+	addr[0x0555] = 0x00900090;
+
+	value = addr[0];
+
+	switch (value) {
+	case AMD_MANUFACT:
+		info->flash_id = FLASH_MAN_AMD;
+		break;
+	case FUJ_MANUFACT:
+		info->flash_id = FLASH_MAN_FUJ;
+		break;
+	default:
+		info->flash_id = FLASH_UNKNOWN;
+		info->sector_count = 0;
+		info->size = 0;
+		return (0);			/* no or unknown flash	*/
+	}
+
+	value = addr[1];			/* device ID		*/
+
+	switch (value) {
+	case AMD_ID_LV400T:
+		info->flash_id += FLASH_AM400T;
+		info->sector_count = 11;
+		info->size = 0x00100000;
+		break;				/* => 1 MB		*/
+
+	case AMD_ID_LV400B:
+		info->flash_id += FLASH_AM400B;
+		info->sector_count = 11;
+		info->size = 0x00100000;
+		break;				/* => 1 MB		*/
+
+	case AMD_ID_LV800T:
+		info->flash_id += FLASH_AM800T;
+		info->sector_count = 19;
+		info->size = 0x00200000;
+		break;				/* => 2 MB		*/
+
+	case AMD_ID_LV800B:
+		info->flash_id += FLASH_AM800B;
+		info->sector_count = 19;
+		info->size = 0x00200000;
+		break;				/* => 2 MB		*/
+
+	case AMD_ID_LV160T:
+		info->flash_id += FLASH_AM160T;
+		info->sector_count = 35;
+		info->size = 0x00400000;
+		break;				/* => 4 MB		*/
+
+	case AMD_ID_LV160B:
+		info->flash_id += FLASH_AM160B;
+		info->sector_count = 35;
+		info->size = 0x00400000;
+		break;				/* => 4 MB		*/
+	case AMD_ID_LV320T:
+		info->flash_id += FLASH_AM320T;
+		info->sector_count = 71;
+		info->size = 0x00800000;
+		break;				/* => 8 MB		*/
+
+	case AMD_ID_LV320B:
+		info->flash_id += FLASH_AM320B;
+		info->sector_count = 71;
+		info->size = 0x00800000;
+		break;				/* => 8 MB		*/
+	default:
+		info->flash_id = FLASH_UNKNOWN;
+		return (0);			/* => no or unknown flash */
+	}
+
+	/* set up sector start address table */
+	switch (value) {
+	case AMD_ID_LV400B:
+	case AMD_ID_LV800B:
+	case AMD_ID_LV160B:
+		/* set sector offsets for bottom boot block type	*/
+		info->start[0] = base + 0x00000000;
+		info->start[1] = base + 0x00008000;
+		info->start[2] = base + 0x0000C000;
+		info->start[3] = base + 0x00010000;
+		for (i = 4; i < info->sector_count; i++) {
+			info->start[i] = base + (i * 0x00020000) - 0x00060000;
+		}
+		break;
+	case AMD_ID_LV400T:
+	case AMD_ID_LV800T:
+	case AMD_ID_LV160T:
+		/* set sector offsets for top boot block type		*/
+		i = info->sector_count - 1;
+		info->start[i--] = base + info->size - 0x00008000;
+		info->start[i--] = base + info->size - 0x0000C000;
+		info->start[i--] = base + info->size - 0x00010000;
+		for (; i >= 0; i--) {
+			info->start[i] = base + i * 0x00020000;
+		}
+		break;
+	case AMD_ID_LV320B:
+		for (i = 0; i < info->sector_count; i++) {
+			info->start[i] = base;
+			/*
+			 * The first 8 sectors are 8 kB,
+			 * all the other ones  are 64 kB
+			 */
+			base += (i < 8)
+				?  2 * ( 8 << 10)
+				:  2 * (64 << 10);
+		}
+		break;
+	case AMD_ID_LV320T:
+		for (i = 0; i < info->sector_count; i++) {
+			info->start[i] = base;
+			/*
+			 * The last 8 sectors are 8 kB,
+			 * all the other ones  are 64 kB
+			 */
+			base += (i < (info->sector_count - 8))
+				?  2 * (64 << 10)
+				:  2 * ( 8 << 10);
+		}
+		break;
+	default:
+		return (0);
+		break;
+	}
+
+	/* 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 */
+		addr = (volatile unsigned long *)(info->start[i]);
+		info->protect[i] = addr[2] & 1;
+	}
+
+	/*
+	 * Prevent writes to uninitialized FLASH.
+	 */
+	if (info->flash_id != FLASH_UNKNOWN) {
+		addr = (volatile unsigned long *)info->start[0];
+
+		*addr = 0x00F000F0;	/* reset bank */
+	}
+
+	return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int	flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+	vu_long *addr = (vu_long*)(info->start[0]);
+	int flag, prot, sect, l_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) ||
+	    (info->flash_id > FLASH_AMD_COMP)) {
+		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");
+	}
+
+	l_sect = -1;
+
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	addr[0x0555] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+	addr[0x0555] = 0x00800080;
+	addr[0x0555] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect<=s_last; sect++) {
+		if (info->protect[sect] == 0) {	/* not protected */
+			addr = (vu_long*)(info->start[sect]);
+			addr[0] = 0x00300030;
+			l_sect = sect;
+		}
+	}
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	/* wait at least 80us - let's wait 1 ms */
+	udelay (1000);
+
+	/*
+	 * We wait for the last triggered sector
+	 */
+	if (l_sect < 0)
+		goto DONE;
+
+	start = get_timer (0);
+	last  = start;
+	addr = (vu_long*)(info->start[l_sect]);
+	while ((addr[0] & 0x00800080) != 0x00800080) {
+		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+			printf ("Timeout\n");
+			return 1;
+		}
+		/* show that we're waiting */
+		if ((now - last) > 1000) {	/* every second */
+			putc ('.');
+			last = now;
+		}
+	}
+
+DONE:
+	/* reset to read mode */
+	addr = (volatile unsigned long *)info->start[0];
+	addr[0] = 0x00F000F0;	/* reset bank */
+
+	printf (" done\n");
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+	ulong cp, wp, data;
+	int i, l, rc;
+
+	wp = (addr & ~3);	/* get lower word aligned address */
+
+	/*
+	 * handle unaligned start bytes
+	 */
+	if ((l = addr - wp) != 0) {
+		data = 0;
+		for (i=0, cp=wp; i<l; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *)cp);
+		}
+		for (; i<4 && cnt>0; ++i) {
+			data = (data << 8) | *src++;
+			--cnt;
+			++cp;
+		}
+		for (; cnt==0 && i<4; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *)cp);
+		}
+
+		if ((rc = write_word(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += 4;
+	}
+
+	/*
+	 * handle word aligned part
+	 */
+	while (cnt >= 4) {
+		data = 0;
+		for (i=0; i<4; ++i) {
+			data = (data << 8) | *src++;
+		}
+		if ((rc = write_word(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp  += 4;
+		cnt -= 4;
+	}
+
+	if (cnt == 0) {
+		return (0);
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+		data = (data << 8) | *src++;
+		--cnt;
+	}
+	for (; i<4; ++i, ++cp) {
+		data = (data << 8) | (*(uchar *)cp);
+	}
+
+	return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+	vu_long *addr = (vu_long*)(info->start[0]);
+	ulong start;
+	int flag;
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*((vu_long *)dest) & data) != data) {
+		return (2);
+	}
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	addr[0x0555] = 0x00AA00AA;
+	addr[0x02AA] = 0x00550055;
+	addr[0x0555] = 0x00A000A0;
+
+	*((vu_long *)dest) = data;
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	/* data polling for D7 */
+	start = get_timer (0);
+	while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
+		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+			return (1);
+		}
+	}
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/tqm8xx/load_sernum_ethaddr.c b/board/tqm8xx/load_sernum_ethaddr.c
new file mode 100644
index 0000000..98baf7f
--- /dev/null
+++ b/board/tqm8xx/load_sernum_ethaddr.c
@@ -0,0 +1,105 @@
+/*
+ * (C) Copyright 2000, 2001, 2002
+ * 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>
+
+/*-----------------------------------------------------------------------
+ * Process Hardware Information Block:
+ *
+ * If we boot on a system fresh from factory, check if the Hardware
+ * Information Block exists and save the information it contains.
+ *
+ * The TQM8xxL / TQM82xx Hardware Information Block is defined as
+ * follows:
+ * - located in first flash bank
+ * - starts at offset 0x0003FFC0
+ * - size 0x00000040
+ *
+ * Internal structure:
+ * - sequence of ASCII character strings
+ * - fields separated by a single space character (0x20)
+ * - last field terminated by NUL character (0x00)
+ * - remaining space filled with NUL characters (0x00)
+ *
+ * Fields in Hardware Information Block:
+ * 1) Module Type
+ * 2) Serial Number
+ * 3) First MAC Address
+ * 4) Number of additional MAC addresses
+ */
+
+void load_sernum_ethaddr (void)
+{
+	unsigned char *hwi;
+	unsigned char  serial [CFG_HWINFO_SIZE];
+	unsigned char  ethaddr[CFG_HWINFO_SIZE];
+	unsigned short ih, is, ie, part;
+
+	hwi = (unsigned char *)(CFG_FLASH_BASE + CFG_HWINFO_OFFSET);
+	ih = is = ie = 0;
+
+	if (*((unsigned long *)hwi) != (unsigned long)CFG_HWINFO_MAGIC) {
+		return;
+	}
+
+	part = 1;
+
+	/* copy serial # / MAC address */
+	while ((hwi[ih] != '\0') && (ih < CFG_HWINFO_SIZE)) {
+		if (hwi[ih] < ' ' || hwi[ih] > '~') { /* ASCII strings! */
+			return;
+		}
+		switch (part) {
+		default:		/* Copy serial # */
+			if (hwi[ih] == ' ') {
+				++part;
+			}
+			serial[is++] = hwi[ih];
+			break;
+		case 3:			/* Copy MAC address */
+			if (hwi[ih] == ' ') {
+				++part;
+				break;
+			}
+			ethaddr[ie++] = hwi[ih];
+			if ((ie % 3) == 2)
+				ethaddr[ie++] = ':';
+			break;
+		}
+		++ih;
+	}
+	serial[is]  = '\0';
+	if (ie && ethaddr[ie-1] == ':')
+		--ie;
+	ethaddr[ie] = '\0';
+
+	/* set serial# and ethaddr if not yet defined */
+	if (getenv("serial#") == NULL) {
+		setenv ("serial#", serial);
+	}
+
+	if (getenv("ethaddr") == NULL) {
+		setenv ("ethaddr", ethaddr);
+	}
+}
diff --git a/board/trab/README.kbd b/board/trab/README.kbd
new file mode 100644
index 0000000..3db00bc
--- /dev/null
+++ b/board/trab/README.kbd
@@ -0,0 +1,44 @@
+
+The TRAB keyboard implementation is similar to that for LWMON and
+R360MPI boards. The only difference concerns key naming. There are 4
+keys on TRAB: 1, 2, 3, 4.
+
+1) The "kbd" command provides information about the current state of
+   the keys. For example,
+
+	TRAB # kbd
+	Keys: 1 0 1 0
+
+   means that keys 1 and 3 are pressed. The keyboard status is also
+   stored in the "keybd" environment variable. In this example we get
+
+	keybd=1010
+
+2) The "preboot" variable is set according to current environment
+   settings and keys pressed. This is an example:
+
+	TRAB # setenv magic_keys XY
+	TRAB # setenv key_magicX 12
+	TRAB # setenv key_cmdX echo ## Keys 1 + 2 pressed ##\;echo
+	TRAB # setenv key_magicY 13
+	TRAB # setenv key_cmdY echo ## Keys 1 + 3 pressed ##\;echo
+
+   Here "magic_keys=XY" means that the "key_magicX" and "key_magicY"
+   variables will be checked for a match. Each variable "key_magic*"
+   defines a set of keys. In the our example, if keys 1 and 3 are
+   pressed during reset, then "key_magicY" matches, so the "preboot"
+   variable will be set to the contents of "key_cmdY":
+
+	preboot=echo ## Keys 1 + 3 pressed ##;echo
+
+3) The TRAB board has optional modem support. When a certain key
+   combination is pressed on the keyboard at power-on, the firmware
+   performs the necessary initialization of the modem and allows for
+   dial-in. The key combination is specified in the
+   "include/configs/trab.h" file. For example:
+
+	#define        CONFIG_MODEM_KEY_MAGIC  "23"
+
+   means that modem will be initialized if and only if both keys 2, 3
+   are pressed. Note that the format of this string is similar to the
+   format of "key_magic*" environment variables described above.
diff --git a/board/trab/trab.c b/board/trab/trab.c
new file mode 100644
index 0000000..3f9b198
--- /dev/null
+++ b/board/trab/trab.c
@@ -0,0 +1,301 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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 DEBUG */
+
+#include <common.h>
+#include <cmd_bsp.h>
+#include <malloc.h>
+#include <s3c2400.h>
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int key_pressed(void);
+extern void disable_putc(void);
+extern int do_mdm_init; /* defined in common/main.c */
+
+/*
+ * We need a delay of at least 500 us after turning on the VFD clock
+ * before we can read any useful information for the CPLD controlling
+ * the keyboard switches. Let's play safe and wait 5 ms. The problem
+ * is that timers are not available yet, so we use a manually timed
+ * loop.
+ */
+#define KBD_MDELAY	100000	/* 1000 */
+static void mdelay_no_timer (int msec)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int i;
+	int delay = msec * 3;
+
+	for (i = 0; i < delay; i ++) gd->bd->bi_arch_number = 145;
+}
+#endif /* CONFIG_MODEM_SUPPORT */
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_init ()
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* memory and cpu-speed are setup before relocation */
+#ifdef CONFIG_TRAB_50MHZ
+	/* change the clock to be 50 MHz 1:1:1 */
+	/* MDIV:0x5c PDIV:4 SDIV:2 */
+	rMPLLCON = 0x5c042;
+	rCLKDIVN = 0;
+#else
+	/* change the clock to be 133 MHz 1:2:4 */
+	/* MDIV:0x7d PDIV:4 SDIV:1 */
+	rMPLLCON = 0x7d041;
+	rCLKDIVN = 3;
+#endif
+
+	/* set up the I/O ports */
+	rPACON = 0x3ffff;
+	rPBCON = 0xaaaaaaaa;
+	rPBUP  = 0xffff;
+	/* INPUT nCTS0 nRTS0 TXD[1] TXD[0] RXD[1] RXD[0]	*/
+	/*  00,    10,      10,      10,      10,      10,      10 	*/
+	rPFCON = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
+#ifdef CONFIG_HWFLOW
+	/* do not pull up RXD0, RXD1, TXD0, TXD1, CTS0, RTS0 */
+	rPFUP  = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
+#else
+	/* do not pull up RXD0, RXD1, TXD0, TXD1 */
+	rPFUP  = (1<<0) | (1<<1) | (1<<2) | (1<<3);
+#endif
+	rPGCON = 0x0;
+	rPGUP  = 0x0;
+	rOPENCR= 0x0;
+
+	/* arch number of SAMSUNG-Board */
+	/* MACH_TYPE_SMDK2400 */
+	/* XXX this isn't really correct, but keep it for now */
+	gd->bd->bi_arch_number = 145;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = 0x0c000100;
+
+#ifdef CONFIG_MODEM_SUPPORT
+	/* This stuff is needed to get interrupts on stop-position
+	 * contact events.
+	 * (Copied from the LCD initialization routine.)
+	 */
+	if (rLCDCON1 == 0)
+	{
+		rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
+		rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
+#if 0
+		rPDCON = (rPDCON & 0xFFFFFF00)| 0x000000AA;
+#endif
+		rLCDCON2 = 0x000DC000;
+		rLCDCON3 = 0x0051000A;
+		rLCDCON4 = 0x00000001;
+		rLCDCON5 = 0x00000440;
+		rLCDCON1 = 0x00000B75;
+	}
+
+	mdelay_no_timer (KBD_MDELAY);
+
+	if (key_pressed()) {
+		disable_putc();	/* modem doesn't understand banner etc */
+		do_mdm_init = 1;
+	}
+#endif	/* CONFIG_MODEM_SUPPORT */
+
+	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;
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+
+/* Maximum key number */
+#define KEYBD_KEY_NUM		4
+
+#define KBD_DATA	(((*(volatile ulong *)0x04020000) >> 16) & 0xF)
+
+static uchar *key_match (ulong);
+
+int misc_init_r (void)
+{
+	ulong kbd_data = KBD_DATA;
+	uchar keybd_env[KEYBD_KEY_NUM + 1];
+	uchar *str;
+	int i;
+
+	for (i = 0; i < KEYBD_KEY_NUM; ++i) {
+		keybd_env[i] = '0' + ((kbd_data >> i) & 1);
+	}
+	keybd_env[i] = '\0';
+	debug ("** Setting keybd=\"%s\"\n", keybd_env);
+	setenv ("keybd", keybd_env);
+
+	str = strdup (key_match (kbd_data));	/* decode keys */
+
+#ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */
+	debug ("** Setting preboot=\"%s\"\n", str);
+	setenv ("preboot", str);	/* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+	if (str != NULL) {
+		free (str);
+	}
+
+	return (0);
+}
+
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static int compare_magic (ulong kbd_data, uchar *str)
+{
+	uchar key_mask;
+
+	debug ("compare_magic: kbd: %04lx  str: \"%s\"\n",kbd_data,str);
+	for (; *str; str++)
+	{
+		uchar c = *str - '1';
+
+		if (c >= KEYBD_KEY_NUM)		/* bad key number */
+			return -1;
+
+		key_mask = 1 << c;
+
+		if (!(kbd_data & key_mask)) {	/* key not pressed */
+			debug ( "compare_magic: "
+				"kbd: %04lx mask: %04lx - key not pressed\n",
+				kbd_data, key_mask );
+			return -1;
+		}
+
+		kbd_data &= ~key_mask;
+	}
+
+	if (kbd_data) {				/* key(s) not released */
+		debug ( "compare_magic: "
+			"kbd: %04lx - key(s) not released\n", kbd_data);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Check if pressed key(s) match magic sequence,
+ * and return the command string associated with that key(s).
+ *
+ * If no key press was decoded, NULL is returned.
+ *
+ * Note: the first character of the argument will be overwritten with
+ * the "magic charcter code" of the decoded key(s), or '\0'.
+ *
+ *
+ * Note: the string points to static environment data and must be
+ * saved before you call any function that modifies the environment.
+ */
+static uchar *key_match (ulong kbd_data)
+{
+	uchar magic[sizeof (kbd_magic_prefix) + 1];
+	uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+	uchar *suffix;
+	uchar *kbd_magic_keys;
+
+	/*
+	 * The following string defines the characters that can pe appended
+	 * to "key_magic" to form the names of environment variables that
+	 * hold "magic" key codes, i. e. such key codes that can cause
+	 * pre-boot actions. If the string is empty (""), then only
+	 * "key_magic" is checked (old behaviour); the string "125" causes
+	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+	 */
+	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+		kbd_magic_keys = "";
+
+	debug ("key_match: magic_keys=\"%s\"\n", kbd_magic_keys);
+
+	/* loop over all magic keys;
+	 * use '\0' suffix in case of empty string
+	 */
+	for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix)
+	{
+		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+
+		debug ("key_match: magic=\"%s\"\n",
+			getenv(magic) ? getenv(magic) : "<UNDEFINED>");
+
+		if (compare_magic(kbd_data, getenv(magic)) == 0)
+		{
+			sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+			debug ("key_match: cmdname %s=\"%s\"\n",
+				cmd_name,
+				getenv (cmd_name) ?
+					getenv (cmd_name) :
+					"<UNDEFINED>");
+			return (getenv (cmd_name));
+		}
+	}
+	debug ("key_match: no match\n");
+	return (NULL);
+}
+#endif							/* CONFIG_PREBOOT */
+
+/* Read Keyboard status */
+int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	ulong kbd_data = KBD_DATA;
+	uchar keybd_env[KEYBD_KEY_NUM + 1];
+	int i;
+
+	puts ("Keys:");
+	for (i = 0; i < KEYBD_KEY_NUM; ++i) {
+		keybd_env[i] = '0' + ((kbd_data >> i) & 1);
+		printf (" %c", keybd_env[i]);
+	}
+	keybd_env[i] = '\0';
+	putc ('\n');
+	setenv ("keybd", keybd_env);
+	return 0;
+}
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int key_pressed(void)
+{
+	return (compare_magic(KBD_DATA, CONFIG_MODEM_KEY_MAGIC) == 0);
+}
+#endif	/* CONFIG_MODEM_SUPPORT */
diff --git a/board/trab/u-boot.lds b/board/trab/u-boot.lds
new file mode 100644
index 0000000..59834af
--- /dev/null
+++ b/board/trab/u-boot.lds
@@ -0,0 +1,63 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm920t/start.o	(.text)
+	  lib_arm/_udivsi3.o	(.text)
+	  lib_arm/_umodsi3.o	(.text)
+	  lib_generic/zlib.o	(.text)
+	  lib_generic/crc32.o	(.text)
+	  lib_generic/string.o	(.text)
+
+	. = env_offset;
+	common/environment.o	(.ppcenv)
+
+	  *(.text)
+	}
+
+        . = ALIGN(4);
+        .rodata : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data : { *(.data) }
+
+        . = ALIGN(4);
+        .got : { *(.got) }
+
+	armboot_end_data = .;
+
+        . = ALIGN(4);
+        .bss : { *(.bss) }
+
+	armboot_end = .;
+}
diff --git a/board/trab/vfd.c b/board/trab/vfd.c
new file mode 100644
index 0000000..1ea483f
--- /dev/null
+++ b/board/trab/vfd.c
@@ -0,0 +1,414 @@
+/*
+ * (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
+ */
+
+/************************************************************************/
+/* ** DEBUG SETTINGS							*/
+/************************************************************************/
+
+/* #define DEBUG	*/
+
+/************************************************************************/
+/* ** HEADER FILES							*/
+/************************************************************************/
+
+#include <config.h>
+#include <common.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <s3c2400.h>
+
+#ifdef CONFIG_VFD
+
+/************************************************************************/
+/* ** CONFIG STUFF -- should be moved to board config file		*/
+/************************************************************************/
+
+/************************************************************************/
+
+#ifndef PAGE_SIZE
+#define	PAGE_SIZE	4096
+#endif
+
+#define ROT	0x09
+#define BLAU	0x0C
+#define VIOLETT	0X0D
+
+ulong vfdbase;
+ulong frame_buf_size;
+#define frame_buf_offs 4
+
+/* taken from armboot/common/vfd.c */
+ulong         adr_vfd_table[112][18][2][4][2];
+unsigned char bit_vfd_table[112][18][2][4][2];
+
+/*
+ * initialize the values for the VFD-grid-control in the framebuffer
+ */
+void init_grid_ctrl(void)
+{
+	ulong adr, grid_cycle;
+	unsigned int bit, display;
+	unsigned char temp, bit_nr;
+
+	for (adr=vfdbase; adr<=(vfdbase+7168); adr+=4) /*clear frame buffer */
+		(*(volatile ulong*)(adr))=0;
+
+	for(display=0;display<=3;display++)
+	{
+		for(grid_cycle=0;grid_cycle<=55;grid_cycle++)
+		{
+			bit = grid_cycle*256*4+(grid_cycle+200)*4+frame_buf_offs+display;
+ 			/* wrap arround if offset (see manual S3C2400) */
+			if (bit>=frame_buf_size*8)
+				bit = bit-(frame_buf_size*8);
+			adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
+			bit_nr = bit%8;
+			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+			temp=(*(volatile unsigned char*)(adr));
+			temp|=(1<<bit_nr);
+			(*(volatile unsigned char*)(adr))=temp;
+
+			if(grid_cycle<55)
+				bit = grid_cycle*256*4+(grid_cycle+201)*4+frame_buf_offs+display;
+			else
+				bit = grid_cycle*256*4+200*4+frame_buf_offs+display-4; 	/* grid nr. 0 */
+			/* wrap arround if offset (see manual S3C2400) */
+			if (bit>=frame_buf_size*8)
+				bit = bit-(frame_buf_size*8);
+			adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
+			bit_nr = bit%8;
+			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+			temp=(*(volatile unsigned char*)(adr));
+			temp|=(1<<bit_nr);
+			(*(volatile unsigned char*)(adr))=temp;
+		}
+	}
+}
+
+/*
+ *create translation table for getting easy the right position in the
+ *physical framebuffer for some x/y-coordinates of the VFDs
+ */
+void create_vfd_table(void)
+{
+	unsigned int vfd_table[112][18][2][4][2];
+	ulong adr;
+	unsigned int x, y, color, display, entry, pixel, bit_nr;
+
+	/*
+	 * Create translation table for Noritake-T119C-VFD-specific
+	 * organized frame-buffer.
+	 * Created is the number of the bit in the framebuffer (the
+	 * first transferred pixel of each frame is bit 0).
+	 */
+	for(y=0;y<=17;y++)   /* Zeile */
+	{
+		for(x=0;x<=111;x++)  /* Spalten */
+		{
+			/*Display 0 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][0][0]=((x%4)*4+y*16+(x/4)*2048);
+			/*Display 0 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][0][0]=((x%4)*4+y*16+(x/4)*2048+512);
+			if(x<=1)
+			{
+				/*Display 0 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1024);
+				/*Display 0 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1024);
+			}
+			else
+			{
+				/*Display 0 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+1024);
+				/*Display 0 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1024);
+			}
+			/*Display 1 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][1][0]=((x%4)*4+y*16+(x/4)*2048+1);
+			/*Display 1 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][1][0]=((x%4)*4+y*16+(x/4)*2048+512+1);
+			if(x<=1)
+			{
+				/*Display 1 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1+1024);
+				/*Display 1 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1+1024);
+			}
+			else
+			{
+				/*Display 1 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+1+1024);
+				/*Display 1 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1+1024);
+			}
+			/*Display 2 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][2][0]=((x%4)*4+y*16+(x/4)*2048+2);
+			/*Display 2 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][2][0]=((x%4)*4+y*16+(x/4)*2048+512+2);
+			if(x<=1)
+			{
+				/*Display 2 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+2+1024);
+				/*Display 2 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+2+1024);
+			}
+			else
+			{
+				/*Display 2 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+2+1024);
+				/*Display 2 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+2+1024);
+			}
+			/*Display 3 blaue Pixel Eintrag 1 */
+			vfd_table[x][y][0][3][0]=((x%4)*4+y*16+(x/4)*2048+3);
+			/*Display 3 rote Pixel Eintrag 1 */
+			vfd_table[x][y][1][3][0]=((x%4)*4+y*16+(x/4)*2048+512+3);
+			if(x<=1)
+			{
+				/*Display 3 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+3+1024);
+				/*Display 3 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+3+1024);
+			}
+			else
+			{
+				/*Display 3 blaue Pixel Eintrag 2 */
+				vfd_table[x][y][0][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+3+1024);
+				/*Display 3 rote Pixel Eintrag 2 */
+				vfd_table[x][y][1][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+3+1024);
+			}
+		}
+	}
+
+	/*
+	 * Create translation table for Noritake-T119C-VFD-specific
+	 * organized frame-buffer
+	 * Create table with entries for physical byte adresses and
+	 * bit-number within the byte
+	 * from table with bit-numbers within the total framebuffer
+	 */
+	for(y=0;y<=17;y++)
+	{
+		for(x=0;x<=111;x++)
+		{
+			for(color=0;color<=1;color++)
+			{
+				for(display=0;display<=3;display++)
+				{
+					for(entry=0;entry<=1;entry++)
+					{
+						pixel  = vfd_table[x][y][color][display][entry] + frame_buf_offs;
+						 /*
+						  * wrap arround if offset
+						  * (see manual S3C2400)
+						  */
+						if (pixel>=frame_buf_size*8)
+							pixel = pixel-(frame_buf_size*8);
+						adr    = vfdbase+(pixel/32)*4+(3-(pixel%32)/8);
+						bit_nr = pixel%8;
+						bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+						adr_vfd_table[x][y][color][display][entry] = adr;
+						bit_vfd_table[x][y][color][display][entry] = bit_nr;
+					}
+				}
+			}
+		}
+	}
+}
+
+/*
+ * Set/clear pixel of the VFDs
+ */
+void set_vfd_pixel(unsigned char x, unsigned char y, unsigned char color, unsigned char display, unsigned char value)
+{
+	ulong adr;
+	unsigned char bit_nr, temp;
+
+	if (value!=0)
+	{
+		/* Pixel-Eintrag Nr. 1 */
+		adr = adr_vfd_table[x][y][color][display][0];
+		/* Pixel-Eintrag Nr. 1 */
+		bit_nr = bit_vfd_table[x][y][color][display][0];
+		temp=(*(volatile unsigned char*)(adr));
+		temp|=1<<bit_nr;
+		(*(volatile unsigned char*)(adr))=temp;
+
+		/* Pixel-Eintrag Nr. 2 */
+		adr = adr_vfd_table[x][y][color][display][1];
+		/* Pixel-Eintrag Nr. 2 */
+		bit_nr = bit_vfd_table[x][y][color][display][1];
+		temp=(*(volatile unsigned char*)(adr));
+		temp|=1<<bit_nr;
+		(*(volatile unsigned char*)(adr))=temp;
+	}
+	else
+	{
+		/* Pixel-Eintrag Nr. 1 */
+		adr = adr_vfd_table[x][y][color][display][0];
+		/* Pixel-Eintrag Nr. 1 */
+		bit_nr = bit_vfd_table[x][y][color][display][0];
+		temp=(*(volatile unsigned char*)(adr));
+		temp&=~(1<<bit_nr);
+		(*(volatile unsigned char*)(adr))=temp;
+
+		/* Pixel-Eintrag Nr. 2 */
+		adr = adr_vfd_table[x][y][color][display][1];
+		/* Pixel-Eintrag Nr. 2 */
+		bit_nr = bit_vfd_table[x][y][color][display][1];
+		temp=(*(volatile unsigned char*)(adr));
+		temp&=~(1<<bit_nr);
+		(*(volatile unsigned char*)(adr))=temp;
+	}
+}
+
+/*
+ * transfer image from BMP-File
+ */
+void transfer_pic(int display, unsigned char *adr, int height, int width)
+{
+	int x, y;
+	unsigned char temp;
+
+	for (; height > 0; height -= 18)
+	{
+		if (height > 18)
+			y = 18;
+		else
+			y = height;
+		for (; y > 0; y--)
+		{
+			for (x = 0; x < width; x += 2)
+			{
+				temp = *adr++;
+				set_vfd_pixel(x, y-1, 0, display, 0);
+				set_vfd_pixel(x, y-1, 1, display, 0);
+				if ((temp >> 4) == BLAU)
+					set_vfd_pixel(x, y-1, 0, display, 1);
+				else if ((temp >> 4) == ROT)
+					set_vfd_pixel(x, y-1, 1, display, 1);
+				else if ((temp >> 4) == VIOLETT)
+				{
+					set_vfd_pixel(x, y-1, 0, display, 1);
+					set_vfd_pixel(x, y-1, 1, display, 1);
+				}
+				set_vfd_pixel(x+1, y-1, 0, display, 0);
+				set_vfd_pixel(x+1, y-1, 1, display, 0);
+				if ((temp & 0x0F) == BLAU)
+					set_vfd_pixel(x+1, y-1, 0, display, 1);
+				else if ((temp & 0x0F) == ROT)
+					set_vfd_pixel(x+1, y-1, 1, display, 1);
+				else if ((temp & 0x0F) == VIOLETT)
+				{
+					set_vfd_pixel(x+1, y-1, 0, display, 1);
+					set_vfd_pixel(x+1, y-1, 1, display, 1);
+				}
+			}
+		}
+		display++;
+		if (display > 3)
+			display = 0;
+	}
+}
+
+/*
+ * initialize LCD-Controller of the S3C2400 for using VFDs
+ */
+int drv_vfd_init(void)
+{
+	ulong palette;
+
+	DECLARE_GLOBAL_DATA_PTR;
+
+	vfdbase = gd->fb_base;
+	create_vfd_table();
+	init_grid_ctrl();
+
+	/*
+	 * Hinweis: Der Framebuffer ist um genau ein Nibble verschoben
+	 * Das erste angezeigte Pixel wird aus dem zweiten Nibble geholt
+	 * das letzte angezeigte Pixel wird aus dem ersten Nibble geholt
+	 * (wrap around)
+	 * see manual S3C2400
+	 */
+	/* frame buffer startadr */
+	rLCDSADDR1 = vfdbase >> 1;
+ 	/* frame buffer endadr */
+	rLCDSADDR2 = (vfdbase + frame_buf_size) >> 1;
+	rLCDSADDR3 = ((256/4));
+
+	/* Port-Pins als LCD-Ausgang */
+	rPCCON =   (rPCCON & 0xFFFFFF00)| 0x000000AA;
+	/* Port-Pins als LCD-Ausgang */
+	rPDCON =   (rPDCON & 0xFFFFFF03)| 0x000000A8;
+#ifdef WITH_VFRAME
+	/* mit VFRAME zum Messen */
+	rPDCON =   (rPDCON & 0xFFFFFF00)| 0x000000AA;
+#endif
+
+	rLCDCON2 = 0x000DC000;
+	rLCDCON3 = 0x0051000A;
+	rLCDCON4 = 0x00000001;
+	rLCDCON5 = 0x00000440;
+	rLCDCON1 = 0x00000B75;
+
+	debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
+	debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
+	debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
+
+	for(palette=0;palette<=15;palette++)
+		(*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
+	for(palette=16;palette<=255;palette++)
+		(*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;
+
+	return 0;
+}
+
+/************************************************************************/
+/* ** ROM capable initialization part - needed to reserve FB memory	*/
+/************************************************************************/
+
+/*
+ * This is called early in the system initialization to grab memory
+ * for the VFD controller.
+ *
+ * Note that this is running from ROM, so no write access to global data.
+ */
+ulong vfd_setmem (ulong addr)
+{
+	ulong size;
+
+	/* MAGIC */
+	frame_buf_size = (256*4*56)/8;
+
+	/* Round up to nearest full page */
+	size = (frame_buf_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+
+	debug ("Reserving %ldk for VFD Framebuffer at: %08lx\n", size>>10, addr);
+
+	return (size);
+}
+
+#endif /* CONFIG_VFD */
diff --git a/board/utx8245/utx8245.c b/board/utx8245/utx8245.c
new file mode 100644
index 0000000..249862a
--- /dev/null
+++ b/board/utx8245/utx8245.c
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2001
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * (C) Copyright 2002
+ * Gregory E. Allen, gallen@arlut.utexas.edu
+ * Matthew E. Karger, karger@arlut.utexas.edu
+ * Applied Research Laboratories, The University of Texas at Austin
+ *
+ * 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>
+#include <asm/io.h>
+#include <pci.h>
+
+#define	SAVE_SZ	32
+
+
+int checkboard(void)
+{
+	ulong busfreq  = get_bus_freq(0);
+	char  buf[32];
+
+	printf("Board: UTX8245 Local Bus at %s MHz\n", strmhz(buf, busfreq));
+	return 0;
+}
+
+
+long int initdram(int board_type)
+{
+#if 1
+	int				i, cnt;
+	volatile uchar	*base =	CFG_SDRAM_BASE;
+	volatile ulong	*addr;
+	ulong			save[SAVE_SZ];
+	ulong			val, ret  = 0;
+
+	for (i=0; i<SAVE_SZ; i++)	{save[i] = 0;}		/* clear table */
+
+	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
+
+}
+
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+
+static struct pci_config_table pci_utx8245_config_table[] = {
+#ifndef CONFIG_PCI_PNP
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+				       PCI_ENET0_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_FIREWIRE_IOADDR,
+				       PCI_FIREWIRE_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+#endif /*CONFIG_PCI_PNP*/
+	{ }
+};
+
+
+static void pci_utx8245_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	if (PCI_DEV(dev) == 11)
+		/* assign serial interrupt line 9 (int25) to FireWire */
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 25);
+
+	else if (PCI_DEV(dev) == 12)
+		/* assign serial interrupt line 8 (int24) to Ethernet */
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 24);
+}
+
+static struct pci_controller utx8245_hose = {
+#ifndef CONFIG_PCI_PNP
+	config_table: pci_utx8245_config_table,
+	fixup_irq: pci_utx8245_fixup_irq,
+	write_byte: pci_hose_write_config_byte
+#endif /*CONFIG_PCI_PNP*/
+};
+
+void pci_init (void)
+{
+	pci_mpc824x_init(&utx8245_hose);
+
+	icache_enable();
+}
+
diff --git a/board/w7o/flash.c b/board/w7o/flash.c
new file mode 100644
index 0000000..0048476
--- /dev/null
+++ b/board/w7o/flash.c
@@ -0,0 +1,941 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *  Based on code by:
+ * 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 <ppc4xx.h>
+#include <asm/processor.h>
+
+#include <watchdog.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_word8(flash_info_t *info, ulong dest, ulong data);
+static int write_word32 (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+    int i;
+    unsigned long size_b0, base_b0;
+    unsigned long size_b1, base_b1;
+
+    /* Init: no FLASHes known */
+    for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+        flash_info[i].flash_id = FLASH_UNKNOWN;
+    }
+
+    /* Get Size of Boot and Main Flashes */
+    size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+    if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+        printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+            size_b0, size_b0<<20);
+        return 0;
+    }
+    size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+    if (flash_info[1].flash_id == FLASH_UNKNOWN) {
+        printf ("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
+            size_b1, size_b1<<20);
+        return 0;
+    }
+
+    /* Calculate base addresses */
+    base_b0 = -size_b0;
+    base_b1 = -size_b1;
+
+    /* Setup offsets for Boot Flash */
+    flash_get_offsets (base_b0, &flash_info[0]);
+
+    /* Protect board level data */
+    (void)flash_protect(FLAG_PROTECT_SET,
+			base_b0,
+			flash_info[0].start[1] - 1,
+			&flash_info[0]);
+
+
+    /* Monitor protection ON by default */
+    (void)flash_protect(FLAG_PROTECT_SET,
+                        base_b0 + size_b0 - CFG_MONITOR_LEN,
+                        base_b0 + size_b0 - 1,
+                        &flash_info[0]);
+
+    /* Protect the FPGA image */
+    (void)flash_protect(FLAG_PROTECT_SET,
+                        FLASH_BASE1_PRELIM,
+                        FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN - 1,
+                        &flash_info[1]);
+
+    /* Protect the default boot image */
+    (void)flash_protect(FLAG_PROTECT_SET,
+                        FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN,
+                        FLASH_BASE1_PRELIM + CFG_FPGA_IMAGE_LEN + 0x600000 - 1,
+                        &flash_info[1]);
+
+    /* Setup offsets for Main Flash */
+    flash_get_offsets (FLASH_BASE1_PRELIM, &flash_info[1]);
+
+    return (size_b0 + size_b1);
+} /* end flash_init() */
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+    int i;
+
+    /* set up sector start address table - FOR BOOT ROM ONLY!!! */
+    if ((info->flash_id & FLASH_TYPEMASK)  == FLASH_AM040) {
+        for (i = 0; i < info->sector_count; i++)
+            info->start[i] = base + (i * 0x00010000);
+    }
+} /* end flash_get_offsets() */
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+    int k;
+    int size;
+    int erased;
+    volatile unsigned long *flash;
+
+    if (info->flash_id == FLASH_UNKNOWN) {
+        printf ("missing or unknown FLASH type\n");
+        return;
+    }
+
+    switch (info->flash_id & FLASH_VENDMASK) {
+        case FLASH_MAN_AMD:     printf ("1 x AMD ");    break;
+	case FLASH_MAN_STM:	printf ("1 x STM ");	break;
+        case FLASH_MAN_INTEL:   printf ("2 x Intel ");  break;
+        default:                printf ("Unknown Vendor ");
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_AM040:
+	    if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
+            	printf ("AM29LV040 (4096 Kbit, uniform sector size)\n");
+	    else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
+            	printf ("M29W040B (4096 Kbit, uniform block size)\n");
+	    else
+            	printf ("UNKNOWN 29x040x (4096 Kbit, uniform sector size)\n");
+            break;
+        case FLASH_28F320J3A:
+            printf ("28F320J3A (32 Mbit = 128K x 32)\n");
+            break;
+        case FLASH_28F640J3A:
+            printf ("28F640J3A (64 Mbit = 128K x 64)\n");
+            break;
+        case FLASH_28F128J3A:
+            printf ("28F128J3A (128 Mbit = 128K x 128)\n");
+            break;
+        default:
+            printf ("Unknown Chip Type\n");
+    }
+
+    if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) {
+    	printf ("  Size: %ld KB in %d Blocks\n",
+        	info->size >> 10, info->sector_count);
+    } else {
+    	printf ("  Size: %ld KB in %d Sectors\n",
+        	info->size >> 10, info->sector_count);
+    }
+
+    printf ("  Sector Start Addresses:");
+    for (i=0; i<info->sector_count; ++i) {
+        /*
+         * Check if whole sector is erased
+         */
+        if (i != (info->sector_count-1))
+            size = info->start[i+1] - info->start[i];
+        else
+            size = info->start[0] + info->size - info->start[i];
+        erased = 1;
+        flash = (volatile unsigned long *)info->start[i];
+        size = size >> 2;        /* divide by 4 for longword access */
+        for (k=0; k<size; k++)
+        {
+            if (*flash++ != 0xffffffff)
+            {
+                erased = 0;
+                break;
+            }
+        }
+
+        if ((i % 5) == 0)
+            printf ("\n   ");
+        printf (" %08lX%s%s",
+            info->start[i],
+            erased ? " E" : "  ",
+            info->protect[i] ? "RO " : "   "
+        );
+    }
+    printf ("\n");
+} /* end flash_print_info() */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+    short i;
+    ulong base = (ulong)addr;
+
+    /* Setup default type */
+    info->flash_id = FLASH_UNKNOWN;
+    info->sector_count =0;
+    info->size = 0;
+
+    /* Test for Boot Flash */
+    if (base == FLASH_BASE0_PRELIM) {
+        unsigned char value;
+        volatile unsigned char * addr2 = (unsigned char *)addr;
+
+        /* Write auto select command: read Manufacturer ID */
+        *(addr2 + 0x555) = 0xaa;
+        *(addr2 + 0x2aa) = 0x55;
+        *(addr2 + 0x555) = 0x90;
+
+        /* Manufacture ID */
+        value = *addr2;
+        switch (value) {
+            case (unsigned char)AMD_MANUFACT:
+                info->flash_id = FLASH_MAN_AMD;
+                break;
+	    case (unsigned char)STM_MANUFACT:
+		info->flash_id = FLASH_MAN_STM;
+		break;
+            default:
+                *addr2 = 0xf0;              /* no or unknown flash  */
+                return 0;
+        }
+
+        /* Device ID */
+        value = *(addr2 + 1);
+        switch (value) {
+            case (unsigned char)AMD_ID_LV040B:
+	    case (unsigned char)STM_ID_29W040B:
+                info->flash_id += FLASH_AM040;
+                info->sector_count = 8;
+                info->size = 0x00080000;
+                break;                       /* => 512Kb */
+            default:
+                *addr2 = 0xf0;               /* => no or unknown flash */
+                return 0;
+        }
+    }
+    else { /* MAIN Flash */
+        unsigned long value;
+        volatile unsigned long * addr2 = (unsigned long *)addr;
+
+        /* Write auto select command: read Manufacturer ID */
+        *addr2 = 0x90909090;
+
+        /* Manufacture ID */
+        value = *addr2;
+        switch (value) {
+            case (unsigned long)INTEL_MANUFACT:
+                info->flash_id = FLASH_MAN_INTEL;
+                break;
+            default:
+                *addr2 = 0xff;              /* no or unknown flash  */
+                return 0;
+        }
+
+        /* Device ID - This shit is interleaved... */
+        value = *(addr2 + 1);
+        switch (value) {
+            case (unsigned long)INTEL_ID_28F320J3A:
+                info->flash_id += FLASH_28F320J3A;
+                info->sector_count = 32;
+                info->size = 0x00400000 * 2;
+                break;                       /* => 2 X 4 MB */
+            case (unsigned long)INTEL_ID_28F640J3A:
+                info->flash_id += FLASH_28F640J3A;
+                info->sector_count = 64;
+                info->size = 0x00800000 * 2;
+                break;                       /* => 2 X 8 MB */
+            case (unsigned long)INTEL_ID_28F128J3A:
+                info->flash_id += FLASH_28F128J3A;
+                info->sector_count = 128;
+                info->size = 0x01000000 * 2;
+                break;                       /* => 2 X 16 MB */
+            default:
+                *addr2 = 0xff;               /* => no or unknown flash */
+        }
+    }
+
+    /* Make sure we don't exceed CFG_MAX_FLASH_SECT */
+    if (info->sector_count > CFG_MAX_FLASH_SECT) {
+        printf ("** ERROR: sector count %d > max (%d) **\n",
+                info->sector_count, CFG_MAX_FLASH_SECT);
+        info->sector_count = CFG_MAX_FLASH_SECT;
+    }
+
+    /* set up sector start address table */
+    switch (info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_AM040:
+            for (i = 0; i < info->sector_count; i++)
+                info->start[i] = base + (i * 0x00010000);
+            break;
+        case FLASH_28F320J3A:
+        case FLASH_28F640J3A:
+        case FLASH_28F128J3A:
+            for (i = 0; i < info->sector_count; i++)
+                info->start[i] = base + (i * 0x00020000 * 2); /* 2 Banks */
+            break;
+    }
+
+    /* Test for Boot Flash */
+    if (base == FLASH_BASE0_PRELIM) {
+        volatile unsigned char *addr2;
+        /* check for protected sectors */
+        for (i = 0; i < info->sector_count; i++) {
+            /* read sector protection at sector address, (AX .. A0) = 0x02 */
+            /* D0 = 1 if protected */
+            addr2 = (volatile unsigned char *)(info->start[i]);
+            info->protect[i] = *(addr2 + 2) & 1;
+        }
+
+        /* Restore read mode */
+        *(unsigned char *)base = 0xF0;       /* Reset NORMAL Flash */
+    }
+    else { /* Main Flash */
+        volatile unsigned long *addr2;
+        /* check for protected sectors */
+        for (i = 0; i < info->sector_count; i++) {
+            /* read sector protection at sector address, (AX .. A0) = 0x02 */
+            /* D0 = 1 if protected */
+            addr2 = (volatile unsigned long *)(info->start[i]);
+            info->protect[i] = *(addr2 + 2) & 0x1;
+        }
+
+        /* Restore read mode */
+        *(unsigned long *)base = 0xFFFFFFFF; /* Reset  Flash */
+    }
+
+    return (info->size);
+} /* end flash_get_size() */
+
+/*-----------------------------------------------------------------------
+ */
+
+static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
+{
+    int i;
+
+    volatile uchar *vaddr =  (uchar *)addr;
+
+    /* Loop X times */
+    for (i = 1; i <= (100 * tout); i++) {    /* Wait up to tout ms */
+        udelay(10);
+        /* Pause 10 us */
+
+        /* Check for completion */
+        if ((vaddr[0] & 0x80) == (cmp_val & 0x80)) {
+            return 0;
+        }
+
+        /* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */
+        if (!(i % 110000))
+            putc('.');
+
+        /* Kick the dog if needed */
+        WATCHDOG_RESET();
+    }
+
+    return 1;
+} /* wait_for_DQ7() */
+
+/*-----------------------------------------------------------------------
+ */
+
+static int flash_erase8(flash_info_t *info, int s_first, int s_last)
+{
+    int tcode, rcode = 0;
+    volatile uchar *addr = (uchar *)(info->start[0]);
+    volatile uchar *sector_addr;
+    int flag, prot, sect;
+
+    /* Validate arguments */
+    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;
+    }
+
+    /* Check for KNOWN flash type */
+    if (info->flash_id == FLASH_UNKNOWN) {
+        printf ("Can't erase unknown flash type - aborted\n");
+        return 1;
+    }
+
+    /* Check for protected sectors */
+    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 erase on unprotected sectors */
+    for (sect = s_first; sect <= s_last; sect++) {
+        if (info->protect[sect] == 0) {      /* not protected */
+            sector_addr = (uchar *)(info->start[sect]);
+
+    		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
+		    printf("Erasing block %p\n", sector_addr);
+		else
+		    printf("Erasing sector %p\n", sector_addr);
+
+            /* Disable interrupts which might cause Flash to timeout */
+            flag = disable_interrupts();
+
+            *(addr + 0x555) = (uchar)0xAA;
+            *(addr + 0x2aa) = (uchar)0x55;
+            *(addr + 0x555) = (uchar)0x80;
+            *(addr + 0x555) = (uchar)0xAA;
+            *(addr + 0x2aa) = (uchar)0x55;
+            *sector_addr = (uchar)0x30;      /* sector erase */
+
+            /*
+             * Wait for each sector to complete, it's more
+             * reliable.  According to AMD Spec, you must
+             * issue all erase commands within a specified
+             * timeout.  This has been seen to fail, especially
+             * if printf()s are included (for debug)!!
+             * Takes up to 6 seconds.
+             */
+            tcode  = wait_for_DQ7((ulong)sector_addr, 0x80, 6000);
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            /* Make sure we didn't timeout */
+            if (tcode) {
+                printf ("Timeout\n");
+                rcode = 1;
+            }
+        }
+    }
+
+    /* wait at least 80us - let's wait 1 ms */
+    udelay (1000);
+
+    /* reset to read mode */
+    addr = (uchar *)info->start[0];
+    *addr = (uchar)0xF0;                     /* reset bank */
+
+    printf (" done\n");
+    return rcode;
+} /* end flash_erase8() */
+
+static int flash_erase32(flash_info_t *info, int s_first, int s_last)
+{
+    int flag, sect;
+    ulong start, now, last;
+    int prot = 0;
+
+    /* Validate arguments */
+    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;
+    }
+
+    /* Check for KNOWN flash type */
+    if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
+        printf ("Can erase only Intel flash types - aborted\n");
+        return 1;
+    }
+
+    /* Check for protected sectors */
+    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++) {
+        WATCHDOG_RESET();
+        if (info->protect[sect] == 0) {      /* not protected */
+            vu_long *addr = (vu_long *)(info->start[sect]);
+            unsigned long status;
+
+            /* Disable interrupts which might cause a timeout here */
+            flag = disable_interrupts();
+
+            *addr = 0x00500050;              /* clear status register */
+            *addr = 0x00200020;              /* erase setup */
+            *addr = 0x00D000D0;              /* erase confirm */
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            /* Wait at least 80us - let's wait 1 ms */
+            udelay (1000);
+
+            while (((status = *addr) & 0x00800080) != 0x00800080) {
+                if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                    printf ("Timeout\n");
+                    *addr = 0x00B000B0;      /* suspend erase      */
+                    *addr = 0x00FF00FF;      /* reset to read mode */
+                    return 1;
+                }
+
+                /* show that we're waiting */
+                if ((now - last) > 990) {   /* every second */
+                    putc ('.');
+                    last = now;
+                }
+            }
+            *addr = 0x00FF00FF;              /* reset to read mode */
+        }
+    }
+    printf (" done\n");
+    return 0;
+} /* end flash_erase32() */
+
+int flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+    if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
+        return flash_erase8(info, s_first, s_last);
+    else
+        return flash_erase32(info, s_first, s_last);
+} /* end flash_erase() */
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong cp, wp, data;
+    ulong start;
+    int i, l, rc;
+
+    start = get_timer (0);
+
+    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_word8(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_word8(info, wp, data)) != 0) {
+            return (rc);
+        }
+        wp  += 4;
+        cnt -= 4;
+        if (get_timer(start) > 1000) {   /* every second */
+           WATCHDOG_RESET();
+           putc ('.');
+           start = get_timer(0);
+        }
+    }
+
+    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_word8(info, wp, data));
+} /* end write_buff8() */
+
+#define	FLASH_WIDTH	4	/* flash bus width in bytes */
+static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+	ulong cp, wp, data;
+	int i, l, rc;
+	ulong start;
+
+	start = get_timer (0);
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		return 4;
+	}
+
+	wp = (addr & ~(FLASH_WIDTH-1));	/* get lower FLASH_WIDTH 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<FLASH_WIDTH && cnt>0; ++i) {
+			data = (data << 8) | *src++;
+			--cnt;
+			++cp;
+		}
+		for (; cnt==0 && i<FLASH_WIDTH; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *)cp);
+		}
+
+		if ((rc = write_word32(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += FLASH_WIDTH;
+	}
+
+	/*
+	 * handle FLASH_WIDTH aligned part
+	 */
+	while (cnt >= FLASH_WIDTH) {
+		data = 0;
+		for (i=0; i<FLASH_WIDTH; ++i) {
+			data = (data << 8) | *src++;
+		}
+		if ((rc = write_word32(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp  += FLASH_WIDTH;
+		cnt -= FLASH_WIDTH;
+          if (get_timer(start) > 990) {   /* every second */
+			putc ('.');
+			start = get_timer(0);
+		}
+	}
+
+	if (cnt == 0) {
+		return (0);
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i=0, cp=wp; i<FLASH_WIDTH && cnt>0; ++i, ++cp) {
+		data = (data << 8) | *src++;
+		--cnt;
+	}
+	for (; i<FLASH_WIDTH; ++i, ++cp) {
+		data = (data << 8) | (*(uchar *)cp);
+	}
+
+	return (write_word32(info, wp, data));
+} /* write_buff32() */
+
+int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    int retval;
+
+    if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
+        retval = write_buff8(info, src, addr, cnt);
+    else
+        retval = write_buff32(info, src, addr, cnt);
+
+    return retval;
+} /* end write_buff() */
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+static int write_word8(flash_info_t *info, ulong dest, ulong data)
+{
+    volatile uchar *addr2 = (uchar *)(info->start[0]);
+    volatile uchar *dest2 = (uchar *)dest;
+    volatile uchar *data2 = (uchar *)&data;
+    int flag;
+    int i, tcode, rcode = 0;
+
+    /* Check if Flash is (sufficently) erased */
+    if ((*((volatile uchar *)dest) &
+        (uchar)data) != (uchar)data) {
+        return (2);
+    }
+
+    for (i=0; i < (4 / sizeof(uchar)); i++) {
+        /* Disable interrupts which might cause a timeout here */
+        flag = disable_interrupts();
+
+        *(addr2 + 0x555) = (uchar)0xAA;
+        *(addr2 + 0x2aa) = (uchar)0x55;
+        *(addr2 + 0x555) = (uchar)0xA0;
+
+        dest2[i] = data2[i];
+
+        /* Wait for write to complete, up to 1ms */
+        tcode = wait_for_DQ7((ulong)&dest2[i], data2[i], 1);
+
+        /* re-enable interrupts if necessary */
+        if (flag)
+            enable_interrupts();
+
+        /* Make sure we didn't timeout */
+        if (tcode) {
+            rcode = 1;
+        }
+    }
+
+    return rcode;
+} /* end write_word8() */
+
+static int write_word32(flash_info_t *info, ulong dest, ulong data)
+{
+    vu_long *addr = (vu_long *)dest;
+    ulong status;
+    ulong start;
+    int flag;
+
+    /* Check if Flash is (sufficiently) erased */
+    if ((*addr & data) != data) {
+        return (2);
+    }
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    *addr = 0x00400040;                      /* write setup */
+    *addr = data;
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+        enable_interrupts();
+
+    start = get_timer (0);
+
+    while (((status = *addr) & 0x00800080) != 0x00800080) {
+        WATCHDOG_RESET();
+        if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+            *addr = 0x00FF00FF;              /* restore read mode */
+            return (1);
+        }
+    }
+
+    *addr = 0x00FF00FF;                      /* restore read mode */
+
+    return (0);
+} /* end write_word32() */
+
+
+static int _flash_protect(flash_info_t *info, long sector)
+{
+    int i;
+    int flag;
+    ulong status;
+    int rcode = 0;
+    volatile long *addr = (unsigned long *)sector;
+
+    switch(info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_28F320J3A:
+        case FLASH_28F640J3A:
+        case FLASH_28F128J3A:
+            /* Disable interrupts which might cause Flash to timeout */
+            flag = disable_interrupts();
+
+            /* Issue command */
+            *addr = 0x00500050L;             /* Clear the status register */
+            *addr = 0x00600060L;             /* Set lock bit setup */
+            *addr = 0x00010001L;             /* Set lock bit confirm */
+
+            /* Wait for command completion */
+            for (i = 0; i < 10; i++) {       /* 75us timeout, wait 100us */
+                udelay(10);
+                if ((*addr & 0x00800080L) == 0x00800080L)
+                    break;
+            }
+
+            /* Not successful? */
+            status = *addr;
+            if (status != 0x00800080L) {
+                printf("Protect %x sector failed: %x\n",
+                       (uint)sector, (uint)status);
+                rcode = 1;
+            }
+
+            /* Restore read mode */
+            *addr = 0x00ff00ffL;
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            break;
+        case FLASH_AM040:                    /* No soft sector protection */
+            break;
+    }
+
+    /* Turn protection on for this sector */
+    for (i = 0; i < info->sector_count; i++) {
+        if (info->start[i] == sector) {
+            info->protect[i] = 1;
+            break;
+        }
+    }
+
+    return rcode;
+} /* end _flash_protect() */
+
+static int _flash_unprotect(flash_info_t *info, long sector)
+{
+    int i;
+    int flag;
+    ulong status;
+    int rcode = 0;
+    volatile long *addr = (unsigned long *)sector;
+
+    switch(info->flash_id & FLASH_TYPEMASK) {
+        case FLASH_28F320J3A:
+        case FLASH_28F640J3A:
+        case FLASH_28F128J3A:
+            /* Disable interrupts which might cause Flash to timeout */
+            flag = disable_interrupts();
+
+            *addr = 0x00500050L;             /* Clear the status register */
+            *addr = 0x00600060L;             /* Clear lock bit setup */
+            *addr = 0x00D000D0L;             /* Clear lock bit confirm */
+
+            /* Wait for command completion */
+            for (i = 0; i < 80 ; i++) {      /* 700ms timeout, wait 800 */
+                udelay(10000);               /* Delay 10ms */
+                if ((*addr & 0x00800080L) == 0x00800080L)
+                    break;
+            }
+
+            /* Not successful? */
+            status = *addr;
+            if (status != 0x00800080L) {
+                printf("Un-protect %x sector failed: %x\n",
+                       (uint)sector, (uint)status);
+                *addr = 0x00ff00ffL;
+                rcode = 1;
+            }
+
+            /* restore read mode */
+            *addr = 0x00ff00ffL;
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+                enable_interrupts();
+
+            break;
+        case FLASH_AM040:                    /* No soft sector protection */
+            break;
+    }
+
+    /*
+     * Fix Intel's little red wagon.  Reprotect
+     * sectors that were protected before we undid
+     * protection on a specific sector.
+     */
+    for (i = 0; i < info->sector_count; i++) {
+        if (info->start[i] != sector) {
+            if (info->protect[i]) {
+                if (_flash_protect(info, info->start[i]))
+                    rcode = 1;
+	    }
+        }
+        else /* Turn protection off for this sector */
+            info->protect[i] = 0;
+    }
+
+    return rcode;
+} /* end _flash_unprotect() */
+
+
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+    int rcode;
+
+    if (prot)
+        rcode = _flash_protect(info, info->start[sector]);
+    else
+        rcode = _flash_unprotect(info, info->start[sector]);
+
+    return rcode;
+} /* end flash_real_protect() */
+
+/*-----------------------------------------------------------------------
+ */
+
diff --git a/board/w7o/fpga.c b/board/w7o/fpga.c
new file mode 100644
index 0000000..e84123b
--- /dev/null
+++ b/board/w7o/fpga.c
@@ -0,0 +1,380 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
+ *  and
+ * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
+ *
+ * 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 <common.h>
+#include "w7o.h"
+#include <asm/processor.h>
+#include "errors.h"
+
+static void
+fpga_img_write(unsigned long *src, unsigned long len, unsigned short *daddr)
+{
+    unsigned long i;
+    volatile unsigned long val;
+    volatile unsigned short *dest = daddr;	/* volatile-bypass optimizer */
+
+    for (i = 0; i < len; i++, src++) {
+        val = *src;
+        *dest = (unsigned short)((val & 0xff000000L) >> 16);
+        *dest = (unsigned short)((val & 0x00ff0000L) >> 8);
+        *dest = (unsigned short)(val & 0x0000ff00L);
+        *dest = (unsigned short)((val & 0x000000ffL) << 8);
+    }
+
+    /* Terminate programming with 4 C clocks */
+    dest = daddr;
+    val = *(unsigned short *)dest;
+    val = *(unsigned short *)dest;
+    val = *(unsigned short *)dest;
+    val = *(unsigned short *)dest;
+
+}
+
+
+int
+fpgaDownload(unsigned char *saddr,
+	     unsigned long size,
+	     unsigned short *daddr)
+{
+    int i;					/* index, intr disable flag */
+    int start;					/* timer */
+    unsigned long greg, grego;			/* GPIO & output register */
+    unsigned long length;			/* image size in words */
+    unsigned long *source;			/* image source addr */
+    unsigned short *dest;			/* destination FPGA addr */
+    volatile unsigned short *ndest;		/* temp dest FPGA addr */
+    volatile unsigned short val;		/* temp val */
+    unsigned long cnfg = GPIO_XCV_CNFG;		/* FPGA CNFG */
+    unsigned long eirq = GPIO_XCV_IRQ;
+    int retval = -1;				/* Function return value */
+
+    /* Setup some basic values */
+    length = (size / 4) + 1;			/* size in words, rounding UP
+						    is OK */
+    source = (unsigned long *)saddr;
+    dest = (unsigned short *)daddr;
+
+    /* Get DCR output register */
+    grego = in32(IBM405GP_GPIO0_OR);
+
+    /* Reset FPGA */
+    grego &= ~GPIO_XCV_PROG;			/* PROG line low */
+    out32(IBM405GP_GPIO0_OR, grego);
+
+    /* Setup timeout timer */
+    start = get_timer(0);
+
+    /* Wait for FPGA init line */
+    while(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT) { /* Wait INIT line low */
+        /* Check for timeout - 100us max, so use 3ms */
+        if (get_timer(start) > 3) {
+            printf("     failed to start init.\n");
+            log_warn(ERR_XINIT0);		/* Don't halt */
+
+            /* Reset line stays low */
+            goto done;				/* I like gotos... */
+        }
+    }
+
+    /* Unreset FPGA */
+    grego |= GPIO_XCV_PROG;			/* PROG line high */
+    out32(IBM405GP_GPIO0_OR, grego);
+
+    /* Wait for FPGA end of init period .  */
+    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT)) { /* Wait for INIT hi */
+
+        /* Check for timeout */
+        if (get_timer(start) > 3) {
+            printf("     failed to exit init.\n");
+            log_warn(ERR_XINIT1);
+
+            /* Reset FPGA */
+            grego &= ~GPIO_XCV_PROG;		/* PROG line low */
+            out32(IBM405GP_GPIO0_OR, grego);
+
+            goto done;
+        }
+    }
+
+    /* Now program FPGA ... */
+    ndest = dest;
+    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+        /* Toggle IRQ/GPIO */
+        greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */
+        greg |= eirq;				/* toggle irq/gpio */
+        mtdcr(CPC0_CR0, greg);			/*  ... just do it */
+
+        /* turn on open drain for CNFG */
+        greg = in32(IBM405GP_GPIO0_ODR);	/* get open drain register */
+        greg |= cnfg;				/* CNFG open drain */
+        out32(IBM405GP_GPIO0_ODR, greg);	/*  .. just do it */
+
+        /* Turn output enable on for CNFG */
+        greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */
+        greg |= cnfg;				/* CNFG tristate inactive */
+        out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */
+
+        /* Setup FPGA for programming */
+        grego &= ~cnfg;				/* CONFIG line low */
+        out32(IBM405GP_GPIO0_OR, grego);
+
+        /*
+         * Program the FPGA
+         */
+        printf("\n       destination: 0x%lx ", (unsigned long)ndest);
+
+        fpga_img_write(source,  length,  (unsigned short *)ndest);
+
+        /* Done programming */
+        grego |= cnfg;				/* CONFIG line high */
+        out32(IBM405GP_GPIO0_OR, grego);
+
+        /* Turn output enable OFF for CNFG */
+        greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */
+        greg &= ~cnfg;				/* CNFG tristate inactive */
+        out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */
+
+        /* Toggle IRQ/GPIO */
+        greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */
+        greg &= ~eirq;				/* toggle irq/gpio */
+        mtdcr(CPC0_CR0, greg);			/*  ... just do it */
+
+        ndest = (unsigned short *)((char *)ndest + 0x00100000L); /* XXX - Next FPGA addr */
+        cnfg >>= 1;				/* XXX - Next  */
+        eirq >>= 1;
+    }
+
+    /* Terminate programming with 4 C clocks */
+    ndest = dest;
+    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+        val = *ndest;
+        val = *ndest;
+        val = *ndest;
+        val = *ndest;
+        ndest = (unsigned short *)((char *)ndest + 0x00100000L);
+    }
+
+    /* Setup timer */
+    start = get_timer(0);
+
+    /* Wait for FPGA end of programming period .  */
+    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_DONE)) { /* Test DONE low */
+
+        /* Check for timeout */
+        if (get_timer(start) > 3) {
+            printf("     done failed to come high.\n");
+            log_warn(ERR_XDONE1);
+
+            /* Reset FPGA */
+            grego &= ~GPIO_XCV_PROG;		/* PROG line low */
+            out32(IBM405GP_GPIO0_OR, grego);
+
+            goto done;
+        }
+    }
+
+    printf("\n       FPGA load succeeded\n");
+    retval = 0;					/* Program OK */
+
+done:
+    return retval;
+}
+
+/* FPGA image is stored in flash */
+extern flash_info_t    flash_info[];
+
+int init_fpga(void)
+{
+    unsigned int i,j,ptr;			/* General purpose */
+    unsigned char bufchar;			/* General purpose character */
+    unsigned char *buf;				/* Start of image pointer */
+    unsigned long len;				/* Length of image */
+    unsigned char *fn_buf;			/* Start of filename string */
+    unsigned int fn_len;			/* Length of filename string */
+    unsigned char *xcv_buf;			/* Pointer to start of image */
+    unsigned long xcv_len;			/* Length of image */
+    unsigned long crc;				/* 30bit crc in image */
+    unsigned long calc_crc;			/* Calc'd 30bit crc */
+    int retval = -1;
+
+    /* Tell the world what we are doing */
+    printf("FPGA:  ");
+
+    /*
+     * Get address of first sector where the FPGA
+     * image is stored.
+     */
+    buf = (unsigned char *)flash_info[1].start[0];
+
+    /*
+     * Get the stored image's CRC & length.
+     */
+    crc = *(unsigned long *)(buf+4);		/* CRC is first long word */
+    len = *(unsigned long *)(buf+8);		/* Image len is next long */
+
+    /* Pedantic */
+    if ((len < 0x133A4) || (len > 0x80000))
+        goto bad_image;
+
+    /*
+     * Get the file name pointer and length.
+     */
+    fn_len = (*(unsigned short *)(buf+12) & 0xff); /* filename length
+						      is next short */
+    fn_buf = buf + 14;
+
+    /*
+     * Get the FPGA image pointer and length length.
+     */
+    xcv_buf = fn_buf + fn_len;			/* pointer to fpga image */
+    xcv_len = len - 14 - fn_len;		/* fpga image length */
+
+    /* Check for uninitialized FLASH */
+    if ((strncmp(buf, "w7o", 3)!=0) || (len > 0x0007ffffL) || (len == 0))
+	goto bad_image;
+
+    /*
+     * Calculate and Check the image's CRC.
+     */
+    calc_crc = crc32(0, xcv_buf, xcv_len);
+    if (crc != calc_crc) {
+        printf("\nfailed - bad CRC\n");
+        goto done;
+    }
+
+    /* Output the file name */
+    printf("file name  : ");
+    for (i=0;i<fn_len;i++) {
+        bufchar = fn_buf[+i];
+        if (bufchar<' ' || bufchar>'~') bufchar = '.';
+        putc(bufchar);
+    }
+
+    /*
+     * find rest of display data
+     */
+    ptr = 15;					/* Offset to ncd filename
+						   length in fpga image */
+    j = xcv_buf[ptr];				/* Get len of ncd filename */
+    if (j > 32) goto bad_image;
+    ptr = ptr + j + 3;				/* skip ncd filename string +
+						   3 bytes more bytes */
+
+    /*
+     * output target device string
+     */
+    j = xcv_buf[ptr++] - 1;			/* len of targ str less term */
+    if (j > 32) goto bad_image;
+    printf("\n       target     : ");
+    for (i = 0; i < j; i++) {
+	bufchar = (xcv_buf[ptr++]);
+	if (bufchar<' ' || bufchar>'~') bufchar = '.';
+	putc(bufchar);
+    }
+
+    /*
+     * output compilation date string and time string
+     */
+    ptr += 3;					/* skip 2 bytes */
+    printf("\n       synth time : ");
+    j = (xcv_buf[ptr++] - 1);			/* len of date str less term */
+    if (j > 32) goto bad_image;
+    for (i = 0; i < j; i++) {
+	bufchar = (xcv_buf[ptr++]);
+	if (bufchar<' ' || bufchar>'~') bufchar = '.';
+	putc(bufchar);
+    }
+
+    ptr += 3;					/* Skip 2 bytes */
+    printf(" - ");
+    j = (xcv_buf[ptr++] - 1);			/* slen = targ dev str len */
+    if (j > 32) goto bad_image;
+    for (i = 0; i < j; i++) {
+	bufchar = (xcv_buf[ptr++]);
+	if (bufchar<' ' || bufchar>'~') bufchar = '.';
+	putc(bufchar);
+    }
+
+    /*
+     * output crc and length strings
+     */
+    printf("\n       len & crc  : 0x%lx  0x%lx", len, crc);
+
+    /*
+     * Program the FPGA.
+     */
+    retval = fpgaDownload((unsigned char*)xcv_buf, xcv_len,
+                          (unsigned short *)0xfd000000L);
+    return retval;
+
+bad_image:
+    printf("\n       BAD FPGA image format @ %lx\n", flash_info[1].start[0]);
+    log_warn(ERR_XIMAGE);
+done:
+    return retval;
+}
+
+void test_fpga(unsigned short *daddr)
+{
+    int i;
+    volatile unsigned short *ndest = daddr;
+
+    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
+#if defined(CONFIG_W7OLMG)
+	ndest[0x7e] = 0x55aa;
+	if (ndest[0x7e] != 0x55aa)
+	    log_warn(ERR_XRW1 + i);
+	ndest[0x7e] = 0xaa55;
+	if (ndest[0x7e] != 0xaa55)
+	    log_warn(ERR_XRW1 + i);
+	ndest[0x7e] = 0xc318;
+	if (ndest[0x7e] != 0xc318)
+	    log_warn(ERR_XRW1 + i);
+
+#elif defined(CONFIG_W7OLMC)
+	ndest[0x800] = 0x55aa;
+	ndest[0x801] = 0xaa55;
+	ndest[0x802] = 0xc318;
+	ndest[0x4800] = 0x55aa;
+	ndest[0x4801] = 0xaa55;
+	ndest[0x4802] = 0xc318;
+	if ((ndest[0x800] != 0x55aa) ||
+	    (ndest[0x801] != 0xaa55) ||
+	    (ndest[0x802] != 0xc318))
+	    log_warn(ERR_XRW1 + (2 * i));       /* Auto gen error code */
+	if ((ndest[0x4800] != 0x55aa) ||
+	    (ndest[0x4801] != 0xaa55) ||
+	    (ndest[0x4802] != 0xc318))
+	    log_warn(ERR_XRW2 + (2 * i));       /* Auto gen error code */
+
+#else
+# error "Unknown W7O board configuration"
+#endif
+    }
+
+    printf("       FPGA ready\n");
+    return;
+}
+
diff --git a/board/w7o/init.S b/board/w7o/init.S
new file mode 100644
index 0000000..0abf21f
--- /dev/null
+++ b/board/w7o/init.S
@@ -0,0 +1,264 @@
+/******************************************************************************
+ *
+ *	 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>
+
+#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/******************************************************************************
+ * Function:	ext_bus_cntlr_init
+ *
+ * Description:	Configures EBC Controller and a few basic chip selects.
+ *
+ *		CS0 is setup to get the Boot Flash out of the addresss range
+ *		so that we may setup a stack.  CS7 is setup so that we can
+ *		access and reset the hardware watchdog.
+ *
+ *		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.
+ *
+ * Notes:	Does NOT use the stack.
+ *****************************************************************************/
+	.section ".text"
+	.align	2
+	.globl	ext_bus_cntlr_init
+	.type	ext_bus_cntlr_init, @function
+ext_bus_cntlr_init:
+	mflr	r0
+	/********************************************************************
+	 * Prefetch entire ext_bus_cntrl_init function into the icache.
+	 * This is necessary because we are going to change the same CS we
+	 * are executing from.  Otherwise a CPU lockup may occur.
+	 *******************************************************************/
+	bl	..getAddr
+..getAddr:
+	mflr	r3			/* get address of ..getAddr */
+
+	/* Calculate number of cache lines for this function */
+	addi	r4, 0, (((.Lfe0 - ..getAddr) / CFG_CACHELINE_SIZE) + 2)
+	mtctr	r4
+..ebcloop:
+	icbt	r0, r3			/* prefetch cache line for addr in r3*/
+	addi	r3, r3, CFG_CACHELINE_SIZE /* move to next cache line */
+	bdnz	..ebcloop		/* continue for $CTR cache lines */
+
+	/********************************************************************
+	 * Delay to ensure all accesses to ROM are complete before changing
+	 * bank 0 timings. 200usec should be enough.
+	 * 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles.
+	 *******************************************************************/
+	addis	r3, 0, 0x0
+	ori	r3, r3, 0xA000		/* wait 200us from reset */
+	mtctr	r3
+..spinlp:
+	bdnz	..spinlp		/* spin loop */
+
+	/********************************************************************
+	 * Setup External Bus Controller (EBC).
+	 *******************************************************************/
+	addi	r3, 0, epcr
+	mtdcr	ebccfga, r3
+	addis	r4, 0, 0xb040		/* Device base timeout = 1024 cycles */
+	ori	r4, r4, 0x0		/* Drive CS with external master */
+	mtdcr	ebccfgd, r4
+
+	/********************************************************************
+	 * Change PCIINT signal to PerWE
+	 *******************************************************************/
+	mfdcr	r4, cntrl1
+	ori	r4, r4, 0x4000
+	mtdcr	cntrl1, r4
+
+	/********************************************************************
+	 * Memory Bank 0 (Flash Bank 0) initialization
+	 *******************************************************************/
+	addi	r3, 0, pb0ap
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB0AP@h
+	ori	r4, r4, CFG_W7O_EBC_PB0AP@l
+	mtdcr	ebccfgd, r4
+
+	addi	r3, 0, pb0cr
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB0CR@h
+	ori	r4, r4, CFG_W7O_EBC_PB0CR@l
+	mtdcr	ebccfgd, r4
+
+	/********************************************************************
+	 * Memory Bank 7 LEDs - NEEDED BECAUSE OF HW WATCHDOG AND LEDs.
+	 *******************************************************************/
+	addi	r3, 0, pb7ap
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB7AP@h
+	ori	r4, r4, CFG_W7O_EBC_PB7AP@l
+	mtdcr	ebccfgd, r4
+
+	addi	r3, 0, pb7cr
+	mtdcr	ebccfga, r3
+	addis	r4, 0, CFG_W7O_EBC_PB7CR@h
+	ori	r4, r4, CFG_W7O_EBC_PB7CR@l
+	mtdcr	ebccfgd, r4
+
+	/* We are all done */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+.Lfe0:	.size	ext_bus_cntlr_init,.Lfe0-ext_bus_cntlr_init
+/* end ext_bus_cntlr_init() */
+
+/******************************************************************************
+ * Function:	sdram_init
+ *
+ * Description:	Configures SDRAM memory banks.
+ *
+ *		Serial Presence Detect, "SPD," reads the SDRAM EEPROM
+ *		via the IIC bus and then configures the SDRAM memory
+ *		banks appropriately. If Auto Memory Configuration is
+ *		is not used, it is assumed that a 4MB 11x8x2, non-ECC,
+ *		SDRAM is soldered down.
+ *
+ * Notes:	Expects that the stack is already setup.
+ *****************************************************************************/
+	.section ".text"
+	.align	2
+	.globl	sdram_init
+	.type	sdram_init, @function
+sdram_init:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -8(r1)		/* Save back chain and move SP */
+	stw	r0, +12(r1)		/* Save link register */
+
+	/*
+	 * First call spd_sdram to try to init SDRAM according to the
+	 * contents of the SPD EEPROM.  If the SPD EEPROM is blank or
+	 * erronious, spd_sdram returns 0 in R3.
+	 */
+	bl	spd_sdram
+	addic.	r3, r3, 0		/* Check for error, save dram size */
+	bne	..sdri_done		/* If it worked, we're done... */
+
+	/********************************************************************
+	 * If SPD detection fails, we'll default to 4MB, 11x8x2, as this
+	 * is the SMALLEST SDRAM size the 405 supports.  We can do this
+	 * because W7O boards have soldered on RAM, and there will always
+	 * be some amount present.  If we were using DIMMs, we should hang
+	 * the board instead, since it doesn't have any RAM to continue
+	 * running with.
+	 *******************************************************************/
+
+	/*
+	 * Disable memory controller to allow
+	 * values to be changed.
+	 */
+	addi    r3, 0, mem_mcopt1
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x0
+	ori     r4, r4, 0x0
+	mtdcr   memcfgd, r4
+
+	/*
+	 * Set MB0CF for ext bank 0. (0-4MB) Address Mode 5 since 11x8x2
+	 * All other banks are disabled.
+	 */
+	addi	r3, 0, mem_mb0cf
+	mtdcr	memcfga, r3
+	addis	r4, 0, 0x0000		/* BA=0x0, SZ=4MB */
+	ori	r4, r4, 0x8001		/* Mode is 5, 11x8x2or4, BE=Enabled */
+	mtdcr	memcfgd, r4
+
+	/* Clear MB1CR,MB2CR,MB3CR to turn other banks off */
+	addi	r4, 0, 0		/* Zero the data reg */
+
+	addi	r3, r3, 4		/* Point to MB1CF reg */
+	mtdcr	memcfga, r3		/* Set the address */
+	mtdcr	memcfgd, r4		/* Zero the reg */
+
+	addi	r3, r3, 4		/* Point to MB2CF reg */
+	mtdcr	memcfga, r3		/* Set the address */
+	mtdcr	memcfgd, r4		/* Zero the reg */
+
+	addi	r3, r3, 4		/* Point to MB3CF reg */
+	mtdcr	memcfga, r3		/* Set the address */
+	mtdcr	memcfgd, r4		/* Zero the reg */
+
+	/********************************************************************
+	 * Set the SDRAM Timing reg, SDTR1 and the refresh timer reg, RTR.
+	 * To set the appropriate timings, we assume sdram is
+	 * 100MHz (pc100 compliant).
+	 *******************************************************************/
+
+	/*
+	 * Set up SDTR1
+	 */
+	addi    r3, 0, mem_sdtr1
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x0086		/* SDTR1 value for 100Mhz */
+	ori     r4, r4, 0x400D
+	mtdcr   memcfgd, r4
+
+	/*
+	 * Set RTR
+	 */
+	addi    r3, 0, mem_rtr
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x05F0		/* RTR refresh val = 15.625ms@100Mhz */
+	mtdcr   memcfgd, r4
+
+	/********************************************************************
+	 * 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		/* Wait 200us from reset */
+	mtctr   r3
+..spinlp2:
+	bdnz    ..spinlp2		/* spin loop */
+
+	/********************************************************************
+	 * Set memory controller options reg, MCOPT1.
+	 *******************************************************************/
+	addi    r3, 0, mem_mcopt1
+	mtdcr   memcfga, r3
+	addis   r4, 0, 0x80E0		/* DC_EN=1,SRE=0,PME=0,MEMCHK=0 */
+	ori     r4, r4, 0x0000		/* REGEN=0,DRW=00,BRPF=01,ECCDD=1 */
+	mtdcr   memcfgd, r4		/* EMDULR=1 */
+
+..sdri_done:
+	/* restore and return */
+	lwz	r0, +12(r1)		/* Get saved link register */
+	addi	r1, r1, +8		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+.Lfe1:	.size	sdram_init,.Lfe1-sdram_init
+/* end sdram_init() */
+
diff --git a/board/w7o/post1.S b/board/w7o/post1.S
new file mode 100644
index 0000000..d510cca
--- /dev/null
+++ b/board/w7o/post1.S
@@ -0,0 +1,745 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
+ *  and
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
+ *
+ * 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
+ */
+/*
+ * Description:
+ *	Routine to exercise memory for the bringing up of our boards.
+ */
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1       /* avoid reading Linux autoconf.h file  */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#include <watchdog.h>
+
+#include "errors.h"
+
+#define _ASMLANGUAGE
+
+	.globl	test_sdram
+	.globl	test_led
+	.globl	log_stat
+	.globl	log_warn
+	.globl	log_err
+	.globl  temp_uart_init
+	.globl  post_puts
+	.globl  disp_hex
+
+/*****************************************************
+*******   Text Strings for low level printing   ******
+*******          In section got2               *******
+*****************************************************/
+
+/*
+ * Define the text strings for errors and warnings.
+ * Switch to .data section.
+ */
+	.section ".data"
+err_str: 	.asciz "*** POST ERROR   = "
+warn_str:	.asciz "*** POST WARNING = "
+end_str:  .asciz "\r\n"
+
+/*
+ * Enter the labels in Global Entry Table (GOT).
+ * Switch to .got2 section.
+ */
+	START_GOT
+	GOT_ENTRY(err_str)
+	GOT_ENTRY(warn_str)
+	GOT_ENTRY(end_str)
+	END_GOT
+
+/*
+ * Switch  back to .text section.
+ */
+	.text
+
+/****************************************
+ ****************************************
+ ********    LED register test   ********
+ ****************************************
+ ***************************************/
+test_led:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	WATCHDOG_RESET        		/* Reset the watchdog */
+
+	addi    r3, 0, ERR_FF		/* first test value is ffff */
+	addi	r4, r3, 0		/* save copy of pattern */
+	bl	set_led			/* store first test value */
+	bl	get_led			/* read it back */
+	xor.	r4, r4, r3		/* compare to original */
+#if defined(CONFIG_W7OLMC)
+	andi.   r4, r4, 0x00ff		/* lmc has 8 bits */
+#else
+	andi.   r4, r4, 0xffff		/* lmg has 16 bits */
+#endif
+	beq     LED2			/* next test */
+	addi    r3, 0, ERR_LED		/* error code = 1 */
+	bl	log_err			/* display error and halt */
+LED2:	addi    r3, 0, ERR_00		/* 2nd test value is 0000 */
+	addi	r4, r3, 0		/* save copy of pattern */
+	bl	set_led			/* store first test value */
+	bl	get_led			/* read it back */
+	xor.	r4, r4, r3		/* compare to original */
+#if defined(CONFIG_W7OLMC)
+	andi.   r4, r4, 0x00ff		/* lmc has 8 bits */
+#else
+	andi.   r4, r4, 0xffff		/* lmg has 16 bits */
+#endif
+	beq     LED3			/* next test */
+	addi    r3, 0, ERR_LED		/* error code = 1 */
+	bl	log_err			/* display error and halt */
+
+LED3:	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/****************************************
+ ****************************************
+ ********     SDRAM TESTS        ********
+ ****************************************
+ ***************************************/
+test_sdram:
+	/* called with mem size in r3 */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stmw	r30, +8(r1)		/* save R30,R31 */
+					/* r30 is log2(mem size) */
+					/* r31 is mem size */
+
+	/* take log2 of total mem size */
+	addi	r31, r3, 0		/* save total mem size */
+	addi	r30, 0, 0		/* clear r30 */
+l2_loop:
+	srwi.	r31, r31, 1		/* shift right 1 */
+	addi	r30, r30, 1		/* count shifts */
+	bne	l2_loop			/* loop till done */
+	addi	r30, r30, -1		/* correct for over count */
+	addi	r31, r3, 0		/* save original size */
+
+	/* now kick the dog and test the mem */
+	WATCHDOG_RESET        		/* Reset the watchdog */
+	bl	Data_Buster		/* test crossed/shorted data lines */
+	addi	r3, r30, 0		/* get log2(memsize) */
+	addi	r4, r31, 0		/* get memsize */
+	bl	Ghost_Buster		/* test crossed/shorted addr lines */
+	addi	r3, r31, 0		/* get mem size */
+	bl	Bit_Buster		/* check for bad internal bits */
+
+	/* restore stack and return */
+	lmw	r30, +8(r1)		/* Restore r30, r31 */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+
+/****************************************
+ ********  sdram data bus test   ********
+ ***************************************/
+Data_Buster:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -24(r1)		/* Save back chain and move SP */
+	stw	r0, +28(r1)		/* Save link register */
+	stmw	r28, 8(r1)		/* save r28 - r31 on stack */
+					/* r31 i/o register */
+					/* r30 sdram base address */
+					/* r29 5555 syndrom */
+					/* r28 aaaa syndrom */
+
+	/* set up led register for this test */
+	addi    r3, 0, ERR_RAMG		/* set led code to 1 */
+	bl	log_stat		/* store test value */
+	/* now test the dram data bus */
+	xor	r30, r30, r30		/* load r30 with base addr of sdram */
+	addis	r31, 0, 0x5555		/* load r31 with test value */
+	ori	r31, r31, 0x5555
+	stw	r31,0(r30)		/* sto the value */
+	lwz	r29,0(r30)		/* read it back */
+	xor	r29,r31,r29		/* compare it to original */
+	addis	r31, 0, 0xaaaa		/* load r31 with test value */
+	ori	r31, r31, 0xaaaa
+	stw	r31,0(r30)		/* sto the value */
+	lwz	r28,0(r30)		/* read it back */
+	xor	r28,r31,r28		/* compare it to original */
+	or	r3,r28,r29		/* or together both error terms */
+	/*
+	 * Now that we have the error bits,
+	 * we have to decide which part they are in.
+	 */
+	bl	get_idx			/* r5 is now index to error */
+	addi	r3, r3, ERR_RAMG
+	cmpwi	r3, ERR_RAMG		/* check for errors */
+	beq	db_done			/* skip if no errors */
+	bl	log_err			/* log the error */
+
+db_done:
+	lmw	r28, 8(r1)		/* restore r28 - r31 from stack */
+	lwz	r0, +28(r1)		/* Get saved link register */
+	addi	r1, r1, +24		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+/****************************************************
+ ********  test for address ghosting in dram ********
+ ***************************************************/
+
+Ghost_Buster:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -36(r1)		/* Save back chain and move SP */
+	stw	r0, +40(r1)		/* Save link register */
+	stmw	r25, 8(r1)		/* save r25 - r31 on stack */
+					/* r31 = scratch register */
+					/* r30 is main referance loop counter,
+					   0 to 23 */
+					/* r29 is ghost loop count, 0 to 22 */
+					/* r28 is referance address */
+					/* r27 is ghost address */
+					/* r26 is log2 (mem size) =
+					     number of byte addr bits */
+					/* r25 is mem size */
+
+	/* save the log2(mem size) and mem size */
+	addi	r26, r3, 0		/* r26 is number of byte addr bits */
+	addi	r25, r4, 0		/* r25 is mem size in bytes */
+
+	/* set the leds for address ghost test */
+	addi	r3, 0, ERR_ADDG
+	bl	set_led
+
+	/* first fill memory with zeros */
+	srwi	r31, r25, 2		/* convert bytes to longs */
+	mtctr	r31			/* setup byte counter */
+	addi	r28, 0, 0		/* start at address at 0 */
+	addi	r31, 0, 0		/* data value = 0 */
+clr_loop:
+	stw	r31, 0(r28)		/* Store zero value */
+	addi	r28, r28, 4		/* Increment to next word */
+	andi.	r27, r28, 0xffff	/* check for 2^16 loops */
+	bne	clr_skip		/* if not there, then skip */
+	WATCHDOG_RESET   		/* kick the dog every now and then */
+clr_skip:
+	bdnz	clr_loop		/* Round and round... */
+
+	/* now do main test */
+	addi	r30, 0, 0		/* start referance counter at 0 */
+outside:
+	/*
+	 * Calculate the referance address
+	 *   the referance address is calculated by setting the (r30-1)
+	 *   bit of the base address
+	 * when r30=0, the referance address is the base address.
+	 * thus the sequence 0,1,2,4,8,..,2^(n-1)
+	 * setting the bit is done with the following shift functions.
+	 */
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	addi	r31, 0, 1		/* r31 = 1 */
+	slw	r28, r31, r30		/* set bit coresponding to loop cnt */
+	srwi	r28, r28, 1		/* then shift it right one so  */
+					/*   we start at location 0 */
+	/* fill referance address with Fs */
+	addi	r31, 0, 0x00ff		/* r31 = one byte of set bits */
+	stb     r31,0(r28)		/* save ff in referance address */
+
+        /* ghost (inner) loop, now check all posible ghosted addresses */
+	addi	r29, 0, 0		/* start ghosted loop counter at 0 */
+inside:
+	/*
+	 * Calculate the ghost address by flipping one
+	 *  bit of referance address.  This gives the
+	 *  sequence 1,2,4,8,...,2^(n-1)
+	 */
+	addi	r31, 0, 1		/* r31 = 1 */
+	slw     r27, r31, r29		/* set  bit coresponding to loop cnt */
+	xor	r27, r28, r27		/* ghost address = ref addr with
+					     bit flipped*/
+
+	/* now check for ghosting */
+	lbz     r31,0(r27)		/* get content of ghost addr */
+	cmpwi   r31, 0			/* compare read value to 0 */
+	bne	Casper			/*   we found a ghost! */
+
+	/* now close ghost ( inner ) loop */
+	addi 	r29, r29, 1		/* increment inner loop counter */
+	cmpw 	r29, r26		/* check for last inner loop */
+	blt		inside		/* do more inner loops */
+
+	/* now close referance ( outer ) loop */
+	addi 	r31, 0, 0 		/* r31 = zero */
+	stb	r31, 0(28)		/* zero out the altered address loc. */
+	/*
+	 * Increment and check for end, count is zero based.
+	 * With the ble, this gives us one more loops than
+	 * address bits for sequence 0,1,2,4,8,...2^(n-1)
+	*/
+	addi 	r30, r30, 1		/* increment outer loop counter */
+	cmpw 	r30, r26		/* check for last inner loop */
+	ble	outside			/* do more outer loops */
+
+	/* were done, lets go home */
+	b	gb_done
+Casper:					/* we found a ghost !! */
+	addi	r3, 0, ERR_ADDF		/* get indexed error message */
+	bl	log_err			/* log error led error code */
+gb_done: /*  pack your bags, and go home */
+        lmw     r25, 8(r1)              /* restore r25 - r31 from stack */
+        lwz     r0, +40(r1)             /* Get saved link register */
+        addi    r1, r1, +36             /* Remove frame from stack */
+        mtlr    r0                      /* Restore link register */
+        blr                             /* Return to calling function */
+
+/****************************************************
+ ********      SDRAM data fill tests       **********
+ ***************************************************/
+Bit_Buster:
+	/* called with mem size in r3 */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+	stw	r5, +12(r1)		/* save r5 */
+
+	addis	r5, r3, 0		/* save mem size */
+
+	/* Test 55555555 */
+	addi	r3, 0, ERR_R55G		/* set up error code in case we fail */
+	bl	log_stat		/* store test value */
+	addis	r4, 0, 0x5555
+	ori	r4, r4, 0x5555
+	bl	fill_test
+
+	/* Test aaaaaaaa  */
+	addi	r3, 0, ERR_RAAG		/* set up error code in case we fail */
+	bl	log_stat		/* store test value */
+	addis	r4, 0, 0xAAAA
+	ori	r4, r4, 0xAAAA
+	bl	fill_test
+
+	/* Test 00000000  */
+	addi	r3, 0, ERR_R00G		/* set up error code in case we fail */
+	bl	log_stat		/* store test value */
+	addis	r4, 0, 0
+	ori	r4, r4, 0
+	bl	fill_test
+
+	/* restore stack and return */
+	lwz	r5, +12(r1)		/* restore r4 */
+	lwz	r4, +8(r1)		/* restore r4 */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+
+/****************************************************
+ ********             fill test              ********
+ ***************************************************/
+/*	tests memory by filling with value, and reading back */
+/*	r5 = Size of memory in bytes */
+/*	r4 = Value to write */
+/*	r3 = Error code */
+fill_test:
+        mflr    r0                      /* Get link register */
+        stwu    r1, -32(r1)             /* Save back chain and move SP */
+        stw     r0, +36(r1)             /* Save link register */
+        stmw    r27, 8(r1)              /* save r27 - r31 on stack */
+                                        /* r31 - scratch register */
+                                        /* r30 - memory address */
+	mr	r27, r3
+	mr	r28, r4
+	mr	r29, r5
+
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	/* first fill memory with Value */
+	srawi	r31, r29, 2		/* convert bytes to longs */
+	mtctr	r31			/* setup counter */
+	addi	r30, 0, 0		/* Make r30 = addr 0 */
+ft_0:	stw	r28, 0(r30)		/* Store value */
+	addi	r30, r30, 4		/* Increment to next word */
+	andi.	r31, r30, 0xffff	/* check for 2^16 loops */
+	bne	ft_0a			/* if not there, then skip */
+	WATCHDOG_RESET   		/* kick the dog every now and then */
+ft_0a:	bdnz	ft_0			/* Round and round... */
+
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	/* Now confirm Value is in memory */
+	srawi	r31, r29, 2		/* convert bytes to longs */
+	mtctr	r31			/* setup counter */
+	addi	r30, 0, 0		/* Make r30 = addr 0 */
+ft_1:	lwz	r31, 0(r30)		/* get value from memory */
+        xor.	r31, r31, r28		/* Writen = Read ? */
+        bne	ft_err			/* If bad, than halt */
+	addi	r30, r30, 4		/* Increment to next word */
+	andi.	r31, r30, 0xffff	/* check for 2^16 loops*/
+	bne	ft_1a			/* if not there, then skip */
+	WATCHDOG_RESET			/* kick the dog every now and then */
+ft_1a:	bdnz	ft_1			/* Round and round... */
+
+	WATCHDOG_RESET   		/* Reset the watchdog */
+
+	b	fill_done		/* restore and return */
+
+ft_err:	addi	r29, r27, 0		/* save current led code */
+	addi	r27, r31, 0		/* get pattern in r27 */
+	bl	get_idx			/* get index from r27 */
+	add	r27, r27, r29		/* add index to old led code */
+	bl	log_err			/* output led err code, halt CPU */
+
+fill_done:
+        lmw     r27, 8(r1)              /* restore r27 - r31 from stack */
+        lwz     r0, +36(r1)             /* Get saved link register */
+        addi    r1, r1, +32             /* Remove frame from stack */
+        mtlr    r0                      /* Restore link register */
+        blr                             /* Return to calling function */
+
+
+/****************************************************
+ *******  get error index from r3 pattern    ********
+ ***************************************************/
+get_idx:				/* r3 = (MSW(r3) !=0)*2 +
+					    (LSW(r3) !=0) */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	andi.	r4, r3, 0xffff		/* check for lower bits */
+	beq	gi2			/* skip if no bits set */
+	andis.	r4, r3, 0xffff		/* check for upper bits */
+	beq	gi3			/* skip if no bits set */
+	addi	r3, 0, 3		/* both upper and lower bits set */
+	b	gi_done
+gi2:	andis.	r4, r3, 0xffff		/* check for upper bits*/
+	beq	gi4			/* skip if no bits set */
+	addi	r3, 0, 2		/* only upper bits set */
+	b	gi_done
+gi3:	addi	r3, 0, 1		/* only lower bits set */
+	b	gi_done
+gi4:	addi	r3, 0, 0		/* no bits set */
+gi_done:
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/****************************************************
+ ********       set LED to R5 and hang       ********
+ ***************************************************/
+log_stat:				/* output a led code and continue */
+set_led:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	addis	r4, 0, 0xfe00		/* LED buffer is at 0xfe000000 */
+#if defined(CONFIG_W7OLMG)		/* only on gateway, invert outputs */
+	xori	r3,r3, 0xffff		/* complement led code, active low */
+	sth	r3, 0(r4)		/* store first test value */
+	xori	r3,r3, 0xffff		/* complement led code, active low */
+#else					/* if not gateway, then don't invert */
+	sth	r3, 0(r4)		/* store first test value */
+#endif
+
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+get_led:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r4, +8(r1)		/* save R4 */
+
+	addis	r4, 0, 0xfe00		/* LED buffer is at 0xfe000000 */
+	lhz	r3, 0(r4)		/* store first test value */
+#if defined(CONFIG_W7OLMG)		/* only on gateway, invert inputs */
+	xori	r3,r3, 0xffff		/* complement led code, active low */
+#endif
+
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	lwz	r4, +8(r1)		/* restore r4 */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+log_err:	/* output the error and hang the board ( for now ) */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r3, +8(r1)		/* save a copy of error code */
+	bl	set_led			/* set the led pattern */
+	GET_GOT				/* get GOT address in r14 */
+	lwz	r3,GOT(err_str)		/* get address of string */
+	bl	post_puts		/* output the warning string */
+	lwz	r3, +8(r1)		/* get error code */
+	addi	r4, 0, 2		/* set disp length to 2 nibbles */
+	bl	disp_hex		/* output the error code */
+	lwz	r3,GOT(end_str)		/* get address of string */
+	bl	post_puts		/* output the warning string */
+halt:
+	b	halt			/* hang */
+
+	/* restore stack and return */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+log_warn:	/* output a warning, then continue with operations */
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stw	r3, +8(r1)		/* save a copy of error code */
+	stw	r14, +12(r1)		/* save a copy of r14 (used by GOT) */
+
+	bl	set_led			/* set the led pattern */
+	GET_GOT				/* get GOT address in r14 */
+	lwz	r3,GOT(warn_str)	/* get address of string */
+	bl	post_puts		/* output the warning string */
+	lwz	r3, +8(r1)		/* get error code */
+	addi	r4, 0, 2		/* set disp length to 2 nibbles */
+	bl	disp_hex		/* output the error code */
+	lwz	r3,GOT(end_str)		/* get address of string */
+	bl	post_puts		/* output the warning string */
+
+	addis	r3, 0, 64		/* has a long delay */
+	mtctr	r3
+log_2:
+	WATCHDOG_RESET			/* this keeps dog from barking, */
+				     	/*   and takes time */
+	bdnz	log_2			/* loop till time expires */
+
+	/* restore stack and return */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	lwz	r14, +12(r1)		/* restore r14 */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/*******************************************************************
+ *	temp_uart_init
+ *	Temporary UART initialization routine
+ *	Sets up UART0 to run at 9600N81 off of the internal clock.
+ *	R3-R4 are used.
+ ******************************************************************/
+temp_uart_init:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -8(r1)		/* Save back chain and move SP */
+	stw	r0, +12(r1)		/* Save link register */
+
+        addis   r3, 0, 0xef60
+        ori     r3, r3, 0x0303          /* r3 = UART0_LCR */
+        addi    r4, 0, 0x83             /* n81 format, divisor regs enabled */
+        stb     r4, 0(r3)
+
+	/* set baud rate to use internal clock,
+	   baud = (200e6/16)/31/42 = 9600 */
+
+        addis   r3, 0, 0xef60		/* Address of baud divisor reg */
+        ori     r3, r3, 0x0300		/*   UART0_DLM */
+        addi    r4, 0, +42		/* uart baud divisor LSB = 93 */
+        stb     r4, 0(r3)               /* baud = (200 /16)/14/93 */
+
+        addi    r3, r3, 0x0001		/* uart baud divisor addr */
+        addi    r4, 0, 0
+        stb     r4, 0(r3)               /* Divisor Latch MSB = 0 */
+
+        addis   r3, 0, 0xef60
+        ori     r3, r3, 0x0303          /* r3 = UART0_LCR */
+        addi    r4, 0, 0x03             /* n81 format, tx/rx regs enabled */
+        stb     r4, 0(r3)
+
+	/* output a few line feeds */
+	addi	r3, 0, '\n'		/* load line feed */
+	bl 	post_putc		/* output the char */
+	addi	r3, 0, '\n'		/* load line feed */
+	bl 	post_putc		/* output the char */
+
+        /* restore stack and return */
+	lwz	r0, +12(r1)		/* Get saved link register */
+	mtlr	r0			/* Restore link register */
+	addi	r1, r1, +8		/* Remove frame from stack */
+	blr				/* Return to calling function */
+
+/**********************************************************************
+ **	post_putc
+ **	outputs charactor in R3
+ **	r3 returns the error code ( -1 if there is an error )
+ *********************************************************************/
+
+post_putc:
+
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -20(r1)		/* Save back chain and move SP */
+	stw	r0, +24(r1)		/* Save link register */
+	stmw	r29, 8(r1)		/* save	r29 - r31 on stack
+					   r31 - uart base address
+       					   r30 - delay counter
+					   r29 - scratch reg */
+
+     addis   r31, 0, 0xef60		/* Point to uart base */
+     ori     r31, r31, 0x0300
+     addis   r30, 0, 152 		/* Load about 10,000,000 ticks. */
+pputc_lp:
+	lbz     r29, 5(r31) 		/* Read Line Status Register */
+	andi.   r29, r29, 0x20		/* Check THRE status */
+	bne     thre_set		/* Branch if FIFO empty */
+	addic.  r30, r30, -1		/* Decrement and check if empty. */
+	bne     pputc_lp		/* Try, try again */
+	addi    r3, 0, -1		/* Load error code for timeout */
+	b       pputc_done 		/* Bail out with error code set */
+thre_set:
+	stb     r3, 0(r31)		/* Store character to UART */
+	addi	r3, 0, 0		/* clear error code */
+pputc_done:
+	lmw	r29, 8(r1)		/*restore r29 - r31 from stack */
+	lwz	r0, +24(r1)		/* Get saved link register */
+	addi	r1, r1, +20		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+/****************************************************************
+    post_puts
+    Accepts a null-terminated string pointed to by R3
+    Outputs to the serial port until 0x00 is found.
+    r3 returns the error code ( -1 if there is an error )
+*****************************************************************/
+post_puts:
+
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -12(r1)		/* Save back chain and move SP */
+	stw	r0, +16(r1)		/* Save link register */
+	stw	r31, 8(r1)		/* save r31 - char pointer */
+
+	addi 	r31, r3, 0              /* move pointer to R31 */
+pputs_nxt:
+	lbz	r3, 0(r31)		/* Get next character */
+	addic.  r3, r3, 0		/* Check for zero */
+	beq	pputs_term		/* bail out if zero */
+	bl	post_putc		/* output the char */
+	addic.	r3, r3, 0		/* check for error */
+	bne	pputs_err
+	addi 	r31, r31, 1		/* point to next char */
+	b	pputs_nxt 		/* loop till term */
+pputs_err:
+	addi 	r3, 0, -1		/* set error code */
+	b	pputs_end		/* were outa here */
+pputs_term:
+	addi 	r3, 0, 1		/* set success code */
+ 	/* restore stack and return */
+pputs_end:
+	lwz	r31, 8(r1)		/* restore r27 - r31 from stack */
+	lwz	r0, +16(r1)		/* Get saved link register */
+	addi	r1, r1, +12		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
+
+
+/********************************************************************
+ *****	disp_hex
+ *****	Routine to display a hex value from a register.
+ *****	R3 is value to display
+ *****	R4 is number of nibbles to display ie 2 for byte 8 for (long)word
+ *****	Returns -1 in R3 if there is an error ( ie serial port hangs )
+ *****	Returns 0 in R3 if no error
+ *******************************************************************/
+disp_hex:
+	/* save the return info on stack */
+	mflr	r0			/* Get link register */
+	stwu	r1, -16(r1)		/* Save back chain and move SP */
+	stw	r0, +20(r1)		/* Save link register */
+	stmw	r30, 8(r1)		/* save r30 - r31 on stack */
+					/* r31 output char */
+					/* r30 uart base address */
+	addi 	r30, 0, 8               /* Go through 8 nibbles. */
+	addi 	r31, r3, 0
+pputh_nxt:
+	rlwinm	r31, r31, 4, 0, 31	/* Rotate next nibble into position */
+	andi. 	r3, r31, 0x0f		/* Get nibble. */
+	addi 	r3, r3, 0x30		/* Add zero's ASCII code. */
+	cmpwi	r3, 0x03a
+	blt	pputh_out
+	addi 	r3, r3, 0x07            /* 0x27 for lower case. */
+pputh_out:
+	cmpw 	r30, r4
+	bgt	pputh_skip
+	bl	post_putc
+	addic. 	r3, r3, 0 		/* check for error */
+	bne	pputh_err
+pputh_skip:
+	addic.	r30, r30, -1
+	bne	pputh_nxt
+	xor	r3, r3, r3		/* Clear error code */
+	b	pputh_done
+pputh_err:
+	addi 	r3, 0, -1 		/* set error code */
+pputh_done:
+        /* restore stack and return */
+	lmw	r30, 8(r1)		/*  restore r30 - r31 from stack */
+	lwz	r0, +20(r1)		/* Get saved link register */
+	addi	r1, r1, +16		/* Remove frame from stack */
+	mtlr	r0			/* Restore link register */
+	blr				/* Return to calling function */
+
diff --git a/board/w7o/post2.c b/board/w7o/post2.c
new file mode 100644
index 0000000..271c197
--- /dev/null
+++ b/board/w7o/post2.c
@@ -0,0 +1,109 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net
+ *   and
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * 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 <config.h>
+#include <rtc.h>
+#include "errors.h"
+#include "dtt.h"
+
+#if defined(CONFIG_RTC_M48T35A)
+void rtctest(void)
+{
+    volatile uchar *tchar = (uchar*)(CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 9);
+    struct rtc_time tmp;
+
+    /* set up led code for RTC tests */
+    log_stat(ERR_RTCG);
+
+    /*
+     * Do RTC battery test. The first write after power up
+     * fails if battery is low.
+     */
+    *tchar = 0xaa;
+    if ((*tchar ^ 0xaa) != 0x0) log_warn(ERR_RTCBAT);
+    *tchar = 0x55;				/* Reset test address */
+
+    /*
+     * Now lets check the validity of the values in the RTC.
+     */
+    rtc_get(&tmp);
+    if ((tmp.tm_sec < 0)	| (tmp.tm_sec  > 59)   |
+	(tmp.tm_min < 0)	| (tmp.tm_min  > 59)   |
+	(tmp.tm_hour < 0)	| (tmp.tm_hour > 23)   |
+	(tmp.tm_mday < 1 )	| (tmp.tm_mday > 31)   |
+	(tmp.tm_mon < 1 )	| (tmp.tm_mon  > 12)   |
+	(tmp.tm_year < 2000)	| (tmp.tm_year > 2500) |
+	(tmp.tm_wday < 1 )	| (tmp.tm_wday > 7)) {
+	log_warn(ERR_RTCTIM);
+	rtc_reset();
+    }
+
+    /*
+     * Now lets do a check to see if the NV RAM is there.
+     */
+    *tchar = 0xaa;
+    if ((*tchar ^ 0xaa) != 0x0) log_err(ERR_RTCVAL);
+    *tchar = 0x55;				/* Reset test address */
+
+} /* rtctest() */
+#endif	/* CONFIG_RTC_M48T35A */
+
+
+#ifdef CONFIG_DTT_LM75
+int dtt_test(int sensor)
+{
+    short temp, trip, hyst;
+
+    /* get values */
+    temp = dtt_read(sensor, DTT_READ_TEMP) / 256;
+    trip = dtt_read(sensor, DTT_TEMP_SET) / 256;
+    hyst = dtt_read(sensor, DTT_TEMP_HYST) / 256;
+
+    /* check values */
+    if ((hyst != (CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS)) ||
+	(trip != CFG_DTT_MAX_TEMP) ||
+	(temp < CFG_DTT_LOW_TEMP) || (temp > CFG_DTT_MAX_TEMP))
+	return 1;
+
+    return 0;
+} /* dtt_test() */
+#endif /* CONFIG_DTT_LM75 */
+
+/*****************************************/
+
+void post2(void)
+{
+#if defined(CONFIG_RTC_M48T35A)
+    rtctest();
+#endif	/* CONFIG_RTC_M48T35A */
+
+#ifdef CONFIG_DTT_LM75
+    log_stat(ERR_TempG);
+    if(dtt_test(2) != 0) log_warn(ERR_Ttest0);
+    if(dtt_test(4) != 0) log_warn(ERR_Ttest1);
+#endif /* CONFIG_DTT_LM75 */
+} /* post2() */
+
diff --git a/board/w7o/vpd.c b/board/w7o/vpd.c
new file mode 100644
index 0000000..c24b127
--- /dev/null
+++ b/board/w7o/vpd.c
@@ -0,0 +1,408 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * 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
+ */
+
+#if defined(VXWORKS)
+# include <stdio.h>
+# include <string.h>
+# define CFG_DEF_EEPROM_ADDR 0xa0
+extern char iicReadByte( char, char );
+extern ulong_t crc32( unsigned char *, unsigned long );
+#else
+#include <common.h>
+#endif
+
+#include "vpd.h"
+
+/*
+ * vpd_reader() - reads VPD data from I2C EEPROMS.
+ *                returns pointer to buffer or NULL.
+ */
+static unsigned char *
+vpd_reader(unsigned char *buf, unsigned dev_addr, unsigned off, unsigned count)
+{
+    unsigned offset = off;			/* Calculated offset */
+
+    /*
+     * The main board EEPROM contains
+     * SDRAM SPD in the first 128 bytes,
+     * so skew the offset.
+     */
+    if (dev_addr == CFG_DEF_EEPROM_ADDR)
+	offset += SDRAM_SPD_DATA_SIZE;
+
+    /* Try to read the I2C EEPROM */
+#if defined(VXWORKS)
+    {
+	int i;
+	for( i = 0; i < count; ++i ) {
+	    buf[ i ] = iicReadByte( dev_addr, offset+i );
+	}
+    }
+#else
+    if (eeprom_read(dev_addr, offset, buf, count)) {
+	printf("Failed to read %d bytes from VPD EEPROM 0x%x @ 0x%x\n",
+	       count, dev_addr, offset);
+	return NULL;
+    }
+#endif
+
+    return buf;
+} /* vpd_reader() */
+
+
+/*
+ * vpd_get_packet() - returns next VPD packet or NULL.
+ */
+static vpd_packet_t *vpd_get_packet(vpd_packet_t *vpd_packet)
+{
+    vpd_packet_t *packet = vpd_packet;
+
+    if (packet != NULL) {
+	if (packet->identifier == VPD_PID_TERM)
+	    return NULL;
+	else
+	    packet = (vpd_packet_t *)((char *)packet + packet->size + 2);
+    }
+
+    return packet;
+} /* vpd_get_packet() */
+
+
+/*
+ * vpd_find_packet() - Locates and returns the specified
+ *		       VPD packet or NULL on error.
+ */
+static vpd_packet_t *vpd_find_packet(vpd_t *vpd, unsigned char ident)
+{
+    vpd_packet_t *packet = (vpd_packet_t *)&vpd->packets;
+
+    /* Guaranteed illegal */
+    if (ident == VPD_PID_GI)
+	return NULL;
+
+    /* Scan tuples looking for a match */
+    while ((packet->identifier != ident) &&
+	   (packet->identifier != VPD_PID_TERM))
+	packet = vpd_get_packet(packet);
+
+    /* Did we find it? */
+    if ((packet->identifier) && (packet->identifier != ident))
+	return NULL;
+    return packet;
+}
+
+
+/*
+ * vpd_is_valid() - Validates contents of VPD data
+ *		    in I2C EEPROM.  Returns 1 for
+ *		    success or 0 for failure.
+ */
+static int vpd_is_valid(unsigned dev_addr, unsigned char *buf)
+{
+    unsigned	    num_bytes;
+    vpd_packet_t    *packet;
+    vpd_t	    *vpd = (vpd_t *)buf;
+    unsigned short  stored_crc16, calc_crc16 = 0xffff;
+
+    /* Check Eyecatcher */
+    if (strncmp(vpd->header.eyecatcher, VPD_EYECATCHER, VPD_EYE_SIZE) != 0) {
+	unsigned offset = 0;
+	if (dev_addr == CFG_DEF_EEPROM_ADDR)
+	    offset += SDRAM_SPD_DATA_SIZE;
+	printf("Error: VPD EEPROM 0x%x corrupt @ 0x%x\n", dev_addr, offset);
+
+	return 0;
+    }
+
+    /* Check Length */
+    if (vpd->header.size> VPD_MAX_EEPROM_SIZE) {
+	printf("Error: VPD EEPROM 0x%x contains bad size 0x%x\n",
+	       dev_addr, vpd->header.size);
+	return 0;
+    }
+
+    /* Now find the termination packet */
+    if ((packet = vpd_find_packet(vpd, VPD_PID_TERM)) == NULL) {
+	printf("Error: VPD EEPROM 0x%x missing termination packet\n",
+	       dev_addr);
+	return 0;
+    }
+
+    /* Calculate data size */
+    num_bytes = (unsigned long)((unsigned char *)packet -
+				(unsigned char *)vpd + sizeof(vpd_packet_t));
+
+    /* Find stored CRC and clear it */
+    if ((packet = vpd_find_packet(vpd, VPD_PID_CRC)) == NULL) {
+	printf("Error: VPD EEPROM 0x%x missing CRC\n", dev_addr);
+	return 0;
+    }
+    stored_crc16 = *((ushort *)packet->data);
+    *(ushort *)packet->data = 0;
+
+    /* OK, lets calculate the CRC and check it */
+#if defined(VXWORKS)
+    calc_crc16 = (0xffff & crc32(buf, num_bytes));
+#else
+    calc_crc16 = (0xffff & crc32(0, buf, num_bytes));
+#endif
+    *(ushort *)packet->data = stored_crc16;     /* Now restore the CRC */
+    if (stored_crc16 != calc_crc16) {
+	printf("Error: VPD EEPROM 0x%x has bad CRC 0x%x\n",
+	       dev_addr, stored_crc16);
+	return 0;
+    }
+
+    return 1;
+} /* vpd_is_valid() */
+
+
+/*
+ * size_ok() - Check to see if packet size matches
+ *	       size of data we want. Returns 1 for
+ *	       good match or 0 for failure.
+ */
+static int size_ok(vpd_packet_t *packet, unsigned long size)
+{
+    if (packet->size != size) {
+	printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+	return 0;
+    }
+    return 1;
+} /* size_ok() */
+
+
+/*
+ * strlen_ok() - Check to see if packet size matches
+ *		 strlen of the string we want to populate.
+ *		 Returns 1 for valid length or 0 for failure.
+ */
+static int strlen_ok(vpd_packet_t *packet, unsigned long length)
+{
+    if (packet->size >= length) {
+	printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+	return 0;
+    }
+    return 1;
+} /* strlen_ok() */
+
+
+/*
+ * get_vpd_data() - populates the passed VPD structure 'vpdInfo'
+ *		    with data obtained from the specified
+ *		    I2C EEPROM 'dev_addr'.  Returns 0 for
+ *		    success or 1 for failure.
+ */
+int vpd_get_data(unsigned char dev_addr, VPD *vpdInfo)
+{
+    unsigned char buf[VPD_EEPROM_SIZE];
+    vpd_t *vpd = (vpd_t *)buf;
+    vpd_packet_t *packet;
+
+    if (vpdInfo == NULL)
+	return 1;
+
+     /*
+      * Fill vpdInfo with 0s to blank out
+      * unused fields, fill vpdInfo->ethAddrs
+      * with all 0xffs so that other's code can
+      * determine how many real Ethernet addresses
+      * there are.  OUIs starting with 0xff are
+      * broadcast addresses, and would never be
+      * permantely stored.
+      */
+    memset((void *)vpdInfo, 0, sizeof(VPD));
+    memset((void *)&vpdInfo->ethAddrs, 0xff, sizeof(vpdInfo->ethAddrs));
+    vpdInfo->_devAddr = dev_addr;
+
+    /* Read the minimum size first */
+    if (vpd_reader(buf, dev_addr, 0, VPD_EEPROM_SIZE) == NULL) {
+	return 1;
+    }
+
+    /* Check validity of VPD data */
+    if (!vpd_is_valid(dev_addr, buf)) {
+	printf("VPD Data is INVALID!\n");
+	return 1;
+    }
+
+    /*
+      * Walk all the packets and populate
+      * the VPD info structure.
+      */
+    packet = (vpd_packet_t *)&vpd->packets;
+    do {
+	switch (packet->identifier) {
+	    case VPD_PID_GI:
+		printf("Error: Illegal VPD value\n");
+		break;
+	    case VPD_PID_PID:
+		if (strlen_ok(packet, MAX_PROD_ID)) {
+		    strncpy(vpdInfo->productId,
+			    packet->data, packet->size);
+		}
+		break;
+	    case VPD_PID_REV:
+		if (size_ok(packet, sizeof(char)))
+		    vpdInfo->revisionId = *packet->data;
+		break;
+	    case VPD_PID_SN:
+		if (size_ok(packet, sizeof(unsigned long))) {
+		    vpdInfo->serialNum =
+			*(unsigned long *)packet->data;
+		}
+		break;
+	    case VPD_PID_MANID:
+		if (size_ok(packet, sizeof(unsigned char)))
+		    vpdInfo->manuID = *packet->data;
+		break;
+	    case VPD_PID_PCO:
+		if (size_ok(packet, sizeof(unsigned long))) {
+		    vpdInfo->configOpt =
+			*(unsigned long *)packet->data;
+		}
+		break;
+	    case VPD_PID_SYSCLK:
+		if (size_ok(packet, sizeof(unsigned long)))
+		    vpdInfo->sysClk = *(unsigned long *)packet->data;
+		break;
+	    case VPD_PID_SERCLK:
+		if (size_ok(packet, sizeof(unsigned long)))
+		    vpdInfo->serClk = *(unsigned long *)packet->data;
+		break;
+	    case VPD_PID_FLASH:
+		if (size_ok(packet, 9)) {	/* XXX - hardcoded,
+						   padding in struct */
+		    memcpy(&vpdInfo->flashCfg, packet->data, 9);
+		}
+		break;
+	    case VPD_PID_ETHADDR:
+		memcpy(vpdInfo->ethAddrs, packet->data, packet->size);
+		break;
+	    case VPD_PID_POTS:
+		if (size_ok(packet, sizeof(char)))
+		    vpdInfo->numPOTS = (unsigned)*packet->data;
+		break;
+	    case VPD_PID_DS1:
+		if (size_ok(packet, sizeof(char)))
+		    vpdInfo->numDS1 = (unsigned)*packet->data;
+	    case VPD_PID_GAL:
+	    case VPD_PID_CRC:
+	    case VPD_PID_TERM:
+		break;
+	    default:
+		printf("Warning: Found unknown VPD packet ID 0x%x\n",
+		       packet->identifier);
+		break;
+	}
+    } while ((packet = vpd_get_packet(packet)));
+
+    return 0;
+} /* end get_vpd_data() */
+
+
+/*
+ * vpd_init() - Initialize default VPD environment
+ */
+int vpd_init(unsigned char dev_addr)
+{
+    return (0);
+} /* vpd_init() */
+
+
+/*
+ * vpd_print() - Pretty print the VPD data.
+ */
+void vpd_print(VPD *vpdInfo)
+{
+    const char *const sp    = "";
+    const char *const sfmt  = "%4s%-20s: \"%s\"\n";
+    const char *const cfmt  = "%4s%-20s: '%c'\n";
+    const char *const dfmt  = "%4s%-20s: %ld\n";
+    const char *const hfmt  = "%4s%-20s: %08lX\n";
+    const char *const dsfmt = "%4s%-20s: %d\n";
+    const char *const hsfmt = "%4s%-20s: %04X\n";
+    const char *const dhfmt = "%4s%-20s: %ld (%lX)\n";
+
+    printf("VPD read from I2C device: %02X\n", vpdInfo->_devAddr);
+
+    if (vpdInfo->productId[0])
+	printf(sfmt, sp, "Product ID", vpdInfo->productId);
+    else
+	printf(sfmt, sp, "Product ID", "UNKNOWN");
+
+    if (vpdInfo->revisionId)
+	printf(cfmt, sp, "Revision ID", vpdInfo->revisionId);
+
+    if (vpdInfo->serialNum)
+	printf(dfmt, sp, "Serial Number", vpdInfo->serialNum);
+
+    if (vpdInfo->manuID)
+	printf(dfmt, sp, "Manufacture ID", (long)vpdInfo->manuID);
+
+    if (vpdInfo->configOpt)
+	printf(hfmt, sp, "Configuration", vpdInfo->configOpt);
+
+    if (vpdInfo->sysClk)
+	printf(dhfmt, sp, "System Clock", vpdInfo->sysClk, vpdInfo->sysClk);
+
+    if (vpdInfo->serClk)
+	printf(dhfmt, sp, "Serial Clock", vpdInfo->serClk, vpdInfo->serClk);
+
+    if (vpdInfo->numPOTS)
+	printf(dfmt, sp, "Number of POTS lines", vpdInfo->numPOTS);
+
+    if (vpdInfo->numDS1)
+	printf(dfmt, sp, "Number of DS1s", vpdInfo->numDS1);
+
+    /* Print Ethernet Addresses */
+    if (vpdInfo->ethAddrs[0][0] != 0xff) {
+	int i, j;
+	printf("%4sEtherNet Address(es): ", sp);
+	for (i = 0; i < MAX_ETH_ADDRS; i++) {
+	    if (vpdInfo->ethAddrs[i][0] != 0xff) {
+		for (j = 0; j < 6; j++) {
+		    printf("%02X", vpdInfo->ethAddrs[i][j]);
+		    if (((j + 1) % 6) != 0)
+			printf(":");
+		    else
+			printf(" ");
+		}
+		if (((i + 1) % 3) == 0) printf("\n%24s: ", sp);
+	    }
+	}
+	printf("\n");
+    }
+
+    if (vpdInfo->flashCfg.mfg && vpdInfo->flashCfg.dev) {
+	printf("Main Flash Configuration:\n");
+	printf(hsfmt, sp, "Manufacture ID", vpdInfo->flashCfg.mfg);
+	printf(hsfmt, sp, "Device ID",      vpdInfo->flashCfg.dev);
+	printf(dsfmt, sp, "Device Width",   vpdInfo->flashCfg.devWidth);
+	printf(dsfmt, sp, "Num. Devices",   vpdInfo->flashCfg.numDevs);
+	printf(dsfmt, sp, "Num. Columns",   vpdInfo->flashCfg.numCols);
+	printf(dsfmt, sp, "Column Width",   vpdInfo->flashCfg.colWidth);
+	printf(dsfmt, sp, "WE Data Width",  vpdInfo->flashCfg.weDataWidth);
+    }
+} /* vpd_print() */
+
diff --git a/board/w7o/vpd.h b/board/w7o/vpd.h
new file mode 100644
index 0000000..35bbe3e
--- /dev/null
+++ b/board/w7o/vpd.h
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * 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
+ */
+
+#ifndef _VPD_H_
+#define _VPD_H_
+
+/*
+ * Main Flash Configuration.
+ */
+typedef struct flashCfg_s {
+    unsigned short mfg;				/* Manufacture ID */
+    unsigned short dev;				/* Device ID */
+    unsigned char devWidth;			/* Device Width */
+    unsigned char numDevs;			/* Number of devices */
+    unsigned char numCols;			/* Number of columns */
+    unsigned char colWidth;			/* Width of a column */
+    unsigned char weDataWidth;			/* Write/Erase Data Width */
+} flashCfg_t;
+
+/*
+ * Vital Product Data - VPD
+ */
+#define MAX_PROD_ID		15
+#define MAX_ETH_ADDRS		10
+typedef unsigned char EthAddr[6];
+typedef struct vpd {
+    unsigned char _devAddr;			/* Device address during read */
+    char productId[MAX_PROD_ID];		/* Product ID */
+    char revisionId;				/* Revision ID as a char */
+    unsigned long serialNum;			/* Serial number */
+    unsigned char  manuID;			/* Manufact ID - byte int */
+    unsigned long configOpt;			/* Config Option - bit field */
+    unsigned long sysClk;			/* System clock in Hertz */
+    unsigned long serClk;			/* Ext. clock in Hertz */
+    flashCfg_t flashCfg;			/* Flash configuration */
+    unsigned long numPOTS;			/* Number of POTS lines */
+    unsigned long numDS1;			/* Number of DS1 circuits */
+    EthAddr ethAddrs[MAX_ETH_ADDRS];		/* Ethernet MAC, 1st = craft */
+} VPD;
+
+
+#define VPD_MAX_EEPROM_SIZE	512		/* Max size VPD EEPROM */
+#define SDRAM_SPD_DATA_SIZE	128		/* Size SPD in VPD EEPROM */
+
+/*
+ * PIDs - Packet Identifiers
+ */
+#define VPD_PID_GI		0x0		/* Guaranted Illegal */
+#define VPD_PID_PID		0x1		/* Product Identifier */
+#define VPD_PID_REV		0x2		/* Product Revision */
+#define VPD_PID_SN		0x3		/* Serial Number */
+#define VPD_PID_MANID		0x4		/* Manufacture ID */
+#define VPD_PID_PCO		0x5		/* Product configuration */
+#define VPD_PID_SYSCLK		0x6		/* System Clock */
+#define VPD_PID_SERCLK		0x7		/* Ser. Clk. Speed in Hertz */
+#define VPD_PID_CRC		0x8		/* VPD CRC */
+#define VPD_PID_FLASH		0x9		/* Flash Configuration */
+#define VPD_PID_ETHADDR		0xA		/* Ethernet Address(es) */
+#define VPD_PID_GAL		0xB		/* Galileo Switch Config */
+#define VPD_PID_POTS		0xC		/* Number of POTS Lines */
+#define VPD_PID_DS1		0xD		/* Number of DS1s */
+#define VPD_PID_TERM		0xFF		/* Termination packet */
+
+/*
+ * VPD - Eyecatcher/Magic
+ */
+#define VPD_EYECATCHER		"W7O"
+#define VPD_EYE_SIZE		3
+typedef struct vpd_header {
+    unsigned char eyecatcher[VPD_EYE_SIZE];	/* eyecatcher - "W7O" */
+    unsigned short size __attribute__((packed)); /* size of EEPROM */
+} vpd_header_t;
+
+
+#define VPD_DATA_SIZE (VPD_MAX_EEPROM_SIZE - SDRAM_SPD_DATA_SIZE - \
+                        sizeof(vpd_header_t))
+typedef struct vpd_s {
+    vpd_header_t header;
+    unsigned char packets[VPD_DATA_SIZE];
+} vpd_t;
+
+typedef struct vpd_packet {
+    unsigned char identifier;
+    unsigned char size;
+    unsigned char data[1];
+} vpd_packet_t;
+
+/*
+ * VPD configOpt bit mask
+ */
+#define VPD_HAS_BBRAM		0x1		/* Battery backed SRAM */
+#define VPD_HAS_RTC		0x2		/* Battery backed RTC */
+#define VPD_HAS_EXT_SER_CLK	0x4		/* External serial clock */
+#define VPD_HAS_SER_TRANS_1	0x8		/* COM1 transceiver */
+#define VPD_HAS_SER_TRANS_2	0x10		/* COM2 transceiver */
+#define VPD_HAS_CRAFT_PHY	0x20		/* CRAFT Ethernet */
+#define VPD_HAS_DTT_1		0x40		/* I2C Digital therm. #1 */
+#define VPD_HAS_DTT_2		0x80		/* I2C Digital therm. #2 */
+#define VPD_HAS_1000_UP_LASER	0x100		/* GMM - 1000Mbit Uplink */
+#define VPD_HAS_70KM_UP_LASER	0x200		/* CMM - 70KM Uplink laser */
+#define VPD_HAS_2_UPLINKS	0x400		/* CMM - 2 uplink lasers */
+#define VPD_HAS_FPGA		0x800		/* Has 1 or more FPGAs */
+#define VPD_HAS_DFA		0x1000		/* CLM - Has 2 Fiber Inter. */
+#define VPD_HAS_GAL_SWITCH	0x2000		/* GMM - Has a Gal switch */
+#define VPD_HAS_POTS_LINES	0x4000		/* GMM - Has POTS lines */
+#define VPD_HAS_DS1_CHANNELS	0x8000		/* GMM - Has DS1 channels */
+#define VPD_HAS_CABLE_RETURN	0x10000		/* GBM/GBR - Cable ret. path */
+
+#define VPD_EEPROM_SIZE         (256 - SDRAM_SPD_DATA_SIZE) /* Size EEPROM */
+
+extern int vpd_get_data(unsigned char dev_addr, VPD *vpd);
+extern void vpd_print(VPD *vpdInfo);
+
+#endif /* _VPD_H_ */
+
diff --git a/board/w7o/w7o.c b/board/w7o/w7o.c
new file mode 100644
index 0000000..b404d61
--- /dev/null
+++ b/board/w7o/w7o.c
@@ -0,0 +1,271 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * 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 "w7o.h"
+#include <asm/processor.h>
+
+#include "vpd.h"
+#include "errors.h"
+#include <watchdog.h>
+
+unsigned long get_dram_size(void);
+
+/*
+ * Macros to transform values
+ * into environment strings.
+ */
+#define XMK_STR(x)	#x
+#define MK_STR(x)	XMK_STR(x)
+
+/* ------------------------------------------------------------------------- */
+
+int board_pre_init (void)
+{
+#if defined(CONFIG_W7OLMG)
+    /*
+     * Setup GPIO pins - reset devices.
+     */
+    out32(IBM405GP_GPIO0_ODR, 0x10000000);	/* one open drain pin */
+    out32(IBM405GP_GPIO0_OR, 0x3E000000);	/* set output pins to default */
+    out32(IBM405GP_GPIO0_TCR, 0x7f800000);	/* setup for output */
+
+    /*
+     * 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) XILINX; active low; level sensitive
+     * IRQ 26 (EXT IRQ 1) PCI INT A; active low; level sensitive
+     * IRQ 27 (EXT IRQ 2) PCI INT B; active low; level sensitive
+     * IRQ 28 (EXT IRQ 3) SAM 2; active low; level sensitive
+     * IRQ 29 (EXT IRQ 4) Battery Bad; active low; level sensitive
+     * IRQ 30 (EXT IRQ 5) Level One PHY; active low; level sensitive
+     * IRQ 31 (EXT IRQ 6) SAM 1; active high; level sensitive
+     */
+    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
+    mtdcr(uicer, 0x00000000);			/* disable all ints */
+
+    mtdcr(uiccr, 0x00000000);			/* set all to be non-critical*/
+    mtdcr(uicpr, 0xFFFFFF80);			/* 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 */
+
+#elif defined(CONFIG_W7OLMC)
+    /*
+     * Setup GPIO pins
+     */
+    out32(IBM405GP_GPIO0_ODR, 0x01800000);	/* XCV Done Open Drain */
+    out32(IBM405GP_GPIO0_OR,  0x03800000);	/* set out pins to default */
+    out32(IBM405GP_GPIO0_TCR, 0x66C00000);	/* setup for output */
+
+    /*
+     * 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) DBE 0; active low; level sensitive
+     * IRQ 26 (EXT IRQ 1) DBE 1; active low; level sensitive
+     * IRQ 27 (EXT IRQ 2) DBE 2; active low; level sensitive
+     * IRQ 28 (EXT IRQ 3) DBE Common; active low; level sensitive
+     * IRQ 29 (EXT IRQ 4) PCI; active low; level sensitive
+     * IRQ 30 (EXT IRQ 5) RCMM Reset; active low; level sensitive
+     * IRQ 31 (EXT IRQ 6) PHY; active high; level sensitive
+     */
+    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
+    mtdcr(uicer, 0x00000000);			/* disable all ints */
+
+    mtdcr(uiccr, 0x00000000);			/* set all to be non-critical*/
+    mtdcr(uicpr, 0xFFFFFF80);			/* 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 */
+
+#else /* Unknown */
+#    error "Unknown W7O board configuration"
+#endif
+
+    WATCHDOG_RESET();				/* Reset the watchdog */
+    temp_uart_init();				/* init the uart for debug */
+    WATCHDOG_RESET();				/* Reset the watchdog */
+    test_led();					/* test the LEDs */
+    test_sdram(get_dram_size());		/* test the dram */
+    log_stat(ERR_POST1);			/* log status,post1 complete */
+    return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+int checkboard (void)
+{
+    VPD vpd;
+
+    puts ("Board: ");
+
+    /* VPD data present in I2C EEPROM */
+    if (vpd_get_data(CFG_DEF_EEPROM_ADDR, &vpd) == 0) {
+	/*
+	 * Known board type.
+	 */
+	if (vpd.productId[0] &&
+	    ((strncmp(vpd.productId, "GMM", 3) == 0) ||
+	     (strncmp(vpd.productId, "CMM", 3) == 0))) {
+
+	    /* Output board information on startup */
+	    printf("\"%s\", revision '%c', serial# %ld, manufacturer %u\n",
+		   vpd.productId, vpd.revisionId, vpd.serialNum, vpd.manuID);
+	    return (0);
+	}
+    }
+
+    puts ("### Unknown HW ID - assuming NOTHING\n");
+    return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+    return get_dram_size();
+}
+
+unsigned long get_dram_size (void)
+{
+    int tmp, i, regs[4];
+    int size = 0;
+
+    /* Get bank Size registers */
+    mtdcr(memcfga, mem_mb0cf);			/* get bank 0 config reg */
+    regs[0] = mfdcr(memcfgd);
+
+    mtdcr(memcfga, mem_mb1cf);			/* get bank 1 config reg */
+    regs[1] = mfdcr(memcfgd);
+
+    mtdcr(memcfga, mem_mb2cf);			/* get bank 2 config reg */
+    regs[2] = mfdcr(memcfgd);
+
+    mtdcr(memcfga, mem_mb3cf);			/* get bank 3 config reg */
+    regs[3] = mfdcr(memcfgd);
+
+    /* compute the size, add each bank if enabled */
+    for(i = 0; i < 4; i++) {
+	if (regs[i] & 0x0001) {			/* if enabled, */
+	    tmp = ((regs[i] >> (31 - 14)) & 0x7); /* get size bits */
+	    tmp = 0x400000 << tmp;		/* Size bits X 4MB = size */
+	    size += tmp;
+	}
+    }
+
+    return size;
+}
+
+int misc_init_f (void)
+{
+    return 0;
+}
+
+static void
+w7o_env_init(VPD *vpd)
+{
+    /*
+     * Read VPD
+     */
+    if (vpd_get_data(CFG_DEF_EEPROM_ADDR, vpd) != 0)
+	return;
+
+     /*
+      * Known board type.
+      */
+    if (vpd->productId[0] &&
+	((strncmp(vpd->productId, "GMM", 3) == 0) ||
+	 (strncmp(vpd->productId, "CMM", 3) == 0))) {
+	char buf[30];
+	char *eth;
+	unsigned char *serial = getenv("serial#");
+	unsigned char *ethaddr = getenv("ethaddr");
+
+	/* Set 'serial#' envvar if serial# isn't set */
+	if (!serial) {
+	    sprintf(buf, "%s-%ld", vpd->productId, vpd->serialNum);
+	    setenv("serial#", buf);
+	}
+
+	/* Set 'ethaddr' envvar if 'ethaddr' envvar is the default */
+	eth = vpd->ethAddrs[0];
+	if (ethaddr && (strcmp(ethaddr, MK_STR(CONFIG_ETHADDR)) == 0)) {
+	    /* Now setup ethaddr */
+	    sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+		    eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
+	    setenv("ethaddr", buf);
+	}
+    }
+} /* w7o_env_init() */
+
+
+int misc_init_r (void)
+{
+    VPD vpd;					/* VPD information */
+
+#if defined(CONFIG_W7OLMG)
+    unsigned long greg;				/* GPIO Register */
+
+    greg = in32(IBM405GP_GPIO0_OR);
+
+    /*
+     * XXX - Unreset devices - this should be moved into VxWorks driver code
+     */
+    greg |= 0x41800000L;			/* SAM, PHY, Galileo */
+
+    out32(IBM405GP_GPIO0_OR, greg);		/* set output pins to default */
+#endif /* CONFIG_W7OLMG */
+
+    /*
+     * Initialize W7O environment variables
+     */
+    w7o_env_init(&vpd);
+
+    /*
+     * Initialize the FPGA(s).
+     */
+    if (init_fpga() == 0)
+	test_fpga((unsigned short *)CONFIG_FPGAS_BASE);
+
+    /* More POST testing. */
+    post2();
+
+    /* Done with hardware initialization and POST. */
+    log_stat(ERR_POSTOK);
+
+    /* Call silly, fail safe boot init routine */
+    init_fsboot();
+
+	return (0);
+}
+