[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <8bc0a2a5-a486-4a4d-83e6-45b6c00685ea@amd.com>
Date: Mon, 7 Apr 2025 15:11:32 +0530
From: "Aithal, Srikanth" <sraithal@....com>
To: Ard Biesheuvel <ardb@...nel.org>
Cc: linux-kernel@...r.kernel.org, Ingo Molnar <mingo@...nel.org>,
David Woodhouse <dwmw@...zon.co.uk>, "H. Peter Anvin" <hpa@...or.com>,
Kees Cook <keescook@...omium.org>, x86@...nel.org
Subject: Re: [tip: x86/boot] x86/boot: Move the EFI mixed mode startup code
back under arch/x86, into startup/
On 4/7/2025 2:00 PM, Ard Biesheuvel wrote:
> On Mon, 7 Apr 2025 at 10:38, Aithal, Srikanth <sraithal@....com> wrote:
>>
>> Hello,
>>
>> This commit breaks the build of next-20250407. The kernel config is
>> attached here.
>>
>> Build error:
>>
>> arch/x86/boot/startup/efi-mixed.o: warning: objtool:
>> efi32_stub_entry+0x0: unannotated intra-function call
>> make[3]: *** [scripts/Makefile.build:335:
>> arch/x86/boot/startup/efi-mixed.o] Error 255
>> make[3]: *** Deleting file 'arch/x86/boot/startup/efi-mixed.o'
>> make[3]: *** Waiting for unfinished jobs....
>> make[2]: *** [scripts/Makefile.build:461: arch/x86/boot/startup] Error 2
>> make[2]: *** Waiting for unfinished jobs....
>> make[1]: *** [/home/VT_BUILD/linux/Makefile:2006: .] Error 2
>> make: *** [Makefile:248: __sub-make] Error 2
>>
>>
>
> Apologies for the breakage.
>
> Does it help to add the following to arch/x86/boot/startup/Makefile:
>
> OBJECT_FILES_NON_STANDARD := y
>
> ?
yes, this fixes the issue.
Reported-by: Srikanth Aithal <sraithal@....com>
Tested-by: Srikanth Aithal <sraithal@....com>
>
>>
>> Thanks,
>> Srikanth Aithal <sraithal@....com>
>>
>>
>> On 4/7/2025 12:03 AM, tip-bot2 for Ard Biesheuvel wrote:
>>> The following commit has been merged into the x86/boot branch of tip:
>>>
>>> Commit-ID: 4f2d1bbc2c92a32fd612e6c3b51832d5c1c3678e
>>> Gitweb: https://git.kernel.org/tip/4f2d1bbc2c92a32fd612e6c3b51832d5c1c3678e
>>> Author: Ard Biesheuvel <ardb@...nel.org>
>>> AuthorDate: Tue, 01 Apr 2025 15:34:20 +02:00
>>> Committer: Ingo Molnar <mingo@...nel.org>
>>> CommitterDate: Sun, 06 Apr 2025 20:15:14 +02:00
>>>
>>> x86/boot: Move the EFI mixed mode startup code back under arch/x86, into startup/
>>>
>>> Linus expressed a strong preference for arch-specific asm code (i.e.,
>>> virtually all of it) to reside under arch/ rather than anywhere else.
>>>
>>> So move the EFI mixed mode startup code back, and put it under
>>> arch/x86/boot/startup/ where all shared x86 startup code is going to
>>> live.
>>>
>>> Suggested-by: Linus Torvalds <torvalds@...ux-foundation.org>
>>> Signed-off-by: Ard Biesheuvel <ardb@...nel.org>
>>> Signed-off-by: Ingo Molnar <mingo@...nel.org>
>>> Cc: David Woodhouse <dwmw@...zon.co.uk>
>>> Cc: H. Peter Anvin <hpa@...or.com>
>>> Cc: Kees Cook <keescook@...omium.org>
>>> Link: https://lore.kernel.org/r/20250401133416.1436741-11-ardb+git@google.com
>>> ---
>>> arch/x86/boot/startup/Makefile | 3 +-
>>> arch/x86/boot/startup/efi-mixed.S | 253 ++++++++++++++++++++++-
>>> drivers/firmware/efi/libstub/Makefile | 1 +-
>>> drivers/firmware/efi/libstub/x86-mixed.S | 253 +----------------------
>>> 4 files changed, 256 insertions(+), 254 deletions(-)
>>> create mode 100644 arch/x86/boot/startup/efi-mixed.S
>>> delete mode 100644 drivers/firmware/efi/libstub/x86-mixed.S
>>>
>>> diff --git a/arch/x86/boot/startup/Makefile b/arch/x86/boot/startup/Makefile
>>> index 03519ef..73946a3 100644
>>> --- a/arch/x86/boot/startup/Makefile
>>> +++ b/arch/x86/boot/startup/Makefile
>>> @@ -1,3 +1,6 @@
>>> # SPDX-License-Identifier: GPL-2.0
>>>
>>> +KBUILD_AFLAGS += -D__DISABLE_EXPORTS
>>> +
>>> lib-$(CONFIG_X86_64) += la57toggle.o
>>> +lib-$(CONFIG_EFI_MIXED) += efi-mixed.o
>>> diff --git a/arch/x86/boot/startup/efi-mixed.S b/arch/x86/boot/startup/efi-mixed.S
>>> new file mode 100644
>>> index 0000000..e04ed99
>>> --- /dev/null
>>> +++ b/arch/x86/boot/startup/efi-mixed.S
>>> @@ -0,0 +1,253 @@
>>> +/* 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.
>>> + */
>>> +
>>> +#include <linux/linkage.h>
>>> +#include <asm/desc_defs.h>
>>> +#include <asm/msr.h>
>>> +#include <asm/page_types.h>
>>> +#include <asm/pgtable_types.h>
>>> +#include <asm/processor-flags.h>
>>> +#include <asm/segment.h>
>>> +
>>> + .text
>>> + .code32
>>> +#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> +SYM_FUNC_START(efi32_stub_entry)
>>> + call 1f
>>> +1: popl %ecx
>>> +
>>> + /* Clear BSS */
>>> + xorl %eax, %eax
>>> + leal (_bss - 1b)(%ecx), %edi
>>> + leal (_ebss - 1b)(%ecx), %ecx
>>> + subl %edi, %ecx
>>> + shrl $2, %ecx
>>> + cld
>>> + rep stosl
>>> +
>>> + add $0x4, %esp /* Discard return address */
>>> + movl 8(%esp), %ebx /* struct boot_params pointer */
>>> + jmp efi32_startup
>>> +SYM_FUNC_END(efi32_stub_entry)
>>> +#endif
>>> +
>>> +/*
>>> + * 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
>>> +
>>> + /* Disable paging */
>>> + movl %cr0, %eax
>>> + btrl $X86_CR0_PG_BIT, %eax
>>> + movl %eax, %cr0
>>> +
>>> + /* Disable long mode via EFER */
>>> + movl $MSR_EFER, %ecx
>>> + rdmsr
>>> + btrl $_EFER_LME, %eax
>>> + wrmsr
>>> +
>>> + call *%edi
>>> +
>>> + /* We must preserve return value */
>>> + movl %eax, %edi
>>> +
>>> + call efi32_enable_long_mode
>>> +
>>> + addl $32, %esp
>>> + movl %edi, %eax
>>> + lret
>>> +SYM_FUNC_END(efi_enter32)
>>> +
>>> + .code64
>>> +SYM_FUNC_START(__efi64_thunk)
>>> + push %rbp
>>> + movl %esp, %ebp
>>> + push %rbx
>>> +
>>> + /* Move args #5 and #6 into 32-bit accessible registers */
>>> + movl %r8d, %eax
>>> + movl %r9d, %ebx
>>> +
>>> + lcalll *efi32_call(%rip)
>>> +
>>> + pop %rbx
>>> + pop %rbp
>>> + RET
>>> +SYM_FUNC_END(__efi64_thunk)
>>> +
>>> + .code32
>>> +SYM_FUNC_START_LOCAL(efi32_enable_long_mode)
>>> + movl %cr4, %eax
>>> + btsl $(X86_CR4_PAE_BIT), %eax
>>> + movl %eax, %cr4
>>> +
>>> + movl $MSR_EFER, %ecx
>>> + rdmsr
>>> + btsl $_EFER_LME, %eax
>>> + wrmsr
>>> +
>>> + /* Disable interrupts - the firmware's IDT does not work in long mode */
>>> + cli
>>> +
>>> + /* Enable paging */
>>> + movl %cr0, %eax
>>> + btsl $X86_CR0_PG_BIT, %eax
>>> + movl %eax, %cr0
>>> + ret
>>> +SYM_FUNC_END(efi32_enable_long_mode)
>>> +
>>> +/*
>>> + * 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 */
>>> +
>>> + call 1f
>>> +1: pop %edi
>>> +
>>> + /* Record mixed mode entry */
>>> + movb $0x0, (efi_is64 - 1b)(%edi)
>>> +
>>> + /* Set up indirect far call to re-enter 32-bit mode */
>>> + leal (efi32_call - 1b)(%edi), %eax
>>> + addl %eax, (%eax)
>>> + movw %cs, 4(%eax)
>>> +
>>> + /* Disable paging */
>>> + movl %cr0, %eax
>>> + btrl $X86_CR0_PG_BIT, %eax
>>> + movl %eax, %cr0
>>> +
>>> + /* Set up 1:1 mapping */
>>> + leal (pte - 1b)(%edi), %eax
>>> + movl $_PAGE_PRESENT | _PAGE_RW | _PAGE_PSE, %ecx
>>> + leal (_PAGE_PRESENT | _PAGE_RW)(%eax), %edx
>>> +2: movl %ecx, (%eax)
>>> + addl $8, %eax
>>> + addl $PMD_SIZE, %ecx
>>> + jnc 2b
>>> +
>>> + movl $PAGE_SIZE, %ecx
>>> + .irpc l, 0123
>>> + movl %edx, \l * 8(%eax)
>>> + addl %ecx, %edx
>>> + .endr
>>> + addl %ecx, %eax
>>> + movl %edx, (%eax)
>>> + movl %eax, %cr3
>>> +
>>> + call efi32_enable_long_mode
>>> +
>>> + /* Set up far jump to 64-bit mode (CS is already on the stack) */
>>> + leal (efi_stub_entry - 1b)(%edi), %eax
>>> + movl %eax, 2(%esp)
>>> +
>>> + movl 0(%ebp), %edi
>>> + movl 4(%ebp), %esi
>>> + movl %ebx, %edx
>>> + ljmpl *2(%esp)
>>> +SYM_FUNC_END(efi32_startup)
>>> +
>>> +/*
>>> + * efi_status_t efi32_pe_entry(efi_handle_t image_handle,
>>> + * efi_system_table_32_t *sys_table)
>>> + */
>>> +SYM_FUNC_START(efi32_pe_entry)
>>> + pushl %ebx // save callee-save registers
>>> +
>>> + /* Check whether the CPU supports long mode */
>>> + movl $0x80000001, %eax // assume extended info support
>>> + cpuid
>>> + btl $29, %edx // check long mode bit
>>> + jnc 1f
>>> + leal 8(%esp), %esp // preserve stack alignment
>>> + xor %ebx, %ebx // no struct boot_params pointer
>>> + jmp efi32_startup // only ESP and EBX remain live
>>> +1: movl $0x80000003, %eax // EFI_UNSUPPORTED
>>> + popl %ebx
>>> + RET
>>> +SYM_FUNC_END(efi32_pe_entry)
>>> +
>>> +#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> + .org efi32_stub_entry + 0x200
>>> + .code64
>>> +SYM_FUNC_START_NOALIGN(efi64_stub_entry)
>>> + jmp efi_handover_entry
>>> +SYM_FUNC_END(efi64_stub_entry)
>>> +#endif
>>> +
>>> + .data
>>> + .balign 8
>>> +SYM_DATA_START_LOCAL(efi32_call)
>>> + .long efi_enter32 - .
>>> + .word 0x0
>>> +SYM_DATA_END(efi32_call)
>>> +SYM_DATA(efi_is64, .byte 1)
>>> +
>>> + .bss
>>> + .balign PAGE_SIZE
>>> +SYM_DATA_LOCAL(pte, .fill 6 * PAGE_SIZE, 1, 0)
>>> diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
>>> index d23a1b9..2f17339 100644
>>> --- a/drivers/firmware/efi/libstub/Makefile
>>> +++ b/drivers/firmware/efi/libstub/Makefile
>>> @@ -85,7 +85,6 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \
>>> lib-$(CONFIG_ARM) += arm32-stub.o
>>> lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o
>>> lib-$(CONFIG_X86) += x86-stub.o smbios.o
>>> -lib-$(CONFIG_EFI_MIXED) += x86-mixed.o
>>> lib-$(CONFIG_X86_64) += x86-5lvl.o
>>> lib-$(CONFIG_RISCV) += kaslr.o riscv.o riscv-stub.o
>>> lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o
>>> diff --git a/drivers/firmware/efi/libstub/x86-mixed.S b/drivers/firmware/efi/libstub/x86-mixed.S
>>> deleted file mode 100644
>>> index e04ed99..0000000
>>> --- a/drivers/firmware/efi/libstub/x86-mixed.S
>>> +++ /dev/null
>>> @@ -1,253 +0,0 @@
>>> -/* 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.
>>> - */
>>> -
>>> -#include <linux/linkage.h>
>>> -#include <asm/desc_defs.h>
>>> -#include <asm/msr.h>
>>> -#include <asm/page_types.h>
>>> -#include <asm/pgtable_types.h>
>>> -#include <asm/processor-flags.h>
>>> -#include <asm/segment.h>
>>> -
>>> - .text
>>> - .code32
>>> -#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> -SYM_FUNC_START(efi32_stub_entry)
>>> - call 1f
>>> -1: popl %ecx
>>> -
>>> - /* Clear BSS */
>>> - xorl %eax, %eax
>>> - leal (_bss - 1b)(%ecx), %edi
>>> - leal (_ebss - 1b)(%ecx), %ecx
>>> - subl %edi, %ecx
>>> - shrl $2, %ecx
>>> - cld
>>> - rep stosl
>>> -
>>> - add $0x4, %esp /* Discard return address */
>>> - movl 8(%esp), %ebx /* struct boot_params pointer */
>>> - jmp efi32_startup
>>> -SYM_FUNC_END(efi32_stub_entry)
>>> -#endif
>>> -
>>> -/*
>>> - * 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
>>> -
>>> - /* Disable paging */
>>> - movl %cr0, %eax
>>> - btrl $X86_CR0_PG_BIT, %eax
>>> - movl %eax, %cr0
>>> -
>>> - /* Disable long mode via EFER */
>>> - movl $MSR_EFER, %ecx
>>> - rdmsr
>>> - btrl $_EFER_LME, %eax
>>> - wrmsr
>>> -
>>> - call *%edi
>>> -
>>> - /* We must preserve return value */
>>> - movl %eax, %edi
>>> -
>>> - call efi32_enable_long_mode
>>> -
>>> - addl $32, %esp
>>> - movl %edi, %eax
>>> - lret
>>> -SYM_FUNC_END(efi_enter32)
>>> -
>>> - .code64
>>> -SYM_FUNC_START(__efi64_thunk)
>>> - push %rbp
>>> - movl %esp, %ebp
>>> - push %rbx
>>> -
>>> - /* Move args #5 and #6 into 32-bit accessible registers */
>>> - movl %r8d, %eax
>>> - movl %r9d, %ebx
>>> -
>>> - lcalll *efi32_call(%rip)
>>> -
>>> - pop %rbx
>>> - pop %rbp
>>> - RET
>>> -SYM_FUNC_END(__efi64_thunk)
>>> -
>>> - .code32
>>> -SYM_FUNC_START_LOCAL(efi32_enable_long_mode)
>>> - movl %cr4, %eax
>>> - btsl $(X86_CR4_PAE_BIT), %eax
>>> - movl %eax, %cr4
>>> -
>>> - movl $MSR_EFER, %ecx
>>> - rdmsr
>>> - btsl $_EFER_LME, %eax
>>> - wrmsr
>>> -
>>> - /* Disable interrupts - the firmware's IDT does not work in long mode */
>>> - cli
>>> -
>>> - /* Enable paging */
>>> - movl %cr0, %eax
>>> - btsl $X86_CR0_PG_BIT, %eax
>>> - movl %eax, %cr0
>>> - ret
>>> -SYM_FUNC_END(efi32_enable_long_mode)
>>> -
>>> -/*
>>> - * 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 */
>>> -
>>> - call 1f
>>> -1: pop %edi
>>> -
>>> - /* Record mixed mode entry */
>>> - movb $0x0, (efi_is64 - 1b)(%edi)
>>> -
>>> - /* Set up indirect far call to re-enter 32-bit mode */
>>> - leal (efi32_call - 1b)(%edi), %eax
>>> - addl %eax, (%eax)
>>> - movw %cs, 4(%eax)
>>> -
>>> - /* Disable paging */
>>> - movl %cr0, %eax
>>> - btrl $X86_CR0_PG_BIT, %eax
>>> - movl %eax, %cr0
>>> -
>>> - /* Set up 1:1 mapping */
>>> - leal (pte - 1b)(%edi), %eax
>>> - movl $_PAGE_PRESENT | _PAGE_RW | _PAGE_PSE, %ecx
>>> - leal (_PAGE_PRESENT | _PAGE_RW)(%eax), %edx
>>> -2: movl %ecx, (%eax)
>>> - addl $8, %eax
>>> - addl $PMD_SIZE, %ecx
>>> - jnc 2b
>>> -
>>> - movl $PAGE_SIZE, %ecx
>>> - .irpc l, 0123
>>> - movl %edx, \l * 8(%eax)
>>> - addl %ecx, %edx
>>> - .endr
>>> - addl %ecx, %eax
>>> - movl %edx, (%eax)
>>> - movl %eax, %cr3
>>> -
>>> - call efi32_enable_long_mode
>>> -
>>> - /* Set up far jump to 64-bit mode (CS is already on the stack) */
>>> - leal (efi_stub_entry - 1b)(%edi), %eax
>>> - movl %eax, 2(%esp)
>>> -
>>> - movl 0(%ebp), %edi
>>> - movl 4(%ebp), %esi
>>> - movl %ebx, %edx
>>> - ljmpl *2(%esp)
>>> -SYM_FUNC_END(efi32_startup)
>>> -
>>> -/*
>>> - * efi_status_t efi32_pe_entry(efi_handle_t image_handle,
>>> - * efi_system_table_32_t *sys_table)
>>> - */
>>> -SYM_FUNC_START(efi32_pe_entry)
>>> - pushl %ebx // save callee-save registers
>>> -
>>> - /* Check whether the CPU supports long mode */
>>> - movl $0x80000001, %eax // assume extended info support
>>> - cpuid
>>> - btl $29, %edx // check long mode bit
>>> - jnc 1f
>>> - leal 8(%esp), %esp // preserve stack alignment
>>> - xor %ebx, %ebx // no struct boot_params pointer
>>> - jmp efi32_startup // only ESP and EBX remain live
>>> -1: movl $0x80000003, %eax // EFI_UNSUPPORTED
>>> - popl %ebx
>>> - RET
>>> -SYM_FUNC_END(efi32_pe_entry)
>>> -
>>> -#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
>>> - .org efi32_stub_entry + 0x200
>>> - .code64
>>> -SYM_FUNC_START_NOALIGN(efi64_stub_entry)
>>> - jmp efi_handover_entry
>>> -SYM_FUNC_END(efi64_stub_entry)
>>> -#endif
>>> -
>>> - .data
>>> - .balign 8
>>> -SYM_DATA_START_LOCAL(efi32_call)
>>> - .long efi_enter32 - .
>>> - .word 0x0
>>> -SYM_DATA_END(efi32_call)
>>> -SYM_DATA(efi_is64, .byte 1)
>>> -
>>> - .bss
>>> - .balign PAGE_SIZE
>>> -SYM_DATA_LOCAL(pte, .fill 6 * PAGE_SIZE, 1, 0)
Powered by blists - more mailing lists