Merge branch 'master' of git://git.denx.de/u-boot-i2c
diff --git a/arch/i386/cpu/Makefile b/arch/i386/cpu/Makefile
index c658c6e..bb0a48f 100644
--- a/arch/i386/cpu/Makefile
+++ b/arch/i386/cpu/Makefile
@@ -29,7 +29,7 @@
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o start16.o resetvec.o
-COBJS	= serial.o interrupts.o cpu.o
+COBJS	= interrupts.o cpu.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/i386/cpu/interrupts.c b/arch/i386/cpu/interrupts.c
index 4b57437..51023f3 100644
--- a/arch/i386/cpu/interrupts.c
+++ b/arch/i386/cpu/interrupts.c
@@ -5,6 +5,9 @@
  * (C) Copyright 2002
  * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
  *
+ * Portions of this file are derived from the Linux kernel source
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -32,12 +35,112 @@
 	".hidden irq_"#x"\n" \
 	".type irq_"#x", @function\n" \
 	"irq_"#x":\n" \
-	"pushl %ebp\n" \
-	"movl %esp,%ebp\n" \
-	"pusha\n" \
 	"pushl $"#x"\n" \
 	"jmp irq_common_entry\n"
 
+/*
+ * Volatile isn't enough to prevent the compiler from reordering the
+ * read/write functions for the control registers and messing everything up.
+ * A memory clobber would solve the problem, but would prevent reordering of
+ * all loads stores around it, which can hurt performance. Solution is to
+ * use a variable and mimic reads and writes to it to enforce serialization
+ */
+static unsigned long __force_order;
+
+static inline unsigned long read_cr0(void)
+{
+	unsigned long val;
+	asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
+	return val;
+}
+
+static inline unsigned long read_cr2(void)
+{
+	unsigned long val;
+	asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));
+	return val;
+}
+
+static inline unsigned long read_cr3(void)
+{
+	unsigned long val;
+	asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
+	return val;
+}
+
+static inline unsigned long read_cr4(void)
+{
+	unsigned long val;
+	asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
+	return val;
+}
+
+static inline unsigned long get_debugreg(int regno)
+{
+	unsigned long val = 0;	/* Damn you, gcc! */
+
+	switch (regno) {
+	case 0:
+		asm("mov %%db0, %0" :"=r" (val));
+		break;
+	case 1:
+		asm("mov %%db1, %0" :"=r" (val));
+		break;
+	case 2:
+		asm("mov %%db2, %0" :"=r" (val));
+		break;
+	case 3:
+		asm("mov %%db3, %0" :"=r" (val));
+		break;
+	case 6:
+		asm("mov %%db6, %0" :"=r" (val));
+		break;
+	case 7:
+		asm("mov %%db7, %0" :"=r" (val));
+		break;
+	default:
+		val = 0;
+	}
+	return val;
+}
+
+void dump_regs(struct pt_regs *regs)
+{
+	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
+	unsigned long d0, d1, d2, d3, d6, d7;
+
+	printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n",
+			(u16)regs->xcs, regs->eip, regs->eflags);
+
+	printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
+		regs->eax, regs->ebx, regs->ecx, regs->edx);
+	printf("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
+		regs->esi, regs->edi, regs->ebp, regs->esp);
+	printf(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
+	       (u16)regs->xds, (u16)regs->xes, (u16)regs->xfs, (u16)regs->xgs, (u16)regs->xss);
+
+	cr0 = read_cr0();
+	cr2 = read_cr2();
+	cr3 = read_cr3();
+	cr4 = read_cr4();
+
+	printf("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
+			cr0, cr2, cr3, cr4);
+
+	d0 = get_debugreg(0);
+	d1 = get_debugreg(1);
+	d2 = get_debugreg(2);
+	d3 = get_debugreg(3);
+
+	printf("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
+			d0, d1, d2, d3);
+
+	d6 = get_debugreg(6);
+	d7 = get_debugreg(7);
+	printf("DR6: %08lx DR7: %08lx\n",
+			d6, d7);
+}
+
 struct idt_entry {
 	u16	base_low;
 	u16	selector;
@@ -122,7 +225,7 @@
 }
 
 /* IRQ Low-Level Service Routine */
