WIP FPC-III support
[linux/fpc-iii.git] / arch / x86 / platform / efi / efi_thunk_64.S
blob26f0da238c1ca8d7c09626e7f77547056227185d
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2014 Intel Corporation; author Matt Fleming
4  *
5  * Support for invoking 32-bit EFI runtime services from a 64-bit
6  * kernel.
7  *
8  * The below thunking functions are only used after ExitBootServices()
9  * has been called. This simplifies things considerably as compared with
10  * the early EFI thunking because we can leave all the kernel state
11  * intact (GDT, IDT, etc) and simply invoke the the 32-bit EFI runtime
12  * services from __KERNEL32_CS. This means we can continue to service
13  * interrupts across an EFI mixed mode call.
14  *
15  * We do however, need to handle the fact that we're running in a full
16  * 64-bit virtual address space. Things like the stack and instruction
17  * addresses need to be accessible by the 32-bit firmware, so we rely on
18  * using the identity mappings in the EFI page table to access the stack
19  * and kernel text (see efi_setup_page_tables()).
20  */
22 #include <linux/linkage.h>
23 #include <asm/page_types.h>
24 #include <asm/segment.h>
26         .text
27         .code64
28 SYM_CODE_START(__efi64_thunk)
29         push    %rbp
30         push    %rbx
32         /*
33          * Switch to 1:1 mapped 32-bit stack pointer.
34          */
35         movq    %rsp, %rax
36         movq    efi_scratch(%rip), %rsp
37         push    %rax
39         /*
40          * Calculate the physical address of the kernel text.
41          */
42         movq    $__START_KERNEL_map, %rax
43         subq    phys_base(%rip), %rax
45         leaq    1f(%rip), %rbp
46         leaq    2f(%rip), %rbx
47         subq    %rax, %rbp
48         subq    %rax, %rbx
50         subq    $28, %rsp
51         movl    %ebx, 0x0(%rsp)         /* return address */
52         movl    %esi, 0x4(%rsp)
53         movl    %edx, 0x8(%rsp)
54         movl    %ecx, 0xc(%rsp)
55         movl    %r8d, 0x10(%rsp)
56         movl    %r9d, 0x14(%rsp)
58         /* Switch to 32-bit descriptor */
59         pushq   $__KERNEL32_CS
60         pushq   %rdi                    /* EFI runtime service address */
61         lretq
63 1:      movq    24(%rsp), %rsp
64         pop     %rbx
65         pop     %rbp
66         retq
68         .code32
69 2:      pushl   $__KERNEL_CS
70         pushl   %ebp
71         lret
72 SYM_CODE_END(__efi64_thunk)