mirror of https://github.com/acidanthera/audk.git
Make DxeIpl "assembly-free" to avoid the undesired LongMode.obj code in image even if we do not choose to switch to long mode.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2031 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
16fdd1e20e
commit
f40793becf
|
@ -107,22 +107,5 @@ PeimInitializeDxeIpl (
|
||||||
IN EFI_PEI_SERVICES **PeiServices
|
IN EFI_PEI_SERVICES **PeiServices
|
||||||
);
|
);
|
||||||
|
|
||||||
EFI_PHYSICAL_ADDRESS
|
|
||||||
CreateIdentityMappingPageTables (
|
|
||||||
IN UINT32 NumberOfProcessorPhysicalAddressBits
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ActivateLongMode (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS PageTables,
|
|
||||||
IN EFI_PHYSICAL_ADDRESS HobStart,
|
|
||||||
IN EFI_PHYSICAL_ADDRESS Stack,
|
|
||||||
IN EFI_PHYSICAL_ADDRESS CodeEntryPoint1,
|
|
||||||
IN EFI_PHYSICAL_ADDRESS CodeEntryPoint2
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
LoadGo64Gdt();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -77,8 +77,6 @@
|
||||||
<Filename>DxeIpl.dxs</Filename>
|
<Filename>DxeIpl.dxs</Filename>
|
||||||
<Filename SupArchList="IA32 X64 EBC">Ia32/ImageRead.c</Filename>
|
<Filename SupArchList="IA32 X64 EBC">Ia32/ImageRead.c</Filename>
|
||||||
<Filename SupArchList="IA32">Ia32/DxeLoadFunc.c</Filename>
|
<Filename SupArchList="IA32">Ia32/DxeLoadFunc.c</Filename>
|
||||||
<Filename SupArchList="IA32">Ia32/LongMode.asm</Filename>
|
|
||||||
<Filename ToolChainFamily="GCC" SupArchList="IA32">Ia32/LongMode.S</Filename>
|
|
||||||
<Filename SupArchList="IA32">Ia32/VirtualMemory.c</Filename>
|
<Filename SupArchList="IA32">Ia32/VirtualMemory.c</Filename>
|
||||||
<Filename SupArchList="IA32">Ia32/VirtualMemory.h</Filename>
|
<Filename SupArchList="IA32">Ia32/VirtualMemory.h</Filename>
|
||||||
<Filename SupArchList="X64 EBC">X64/DxeLoadFunc.c</Filename>
|
<Filename SupArchList="X64 EBC">X64/DxeLoadFunc.c</Filename>
|
||||||
|
|
|
@ -20,6 +20,31 @@ Abstract:
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#include "DxeIpl.h"
|
#include "DxeIpl.h"
|
||||||
|
#include "VirtualMemory.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global Descriptor Table (GDT)
|
||||||
|
//
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT gGdtEntries [] = {
|
||||||
|
/* selector { Global Segment Descriptor } */
|
||||||
|
/* 0x00 */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //null descriptor
|
||||||
|
/* 0x08 */ {0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}, //linear data segment descriptor
|
||||||
|
/* 0x10 */ {0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}, //linear code segment descriptor
|
||||||
|
/* 0x18 */ {0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}, //system data segment descriptor
|
||||||
|
/* 0x20 */ {0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}, //system code segment descriptor
|
||||||
|
/* 0x28 */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //spare segment descriptor
|
||||||
|
/* 0x30 */ {0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}, //system data segment descriptor
|
||||||
|
/* 0x38 */ {0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 1, 0, 1, 0}, //system code segment descriptor
|
||||||
|
/* 0x40 */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //spare segment descriptor
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// IA32 Gdt register
|
||||||
|
//
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = {
|
||||||
|
sizeof (gGdtEntries) - 1,
|
||||||
|
(UINTN) gGdtEntries
|
||||||
|
};
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
HandOffToDxeCore (
|
HandOffToDxeCore (
|
||||||
|
@ -30,7 +55,7 @@ HandOffToDxeCore (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_PHYSICAL_ADDRESS BaseOfStack;
|
EFI_PHYSICAL_ADDRESS BaseOfStack;
|
||||||
EFI_PHYSICAL_ADDRESS TopOfStack;
|
EFI_PHYSICAL_ADDRESS TopOfStack;
|
||||||
EFI_PHYSICAL_ADDRESS PageTables;
|
UINTN PageTables;
|
||||||
|
|
||||||
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
|
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
@ -51,25 +76,27 @@ HandOffToDxeCore (
|
||||||
// X64 Calling Conventions requires that the stack must be aligned to 16 bytes
|
// X64 Calling Conventions requires that the stack must be aligned to 16 bytes
|
||||||
//
|
//
|
||||||
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, 16);
|
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, 16);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA
|
// Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA
|
||||||
// memory, it may be corrupted when copying FV to high-end memory
|
// memory, it may be corrupted when copying FV to high-end memory
|
||||||
//
|
//
|
||||||
LoadGo64Gdt();
|
AsmWriteGdtr (&gGdt);
|
||||||
//
|
//
|
||||||
// Limit to 36 bits of addressing for debug. Should get it from CPU
|
// Create page table and save PageMapLevel4 to CR3
|
||||||
//
|
|
||||||
PageTables = CreateIdentityMappingPageTables (36);
|
|
||||||
//
|
//
|
||||||
|
PageTables = CreateIdentityMappingPageTables ();
|
||||||
|
AsmWriteCr3 (PageTables);
|
||||||
|
//
|
||||||
// Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
|
// Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
|
||||||
// Call x64 drivers passing in single argument, a pointer to the HOBs.
|
// Call x64 drivers passing in single argument, a pointer to the HOBs.
|
||||||
//
|
//
|
||||||
ActivateLongMode (
|
AsmEnablePaging64 (
|
||||||
PageTables,
|
SYS_CODE64_SEL,
|
||||||
(EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw),
|
DxeCoreEntryPoint,
|
||||||
TopOfStack,
|
(EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw),
|
||||||
0x00000000,
|
0,
|
||||||
DxeCoreEntryPoint
|
TopOfStack
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
|
@ -87,3 +114,4 @@ HandOffToDxeCore (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,296 +0,0 @@
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
#*
|
|
||||||
#* 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:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,294 +0,0 @@
|
||||||
TITLE LongMode.asm: Assembly code for the entering long mode
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
;*
|
|
||||||
;* 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.asm
|
|
||||||
;*
|
|
||||||
;* Abstract:
|
|
||||||
;*
|
|
||||||
;* Transition from 32-bit protected mode EFI environment into x64
|
|
||||||
;* 64-bit bit long mode.
|
|
||||||
;*
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.686p
|
|
||||||
.model flat
|
|
||||||
|
|
||||||
;
|
|
||||||
; Create the exception handler code in IA32 C code
|
|
||||||
;
|
|
||||||
|
|
||||||
.code
|
|
||||||
.stack
|
|
||||||
.MMX
|
|
||||||
.XMM
|
|
||||||
|
|
||||||
_LoadGo64Gdt PROC Near Public
|
|
||||||
push ebp ; C prolog
|
|
||||||
push edi
|
|
||||||
mov ebp, esp
|
|
||||||
;
|
|
||||||
; Disable interrupts
|
|
||||||
;
|
|
||||||
cli
|
|
||||||
;
|
|
||||||
; Reload the selectors
|
|
||||||
; Note:
|
|
||||||
; Make the Selectors 64-bit ready
|
|
||||||
;
|
|
||||||
mov edi, OFFSET gdtr ; Load GDT register
|
|
||||||
mov ax,cs ; Get the selector data from our code image
|
|
||||||
mov es,ax
|
|
||||||
lgdt FWORD PTR es:[edi] ; and update the GDTR
|
|
||||||
|
|
||||||
db 067h
|
|
||||||
db 0eah ; Far Jump Offset:Selector to reload CS
|
|
||||||
dd OFFSET DataSelectorRld; Offset is ensuing instruction boundary
|
|
||||||
dw LINEAR_CODE_SEL ; Selector is our code selector, 10h
|
|
||||||
DataSelectorRld::
|
|
||||||
mov ax, SYS_DATA_SEL ; Update the Base for the new selectors, too
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov ss, ax
|
|
||||||
|
|
||||||
pop edi
|
|
||||||
pop 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
|
|
||||||
;
|
|
||||||
;
|
|
||||||
_ActivateLongMode PROC Near Public
|
|
||||||
push ebp ; C prolog
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
;
|
|
||||||
; Use CPUID to determine if the processor supports long mode.
|
|
||||||
;
|
|
||||||
mov eax, 80000000h ; Extended-function code 8000000h.
|
|
||||||
cpuid ; Is largest extended function
|
|
||||||
cmp eax, 80000000h ; any function > 80000000h?
|
|
||||||
jbe no_long_mode ; If not, no long mode.
|
|
||||||
mov eax, 80000001h ; Extended-function code 8000001h.
|
|
||||||
cpuid ; Now EDX = extended-features flags.
|
|
||||||
bt edx, 29 ; 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.
|
|
||||||
;
|
|
||||||
mov eax, cr4
|
|
||||||
bts eax, 5
|
|
||||||
mov cr4, eax
|
|
||||||
|
|
||||||
;
|
|
||||||
; 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.
|
|
||||||
;
|
|
||||||
mov eax, [ebp+8h] ; Get Page Tables
|
|
||||||
mov cr3, eax ; Initialize CR3 with PML4 base.
|
|
||||||
|
|
||||||
;
|
|
||||||
; Enable long mode (set EFER.LME=1).
|
|
||||||
;
|
|
||||||
mov ecx, 0c0000080h ; EFER MSR number.
|
|
||||||
rdmsr ; Read EFER.
|
|
||||||
bts eax, 8 ; Set LME=1.
|
|
||||||
wrmsr ; Write EFER.
|
|
||||||
|
|
||||||
;
|
|
||||||
; Enable paging to activate long mode (set CR0.PG=1)
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
mov eax, cr0 ; Read CR0.
|
|
||||||
bts eax, 31 ; Set PG=1.
|
|
||||||
mov cr0, eax ; Write CR0.
|
|
||||||
jmp go_to_long_mode
|
|
||||||
go_to_long_mode:
|
|
||||||
|
|
||||||
;
|
|
||||||
; This is the next instruction after enabling paging. Jump to long mode
|
|
||||||
;
|
|
||||||
db 067h
|
|
||||||
db 0eah ; Far Jump Offset:Selector to reload CS
|
|
||||||
dd OFFSET in_long_mode; Offset is ensuing instruction boundary
|
|
||||||
dw SYS_CODE64_SEL ; Selector is our code selector, 10h
|
|
||||||
in_long_mode::
|
|
||||||
mov ax, SYS_DATA64_SEL
|
|
||||||
mov es, ax
|
|
||||||
mov ss, ax
|
|
||||||
mov ds, ax
|
|
||||||
;; 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
|
|
||||||
;
|
|
||||||
db 48h
|
|
||||||
mov ebx, [ebp+18h] ; Setup the stack
|
|
||||||
db 48h
|
|
||||||
mov esp, ebx ; On a new stack now
|
|
||||||
|
|
||||||
|
|
||||||
;; 00000905 FF D0 call rax
|
|
||||||
|
|
||||||
db 48h
|
|
||||||
mov ecx, [ebp+10h] ; Pass Hob Start in RCX
|
|
||||||
db 48h
|
|
||||||
mov eax, [ebp+28h] ; Get the function pointer for
|
|
||||||
; DxeCoreEntryPoint into EAX
|
|
||||||
|
|
||||||
;; 00000905 FF D0 call rax
|
|
||||||
db 0ffh
|
|
||||||
db 0d0h
|
|
||||||
|
|
||||||
;
|
|
||||||
; WE SHOULD NEVER GET HERE!!!!!!!!!!!!!
|
|
||||||
;
|
|
||||||
no_long_mode:
|
|
||||||
jmp no_long_mode
|
|
||||||
_ActivateLongMode endp
|
|
||||||
|
|
||||||
align 16
|
|
||||||
|
|
||||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
|
||||||
dd OFFSET GDT_BASE ; (GDT base gets set above)
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------;
|
|
||||||
; global descriptor table (GDT)
|
|
||||||
;-----------------------------------------------------------------------------;
|
|
||||||
|
|
||||||
align 16
|
|
||||||
|
|
||||||
public GDT_BASE
|
|
||||||
GDT_BASE:
|
|
||||||
; null descriptor
|
|
||||||
NULL_SEL equ $-GDT_BASE ; Selector [0]
|
|
||||||
dw 0 ; limit 15:0
|
|
||||||
dw 0 ; base 15:0
|
|
||||||
db 0 ; base 23:16
|
|
||||||
db 0 ; type
|
|
||||||
db 0 ; limit 19:16, flags
|
|
||||||
db 0 ; base 31:24
|
|
||||||
|
|
||||||
; linear data segment descriptor
|
|
||||||
LINEAR_SEL equ $-GDT_BASE ; Selector [0x8]
|
|
||||||
dw 0FFFFh ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 092h ; present, ring 0, data, expand-up, writable
|
|
||||||
db 0CFh ; page-granular, 32-bit
|
|
||||||
db 0
|
|
||||||
|
|
||||||
; linear code segment descriptor
|
|
||||||
LINEAR_CODE_SEL equ $-GDT_BASE ; Selector [0x10]
|
|
||||||
dw 0FFFFh ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 09Fh ; present, ring 0, data, expand-up, writable
|
|
||||||
db 0CFh ; page-granular, 32-bit
|
|
||||||
db 0
|
|
||||||
|
|
||||||
; system data segment descriptor
|
|
||||||
SYS_DATA_SEL equ $-GDT_BASE ; Selector [0x18]
|
|
||||||
dw 0FFFFh ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 093h ; present, ring 0, data, expand-up, writable
|
|
||||||
db 0CFh ; page-granular, 32-bit
|
|
||||||
db 0
|
|
||||||
|
|
||||||
; system code segment descriptor
|
|
||||||
SYS_CODE_SEL equ $-GDT_BASE ; Selector [0x20]
|
|
||||||
dw 0FFFFh ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
|
||||||
db 0CFh ; page-granular, 32-bit
|
|
||||||
db 0
|
|
||||||
|
|
||||||
; spare segment descriptor
|
|
||||||
SPARE3_SEL equ $-GDT_BASE ; Selector [0x28]
|
|
||||||
dw 0 ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 0 ; present, ring 0, data, expand-up, writable
|
|
||||||
db 0 ; page-granular, 32-bit
|
|
||||||
db 0
|
|
||||||
|
|
||||||
;
|
|
||||||
; system data segment descriptor
|
|
||||||
;
|
|
||||||
SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30]
|
|
||||||
dw 0FFFFh ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 092h ; P | DPL [1..2] | 1 | 1 | C | R | A
|
|
||||||
db 0CFh ; G | D | L | AVL | Segment [19..16]
|
|
||||||
db 0
|
|
||||||
|
|
||||||
;
|
|
||||||
; system code segment descriptor
|
|
||||||
;
|
|
||||||
SYS_CODE64_SEL equ $-GDT_BASE ; Selector [0x38]
|
|
||||||
dw 0FFFFh ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 09Ah ; P | DPL [1..2] | 1 | 1 | C | R | A
|
|
||||||
db 0AFh ; G | D | L | AVL | Segment [19..16]
|
|
||||||
db 0
|
|
||||||
|
|
||||||
; spare segment descriptor
|
|
||||||
SPARE4_SEL equ $-GDT_BASE ; Selector [0x40]
|
|
||||||
dw 0 ; limit 0xFFFFF
|
|
||||||
dw 0 ; base 0
|
|
||||||
db 0
|
|
||||||
db 0 ; present, ring 0, data, expand-up, writable
|
|
||||||
db 0 ; page-granular, 32-bit
|
|
||||||
db 0
|
|
||||||
|
|
||||||
GDT_END:
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Abstract:
|
||||||
|
|
||||||
#include "VirtualMemory.h"
|
#include "VirtualMemory.h"
|
||||||
|
|
||||||
EFI_PHYSICAL_ADDRESS
|
UINTN
|
||||||
CreateIdentityMappingPageTables (
|
CreateIdentityMappingPageTables (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
|
@ -155,6 +155,6 @@ Returns:
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (EFI_PHYSICAL_ADDRESS) (UINTN)PageMap; // FIXME
|
return (UINTN)PageMap; // FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,29 @@ Abstract:
|
||||||
#define _VIRTUAL_MEMORY_H_
|
#define _VIRTUAL_MEMORY_H_
|
||||||
|
|
||||||
|
|
||||||
|
#define SYS_CODE64_SEL 0x38
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
UINT32 LimitLow : 16;
|
||||||
|
UINT32 BaseLow : 16;
|
||||||
|
UINT32 BaseMid : 8;
|
||||||
|
UINT32 Type : 4;
|
||||||
|
UINT32 System : 1;
|
||||||
|
UINT32 Dpl : 2;
|
||||||
|
UINT32 Present : 1;
|
||||||
|
UINT32 LimitHigh : 4;
|
||||||
|
UINT32 Software : 1;
|
||||||
|
UINT32 Reserved : 1;
|
||||||
|
UINT32 DefaultSize : 1;
|
||||||
|
UINT32 Granularity : 1;
|
||||||
|
UINT32 BaseHigh : 8;
|
||||||
|
} Bits;
|
||||||
|
UINT64 Uint64;
|
||||||
|
} IA32_GDT;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Page-Map Level-4 Offset (PML4) and
|
// Page-Map Level-4 Offset (PML4) and
|
||||||
// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
|
// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
|
||||||
|
@ -77,7 +98,7 @@ typedef union {
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
EFI_PHYSICAL_ADDRESS
|
UINTN
|
||||||
CreateIdentityMappingPageTables (
|
CreateIdentityMappingPageTables (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue