Merge tag 'pci-v3.15-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaa...
[deliverable/linux.git] / arch / x86 / platform / efi / efi_stub_64.S
CommitLineData
5b83683f
HY
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>
0154416a
MF
10#include <asm/segment.h>
11#include <asm/msr.h>
12#include <asm/processor-flags.h>
13#include <asm/page_types.h>
5b83683f
HY
14
15#define SAVE_XMM \
16 mov %rsp, %rax; \
17 subq $0x70, %rsp; \
18 and $~0xf, %rsp; \
19 mov %rax, (%rsp); \
20 mov %cr0, %rax; \
21 clts; \
22 mov %rax, 0x8(%rsp); \
23 movaps %xmm0, 0x60(%rsp); \
24 movaps %xmm1, 0x50(%rsp); \
25 movaps %xmm2, 0x40(%rsp); \
26 movaps %xmm3, 0x30(%rsp); \
27 movaps %xmm4, 0x20(%rsp); \
28 movaps %xmm5, 0x10(%rsp)
29
30#define RESTORE_XMM \
31 movaps 0x60(%rsp), %xmm0; \
32 movaps 0x50(%rsp), %xmm1; \
33 movaps 0x40(%rsp), %xmm2; \
34 movaps 0x30(%rsp), %xmm3; \
35 movaps 0x20(%rsp), %xmm4; \
36 movaps 0x10(%rsp), %xmm5; \
37 mov 0x8(%rsp), %rsi; \
38 mov %rsi, %cr0; \
39 mov (%rsp), %rsp
40
d2f7cbe7
BP
41 /* stolen from gcc */
42 .macro FLUSH_TLB_ALL
43 movq %r15, efi_scratch(%rip)
44 movq %r14, efi_scratch+8(%rip)
45 movq %cr4, %r15
46 movq %r15, %r14
47 andb $0x7f, %r14b
48 movq %r14, %cr4
49 movq %r15, %cr4
50 movq efi_scratch+8(%rip), %r14
51 movq efi_scratch(%rip), %r15
52 .endm
53
54 .macro SWITCH_PGT
55 cmpb $0, efi_scratch+24(%rip)
56 je 1f
57 movq %r15, efi_scratch(%rip) # r15
58 # save previous CR3
59 movq %cr3, %r15
60 movq %r15, efi_scratch+8(%rip) # prev_cr3
61 movq efi_scratch+16(%rip), %r15 # EFI pgt
62 movq %r15, %cr3
63 1:
64 .endm
65
66 .macro RESTORE_PGT
67 cmpb $0, efi_scratch+24(%rip)
68 je 2f
69 movq efi_scratch+8(%rip), %r15
70 movq %r15, %cr3
71 movq efi_scratch(%rip), %r15
72 FLUSH_TLB_ALL
73 2:
74 .endm
75
5b83683f
HY
76ENTRY(efi_call0)
77 SAVE_XMM
78 subq $32, %rsp
d2f7cbe7 79 SWITCH_PGT
5b83683f 80 call *%rdi
d2f7cbe7 81 RESTORE_PGT
5b83683f
HY
82 addq $32, %rsp
83 RESTORE_XMM
84 ret
9f331119 85ENDPROC(efi_call0)
5b83683f
HY
86
87ENTRY(efi_call1)
88 SAVE_XMM
89 subq $32, %rsp
90 mov %rsi, %rcx
d2f7cbe7 91 SWITCH_PGT
5b83683f 92 call *%rdi
d2f7cbe7 93 RESTORE_PGT
5b83683f
HY
94 addq $32, %rsp
95 RESTORE_XMM
96 ret
9f331119 97ENDPROC(efi_call1)
5b83683f
HY
98
99ENTRY(efi_call2)
100 SAVE_XMM
101 subq $32, %rsp
102 mov %rsi, %rcx
d2f7cbe7 103 SWITCH_PGT
5b83683f 104 call *%rdi
d2f7cbe7 105 RESTORE_PGT
5b83683f
HY
106 addq $32, %rsp
107 RESTORE_XMM
108 ret
9f331119 109ENDPROC(efi_call2)
5b83683f
HY
110
111ENTRY(efi_call3)
112 SAVE_XMM
113 subq $32, %rsp
114 mov %rcx, %r8
115 mov %rsi, %rcx
d2f7cbe7 116 SWITCH_PGT
5b83683f 117 call *%rdi
d2f7cbe7 118 RESTORE_PGT
5b83683f
HY
119 addq $32, %rsp
120 RESTORE_XMM
121 ret
9f331119 122ENDPROC(efi_call3)
5b83683f
HY
123
124ENTRY(efi_call4)
125 SAVE_XMM
126 subq $32, %rsp
127 mov %r8, %r9
128 mov %rcx, %r8
129 mov %rsi, %rcx
d2f7cbe7 130 SWITCH_PGT
5b83683f 131 call *%rdi
d2f7cbe7 132 RESTORE_PGT
5b83683f
HY
133 addq $32, %rsp
134 RESTORE_XMM
135 ret
9f331119 136ENDPROC(efi_call4)
5b83683f
HY
137
138ENTRY(efi_call5)
139 SAVE_XMM
140 subq $48, %rsp
141 mov %r9, 32(%rsp)
142 mov %r8, %r9
143 mov %rcx, %r8
144 mov %rsi, %rcx
d2f7cbe7 145 SWITCH_PGT
5b83683f 146 call *%rdi
d2f7cbe7 147 RESTORE_PGT
5b83683f
HY
148 addq $48, %rsp
149 RESTORE_XMM
150 ret
9f331119 151ENDPROC(efi_call5)
5b83683f
HY
152
153ENTRY(efi_call6)
154 SAVE_XMM
155 mov (%rsp), %rax
156 mov 8(%rax), %rax
157 subq $48, %rsp
158 mov %r9, 32(%rsp)
159 mov %rax, 40(%rsp)
160 mov %r8, %r9
161 mov %rcx, %r8
162 mov %rsi, %rcx
d2f7cbe7 163 SWITCH_PGT
5b83683f 164 call *%rdi
d2f7cbe7 165 RESTORE_PGT
5b83683f
HY
166 addq $48, %rsp
167 RESTORE_XMM
168 ret
9f331119 169ENDPROC(efi_call6)
d2f7cbe7 170
0154416a
MF
171#ifdef CONFIG_EFI_MIXED
172
173/*
174 * We run this function from the 1:1 mapping.
175 *
176 * This function must be invoked with a 1:1 mapped stack.
177 */
178ENTRY(__efi64_thunk)
e10848a2
MF
179 movl %ds, %eax
180 push %rax
181 movl %es, %eax
182 push %rax
183 movl %ss, %eax
184 push %rax
185
0154416a
MF
186 subq $32, %rsp
187 movl %esi, 0x0(%rsp)
188 movl %edx, 0x4(%rsp)
189 movl %ecx, 0x8(%rsp)
190 movq %r8, %rsi
191 movl %esi, 0xc(%rsp)
192 movq %r9, %rsi
193 movl %esi, 0x10(%rsp)
194
195 sgdt save_gdt(%rip)
196
197 leaq 1f(%rip), %rbx
198 movq %rbx, func_rt_ptr(%rip)
199
200 /* Switch to gdt with 32-bit segments */
e10848a2 201 movl 64(%rsp), %eax
0154416a
MF
202 lgdt (%rax)
203
204 leaq efi_enter32(%rip), %rax
205 pushq $__KERNEL_CS
206 pushq %rax
207 lretq
208
2091: addq $32, %rsp
210
211 lgdt save_gdt(%rip)
212
e10848a2
MF
213 pop %rbx
214 movl %ebx, %ss
215 pop %rbx
216 movl %ebx, %es
217 pop %rbx
218 movl %ebx, %ds
219
0154416a
MF
220 /*
221 * Convert 32-bit status code into 64-bit.
222 */
223 test %rax, %rax
224 jz 1f
225 movl %eax, %ecx
226 andl $0x0fffffff, %ecx
227 andl $0xf0000000, %eax
228 shl $32, %rax
229 or %rcx, %rax
2301:
231 ret
232ENDPROC(__efi64_thunk)
233
234ENTRY(efi_exit32)
0154416a
MF
235 movq func_rt_ptr(%rip), %rax
236 push %rax
237 mov %rdi, %rax
238 ret
239ENDPROC(efi_exit32)
240
241 .code32
242/*
243 * EFI service pointer must be in %edi.
244 *
245 * The stack should represent the 32-bit calling convention.
246 */
247ENTRY(efi_enter32)
248 movl $__KERNEL_DS, %eax
249 movl %eax, %ds
250 movl %eax, %es
251 movl %eax, %ss
252
253 /* Reload pgtables */
254 movl %cr3, %eax
255 movl %eax, %cr3
256
257 /* Disable paging */
258 movl %cr0, %eax
259 btrl $X86_CR0_PG_BIT, %eax
260 movl %eax, %cr0
261
262 /* Disable long mode via EFER */
263 movl $MSR_EFER, %ecx
264 rdmsr
265 btrl $_EFER_LME, %eax
266 wrmsr
267
268 call *%edi
269
270 /* We must preserve return value */
271 movl %eax, %edi
272
18c46461
MF
273 /*
274 * Some firmware will return with interrupts enabled. Be sure to
275 * disable them before we switch GDTs.
276 */
277 cli
278
e10848a2 279 movl 68(%esp), %eax
0154416a
MF
280 movl %eax, 2(%eax)
281 lgdtl (%eax)
282
283 movl %cr4, %eax
284 btsl $(X86_CR4_PAE_BIT), %eax
285 movl %eax, %cr4
286
287 movl %cr3, %eax
288 movl %eax, %cr3
289
290 movl $MSR_EFER, %ecx
291 rdmsr
292 btsl $_EFER_LME, %eax
293 wrmsr
294
295 xorl %eax, %eax
296 lldt %ax
297
e10848a2 298 movl 72(%esp), %eax
0154416a
MF
299 pushl $__KERNEL_CS
300 pushl %eax
301
302 /* Enable paging */
303 movl %cr0, %eax
304 btsl $X86_CR0_PG_BIT, %eax
305 movl %eax, %cr0
306 lret
307ENDPROC(efi_enter32)
308
309 .data
310 .balign 8
311 .global efi32_boot_gdt
312efi32_boot_gdt: .word 0
313 .quad 0
314
315save_gdt: .word 0
316 .quad 0
317func_rt_ptr: .quad 0
318
319 .global efi_gdt64
320efi_gdt64:
321 .word efi_gdt64_end - efi_gdt64
322 .long 0 /* Filled out by user */
323 .word 0
324 .quad 0x0000000000000000 /* NULL descriptor */
325 .quad 0x00af9a000000ffff /* __KERNEL_CS */
326 .quad 0x00cf92000000ffff /* __KERNEL_DS */
327 .quad 0x0080890000000000 /* TS descriptor */
328 .quad 0x0000000000000000 /* TS continued */
329efi_gdt64_end:
330#endif /* CONFIG_EFI_MIXED */
331
d2f7cbe7
BP
332 .data
333ENTRY(efi_scratch)
334 .fill 3,8,0
335 .byte 0
4f9dbcfc 336 .quad 0
This page took 0.435182 seconds and 5 git commands to generate.