-__isr__ irq_llsr(int ip, int seg, int irq)
+__isr__ irq_llsr(struct pt_regs *regs)
 {
 	/*
 	 * For detailed description of each exception, refer to:
@@ -131,73 +234,92 @@
 	 * Order Number: 253665-029US, November 2008
 	 * Table 6-1. Exceptions and Interrupts
 	 */
-	switch (irq) {
+	switch (regs->orig_eax) {
 	case 0x00:
-		printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
+		printf("Divide Error (Division by zero)\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x01:
-		printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
+		printf("Debug Interrupt (Single step)\n");
+		dump_regs(regs);
 		break;
 	case 0x02:
-		printf("NMI Interrupt at %04x:%08x\n", seg, ip);
+		printf("NMI Interrupt\n");
+		dump_regs(regs);
 		break;
 	case 0x03:
-		printf("Breakpoint at %04x:%08x\n", seg, ip);
+		printf("Breakpoint\n");
+		dump_regs(regs);
 		break;
 	case 0x04:
-		printf("Overflow at %04x:%08x\n", seg, ip);
+		printf("Overflow\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x05:
-		printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
+		printf("BOUND Range Exceeded\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x06:
-		printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
+		printf("Invalid Opcode (UnDefined Opcode)\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x07:
-		printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
+		printf("Device Not Available (No Math Coprocessor)\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x08:
-		printf("Double fault at %04x:%08x\n", seg, ip);
+		printf("Double fault\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x09:
-		printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
+		printf("Co-processor segment overrun\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x0a:
-		printf("Invalid TSS at %04x:%08x\n", seg, ip);
+		printf("Invalid TSS\n");
+		dump_regs(regs);
 		break;
 	case 0x0b:
-		printf("Segment Not Present at %04x:%08x\n", seg, ip);
+		printf("Segment Not Present\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x0c:
-		printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
+		printf("Stack Segment Fault\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x0d:
-		printf("General Protection at %04x:%08x\n", seg, ip);
+		printf("General Protection\n");
+		dump_regs(regs);
 		break;
 	case 0x0e:
-		printf("Page fault at %04x:%08x\n", seg, ip);
+		printf("Page fault\n");
+		dump_regs(regs);
 		while(1);
 		break;
 	case 0x0f:
-		printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
+		printf("Floating-Point Error (Math Fault)\n");
+		dump_regs(regs);
 		break;
 	case 0x10:
-		printf("Alignment check at %04x:%08x\n", seg, ip);
+		printf("Alignment check\n");
+		dump_regs(regs);
 		break;
 	case 0x11:
-		printf("Machine Check at %04x:%08x\n", seg, ip);
+		printf("Machine Check\n");
+		dump_regs(regs);
 		break;
 	case 0x12:
-		printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
+		printf("SIMD Floating-Point Exception\n");
+		dump_regs(regs);
 		break;
 	case 0x13:
 	case 0x14:
@@ -212,12 +334,13 @@
 	case 0x1d:
 	case 0x1e:
 	case 0x1f:
-		printf("Reserved Exception %d at %04x:%08x\n", irq, seg, ip);
+		printf("Reserved Exception\n");
+		dump_regs(regs);
 		break;
 
 	default:
 		/* Hardware or User IRQ */
-		do_irq(irq);
+		do_irq(regs->orig_eax);
 	}
 }
 
@@ -226,22 +349,45 @@
  * fully relocatable code.
  *  - The call to irq_llsr will be a relative jump
  *  - The IRQ entries will be guaranteed to be in order
- * It's a bit annoying that we need to waste 3 bytes per interrupt entry
- * (total of 768 code bytes), but we MUST create a Stack Frame and this is
- * the easiest way I could do it. Maybe it can be made better later.
+ *  Interrupt entries are now very small (a push and a jump) but they are
+ *  now slower (all registers pushed on stack which provides complete
+ *  crash dumps in the low level handlers
  */
 asm(".globl irq_common_entry\n" \
 	".hidden irq_common_entry\n" \
 	".type irq_common_entry, @function\n" \
 	"irq_common_entry:\n" \
-	"pushl $0\n" \
-	"pushl $0\n" \
+	"cld\n" \
+	"pushl %gs\n" \
+	"pushl %fs\n" \
+	"pushl %es\n" \
+	"pushl %ds\n" \
+	"pushl %eax\n" \
+	"pushl %ebp\n" \
+	"pushl %edi\n" \
+	"pushl %esi\n" \
+	"pushl %edx\n" \
+	"pushl %ecx\n" \
+	"pushl %ebx\n" \
+	"mov   %esp, %eax\n" \
+	"pushl %ebp\n" \
+	"movl %esp,%ebp\n" \
+	"pushl %eax\n" \
 	"call irq_llsr\n" \
 	"popl %eax\n" \
-	"popl %eax\n" \
-	"popl %eax\n" \
-	"popa\n" \
 	"leave\n"\
+	"popl %ebx\n" \
+	"popl %ecx\n" \
+	"popl %edx\n" \
+	"popl %esi\n" \
+	"popl %edi\n" \
+	"popl %ebp\n" \
+	"popl %eax\n" \
+	"popl %ds\n" \
+	"popl %es\n" \
+	"popl %fs\n" \
+	"popl %gs\n" \
+	"add  $4, %esp\n" \
 	"iret\n" \
 	DECLARE_INTERRUPT(0) \
 	DECLARE_INTERRUPT(1) \
diff --git a/arch/i386/cpu/sc520/sc520.c b/arch/i386/cpu/sc520/sc520.c
index 4b566a7..519bfd8 100644
--- a/arch/i386/cpu/sc520/sc520.c
+++ b/arch/i386/cpu/sc520/sc520.c
@@ -44,24 +44,24 @@
 	/* Set the UARTxCTL register at it's slower,
 	 * baud clock giving us a 1.8432 MHz reference
 	 */
-	sc520_mmcr->uart1ctl = 0x07;
-	sc520_mmcr->uart2ctl = 0x07;
+	writeb(0x07, &sc520_mmcr->uart1ctl);
+	writeb(0x07, &sc520_mmcr->uart2ctl);
 
 	/* first set the timer pin mapping */
-	sc520_mmcr->clksel = 0x72;	/* no clock frequency selected, use 1.1892MHz */
+	writeb(0x72, &sc520_mmcr->clksel);	/* no clock frequency selected, use 1.1892MHz */
 
 	/* enable PCI bus arbitrer */
-	sc520_mmcr->sysarbctl = 0x02;	/* enable concurrent mode */
+	writeb(0x02, &sc520_mmcr->sysarbctl);	/* enable concurrent mode */
 
-	sc520_mmcr->sysarbmenb = 0x1f;	/* enable external grants */
-	sc520_mmcr->hbctl = 0x04;	/* enable posted-writes */
+	writeb(0x1f, &sc520_mmcr->sysarbmenb);	/* enable external grants */
+	writeb(0x04, &sc520_mmcr->hbctl);	/* enable posted-writes */
 
 	if (CONFIG_SYS_SC520_HIGH_SPEED) {
-		sc520_mmcr->cpuctl = 0x02;	/* set it to 133 MHz and write back */
+		writeb(0x02, &sc520_mmcr->cpuctl);	/* set it to 133 MHz and write back */
 		gd->cpu_clk = 133000000;
 		printf("## CPU Speed set to 133MHz\n");
 	} else {
-		sc520_mmcr->cpuctl = 0x01;	/* set it to 100 MHz and write back */
+		writeb(0x01, &sc520_mmcr->cpuctl);	/* set it to 100 MHz and write back */
 		printf("## CPU Speed set to 100MHz\n");
 		gd->cpu_clk = 100000000;
 	}
@@ -74,7 +74,7 @@
 	    "loop 0b\n": : : "ecx");
 
 	/* turn on the SDRAM write buffer */
-	sc520_mmcr->dbctl = 0x11;
+	writeb(0x11, &sc520_mmcr->dbctl);
 
 	/* turn on the cache and disable write through */
 	asm("movl	%%cr0, %%eax\n"
@@ -88,6 +88,7 @@
 
 	u32 dram_present=0;
 	u32 dram_ctrl;
+
 #ifdef CONFIG_SYS_SDRAM_DRCTMCTL
 	/* these memory control registers are set up in the assember part,
 	 * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
@@ -97,7 +98,8 @@
 	 * simply dictates it.
 	 */
 #else
-	int val;
+	u8 tmp;
+	u8 val;
 
 	int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY;
 	int refresh_rate        = CONFIG_SYS_SDRAM_REFRESH_RATE;
@@ -116,9 +118,10 @@
 		val = 3;  /* 62.4us */
 	}
 
-	sc520_mmcr->drcctl = (sc520_mmcr->drcctl & 0xcf) | (val<<4);
+	tmp = (readb(&sc520_mmcr->drcctl) & 0xcf) | (val<<4);
+	writeb(tmp, &sc520_mmcr->drcctl);
 
-	val = sc520_mmcr->drctmctl & 0xf0;
+	val = readb(&sc520_mmcr->drctmctl) & 0xf0;
 
 	if (cas_precharge_delay==3) {
 		val |= 0x04;   /* 3T */
@@ -133,12 +136,12 @@
 	} else {
 		val |= 1;
 	}
-	sc520_mmcr->drctmctl = val;
+	writeb(val, &c520_mmcr->drctmctl);
 #endif
 
 	/* We read-back the configuration of the dram
 	 * controller that the assembly code wrote */
-	dram_ctrl = sc520_mmcr->drcbendadr;
+	dram_ctrl = readl(&sc520_mmcr->drcbendadr);
 
 	bd->bi_dram[0].start = 0;
 	if (dram_ctrl & 0x80) {
@@ -191,7 +194,7 @@
 {
 	printf("Resetting using SC520 MMCR\n");
 	/* Write a '1' to the SYS_RST of the RESCFG MMCR */
-	sc520_mmcr->rescfg = 0x01;
+	writeb(0x01, &sc520_mmcr->rescfg);
 
 	/* NOTREACHED */
 }
diff --git a/arch/i386/cpu/sc520/sc520_asm.S b/arch/i386/cpu/sc520/sc520_asm.S
index 2042d9b..fff56c0 100644
--- a/arch/i386/cpu/sc520/sc520_asm.S
+++ b/arch/i386/cpu/sc520/sc520_asm.S
@@ -25,48 +25,85 @@
  * copyright is included below
  */
 
-/*
- *  =============================================================================
- *
- *   Copyright 1999 Advanced Micro Devices, Inc.
+/*		TITLE	SIZER - Aspen DRAM Sizing Routine.
+ * =============================================================================
  *
- *  This software is the property of Advanced Micro Devices, Inc  (AMD)  which
- *  specifically grants the user the right to modify, use and distribute this
- *  software provided this COPYRIGHT NOTICE is not removed or altered.  All
- *  other rights are reserved by AMD.
+ *  Copyright 1999 Advanced Micro Devices, Inc.
+ * You may redistribute this program and/or modify this program 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.
  *
- *  THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY
- *  OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF
- *  THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE.
- *  IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
- *  (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
- *  INTERRUPTION, LOSS OF INFORMAITON) ARISING OUT OF THE USE OF OR INABILITY
- *  TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF
- *  SUCH DAMAGES.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
- *  LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
- *  LIMITATION MAY NOT APPLY TO YOU.
+ *  This program is distributed 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.
  *
- *  AMD does not assume any responsibility for any errors that may appear in
- *  the Materials nor any responsibility to support or update the Materials.
- *  AMD retains the right to make changes to its test specifications at any
- *  time, without notice.
+ * 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.
  *
- *  So that all may benefit from your experience, please report  any  problems
- *  or suggestions about this software back to AMD.  Please include your name,
- *  company,  telephone number,  AMD product requiring support and question or
- *  problem encountered.
+ * THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY
+ * OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF
+ * THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE.
+ * IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
+ * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
+ * INTERRUPTION, LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR INABILITY
+ * TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
+ * LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
+ * LIMITATION MAY NOT APPLY TO YOU.
  *
- *  Advanced Micro Devices, Inc.         Worldwide support and contact
- *  Embedded Processor Division            information available at:
- *  Systems Engineering                       epd.support@amd.com
- *  5204 E. Ben White Blvd.                          -or-
- *  Austin, TX 78741                http://www.amd.com/html/support/techsup.html
- *  ============================================================================
+ * AMD does not assume any responsibility for any errors that may appear in
+ * the Materials nor any responsibility to support or update the Materials.
+ * AMD retains the right to make changes to its test specifications at any
+ * time, without notice.
+ * ==============================================================================
  */
 
-
-/*******************************************************************************
- *	 AUTHOR      : Buddy Fey - Original.
+/*
+ ******************************************************************************
+ *
+ *  FILE        : sizer.asm - SDRAM DIMM Sizing Algorithm
+ *
+ *
+ *
+ *  FUNCTIONS   : sizemem() - jumped to, not called.  To be executed after
+ *                reset to determine the size of the SDRAM DIMMs. Initializes
+ *		 the memory subsystem.
+ *
+ *
+ *  AUTHOR      : Buddy Fey - Original.
+ *
+ *
+ *  DESCRIPTION : Performs sizing on SDRAM DIMMs on ASPEN processor.
+ *                NOTE: This is a small memory model version
+ *
+ *
+ *  INPUTS      : BP contains return address offset
+ *		 CACHE is assumed to be disabled.
+ *		 The FS segment limit has already been set to big real mode
+ *		 (full 32-bit addressing capability)
+ *
+ *
+ *  OUTPUTS     : None
+ *
+ *
+ *  REG USE     :  ax,bx,cx,dx,di,si,bp, fs
+ *
+ *
+ *  REVISION    : See PVCS info below
+ *
+ *
+ *  TEST PLAN CROSS REFERENCE:
+ *
+ *
+ * $Workfile: $
+ * $Revision: 1.2 $
+ * $Date: 1999/09/22 12:49:33 $
+ * $Author: chipf $
+ * $Log: sizer.asm $
+ * Revision 1.2  1999/09/22 12:49:33  chipf
+ * Add legal header
+ *
  *******************************************************************************
  */
 
@@ -463,7 +500,7 @@
 	/* just have your hardware desinger _GIVE_ you what you need here! */
 	movl    $DRCTMCTL, %edi
 	movb    $CONFIG_SYS_SDRAM_DRCTMCTL,%al
-	movb    (%edi), %al
+	movb    %al, (%edi)
 #else
 #if defined(CONFIG_SYS_SDRAM_CAS_LATENCY_2T) || defined(CONFIG_SYS_SDRAM_CAS_LATENCY_3T)
 	/* set the CAS latency now since it is hard to do
@@ -498,48 +535,21 @@
 
 dram_done:
 
-	/* readback DRCBENDADR and return the number
-	 * of available ram bytes in %eax */
-
-	movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
-
-	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x80000000, %ecx
-	jz	bank2
-	andl	$0x7f000000, %eax
-	shrl	$2, %eax
-	movl	%eax, %ebx
-
-bank2:	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x00800000, %ecx
-	jz	bank1
-	andl	$0x007f0000, %eax
-	shll	$6, %eax
-	movl	%eax, %ebx
-
-bank1:	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x00008000, %ecx
-	jz	bank0
-	andl	$0x00007f00, %eax
-	shll	$14, %eax
-	movl	%eax, %ebx
-
-bank0:	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x00000080, %ecx
-	jz	done
-	andl	$0x0000007f, %eax
-	shll	$22, %eax
-	movl	%eax, %ebx
+#if CONFIG_SYS_SDRAM_ECC_ENABLE
+	/*
+	 * We are in the middle of an existing 'call' - Need to store the
+	 * existing return address before making another 'call'
+	 */
+	movl	%ebp, %ebx
 
+	/* Get the memory size */
+	movl	$init_ecc, %ebp
+	jmpl	get_mem_size
 
-done:
-	movl	%ebx, %eax
+init_ecc:
+	/* Restore the orignal return address */
+	movl	%ebx, %ebp
 
-#if CONFIG_SYS_SDRAM_ECC_ENABLE
 	/* A nominal memory test: just a byte at each address line */
 	movl    %eax, %ecx
 	shrl    $0x1, %ecx
@@ -576,6 +586,50 @@
 	mov	$0x05, %al
 	movb    %al, (%edi)
 #endif
+
 out:
+	jmp	*%ebp
+
+/*
+ * Read and decode the sc520 DRCBENDADR MMCR and return the number of
+ * available ram bytes in %eax
+ */
+.globl get_mem_size
+get_mem_size:
+	movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
+
+bank0:	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x00000080, %ecx
+	jz	bank1
+	andl	$0x0000007f, %eax
+	shll	$22, %eax
+	movl	%eax, %ebx
+
+bank1:	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x00008000, %ecx
+	jz	bank2
+	andl	$0x00007f00, %eax
+	shll	$14, %eax
+	movl	%eax, %ebx
+
+bank2:	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x00800000, %ecx
+	jz	bank3
+	andl	$0x007f0000, %eax
+	shll	$6, %eax
+	movl	%eax, %ebx
+
+bank3:	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x80000000, %ecx
+	jz	done
+	andl	$0x7f000000, %eax
+	shrl	$2, %eax
+	movl	%eax, %ebx
+
+done:
 	movl	%ebx, %eax
 	jmp	*%ebp
diff --git a/arch/i386/cpu/sc520/sc520_pci.c b/arch/i386/cpu/sc520/sc520_pci.c
index f446c6d..b917734 100644
--- a/arch/i386/cpu/sc520/sc520_pci.c
+++ b/arch/i386/cpu/sc520/sc520_pci.c
@@ -25,7 +25,9 @@
 
 #include <common.h>
 #include <pci.h>
+#include <asm/io.h>
 #include <asm/pci.h>
+#include <asm/ic/pci.h>
 #include <asm/ic/sc520.h>
 
 static struct {
@@ -63,6 +65,8 @@
 int pci_sc520_set_irq(int pci_pin, int irq)
 {
 	int i;
+	u8 tmpb;
+	u16 tmpw;
 
 # if 1
 	printf("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq);
@@ -80,31 +84,34 @@
 
 	/* PCI interrupt mapping (A through D)*/
 	for (i=0; i<=3 ;i++) {
-		if (sc520_mmcr->pci_int_map[i] == sc520_irq[irq].priority)
-			sc520_mmcr->pci_int_map[i] = SC520_IRQ_DISABLED;
+		if (readb(&sc520_mmcr->pci_int_map[i]) == sc520_irq[irq].priority)
+			writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pci_int_map[i]);
 	}
 
 	/* GP IRQ interrupt mapping */
 	for (i=0; i<=10 ;i++) {
-		if (sc520_mmcr->gp_int_map[i] == sc520_irq[irq].priority)
-			sc520_mmcr->gp_int_map[i] = SC520_IRQ_DISABLED;
+		if (readb(&sc520_mmcr->gp_int_map[i]) == sc520_irq[irq].priority)
+			writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_int_map[i]);
 	}
 
 	/* Set the trigger to level */
-	sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] =
-		sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] | sc520_irq[irq].level_bit;
+	tmpb = readb(&sc520_mmcr->pic_mode[sc520_irq[irq].level_reg]);
+	tmpb |= sc520_irq[irq].level_bit;
+	writeb(tmpb, &sc520_mmcr->pic_mode[sc520_irq[irq].level_reg]);
 
 
 	if (pci_pin < 4) {
 		/* PCI INTA-INTD */
 		/* route the interrupt */
-		sc520_mmcr->pci_int_map[pci_pin] = sc520_irq[irq].priority;
+		writeb(sc520_irq[irq].priority, &sc520_mmcr->pci_int_map[pci_pin]);
 	} else {
 		/* GPIRQ0-GPIRQ10 used for additional PCI INTS */
-		sc520_mmcr->gp_int_map[pci_pin - 4] = sc520_irq[irq].priority;
+		writeb(sc520_irq[irq].priority, &sc520_mmcr->gp_int_map[pci_pin - 4]);
 
 		/* also set the polarity in this case */
-		sc520_mmcr->intpinpol = sc520_mmcr->intpinpol | (1 << (pci_pin-4));
+		tmpw = readw(&sc520_mmcr->intpinpol);
+		tmpw |= (1 << (pci_pin-4));
+		writew(tmpw, &sc520_mmcr->intpinpol);
 	}
 
 	/* register the pin */
@@ -118,43 +125,7 @@
 {
 	hose->first_busno = 0;
 	hose->last_busno = 0xff;
-
-	/* System memory space */
-	pci_set_region(hose->regions + 0,
-		       SC520_PCI_MEMORY_BUS,
-		       SC520_PCI_MEMORY_PHYS,
-		       SC520_PCI_MEMORY_SIZE,
-		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
-
-	/* PCI memory space */
-	pci_set_region(hose->regions + 1,
-		       SC520_PCI_MEM_BUS,
-		       SC520_PCI_MEM_PHYS,
-		       SC520_PCI_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	/* ISA/PCI memory space */
-	pci_set_region(hose->regions + 2,
-		       SC520_ISA_MEM_BUS,
-		       SC520_ISA_MEM_PHYS,
-		       SC520_ISA_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	/* PCI I/O space */
-	pci_set_region(hose->regions + 3,
-		       SC520_PCI_IO_BUS,
-		       SC520_PCI_IO_PHYS,
-		       SC520_PCI_IO_SIZE,
-		       PCI_REGION_IO);
-
-	/* ISA/PCI I/O space */
-	pci_set_region(hose->regions + 4,
-		       SC520_ISA_IO_BUS,
-		       SC520_ISA_IO_PHYS,
-		       SC520_ISA_IO_SIZE,
-		       PCI_REGION_IO);
-
-	hose->region_count = 5;
+	hose->region_count = pci_set_regions(hose);
 
 	pci_setup_type1(hose,
 			SC520_REG_ADDR,
diff --git a/arch/i386/cpu/sc520/sc520_ssi.c b/arch/i386/cpu/sc520/sc520_ssi.c
index 8dbe17a..6e5e346 100644
--- a/arch/i386/cpu/sc520/sc520_ssi.c
+++ b/arch/i386/cpu/sc520/sc520_ssi.c
@@ -24,6 +24,7 @@
 /* stuff specific for the sc520, but independent of implementation */
 
 #include <common.h>
+#include <asm/io.h>
 #include <asm/ic/ssi.h>
 #include <asm/ic/sc520.h>
 
@@ -61,34 +62,34 @@
 		temp |= PHS_INV_ENB;
 	}
 
-	sc520_mmcr->ssictl = temp;
+	writeb(temp, &sc520_mmcr->ssictl);
 
 	return 0;
 }
 
 u8 ssi_txrx_byte(u8 data)
 {
-	sc520_mmcr->ssixmit = data;
-	while (sc520_mmcr->ssista & SSISTA_BSY);
-	sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMITRCV;
-	while (sc520_mmcr->ssista & SSISTA_BSY);
+	writeb(data, &sc520_mmcr->ssixmit);
+	while (readb(&sc520_mmcr->ssista) & SSISTA_BSY);
+	writeb(SSICMD_CMD_SEL_XMITRCV, &sc520_mmcr->ssicmd);
+	while (readb(&sc520_mmcr->ssista) & SSISTA_BSY);
 
-	return sc520_mmcr->ssircv;
+	return readb(&sc520_mmcr->ssircv);
 }
 
 
 void ssi_tx_byte(u8 data)
 {
-	sc520_mmcr->ssixmit = data;
-	while (sc520_mmcr->ssista & SSISTA_BSY);
-	sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMIT;
+	writeb(data, &sc520_mmcr->ssixmit);
+	while (readb(&sc520_mmcr->ssista) & SSISTA_BSY);
+	writeb(SSICMD_CMD_SEL_XMIT, &sc520_mmcr->ssicmd);
 }
 
 u8 ssi_rx_byte(void)
 {
-	while (sc520_mmcr->ssista & SSISTA_BSY);
-	sc520_mmcr->ssicmd = SSICMD_CMD_SEL_RCV;
-	while (sc520_mmcr->ssista & SSISTA_BSY);
+	while (readb(&sc520_mmcr->ssista) & SSISTA_BSY);
+	writeb(SSICMD_CMD_SEL_RCV, &sc520_mmcr->ssicmd);
+	while (readb(&sc520_mmcr->ssista) & SSISTA_BSY);
 
-	return sc520_mmcr->ssircv;
+	return readb(&sc520_mmcr->ssircv);
 }
diff --git a/arch/i386/cpu/sc520/sc520_timer.c b/arch/i386/cpu/sc520/sc520_timer.c
index 93b5b55..d5617e9 100644
--- a/arch/i386/cpu/sc520/sc520_timer.c
+++ b/arch/i386/cpu/sc520/sc520_timer.c
@@ -24,13 +24,14 @@
 /* stuff specific for the sc520, but independent of implementation */
 
 #include <common.h>
+#include <asm/io.h>
 #include <asm/interrupt.h>
 #include <asm/ic/sc520.h>
 
 void sc520_timer_isr(void)
 {
 	/* Ack the GP Timer Interrupt */
-	sc520_mmcr->gptmrsta = 0x02;
+	writeb(0x02, &sc520_mmcr->gptmrsta);
 }
 
 int timer_init(void)
@@ -42,43 +43,47 @@
 	irq_install_handler (0, timer_isr, NULL);
 
 	/* Map GP Timer 1 to Master PIC IR0  */
-	sc520_mmcr->gp_tmr_int_map[1] = 0x01;
+	writeb(0x01, &sc520_mmcr->gp_tmr_int_map[1]);
 
 	/* Disable GP Timers 1 & 2 - Allow configuration writes */
-	sc520_mmcr->gptmr1ctl = 0x4000;
-	sc520_mmcr->gptmr2ctl = 0x4000;
+	writew(0x4000, &sc520_mmcr->gptmr1ctl);
+	writew(0x4000, &sc520_mmcr->gptmr2ctl);
 
 	/* Reset GP Timers 1 & 2 */
-	sc520_mmcr->gptmr1cnt = 0x0000;
-	sc520_mmcr->gptmr2cnt = 0x0000;
+	writew(0x0000, &sc520_mmcr->gptmr1cnt);
+	writew(0x0000, &sc520_mmcr->gptmr2cnt);
 
 	/* Setup GP Timer 2 as a 100kHz (10us) prescaler */
-	sc520_mmcr->gptmr2maxcmpa = 83;
-	sc520_mmcr->gptmr2ctl = 0xc001;
+	writew(83, &sc520_mmcr->gptmr2maxcmpa);
+	writew(0xc001, &sc520_mmcr->gptmr2ctl);
 
 	/* Setup GP Timer 1 as a 1000 Hz (1ms) interrupt generator */
-	sc520_mmcr->gptmr1maxcmpa = 100;
-	sc520_mmcr->gptmr1ctl = 0xe009;
+	writew(100, &sc520_mmcr->gptmr1maxcmpa);
+	writew(0xe009, &sc520_mmcr->gptmr1ctl);
 
 	unmask_irq (0);
 
 	/* Clear the GP Timer 1 status register to get the show rolling*/
-	sc520_mmcr->gptmrsta = 0x02;
+	writeb(0x02, &sc520_mmcr->gptmrsta);
 
 	return 0;
 }
 
+/* Allow boards to override udelay implementation */
 void __udelay(unsigned long usec)
+	__attribute__((weak, alias("sc520_udelay")));
+
+void sc520_udelay(unsigned long usec)
 {
 	int m = 0;
 	long u;
 	long temp;
 
-	temp = sc520_mmcr->swtmrmilli;
-	temp = sc520_mmcr->swtmrmicro;
+	temp = readw(&sc520_mmcr->swtmrmilli);
+	temp = readw(&sc520_mmcr->swtmrmicro);
 
 	do {
-		m += sc520_mmcr->swtmrmilli;
-		u = sc520_mmcr->swtmrmicro + (m * 1000);
+		m += readw(&sc520_mmcr->swtmrmilli);
+		u = readw(&sc520_mmcr->swtmrmicro) + (m * 1000);
 	} while (u < usec);
 }
diff --git a/arch/i386/cpu/serial.c b/arch/i386/cpu/serial.c
deleted file mode 100644
index e7025a3..0000000
--- a/arch/i386/cpu/serial.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
- *
- * (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
- */
-/*------------------------------------------------------------------------------+ */
-
-/*
- * This source code is dual-licensed.  You may use it under the terms of the
- * GNU General Public License version 2, or under the license below.
- *
- * 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 <common.h>
-#include <watchdog.h>
-#include <asm/io.h>
-#include <asm/ibmpc.h>
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-#include <malloc.h>
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define UART_RBR    0x00
-#define UART_THR    0x00
-#define UART_IER    0x01
-#define UART_IIR    0x02
-#define UART_FCR    0x02
-#define UART_LCR    0x03
-#define UART_MCR    0x04
-#define UART_LSR    0x05
-#define UART_MSR    0x06
-#define UART_SCR    0x07
-#define UART_DLL    0x00
-#define UART_DLM    0x01
-
-/*-----------------------------------------------------------------------------+
-  | Line Status Register.
-  +-----------------------------------------------------------------------------*/
-#define asyncLSRDataReady1            0x01
-#define asyncLSROverrunError1         0x02
-#define asyncLSRParityError1          0x04
-#define asyncLSRFramingError1         0x08
-#define asyncLSRBreakInterrupt1       0x10
-#define asyncLSRTxHoldEmpty1          0x20
-#define asyncLSRTxShiftEmpty1         0x40
-#define asyncLSRRxFifoError1          0x80
-
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-/*-----------------------------------------------------------------------------+
-  | Fifo
-  +-----------------------------------------------------------------------------*/
-typedef struct {
-	char *rx_buffer;
-	ulong rx_put;
-	ulong rx_get;
-	int cts;
-} serial_buffer_t;
-
-volatile serial_buffer_t buf_info;
-static int serial_buffer_active=0;
-#endif
-
-
-static int serial_div(int baudrate)
-{
-
-	switch (baudrate) {
-	case 1200:
-		return 96;
-	case 9600:
-		return 12;
-	case 19200:
-		return 6;
-	case 38400:
-		return 3;
-	case 57600:
-		return 2;
-	case 115200:
-		return 1;
-	}
-
-	return 12;
-}
-
-
-/*
- * Minimal serial functions needed to use one of the SMC ports
- * as serial console interface.
- */
-
-int serial_init(void)
-{
-	volatile char val;
-	int bdiv = serial_div(gd->baudrate);
-
-	outb(0x80, UART0_BASE + UART_LCR);	/* set DLAB bit */
-	outb(bdiv, UART0_BASE + UART_DLL);	/* set baudrate divisor */
-	outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */
-	outb(0x03, UART0_BASE + UART_LCR);	/* clear DLAB; set 8 bits, no parity */
-	outb(0x01, UART0_BASE + UART_FCR);	/* enable FIFO */
-	outb(0x0b, UART0_BASE + UART_MCR);	/* Set DTR and RTS active */
-	val = inb(UART0_BASE + UART_LSR);	/* clear line status */
-	val = inb(UART0_BASE + UART_RBR);	/* read receive buffer */
-	outb(0x00, UART0_BASE + UART_SCR);	/* set scratchpad */
-	outb(0x00, UART0_BASE + UART_IER);	/* set interrupt enable reg */
-
-	return 0;
-}
-
-
-void serial_setbrg(void)
-{
-	unsigned short bdiv;
-
-	bdiv = serial_div(gd->baudrate);
-
-	outb(0x80, UART0_BASE + UART_LCR);	/* set DLAB bit */
-	outb(bdiv&0xff, UART0_BASE + UART_DLL);	/* set baudrate divisor */
-	outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */
-	outb(0x03, UART0_BASE + UART_LCR);	/* clear DLAB; set 8 bits, no parity */
-}
-
-
-void serial_putc(const char c)
-{
-	int i;
-
-	if (c == '\n')
-		serial_putc ('\r');
-
-	/* check THRE bit, wait for transmiter available */
-	for (i = 1; i < 3500; i++) {
-		if ((inb (UART0_BASE + UART_LSR) & 0x20) == 0x20) {
-			break;
-		}
-		udelay(100);
-	}
-	outb(c, UART0_BASE + UART_THR);	/* put character out */
-}
-
-
-void serial_puts(const char *s)
-{
-	while (*s) {
-		serial_putc(*s++);
-	}
-}
-
-
-int serial_getc(void)
-{
-	unsigned char status = 0;
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-	if (serial_buffer_active) {
-		return serial_buffered_getc();
-	}
-#endif
-
-	while (1) {
-#if defined(CONFIG_HW_WATCHDOG)
-		WATCHDOG_RESET();	/* Reset HW Watchdog, if needed */
-#endif	/* CONFIG_HW_WATCHDOG */
-		status = inb(UART0_BASE + UART_LSR);
-		if ((status & asyncLSRDataReady1) != 0x0) {
-			break;
-		}
-		if ((status & ( asyncLSRFramingError1 |
-				asyncLSROverrunError1 |
-				asyncLSRParityError1  |
-				asyncLSRBreakInterrupt1 )) != 0) {
-			outb(asyncLSRFramingError1 |
-			      asyncLSROverrunError1 |
-			      asyncLSRParityError1  |
-			      asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR);
-		}
-	}
-	return (0x000000ff & (int) inb (UART0_BASE));
-}
-
-
-int serial_tstc(void)
-{
-	unsigned char status;
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-	if (serial_buffer_active) {
-		return serial_buffered_tstc();
-	}
-#endif
-
-	status = inb(UART0_BASE + UART_LSR);
-	if ((status & asyncLSRDataReady1) != 0x0) {
-		return (1);
-	}
-	if ((status & ( asyncLSRFramingError1 |
-			asyncLSROverrunError1 |
-			asyncLSRParityError1  |
-			asyncLSRBreakInterrupt1 )) != 0) {
-		outb(asyncLSRFramingError1 |
-		      asyncLSROverrunError1 |
-		      asyncLSRParityError1  |
-		      asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR);
-	}
-	return 0;
-}
-
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-
-void serial_isr(void *arg)
-{
-	int space;
-	int c;
-	int rx_put = buf_info.rx_put;
-
-	if (buf_info.rx_get <= rx_put) {
-		space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - buf_info.rx_get);
-	} else {
-		space = buf_info.rx_get - rx_put;
-	}
-
-	while (inb(UART0_BASE + UART_LSR) & 1) {
-		c = inb(UART0_BASE);
-		if (space) {
-			buf_info.rx_buffer[rx_put++] = c;
-			space--;
-
-			if (rx_put == buf_info.rx_get) {
-				buf_info.rx_get++;
-				if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) {
-					buf_info.rx_get = 0;
-				}
-			}
-
-			if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) {
-				rx_put = 0;
-				if (0 == buf_info.rx_get) {
-					buf_info.rx_get = 1;
-				}
-
-			}
-
-		}
-		if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) {
-			/* Stop flow by setting RTS inactive */
-			outb(inb(UART0_BASE + UART_MCR) & (0xFF ^ 0x02),
-			      UART0_BASE + UART_MCR);
-		}
-	}
-	buf_info.rx_put = rx_put;
-}
-
-void serial_buffered_init(void)
-{
-	serial_puts ("Switching to interrupt driven serial input mode.\n");
-	buf_info.rx_buffer = malloc (CONFIG_SERIAL_SOFTWARE_FIFO);
-	buf_info.rx_put = 0;
-	buf_info.rx_get = 0;
-
-	if (inb (UART0_BASE + UART_MSR) & 0x10) {
-		serial_puts ("Check CTS signal present on serial port: OK.\n");
-		buf_info.cts = 1;
-	} else {
-		serial_puts ("WARNING: CTS signal not present on serial port.\n");
-		buf_info.cts = 0;
-	}
-
-	irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ ,
-			      serial_isr /*interrupt_handler_t *handler */ ,
-			      (void *) &buf_info /*void *arg */ );
-
-	/* Enable "RX Data Available" Interrupt on UART */
-	/* outb(inb(UART0_BASE + UART_IER) |0x01, UART0_BASE + UART_IER); */
-	outb(0x01, UART0_BASE + UART_IER);
-
-	/* Set DTR and RTS active, enable interrupts  */
-	outb(inb (UART0_BASE + UART_MCR) | 0x0b, UART0_BASE + UART_MCR);
-
-	/* Setup UART FIFO: RX trigger level: 1 byte, Enable FIFO */
-	outb( /*(1 << 6) |*/  1, UART0_BASE + UART_FCR);
-
-	serial_buffer_active = 1;
-}
-
-void serial_buffered_putc (const char c)
-{
-	int i;
-	/* Wait for CTS */
-#if defined(CONFIG_HW_WATCHDOG)
-	while (!(inb (UART0_BASE + UART_MSR) & 0x10))
-		WATCHDOG_RESET ();
-#else
-	if (buf_info.cts)  {
-		for (i=0;i<1000;i++) {
-			if ((inb (UART0_BASE + UART_MSR) & 0x10)) {
-				break;
-			}
-		}
-		if (i!=1000) {
-			buf_info.cts = 0;
-		}
-	} else {
-		if ((inb (UART0_BASE + UART_MSR) & 0x10)) {
-			buf_info.cts = 1;
-		}
-	}
-
-#endif
-	serial_putc (c);
-}
-
-void serial_buffered_puts(const char *s)
-{
-	serial_puts (s);
-}
-
-int serial_buffered_getc(void)
-{
-	int space;
-	int c;
-	int rx_get = buf_info.rx_get;
-	int rx_put;
-
-#if defined(CONFIG_HW_WATCHDOG)
-	while (rx_get == buf_info.rx_put)
-		WATCHDOG_RESET ();
-#else
-	while (rx_get == buf_info.rx_put);
-#endif
-	c = buf_info.rx_buffer[rx_get++];
-	if (rx_get == CONFIG_SERIAL_SOFTWARE_FIFO) {
-		rx_get = 0;
-	}
-	buf_info.rx_get = rx_get;
-
-	rx_put = buf_info.rx_put;
-	if (rx_get <= rx_put) {
-		space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
-	} else {
-		space = rx_get - rx_put;
-	}
-	if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) {
-		/* Start flow by setting RTS active */
-		outb(inb (UART0_BASE + UART_MCR) | 0x02, UART0_BASE + UART_MCR);
-	}
-
-	return c;
-}
-
-int serial_buffered_tstc(void)
-{
-	return (buf_info.rx_get != buf_info.rx_put) ? 1 : 0;
-}
-
-#endif	/* CONFIG_SERIAL_SOFTWARE_FIFO */
-
-
-#if defined(CONFIG_CMD_KGDB)
-/*
-  AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port
-  number 0 or number 1
-  - if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 :
-  configuration has been already done
-  - if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 :
-  configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE
-*/
-#if (CONFIG_KGDB_SER_INDEX & 2)
-void kgdb_serial_init(void)
-{
-	volatile char val;
-	bdiv = serial_div (CONFIG_KGDB_BAUDRATE);
-
-	/*
-	 * Init onboard 16550 UART
-	 */
-	outb(0x80, UART1_BASE + UART_LCR);	/* set DLAB bit */
-	outb((bdiv & 0xff), UART1_BASE + UART_DLL);	/* set divisor for 9600 baud */
-	outb((bdiv >> 8  ), UART1_BASE + UART_DLM);	/* set divisor for 9600 baud */
-	outb(0x03, UART1_BASE + UART_LCR);	/* line control 8 bits no parity */
-	outb(0x00, UART1_BASE + UART_FCR);	/* disable FIFO */
-	outb(0x00, UART1_BASE + UART_MCR);	/* no modem control DTR RTS */
-	val = inb(UART1_BASE + UART_LSR);	/* clear line status */
-	val = inb(UART1_BASE + UART_RBR);	/* read receive buffer */
-	outb(0x00, UART1_BASE + UART_SCR);	/* set scratchpad */
-	outb(0x00, UART1_BASE + UART_IER);	/* set interrupt enable reg */
-}
-
-
-void putDebugChar(const char c)
-{
-	if (c == '\n')
-		serial_putc ('\r');
-
-	outb(c, UART1_BASE + UART_THR);	/* put character out */
-
-	/* check THRE bit, wait for transfer done */
-	while ((inb(UART1_BASE + UART_LSR) & 0x20) != 0x20);
-}
-
-
-void putDebugStr(const char *s)
-{
-	while (*s) {
-		serial_putc(*s++);
-	}
-}
-
-
-int getDebugChar(void)
-{
-	unsigned char status = 0;
-
-	while (1) {
-		status = inb(UART1_BASE + UART_LSR);
-		if ((status & asyncLSRDataReady1) != 0x0) {
-			break;
-		}
-		if ((status & ( asyncLSRFramingError1 |
-				asyncLSROverrunError1 |
-				asyncLSRParityError1  |
-				asyncLSRBreakInterrupt1 )) != 0) {
-			outb(asyncLSRFramingError1 |
-			     asyncLSROverrunError1 |
-			     asyncLSRParityError1  |
-			     asyncLSRBreakInterrupt1, UART1_BASE + UART_LSR);
-		}
-	}
-	return (0x000000ff & (int) inb(UART1_BASE));
-}
-
-
-void kgdb_interruptible(int yes)
-{
-	return;
-}
-
-#else	/* ! (CONFIG_KGDB_SER_INDEX & 2) */
-
-void kgdb_serial_init(void)
-{
-	serial_printf ("[on serial] ");
-}
-
-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	/* (CONFIG_KGDB_SER_INDEX & 2) */
-#endif
diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S
index 25d32e6..7def8de 100644
--- a/arch/i386/cpu/start.S
+++ b/arch/i386/cpu/start.S
@@ -33,7 +33,27 @@
 .type _start, @function
 .globl _i386boot_start
 _i386boot_start:
+	/*
+	 * This is the fail safe 32-bit bootstrap entry point. The
+	 * following code is not executed from a cold-reset (actually, a
+	 * lot of it is, but from real-mode after cold reset. It is
+	 * repeated here to put the board into a state as close to cold
+	 * reset as necessary)
+	 */
+	cli
+	cld
+
+	/* Turn of cache (this might require a 486-class CPU) */
+	movl	%cr0, %eax
+	orl	$0x60000000,%eax
+	movl	%eax, %cr0
+	wbinvd
+
+	/* Tell 32-bit code it is being entered from an in-RAM copy */
+	movw	$0x0000, %bx
 _start:
+	/* This is the 32-bit cold-reset entry point */
+
 	movl    $0x18,%eax	/* Load our segement registes, the
 				 * gdt have already been loaded by start16.S */
 	movw    %ax,%fs
@@ -42,6 +62,18 @@
 	movw    %ax,%es
 	movw    %ax,%ss
 
+	/* Clear the interupt vectors */
+	lidt	blank_idt_ptr
+
+	/*
+	 * Skip low-level board and memory initialization if not starting
+	 * from cold-reset. This allows us to do a fail safe boot-strap
+	 * into a new build of U-Boot from a known-good boot flash
+	 */
+	movw	$0x0001, %ax
+	cmpw	%ax, %bx
+	jne	mem_init_ret
+
 	/* We call a few functions in the board support package
 	 * since we have no stack yet we'll have to use %ebp
 	 * to store the return address */
@@ -63,6 +95,58 @@
 	jmp     mem_init
 mem_init_ret:
 
+	/* fetch memory size (into %eax) */
+	mov	$get_mem_size_ret, %ebp
+	jmp     get_mem_size
+get_mem_size_ret:
+
+	/*
+	 * We are now in 'Flat Protected Mode' and we know how much memory
+	 * the board has. The (temporary) Global Descriptor Table is not
+	 * in a 'Safe' place (it is either in Flash which can be erased or
+	 * reprogrammed or in a fail-safe boot-strap image which could be
+	 * over-written).
+	 *
+	 * Move the final gdt to a safe place (top of RAM) and load it.
+	 * This is not a trivial excercise - the lgdt instruction does not
+	 * have a register operand (memory only) and we may well be
+	 * running from Flash, so self modifying code will not work here.
+	 * To overcome this, we copy a stub into upper memory along with
+	 * the GDT.
+	 */
+
+	/* Reduce upper memory limit by (Stub + GDT Pointer + GDT) */
+	subl	$(end_gdt_setup - start_gdt_setup), %eax
+
+	/* Copy the GDT and Stub */
+	movl	$start_gdt_setup, %esi
+	movl	%eax, %edi
+	movl	$(end_gdt_setup - start_gdt_setup), %ecx
+	shrl	$2, %ecx
+	cld
+	rep	movsl
+
+	/* write the lgdt 'parameter' */
+	subl	$(jmp_instr - start_gdt_setup - 4), %ebp
+	addl	%eax, %ebp
+	movl	$(gdt_ptr - start_gdt_setup), %ebx
+	addl	%eax, %ebx
+	movl	%ebx, (%ebp)
+
+	/* write the gdt address into the pointer */
+	movl	$(gdt_addr - start_gdt_setup), %ebp
+	addl	%eax, %ebp
+	movl	$(gdt - start_gdt_setup), %ebx
+	addl	%eax, %ebx
+	movl	%ebx, (%ebp)
+
+	/* Save the return address */
+	movl	$load_gdt_ret, %ebp
+
+	/* Load the new (safe) Global Descriptor Table */
+	jmp	*%eax
+
+load_gdt_ret:
 	/* Check we have enough memory for stack */
 	movl	$CONFIG_SYS_STACK_SIZE, %ecx
 	cmpl	%ecx, %eax
@@ -133,3 +217,56 @@
 die:	hlt
 	jmp	die
 	hlt
+
+blank_idt_ptr:
+	.word	0		/* limit */
+	.long	0		/* base */
+
+.align 4
+start_gdt_setup:
+	lgdt	gdt_ptr
+jmp_instr:
+	jmp	*%ebp
+
+.align 4
+gdt_ptr:
+	.word	0x30		/* limit (48 bytes = 6 GDT entries) */
+gdt_addr:
+	.long	gdt		/* base */
+
+	/* The GDT table ...
+	 *
+	 *	 Selector	Type
+	 *	 0x00		NULL
+	 *	 0x08		Unused
+	 *	 0x10		32bit code
+	 *	 0x18		32bit data/stack
+	 *	 0x20		16bit code
+	 *	 0x28		16bit data/stack
+	 */
+
+.align 4
+gdt:
+	.word	0, 0, 0, 0	/* NULL  */
+	.word	0, 0, 0, 0	/* unused */
+
+	.word	0xFFFF		/* 4Gb - (0x100000*0x1000 = 4Gb) */
+	.word	0		/* base address = 0 */
+	.word	0x9B00		/* code read/exec */
+	.word	0x00CF		/* granularity = 4096, 386 (+5th nibble of limit) */
+
+	.word	0xFFFF		/* 4Gb - (0x100000*0x1000 = 4Gb) */
+	.word	0x0		/* base address = 0 */
+	.word	0x9300		/* data read/write */
+	.word	0x00CF		/* granularity = 4096, 386 (+5th nibble of limit) */
+
+	.word	0xFFFF		/* 64kb */
+	.word	0		/* base address = 0 */
+	.word	0x9b00		/* data read/write */
+	.word	0x0010		/* granularity = 1  (+5th nibble of limit) */
+
+	.word	0xFFFF		/* 64kb */
+	.word	0		/* base address = 0 */
+	.word	0x9300		/* data read/write */
+	.word	0x0010		/* granularity = 1 (+5th nibble of limit) */
+end_gdt_setup:
diff --git a/arch/i386/cpu/start16.S b/arch/i386/cpu/start16.S
index 1ebb6bc..3e8b2cc 100644
--- a/arch/i386/cpu/start16.S
+++ b/arch/i386/cpu/start16.S
@@ -44,11 +44,9 @@
 	movl	%eax, %cr0
 	wbinvd
 
-	/* load the descriptor tables */
-o32 cs	lidt	idt_ptr
+	/* load the temporary Global Descriptor Table */
 o32 cs	lgdt	gdt_ptr
 
-
 	/* Now, we enter protected mode */
 	movl	%cr0, %eax
 	orl	$1,%eax
@@ -57,6 +55,8 @@
 	/* Flush the prefetch queue */
 	jmp	ff
 ff:
+	/* Tell 32-bit code it is being entered from hard-reset */
+	movw	$0x0001, %bx
 
 	/* Finally jump to the 32bit initialization code */
 	movw	$code32start, %ax
@@ -68,12 +68,13 @@
 	.long	_start		/* offset */
 	.word	0x10		/* segment */
 
-idt_ptr:
-	.word	0		/* limit */
-	.long	0		/* base */
-
+/*
+ * The following Global Descriptor Table is just enough to get us into
+ * 'Flat Protected Mode' - It will be discarded as soon as the final
+ * GDT is setup in a safe location in RAM
+ */
 gdt_ptr:
-	.word	0x30		/* limit (48 bytes = 6 GDT entries) */
+	.word	0x20		/* limit (32 bytes = 4 GDT entries) */
 	.long	BOOT_SEG + gdt	/* base */
 
 	/* The GDT table ...
@@ -83,8 +84,6 @@
 	 *	 0x08		Unused
 	 *	 0x10		32bit code
 	 *	 0x18		32bit data/stack
-	 *	 0x20		16bit code
-	 *	 0x28		16bit data/stack
 	 */
 
 gdt:
@@ -100,13 +99,3 @@
 	.word	0x0		/* base address = 0 */
 	.word	0x9300		/* data read/write */
 	.word	0x00CF		/* granularity = 4096, 386 (+5th nibble of limit) */
-
-	.word	0xFFFF		/* 64kb */
-	.word	0		/* base address = 0 */
-	.word	0x9b00		/* data read/write */
-	.word	0x0010		/* granularity = 1  (+5th nibble of limit) */
-
-	.word	0xFFFF		/* 64kb */
-	.word	0		/* base address = 0 */
-	.word	0x9300		/* data read/write */
-	.word	0x0010		/* granularity = 1 (+5th nibble of limit) */
diff --git a/arch/i386/include/asm/bootparam.h b/arch/i386/include/asm/bootparam.h
new file mode 100644
index 0000000..64d2e1f
--- /dev/null
+++ b/arch/i386/include/asm/bootparam.h
@@ -0,0 +1,123 @@
+#ifndef _ASM_X86_BOOTPARAM_H
+#define _ASM_X86_BOOTPARAM_H
+
+#include <linux/types.h>
+#include <linux/screen_info.h>
+#include <linux/apm_bios.h>
+#include <linux/edd.h>
+#include <asm/e820.h>
+#include <asm/ist.h>
+#include <asm/video/edid.h>
+
+/* setup data types */
+#define SETUP_NONE			0
+#define SETUP_E820_EXT			1
+
+/* extensible setup data list node */
+struct setup_data {
+	__u64 next;
+	__u32 type;
+	__u32 len;
+	__u8 data[0];
+};
+
+struct setup_header {
+	__u8	setup_sects;
+	__u16	root_flags;
+	__u32	syssize;
+	__u16	ram_size;
+#define RAMDISK_IMAGE_START_MASK	0x07FF
+#define RAMDISK_PROMPT_FLAG		0x8000
+#define RAMDISK_LOAD_FLAG		0x4000
+	__u16	vid_mode;
+	__u16	root_dev;
+	__u16	boot_flag;
+	__u16	jump;
+	__u32	header;
+	__u16	version;
+	__u32	realmode_swtch;
+	__u16	start_sys;
+	__u16	kernel_version;
+	__u8	type_of_loader;
+	__u8	loadflags;
+#define LOADED_HIGH	(1<<0)
+#define QUIET_FLAG	(1<<5)
+#define KEEP_SEGMENTS	(1<<6)
+#define CAN_USE_HEAP	(1<<7)
+	__u16	setup_move_size;
+	__u32	code32_start;
+	__u32	ramdisk_image;
+	__u32	ramdisk_size;
+	__u32	bootsect_kludge;
+	__u16	heap_end_ptr;
+	__u8	ext_loader_ver;
+	__u8	ext_loader_type;
+	__u32	cmd_line_ptr;
+	__u32	initrd_addr_max;
+	__u32	kernel_alignment;
+	__u8	relocatable_kernel;
+	__u8	_pad2[3];
+	__u32	cmdline_size;
+	__u32	hardware_subarch;
+	__u64	hardware_subarch_data;
+	__u32	payload_offset;
+	__u32	payload_length;
+	__u64	setup_data;
+} __attribute__((packed));
+
+struct sys_desc_table {
+	__u16 length;
+	__u8  table[14];
+};
+
+struct efi_info {
+	__u32 efi_loader_signature;
+	__u32 efi_systab;
+	__u32 efi_memdesc_size;
+	__u32 efi_memdesc_version;
+	__u32 efi_memmap;
+	__u32 efi_memmap_size;
+	__u32 efi_systab_hi;
+	__u32 efi_memmap_hi;
+};
+
+/* The so-called "zeropage" */
+struct boot_params {
+	struct screen_info screen_info;			/* 0x000 */
+	struct apm_bios_info apm_bios_info;		/* 0x040 */
+	__u8  _pad2[4];					/* 0x054 */
+	__u64  tboot_addr;				/* 0x058 */
+	struct ist_info ist_info;			/* 0x060 */
+	__u8  _pad3[16];				/* 0x070 */
+	__u8  hd0_info[16];	/* obsolete! */		/* 0x080 */
+	__u8  hd1_info[16];	/* obsolete! */		/* 0x090 */
+	struct sys_desc_table sys_desc_table;		/* 0x0a0 */
+	__u8  _pad4[144];				/* 0x0b0 */
+	struct edid_info edid_info;			/* 0x140 */
+	struct efi_info efi_info;			/* 0x1c0 */
+	__u32 alt_mem_k;				/* 0x1e0 */
+	__u32 scratch;		/* Scratch field! */	/* 0x1e4 */
+	__u8  e820_entries;				/* 0x1e8 */
+	__u8  eddbuf_entries;				/* 0x1e9 */
+	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
+	__u8  _pad6[6];					/* 0x1eb */
+	struct setup_header hdr;    /* setup header */	/* 0x1f1 */
+	__u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+	__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];	/* 0x290 */
+	struct e820entry e820_map[E820MAX];		/* 0x2d0 */
+	__u8  _pad8[48];				/* 0xcd0 */
+	struct edd_info eddbuf[EDDMAXNR];		/* 0xd00 */
+	__u8  _pad9[276];				/* 0xeec */
+} __attribute__((packed));
+
+enum {
+	X86_SUBARCH_PC = 0,
+	X86_SUBARCH_LGUEST,
+	X86_SUBARCH_XEN,
+	X86_SUBARCH_MRST,
+	X86_NR_SUBARCHS,
+};
+
+
+
+#endif /* _ASM_X86_BOOTPARAM_H */
diff --git a/arch/i386/include/asm/e820.h b/arch/i386/include/asm/e820.h
new file mode 100644
index 0000000..d155ce9
--- /dev/null
+++ b/arch/i386/include/asm/e820.h
@@ -0,0 +1,155 @@
+#ifndef _ASM_X86_E820_H
+#define _ASM_X86_E820_H
+#define E820MAP	0x2d0		/* our map */
+#define E820MAX	128		/* number of entries in E820MAP */
+
+/*
+ * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the
+ * constrained space in the zeropage.  If we have more nodes than
+ * that, and if we've booted off EFI firmware, then the EFI tables
+ * passed us from the EFI firmware can list more nodes.  Size our
+ * internal memory map tables to have room for these additional
+ * nodes, based on up to three entries per node for which the
+ * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT),
+ * plus E820MAX, allowing space for the possible duplicate E820
+ * entries that might need room in the same arrays, prior to the
+ * call to sanitize_e820_map() to remove duplicates.  The allowance
+ * of three memory map entries per node is "enough" entries for
+ * the initial hardware platform motivating this mechanism to make
+ * use of additional EFI map entries.  Future platforms may want
+ * to allow more than three entries per node or otherwise refine
+ * this size.
+ */
+
+/*
+ * Odd: 'make headers_check' complains about numa.h if I try
+ * to collapse the next two #ifdef lines to a single line:
+ *	#if defined(__KERNEL__) && defined(CONFIG_EFI)
+ */
+#ifdef __KERNEL__
+#ifdef CONFIG_EFI
+#include <linux/numa.h>
+#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES)
+#else	/* ! CONFIG_EFI */
+#define E820_X_MAX E820MAX
+#endif
+#else	/* ! __KERNEL__ */
+#define E820_X_MAX E820MAX
+#endif
+
+#define E820NR	0x1e8		/* # entries in E820MAP */
+
+#define E820_RAM	1
+#define E820_RESERVED	2
+#define E820_ACPI	3
+#define E820_NVS	4
+#define E820_UNUSABLE	5
+
+/* reserved RAM used by kernel itself */
+#define E820_RESERVED_KERN        128
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+struct e820entry {
+	__u64 addr;	/* start of memory segment */
+	__u64 size;	/* size of memory segment */
+	__u32 type;	/* type of memory segment */
+} __attribute__((packed));
+
+struct e820map {
+	__u32 nr_map;
+	struct e820entry map[E820_X_MAX];
+};
+
+#define ISA_START_ADDRESS	0xa0000
+#define ISA_END_ADDRESS		0x100000
+
+#define BIOS_BEGIN		0x000a0000
+#define BIOS_END		0x00100000
+
+#ifdef __KERNEL__
+/* see comment in arch/x86/kernel/e820.c */
+extern struct e820map e820;
+extern struct e820map e820_saved;
+
+extern unsigned long pci_mem_start;
+extern int e820_any_mapped(u64 start, u64 end, unsigned type);
+extern int e820_all_mapped(u64 start, u64 end, unsigned type);
+extern void e820_add_region(u64 start, u64 size, int type);
+extern void e820_print_map(char *who);
+extern int
+sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map);
+extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
+			       unsigned new_type);
+extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
+			     int checktype);
+extern void update_e820(void);
+extern void e820_setup_gap(void);
+extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
+			unsigned long start_addr, unsigned long long end_addr);
+struct setup_data;
+extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
+
+#if defined(CONFIG_X86_64) || \
+	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
+extern void e820_mark_nosave_regions(unsigned long limit_pfn);
+#else
+static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
+{
+}
+#endif
+
+#ifdef CONFIG_MEMTEST
+extern void early_memtest(unsigned long start, unsigned long end);
+#else
+static inline void early_memtest(unsigned long start, unsigned long end)
+{
+}
+#endif
+
+extern unsigned long end_user_pfn;
+
+extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
+extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
+extern void reserve_early(u64 start, u64 end, char *name);
+extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
+extern void free_early(u64 start, u64 end);
+extern void early_res_to_bootmem(u64 start, u64 end);
+extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
+
+extern unsigned long e820_end_of_ram_pfn(void);
+extern unsigned long e820_end_of_low_ram_pfn(void);
+extern int e820_find_active_region(const struct e820entry *ei,
+				  unsigned long start_pfn,
+				  unsigned long last_pfn,
+				  unsigned long *ei_startpfn,
+				  unsigned long *ei_endpfn);
+extern void e820_register_active_regions(int nid, unsigned long start_pfn,
+					 unsigned long end_pfn);
+extern u64 e820_hole_size(u64 start, u64 end);
+extern void finish_e820_parsing(void);
+extern void e820_reserve_resources(void);
+extern void e820_reserve_resources_late(void);
+extern void setup_memory_map(void);
+extern char *default_machine_specific_memory_setup(void);
+
+/*
+ * Returns true iff the specified range [s,e) is completely contained inside
+ * the ISA region.
+ */
+/*
+static inline bool is_ISA_range(u64 s, u64 e)
+{
+	return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS;
+}
+*/
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
+/* #include <linux/ioport.h> */
+
+#define HIGH_MEMORY	(1024*1024)
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_X86_E820_H */
diff --git a/arch/i386/include/asm/ic/pci.h b/arch/i386/include/asm/ic/pci.h
index bcccdbe..2e4376b 100644
--- a/arch/i386/include/asm/ic/pci.h
+++ b/arch/i386/include/asm/ic/pci.h
@@ -24,6 +24,35 @@
 #ifndef _ASM_IC_SC520_PCI_H_
 #define _ASM_IC_SC520_PCI_H_ 1
 
+/* bus mapping constants (used for PCI core initialization) */																																																 /* bus mapping constants */
+#define SC520_REG_ADDR		0x00000cf8
+#define SC520_REG_DATA		0x00000cfc
+
+#define SC520_ISA_MEM_PHYS	0x00000000
+#define SC520_ISA_MEM_BUS	0x00000000
+#define SC520_ISA_MEM_SIZE	0x01000000
+
+#define SC520_ISA_IO_PHYS	0x00000000
+#define SC520_ISA_IO_BUS	0x00000000
+#define SC520_ISA_IO_SIZE	0x00001000
+
+/* PCI I/O space from 0x1000 to 0xdfff
+ * (make 0xe000-0xfdff available for stuff like PCCard boot) */
+#define SC520_PCI_IO_PHYS	0x00001000
+#define SC520_PCI_IO_BUS	0x00001000
+#define SC520_PCI_IO_SIZE	0x0000d000
+
+/* system memory from 0x00000000 to 0x0fffffff */
+#define	SC520_PCI_MEMORY_PHYS	0x00000000
+#define	SC520_PCI_MEMORY_BUS	0x00000000
+#define SC520_PCI_MEMORY_SIZE	0x10000000
+
+/* PCI bus memory from 0x10000000 to 0x26ffffff
+ * (make 0x27000000 - 0x27ffffff available for stuff like PCCard boot) */
+#define SC520_PCI_MEM_PHYS	0x10000000
+#define SC520_PCI_MEM_BUS	0x10000000
+#define SC520_PCI_MEM_SIZE	0x17000000
+
 /* pin number used for PCI interrupt mappings */
 #define SC520_PCI_INTA 0
 #define SC520_PCI_INTB 1
@@ -44,6 +73,7 @@
 extern int sc520_pci_ints[];
 
 void pci_sc520_init(struct pci_controller *hose);
+int pci_set_regions(struct pci_controller *hose);
 int pci_sc520_set_irq(int pci_pin, int irq);
 
 #endif
diff --git a/arch/i386/include/asm/ic/sc520.h b/arch/i386/include/asm/ic/sc520.h
index 57c9904..053d9c6 100644
--- a/arch/i386/include/asm/ic/sc520.h
+++ b/arch/i386/include/asm/ic/sc520.h
@@ -28,6 +28,7 @@
 
 void init_sc520(void);
 unsigned long init_sc520_dram(void);
+void sc520_udelay(unsigned long usec);
 
 /* Memory mapped configuration registers */
 typedef struct sc520_mmcr {
@@ -292,35 +293,6 @@
 #define UART2_DIS		0x02	/* UART2 Disable */
 #define UART1_DIS		0x01	/* UART1 Disable */
 
-/* bus mapping constants (used for PCI core initialization) */																																																 /* bus mapping constants */
-#define SC520_REG_ADDR		0x00000cf8
-#define SC520_REG_DATA		0x00000cfc
-
-#define SC520_ISA_MEM_PHYS	0x00000000
-#define SC520_ISA_MEM_BUS	0x00000000
-#define SC520_ISA_MEM_SIZE	0x01000000
-
-#define SC520_ISA_IO_PHYS	0x00000000
-#define SC520_ISA_IO_BUS	0x00000000
-#define SC520_ISA_IO_SIZE	0x00001000
-
-/* PCI I/O space from 0x1000 to 0xdfff
- * (make 0xe000-0xfdff available for stuff like PCCard boot) */
-#define SC520_PCI_IO_PHYS	0x00001000
-#define SC520_PCI_IO_BUS	0x00001000
-#define SC520_PCI_IO_SIZE	0x0000d000
-
-/* system memory from 0x00000000 to 0x0fffffff */
-#define	SC520_PCI_MEMORY_PHYS	0x00000000
-#define	SC520_PCI_MEMORY_BUS	0x00000000
-#define SC520_PCI_MEMORY_SIZE	0x10000000
-
-/* PCI bus memory from 0x10000000 to 0x26ffffff
- * (make 0x27000000 - 0x27ffffff available for stuff like PCCard boot) */
-#define SC520_PCI_MEM_PHYS	0x10000000
-#define SC520_PCI_MEM_BUS	0x10000000
-#define SC520_PCI_MEM_SIZE	0x17000000
-
 /* 0x28000000 - 0x3fffffff is used by the flash banks */
 
 /* 0x40000000 - 0xffffffff is not adressable by the SC520 */
diff --git a/arch/i386/include/asm/ioctl.h b/arch/i386/include/asm/ioctl.h
new file mode 100644
index 0000000..b279fe0
--- /dev/null
+++ b/arch/i386/include/asm/ioctl.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/arch/i386/include/asm/ist.h b/arch/i386/include/asm/ist.h
new file mode 100644
index 0000000..7e5dff1
--- /dev/null
+++ b/arch/i386/include/asm/ist.h
@@ -0,0 +1,34 @@
+#ifndef _ASM_X86_IST_H
+#define _ASM_X86_IST_H
+
+/*
+ * Include file for the interface to IST BIOS
+ * Copyright 2002 Andy Grover <andrew.grover@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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.
+ */
+
+
+#include <linux/types.h>
+
+struct ist_info {
+	__u32 signature;
+	__u32 command;
+	__u32 event;
+	__u32 perf_level;
+};
+
+#ifdef __KERNEL__
+
+extern struct ist_info ist_info;
+
+#endif	/* __KERNEL__ */
+#endif /* _ASM_X86_IST_H */
diff --git a/arch/i386/include/asm/u-boot-i386.h b/arch/i386/include/asm/u-boot-i386.h
index 521fd35..ce097a3 100644
--- a/arch/i386/include/asm/u-boot-i386.h
+++ b/arch/i386/include/asm/u-boot-i386.h
@@ -43,6 +43,8 @@
 int board_init(void);
 int dram_init(void);
 
+void setup_pcat_compatibility(void);
+
 void isa_unmap_rom(u32 addr);
 u32 isa_map_rom(u32 bus_addr, int size);
 
diff --git a/arch/i386/include/asm/unaligned.h b/arch/i386/include/asm/unaligned.h
new file mode 100644
index 0000000..6cecbbb
--- /dev/null
+++ b/arch/i386/include/asm/unaligned.h
@@ -0,0 +1 @@
+#include <asm-generic/unaligned.h>
diff --git a/arch/i386/include/asm/video/edid.h b/arch/i386/include/asm/video/edid.h
new file mode 100644
index 0000000..928c342
--- /dev/null
+++ b/arch/i386/include/asm/video/edid.h
@@ -0,0 +1,16 @@
+#ifndef __linux_video_edid_h__
+#define __linux_video_edid_h__
+
+#if !defined(__KERNEL__) || defined(CONFIG_X86)
+
+struct edid_info {
+	unsigned char dummy[128];
+};
+
+#ifdef __KERNEL__
+extern struct edid_info edid_info;
+#endif /* __KERNEL__ */
+
+#endif
+
+#endif /* __linux_video_edid_h__ */
diff --git a/arch/i386/lib/bios_setup.c b/arch/i386/lib/bios_setup.c
index 6491e52..a92b77e 100644
--- a/arch/i386/lib/bios_setup.c
+++ b/arch/i386/lib/bios_setup.c
@@ -141,7 +141,7 @@
 
 int bios_setup(void)
 {
-	ulong i386boot_bios      = (ulong)&_i386boot_bios;
+	ulong i386boot_bios      = (ulong)&_i386boot_bios + gd->reloc_off;
 	ulong i386boot_bios_size = (ulong)&_i386boot_bios_size;
 
 	static int done=0;
diff --git a/arch/i386/lib/board.c b/arch/i386/lib/board.c
index f3b6348..3f849f6 100644
--- a/arch/i386/lib/board.c
+++ b/arch/i386/lib/board.c
@@ -37,6 +37,7 @@
 #include <malloc.h>
 #include <net.h>
 #include <ide.h>
+#include <serial.h>
 #include <asm/u-boot-i386.h>
 #include <elf.h>
 
@@ -52,7 +53,9 @@
 extern ulong _i386boot_rel_dyn_end;
 extern ulong _i386boot_bss_start;
 extern ulong _i386boot_bss_size;
-void ram_bootstrap (void *);
+
+void ram_bootstrap (void *, ulong);
+
 const char version_string[] =
 	U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")";
 
@@ -147,7 +150,6 @@
 typedef int (init_fnc_t) (void);
 
 init_fnc_t *init_sequence[] = {
-	serial_init,
 	cpu_init_r,		/* basic cpu dependent setup */
 	board_early_init_r,	/* basic board dependent setup */
 	dram_init,		/* configure available RAM banks */
@@ -162,6 +164,7 @@
 	NULL,
 };
 
+static gd_t gd_data;
 gd_t *gd;
 
 /*
@@ -174,21 +177,18 @@
 	Elf32_Rel *rel_dyn_start = (Elf32_Rel *)&_i386boot_rel_dyn_start;
 	Elf32_Rel *rel_dyn_end = (Elf32_Rel *)&_i386boot_rel_dyn_end;
 	void *bss_start = &_i386boot_bss_start;
-	void *bss_size = &_i386boot_bss_size;
+	ulong bss_size = (ulong)&_i386boot_bss_size;
 
-	size_t uboot_size;
-	void *ram_start;
+	ulong uboot_size;
+	void *dest_addr;
 	ulong rel_offset;
 	Elf32_Rel *re;
 
-	void (*start_func)(void *);
-
-	/* compiler optimization barrier needed for GCC >= 3.4 */
-	__asm__ __volatile__("": : :"memory");
+	void (*start_func)(void *, ulong);
 
-	uboot_size = (size_t)u_boot_cmd_end - (size_t)text_start;
-	ram_start  = (void *)stack_limit - (uboot_size + (ulong)bss_size);
-	rel_offset = text_start - ram_start;
+	uboot_size = (ulong)u_boot_cmd_end - (ulong)text_start;
+	dest_addr  = (void *)stack_limit - (uboot_size + (ulong)bss_size);
+	rel_offset = text_start - dest_addr;
 	start_func = ram_bootstrap - rel_offset;
 
 	/* First stage CPU initialization */
@@ -200,10 +200,10 @@
 		hang();
 
 	/* Copy U-Boot into RAM */
-	memcpy(ram_start, text_start, (size_t)uboot_size);
+	memcpy(dest_addr, text_start, uboot_size);
 
 	/* Clear BSS */
-	memset(bss_start - rel_offset,	0, (size_t)bss_size);
+	memset(bss_start - rel_offset,	0, bss_size);
 
 	/* Perform relocation adjustments */
 	for (re = rel_dyn_start; re < rel_dyn_end; re++)
@@ -213,27 +213,39 @@
 				*(ulong *)(re->r_offset - rel_offset) -= (Elf32_Addr)rel_offset;
 	}
 
-	start_func(ram_start);
-
-	/* NOTREACHED - relocate_code() does not return */
+	/* Enter the relocated U-Boot! */
+	start_func(dest_addr, rel_offset);
+	/* NOTREACHED - board_init_f() does not return */
 	while(1);
 }
 
 /*
- * All attempts to jump straight from board_init_f() to board_init_r()
- * have failed, hence this special 'bootstrap' function.
+ * We cannot initialize gd_data in board_init_f() because we would be
+ * attempting to write to flash (I have even tried using manual relocation
+ * adjustments on pointers but it just won't work) and board_init_r() does
+ * not have enough arguments to allow us to pass the relocation offset
+ * straight up. This bootstrap function (which runs in RAM) is used to
+ * setup gd_data in order to pass the relocation offset to the rest of
+ * U-Boot.
+ *
+ * TODO: The compiler optimization barrier is intended to stop GCC from
+ * optimizing this function into board_init_f(). It seems to work without
+ * it, but I've left it in to be sure. I think also that the barrier in
+ * board_init_r() is no longer needed, but left it in 'just in case'
  */
-void ram_bootstrap (void *ram_start)
+void ram_bootstrap (void *dest_addr, ulong rel_offset)
 {
-	static gd_t gd_data;
-
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");
 
-	board_init_r(&gd_data, (ulong)ram_start);
+	/* tell others: relocation done */
+	gd_data.reloc_off = rel_offset;
+	gd_data.flags |= GD_FLG_RELOC;
+
+	board_init_r(&gd_data, (ulong)dest_addr);
 }
 
-void board_init_r(gd_t *id, ulong ram_start)
+void board_init_r(gd_t *id, ulong dest_addr)
 {
 	char *s;
 	int i;
@@ -247,16 +259,13 @@
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");
 
-	memset (gd, 0, sizeof (gd_t));
 	gd->bd = &bd_data;
 	memset (gd->bd, 0, sizeof (bd_t));
 	show_boot_progress(0x22);
 
 	gd->baudrate =  CONFIG_BAUDRATE;
 
-	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
-
-	mem_malloc_init((((ulong)ram_start - CONFIG_SYS_MALLOC_LEN)+3)&~3,
+	mem_malloc_init((((ulong)dest_addr - CONFIG_SYS_MALLOC_LEN)+3)&~3,
 			CONFIG_SYS_MALLOC_LEN);
 
 	for (init_fnc_ptr = init_sequence, i=0; *init_fnc_ptr; ++init_fnc_ptr, i++) {
@@ -268,6 +277,9 @@
 	}
 	show_boot_progress(0x23);
 
+#ifdef CONFIG_SERIAL_MULTI
+	serial_initialize();
+#endif
 	/* configure available FLASH banks */
 	size = flash_init();
 	display_flash_config(size);
@@ -280,8 +292,10 @@
 	show_boot_progress(0x26);
 
 
+#ifdef CONFIG_CMD_NET
 	/* IP Address */
 	bd_data.bi_ip_addr = getenv_IPaddr ("ipaddr");
+#endif
 
 #if defined(CONFIG_PCI)
 	/*
@@ -420,10 +434,17 @@
 unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char *argv[])
 {
 	/*
-	 * TODO: Test this function - changed to fix compiler error.
-	 * Original code was:
-	 *   return (entry >> 1) (argc, argv);
-	 * with a comment about Nios function pointers are address >> 1
+	 * x86 does not use a dedicated register to pass the pointer
+	 * to the global_data
 	 */
+	argv[-1] = (char *)gd;
+
 	return (entry) (argc, argv);
 }
+
+void setup_pcat_compatibility(void)
+	__attribute__((weak, alias("__setup_pcat_compatibility")));
+
+void __setup_pcat_compatibility(void)
+{
+}
diff --git a/arch/i386/lib/realmode.c b/arch/i386/lib/realmode.c
index 3c3c1fc..b3f5123 100644
--- a/arch/i386/lib/realmode.c
+++ b/arch/i386/lib/realmode.c
@@ -37,7 +37,7 @@
 
 int realmode_setup(void)
 {
-	ulong i386boot_realmode      = (ulong)&_i386boot_realmode;
+	ulong i386boot_realmode      = (ulong)&_i386boot_realmode + gd->reloc_off;
 	ulong i386boot_realmode_size = (ulong)&_i386boot_realmode_size;
 
 	/* copy the realmode switch code */
diff --git a/arch/i386/lib/zimage.c b/arch/i386/lib/zimage.c
index c3b4e59..b39615a 100644
--- a/arch/i386/lib/zimage.c
+++ b/arch/i386/lib/zimage.c
@@ -34,6 +34,8 @@
 #include <asm/zimage.h>
 #include <asm/realmode.h>
 #include <asm/byteorder.h>
+#include <asm/bootparam.h>
+#include <asm/ic/sc520.h>
 
 /*
  * Memory lay-out:
@@ -90,48 +92,56 @@
 	int big_image;
 	void *load_address;
 
+	struct setup_header *hdr = (struct setup_header *)(image + SETUP_SECTS_OFF);
 
 	setup_base = (void*)DEFAULT_SETUP_BASE;	/* base address for real-mode segment */
 
-	if (KERNEL_MAGIC != *(u16*)(image + BOOT_FLAG_OFF)) {
-		printf("Error: Invalid kernel magic (found 0x%04x, expected 0xaa55)\n",
-		       *(u16*)(image + BOOT_FLAG_OFF));
+	if (KERNEL_MAGIC != hdr->boot_flag) {
+		printf("Error: Invalid Boot Flag (found 0x%04x, expected 0x%04x)\n",
+				hdr->boot_flag, KERNEL_MAGIC);
 		return 0;
+	} else {
+		printf("Valid Boot Flag\n");
 	}
 
-
 	/* determine boot protocol version */
-	if (KERNEL_V2_MAGIC == *(u32*)(image+HEADER_OFF)) {
-		bootproto = *(u16*)(image+VERSION_OFF);
+	if (KERNEL_V2_MAGIC == hdr->header) {
+		printf("Magic signature found\n");
+
+		bootproto = hdr->version;
 	} else {
 		/* Very old kernel */
+		printf("Magic signature not found\n");
 		bootproto = 0x0100;
 	}
 
 	/* determine size of setup */
-	if (0 == *(u8*)(image + SETUP_SECTS_OFF)) {
+	if (0 == hdr->setup_sects) {
+		printf("Setup Sectors = 0 (defaulting to 4)\n");
 		setup_size = 5 * 512;
 	} else {
-		setup_size = (*(u8*)(image + SETUP_SECTS_OFF) + 1) * 512;
+		setup_size = (hdr->setup_sects + 1) * 512;
 	}
 
+	printf("Setup Size = 0x%8.8lx\n", (ulong)setup_size);
+
 	if (setup_size > SETUP_MAX_SIZE) {
 		printf("Error: Setup is too large (%d bytes)\n", setup_size);
 	}
 
 	/* Determine image type */
-	big_image = (bootproto >= 0x0200) && (*(u8*)(image + LOADFLAGS_OFF) & BIG_KERNEL_FLAG);
+	big_image = (bootproto >= 0x0200) && (hdr->loadflags & BIG_KERNEL_FLAG);
 
-	/* Derermine load address */
-	load_address = (void*)(big_image ? BZIMAGE_LOAD_ADDR:ZIMAGE_LOAD_ADDR);
+	/* Determine load address */
+	load_address = (void*)(big_image ? BZIMAGE_LOAD_ADDR : ZIMAGE_LOAD_ADDR);
 
 	/* load setup */
+	printf("Moving Real-Mode Code to 0x%8.8lx (%d bytes)\n", (ulong)setup_base, setup_size);
 	memmove(setup_base, image, setup_size);
 
 	printf("Using boot protocol version %x.%02x\n",
 	       (bootproto & 0xff00) >> 8, bootproto & 0xff);
 
-
 	if (bootproto == 0x0100) {
 
 		*(u16*)(setup_base + CMD_LINE_MAGIC_OFF) = COMMAND_LINE_MAGIC;
@@ -154,48 +164,58 @@
 		memset((void*)0x90000 + setup_size, 0, SETUP_MAX_SIZE-setup_size);
 	}
 
+	/* We are now setting up the real-mode version of the header */
+	hdr = (struct setup_header *)(setup_base + SETUP_SECTS_OFF);
+
 	if (bootproto >= 0x0200) {
-		*(u8*)(setup_base + TYPE_OF_LOADER_OFF) = 0xff;
-		printf("Linux kernel version %s\n",
-		       (char*)(setup_base + SETUP_START_OFFSET +
-			       *(u16*)(setup_base + START_SYS_OFF + 2)));
+		hdr->type_of_loader = 8;
+
+		if (hdr->setup_sects >= 15)
+			printf("Linux kernel version %s\n", (char *)
+					(setup_base + (hdr->kernel_version + 0x200)));
+		else
+			printf("Setup Sectors < 15 - Cannot print kernel version.\n");
 
 		if (initrd_addr) {
 			printf("Initial RAM disk at linear address 0x%08lx, size %ld bytes\n",
 			       initrd_addr, initrd_size);
 
-			*(u32*)(setup_base + RAMDISK_IMAGE_OFF) = initrd_addr;
-			*(u32*)(setup_base + RAMDISK_SIZE_OFF)=initrd_size;
+			hdr->ramdisk_image = initrd_addr;
+			hdr->ramdisk_size = initrd_size;
 		}
 	}
 
 	if (bootproto >= 0x0201) {
-		*(u16*)(setup_base + HEAP_END_PTR_OFF) = HEAP_END_OFFSET;
-
-		/* CAN_USE_HEAP */
-		*(u8*)(setup_base + LOADFLAGS_OFF) =
-			*(u8*)(setup_base + LOADFLAGS_OFF) | HEAP_FLAG;
+		hdr->heap_end_ptr = HEAP_END_OFFSET;
+		hdr->loadflags |= HEAP_FLAG;
 	}
 
 	if (bootproto >= 0x0202) {
-		*(u32*)(setup_base + CMD_LINE_PTR_OFF) = (u32)setup_base + COMMAND_LINE_OFFSET;
+		hdr->cmd_line_ptr = (u32)setup_base + COMMAND_LINE_OFFSET;
 	} else if (bootproto >= 0x0200) {
+
 		*(u16*)(setup_base + CMD_LINE_MAGIC_OFF) = COMMAND_LINE_MAGIC;
 		*(u16*)(setup_base + CMD_LINE_OFFSET_OFF) = COMMAND_LINE_OFFSET;
-		*(u16*)(setup_base + SETUP_MOVE_SIZE_OFF) = 0x9100;
+
+		hdr->setup_move_size = 0x9100;
 	}
 
+	if (bootproto >= 0x0204)
+		kernel_size = hdr->syssize * 16;
+	else
+		kernel_size -= setup_size;
+
 
 	if (big_image) {
-		if ((kernel_size - setup_size) > BZIMAGE_MAX_SIZE) {
+		if ((kernel_size) > BZIMAGE_MAX_SIZE) {
 			printf("Error: bzImage kernel too big! (size: %ld, max: %d)\n",
-			       kernel_size - setup_size, BZIMAGE_MAX_SIZE);
+			       kernel_size, BZIMAGE_MAX_SIZE);
 			return 0;
 		}
 
-	} else if ((kernel_size - setup_size) > ZIMAGE_MAX_SIZE) {
+	} else if ((kernel_size) > ZIMAGE_MAX_SIZE) {
 		printf("Error: zImage kernel too big! (size: %ld, max: %d)\n",
-		       kernel_size - setup_size, ZIMAGE_MAX_SIZE);
+		       kernel_size, ZIMAGE_MAX_SIZE);
 		return 0;
 	}
 
@@ -203,10 +223,10 @@
 	build_command_line(setup_base + COMMAND_LINE_OFFSET, auto_boot);
 
 	printf("Loading %czImage at address 0x%08x (%ld bytes)\n", big_image ? 'b' : ' ',
-	       (u32)load_address, kernel_size - setup_size);
+	       (u32)load_address, kernel_size);
 
 
-	memmove(load_address, image + setup_size, kernel_size - setup_size);
+	memmove(load_address, image + setup_size, kernel_size);
 
 	/* ready for booting */
 	return setup_base;
@@ -218,8 +238,51 @@
 
 	memset(&regs, 0, sizeof(struct pt_regs));
 	regs.xds = (u32)setup_base >> 4;
-	regs.xss = 0x9000;
+	regs.xes = regs.xds;
+	regs.xss = regs.xds;
 	regs.esp = 0x9000;
 	regs.eflags = 0;
 	enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, &regs, &regs);
 }
+
+int do_zboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	void *base_ptr;
+	void *bzImage_addr;
+	ulong bzImage_size = 0;
+
+	disable_interrupts();
+
+	/* Setup board for maximum PC/AT Compatibility */
+	setup_pcat_compatibility();
+
+	/* argv[1] holds the address of the bzImage */
+	bzImage_addr = (void *)simple_strtoul(argv[1], NULL, 16);
+
+	if (argc == 3)
+		bzImage_size = simple_strtoul(argv[2], NULL, 16);
+
+	/* Lets look for*/
+	base_ptr = load_zimage (bzImage_addr, bzImage_size, 0, 0, 0);
+
+	if (NULL == base_ptr) {
+		printf ("## Kernel loading failed ...\n");
+	} else {
+		printf ("## Transferring control to Linux (at address %08x) ...\n",
+			(u32)base_ptr);
+
+		/* we assume that the kernel is in place */
+		printf("\nStarting kernel ...\n\n");
+
+		boot_zimage(base_ptr);
+		/* does not return */
+	}
+
+	return -1;
+}
+
+U_BOOT_CMD(
+	zboot, 3, 0,	do_zboot,
+	"Boot bzImage",
+	""
+);
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index 0685a93..6702df5 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -163,8 +163,8 @@
 	sp = get_sp();
 	debug ("## Current stack ends at 0x%08lx\n", sp);
 
-	/* adjust sp by 1K to be safe */
-	sp -= 1024;
+	/* adjust sp by 4K to be safe */
+	sp -= 4096;
 	lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + get_effective_memsize() - sp));
 
 	return ;
diff --git a/board/eNET/config.mk b/board/eNET/config.mk
index dcde7fc..63a58fd 100644
--- a/board/eNET/config.mk
+++ b/board/eNET/config.mk
@@ -21,7 +21,7 @@
 # MA 02111-1307 USA
 #
 
-TEXT_BASE = 0x38040000
+TEXT_BASE = 0x06000000
 CFLAGS_common/dlmalloc.o += -Wa,--no-warn -fno-strict-aliasing
 PLATFORM_RELFLAGS += -fvisibility=hidden
 PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
diff --git a/board/eNET/eNET.c b/board/eNET/eNET.c
index 6d0b15a..7f0e257 100644
--- a/board/eNET/eNET.c
+++ b/board/eNET/eNET.c
@@ -24,6 +24,8 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/ic/sc520.h>
+#include <net.h>
+#include <netdev.h>
 
 #ifdef CONFIG_HW_WATCHDOG
 #include <watchdog.h>
@@ -43,10 +45,13 @@
 
 unsigned long monitor_flash_len = CONFIG_SYS_MONITOR_LEN;
 
+static void enet_timer_isr(void);
+static void enet_toggle_run_led(void);
+
 void init_sc520_enet (void)
 {
 	/* Set CPU Speed to 100MHz */
-	sc520_mmcr->cpuctl = 0x01;
+	writeb(0x01, &sc520_mmcr->cpuctl);
 
 	/* wait at least one millisecond */
 	asm("movl	$0x2000,%%ecx\n"
@@ -55,7 +60,7 @@
 	    "loop 0b\n": : : "ecx");
 
 	/* turn on the SDRAM write buffer */
-	sc520_mmcr->dbctl = 0x11;
+	writeb(0x11, &sc520_mmcr->dbctl);
 
 	/* turn on the cache and disable write through */
 	asm("movl	%%cr0, %%eax\n"
@@ -70,51 +75,52 @@
 {
 	init_sc520_enet();
 
-	sc520_mmcr->gpcsrt = 0x01;		/* GP Chip Select Recovery Time */
-	sc520_mmcr->gpcspw = 0x07;		/* GP Chip Select Pulse Width */
-	sc520_mmcr->gpcsoff = 0x00;		/* GP Chip Select Offset */
-	sc520_mmcr->gprdw = 0x05;		/* GP Read pulse width */
-	sc520_mmcr->gprdoff = 0x01;		/* GP Read offset */
-	sc520_mmcr->gpwrw = 0x05;		/* GP Write pulse width */
-	sc520_mmcr->gpwroff = 0x01;		/* GP Write offset */
+	writeb(0x01, &sc520_mmcr->gpcsrt);		/* GP Chip Select Recovery Time */
+	writeb(0x07, &sc520_mmcr->gpcspw);		/* GP Chip Select Pulse Width */
+	writeb(0x00, &sc520_mmcr->gpcsoff);		/* GP Chip Select Offset */
+	writeb(0x05, &sc520_mmcr->gprdw);		/* GP Read pulse width */
+	writeb(0x01, &sc520_mmcr->gprdoff);		/* GP Read offset */
+	writeb(0x05, &sc520_mmcr->gpwrw);		/* GP Write pulse width */
+	writeb(0x01, &sc520_mmcr->gpwroff);		/* GP Write offset */
 
-	sc520_mmcr->piodata15_0 = 0x0630;	/* PIO15_PIO0 Data */
-	sc520_mmcr->piodata31_16 = 0x2000;	/* PIO31_PIO16 Data */
-	sc520_mmcr->piodir31_16 = 0x2000;	/* GPIO Direction */
-	sc520_mmcr->piodir15_0 = 0x87b5;	/* GPIO Direction */
-	sc520_mmcr->piopfs31_16 = 0x0dfe;	/* GPIO pin function 31-16 reg */
-	sc520_mmcr->piopfs15_0 = 0x200a;	/* GPIO pin function 15-0 reg */
-	sc520_mmcr->cspfs = 0x00f8;		/* Chip Select Pin Function Select */
+	writew(0x0630, &sc520_mmcr->piodata15_0);	/* PIO15_PIO0 Data */
+	writew(0x2000, &sc520_mmcr->piodata31_16);	/* PIO31_PIO16 Data */
+	writew(0x2000, &sc520_mmcr->piodir31_16);	/* GPIO Direction */
+	writew(0x87b5, &sc520_mmcr->piodir15_0);	/* GPIO Direction */
+	writew(0x0dfe, &sc520_mmcr->piopfs31_16);	/* GPIO pin function 31-16 reg */
+	writew(0x200a, &sc520_mmcr->piopfs15_0);	/* GPIO pin function 15-0 reg */
+	writeb(0xf8, &sc520_mmcr->cspfs);		/* Chip Select Pin Function Select */
 
-	sc520_mmcr->par[2] = 0x200713f8;	/* Uart A (GPCS0, 0x013f8, 8 Bytes) */
-	sc520_mmcr->par[3] = 0x2c0712f8;	/* Uart B (GPCS3, 0x012f8, 8 Bytes) */
-	sc520_mmcr->par[4] = 0x300711f8;	/* Uart C (GPCS4, 0x011f8, 8 Bytes) */
-	sc520_mmcr->par[5] = 0x340710f8;	/* Uart D (GPCS5, 0x010f8, 8 Bytes) */
-	sc520_mmcr->par[6] =  0xe3ffc000;	/* SDRAM (0x00000000, 128MB) */
-	sc520_mmcr->par[7] = 0xaa3fd000;	/* StrataFlash (ROMCS1, 0x10000000, 16MB) */
-	sc520_mmcr->par[8] = 0xca3fd100;	/* StrataFlash (ROMCS2, 0x11000000, 16MB) */
-	sc520_mmcr->par[9] = 0x4203d900;	/* SRAM (GPCS0, 0x19000000, 1MB) */
-	sc520_mmcr->par[10] = 0x4e03d910;	/* SRAM (GPCS3, 0x19100000, 1MB) */
-	sc520_mmcr->par[11] = 0x50018100;	/* DP-RAM (GPCS4, 0x18100000, 4kB) */
-	sc520_mmcr->par[12] = 0x54020000;	/* CFLASH1 (0x200000000, 4kB) */
-	sc520_mmcr->par[13] = 0x5c020001;	/* CFLASH2 (0x200010000, 4kB) */
-/*	sc520_mmcr->par14 = 0x8bfff800; */	/* BOOTCS at  0x18000000 */
-/*	sc520_mmcr->par15 = 0x38201000; */	/* LEDs etc (GPCS6, 0x1000, 20 Bytes */
+	writel(0x200713f8, &sc520_mmcr->par[2]);	/* Uart A (GPCS0, 0x013f8, 8 Bytes) */
+	writel(0x2c0712f8, &sc520_mmcr->par[3]);	/* Uart B (GPCS3, 0x012f8, 8 Bytes) */
+	writel(0x300711f8, &sc520_mmcr->par[4]);	/* Uart C (GPCS4, 0x011f8, 8 Bytes) */
+	writel(0x340710f8, &sc520_mmcr->par[5]);	/* Uart D (GPCS5, 0x010f8, 8 Bytes) */
+	writel(0xe3ffc000, &sc520_mmcr->par[6]);	/* SDRAM (0x00000000, 128MB) */
+	writel(0xaa3fd000, &sc520_mmcr->par[7]);	/* StrataFlash (ROMCS1, 0x10000000, 16MB) */
+	writel(0xca3fd100, &sc520_mmcr->par[8]);	/* StrataFlash (ROMCS2, 0x11000000, 16MB) */
+	writel(0x4203d900, &sc520_mmcr->par[9]);	/* SRAM (GPCS0, 0x19000000, 1MB) */
+	writel(0x4e03d910, &sc520_mmcr->par[10]);	/* SRAM (GPCS3, 0x19100000, 1MB) */
+	writel(0x50018100, &sc520_mmcr->par[11]);	/* DP-RAM (GPCS4, 0x18100000, 4kB) */
+	writel(0x54020000, &sc520_mmcr->par[12]);	/* CFLASH1 (0x200000000, 4kB) */
+	writel(0x5c020001, &sc520_mmcr->par[13]);	/* CFLASH2 (0x200010000, 4kB) */
+/*	writel(0x8bfff800, &sc520_mmcr->par14); */	/* BOOTCS at  0x18000000 */
+/*	writel(0x38201000, &sc520_mmcr->par15); */	/* LEDs etc (GPCS6, 0x1000, 20 Bytes */
 
 	/* Disable Watchdog */
-	sc520_mmcr->wdtmrctl = 0x3333;
-	sc520_mmcr->wdtmrctl = 0xcccc;
-	sc520_mmcr->wdtmrctl = 0x0000;
+	writew(0x3333, &sc520_mmcr->wdtmrctl);
+	writew(0xcccc, &sc520_mmcr->wdtmrctl);
+	writew(0x0000, &sc520_mmcr->wdtmrctl);
 
 	/* Chip Select Configuration */
-	sc520_mmcr->bootcsctl = 0x0033;
-	sc520_mmcr->romcs1ctl = 0x0615;
-	sc520_mmcr->romcs2ctl = 0x0615;
+	writew(0x0033, &sc520_mmcr->bootcsctl);
+	writew(0x0615, &sc520_mmcr->romcs1ctl);
+	writew(0x0615, &sc520_mmcr->romcs2ctl);
 
-	sc520_mmcr->adddecctl = 0x02;
-	sc520_mmcr->uart1ctl = 0x07;
-	sc520_mmcr->sysarbctl = 0x06;
-	sc520_mmcr->sysarbmenb = 0x0003;
+	writeb(0x00, &sc520_mmcr->adddecctl);
+	writeb(0x07, &sc520_mmcr->uart1ctl);
+	writeb(0x07, &sc520_mmcr->uart2ctl);
+	writeb(0x06, &sc520_mmcr->sysarbctl);
+	writew(0x0003, &sc520_mmcr->sysarbmenb);
 
 	return 0;
 }
@@ -157,6 +163,10 @@
 
 	major = minor = 0;
 
+	outb(0x00, LED_LATCH_ADDRESS);
+
+	register_timer_isr (enet_timer_isr);
+
 	printf("Serck Controls eNET\n");
 
 	return 0;
@@ -172,3 +182,84 @@
 	} else
 		return 0;
 }
+
+int board_eth_init(bd_t *bis)
+{
+	return pci_eth_init(bis);
+}
+
+void setup_pcat_compatibility()
+{
+	/* disable global interrupt mode */
+	writeb(0x40, &sc520_mmcr->picicr);
+
+	/* set all irqs to edge */
+	writeb(0x00, &sc520_mmcr->pic_mode[0]);
+	writeb(0x00, &sc520_mmcr->pic_mode[1]);
+	writeb(0x00, &sc520_mmcr->pic_mode[2]);
+
+	/*
+	 *  active low polarity on PIC interrupt pins,
+	 *  active high polarity on all other irq pins
+	 */
+	writew(0x0000,&sc520_mmcr->intpinpol);
+
+	/* Set PIT 0 -> IRQ0, RTC -> IRQ8, FP error -> IRQ13 */
+	writeb(SC520_IRQ0, &sc520_mmcr->pit_int_map[0]);
+	writeb(SC520_IRQ8, &sc520_mmcr->rtcmap);
+	writeb(SC520_IRQ13, &sc520_mmcr->ferrmap);
+
+	/* Disable all other interrupt sources */
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_tmr_int_map[0]);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_tmr_int_map[1]);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_tmr_int_map[2]);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pit_int_map[1]);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pit_int_map[2]);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pci_int_map[0]);	/* disable PCI INT A */
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pci_int_map[1]);	/* disable PCI INT B */
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pci_int_map[2]);	/* disable PCI INT C */
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pci_int_map[3]);	/* disable PCI INT D */
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->dmabcintmap);		/* disable DMA INT */
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->ssimap);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->wdtmap);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->wpvmap);
+	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->icemap);
+}
+
+void enet_timer_isr(void)
+{
+	static long enet_ticks = 0;
+
+	enet_ticks++;
+
+	/* Toggle Watchdog every 100ms */
+	if ((enet_ticks % 100) == 0)
+		hw_watchdog_reset();
+
+	/* Toggle Run LED every 500ms */
+	if ((enet_ticks % 500) == 0)
+		enet_toggle_run_led();
+}
+
+void hw_watchdog_reset(void)
+{
+	/* Watchdog Reset must be atomic */
+	long flag = disable_interrupts();
+
+	if (sc520_mmcr->piodata15_0 & WATCHDOG_PIO_BIT)
+		sc520_mmcr->pioclr15_0 = WATCHDOG_PIO_BIT;
+	else
+		sc520_mmcr->pioset15_0 = WATCHDOG_PIO_BIT;
+
+	if (flag)
+		enable_interrupts();
+}
+
+void enet_toggle_run_led(void)
+{
+	unsigned char leds_state= inb(LED_LATCH_ADDRESS);
+	if (leds_state & LED_RUN_BITMASK)
+		outb(leds_state &~ LED_RUN_BITMASK, LED_LATCH_ADDRESS);
+	else
+		outb(leds_state | LED_RUN_BITMASK, LED_LATCH_ADDRESS);
+}
diff --git a/board/eNET/eNET_pci.c b/board/eNET/eNET_pci.c
index e80a8fe..fefb1a4 100644
--- a/board/eNET/eNET_pci.c
+++ b/board/eNET/eNET_pci.c
@@ -93,3 +93,36 @@
 {
 	pci_sc520_init(&enet_hose);
 }
