diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/cpu/cpu.c | 6 | ||||
-rw-r--r-- | arch/x86/cpu/start.S | 67 | ||||
-rw-r--r-- | arch/x86/include/asm/global_data.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/init_helpers.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/x86/lib/board.c | 2 | ||||
-rw-r--r-- | arch/x86/lib/init_helpers.c | 37 |
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) */ |