/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming * * Early support for invoking 32-bit EFI services from a 64-bit kernel. * * Because this thunking occurs before ExitBootServices() we have to * restore the firmware's 32-bit GDT and IDT before we make EFI service * calls. * * On the plus side, we don't have to worry about mangling 64-bit * addresses into 32-bits because we're executing with an identity * mapped pagetable and haven't transitioned to 64-bit virtual addresses * yet.
*/
/* * Called using a far call from __efi64_thunk() below, using the x86_64 SysV * ABI (except for R8/R9 which are inaccessible to 32-bit code - EAX/EBX are * used instead). EBP+16 points to the arguments passed via the stack. * * The first argument (EDI) is a pointer to the boot service or protocol, to * which the remaining arguments are passed, each truncated to 32 bits.
*/
SYM_FUNC_START_LOCAL(efi_enter32) /* * Convert x86-64 SysV ABI params to i386 ABI
*/
pushl 32(%ebp) /* Up to 3 args passed via the stack */
pushl 24(%ebp)
pushl 16(%ebp)
pushl %ebx /* R9 */
pushl %eax /* R8 */
pushl %ecx
pushl %edx
pushl %esi
/* * This is the common EFI stub entry point for mixed mode. It sets up the GDT * and page tables needed for 64-bit execution, after which it calls the * common 64-bit EFI entrypoint efi_stub_entry(). * * Arguments: 0(%esp) image handle * 4(%esp) EFI system table pointer * %ebx struct boot_params pointer (or NULL) * * Since this is the point of no return for ordinary execution, no registers * are considered live except for the function parameters. [Note that the EFI * stub may still exit and return to the firmware using the Exit() EFI boot * service.]
*/
SYM_FUNC_START_LOCAL(efi32_startup)
movl %esp, %ebp
subl $8, %esp
sgdtl (%esp) /* Save GDT descriptor to the stack */
movl 2(%esp), %esi /* Existing GDT pointer */
movzwl (%esp), %ecx /* Existing GDT limit */
inc %ecx /* Existing GDT size */
andl $~7, %ecx /* Ensure size is multiple of 8 */
subl %ecx, %esp /* Allocate new GDT */
andl $~15, %esp /* Realign the stack */
movl %esp, %edi /* New GDT address */
leal 7(%ecx), %eax /* New GDT limit */
pushw %cx /* Push 64-bit CS (for LJMP below) */
pushl %edi /* Push new GDT address */
pushw %ax /* Push new GDT limit */
/* Copy GDT to the stack and add a 64-bit code segment at the end */
movl $GDT_ENTRY(DESC_CODE64, 0, 0xfffff) & 0xffffffff, (%edi,%ecx)
movl $GDT_ENTRY(DESC_CODE64, 0, 0xfffff) >> 32, 4(%edi,%ecx)
shrl $2, %ecx
cld
rep movsl /* Copy the firmware GDT */
lgdtl (%esp) /* Switch to the new GDT */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.