xref: /DragonStub/lib/x86_64/efi_stub.S (revision 803b49c40bb0b720b90d9c31d372911f1b946aa7)
1530d68baSNigel Croxon/*
2530d68baSNigel Croxon * Function calling ABI conversion from Linux to EFI for x86_64
3530d68baSNigel Croxon *
4530d68baSNigel Croxon * Copyright (C) 2007 Intel Corp
5530d68baSNigel Croxon *	Bibo Mao <bibo.mao@intel.com>
6530d68baSNigel Croxon *	Huang Ying <ying.huang@intel.com>
7530d68baSNigel Croxon * Copyright (C) 2012 Felipe Contreras <felipe.contreras@gmail.com>
8530d68baSNigel Croxon */
9530d68baSNigel Croxon
10530d68baSNigel Croxon#if !defined(HAVE_USE_MS_ABI)
11530d68baSNigel Croxon/*
12530d68baSNigel Croxon * EFI calling conventions are documented at:
13530d68baSNigel Croxon *   http://msdn.microsoft.com/en-us/library/ms235286%28v=vs.80%29.aspx
14530d68baSNigel Croxon * ELF calling conventions are documented at:
15530d68baSNigel Croxon *   http://www.x86-64.org/documentation/abi.pdf
16530d68baSNigel Croxon *
17530d68baSNigel Croxon * Basically here are the conversion rules:
18530d68baSNigel Croxon * a) our function pointer is in %rdi
19530d68baSNigel Croxon * b) rsi through r8 (elf) aka rcx through r9 (ms) require stack space
20530d68baSNigel Croxon *    on the MS side even though it's not getting used at all.
21530d68baSNigel Croxon * c) 8(%rsp) is always aligned to 16 in ELF, so %rsp is shifted 8 bytes extra
22530d68baSNigel Croxon * d) arguments are as follows: (elf -> ms)
23530d68baSNigel Croxon *   1) rdi -> rcx (32 saved)
24530d68baSNigel Croxon *   2) rsi -> rdx (32 saved)
25530d68baSNigel Croxon *   3) rdx -> r8 (32 saved)
26530d68baSNigel Croxon *   4) rcx -> r9 (32 saved)
27530d68baSNigel Croxon *   5) r8 -> 32(%rsp) (32 saved)
28530d68baSNigel Croxon *   6) r9 -> 40(%rsp) (48 saved)
29530d68baSNigel Croxon *   7) 8(%rsp) -> 48(%rsp) (48 saved)
30530d68baSNigel Croxon *   8) 16(%rsp) -> 56(%rsp) (64 saved)
31530d68baSNigel Croxon *   9) 24(%rsp) -> 64(%rsp) (64 saved)
32530d68baSNigel Croxon *  10) 32(%rsp) -> 72(%rsp) (80 saved)
33530d68baSNigel Croxon * e) because the first argument we recieve in a thunker is actually the
34530d68baSNigel Croxon *    function to be called, arguments are offset as such:
35530d68baSNigel Croxon *   0) rdi -> caller
36530d68baSNigel Croxon *   1) rsi -> rcx (32 saved)
37530d68baSNigel Croxon *   2) rdx -> rdx (32 saved)
38530d68baSNigel Croxon *   3) rcx -> r8 (32 saved)
39530d68baSNigel Croxon *   4) r8 -> r9 (32 saved)
40530d68baSNigel Croxon *   5) r9 -> 32(%rsp) (32 saved)
41530d68baSNigel Croxon *   6) 8(%rsp) -> 40(%rsp) (48 saved)
42530d68baSNigel Croxon *   7) 16(%rsp) -> 48(%rsp) (48 saved)
43530d68baSNigel Croxon *   8) 24(%rsp) -> 56(%rsp) (64 saved)
44530d68baSNigel Croxon *   9) 32(%rsp) -> 64(%rsp) (64 saved)
45530d68baSNigel Croxon *  10) 40(%rsp) -> 72(%rsp) (80 saved)
46530d68baSNigel Croxon * f) arguments need to be moved in opposite order to avoid clobbering
47530d68baSNigel Croxon */
48530d68baSNigel Croxon
49530d68baSNigel Croxon#define ENTRY(name)	\
50530d68baSNigel Croxon	.globl name;	\
51530d68baSNigel Croxon	name:
52530d68baSNigel Croxon
53530d68baSNigel CroxonENTRY(efi_call0)
54530d68baSNigel Croxon	subq $40, %rsp
55530d68baSNigel Croxon	call *%rdi
56530d68baSNigel Croxon	addq $40, %rsp
57530d68baSNigel Croxon	ret
58530d68baSNigel Croxon
59530d68baSNigel CroxonENTRY(efi_call1)
60530d68baSNigel Croxon	subq $40, %rsp
61530d68baSNigel Croxon	mov  %rsi, %rcx
62530d68baSNigel Croxon	call *%rdi
63530d68baSNigel Croxon	addq $40, %rsp
64530d68baSNigel Croxon	ret
65530d68baSNigel Croxon
66530d68baSNigel CroxonENTRY(efi_call2)
67530d68baSNigel Croxon	subq $40, %rsp
68530d68baSNigel Croxon	/* mov %rdx, %rdx */
69530d68baSNigel Croxon	mov  %rsi, %rcx
70530d68baSNigel Croxon	call *%rdi
71530d68baSNigel Croxon	addq $40, %rsp
72530d68baSNigel Croxon	ret
73530d68baSNigel Croxon
74530d68baSNigel CroxonENTRY(efi_call3)
75530d68baSNigel Croxon	subq $40, %rsp
76530d68baSNigel Croxon	mov  %rcx, %r8
77530d68baSNigel Croxon	/* mov %rdx, %rdx */
78530d68baSNigel Croxon	mov  %rsi, %rcx
79530d68baSNigel Croxon	call *%rdi
80530d68baSNigel Croxon	addq $40, %rsp
81530d68baSNigel Croxon	ret
82530d68baSNigel Croxon
83530d68baSNigel CroxonENTRY(efi_call4)
84530d68baSNigel Croxon	subq $40, %rsp
85530d68baSNigel Croxon	mov %r8, %r9
86530d68baSNigel Croxon	mov %rcx, %r8
87530d68baSNigel Croxon	/* mov %rdx, %rdx */
88530d68baSNigel Croxon	mov %rsi, %rcx
89530d68baSNigel Croxon	call *%rdi
90530d68baSNigel Croxon	addq $40, %rsp
91530d68baSNigel Croxon	ret
92530d68baSNigel Croxon
93530d68baSNigel CroxonENTRY(efi_call5)
94530d68baSNigel Croxon	subq $40, %rsp
95530d68baSNigel Croxon	mov %r9, 32(%rsp)
96530d68baSNigel Croxon	mov %r8, %r9
97530d68baSNigel Croxon	mov %rcx, %r8
98530d68baSNigel Croxon	/* mov %rdx, %rdx */
99530d68baSNigel Croxon	mov %rsi, %rcx
100530d68baSNigel Croxon	call *%rdi
101530d68baSNigel Croxon	addq $40, %rsp
102530d68baSNigel Croxon	ret
103530d68baSNigel Croxon
104530d68baSNigel CroxonENTRY(efi_call6)
105530d68baSNigel Croxon	subq $56, %rsp
106530d68baSNigel Croxon	mov 56+8(%rsp), %rax
107530d68baSNigel Croxon	mov %rax, 40(%rsp)
108530d68baSNigel Croxon	mov %r9, 32(%rsp)
109530d68baSNigel Croxon	mov %r8, %r9
110530d68baSNigel Croxon	mov %rcx, %r8
111530d68baSNigel Croxon	/* mov %rdx, %rdx */
112530d68baSNigel Croxon	mov %rsi, %rcx
113530d68baSNigel Croxon	call *%rdi
114530d68baSNigel Croxon	addq $56, %rsp
115530d68baSNigel Croxon	ret
116530d68baSNigel Croxon
117530d68baSNigel CroxonENTRY(efi_call7)
118530d68baSNigel Croxon	subq $56, %rsp
119530d68baSNigel Croxon	mov 56+16(%rsp), %rax
120530d68baSNigel Croxon	mov %rax, 48(%rsp)
121530d68baSNigel Croxon	mov 56+8(%rsp), %rax
122530d68baSNigel Croxon	mov %rax, 40(%rsp)
123530d68baSNigel Croxon	mov %r9, 32(%rsp)
124530d68baSNigel Croxon	mov %r8, %r9
125530d68baSNigel Croxon	mov %rcx, %r8
126530d68baSNigel Croxon	/* mov %rdx, %rdx */
127530d68baSNigel Croxon	mov %rsi, %rcx
128530d68baSNigel Croxon	call *%rdi
129530d68baSNigel Croxon	addq $56, %rsp
130530d68baSNigel Croxon	ret
131530d68baSNigel Croxon
132530d68baSNigel CroxonENTRY(efi_call8)
133530d68baSNigel Croxon	subq $72, %rsp
134530d68baSNigel Croxon	mov 72+24(%rsp), %rax
135530d68baSNigel Croxon	mov %rax, 56(%rsp)
136530d68baSNigel Croxon	mov 72+16(%rsp), %rax
137530d68baSNigel Croxon	mov %rax, 48(%rsp)
138530d68baSNigel Croxon	mov 72+8(%rsp), %rax
139530d68baSNigel Croxon	mov %rax, 40(%rsp)
140530d68baSNigel Croxon	mov %r9, 32(%rsp)
141530d68baSNigel Croxon	mov %r8, %r9
142530d68baSNigel Croxon	mov %rcx, %r8
143530d68baSNigel Croxon	/* mov %rdx, %rdx */
144530d68baSNigel Croxon	mov %rsi, %rcx
145530d68baSNigel Croxon	call *%rdi
146530d68baSNigel Croxon	addq $72, %rsp
147530d68baSNigel Croxon	ret
148530d68baSNigel Croxon
149530d68baSNigel CroxonENTRY(efi_call9)
150530d68baSNigel Croxon	subq $72, %rsp
151530d68baSNigel Croxon	mov 72+32(%rsp), %rax
152530d68baSNigel Croxon	mov %rax, 64(%rsp)
153530d68baSNigel Croxon	mov 72+24(%rsp), %rax
154530d68baSNigel Croxon	mov %rax, 56(%rsp)
155530d68baSNigel Croxon	mov 72+16(%rsp), %rax
156530d68baSNigel Croxon	mov %rax, 48(%rsp)
157530d68baSNigel Croxon	mov 72+8(%rsp), %rax
158530d68baSNigel Croxon	mov %rax, 40(%rsp)
159530d68baSNigel Croxon	mov %r9, 32(%rsp)
160530d68baSNigel Croxon	mov %r8, %r9
161530d68baSNigel Croxon	mov %rcx, %r8
162530d68baSNigel Croxon	/* mov %rdx, %rdx */
163530d68baSNigel Croxon	mov %rsi, %rcx
164530d68baSNigel Croxon	call *%rdi
165530d68baSNigel Croxon	addq $72, %rsp
166530d68baSNigel Croxon	ret
167530d68baSNigel Croxon
168530d68baSNigel CroxonENTRY(efi_call10)
169530d68baSNigel Croxon	subq $88, %rsp
170530d68baSNigel Croxon	mov 88+40(%rsp), %rax
171530d68baSNigel Croxon	mov %rax, 72(%rsp)
172530d68baSNigel Croxon	mov 88+32(%rsp), %rax
173530d68baSNigel Croxon	mov %rax, 64(%rsp)
174530d68baSNigel Croxon	mov 88+24(%rsp), %rax
175530d68baSNigel Croxon	mov %rax, 56(%rsp)
176530d68baSNigel Croxon	mov 88+16(%rsp), %rax
177530d68baSNigel Croxon	mov %rax, 48(%rsp)
178530d68baSNigel Croxon	mov 88+8(%rsp), %rax
179530d68baSNigel Croxon	mov %rax, 40(%rsp)
180530d68baSNigel Croxon	mov %r9, 32(%rsp)
181530d68baSNigel Croxon	mov %r8, %r9
182530d68baSNigel Croxon	mov %rcx, %r8
183530d68baSNigel Croxon	/* mov %rdx, %rdx */
184530d68baSNigel Croxon	mov %rsi, %rcx
185530d68baSNigel Croxon	call *%rdi
186530d68baSNigel Croxon	addq $88, %rsp
187530d68baSNigel Croxon	ret
188530d68baSNigel Croxon
189530d68baSNigel Croxon#endif
190*803b49c4SSergei Trofimovich
191*803b49c4SSergei Trofimovich#if defined(__ELF__) && defined(__linux__)
192*803b49c4SSergei Trofimovich	.section .note.GNU-stack,"",%progbits
193*803b49c4SSergei Trofimovich#endif
194