1/*
2 * Copyright (C) 2014 Intel Corporation; author Matt Fleming
3 */
4
5#include <linux/linkage.h>
6#include <asm/page_types.h>
7
8	.text
9	.code64
10ENTRY(efi64_thunk)
11	push	%rbp
12	push	%rbx
13
14	/*
15	 * Switch to 1:1 mapped 32-bit stack pointer.
16	 */
17	movq	%rsp, efi_saved_sp(%rip)
18	movq	efi_scratch+25(%rip), %rsp
19
20	/*
21	 * Calculate the physical address of the kernel text.
22	 */
23	movq	$__START_KERNEL_map, %rax
24	subq	phys_base(%rip), %rax
25
26	/*
27	 * Push some physical addresses onto the stack. This is easier
28	 * to do now in a code64 section while the assembler can address
29	 * 64-bit values. Note that all the addresses on the stack are
30	 * 32-bit.
31	 */
32	subq	$16, %rsp
33	leaq	efi_exit32(%rip), %rbx
34	subq	%rax, %rbx
35	movl	%ebx, 8(%rsp)
36	leaq	efi_gdt64(%rip), %rbx
37	subq	%rax, %rbx
38	movl	%ebx, 2(%ebx)
39	movl	%ebx, 4(%rsp)
40	leaq	efi_gdt32(%rip), %rbx
41	subq	%rax, %rbx
42	movl	%ebx, 2(%ebx)
43	movl	%ebx, (%rsp)
44
45	leaq	__efi64_thunk(%rip), %rbx
46	subq	%rax, %rbx
47	call	*%rbx
48
49	movq	efi_saved_sp(%rip), %rsp
50	pop	%rbx
51	pop	%rbp
52	retq
53ENDPROC(efi64_thunk)
54
55	.data
56efi_gdt32:
57	.word 	efi_gdt32_end - efi_gdt32
58	.long	0			/* Filled out above */
59	.word	0
60	.quad	0x0000000000000000	/* NULL descriptor */
61	.quad	0x00cf9a000000ffff	/* __KERNEL_CS */
62	.quad	0x00cf93000000ffff	/* __KERNEL_DS */
63efi_gdt32_end:
64
65efi_saved_sp:		.quad 0
66