Add missing files in msa file and add module description in msa file, and reorganize DriverSample and DxeIplX64 module directory.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@927 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lgao4
2006-07-12 23:38:53 +00:00
parent 47a16b84f2
commit 5343eab11a
16 changed files with 215 additions and 34 deletions

View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--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,
<!--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.-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
@@ -16,11 +16,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
<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>
@@ -78,6 +78,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
</LibraryClassDefinitions>
<SourceFiles>
<Filename>DxeLoad.c</Filename>
<Filename>DxeIpl.h</Filename>
<Filename>DxeIpl.dxs</Filename>
<Filename SupArchList="IA32">Ia32/ImageRead.c</Filename>
<Filename SupArchList="IA32">Ia32/DxeLoadFunc.c</Filename>

View File

@@ -1,143 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--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.-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>DxeIplX64</ModuleName>
<ModuleType>PEIM</ModuleType>
<GuidValue>0c55bdf7-d71d-4962-8fcb-348773e48929</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for DxeIplX64 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 64-bit DXE Core.</Description>
<Copyright>Copyright 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,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>DxeIplX64</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeimEntryPoint</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>HobLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PerformanceLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeiServicesLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>ReportStatusCodeLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>CacheMaintenanceLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>EdkPeCoffLoaderLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiDecompressLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>TianoDecompressLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>CustomDecompressLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeiServicesTablePointerLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>MemoryAllocationLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>EdkPeCoffLoaderX64Lib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>DxeIpl.dxs</Filename>
<Filename>DxeLoadX64.c</Filename>
<Filename SupArchList="IA32">x64/ImageRead.c</Filename>
<Filename SupArchList="IA32">x64/LongMode.asm</Filename>
<Filename SupArchList="IA32">x64/DxeLoadFunc.c</Filename>
<Filename SupArchList="IA32">x64/VirtualMemory.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiDecompressProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiTianoDecompressProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiCustomizedDecompressProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<PPIs>
<Ppi Usage="SOMETIMES_PRODUCED">
<PpiCName>gEfiDxeIplPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_PRODUCED">
<PpiCName>gEfiPeiFvFileLoaderPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_PRODUCED">
<PpiCName>gEfiEndOfPeiSignalPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_CONSUMED">
<PpiCName>gEfiPeiRecoveryModulePpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_CONSUMED">
<PpiCName>gEfiPeiS3ResumePpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_CONSUMED">
<PpiCName>gEfiPeiSectionExtractionPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_CONSUMED">
<PpiCName>gEfiPeiSecurityPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="PRIVATE">
<PpiCName>gPeiInMemoryGuid</PpiCName>
</Ppi>
</PPIs>
<Guids>
<GuidCNames Usage="ALWAYS_CONSUMED">
<GuidCName>gEfiPeiPeCoffLoaderGuid</GuidCName>
</GuidCNames>
</Guids>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<ModuleEntryPoint>PeimInitializeDxeIpl</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -1,997 +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.
Module Name:
DxeLoad.c
Abstract:
Last PEIM.
Responsibility of this module is to load the DXE Core from a Firmware Volume.
--*/
#include <DxeIpl.h>
#pragma warning( disable : 4305 )
BOOLEAN gInMemory = FALSE;
//
// GUID for EM64T
//
#define EFI_PPI_NEEDED_BY_DXE \
{ \
0x4d37da42, 0x3a0c, 0x4eda, 0xb9, 0xeb, 0xbc, 0x0e, 0x1d, 0xb4, 0x71, 0x3b \
}
EFI_GUID mPpiNeededByDxeGuid = EFI_PPI_NEEDED_BY_DXE;
//
// Module Globals used in the DXE to PEI handoff
// These must be module globals, so the stack can be switched
//
static EFI_DXE_IPL_PPI mDxeIplPpi = {
DxeLoadCore
};
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),
&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 = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiEndOfPeiSignalPpiGuid,
NULL
};
DECOMPRESS_LIBRARY gEfiDecompress = {
UefiDecompressGetInfo,
UefiDecompress
};
DECOMPRESS_LIBRARY gTianoDecompress = {
TianoDecompressGetInfo,
TianoDecompress
};
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 (
IN EFI_FFS_FILE_HEADER *FfsHeader,
IN EFI_PEI_SERVICES **PeiServices
)
/*++
Routine Description:
Initializes the Dxe Ipl PPI
Arguments:
FfsHeader - Pointer to FFS file header
PeiServices - General purpose services available to every PEIM.
Returns:
EFI_SUCCESS
--*/
{
EFI_STATUS Status;
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
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)) {
//
// The DxeIpl has not yet been shadowed
//
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
//
// 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
//
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;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DxeLoadCore (
IN EFI_DXE_IPL_PPI *This,
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_HOB_POINTERS HobList
)
/*++
Routine Description:
Main entry point to last PEIM
Arguments:
This - Entry point for DXE IPL PPI
PeiServices - General purpose services available to every PEIM.
HobList - Address to the Pei HOB list
Returns:
EFI_SUCCESS - DEX core was successfully loaded.
EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.
--*/
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS TopOfStack;
EFI_PHYSICAL_ADDRESS BaseOfStack;
EFI_PHYSICAL_ADDRESS BspStore;
EFI_GUID DxeCoreFileName;
VOID *DxeCorePe32Data;
EFI_PHYSICAL_ADDRESS DxeCoreAddress;
UINT64 DxeCoreSize;
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
EFI_BOOT_MODE BootMode;
EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery;
EFI_PEI_S3_RESUME_PPI *S3Resume;
EFI_PHYSICAL_ADDRESS PageTables;
TopOfStack = 0;
BaseOfStack = 0;
BspStore = 0;
Status = EFI_SUCCESS;
//
// if in S3 Resume, restore configure
//
Status = PeiServicesGetBootMode (&BootMode);
if (!EFI_ERROR (Status) && (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
//
#ifdef EFI_NT_EMULATOR
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
ASSERT (PeiEfiPeiPeCoffLoader != NULL);
#else
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderX64Protocol ();
#endif
#if 0
Status = InstallEfiPeiPeCoffLoader64 (PeiServices, &PeiEfiPeiPeCoffLoader, NULL);
ASSERT_EFI_ERROR (Status);
#endif
//
// Allocate 128KB for the Stack
//
PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
ASSERT (BaseOfStack != 0);
//
// Compute the top of the stack we were allocated. Pre-allocate a 32 bytes
// for safety (PpisNeededByDxe and DxeCore).
//
TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;
//
// Add architecture-specifc HOBs (including the BspStore HOB)
//
Status = CreateArchSpecificHobs (&BspStore);
ASSERT_EFI_ERROR (Status);
//
// See if we are in crisis recovery
//
Status = PeiServicesGetBootMode (&BootMode);
if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) {
Status = PeiServicesLocatePpi (
&gEfiPeiRecoveryModulePpiGuid,
0,
NULL,
(VOID **)&PeiRecovery
);
ASSERT_EFI_ERROR (Status);
Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
ASSERT_EFI_ERROR (Status);
}
//
// Find the DXE Core in a Firmware Volume
//
Status = PeiFindFile (
EFI_FV_FILETYPE_DXE_CORE,
EFI_SECTION_PE32,
&DxeCoreFileName,
&DxeCorePe32Data
);
ASSERT_EFI_ERROR (Status);
//
// Transfer control to the DXE Core
// The handoff state is simply a pointer to the HOB list
//
// PEI_PERF_END (PeiServices, L"DxeIpl", NULL, 0);
Status = PeiServicesInstallPpi (&mPpiSignal);
ASSERT_EFI_ERROR (Status);
//
// 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);
//
// Load the DXE Core from a Firmware Volume
//
Status = PeiLoadx64File (
PeiEfiPeiPeCoffLoader,
DxeCorePe32Data,
EfiBootServicesData,
&DxeCoreAddress,
&DxeCoreSize,
&DxeCoreEntryPoint
);
ASSERT_EFI_ERROR (Status);
//
//
// Add HOB for the DXE Core
//
BuildModuleHob (
&DxeCoreFileName,
DxeCoreAddress,
DxeCoreSize,
DxeCoreEntryPoint
);
//
// Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
//
REPORT_STATUS_CODE (
EFI_PROGRESS_CODE,
EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
);
DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));
//
// 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
);
//
// If we get here, then the DXE Core returned. This is an error
//
ASSERT_EFI_ERROR (Status);
return EFI_OUT_OF_RESOURCES;
}
EFI_STATUS
PeiFindFile (
IN UINT8 Type,
IN UINT16 SectionType,
OUT EFI_GUID *FileName,
OUT VOID **Pe32Data
)
/*++
Routine Description:
Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
described in the HOB list. Able to search in a compression set in a FFS file.
But only one level of compression is supported, that is, not able to search
in a compression set that is within another compression set.
Arguments:
Type - The Type of file to retrieve
SectionType - The type of section to retrieve from a file
FileName - The name of the file found in the Firmware Volume
Pe32Data - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
Returns:
EFI_SUCCESS - The file was found, and the name is returned in FileName, and a pointer to
the PE/COFF image is returned in Pe32Data
EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
--*/
{
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_FFS_FILE_HEADER *FfsFileHeader;
VOID *SectionData;
EFI_STATUS Status;
EFI_PEI_HOB_POINTERS Hob;
FwVolHeader = NULL;
FfsFileHeader = NULL;
SectionData = NULL;
//
// Foreach Firmware Volume, look for a specified type
// of file and break out when one is found
//
Hob.Raw = GetHobList ();
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (Hob.FirmwareVolume->BaseAddress);
Status = PeiServicesFfsFindNextFile (
Type,
FwVolHeader,
&FfsFileHeader
);
if (!EFI_ERROR (Status)) {
Status = PeiProcessFile (
SectionType,
&FfsFileHeader,
Pe32Data
);
CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));
return Status;
}
Hob.Raw = GET_NEXT_HOB (Hob);
}
return EFI_NOT_FOUND;
}
EFI_STATUS
PeiLoadx64File (
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader,
IN VOID *Pe32Data,
IN EFI_MEMORY_TYPE MemoryType,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
)
/*++
Routine Description:
Loads and relocates a PE/COFF image into memory.
Arguments:
PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
ImageAddress - The base address of the relocated PE/COFF image
ImageSize - The size of the relocated PE/COFF image
EntryPoint - The entry point of the relocated PE/COFF image
Returns:
EFI_SUCCESS - The file was loaded and relocated
EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
--*/
{
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_PHYSICAL_ADDRESS MemoryBuffer;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = Pe32Data;
Status = GetImageReadFunction (&ImageContext);
ASSERT_EFI_ERROR (Status);
Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Allocate Memory for the image
//
//
// Allocate Memory for the image
//
PeiServicesAllocatePages (MemoryType, EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize), &MemoryBuffer);
ImageContext.ImageAddress = MemoryBuffer;
ASSERT (ImageContext.ImageAddress != 0);
//
// Load the image to our new buffer
//
Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Relocate the image in our new buffer
//
Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Flush the instruction cache so the image data is written before we execute it
//
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
*ImageAddress = ImageContext.ImageAddress;
*ImageSize = ImageContext.ImageSize;
*EntryPoint = ImageContext.EntryPoint;
return EFI_SUCCESS;
}
EFI_STATUS
ShadowDxeIpl (
IN EFI_FFS_FILE_HEADER *DxeIplFileHeader,
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader
)
/*++
Routine Description:
Shadow the DXE IPL to a different memory location. This occurs after permanent
memory has been discovered.
Arguments:
DxeIplFileHeader - Pointer to the FFS file header of the DXE IPL driver
PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
Returns:
EFI_SUCCESS - DXE IPL was successfully shadowed to a different memory location.
EFI_ ERROR - The shadow was unsuccessful.
--*/
{
UINTN SectionLength;
UINTN OccupiedSectionLength;
EFI_PHYSICAL_ADDRESS DxeIplAddress;
UINT64 DxeIplSize;
EFI_PHYSICAL_ADDRESS DxeIplEntryPoint;
EFI_STATUS Status;
EFI_COMMON_SECTION_HEADER *Section;
Section = (EFI_COMMON_SECTION_HEADER *) (DxeIplFileHeader + 1);
while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {
SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
}
//
// Relocate DxeIpl into memory by using loadfile service
//
Status = PeiLoadx64File (
PeiEfiPeiPeCoffLoader,
(VOID *) (Section + 1),
EfiBootServicesData,
&DxeIplAddress,
&DxeIplSize,
&DxeIplEntryPoint
);
if (Status == EFI_SUCCESS) {
//
// Install PeiInMemory to indicate the Dxeipl is shadowed
//
Status = PeiServicesInstallPpi (&mPpiPeiInMemory);
if (EFI_ERROR (Status)) {
return Status;
}
Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer());
}
return Status;
}
EFI_STATUS
EFIAPI
DxeIplLoadFile (
IN EFI_PEI_FV_FILE_LOADER_PPI *This,
IN EFI_FFS_FILE_HEADER *FfsHeader,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
)
/*++
Routine Description:
Given a pointer to an FFS file containing a PE32 image, get the
information on the PE32 image, and then "load" it so that it
can be executed.
Arguments:
This - pointer to our file loader protocol
FfsHeader - pointer to the FFS file header of the FFS file that
contains the PE32 image we want to load
ImageAddress - returned address where the PE32 image is loaded
ImageSize - returned size of the loaded PE32 image
EntryPoint - entry point to the loaded PE32 image
Returns:
EFI_SUCCESS - The FFS file was successfully loaded.
EFI_ERROR - Unable to load the FFS file.
--*/
{
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
EFI_STATUS Status;
VOID *Pe32Data;
Pe32Data = NULL;
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
//
// Preprocess the FFS file to get a pointer to the PE32 information
// in the enclosed PE32 image.
//
Status = PeiProcessFile (
EFI_SECTION_PE32,
&FfsHeader,
&Pe32Data
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Load the PE image from the FFS file
//
Status = PeiLoadx64File (
PeiEfiPeiPeCoffLoader,
Pe32Data,
EfiBootServicesData,
ImageAddress,
ImageSize,
EntryPoint
);
return Status;
}
EFI_STATUS
PeiProcessFile (
IN UINT16 SectionType,
IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader,
OUT VOID **Pe32Data
)
/*++
Routine Description:
Arguments:
SectionType - The type of section in the FFS file to process.
FfsFileHeader - Pointer to the FFS file to process, looking for the
specified SectionType
Pe32Data - returned pointer to the start of the PE32 image found
in the FFS file.
Returns:
EFI_SUCCESS - found the PE32 section in the FFS file
--*/
{
EFI_STATUS Status;
VOID *SectionData;
DECOMPRESS_LIBRARY *DecompressLibrary;
UINT8 *DstBuffer;
UINT8 *ScratchBuffer;
UINT32 DstBufferSize;
UINT32 ScratchBufferSize;
EFI_COMMON_SECTION_HEADER *CmpSection;
UINTN CmpSectionLength;
UINTN OccupiedCmpSectionLength;
VOID *CmpFileData;
UINTN CmpFileSize;
EFI_COMMON_SECTION_HEADER *Section;
UINTN SectionLength;
UINTN OccupiedSectionLength;
UINT64 FileSize;
EFI_GUID_DEFINED_SECTION *GuidedSectionHeader;
UINT32 AuthenticationStatus;
EFI_PEI_SECTION_EXTRACTION_PPI *SectionExtract;
UINT32 BufferSize;
UINT8 *Buffer;
EFI_PEI_SECURITY_PPI *Security;
BOOLEAN StartCrisisRecovery;
EFI_GUID TempGuid;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_COMPRESSION_SECTION *CompressionSection;
EFI_FFS_FILE_HEADER *FfsFileHeader;
FfsFileHeader = *RealFfsFileHeader;
Status = PeiServicesFfsFindSectionData (
EFI_SECTION_COMPRESSION,
FfsFileHeader,
&SectionData
);
//
// Upon finding a DXE Core file, see if there is first a compression section
//
if (!EFI_ERROR (Status)) {
//
// Yes, there is a compression section, so extract the contents
// Decompress the image here
//
Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));
do {
SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);
//
// Was the DXE Core file encapsulated in a GUID'd section?
//
if (Section->Type == EFI_SECTION_GUID_DEFINED) {
//
// Locate the GUID'd Section Extractor
//
GuidedSectionHeader = (VOID *) (Section + 1);
//
// This following code constitutes the addition of the security model
// to the DXE IPL.
//
//
// Set a default authenticatino state
//
AuthenticationStatus = 0;
Status = PeiServicesLocatePpi (
&gEfiPeiSectionExtractionPpiGuid,
0,
NULL,
(VOID **)&SectionExtract
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Verify Authentication State
//
CopyMem (&TempGuid, Section + 1, sizeof (EFI_GUID));
Status = SectionExtract->PeiGetSection (
GetPeiServicesTablePointer(),
SectionExtract,
(EFI_SECTION_TYPE *) &SectionType,
&TempGuid,
0,
(VOID **) &Buffer,
&BufferSize,
&AuthenticationStatus
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// If not ask the Security PPI, if exists, for disposition
//
//
Status = PeiServicesLocatePpi (
&gEfiPeiSecurityPpiGuid,
0,
NULL,
(VOID **)&Security
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = Security->AuthenticationState (
GetPeiServicesTablePointer(),
(struct _EFI_PEI_SECURITY_PPI *) Security,
AuthenticationStatus,
FfsFileHeader,
&StartCrisisRecovery
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// If there is a security violation, report to caller and have
// the upper-level logic possible engender a crisis recovery
//
if (StartCrisisRecovery) {
return EFI_SECURITY_VIOLATION;
}
}
if (Section->Type == EFI_SECTION_PE32) {
//
// This is what we want
//
*Pe32Data = (VOID *) (Section + 1);
return EFI_SUCCESS;
} else if (Section->Type == EFI_SECTION_COMPRESSION) {
//
// This is a compression set, expand it
//
CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
switch (CompressionSection->CompressionType) {
case EFI_STANDARD_COMPRESSION:
DecompressLibrary = &gTianoDecompress;
break;
case EFI_CUSTOMIZED_COMPRESSION:
//
// Load user customized compression protocol.
//
DecompressLibrary = &gCustomDecompress;
break;
case EFI_NOT_COMPRESSED:
default:
//
// Need to support not compressed file
//
ASSERT_EFI_ERROR (Status);
return EFI_NOT_FOUND;
}
Status = DecompressLibrary->GetInfo (
(UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
(UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
&DstBufferSize,
&ScratchBufferSize
);
if (EFI_ERROR (Status)) {
//
// GetInfo failed
//
return EFI_NOT_FOUND;
}
//
// Allocate scratch buffer
//
ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
if (ScratchBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Allocate destination buffer
//
DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
if (DstBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Call decompress function
//
Status = DecompressLibrary->Decompress (
(CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
DstBuffer,
ScratchBuffer
);
CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
if (CmpSection->Type == EFI_SECTION_RAW) {
//
// Skip the section header and
// adjust the pointer alignment to 16
//
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);
if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
FfsFileHeader = NULL;
BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
Status = PeiServicesFfsFindNextFile (
EFI_FV_FILETYPE_DXE_CORE,
FvHeader,
&FfsFileHeader
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Reture the FfsHeader that contain Pe32Data.
//
*RealFfsFileHeader = FfsFileHeader;
return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data);
}
}
//
// Decompress successfully.
// Loop the decompressed data searching for expected section.
//
CmpFileData = (VOID *) DstBuffer;
CmpFileSize = DstBufferSize;
do {
CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;
if (CmpSection->Type == EFI_SECTION_PE32) {
//
// This is what we want
//
*Pe32Data = (VOID *) (CmpSection + 1);
return EFI_SUCCESS;
}
OccupiedCmpSectionLength = GetOccupiedSize (CmpSectionLength, 4);
CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
} while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
}
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
FileSize = FfsFileHeader->Size[0] & 0xFF;
FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;
FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
FileSize &= 0x00FFFFFF;
} while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);
//
// End of the decompression activity
//
} else {
Status = PeiServicesFfsFindSectionData (
EFI_SECTION_PE32,
FfsFileHeader,
&SectionData
);
if (EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData (
EFI_SECTION_TE,
FfsFileHeader,
&SectionData
);
if (EFI_ERROR (Status)) {
return Status;
}
}
}
*Pe32Data = SectionData;
return EFI_SUCCESS;
}

View File

@@ -1,53 +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.
Module Name:
DxeLoadFunc.c
Abstract:
Ia32-specifc functionality for DxeLoad X64 Lakeport.
--*/
#include <DxeIpl.h>
EFI_STATUS
CreateArchSpecificHobs (
OUT EFI_PHYSICAL_ADDRESS *BspStore
)
/*++
Routine Description:
Creates architecture-specific HOBs.
Note: New parameters should NOT be added for any HOBs that are added to this
function. BspStore is a special case because it is required for the
call to SwitchStacks() in DxeLoad().
Arguments:
PeiServices - General purpose services available to every PEIM.
BspStore - The address of the BSP Store for those architectures that need
it. Otherwise 0.
Returns:
EFI_SUCCESS - The HOBs were created successfully.
--*/
{
*BspStore = 0;
return EFI_SUCCESS;
}

View File

@@ -1,106 +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.
Module Name:
ImageRead.c
Abstract:
--*/
#include <DxeIpl.h>
EFI_STATUS
EFIAPI
PeiImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
Arguments:
FileHandle - The handle to the PE/COFF file
FileOffset - The offset, in bytes, into the file to read
ReadSize - The number of bytes to read from the file starting at FileOffset
Buffer - A pointer to the buffer to read the data into.
Returns:
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
--*/
{
CHAR8 *Destination8;
CHAR8 *Source8;
UINTN Length;
Destination8 = Buffer;
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
Length = *ReadSize;
while (Length--) {
*(Destination8++) = *(Source8++);
}
return EFI_SUCCESS;
}
EFI_STATUS
GetImageReadFunction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
/*++
Routine Description:
Support routine to return the PE32 Image Reader.
If the PeiImageRead() function is less than a page
in legnth. If the function is more than a page the DXE IPL will crash!!!!
Arguments:
ImageContext - The context of the image being loaded
Returns:
EFI_SUCCESS - If Image function location is found
--*/
{
VOID *MemoryBuffer;
if (gInMemory) {
ImageContext->ImageRead = PeiImageRead;
return EFI_SUCCESS;
}
//
// BugBug; This code assumes PeiImageRead() is less than a page in size!
// Allocate a page so we can shaddow the read function from FLASH into
// memory to increase performance.
//
MemoryBuffer = AllocateCopyPool (0x400, (VOID *)(UINTN) PeiImageRead);
ASSERT (MemoryBuffer != NULL);
ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;
return EFI_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,434 +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.
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"
x64_MTRR_VARIABLE_RANGE *mMTRRVariableRange;
x64_MTRR_FIXED_RANGE mMTRRFixedRange;
//
// Physial memory limit values for each of the 11 fixed MTRRs
//
UINTN mFixedRangeLimit[] = {
0x7FFFF, // Fixed MTRR #0 describes 0x00000..0x7FFFF
0x9FFFF, // Fixed MTRR #1 describes 0x80000..0x9FFFF
0xBFFFF, // Fixed MTRR #2 describes 0xA0000..0xBFFFF
0xC7FFF, // Fixed MTRR #3 describes 0xC0000..0xC7FFF
0xCFFFF, // Fixed MTRR #4 describes 0xC8000..0xCFFFF
0xD7FFF, // Fixed MTRR #5 describes 0xD0000..0xD7FFF
0xDFFFF, // Fixed MTRR #6 describes 0xD8000..0xDFFFF
0xE7FFF, // Fixed MTRR #7 describes 0xE0000..0xE7FFF
0xEFFFF, // Fixed MTRR #8 describes 0xE8000..0xEFFFF
0xF7FFF, // Fixed MTRR #9 describes 0xF0000..0xF7FFF
0xFFFFF // Fixed MTRR #10 describes 0xF8000..0xFFFFF
};
//
// The size, in bits, of each of the 11 fixed MTRR.
//
UINTN mFixedRangeShift[] = {
16, // Fixed MTRR #0 describes 8, 64 KB ranges
14, // Fixed MTRR #1 describes 8, 16 KB ranges
14, // Fixed MTRR #2 describes 8, 16 KB ranges
12, // Fixed MTRR #3 describes 8, 4 KB ranges
12, // Fixed MTRR #4 describes 8, 4 KB ranges
12, // Fixed MTRR #5 describes 8, 4 KB ranges
12, // Fixed MTRR #6 describes 8, 4 KB ranges
12, // Fixed MTRR #7 describes 8, 4 KB ranges
12, // Fixed MTRR #8 describes 8, 4 KB ranges
12, // Fixed MTRR #9 describes 8, 4 KB ranges
12 // Fixed MTRR #10 describes 8, 4 KB ranges
};
UINTN mPowerOf2[] = {
1,
2,
4,
8,
16,
32,
64,
128,
256,
512
};
x64_MTRR_MEMORY_TYPE
EfiGetMTRRMemoryType (
IN EFI_PHYSICAL_ADDRESS Address
)
/*++
Routine Description:
Retrieves the memory type from the MTRR that describes a physical address.
Arguments:
VariableRange - Set of Variable MTRRs
FixedRange - Set of Fixed MTRRs
Address - The physical address for which the MTRR memory type is being retrieved
Returns:
The MTRR Memory Type for the physical memory specified by Address.
--*/
{
UINTN Index;
UINTN TypeIndex;
BOOLEAN Found;
x64_MTRR_MEMORY_TYPE VariableType;
EFI_PHYSICAL_ADDRESS MaskBase;
EFI_PHYSICAL_ADDRESS PhysMask;
//
// If the MTRRs are disabled, then return the Uncached Memory Type
//
if (mMTRRFixedRange.DefaultType.Bits.E == 0) {
return Uncached;
}
//
// If the CPU supports Fixed MTRRs and the Fixed MTRRs are enabled, then
// see if Address falls into one of the Fixed MTRRs
//
if (mMTRRFixedRange.Capabilities.Bits.FIX && mMTRRFixedRange.DefaultType.Bits.FE) {
//
// Loop though 11 fixed MTRRs
//
for (Index = 0; Index < 11; Index++) {
//
// Check for a matching range
//
if (Address <= mFixedRangeLimit[Index]) {
//
// Compute the offset address into the MTRR bu subtrating the base address of the MTRR
//
if (Index > 0) {
Address = Address - (mFixedRangeLimit[Index-1] + 1);
}
//
// Retrieve the index into the MTRR to extract the memory type. The range is 0..7
//
TypeIndex = (UINTN)RShiftU64 (Address, mFixedRangeShift[Index]);
//
// Retrieve and return the memory type for the matching range
//
return mMTRRFixedRange.Fixed[Index].Type[TypeIndex];
}
}
}
//
// If Address was not found in a Fixed MTRR, then search the Variable MTRRs
//
for (Index = 0, Found = FALSE, VariableType = WriteBack; Index < mMTRRFixedRange.Capabilities.Bits.VCNT; Index++) {
//
// BugBug: __aullshr complier error
//
if ((mMTRRVariableRange[Index].PhysMask.Uint64 & 0x800) == 0x800) {
//if (mMTRRVariableRange[Index].PhysMask.Bits.Valid == 1) {
PhysMask = mMTRRVariableRange[Index].PhysMask.Uint64 & ~0xfff;
MaskBase = PhysMask & (mMTRRVariableRange[Index].PhysBase.Uint64 & ~0xfff);
if (MaskBase == (PhysMask & Address)) {
//
// Check to see how many matches we find
//
Found = TRUE;
if ((mMTRRVariableRange[Index].PhysBase.Bits.Type == Uncached) || (VariableType == Uncached)) {
//
// If any matching region uses UC, the memory region is UC
//
VariableType = Uncached;
} else if ((mMTRRVariableRange[Index].PhysBase.Bits.Type == WriteThrough) || (VariableType == WriteThrough)){
//
// If it's WT and WB then set it to WT. If it's WT and other type it's undefined
//
VariableType = WriteThrough;
} else {
VariableType = mMTRRVariableRange[Index].PhysBase.Bits.Type;
}
}
}
}
if (Found) {
return VariableType;
}
//
// Address was not found in the Fixed or Variable MTRRs, so return the default memory type
//
return mMTRRFixedRange.DefaultType.Bits.Type;
}
BOOLEAN
CanNotUse2MBPage (
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
/*++
Routine Description:
Test to see if a 2MB aligned page has all the same attributes. If a 2MB page
has more than one attibute type it needs to be split into multiple 4K pages.
Arguments:
BaseAddress - 2MB aligned address to check out
Returns:
TRUE - This 2MB address range (BaseAddress) can NOT be mapped by a 2MB page
FALSE - This 2MB address range can be mapped by a 2MB page
--*/
{
UINTN Index;
x64_MTRR_MEMORY_TYPE MemoryType;
x64_MTRR_MEMORY_TYPE PreviousMemoryType;
//
// Address needs to be 2MB aligned
//
ASSERT ((BaseAddress & 0x1fffff) == 0);
PreviousMemoryType = -1;
for (Index = 0; Index < 512; Index++, BaseAddress += 0x1000) {
MemoryType = EfiGetMTRRMemoryType (BaseAddress);
if ((Index != 0) && (MemoryType != PreviousMemoryType)) {
return TRUE;
}
PreviousMemoryType = MemoryType;
}
//
// All the pages had the same type
//
return FALSE;
}
VOID
Convert2MBPageTo4KPages (
IN x64_PAGE_TABLE_ENTRY_2M *PageDirectoryEntry2MB,
IN EFI_PHYSICAL_ADDRESS PageAddress
)
/*++
Routine Description:
Convert a single 2MB page entry to 512 4K page entries. The attributes for
the 4K pages are read from the MTRR registers.
Arguments:
PageDirectoryEntry2MB - Page directory entry for PageAddress
PageAddress - 2MB algined address of region to convert
Returns:
None
--*/
{
EFI_PHYSICAL_ADDRESS Address;
x64_PAGE_DIRECTORY_ENTRY_4K *PageDirectoryEntry4k;
x64_PAGE_TABLE_ENTRY_4K *PageTableEntry;
UINTN Index1;
//
// Allocate the page table entry for the 4K pages
//
PageTableEntry = (x64_PAGE_TABLE_ENTRY_4K *) AllocatePages (1);
ASSERT (PageTableEntry != NULL);
//
// Convert PageDirectoryEntry2MB into a 4K Page Directory
//
PageDirectoryEntry4k = (x64_PAGE_DIRECTORY_ENTRY_4K *)PageDirectoryEntry2MB;
PageDirectoryEntry2MB->Uint64 = (UINT64)PageTableEntry;
PageDirectoryEntry2MB->Bits.ReadWrite = 1;
PageDirectoryEntry2MB->Bits.Present = 1;
//
// Fill in the 4K page entries with the attributes from the MTRRs
//
for (Index1 = 0, Address = PageAddress; Index1 < 512; Index1++, PageTableEntry++, Address += 0x1000) {
PageTableEntry->Uint64 = (UINT64)Address;
PageTableEntry->Bits.ReadWrite = 1;
PageTableEntry->Bits.Present = 1;
}
}
EFI_PHYSICAL_ADDRESS
CreateIdentityMappingPageTables (
IN UINT32 NumberOfProcessorPhysicalAddressBits
)
/*++
Routine Description:
Allocates and fills in the Page Directory and Page Table Entries to
establish a 1:1 Virtual to Physical mapping for physical memory from
0 to 4GB. Memory above 4GB is not mapped. The MTRRs are used to
determine the cachability of the physical memory regions
Arguments:
NumberOfProcessorPhysicalAddressBits - Number of processor address bits to use.
Limits the number of page table entries
to the physical address space.
Returns:
EFI_OUT_OF_RESOURCES There are not enough resources to allocate the Page Tables
EFI_SUCCESS The 1:1 Virtual to Physical identity mapping was created
--*/
{
EFI_PHYSICAL_ADDRESS PageAddress;
UINTN Index;
UINTN MaxBitsSupported;
UINTN Index1;
UINTN Index2;
x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *PageMapLevel4Entry;
x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *PageMap;
x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *PageDirectoryPointerEntry;
x64_PAGE_TABLE_ENTRY_2M *PageDirectoryEntry2MB;
//
// Page Table structure 4 level 4K, 3 level 2MB.
//
// PageMapLevel4Entry : bits 47-39
// PageDirectoryPointerEntry : bits 38-30
// Page Table 2MB : PageDirectoryEntry2M : bits 29-21
// Page Table 4K : PageDirectoryEntry4K : bits 29 - 21
// PageTableEntry : bits 20 - 12
//
// Strategy is to map every thing in the processor address space using
// 2MB pages. If more granularity is required the 2MB page will get
// converted to set of 4K pages.
//
//
// By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.
//
PageMap = PageMapLevel4Entry = (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *) AllocatePages (1);
ASSERT (PageMap != NULL);
PageAddress = 0;
//
// The number of page-map Level-4 Offset entries is based on the number of
// physical address bits. Less than equal to 38 bits only takes one entry.
// 512 entries represents 48 address bits.
//
if (NumberOfProcessorPhysicalAddressBits <= 38) {
MaxBitsSupported = 1;
} else {
MaxBitsSupported = mPowerOf2[NumberOfProcessorPhysicalAddressBits - 39];
}
for (Index = 0; Index < MaxBitsSupported; Index++, 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 Index1 loop.
//
PageDirectoryPointerEntry = (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *) AllocatePages (1);
ASSERT (PageDirectoryPointerEntry != NULL);
//
// Make a PML4 Entry
//
PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
PageMapLevel4Entry->Bits.ReadWrite = 1;
PageMapLevel4Entry->Bits.Present = 1;
for (Index1 = 0; Index1 < 512; Index1++, PageDirectoryPointerEntry++) {
//
// Each Directory Pointer entries points to a page of Page Directory entires.
// So lets allocate space for them and fill them in in the Index2 loop.
//
PageDirectoryEntry2MB = (x64_PAGE_TABLE_ENTRY_2M *) AllocatePages (1);
ASSERT (PageDirectoryEntry2MB != NULL);
//
// Fill in a Page Directory Pointer Entries
//
PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry2MB;
PageDirectoryPointerEntry->Bits.ReadWrite = 1;
PageDirectoryPointerEntry->Bits.Present = 1;
for (Index2 = 0; Index2 < 512; Index2++, PageDirectoryEntry2MB++, PageAddress += 0x200000) {
//
// Fill in the Page Directory entries
//
PageDirectoryEntry2MB->Uint64 = (UINT64)PageAddress;
PageDirectoryEntry2MB->Bits.ReadWrite = 1;
PageDirectoryEntry2MB->Bits.Present = 1;
PageDirectoryEntry2MB->Bits.MustBe1 = 1;
if (CanNotUse2MBPage (PageAddress)) {
//
// Check to see if all 2MB has the same mapping. If not convert
// to 4K pages by adding the 4th level of page table entries
//
Convert2MBPageTo4KPages (PageDirectoryEntry2MB, PageAddress);
}
}
}
}
//
// For the PML4 entries we are not using fill in a null entry.
// for now we just copy the first entry.
//
for (; Index < 512; Index++, PageMapLevel4Entry++) {
// EfiCopyMem (PageMapLevel4Entry, PageMap, sizeof (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K));
CopyMem (PageMapLevel4Entry,
PageMap,
sizeof (x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K)
);
}
return (EFI_PHYSICAL_ADDRESS)PageMap;
}

View File

@@ -1,239 +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.
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;
} x64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K;
//
// Page-Directory Offset 4K
//
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:1; // Must Be Zero
UINT64 Reserved2:1; // Reserved
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;
} x64_PAGE_DIRECTORY_ENTRY_4K;
//
// Page Table Entry 4K
//
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 PAT:1; // 0 = Ignore Page Attribute Table
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 PageTableBaseAddress:40; // 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;
} x64_PAGE_TABLE_ENTRY_4K;
//
// 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;
} x64_PAGE_TABLE_ENTRY_2M;
typedef union {
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 Reserved:57;
} x64_PAGE_TABLE_ENTRY_COMMON;
typedef union {
x64_PAGE_TABLE_ENTRY_4K Page4k;
x64_PAGE_TABLE_ENTRY_2M Page2Mb;
x64_PAGE_TABLE_ENTRY_COMMON Common;
} x64_PAGE_TABLE_ENTRY;
//
// MTRR Definitions
//
typedef enum {
Uncached = 0,
WriteCombining = 1,
WriteThrough = 4,
WriteProtected = 5,
WriteBack = 6
} x64_MTRR_MEMORY_TYPE;
typedef union {
struct {
UINT32 VCNT:8; // The number of Variable Range MTRRs
UINT32 FIX:1; // 1=Fixed Range MTRRs supported. 0=Fixed Range MTRRs not supported
UINT32 Reserved_0; // Reserved
UINT32 WC:1; // Write combining memory type supported
UINT32 Reserved_1:21; // Reserved
UINT32 Reserved_2:32; // Reserved
} Bits;
UINT64 Uint64;
} x64_MTRRCAP_MSR;
typedef union {
struct {
UINT32 Type:8; // Default Memory Type
UINT32 Reserved_0:2; // Reserved
UINT32 FE:1; // 1=Fixed Range MTRRs enabled. 0=Fixed Range MTRRs disabled
UINT32 E:1; // 1=MTRRs enabled, 0=MTRRs disabled
UINT32 Reserved_1:20; // Reserved
UINT32 Reserved_2:32; // Reserved
} Bits;
UINT64 Uint64;
} x64_MTRR_DEF_TYPE_MSR;
typedef union {
UINT8 Type[8]; // The 8 Memory Type values in the 64-bit MTRR
UINT64 Uint64; // The full 64-bit MSR
} x64_MTRR_FIXED_RANGE_MSR;
typedef struct {
x64_MTRRCAP_MSR Capabilities; // MTRR Capabilities MSR value
x64_MTRR_DEF_TYPE_MSR DefaultType; // Default Memory Type MSR Value
x64_MTRR_FIXED_RANGE_MSR Fixed[11]; // The 11 Fixed MTRR MSR Values
} x64_MTRR_FIXED_RANGE;
typedef union {
struct {
UINT64 Type:8; // Memory Type
UINT64 Reserved0:4; // Reserved
UINT64 PhysBase:40; // The physical base address(bits 35..12) of the MTRR
UINT64 Reserved1:12 ; // Reserved
} Bits;
UINT64 Uint64;
} x64_MTRR_PHYSBASE_MSR;
typedef union {
struct {
UINT64 Reserved0:11; // Reserved
UINT64 Valid:1; // 1=MTRR is valid, 0=MTRR is not valid
UINT64 PhysMask:40; // The physical address mask (bits 35..12) of the MTRR
UINT64 Reserved1:12; // Reserved
} Bits;
UINT64 Uint64;
} x64_MTRR_PHYSMASK_MSR;
typedef struct {
x64_MTRR_PHYSBASE_MSR PhysBase; // Variable MTRR Physical Base MSR
x64_MTRR_PHYSMASK_MSR PhysMask; // Variable MTRR Physical Mask MSR
} x64_MTRR_VARIABLE_RANGE;
#pragma pack()
x64_MTRR_MEMORY_TYPE
EfiGetMTRRMemoryType (
IN EFI_PHYSICAL_ADDRESS Address
)
;
BOOLEAN
CanNotUse2MBPage (
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
;
VOID
Convert2MBPageTo4KPages (
IN x64_PAGE_TABLE_ENTRY_2M *PageDirectoryEntry2MB,
IN EFI_PHYSICAL_ADDRESS PageAddress
)
;
EFI_PHYSICAL_ADDRESS
CreateIdentityMappingPageTables (
IN UINT32 NumberOfProcessorPhysicalAddressBits
)
;
#endif