+
+int pci_set_regions(struct pci_controller *hose)
+{
+	/* System memory space */
+	pci_set_region(hose->regions + 0,
+		       SC520_PCI_MEMORY_BUS,
+		       SC520_PCI_MEMORY_PHYS,
+		       SC520_PCI_MEMORY_SIZE,
+		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+	/* ISA/PCI memory space */
+	pci_set_region(hose->regions + 1,
+		       SC520_ISA_MEM_BUS,
+		       SC520_ISA_MEM_PHYS,
+		       SC520_ISA_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* PCI I/O space */
+	pci_set_region(hose->regions + 2,
+		       SC520_PCI_IO_BUS,
+		       SC520_PCI_IO_PHYS,
+		       SC520_PCI_IO_SIZE,
+		       PCI_REGION_IO);
+
+	/* ISA/PCI I/O space */
+	pci_set_region(hose->regions + 3,
+		       SC520_ISA_IO_BUS,
+		       SC520_ISA_IO_PHYS,
+		       SC520_ISA_IO_SIZE,
+		       PCI_REGION_IO);
+
+	return 4;
+}
diff --git a/board/eNET/hardware.h b/board/eNET/hardware.h
index 42474a6..dec2cd8 100644
--- a/board/eNET/hardware.h
+++ b/board/eNET/hardware.h
@@ -31,5 +31,6 @@
 #define LED_RX_BITMASK		0x08
 #define LED_TX_BITMASK		0x10
 #define LED_ERR_BITMASK		0x20
+#define WATCHDOG_PIO_BIT	0x8000
 
 #endif /* HARDWARE_H_ */
diff --git a/board/eNET/u-boot.lds b/board/eNET/u-boot.lds
index 0d74021..7b0ffaa 100644
--- a/board/eNET/u-boot.lds
+++ b/board/eNET/u-boot.lds
@@ -27,7 +27,7 @@
 
 SECTIONS
 {
-	. = 0x38040000;		/* Location of bootcode in flash */
+	. = 0x06000000;		/* Location of bootcode in flash */
 	_i386boot_text_start = .;
 	.text  : { *(.text); }
 
@@ -97,14 +97,13 @@
 	 * at reset and the code have to fit.
 	 * The fff0 offset of resetvec is important, however.
 	 */
-
 	. = 0xfffffe00;
-	.start32 : AT (0x3807fe00) { *(.start32); }
+	.start32 : AT (0x0603fe00) { *(.start32); }
 
 	. = 0xf800;
-	.start16 : AT (0x3807f800) { *(.start16); }
+	.start16 : AT (0x0603f800) { *(.start16); }
 
 	. = 0xfff0;
-	.resetvec : AT (0x3807fff0) { *(.resetvec); }
+	.resetvec : AT (0x0603fff0) { *(.resetvec); }
 	_i386boot_end = (LOADADDR(.resetvec) + SIZEOF(.resetvec) );
 }
diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c
index 2ae4cbd..a199d46 100644
--- a/board/esd/cpci750/cpci750.c
+++ b/board/esd/cpci750/cpci750.c
@@ -1090,3 +1090,15 @@
 	"Show Marvell strapping register",
 	"Show Marvell strapping register (ResetSampleLow ResetSampleHigh)"
 );
+
+int do_pldver(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	printf("PLD version:0x%02x\n", in_8((void *)CONFIG_SYS_PLD_VER));
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	pldver, 1, 1, do_pldver,
+	"Show PLD version",
+	"Show PLD version)");
diff --git a/board/esd/cpci750/sdram_init.c b/board/esd/cpci750/sdram_init.c
index 4c03630..5347958 100644
--- a/board/esd/cpci750/sdram_init.c
+++ b/board/esd/cpci750/sdram_init.c
@@ -538,14 +538,14 @@
 			break;
 /*------------------------------------------------------------------------------------------------------------------------------*/
 
-#ifdef CONFIG_ECC
+#ifdef CONFIG_MV64360_ECC
 		case 11:	/* Error Check Type */
 			dimmInfo->errorCheckType = data[i];
 			DP (printf
 			    ("Error Check Type (0=NONE):			%d\n",
 			     dimmInfo->errorCheckType));
 			break;
-#endif
+#endif /* of ifdef CONFIG_MV64360_ECC */
 /*------------------------------------------------------------------------------------------------------------------------------*/
 
 		case 12:	/* Refresh Interval */
@@ -1254,6 +1254,7 @@
 	ulong tmp;
 	ulong tmp_sdram_mode = 0;	/* 0x141c */
 	ulong tmp_dunit_control_low = 0;	/* 0x1404 */
+	uint sdram_config_reg = CONFIG_SYS_SDRAM_CONFIG;
 	int i;
 
 	/* sanity checking */
@@ -1269,7 +1270,6 @@
 		DP (printf
 		    ("Module is registered, but we do not support registered Modules !!!\n"));
 
-
 	/* delay line */
 	set_dfcdlInit ();	/* may be its not needed */
 	DP (printf ("Delay line set done\n"));
@@ -1280,9 +1280,17 @@
 		DP (printf
 		    ("\n*** SDRAM_OPERATION 1418: Module still busy ... please wait... ***\n"));
 	}
