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