aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/compressed
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2014-01-10 10:37:17 -0500
committerMatt Fleming <matt.fleming@intel.com>2014-03-04 16:25:04 -0500
commit0154416a71c2a84c3746c8dd8ed25287e36934d3 (patch)
tree80251a960a808ee33b4822b5613b55ceec28c714 /arch/x86/boot/compressed
parent54b52d87268034859191d671505bb1cfce6bd74d (diff)
x86/efi: Add early thunk code to go from 64-bit to 32-bit
Implement the transition code to go from IA32e mode to protected mode in the EFI boot stub. This is required to use 32-bit EFI services from a 64-bit kernel. Since EFI boot stub is executed in an identity-mapped region, there's not much we need to do before invoking the 32-bit EFI boot services. However, we do reload the firmware's global descriptor table (efi32_boot_gdt) in case things like timer events are still running in the firmware. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'arch/x86/boot/compressed')
-rw-r--r--arch/x86/boot/compressed/efi_stub_64.S29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/x86/boot/compressed/efi_stub_64.S b/arch/x86/boot/compressed/efi_stub_64.S
index cedc60de86eb..7ff3632806b1 100644
--- a/arch/x86/boot/compressed/efi_stub_64.S
+++ b/arch/x86/boot/compressed/efi_stub_64.S
@@ -1 +1,30 @@
1#include <asm/segment.h>
2#include <asm/msr.h>
3#include <asm/processor-flags.h>
4
1#include "../../platform/efi/efi_stub_64.S" 5#include "../../platform/efi/efi_stub_64.S"
6
7#ifdef CONFIG_EFI_MIXED
8 .code64
9 .text
10ENTRY(efi64_thunk)
11 push %rbp
12 push %rbx
13
14 subq $16, %rsp
15 leaq efi_exit32(%rip), %rax
16 movl %eax, 8(%rsp)
17 leaq efi_gdt64(%rip), %rax
18 movl %eax, 4(%rsp)
19 movl %eax, 2(%rax) /* Fixup the gdt base address */
20 leaq efi32_boot_gdt(%rip), %rax
21 movl %eax, (%rsp)
22
23 call __efi64_thunk
24
25 addq $16, %rsp
26 pop %rbx
27 pop %rbp
28 ret
29ENDPROC(efi64_thunk)
30#endif /* CONFIG_EFI_MIXED */