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/page_types.h>
12
13	__INIT
14SYM_FUNC_START(efi_call_svam)
15	push	8(%esp)
16	push	8(%esp)
17	push	%ecx
18	push	%edx
19
20	/*
21	 * Switch to the flat mapped alias of this routine, by jumping to the
22	 * address of label '1' after subtracting PAGE_OFFSET from it.
23	 */
24	movl	$1f, %edx
25	subl	$__PAGE_OFFSET, %edx
26	jmp	*%edx
271:
28
29	/* disable paging */
30	movl	%cr0, %edx
31	andl	$0x7fffffff, %edx
32	movl	%edx, %cr0
33
34	/* convert the stack pointer to a flat mapped address */
35	subl	$__PAGE_OFFSET, %esp
36
37	/* call the EFI routine */
38	call	*(%eax)
39
40	/* convert ESP back to a kernel VA, and pop the outgoing args */
41	addl	$__PAGE_OFFSET + 16, %esp
42
43	/* re-enable paging */
44	movl	%cr0, %edx
45	orl	$0x80000000, %edx
46	movl	%edx, %cr0
47
48	ret
49SYM_FUNC_END(efi_call_svam)
50