]> git.sur5r.net Git - u-boot/commitdiff
x86: Put global data on the stack
authorGraeme Russ <graeme.russ@gmail.com>
Tue, 27 Nov 2012 15:38:36 +0000 (15:38 +0000)
committerSimon Glass <sjg@chromium.org>
Wed, 28 Nov 2012 19:40:03 +0000 (11:40 -0800)
Putting global data on the stack simplifies the init process (and makes it
slightly quicker). During the 'flash' stage of the init sequence, global
data is in the CAR stack. After SDRAM is initialised, global data is copied
from CAR to the SDRAM stack

Signed-off-by: Graeme Russ <graeme.russ@gmail.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
arch/x86/cpu/cpu.c
arch/x86/cpu/start.S
arch/x86/include/asm/global_data.h
arch/x86/include/asm/init_helpers.h
arch/x86/include/asm/processor.h
arch/x86/lib/board.c
arch/x86/lib/init_helpers.c
include/configs/coreboot.h
include/configs/eNET.h

index 67de6bcb38b47a6ae8e37ccd38e38ba6aa63bbb2..9c2db9f21e44b8dd21744967d2d5c9e2093f8c9c 100644 (file)
@@ -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 */
index ee0dabe4bcd049becb3c632ec408c98f32d13fb3..ec12e8044fd92a6f4c8fcf24057bb19f3645324f 100644 (file)
@@ -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
 
index 13a3ce8fbf5e24bc47aceffc89e5e73c3cfd40d3..59c2a9095bd662c579b41030418f54ca6b6e7e7c 100644 (file)
@@ -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 */
index 8afb4432906b6d9e3c9431178ddb5b64ced998b7..ade694fba334205f811eabdad389c70cae1769dc 100644 (file)
@@ -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);
index 6eb518063bd8ec031706f778c83710004952cfb8..17f27cbb68468c31079433dc7cadc1df8b894458 100644 (file)
@@ -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)
index e5caf13561b1585cfd36842c15aa0e9156d583c4..a13f5c0e109bca853307653116b26b32df401540 100644 (file)
@@ -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,
index 2f718d7c4ac1a7efafe822962493c885896fd973..87c7263fcb5094824e141cf737a5deac507744d5 100644 (file)
@@ -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) */
index cc95e2be987212014e6b6cffc23365f3c23c45cd..8d3c21f05dbfe055233c754f0f00ffb58152e8d2 100644 (file)
  * (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 */
index 4b1c21904cb05f68492539a93b244db27d86f27c..28cf95b7788549063d86a189844f942c894b7b7f 100644 (file)
 #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