| /* 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) |