diff options
author | Matt Fleming <matt.fleming@intel.com> | 2014-01-10 15:27:14 +0000 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2014-03-04 21:25:03 +0000 |
commit | 54b52d87268034859191d671505bb1cfce6bd74d (patch) | |
tree | 63c39b9a828e9d6dad97118cbd2e1e1210da6358 /arch/x86/boot/compressed/head_64.S | |
parent | 677703cef0a148ba07d37ced649ad25b1cda2f78 (diff) |
x86/efi: Build our own EFI services pointer table
It's not possible to dereference the EFI System table directly when
booting a 64-bit kernel on a 32-bit EFI firmware because the size of
pointers don't match.
In preparation for supporting the above use case, build a list of
function pointers on boot so that callers don't have to worry about
converting pointer sizes through multiple levels of indirection.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'arch/x86/boot/compressed/head_64.S')
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index c5c1ae0997e7..1bc206fa4bd0 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -209,26 +209,55 @@ ENTRY(startup_64) jmp preferred_addr ENTRY(efi_pe_entry) - mov %rcx, %rdi - mov %rdx, %rsi - pushq %rdi - pushq %rsi + movq %rcx, efi64_config(%rip) /* Handle */ + movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ + + leaq efi64_config(%rip), %rax + movq %rax, efi_config(%rip) + + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + addq %rbp, efi64_config+88(%rip) + + movq %rax, %rdi call make_boot_params cmpq $0,%rax - je 1f - mov %rax, %rdx - popq %rsi - popq %rdi + je fail + mov %rax, %rsi + jmp 2f /* Skip the relocation */ ENTRY(efi_stub_entry) + movq %rdi, efi64_config(%rip) /* Handle */ + movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */ + + leaq efi64_config(%rip), %rax + movq %rax, efi_config(%rip) + + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + movq efi_config(%rip), %rax + addq %rbp, 88(%rax) + movq %rdx, %rsi +2: + movq efi_config(%rip), %rdi call efi_main movq %rax,%rsi cmpq $0,%rax jne 2f -1: +fail: /* EFI init failed, so hang. */ hlt - jmp 1b + jmp fail 2: call 3f 3: @@ -372,6 +401,14 @@ gdt: .quad 0x0000000000000000 /* TS continued */ gdt_end: +efi_config: + .quad 0 + + .global efi64_config +efi64_config: + .fill 11,8,0 + .quad efi_call6 + .byte 1 /* * Stack and heap for uncompression */ |