diff options
author | Simon Glass <sjg@chromium.org> | 2023-07-15 21:38:52 -0600 |
---|---|---|
committer | Bin Meng <bmeng@tinylab.org> | 2023-07-17 17:12:07 +0800 |
commit | 8f015d37813b398c9f2bde9bbf531278a399ad88 (patch) | |
tree | ef97aa4ad282bab394fdbd0b8ee8c1847b38d351 | |
parent | 3710802ebfc42e24fa6b7f8b78f3d668dac1363e (diff) | |
download | u-boot-8f015d37813b398c9f2bde9bbf531278a399ad88.zip u-boot-8f015d37813b398c9f2bde9bbf531278a399ad88.tar.gz u-boot-8f015d37813b398c9f2bde9bbf531278a399ad88.tar.bz2 |
x86: Improve the trampoline in 64-bit mode
At present this leaves the stack at the pre-relocation value. This is not
ideal since we want to have U-Boot running entirely from the top of
memory.
In addition, the new global_data pointer is not actually used, since
the global_data pointer itself is relocated, then the pre-relocation value
is changed, so the effective value (after relocation) does not update.
Adjust the implementation to follow the 32-bit code more closely, with a
trampoline function which is passed the new stack and global_data pointer.
This ensures that the correct values come through even when relocating.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r-- | arch/x86/cpu/start64.S | 19 | ||||
-rw-r--r-- | arch/x86/include/asm/u-boot-x86.h | 11 | ||||
-rw-r--r-- | common/board_f.c | 12 |
3 files changed, 37 insertions, 5 deletions
diff --git a/arch/x86/cpu/start64.S b/arch/x86/cpu/start64.S index 7be8347..78e894d 100644 --- a/arch/x86/cpu/start64.S +++ b/arch/x86/cpu/start64.S @@ -26,3 +26,22 @@ _start: /* Should not return here */ jmp . + +.globl board_init_f_r_trampoline64 +.type board_init_f_r_trampoline64, @function +board_init_f_r_trampoline64: + /* + * SDRAM has been initialised, U-Boot code has been copied into + * RAM, BSS has been cleared and relocation adjustments have been + * made. It is now time to jump into the in-RAM copy of U-Boot + * + * %eax = Address of top of new stack + */ + + /* Stack grows down from top of SDRAM */ + movq %rsi, %rsp + + /* New gd is in rdi */ + + /* Re-enter U-Boot by calling board_init_f_r() */ + call board_init_f_r diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 1d8aa32..02a8b0f 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -117,6 +117,17 @@ void __noreturn board_init_f_r_trampoline(ulong sp); */ void __noreturn board_init_f_r(void); +/* + * board_init_f_r_trampoline64() - jump to relocated address with new stack + * + * This is the 64-bit version + * + * @new_gd: New global_data pointer to use + * @sp: New stack pointer to pass on to board_init_r() + */ +void __noreturn board_init_f_r_trampoline64(struct global_data *new_gd, + ulong sp); + int arch_misc_init(void); /* Read the time stamp counter */ diff --git a/common/board_f.c b/common/board_f.c index 334d04a..e5969ec 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -729,8 +729,7 @@ static int fix_fdt(void) #endif /* ARM calls relocate_code from its crt0.S */ -#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ - !CONFIG_IS_ENABLED(X86_64) +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) static int jump_to_copy(void) { @@ -752,7 +751,11 @@ static int jump_to_copy(void) * (CPU cache) */ arch_setup_gd(gd->new_gd); - board_init_f_r_trampoline(gd->start_addr_sp); +# if CONFIG_IS_ENABLED(X86_64) + board_init_f_r_trampoline64(gd->new_gd, gd->start_addr_sp); +# else + board_init_f_r_trampoline(gd->start_addr_sp); +# endif #else relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr); #endif @@ -967,8 +970,7 @@ static const init_fnc_t init_sequence_f[] = { * watchdog device is not serviced is as small as possible. */ cyclic_unregister_all, -#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ - !CONFIG_IS_ENABLED(X86_64) +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) jump_to_copy, #endif NULL, |