GNU Linux-libre 6.8.9-gnu
[releases.git] / arch / x86 / platform / efi / efi_stub_32.S
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
15 SYM_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
33 1:
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
60 SYM_FUNC_END(efi_call_svam)