mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
1.8 KiB
76 lines
1.8 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
/* |
|
* Copyright (C) 2014 Intel Corporation; author Matt Fleming |
|
* |
|
* Support for invoking 32-bit EFI runtime services from a 64-bit |
|
* kernel. |
|
* |
|
* The below thunking functions are only used after ExitBootServices() |
|
* has been called. This simplifies things considerably as compared with |
|
* the early EFI thunking because we can leave all the kernel state |
|
* intact (GDT, IDT, etc) and simply invoke the the 32-bit EFI runtime |
|
* services from __KERNEL32_CS. This means we can continue to service |
|
* interrupts across an EFI mixed mode call. |
|
* |
|
* We do however, need to handle the fact that we're running in a full |
|
* 64-bit virtual address space. Things like the stack and instruction |
|
* addresses need to be accessible by the 32-bit firmware, so we rely on |
|
* using the identity mappings in the EFI page table to access the stack |
|
* and kernel text (see efi_setup_page_tables()). |
|
*/ |
|
|
|
#include <linux/linkage.h> |
|
#include <asm/page_types.h> |
|
#include <asm/segment.h> |
|
|
|
.text |
|
.code64 |
|
SYM_CODE_START(__efi64_thunk) |
|
push %rbp |
|
push %rbx |
|
|
|
/* |
|
* Switch to 1:1 mapped 32-bit stack pointer. |
|
*/ |
|
movq %rsp, %rax |
|
movq efi_mixed_mode_stack_pa(%rip), %rsp |
|
push %rax |
|
|
|
/* |
|
* Calculate the physical address of the kernel text. |
|
*/ |
|
movq $__START_KERNEL_map, %rax |
|
subq phys_base(%rip), %rax |
|
|
|
leaq 1f(%rip), %rbp |
|
leaq 2f(%rip), %rbx |
|
subq %rax, %rbp |
|
subq %rax, %rbx |
|
|
|
subq $28, %rsp |
|
movl %ebx, 0x0(%rsp) /* return address */ |
|
movl %esi, 0x4(%rsp) |
|
movl %edx, 0x8(%rsp) |
|
movl %ecx, 0xc(%rsp) |
|
movl %r8d, 0x10(%rsp) |
|
movl %r9d, 0x14(%rsp) |
|
|
|
/* Switch to 32-bit descriptor */ |
|
pushq $__KERNEL32_CS |
|
pushq %rdi /* EFI runtime service address */ |
|
lretq |
|
|
|
1: movq 24(%rsp), %rsp |
|
pop %rbx |
|
pop %rbp |
|
retq |
|
|
|
.code32 |
|
2: pushl $__KERNEL_CS |
|
pushl %ebp |
|
lret |
|
SYM_CODE_END(__efi64_thunk) |
|
|
|
.bss |
|
.balign 8 |
|
SYM_DATA(efi_mixed_mode_stack_pa, .quad 0)
|
|
|