Index: coreboot-v2/src/arch/i386/lib/copy_and_run.c
===================================================================
--- /dev/null
+++ coreboot-v2/src/arch/i386/lib/copy_and_run.c
@@ -0,0 +1,54 @@
+/* by yhlu 6.2005
+	moved from nrv2v.c and some lines from crt0.S
+   2006/05/02 - stepan: move nrv2b to an extra file.
+*/
+
+#include <console/console.h>
+#include <stdint.h>
+#include <string.h>
+
+#if CONFIG_COMPRESS
+#define ENDIAN   0
+#define BITSIZE 32
+#include "../lib/nrv2b.c"
+#endif
+
+void copy_and_run_core(u8 *src, u8 *dst, unsigned long ilen, unsigned ebp)
+{
+        unsigned long olen;
+
+#if CONFIG_USE_INIT
+	printk_spew("src=%08x\r\n",src);
+	printk_spew("dst=%08x\r\n",dst);
+#else
+        print_spew("src="); print_spew_hex32((uint32_t)src); print_spew("\r\n");
+        print_spew("dst="); print_spew_hex32((uint32_t)dst); print_spew("\r\n");
+#endif
+
+#if !CONFIG_COMPRESS
+	print_debug("Copying image to RAM.\r\n");
+	memcpy(src, dst, ilen);
+	olen = ilen;
+#else
+	print_debug("Uncompressing image to RAM.\r\n");
+//	dump_mem(src, src+0x100);
+	olen = unrv2b(src, dst, &ilen);
+#endif
+
+//	dump_mem(dst, dst+0x100);
+#if CONFIG_USE_INIT
+	printk_spew("image length = %08x\r\n", olen);
+#else
+	print_spew("image length = "); print_spew_hex32(olen); print_spew("\r\n");
+#endif
+	print_debug("Jumping to image.\r\n");
+
+	__asm__ volatile (
+		"movl %0, %%ebp\n\t"
+		"cli\n\t"
+		"leal    _iseg, %%edi\n\t"
+		"jmp     *%%edi\n\t"
+		:: "a"(ebp)
+	);
+
+}
Index: coreboot-v2/src/cpu/amd/car/copy_and_run.c
===================================================================
--- coreboot-v2.orig/src/cpu/amd/car/copy_and_run.c
+++ coreboot-v2/src/cpu/amd/car/copy_and_run.c
@@ -3,59 +3,20 @@
    2006/05/02 - stepan: move nrv2b to an extra file.
 */
 
-#if CONFIG_COMPRESS
-#define ENDIAN   0
-#define BITSIZE 32
-#include "lib/nrv2b.c"
-#endif
+void copy_and_run_core(u8 *src, u8 *dst, unsigned long ilen, unsigned ebp);
 
 extern u8 _liseg, _iseg, _eiseg;
 
 static void copy_and_run(void)
 {
 	uint8_t *src, *dst; 
-        unsigned long ilen, olen;
-
+        unsigned long ilen;
 
 	src = &_liseg;
 	dst = &_iseg;
 	ilen = &_eiseg - dst;
 
-#if CONFIG_USE_INIT
-	printk_spew("src=%08x\r\n",src);
-	printk_spew("dst=%08x\r\n",dst);
-#else
-	print_spew("src="); print_spew_hex32((uint32_t)src); print_spew("\r\n");
-	print_spew("dst="); print_spew_hex32((uint32_t)dst); print_spew("\r\n");
-#endif
-
-#if !CONFIG_COMPRESS
-        print_debug("Copying coreboot to RAM.\r\n");
-        memcpy(src, dst, ilen);
-        olen = ilen;
-#else
-        print_debug("Uncompressing coreboot to RAM.\r\n");
-//      dump_mem(src, src+0x100);
-        olen = unrv2b(src, dst, &ilen);
-#endif
-
-//	dump_mem(dst, dst+0x100);
-
-#if CONFIG_USE_INIT
-	printk_spew("coreboot_ram.bin length = %08x\r\n", olen);
-#else
-	print_spew("coreboot_ram.bin length = "); print_spew_hex32(olen); print_spew("\r\n");
-#endif
-
-	print_debug("Jumping to coreboot.\r\n");
-
-        __asm__ volatile (
-                "xorl %ebp, %ebp\n\t" /* cpu_reset for hardwaremain dummy */
-		"cli\n\t"
-		"leal    _iseg, %edi\n\t"
-		"jmp     *%edi\n\t"
-	);
-
+	copy_and_run_core(src, dst, ilen, 0);
 }
 
 #if CONFIG_AP_CODE_IN_CAR == 1
