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