root/arch/x86/platform/efi/efi_stub_32.S
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * EFI call stub for IA32.
 *
 * This stub allows us to make EFI calls in physical mode with interrupts
 * turned off.
 */

#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/page_types.h>

        __INIT
SYM_FUNC_START(efi_call_svam)
        push    %ebp
        movl    %esp, %ebp
        push    %ebx

        push    16(%esp)
        push    16(%esp)
        push    %ecx
        push    %edx
        movl    %eax, %ebx              // &systab_phys->runtime

        /*
         * Switch to the flat mapped alias of this routine, by jumping to the
         * address of label '1' after subtracting PAGE_OFFSET from it.
         */
        movl    $1f, %edx
        subl    $__PAGE_OFFSET, %edx
        jmp     *%edx
1:

        /* disable paging */
        movl    %cr0, %edx
        andl    $0x7fffffff, %edx
        movl    %edx, %cr0

        /* convert the stack pointer to a flat mapped address */
        subl    $__PAGE_OFFSET, %esp

        /* call the EFI routine */
        movl    (%eax), %eax
        call    *EFI_svam(%eax)

        /* grab the virtually remapped EFI runtime services table pointer */
        movl    (%ebx), %ecx
        movl    36(%esp), %edx          // &efi.runtime
        movl    %ecx, (%edx)

        /* re-enable paging */
        movl    %cr0, %edx
        orl     $0x80000000, %edx
        movl    %edx, %cr0

        movl    16(%esp), %ebx
        leave
        RET
SYM_FUNC_END(efi_call_svam)