@@ -65,41 +26,12 @@ extern u8 _liseg_apc, _iseg_apc, _eiseg_
 static void copy_and_run_ap_code_in_car(unsigned ret_addr)
 {
         uint8_t *src, *dst;
-        unsigned long ilen, olen;
-
-//        print_debug("Copying coreboot AP code to CAR.\r\n");
+        unsigned long ilen;
 
 	src = &_liseg_apc;
 	dst = &_iseg_apc;
 	ilen = &_eiseg_apc - dst;
 
-#if !CONFIG_COMPRESS
-        memcpy(dst, src, ilen);
-	olen = ilen;
-#else
-
-//        print_debug_cp_run("src=",(uint32_t)src);
-//        print_debug_cp_run("dst=",(uint32_t)dst);
-
-//      dump_mem(src, src+0x100);
-
-        olen = unrv2b(src, dst, &ilen);
-//        print_debug_cp_run("coreboot_apc.nrv2b length = ", ilen);
-
-#endif
-//      dump_mem(dst, dst+0x100);
-
-//        print_debug_cp_run("coreboot_apc.bin   length = ", olen);
-
-//        print_debug("Jumping to coreboot AP code in CAR.\r\n");
-
-        __asm__ volatile (
-                "movl %0, %%ebp\n\t" /* cpu_reset for hardwaremain dummy */
-                "cli\n\t"
-                "leal    _iseg_apc, %%edi\n\t"
-                "jmp     *%%edi\n\t"
-		:: "a"(ret_addr)
-        );
-
+	copy_and_run_core(src, dst, ilen, ret_addr);
 }
 #endif
Index: coreboot-v2/src/cpu/x86/car/copy_and_run.c
===================================================================
--- coreboot-v2.orig/src/cpu/x86/car/copy_and_run.c
+++ coreboot-v2/src/cpu/x86/car/copy_and_run.c
@@ -1,67 +1,23 @@
-/* by yhlu 6.2005 
-	moved from nrv2v.c and some lines from crt0.S
-   2006/05/02 - stepan: move nrv2b to an extra file.
+/* Copyright (C) 2009 coresystems GmbH
+   (Written by Patrick Georgi <patrick.georgi@coresystems.de> for coresystems GmbH
 */
 
-#if CONFIG_COMPRESS
-#define ENDIAN   0
-#define BITSIZE 32
-#include "lib/nrv2b.c"
-#endif
+void copy_and_run_core(u8 *src, u8 *dst, unsigned long ilen, unsigned ebp);
 
 extern u8 _liseg, _iseg, _eiseg;
 
 static void copy_and_run(unsigned cpu_reset)
 {
 	uint8_t *src, *dst; 
-        unsigned long ilen, olen;
+        unsigned long ilen;
 
 
 	src = &_liseg;
 	dst = &_iseg;
 	ilen = &_eiseg - dst;
 
-#if CONFIG_USE_INIT		
-	printk_spew("src=%08x\r\n",src); 
-	printk_spew("dst=%08x\r\n",dst);
-#else
-        print_spew("src="); print_spew_hex32((uint32_t)src); print_spew("\r\n");
-        print_spew("dst="); print_spew_hex32((uint32_t)dst); print_spew("\r\n");
-#endif
-
-#if !CONFIG_COMPRESS
-	print_debug("Copying coreboot to RAM.\r\n");
-	memcpy(src, dst, ilen);
-	olen = ilen;
-#else
-	print_debug("Uncompressing coreboot to RAM.\r\n");
-//	dump_mem(src, src+0x100);
-	olen = unrv2b(src, dst, &ilen);
-#endif
-
-//	dump_mem(dst, dst+0x100);
-#if CONFIG_USE_INIT
-	printk_spew("coreboot_ram.bin length = %08x\r\n", olen);
-#else
-	print_spew("coreboot_ram.bin length = "); print_spew_hex32(olen); print_spew("\r\n");
-#endif
-	print_debug("Jumping to coreboot.\r\n");
-
-	if(cpu_reset == 1 ) {
-		__asm__ volatile (
-			"movl $0xffffffff, %ebp\n\t"
-		);
-	}
-	else {
-                __asm__ volatile (
-                        "xorl %ebp, %ebp\n\t"
-                );
-	}
-	
-	__asm__ volatile (
-		"cli\n\t"
-		"leal    _iseg, %edi\n\t"
-		"jmp     *%edi\n\t"
-	);
+	if (cpu_reset == 1) cpu_reset = -1;
+	else cpu_reset = 0;
 
+	copy_and_run_core(src, dst, ilen, cpu_reset);
 }
Index: coreboot-v2/src/arch/i386/lib/Config.lb
===================================================================
--- coreboot-v2.orig/src/arch/i386/lib/Config.lb
+++ coreboot-v2/src/arch/i386/lib/Config.lb
@@ -1,5 +1,6 @@
 uses CONFIG_USE_INIT
 uses CONFIG_USE_PRINTK_IN_CAR
