1/*
2 * Function calling ABI conversion from Linux to EFI for x86_64
3 *
4 * Copyright (C) 2007 Intel Corp
5 *	Bibo Mao <bibo.mao@intel.com>
6 *	Huang Ying <ying.huang@intel.com>
7 */
8
9#include <linux/linkage.h>
10
11#define SAVE_XMM			\
12	mov %rsp, %rax;			\
13	subq $0x70, %rsp;		\
14	and $~0xf, %rsp;		\
15	mov %rax, (%rsp);		\
16	mov %cr0, %rax;			\
17	clts;				\
18	mov %rax, 0x8(%rsp);		\
19	movaps %xmm0, 0x60(%rsp);	\
20	movaps %xmm1, 0x50(%rsp);	\
21	movaps %xmm2, 0x40(%rsp);	\
22	movaps %xmm3, 0x30(%rsp);	\
23	movaps %xmm4, 0x20(%rsp);	\
24	movaps %xmm5, 0x10(%rsp)
25
26#define RESTORE_XMM			\
27	movaps 0x60(%rsp), %xmm0;	\
28	movaps 0x50(%rsp), %xmm1;	\
29	movaps 0x40(%rsp), %xmm2;	\
30	movaps 0x30(%rsp), %xmm3;	\
31	movaps 0x20(%rsp), %xmm4;	\
32	movaps 0x10(%rsp), %xmm5;	\
33	mov 0x8(%rsp), %rsi;		\
34	mov %rsi, %cr0;			\
35	mov (%rsp), %rsp
36
37	/* stolen from gcc */
38	.macro FLUSH_TLB_ALL
39	movq %r15, efi_scratch(%rip)
40	movq %r14, efi_scratch+8(%rip)
41	movq %cr4, %r15
42	movq %r15, %r14
43	andb $0x7f, %r14b
44	movq %r14, %cr4
45	movq %r15, %cr4
46	movq efi_scratch+8(%rip), %r14
47	movq efi_scratch(%rip), %r15
48	.endm
49
50	.macro SWITCH_PGT
51	cmpb $0, efi_scratch+24(%rip)
52	je 1f
53	movq %r15, efi_scratch(%rip)		# r15
54	# save previous CR3
55	movq %cr3, %r15
56	movq %r15, efi_scratch+8(%rip)		# prev_cr3
57	movq efi_scratch+16(%rip), %r15		# EFI pgt
58	movq %r15, %cr3
59	1:
60	.endm
61
62	.macro RESTORE_PGT
63	cmpb $0, efi_scratch+24(%rip)
64	je 2f
65	movq efi_scratch+8(%rip), %r15
66	movq %r15, %cr3
67	movq efi_scratch(%rip), %r15
68	FLUSH_TLB_ALL
69	2:
70	.endm
71
72ENTRY(efi_call0)
73	SAVE_XMM
74	subq $32, %rsp
75	SWITCH_PGT
76	call *%rdi
77	RESTORE_PGT
78	addq $32, %rsp
79	RESTORE_XMM
80	ret
81ENDPROC(efi_call0)
82
83ENTRY(efi_call1)
84	SAVE_XMM
85	subq $32, %rsp
86	mov  %rsi, %rcx
87	SWITCH_PGT
88	call *%rdi
89	RESTORE_PGT
90	addq $32, %rsp
91	RESTORE_XMM
92	ret
93ENDPROC(efi_call1)
94
95ENTRY(efi_call2)
96	SAVE_XMM
97	subq $32, %rsp
98	mov  %rsi, %rcx
99	SWITCH_PGT
100	call *%rdi
101	RESTORE_PGT
102	addq $32, %rsp
103	RESTORE_XMM
104	ret
105ENDPROC(efi_call2)
106
107ENTRY(efi_call3)
108	SAVE_XMM
109	subq $32, %rsp
110	mov  %rcx, %r8
111	mov  %rsi, %rcx
112	SWITCH_PGT
113	call *%rdi
114	RESTORE_PGT
115	addq $32, %rsp
116	RESTORE_XMM
117	ret
118ENDPROC(efi_call3)
119
120ENTRY(efi_call4)
121	SAVE_XMM
122	subq $32, %rsp
123	mov %r8, %r9
124	mov %rcx, %r8
125	mov %rsi, %rcx
126	SWITCH_PGT
127	call *%rdi
128	RESTORE_PGT
129	addq $32, %rsp
130	RESTORE_XMM
131	ret
132ENDPROC(efi_call4)
133
134ENTRY(efi_call5)
135	SAVE_XMM
136	subq $48, %rsp
137	mov %r9, 32(%rsp)
138	mov %r8, %r9
139	mov %rcx, %r8
140	mov %rsi, %rcx
141	SWITCH_PGT
142	call *%rdi
143	RESTORE_PGT
144	addq $48, %rsp
145	RESTORE_XMM
146	ret
147ENDPROC(efi_call5)
148
149ENTRY(efi_call6)
150	SAVE_XMM
151	mov (%rsp), %rax
152	mov 8(%rax), %rax
153	subq $48, %rsp
154	mov %r9, 32(%rsp)
155	mov %rax, 40(%rsp)
156	mov %r8, %r9
157	mov %rcx, %r8
158	mov %rsi, %rcx
159	SWITCH_PGT
160	call *%rdi
161	RESTORE_PGT
162	addq $48, %rsp
163	RESTORE_XMM
164	ret
165ENDPROC(efi_call6)
166
167	.data
168ENTRY(efi_scratch)
169	.fill 3,8,0
170	.byte 0
171