From: bbahnsen Date: Fri, 17 Nov 2006 19:49:28 +0000 (+0000) Subject: Start to port the LongMode stuff to gnu asm. X-Git-Tag: edk2-stable201903~23903 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=3219f9742bc96844dc8b4210f60d018e62664dcf;ds=sidebyside Start to port the LongMode stuff to gnu asm. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1974 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa b/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa index 40ea70b2e2..d6e1057785 100644 --- a/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa +++ b/EdkModulePkg/Core/DxeIplX64Peim/DxeIplX64.msa @@ -74,6 +74,7 @@ DxeLoadX64.c x64/ImageRead.c x64/LongMode.asm + x64/LongMode.S x64/DxeLoadFunc.c x64/VirtualMemory.h x64/VirtualMemory.c diff --git a/EdkModulePkg/Core/DxeIplX64Peim/x64/LongMode.S b/EdkModulePkg/Core/DxeIplX64Peim/x64/LongMode.S new file mode 100644 index 0000000000..273b3d5bc2 --- /dev/null +++ b/EdkModulePkg/Core/DxeIplX64Peim/x64/LongMode.S @@ -0,0 +1,296 @@ +#------------------------------------------------------------------------------ +#* +#* Copyright (c) 2006, Intel Corporation +#* All rights reserved. This program and the accompanying materials +#* are licensed and made available under the terms and conditions of the BSD License +#* which accompanies this distribution. The full text of the license may be found at +#* http://opensource.org/licenses/bsd-license.php +#* +#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +#* +#* LongMode.S +#* +#* Abstract: +#* +#* Transition from 32-bit protected mode EFI environment into x64 +#* 64-bit bit long mode. +#* +#* This file is not fully ported or operational. +#* +#------------------------------------------------------------------------------ + +.686p: +#.MODEL flat + +# +# Create the exception handler code in IA32 C code +# + +.code: +.stack: +.MMX: +.XMM: + +.global _LoadGo64Gdt; +_LoadGo64Gdt: + pushl %ebp # C prolog + pushl %edi + movl %esp, %ebp + # + # Disable interrupts + # + cli + # + # Reload the selectors + # Note: + # Make the Selectors 64-bit ready + # + movl gdtr, %edi # Load GDT register + movw %cs, %ax # Get the selector data from our code image + mov %ax, %es +# FIXME MISMATCH: " lgdt FWORD PTR es:[edi] " + + .byte 0x67 + .byte 0xea # Far Jump Offset:Selector to reload CS +# FIXME MISMATCH: " dd OFFSET DataSelectorRld" +# FIXME MISMATCH: " dw LINEAR_CODE_SEL " +DataSelectorRld: + movw SYS_DATA_SEL, %ax # Update the Base for the new selectors, too + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + popl %edi + popl %ebp + ret +#_LoadGo64Gdt ENDP + + +# VOID +# ActivateLongMode ( +# IN EFI_PHYSICAL_ADDRESS PageTables, +# IN EFI_PHYSICAL_ADDRESS HobStart, +# IN EFI_PHYSICAL_ADDRESS Stack, +# IN EFI_PHYSICAL_ADDRESS PpisNeededByDxeIplEntryPoint, +# IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint +# ) +# +# Input: [ebp][0h] = Original ebp +# [ebp][4h] = Return address +# [ebp][8h] = PageTables +# [ebp][10h] = HobStart +# [ebp][18h] = Stack +# [ebp][20h] = CodeEntryPoint1 <--- Call this first (for each call, pass HOB pointer) +# [ebp][28h] = CodeEntryPoint2 <--- Call this second +# +# +.global _ActivateLongMode; +_ActivateLongMode: + pushl %ebp # C prolog + movl %esp, %ebp + + # + # Use CPUID to determine if the processor supports long mode. + # + movl $0x80000000, %eax # Extended-function code 8000000h. + cpuid # Is largest extended function + cmpl $0x80000000, %eax # any function > 80000000h? + jbe no_long_mode # If not, no long mode. + movl $0x80000001, %eax # Extended-function code 8000001h. + cpuid # Now EDX = extended-features flags. + btl $29, %edx # Test if long mode is supported. + jnc no_long_mode # Exit if not supported. + + # + # Enable the 64-bit page-translation-table entries by + # setting CR4.PAE=1 (this is _required_ before activating + # long mode). Paging is not enabled until after long mode + # is enabled. + # + movl %cr4, %eax + btsl $5, %eax + movl %eax, %cr4 + + # + # Get the long-mode page tables, and initialize the + # 64-bit CR3 (page-table base address) to point to the base + # of the PML4 page table. The PML4 page table must be located + # below 4 Gbytes because only 32 bits of CR3 are loaded when + # the processor is not in 64-bit mode. + # + movl 0x8(%ebp), %eax # Get Page Tables + movl %eax, %cr3 # Initialize CR3 with PML4 base. + + # + # Enable long mode (set EFER.LME=1). + # + movl $0xc0000080, %ecx # EFER MSR number. + rdmsr # Read EFER. + btsl $8, %eax # Set LME=1. + wrmsr # Write EFER. + + # + # Enable paging to activate long mode (set CR0.PG=1) + # + + + movl %cr0, %eax # Read CR0. + btsl $31, %eax # Set PG=1. + movl %eax, %cr0 # Write CR0. + jmp go_to_long_mode +go_to_long_mode: + + # + # This is the next instruction after enabling paging. Jump to long mode + # + .byte 0x67 + .byte 0xea # Far Jump Offset:Selector to reload CS +#FIXME MISMATCH: " dd OFFSET in_long_mode" +#FIXME MISMATCH: " dw SYS_CODE64_SEL " +in_long_mode: + movw SYS_DATA64_SEL, %ax + movw %ax, %es + movw %ax, %ss + movw %ax, %ds + jmp . + + + # + # We're in long mode, so marshall the arguments to call the + # passed in function pointers + # Recall + # [ebp][10h] = HobStart + # [ebp][18h] = Stack + # [ebp][20h] = PpisNeededByDxeIplEntryPoint <--- Call this first (for each call, pass HOB pointer) + # [ebp][28h] = DxeCoreEntryPoint <--- Call this second + # + .byte 0x48 + movl 0x18(%ebp), %ebx # Setup the stack + .byte 0x48 + movl %ebx, %esp # On a new stack now + + +## 00000905 FF D0 call rax + + .byte 0x48 + movl 0x10(%ebp), %ecx # Pass Hob Start in RCX + .byte 0x48 + movl 0x28(%ebp), %eax # Get the function pointer for + # DxeCoreEntryPoint into EAX + +## 00000905 FF D0 call rax + .byte 0xff + .byte 0xd0 + + # + # WE SHOULD NEVER GET HERE!!!!!!!!!!!!! + # +no_long_mode: + jmp no_long_mode +#_ActivateLongMode ENDP + + .align 16 + +gdtr: #FIXME MISMATCH: "gdtr dw _GDT_END - _GDT_BASE - 1 " +#FIXME MISMATCH: " dd OFFSET _GDT_BASE " + +#-----------------------------------------------------------------------------; +# global descriptor table (GDT) +#-----------------------------------------------------------------------------; + + .align 16 + +.global _GDT_BASE +_GDT_BASE: +# null descriptor +.equ NULL_SEL, .-_GDT_BASE # Selector [0] + .word 0 # limit 15:0 + .word 0 # base 15:0 + .byte 0 # base 23:16 + .byte 0 # type + .byte 0 # limit 19:16, flags + .byte 0 # base 31:24 + +# linear data segment descriptor +.equ LINEAR_SEL, .-_GDT_BASE # Selector [0x8] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x92 # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +# linear code segment descriptor +.equ LINEAR_CODE_SEL, .-_GDT_BASE # Selector [0x10] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9F # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +# system data segment descriptor +.equ SYS_DATA_SEL, .-_GDT_BASE # Selector [0x18] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +# system code segment descriptor +.equ SYS_CODE_SEL, .-_GDT_BASE # Selector [0x20] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9A # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +# spare segment descriptor +.equ SPARE3_SEL, .-_GDT_BASE # Selector [0x28] + .word 0 # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0 # present, ring 0, data, expand-up, writable + .byte 0 # page-granular, 32-bit + .byte 0 + +# +# system data segment descriptor +# +.equ SYS_DATA64_SEL, .-_GDT_BASE # Selector [0x30] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x92 # P | DPL [1..2] | 1 | 1 | C | R | A + .byte 0xCF # G | D | L | AVL | Segment [19..16] + .byte 0 + +# +# system code segment descriptor +# +.equ SYS_CODE64_SEL, .-_GDT_BASE # Selector [0x38] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9A # P | DPL [1..2] | 1 | 1 | C | R | A + .byte 0xAF # G | D | L | AVL | Segment [19..16] + .byte 0 + +# spare segment descriptor +.equ SPARE4_SEL, .-_GDT_BASE # Selector [0x40] + .word 0 # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0 # present, ring 0, data, expand-up, writable + .byte 0 # page-granular, 32-bit + .byte 0 + +_GDT_END: + + +