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 */
 
         * 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
         * %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
 
 
        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 */
 
 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);
 
 #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)
 
 #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>
  * 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,
 
         *       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 */
        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) */
 
  * (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 */
 
 #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