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) |
61 | |