1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * EFI call stub for IA32.
4 *
5 * This stub allows us to make EFI calls in physical mode with interrupts
6 * turned off.
7 */
8
9#include <linux/linkage.h>
10#include <linux/init.h>
11#include <asm/asm-offsets.h>
12#include <asm/page_types.h>
13
14 __INIT
15SYM_FUNC_START(efi_call_svam)
16 push %ebp
17 movl %esp, %ebp
18 push %ebx
19
20 push 16(%esp)
21 push 16(%esp)
22 push %ecx
23 push %edx
24 movl %eax, %ebx // &systab_phys->runtime
25
26 /*
27 * Switch to the flat mapped alias of this routine, by jumping to the
28 * address of label '1' after subtracting PAGE_OFFSET from it.
29 */
30 movl $1f, %edx
31 subl $__PAGE_OFFSET, %edx
32 jmp *%edx
331:
34
35 /* disable paging */
36 movl %cr0, %edx
37 andl $0x7fffffff, %edx
38 movl %edx, %cr0
39
40 /* convert the stack pointer to a flat mapped address */
41 subl $__PAGE_OFFSET, %esp
42
43 /* call the EFI routine */
44 movl (%eax), %eax
45 call *EFI_svam(%eax)
46
47 /* grab the virtually remapped EFI runtime services table pointer */
48 movl (%ebx), %ecx
49 movl 36(%esp), %edx // &efi.runtime
50 movl %ecx, (%edx)
51
52 /* re-enable paging */
53 movl %cr0, %edx
54 orl $0x80000000, %edx
55 movl %edx, %cr0
56
57 movl 16(%esp), %ebx
58 leave
59 RET
60SYM_FUNC_END(efi_call_svam)
61

source code of linux/arch/x86/platform/efi/efi_stub_32.S