+
+#ifdef CONFIG_MV64360_ECC
+	if ((info->errorCheckType == 0x2) && (CPCI750_ECC_TEST)) {
+		/* DRAM has ECC, so turn it on */
+		sdram_config_reg |= BIT18;
+		DP(printf("Enabling ECC\n"));
+	}
+#endif /* of ifdef CONFIG_MV64360_ECC */
 
 	/* SDRAM configuration */
-	GT_REG_WRITE (SDRAM_CONFIG, 0x58200400);
+	GT_REG_WRITE(SDRAM_CONFIG, sdram_config_reg);
 	DP (printf ("sdram_conf 0x1400: %08x\n", GTREGREAD (SDRAM_CONFIG)));
 
 	/* SDRAM open pages controll keep open as much as I can */
@@ -1598,7 +1606,84 @@
     return maxsize;
 }
 
+#ifdef CONFIG_MV64360_ECC
+/*
+ * mv_dma_is_channel_active:
+ * Checks if a engine is busy.
+ */
+int mv_dma_is_channel_active(int engine)
+{
+	ulong data;
+
+	data = GTREGREAD(MV64360_DMA_CHANNEL0_CONTROL + 4 * engine);
+	if (data & BIT14)	/* activity status */
+		return 1;
+
+	return 0;
+}
+
+/*
+ * mv_dma_set_memory_space:
+ * Set a DMA memory window for the DMA's address decoding map.
+ */
+int mv_dma_set_memory_space(ulong mem_space, ulong mem_space_target,
+			    ulong mem_space_attr, ulong base_address,
+			    ulong size)
+{
+	ulong temp;
+
+	/* The base address must be aligned to the size.  */
+	if (base_address % size != 0)
+		return 0;
+
+	if (size >= 0x10000) {
+		size &= 0xffff0000;
+		base_address = (base_address & 0xffff0000);
+		/* Set the new attributes */
+		GT_REG_WRITE(MV64360_DMA_BASE_ADDR_REG0 + mem_space * 8,
+			     (base_address | mem_space_target |
+			      mem_space_attr));
+		GT_REG_WRITE((MV64360_DMA_SIZE_REG0 + mem_space * 8),
+			     (size - 1) & 0xffff0000);
+		temp = GTREGREAD(MV64360_DMA_BASE_ADDR_ENABLE_REG);
+		GT_REG_WRITE(DMA_BASE_ADDR_ENABLE_REG,
+			     (temp & ~(BIT0 << mem_space)));
+		return 1;
+	}
+
-/* ------------------------------------------------------------------------- */
+	return 0;
+}
+
+
+/*
+ * mv_dma_transfer:
+ * Transfer data from source_addr to dest_addr on one of the 4 DMA channels.
+ */
+int mv_dma_transfer(int engine, ulong source_addr,
+		    ulong dest_addr, ulong bytes, ulong command)
+{
+	ulong eng_off_reg;	/* Engine Offset Register */
+
+	if (bytes > 0xffff)
+		command = command | BIT31;	 /* DMA_16M_DESCRIPTOR_MODE */
+
+	command = command | ((command >> 6) & 0x7);
+	eng_off_reg = engine * 4;
+	GT_REG_WRITE(MV64360_DMA_CHANNEL0_BYTE_COUNT + eng_off_reg,
+		     bytes);
+	GT_REG_WRITE(MV64360_DMA_CHANNEL0_SOURCE_ADDR + eng_off_reg,
+		     source_addr);
+	GT_REG_WRITE(MV64360_DMA_CHANNEL0_DESTINATION_ADDR + eng_off_reg,
+		     dest_addr);
+	command |= BIT12	/* DMA_CHANNEL_ENABLE */
+		| BIT9;		/* DMA_NON_CHAIN_MODE */
+
+	/* Activate DMA engine By writting to mv_dma_control_register */
+	GT_REG_WRITE(MV64360_DMA_CHANNEL0_CONTROL + eng_off_reg, command);
+
+	return 1;
+}
+#endif /* of ifdef CONFIG_MV64360_ECC */
 
 /* ppcboot interface function to SDRAM init - this is where all the
  * controlling logic happens */
