Introduce PcdDxeIplSwitchToLongMode to DxeIplPeim and remove DxeIplX64Peim.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2018 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -23,6 +23,8 @@ Abstract:
|
||||
#define STACK_SIZE 0x20000
|
||||
#define BSP_STORE_SIZE 0x4000
|
||||
|
||||
#define GET_OCCUPIED_SIZE(ActualSize, Alignment) ((ActualSize + (Alignment - 1)) & ~(Alignment - 1))
|
||||
|
||||
extern BOOLEAN gInMemory;
|
||||
|
||||
/**
|
||||
@@ -125,8 +127,9 @@ DxeLoadCore (
|
||||
EFI_STATUS
|
||||
PeiProcessFile (
|
||||
IN UINT16 SectionType,
|
||||
IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader,
|
||||
OUT VOID **Pe32Data
|
||||
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
|
||||
OUT VOID **Pe32Data,
|
||||
IN EFI_PEI_HOB_POINTERS *OrigHob
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<MsaHeader>
|
||||
<ModuleName>DxeIpl</ModuleName>
|
||||
<ModuleType>PEIM</ModuleType>
|
||||
@@ -8,11 +8,11 @@
|
||||
<Abstract>Component description file for DxeIpl module</Abstract>
|
||||
<Description>The responsibility of this module is to load the DXE Core from a Firmware Volume. This implementation i used to load a 32-bit DXE Core.</Description>
|
||||
<Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
|
||||
<License>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,
|
||||
<License>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.</License>
|
||||
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
|
||||
</MsaHeader>
|
||||
@@ -67,6 +67,9 @@
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>MemoryAllocationLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>PcdLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>DxeLoad.c</Filename>
|
||||
@@ -74,12 +77,17 @@
|
||||
<Filename>DxeIpl.dxs</Filename>
|
||||
<Filename SupArchList="IA32">Ia32/ImageRead.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.h</Filename>
|
||||
<Filename SupArchList="X64">Ia32/ImageRead.c</Filename>
|
||||
<Filename SupArchList="X64">Ia32/DxeLoadFunc.c</Filename>
|
||||
<Filename SupArchList="IPF">ipf/ImageRead.c</Filename>
|
||||
<Filename SupArchList="IPF">ipf/DxeLoadFunc.c</Filename>
|
||||
<Filename SupArchList="EBC">Ia32/ImageRead.c</Filename>
|
||||
<Filename SupArchList="EBC">Ia32/DxeLoadFunc.c</Filename>
|
||||
<Filename SupArchList="X64 IPF EBC">Non-existing.c</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
@@ -118,9 +126,6 @@
|
||||
<Ppi Usage="SOMETIMES_CONSUMED">
|
||||
<PpiCName>gEfiPeiSecurityPpiGuid</PpiCName>
|
||||
</Ppi>
|
||||
<Ppi Usage="PRIVATE">
|
||||
<PpiCName>gPeiInMemoryGuid</PpiCName>
|
||||
</Ppi>
|
||||
</PPIs>
|
||||
<Guids>
|
||||
<GuidCNames Usage="SOMETIMES_CONSUMED">
|
||||
@@ -134,4 +139,30 @@
|
||||
<ModuleEntryPoint>PeimInitializeDxeIpl</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
<PcdCoded>
|
||||
<PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
|
||||
<C_Name>PcdDxeIplSwitchToLongMode</C_Name>
|
||||
<TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>
|
||||
<DefaultValue>FALSE</DefaultValue>
|
||||
<HelpText>If this feature is enabled, then the DXE IPL will load a 64-bit DxeCore.</HelpText>
|
||||
</PcdEntry>
|
||||
<PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
|
||||
<C_Name>PcdDxeIplSupportEfiDecompress</C_Name>
|
||||
<TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>
|
||||
<DefaultValue>TRUE</DefaultValue>
|
||||
<HelpText>If this feature is enabled, then the DXE IPL must support decompressing files compressed with the EFI Compression algorithm</HelpText>
|
||||
</PcdEntry>
|
||||
<PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
|
||||
<C_Name>PcdDxeIplSupportTianoDecompress</C_Name>
|
||||
<TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>
|
||||
<DefaultValue>TRUE</DefaultValue>
|
||||
<HelpText>If this feature is enabled, then the DXE IPL must support decompressing files compressed with the Tiano Compression algorithm</HelpText>
|
||||
</PcdEntry>
|
||||
<PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
|
||||
<C_Name>PcdDxeIplSupportCustomDecompress</C_Name>
|
||||
<TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>
|
||||
<DefaultValue>TRUE</DefaultValue>
|
||||
<HelpText>If this feature is enabled, then the DXE IPL must support decompressing files compressed with the Custom Compression algorithm</HelpText>
|
||||
</PcdEntry>
|
||||
</PcdCoded>
|
||||
</ModuleSurfaceArea>
|
@@ -20,7 +20,11 @@ Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeIpl.h>
|
||||
#include "DxeIpl.h"
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma warning( disable : 4305 )
|
||||
#endif
|
||||
|
||||
BOOLEAN gInMemory = FALSE;
|
||||
|
||||
@@ -36,22 +40,17 @@ static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = {
|
||||
DxeIplLoadFile
|
||||
};
|
||||
|
||||
static EFI_PEI_PPI_DESCRIPTOR mPpiLoadFile = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gEfiPeiFvFileLoaderPpiGuid,
|
||||
&mLoadFilePpi
|
||||
};
|
||||
|
||||
static EFI_PEI_PPI_DESCRIPTOR mPpiList = {
|
||||
},
|
||||
{
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiDxeIplPpiGuid,
|
||||
&mDxeIplPpi
|
||||
};
|
||||
|
||||
static EFI_PEI_PPI_DESCRIPTOR mPpiPeiInMemory = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gPeiInMemoryGuid,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = {
|
||||
@@ -60,38 +59,21 @@ static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = {
|
||||
NULL
|
||||
};
|
||||
|
||||
DECOMPRESS_LIBRARY gEfiDecompress = {
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gEfiDecompress = {
|
||||
UefiDecompressGetInfo,
|
||||
UefiDecompress
|
||||
};
|
||||
|
||||
DECOMPRESS_LIBRARY gTianoDecompress = {
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gTianoDecompress = {
|
||||
TianoDecompressGetInfo,
|
||||
TianoDecompress
|
||||
};
|
||||
|
||||
DECOMPRESS_LIBRARY gCustomDecompress = {
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gCustomDecompress = {
|
||||
CustomDecompressGetInfo,
|
||||
CustomDecompress
|
||||
};
|
||||
|
||||
STATIC
|
||||
UINTN
|
||||
GetOccupiedSize (
|
||||
IN UINTN ActualSize,
|
||||
IN UINTN Alignment
|
||||
)
|
||||
{
|
||||
UINTN OccupiedSize;
|
||||
|
||||
OccupiedSize = ActualSize;
|
||||
while ((OccupiedSize & (Alignment - 1)) != 0) {
|
||||
OccupiedSize++;
|
||||
}
|
||||
|
||||
return OccupiedSize;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeimInitializeDxeIpl (
|
||||
@@ -120,17 +102,9 @@ Returns:
|
||||
EFI_BOOT_MODE BootMode;
|
||||
|
||||
Status = PeiServicesGetBootMode (&BootMode);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gPeiInMemoryGuid,
|
||||
0,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) {
|
||||
if (!gInMemory && (BootMode != BOOT_ON_S3_RESUME)) {
|
||||
//
|
||||
// The DxeIpl has not yet been shadowed
|
||||
//
|
||||
@@ -140,38 +114,15 @@ Returns:
|
||||
// Shadow DxeIpl and then re-run its entry point
|
||||
//
|
||||
Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (BootMode != BOOT_ON_S3_RESUME) {
|
||||
//
|
||||
// The DxeIpl has been shadowed
|
||||
// Install FvFileLoader and DxeIpl PPIs.
|
||||
//
|
||||
gInMemory = TRUE;
|
||||
|
||||
//
|
||||
// Install LoadFile PPI
|
||||
//
|
||||
Status = PeiServicesInstallPpi (&mPpiLoadFile);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Install DxeIpl PPI
|
||||
//
|
||||
PeiServicesInstallPpi (&mPpiList);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PeiServicesInstallPpi (mPpiList);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
@@ -200,12 +151,13 @@ Returns:
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *TopOfStack;
|
||||
VOID *BaseOfStack;
|
||||
EFI_PHYSICAL_ADDRESS TopOfStack;
|
||||
EFI_PHYSICAL_ADDRESS BaseOfStack;
|
||||
EFI_PHYSICAL_ADDRESS BspStore;
|
||||
EFI_GUID DxeCoreFileName;
|
||||
EFI_GUID FirmwareFileName;
|
||||
VOID *Pe32Data;
|
||||
VOID *FvImageData;
|
||||
EFI_PHYSICAL_ADDRESS DxeCoreAddress;
|
||||
UINT64 DxeCoreSize;
|
||||
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;
|
||||
@@ -213,104 +165,32 @@ Returns:
|
||||
EFI_BOOT_MODE BootMode;
|
||||
EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery;
|
||||
EFI_PEI_S3_RESUME_PPI *S3Resume;
|
||||
EFI_PHYSICAL_ADDRESS PageTables;
|
||||
|
||||
// PERF_START (PeiServices, L"DxeIpl", NULL, 0);
|
||||
TopOfStack = NULL;
|
||||
BaseOfStack = NULL;
|
||||
TopOfStack = 0;
|
||||
BaseOfStack = 0;
|
||||
BspStore = 0;
|
||||
Status = EFI_SUCCESS;
|
||||
PageTables = 0;
|
||||
|
||||
//
|
||||
// if in S3 Resume, restore configure
|
||||
//
|
||||
Status = PeiServicesGetBootMode (&BootMode);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) {
|
||||
if (BootMode == BOOT_ON_S3_RESUME) {
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiS3ResumePpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **)&S3Resume
|
||||
);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = S3Resume->S3RestoreConfig (PeiServices);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Install the PEI Protocols that are shared between PEI and DXE
|
||||
//
|
||||
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
|
||||
ASSERT (PeiEfiPeiPeCoffLoader != NULL);
|
||||
|
||||
|
||||
//
|
||||
// Allocate 128KB for the Stack
|
||||
//
|
||||
BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
|
||||
ASSERT (BaseOfStack != NULL);
|
||||
|
||||
//
|
||||
// Compute the top of the stack we were allocated. Pre-allocate a UINTN
|
||||
// for safety.
|
||||
//
|
||||
TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
|
||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
|
||||
//
|
||||
// Add architecture-specifc HOBs (including the BspStore HOB)
|
||||
//
|
||||
Status = CreateArchSpecificHobs (&BspStore);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Add HOB for the EFI Decompress Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiDecompressProtocolGuid,
|
||||
(VOID *)&gEfiDecompress,
|
||||
sizeof (gEfiDecompress)
|
||||
);
|
||||
|
||||
//
|
||||
// Add HOB for the Tiano Decompress Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiTianoDecompressProtocolGuid,
|
||||
(VOID *)&gTianoDecompress,
|
||||
sizeof (gTianoDecompress)
|
||||
);
|
||||
|
||||
//
|
||||
// Add HOB for the user customized Decompress Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiCustomizedDecompressProtocolGuid,
|
||||
(VOID *)&gCustomDecompress,
|
||||
sizeof (gCustomDecompress)
|
||||
);
|
||||
|
||||
//
|
||||
// Add HOB for the PE/COFF Loader Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiPeiPeCoffLoaderGuid,
|
||||
(VOID *)&PeiEfiPeiPeCoffLoader,
|
||||
sizeof (VOID *)
|
||||
);
|
||||
|
||||
//
|
||||
// See if we are in crisis recovery
|
||||
//
|
||||
Status = PeiServicesGetBootMode (&BootMode);
|
||||
|
||||
if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) {
|
||||
} else if (BootMode == BOOT_IN_RECOVERY_MODE) {
|
||||
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiRecoveryModulePpiGuid,
|
||||
@@ -318,8 +198,8 @@ Returns:
|
||||
NULL,
|
||||
(VOID **)&PeiRecovery
|
||||
);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
|
||||
@@ -332,19 +212,34 @@ Returns:
|
||||
}
|
||||
|
||||
//
|
||||
// Find the EFI_FV_FILETYPE_RAW type compressed Firmware Volume file in FTW spare block
|
||||
// Install the PEI Protocols that are shared between PEI and DXE
|
||||
//
|
||||
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
|
||||
ASSERT (PeiEfiPeiPeCoffLoader != NULL);
|
||||
|
||||
//
|
||||
// Allocate 128KB for the Stack
|
||||
//
|
||||
PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
|
||||
ASSERT (BaseOfStack != 0);
|
||||
|
||||
//
|
||||
// Add architecture-specifc HOBs (including the BspStore HOB)
|
||||
//
|
||||
Status = CreateArchSpecificHobs (&BspStore);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file
|
||||
// The file found will be processed by PeiProcessFile: It will first be decompressed to
|
||||
// a normal FV, then a corresponding FV type hob will be built which is provided for DXE
|
||||
// core to find and dispatch drivers in this FV. Because PeiProcessFile typically checks
|
||||
// for EFI_FV_FILETYPE_DXE_CORE type file, in this condition we need not check returned
|
||||
// status
|
||||
// a normal FV, then a corresponding FV type hob will be built.
|
||||
//
|
||||
Status = PeiFindFile (
|
||||
EFI_FV_FILETYPE_RAW,
|
||||
EFI_SECTION_PE32,
|
||||
&FirmwareFileName,
|
||||
&Pe32Data
|
||||
);
|
||||
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
|
||||
EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
|
||||
&FirmwareFileName,
|
||||
&FvImageData
|
||||
);
|
||||
|
||||
//
|
||||
// Find the DXE Core in a Firmware Volume
|
||||
@@ -355,20 +250,18 @@ Returns:
|
||||
&DxeCoreFileName,
|
||||
&Pe32Data
|
||||
);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Load the DXE Core from a Firmware Volume
|
||||
//
|
||||
Status = PeiLoadFile (
|
||||
PeiEfiPeiPeCoffLoader,
|
||||
Pe32Data,
|
||||
&DxeCoreAddress,
|
||||
&DxeCoreSize,
|
||||
&DxeCoreEntryPoint
|
||||
);
|
||||
|
||||
PeiEfiPeiPeCoffLoader,
|
||||
Pe32Data,
|
||||
&DxeCoreAddress,
|
||||
&DxeCoreSize,
|
||||
&DxeCoreEntryPoint
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
@@ -377,7 +270,6 @@ Returns:
|
||||
//
|
||||
|
||||
Status = PeiServicesInstallPpi (&mPpiSignal);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
@@ -399,14 +291,93 @@ Returns:
|
||||
);
|
||||
|
||||
DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));
|
||||
SwitchIplStacks (
|
||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
|
||||
HobList.Raw,
|
||||
NULL,
|
||||
TopOfStack,
|
||||
(VOID *) (UINTN) BspStore
|
||||
);
|
||||
if (FeaturePcdGet(PcdDxeIplSwitchToLongMode)) {
|
||||
//
|
||||
// Compute the top of the stack we were allocated, which is used to load X64 dxe core.
|
||||
// Pre-allocate a 32 bytes which confroms to x64 calling convention.
|
||||
//
|
||||
// The first four parameters to a function are passed in rcx, rdx, r8 and r9.
|
||||
// Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the
|
||||
// register parameters is reserved on the stack, in case the called function
|
||||
// wants to spill them; this is important if the function is variadic.
|
||||
//
|
||||
TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;
|
||||
|
||||
//
|
||||
// X64 Calling Conventions requires that the stack must be aligned to 16 bytes
|
||||
//
|
||||
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
|
||||
// memory, it may be corrupted when copying FV to high-end memory
|
||||
//
|
||||
LoadGo64Gdt();
|
||||
//
|
||||
// Limit to 36 bits of addressing for debug. Should get it from CPU
|
||||
//
|
||||
PageTables = CreateIdentityMappingPageTables (36);
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
ActivateLongMode (
|
||||
PageTables,
|
||||
(EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw),
|
||||
TopOfStack,
|
||||
0x00000000,
|
||||
DxeCoreEntryPoint
|
||||
);
|
||||
} else {
|
||||
//
|
||||
// Add HOB for the EFI Decompress Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiDecompressProtocolGuid,
|
||||
(VOID *)&gEfiDecompress,
|
||||
sizeof (gEfiDecompress)
|
||||
);
|
||||
|
||||
//
|
||||
// Add HOB for the Tiano Decompress Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiTianoDecompressProtocolGuid,
|
||||
(VOID *)&gTianoDecompress,
|
||||
sizeof (gTianoDecompress)
|
||||
);
|
||||
|
||||
//
|
||||
// Add HOB for the user customized Decompress Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiCustomizedDecompressProtocolGuid,
|
||||
(VOID *)&gCustomDecompress,
|
||||
sizeof (gCustomDecompress)
|
||||
);
|
||||
|
||||
//
|
||||
// Add HOB for the PE/COFF Loader Protocol
|
||||
//
|
||||
BuildGuidDataHob (
|
||||
&gEfiPeiPeCoffLoaderGuid,
|
||||
(VOID *)&PeiEfiPeiPeCoffLoader,
|
||||
sizeof (VOID *)
|
||||
);
|
||||
//
|
||||
// Compute the top of the stack we were allocated. Pre-allocate a UINTN
|
||||
// for safety.
|
||||
//
|
||||
TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT;
|
||||
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
|
||||
SwitchIplStacks (
|
||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
|
||||
HobList.Raw,
|
||||
NULL,
|
||||
(VOID *) (UINTN) TopOfStack,
|
||||
(VOID *) (UINTN) BspStore
|
||||
);
|
||||
}
|
||||
//
|
||||
// If we get here, then the DXE Core returned. This is an error
|
||||
// Dxe Core should not return.
|
||||
@@ -462,10 +433,11 @@ Returns:
|
||||
FwVolHeader = NULL;
|
||||
FfsFileHeader = NULL;
|
||||
SectionData = NULL;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Foreach Firmware Volume, look for a specified type
|
||||
// of file and break out when one is found
|
||||
// For each Firmware Volume, look for a specified type
|
||||
// of file and break out until no one is found
|
||||
//
|
||||
Hob.Raw = GetHobList ();
|
||||
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {
|
||||
@@ -478,11 +450,14 @@ Returns:
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PeiProcessFile (
|
||||
SectionType,
|
||||
&FfsFileHeader,
|
||||
Pe32Data
|
||||
FfsFileHeader,
|
||||
Pe32Data,
|
||||
&Hob
|
||||
);
|
||||
CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));
|
||||
return Status;
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
Hob.Raw = GET_NEXT_HOB (Hob);
|
||||
}
|
||||
@@ -608,7 +583,7 @@ Returns:
|
||||
|
||||
while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {
|
||||
SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
|
||||
OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);
|
||||
OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
|
||||
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
|
||||
}
|
||||
//
|
||||
@@ -624,14 +599,9 @@ Returns:
|
||||
|
||||
if (Status == EFI_SUCCESS) {
|
||||
//
|
||||
// Install PeiInMemory to indicate the Dxeipl is shadowed
|
||||
// Set gInMemory global variable to TRUE to indicate the dxeipl is shadowed.
|
||||
//
|
||||
Status = PeiServicesInstallPpi (&mPpiPeiInMemory);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*(BOOLEAN *) ((UINTN) &gInMemory + (UINTN) DxeIplEntryPoint - (UINTN) _ModuleEntryPoint) = TRUE;
|
||||
Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer());
|
||||
}
|
||||
|
||||
@@ -689,8 +659,9 @@ Returns:
|
||||
//
|
||||
Status = PeiProcessFile (
|
||||
EFI_SECTION_PE32,
|
||||
&FfsHeader,
|
||||
&Pe32Data
|
||||
FfsHeader,
|
||||
&Pe32Data,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
@@ -713,8 +684,9 @@ Returns:
|
||||
EFI_STATUS
|
||||
PeiProcessFile (
|
||||
IN UINT16 SectionType,
|
||||
IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader,
|
||||
OUT VOID **Pe32Data
|
||||
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
|
||||
OUT VOID **Pe32Data,
|
||||
IN EFI_PEI_HOB_POINTERS *OrigHob
|
||||
)
|
||||
/*++
|
||||
|
||||
@@ -762,9 +734,7 @@ Returns:
|
||||
EFI_GUID TempGuid;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
|
||||
EFI_COMPRESSION_SECTION *CompressionSection;
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
|
||||
FfsFileHeader = *RealFfsFileHeader;
|
||||
UINT32 FvAlignment;
|
||||
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_COMPRESSION,
|
||||
@@ -773,7 +743,7 @@ Returns:
|
||||
);
|
||||
|
||||
//
|
||||
// Upon finding a DXE Core file, see if there is first a compression section
|
||||
// First process the compression section
|
||||
//
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
@@ -784,7 +754,7 @@ Returns:
|
||||
|
||||
do {
|
||||
SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
|
||||
OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);
|
||||
OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
|
||||
|
||||
//
|
||||
// Was the DXE Core file encapsulated in a GUID'd section?
|
||||
@@ -881,14 +851,24 @@ Returns:
|
||||
|
||||
switch (CompressionSection->CompressionType) {
|
||||
case EFI_STANDARD_COMPRESSION:
|
||||
DecompressLibrary = &gTianoDecompress;
|
||||
if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {
|
||||
DecompressLibrary = &gTianoDecompress;
|
||||
} else {
|
||||
ASSERT (FALSE);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_CUSTOMIZED_COMPRESSION:
|
||||
//
|
||||
// Load user customized compression protocol.
|
||||
//
|
||||
DecompressLibrary = &gCustomDecompress;
|
||||
if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {
|
||||
DecompressLibrary = &gCustomDecompress;
|
||||
} else {
|
||||
ASSERT (FALSE);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_NOT_COMPRESSED:
|
||||
@@ -939,31 +919,64 @@ Returns:
|
||||
);
|
||||
|
||||
CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
|
||||
if (CmpSection->Type == EFI_SECTION_RAW) {
|
||||
if (CmpSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
|
||||
//
|
||||
// Firmware Volume Image in this Section
|
||||
// Skip the section header to get FvHeader
|
||||
//
|
||||
// Skip the section header and
|
||||
// adjust the pointer alignment to 16
|
||||
//
|
||||
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);
|
||||
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);
|
||||
|
||||
if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
|
||||
FfsFileHeader = NULL;
|
||||
if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
|
||||
//
|
||||
// Adjust Fv Base Address Alignment based on Align Attributes in Fv Header
|
||||
//
|
||||
|
||||
//
|
||||
// When FvImage support Alignment, we need to check whether
|
||||
// its alignment is correct.
|
||||
//
|
||||
if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) {
|
||||
|
||||
//
|
||||
// Calculate the mini alignment for this FvImage
|
||||
//
|
||||
FvAlignment = 1 << (LowBitSet32 (FvHeader->Attributes >> 16) + 1);
|
||||
|
||||
//
|
||||
// If current FvImage base address doesn't meet the its alignment,
|
||||
// we need to reload this FvImage to another correct memory address.
|
||||
//
|
||||
if (((UINTN) FvHeader % FvAlignment) != 0) {
|
||||
DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), FvAlignment);
|
||||
if (DstBuffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (DstBuffer, FvHeader, (UINTN) FvHeader->FvLength);
|
||||
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Build new FvHob for new decompressed Fv image.
|
||||
//
|
||||
BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
|
||||
Status = PeiServicesFfsFindNextFile (
|
||||
EFI_FV_FILETYPE_DXE_CORE,
|
||||
FvHeader,
|
||||
&FfsFileHeader
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
//
|
||||
// Set the original FvHob to unused.
|
||||
//
|
||||
if (OrigHob != NULL) {
|
||||
OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;
|
||||
}
|
||||
|
||||
//
|
||||
// when search FvImage Section return true.
|
||||
//
|
||||
if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
|
||||
*Pe32Data = (VOID *) FvHeader;
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Reture the FfsHeader that contain Pe32Data.
|
||||
//
|
||||
*RealFfsFileHeader = FfsFileHeader;
|
||||
return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data);
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -982,10 +995,13 @@ Returns:
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
OccupiedCmpSectionLength = GetOccupiedSize (CmpSectionLength, 4);
|
||||
OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);
|
||||
CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
|
||||
} while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
|
||||
}
|
||||
//
|
||||
// End of the decompression activity
|
||||
//
|
||||
|
||||
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
|
||||
FileSize = FfsFileHeader->Size[0] & 0xFF;
|
||||
@@ -993,11 +1009,17 @@ Returns:
|
||||
FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
|
||||
FileSize &= 0x00FFFFFF;
|
||||
} while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);
|
||||
|
||||
|
||||
//
|
||||
// End of the decompression activity
|
||||
// search all sections (compression and non compression) in this FFS, don't
|
||||
// find expected section.
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
} else {
|
||||
//
|
||||
// For those FFS that doesn't contain compression section, directly search
|
||||
// PE or TE section in this FFS.
|
||||
//
|
||||
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_PE32,
|
||||
@@ -1021,3 +1043,4 @@ Returns:
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,7 @@ Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeIpl.h>
|
||||
#include "DxeIpl.h"
|
||||
|
||||
EFI_STATUS
|
||||
CreateArchSpecificHobs (
|
||||
|
@@ -17,7 +17,7 @@ Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeIpl.h>
|
||||
#include "DxeIpl.h"
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
|
296
EdkModulePkg/Core/DxeIplPeim/Ia32/LongMode.S
Normal file
296
EdkModulePkg/Core/DxeIplPeim/Ia32/LongMode.S
Normal file
@@ -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:
|
||||
|
||||
|
||||
|
294
EdkModulePkg/Core/DxeIplPeim/Ia32/LongMode.asm
Normal file
294
EdkModulePkg/Core/DxeIplPeim/Ia32/LongMode.asm
Normal file
@@ -0,0 +1,294 @@
|
||||
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
|
||||
|
160
EdkModulePkg/Core/DxeIplPeim/Ia32/VirtualMemory.c
Normal file
160
EdkModulePkg/Core/DxeIplPeim/Ia32/VirtualMemory.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*++
|
||||
|
||||
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.
|
||||
|
||||
Module Name:
|
||||
VirtualMemory.c
|
||||
|
||||
Abstract:
|
||||
|
||||
x64 Virtual Memory Management Services in the form of an IA-32 driver.
|
||||
Used to establish a 1:1 Virtual to Physical Mapping that is required to
|
||||
enter Long Mode (x64 64-bit mode).
|
||||
|
||||
While we make a 1:1 mapping (identity mapping) for all physical pages
|
||||
we still need to use the MTRR's to ensure that the cachability attirbutes
|
||||
for all memory regions is correct.
|
||||
|
||||
The basic idea is to use 2MB page table entries where ever possible. If
|
||||
more granularity of cachability is required then 4K page tables are used.
|
||||
|
||||
References:
|
||||
1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel
|
||||
2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
|
||||
3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
|
||||
|
||||
--*/
|
||||
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
EFI_PHYSICAL_ADDRESS
|
||||
CreateIdentityMappingPageTables (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocates and fills in the Page Directory and Page Table Entries to
|
||||
establish a 1:1 Virtual to Physical mapping.
|
||||
|
||||
Arguments:
|
||||
|
||||
NumberOfProcessorPhysicalAddressBits - Number of processor address bits to use.
|
||||
Limits the number of page table entries
|
||||
to the physical address space.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS The 1:1 Virtual to Physical identity mapping was created
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 RegEax;
|
||||
UINT8 PhysicalAddressBits;
|
||||
EFI_PHYSICAL_ADDRESS PageAddress;
|
||||
UINTN IndexOfPml4Entries;
|
||||
UINTN IndexOfPdpEntries;
|
||||
UINTN IndexOfPageDirectoryEntries;
|
||||
UINTN NumberOfPml4EntriesNeeded;
|
||||
UINTN NumberOfPdpEntriesNeeded;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
|
||||
PAGE_TABLE_ENTRY *PageDirectoryEntry;
|
||||
|
||||
//
|
||||
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
|
||||
//
|
||||
PageMap = AllocatePages (1);
|
||||
ASSERT (PageMap != NULL);
|
||||
|
||||
//
|
||||
// Get physical address bits supported.
|
||||
//
|
||||
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
|
||||
if (RegEax >= 0x80000008) {
|
||||
AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
|
||||
PhysicalAddressBits = (UINT8) RegEax;
|
||||
} else {
|
||||
PhysicalAddressBits = 36;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the table entries needed.
|
||||
//
|
||||
if (PhysicalAddressBits <= 39 ) {
|
||||
NumberOfPml4EntriesNeeded = 1;
|
||||
NumberOfPdpEntriesNeeded = 1 << (PhysicalAddressBits - 30);
|
||||
} else {
|
||||
NumberOfPml4EntriesNeeded = 1 << (PhysicalAddressBits - 39);
|
||||
NumberOfPdpEntriesNeeded = 512;
|
||||
}
|
||||
|
||||
PageMapLevel4Entry = PageMap;
|
||||
PageAddress = 0;
|
||||
for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
|
||||
//
|
||||
// Each PML4 entry points to a page of Page Directory Pointer entires.
|
||||
// So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
|
||||
//
|
||||
PageDirectoryPointerEntry = AllocatePages (1);
|
||||
ASSERT (PageDirectoryPointerEntry != NULL);
|
||||
|
||||
//
|
||||
// Make a PML4 Entry
|
||||
//
|
||||
PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
|
||||
PageMapLevel4Entry->Bits.ReadWrite = 1;
|
||||
PageMapLevel4Entry->Bits.Present = 1;
|
||||
|
||||
for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
|
||||
//
|
||||
// Each Directory Pointer entries points to a page of Page Directory entires.
|
||||
// So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
|
||||
//
|
||||
PageDirectoryEntry = AllocatePages (1);
|
||||
ASSERT (PageDirectoryEntry != NULL);
|
||||
|
||||
//
|
||||
// Fill in a Page Directory Pointer Entries
|
||||
//
|
||||
PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;
|
||||
PageDirectoryPointerEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryPointerEntry->Bits.Present = 1;
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += 0x200000) {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
|
||||
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryEntry->Bits.Present = 1;
|
||||
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// For the PML4 entries we are not using fill in a null entry.
|
||||
// For now we just copy the first entry.
|
||||
//
|
||||
for (; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entry++) {
|
||||
CopyMem (
|
||||
PageMapLevel4Entry,
|
||||
PageMap,
|
||||
sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
|
||||
);
|
||||
}
|
||||
|
||||
return (EFI_PHYSICAL_ADDRESS) (UINTN)PageMap; // FIXME
|
||||
}
|
||||
|
86
EdkModulePkg/Core/DxeIplPeim/Ia32/VirtualMemory.h
Normal file
86
EdkModulePkg/Core/DxeIplPeim/Ia32/VirtualMemory.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*++
|
||||
|
||||
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.
|
||||
|
||||
Module Name:
|
||||
VirtualMemory.h
|
||||
|
||||
Abstract:
|
||||
|
||||
x64 Long Mode Virtual Memory Management Definitions
|
||||
|
||||
References:
|
||||
1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel
|
||||
2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
|
||||
3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
|
||||
4) AMD64 Architecture Programmer's Manual Volume 2: System Programming
|
||||
--*/
|
||||
#ifndef _VIRTUAL_MEMORY_H_
|
||||
#define _VIRTUAL_MEMORY_H_
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
//
|
||||
// Page-Map Level-4 Offset (PML4) and
|
||||
// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
|
||||
//
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
|
||||
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
|
||||
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
|
||||
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
|
||||
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
|
||||
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
||||
UINT64 Reserved:1; // Reserved
|
||||
UINT64 MustBeZero:2; // Must Be Zero
|
||||
UINT64 Available:3; // Available for use by system software
|
||||
UINT64 PageTableBaseAddress:40; // Page Table Base Address
|
||||
UINT64 AvabilableHigh:11; // Available for use by system software
|
||||
UINT64 Nx:1; // No Execute bit
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} PAGE_MAP_AND_DIRECTORY_POINTER;
|
||||
|
||||
//
|
||||
// Page Table Entry 2MB
|
||||
//
|
||||
typedef union {
|
||||
struct {
|
||||
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
|
||||
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
|
||||
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
|
||||
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
|
||||
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
|
||||
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
||||
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
|
||||
UINT64 MustBe1:1; // Must be 1
|
||||
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
|
||||
UINT64 Available:3; // Available for use by system software
|
||||
UINT64 PAT:1; //
|
||||
UINT64 MustBeZero:8; // Must be zero;
|
||||
UINT64 PageTableBaseAddress:31; // Page Table Base Address
|
||||
UINT64 AvabilableHigh:11; // Available for use by system software
|
||||
UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} PAGE_TABLE_ENTRY;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
EFI_PHYSICAL_ADDRESS
|
||||
CreateIdentityMappingPageTables (
|
||||
VOID
|
||||
)
|
||||
;
|
||||
|
||||
#endif
|
@@ -19,7 +19,7 @@ Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeIpl.h>
|
||||
#include "DxeIpl.h"
|
||||
|
||||
EFI_STATUS
|
||||
CreateArchSpecificHobs (
|
||||
|
@@ -17,7 +17,7 @@ Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeIpl.h>
|
||||
#include "DxeIpl.h"
|
||||
|
||||
EFI_STATUS
|
||||
PeiImageRead (
|
||||
|
55
EdkModulePkg/Core/DxeIplPeim/Non-existing.c
Normal file
55
EdkModulePkg/Core/DxeIplPeim/Non-existing.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/** @file
|
||||
Non-existing functions other than Ia32 architecture.
|
||||
|
||||
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.
|
||||
|
||||
Module Name: Non-existing.c
|
||||
|
||||
**/
|
||||
|
||||
#include "DxeIpl.h"
|
||||
|
||||
EFI_PHYSICAL_ADDRESS
|
||||
CreateIdentityMappingPageTables (
|
||||
IN UINT32 NumberOfProcessorPhysicalAddressBits
|
||||
)
|
||||
{
|
||||
//
|
||||
// This function cannot work on non-Ia32 architecture.
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
//
|
||||
// This function cannot work on non-Ia32 architecture.
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
VOID
|
||||
LoadGo64Gdt(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
//
|
||||
// This function cannot work on non-Ia32 architecture.
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
}
|
Reference in New Issue
Block a user