With the 64-bit descriptor we can use a jump instruction, rather than pushing things on the stack.
Since the processor is in 64-bit mode by this point, pop a 64-bit value from the stack, containing the target address. This simplifies the code slightly, in particular its use of the stack. Signed-off-by: Simon Glass <s...@chromium.org> --- (no changes since v1) arch/x86/cpu/i386/call64.S | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/x86/cpu/i386/call64.S b/arch/x86/cpu/i386/call64.S index 3137ec17d31..c6308b92e25 100644 --- a/arch/x86/cpu/i386/call64.S +++ b/arch/x86/cpu/i386/call64.S @@ -22,6 +22,7 @@ cpu_call64: * ecx - target */ cli + pushl $0 /* top 64-bits of target */ push %ecx /* arg2 = target */ push %edx /* arg1 = setup_base */ mov %eax, %ebx @@ -32,7 +33,8 @@ cpu_call64: movl %eax, %cr0 /* Enable PAE mode */ - movl $(X86_CR4_PAE), %eax + movl %cr4, %eax + orl $X86_CR4_PAE, %eax movl %eax, %cr4 /* Enable the boot page tables */ @@ -57,23 +59,18 @@ cpu_call64: */ pop %esi /* setup_base */ - pushl $(X86_GDT_ENTRY_64BIT_CS * X86_GDT_ENTRY_SIZE) - leal lret_target, %eax - pushl %eax - /* Enter paged protected Mode, activating Long Mode */ movl %cr0, %eax orl $X86_CR0_PG, %eax movl %eax, %cr0 /* Jump from 32bit compatibility mode into 64bit mode. */ - lret + ljmp $(X86_GDT_ENTRY_64BIT_CS * X86_GDT_ENTRY_SIZE), $lret_target -code64: +.code64 lret_target: - pop %eax /* target */ - mov %eax, %eax /* Clear bits 63:32 */ - jmp *%eax /* Jump to the 64-bit target */ + pop %rax /* target */ + jmp *%rax /* Jump to the 64-bit target */ .globl call64_stub_size call64_stub_size: -- 2.43.0