@@ -1607,10 +1692,13 @@
 {
 	int s0 = 0, s1 = 0;
 	int checkbank[4] = { [0 ... 3] = 0 };
-		ulong bank_no, realsize, total, check;
+	ulong realsize, total, check;
 	AUX_MEM_DIMM_INFO dimmInfo1;
 	AUX_MEM_DIMM_INFO dimmInfo2;
-	int nhr;
+	int bank_no, nhr;
+#ifdef CONFIG_MV64360_ECC
+	ulong dest, mem_space_attr;
+#endif /* of ifdef CONFIG_MV64360_ECC */
 
 	/* first, use the SPD to get info about the SDRAM/ DDRRAM */
 
@@ -1668,6 +1756,28 @@
 		realsize = dram_size((long int *)total, check);
 		memory_map_bank(bank_no, total, realsize);
 
+#ifdef CONFIG_MV64360_ECC
+		if (((dimmInfo1.errorCheckType != 0) &&
+		     ((dimmInfo2.errorCheckType != 0) ||
+		      (dimmInfo2.numOfModuleBanks == 0))) &&
+		    (CPCI750_ECC_TEST)) {
+			printf("ECC Initialization of Bank %d:", bank_no);
+			mem_space_attr = ((~(BIT0 << bank_no)) & 0xf) << 8;
+			mv_dma_set_memory_space(0, 0, mem_space_attr, total,
+						realsize);
+			for (dest = total; dest < total + realsize;
+			     dest += _8M) {
+				mv_dma_transfer(0, total, dest, _8M,
+						BIT8 |	/* DMA_DTL_128BYTES */
+						BIT3 |	/* DMA_HOLD_SOURCE_ADDR */
+						BIT11);	/* DMA_BLOCK_TRANSFER_MODE */
+				while (mv_dma_is_channel_active(0))
+					;
+			}
+			printf(" PASS\n");
+		}
+#endif /* of ifdef CONFIG_MV64360_ECC */
+
 		total += realsize;
 	}
 
@@ -1700,3 +1810,30 @@
 
 	return (0);
 }
+
+int do_show_ecc(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unsigned int ecc_counter;
+	unsigned int ecc_addr;
+
+	GT_REG_READ(0x1458, &ecc_counter);
+	GT_REG_READ(0x1450, &ecc_addr);
+	GT_REG_WRITE(0x1450, 0);
+
+	printf("Error Counter since Reset:  %8d\n", ecc_counter);
+	printf("Last error address       :0x%08x (" , ecc_addr & 0xfffffff8);
+	if (ecc_addr & 0x01)
+		printf("double");
+	else
+		printf("single");
+	printf(" bit) at DDR-RAM CS#%d\n", ((ecc_addr & 0x6) >> 1));
+
+	return 0;
+}
+
+
+U_BOOT_CMD(
+	show_ecc, 1, 1, do_show_ecc,
+	"Show Marvell MV64360 ECC Info",
+	"Show Marvell MV64360 ECC Counter and last error."
+);
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 452686d..da06009 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -344,11 +344,8 @@
 			printf ("   XIP %s ... ", type_name);
 		} else {
 			printf ("   Loading %s ... ", type_name);
-
-			if (load != image_start) {
-				memmove_wd ((void *)load,
-						(void *)image_start, image_len, CHUNKSZ);
-			}
+			memmove_wd ((void *)load, (void *)image_start,
+					image_len, CHUNKSZ);
 		}
 		*load_end = load + image_len;
 		puts("OK\n");
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 565257c..2646ae9 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -330,154 +330,231 @@
 	return 0;
 }
 
-int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+static int do_onenand_info(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
-	struct onenand_chip *this;
-	int blocksize;
+	printf("%s\n", mtd->name);
+	return 0;
+}
+
+static int do_onenand_bad(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	ulong ofs;
+
+	mtd = &onenand_mtd;
+	/* Currently only one OneNAND device is supported */
+	printf("\nDevice %d bad blocks:\n", 0);
+	for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
+		if (mtd->block_isbad(mtd, ofs))
+			printf("  %08x\n", (u32)ofs);
+	}
+
+	return 0;
+}
+
+static int do_onenand_read(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	char *s;
+	int oob = 0;
 	ulong addr, ofs;
-	size_t len, retlen = 0;
+	size_t len;
 	int ret = 0;
-	char *cmd, *s;
+	size_t retlen = 0;
 
-	mtd = &onenand_mtd;
-	this = mtd->priv;
-	blocksize = (1 << this->erase_shift);
+	if (argc < 3)
+	{
+		cmd_usage(cmdtp);
+		return 1;
+	}
 
-	cmd = argv[1];
+	s = strchr(argv[0], '.');
+	if ((s != NULL) && (!strcmp(s, ".oob")))
+		oob = 1;
 
-	switch (argc) {
-	case 0:
-	case 1:
-		goto usage;
+	addr = (ulong)simple_strtoul(argv[1], NULL, 16);
 
-	case 2:
-		if (strcmp(cmd, "info") == 0) {
-			printf("%s\n", mtd->name);
-			return 0;
-		}
+	printf("\nOneNAND read: ");
+	if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0)
+		return 1;
 
-		if (strcmp(cmd, "bad") == 0) {
-			/* Currently only one OneNAND device is supported */
-			printf("\nDevice %d bad blocks:\n", 0);
-			for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
-				if (mtd->block_isbad(mtd, ofs))
-					printf("  %08x\n", (u32)ofs);
-			}
+	ret = onenand_block_read(ofs, len, &retlen, (u8 *)addr, oob);
 
-			return 0;
-		}
+	printf(" %d bytes read: %s\n", retlen, ret ? "ERROR" : "OK");
+
+	return ret == 0 ? 0 : 1;
+}
+
+static int do_onenand_write(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	ulong addr, ofs;
+	size_t len;
+	int ret = 0;
+	size_t retlen = 0;
 
-	default:
-		/* At least 4 args */
+	if (argc < 3)
+	{
+		cmd_usage(cmdtp);
+		return 1;
+	}
 
-		/*
-		 * Syntax is:
-		 *   0       1     2       3    4
-		 *   onenand erase [force] [off size]
-		 */
-		if ((strcmp(cmd, "erase") == 0) || (strcmp(cmd, "test") == 0)) {
-			int force = argc > 2 && !strcmp("force", argv[2]);
-			int o = force ? 3 : 2;
-			int erase;
+	addr = (ulong)simple_strtoul(argv[1], NULL, 16);
 
-			erase = strcmp(cmd, "erase") == 0; /* 1 = erase, 0 = test */
-			printf("\nOneNAND %s: ", erase ? "erase" : "test");
+	printf("\nOneNAND write: ");
+	if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0)
+		return 1;
 
-			/* skip first two or three arguments, look for offset and size */
-			if (arg_off_size(argc - o, argv + o, &ofs, &len) != 0)
-				return 1;
+	ret = onenand_block_write(ofs, len, &retlen, (u8 *)addr);
 
-			if (erase)
-				ret = onenand_block_erase(ofs, len, force);
-			else
-				ret = onenand_block_test(ofs, len);
+	printf(" %d bytes written: %s\n", retlen, ret ? "ERROR" : "OK");
 
-			printf("%s\n", ret ? "ERROR" : "OK");
+	return ret == 0 ? 0 : 1;
+}
 
-			return ret == 0 ? 0 : 1;
+static int do_onenand_erase(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	ulong ofs;
+	int ret = 0;
+	size_t len;
+	int force;
+
+	/*
+	 * Syntax is:
+	 *   0       1     2       3    4
+	 *   onenand erase [force] [off size]
+	 */
+	argc--;
+	argv++;
+	if (argc)
+	{
+		if (!strcmp("force", argv[0]))
+		{
+			force = 1;
+			argc--;
+			argv++;
 		}
+	}
+	printf("\nOneNAND erase: ");
 
-		if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
-			int read;
-			int oob = 0;
+	/* skip first two or three arguments, look for offset and size */
+	if (arg_off_size(argc, argv, &ofs, &len) != 0)
+		return 1;
 
-			if (argc < 4)
-				goto usage;
+	ret = onenand_block_erase(ofs, len, force);
 
-			addr = (ulong)simple_strtoul(argv[2], NULL, 16);
+	printf("%s\n", ret ? "ERROR" : "OK");
 
-			read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
-			printf("\nOneNAND %s: ", read ? "read" : "write");
-			if (arg_off_size(argc - 3, argv + 3, &ofs, &len) != 0)
-				return 1;
+	return ret == 0 ? 0 : 1;
+}
 
