summaryrefslogtreecommitdiff
path: root/arch/x86/cpu
diff options
context:
space:
mode:
authorGraeme Russ <graeme.russ@gmail.com>2012-11-27 15:38:36 (GMT)
committerSimon Glass <sjg@chromium.org>2012-11-28 19:40:03 (GMT)
commit8d61625d6a73307857f80002949583105545dbbc (patch)
tree2f5da8cb7d9df09564e2c35818c429f247076582 /arch/x86/cpu
parente4fb6116495eafbeee5ea8ff7ea245eb5e96d012 (diff)
downloadu-boot-8d61625d6a73307857f80002949583105545dbbc.tar.xz
x86: Put global data on the stack
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>
Diffstat (limited to 'arch/x86/cpu')
-rw-r--r--arch/x86/cpu/cpu.c6
-rw-r--r--arch/x86/cpu/start.S67
2 files changed, 60 insertions, 13 deletions
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 67de6bc..9c2db9f 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 ee0dabe..ec12e80 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