+uses USE_FAILOVER_IMAGE
 
 object c_start.S
 object cpu.c
@@ -11,3 +12,7 @@ object exception.c
 
 initobject printk_init.o
 
+if USE_FAILOVER_IMAGE
+else
+	initobject copy_and_run.o
+end
Index: coreboot-v2/src/arch/i386/init/crt0.S.lb
===================================================================
--- coreboot-v2.orig/src/arch/i386/init/crt0.S.lb
+++ coreboot-v2/src/arch/i386/init/crt0.S.lb
@@ -69,106 +69,18 @@ __main:
 	 * the location it is compiled to run at.
 	 * Normally this is copying from FLASH ROM to RAM.
 	 */
-#if !CONFIG_COMPRESS
+	movl	%ebp, %esi
+	movl	$0x4000000, %esp
+	movl	%esp, %ebp
+	pushl %esi
 	movl	$_liseg, %esi
 	movl	$_iseg,  %edi
 	movl	$_eiseg, %ecx
 	subl	%edi, %ecx
-	movb	%cl, %al
-	shrl	$2, %ecx
-	andb	$3, %al
-	rep	movsl
-	movb	%al, %cl
-	rep	movsb
-#else
-	leal	4+_liseg, %esi
-	leal	_iseg, %edi
-	movl	%ebp, %esp	/* preserve %ebp */
-	movl	$-1, %ebp	/* last_m_off = -1 */
-	jmp	dcl1_n2b
-
-/* ------------- DECOMPRESSION -------------
-
- Input:
-   %esi - source
-   %edi - dest
-   %ebp - -1
-   cld
-
- Output:
-   %eax - 0
-   %ecx - 0
-*/
-
-.macro getbit bits
-.if	\bits == 1
-	addl	%ebx, %ebx
-	jnz	1f
-.endif
-	movl	(%esi), %ebx
-	subl	$-4, %esi	/* sets carry flag */
-	adcl	%ebx, %ebx
-1:
-.endm
-
-decompr_literals_n2b:
-	movsb
-
-decompr_loop_n2b:
-	addl	%ebx, %ebx
-	jnz	dcl2_n2b
-dcl1_n2b:
-	getbit	32
-dcl2_n2b:
-	jc	decompr_literals_n2b
-	xorl	%eax, %eax
-	incl	%eax		/* m_off = 1 */
-loop1_n2b:
-	getbit	1
-	adcl	%eax, %eax	/* m_off = m_off*2 + getbit() */
-	getbit	1
-	jnc	loop1_n2b	/* while(!getbit()) */
-	xorl	%ecx, %ecx
-	subl	$3, %eax
-	jb	decompr_ebpeax_n2b	/* if (m_off == 2) goto decompr_ebpeax_n2b ? */
-	shll	$8, %eax	
-	movb	(%esi), %al	/* m_off = (m_off - 3)*256 + src[ilen++] */
-	incl	%esi
-	xorl	$-1, %eax	
-	jz	decompr_end_n2b	/* if (m_off == 0xffffffff) goto decomp_end_n2b */
-	movl	%eax, %ebp	/* last_m_off = m_off ?*/
-decompr_ebpeax_n2b:
-	getbit	1		
-	adcl	%ecx, %ecx	/* m_len = getbit() */
-	getbit	1
-	adcl	%ecx, %ecx	/* m_len = m_len*2 + getbit()) */
-	jnz	decompr_got_mlen_n2b	/* if (m_len == 0) goto decompr_got_mlen_n2b */
-	incl	%ecx		/* m_len++ */
-loop2_n2b:
-	getbit	1	
-	adcl	%ecx, %ecx	/* m_len = m_len*2 + getbit() */
-	getbit	1
-	jnc	loop2_n2b	/* while(!getbit()) */
-	incl	%ecx
-	incl	%ecx		/* m_len += 2 */
-decompr_got_mlen_n2b:
-	cmpl	$-0xd00, %ebp
-	adcl	$1, %ecx	/* m_len = m_len + 1 + (last_m_off > 0xd00) */
-	movl	%esi, %edx
-	leal	(%edi,%ebp), %esi	/* m_pos = dst + olen + -m_off  */
-	rep
-	movsb			/* dst[olen++] = *m_pos++ while(m_len > 0) */
-	movl	%edx, %esi
-	jmp	decompr_loop_n2b
-decompr_end_n2b:
-	intel_chip_post_macro(0x12)		/* post 12 */
-
-	movl	%esp, %ebp
-#endif
-
-	CONSOLE_DEBUG_TX_STRING($str_pre_main)
-	leal	_iseg, %edi
-	jmp	*%edi
+	pushl %ecx
+	pushl %edi
+	pushl %esi
+	call copy_and_run_core
 
 .Lhlt:	
 	intel_chip_post_macro(0xee)	/* post fe */