-			s = strchr(cmd, '.');
-			if ((s != NULL) && (!strcmp(s, ".oob")))
-				oob = 1;
+static int do_onenand_test(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	ulong ofs;
+	int ret = 0;
+	size_t len;
 
-			if (read) {
-				ret = onenand_block_read(ofs, len, &retlen,
-							 (u8 *)addr, oob);
-			} else {
-				ret = onenand_block_write(ofs, len, &retlen,
-							  (u8 *)addr);
-			}
+	/*
+	 * Syntax is:
+	 *   0       1     2       3    4
+	 *   onenand test [force] [off size]
+	 */
 
-			printf(" %d bytes %s: %s\n", retlen,
-			       read ? "read" : "written", ret ? "ERROR" : "OK");
+	printf("\nOneNAND test: ");
 
-			return ret == 0 ? 0 : 1;
-		}
+	/* skip first two or three arguments, look for offset and size */
+	if (arg_off_size(argc - 1, argv + 1, &ofs, &len) != 0)
+		return 1;
 
-		if (strcmp(cmd, "markbad") == 0) {
-			argc -= 2;
-			argv += 2;
+	ret = onenand_block_test(ofs, len);
 
-			if (argc <= 0)
-				goto usage;
+	printf("%s\n", ret ? "ERROR" : "OK");
 
-			while (argc > 0) {
-				addr = simple_strtoul(*argv, NULL, 16);
+	return ret == 0 ? 0 : 1;
+}
 
-				if (mtd->block_markbad(mtd, addr)) {
-					printf("block 0x%08lx NOT marked "
-						"as bad! ERROR %d\n",
-						addr, ret);
-					ret = 1;
-				} else {
-					printf("block 0x%08lx successfully "
-						"marked as bad\n",
-						addr);
-				}
-				--argc;
-				++argv;
-			}
-			return ret;
-		}
+static int do_onenand_dump(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	ulong ofs;
+	int ret = 0;
+	char *s;
 
-		if (strncmp(cmd, "dump", 4) == 0) {
-			if (argc < 3)
-				goto usage;
+	if (argc < 2)
+	{
+		cmd_usage(cmdtp);
+		return 1;
+	}
 
-			s = strchr(cmd, '.');
-			ofs = (int)simple_strtoul(argv[2], NULL, 16);
+	s = strchr(argv[0], '.');
+	ofs = (int)simple_strtoul(argv[1], NULL, 16);
 
-			if (s != NULL && strcmp(s, ".oob") == 0)
-				ret = onenand_dump(mtd, ofs, 1);
-			else
-				ret = onenand_dump(mtd, ofs, 0);
+	if (s != NULL && strcmp(s, ".oob") == 0)
+		ret = onenand_dump(mtd, ofs, 1);
+	else
+		ret = onenand_dump(mtd, ofs, 0);
 
-			return ret == 0 ? 1 : 0;
-		}
+	return ret == 0 ? 1 : 0;
+}
+
+static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	int ret = 0;
+	ulong addr;
 
-		break;
+	argc -= 2;
+	argv += 2;
+
+	if (argc <= 0)
+	{
+		cmd_usage(cmdtp);
+		return 1;
 	}
 
-	return 0;
+	while (argc > 0) {
+		addr = simple_strtoul(*argv, NULL, 16);
+
+		if (mtd->block_markbad(mtd, addr)) {
+			printf("block 0x%08lx NOT marked "
+				"as bad! ERROR %d\n",
+				addr, ret);
+			ret = 1;
+		} else {
+			printf("block 0x%08lx successfully "
+				"marked as bad\n",
+				addr);
+		}
+		--argc;
+		++argv;
+	}
+	return ret;
+}
+
+static cmd_tbl_t cmd_onenand_sub[] = {
+	U_BOOT_CMD_MKENT(info, 1, 0, do_onenand_info, "", ""),
+	U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", ""),
+	U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", ""),
+	U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", ""),
+	U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", ""),
+	U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", ""),
+	U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", ""),
+	U_BOOT_CMD_MKENT(markbad, CONFIG_SYS_MAXARGS, 0, do_onenand_markbad, "", ""),
+};
 
-usage:
-	cmd_usage(cmdtp);
-	return 1;
+static int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	cmd_tbl_t *c;
+
+	mtd = &onenand_mtd;
+
+	/* Strip off leading 'onenand' command argument */
+	argc--;
+	argv++;
+
+	c = find_cmd_tbl(argv[0], &cmd_onenand_sub[0], ARRAY_SIZE(cmd_onenand_sub));
+
+	if (c) {
+		return  c->cmd(cmdtp, flag, argc, argv);
+	} else {
+		cmd_usage(cmdtp);
+		return 1;
+	}
 }
 
 U_BOOT_CMD(
@@ -486,7 +563,7 @@
 	"info - show available OneNAND devices\n"
 	"onenand bad - show bad blocks\n"
 	"onenand read[.oob] addr off size\n"
-	"onenand write[.oob] addr off size\n"
+	"onenand write addr off size\n"
 	"    read/write 'size' bytes starting at offset 'off'\n"
 	"    to/from memory address 'addr', skipping bad blocks.\n"
 	"onenand erase [force] [off size] - erase 'size' bytes from\n"
diff --git a/common/command.c b/common/command.c
index 0c66b7a..67ad692 100644
--- a/common/command.c
+++ b/common/command.c
@@ -188,6 +188,9 @@
 
 void install_auto_complete(void)
 {
+#if defined(CONFIG_CMD_EDITENV)
+	install_auto_complete_handler("editenv", var_complete);
+#endif
 	install_auto_complete_handler("printenv", var_complete);
 	install_auto_complete_handler("setenv", var_complete);
 #if defined(CONFIG_CMD_RUN)
diff --git a/common/image.c b/common/image.c
index 9e49713..8d4be14 100644
--- a/common/image.c
+++ b/common/image.c
@@ -450,6 +450,9 @@
 
 void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
 {
+	if (to == from)
+		return;
+
 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 	while (len > 0) {
 		size_t tail = (len > chunksz) ? chunksz : len;
diff --git a/common/serial.c b/common/serial.c
index 0682faa..fceabfa 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -41,7 +41,8 @@
 #elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
    || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \
    || defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC83xx) \
-   || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+   || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) \
+   || defined(CONFIG_SYS_SC520)
 #if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL)
 #if (CONFIG_CONS_INDEX==1)
 	return &eserial1_device;
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 23c0f76..7e833fd 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -7,6 +7,8 @@
 #include <config.h>
 #include <ns16550.h>
 #include <watchdog.h>
+#include <linux/types.h>
+#include <asm/io.h>
 
 #define UART_LCRVAL UART_LCR_8N1		/* 8 data, 1 stop, no parity */
 #define UART_MCRVAL (UART_MCR_DTR | \
@@ -14,28 +16,35 @@
 #define UART_FCRVAL (UART_FCR_FIFO_EN |	\
 		     UART_FCR_RXSR |	\
 		     UART_FCR_TXSR)		/* Clear & enable FIFOs */
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+#define serial_out(x,y)	outb(x,(ulong)y)
+#define serial_in(y)	inb((ulong)y)
+#else
+#define serial_out(x,y) writeb(x,y)
+#define serial_in(y) 	readb(y)
+#endif
 
 void NS16550_init (NS16550_t com_port, int baud_divisor)
 {
-	com_port->ier = 0x00;
+	serial_out(0x00, &com_port->ier);
 #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
-	com_port->mdr1 = 0x7;	/* mode select reset TL16C750*/
+	serial_out(0x7, &com_port->mdr1);	/* mode select reset TL16C750*/
 #endif
-	com_port->lcr = UART_LCR_BKSE | UART_LCRVAL;
-	com_port->dll = 0;
-	com_port->dlm = 0;
-	com_port->lcr = UART_LCRVAL;
-	com_port->mcr = UART_MCRVAL;
-	com_port->fcr = UART_FCRVAL;
-	com_port->lcr = UART_LCR_BKSE | UART_LCRVAL;
-	com_port->dll = baud_divisor & 0xff;
-	com_port->dlm = (baud_divisor >> 8) & 0xff;
-	com_port->lcr = UART_LCRVAL;
+	serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr);
+	serial_out(0, &com_port->dll);
+	serial_out(0, &com_port->dlm);
+	serial_out(UART_LCRVAL, &com_port->lcr);
+	serial_out(UART_MCRVAL, &com_port->mcr);
+	serial_out(UART_FCRVAL, &com_port->fcr);
+	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
+	serial_out(baud_divisor & 0xff, &com_port->dll);
+	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
+	serial_out(UART_LCRVAL, &com_port->lcr);
 #if defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)
 #if defined(CONFIG_APTIX)
-	com_port->mdr1 = 3;	/* /13 mode so Aptix 6MHz can hit 115200 */
+	serial_out(3, &com_port->mdr1);	/* /13 mode so Aptix 6MHz can hit 115200 */
 #else
-	com_port->mdr1 = 0;	/* /16 is proper to hit 115200 with 48MHz */
+	serial_out(0, &com_port->mdr1);	/* /16 is proper to hit 115200 with 48MHz */
 #endif
 #endif /* CONFIG_OMAP */
 }
@@ -43,42 +52,42 @@
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
 void NS16550_reinit (NS16550_t com_port, int baud_divisor)
 {
-	com_port->ier = 0x00;
-	com_port->lcr = UART_LCR_BKSE | UART_LCRVAL;
-	com_port->dll = 0;
-	com_port->dlm = 0;
-	com_port->lcr = UART_LCRVAL;
-	com_port->mcr = UART_MCRVAL;
-	com_port->fcr = UART_FCRVAL;
-	com_port->lcr = UART_LCR_BKSE;
-	com_port->dll = baud_divisor & 0xff;
-	com_port->dlm = (baud_divisor >> 8) & 0xff;
-	com_port->lcr = UART_LCRVAL;
+	serial_out(0x00, &com_port->ier);
+	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
+	serial_out(0, &com_port->dll);
+	serial_out(0, &com_port->dlm);
+	serial_out(UART_LCRVAL, &com_port->lcr);
+	serial_out(UART_MCRVAL, &com_port->mcr);
+	serial_out(UART_FCRVAL, &com_port->fcr);
+	serial_out(UART_LCR_BKSE, &com_port->lcr);
+	serial_out(baud_divisor & 0xff, &com_port->dll);
+	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
+	serial_out(UART_LCRVAL, &com_port->lcr);
 }
 #endif /* CONFIG_NS16550_MIN_FUNCTIONS */
 
 void NS16550_putc (NS16550_t com_port, char c)
 {
-	while ((com_port->lsr & UART_LSR_THRE) == 0);
-	com_port->thr = c;
+	while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0);
+	serial_out(c, &com_port->thr);
 }
 
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
 char NS16550_getc (NS16550_t com_port)
 {
-	while ((com_port->lsr & UART_LSR_DR) == 0) {
+	while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
 #ifdef CONFIG_USB_TTY
 		extern void usbtty_poll(void);
 		usbtty_poll();
 #endif
 		WATCHDOG_RESET();
 	}
-	return (com_port->rbr);
+	return serial_in(&com_port->rbr);
 }
 
 int NS16550_tstc (NS16550_t com_port)
 {
-	return ((com_port->lsr & UART_LSR_DR) != 0);
+	return ((serial_in(&com_port->lsr) & UART_LSR_DR) != 0);
 }
 
 #endif /* CONFIG_NS16550_MIN_FUNCTIONS */
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 200b907..f09e55f 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -23,7 +23,6 @@
 LIB	:= $(obj)libusb_phy.a
 
 COBJS-$(CONFIG_TWL4030_USB) += twl4030.o
-COBJS-y := twl4030.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index a5e339a..7d84fc7 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -25,20 +25,19 @@
 
 LIB	:= $(obj)libvideo.a
 
-COBJS-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o
+COBJS-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 COBJS-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
 COBJS-$(CONFIG_CFB_CONSOLE) += cfb_console.o
 COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
 COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
-COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o
-COBJS-$(CONFIG_VIDEO_MB862xx) += mb862xx.o
+COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
+COBJS-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o
 COBJS-$(CONFIG_VIDEO_MX3) += mx3fb.o
 COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o
 COBJS-$(CONFIG_SED156X) += sed156x.o
 COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
-COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o
+COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
 COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
