diff --git a/src/cpu/x86/64bit/mode_switch.S b/src/cpu/x86/64bit/mode_switch.S index e5be44a318..a4c58f2573 100644 --- a/src/cpu/x86/64bit/mode_switch.S +++ b/src/cpu/x86/64bit/mode_switch.S @@ -26,6 +26,10 @@ protected_mode_call_wrapper: /* Store stack pointer */ mov %rsp, %rbp + /* Backup cr3 to stack */ + mov %cr3, %rax + push %rax + /* New IDT to stack */ pushq $0 pushq $0 @@ -47,7 +51,7 @@ protected_mode_call_wrapper: #include /* Load zero IDT. x86_32 FSP doesn't like to find a x86_64 IDT */ - lidt -16(%ebp) + lidt -24(%ebp) /* Fetch function to call */ movl 12(%esp), %ebx @@ -56,8 +60,11 @@ protected_mode_call_wrapper: call *%ebx movl %eax, %ebx - /* Preserves ebx */ - setup_longmode $PM4LE + /* + * Back to long mode by using cr3 previously stored on stack. + * Preserves ebx. + */ + setup_longmode -8(%ebp) /* Place return value in rax */ movl %ebx, %eax