summaryrefslogtreecommitdiff
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/cpu/cpu.c6
-rw-r--r--arch/x86/cpu/start.S67
-rw-r--r--arch/x86/include/asm/global_data.h1
-rw-r--r--arch/x86/include/asm/init_helpers.h1
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/lib/board.c2
-rw-r--r--arch/x86/lib/init_helpers.c37
7 files changed, 63 insertions, 52 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
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 13a3ce8..59c2a90 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 8afb443..ade694f 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 6eb5180..17f27cb 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 e5caf13..a13f5c0 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 2f718d7..87c7263 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) */