-COBJS-y += videomodes.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/include/asm-generic/ioctl.h b/include/asm-generic/ioctl.h
new file mode 100644
index 0000000..15828b2
--- /dev/null
+++ b/include/asm-generic/ioctl.h
@@ -0,0 +1,105 @@
+#ifndef _ASM_GENERIC_IOCTL_H
+#define _ASM_GENERIC_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The generic ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+
+/*
+ * Let any architecture override either of the following before
+ * including this file.
+ */
+
+#ifndef _IOC_SIZEBITS
+# define _IOC_SIZEBITS	14
+#endif
+
+#ifndef _IOC_DIRBITS
+# define _IOC_DIRBITS	2
+#endif
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits, which any architecture can choose to override
+ * before including this file.
+ */
+
+#ifndef _IOC_NONE
+# define _IOC_NONE	0U
+#endif
+
+#ifndef _IOC_WRITE
+# define _IOC_WRITE	1U
+#endif
+
+#ifndef _IOC_READ
+# define _IOC_READ	2U
+#endif
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+#ifdef __KERNEL__
+/* provoke compile error for invalid uses of size argument */
+extern unsigned int __invalid_size_argument_for_IOC;
+#define _IOC_TYPECHECK(t) \
+	((sizeof(t) == sizeof(t[1]) && \
+	  sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
+	  sizeof(t) : __invalid_size_argument_for_IOC)
+#else
+#define _IOC_TYPECHECK(t) (sizeof(t))
+#endif
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOR_BAD(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW_BAD(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR_BAD(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _ASM_GENERIC_IOCTL_H */
diff --git a/include/common.h b/include/common.h
index df956bb..5591e1d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -218,7 +218,7 @@
 /* */
 phys_size_t initdram (int);
 int	display_options (void);
-void	print_size (phys_size_t, const char *);
+void	print_size(unsigned long long, const char *);
 int	print_buffer (ulong addr, void* data, uint width, uint count, uint linelen);
 
 /* common/main.c */
diff --git a/include/compiler.h b/include/compiler.h
index 332618e..8030bf6 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -55,6 +55,7 @@
 typedef uint8_t __u8;
 typedef uint16_t __u16;
 typedef uint32_t __u32;
+typedef unsigned int uint;
 
 #define uswap_16(x) \
 	((((x) & 0xff00) >> 8) | \
diff --git a/include/configs/CPCI750.h b/include/configs/CPCI750.h
index d516c3c..1c8c68b 100644
--- a/include/configs/CPCI750.h
+++ b/include/configs/CPCI750.h
@@ -59,7 +59,7 @@
 
 #define CONFIG_BAUDRATE		9600	/* console baudrate = 9600	*/
 
-#undef	CONFIG_ECC			/* enable ECC support */
+#define CONFIG_MV64360_ECC		/* enable ECC support */
 
 #define CONFIG_HIGH_BATS	1	/* High BATs supported */
 
@@ -628,5 +628,7 @@
 #define CONFIG_SYS_BOARD_ASM_INIT	1
 
 #define CPCI750_SLAVE_TEST	(((in8(0xf0300000) & 0x80) == 0) ? 0 : 1)
+#define CPCI750_ECC_TEST	(((in8(0xf0300000) & 0x02) == 0) ? 1 : 0)
+#define CONFIG_SYS_PLD_VER	0xf0e00000
 
 #endif	/* __CONFIG_H */
diff --git a/include/configs/eNET.h b/include/configs/eNET.h
index 6a68bf4..361fe61 100644
--- a/include/configs/eNET.h
+++ b/include/configs/eNET.h
@@ -21,6 +21,7 @@
  * MA 02111-1307 USA
  */
 
+#include <asm/ibmpc.h>
 /*
  * board/config.h - configuration options, board specific
  */
@@ -52,9 +53,29 @@
  * bottom (processor) board MUST be removed!
  */
 #undef CONFIG_WATCHDOG
-#undef CONFIG_HW_WATCHDOG
+#define CONFIG_HW_WATCHDOG
 
  /*-----------------------------------------------------------------------
+  * Serial Configuration
+  */
+#define CONFIG_SERIAL_MULTI
+#undef CONFIG_SERIAL_SOFTWARE_FIFO
+#define CONFIG_CONS_INDEX		1
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	1
+#define CONFIG_SYS_NS16550_CLK		1843200
+#define CONFIG_BAUDRATE			9600
+#define CONFIG_SYS_BAUDRATE_TABLE	\
+	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200}
+
+#define CONFIG_SYS_NS16550_COM1		UART0_BASE
+#define CONFIG_SYS_NS16550_COM2		UART1_BASE
+#define CONFIG_SYS_NS16550_COM3		(0x1000 + UART0_BASE)
+#define CONFIG_SYS_NS16550_COM4		(0x1000 + UART1_BASE)
+#define CONFIG_SYS_NS16550_PORT_MAPPED
+
+ /*-----------------------------------------------------------------------
   * Video Configuration
   */
 #undef CONFIG_VIDEO			/* No Video Hardware */
@@ -65,8 +86,6 @@
  */
 #define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 128*1024)
 
-#define CONFIG_BAUDRATE		9600
-
 /*-----------------------------------------------------------------------
  * Command line configuration.
  */
@@ -86,9 +105,10 @@
 #define CONFIG_CMD_LOADS	/* loads			*/
 #define CONFIG_CMD_MEMORY	/* md mm nm mw cp cmp crc base loop mtest */
 #define CONFIG_CMD_MISC		/* Misc functions like sleep etc*/
-#undef CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/
+#define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/
 #undef CONFIG_CMD_NFS		/* NFS support			*/
 #define CONFIG_CMD_PCI		/* PCI support			*/
+#define CONFIG_CMD_PING		/* ICMP echo support		*/
 #define CONFIG_CMD_RUN		/* run command in env variable	*/
 #define CONFIG_CMD_SAVEENV	/* saveenv			*/
 #define CONFIG_CMD_SETGETDCR	/* DCR support on 4xx		*/
@@ -121,10 +141,7 @@
 
 #define	CONFIG_SYS_LOAD_ADDR		0x100000	/* default load address	*/
 
-#define	CONFIG_SYS_HZ			1024		/* incrementer freq: 1kHz */
-
-						/* valid baudrates */
-#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define	CONFIG_SYS_HZ			1000		/* incrementer freq: 1kHz */
 
 /*-----------------------------------------------------------------------
  * SDRAM Configuration
@@ -143,7 +160,7 @@
  * CPU Features
  */
 #define CONFIG_SYS_SC520_HIGH_SPEED	0	/* 100 or 133MHz */
-#undef  CONFIG_SYS_SC520_RESET			/* use SC520 MMCR's to reset cpu */
+#define CONFIG_SYS_SC520_RESET			/* use SC520 MMCR's to reset cpu */
 #define CONFIG_SYS_SC520_TIMER			/* use SC520 swtimers */
 #undef  CONFIG_SYS_GENERIC_TIMER		/* use the i8254 PIT timers */
 #undef  CONFIG_SYS_TSC_TIMER			/* use the Pentium TSC timers */
@@ -182,7 +199,7 @@
 					 CONFIG_SYS_FLASH_BASE_1, \
 					 CONFIG_SYS_FLASH_BASE_2}
 #define CONFIG_SYS_FLASH_EMPTY_INFO
-#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+#undef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
 #define CONFIG_SYS_MAX_FLASH_SECT	128	/* max number of sectors on one chip */
 #define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
 #define CONFIG_SYS_FLASH_LEGACY_512Kx8
@@ -210,13 +227,11 @@
 #define CONFIG_SYS_THIRD_PCI_IRQ   11
 #define CONFIG_SYS_FORTH_PCI_IRQ   15
 
-/*-----------------------------------------------------------------------
- * Hardware watchdog configuration
+ /*
+ * Network device (TRL8100B) support
  */
-#define CONFIG_SYS_WATCHDOG_PIO_BIT  		0x8000
-#define CONFIG_SYS_WATCHDIG_PIO_DATA 		SC520_PIODATA15_0
-#define CONFIG_SYS_WATCHDIG_PIO_CLR  		SC520_PIOCLR15_0
-#define CONFIG_SYS_WATCHDIG_PIO_SET  		SC520_PIOSET15_0
+#define CONFIG_NET_MULTI
+#define CONFIG_RTL8139
 
 /*-----------------------------------------------------------------------
  * FPGA configuration
diff --git a/include/linux/apm_bios.h b/include/linux/apm_bios.h
new file mode 100644
index 0000000..01a6244
--- /dev/null
+++ b/include/linux/apm_bios.h
@@ -0,0 +1,220 @@
+#ifndef _LINUX_APM_H
+#define _LINUX_APM_H
+
+/*
+ * Include file for the interface to an APM BIOS
+ * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
+ *
+ * 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, 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.
+ */
+
+#include <linux/types.h>
+
+typedef unsigned short	apm_event_t;
+typedef unsigned short	apm_eventinfo_t;
+
+struct apm_bios_info {
+	__u16	version;
+	__u16	cseg;
+	__u32	offset;
+	__u16	cseg_16;
+	__u16	dseg;
+	__u16	flags;
+	__u16	cseg_len;
+	__u16	cseg_16_len;
+	__u16	dseg_len;
+};
+
+#ifdef __KERNEL__
+
+#define APM_CS		(GDT_ENTRY_APMBIOS_BASE * 8)
+#define APM_CS_16	(APM_CS + 8)
+#define APM_DS		(APM_CS_16 + 8)
+
+/* Results of APM Installation Check */
+#define APM_16_BIT_SUPPORT	0x0001
+#define APM_32_BIT_SUPPORT	0x0002
+#define APM_IDLE_SLOWS_CLOCK	0x0004
+#define APM_BIOS_DISABLED      	0x0008
+#define APM_BIOS_DISENGAGED     0x0010
+
+/*
+ * Data for APM that is persistent across module unload/load
+ */
+struct apm_info {
+	struct apm_bios_info	bios;
+	unsigned short		connection_version;
+	int			get_power_status_broken;
+	int			get_power_status_swabinminutes;
+	int			allow_ints;
+	int			forbid_idle;
+	int			realmode_power_off;
+	int			disabled;
+};
+
+/*
+ * The APM function codes
+ */
+#define	APM_FUNC_INST_CHECK	0x5300
+#define	APM_FUNC_REAL_CONN	0x5301
+#define	APM_FUNC_16BIT_CONN	0x5302
+#define	APM_FUNC_32BIT_CONN	0x5303
+#define	APM_FUNC_DISCONN	0x5304
+#define	APM_FUNC_IDLE		0x5305
+#define	APM_FUNC_BUSY		0x5306
+#define	APM_FUNC_SET_STATE	0x5307
+#define	APM_FUNC_ENABLE_PM	0x5308
+#define	APM_FUNC_RESTORE_BIOS	0x5309
+#define	APM_FUNC_GET_STATUS	0x530a
+#define	APM_FUNC_GET_EVENT	0x530b
+#define	APM_FUNC_GET_STATE	0x530c
+#define	APM_FUNC_ENABLE_DEV_PM	0x530d
+#define	APM_FUNC_VERSION	0x530e
+#define	APM_FUNC_ENGAGE_PM	0x530f
+#define	APM_FUNC_GET_CAP	0x5310
+#define	APM_FUNC_RESUME_TIMER	0x5311
+#define	APM_FUNC_RESUME_ON_RING	0x5312
+#define	APM_FUNC_TIMER		0x5313
+
+/*
+ * Function code for APM_FUNC_RESUME_TIMER
+ */
+#define	APM_FUNC_DISABLE_TIMER	0
+#define	APM_FUNC_GET_TIMER	1
+#define	APM_FUNC_SET_TIMER	2
+
+/*
+ * Function code for APM_FUNC_RESUME_ON_RING
+ */
+#define	APM_FUNC_DISABLE_RING	0
+#define	APM_FUNC_ENABLE_RING	1
+#define	APM_FUNC_GET_RING	2
+
+/*
+ * Function code for APM_FUNC_TIMER_STATUS
+ */
+#define	APM_FUNC_TIMER_DISABLE	0
+#define	APM_FUNC_TIMER_ENABLE	1
+#define	APM_FUNC_TIMER_GET	2
+
+/*
+ * in arch/i386/kernel/setup.c
+ */
+extern struct apm_info	apm_info;
+
+#endif	/* __KERNEL__ */
+
+/*
+ * Power states
+ */
+#define APM_STATE_READY		0x0000
+#define APM_STATE_STANDBY	0x0001
+#define APM_STATE_SUSPEND	0x0002
+#define APM_STATE_OFF		0x0003
+#define APM_STATE_BUSY		0x0004
+#define APM_STATE_REJECT	0x0005
+#define APM_STATE_OEM_SYS	0x0020
+#define APM_STATE_OEM_DEV	0x0040
+
+#define APM_STATE_DISABLE	0x0000
+#define APM_STATE_ENABLE	0x0001
+
+#define APM_STATE_DISENGAGE	0x0000
+#define APM_STATE_ENGAGE	0x0001
+
+/*
+ * Events (results of Get PM Event)
+ */
+#define APM_SYS_STANDBY		0x0001
+#define APM_SYS_SUSPEND		0x0002
+#define APM_NORMAL_RESUME	0x0003
+#define APM_CRITICAL_RESUME	0x0004
+#define APM_LOW_BATTERY		0x0005
+#define APM_POWER_STATUS_CHANGE	0x0006
+#define APM_UPDATE_TIME		0x0007
+#define APM_CRITICAL_SUSPEND	0x0008
+#define APM_USER_STANDBY	0x0009
+#define APM_USER_SUSPEND	0x000a
+#define APM_STANDBY_RESUME	0x000b
+#define APM_CAPABILITY_CHANGE	0x000c
+
+/*
+ * Error codes
+ */
+#define APM_SUCCESS		0x00
+#define APM_DISABLED		0x01
+#define APM_CONNECTED		0x02
+#define APM_NOT_CONNECTED	0x03
+#define APM_16_CONNECTED	0x05
+#define APM_16_UNSUPPORTED	0x06
+#define APM_32_CONNECTED	0x07
+#define APM_32_UNSUPPORTED	0x08
+#define APM_BAD_DEVICE		0x09
+#define APM_BAD_PARAM		0x0a
+#define APM_NOT_ENGAGED		0x0b
+#define APM_BAD_FUNCTION	0x0c
+#define APM_RESUME_DISABLED	0x0d
+#define APM_NO_ERROR		0x53
+#define APM_BAD_STATE		0x60
+#define APM_NO_EVENTS		0x80
+#define APM_NOT_PRESENT		0x86
+
+/*
+ * APM Device IDs
+ */
+#define APM_DEVICE_BIOS		0x0000
+#define APM_DEVICE_ALL		0x0001
+#define APM_DEVICE_DISPLAY	0x0100
+#define APM_DEVICE_STORAGE	0x0200
+#define APM_DEVICE_PARALLEL	0x0300
+#define APM_DEVICE_SERIAL	0x0400
+#define APM_DEVICE_NETWORK	0x0500
+#define APM_DEVICE_PCMCIA	0x0600
+#define APM_DEVICE_BATTERY	0x8000
+#define APM_DEVICE_OEM		0xe000
+#define APM_DEVICE_OLD_ALL	0xffff
+#define APM_DEVICE_CLASS	0x00ff
+#define APM_DEVICE_MASK		0xff00
+
+#ifdef __KERNEL__
+/*
+ * This is the "All Devices" ID communicated to the BIOS
+ */
+#define APM_DEVICE_BALL		((apm_info.connection_version > 0x0100) ? \
+				 APM_DEVICE_ALL : APM_DEVICE_OLD_ALL)
+#endif
+
+/*
+ * Battery status
+ */
+#define APM_MAX_BATTERIES	2
+
+/*
+ * APM defined capability bit flags
+ */
+#define APM_CAP_GLOBAL_STANDBY		0x0001
+#define APM_CAP_GLOBAL_SUSPEND		0x0002
+#define APM_CAP_RESUME_STANDBY_TIMER	0x0004 /* Timer resume from standby */
+#define APM_CAP_RESUME_SUSPEND_TIMER	0x0008 /* Timer resume from suspend */
+#define APM_CAP_RESUME_STANDBY_RING	0x0010 /* Resume on Ring fr standby */
+#define APM_CAP_RESUME_SUSPEND_RING	0x0020 /* Resume on Ring fr suspend */
+#define APM_CAP_RESUME_STANDBY_PCMCIA	0x0040 /* Resume on PCMCIA Ring	*/
+#define APM_CAP_RESUME_SUSPEND_PCMCIA	0x0080 /* Resume on PCMCIA Ring	*/
+
+/*
+ * ioctl operations
+ */
+#include <linux/ioctl.h>
+
+#define APM_IOC_STANDBY		_IO('A', 1)
+#define APM_IOC_SUSPEND		_IO('A', 2)
+
+#endif	/* LINUX_APM_H */
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
new file mode 100644
index 0000000..73dcf80
--- /dev/null
+++ b/include/linux/compiler-gcc.h
@@ -0,0 +1,87 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead."
+#endif
+
+/*
+ * Common definitions for all gcc versions go here.
+ */
+
+
+/* Optimization barrier */
+/* The "volatile" is due to gcc bugs */
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+/*
+ * This macro obfuscates arithmetic on a variable address so that gcc
+ * shouldn't recognize the original var, and make assumptions about it.
+ *
+ * This is needed because the C standard makes it undefined to do
+ * pointer arithmetic on "objects" outside their boundaries and the
+ * gcc optimizers assume this is the case. In particular they
+ * assume such arithmetic does not wrap.
+ *
+ * A miscompilation has been observed because of this on PPC.
+ * To work around it we hide the relationship of the pointer and the object
+ * using this macro.
+ *
+ * Versions of the ppc64 compiler before 4.1 had a bug where use of
+ * RELOC_HIDE could trash r30. The bug can be worked around by changing
+ * the inline assembly constraint from =g to =r, in this particular
+ * case either is valid.
+ */
+#define RELOC_HIDE(ptr, off)					\
+  ({ unsigned long __ptr;					\
+    __asm__ ("" : "=r"(__ptr) : "0"(ptr));		\
+    (typeof(ptr)) (__ptr + (off)); })
+
+/* &a[0] degrades to a pointer: a different type from an array */
+#define __must_be_array(a) \
+  BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
+
+/*
+ * Force always-inline if the user requests it so via the .config,
+ * or if gcc is too old:
+ */
+#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \
+    !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4)
+# define inline		inline		__attribute__((always_inline))
+# define __inline__	__inline__	__attribute__((always_inline))
+# define __inline	__inline	__attribute__((always_inline))
+#endif
+
+#define __deprecated			__attribute__((deprecated))
+#define __packed			__attribute__((packed))
+#define __weak				__attribute__((weak))
+
+/*
+ * it doesn't make sense on ARM (currently the only user of __naked) to trace
+ * naked functions because then mcount is called without stack and frame pointer
+ * being set up and there is no chance to restore the lr register to the value
+ * before mcount was called.
+ */
+#define __naked				__attribute__((naked)) notrace
+
+#define __noreturn			__attribute__((noreturn))
+
+/*
+ * From the GCC manual:
+ *
+ * Many functions have no effects except the return value and their
+ * return value depends only on the parameters and/or global
+ * variables.  Such a function can be subject to common subexpression
+ * elimination and loop optimization just as an arithmetic operator
+ * would be.
+ * [...]
+ */
+#define __pure				__attribute__((pure))
+#define __aligned(x)			__attribute__((aligned(x)))
+#define __printf(a,b)			__attribute__((format(printf,a,b)))
+#define  noinline			__attribute__((noinline))
+#define __attribute_const__		__attribute__((__const__))
+#define __maybe_unused			__attribute__((unused))
+#define __always_unused			__attribute__((unused))
+
+#define __gcc_header(x) #x
+#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
+#define gcc_header(x) _gcc_header(x)
+#include gcc_header(__GNUC__)
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
new file mode 100644
index 0000000..94dea3f
--- /dev/null
+++ b/include/linux/compiler-gcc4.h
@@ -0,0 +1,61 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead."
+#endif
+
+/* GCC 4.1.[01] miscompiles __weak */
+#ifdef __KERNEL__
+# if __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1
+#  error Your version of gcc miscompiles the __weak directive
+# endif
+#endif
+
+#define __used			__attribute__((__used__))
+#define __must_check 		__attribute__((warn_unused_result))
+#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
+#define __always_inline		inline __attribute__((always_inline))
+
+/*
+ * A trick to suppress uninitialized variable warning without generating any
+ * code
+ */
+#define uninitialized_var(x) x = x
+
+#if __GNUC_MINOR__ >= 3
+/* Mark functions as cold. gcc will assume any path leading to a call
+   to them will be unlikely.  This means a lot of manual unlikely()s
+   are unnecessary now for any paths leading to the usual suspects
+   like BUG(), printk(), panic() etc. [but let's keep them for now for
+   older compilers]
+
+   Early snapshots of gcc 4.3 don't support this and we can't detect this
+   in the preprocessor, but we can live with this because they're unreleased.
+   Maketime probing would be overkill here.
+
+   gcc also has a __attribute__((__hot__)) to move hot functions into
+   a special section, but I don't see any sense in this right now in
+   the kernel context */
+#define __cold			__attribute__((__cold__))
+
+
+#if __GNUC_MINOR__ >= 5
+/*
+ * Mark a position in code as unreachable.  This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased.  Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+#endif
+
+#endif
+
+#if __GNUC_MINOR__ > 0
+#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+#endif
+#if __GNUC_MINOR__ >= 4
+#define __compiletime_warning(message) __attribute__((warning(message)))
+#define __compiletime_error(message) __attribute__((error(message)))
+#endif
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
new file mode 100644
index 0000000..5be3dab
--- /dev/null
+++ b/include/linux/compiler.h
@@ -0,0 +1,303 @@
+#ifndef __LINUX_COMPILER_H
+#define __LINUX_COMPILER_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef __CHECKER__
+# define __user		__attribute__((noderef, address_space(1)))
+# define __kernel	/* default address space */
+# define __safe		__attribute__((safe))
+# define __force	__attribute__((force))
+# define __nocast	__attribute__((nocast))
+# define __iomem	__attribute__((noderef, address_space(2)))
+# define __acquires(x)	__attribute__((context(x,0,1)))
+# define __releases(x)	__attribute__((context(x,1,0)))
+# define __acquire(x)	__context__(x,1)
+# define __release(x)	__context__(x,-1)
+# define __cond_lock(x,c)	((c) ? ({ __acquire(x); 1; }) : 0)
+extern void __chk_user_ptr(const volatile void __user *);
+extern void __chk_io_ptr(const volatile void __iomem *);
+#else
+# define __user
+# define __kernel
+# define __safe
+# define __force
+# define __nocast
+# define __iomem
+# define __chk_user_ptr(x) (void)0
+# define __chk_io_ptr(x) (void)0
+# define __builtin_warning(x, y...) (1)
+# define __acquires(x)
+# define __releases(x)
+# define __acquire(x) (void)0
+# define __release(x) (void)0
+# define __cond_lock(x,c) (c)
+#endif
+
+#ifdef __KERNEL__
+
+#ifdef __GNUC__
+#include <linux/compiler-gcc.h>
+#endif
+
+#define notrace __attribute__((no_instrument_function))
+
+/* Intel compiler defines __GNUC__. So we will overwrite implementations
+ * coming from above header files here
+ */
+#ifdef __INTEL_COMPILER
+# include <linux/compiler-intel.h>
+#endif
+
+/*
+ * Generic compiler-dependent macros required for kernel
+ * build go below this comment. Actual compiler/compiler version
+ * specific implementations come from the above header files
+ */
+
+struct ftrace_branch_data {
+	const char *func;
+	const char *file;
+	unsigned line;
+	union {
+		struct {
+			unsigned long correct;
+			unsigned long incorrect;
+		};
+		struct {
+			unsigned long miss;
+			unsigned long hit;
+		};
+		unsigned long miss_hit[2];
+	};
+};
+
+/*
+ * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
+ * to disable branch tracing on a per file basis.
+ */
+#if defined(CONFIG_TRACE_BRANCH_PROFILING) \
+    && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__)
+void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+
+#define likely_notrace(x)	__builtin_expect(!!(x), 1)
+#define unlikely_notrace(x)	__builtin_expect(!!(x), 0)
+
+#define __branch_check__(x, expect) ({					\
+			int ______r;					\
+			static struct ftrace_branch_data		\
+				__attribute__((__aligned__(4)))		\
+				__attribute__((section("_ftrace_annotated_branch"))) \
+				______f = {				\
+				.func = __func__,			\
+				.file = __FILE__,			\
+				.line = __LINE__,			\
+			};						\
+			______r = likely_notrace(x);			\
+			ftrace_likely_update(&______f, ______r, expect); \
+			______r;					\
+		})
+
+/*
+ * Using __builtin_constant_p(x) to ignore cases where the return
+ * value is always the same.  This idea is taken from a similar patch
+ * written by Daniel Walker.
+ */
+# ifndef likely
+#  define likely(x)	(__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
+# endif
+# ifndef unlikely
+#  define unlikely(x)	(__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
+# endif
+
+#ifdef CONFIG_PROFILE_ALL_BRANCHES
+/*
+ * "Define 'is'", Bill Clinton
+ * "Define 'if'", Steven Rostedt
+ */
+#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
+#define __trace_if(cond) \
+	if (__builtin_constant_p((cond)) ? !!(cond) :			\
+	({								\
+		int ______r;						\
+		static struct ftrace_branch_data			\
+			__attribute__((__aligned__(4)))			\
+			__attribute__((section("_ftrace_branch")))	\
+			______f = {					\
+				.func = __func__,			\
+				.file = __FILE__,			\
+				.line = __LINE__,			\
+			};						\
+		______r = !!(cond);					\
+		______f.miss_hit[______r]++;					\
+		______r;						\
+	}))
+#endif /* CONFIG_PROFILE_ALL_BRANCHES */
+
+#else
+# define likely(x)	__builtin_expect(!!(x), 1)
+# define unlikely(x)	__builtin_expect(!!(x), 0)
+#endif
+
+/* Optimization barrier */
+#ifndef barrier
+# define barrier() __memory_barrier()
+#endif
+
+/* Unreachable code */
+#ifndef unreachable
+# define unreachable() do { } while (1)
+#endif
+
+#ifndef RELOC_HIDE
+# define RELOC_HIDE(ptr, off)					\
+  ({ unsigned long __ptr;					\
+     __ptr = (unsigned long) (ptr);				\
+    (typeof(ptr)) (__ptr + (off)); })
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
+/*
+ * Allow us to mark functions as 'deprecated' and have gcc emit a nice
+ * warning for each use, in hopes of speeding the functions removal.
+ * Usage is:
+ * 		int __deprecated foo(void)
+ */
+#ifndef __deprecated
+# define __deprecated		/* unimplemented */
+#endif
+
+#ifdef MODULE
+#define __deprecated_for_modules __deprecated
+#else
+#define __deprecated_for_modules
+#endif
+
+#ifndef __must_check
+#define __must_check
+#endif
+
+#ifndef CONFIG_ENABLE_MUST_CHECK
+#undef __must_check
+#define __must_check
+#endif
+#ifndef CONFIG_ENABLE_WARN_DEPRECATED
+#undef __deprecated
+#undef __deprecated_for_modules
+#define __deprecated
+#define __deprecated_for_modules
+#endif
+
+/*
+ * Allow us to avoid 'defined but not used' warnings on functions and data,
+ * as well as force them to be emitted to the assembly file.
+ *
+ * As of gcc 3.4, static functions that are not marked with attribute((used))
+ * may be elided from the assembly file.  As of gcc 3.4, static data not so
+ * marked will not be elided, but this may change in a future gcc version.
+ *
+ * NOTE: Because distributions shipped with a backported unit-at-a-time
+ * compiler in gcc 3.3, we must define __used to be __attribute__((used))
+ * for gcc >=3.3 instead of 3.4.
+ *
+ * In prior versions of gcc, such functions and data would be emitted, but
+ * would be warned about except with attribute((unused)).
+ *
+ * Mark functions that are referenced only in inline assembly as __used so
+ * the code is emitted even though it appears to be unreferenced.
+ */
+#ifndef __used
+# define __used			/* unimplemented */
+#endif
+
+#ifndef __maybe_unused
+# define __maybe_unused		/* unimplemented */
+#endif
+
+#ifndef __always_unused
+# define __always_unused	/* unimplemented */
+#endif
+
+#ifndef noinline
+#define noinline
+#endif
+
+/*
+ * Rather then using noinline to prevent stack consumption, use
+ * noinline_for_stack instead.  For documentaiton reasons.
+ */
+#define noinline_for_stack noinline
+
+#ifndef __always_inline
+#define __always_inline inline
+#endif
+
+#endif /* __KERNEL__ */
+
+/*
+ * From the GCC manual:
+ *
+ * Many functions do not examine any values except their arguments,
+ * and have no effects except the return value.  Basically this is
+ * just slightly more strict class than the `pure' attribute above,
+ * since function is not allowed to read global memory.
+ *
+ * Note that a function that has pointer arguments and examines the
+ * data pointed to must _not_ be declared `const'.  Likewise, a
+ * function that calls a non-`const' function usually must not be
+ * `const'.  It does not make sense for a `const' function to return
+ * `void'.
+ */
+#ifndef __attribute_const__
+# define __attribute_const__	/* unimplemented */
+#endif
+
+/*
+ * Tell gcc if a function is cold. The compiler will assume any path
+ * directly leading to the call is unlikely.
+ */
+
+#ifndef __cold
+#define __cold
+#endif
+
+/* Simple shorthand for a section definition */
+#ifndef __section
+# define __section(S) __attribute__ ((__section__(#S)))
+#endif
+
+/* Are two types/vars the same type (ignoring qualifiers)? */
+#ifndef __same_type
+# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+#endif
+
+/* Compile time object size, -1 for unknown */
+#ifndef __compiletime_object_size
+# define __compiletime_object_size(obj) -1
+#endif
+#ifndef __compiletime_warning
+# define __compiletime_warning(message)
+#endif
+#ifndef __compiletime_error
+# define __compiletime_error(message)
+#endif
+
+/*
+ * Prevent the compiler from merging or refetching accesses.  The compiler
+ * is also forbidden from reordering successive instances of ACCESS_ONCE(),
+ * but only when the compiler is aware of some particular ordering.  One way
+ * to make the compiler aware of ordering is to put the two invocations of
+ * ACCESS_ONCE() in different C statements.
+ *
+ * This macro does absolutely -nothing- to prevent the CPU from reordering,
+ * merging, or refetching absolutely anything at any time.  Its main intended
+ * use is to mediate communication between process-level code and irq/NMI
+ * handlers, all running on the same CPU.
+ */
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
+#endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/edd.h b/include/linux/edd.h
new file mode 100644
index 0000000..4cbd0fe
--- /dev/null
+++ b/include/linux/edd.h
@@ -0,0 +1,194 @@
+/*
+ * linux/include/linux/edd.h
+ *  Copyright (C) 2002, 2003, 2004 Dell Inc.
+ *  by Matt Domsch <Matt_Domsch@dell.com>
+ *
+ * structures and definitions for the int 13h, ax={41,48}h
+ * BIOS Enhanced Disk Drive Services
+ * This is based on the T13 group document D1572 Revision 0 (August 14 2002)
+ * available at http://www.t13.org/docs2002/d1572r0.pdf.  It is
+ * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf
+ *
+ * In a nutshell, arch/{i386,x86_64}/boot/setup.S populates a scratch
+ * table in the boot_params that contains a list of BIOS-enumerated
+ * boot devices.
+ * In arch/{i386,x86_64}/kernel/setup.c, this information is
+ * transferred into the edd structure, and in drivers/firmware/edd.c, that
+ * information is used to identify BIOS boot disk.  The code in setup.S
+ * is very sensitive to the size of these structures.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * 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.
+ *
+ */
+#ifndef _LINUX_EDD_H
+#define _LINUX_EDD_H
+
+#include <linux/types.h>
+
+#define EDDNR 0x1e9		/* addr of number of edd_info structs at EDDBUF
+				   in boot_params - treat this as 1 byte  */
+#define EDDBUF	0xd00		/* addr of edd_info structs in boot_params */
+#define EDDMAXNR 6		/* number of edd_info structs starting at EDDBUF  */
+#define EDDEXTSIZE 8		/* change these if you muck with the structures */
+#define EDDPARMSIZE 74
+#define CHECKEXTENSIONSPRESENT 0x41
+#define GETDEVICEPARAMETERS 0x48
+#define LEGACYGETDEVICEPARAMETERS 0x08
+#define EDDMAGIC1 0x55AA
+#define EDDMAGIC2 0xAA55
+
+
+#define READ_SECTORS 0x02         /* int13 AH=0x02 is READ_SECTORS command */
+#define EDD_MBR_SIG_OFFSET 0x1B8  /* offset of signature in the MBR */
+#define EDD_MBR_SIG_BUF    0x290  /* addr in boot params */
+#define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
+#define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
+				     in boot_params - treat this as 1 byte  */
+
+#ifndef __ASSEMBLY__
+
+#define EDD_EXT_FIXED_DISK_ACCESS           (1 << 0)
+#define EDD_EXT_DEVICE_LOCKING_AND_EJECTING (1 << 1)
+#define EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT (1 << 2)
+#define EDD_EXT_64BIT_EXTENSIONS            (1 << 3)
+
+#define EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT (1 << 0)
+#define EDD_INFO_GEOMETRY_VALID                (1 << 1)
+#define EDD_INFO_REMOVABLE                     (1 << 2)
+#define EDD_INFO_WRITE_VERIFY                  (1 << 3)
+#define EDD_INFO_MEDIA_CHANGE_NOTIFICATION     (1 << 4)
+#define EDD_INFO_LOCKABLE                      (1 << 5)
+#define EDD_INFO_NO_MEDIA_PRESENT              (1 << 6)
+#define EDD_INFO_USE_INT13_FN50                (1 << 7)
+
+struct edd_device_params {
+	__u16 length;
+	__u16 info_flags;
+	__u32 num_default_cylinders;
+	__u32 num_default_heads;
+	__u32 sectors_per_track;
+	__u64 number_of_sectors;
+	__u16 bytes_per_sector;
+	__u32 dpte_ptr;		/* 0xFFFFFFFF for our purposes */
+	__u16 key;		/* = 0xBEDD */
+	__u8 device_path_info_length;	/* = 44 */
+	__u8 reserved2;
+	__u16 reserved3;
+	__u8 host_bus_type[4];
+	__u8 interface_type[8];
+	union {
+		struct {
+			__u16 base_address;
+			__u16 reserved1;
+			__u32 reserved2;
+		} __attribute__ ((packed)) isa;
+		struct {
+			__u8 bus;
+			__u8 slot;
+			__u8 function;
+			__u8 channel;
+			__u32 reserved;
+		} __attribute__ ((packed)) pci;
+		/* pcix is same as pci */
+		struct {
+			__u64 reserved;
+		} __attribute__ ((packed)) ibnd;
+		struct {
+			__u64 reserved;
+		} __attribute__ ((packed)) xprs;
+		struct {
+			__u64 reserved;
+		} __attribute__ ((packed)) htpt;
+		struct {
+			__u64 reserved;
+		} __attribute__ ((packed)) unknown;
+	} interface_path;
+	union {
+		struct {
+			__u8 device;
+			__u8 reserved1;
+			__u16 reserved2;
+			__u32 reserved3;
+			__u64 reserved4;
+		} __attribute__ ((packed)) ata;
+		struct {
+			__u8 device;
+			__u8 lun;
+			__u8 reserved1;
+			__u8 reserved2;
+			__u32 reserved3;
+			__u64 reserved4;
+		} __attribute__ ((packed)) atapi;
+		struct {
+			__u16 id;
+			__u64 lun;
+			__u16 reserved1;
+			__u32 reserved2;
+		} __attribute__ ((packed)) scsi;
+		struct {
+			__u64 serial_number;
+			__u64 reserved;
+		} __attribute__ ((packed)) usb;
+		struct {
+			__u64 eui;
+			__u64 reserved;
+		} __attribute__ ((packed)) i1394;
+		struct {
+			__u64 wwid;
+			__u64 lun;
+		} __attribute__ ((packed)) fibre;
+		struct {
+			__u64 identity_tag;
+			__u64 reserved;
+		} __attribute__ ((packed)) i2o;
+		struct {
+			__u32 array_number;
+			__u32 reserved1;
+			__u64 reserved2;
+		} __attribute__ ((packed)) raid;
+		struct {
+			__u8 device;
+			__u8 reserved1;
+			__u16 reserved2;
+			__u32 reserved3;
+			__u64 reserved4;
+		} __attribute__ ((packed)) sata;
+		struct {
+			__u64 reserved1;
+			__u64 reserved2;
+		} __attribute__ ((packed)) unknown;
+	} device_path;
+	__u8 reserved4;
+	__u8 checksum;
+} __attribute__ ((packed));
+
+struct edd_info {
+	__u8 device;
+	__u8 version;
+	__u16 interface_support;
+	__u16 legacy_max_cylinder;
+	__u8 legacy_max_head;
+	__u8 legacy_sectors_per_track;
+	struct edd_device_params params;
+} __attribute__ ((packed));
+
+struct edd {
+	unsigned int mbr_signature[EDD_MBR_SIG_MAX];
+	struct edd_info edd_info[EDDMAXNR];
+	unsigned char mbr_signature_nr;
+	unsigned char edd_info_nr;
+};
+
+#ifdef __KERNEL__
+extern struct edd edd;
+#endif /* __KERNEL__ */
+#endif				/*!__ASSEMBLY__ */
+
+#endif				/* _LINUX_EDD_H */
diff --git a/include/linux/ioctl.h b/include/linux/ioctl.h
new file mode 100644
index 0000000..7e55c36
--- /dev/null
+++ b/include/linux/ioctl.h
@@ -0,0 +1,6 @@
+#ifndef _LINUX_IOCTL_H
+#define _LINUX_IOCTL_H
+
+#include <asm/ioctl.h>
+
+#endif /* _LINUX_IOCTL_H */
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
new file mode 100644
index 0000000..7129504
--- /dev/null
+++ b/include/linux/ioport.h
@@ -0,0 +1,192 @@
+/*
+ * ioport.h	Definitions of routines for detecting, reserving and
+ *		allocating system resources.
+ *
+ * Authors:	Linus Torvalds
+ */
+
+#ifndef _LINUX_IOPORT_H
+#define _LINUX_IOPORT_H
+
+#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+#include <linux/types.h>
+/*
+ * Resources are tree-like, allowing
+ * nesting etc..
+ */
+struct resource {
+	resource_size_t start;
+	resource_size_t end;
+	const char *name;
+	unsigned long flags;
+	struct resource *parent, *sibling, *child;
+};
+
+struct resource_list {
+	struct resource_list *next;
+	struct resource *res;
+	struct pci_dev *dev;
+};
+
+/*
+ * IO resources have these defined flags.
+ */
+#define IORESOURCE_BITS		0x000000ff	/* Bus-specific bits */
+
+#define IORESOURCE_TYPE_BITS	0x00000f00	/* Resource type */
+#define IORESOURCE_IO		0x00000100
+#define IORESOURCE_MEM		0x00000200
+#define IORESOURCE_IRQ		0x00000400
+#define IORESOURCE_DMA		0x00000800
+
+#define IORESOURCE_PREFETCH	0x00001000	/* No side effects */
+#define IORESOURCE_READONLY	0x00002000
+#define IORESOURCE_CACHEABLE	0x00004000
+#define IORESOURCE_RANGELENGTH	0x00008000
+#define IORESOURCE_SHADOWABLE	0x00010000
+
+#define IORESOURCE_SIZEALIGN	0x00020000	/* size indicates alignment */
+#define IORESOURCE_STARTALIGN	0x00040000	/* start field is alignment */
+
+#define IORESOURCE_MEM_64	0x00100000
+
+#define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
+#define IORESOURCE_DISABLED	0x10000000
+#define IORESOURCE_UNSET	0x20000000
+#define IORESOURCE_AUTO		0x40000000
+#define IORESOURCE_BUSY		0x80000000	/* Driver has marked this resource busy */
+
+/* PnP IRQ specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_IRQ_HIGHEDGE		(1<<0)
+#define IORESOURCE_IRQ_LOWEDGE		(1<<1)
+#define IORESOURCE_IRQ_HIGHLEVEL	(1<<2)
+#define IORESOURCE_IRQ_LOWLEVEL		(1<<3)
+#define IORESOURCE_IRQ_SHAREABLE	(1<<4)
+#define IORESOURCE_IRQ_OPTIONAL 	(1<<5)
+
+/* PnP DMA specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_DMA_TYPE_MASK	(3<<0)
+#define IORESOURCE_DMA_8BIT		(0<<0)
+#define IORESOURCE_DMA_8AND16BIT	(1<<0)
+#define IORESOURCE_DMA_16BIT		(2<<0)
+
+#define IORESOURCE_DMA_MASTER		(1<<2)
+#define IORESOURCE_DMA_BYTE		(1<<3)
+#define IORESOURCE_DMA_WORD		(1<<4)
+
+#define IORESOURCE_DMA_SPEED_MASK	(3<<6)
+#define IORESOURCE_DMA_COMPATIBLE	(0<<6)
+#define IORESOURCE_DMA_TYPEA		(1<<6)
+#define IORESOURCE_DMA_TYPEB		(2<<6)
+#define IORESOURCE_DMA_TYPEF		(3<<6)
+
+/* PnP memory I/O specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_MEM_WRITEABLE	(1<<0)	/* dup: IORESOURCE_READONLY */
+#define IORESOURCE_MEM_CACHEABLE	(1<<1)	/* dup: IORESOURCE_CACHEABLE */
+#define IORESOURCE_MEM_RANGELENGTH	(1<<2)	/* dup: IORESOURCE_RANGELENGTH */
+#define IORESOURCE_MEM_TYPE_MASK	(3<<3)
+#define IORESOURCE_MEM_8BIT		(0<<3)
+#define IORESOURCE_MEM_16BIT		(1<<3)
+#define IORESOURCE_MEM_8AND16BIT	(2<<3)
+#define IORESOURCE_MEM_32BIT		(3<<3)
+#define IORESOURCE_MEM_SHADOWABLE	(1<<5)	/* dup: IORESOURCE_SHADOWABLE */
+#define IORESOURCE_MEM_EXPANSIONROM	(1<<6)
+
+/* PnP I/O specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_IO_16BIT_ADDR	(1<<0)
+#define IORESOURCE_IO_FIXED		(1<<1)
+
+/* PCI ROM control bits (IORESOURCE_BITS) */
+#define IORESOURCE_ROM_ENABLE		(1<<0)	/* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
+#define IORESOURCE_ROM_SHADOW		(1<<1)	/* ROM is copy at C000:0 */
+#define IORESOURCE_ROM_COPY		(1<<2)	/* ROM is alloc'd copy, resource field overlaid */
+#define IORESOURCE_ROM_BIOS_COPY	(1<<3)	/* ROM is BIOS copy, resource field overlaid */
+
+/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
+#define IORESOURCE_PCI_FIXED		(1<<4)	/* Do not move resource */
+
+/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+
+extern int request_resource(struct resource *root, struct resource *new);
+extern int release_resource(struct resource *new);
+extern void reserve_region_with_split(struct resource *root,
+			     resource_size_t start, resource_size_t end,
+			     const char *name);
+extern int insert_resource(struct resource *parent, struct resource *new);
+extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
+extern int allocate_resource(struct resource *root, struct resource *new,
+			     resource_size_t size, resource_size_t min,
+			     resource_size_t max, resource_size_t align,
+			     void (*alignf)(void *, struct resource *,
+					    resource_size_t, resource_size_t),
+			     void *alignf_data);
+int adjust_resource(struct resource *res, resource_size_t start,
+		    resource_size_t size);
+resource_size_t resource_alignment(struct resource *res);
+static inline resource_size_t resource_size(const struct resource *res)
+{
+	return res->end - res->start + 1;
+}
+static inline unsigned long resource_type(const struct resource *res)
+{
+	return res->flags & IORESOURCE_TYPE_BITS;
+}
+
+/* Convenience shorthand with allocation */
+#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
+#define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
+#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
+#define request_mem_region_exclusive(start,n,name) \
+	__request_region(&iomem_resource, (start), (n), (name), IORESOURCE_EXCLUSIVE)
+#define rename_region(region, newname) do { (region)->name = (newname); } while (0)
+
+extern struct resource * __request_region(struct resource *,
+					resource_size_t start,
+					resource_size_t n,
+					const char *name, int flags);
+
+/* Compatibility cruft */
+#define release_region(start,n)	__release_region(&ioport_resource, (start), (n))
+#define check_mem_region(start,n)	__check_region(&iomem_resource, (start), (n))
+#define release_mem_region(start,n)	__release_region(&iomem_resource, (start), (n))
+
+extern int __check_region(struct resource *, resource_size_t, resource_size_t);
+extern void __release_region(struct resource *, resource_size_t,
+				resource_size_t);
+
+static inline int __deprecated check_region(resource_size_t s,
+						resource_size_t n)
+{
+	return __check_region(&ioport_resource, s, n);
+}
+
+/* Wrappers for managed devices */
+struct device;
+#define devm_request_region(dev,start,n,name) \
+	__devm_request_region(dev, &ioport_resource, (start), (n), (name))
+#define devm_request_mem_region(dev,start,n,name) \
+	__devm_request_region(dev, &iomem_resource, (start), (n), (name))
+
+extern struct resource * __devm_request_region(struct device *dev,
+				struct resource *parent, resource_size_t start,
+				resource_size_t n, const char *name);
+
+#define devm_release_region(dev, start, n) \
+	__devm_release_region(dev, &ioport_resource, (start), (n))
+#define devm_release_mem_region(dev, start, n) \
+	__devm_release_region(dev, &iomem_resource, (start), (n))
+
+extern void __devm_release_region(struct device *dev, struct resource *parent,
+				  resource_size_t start, resource_size_t n);
+extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);
+extern int iomem_is_exclusive(u64 addr);
+
+extern int
+walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
+		void *arg, int (*func)(unsigned long, unsigned long, void *));
+
+#endif /* __ASSEMBLY__ */
+#endif	/* _LINUX_IOPORT_H */
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
new file mode 100644
index 0000000..899fbb4
--- /dev/null
+++ b/include/linux/screen_info.h
@@ -0,0 +1,84 @@
+#ifndef _SCREEN_INFO_H
+#define _SCREEN_INFO_H
+
+#include <linux/types.h>
+
+/*
+ * These are set up by the setup-routine at boot-time:
+ */
+
+struct screen_info {
+	__u8  orig_x;		/* 0x00 */
+	__u8  orig_y;		/* 0x01 */
+	__u16 ext_mem_k;	/* 0x02 */
+	__u16 orig_video_page;	/* 0x04 */
+	__u8  orig_video_mode;	/* 0x06 */
+	__u8  orig_video_cols;	/* 0x07 */
+	__u8  flags;		/* 0x08 */
+	__u8  unused2;		/* 0x09 */
+	__u16 orig_video_ega_bx;/* 0x0a */
+	__u16 unused3;		/* 0x0c */
+	__u8  orig_video_lines;	/* 0x0e */
+	__u8  orig_video_isVGA;	/* 0x0f */
+	__u16 orig_video_points;/* 0x10 */
+
+	/* VESA graphic mode -- linear frame buffer */
+	__u16 lfb_width;	/* 0x12 */
+	__u16 lfb_height;	/* 0x14 */
+	__u16 lfb_depth;	/* 0x16 */
+	__u32 lfb_base;		/* 0x18 */
+	__u32 lfb_size;		/* 0x1c */
+	__u16 cl_magic, cl_offset; /* 0x20 */
+	__u16 lfb_linelength;	/* 0x24 */
+	__u8  red_size;		/* 0x26 */
+	__u8  red_pos;		/* 0x27 */
+	__u8  green_size;	/* 0x28 */
+	__u8  green_pos;	/* 0x29 */
+	__u8  blue_size;	/* 0x2a */
+	__u8  blue_pos;		/* 0x2b */
+	__u8  rsvd_size;	/* 0x2c */
+	__u8  rsvd_pos;		/* 0x2d */
+	__u16 vesapm_seg;	/* 0x2e */
+	__u16 vesapm_off;	/* 0x30 */
+	__u16 pages;		/* 0x32 */
+	__u16 vesa_attributes;	/* 0x34 */
+	__u32 capabilities;     /* 0x36 */
+	__u8  _reserved[6];	/* 0x3a */
+} __attribute__((packed));
+
+#define VIDEO_TYPE_MDA		0x10	/* Monochrome Text Display	*/
+#define VIDEO_TYPE_CGA		0x11	/* CGA Display 			*/
+#define VIDEO_TYPE_EGAM		0x20	/* EGA/VGA in Monochrome Mode	*/
+#define VIDEO_TYPE_EGAC		0x21	/* EGA in Color Mode		*/
+#define VIDEO_TYPE_VGAC		0x22	/* VGA+ in Color Mode		*/
+#define VIDEO_TYPE_VLFB		0x23	/* VESA VGA in graphic mode	*/
+
+#define VIDEO_TYPE_PICA_S3	0x30	/* ACER PICA-61 local S3 video	*/
+#define VIDEO_TYPE_MIPS_G364	0x31    /* MIPS Magnum 4000 G364 video  */
+#define VIDEO_TYPE_SGI          0x33    /* Various SGI graphics hardware */
+
+#define VIDEO_TYPE_TGAC		0x40	/* DEC TGA */
+
+#define VIDEO_TYPE_SUN          0x50    /* Sun frame buffer. */
+#define VIDEO_TYPE_SUNPCI       0x51    /* Sun PCI based frame buffer. */
+
+#define VIDEO_TYPE_PMAC		0x60	/* PowerMacintosh frame buffer. */
+
+#define VIDEO_TYPE_EFI		0x70	/* EFI graphic mode		*/
+
+#define VIDEO_FLAGS_NOCURSOR	(1 << 0) /* The video mode has no cursor set */
+
+#ifdef __KERNEL__
+extern struct screen_info screen_info;
+
+#define ORIG_X			(screen_info.orig_x)
+#define ORIG_Y			(screen_info.orig_y)
+#define ORIG_VIDEO_MODE		(screen_info.orig_video_mode)
+#define ORIG_VIDEO_COLS 	(screen_info.orig_video_cols)
+#define ORIG_VIDEO_EGA_BX	(screen_info.orig_video_ega_bx)
+#define ORIG_VIDEO_LINES	(screen_info.orig_video_lines)
+#define ORIG_VIDEO_ISVGA	(screen_info.orig_video_isVGA)
+#define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
+#endif /* __KERNEL__ */
+
+#endif /* _SCREEN_INFO_H */
diff --git a/include/serial.h b/include/serial.h
index 111edbe..6513d8e 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -26,7 +26,8 @@
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || \
     defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) || \
     defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC83xx) || \
