summaryrefslogtreecommitdiff
path: root/Core/CORE_PEI/AmiPeiInit.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/CORE_PEI/AmiPeiInit.c')
-rw-r--r--Core/CORE_PEI/AmiPeiInit.c887
1 files changed, 887 insertions, 0 deletions
diff --git a/Core/CORE_PEI/AmiPeiInit.c b/Core/CORE_PEI/AmiPeiInit.c
new file mode 100644
index 0000000..33931ae
--- /dev/null
+++ b/Core/CORE_PEI/AmiPeiInit.c
@@ -0,0 +1,887 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PeiMain/AmiPeiInit.c 24 5/13/11 5:10p Artems $
+//
+// $Revision: 24 $
+//
+// $Date: 5/13/11 5:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PeiMain/AmiPeiInit.c $
+//
+// 24 5/13/11 5:10p Artems
+// Added functions CopyMem and ZeroMem for PEI build
+//
+// 23 3/22/11 5:20p Felixp
+// LOAD_HOB processing and AmiInitParts-related code has been restructured
+// to achieve the following goals:
+// - Support LOAD_HOB in PI mode
+// - Reduce amount of PI version specific code
+// - Minimize number of patches in the EDK portion of code
+// - Eliminate global variables
+// - Simplify the implementation
+//
+// 22 3/09/11 5:53p Artems
+// Removed usage of global pointer InitFunction. Fixed bug in
+// MigrateIdtTable with wrong IdtBase
+//
+// 21 3/08/11 10:22a Artems
+// Fixed bug in MigrateIdtTable, where IdtBase assigned wrong address
+//
+// 20 3/04/11 4:06p Artems
+// Modified FindPPI function to work with both FV hob types
+//
+// 19 2/05/11 3:42p Artems
+// Added PI 1.0 support
+//
+// 18 9/22/10 7:13p Felixp
+// Imrpovement: gEfiStatusCodeSpecificDataGuid variable is added. Used by
+// PEI Core to report status codes.
+//
+// 17 8/20/10 3:26p Felixp
+// LZMA compression support: ReadSection function updated.
+//
+// 16 8/28/09 3:08p Felixp
+// More generic FindFv PPI implementation. Old implementation was assuming
+// that boot FV is described by the first FV HOB.
+//
+// 15 8/27/09 1:58p Felixp
+// AmiInitParts is updated to call InitFunction once when AmiInitParts is
+// called multiple times.
+//
+// 14 7/30/09 4:46p Vyacheslava
+// Fixed comments.
+//
+// 13 7/28/09 4:56p Vyacheslava
+// Minor bug fix. EIP#24453: Synopsis: CPU exception when printing long
+// debug messages.
+//
+// 12 5/04/09 3:09p Felixp
+// Creation of CPU HOB moved from AmiPeiInit.c to AmiDxeInit.c
+//
+// 11 8/07/07 2:24p Felixp
+// Additional Status Codes added
+//
+// 10 3/12/07 10:26a Felixp
+// LoadedImage PPI support added (defined in PI 1.0; used by AmiDebugger)
+//
+// 8 10/18/06 11:30a Felixp
+// LoadFile updated to return EFI_LOAD_ERROR when image format is invalid
+//
+// 7 8/24/06 9:43a Felixp
+// Preliminary x64 support (work in progress)
+// DXE Core interfaces are no longer passed from PEI Core.
+// They are linked directly with DXE Core
+//
+// 6 6/04/06 9:20p Ambikas
+//
+// 5 5/30/06 7:06p Yakovlevs
+// Fixed STACK HOB memory type from ConventionalMemory to EfiLoaderData.
+//
+// 4 5/20/06 12:58a Felixp
+//
+// 3 5/20/06 12:36a Felixp
+// checkpoints added
+//
+// 2 5/19/06 10:38p Felixp
+// Clean up
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiPeiInit.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiHobs.h>
+#include <AmiPeiLib.h>
+#include <PPI/LoadFile.h>
+#include <PPI/LoadedImagePpi.h>
+#include <PPI/Decompress.h>
+#include <StatusCodes.h>
+
+typedef VOID (*INIT_PARTS)(VOID* p1, VOID*p2);
+VOID InitParts(VOID* p1, VOID*p2);
+VOID InitParts2(VOID* p1, VOID*p2);
+
+EFI_GUID gEfiStatusCodeSpecificDataGuid = EFI_STATUS_CODE_SPECIFIC_DATA_GUID;
+
+//defined in PeiMain.c
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+);
+////////////// from PeiCore.c
+#if PI_SPECIFICATION_VERSION<0x00010000
+EFI_PEI_SERVICES **ppPS = NULL;
+#endif
+
+VOID InitPartsMem(VOID* p1, VOID*p2)
+{
+#if PI_SPECIFICATION_VERSION<0x00010000
+ ppPS = (EFI_PEI_SERVICES**)p2;
+#endif
+ InitParts2(p1,p2);
+}
+
+#if PI_SPECIFICATION_VERSION<0x00010000
+EFI_STATUS FvLoadFile(
+ 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
+);
+
+// PPIs
+EFI_PEI_FV_FILE_LOADER_PPI FileLoader = {FvLoadFile};
+
+// PPI to be installed
+EFI_GUID gPeiLoadFilePpiGuid = EFI_PEI_FV_FILE_LOADER_GUID;
+static EFI_PEI_PPI_DESCRIPTOR FileLoaderPpi[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiLoadFilePpiGuid, &FileLoader
+ }
+};
+
+EFI_STATUS ReadSection(
+ EFI_PEI_SERVICES **ppPS, IN EFI_SECTION_TYPE SectionType,
+ IN EFI_FFS_FILE_HEADER *pFile, OUT VOID **ppData
+)
+{
+ EFI_STATUS Status;
+ UINT32 SrcSize, DstSize, TmpSize;
+ VOID *pSrc;
+ EFI_PHYSICAL_ADDRESS DstAddress;
+ EFI_HOB_HANDOFF_INFO_TABLE *pHob;
+ EFI_COMPRESSION_SECTION_HEADER *pCompressionSection;
+ if (!ppData) return EFI_INVALID_PARAMETER;
+ //TODO: Support for GUIDed sections
+ Status = (*ppPS)->FfsFindSectionData(
+ ppPS, SectionType, pFile, &pSrc
+ );
+ if (!EFI_ERROR(Status)){*ppData=pSrc; return Status; }
+ Status = (*ppPS)->FfsFindSectionData(
+ ppPS, EFI_SECTION_COMPRESSION,
+ pFile, &pCompressionSection
+ );
+ if (EFI_ERROR(Status)) return Status;
+ SrcSize = FVSECTION_SIZE(pCompressionSection) - sizeof(EFI_COMPRESSION_SECTION_HEADER);
+ pSrc = pCompressionSection + 1;
+ if (pCompressionSection->CompressionType!=EFI_NOT_COMPRESSED){
+ GET_INFO GetInfoPtr;
+ DECOMPRESS DecompressPtr;
+ BOOLEAN KnownCompressionType = GetDecompressInterface(
+ pCompressionSection->CompressionType,
+ &GetInfoPtr, &DecompressPtr
+ );
+ if (!KnownCompressionType) return EFI_UNSUPPORTED;
+ Status = GetInfoPtr(pSrc, SrcSize, &DstSize, &TmpSize);
+ if (EFI_ERROR(Status)) return Status;
+ //No FreePool, so the memory is never freed
+ Status = (*ppPS)->AllocatePages(
+ ppPS,EfiBootServicesCode,(DstSize>>12)+1,&DstAddress
+ );
+ if (EFI_ERROR(Status)) return Status;
+ (*ppPS)->GetHobList(ppPS,&pHob);
+ if (pHob->EfiFreeMemoryTop - pHob->EfiFreeMemoryBottom < TmpSize)
+ return EFI_OUT_OF_RESOURCES;
+ Status = DecompressPtr(
+ pSrc, SrcSize, (VOID*)DstAddress, DstSize,
+ (VOID*)pHob->EfiFreeMemoryBottom, TmpSize
+ );
+ if (EFI_ERROR(Status)) return Status;
+ pSrc = (VOID*)(UINTN)DstAddress;
+ }
+ do {
+ if (((EFI_COMMON_SECTION_HEADER*)pSrc)->Type==SectionType){
+ *ppData = (EFI_COMMON_SECTION_HEADER*)pSrc+1;
+ return EFI_SUCCESS;
+ }
+ TmpSize = FVSECTION_SIZE(pSrc);
+ TmpSize += (4 - (TmpSize & 3)) & 3;
+ if (TmpSize>=DstSize) return EFI_NOT_FOUND;
+ DstSize -= TmpSize;
+ pSrc = (UINT8*)pSrc + TmpSize;
+ }while(TRUE);
+}
+
+EFI_STATUS LoadFile(
+ EFI_PEI_SERVICES **ppPS,
+ IN EFI_FFS_FILE_HEADER *pFfsHeader,
+ OUT VOID **ppFfsImageAddress,
+ OUT EFI_PHYSICAL_ADDRESS *pImageAddress,
+ OUT UINT64 *pImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *pEntryPoint
+)
+{
+ VOID *pData;
+ EFI_STATUS Status;
+ UINTN Size;
+ if (!pEntryPoint || !pImageAddress) return EFI_INVALID_PARAMETER;
+ Status = ReadSection(ppPS, EFI_SECTION_PE32, pFfsHeader, &pData);
+ //TODO: add TE support ???
+ if (EFI_ERROR(Status)) return Status;
+ Size = GetImageSize(pData);
+ if (EFI_ERROR((*ppPS)->AllocatePages(
+ ppPS, EfiBootServicesCode,
+ (Size >> 12)+1, pImageAddress)
+ )
+ ) return EFI_OUT_OF_RESOURCES;
+
+ *pEntryPoint = (EFI_PHYSICAL_ADDRESS)LoadPeImage(pData,(UINT8*)*pImageAddress);
+ if (!*pEntryPoint) return EFI_LOAD_ERROR;
+ if (pImageSize) *pImageSize = Size;
+ if (ppFfsImageAddress) *ppFfsImageAddress = pData;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS FvLoadFile(
+ 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
+)
+{
+ return LoadFile(ppPS,FfsHeader,NULL,ImageAddress,ImageSize,EntryPoint);
+}
+
+typedef VOID (*PEICORE_INMEM_ENTRY_POINT)(
+ EFI_PHYSICAL_ADDRESS Delta,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+);
+
+VOID SwitchCoreStacks(
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1,
+ IN UINTN Parameter2,
+ IN VOID *NewStack
+);
+
+VOID PeiCoreMemEntry(
+ EFI_PHYSICAL_ADDRESS Delta,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+)
+{
+ ppPS = PeiServices;
+ if (Delta)
+ {
+ PEI_TRACE((TRACE_PEICORE,PeiServices,"PEI core reallocated to memory\n"));
+ // intall file loader
+ (*ppPS)->InstallPpi(ppPS, FileLoaderPpi);
+ }
+ SwitchCoreStacks(
+ (UINT8*)PeiCoreEntryPoint+(UINTN)Delta,Parameter1,Parameter2,NewStack
+ );
+}
+
+VOID AmiSwitchToMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+)
+{
+ //reallocate ourself to memory
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+ EFI_PHYSICAL_ADDRESS NewAddress, EntryPoint;
+ VOID *pOldAddress;
+ UINT64 Size;
+ EFI_FFS_FILE_HEADER* pFile=NULL;
+ PEI_PROGRESS_CODE(PeiServices,PEI_MEMORY_INSTALLED);
+ // if we already in memory just call memory routine
+ //TODO: if (pData->pLoader) PeiCoreInMem(pData, 0);
+ //find our FFS file header
+ //PEI Core must be in boot FV.
+ //Boot FV must be the first one returned by FfsFindNextVolume
+ (*PeiServices)->FfsFindNextVolume (PeiServices, 0, &pFV);
+ //No error checking. Since if we are here, the file is in the FV, so we should be able to find it.
+ (*PeiServices)->FfsFindNextFile (PeiServices, EFI_FV_FILETYPE_PEI_CORE, pFV, &pFile);
+ if (EFI_ERROR(LoadFile(PeiServices,pFile,&pOldAddress,&NewAddress,&Size,&EntryPoint))){
+ //if we don't have enough memory, don't install FileLoader PPI
+ PeiCoreMemEntry(0,PeiServices,PeiCoreEntryPoint,Parameter1,Parameter2,NewStack);
+ }else{
+ //Update LoadedImage PPI information
+ UpdatedLoadedImagePpi(PeiServices,NewAddress,Size,pFile);
+ ((PEICORE_INMEM_ENTRY_POINT)(
+ (UINT8*)PeiCoreMemEntry-(UINT8*)pOldAddress+(UINT8*)NewAddress
+ ))(NewAddress-(UINT64)(UINTN)pOldAddress,PeiServices,PeiCoreEntryPoint,Parameter1,Parameter2,NewStack);
+ }
+}
+
+typedef struct {
+ UINTN BootFirmwareVolume;
+ UINTN SizeOfCacheAsRam;
+ EFI_PEI_PPI_DESCRIPTOR *DispatchTable;
+} EFI_PEI_STARTUP_DESCRIPTOR;
+
+EFI_STATUS EFIAPI PeiMain(
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+);
+
+VOID PeiCoreEntry(
+ EFI_PEI_STARTUP_DESCRIPTOR StartUpDescriptor
+)
+{
+ checkpoint(0x10);
+ PeiMain(&StartUpDescriptor);
+}
+
+#include <PPI/FindFv.h>
+
+EFI_STATUS FindFv(
+ IN EFI_FIND_FV_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ UINT8 *FvNumber,
+ EFI_FIRMWARE_VOLUME_HEADER **FVAddress
+)
+{
+ UINT8 Instance;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFv;
+ EFI_HOB_GENERIC_HEADER *HobPointer;
+ EFI_STATUS Status;
+
+ if (!FVAddress || !FvNumber)
+ return EFI_INVALID_PARAMETER;
+
+ Status = (*PeiServices)->FfsFindNextVolume(PeiServices, 0, &BootFv);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if (*FvNumber == 0) { //0 is always Boot FV
+ *FVAddress = BootFv;
+ (*FvNumber)++;
+ return Status;
+ }
+
+ Instance = *FvNumber;
+ Status = (*PeiServices)->GetHobList(PeiServices, &HobPointer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ while(HobPointer->HobType != EFI_HOB_TYPE_END_OF_HOB_LIST) {
+ if(HobPointer->HobType == EFI_HOB_TYPE_FV || HobPointer->HobType == EFI_HOB_TYPE_FV2) {
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER *)((EFI_HOB_FIRMWARE_VOLUME *)HobPointer)->BaseAddress;
+ if (Fv == BootFv) {
+ HobPointer = NextHob(HobPointer, EFI_HOB_GENERIC_HEADER);
+ continue;
+ }
+
+ if (Instance == 1) {
+ *FVAddress = Fv;
+ (*FvNumber)++;
+ return EFI_SUCCESS;
+ }
+ Instance--;
+ }
+ HobPointer = NextHob(HobPointer, EFI_HOB_GENERIC_HEADER);
+ }
+ return EFI_OUT_OF_RESOURCES; //EFI_NOT_FOUND;
+}
+
+EFI_GUID gPeiFindFvPpiGuid = EFI_FIND_FV_PPI_GUID;
+
+// PPIs
+EFI_FIND_FV_PPI FindFvPpi = {FindFv};
+
+// PPI to be installed
+EFI_PEI_PPI_DESCRIPTOR FindFvPpiDescriptor[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiFindFvPpiGuid, &FindFvPpi
+ }
+};
+
+EFI_STATUS EFIAPI InstallFindFv(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ return (*PeiServices)->InstallPpi(PeiServices,FindFvPpiDescriptor);
+}
+#else //#if PI_SPECIFICATION_VERSION<0x00010000
+
+EFI_STATUS DecompressPpiDecompress(
+ IN CONST EFI_PEI_DECOMPRESS_PPI *This,
+ IN CONST EFI_COMPRESSION_SECTION *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize
+){
+ EFI_STATUS Status;
+ UINT32 SrcSize, DstSize, TmpSize;
+ VOID *pSrc;
+ EFI_PHYSICAL_ADDRESS DstAddress;
+ EFI_HOB_HANDOFF_INFO_TABLE *pHob;
+ EFI_COMPRESSION_SECTION_HEADER *pCompressionSection;
+
+ if (!OutputBuffer || !OutputSize) return EFI_INVALID_PARAMETER;
+
+ pCompressionSection = (EFI_COMPRESSION_SECTION_HEADER*)&InputSection->UncompressedLength;
+ SrcSize = FVSECTION_SIZE(pCompressionSection) - sizeof(EFI_COMPRESSION_SECTION_HEADER);
+ pSrc = pCompressionSection + 1;
+ if (pCompressionSection->CompressionType!=EFI_NOT_COMPRESSED){
+ GET_INFO GetInfoPtr;
+ DECOMPRESS DecompressPtr;
+ EFI_PEI_SERVICES **ppPS = GetPeiServicesTablePointer();
+ BOOLEAN KnownCompressionType = GetDecompressInterface(
+ pCompressionSection->CompressionType,
+ &GetInfoPtr, &DecompressPtr
+ );
+ if (!KnownCompressionType) return EFI_UNSUPPORTED;
+ Status = GetInfoPtr(pSrc, SrcSize, &DstSize, &TmpSize);
+ if (EFI_ERROR(Status)) return Status;
+ //No FreePool, so the memory is never freed
+ Status = (*ppPS)->AllocatePages(
+ ppPS,EfiBootServicesCode,(DstSize>>12)+1,&DstAddress
+ );
+ if (EFI_ERROR(Status)) return Status;
+ (*ppPS)->GetHobList(ppPS,&pHob);
+ if (pHob->EfiFreeMemoryTop - pHob->EfiFreeMemoryBottom < TmpSize)
+ return EFI_OUT_OF_RESOURCES;
+ Status = DecompressPtr(
+ pSrc, SrcSize, (VOID*)DstAddress, DstSize,
+ (VOID*)pHob->EfiFreeMemoryBottom, TmpSize
+ );
+ if (EFI_ERROR(Status)) return Status;
+ *OutputBuffer = (VOID*)(UINTN)DstAddress;
+ *OutputSize = DstSize;
+ }else{
+ *OutputBuffer = pSrc;
+ *OutputSize = SrcSize;
+ }
+ return EFI_SUCCESS;
+}
+
+// PPI to be installed
+EFI_PEI_DECOMPRESS_PPI DecomppressInterface = {DecompressPpiDecompress};
+static EFI_PEI_PPI_DESCRIPTOR DecompressPpi[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiDecompressPpiGuid, &DecomppressInterface
+ }
+};
+
+
+EFI_STATUS EFIAPI InstallDecompressionPpi(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ return (*PeiServices)->InstallPpi(PeiServices, DecompressPpi);
+}
+
+EFI_STATUS PeiMain(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList);
+
+VOID PeiCoreEntry(
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList)
+{
+ checkpoint(0x10);
+ PeiMain(SecCoreData,PpList);
+}
+#endif //#else branch of #if PI_SPECIFICATION_VERSION<0x00010000
+
+VOID AmiInitParts(IN EFI_PEI_SERVICES **PeiServices, INIT_PARTS InitFunctionPtr)
+{
+ if (InitFunctionPtr == NULL)
+ return;
+
+ (InitFunctionPtr)(NULL, PeiServices);
+}
+
+VOID ProcessLoadHob(IN EFI_PEI_SERVICES **PeiServices)
+{
+ static EFI_GUID LoadHobGuid = AMI_PEIM_LOAD_HOB_GUID;
+ PEIM_LOAD_HOB *LoadHob;
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->GetHobList(PeiServices,&LoadHob);
+ if (EFI_ERROR(Status)) return;
+ // Load PEIMs
+ while(!EFI_ERROR(FindNextHobByGuid(&LoadHobGuid, &LoadHob)))
+ {
+ EFI_PHYSICAL_ADDRESS Address,EntryPoint, ModuleDelta;
+ UINT64 Size;
+ // if file header is NULL, the entry is in the PEI Core binary
+ if (LoadHob->pFfsHeader == NULL) continue;
+ Status = PeiLoadFile(
+ PeiServices,LoadHob->pFfsHeader,&Address,&Size,&EntryPoint
+ );
+ if (EFI_ERROR(Status)) continue;
+ ModuleDelta = EntryPoint - (UINT64)LoadHob->EntryPoint;
+ if (ModuleDelta==0) continue; // the module was not loaded
+#ifdef EFI_DEBUG
+{
+ char sName[0x100];
+ EFI_FFS_FILE_HEADER *PeimFileHeader = LoadHob->pFfsHeader;
+
+ if (!GetName((VOID*)(UINTN)Address,sName))
+ Sprintf_s(sName,sizeof(sName),"[%G]",&PeimFileHeader->Name);
+ PeiTrace(
+ TRACE_PEICORE, PeiServices, "%s.InMemEntry(%X)\n", sName,
+ (UINT64)LoadHob->InMemEntryPoint+ModuleDelta
+ );
+}
+#endif
+ ((EFI_PEIM_ENTRY_POINT)(
+ (UINT64)LoadHob->InMemEntryPoint+ModuleDelta
+ ))(LoadHob->pFfsHeader, PeiServices);
+ }
+}
+
+EFI_STATUS
+PeiBuildHobStack (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the Stack
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The 64 bit physical address of the Stack
+
+ Length - The length of the stack in bytes
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;
+ static EFI_GUID gEfiHobMemeryAllocStackGuid=EFI_HOB_MEMORY_ALLOC_STACK_GUID;
+
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_MEMORY_ALLOCATION,
+ sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK),
+ &Hob
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Hob->AllocDescriptor.Name = gEfiHobMemeryAllocStackGuid;
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob->AllocDescriptor.MemoryLength = Length;
+ Hob->AllocDescriptor.MemoryType = EfiLoaderData;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PeiBuildHobMemoryAllocation (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_GUID *Name,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the memory allocation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The 64 bit physical address of the memory
+
+ Length - The length of the memory allocation in bytes
+
+ Name - Name for Hob
+
+ MemoryType - Memory type
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_ALLOCATION *Hob;
+
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_MEMORY_ALLOCATION,
+ sizeof (EFI_HOB_MEMORY_ALLOCATION),
+ &Hob
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Name != NULL) {
+ Hob->AllocDescriptor.Name = *Name;
+ } else {
+ (*PeiServices)->SetMem(&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID), 0);
+ }
+
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob->AllocDescriptor.MemoryLength = Length;
+ Hob->AllocDescriptor.MemoryType = MemoryType;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PeiBuildHobGuid (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN DataLength,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Builds a custom HOB that is tagged with a GUID for identification
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Guid - The GUID of the custome HOB type
+
+ DataLength - The size of the data payload for the GUIDed HOB
+
+ Hob - Pointer to the Hob
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength),
+ Hob
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ((EFI_HOB_GUID_TYPE *)(*Hob))->Name = *Guid;
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN CompareGuid (IN EFI_GUID *Guid1,IN EFI_GUID *Guid2)
+{
+ return !MemCmp(Guid1,Guid2,sizeof(EFI_GUID));
+}
+
+VOID CopyMem (
+ IN VOID *Destination, IN VOID *Source, IN UINTN Length
+)
+{
+ MemCpy (Destination, Source, Length);
+}
+
+VOID ZeroMem(IN VOID *Buffer, IN UINTN Size)
+{
+ MemSet(Buffer,Size,0);
+}
+
+#ifdef EFI_DEBUG
+ VOID
+ PeiDebugAssert (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description
+ )
+ {
+ PeiTrace(TRACE_ALWAYS,PeiServices,"ASSERT in %s on %i: %s\n",FileName, LineNumber, Description);
+ EFI_DEADLOOP()
+ }
+
+ VOID
+ PeiDebugPrint (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ...
+ )
+ {
+ CHAR8 Buffer[256];
+ va_list ArgList = va_start(ArgList,Format);
+ PrepareStatusCodeString( Buffer, sizeof(Buffer), Format, ArgList );
+ (*PeiServices)->ReportStatusCode (
+ (EFI_PEI_SERVICES**)PeiServices, EFI_DEBUG_CODE,
+ EFI_SOFTWARE_UNSPECIFIED, 0, NULL,
+ (EFI_STATUS_CODE_DATA *)Buffer
+ );
+ va_end(ArgList);
+ }
+#endif
+#if PI_SPECIFICATION_VERSION >= 0x00010000
+#pragma pack (1)
+typedef struct {
+ UINT16 Limit;
+ UINTN Base;
+} DESCRIPTOR_TABLE;
+#pragma pack()
+
+VOID CPULib_LoadIdt(DESCRIPTOR_TABLE *Idt);
+VOID CPULib_SaveIdt(DESCRIPTOR_TABLE *Idt);
+
+/*++
+
+Routine Description:
+
+ Invalidates a range of instruction cache lines in the cache coherency domain
+ of the calling CPU.
+
+ Invalidates the instruction cache lines specified by Address and Length. If
+ Address is not aligned on a cache line boundary, then entire instruction
+ cache line containing Address is invalidated. If Address + Length is not
+ aligned on a cache line boundary, then the entire instruction cache line
+ containing Address + Length -1 is invalidated. This function may choose to
+ invalidate the entire instruction cache if that is more efficient than
+ invalidating the specified range. If Length is 0, the no instruction cache
+ lines are invalidated. Address is returned.
+
+ If Length is greater than (EFI_MAX_ADDRESS - Address + 1), then ASSERT().
+
+Arguments:
+
+ Address - The base address of the instruction cache lines to
+ invalidate. If the CPU is in a physical addressing mode, then
+ Address is a physical address. If the CPU is in a virtual
+ addressing mode, then Address is a virtual address.
+
+ Length - The number of bytes to invalidate from the instruction cache.
+
+ Returns:
+ Address
+
+**/
+VOID MigrateIdtTable (IN EFI_PEI_SERVICES **PeiServices){
+ UINTN Size;
+ VOID *NewIdtBase;
+ EFI_STATUS Status;
+ DESCRIPTOR_TABLE IdtDescriptor;
+
+ CPULib_SaveIdt(&IdtDescriptor);
+
+ Size = sizeof(EFI_PEI_SERVICES**) + (IdtDescriptor.Limit + 1);
+ Status = (*PeiServices)->AllocatePool (PeiServices, Size, &NewIdtBase);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+ (*PeiServices)->CopyMem (
+ (VOID*)((UINTN)NewIdtBase + sizeof(EFI_PEI_SERVICES**)),
+ (VOID*)IdtDescriptor.Base, (IdtDescriptor.Limit + 1)
+ );
+
+ IdtDescriptor.Base = (UINTN)NewIdtBase + sizeof(EFI_PEI_SERVICES**);
+ CPULib_LoadIdt(&IdtDescriptor);
+ SetPeiServicesTablePointer(PeiServices);
+}
+/**
+Routine Description:
+
+ Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+ in the target buffer.
+
+ This function searches target the buffer specified by Buffer and Length from
+ the lowest address to the highest address at 128-bit increments for the 128-bit
+ GUID value that matches Guid. If a match is found, then a pointer to the matching
+ GUID in the target buffer is returned. If no match is found, then NULL is returned.
+ If Length is 0, then NULL is returned.
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 128-bit boundary, then ASSERT().
+ If Length is greater than (EFI_MAX_ADDRESS ?Buffer + 1), then ASSERT().
+
+Arguments:
+
+ Buffer - Pointer to the target buffer to scan.
+ Length - Number of bytes in Buffer to scan.
+ Guid - Value to search for in the target buffer.
+
+Returns:
+ A pointer to the matching Guid in the target buffer or NULL otherwise.
+
+**/
+VOID *ScanGuid (IN VOID *Buffer, IN UINTN Length, IN EFI_GUID *Guid){
+ EFI_GUID *GuidPtr;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer();
+ PEI_ASSERT(PeiServices, (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0));
+ PEI_ASSERT(PeiServices, (Length <= (0xFFFFFFFF - (UINTN)Buffer + 1)));
+ PEI_ASSERT(PeiServices, ((Length & (sizeof (*GuidPtr) - 1)) == 0));
+
+ GuidPtr = (EFI_GUID*)Buffer;
+ Buffer = GuidPtr + Length / sizeof (*GuidPtr);
+ while (GuidPtr < (EFI_GUID*)Buffer) {
+ if (!guidcmp (GuidPtr, Guid)) {
+ return (VOID*)GuidPtr;
+ }
+ GuidPtr++;
+ }
+ return NULL;
+}
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file