/* SPDX-License-Identifier: GPL-2.0 */1/*2* Copyright (C) 2014 Intel Corporation; author Matt Fleming3*4* Support for invoking 32-bit EFI runtime services from a 64-bit5* kernel.6*7* The below thunking functions are only used after ExitBootServices()8* has been called. This simplifies things considerably as compared with9* the early EFI thunking because we can leave all the kernel state10* intact (GDT, IDT, etc) and simply invoke the 32-bit EFI runtime11* services from __KERNEL32_CS. This means we can continue to service12* interrupts across an EFI mixed mode call.13*14* We do however, need to handle the fact that we're running in a full15* 64-bit virtual address space. Things like the stack and instruction16* addresses need to be accessible by the 32-bit firmware, so we rely on17* using the identity mappings in the EFI page table to access the stack18* and kernel text (see efi_setup_page_tables()).19*/2021#include <linux/linkage.h>22#include <linux/objtool.h>23#include <asm/page_types.h>24#include <asm/segment.h>2526.text27.code6428SYM_FUNC_START(__efi64_thunk)29STACK_FRAME_NON_STANDARD __efi64_thunk30push %rbp31push %rbx3233/*34* Switch to 1:1 mapped 32-bit stack pointer.35*/36movq %rsp, %rax37movq efi_mixed_mode_stack_pa(%rip), %rsp38push %rax3940/*41* Copy args passed via the stack42*/43subq $0x24, %rsp44movq 0x18(%rax), %rbp45movq 0x20(%rax), %rbx46movq 0x28(%rax), %rax47movl %ebp, 0x18(%rsp)48movl %ebx, 0x1c(%rsp)49movl %eax, 0x20(%rsp)5051/*52* Calculate the physical address of the kernel text.53*/54movq $__START_KERNEL_map, %rax55subq phys_base(%rip), %rax5657leaq 1f(%rip), %rbp58leaq 2f(%rip), %rbx59subq %rax, %rbp60subq %rax, %rbx6162movl %ebx, 0x0(%rsp) /* return address */63movl %esi, 0x4(%rsp)64movl %edx, 0x8(%rsp)65movl %ecx, 0xc(%rsp)66movl %r8d, 0x10(%rsp)67movl %r9d, 0x14(%rsp)6869/* Switch to 32-bit descriptor */70pushq $__KERNEL32_CS71pushq %rdi /* EFI runtime service address */72lretq7374// This return instruction is not needed for correctness, as it will75// never be reached. It only exists to make objtool happy, which will76// otherwise complain about unreachable instructions in the callers.77RET78SYM_FUNC_END(__efi64_thunk)7980.section ".rodata", "a", @progbits81.balign 1682SYM_DATA_START(__efi64_thunk_ret_tramp)831: movq 0x20(%rsp), %rsp84pop %rbx85pop %rbp86ret87int38889.code32902: pushl $__KERNEL_CS91pushl %ebp92lret93SYM_DATA_END(__efi64_thunk_ret_tramp)9495.bss96.balign 897SYM_DATA(efi_mixed_mode_stack_pa, .quad 0)9899100