-    defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+    defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) || \
+    defined(CONFIG_SYS_SC520)
 extern struct serial_device serial0_device;
 extern struct serial_device serial1_device;
 #if defined(CONFIG_SYS_NS16550_SERIAL)
diff --git a/lib/display_options.c b/lib/display_options.c
index 2dc2567..86df05d 100644
--- a/lib/display_options.c
+++ b/lib/display_options.c
@@ -39,25 +39,30 @@
 }
 
 /*
- * print sizes as "xxx kB", "xxx.y kB", "xxx MB", "xxx.y MB",
- * xxx GB, or xxx.y GB as needed; allow for optional trailing string
+ * print sizes as "xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB",
+ * xxx GiB, xxx.y GiB, etc as needed; allow for optional trailing string
  * (like "\n")
  */
-void print_size (phys_size_t size, const char *s)
+void print_size(unsigned long long size, const char *s)
 {
-	ulong m = 0, n;
-	phys_size_t d = 1 << 30;		/* 1 GB */
-	char  c = 'G';
+	unsigned long m = 0, n;
+	static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'};
+	unsigned long long d = 1ULL << (10 * ARRAY_SIZE(names));
+	char c = 0;
+	unsigned int i;
 
-	if (size < d) {			/* try MB */
-		c = 'M';
-		d = 1 << 20;
-		if (size < d) {		/* print in kB */
-			c = 'k';
-			d = 1 << 10;
+	for (i = 0; i < ARRAY_SIZE(names); i++, d >>= 10) {
+		if (size >= d) {
+			c = names[i];
+			break;
 		}
 	}
 
+	if (!c) {
+		printf("%llu Bytes%s", size, s);
+		return;
+	}
+
 	n = size / d;
 
 	/* If there's a remainder, deal with it */
@@ -70,11 +75,11 @@
 		}
 	}
 
-	printf ("%2ld", n);
+	printf ("%lu", n);
 	if (m) {
 		printf (".%ld", m);
 	}
-	printf (" %cB%s", c, s);
+	printf (" %ciB%s", c, s);
 }
 
 /*
diff --git a/post/cpu/mpc83xx/Makefile b/post/cpu/mpc83xx/Makefile
new file mode 100644
index 0000000..86d8784
--- /dev/null
+++ b/post/cpu/mpc83xx/Makefile
@@ -0,0 +1,30 @@
+#
+# (C) Copyright 2002-2007
+# 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 $(OBJTREE)/include/autoconf.mk
+
+LIB	= libpostmpc83xx.a
+
+AOBJS-$(CONFIG_HAS_POST)	+=
+COBJS-$(CONFIG_HAS_POST)	+= ecc.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/post/cpu/mpc83xx/ecc.c b/post/cpu/mpc83xx/ecc.c
new file mode 100644
index 0000000..de87339
--- /dev/null
+++ b/post/cpu/mpc83xx/ecc.c
@@ -0,0 +1,166 @@
+/*
+ * (C) Copyright 2010
+ * Eastman Kodak Company, <www.kodak.com>
+ * Michael Zaidman, <michael.zaidman@kodak.com>
+ *
+ * The code is based on the cpu/mpc83xx/ecc.c written by
+ * Dave Liu <daveliu@freescale.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 <mpc83xx.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <post.h>
+
+#if CONFIG_POST & CONFIG_SYS_POST_ECC
+/*
+ * We use the RAW I/O accessors where possible in order to
+ * achieve performance goal, since the test's execution time
+ * affects the board start up time.
+ */
+static inline void ecc_clear(ddr83xx_t *ddr)
+{
+	/* Clear capture registers */
+	__raw_writel(0, &ddr->capture_address);
+	__raw_writel(0, &ddr->capture_data_hi);
+	__raw_writel(0, &ddr->capture_data_lo);
+	__raw_writel(0, &ddr->capture_ecc);
+	__raw_writel(0, &ddr->capture_attributes);
+
+	/* Clear SBEC and set SBET to 1 */
+	out_be32(&ddr->err_sbe, 1 << ECC_ERROR_MAN_SBET_SHIFT);
+
+	/* Clear Error Detect register */
+	out_be32(&ddr->err_detect, ECC_ERROR_DETECT_MME |\
+			ECC_ERROR_DETECT_MBE |\
+			ECC_ERROR_DETECT_SBE |\
+			ECC_ERROR_DETECT_MSE);
+
+	isync();
+}
+
+int ecc_post_test(int flags)
+{
+	int ret = 0;
+	int int_state;
+	int errbit;
+	u32 pattern[2], writeback[2], retval[2];
+	ddr83xx_t *ddr = &((immap_t *)CONFIG_SYS_IMMR)->ddr;
+	volatile u64 *addr = (u64 *)CONFIG_SYS_POST_ECC_START_ADDR;
+
+	/* The pattern is written into memory to generate error */
+	pattern[0] = 0xfedcba98UL;
+	pattern[1] = 0x76543210UL;
+
+	/* After injecting error, re-initialize the memory with the value */
+	writeback[0] = ~pattern[0];
+	writeback[1] = ~pattern[1];
+
+	/* Check if ECC is enabled */
+	if (__raw_readl(&ddr->err_disable) & ECC_ERROR_ENABLE) {
+		debug("DDR's ECC is not enabled, skipping the ECC POST.\n");
+		return 0;
+	}
+
+	int_state = disable_interrupts();
+	icache_enable();
+
+#ifdef CONFIG_DDR_32BIT
+	/* It seems like no one really uses the CONFIG_DDR_32BIT mode */
+#error "Add ECC POST support for CONFIG_DDR_32BIT here!"
+#else
+	for (addr = (u64*)CONFIG_SYS_POST_ECC_START_ADDR, errbit=0;
+	     addr < (u64*)CONFIG_SYS_POST_ECC_STOP_ADDR; addr++, errbit++ ) {
+
+		WATCHDOG_RESET();
+
+		ecc_clear(ddr);
+
+		/* Enable error injection */
+		setbits_be32(&ddr->ecc_err_inject, ECC_ERR_INJECT_EIEN);
+		sync();
+		isync();
+
+		/* Set bit to be injected */
+		if (errbit < 32) {
+			__raw_writel(1 << errbit, &ddr->data_err_inject_lo);
+			__raw_writel(0, &ddr->data_err_inject_hi);
+		} else {
+			__raw_writel(0, &ddr->data_err_inject_lo);
+			__raw_writel(1<<(errbit-32), &ddr->data_err_inject_hi);
+		}
+		sync();
+		isync();
+
+		/* Write memory location injecting SBE */
+		ppcDWstore((u32*)addr, pattern);
+		sync();
+
+		/* Disable error injection */
+		clrbits_be32(&ddr->ecc_err_inject, ECC_ERR_INJECT_EIEN);
+		sync();
+		isync();
+
+		/* Data read should generate SBE */
+		ppcDWload((u32*)addr, retval);
+		sync();
+
+		if (!(__raw_readl(&ddr->err_detect) & ECC_ERROR_DETECT_SBE) ||
+			(__raw_readl(&ddr->data_err_inject_hi) !=
+			(__raw_readl(&ddr->capture_data_hi) ^ pattern[0])) ||
+			(__raw_readl(&ddr->data_err_inject_lo) !=
+			(__raw_readl(&ddr->capture_data_lo) ^ pattern[1]))) {
+
+			post_log("ECC failed to detect SBE error at %08x, "
+				"SBE injection mask %08x-%08x, wrote "
+				"%08x-%08x, read %08x-%08x\n", addr,
+				ddr->data_err_inject_hi,
+				ddr->data_err_inject_lo,
+				pattern[0], pattern[1],
+				retval[0], retval[1]);
+
+			printf("ERR_DETECT Reg: %08x\n", ddr->err_detect);
+			printf("ECC CAPTURE_DATA Reg: %08x-%08x\n",
+				ddr->capture_data_hi, ddr->capture_data_lo);
+			ret = 1;
+			break;
+		}
+
+		/* Re-initialize the ECC memory */
+		ppcDWstore((u32*)addr, writeback);
+		sync();
+		isync();
+
+		errbit %= 63;
+	}
+#endif /* !CONFIG_DDR_32BIT */
+
+	ecc_clear(ddr);
+
+	icache_disable();
+
+	if (int_state)
+		enable_interrupts();
+
+	return ret;
+}
+#endif