diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 67de6bcb38b47a6ae8e37ccd38e38ba6aa63bbb2..9c2db9f21e44b8dd21744967d2d5c9e2093f8c9c 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -90,12 +90,6 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries)
 	asm volatile("lgdtl %0\n" : : "m" (gdt));
 }
 
-void init_gd(gd_t *id, u64 *gdt_addr)
-{
-	id->gd_addr = id;
-	setup_gdt(id, gdt_addr);
-}
-
 void setup_gdt(gd_t *id, u64 *gdt_addr)
 {
 	/* CS: code, read/execute, 4 GB, base 0 */
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index ee0dabe4bcd049becb3c632ec408c98f32d13fb3..ec12e8044fd92a6f4c8fcf24057bb19f3645324f 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -83,13 +83,33 @@ car_init_ret:
 	 * or fully initialised SDRAM - we really don't care which)
 	 * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack
 	 */
-	movl	$CONFIG_SYS_INIT_SP_ADDR, %esp
 
-	/* Initialise the Global Data Pointer */
-	movl	$CONFIG_SYS_INIT_GD_ADDR, %eax
-	movl	%eax, %edx
-	addl	$GENERATED_GBL_DATA_SIZE, %edx
-	call	init_gd;
+	/* Stack grows down from top of CAR */
+	movl	$(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp
+
+	/* Reserve space on stack for global data */
+	subl	$GENERATED_GBL_DATA_SIZE, %esp
+
+	/* Align global data to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Setup first parameter to setup_gdt */
+	movl	%esp, %eax
+
+	/* Reserve space for global descriptor table */
+	subl	$X86_GDT_SIZE, %esp
+
+	/* Align temporary global descriptor table to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Set second parameter to setup_gdt */
+	movl	%esp, %edx
+
+	/* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+	movl	%eax, (%eax)
+
+	/* Setup global descriptor table so gd->xyz works */
+	call	setup_gdt
 
 	/* Set parameter to board_init_f() to boot flags */
 	xorl	%eax, %eax
@@ -113,9 +133,42 @@ board_init_f_r_trampoline:
 	 * %eax = Address of top of new stack
 	 */
 
-	/* Setup stack in RAM */
+	/* Stack grows down from top of SDRAM */
 	movl	%eax, %esp
 
+	/* Reserve space on stack for global data */
+	subl	$GENERATED_GBL_DATA_SIZE, %esp
+
+	/* Align global data to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Setup first parameter to memcpy (and setup_gdt) */
+	movl	%esp, %eax
+
+	/* Setup second parameter to memcpy */
+	fs movl 0, %edx
+
+	/* Set third parameter to memcpy */
+	movl	$GENERATED_GBL_DATA_SIZE, %ecx
+
+	/* Copy global data from CAR to SDRAM stack */
+	call	memcpy
+
+	/* Reserve space for global descriptor table */
+	subl	$X86_GDT_SIZE, %esp
+
+	/* Align global descriptor table to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Set second parameter to setup_gdt */
+	movl	%esp, %edx
+
+	/* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+	movl	%eax, (%eax)
+
+	/* Setup global descriptor table so gd->xyz works */
+	call	setup_gdt
+
 	/* Re-enter U-Boot by calling board_init_f_r */
 	call	board_init_f_r
 
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 13a3ce8fbf5e24bc47aceffc89e5e73c3cfd40d3..59c2a9095bd662c579b41030418f54ca6b6e7e7c 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -54,7 +54,6 @@ struct global_data {
 	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
 	unsigned long	start_addr_sp;	/* start_addr_stackpointer */
 	unsigned long	gdt_addr;	/* Location of GDT */
-	unsigned long	new_gd_addr;	/* New location of Global Data */
 	phys_size_t	ram_size;	/* RAM size */
 	unsigned long	reset_status;	/* reset status register at boot */
 	void		**jt;		/* jump table */
diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h
index 8afb4432906b6d9e3c9431178ddb5b64ced998b7..ade694fba334205f811eabdad389c70cae1769dc 100644
--- a/arch/x86/include/asm/init_helpers.h
+++ b/arch/x86/include/asm/init_helpers.h
@@ -29,7 +29,6 @@ int display_dram_config(void);
 int init_baudrate_f(void);
 int calculate_relocation_address(void);
 
-int copy_gd_to_ram_f_r(void);
 int init_cache_f_r(void);
 
 int set_reloc_flag_r(void);
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 6eb518063bd8ec031706f778c83710004952cfb8..17f27cbb68468c31079433dc7cadc1df8b894458 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -41,6 +41,7 @@ enum {
 #else
 /* NOTE: If the above enum is modified, this define must be checked */
 #define X86_GDT_ENTRY_32BIT_DS	3
+#define X86_GDT_NUM_ENTRIES	7
 #endif
 
 #define X86_GDT_SIZE		(X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE)
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index e5caf13561b1585cfd36842c15aa0e9156d583c4..a13f5c0e109bca853307653116b26b32df401540 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -36,6 +36,7 @@
 #include <stdio_dev.h>
 #include <asm/u-boot-x86.h>
 #include <asm/relocate.h>
+#include <asm/processor.h>
 
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
@@ -121,7 +122,6 @@ init_fnc_t *init_sequence_f[] = {
  * initialise the CPU caches (to speed up the relocation process)
  */
 init_fnc_t *init_sequence_f_r[] = {
-	copy_gd_to_ram_f_r,
 	init_cache_f_r,
 	copy_uboot_to_ram,
 	clear_bss,
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 2f718d7c4ac1a7efafe822962493c885896fd973..87c7263fcb5094824e141cf737a5deac507744d5 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -83,18 +83,8 @@ int calculate_relocation_address(void)
 	 *       requirements
 	 */
 
-	/* Global Data is at top of available memory */
+	/* Stack is at top of available memory */
 	dest_addr = gd->ram_size;
-	dest_addr -= GENERATED_GBL_DATA_SIZE;
-	dest_addr &= ~15;
-	gd->new_gd_addr = dest_addr;
-
-	/* GDT is below Global Data */
-	dest_addr -= X86_GDT_SIZE;
-	dest_addr &= ~15;
-	gd->gdt_addr = dest_addr;
-
-	/* Stack is below GDT */
 	gd->start_addr_sp = dest_addr;
 
 	/* U-Boot is below the stack */
@@ -107,31 +97,6 @@ int calculate_relocation_address(void)
 	return 0;
 }
 
-int copy_gd_to_ram_f_r(void)
-{
-	gd_t *ram_gd;
-
-	/*
-	 * Global data is still in temporary memory (the CPU cache).
-	 * calculate_relocation_address() has set gd->new_gd_addr to
-	 * where the global data lives in RAM but getting it there
-	 * safely is a bit tricky due to the 'F-Segment Hack' that
-	 * we need to use for x86
-	 */
-	ram_gd = (gd_t *)gd->new_gd_addr;
-	memcpy((void *)ram_gd, gd, sizeof(gd_t));
-
-	/*
-	 * Reload the Global Descriptor Table so FS points to the
-	 * in-RAM copy of Global Data (calculate_relocation_address()
-	 * has already calculated the in-RAM location of the GDT)
-	 */
-	ram_gd->gd_addr = ram_gd;
-	init_gd(ram_gd, (u64 *)gd->gdt_addr);
-
-	return 0;
-}
-
 int init_cache_f_r(void)
 {
 	/* Initialise the CPU cache(s) */
diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h
index cc95e2be987212014e6b6cffc23365f3c23c45cd..8d3c21f05dbfe055233c754f0f00ffb58152e8d2 100644
--- a/include/configs/coreboot.h
+++ b/include/configs/coreboot.h
@@ -210,12 +210,11 @@
  * (128kB + Environment Sector Size) malloc pool
  */
 #define CONFIG_SYS_STACK_SIZE			(32 * 1024)
-#define CONFIG_SYS_INIT_SP_ADDR		(256 * 1024 + 16 * 1024)
+#define CONFIG_SYS_CAR_ADDR			0x19200000
+#define CONFIG_SYS_CAR_SIZE			(16 * 1024)
 #define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_MONITOR_LEN			(256 * 1024)
 #define CONFIG_SYS_MALLOC_LEN			(0x20000 + 128 * 1024)
-/* Address of temporary Global Data */
-#define CONFIG_SYS_INIT_GD_ADDR		(256 * 1024)
 
 
 /* allow to overwrite serial and ethaddr */
diff --git a/include/configs/eNET.h b/include/configs/eNET.h
index 4b1c21904cb05f68492539a93b244db27d86f27c..28cf95b7788549063d86a189844f942c894b7b7f 100644
--- a/include/configs/eNET.h
+++ b/include/configs/eNET.h
@@ -168,16 +168,10 @@
 #define CONFIG_SYS_STACK_SIZE			(32 * 1024)
 #define CONFIG_SYS_CAR_ADDR			0x19200000
 #define CONFIG_SYS_CAR_SIZE			(16 * 1024)
-#define CONFIG_SYS_INIT_SP_ADDR			(CONFIG_SYS_CAR_ADDR + \
-						 CONFIG_SYS_CAR_SIZE)
 #define CONFIG_SYS_MONITOR_BASE			CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_MONITOR_LEN			(256 * 1024)
 #define CONFIG_SYS_MALLOC_LEN			(CONFIG_ENV_SECT_SIZE + \
 						 128*1024)
-/* Address of temporary Global Data */
-#define CONFIG_SYS_INIT_GD_ADDR			CONFIG_SYS_CAR_ADDR
-
-
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE