summaryrefslogtreecommitdiff
path: root/Core/CORE_PEI
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/CORE_PEI
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/CORE_PEI')
-rw-r--r--Core/CORE_PEI/AmiPeiInit.c887
-rw-r--r--Core/CORE_PEI/CORE_PEI.cif9
-rw-r--r--Core/CORE_PEI/CORE_PEI.mak163
-rw-r--r--Core/CORE_PEI/CORE_PEI.sdl97
-rw-r--r--Core/CORE_PEI/CORE_PEISrc.cif17
-rw-r--r--Core/CORE_PEI/CORE_PEISrc.mak103
-rw-r--r--Core/CORE_PEI/CORE_PEISrc.sdl33
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c108
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif21
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c604
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c488
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c198
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c341
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c440
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h1260
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c405
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c673
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c77
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c194
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c102
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c268
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h38
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/BootMode.c107
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif21
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c689
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/FwVol.c782
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Hob.c191
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Image.c932
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c392
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/PeiCore.h1416
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/PeiMain.c404
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Ppi.c687
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Reset.c76
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Security.c192
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/StatusCode.c94
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/dependency.c265
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/dependency.h38
-rw-r--r--Core/CORE_PEI/CpuIo.c1158
-rw-r--r--Core/CORE_PEI/DxeIpl.c838
-rw-r--r--Core/CORE_PEI/PciCfg.c491
-rw-r--r--Core/CORE_PEI/PeiPerf.c30
41 files changed, 15329 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
diff --git a/Core/CORE_PEI/CORE_PEI.cif b/Core/CORE_PEI/CORE_PEI.cif
new file mode 100644
index 0000000..fb412a8
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "CORE_PEI"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\"
+ RefName = "CORE_PEI"
+[files]
+"CORE_PEI.sdl"
+"CORE_PEI.mak"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEI.mak b/Core/CORE_PEI/CORE_PEI.mak
new file mode 100644
index 0000000..fa25508
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI.mak
@@ -0,0 +1,163 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/CORE_PEI/CORE_PEI.mak 6 5/01/09 6:12p Felixp $
+#
+# $Revision: 6 $
+#
+# $Date: 5/01/09 6:12p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/CORE_PEI/CORE_PEI.mak $
+#
+# 6 5/01/09 6:12p Felixp
+# Bug fix(EIP 19816). $(AMICSPLib) is linked with CORE_PEI module
+# (Used to be linked with NVRAM library that caused problems on systems
+# without Core Sources).
+#
+# 5 8/24/06 9:17a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 4 12/02/05 11:15a Felixp
+# @set INCLUDE=%%INCLUDE%% removed since it's not needed.
+#
+# 3 6/16/05 10:47a Felixp
+# 1. variables from NVRAMTokens.c moved to Tokens.c
+# 2. PeiCoreMemoryInstalled initialization list added
+#
+# 2 2/11/05 5:46p Felixp
+# Binary files organization improved:
+# - extra layer of sub-component removed
+# - macros initialization moved to SDL tokens to eliminate undefined
+# macros situation
+# - debug and release binaries have different names now (workaround for
+# VeB limitation)
+#
+# 1 1/28/05 12:44p Felixp
+#
+# 3 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 1 12/23/04 9:42a Felixp
+#
+# 2 11/01/04 8:06a Felixp
+#
+# 1 7/12/04 6:33p Felixp
+#
+# 24 3/29/04 2:32a Felixp
+#
+# 23 3/28/04 2:11p Felixp
+# 1. PE Loader and some other commonly used code moved to the Library
+# 2. Warnings fixed (from now on warning will be treated as error)
+#
+# 22 3/23/04 4:56p Felixp
+#
+# 21 3/20/04 12:03p Felixp
+#
+# 20 3/19/04 11:12a Robert
+#
+# 19 2/19/04 10:08a Felixp
+# Debugging code removed.
+#
+# 18 2/10/04 1:24p Felixp
+#
+# 17 2/06/04 2:46a Felixp
+# - Support for VC6 tools
+# - bug fixes
+# - component AddOn added
+#
+# 16 2/04/04 2:04a Felixp
+# work in progress...
+#
+# 15 1/28/04 3:24a Felixp
+#
+# 14 1/22/04 12:47p Felixp
+#
+# 13 1/19/04 4:23p Felixp
+# work in progress...
+#
+# 12 1/18/04 8:34a Felixp
+# 1. From now on, OBJ files are created in a component specific
+# subdirectory of $(BUILD_DIR)
+# 2. New files added
+#
+# 11 1/15/04 11:05a Felixp
+# hob.c and ffs.c files added
+#
+# 10 1/06/04 5:28p Yakovlevs
+#
+# 9 1/06/04 4:03p Felixp
+#
+# 8 1/06/04 11:26a Felixp
+#
+# 7 1/02/04 5:39p Robert
+#
+# 6 12/30/03 5:54p Robert
+#
+# 5 12/23/03 9:34a Felixp
+# dependency from the makefile added
+#
+# 4 12/12/03 12:23p Felixp
+#
+# 3 12/12/03 12:07p Robert
+# Added Pci Cfg and Cpu Io obj references to the mak file
+#
+# 2 12/12/03 11:29a Felixp
+# PEICORE_OBJECTS and PEICORE_HEADERS variables created
+#
+# 1 12/05/03 4:15p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Pei.mak
+#
+# Description: PeiCore makefile:
+# -Builds EXE File
+# -Invokes FFS.Mak to build PeiCore.FFS
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CORE_PEI
+
+CORE_PEI : $(BUILD_DIR)\CORE_PEI.mak CORE_PEIBin
+
+$(BUILD_DIR)\CORE_PEI.mak : $(CORE_PEI_DIR)\$(@B).cif $(CORE_PEI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CORE_PEI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CORE_PEIBin : $(AMIPEILIB) $(CORE_PEI_LIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CORE_PEI.mak all\
+ GUID=92685943-D810-47ff-A112-CC8490776A1F \
+ ENTRY_POINT=PeiCoreEntry \
+ TYPE=PEI_CORE LIBRARIES= \
+ COMPRESS=0\
+ EXT_HEADERS=$(BUILD_DIR)\token.h\
+ "INIT_LIST=$(PeiCoreInitialize)"\
+ "INIT_LIST2=$(PeiCoreMemoryInstalled)"\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_PEI/CORE_PEI.sdl b/Core/CORE_PEI/CORE_PEI.sdl
new file mode 100644
index 0000000..9177b10
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI.sdl
@@ -0,0 +1,97 @@
+TOKEN
+ Name = "CORE_PEI_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CORE_PEI support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "CORE_PEI_DIR"
+End
+
+MODULE
+ Help = "Includes CORE_PEI.mak to Project"
+ File = "CORE_PEI.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CORE_PEI.ffs"
+ Parent = "FV_BB"
+ Help = "PEI Core"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiCoreInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CpuIoInit,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PciCfgInit,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiInitDxeIpl,"
+ Parent = "PeiCoreMemoryInstalled"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CORE_PEI_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(CORE_PEI_DIR)\CORE_PEI$(ARCH)$(DBG).lib"
+ Parent = "CORE_PEI_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiCoreMemoryInstalled"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiInitNV,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallFindFv,"
+ Parent = "PeiCoreInitialize"
+ Token = "PI_SPECIFICATION_VERSION" "<" "0x10000"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallDecompressionPpi,"
+ Parent = "PeiCoreMemoryInstalled"
+ Token = "PI_SPECIFICATION_VERSION" ">=" "0x10000"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CpuIoMemInit,"
+ Parent = "PeiCoreMemoryInstalled"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PciCfgMemInit,"
+ Parent = "PeiCoreMemoryInstalled"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/CORE_PEI/CORE_PEISrc.cif b/Core/CORE_PEI/CORE_PEISrc.cif
new file mode 100644
index 0000000..c9f5317
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEISrc.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "CORE_PEI Source(EDK)"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\"
+ RefName = "CORE_PEISrc_EDK"
+[files]
+"CORE_PEISrc.sdl"
+"CORE_PEISrc.mak"
+"AmiPeiInit.c"
+"CpuIo.c"
+"PciCfg.c"
+"DxeIpl.c"
+"PeiPerf.c"
+[parts]
+"CORE_PEISrcFramework_EDK"
+"CORE_PEISrcPI_EDK"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEISrc.mak b/Core/CORE_PEI/CORE_PEISrc.mak
new file mode 100644
index 0000000..32036c2
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEISrc.mak
@@ -0,0 +1,103 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/PeiMain/CORE_PEISrc.mak 11 2/05/11 3:41p Artems $
+#
+# $Revision: 11 $
+#
+# $Date: 2/05/11 3:41p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/PeiMain/CORE_PEISrc.mak $
+#
+# 11 2/05/11 3:41p Artems
+# Added support to build source in PI 0.91 or PI 1.0 mode
+#
+# 10 3/05/09 1:07p Felixp
+# Minor improvements:
+# - Unconditional optimization (despite debug flag settings) is removed
+# - Headers updated
+#
+# 9 8/25/06 10:58a Felixp
+#
+# 8 8/25/06 10:57a Felixp
+#
+# 7 8/25/06 10:56a Felixp
+#
+# 6 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
+#
+# 5 5/20/06 12:34a Felixp
+# Optimization is always on
+#
+# 4 5/19/06 10:37p Felixp
+#
+# 3 3/17/06 4:28p Felixp
+#
+# 2 3/13/06 5:25p Felixp
+#
+# 1 3/13/06 1:57a Felixp
+#
+# 2 12/02/05 11:19a Felixp
+#
+# 1 1/28/05 12:44p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CORE_PEISrc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CORE_PEI_LIB
+
+$(CORE_PEI_LIB) : CORE_PEI_LIB
+
+CORE_PEI_LIB : $(BUILD_DIR)\CORE_PEISrc.mak CORE_PEI_LIBBin
+
+$(BUILD_DIR)\CORE_PEISrc.mak : $(CORE_PEI_SRC_DIR)\$(@B).cif $(CORE_PEI_SRC_DIR)\$(@B).mak $(BUILD_RULES)
+!IF $(PI_SPECIFICATION_VERSION)>=0x00010000
+ $(CIF2MAK) $(CORE_PEI_SRC_DIR)\$(@B).cif $(CORE_PEI_SRC_DIR)\CORE_PEI_PI\$(@B)Pi.cif $(CIF2MAK_DEFAULTS)
+!ELSE
+ $(CIF2MAK) $(CORE_PEI_SRC_DIR)\$(@B).cif $(CORE_PEI_SRC_DIR)\CORE_PEI_FRAMEWORK\$(@B)Framework.cif $(CIF2MAK_DEFAULTS)
+!ENDIF
+
+CORE_PEI_LIBBin : $(BUILD_DIR)\FoundationPei.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CORE_PEISrc.mak all\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(CORE_PEI_LIB)\
+ "MY_INCLUDES=/I$(Foundation_DIR)"\
+!IF "$(x64_BUILD)"=="1"
+ "MY_DEFINES=/Dx64_BUILD_SUPPORT"\
+!ENDIF
+ EXT_HEADERS=$(BUILD_DIR)\token.h NAME=CORE_PEISrc
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_PEI/CORE_PEISrc.sdl b/Core/CORE_PEI/CORE_PEISrc.sdl
new file mode 100644
index 0000000..1c62c64
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEISrc.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = "DXE_STACK_SIZE"
+ Value = "0x100000"
+ Help = "Size of DXE Stack"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CORE_PEISrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CORE_PEI Source support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "CORE_PEI_SRC_DIR"
+End
+
+MODULE
+ Help = "Includes CORE_PEISrc.mak to Project"
+ File = "CORE_PEISrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CORE_PEI.lib"
+ Parent = "$(CORE_PEI_DIR)\CORE_PEI$(ARCH)$(DBG).lib"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c
new file mode 100644
index 0000000..782950a
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c
@@ -0,0 +1,108 @@
+/*++
+
+Copyright (c) 2004, 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:
+
+ BootMode.c
+
+Abstract:
+
+ EFI PEI Core Boot Mode services
+
+
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ if (BootMode == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ *BootMode = HandOffHob->BootMode;
+
+
+ return EFI_SUCCESS;
+};
+
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ HandOffHob->BootMode = BootMode;
+
+
+ return EFI_SUCCESS;
+};
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif
new file mode 100644
index 0000000..9c5a51e
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "CORE_PEI Source Framework (EDK)"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\CORE_PEI_FRAMEWORK"
+ RefName = "CORE_PEISrcFramework_EDK"
+[files]
+"BootMode.c"
+"dependency.c"
+"dependency.h"
+"Dispatcher.c"
+"FwVol.c"
+"Hob.c"
+"Image.c"
+"MemoryServices.c"
+"PeiCore.h"
+"PeiMain.c"
+"Ppi.c"
+"Reset.c"
+"Security.c"
+"StatusCode.c"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c
new file mode 100644
index 0000000..c82752f
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c
@@ -0,0 +1,604 @@
+/*++
+
+Copyright (c) 2004 - 2009, 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:
+
+ Dispatcher.c
+
+Abstract:
+
+ EFI PEI Core dispatch services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+
+EFI_STATUS
+TransferOldDataToNewDataRange (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ OUT UINTN *PrivateDataInMem
+ );
+
+EFI_GUID gEfiPeiCorePrivateGuid = EFI_PEI_CORE_PRIVATE_GUID;
+//*** AMI PORTING BEGIN ***//
+VOID AmiSwitchToMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *EntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+);
+//*** AMI PORTING END *****//
+
+EFI_STATUS
+PeiDispatcher (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_DISPATCH_DATA *DispatchData
+ )
+
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR
+ PrivateData - Pointer to the private data passed in from caller
+ DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_CORE_TEMP_POINTERS TempPtr;
+ UINTN PrivateDataInMem;
+ BOOLEAN NextFvFound;
+ EFI_FIRMWARE_VOLUME_HEADER *NextFvAddress;
+ EFI_FIRMWARE_VOLUME_HEADER *DefaultFvAddress;
+
+ //
+ // Debug data for uninstalled Peim list
+ //
+ PEI_DEBUG_CODE (
+
+ UINT64 DebugNotDispatchedBitmap;
+ EFI_GUID DebugFoundPeimList[64];
+ UINT8 DebugFoundPeimPoint;
+
+ )
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
+
+ ExtendedData.DataHeader.HeaderSize = (UINT16)sizeof (EFI_STATUS_CODE_DATA);
+ ExtendedData.DataHeader.Size = (UINT16)(sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - ExtendedData.DataHeader.HeaderSize);
+
+ PeiCoreCopyMem (
+ &ExtendedData.DataHeader.Type,
+ &gEfiStatusCodeSpecificDataGuid,
+ sizeof (EFI_GUID)
+ );
+ )
+ //
+ // save the Current FV Address so that we will not process it again if FindFv returns it later
+ //
+ DefaultFvAddress = DispatchData->BootFvAddress;
+
+ //
+ // This is the main dispatch loop. It will search known FVs for PEIMs and
+ // attempt to dispatch them. If any PEIM gets dispatched through a single
+ // pass of the dispatcher, it will start over from the Bfv again to see
+ // if any new PEIMs dependencies got satisfied. With a well ordered
+ // FV where PEIMs are found in the order their dependencies are also
+ // satisfied, this dipatcher should run only once.
+ //
+ for (;;) {
+ //
+ // This is the PEIM search loop. It will scan through all PEIMs it can find
+ // looking for PEIMs to dispatch, and will dipatch them if they have not
+ // already been dispatched and all of their dependencies are met.
+ // If no more PEIMs can be found in this pass through all known FVs,
+ // then it will break out of this loop.
+ //
+ for (;;) {
+
+ Status = FindNextPeim (
+ &PrivateData->PS,
+ DispatchData->CurrentFvAddress,
+ &DispatchData->CurrentPeimAddress
+ );
+
+ //
+ // If we found a PEIM, check if it is dispatched. If so, go to the
+ // next PEIM. If not, dispatch it if its dependencies are satisfied.
+ // If its dependencies are not satisfied, go to the next PEIM.
+ //
+ if (Status == EFI_SUCCESS) {
+
+ PEI_DEBUG_CODE (
+
+ //
+ // Fill list of found Peims for later list of those not installed
+ //
+ PeiCoreCopyMem (
+ &DebugFoundPeimList[DispatchData->CurrentPeim],
+ &DispatchData->CurrentPeimAddress->Name,
+ sizeof (EFI_GUID)
+ );
+
+ )
+
+ if (!Dispatched (
+ DispatchData->CurrentPeim,
+ DispatchData->DispatchedPeimBitMap
+ )) {
+ if (DepexSatisfied (&PrivateData->PS, DispatchData->CurrentPeimAddress)) {
+ Status = PeiLoadImage (
+ &PrivateData->PS,
+ DispatchData->CurrentPeimAddress,
+ &TempPtr.Raw
+ );
+ if (Status == EFI_SUCCESS) {
+
+ //
+ // The PEIM has its dependencies satisfied, and its entry point
+ // has been found, so invoke it.
+ //
+ PEI_PERF_START (
+ &PrivateData->PS,
+ L"PEIM",
+ (EFI_FFS_FILE_HEADER *)(DispatchData->CurrentPeimAddress),
+ 0
+ );
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ ExtendedData.Handle = (EFI_HANDLE)DispatchData->CurrentPeimAddress;
+
+ )
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ PeiReportStatusCode (
+ &(PrivateData->PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+
+ )
+
+ //
+ // Is this a authentic image
+ //
+ Status = VerifyPeim (
+ &PrivateData->PS,
+ DispatchData->CurrentPeimAddress
+ );
+
+ if (Status != EFI_SECURITY_VIOLATION) {
+
+ Status = TempPtr.PeimEntry (
+ DispatchData->CurrentPeimAddress,
+ &PrivateData->PS
+ );
+ }
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ PeiReportStatusCode (
+ &(PrivateData->PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+
+ )
+ PEI_PERF_END (&PrivateData->PS, L"PEIM", (EFI_FFS_FILE_HEADER *)(DispatchData->CurrentPeimAddress), 0);
+
+ //
+ // Mark the PEIM as dispatched so we don't attempt to run it again
+ //
+ SetDispatched (
+ &PrivateData->PS,
+ DispatchData->CurrentPeim,
+ &DispatchData->DispatchedPeimBitMap
+ );
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (&PrivateData->PS);
+
+ //
+ // If real system memory was discovered and installed by this
+ // PEIM, switch the stacks to the new memory. Since we are
+ // at dispatch level, only the Core's private data is preserved,
+ // nobody else should have any data on the stack.
+ //
+ if (PrivateData->SwitchStackSignal) {
+ TempPtr.PeiCore = PeiCore;
+ Status = TransferOldDataToNewDataRange (
+ PrivateData,
+ &PrivateDataInMem
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ //Subtract 0x10 from the 4th parameter indicating the new stack base,
+ //in order to provide buffer protection against possible illegal stack
+ //access that might corrupt the stack.
+ //
+//*** AMI PORTING BEGIN ***//
+ AmiSwitchToMemory (
+ &((PEI_CORE_INSTANCE*)PrivateDataInMem)->PS,
+ //SwitchCoreStacks (
+//*** AMI PORTING END *****//
+ TempPtr.Raw,
+ (UINTN)PeiStartupDescriptor,
+ PrivateDataInMem,
+ (VOID *)((UINTN)PrivateData->StackBase + (UINTN)PrivateData->StackSize - 0x10)
+ );
+ }
+ }
+ }
+ }
+ DispatchData->CurrentPeim++;
+ continue;
+
+ } else {
+
+ //
+ // If we could not find another PEIM in the current FV, go try
+ // the FindFv PPI to look in other FVs for more PEIMs. If we can
+ // not locate the FindFv PPI, or if the FindFv PPI can not find
+ // anymore FVs, then exit the PEIM search loop.
+ //
+ if (DispatchData->FindFv == NULL) {
+ Status = PeiLocatePpi (
+ &PrivateData->PS,
+ &gEfiFindFvPpiGuid,
+ 0,
+ NULL,
+ &DispatchData->FindFv
+ );
+ if (Status != EFI_SUCCESS) {
+ break;
+ }
+ }
+ NextFvFound = FALSE;
+ while (!NextFvFound) {
+ Status = DispatchData->FindFv->FindFv (
+ DispatchData->FindFv,
+ &PrivateData->PS,
+ &DispatchData->CurrentFv,
+ &NextFvAddress
+ );
+ //
+ // if there is no next fv, get out of this loop of finding FVs
+ //
+ if (Status != EFI_SUCCESS) {
+ break;
+ }
+ //
+ // don't process the default Fv again. (we don't know the order in which the hobs were created)
+ //
+ if ((NextFvAddress != DefaultFvAddress) &&
+ (NextFvAddress != DispatchData->CurrentFvAddress)) {
+
+ //
+ // VerifyFv() is currently returns SUCCESS all the time, add code to it to
+ // actually verify the given FV
+ //
+ Status = VerifyFv (NextFvAddress);
+ if (Status == EFI_SUCCESS) {
+ NextFvFound = TRUE;
+ DispatchData->CurrentFvAddress = NextFvAddress;
+ DispatchData->CurrentPeimAddress = NULL;
+ //
+ // current PRIM number (CurrentPeim) must continue as is, don't reset it here
+ //
+ }
+ }
+ }
+ //
+ // if there is no next fv, get out of this loop of dispatching PEIMs
+ //
+ if (!NextFvFound) {
+ break;
+ }
+ //
+ // continue in the inner for(;;) loop with a new FV;
+ //
+ }
+ }
+
+ //
+ // If all the PEIMs that we have found have been dispatched, then
+ // there is nothing left to dispatch and we don't need to go search
+ // through all PEIMs again.
+ //
+ if ((~(DispatchData->DispatchedPeimBitMap) &
+ (LShiftU64 (1, DispatchData->CurrentPeim)-1)) == 0) {
+ break;
+ }
+
+ //
+ // Check if no more PEIMs that depex was satisfied
+ //
+ if (DispatchData->DispatchedPeimBitMap == DispatchData->PreviousPeimBitMap) {
+ break;
+ }
+
+ //
+ // Case when Depex is not satisfied and has to traverse the list again
+ //
+ DispatchData->CurrentPeim = 0;
+ DispatchData->CurrentPeimAddress = 0;
+ DispatchData->PreviousPeimBitMap = DispatchData->DispatchedPeimBitMap;
+
+ //
+ // don't go back to the loop without making sure that the CurrentFvAddress is the
+ // same as the 1st (or default) FV we started with. otherwise we will interpret the bimap wrongly and
+ // mess it up, always start processing the PEIMs from the default FV just like in the first time around.
+ //
+ DispatchData->CurrentFv = 0;
+ DispatchData->CurrentFvAddress = DefaultFvAddress;
+ }
+
+ PEI_DEBUG_CODE (
+
+ DebugFoundPeimPoint = 0;
+ //
+ // Get bitmap of Peims that were not dispatched,
+ //
+
+ DebugNotDispatchedBitmap = ((DispatchData->DispatchedPeimBitMap) ^ (LShiftU64 (1, DispatchData->CurrentPeim)-1));
+ //
+ // Scan bitmap of Peims not installed and print GUIDS
+ //
+ while (DebugNotDispatchedBitmap != 0) {
+ if ((DebugNotDispatchedBitmap & 1) != 0) {
+ PEI_DEBUG (
+ (&PrivateData->PS, EFI_D_INFO,
+ "WARNING -> PEIM Not Dispatched: %g\n",
+ &DebugFoundPeimList[DebugFoundPeimPoint])
+ );
+ }
+ DebugFoundPeimPoint++;
+ DebugNotDispatchedBitmap = RShiftU64 (DebugNotDispatchedBitmap, 1);
+ }
+
+ )
+
+ return EFI_NOT_FOUND;
+}
+
+VOID
+InitializeDispatcherData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+Returns:
+
+ None.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ if (OldCoreData == NULL) {
+ PrivateData->DispatchData.CurrentFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;
+ PrivateData->DispatchData.BootFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;
+ } else {
+
+ //
+ // Current peim has been dispatched, but not count
+ //
+ PrivateData->DispatchData.CurrentPeim = (UINT8)(OldCoreData->DispatchData.CurrentPeim + 1);
+ }
+
+ return;
+}
+
+
+BOOLEAN
+Dispatched (
+ IN UINT8 CurrentPeim,
+ IN UINT64 DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine checks to see if a particular PEIM has been dispatched during
+ the PEI core dispatch.
+
+Arguments:
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ TRUE - PEIM already dispatched
+ FALSE - Otherwise
+
+--*/
+{
+ return (BOOLEAN)((DispatchedPeimBitMap & LShiftU64 (1, CurrentPeim)) != 0);
+}
+
+VOID
+SetDispatched (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 CurrentPeim,
+ OUT UINT64 *DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine sets a PEIM as having been dispatched once its entry
+ point has been invoked.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ None
+
+--*/
+{
+ //
+ // Check if the total number of PEIMs exceed the bitmap.
+ // CurrentPeim is 0-based
+ //
+PEI_DEBUG_CODE (
+ if (CurrentPeim > (sizeof (*DispatchedPeimBitMap) * 8 - 1)) {
+ ASSERT_PEI_ERROR (PeiServices, EFI_OUT_OF_RESOURCES);
+ }
+)
+ *DispatchedPeimBitMap |= LShiftU64 (1, CurrentPeim);
+ return;
+}
+
+BOOLEAN
+DepexSatisfied (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+ PeiServices - The PEI Service Table
+ CurrentPeimAddress - Address of the PEIM Firmware File under investigation
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+{
+ EFI_STATUS Status;
+ INT8 *DepexData;
+ BOOLEAN Runnable;
+
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_PEI_DEPEX,
+ CurrentPeimAddress,
+ &DepexData
+ );
+ //
+ // If there is no DEPEX, assume the module can be executed
+ //
+ if (EFI_ERROR (Status)) {
+ return TRUE;
+ }
+
+ //
+ // Evaluate a given DEPEX
+ //
+ Status = PeimDispatchReadiness (
+ PeiServices,
+ DepexData,
+ &Runnable
+ );
+
+ return Runnable;
+}
+
+
+EFI_STATUS
+TransferOldDataToNewDataRange (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ OUT UINTN *PrivateDataInMem
+ )
+/*++
+
+Routine Description:
+
+ This routine transfers the contents of the pre-permanent memory
+ PEI Core private data to a post-permanent memory data location.
+
+Arguments:
+ PrivateData - Pointer to the current PEI Core private data pre-permanent memory
+ PrivateDataInMem - Pointer to the PrivateData once the private data has been transferred
+ to permanent memory
+
+Returns:
+ EFI_SUCCESS - Successfully transfered
+ EFI_ERROR - Fail to transfer
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = PeiBuildHobGuid (
+ &(PrivateData->PS),
+ &gEfiPeiCorePrivateGuid,
+ sizeof (PEI_CORE_INSTANCE),
+ (VOID*)PrivateDataInMem
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ (*PrivateDataInMem) += sizeof (EFI_HOB_GUID_TYPE);
+ PrivateData->PS->CopyMem (
+ (VOID*)(*PrivateDataInMem),
+ (VOID*)PrivateData,
+ sizeof (PEI_CORE_INSTANCE)
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c
new file mode 100644
index 0000000..14eb90c
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c
@@ -0,0 +1,488 @@
+/*++
+
+Copyright (c) 2004 - 2005, 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:
+
+ FwVol.c
+
+Abstract:
+
+ Pei Core Firmware File System service routines.
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImageFormat.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#define GETOCCUPIEDSIZE(ActualSize, Alignment) \
+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
+
+STATIC
+EFI_FFS_FILE_STATE
+GetFileState(
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Returns the highest bit set of the State field
+
+Arguments:
+
+ ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY
+ in the Attributes field.
+ FfsHeader - Pointer to FFS File Header.
+
+Returns:
+ Returns the highest bit in the State field
+
+--*/
+{
+ EFI_FFS_FILE_STATE FileState;
+ EFI_FFS_FILE_STATE HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
+
+STATIC
+UINT8
+CalculateHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FileHeader
+ )
+/*++
+
+Routine Description:
+
+ Calculates the checksum of the header of a file.
+
+Arguments:
+
+ FileHeader - Pointer to FFS File Header.
+
+Returns:
+ Checksum of the header.
+
+ The header is zero byte checksum.
+ - Zero means the header is good.
+ - Non-zero means the header is bad.
+
+
+Bugbug: For PEI performance reason, we comments this code at this time.
+--*/
+{
+ UINT8 *ptr;
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+ ptr = (UINT8 *)FileHeader;
+
+ for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ Sum = (UINT8)(Sum + ptr[Index+1]);
+ Sum = (UINT8)(Sum + ptr[Index+2]);
+ Sum = (UINT8)(Sum + ptr[Index+3]);
+ }
+
+ for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ }
+
+ //
+ // State field (since this indicates the different state of file).
+ //
+ Sum = (UINT8)(Sum - FileHeader->State);
+ //
+ // Checksum field of the file is not part of the header checksum.
+ //
+ Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
+
+ return Sum;
+}
+
+STATIC
+EFI_STATUS
+PeiFfsFindNextFileEx (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **FileHeader,
+ IN BOOLEAN Flag
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+ Flag - Indicator for if this is for PEI Dispath search
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINT32 FileLength;
+ UINT32 FileOccupiedSize;
+ UINT32 FileOffset;
+ UINT64 FvLength;
+ UINT8 ErasePolarity;
+ UINT8 FileState;
+
+
+ FvLength = FwVolHeader->FvLength;
+ if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // If FileHeader is not specified (NULL) start with the first file in the
+ // firmware volume. Otherwise, start from the FileHeader.
+ //
+ if (*FileHeader == NULL) {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
+ } else {
+ //
+ // Length is 24 bits wide so mask upper 8 bits
+ // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
+ }
+
+ FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
+ PEI_ASSERT (PeiServices, (FileOffset <= 0xFFFFFFFF));
+
+ while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, FfsFileHeader);
+
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_INVALID:
+ FileOffset += sizeof(EFI_FFS_FILE_HEADER);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
+ break;
+
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
+ if (Flag) {
+ if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
+
+ *FileHeader = FfsFileHeader;
+
+
+ return EFI_SUCCESS;
+ }
+ } else {
+ if ((SearchType == FfsFileHeader->Type) ||
+ (SearchType == EFI_FV_FILETYPE_ALL)) {
+
+ *FileHeader = FfsFileHeader;
+
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ } else {
+//*** AMI PORTING BEGIN ***//
+// Skip the assert to support a more sophisiticated
+// FV corruption handling outside of the Core.
+// PEI_ASSERT (PeiServices, (0));
+//*** AMI PORTING END *****//
+ return EFI_NOT_FOUND;
+ }
+ break;
+
+ case EFI_FILE_DELETED:
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ default:
+ return EFI_NOT_FOUND;
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_FFS_FILE_HEADER *FfsFileHeader,
+ IN OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FfsFileHeader - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+ UINT32 SectionLength;
+ UINT32 ParsedLength;
+
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // Does not include FfsFileHeader header size
+ // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
+ FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileSize -= sizeof(EFI_FFS_FILE_HEADER);
+
+ *SectionData = NULL;
+ ParsedLength = 0;
+ while (ParsedLength < FileSize) {
+ if (Section->Type == SectionType) {
+ *SectionData = (VOID *)(Section + 1);
+
+
+ return EFI_SUCCESS;
+ }
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+ SectionLength = GETOCCUPIEDSIZE (SectionLength, 4);
+ PEI_ASSERT (PeiServices, SectionLength != 0);
+ ParsedLength += SectionLength;
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ }
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+EFI_STATUS
+FindNextPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ PeimFileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ return PeiFfsFindNextFileEx (
+ PeiServices,
+ 0,
+ FwVolHeader,
+ PeimFileHeader,
+ TRUE
+ );
+}
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **FileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ return PeiFfsFindNextFileEx (
+ PeiServices,
+ SearchType,
+ FwVolHeader,
+ FileHeader,
+ FALSE
+ );
+}
+
+EFI_STATUS
+EFIAPI
+PeiFvFindNextVolume (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
+ )
+/*++
+
+Routine Description:
+
+ Return the Firmware Volume instance requested
+
+ BugBug -- Move this to the location of this code to where the
+ other FV and FFS support code lives.
+ Also, update to use FindFV for instances #'s >= 1.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Instance - Instance of FV to find
+ FwVolHeader - Pointer to contain the data to return
+
+Returns:
+ Pointer to the Firmware Volume instance requested
+
+ EFI_INVALID_PARAMETER - FwVolHeader is NULL
+
+ EFI_SUCCESS - Firmware volume instance successfully found.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_STATUS Status;
+ EFI_FIND_FV_PPI *FindFvPpi;
+ UINT8 LocalInstance;
+
+
+ LocalInstance = (UINT8) Instance;
+
+ Status = EFI_SUCCESS;
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ if (FwVolHeader == NULL) {
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Instance == 0) {
+ //
+ // If instance is 0, the first firmware volume must be BFV.
+ //
+ *FwVolHeader = PrivateData->DispatchData.BootFvAddress;
+
+
+ return Status;
+ } else {
+ //
+ // Locate all instances of FindFV
+ // Alternately, could use FV HOBs, but the PPI is cleaner
+ //
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gEfiFindFvPpiGuid,
+ 0,
+ NULL,
+ &FindFvPpi
+ );
+
+ if (Status != EFI_SUCCESS) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ Status = FindFvPpi->FindFv (
+ FindFvPpi,
+ PeiServices,
+ &LocalInstance,
+ FwVolHeader
+ );
+
+ }
+ }
+ return Status;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c
new file mode 100644
index 0000000..cffbf6c
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c
@@ -0,0 +1,198 @@
+/*++
+
+Copyright (c) 2004 - 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:
+
+ Hob.c
+
+Abstract:
+
+ EFI PEI Core HOB services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+
+ //
+ // Only check this parameter in debug mode
+ //
+
+ PEI_DEBUG_CODE (
+ if (HobList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ )
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ *HobList = PrivateData->HobList.Raw;
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+ EFI_PHYSICAL_ADDRESS FreeMemory;
+
+
+ Status = PeiGetHobList (PeiServices, Hob);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ HandOffHob = *Hob;
+
+ Length = (UINT16)((Length + 0x7) & (~0x7));
+
+ FreeMemory = HandOffHob->EfiFreeMemoryTop -
+ HandOffHob->EfiFreeMemoryBottom;
+
+ if (FreeMemory < Length) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0;
+
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+ HobEnd++;
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+
+ Hob = (VOID *)(UINTN)MemoryBegin;
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1);
+ Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
+ Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+ Hob->Header.Reserved = 0;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+
+ Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
+ Hob->BootMode = BootMode;
+
+ Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiMemoryBottom = MemoryBegin;
+ Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);
+ Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c
new file mode 100644
index 0000000..8ccbd68
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c
@@ -0,0 +1,341 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ Image.c
+
+Abstract:
+
+ Pei Core Load Image Support
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_PPI_DEFINITION (LoadFile)
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *PeimFileHeader,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Routine for loading file image.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeimFileHeader - Pointer to the FFS file header of the image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *Pe32Data;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_PEI_FV_FILE_LOADER_PPI *FvLoadFilePpi;
+#ifdef EFI_NT_EMULATOR
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ NT_PEI_LOAD_FILE_PPI *PeiNtService;
+ EFI_PHYSICAL_ADDRESS NtEntryPoint;
+#endif
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ EFI_PHYSICAL_ADDRESS ImageEntryPoint;
+ EFI_TE_IMAGE_HEADER *TEImageHeader;
+ UINT16 Machine;
+
+ PEI_DEBUG_CODE (ImageAddress = 0;)
+
+ *EntryPoint = NULL;
+ TEImageHeader = NULL;
+ PeHdr = NULL;
+ //
+ // Try to find a PE32 section.
+ //
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_PE32,
+ PeimFileHeader,
+ &Pe32Data
+ );
+ //
+ // If we didn't find a PE32 section, try to find a TE section.
+ //
+ if (Status != EFI_SUCCESS) {
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_TE,
+ PeimFileHeader,
+ (VOID **) &TEImageHeader
+ );
+ Pe32Data = (VOID *) TEImageHeader;
+ }
+ if (Status == EFI_SUCCESS) {
+ if (TEImageHeader == NULL) {
+ if (((EFI_IMAGE_DOS_HEADER *) Pe32Data)->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) Pe32Data)->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) Pe32Data;
+ }
+ Machine = PeHdr->FileHeader.Machine;
+//*** AMI PORTING BEGIN ***//
+//This is needed to enable execution of the PEIMS
+//from the firmware volumes in memory.
+ if ( PeHdr->OptionalHeader.ImageBase
+ !=(UINTN)Pe32Data
+ ) Status=EFI_NOT_FOUND;
+//Init ImageSize for to pass into UpdatedLoadedImagePpi
+ ImageSize = PeHdr->OptionalHeader.SizeOfImage;
+//*** AMI PORTING END *****//
+ } else {
+//*** AMI PORTING BEGIN ***//
+ Machine = TEImageHeader->Machine;
+//This is needed to enable execution of the PEIMS
+//from the firmware volumes in memory.
+//The following two lines are not needed because
+//we don't support reallocation of TE image into memory.
+// if ( TEImageHeader->ImageBase!=(UINTN)(TEImageHeader))
+// Status=EFI_NOT_FOUND;
+
+//Init ImageSize for to pass into UpdatedLoadedImagePpi.
+//Let's get size from the FFS section header
+ ImageSize = FVSECTION_SIZE(TEImageHeader);
+//*** AMI PORTING END *****//
+ }
+ //
+ // Check PEIM image machine. A PEIM image for different processor architecture
+ // from the host can't be started.
+ //
+ if (Machine != EFI_IMAGE_MACHINE_TYPE) {
+ return EFI_UNSUPPORTED;
+ }
+
+#ifdef EFI_NT_EMULATOR
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gNtPeiLoadFileGuid,
+ 0,
+ &PpiDescriptor,
+ &PeiNtService
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PeiNtService->PeiLoadFileService (
+ Pe32Data,
+ &ImageAddress,
+ &ImageSize,
+ &NtEntryPoint
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (TEImageHeader != NULL) {
+ *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ }
+ } else {
+ *EntryPoint = (VOID *) (UINTN) NtEntryPoint;
+ }
+
+#else
+ ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;
+ if (TEImageHeader != NULL) {
+ *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ }
+#endif
+//*** AMI PORTING BEGIN ***//
+// } else {
+ }
+ if (Status!=EFI_SUCCESS){
+//*** AMI PORTING END *****//
+ //
+ // There was not a PE32 section, so assume that it's a Compressed section
+ // and use the LoadFile
+ //
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiFvFileLoaderPpiGuid,
+ 0,
+ NULL,
+ &FvLoadFilePpi
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = FvLoadFilePpi->FvLoadFile (
+ FvLoadFilePpi,
+ PeimFileHeader,
+ &ImageAddress,
+ &ImageSize,
+ &ImageEntryPoint
+ );
+
+ if (!EFI_ERROR (Status)) {
+ *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);
+ if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress;
+ Machine = TEImageHeader->Machine;
+ } else {
+ if (((EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress)->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) ImageAddress + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress)->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) (UINTN) ImageAddress;
+ }
+ Machine = PeHdr->FileHeader.Machine;
+ }
+ //
+ // Check PEIM image machine. A PEIM image for different processor architecture
+ // from the host can't be started.
+ //
+ if (Machine != EFI_IMAGE_MACHINE_TYPE) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+ }
+//*** AMI PORTING BEGIN ***//
+//Message is printed later. Disable this one
+/*
+ PEI_DEBUG_CODE (
+ {
+ EFI_IMAGE_DATA_DIRECTORY * DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY * DebugEntry;
+ UINTN DirCount;
+ UINTN Index;
+ UINTN Index1;
+ BOOLEAN FileNameFound;
+ CHAR8 *AsciiString;
+ CHAR8 AsciiBuffer[512];
+ VOID *CodeViewEntryPointer;
+ INTN TEImageAdjust;
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
+ //
+ PEI_DEBUG ((PeiServices, EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));
+
+ //
+ // Find the codeview info in the image and display the file name
+ // being loaded.
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ DebugEntry = NULL;
+ DirectoryEntry = NULL;
+ TEImageAdjust = 0;
+ if (TEImageHeader == NULL) {
+ if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) ImageAddress + DirectoryEntry->VirtualAddress);
+ }
+ } else {
+ if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
+ DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +
+ TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
+ TEImageAdjust);
+ }
+ }
+
+ if (DebugEntry != NULL && DirectoryEntry != NULL) {
+ for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ if (DebugEntry->SizeOfData > 0) {
+ CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
+ switch (* (UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_RSDS:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+
+ default:
+ AsciiString = NULL;
+ break;
+ }
+ if (AsciiString != NULL) {
+ FileNameFound = FALSE;
+ for (Index = 0, Index1 = 0; AsciiString[Index] != 0; Index++) {
+ if (AsciiString[Index] == '\\') {
+ Index1 = Index;
+ FileNameFound = TRUE;
+ }
+ }
+
+ if (FileNameFound) {
+ for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {
+ AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];
+ }
+ AsciiBuffer[Index - (Index1 + 1)] = 0;
+ PEI_DEBUG ((PeiServices, EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ PEI_DEBUG ((PeiServices, EFI_D_INFO | EFI_D_LOAD, "\n"));
+ }
+ }
+ )
+*/
+#ifdef EFI_DEBUG
+if (!EFI_ERROR (Status)){
+ char sName[0x100];
+ if (!GetName((VOID*)(UINTN)ImageAddress,sName)) Sprintf_s(sName,sizeof(sName),"[%G]",&PeimFileHeader->Name);
+ PeiTrace(TRACE_PEICORE, PeiServices, "%s.Entry(%X)\n", sName, *EntryPoint);
+}
+else PeiTrace(TRACE_PEICORE, PeiServices, "ERROR: attempt to load FFS file [%G] has failed\n", &PeimFileHeader->Name);
+#endif
+//New image is loaded and is about to be launched
+//Update LoadedImage PPI information
+if (!EFI_ERROR (Status))
+ UpdatedLoadedImagePpi(PeiServices,ImageAddress,ImageSize,PeimFileHeader);
+//*** AMI PORTING END *****//
+ return Status;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c
new file mode 100644
index 0000000..9566e02
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c
@@ -0,0 +1,440 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ MemoryServices.c
+
+Abstract:
+
+ EFI PEI Core memory services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiApi.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+//*** AMI PORTING BEGIN ***//
+//use SDL token 'DXE_STACK_SIZE' to define stack size
+#include <Token.h>
+#undef PEI_STACK_SIZE
+#define PEI_STACK_SIZE DXE_STACK_SIZE
+//*** AMI PORTING END *****//
+
+VOID
+InitializeMemoryServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ UINT64 SizeOfCarHeap;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+ PrivateData->SwitchStackSignal = FALSE;
+
+ if (OldCoreData == NULL) {
+
+ PrivateData->PeiMemoryInstalled = FALSE;
+
+//*** AMI PORTING BEGIN ***//
+//The original method of getting CAR top and bootom addresses assumes that CAR base address is aligned
+//on CAR size boundary, which is not always the case.
+//Make the algorithm more flexible
+//Comment out the old code:
+// PrivateData->BottomOfCarHeap = (VOID *) (((UINTN)(VOID *)(&PrivateData))
+// & (~((PeiStartupDescriptor->SizeOfCacheAsRam) - 1)));
+// PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + PeiStartupDescriptor->SizeOfCacheAsRam);
+//New code:
+// Private data is located towards the top of the stack.
+// The stack is located at the top of the CAR.
+// We assume that:
+// 1) CAR address and size are at least 1K aligned.
+// 2) Not more than 1K of Stack is used by SEC phase.
+// The top of the CAR should be the next 1K boundary
+//NOTE: New PI 1.0 spec provides a better solution.
+//It expends SEC to PI hand off structure to explicitly pass CAR address
+//This code will be changed once PI support is added.
+#define CAR_ADDRESS_AND_SIZE_ALIGNMENT 0x400
+ PrivateData->TopOfCarHeap = (VOID *)(
+ (((UINTN)(VOID *)(&PrivateData))+CAR_ADDRESS_AND_SIZE_ALIGNMENT)
+ & (~(CAR_ADDRESS_AND_SIZE_ALIGNMENT-1))
+ );
+ PrivateData->BottomOfCarHeap = (VOID *)(
+ (UINTN)(PrivateData->TopOfCarHeap)
+ - PeiStartupDescriptor->SizeOfCacheAsRam
+ );
+//*** AMI PORTING END *****//
+ //
+ // SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.
+ //
+ SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;
+ SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);
+
+ PEI_DEBUG_CODE (
+ {
+ PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;
+ PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);
+ }
+ )
+
+ PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;
+
+ PeiCoreBuildHobHandoffInfoTable (
+ BOOT_WITH_FULL_CONFIGURATION,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,
+ (UINTN) SizeOfCarHeap
+ );
+ //
+ // Copy PeiServices from ROM to Cache in PrivateData
+ //
+ PeiCoreCopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));
+
+ //
+ // Set PS to point to ServiceTableShadow in Cache
+ //
+ PrivateData->PS = &(PrivateData->ServiceTableShadow);
+ } else {
+ //
+ // Set PS to point to ServiceTableShadow in Cache one time after the
+ // stack switched to main memory
+ //
+ PrivateData->PS = &(PrivateData->ServiceTableShadow);
+}
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;
+ EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;
+ UINT64 PeiStackSize;
+ UINT64 EfiFreeMemorySize;
+ EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+//*** AMI PORTING BEGIN ***//
+ if (PrivateData->PeiMemoryInstalled) {
+ //This function should be called once. Report error if this is the second call
+ PEI_ERROR_CODE(PeiServices, PEI_MEMORY_INSTALLED_TWICE, EFI_ERROR_MINOR);
+ }else {
+ //Debug message
+ PEI_TRACE((TRACE_PEICORE, PeiServices, "Memory Installed: Address=%lX; Length=%lX\n",MemoryBegin,MemoryLength));
+ }
+//*** AMI PORTING END *****//
+
+ PrivateData->SwitchStackSignal = TRUE;
+ PrivateData->PeiMemoryInstalled = TRUE;
+
+ PrivateData->StackBase = MemoryBegin;
+
+ PeiStackSize = RShiftU64 (MemoryLength, 1);
+ if (PEI_STACK_SIZE > PeiStackSize) {
+ PrivateData->StackSize = PeiStackSize;
+ } else {
+ PrivateData->StackSize = PEI_STACK_SIZE;
+ }
+
+ OldHandOffHob = PrivateData->HobList.HandoffInformationTable;
+
+ PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));
+ NewHandOffHob = PrivateData->HobList.HandoffInformationTable;
+ PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;
+
+ EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;
+
+ PeiCoreCopyMem (
+ NewHandOffHob,
+ OldHandOffHob,
+ (UINTN)EfiFreeMemorySize
+ );
+
+ NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;
+ NewHandOffHob->EfiMemoryBottom = MemoryBegin;
+
+ NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;
+
+ NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +
+ (OldHandOffHob->EfiEndOfHobList -
+ PhysicalAddressOfOldHob);
+
+ ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);
+
+ PeiBuildHobStack (PeiServices, PrivateData->StackBase, PrivateData->StackSize);
+//*** AMI PORTING BEGIN ***//
+//Update LoadedImage pointers
+PrivateData->LoadedImage = (EFI_PEI_PPI_DESCRIPTOR*)
+ ( (UINTN)PrivateData->LoadedImage + ((UINTN)NewHandOffHob - (UINTN)OldHandOffHob) );
+//*** AMI PORTING END *****//
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));
+ }
+ )
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS Offset;
+ EFI_STATUS Status;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // Check if Hob already available
+ //
+ if (!PrivateData->PeiMemoryInstalled) {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+
+ Hob.Raw = PrivateData->HobList.Raw;
+
+ //
+ // Check to see if on 4k boundary
+ //
+ Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;
+
+ //
+ // If not aligned, make the allocation aligned.
+ //
+ if (Offset != 0) {
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;
+ }
+
+ //
+ // Verify that there is sufficient memory to satisfy the allocation
+ //
+ if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
+ Hob.HandoffInformationTable->EfiFreeMemoryBottom) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiAllocatePages fail: Pages - 0x%08x\n", Pages));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Update the PHIT to reflect the memory usage
+ //
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
+
+ //
+ // Update the value for the caller
+ //
+ *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;
+
+ //
+ // Create a memory allocation HOB.
+ //
+ Status = PeiBuildHobMemoryAllocation (
+ PeiServices,
+ Hob.HandoffInformationTable->EfiFreeMemoryTop,
+ Pages * EFI_PAGE_SIZE + Offset,
+ NULL,
+ MemoryType
+ );
+
+ return Status;
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_POOL *Hob;
+
+
+ Status = PeiCreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_PEI_MEMORY_POOL,
+ (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
+ &Hob
+ );
+ *Buffer = Hob+1;
+
+
+ return Status;
+}
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibCopyMem (Destination, Source, Length);
+}
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibSetMem (Buffer, Size, Value);
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h
new file mode 100644
index 0000000..24130e5
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h
@@ -0,0 +1,1260 @@
+/*++
+
+Copyright (c) 2004 - 2009, 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:
+
+ PeiCore.h
+
+Abstract:
+
+ Definition of Pei Core Structures and Services
+
+Revision History
+
+--*/
+
+#ifndef _PEICORE_H_
+#define _PEICORE_H_
+
+#include "EfiImage.h"
+#include "Pei.h"
+#include "PeiHob.h"
+
+#ifdef EFI64
+#include "SalApi.h"
+#endif
+
+#include "EfiCommonLib.h"
+
+#include EFI_PPI_DEFINITION (FindFv)
+#include EFI_PPI_DEFINITION (DxeIpl)
+#include EFI_PPI_DEFINITION (StatusCode)
+#include EFI_PPI_DEFINITION (Security)
+
+
+#ifdef EFI_NT_EMULATOR
+#include EFI_PPI_DEFINITION (NtPeiLoadFile)
+#endif
+
+//*** AMI PORTING BEGIN ***//
+#include <PPI/LoadedImagePpi.h>
+//*** AMI PORTING END *****//
+
+//
+//Build private HOB to PEI core to transfer old NEM-range data to new NEM-range
+//
+#define EFI_PEI_CORE_PRIVATE_GUID \
+ {0xd641a0f5, 0xcb7c, 0x4846, 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9}
+
+//
+// Pei Core private data structures
+//
+typedef union _PEI_PPI_LIST_POINTERS {
+ EFI_PEI_PPI_DESCRIPTOR *Ppi;
+ EFI_PEI_NOTIFY_DESCRIPTOR *Notify;
+ VOID *Raw;
+} PEI_PPI_LIST_POINTERS;
+
+#define PEI_STACK_SIZE 0x20000
+
+#define MAX_PPI_DESCRIPTORS 128
+
+typedef struct {
+ INTN PpiListEnd;
+ INTN NotifyListEnd;
+ INTN DispatchListEnd;
+ INTN LastDispatchedInstall;
+ INTN LastDispatchedNotify;
+ PEI_PPI_LIST_POINTERS PpiListPtrs[MAX_PPI_DESCRIPTORS];
+} PEI_PPI_DATABASE;
+
+typedef struct {
+ UINT8 CurrentPeim;
+ UINT8 CurrentFv;
+ UINT64 DispatchedPeimBitMap;
+ UINT64 PreviousPeimBitMap;
+ EFI_FFS_FILE_HEADER *CurrentPeimAddress;
+ EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFvAddress;
+ EFI_FIND_FV_PPI *FindFv;
+} PEI_CORE_DISPATCH_DATA;
+
+
+//
+// Pei Core private data structure instance
+//
+
+#define PEI_CORE_HANDLE_SIGNATURE EFI_SIGNATURE_32('P','e','i','C')
+
+typedef struct{
+ UINTN Signature;
+ EFI_PEI_SERVICES *PS; // Point to ServiceTableShadow
+ PEI_PPI_DATABASE PpiData;
+ PEI_CORE_DISPATCH_DATA DispatchData;
+ EFI_PEI_HOB_POINTERS HobList;
+ BOOLEAN SwitchStackSignal;
+ BOOLEAN PeiMemoryInstalled;
+ EFI_PHYSICAL_ADDRESS StackBase;
+ UINT64 StackSize;
+ VOID *BottomOfCarHeap;
+ VOID *TopOfCarHeap;
+ VOID *CpuIo;
+ PEI_SECURITY_PPI *PrivateSecurityPpi;
+ EFI_PEI_SERVICES ServiceTableShadow;
+//*** AMI PORTING BEGIN ***//
+ EFI_PEI_PPI_DESCRIPTOR *LoadedImage;
+ EFI_PEI_LOADED_IMAGE_PPI LoadedImagePpi;
+//*** AMI PORTING END *****//
+ PEI_DEBUG_CODE (
+ UINTN SizeOfCacheAsRam;
+ VOID *MaxTopOfCarHeap;
+ )
+} PEI_CORE_INSTANCE;
+
+//
+// Pei Core Instance Data Macros
+//
+
+#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \
+ PEI_CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE)
+
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CORE_ENTRY_POINT) (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ );
+
+//
+// Union of temporarily used function pointers (to save stack space)
+//
+typedef union {
+ PEI_CORE_ENTRY_POINT PeiCore;
+ EFI_PEIM_ENTRY_POINT PeimEntry;
+ EFI_PEIM_NOTIFY_ENTRY_POINT PeimNotifyEntry;
+ EFI_DXE_IPL_PPI *DxeIpl;
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
+ VOID *Raw;
+} PEI_CORE_TEMP_POINTERS;
+
+
+//
+// Main PEI entry
+//
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+//
+// Dispatcher support functions
+//
+
+EFI_STATUS
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression,
+ IN OUT BOOLEAN *Runnable
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+;
+
+
+EFI_STATUS
+PeiDispatcher (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_DISPATCH_DATA *DispatchData
+ )
+
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR
+ PrivateData - Pointer to the private data passed in from caller
+ DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+;
+
+
+VOID
+InitializeDispatcherData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+EFI_STATUS
+FindNextPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ PeimFileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+BOOLEAN
+Dispatched (
+ IN UINT8 CurrentPeim,
+ IN UINT64 DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine checks to see if a particular PEIM has been dispatched during
+ the PEI core dispatch.
+
+Arguments:
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ TRUE if PEIM already dispatched
+ FALSE if not
+
+--*/
+;
+
+VOID
+SetDispatched (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 CurrentPeim,
+ OUT UINT64 *DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine sets a PEIM as having been dispatched once its entry
+ point has been invoked.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ None
+
+--*/
+;
+
+BOOLEAN
+DepexSatisfied (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+ PeiServices - The PEI Service Table
+ CurrentPeimAddress - Address of the PEIM Firmware File under investigation
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+;
+
+VOID
+SwitchCoreStacks (
+ IN VOID *EntryPoint,
+ IN UINTN Parameter1,
+ IN UINTN Parameter2,
+ IN VOID *NewStack
+ )
+/*++
+
+Routine Description:
+
+ Routine for PEI switching stacks.
+
+Arguments:
+
+ EntryPoint - Entry point with new stack.
+ Parameter1 - First parameter for entry point.
+ Parameter2 - Second parameter for entry point.
+ NewStack - Pointer to new stack.
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+#ifdef EFI64
+ //
+ // In Ipf we should make special changes for the PHIT pointers to support
+ // recovery boot in cache mode.
+ //
+#define SWITCH_TO_CACHE_MODE(CoreData) SwitchToCacheMode(CoreData)
+#define CACHE_MODE_ADDRESS_MASK 0x7FFFFFFFFFFFFFFF
+VOID
+SwitchToCacheMode (
+ IN PEI_CORE_INSTANCE *CoreData
+)
+/*++
+
+Routine Description:
+
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
+
+Arguments:
+
+ CoreData - The PEI core Private Data
+
+Returns:
+
+--*/
+;
+
+#else
+
+#define SWITCH_TO_CACHE_MODE(CoreData)
+
+#endif
+
+//
+// PPI support functions
+//
+VOID
+InitializePpiServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+;
+
+VOID
+ConvertPpiPointers (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Migrate the Hob list from the CAR stack to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *OldPpi,
+ IN EFI_PEI_PPI_DESCRIPTOR *NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+;
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+;
+
+VOID
+DispatchNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+;
+
+//
+// Boot mode support functions
+//
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+;
+
+//
+// Security support functions
+//
+VOID
+InitializeSecurityServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the OEM FV verification service.
+
+Arguments:
+
+ CurrentFvAddress - Pointer to the FV under investigation.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+
+EFI_STATUS
+VerifyPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+;
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
+
+
+//
+// FFS Fw Volume support functions
+//
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 SearchType,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **FileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_FFS_FILE_HEADER *FfsFileHeader,
+ IN OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FfsFileHeader - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFvFindNextVolume (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
+ )
+/*++
+
+Routine Description:
+
+ Return the BFV location
+
+ BugBug -- Move this to the location of this code to where the
+ other FV and FFS support code lives.
+ Also, update to use FindFV for instances #'s >= 1.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Instance - Instance of FV to find
+ FwVolHeader - Pointer to contain the data to return
+
+Returns:
+ Pointer to the Firmware Volume instance requested
+
+ EFI_INVALID_PARAMETER - FwVolHeader is NULL
+
+ EFI_SUCCESS - Firmware volume instance successfully found.
+
+--*/
+;
+
+//
+// Memory support functions
+//
+VOID
+InitializeMemoryServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of allocation.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *PeimFileHeader,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Get entry point of a Peim file.
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ PeimFileHeader - Peim file's header.
+
+ EntryPoint - Entry point of that Peim file.
+
+Returns:
+
+ Status code.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ CodeType - Type of Status Code.
+
+ Value - Value to output for Status Code.
+
+ Instance - Instance Number of this status code.
+
+ CallerId - ID of the caller of this status code.
+
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiCoreResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+;
+//*** AMI PORTING BEGIN ***//
+//This function is used to update LoadedImage PPI information
+//LoadedImage PPI is defined in PI 1.0 specification
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+);
+
+#include <AmiPeiLib.h>
+//*** AMI PORTING END *****//
+#endif
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c
new file mode 100644
index 0000000..bfcdbe4
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c
@@ -0,0 +1,405 @@
+/*++
+
+Copyright (c) 2004 - 2005, 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:
+
+ PeiMain.c
+
+Abstract:
+
+ Pei Core Main Entry Point
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_PPI_DEFINITION (MemoryDiscovered)
+#include EFI_PPI_DEFINITION (FindFv)
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+#include EFI_GUID_DEFINITION (StatusCode)
+
+//
+//CAR is filled with this initial value during SEC phase
+//
+#define INIT_CAR_VALUE 0x5AA55AA5
+
+#ifdef EFI_PEI_PERFORMANCE
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+
+#endif
+
+//*** AMI PORTING BEGIN ***//
+VOID InitParts(VOID* p1, VOID*p2);
+VOID InitPartsMem(VOID* p1, VOID*p2);
+VOID ProcessLoadHob(EFI_PEI_SERVICES **PeiServices);
+VOID AmiInitParts(IN EFI_PEI_SERVICES **PeiServices, VOID* InitFunction);
+//*** AMI PORTING END *****//
+
+static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiMemoryDiscoveredPpiGuid,
+ NULL
+};
+
+//
+// Pei Core Module Variables
+//
+//
+static EFI_PEI_SERVICES mPS = {
+ {
+ PEI_SERVICES_SIGNATURE,
+ PEI_SERVICES_REVISION,
+ sizeof (EFI_PEI_SERVICES),
+ 0,
+ 0
+ },
+ PeiInstallPpi,
+ PeiReInstallPpi,
+ PeiLocatePpi,
+ PeiNotifyPpi,
+
+ PeiGetBootMode,
+ PeiSetBootMode,
+
+ PeiGetHobList,
+ PeiCreateHob,
+
+ PeiFvFindNextVolume,
+ PeiFfsFindNextFile,
+ PeiFfsFindSectionData,
+
+ PeiInstallPeiMemory,
+ PeiAllocatePages,
+ PeiAllocatePool,
+ PeiCoreCopyMem,
+ PeiCoreSetMem,
+
+ PeiReportStatusCode,
+
+//*** AMI PORTING BEGIN ***//
+// This is a bug fix.
+// In accordance with PEI CIS 0.91
+// this structure has been extended with two more pointers.
+// PeiCoreResetSystem
+ PeiCoreResetSystem,
+ NULL,
+ NULL
+//*** AMI PORTING END *****//
+};
+
+VOID
+EFIAPI
+AsmWriteMm7 (
+ IN UINT64 Value
+ );
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ );
+
+//
+// Main entry point to the PEI Core
+//
+EFI_PEI_CORE_ENTRY_POINT (PeiMain)
+
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+Returns:
+
+ This function never returns
+
+--*/
+{
+ return PeiCore (PeiStartupDescriptor, NULL);
+}
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+ EFI_NOT_FOUND - Never reach
+
+--*/
+{
+ PEI_CORE_INSTANCE PrivateData;
+ EFI_STATUS Status;
+ PEI_CORE_TEMP_POINTERS TempPtr;
+ PEI_CORE_DISPATCH_DATA *DispatchData;
+
+
+#ifdef EFI_PEI_PERFORMANCE
+ UINT64 mTick;
+
+ mTick = 0;
+ if (OldCoreData == NULL) {
+ GetTimerValue (&mTick);
+ }
+#endif
+
+
+ //
+ // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
+ // the 63-bit of address is set to 1.
+ //
+ SWITCH_TO_CACHE_MODE (OldCoreData);
+
+ if (OldCoreData != NULL) {
+ PeiCoreCopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
+ } else {
+ PeiCoreSetMem (&PrivateData, sizeof (PEI_CORE_INSTANCE), 0);
+ }
+
+ PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
+ PrivateData.PS = &mPS;
+
+ //
+ // Mm7 stored PeiServicesTablePointer in EdkII Glue Library
+ // Update Mm7 now
+ //
+//*** AMI PORTING BEGIN ***//
+//#if (defined(EFI32)) || (defined(EFIX64))
+#ifndef EFI64
+//*** AMI PORTING END *****//
+ AsmWriteMm7 ((UINT64)(UINTN)(&PrivateData.PS));
+#endif
+
+ InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData);
+
+ InitializePpiServices (&PrivateData.PS, OldCoreData);
+
+ InitializeSecurityServices (&PrivateData.PS, OldCoreData);
+
+ InitializeDispatcherData (&PrivateData.PS, OldCoreData, PeiStartupDescriptor);
+
+ if (OldCoreData != NULL) {
+
+ PEI_PERF_END (&PrivateData.PS,L"PreMem", NULL, 0);
+ PEI_PERF_START (&PrivateData.PS,L"PostMem", NULL, 0);
+
+ //
+ // The following code dumps out interesting cache as RAM usage information
+ // so we can keep tabs on how the cache as RAM is being utilized. The
+ // PEI_DEBUG_CODE macro is used to prevent this code from being compiled
+ // on a debug build.
+ //
+ PEI_DEBUG_CODE (
+ {
+ UINTN *StackPointer;
+ UINTN StackValue;
+
+ StackValue = INIT_CAR_VALUE;
+ for (StackPointer = (UINTN *) OldCoreData->MaxTopOfCarHeap;
+ ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
+ && StackValue == INIT_CAR_VALUE;
+ StackPointer++) {
+ StackValue = *StackPointer;
+ }
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
+ ((UINTN) OldCoreData->TopOfCarHeap - (UINTN) StackPointer)
+ )
+ );
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR heap used: %d bytes.\n",
+ ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
+ (UINTN) OldCoreData->HobList.Raw)
+ )
+ );
+ }
+ )
+
+//*** AMI PORTING BEGIN ***//
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+//*** AMI PORTING END *****//
+
+ //
+ // Alert any listeners that there is permanent memory available
+ //
+ PEI_PERF_START (&PrivateData.PS,L"DisMem", NULL, 0);
+ Status = PeiInstallPpi (&PrivateData.PS, &mMemoryDiscoveredPpi);
+ PEI_PERF_END (&PrivateData.PS,L"DisMem", NULL, 0);
+
+ } else {
+
+ //
+ // Report Status Code EFI_SW_PC_INIT
+ //
+ PEI_REPORT_STATUS_CODE (
+ &(PrivateData.PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT,
+ 0,
+ NULL,
+ NULL
+ );
+
+ //
+ // If first pass, start performance measurement.
+ //
+ PEI_PERF_START (&PrivateData.PS,L"PreMem", NULL, mTick);
+
+ //
+ // If SEC provided any PPI services to PEI, install them.
+ //
+ if (PeiStartupDescriptor->DispatchTable != NULL) {
+ Status = PeiInstallPpi (&PrivateData.PS, PeiStartupDescriptor->DispatchTable);
+
+ ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+ }
+//*** AMI PORTING BEGIN ***//
+{
+ static EFI_GUID gEfiPeiLoadedImagePpiGuid = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+ static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiLoadedImagePpiGuid, NULL
+ };
+ PeiAllocatePool(&PrivateData.PS,sizeof(EFI_PEI_PPI_DESCRIPTOR),&PrivateData.LoadedImage);
+ *PrivateData.LoadedImage = LoadedImagePpiDesc;
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+ PeiInstallPpi (&PrivateData.PS, PrivateData.LoadedImage);
+}
+//*** AMI PORTING END *****//
+ }
+
+ DispatchData = &PrivateData.DispatchData;
+
+ //
+ // Call PEIM dispatcher
+ //
+//*** AMI PORTING BEGIN ***//
+ if (OldCoreData != NULL) {
+ AmiInitParts(&PrivateData.PS, InitPartsMem);
+ ProcessLoadHob(&PrivateData.PS);
+ } else {
+ AmiInitParts(&PrivateData.PS, InitParts);
+ }
+//*** AMI PORTING END *****//
+ PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);
+
+ //
+ // Check if InstallPeiMemory service was called.
+ //
+//*** AMI PORTING BEGIN ***//
+ //report MEMORY_NOT_INSTALLED error
+ if (!PrivateData.PeiMemoryInstalled)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_MEMORY_NOT_INSTALLED, EFI_ERROR_MAJOR);
+// PEI_ASSERT(&PrivateData.PS, PrivateData.PeiMemoryInstalled == TRUE);
+//*** AMI PORTING END *****//
+
+ PEI_PERF_END (&PrivateData.PS, L"PostMem", NULL, 0);
+
+ Status = PeiLocatePpi (
+ &PrivateData.PS,
+ &gEfiDxeIplPpiGuid,
+ 0,
+ NULL,
+ &TempPtr.DxeIpl
+ );
+//*** AMI PORTING BEGIN ***//
+ //report DXEIPL_NOT_FOUND error
+ if (EFI_ERROR(Status))
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_DXEIPL_NOT_FOUND, EFI_ERROR_MAJOR);
+// ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+//*** AMI PORTING END *****//
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "DXE IPL Entry(%X)\n",TempPtr.DxeIpl->Entry));
+ Status = TempPtr.DxeIpl->Entry (
+ TempPtr.DxeIpl,
+ &PrivateData.PS,
+//*** AMI PORTING BEGIN ***//
+// PEI CIS defines parameter as EFI_PEI_HOB_POINTERS, but
+// EFI_PEI_HOB_POINTERS is not defined in PEI CIS.
+// Until this is fixed PEI.h defines this parameter as VOID*
+// PrivateData.HobList
+ PrivateData.HobList.Raw
+//*** AMI PORTING END *****//
+ );
+//*** AMI PORTING BEGIN ***//
+ // If DXE IPL returned control, let's call dispatcher again
+ // DXE IPL might have dicovered new FV or have changed a boot mode
+
+ // reset previous bitmap so that the dispatcher will attempt to execute any new PEIMs
+ DispatchData->PreviousPeimBitMap = 0;
+ // dispatch
+ PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);
+ // DXE IPL
+ Status = TempPtr.DxeIpl->Entry (
+ TempPtr.DxeIpl,
+ &PrivateData.PS,
+ PrivateData.HobList.Raw
+ );
+//*** AMI PORTING END *****//
+ ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+ return EFI_NOT_FOUND;
+}
+
+//*** AMI PORTING BEGIN ***//
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+)
+{
+ PEI_CORE_INSTANCE *Private = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ Private->LoadedImagePpi.ImageAddress = ImageAddress;
+ Private->LoadedImagePpi.ImageSize = ImageSize;
+ Private->LoadedImagePpi.FileHandle = FileHandle;
+ PeiReInstallPpi(PeiServices,Private->LoadedImage,Private->LoadedImage);
+}
+//*** AMI PORTING END *****// \ No newline at end of file
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c
new file mode 100644
index 0000000..62077e3
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c
@@ -0,0 +1,673 @@
+/*++
+
+Copyright (c) 2004 - 2005, 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:
+
+ Ppi.c
+
+Abstract:
+
+ EFI PEI Core PPI services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+VOID
+InitializePpiServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ if (OldCoreData == NULL) {
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
+ }
+
+ return;
+}
+
+VOID
+ConvertPpiPointers (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Convert PPI pointers after the Hob list was migrated from the CAR stack
+ to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+
+ None.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ UINT8 Index;
+ PEI_PPI_LIST_POINTERS *PpiPointer;
+ UINTN Fixup;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;
+
+ for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {
+ if (Index < PrivateData->PpiData.PpiListEnd ||
+ Index > PrivateData->PpiData.NotifyListEnd) {
+ PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
+
+ if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the PEIM descriptor from the old HOB heap
+ // to the relocated HOB heap.
+ //
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);
+
+ //
+ // Only when the PEIM descriptor is in the old HOB should it be necessary
+ // to try to convert the pointers in the PEIM descriptor
+ //
+
+ if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);
+ }
+
+ //
+ // Assume that no code is located in the temporary memory, so the pointer to
+ // the notification function in the NOTIFY descriptor needs not be converted.
+ //
+ if (Index < PrivateData->PpiData.PpiListEnd &&
+ (UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&
+ (UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {
+ //
+ // Convert the pointer to the PPI interface structure in the PPI descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);
+ }
+ }
+ }
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN LastCallbackInstall;
+
+
+ if (PpiList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Index = PrivateData->PpiData.PpiListEnd;
+ LastCallbackInstall = Index;
+
+ //
+ // This is loop installs all PPI descriptors in the PpiList. It is terminated
+ // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_PPI_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the NotifyList
+ //
+ if (Index == PrivateData->PpiData.NotifyListEnd + 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Check if it is a valid PPI.
+ // If not, rollback list to exclude all in this list.
+ // Try to indicate which item failed.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ PrivateData->PpiData.PpiListEnd = LastCallbackInstall;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));
+ return EFI_INVALID_PARAMETER;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));
+//*** AMI PORTING END *****//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = PpiList;
+ PrivateData->PpiData.PpiListEnd++;
+
+ //
+ // Continue until the end of the PPI List.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ PpiList++;
+ Index++;
+ }
+
+ //
+ // Dispatch any callback level notifies for newly installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ LastCallbackInstall,
+ PrivateData->PpiData.PpiListEnd,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *OldPpi,
+ IN EFI_PEI_PPI_DESCRIPTOR *NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+
+
+ if ((OldPpi == NULL) || (NewPpi == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Find the old PPI instance in the database. If we can not find it,
+ // return the EFI_NOT_FOUND error.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {
+ break;
+ }
+ }
+ if (Index == PrivateData->PpiData.PpiListEnd) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Remove the old PPI from the database, add the new one.
+ //
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
+//*** AMI PORTING END *****//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = NewPpi;
+
+ //
+ // Dispatch any callback level notifies for the newly installed PPI.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ Index,
+ Index+1,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_PPI_DESCRIPTOR *TempPtr;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Search the data base for the matching instance of the GUIDed PPI.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;
+ CheckGuid = TempPtr->Guid;
+
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {
+ if (Instance == 0) {
+
+ if (PpiDescriptor != NULL) {
+ *PpiDescriptor = TempPtr;
+ }
+
+ if (Ppi != NULL) {
+ *Ppi = TempPtr->Ppi;
+ }
+
+
+ return EFI_SUCCESS;
+ }
+ Instance--;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN NotifyIndex;
+ INTN LastCallbackNotify;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr;
+ UINTN NotifyDispatchCount;
+
+
+ NotifyDispatchCount = 0;
+
+ if (NotifyList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Index = PrivateData->PpiData.NotifyListEnd;
+ LastCallbackNotify = Index;
+
+ //
+ // This is loop installs all Notify descriptors in the NotifyList. It is
+ // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the PpiList
+ //
+ if (Index == PrivateData->PpiData.PpiListEnd - 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // If some of the PPI data is invalid restore original Notify PPI database value
+ //
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
+ PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyDispatchCount ++;
+ }
+
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyList;
+
+ PrivateData->PpiData.NotifyListEnd--;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ //
+ // Go the next descriptor. Remember the NotifyList moves down.
+ //
+ NotifyList++;
+ Index--;
+ }
+
+ //
+ // If there is Dispatch Notify PPI installed put them on the bottom
+ //
+ if (NotifyDispatchCount > 0) {
+ for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {
+ if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;
+
+ for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;
+ }
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;
+ PrivateData->PpiData.DispatchListEnd--;
+ }
+ }
+
+ LastCallbackNotify -= NotifyDispatchCount;
+ }
+
+ //
+ // Dispatch any callback level notifies for all previously installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ 0,
+ PrivateData->PpiData.PpiListEnd,
+ LastCallbackNotify,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN TempValue;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+
+ while (TRUE) {
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // Notifies getting installed. If so, go process any dispatch
+ // level Notifies that match the previouly installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
+ TempValue = PrivateData->PpiData.DispatchListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ 0,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.LastDispatchedNotify,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedNotify = TempValue;
+ }
+
+
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // PPIs getting installed. If so, go process any dispatch
+ // level Notifies that match the installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // PpiListEnd (with InstallPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
+ TempValue = PrivateData->PpiData.PpiListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.PpiListEnd,
+ MAX_PPI_DESCRIPTORS-1,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedInstall = TempValue;
+ }
+
+ if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {
+ break;
+ }
+ }
+ return;
+}
+
+VOID
+DispatchNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index1;
+ INTN Index2;
+ EFI_GUID *SearchGuid;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Remember that Installs moves up and Notifies moves down.
+ //
+ for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {
+ NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;
+
+ CheckGuid = NotifyDescriptor->Guid;
+
+ for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
+ SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {
+ PEI_DEBUG (
+ (
+ PeiServices,
+ EFI_D_INFO,
+ "Notify: PPI Guid: %g, Peim notify entry point: %x\n",
+ SearchGuid,
+ NotifyDescriptor->Notify
+ )
+ );
+ NotifyDescriptor->Notify (
+ PeiServices,
+ NotifyDescriptor,
+ (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi
+ );
+ }
+ }
+ }
+
+ return;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c
new file mode 100644
index 0000000..bbfd4a9
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c
@@ -0,0 +1,77 @@
+/*++
+
+Copyright (c) 2004, 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:
+
+ Reset.c
+
+Abstract:
+
+ Pei Core Reset System Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (Reset)
+
+EFI_STATUS
+EFIAPI
+PeiCoreResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_RESET_PPI *ResetPpi;
+
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiResetPpiGuid,
+ 0,
+ NULL,
+ &ResetPpi
+ );
+
+ //
+ // LocatePpi returns EFI_NOT_FOUND on error
+ //
+ if (!EFI_ERROR (Status)) {
+ return ResetPpi->ResetSystem (PeiServices);
+ }
+//*** AMI PORTING BEGIN ***//
+ //Report error
+ PEI_ERROR_CODE(PeiServices,PEI_RESET_NOT_AVAILABLE,EFI_ERROR_MINOR);
+//*** AMI PORTING END *****//
+ return EFI_NOT_AVAILABLE_YET;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c
new file mode 100644
index 0000000..928e21a
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c
@@ -0,0 +1,194 @@
+/*++
+
+Copyright (c) 2004 - 2005, 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:
+
+ Security.c
+
+Abstract:
+
+ EFI PEI Core Security services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include EFI_PPI_DEFINITION (Security)
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiSecurityPpiGuid,
+ SecurityPpiNotifyCallback
+};
+
+VOID
+InitializeSecurityServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PeiNotifyPpi (PeiServices, &mNotifyList);
+ }
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Provide a callback for when the security PPI is installed.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ NotifyDescriptor - The descriptor for the notification event.
+ Ppi - Pointer to the PPI in question.
+
+Returns:
+
+ EFI_SUCCESS - The function is successfully processed.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ //
+ // Get PEI Core private data
+ //
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // If there isn't a security PPI installed, use the one from notification
+ //
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ PrivateData->PrivateSecurityPpi = (PEI_SECURITY_PPI *)Ppi;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+VerifyPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_STATUS Status;
+ UINT32 AuthenticationStatus;
+ BOOLEAN StartCrisisRecovery;
+
+ //
+ // Set a default authentication state
+ //
+ AuthenticationStatus = 0;
+
+ //
+ // get security PPI instance from PEI private data
+ //
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Check to see if the image is OK
+ //
+ Status = PrivateData->PrivateSecurityPpi->AuthenticationState (
+ PeiServices,
+ PrivateData->PrivateSecurityPpi,
+ AuthenticationStatus,
+ CurrentPeimAddress,
+ &StartCrisisRecovery
+ );
+ if (StartCrisisRecovery) {
+ Status = EFI_SECURITY_VIOLATION;
+ }
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress
+ )
+/*++
+
+Routine Description:
+
+ Verify a Firmware volume
+
+Arguments:
+
+ CurrentFvAddress - Pointer to the current Firmware Volume under consideration
+
+Returns:
+
+ EFI_SUCCESS - Firmware Volume is legal
+ EFI_SECURITY_VIOLATION - Firmware Volume fails integrity test
+
+--*/
+{
+ //
+ // Right now just pass the test. Future can authenticate and/or check the
+ // FV-header or other metric for goodness of binary.
+ //
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c
new file mode 100644
index 0000000..26cac94
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c
@@ -0,0 +1,102 @@
+/*++
+
+Copyright (c) 2004, 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:
+
+ StatusCode.c
+
+Abstract:
+
+ Pei Core Status Code Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (StatusCode)
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ CodeType - Type of Status Code.
+
+ Value - Value to output for Status Code.
+
+ Instance - Instance Number of this status code.
+
+ CallerId - ID of the caller of this status code.
+
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_STATUS_CODE_PPI *StatusCodePpi;
+
+
+ //
+ //Locate StatusCode Ppi.
+ //
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiStatusCodePpiGuid,
+ 0,
+ NULL,
+ &StatusCodePpi
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = StatusCodePpi->ReportStatusCode (
+ PeiServices,
+ CodeType,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+
+
+ return Status;
+
+ }
+
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c
new file mode 100644
index 0000000..ff3b2e4
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c
@@ -0,0 +1,268 @@
+/*++
+
+Copyright (c) 2004, 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:
+
+ dependency.c
+
+Abstract:
+
+ PEI Dispatcher Dependency Evaluator
+
+ This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine
+ if a driver can be scheduled for execution. The criteria for
+ schedulability is that the dependency expression is satisfied.
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include "EfiDependency.h"
+#include "Dependency.h"
+
+STATIC
+BOOLEAN
+IsPpiInstalled (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EVAL_STACK_ENTRY *Stack
+ )
+/*++
+
+Routine Description:
+
+ This routine determines if a PPI has been installed.
+ The truth value of a GUID is determined by if the PPI has
+ been published and can be queried from the PPI database.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Stack - Reference to EVAL_STACK_ENTRY that contains PPI GUID to check
+
+Returns:
+
+ True if the PPI is already installed.
+ False if the PPI has yet to be installed.
+
+--*/
+{
+ VOID *PeiInstance;
+ EFI_STATUS Status;
+ EFI_GUID PpiGuid;
+
+ //
+ // If there is no GUID to evaluate, just return current result on stack.
+ //
+ if (Stack->Operator == NULL) {
+ return Stack->Result;
+ }
+
+ //
+ // Copy the Guid into a locale variable so that there are no
+ // possibilities of alignment faults for cross-compilation
+ // environments such as Intel?Itanium(TM).
+ //
+ PeiCoreCopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));
+
+ //
+ // Check if the PPI is installed.
+ //
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &PpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiInstance // PPI
+ );
+
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+EFI_STATUS
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression,
+ OUT BOOLEAN *Runnable
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+{
+ EFI_STATUS Status;
+ DEPENDENCY_EXPRESSION_OPERAND *Iterator;
+ EVAL_STACK_ENTRY *StackPtr;
+ EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];
+
+ Status = EFI_SUCCESS;
+ Iterator = DependencyExpression;
+ *Runnable = FALSE;
+
+ StackPtr = &EvalStack[0];
+
+ while (TRUE) {
+
+ switch (*(Iterator++)) {
+
+ //
+ // For performance reason we put the frequently used items in front of
+ // the rarely used items
+ //
+
+ case (EFI_DEP_PUSH):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)
+ // We will evaluate if the PPI is insalled on the POP operation.
+ //
+ StackPtr->Operator = (VOID *) Iterator;
+ Iterator = Iterator + sizeof (EFI_GUID);
+ StackPtr++;
+ break;
+
+ case (EFI_DEP_AND):
+ case (EFI_DEP_OR):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the two POPs for the AND operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did two POPs.
+ //
+ if (StackPtr < &EvalStack[2]) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Evaluate the first POPed operator only. If the operand is
+ // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the
+ // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,
+ // we don't need to check the second operator, and the result will be
+ // evaluation of the POPed operator. Otherwise, don't POP the second
+ // operator since it will now evaluate to the final result on the
+ // next operand that causes a POP.
+ //
+ StackPtr--;
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_AND) {
+ if (!(IsPpiInstalled (PeiServices, StackPtr))) {
+ (StackPtr-1)->Result = FALSE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ } else {
+ if (IsPpiInstalled (PeiServices, StackPtr)) {
+ (StackPtr-1)->Result = TRUE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ }
+ break;
+
+ case (EFI_DEP_END):
+ StackPtr--;
+ //
+ // Check to make sure EvalStack is balanced. If not, then there is
+ // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.
+ //
+ if (StackPtr != &EvalStack[0]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Runnable = IsPpiInstalled (PeiServices, StackPtr);
+ return EFI_SUCCESS;
+ break;
+
+ case (EFI_DEP_NOT):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the POP for the NOT operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did a POP.
+ //
+ if (StackPtr < &EvalStack[1]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));
+ (StackPtr-1)->Operator = NULL;
+ break;
+
+ case (EFI_DEP_TRUE):
+ case (EFI_DEP_FALSE):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_TRUE) {
+ StackPtr->Result = TRUE;
+ } else {
+ StackPtr->Result = FALSE;
+ }
+ StackPtr->Operator = NULL;
+ StackPtr++;
+ break;
+
+ default:
+ //
+ // The grammar should never arrive here
+ //
+ return EFI_INVALID_PARAMETER;
+ break;
+ }
+ }
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h
new file mode 100644
index 0000000..9df008b
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h
@@ -0,0 +1,38 @@
+/*++
+
+Copyright (c) 2004, 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:
+
+ dependency.h
+
+Abstract:
+
+ This module contains data specific to dependency expressions
+ and local function prototypes.
+
+--*/
+
+#ifndef _PEI_DEPENDENCY_H_
+#define _PEI_DEPENDENCY_H_
+
+#define MAX_GRAMMAR_SIZE 256
+
+//
+// type definitions
+//
+typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND;
+
+typedef struct {
+ BOOLEAN Result;
+ VOID *Operator;
+} EVAL_STACK_ENTRY;
+
+#endif
diff --git a/Core/CORE_PEI/CORE_PEI_PI/BootMode.c b/Core/CORE_PEI/CORE_PEI_PI/BootMode.c
new file mode 100644
index 0000000..2c5845a
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/BootMode.c
@@ -0,0 +1,107 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ BootMode.c
+
+Abstract:
+
+ EFI PEI Core Boot Mode services
+
+
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ if (BootMode == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ *BootMode = HandOffHob->BootMode;
+
+
+ return EFI_SUCCESS;
+};
+
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ HandOffHob->BootMode = BootMode;
+
+ return EFI_SUCCESS;
+};
diff --git a/Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif b/Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif
new file mode 100644
index 0000000..62d8649
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "CORE_PEI Source PI (EDK)"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\CORE_PEI_PI"
+ RefName = "CORE_PEISrcPI_EDK"
+[files]
+"BootMode.c"
+"dependency.c"
+"dependency.h"
+"Dispatcher.c"
+"FwVol.c"
+"Hob.c"
+"Image.c"
+"MemoryServices.c"
+"PeiCore.h"
+"PeiMain.c"
+"Ppi.c"
+"Reset.c"
+"Security.c"
+"StatusCode.c"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c b/Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c
new file mode 100644
index 0000000..91e8821
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c
@@ -0,0 +1,689 @@
+/*++
+
+Copyright (c) 2004 - 2009, 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:
+
+ Dispatcher.c
+
+Abstract:
+
+ EFI PEI Core dispatch services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+
+//*** AMI PORTING BEGIN ***//
+VOID PeiCoreEntry(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList);
+//*** AMI PORTING END *****//
+VOID
+DiscoverPeimsAndOrderWithApriori (
+ IN PEI_CORE_INSTANCE *Private,
+ IN EFI_PEI_FV_HANDLE VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Discover all Peims and optional Apriori file in one FV. There is at most one
+ Apriori file in one FV.
+
+Arguments:
+
+ Private - Pointer to the private data passed in from caller
+ VolumeHandle - Fv handle.
+Returns:
+
+ NONE
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE FileHandle;
+ EFI_PEI_FILE_HANDLE AprioriFileHandle;
+ EFI_GUID *Apriori;
+ UINTN Index;
+ UINTN Index2;
+ UINTN PeimIndex;
+ UINTN PeimCount;
+ EFI_GUID *Guid;
+ EFI_PEI_FV_HANDLE TempFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
+ EFI_GUID FileGuid[PEI_CORE_MAX_PEIM_PER_FV];
+
+ //
+ // Walk the FV and find all the PEIMs and the Apriori file.
+ //
+ AprioriFileHandle = NULL;
+ Private->CurrentFvFileHandles[0] = NULL;
+ Guid = NULL;
+ FileHandle = NULL;
+
+ //
+ // If the current Fv has been scanned, directly get its cachable record.
+ //
+ if (Private->Fv[Private->CurrentPeimFvCount].ScanFv) {
+ PeiCoreCopyMem (Private->CurrentFvFileHandles, Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, sizeof (Private->CurrentFvFileHandles));
+ return;
+ }
+
+ //
+ // Go ahead to scan this Fv, and cache FileHandles within it.
+ //
+ for (PeimCount = 0; PeimCount < PEI_CORE_MAX_PEIM_PER_FV; PeimCount++) {
+ Status = PeiFindFileEx (
+ VolumeHandle,
+ NULL,
+ PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
+ &FileHandle,
+ &AprioriFileHandle
+ );
+ if (Status != EFI_SUCCESS) {
+ break;
+ }
+
+ Private->CurrentFvFileHandles[PeimCount] = FileHandle;
+ }
+
+ Private->AprioriCount = 0;
+ if (AprioriFileHandle != NULL) {
+ //
+ // Read the Apriori file
+ //
+ Status = PeiFfsFindSectionData (&Private->PS, EFI_SECTION_RAW, AprioriFileHandle, &Apriori);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Calculate the number of PEIMs in the A Priori list
+ //
+ Private->AprioriCount = *(UINT32 *)(((EFI_FFS_FILE_HEADER *)AprioriFileHandle)->Size) & 0x00FFFFFF;
+ Private->AprioriCount -= sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_COMMON_SECTION_HEADER);
+ Private->AprioriCount /= sizeof (EFI_GUID);
+
+ PeiCoreSetMem (FileGuid, sizeof (FileGuid), 0);
+ for (Index = 0; Index < PeimCount; Index++) {
+ //
+ // Make an array of file name guids that matches the FileHandle array so we can convert
+ // quickly from file name to file handle
+ //
+ PeiCoreCopyMem (&FileGuid[Index], &((EFI_FFS_FILE_HEADER *)Private->CurrentFvFileHandles[Index])->Name,sizeof(EFI_GUID));
+ }
+
+ //
+ // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
+ // Add avalible PEIMs in Apriori file into TempFileHandles array at first.
+ //
+ Index2 = 0;
+ for (Index = 0; Index2 < Private->AprioriCount; Index++) {
+ while (Index2 < Private->AprioriCount) {
+ Guid = ScanGuid (FileGuid, PeimCount * sizeof (EFI_GUID), &Apriori[Index2++]);
+ if (Guid != NULL) {
+ break;
+ }
+ }
+ if (Guid == NULL) {
+ break;
+ }
+ PeimIndex = ((UINTN)Guid - (UINTN)&FileGuid[0])/sizeof (EFI_GUID);
+ TempFileHandles[Index] = Private->CurrentFvFileHandles[PeimIndex];
+
+ //
+ // Since we have copied the file handle we can remove it from this list.
+ //
+ Private->CurrentFvFileHandles[PeimIndex] = NULL;
+ }
+
+ //
+ // Update valid Aprioricount
+ //
+ Private->AprioriCount = Index;
+
+ //
+ // Add in any PEIMs not in the Apriori file
+ //
+ for (;Index < PeimCount; Index++) {
+ for (Index2 = 0; Index2 < PeimCount; Index2++) {
+ if (Private->CurrentFvFileHandles[Index2] != NULL) {
+ TempFileHandles[Index] = Private->CurrentFvFileHandles[Index2];
+ Private->CurrentFvFileHandles[Index2] = NULL;
+ break;
+ }
+ }
+ }
+ //
+ //Index the end of array contains re-range Pei moudle.
+ //
+ TempFileHandles[Index] = NULL;
+
+ //
+ // Private->CurrentFvFileHandles is currently in PEIM in the FV order.
+ // We need to update it to start with files in the A Priori list and
+ // then the remaining files in PEIM order.
+ //
+ PeiCoreCopyMem (Private->CurrentFvFileHandles, TempFileHandles, sizeof (Private->CurrentFvFileHandles));
+ }
+ }
+ //
+ // Cache the current Fv File Handle. So that we don't have to scan the Fv again.
+ // Instead, we can retrieve the file handles within this Fv from cachable data.
+ //
+ Private->Fv[Private->CurrentPeimFvCount].ScanFv = TRUE;
+ PeiCoreCopyMem (Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles));
+
+}
+
+
+VOID
+PeiDispatcher (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *Private
+ )
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ Private - Pointer to the private data passed in from caller
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 Index1;
+ UINT32 Index2;
+ EFI_PEI_SERVICES **PeiServices;
+ VOID *PrivateInMem;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
+ EFI_PEI_FILE_HANDLE PeimFileHandle;
+ UINTN FvCount;
+ UINTN PeimCount;
+ UINT32 AuthenticationState;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+ EFI_PEIM_ENTRY_POINT PeimEntryPoint;
+ VOID* PeiCoreReentryPoint;
+ UINTN SaveCurrentPeimCount;
+ UINTN SaveCurrentFvCount;
+ EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
+
+ ExtendedData.DataHeader.HeaderSize = (UINT16)sizeof (EFI_STATUS_CODE_DATA);
+ ExtendedData.DataHeader.Size = (UINT16)(sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - ExtendedData.DataHeader.HeaderSize);
+
+ PeiCoreCopyMem (
+ &ExtendedData.DataHeader.Type,
+ &gEfiStatusCodeSpecificDataGuid,
+ sizeof (EFI_GUID)
+ );
+ )
+
+ PeiServices = &Private->PS;
+ PeimEntryPoint = NULL;
+ PeimFileHandle = NULL;
+
+ if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ //
+ // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
+ // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
+ //
+ SaveCurrentPeimCount = Private->CurrentPeimCount;
+ SaveCurrentFvCount = Private->CurrentPeimFvCount;
+ SaveCurrentFileHandle = Private->CurrentFileHandle;
+
+ for (Index1 = 0;Index1 <= SaveCurrentFvCount; Index1++) {
+ for (Index2 = 0; (Index2 < PEI_CORE_MAX_PEIM_PER_FV) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {
+ if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {
+ PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
+ Status = PeiLoadImage (
+ &Private->PS,
+ PeimFileHandle,
+ &EntryPoint,
+ &AuthenticationState
+ );
+ if (Status == EFI_SUCCESS) {
+ //
+ // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
+ //
+ Private->Fv[Index1].PeimState[Index2]++;
+ Private->CurrentFileHandle = PeimFileHandle;
+ Private->CurrentPeimFvCount = Index1;
+ Private->CurrentPeimCount = Index2;
+
+ //
+ // Call the PEIM entry point
+ //
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
+
+ PEI_PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
+ PeimEntryPoint(PeimFileHandle, &Private->PS);
+ PEI_PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
+ }
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (&Private->PS);
+ }
+ }
+ }
+ Private->CurrentFileHandle = SaveCurrentFileHandle;
+ Private->CurrentPeimFvCount = SaveCurrentFvCount;
+ Private->CurrentPeimCount = SaveCurrentPeimCount;
+ }
+
+ //
+ // This is the main dispatch loop. It will search known FVs for PEIMs and
+ // attempt to dispatch them. If any PEIM gets dispatched through a single
+ // pass of the dispatcher, it will start over from the Bfv again to see
+ // if any new PEIMs dependencies got satisfied. With a well ordered
+ // FV where PEIMs are found in the order their dependencies are also
+ // satisfied, this dipatcher should run only once.
+ //
+ do {
+ //
+ // In case that reenter PeiCore happens, the last pass record is still available.
+ //
+ if (!Private->PeimDispatcherReenter) {
+ Private->PeimNeedingDispatch = FALSE;
+ Private->PeimDispatchOnThisPass = FALSE;
+ } else {
+ Private->PeimDispatcherReenter = FALSE;
+ }
+ for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {
+ Private->CurrentPeimFvCount = FvCount;
+ VolumeHandle = Private->Fv[FvCount].FvHeader;
+
+ if (Private->CurrentPeimCount == 0) {
+ //
+ // When going through each FV, at first, search Apriori file to
+ // reorder all PEIMs to ensure the PEIMs in Apriori file to get
+ // dispatch at first.
+ //
+ DiscoverPeimsAndOrderWithApriori (Private, VolumeHandle);
+ }
+
+ //
+ // Start to dispatch all modules within the current Fv.
+ //
+ for (PeimCount = Private->CurrentPeimCount;
+ (PeimCount < PEI_CORE_MAX_PEIM_PER_FV) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
+ PeimCount++) {
+ Private->CurrentPeimCount = PeimCount;
+ PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
+
+ if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {
+ if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
+ Private->PeimNeedingDispatch = TRUE;
+ } else {
+ Status = PeiLoadImage (
+ PeiServices,
+ PeimFileHandle,
+ &EntryPoint,
+ &AuthenticationState
+ );
+ if ((Status == EFI_SUCCESS)) {
+ //
+ // The PEIM has its dependencies satisfied, and its entry point
+ // has been found, so invoke it.
+ //
+ PEI_PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
+
+ PEI_REPORT_STATUS_CODE_CODE (
+ ExtendedData.Handle = PeimFileHandle;
+ )
+
+ PEI_REPORT_STATUS_CODE_CODE (
+ PeiReportStatusCode (
+ PeiServices,
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+ )
+
+ Status = VerifyPeim (Private, VolumeHandle, PeimFileHandle);
+ if (Status != EFI_SECURITY_VIOLATION && (AuthenticationState == 0)) {
+ //
+ // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
+ //
+ Private->Fv[FvCount].PeimState[PeimCount]++;
+
+ //
+ // Call the PEIM entry point
+ //
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
+ PeimEntryPoint (PeimFileHandle, PeiServices);
+ Private->PeimDispatchOnThisPass = TRUE;
+ }
+
+ PEI_REPORT_STATUS_CODE_CODE (
+ PeiReportStatusCode (
+ PeiServices,
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+ )
+ PEI_PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
+ }
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (PeiServices);
+
+ //
+ // If permanent memory was discovered and installed by this
+ // PEIM, shadow PEI Core and switch the stacks to the new memory.
+ //
+ if (Private->SwitchStackSignal) {
+
+ //
+ // Make sure we don't retry the same PEIM that added memory
+ //
+ Private->CurrentPeimCount++;
+
+ //
+ // Indicate that PeiCore reenter
+ //
+ Private->PeimDispatcherReenter = TRUE;
+ //
+ // Migrate IDT from CAR into real memory, so after stack switches to
+ // the new memory, the caller can get memory version PeiServiceTable.
+ //
+ MigrateIdtTable (PeiServices);
+ //
+ // Since we are at dispatch level, only the Core's private data
+ // is preserved, nobody else should have any data on the stack.
+ // So we need to copy PEI core instance data to memory.
+ //
+ Status = PeiAllocatePool (PeiServices, sizeof (PEI_CORE_INSTANCE), &PrivateInMem);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+ PeiCoreCopyMem (PrivateInMem, Private, sizeof (PEI_CORE_INSTANCE));
+
+ //
+ // Shadow PEI Core. When permanent memory is avaiable, shadow
+ // PEI Core and PEIMs to get high performance.
+ //
+ PeiCoreFileHandle = NULL;
+ //
+ // Find the PEI Core in the BFV
+ //
+ Status = PeiFindFileEx (
+ (EFI_PEI_FV_HANDLE)Private->Fv[0].FvHeader,
+ NULL,
+ EFI_FV_FILETYPE_PEI_CORE,
+ &PeiCoreFileHandle,
+ NULL
+ );
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //
+ // Shadow PEI Core into memory so it will run faster
+ //
+ Status = PeiLoadImage (PeiServices, PeiCoreFileHandle, &EntryPoint, &AuthenticationState);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //
+ // The 2nd time around we need to call PeiCore passing in a non
+ // NULL value to OldCoreData. We can not call the PE COFF entry
+ // point (_EntryPoint) as it had codes a NULL into OldCoreData.
+ // We calculate the memory (shadowed) address of PeiCore by
+ // figuring out the offset from _EntryPoint to PeiCore and then
+ // adding that value to the new memory based entry point.
+ //
+ PeiCoreReentryPoint = (VOID*)(UINTN)(EntryPoint +
+//*** AMI PORTING BEGIN ***//
+// (((UINT8 *)(UINTN)PeiCore) - (UINT8 *)(UINTN)PeiMain));
+ (((UINT8 *)(UINTN)PeiCore) - (UINT8 *)(UINTN)PeiCoreEntry));
+//*** AMI PORTING END ***//
+
+
+ //
+ // Switch to memory based stack and reenter PEI Core that has been
+ // shadowed to memory.
+ //
+ SwitchCoreStacks (
+ PeiCoreReentryPoint,
+ (UINTN)SecCoreData,
+ (UINTN)NULL,
+ (UINTN)PrivateInMem,
+ (VOID*)((UINTN)Private->StackBase + (UINTN)Private->StackSize - 0x10)
+ );
+ }
+
+ if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
+ (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ //
+ // If memory is availble we shadow images by default for performance reasons.
+ // We call the entry point a 2nd time so the module knows it's shadowed.
+ //
+ PEI_PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
+ PeimEntryPoint (PeimFileHandle, PeiServices);
+ PEI_PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
+
+ //
+ // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
+ //
+ Private->Fv[FvCount].PeimState[PeimCount]++;
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (PeiServices);
+ }
+ }
+ }
+ }
+
+ //
+ // We set to NULL here to optimize the 2nd entry to this routine after
+ // memory is found. This reprevents rescanning of the FV. We set to
+ // NULL here so we start at the begining of the next FV
+ //
+ Private->CurrentFileHandle = NULL;
+ Private->CurrentPeimCount = 0;
+ //
+ // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
+ //
+ PeiCoreSetMem (Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles), 0);
+ }
+
+ //
+ // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
+ // through all the FV.
+ //
+ Private->CurrentPeimFvCount = 0;
+
+ //
+ // PeimNeedingDispatch being TRUE means we found a PEIM that did not get
+ // dispatched. So we need to make another pass
+ //
+ // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
+ // pass. If we did not dispatch a PEIM there is no point in trying again
+ // as it will fail the next time too (nothing has changed).
+ //
+ } while (Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass);
+
+//*** AMI PORTING BEGIN ***//
+ // Print out a list of the PEIMs that were not dispatched
+ PEI_DEBUG_CODE
+ (
+ {
+ UINTN i = 0;
+ UINTN j = 0;
+
+ for(i = 0; i < PEI_CORE_MAX_FV_SUPPORTED; i++)
+ {
+ for(j = 0; j < PEI_CORE_MAX_PEIM_PER_FV; j++)
+ {
+ if( Private->Fv[i].FvFileHandles[j] == NULL) continue;
+
+ if(Private->Fv[i].PeimState[j] == PEIM_STATE_NOT_DISPATCHED)
+ PEI_DEBUG((&Private->PS, -1, "WARNING -> PEIM Not Dispatched: %g\n", &((EFI_FFS_FILE_HEADER*)(Private->Fv[i].FvFileHandles[j]))->Name ));
+ }
+ }
+ }
+ )
+//*** AMI PORTING END *****//
+}
+
+
+VOID
+InitializeDispatcherData (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ SecCoreData - Information and services provided by SEC phase.
+
+Returns:
+
+ None.
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PeiInitializeFv (PrivateData, SecCoreData);
+ }
+
+ return;
+}
+
+
+BOOLEAN
+DepexSatisfied (
+ IN PEI_CORE_INSTANCE *Private,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN UINTN PeimCount
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+
+ Private - Pointer to the private data passed in from caller.
+ FileHandle - File handle of PEIM.
+ PeimCount - The PEIM sequence in one FV.
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+{
+ EFI_STATUS Status;
+ INT8 *DepexData;
+
+ if (PeimCount < Private->AprioriCount) {
+ //
+ // If its in the A priori file then we set Depex to TRUE
+ //
+ return TRUE;
+ }
+
+ Status = PeiFfsFindSectionData (&Private->PS, EFI_SECTION_PEI_DEPEX, FileHandle, &DepexData);
+ if (EFI_ERROR (Status)) {
+ //
+ // If there is no DEPEX, assume the module can be executed
+ //
+ return TRUE;
+ }
+
+ //
+ // Evaluate a given DEPEX
+ //
+ return PeimDispatchReadiness (&Private->PS, DepexData);
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiRegisterForShadow (
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ This routine enable a PEIM to register itself to shadow when PEI Foundation
+ discovery permanent memory.
+
+Arguments:
+ FileHandle - File handle of a PEIM.
+
+Returns:
+ EFI_NOT_FOUND - The file handle doesn't point to PEIM itself.
+ EFI_ALREADY_STARTED - Indicate that the PEIM has been registered itself.
+ EFI_SUCCESS - Successfully to register itself.
+
+--*/
+{
+ PEI_CORE_INSTANCE *Private;
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
+
+ if (Private->CurrentFileHandle != FileHandle) {
+ //
+ // The FileHandle must be for the current PEIM
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ if (Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] >= PEIM_STATE_REGISITER_FOR_SHADOW) {
+ //
+ // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
+ //
+ return EFI_ALREADY_STARTED;
+ }
+
+ Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] = PEIM_STATE_REGISITER_FOR_SHADOW;
+
+ return EFI_SUCCESS;
+}
+
+
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/FwVol.c b/Core/CORE_PEI/CORE_PEI_PI/FwVol.c
new file mode 100644
index 0000000..2ecf88e
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/FwVol.c
@@ -0,0 +1,782 @@
+/*++
+
+Copyright (c) 2004 - 2009, 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:
+
+ FwVol.c
+
+Abstract:
+
+ Pei Core Firmware File System service routines.
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImageFormat.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
+
+
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiFirmwareVolumeInfoPpiGuid,
+ FirmwareVolmeInfoPpiNotifyCallback
+};
+
+
+
+
+STATIC
+EFI_FFS_FILE_STATE
+GetFileState(
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Returns the highest bit set of the State field
+
+Arguments:
+
+ ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY
+ in the Attributes field.
+ FfsHeader - Pointer to FFS File Header.
+
+Returns:
+ Returns the highest bit in the State field
+
+--*/
+{
+ EFI_FFS_FILE_STATE FileState;
+ EFI_FFS_FILE_STATE HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
+
+STATIC
+UINT8
+CalculateHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FileHeader
+ )
+/*++
+
+Routine Description:
+
+ Calculates the checksum of the header of a file.
+
+Arguments:
+
+ FileHeader - Pointer to FFS File Header.
+
+Returns:
+ Checksum of the header.
+
+ The header is zero byte checksum.
+ - Zero means the header is good.
+ - Non-zero means the header is bad.
+
+
+Bugbug: For PEI performance reason, we comments this code at this time.
+--*/
+{
+ UINT8 *ptr;
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+ ptr = (UINT8 *)FileHeader;
+
+ for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ Sum = (UINT8)(Sum + ptr[Index+1]);
+ Sum = (UINT8)(Sum + ptr[Index+2]);
+ Sum = (UINT8)(Sum + ptr[Index+3]);
+ }
+
+ for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ }
+
+ //
+ // State field (since this indicates the different state of file).
+ //
+ Sum = (UINT8)(Sum - FileHeader->State);
+ //
+ // Checksum field of the file is not part of the header checksum.
+ //
+ Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
+
+ return Sum;
+}
+
+STATIC
+BOOLEAN
+EFIAPI
+PeiFileHandleToVolume (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+{
+ UINTN Index;
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
+ for (Index = 0; Index < PrivateData->FvCount; Index++) {
+ FwVolHeader = PrivateData->Fv[Index].FvHeader;
+ if (((UINTN)FileHandle > (UINTN)FwVolHeader ) && \
+ ((UINTN)FileHandle < ((UINTN)FwVolHeader + (UINTN)FwVolHeader->FvLength))) {
+ *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+EFI_STATUS
+PeiFindFileEx (
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN CONST EFI_GUID *FileName, OPTIONAL
+ IN EFI_FV_FILETYPE SearchType,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *AprioriFile OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+ Flag - Indicator for if this is for PEI Dispath search
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FFS_FILE_HEADER **FileHeader;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+ UINT32 FileLength;
+ UINT32 FileOccupiedSize;
+ UINT32 FileOffset;
+ UINT64 FvLength;
+ UINT8 ErasePolarity;
+ UINT8 FileState;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer();
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
+ FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
+
+ FvLength = FwVolHeader->FvLength;
+ if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // If FileHeader is not specified (NULL) or FileName is not NULL,
+ // start with the first file in the firmware volume. Otherwise,
+ // start from the FileHeader.
+ //
+ if ((*FileHeader == NULL) || (FileName != NULL)) {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
+ if (FwVolHeader->ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);
+ }
+ } else {
+ //
+ // Length is 24 bits wide so mask upper 8 bits
+ // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
+ }
+
+ FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
+ PEI_ASSERT (PeiServices,(FileOffset <= 0xFFFFFFFF));
+
+ while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, FfsFileHeader);
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_INVALID:
+ FileOffset += sizeof(EFI_FFS_FILE_HEADER);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
+ break;
+
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
+//*** AMI PORTING BEGIN ***//
+// Skip the assert to support a more sophisiticated
+// FV corruption handling outside of the Core.
+// PEI_ASSERT (PeiServices,FALSE);
+//*** AMI PORTING END *****//
+ return EFI_NOT_FOUND;
+ }
+
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+
+ if (FileName != NULL) {
+ if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+ } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {
+ if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
+
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ } else if (AprioriFile != NULL) {
+ if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {
+ if (CompareGuid (&FfsFileHeader->Name, &gEfiPeiAprioriGuid)) {
+ *AprioriFile = FfsFileHeader;
+ }
+ }
+ }
+ } else if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ case EFI_FILE_DELETED:
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ default:
+ return EFI_NOT_FOUND;
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+VOID
+PeiInitializeFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PeiCore Fv List.
+
+Arguments:
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
+
+Returns:
+ NONE
+
+--*/
+{
+ EFI_STATUS Status;
+ //
+ // The BFV must be the first entry. The Core FV support is stateless
+ // The AllFV list has a single entry per FV in PEI.
+ // The Fv list only includes FV that PEIMs will be dispatched from and
+ // its File System Format is PI 1.0 definition.
+ //
+ PrivateData->FvCount = 1;
+ PrivateData->Fv[0].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+
+ PrivateData->AllFvCount = 1;
+ PrivateData->AllFv[0] = (EFI_PEI_FV_HANDLE)PrivateData->Fv[0].FvHeader;
+
+
+ //
+ // Post a call-back for the FvInfoPPI services to expose
+ // additional Fvs to PeiCore.
+ //
+ Status = (PrivateData->PS)->NotifyPpi (&PrivateData->PS, &mNotifyList);
+ ASSERT_PEI_ERROR (&PrivateData->PS, Status);
+
+}
+
+
+
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Process Firmware Volum Information once FvInfoPPI install.
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+
+ Status - EFI_SUCCESS if the interface could be successfully
+ installed
+
+--*/
+{
+ UINT8 FvCount;
+ EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
+ PEI_CORE_INSTANCE *PrivateData;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ if (PrivateData->FvCount >= PEI_CORE_MAX_FV_SUPPORTED) {
+ PEI_ASSERT (GetPeiServicesTablePointer(),FALSE);
+ }
+
+ Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;
+
+ if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {
+ for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {
+ if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {
+ return EFI_SUCCESS;
+ }
+ }
+ PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;
+ }
+
+ //
+ // Allways add to the All list
+ //
+ PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextVolume (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Search the next FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ Instance - The Fv Volume Instance.
+ VolumeHandle - Pointer to the current Fv Volume to search.
+
+Returns:
+ EFI_INVALID_PARAMETER - VolumeHandle is NULL.
+ EFI_NOT_FOUND - No FV Volume is found.
+ EFI_SUCCESS - The next FV Volume is found.
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *Private;
+
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+ if (VolumeHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Instance >= Private->AllFvCount) {
+ VolumeHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ *VolumeHandle = Private->AllFv[Instance];
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input FvHandle, search for the next matching type file in the FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only file of this type.
+ FvHandle - Pointer to the current FV to search.
+ FileHandle - Pointer to the file matching SearchType in FwVolHeader.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ return PeiFindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);
+}
+
+EFI_STATUS
+PeiFfsProcessSection (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_COMMON_SECTION_HEADER *Section,
+ IN UINTN SectionSize,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *Authentication
+ )
+/*++
+
+Routine Description:
+
+ Go through the file to search SectionType section,
+ when meeting an encapsuled section, search recursively.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only section of this type.
+ Section - From where to search.
+ SectionSize - The file size to search.
+ OutputBuffer - Pointer to the section to search.
+ OutputSize - The size of the section to search.
+ Authentication - Authenticate the section.
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 SectionLength;
+ UINT32 ParsedLength;
+ EFI_GUID_DEFINED_SECTION *GuidSection;
+ EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;
+ EFI_COMPRESSION_SECTION *CompressionSection;
+ EFI_PEI_DECOMPRESS_PPI *DecompressPpi;
+ VOID *PpiOutput;
+ UINTN PpiOutputSize;
+
+ *OutputBuffer = NULL;
+ ParsedLength = 0;
+ while (ParsedLength < SectionSize) {
+ if (Section->Type == SectionType) {
+ *OutputBuffer = (VOID *)(Section + 1);
+ return EFI_SUCCESS;
+ } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;
+ GuidSectionPpi = PeiReturnPpi (PeiServices, &GuidSection->SectionDefinitionGuid);
+ if (GuidSectionPpi != NULL) {
+ Status = GuidSectionPpi->ExtractSection (
+ GuidSectionPpi,
+ Section,
+ &PpiOutput,
+ &PpiOutputSize,
+ Authentication
+ );
+ if (!EFI_ERROR (Status)) {
+ return PeiFfsProcessSection (
+ PeiServices,
+ SectionType,
+ PpiOutput,
+ PpiOutputSize,
+ OutputBuffer,
+ OutputSize,
+ Authentication
+ );
+ }
+ }
+ } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+ CompressionSection = (EFI_COMPRESSION_SECTION *)Section;
+ DecompressPpi = PeiReturnPpi (PeiServices, &gEfiPeiDecompressPpiGuid);
+ if (DecompressPpi != NULL) {
+ Status = DecompressPpi->Decompress (
+ DecompressPpi,
+ CompressionSection,
+ &PpiOutput,
+ &PpiOutputSize
+ );
+ if (!EFI_ERROR (Status)) {
+ return PeiFfsProcessSection (
+ PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication
+ );
+ }
+ }
+ }
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+ SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ PEI_ASSERT (PeiServices, (SectionLength != 0));
+ ParsedLength += SectionLength;
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FileHandle - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+ UINTN OutputSize;
+ UINT32 AuthenticationStatus;
+
+
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // Does not include FfsFileHeader header size
+ // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
+ FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileSize -= sizeof (EFI_FFS_FILE_HEADER);
+
+ return PeiFfsProcessSection (
+ PeiServices,
+ SectionType,
+ Section,
+ FileSize,
+ SectionData,
+ &OutputSize,
+ &AuthenticationStatus
+ );
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindFileByName (
+ IN CONST EFI_GUID *FileName,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input VolumeHandle, search for the next matching name file.
+
+Arguments:
+
+ FileName - File name to search.
+ VolumeHandle - The current FV to search.
+ FileHandle - Pointer to the file matching name in VolumeHandle.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = PeiFindFileEx (VolumeHandle, FileName, 0, FileHandle, NULL);
+ if (Status == EFI_NOT_FOUND) {
+ *FileHandle = NULL;
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetFileInfo (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given file.
+
+Arguments:
+ FileHandle - The handle to file.
+ FileInfo - Pointer to the file information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ UINT8 FileState;
+ UINT8 ErasePolarity;
+ EFI_FFS_FILE_HEADER *FileHeader;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+
+ if ((FileHandle == NULL) || (FileInfo == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Retrieve the FirmwareVolume which the file resides in.
+ //
+ if (!PeiFileHandleToVolume(FileHandle, &VolumeHandle)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);
+
+ switch (FileState) {
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
+ CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));
+ FileInfo->FileType = FileHeader->Type;
+ FileInfo->FileAttributes = FileHeader->Attributes;
+ FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
+ FileInfo->Buffer = (FileHeader + 1);
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetVolumeInfo (
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given Fv Volume.
+
+Arguments:
+ VolumeHandle - The handle to Fv Volume.
+ VolumeInfo - The pointer to volume information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+
+ if (VolumeInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)VolumeHandle;
+ VolumeInfo->FvAttributes = FwVolHeader->Attributes;
+ VolumeInfo->FvStart = FwVolHeader;
+ VolumeInfo->FvSize = FwVolHeader->FvLength;
+ CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));
+
+ if (FwVolHeader->ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
+ CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
+ }
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Hob.c b/Core/CORE_PEI/CORE_PEI_PI/Hob.c
new file mode 100644
index 0000000..30b7b3f
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Hob.c
@@ -0,0 +1,191 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ Hob.c
+
+Abstract:
+
+ EFI PEI Core HOB services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+{
+ //
+ // Only check this parameter in debug mode
+ //
+
+ PEI_DEBUG_CODE (
+ if (HobList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ )
+
+ *HobList = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices)->HobList.Raw;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+ EFI_PHYSICAL_ADDRESS FreeMemory;
+
+
+ Status = PeiGetHobList (PeiServices, Hob);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ HandOffHob = *Hob;
+
+ Length = (UINT16)((Length + 0x7) & (~0x7));
+
+ FreeMemory = HandOffHob->EfiFreeMemoryTop -
+ HandOffHob->EfiFreeMemoryBottom;
+
+ if (FreeMemory < Length) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0;
+
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+ HobEnd++;
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+
+ Hob = (VOID *)(UINTN)MemoryBegin;
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1);
+ Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
+ Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+ Hob->Header.Reserved = 0;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+
+ Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
+ Hob->BootMode = BootMode;
+
+ Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiMemoryBottom = MemoryBegin;
+ Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);
+ Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Image.c b/Core/CORE_PEI/CORE_PEI_PI/Image.c
new file mode 100644
index 0000000..a6967e0
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Image.c
@@ -0,0 +1,932 @@
+/*++
+
+Copyright (c) 2004 - 2009, 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:
+
+ Image.c
+
+Abstract:
+
+ Pei Core Load Image Support
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include "PeiApi.h"
+#include "EfiImage.h"
+#include EFI_PROTOCOL_DEFINITION (CustomizedDecompress)
+
+#include EFI_PPI_DEFINITION (LoadFile2)
+#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
+#include EFI_PPI_DEFINITION (SectionExtraction)
+
+
+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
+
+--*/
+;
+
+EFI_STATUS
+PeiLoadImageLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for loading file image.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiLoadImageLoadImageWrapper (
+ IN CONST EFI_PEI_LOAD_FILE_PPI *This,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ The wrapper function of PeiLoadImageLoadImage().
+
+Arguments:
+
+ This - Pointer to EFI_PEI_LOAD_FILE_PPI.
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ EFI_STATUS.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderGetEntryPoint (
+ IN VOID *Pe32Data,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image entry point.
+
+Arguments:
+
+ Pe32Data - Pointer to PE image.
+ EntryPoint - Pointer to entry point of PE image.
+
+Returns:
+
+ EFI_SUCCESS.
+
+--*/
+;
+
+EFI_IMAGE_NT_HEADERS*
+EFIAPI
+GetPeHeader (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Pe32Data
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image header.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Pe32Data - Pointer to PE image.
+
+Returns:
+
+ Pointer to PE header.
+
+--*/
+;
+
+static EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {
+ PeiLoadImageLoadImageWrapper
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiLoadFile2PpiGuid,
+ &mPeiLoadImagePpi
+};
+
+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 EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Support routine to return the Image Read
+
+Arguments:
+
+ PeiServices - PEI Services Table
+
+ ImageContext - The context of the image being loaded
+
+Returns:
+
+ EFI_SUCCESS - If Image function location is found
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemoryBuffer;
+
+ Status = (*PeiServices)->AllocatePages (
+ PeiServices,
+ EfiBootServicesData,
+ 0x400 / EFI_PAGE_SIZE + 1,
+ &MemoryBuffer
+ );
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ (*PeiServices)->CopyMem (
+ (VOID *) (UINTN) MemoryBuffer,
+ (VOID *) (UINTN) PeiImageRead,
+ 0x400
+ );
+
+ ImageContext->ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;
+
+ return Status;
+}
+
+EFI_STATUS
+PeiLoadImageLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for loading file image.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_CORE_INSTANCE *Private;
+ VOID *Pe32Data;
+ EFI_TE_IMAGE_HEADER *TEImageHeader;
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeCoffLoader;
+
+#ifdef EFI_NT_EMULATOR
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ NT_PEI_LOAD_FILE_PPI *PeiNtService;
+#else
+ VOID *EntryPointPtr;
+#endif
+//*** AMI PORTING BEGIN ***//
+//This is needed to enable execution of compressed PEIMS
+//and PEIMS from the firmware volumes in memory (see below).
+ BOOLEAN FixupRequired = FALSE;
+//*** AMI PORTING END *****//
+
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ *EntryPoint = 0;
+ *AuthenticationState = 0;
+ ImageAddress = 0;
+ ImageSize = 0;
+ PeHdr = NULL;
+
+ //
+ // Try to find a TE or PE32 section.
+ //
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_TE,
+ FileHandle,
+ (VOID **)&TEImageHeader
+ );
+ Pe32Data = TEImageHeader;
+ if (EFI_ERROR (Status)) {
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_PE32,
+ FileHandle,
+ &Pe32Data
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // NO image types we support so exit.
+ //
+ return Status;
+ }
+
+ //
+ // Check image header machine type. If not supported, skip it.
+ //
+ if (TEImageHeader != NULL) {
+ if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (TEImageHeader->Machine) &&
+ !EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (TEImageHeader->Machine)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ //
+ // Get PE32 Header to check machine type.
+ //
+ PeHdr = GetPeHeader(PeiServices, Pe32Data);
+ if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeHdr->FileHeader.Machine) &&
+ !EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (PeHdr->FileHeader.Machine)) {
+ return EFI_UNSUPPORTED;
+ }
+//*** AMI PORTING BEGIN ***//
+//This is needed to enable execution of compressed PEIMS
+//and PEIMS from the firmware volumes in memory.
+ if (PeHdr->OptionalHeader.ImageBase != (UINTN)Pe32Data)
+ FixupRequired = TRUE;
+//*** AMI PORTING END *****//
+ }
+
+ if (Private->PeiMemoryInstalled &&
+ (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || FixupRequired)) {
+ //
+ // Load, relocate, and run image in memory
+ //
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+ ImageContext.Handle = Pe32Data;
+ if (Private->ImageReadFile == NULL) {
+ GetImageReadFunction (PeiServices, &ImageContext);
+ Private->ImageReadFile = ImageContext.ImageRead;
+ } else {
+ ImageContext.ImageRead = Private->ImageReadFile;
+ }
+ PeCoffLoader = Private->PeCoffLoader;
+ Status = PeCoffLoader->GetImageInfo (PeCoffLoader, &ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Allocate Memory for the image
+ //
+ Status = PeiAllocatePages (
+ PeiServices,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize),
+ &ImageContext.ImageAddress
+ );
+ ASSERT_PEI_ERROR (PeiServices,Status);
+
+ if (ImageContext.IsTeImage &&
+ TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {
+ ImageContext.ImageAddress = ImageContext.ImageAddress +
+ TEImageHeader->StrippedSize -
+ sizeof (EFI_TE_IMAGE_HEADER);
+ }
+
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoader->LoadImage (PeCoffLoader, &ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoader->RelocateImage (PeCoffLoader, &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;
+ }
+#ifndef EFI_NT_EMULATOR
+ else if (TEImageHeader != NULL) {
+ //
+ // Get entry point from the TE image header
+ //
+ ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)TEImageHeader;
+//*** AMI PORTING BEGIN ***//
+//Bug fix: the function must return a valid image size
+// The original implmentation always returns NULL for XIP images.
+ ImageSize = FVSECTION_SIZE(TEImageHeader);
+// ImageSize = 0;
+//*** AMI PORTING END ***//
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ //
+ // Retrieve the entry point from the PE/COFF image header
+ //
+ ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
+//*** AMI PORTING BEGIN ***//
+//Bug fix: the function must return a valid image size
+// The original implmentation always returns NULL for XIP images.
+ ImageSize = PeHdr->OptionalHeader.SizeOfImage;
+// ImageSize = 0;
+//*** AMI PORTING END ***//
+ Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointPtr);
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPointPtr;
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+#else
+ else {
+ if (TEImageHeader == NULL) {
+ PeHdr = GetPeHeader(PeiServices,Pe32Data);
+ }
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gNtPeiLoadFileGuid,
+ 0,
+ &PpiDescriptor,
+ &PeiNtService
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PeiNtService->PeiLoadFileService (
+ Pe32Data,
+ &ImageAddress,
+ &ImageSize,
+ EntryPoint
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (TEImageHeader != NULL) {
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ }
+ }
+ }
+#endif
+
+
+ if (ImageAddressArg != NULL) {
+ *ImageAddressArg = ImageAddress;
+ }
+
+ if (ImageSizeArg != NULL) {
+ *ImageSizeArg = ImageSize;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Message is printed later. Disable this one
+/*
+ //
+ // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
+ //
+ PEI_DEBUG ((PeiServices,EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", Pe32Data, *EntryPoint));
+ PEI_DEBUG_CODE (
+ {
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ UINTN DirCount;
+ UINTN Index;
+ UINTN Index1;
+ BOOLEAN FileNameFound;
+ CHAR8 *AsciiString;
+ CHAR8 AsciiBuffer[512];
+ VOID *CodeViewEntryPointer;
+ INTN TEImageAdjust;
+ EFI_IMAGE_DOS_HEADER *DosHeader;
+ EFI_IMAGE_NT_HEADERS *PeHeader;
+
+ DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+ if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base
+ //
+ PeHeader = (EFI_IMAGE_NT_HEADERS *) Pe32Data;
+ }
+
+ //
+ // Find the codeview info in the image and display the file name
+ // being loaded.
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ DebugEntry = NULL;
+ DirectoryEntry = NULL;
+ TEImageAdjust = 0;
+ if (TEImageHeader == NULL) {
+ if (PeHeader->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHeader->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) ImageAddress + DirectoryEntry->VirtualAddress);
+ }
+ } else {
+ if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
+ DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +
+ TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
+ TEImageAdjust);
+ }
+ }
+
+ if (DebugEntry != NULL && DirectoryEntry != NULL) {
+ for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ if (DebugEntry->SizeOfData > 0) {
+ CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
+ switch (* (UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_RSDS:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+
+ default:
+ AsciiString = NULL;
+ break;
+ }
+ if (AsciiString != NULL) {
+ FileNameFound = FALSE;
+ for (Index = 0, Index1 = 0; AsciiString[Index] != 0; Index++) {
+ if (AsciiString[Index] == '\\') {
+ Index1 = Index;
+ FileNameFound = TRUE;
+ }
+ }
+
+ if (FileNameFound) {
+ for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {
+ AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];
+ }
+ AsciiBuffer[Index - (Index1 + 1)] = 0;
+ PEI_DEBUG ((PeiServices,EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+
+ PEI_DEBUG ((PeiServices,EFI_D_INFO | EFI_D_LOAD, "\n"));
+*/
+//*** AMI PORTING END ***//
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiLoadImageLoadImageWrapper (
+ IN CONST EFI_PEI_LOAD_FILE_PPI *This,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ The wrapper function of PeiLoadImageLoadImage().
+
+Arguments:
+
+ This - Pointer to EFI_PEI_LOAD_FILE_PPI.
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ EFI_STATUS.
+
+--*/
+{
+ return PeiLoadImageLoadImage (
+ GetPeiServicesTablePointer (),
+ FileHandle,
+ ImageAddressArg,
+ ImageSizeArg,
+ EntryPoint,
+ AuthenticationState
+ );
+}
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for load image file.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+{
+ EFI_STATUS PpiStatus;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_PEI_LOAD_FILE_PPI *LoadFile;
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ UINT16 Magic;
+ UINT16 Machine;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_TE_IMAGE_HEADER *TeHdr;
+
+ //
+ // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.
+ // one at a time, until one reports EFI_SUCCESS.
+ //
+ Index = 0;
+ do {
+ PpiStatus = PeiLocatePpi (
+ PeiServices,
+ &gEfiLoadFile2PpiGuid,
+ Index,
+ NULL,
+ (VOID **)&LoadFile
+ );
+ if (!EFI_ERROR (PpiStatus)) {
+ Status = LoadFile->LoadFile (
+ LoadFile,
+ FileHandle,
+ &ImageAddress,
+ &ImageSize,
+ EntryPoint,
+ AuthenticationState
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Only support image machine type that is the same as PEI core.
+ // Get the image's machine type to check if supported.
+ //
+ Magic = *(UINT16 *)(UINTN) ImageAddress;
+ if (Magic == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ TeHdr = (EFI_TE_IMAGE_HEADER *)(UINTN) ImageAddress;
+ Machine = TeHdr->Machine;
+ } else {
+ if (Magic == EFI_IMAGE_DOS_SIGNATURE) {
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN) ImageAddress + (UINTN) ((((EFI_IMAGE_DOS_HEADER *)(UINTN) ImageAddress)->e_lfanew) & 0x0ffff));
+ } else {
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)(UINTN) ImageAddress;
+ }
+ Machine = PeHdr->FileHeader.Machine;
+ }
+ if (Machine == EFI_IMAGE_MACHINE_TYPE) {
+//*** AMI PORTING BEGIN ***//
+//break from the loop to print debug message (see below)
+// return EFI_SUCCESS;
+ PpiStatus=EFI_SUCCESS;
+ break;
+//*** AMI PORTING END *****//
+ } else {
+//*** AMI PORTING BEGIN ***//
+//break from the loop to print debug message (see below)
+// return EFI_UNSUPPORTED;
+ PpiStatus=EFI_SUCCESS;
+ break;
+//*** AMI PORTING END *****//
+ }
+ }
+ }
+ Index++;
+ } while (!EFI_ERROR (PpiStatus));
+//*** AMI PORTING BEGIN ***//
+//Print debug message
+#ifdef EFI_DEBUG
+{
+ EFI_FFS_FILE_HEADER *PeimFileHeader = (EFI_FFS_FILE_HEADER*)FileHandle;
+ if(!EFI_ERROR(PpiStatus))
+ {
+ char sName[0x100];
+ if (!GetName((VOID*)(UINTN)ImageAddress,sName))
+ Sprintf_s(sName,sizeof(sName),"[%G]",&PeimFileHeader->Name);
+ PeiTrace(TRACE_PEICORE, PeiServices, "%s.Entry(%X)\n", sName, *EntryPoint);
+ }
+ else
+ {
+ PeiTrace(
+ TRACE_PEICORE, PeiServices,
+ "ERROR: attempt to load FFS file [%G] has failed\n",
+ &PeimFileHeader->Name
+ );
+ }
+}
+#endif
+//New image is loaded and is about to be launched
+//Update LoadedImage PPI information
+ if(!EFI_ERROR(PpiStatus))
+ UpdatedLoadedImagePpi(PeiServices,ImageAddress,ImageSize,FileHandle);
+//*** AMI PORTING END *****//
+ return PpiStatus;
+}
+
+
+VOID
+InitializeImageServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Regitser PeCoffLoader to PeiCore PrivateData. And install
+ Pei Load File PPI.
+
+Arguments:
+
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ OldCoreData - Pointer to PEI_CORE_INSTANCE.
+
+Returns:
+
+ NONE.
+
+--*/
+{
+ EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
+
+ InstallEfiPeiPeCoffLoader (&PrivateData->PS, &PeiEfiPeiPeCoffLoader, NULL);
+ PrivateData->PeCoffLoader = PeiEfiPeiPeCoffLoader;
+
+ if (OldCoreData == NULL) {
+ //
+ // The first time we are XIP (running from FLASH). We need to remember the
+ // FLASH address so we can reinstall the memory version that runs faster
+ //
+ PrivateData->XipLoadFile = &gPpiLoadFilePpiList;
+ PeiInstallPpi (&PrivateData->PS, PrivateData->XipLoadFile);
+ } else {
+ //
+ // 2nd time we are running from memory so replace the XIP version with the
+ // new memory version.
+ //
+ PeiReInstallPpi (&PrivateData->PS, PrivateData->XipLoadFile, &gPpiLoadFilePpiList);
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderGetEntryPoint (
+ IN VOID *Pe32Data,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image entry point.
+
+Arguments:
+
+ Pe32Data - Pointer to PE image.
+ EntryPoint - Pointer to entry point of PE image.
+
+Returns:
+
+ EFI_SUCCESS.
+
+--*/
+{
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeHdr = NULL;
+ PeiServices = GetPeiServicesTablePointer();
+
+ PEI_ASSERT (PeiServices, (Pe32Data != NULL));
+ PEI_ASSERT (PeiServices,(EntryPoint != NULL));
+
+ PeHdr = GetPeHeader(PeiServices, Pe32Data);
+
+ //
+ // Calculate the entry point relative to the start of the image.
+ // AddressOfEntryPoint is common for PE32 & PE32+
+ //
+ *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ return EFI_SUCCESS;
+}
+
+EFI_IMAGE_NT_HEADERS*
+EFIAPI
+GetPeHeader (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Pe32Data
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image header.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Pe32Data - Pointer to PE image.
+
+Returns:
+
+ Pointer to PE header.
+
+--*/
+{
+ EFI_IMAGE_DOS_HEADER *DosHeader;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+
+ PeHdr = NULL;
+ PEI_ASSERT (PeiServices, (Pe32Data != NULL));
+
+ DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+ if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header.
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) Pe32Data)->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base.
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) Pe32Data;
+ }
+ return PeHdr;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c b/Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c
new file mode 100644
index 0000000..05a0ff3
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c
@@ -0,0 +1,392 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ MemoryServices.c
+
+Abstract:
+
+ EFI PEI Core memory services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiApi.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+//*** AMI PORTING BEGIN ***//
+//use SDL token 'DXE_STACK_SIZE' to define stack size
+#include <Token.h>
+#undef PEI_STACK_SIZE
+#define PEI_STACK_SIZE DXE_STACK_SIZE
+//*** AMI PORTING END *****//
+
+VOID
+InitializeMemoryServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+{
+ PrivateData->SwitchStackSignal = FALSE;
+
+ if (OldCoreData == NULL) {
+ //
+ // 1st time through we are using Temp memory
+ //
+ PrivateData->PeiMemoryInstalled = FALSE;
+ PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase;
+ PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);
+
+ PEI_DEBUG_CODE (
+ {
+ PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;
+ PrivateData->MaxTopOfCarHeap = (VOID*)((UINTN)PrivateData->BottomOfCarHeap + PrivateData->SizeOfCacheAsRam);
+ }
+ )
+
+ PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;
+
+ PeiCoreBuildHobHandoffInfoTable (
+ BOOT_WITH_FULL_CONFIGURATION,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,
+ (UINTN) SecCoreData->PeiTemporaryRamSize
+ );
+ }
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;
+ EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;
+ UINT64 PeiStackSize;
+ UINT64 EfiFreeMemorySize;
+ EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+//*** AMI PORTING BEGIN ***//
+ if (PrivateData->PeiMemoryInstalled) {
+ //This function should be called once. Report error if this is the second call
+ PEI_ERROR_CODE(PeiServices, PEI_MEMORY_INSTALLED_TWICE, EFI_ERROR_MINOR);
+ }else {
+ //Debug message
+ PEI_TRACE((TRACE_PEICORE, PeiServices, "Memory Installed: Address=%lX; Length=%lX\n",MemoryBegin,MemoryLength));
+ }
+//*** AMI PORTING END *****//
+
+ PrivateData->SwitchStackSignal = TRUE;
+ PrivateData->PeiMemoryInstalled = TRUE;
+
+ PrivateData->StackBase = MemoryBegin;
+
+ PeiStackSize = RShiftU64 (MemoryLength, 1);
+ if (PEI_STACK_SIZE > PeiStackSize) {
+ PrivateData->StackSize = PeiStackSize;
+ } else {
+ PrivateData->StackSize = PEI_STACK_SIZE;
+ }
+
+ OldHandOffHob = PrivateData->HobList.HandoffInformationTable;
+
+ PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));
+ NewHandOffHob = PrivateData->HobList.HandoffInformationTable;
+ PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;
+
+ EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;
+
+ PeiCoreCopyMem (
+ NewHandOffHob,
+ OldHandOffHob,
+ (UINTN)EfiFreeMemorySize
+ );
+
+ NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;
+ NewHandOffHob->EfiMemoryBottom = MemoryBegin;
+
+ NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;
+
+ NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +
+ (OldHandOffHob->EfiEndOfHobList -
+ PhysicalAddressOfOldHob);
+
+ ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);
+
+ PeiBuildHobStack ((EFI_PEI_SERVICES**)PeiServices, PrivateData->StackBase, PrivateData->StackSize);
+
+//*** AMI PORTING BEGIN ***//
+//Update LoadedImage pointers
+PrivateData->LoadedImage = (EFI_PEI_PPI_DESCRIPTOR*)
+ ( (UINTN)PrivateData->LoadedImage + ((UINTN)NewHandOffHob - (UINTN)OldHandOffHob) );
+//*** AMI PORTING END *****//
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));
+ }
+ )
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS Offset;
+ EFI_STATUS Status;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // Check if Hob already available
+ //
+ if (!PrivateData->PeiMemoryInstalled) {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+
+ Hob.Raw = PrivateData->HobList.Raw;
+
+ //
+ // Check to see if on 4k boundary
+ //
+ Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;
+
+ //
+ // If not aligned, make the allocation aligned.
+ //
+ if (Offset != 0) {
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;
+ }
+
+ //
+ // Verify that there is sufficient memory to satisfy the allocation
+ //
+ if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
+ Hob.HandoffInformationTable->EfiFreeMemoryBottom) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiAllocatePages fail: Pages - 0x%08x\n", Pages));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Update the PHIT to reflect the memory usage
+ //
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
+
+ //
+ // Update the value for the caller
+ //
+ *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;
+
+ //
+ // Create a memory allocation HOB.
+ //
+ Status = PeiBuildHobMemoryAllocation (
+ (EFI_PEI_SERVICES**)PeiServices,
+ Hob.HandoffInformationTable->EfiFreeMemoryTop,
+ Pages * EFI_PAGE_SIZE + Offset,
+ NULL,
+ MemoryType
+ );
+
+ return Status;
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_POOL *Hob;
+
+
+ Status = PeiCreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_PEI_MEMORY_POOL,
+ (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
+ &Hob
+ );
+ *Buffer = Hob+1;
+
+
+ return Status;
+}
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibCopyMem (Destination, Source, Length);
+}
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibSetMem (Buffer, Size, Value);
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/PeiCore.h b/Core/CORE_PEI/CORE_PEI_PI/PeiCore.h
new file mode 100644
index 0000000..2913deb
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/PeiCore.h
@@ -0,0 +1,1416 @@
+/*++
+
+Copyright (c) 2004 - 2009, 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:
+
+ PeiCore.h
+
+Abstract:
+
+ Definition of Pei Core Structures and Services
+
+Revision History
+
+--*/
+
+#ifndef _PEICORE_H_
+#define _PEICORE_H_
+
+#include "EfiImage.h"
+#include "Pei.h"
+#include "PeiLib.h"
+#include "PeiApi.h"
+#include "PeiHob.h"
+#include "PeiDebug.h"
+#include "EfiFirmwareFileSystem.h"
+#include "EfiFirmwareVolumeHeader.h"
+#ifdef EFI64
+#include "SalApi.h"
+#endif
+
+#include "EfiCommonLib.h"
+#include EFI_GUID_DEFINITION (FirmwareFileSystem2)
+#include EFI_GUID_DEFINITION (PeiApriori)
+#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
+#include EFI_PPI_DEFINITION (Reset)
+#include EFI_PPI_DEFINITION (DxeIpl)
+#include EFI_PPI_DEFINITION (StatusCode)
+#include EFI_PPI_DEFINITION (Security2)
+#include EFI_PPI_DEFINITION (Decompress)
+#include EFI_PPI_DEFINITION (FirmwareVolumeInfo)
+#include EFI_PPI_DEFINITION (LoadFile2)
+#include EFI_PPI_DEFINITION (FirmwareVolume)
+#include EFI_PPI_DEFINITION (GuidedSectionExtraction)
+
+
+#ifdef EFI_NT_EMULATOR
+#include EFI_PPI_DEFINITION (NtPeiLoadFile)
+#endif
+
+//*** AMI PORTING BEGIN ***//
+#include <PPI/LoadedImagePpi.h>
+//*** AMI PORTING END *****//
+
+//
+//Build private HOB to PEI core to transfer old NEM-range data to new NEM-range
+//
+#define EFI_PEI_CORE_PRIVATE_GUID \
+ {0xd641a0f5, 0xcb7c, 0x4846, 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9}
+
+#define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE 0xff
+
+//
+// Pei Core private data structures
+//
+typedef union {
+ EFI_PEI_PPI_DESCRIPTOR *Ppi;
+ EFI_PEI_NOTIFY_DESCRIPTOR *Notify;
+ VOID *Raw;
+} PEI_PPI_LIST_POINTERS;
+
+
+#define PEI_STACK_SIZE 0x20000
+#define MAX_PPI_DESCRIPTORS 128
+
+typedef struct {
+ INTN PpiListEnd;
+ INTN NotifyListEnd;
+ INTN DispatchListEnd;
+ INTN LastDispatchedInstall;
+ INTN LastDispatchedNotify;
+ PEI_PPI_LIST_POINTERS PpiListPtrs[MAX_PPI_DESCRIPTORS];
+} PEI_PPI_DATABASE;
+
+
+#define PEI_CORE_MAX_FV_SUPPORTED 8
+#define PEI_CORE_MAX_PEIM_PER_FV 64
+
+//
+// PEI_CORE_FV_HANDE.PeimState
+// Do not change these values as there is code doing math to change states.
+// Look for Private->Fv[FvCount].PeimState[PeimCount]++;
+//
+#define PEIM_STATE_NOT_DISPATCHED 0x00
+#define PEIM_STATE_DISPATCHED 0x01
+#define PEIM_STATE_REGISITER_FOR_SHADOW 0x02
+#define PEIM_STATE_DONE 0x03
+
+typedef struct {
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ UINT8 PeimState[PEI_CORE_MAX_PEIM_PER_FV];
+ EFI_PEI_FILE_HANDLE FvFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
+ BOOLEAN ScanFv;
+} PEI_CORE_FV_HANDLE;
+
+//
+// Pei Core private data structure instance
+//
+#define PEI_CORE_HANDLE_SIGNATURE EFI_SIGNATURE_32('P','e','i','C')
+
+typedef struct{
+ UINTN Signature;
+ EFI_PEI_SERVICES *PS;
+ PEI_PPI_DATABASE PpiData;
+ UINTN FvCount;
+ PEI_CORE_FV_HANDLE Fv[PEI_CORE_MAX_FV_SUPPORTED];
+ EFI_PEI_FILE_HANDLE CurrentFvFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
+ UINTN AprioriCount;
+ UINTN CurrentPeimFvCount;
+ UINTN CurrentPeimCount;
+ EFI_PEI_FILE_HANDLE CurrentFileHandle;
+ BOOLEAN PeimNeedingDispatch;
+ BOOLEAN PeimDispatchOnThisPass;
+ BOOLEAN PeimDispatcherReenter;
+ UINTN AllFvCount;
+ EFI_PEI_FV_HANDLE AllFv[PEI_CORE_MAX_FV_SUPPORTED];
+ EFI_PEI_HOB_POINTERS HobList;
+ BOOLEAN SwitchStackSignal;
+ BOOLEAN PeiMemoryInstalled;
+ EFI_PHYSICAL_ADDRESS StackBase;
+ UINT64 StackSize;
+ VOID *BottomOfCarHeap;
+ VOID *TopOfCarHeap;
+ VOID *CpuIo;
+ EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi;
+ EFI_PEI_SERVICES ServiceTableShadow;
+ UINTN SizeOfCacheAsRam;
+ VOID *MaxTopOfCarHeap;
+ EFI_PEI_PPI_DESCRIPTOR *XipLoadFile;
+ EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeCoffLoader;
+ EFI_PEI_PE_COFF_LOADER_READ_FILE ImageReadFile;
+//*** AMI PORTING BEGIN ***//
+ EFI_PEI_PPI_DESCRIPTOR *LoadedImage;
+ EFI_PEI_LOADED_IMAGE_PPI LoadedImagePpi;
+//*** AMI PORTING END *****//
+} PEI_CORE_INSTANCE;
+
+
+//
+// Pei Core Instance Data Macros
+//
+
+#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \
+ (PEI_CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE))
+
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CORE_ENTRY_POINT) (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ );
+
+
+VOID
+SwitchCoreStacks (
+ IN VOID *EntryPoint,
+ IN UINTN Parameter1,
+ IN UINTN Parameter2,
+ IN UINTN Parameter3,
+ IN VOID *NewStack
+ )
+/*++
+
+Routine Description:
+
+ Routine for PEI switching stacks.
+
+Arguments:
+
+ EntryPoint - Entry point with new stack.
+ Parameter1 - First parameter for entry point.
+ Parameter2 - Second parameter for entry point.
+ NewStack - Pointer to new stack.
+
+Returns:
+
+ None
+
+--*/
+;
+extern EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList;
+
+
+typedef
+VOID
+(EFIAPI *SWITCH_STACK_ENTRY_POINT) (
+ IN VOID *Context1, OPTIONAL
+ IN VOID *Context2 OPTIONAL
+ );
+
+
+
+//
+// Main PEI entry
+//
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ PpList - Pointer to Ppi list provided by SEC phase.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ PpList - Pointer to Ppi list provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+//
+// Dispatcher support functions
+//
+
+BOOLEAN
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+;
+
+
+VOID
+PeiDispatcher (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *Private
+ )
+
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ Private - Pointer to the private data passed in from caller
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+;
+
+
+VOID
+InitializeDispatcherData (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ SecCoreData - Information and services provided by SEC phase.
+
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+BOOLEAN
+DepexSatisfied (
+ IN PEI_CORE_INSTANCE *Private,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN UINTN PeimCount
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+
+ Private - Pointer to the private data passed in from caller.
+ FileHandle - File handle of PEIM.
+ PeimCount - The PEIM sequence in one FV.
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+;
+
+#ifdef EFI64
+ //
+ // In Ipf we should make special changes for the PHIT pointers to support
+ // recovery boot in cache mode.
+ //
+#define SWITCH_TO_CACHE_MODE(CoreData) SwitchToCacheMode(CoreData)
+#define CACHE_MODE_ADDRESS_MASK 0x7FFFFFFFFFFFFFFFULL
+VOID
+SwitchToCacheMode (
+ IN PEI_CORE_INSTANCE *CoreData
+)
+/*++
+
+Routine Description:
+
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
+
+Arguments:
+
+ CoreData - The PEI core Private Data
+
+Returns:
+
+--*/
+;
+
+#else
+
+#define SWITCH_TO_CACHE_MODE(CoreData)
+
+#endif
+
+//
+// PPI support functions
+//
+VOID
+InitializePpiServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+;
+
+VOID
+ConvertPpiPointers (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Migrate the Hob list from the CAR stack to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR * PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR * OldPpi,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR * NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID * Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor OPTIONAL,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+;
+
+
+VOID *
+PeiReturnPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID *Guid
+ );
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_NOTIFY_DESCRIPTOR * NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+;
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+;
+
+VOID
+DispatchNotify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+;
+
+//
+// Boot mode support functions
+//
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+;
+
+//
+// Security support functions
+//
+VOID
+InitializeSecurityServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_PEI_FV_HANDLE VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the OEM FV verification service.
+
+Arguments:
+
+ VolumeHandle - Pointer to the FV under investigation.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+
+EFI_STATUS
+VerifyPeim (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+;
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
+
+
+//
+// FFS Fw Volume support functions
+//
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextVolume (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Search the next FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ Instance - The Fv Volume Instance.
+ VolumeHandle - Pointer to the current Fv Volume to search.
+
+Returns:
+ EFI_INVALID_PARAMETER - VolumeHandle is NULL.
+ EFI_NOT_FOUND - No FV Volume is found.
+ EFI_SUCCESS - The next FV Volume is found.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input FvHandle, search for the next matching type file in the FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only file of this type.
+ FvHandle - Pointer to the current FV to search.
+ FileHandle - Pointer to the file matching SearchType in FwVolHeader.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FileHandle - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+//
+// Memory support functions
+//
+VOID
+InitializeMemoryServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS * Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of allocation.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for load image file.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID * CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA * Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ CodeType - Type of Status Code.
+
+ Value - Value to output for Status Code.
+
+ Instance - Instance Number of this status code.
+
+ CallerId - ID of the caller of this status code.
+
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+;
+
+
+VOID
+PeiInitializeFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PeiCore Fv List.
+
+Arguments:
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
+
+Returns:
+ NONE
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Process Firmware Volum Information once FvInfoPPI install.
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+
+ Status - EFI_SUCCESS if the interface could be successfully
+ installed
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindFileByName (
+ IN CONST EFI_GUID *FileName,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input VolumeHandle, search for the next matching name file.
+
+Arguments:
+
+ FileName - File name to search.
+ VolumeHandle - The current FV to search.
+ FileHandle - Pointer to the file matching name in VolumeHandle.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetFileInfo (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given file.
+
+Arguments:
+ FileHandle - The handle to file.
+ FileInfo - Pointer to the file information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetVolumeInfo (
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given Fv Volume.
+
+Arguments:
+ VolumeHandle - The handle to Fv Volume.
+ VolumeInfo - The pointer to volume information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiRegisterForShadow (
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ This routine enable a PEIM to register itself to shadow when PEI Foundation
+ discovery permanent memory.
+
+Arguments:
+ FileHandle - File handle of a PEIM.
+
+Returns:
+ EFI_NOT_FOUND - The file handle doesn't point to PEIM itself.
+ EFI_ALREADY_STARTED - Indicate that the PEIM has been registered itself.
+ EFI_SUCCESS - Successfully to register itself.
+
+--*/
+;
+
+
+EFI_STATUS
+PeiFindFileEx (
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN CONST EFI_GUID *FileName, OPTIONAL
+ IN EFI_FV_FILETYPE SearchType,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle,
+ IN OUT EFI_PEI_FV_HANDLE *AprioriFile OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+ Flag - Indicator for if this is for PEI Dispath search
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+VOID
+InitializeImageServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Regitser PeCoffLoader to PeiCore PrivateData. And install
+ Pei Load File PPI.
+
+Arguments:
+
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ OldCoreData - Pointer to PEI_CORE_INSTANCE.
+
+Returns:
+
+ NONE.
+
+--*/
+;
+
+//*** AMI PORTING BEGIN ***//
+//This function is used to update LoadedImage PPI information
+//LoadedImage PPI is defined in PI 1.0 specification
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+);
+
+#include <AmiPeiLib.h>
+//*** AMI PORTING END *****//
+#endif
diff --git a/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c b/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c
new file mode 100644
index 0000000..31c5db1
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c
@@ -0,0 +1,404 @@
+/*++
+
+Copyright (c) 2006 - 2007, 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:
+
+ PeiMain.c
+
+Abstract:
+
+ Pei Core Main Entry Point
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_PPI_DEFINITION (MemoryDiscovered)
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+#include EFI_GUID_DEFINITION (StatusCode)
+
+//
+// CAR is filled with this initial value during SEC phase
+//
+#define INIT_CAR_VALUE 0x5AA55AA5
+
+#ifdef EFI_PEI_PERFORMANCE
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+
+#endif
+
+//*** AMI PORTING BEGIN ***//
+VOID InitParts(VOID* p1, VOID*p2);
+VOID InitPartsMem(VOID* p1, VOID*p2);
+VOID ProcessLoadHob(EFI_PEI_SERVICES **PeiServices);
+VOID AmiInitParts(IN EFI_PEI_SERVICES **PeiServices, VOID* InitFunction);
+//*** AMI PORTING END *****//
+
+//
+// PPI that represents memory being discoverd in PEI.
+//
+static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiMemoryDiscoveredPpiGuid,
+ NULL
+};
+
+static EFI_PEI_SERVICES mPS = {
+ {
+ PEI_SERVICES_SIGNATURE,
+ PEI_SERVICES_REVISION,
+ sizeof (EFI_PEI_SERVICES),
+ 0,
+ 0
+ },
+ PeiInstallPpi,
+ PeiReInstallPpi,
+ PeiLocatePpi,
+ PeiNotifyPpi,
+
+ PeiGetBootMode,
+ PeiSetBootMode,
+
+ PeiGetHobList,
+ PeiCreateHob,
+
+ PeiFfsFindNextVolume,
+ PeiFfsFindNextFile,
+ PeiFfsFindSectionData,
+
+ PeiInstallPeiMemory,
+ PeiAllocatePages,
+ PeiAllocatePool,
+ PeiCoreCopyMem,
+ PeiCoreSetMem,
+
+ PeiReportStatusCode,
+ PeiResetSystem,
+
+ NULL,
+ NULL,
+
+ PeiFfsFindFileByName,
+ PeiFfsGetFileInfo,
+ PeiFfsGetVolumeInfo,
+ PeiRegisterForShadow
+};
+
+
+//
+// Main entry point to the PEI Core
+//
+EFI_PEI_CORE_ENTRY_POINT (PeiMain)
+
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ SecCoreData - Information about the PEI core's operating environment.
+ PpList - Points to a list of one or more PPI descriptors to be
+ installed initially by the PEI core.
+
+Returns:
+
+ This function never returns
+
+--*/
+{
+ return PeiCore (SecCoreData,PpList, NULL);
+}
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ PpList - Pointer to Ppi list provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+ EFI_NOT_FOUND - Never reach
+
+--*/
+{
+ PEI_CORE_INSTANCE PrivateData;
+ EFI_PEI_SERVICES **PeiServices;
+ EFI_STATUS Status;
+ EFI_DXE_IPL_PPI *DxeIpl;
+ EFI_PEI_CPU_IO_PPI *CpuIo;
+ EFI_PEI_PCI_CFG2_PPI *PciCfg;
+
+#ifdef EFI_PEI_PERFORMANCE
+ UINT64 mTick;
+
+ mTick = 0;
+ if (OldCoreData == NULL) {
+ GetTimerValue (&mTick);
+ }
+#endif
+
+
+ //
+ // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
+ // the 63-bit of address is set to 1.
+ //
+ SWITCH_TO_CACHE_MODE (OldCoreData);
+
+ if (OldCoreData != NULL) {
+
+ //
+ // 2nd time through we are using System Memory and we restore a previous
+ // state by copying the OldCoreData into PrivateData. A lot of the
+ // init code will note initialize PrivateData on the 2nd pass.
+ //
+ PeiCoreCopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
+
+ //
+ // 2nd time through Pei Core has been shadowed. To Pei Services,
+ // CpuIo and PciCfg services may have been updated by some Pei Modules. So before
+ // update PrivateData.ServiceTableShadow with memory version, save the CpuIo
+ // PciCfg and restore them then.
+ //
+ CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
+ PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
+ PeiCoreCopyMem (&(PrivateData.ServiceTableShadow), &mPS, sizeof (EFI_PEI_SERVICES));
+ PrivateData.ServiceTableShadow.CpuIo = CpuIo;
+ PrivateData.ServiceTableShadow.PciCfg = PciCfg;
+ } else {
+
+ //
+ // 1st time through we are using Temp memory
+ //
+ PeiCoreSetMem (&PrivateData, sizeof (PEI_CORE_INSTANCE),0);
+ PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
+
+ //
+ // Copy PeiServices from ROM to Temp memory in PrivateData
+ //
+ PeiCoreCopyMem (&(PrivateData.ServiceTableShadow), &mPS, sizeof (EFI_PEI_SERVICES));
+ }
+
+ PrivateData.PS = &PrivateData.ServiceTableShadow;
+ PeiServices = &PrivateData.PS;
+
+ InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);
+
+ InitializePpiServices (&PrivateData, OldCoreData);
+
+ //
+ // Save PeiServicePointer so that it can be retrieved anywhere.
+ //
+ SetPeiServicesTablePointer(PeiServices);
+
+ if (OldCoreData != NULL) {
+
+ PEI_PERF_END (&PrivateData.PS,L"PreMem", NULL, 0);
+ PEI_PERF_START (&PrivateData.PS,L"PostMem", NULL, 0);
+
+ //
+ // The following code dumps out interesting cache as RAM usage information
+ // so we can keep tabs on how the cache as RAM is being utilized. The
+ // PEI_DEBUG_CODE macro is used to prevent this code from being compiled
+ // on a debug build.
+ //
+ PEI_DEBUG_CODE (
+ {
+ UINTN *StackPointer;
+ UINTN StackValue;
+
+ StackValue = INIT_CAR_VALUE;
+ for (StackPointer = (UINTN *) OldCoreData->TopOfCarHeap;
+ ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
+ && StackValue == INIT_CAR_VALUE;
+ StackPointer++) {
+ StackValue = *StackPointer;
+ }
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
+ ((UINTN) OldCoreData->MaxTopOfCarHeap - (UINTN) StackPointer)
+ )
+ );
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR heap used: %d bytes.\n",
+ ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
+ (UINTN) OldCoreData->HobList.Raw)
+ )
+ );
+ }
+ )
+
+//*** AMI PORTING BEGIN ***//
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+//*** AMI PORTING END *****//
+
+ //
+ // Alert any listeners that there is permanent memory available
+ //
+ PEI_PERF_START (&PrivateData.PS,L"DisMem", NULL, 0);
+ Status = PeiInstallPpi (&PrivateData.PS, &mMemoryDiscoveredPpi);
+ PEI_PERF_END (&PrivateData.PS,L"DisMem", NULL, 0);
+
+ } else {
+
+ //
+ // Report Status Code EFI_SW_PC_INIT
+ //
+ PEI_REPORT_STATUS_CODE (
+ &(PrivateData.PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT,
+ 0,
+ NULL,
+ NULL
+ );
+
+ //
+ // If first pass, start performance measurement.
+ //
+ PEI_PERF_START (&PrivateData.PS,L"PreMem", NULL, mTick);
+
+ //
+ // If SEC provided any PPI services to PEI, install them.
+ //
+ if (PpList != NULL) {
+ Status = PeiInstallPpi (&PrivateData.PS, PpList);
+ ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+ }
+//*** AMI PORTING BEGIN ***//
+{
+ static EFI_GUID gEfiPeiLoadedImagePpiGuid = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+ static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiLoadedImagePpiGuid, NULL
+ };
+ PeiAllocatePool(&PrivateData.PS,sizeof(EFI_PEI_PPI_DESCRIPTOR),&PrivateData.LoadedImage);
+ *PrivateData.LoadedImage = LoadedImagePpiDesc;
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+ PeiInstallPpi (&PrivateData.PS, PrivateData.LoadedImage);
+}
+//*** AMI PORTING END *****//
+ }
+
+ InitializeSecurityServices (&PrivateData, OldCoreData);
+
+ InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);
+
+ //
+ // Install Pei Load File PPI.
+ //
+ InitializeImageServices (&PrivateData, OldCoreData);
+
+ //
+ // Call PEIM dispatcher
+ //
+//*** AMI PORTING BEGIN ***//
+ if (OldCoreData != NULL) {
+ AmiInitParts(PeiServices, InitPartsMem);
+ ProcessLoadHob(PeiServices);
+ } else {
+ AmiInitParts(PeiServices, InitParts);
+ }
+//*** AMI PORTING END *****//
+ PeiDispatcher (SecCoreData, &PrivateData);
+
+ //
+ // Check if InstallPeiMemory service was called.
+ //
+//*** AMI PORTING BEGIN ***//
+ //report MEMORY_NOT_INSTALLED error
+ if (!PrivateData.PeiMemoryInstalled)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_MEMORY_NOT_INSTALLED, EFI_ERROR_MAJOR);
+// PEI_ASSERT(&PrivateData.PS, PrivateData.PeiMemoryInstalled == TRUE);
+//*** AMI PORTING END *****//
+
+ PEI_PERF_END (&PrivateData.PS, L"PostMem", NULL, 0);
+
+ DxeIpl = PeiReturnPpi (&PrivateData.PS, &gEfiDxeIplPpiGuid);
+//*** AMI PORTING BEGIN ***//
+ //report DXEIPL_NOT_FOUND error
+ if (DxeIpl==NULL)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_DXEIPL_NOT_FOUND, EFI_ERROR_MAJOR);
+// PEI_ASSERT (&PrivateData.PS, DxeIpl != NULL);
+//*** AMI PORTING END *****//
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "DXE IPL Entry\n"));
+
+//*** AMI PORTING BEGIN ***//
+ //DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList);
+ DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList.Raw);
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+ // If DXE IPL returned control, let's call dispatcher again
+ // DXE IPL might have dicovered new FV or have changed a boot mode
+
+ // reset previous bitmap so that the dispatcher will attempt to execute any new PEIMs
+ // dispatch
+ PeiDispatcher (SecCoreData, &PrivateData);
+ // DXE IPL
+ DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList.Raw);
+//*** AMI PORTING END *****//
+ PEI_ASSERT (&PrivateData.PS,FALSE);
+ return EFI_NOT_FOUND;
+
+}
+
+//*** AMI PORTING BEGIN ***//
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+)
+{
+ PEI_CORE_INSTANCE *Private = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ Private->LoadedImagePpi.ImageAddress = ImageAddress;
+ Private->LoadedImagePpi.ImageSize = ImageSize;
+ Private->LoadedImagePpi.FileHandle = FileHandle;
+ PeiReInstallPpi(PeiServices,Private->LoadedImage,Private->LoadedImage);
+}
+//*** AMI PORTING END *****//
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Ppi.c b/Core/CORE_PEI/CORE_PEI_PI/Ppi.c
new file mode 100644
index 0000000..01236e7
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Ppi.c
@@ -0,0 +1,687 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ Ppi.c
+
+Abstract:
+
+ EFI PEI Core PPI services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+VOID
+InitializePpiServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
+ }
+
+ return;
+}
+
+VOID
+ConvertPpiPointers (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Convert PPI pointers after the Hob list was migrated from the temporary memory
+ to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+ None
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ UINT8 Index;
+ PEI_PPI_LIST_POINTERS *PpiPointer;
+ UINTN Fixup;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;
+
+ for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {
+ if (Index < PrivateData->PpiData.PpiListEnd ||
+ Index > PrivateData->PpiData.NotifyListEnd) {
+ PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
+
+ if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the PEIM descriptor from the old HOB heap
+ // to the relocated HOB heap.
+ //
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);
+
+ //
+ // Only when the PEIM descriptor is in the old HOB should it be necessary
+ // to try to convert the pointers in the PEIM descriptor
+ //
+
+ if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);
+ }
+
+ //
+ // Assume that no code is located in the temporary memory, so the pointer to
+ // the notification function in the NOTIFY descriptor needs not be converted.
+ //
+ if (Index < PrivateData->PpiData.PpiListEnd &&
+ (UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&
+ (UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {
+ //
+ // Convert the pointer to the PPI interface structure in the PPI descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);
+ }
+ }
+ }
+ }
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN LastCallbackInstall;
+
+
+ if (PpiList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ Index = PrivateData->PpiData.PpiListEnd;
+ LastCallbackInstall = Index;
+
+ //
+ // This is loop installs all PPI descriptors in the PpiList. It is terminated
+ // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_PPI_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the NotifyList
+ //
+ if (Index == PrivateData->PpiData.NotifyListEnd + 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Check if it is a valid PPI.
+ // If not, rollback list to exclude all in this list.
+ // Try to indicate which item failed.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ PrivateData->PpiData.PpiListEnd = LastCallbackInstall;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));
+ return EFI_INVALID_PARAMETER;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));
+//*** AMI PORTING END ***//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*)PpiList;
+ PrivateData->PpiData.PpiListEnd++;
+
+ //
+ // Continue until the end of the PPI List.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ PpiList++;
+ Index++;
+ }
+
+ //
+ // Dispatch any callback level notifies for newly installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ LastCallbackInstall,
+ PrivateData->PpiData.PpiListEnd,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+
+
+ if ((OldPpi == NULL) || (NewPpi == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // Find the old PPI instance in the database. If we can not find it,
+ // return the EFI_NOT_FOUND error.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {
+ break;
+ }
+ }
+ if (Index == PrivateData->PpiData.PpiListEnd) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Remove the old PPI from the database, add the new one.
+ //
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
+//*** AMI PORTING END ***//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*)NewPpi;
+
+ //
+ // Dispatch any callback level notifies for the newly installed PPI.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ Index,
+ Index+1,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID *Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor OPTIONAL,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_PPI_DESCRIPTOR *TempPtr;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Search the data base for the matching instance of the GUIDed PPI.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;
+ CheckGuid = TempPtr->Guid;
+
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {
+ if (Instance == 0) {
+
+ if (PpiDescriptor != NULL) {
+ *PpiDescriptor = TempPtr;
+ }
+
+ if (Ppi != NULL) {
+ *Ppi = TempPtr->Ppi;
+ }
+
+
+ return EFI_SUCCESS;
+ }
+ Instance--;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+
+VOID *
+PeiReturnPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID *Guid
+ )
+{
+ EFI_STATUS Status;
+ VOID *Ppi;
+
+ Status = PeiLocatePpi (PeiServices, Guid, 0, NULL, &Ppi);
+
+ return (EFI_ERROR (Status)) ? NULL : Ppi;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN NotifyIndex;
+ INTN LastCallbackNotify;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr;
+ UINTN NotifyDispatchCount;
+
+
+ NotifyDispatchCount = 0;
+
+ if (NotifyList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ Index = PrivateData->PpiData.NotifyListEnd;
+ LastCallbackNotify = Index;
+
+ //
+ // This is loop installs all Notify descriptors in the NotifyList. It is
+ // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the PpiList
+ //
+ if (Index == PrivateData->PpiData.PpiListEnd - 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // If some of the PPI data is invalid restore original Notify PPI database value
+ //
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
+ PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyDispatchCount ++;
+ }
+
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR*)NotifyList;
+
+ PrivateData->PpiData.NotifyListEnd--;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ //
+ // Go the next descriptor. Remember the NotifyList moves down.
+ //
+ NotifyList++;
+ Index--;
+ }
+
+ //
+ // If there is Dispatch Notify PPI installed put them on the bottom
+ //
+ if (NotifyDispatchCount > 0) {
+ for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {
+ if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;
+
+ for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;
+ }
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;
+ PrivateData->PpiData.DispatchListEnd--;
+ }
+ }
+
+ LastCallbackNotify -= NotifyDispatchCount;
+ }
+
+ //
+ // Dispatch any callback level notifies for all previously installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ 0,
+ PrivateData->PpiData.PpiListEnd,
+ LastCallbackNotify,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN TempValue;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+
+ while (TRUE) {
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // Notifies getting installed. If so, go process any dispatch
+ // level Notifies that match the previouly installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
+ TempValue = PrivateData->PpiData.DispatchListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ 0,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.LastDispatchedNotify,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedNotify = TempValue;
+ }
+
+
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // PPIs getting installed. If so, go process any dispatch
+ // level Notifies that match the installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // PpiListEnd (with InstallPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
+ TempValue = PrivateData->PpiData.PpiListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.PpiListEnd,
+ MAX_PPI_DESCRIPTORS-1,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedInstall = TempValue;
+ }
+
+ if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {
+ break;
+ }
+ }
+ return;
+}
+
+VOID
+DispatchNotify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index1;
+ INTN Index2;
+ EFI_GUID *SearchGuid;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Remember that Installs moves up and Notifies moves down.
+ //
+ for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {
+ NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;
+
+ CheckGuid = NotifyDescriptor->Guid;
+
+ for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
+ SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {
+ PEI_DEBUG (
+ (
+ PeiServices,
+ EFI_D_INFO,
+ "Notify: PPI Guid: %g, Peim notify entry point: %x\n",
+ SearchGuid,
+ NotifyDescriptor->Notify
+ )
+ );
+ NotifyDescriptor->Notify (
+ (EFI_PEI_SERVICES**)PeiServices,
+ NotifyDescriptor,
+ (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi
+ );
+ }
+ }
+ }
+
+ return;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Reset.c b/Core/CORE_PEI/CORE_PEI_PI/Reset.c
new file mode 100644
index 0000000..eb824f3
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Reset.c
@@ -0,0 +1,76 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ Reset.c
+
+Abstract:
+
+ Pei Core Reset System Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (Reset)
+EFI_STATUS
+EFIAPI
+PeiResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_RESET_PPI *ResetPpi;
+
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiResetPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&ResetPpi
+ );
+
+ //
+ // LocatePpi returns EFI_NOT_FOUND on error
+ //
+ if (!EFI_ERROR (Status)) {
+ return ResetPpi->ResetSystem (PeiServices);
+ }
+//*** AMI PORTING BEGIN ***//
+ //Report error
+ PEI_ERROR_CODE(PeiServices,PEI_RESET_NOT_AVAILABLE,EFI_ERROR_MINOR);
+//*** AMI PORTING END *****//
+ return EFI_NOT_AVAILABLE_YET;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Security.c b/Core/CORE_PEI/CORE_PEI_PI/Security.c
new file mode 100644
index 0000000..8d85b86
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Security.c
@@ -0,0 +1,192 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ Security.c
+
+Abstract:
+
+ EFI PEI Core Security services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include EFI_PPI_DEFINITION (Security2)
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiSecurity2PpiGuid,
+ SecurityPpiNotifyCallback
+};
+
+VOID
+InitializeSecurityServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PeiNotifyPpi (&PrivateData->PS, &mNotifyList);
+ }
+ return;
+}
+
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Provide a callback for when the security PPI is installed.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ NotifyDescriptor - The descriptor for the notification event.
+ Ppi - Pointer to the PPI in question.
+
+Returns:
+
+ EFI_SUCCESS - The function is successfully processed.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ //
+ // Get PEI Core private data
+ //
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // If there isn't a security PPI installed, use the one from notification
+ //
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY2_PPI *)Ppi;
+ }
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+VerifyPeim (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 AuthenticationStatus;
+ BOOLEAN DeferExection;
+
+ //
+ // Set a default authentication state
+ //
+ AuthenticationStatus = 0;
+
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Check to see if the image is OK
+ //
+ Status = PrivateData->PrivateSecurityPpi->AuthenticationState (
+ &PrivateData->PS,
+ PrivateData->PrivateSecurityPpi,
+ AuthenticationStatus,
+ VolumeHandle,
+ FileHandle,
+ &DeferExection
+ );
+ if (DeferExection) {
+ Status = EFI_SECURITY_VIOLATION;
+ }
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_PEI_FV_HANDLE VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Verify a Firmware volume
+
+Arguments:
+
+ CurrentFvAddress - Pointer to the current Firmware Volume under consideration
+
+Returns:
+
+ EFI_SUCCESS - Firmware Volume is legal
+ EFI_SECURITY_VIOLATION - Firmware Volume fails integrity test
+
+--*/
+{
+ //
+ // Right now just pass the test. Future can authenticate and/or check the
+ // FV-header or other metric for goodness of binary.
+ //
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_PI/StatusCode.c b/Core/CORE_PEI/CORE_PEI_PI/StatusCode.c
new file mode 100644
index 0000000..8df4058
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/StatusCode.c
@@ -0,0 +1,94 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ StatusCode.c
+
+Abstract:
+
+ Pei Core Status Code Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (StatusCode)
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CodeType - Type of Status Code.
+ Value - Value to output for Status Code.
+ Instance - Instance Number of this status code.
+ CallerId - ID of the caller of this status code.
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_STATUS_CODE_PPI *StatusCodePpi;
+
+
+ //
+ //Locate StatusCode Ppi.
+ //
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiStatusCodePpiGuid,
+ 0,
+ NULL,
+ (VOID **)&StatusCodePpi
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = StatusCodePpi->ReportStatusCode (
+ PeiServices,
+ Type,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+ return Status;
+ }
+
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/dependency.c b/Core/CORE_PEI/CORE_PEI_PI/dependency.c
new file mode 100644
index 0000000..f890a42
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/dependency.c
@@ -0,0 +1,265 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ dependency.c
+
+Abstract:
+
+ PEI Dispatcher Dependency Evaluator
+
+ This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine
+ if a driver can be scheduled for execution. The criteria for
+ schedulability is that the dependency expression is satisfied.
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include "EfiDependency.h"
+#include "Dependency.h"
+
+STATIC
+BOOLEAN
+IsPpiInstalled (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EVAL_STACK_ENTRY *Stack
+ )
+/*++
+
+Routine Description:
+
+ This routine determines if a PPI has been installed.
+ The truth value of a GUID is determined by if the PPI has
+ been published and can be queried from the PPI database.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Stack - Reference to EVAL_STACK_ENTRY that contains PPI GUID to check
+
+Returns:
+
+ True if the PPI is already installed.
+ False if the PPI has yet to be installed.
+
+--*/
+{
+ VOID *PeiInstance;
+ EFI_STATUS Status;
+ EFI_GUID PpiGuid;
+
+ //
+ // If there is no GUID to evaluate, just return current result on stack.
+ //
+ if (Stack->Operator == NULL) {
+ return Stack->Result;
+ }
+
+ //
+ // Copy the Guid into a locale variable so that there are no
+ // possibilities of alignment faults for cross-compilation
+ // environments such as Intel?Itanium(TM).
+ //
+ PeiCoreCopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));
+
+ //
+ // Check if the PPI is installed.
+ //
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &PpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiInstance // PPI
+ );
+
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+{
+ EFI_STATUS Status;
+ DEPENDENCY_EXPRESSION_OPERAND *Iterator;
+ EVAL_STACK_ENTRY *StackPtr;
+ EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];
+
+ Status = EFI_SUCCESS;
+ Iterator = DependencyExpression;
+
+ StackPtr = &EvalStack[0];
+
+ while (TRUE) {
+
+ switch (*(Iterator++)) {
+
+ //
+ // For performance reason we put the frequently used items in front of
+ // the rarely used items
+ //
+
+ case (EFI_DEP_PUSH):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return FALSE;
+ }
+
+ //
+ // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)
+ // We will evaluate if the PPI is insalled on the POP operation.
+ //
+ StackPtr->Operator = (VOID *) Iterator;
+ Iterator = Iterator + sizeof (EFI_GUID);
+ StackPtr++;
+ break;
+
+ case (EFI_DEP_AND):
+ case (EFI_DEP_OR):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the two POPs for the AND operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did two POPs.
+ //
+ if (StackPtr < &EvalStack[2]) {
+ return FALSE;
+ }
+
+ //
+ // Evaluate the first POPed operator only. If the operand is
+ // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the
+ // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,
+ // we don't need to check the second operator, and the result will be
+ // evaluation of the POPed operator. Otherwise, don't POP the second
+ // operator since it will now evaluate to the final result on the
+ // next operand that causes a POP.
+ //
+ StackPtr--;
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_AND) {
+ if (!(IsPpiInstalled (PeiServices, StackPtr))) {
+ (StackPtr-1)->Result = FALSE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ } else {
+ if (IsPpiInstalled (PeiServices, StackPtr)) {
+ (StackPtr-1)->Result = TRUE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ }
+ break;
+
+ case (EFI_DEP_END):
+ StackPtr--;
+ //
+ // Check to make sure EvalStack is balanced. If not, then there is
+ // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.
+ //
+ if (StackPtr != &EvalStack[0]) {
+ return FALSE;
+ }
+ return IsPpiInstalled (PeiServices, StackPtr);
+ break;
+
+ case (EFI_DEP_NOT):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the POP for the NOT operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did a POP.
+ //
+ if (StackPtr < &EvalStack[1]) {
+ return FALSE;
+ }
+ (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));
+ (StackPtr-1)->Operator = NULL;
+ break;
+
+ case (EFI_DEP_TRUE):
+ case (EFI_DEP_FALSE):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return FALSE;
+ }
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_TRUE) {
+ StackPtr->Result = TRUE;
+ } else {
+ StackPtr->Result = FALSE;
+ }
+ StackPtr->Operator = NULL;
+ StackPtr++;
+ break;
+
+ default:
+ //
+ // The grammar should never arrive here
+ //
+ return FALSE;
+ break;
+ }
+ }
+}
diff --git a/Core/CORE_PEI/CORE_PEI_PI/dependency.h b/Core/CORE_PEI/CORE_PEI_PI/dependency.h
new file mode 100644
index 0000000..413c068
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/dependency.h
@@ -0,0 +1,38 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ dependency.h
+
+Abstract:
+
+ This module contains data specific to dependency expressions
+ and local function prototypes.
+
+--*/
+
+#ifndef _PEI_DEPENDENCY_H_
+#define _PEI_DEPENDENCY_H_
+
+#define MAX_GRAMMAR_SIZE 256
+
+//
+// type definitions
+//
+typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND;
+
+typedef struct {
+ BOOLEAN Result;
+ VOID *Operator;
+} EVAL_STACK_ENTRY;
+
+#endif
diff --git a/Core/CORE_PEI/CpuIo.c b/Core/CORE_PEI/CpuIo.c
new file mode 100644
index 0000000..634f676
--- /dev/null
+++ b/Core/CORE_PEI/CpuIo.c
@@ -0,0 +1,1158 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PeiMain/CpuIo.c 13 3/22/11 5:14p Felixp $
+//
+// $Revision: 13 $
+//
+// $Date: 3/22/11 5:14p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PeiMain/CpuIo.c $
+//
+// 13 3/22/11 5:14p Felixp
+// Method of invocation of the in-memory entry point has changed
+// from LOAD_HOB to eLink registered under PeiCoreMemoryInstalled.
+// This is more efficient.
+//
+// 12 2/05/11 3:43p Artems
+// Changed functions calling interface (added CONST qualifiers) as
+// required by PI 1.0 specification
+//
+// 11 11/05/09 4:59p Oleksiyy
+// EIP 27821 Support for 64 bit operations in IoRead and IoWrite added. To
+// use this functions IA32CLib.c, x64AsmLib.asm files should be updated
+// also.
+//
+// 10 7/08/09 5:53p Vyacheslava
+// Updated according to the coding standards.
+//
+// 9 6/16/05 10:56a Felixp
+// 1. Once memory is available, PEI Core PEIMs that created PEIM_LOAD_HOB
+// are reallocated to memory.
+// 2. ImagePei.c removed
+// 3. FileLoader moved from DxeIpl to PEI Core
+//
+// 8 6/10/05 5:49p Felixp
+// Bug fixes in MemRead, MemWrite, IoRead, IoWrite
+//
+// 7 6/06/05 7:48p Felixp
+//
+// 6 6/06/05 1:25p Felixp
+//
+// 5 6/03/05 3:45p Felixp
+// Updated to support changes introduced in PEI CIS 0.91
+//
+// 4 3/04/05 9:38a Mandal
+//
+// 3 2/01/05 2:35a Felixp
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 7 1/27/04 3:58a Felixp
+// Bug fixes and improvements as a part of PEI CORE integration
+//
+// 6 12/29/03 5:25p Felixp
+// preffix 'EFI_' added to the names of the PEIM descriptor structures and
+// flags
+//
+// 5 12/15/03 4:35p Robert
+//
+// 4 12/15/03 4:25p Robert
+//
+// 3 12/15/03 12:40p Robert
+// changed position of GUID definition below PPI include
+//
+// 2 12/15/03 11:49a Robert
+// updated PPI definitions and removed entry point definitions
+//
+// 1 12/11/03 5:34p Robert
+// Initial Check In
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CpuIo.c
+//
+// Description: This file contains the implementation of the CPU I/O
+// specification. For questions about the specification refer to the
+// PEI CIS specification chapter 9
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+// Module specific Includes
+#include <AmiPeiLib.h>
+#include <AmiHobs.h>
+// Produced PPIs
+#include <PPI/CpuIo.h>
+
+// Function Prototypes
+static EFI_STATUS LocalMemRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static EFI_STATUS LocalMemWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static EFI_STATUS LocalIoRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static EFI_STATUS LocalIoWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static UINT8 LocalIoRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT16 LocalIoRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT32 LocalIoRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT64 LocalIoRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static VOID LocalIoWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+);
+
+static VOID LocalIoWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+);
+
+static VOID LocalIoWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+);
+
+static VOID LocalIoWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+);
+
+static UINT8 MemRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT16 MemRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT32 MemRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT64 MemRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static VOID MemWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+);
+
+static VOID MemWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+);
+
+static VOID MemWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+);
+
+static VOID MemWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+);
+
+// PPI interface definition
+static EFI_PEI_CPU_IO_PPI mCpuIoPpi = {
+ {LocalMemRead, LocalMemWrite},
+ {LocalIoRead, LocalIoWrite},
+ LocalIoRead8, LocalIoRead16, LocalIoRead32, LocalIoRead64,
+ LocalIoWrite8, LocalIoWrite16, LocalIoWrite32, LocalIoWrite64,
+ MemRead8, MemRead16, MemRead32, MemRead64,
+ MemWrite8, MemWrite16, MemWrite32, MemWrite64
+};
+
+// PPI that are installed
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiCpuIoPpiInServiceTableGuid,
+ NULL
+ }
+};
+
+// Function Definitions
+EFI_STATUS EFIAPI CpuIoMemInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ // Update the CpuIo pointer
+ (*PeiServices)->CpuIo = &mCpuIoPpi;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: CpuIoInit
+//
+// Description: This function installs the CPU I/O PPI and exits
+//
+// Input:
+// *FfsHeader - pointer to the header of the current firmware file system
+// **PeiServices - pointer to the Pei Services function and data structure
+//
+// Output: always returns EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI CpuIoInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+
+ // Install the CpuIo Ppi
+ (*PeiServices)->CpuIo = &mCpuIoPpi;
+ Status = (*PeiServices)->InstallPpi( PeiServices, mPpiList );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: CalcAddrChanges
+//
+// Description: This function determines which addresses need to be changed
+// as data is read or written.
+//
+// Input:
+// Width - Contains the width and type of memory or I/O read that is needed
+//
+// Output:
+// *In - The number of bytes to increment the input buffer address after
+// every read or write access
+// *Out - The number of bytes to increment the output buffer address after
+// every read or write access
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+VOID CalcAddrChanges(
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ OUT UINTN *In,
+ OUT UINTN *Out
+)
+{
+ // get the number of bytes per read or write access and the turn that into
+ // an Hex Address Incrementing value
+ *In = *Out = 1 << (Width % 4);
+
+ if ( (Width >= EfiPeiCpuIoWidthFifoUint8) &&
+ (Width <= EfiPeiCpuIoWidthFifoUint64) )
+ *Out = 0;
+
+ else if ( (Width >= EfiPeiCpuIoWidthFillUint8) &&
+ (Width <= EfiPeiCpuIoWidthFillUint64) )
+ *In = 0;
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead8
+//
+// Description: This function is called to read a byte from the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT8 - This is the value read from the I/O space specified by the
+// value passed in by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT8 LocalIoRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead8 ((UINT16) Address);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead16
+//
+// Description: This function is called to read a word from the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT16 - This is the value read from the I/O space specified by the
+// by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT16 LocalIoRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead16 ((UINT16) Address);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead32
+//
+// Description: This function is called to read a dword from the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT32 - This is the value read from the I/O space specified by the
+// value passed in by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT32 LocalIoRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead32 ((UINT16) Address);
+}
+
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead64
+//
+// Description: This function is called to read a qword from the I/O space
+// This function is not available in a 32bit system so we just return 0 if
+// it is called. We cannot remove this function because it is part of the
+// specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT64 - This is the value read from the I/O space specified by the
+// value passed in by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+static UINT64 LocalIoRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead64 ((UINT16) Address);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoWrite8
+//
+// Description: This function is called to write a byte to the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer8 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Buffer8
+)
+{
+ IoWrite8 ((UINT16) Address, Buffer8);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocaIoWrite16
+//
+// Description: This function is called to write a word to the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer16 - The value to be written to location specified by Address
+//
+// Output: VOID
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Buffer16
+)
+{
+ IoWrite16 ((UINT16) Address, Buffer16);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocaIoWrite32
+//
+// Description: This function is called to write a dword to the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer32 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Buffer32
+)
+{
+ IoWrite32 ((UINT16) Address, Buffer32);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocaIoWrite64
+//
+// Description: This function is called to write a qword to the I/O space
+// This function is not available in a 32bit system so we just do nothing
+// if it is called. We cannot remove this function because it is part of
+// the specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer64 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Buffer64
+)
+{
+ IoWrite64 ((UINT16) Address, Buffer64);
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead8
+//
+// Description: This function is called to read a byte from the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT8 - This is the value read from the Memory space specified by
+// the input variable Address
+//
+// Referrals:
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT8 MemRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT8*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead16
+//
+// Description: This function is called to read a word from the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT16 - This is the value read from the Memory space specified
+// by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT16 MemRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT16*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead32
+//
+// Description: This function is called to read a dword from the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT32 - This is the value read from the Memory space specified by
+// the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT32 MemRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT32*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead64
+//
+// Description: This function is called to read a qword from the Memory space
+// This function is not available in a 32bit system so we just return 0 if
+// it is called. We cannot remove this function because it is part of the
+// specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT64 - This is the value read from the Memory space specified by
+// the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT64 MemRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT64*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite8
+//
+// Description: This function is called to write a byte to the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer8 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Buffer8
+)
+{
+ *(volatile UINT8*) Address = Buffer8;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite16
+//
+// Description: This function is called to write a word to the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer16 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Buffer16
+)
+{
+ *(volatile UINT16*) Address = Buffer16;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite32
+//
+// Description: This function is called to write a dword to the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer32 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Buffer32
+)
+{
+ *(volatile UINT32*) Address = Buffer32;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite64
+//
+// Description: This function is called to write a qword to the Memory space
+// This function is not available in a 32bit system so we just do nothing
+// if it is called. We cannot remove this function because it is part of
+// the specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer64 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Buffer
+)
+{
+ *(volatile UINT64*) Address = Buffer;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalMemWrite
+//
+// Description: This function is called to do multiple writes to the memory
+// space. It also is capable of doing a memory space fill of a single value
+// or a serial write from a buffer depending on the Width type being passed
+// in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the I/O space that is to be written
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to write
+// *Buffer - Data to be written to the I/O space
+//
+// Output: always returns EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalMemWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ MemWrite8(
+ PeiServices,
+ This,
+ Address,
+ *(UINT8*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ MemWrite16(
+ PeiServices,
+ This,
+ Address,
+ *(UINT16*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ MemWrite32(
+ PeiServices,
+ This,
+ Address,
+ *(UINT32*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ MemWrite64(
+ PeiServices,
+ This,
+ Address,
+ *(UINT64*)Buffer
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalMemRead
+//
+// Description: This function is called to do multiple reads from the Memory
+// space. It also is capable of doing an read of an I/O space area to a
+// single byte or a serial read into a buffer depending on the Width type
+// being passed in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the Memory space that is to be read each time
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to read
+//
+// Output: always returns EFI_SUCCESS
+// *Buffer - Data to be read from the Memory space
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalMemRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ *(UINT8*)Buffer = MemRead8(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ *(UINT16*)Buffer = MemRead16(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ *(UINT32*)Buffer = MemRead32(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ *(UINT64*)Buffer = MemRead64(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead
+//
+// Description: This function is called to do multiple reads from the I/O space
+// It also is capable of doing an read of an I/O space area to a single byte
+// or a serial read into a buffer depending on the Width type being passed in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the I/O space that is to be read
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to read
+//
+// Output: always returns EFI_SUCCESS
+// *Buffer - Data to be read from the I/O space
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalIoRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer )
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ *(UINT8*)Buffer = LocalIoRead8(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ *(UINT16*)Buffer = LocalIoRead16(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ *(UINT32*)Buffer = LocalIoRead32(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ *(UINT64*)Buffer = LocalIoRead64(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoWrite
+//
+// Description: This function is called to do multiple writes to the I/O space
+// It also is capable of doing an I/O space fill of a single value or a
+// serial write from a buffer depending on the Width type being passed in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the I/O space that is to be written
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to write
+// *Buffer - Data to be written to the I/O space
+//
+// Output: always returns EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalIoWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer )
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ LocalIoWrite8(
+ PeiServices,
+ This,
+ Address,
+ *(UINT8*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ LocalIoWrite16(
+ PeiServices,
+ This,
+ Address,
+ *(UINT16*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ LocalIoWrite32(
+ PeiServices,
+ This,
+ Address,
+ *(UINT32*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ LocalIoWrite64(
+ PeiServices,
+ This,
+ Address,
+ *(UINT64*)Buffer
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CORE_PEI/DxeIpl.c b/Core/CORE_PEI/DxeIpl.c
new file mode 100644
index 0000000..8a1a129
--- /dev/null
+++ b/Core/CORE_PEI/DxeIpl.c
@@ -0,0 +1,838 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_PEI/DxeIpl.c 4 10/25/12 8:50a Wesleychen $
+//
+// $Revision: 4 $
+//
+// $Date: 10/25/12 8:50a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_PEI/DxeIpl.c $
+//
+// 4 10/25/12 8:50a Wesleychen
+// - Update Core to 4.6.5.4.
+// - Fixed system hang at CKP 0x4F during S3 resume if HT is disabled.
+//
+// 45 5/21/12 10:42a Artems
+// [TAG] EIP87678
+// [Category] Improvement
+// [Description] Select ROM image to use on BOOT_ON_FLASH_UPDATE path
+// We have two images - one already in flash (old) and one in reflash
+// capsule
+// We can use either one to boot
+// [Files] DxeIpl.c
+//
+// 44 4/20/12 2:23p Artems
+// [TAG] EIP87678
+// [Category] New Feature
+// [Description] Select image to boot from on flash update boot path -
+// either old one (currently in flash) or new one (in recovery capsule)
+// [Files] Recovery.c DxeIpl.c Core.sdl Tokens.c
+//
+// 43 11/01/11 1:57p Felixp
+// [TAG] EIP 69841 and 71719
+// [Category] Improvement
+// [Description] The AMI customizations are removed from the DXE memory
+// manager.
+// They are replaced with the Memory Type Information HOB used in Tiano
+// projects.
+// This is done to reduces number of descriptors in the memory map
+// and to workaround Windows bug (Windows can't handle memory allocations
+// that happen after the start of the OS loader).
+// [Files] CORE_DXE.sdl, Page.c, BDS.c, DxeIpl.c
+//
+// 42 7/19/11 11:29a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 41 6/02/11 4:49p Artems
+//
+// 40 5/13/11 5:12p Artems
+// Preserved boot mode when recovery/flash update failed for error
+// reporting
+//
+// 39 5/05/11 3:44p Artems
+// Bugfix: different FV count for PI 0.9 and PI 1.0 specification
+//
+// 38 2/15/11 12:35p Artems
+// Added workaround so in recovery DXE_CORE ffs will be picked from right
+// FV
+//
+// 37 2/05/11 3:48p Artems
+// Added new ROM layout infrastructure support
+// Replaced call to FFS PPI with library function to work both in PI 0.91
+// and 1.0 modes
+//
+// 36 10/01/10 4:33p Felixp
+// Debug message with DXE Core addres is moved to after the instalaltion
+// of the END of PEI PPI
+//
+// 35 11/13/09 4:32p Felixp
+// Buffer overflow protection is added (calls to Sprintf replaced with
+// Sprintf_s).
+//
+// 34 7/10/09 4:32p Artems
+// Added function headers
+//
+// 33 5/21/09 5:19p Felixp
+// RomLayout support. Call to ReportFvDxeIpl is added.
+//
+// 32 5/07/08 12:23p Felixp
+// Converted to use new Performance API
+//
+// 31 4/18/08 6:27p Felixp
+// DXE_CORE_STARTED reported at the very end of PEI phase
+//
+// 30 4/20/07 5:10p Felixp
+// Status codes added
+//
+// 29 4/19/07 1:03p Felixp
+//
+// 27 4/17/07 9:07a Felixp
+// S3 & Recovery Status Codes removed. They are reported by the S3 &
+// Recovery PEIM
+//
+// 26 3/13/07 1:46a Felixp
+// Error reporting updated to use new PEI_ERROR_CODE macro
+//
+// 25 3/12/07 10:26a Felixp
+// LoadedImage PPI support added (defined in PI 1.0; used by AmiDebugger)
+//
+// 23 11/02/06 10:25p Felixp
+// Install EFI_PEI_END_OF_PEI_PHASE_PPI_GUID right before launching DXE
+// Core
+//
+// 22 8/25/06 10:58a Felixp
+//
+// 21 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
+//
+// 20 6/04/06 10:50p Ambikas
+//
+// 19 5/22/06 12:14a Felixp
+// More status/error codes added
+//
+// 18 3/13/06 9:51a Felixp
+//
+// 17 12/01/05 9:52a Felixp
+// Recovery Logic changed: RecoveryModule PPI is used. Capsule processing
+// is moved to Recovery.c
+//
+// 16 10/09/05 11:25a Felixp
+// Performance measurements added.
+//
+// 15 6/16/05 10:56a Felixp
+// 1. Once memory is available, PEI Core PEIMs that created PEIM_LOAD_HOB
+// are reallocated to memory.
+// 2. ImagePei.c removed
+// 3. FileLoader moved from DxeIpl to PEI Core
+//
+// 14 6/06/05 1:25p Felixp
+// Type parameter removed from AllocatePages to match PEI CIS 0.91
+//
+// 13 3/25/05 5:47p Felixp
+// 1. S3 boot path: call of S3RestoreConfig added
+// 3. Recovery boot path: trace messages added
+//
+// 12 3/24/05 6:48p Felixp
+//
+// 11 3/22/05 10:03p Felixp
+// Recovery Support
+//
+// 10 3/17/05 1:54p Felixp
+// implementation of S3Resume boot path started
+//
+// 9 3/17/05 1:45p Felixp
+// Bug fix in memory installed callback (status was not checked)
+//
+// 8 3/04/05 9:39a Mandal
+//
+// 7 1/25/05 3:37p Felixp
+//
+// 6 1/25/05 3:26p Felixp
+// Once memory is available DxeIpl realocates itself to memory and
+// installs
+// LoadFile PPI
+//
+// 5 1/22/05 12:29p Felixp
+// Bug fix:
+// Last parameter to AllocatePages was VOID* instead of
+// EFI_PHYSICAL_ADDRESS, which
+// resulted in a stack corruption.
+//
+// 4 1/22/05 11:29a Felixp
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 19 12/20/04 5:10p Felixp
+//
+// 18 12/20/04 4:54p Felixp
+//
+// 17 12/17/04 6:59p Felixp
+// PEI_DEBUG_MSG renamed to PEI_TRACE
+//
+// 16 11/24/04 9:38a Felixp
+// format of debug message changed
+//
+// 15 11/19/04 1:23a Felixp
+//
+// 14 11/10/04 5:18p Felixp
+// Debug message added
+//
+// 13 10/21/04 2:47p Felixp
+// Support for DXE Core compression added
+//
+// 12 7/13/04 10:42a Felixp
+//
+// 11 4/11/04 2:49p Felixp
+//
+// 10 4/07/04 12:46a Felixp
+// REAL PLATFORM DEBUGGING (lots of bug fixes)
+//
+// 9 3/29/04 6:06p Felixp
+//
+// 8 3/29/04 5:40p Felixp
+//
+// 7 3/28/04 2:11p Felixp
+// 1. PE Loader and some other commonly used code moved to the Library
+// 2. Warnings fixed (from now on warning will be treated as error)
+//
+// 6 3/20/04 12:03p Felixp
+//
+// 5 2/19/04 10:08a Felixp
+// Debugging code removed.
+//
+// 4 2/11/04 12:29a Felixp
+//
+// 3 2/10/04 4:02p Felixp
+//
+// 2 2/04/04 2:04a Felixp
+// work in progress...
+//
+// 1 1/28/04 3:23a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DxeIpl.c
+//
+// Description: DXE Core Loader
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//-----------------------------------------------------------------------------
+
+#include <PEI.h>
+#include <HOB.h>
+#include <AmiHobs.h>
+#include <AmiPeiLib.h>
+#include <PPI/RecoveryModule.h>
+#include <PPI/S3Resume2.h>
+#include <PPI/S3Resume.h>
+#include <PPI/LoadedImagePpi.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <token.h>
+#include <AmiHobs.h>
+#include "Core/CPU/CPU.h"
+#include "Core/CPU/CpuCspLib.h"
+
+#define SMM_ASM_FIXUP_SMM_BASE 0x38002
+#define SMM_ASM_FIXUP_IED_ZERO_MEM 0x38029
+#define SMM_ASM_BASE_CHANGE_FLAG 0x3808f
+#define APIC_SMI (2 << 8)
+#define APIC_LEVEL_ASSERT (1 << 14)
+#define APIC_NO_SHORT_HAND (0 << 18)
+
+//-----------------------------------------------------------------------------
+
+//****************************************************************************/
+// TYPE DECLARATIONS
+//****************************************************************************/
+typedef VOID (EFIAPI *DXE_ENTRY_POINT)(
+ IN VOID *HobStart
+);
+
+//****************************************************************************/
+// FUNCTION DECLARATIONS
+//****************************************************************************/
+EFI_STATUS EFIAPI Entry(
+ IN EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *HobList
+);
+
+#ifdef x64_BUILD_SUPPORT
+VOID InitLongMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1
+);
+#endif
+
+//****************************************************************************/
+// VARIABLE DECLARATIONS
+//****************************************************************************/
+// PPIs
+EFI_DXE_IPL_PPI DxeIplPpi = { Entry };
+EFI_GUID guidDxeIpl = EFI_DXE_IPL_PPI_GUID;
+EFI_GUID guidEndOfPei = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+
+// PPI to be installed
+static EFI_PEI_PPI_DESCRIPTOR PpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidDxeIpl, &DxeIplPpi
+ }
+};
+
+static EFI_PEI_PPI_DESCRIPTOR EndOfPpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidEndOfPei, NULL
+ }
+};
+
+EFI_PEI_LOADED_IMAGE_PPI LoadedImagePpi;
+EFI_GUID guidLoadedImage = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidLoadedImage, &LoadedImagePpi
+ }
+};
+
+// The order of elements in this array is important.
+// It defines the order of memory types in the DXE memory map.
+// The first array element corresponds to the type with the largest address.
+// Keeping boot time memory types at the bottom of the list improves
+// stability of the runtime portions of the memory map
+// which is important during S4 resume.
+CONST EFI_MEMORY_TYPE_INFORMATION DefaultMemoryTypeInformation[] = {
+ { EfiRuntimeServicesCode, 0x30 },
+ { EfiRuntimeServicesData, 0x20 },
+ { EfiACPIMemoryNVS, 0x60 },
+ { EfiACPIReclaimMemory, 0x10 },
+ { EfiReservedMemoryType, 0x30 },
+ { EfiBootServicesCode, 0x600 },
+ { EfiBootServicesData, 0x1500 },
+ { EfiMaxMemoryType, 0 } // indicates the end of the table
+};
+
+//****************************************************************************/
+// IMPLEMENTATION
+//****************************************************************************/
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: LoadDxeCore
+//
+// Description:
+// Loads DXE core file into memory
+//
+// Input:
+// IN EFI_PEI_SERVICES **ppPS - pointer to PEI services structure
+// IN EFI_FIRMWARE_VOLUME_HEADER *pFV - pointer to firmware volume header
+// OUT EFI_FFS_FILE_HEADER **ppFile - pointer to returned FFS file header
+// OUT EFI_PHYSICAL_ADDRESS *pAddress - pointer to returned address where file loaded
+// OUT UINT64 *pSize - pointer to returned file size
+// OUT EFI_PHYSICAL_ADDRESS *pEntry - pointer to returned address of entry point
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - DXE core loaded successfully
+// EFI_ERROR - DXE core file not found or cannot be loaded
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LoadDxeCore(
+ IN EFI_PEI_SERVICES **ppPS,
+ IN EFI_FIRMWARE_VOLUME_HEADER *pFV,
+ OUT EFI_FFS_FILE_HEADER **ppFile,
+ OUT EFI_PHYSICAL_ADDRESS *pAddress,
+ OUT UINT64 *pSize,
+ OUT EFI_PHYSICAL_ADDRESS *pEntry
+)
+{
+ EFI_STATUS Status;
+ *ppFile = NULL;
+ // loop via all files
+ while(TRUE)
+ {
+ Status = (*ppPS)->FfsFindNextFile(ppPS, EFI_FV_FILETYPE_DXE_CORE, pFV, ppFile);
+ if( EFI_ERROR(Status) ) return Status;
+ Status = PeiLoadFile(ppPS,*ppFile,pAddress,pSize,pEntry);
+ if( !EFI_ERROR(Status) ) return Status;
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: S3Resume
+//
+// Description:
+// Implementation of S3 wake boot path
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - S3 resume boot path is failed or cannot be found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS S3Resume(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_S3_RESUME2_PPI *pS32;
+ EFI_PEI_S3_RESUME_PPI *pS3;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ EFI_STATUS Status;
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "S3Resume\n"));
+ Status = (*PeiServices)->LocatePpi(PeiServices,&gEfiPeiS3Resume2PpiGuid,0,&pDummy,&pS32);
+ if (EFI_ERROR(Status))
+ {
+ Status = (*PeiServices)->LocatePpi(PeiServices,&gPeiS3ResumePpiGuid,0,&pDummy,&pS3);
+ if (EFI_ERROR(Status))
+ {
+ PEI_ERROR_CODE(PeiServices,PEI_S3_RESUME_PPI_NOT_FOUND,EFI_ERROR_MAJOR);
+ return Status;
+ }
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Calling S3RestoreConfig\n"));
+ return pS3->S3RestoreConfig(PeiServices);
+ }
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Calling S3RestoreConfig2\n"));
+ return pS32->S3RestoreConfig2(pS32);
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: Recovery
+//
+// Description:
+// Implementation of recovery boot path
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - recovery capsule not found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS Recovery(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ static EFI_GUID guidRecoveryModule = EFI_PEI_RECOVERY_MODULE_PPI_GUID;
+ EFI_PEI_RECOVERY_MODULE_PPI *pRecovery;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ EFI_STATUS Status = (*PeiServices)->LocatePpi(PeiServices,&guidRecoveryModule,0,&pDummy,&pRecovery);
+ if (EFI_ERROR(Status)){
+ PEI_ERROR_CODE(PeiServices,PEI_RECOVERY_PPI_NOT_FOUND,EFI_ERROR_MAJOR);
+ return Status;
+ }
+ return pRecovery->LoadRecoveryCapsule(PeiServices,pRecovery);
+}
+
+//defined in ReportFv2.c
+EFI_STATUS ReportFV2Dxe(
+ IN VOID* RecoveryCapsule OPTIONAL,
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: FindRecoveryBuffer
+//
+// Description:
+// Searches for recovery capsule address in HOB
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// OUT VOID **Buffer - pointer where to store found address
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - recovery capsule not found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindRecoveryBuffer(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT VOID **Buffer
+)
+{
+ EFI_STATUS Status;
+ RECOVERY_IMAGE_HOB *RecoveryHob;
+ static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &RecoveryHob);
+ if(EFI_ERROR(Status))
+ return Status; //we are not on recovery boot path
+
+ Status = FindNextHobByGuid(&RecoveryHobGuid, &RecoveryHob);
+ if(EFI_ERROR(Status))
+ return Status; //we are not on recovery boot path
+
+ if(RecoveryHob->Status == EFI_SUCCESS && RecoveryHob->Address != NULL) {
+ *Buffer = (VOID *)(UINTN)RecoveryHob->Address;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+extern const BOOLEAN UseNewImage;
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: PublishDxeFv
+//
+// Description:
+// Publishes Firmware volumes required for DXE phase
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// IN EFI_BOOT_MODE BootMode - current boot mode
+//
+// Output:
+// UINTN - Number of next firmware volume to start search for DXE_CORE from
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN PublishDxeFv(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+)
+{
+ EFI_STATUS Status;
+ UINTN FvNum = 0;
+ VOID *RecoveryBuffer = NULL;
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+
+/* first check for recovery/flashupdate capsule
+BOOT_IN_RECOVERY_MODE - actual recovery or flash update via recovery capsule on disk (in latter case
+boot mode will be changed to BOOT_ON_FLASH_UPDATE after call to Recovery() function)
+BOOT_ON_FLASH_UPDATE - flash update via recovery capsule in memory
+*/
+ if (BootMode == BOOT_IN_RECOVERY_MODE || BootMode == BOOT_ON_FLASH_UPDATE) {
+ Status = Recovery(PeiServices);
+ if (!EFI_ERROR(Status)) {
+ Status = FindRecoveryBuffer(PeiServices, &RecoveryBuffer);
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode); //check if boot mode changed
+ }
+
+ if(EFI_ERROR(Status)) {
+ /* we can't find recovery capsule, report error */
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_FAILED, EFI_ERROR_MAJOR);
+ }
+ }
+
+ if(RecoveryBuffer != NULL) {
+ if(BootMode == BOOT_IN_RECOVERY_MODE || UseNewImage) {
+#if PI_SPECIFICATION_VERSION >= 0x00010000
+ /* when we're in recovery we publish DXE Fv from recovery buffer, instead of flash */
+ while( !EFI_ERROR((*PeiServices)->FfsFindNextVolume(PeiServices, FvNum, &pFV)))
+ FvNum++; //determine how many FVs published already
+#endif
+ Status = ReportFV2Dxe(RecoveryBuffer, PeiServices);
+ if(!EFI_ERROR(Status)) {
+ return FvNum;
+ } else {
+ /* we can't publish recovery capsule, report error */
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_FAILED, EFI_ERROR_MAJOR);
+ }
+ }
+ }
+
+ Status = ReportFV2Dxe(NULL, PeiServices);
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: Entry
+//
+// Description:
+// Implementation of EFI_DXE_IPL_PPI Entry function
+//
+// Input:
+// IN EFI_DXE_IPL_PPI *This - pointer to PPI instance
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// IN EFI_HOB_HANDOFF_INFO_TABLE *HobList - pointer to HOB list
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - Boot failed
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI Entry(
+ IN EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *HobList
+)
+{
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+ UINTN FvNum;
+ EFI_PHYSICAL_ADDRESS DxeCoreAddress, DxeCoreEntry;
+ UINT64 DxeCoreSize;
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER* pFile;
+ EFI_BOOT_MODE BootMode=(EFI_BOOT_MODE)-1; //set it to invalid value
+ EFI_PEI_LOADED_IMAGE_PPI *OldLoadedImagePpi;
+ EFI_PEI_PPI_DESCRIPTOR *OldLoadedImageDesc;
+#ifdef EFI_DEBUG
+ CHAR8 sName[0x100];
+#endif
+ EFI_MEMORY_TYPE_INFORMATION MemoryInformationBuffer[EfiMaxMemoryType + 1];
+ EFI_MEMORY_TYPE_INFORMATION *MemoryInformationPtr = NULL;
+ UINTN MemoryInformationSize;
+ EFI_HOB_GUID_TYPE *MemoryInformationHob;
+
+ PEI_PERF_START(PeiServices,DXEIPL_TOK, NULL,0);
+ PEI_PROGRESS_CODE(PeiServices,PEI_DXE_IPL_STARTED);
+
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ if (BootMode == BOOT_ON_S3_RESUME) {
+#ifndef AMI_CPU_S3_PEI_SUPPORT
+#define AMI_CPU_S3_PEI_SUPPORT 0
+#endif
+#if AMI_CPU_S3_PEI_SUPPORT == 0
+ {
+ VOID *FirstHob;
+ SMM_HOB *SmmHob;
+ EFI_GUID gSmmHobGuid = SMM_HOB_GUID;
+ VOID *SaveBuffer;
+ UINT8 ApicId;
+ UINT8 i,j;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ SmmHob = (SMM_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &SmmHob)))
+ {
+ if (guidcmp(&SmmHob->EfiHobGuidType.Name, &gSmmHobGuid) == 0)
+ break;
+ }
+ if (!EFI_ERROR(Status))
+ {
+ //Allocate memory for temporarly perserve the 3000:8000 data.
+ Status = (*PeiServices)->AllocatePool(
+ PeiServices,
+ SmmGetBaseSaveBufferSize(),
+ &SaveBuffer
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ SmmSetupDefaultHandler(SaveBuffer, SmmHob);
+
+ for (i = 0, j = 0; i < SmmHob->NumCpus; ++i)
+ {
+ *(UINT32*)SMM_ASM_FIXUP_SMM_BASE = (UINT32)SmmHob->SmmBase[i];
+ *(UINT8*)SMM_ASM_BASE_CHANGE_FLAG = 0; //Initialize Flag
+
+ ApicId = j;
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER), ApicId << 24, 0x00ffffff);
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_LOW_REGISTER), APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI, 0);
+
+ while (!(*(volatile UINT8*)SMM_ASM_BASE_CHANGE_FLAG))
+ {
+ CPULib_Pause(); //Wait on Flag
+ }
+ ++*(UINT16*)SMM_ASM_FIXUP_IED_ZERO_MEM; //Only 0, for first thread to clear IED memory.
+
+ if (IsHtEnabled())
+ {
+ j++;
+ }
+ else
+ {
+ j += 2;
+ }
+ }
+
+ SmmRemoveDefaultHandler(SaveBuffer);
+ }
+ }
+#endif
+ PEI_PERF_END(PeiServices, DXEIPL_TOK, NULL, 0);
+ S3Resume(PeiServices);
+ //if S3 Resume failed, report error and reset system
+ PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_FAILED, EFI_ERROR_MAJOR);
+ (*PeiServices)->ResetSystem(PeiServices);
+ } else {
+ FvNum = PublishDxeFv(PeiServices, BootMode);
+ }
+
+ while( !EFI_ERROR ((*PeiServices)->FfsFindNextVolume (PeiServices, FvNum++, &pFV) )
+ && EFI_ERROR(Status=LoadDxeCore(PeiServices,pFV,&pFile,&DxeCoreAddress,&DxeCoreSize,&DxeCoreEntry))
+ );
+ if (EFI_ERROR(Status))
+ {
+ PEI_ERROR_CODE(PeiServices,PEI_DXE_CORE_NOT_FOUND,EFI_ERROR_MAJOR);
+ PEI_PERF_END(PeiServices,DXEIPL_TOK, NULL,0);
+ return Status;
+ }
+ //Create module allocation HOB for DXE Core
+ CreateHobMemoryAllocationModule(
+ PeiServices, DxeCoreAddress, DxeCoreSize,
+ EfiBootServicesCode, &pFile->Name,
+ DxeCoreEntry
+ );
+
+ // Create a MemoryTypeInformation HOB (used by DXE memory manager)
+
+ // There can only be a single memory type information HOB.
+ // Invalidate other HOB instances (if any).
+ Status = (*PeiServices)->GetHobList(PeiServices, &MemoryInformationHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ while (!EFI_ERROR(
+ FindNextHobByGuid(&gEfiMemoryTypeInformationGuid, &MemoryInformationHob)
+ )) MemoryInformationHob->Header.HobType = EFI_HOB_TYPE_UNUSED;
+
+ MemoryInformationSize = sizeof(MemoryInformationBuffer);
+
+ // In case of S4 resume, use memory type information
+ // from the last full boot (S5 resume).
+ // This preserves the memory map across sessions.
+ Status = PeiGetVariable (
+ PeiServices,
+ (BootMode == BOOT_ON_S4_RESUME)
+ ? L"PreviousMemoryTypeInformation"
+ : EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+ &gEfiMemoryTypeInformationGuid,
+ NULL, &MemoryInformationSize, MemoryInformationBuffer
+ );
+ if (EFI_ERROR(Status)){
+ MemoryInformationPtr = (EFI_MEMORY_TYPE_INFORMATION*)DefaultMemoryTypeInformation;
+ MemoryInformationSize = sizeof(DefaultMemoryTypeInformation);
+ }else{
+ MemoryInformationPtr=MemoryInformationBuffer;
+ }
+ Status = (*PeiServices)->CreateHob (
+ PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(EFI_HOB_GUID_TYPE) + MemoryInformationSize,
+ &MemoryInformationHob
+ );
+ if (!EFI_ERROR(Status)) {
+ MemoryInformationHob->Name = gEfiMemoryTypeInformationGuid;
+ MemCpy( MemoryInformationHob+1, MemoryInformationPtr, MemoryInformationSize);
+ }
+
+
+ //Update LoadedImage PPI information
+ LoadedImagePpi.ImageAddress = DxeCoreAddress;
+ LoadedImagePpi.ImageSize = DxeCoreSize;
+ LoadedImagePpi.FileHandle = pFile;
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices, &guidLoadedImage,
+ 0, &OldLoadedImageDesc, &OldLoadedImagePpi
+ );
+ if (!(EFI_ERROR(Status))) { // if Loaded Image PPI was located
+ Status = (*PeiServices)->ReInstallPpi (
+ PeiServices, OldLoadedImageDesc, LoadedImagePpiDesc
+ );
+ } else {
+ // Loaded Image PPI not found, try installing it again.
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices,LoadedImagePpiDesc
+ );
+ }
+ PEI_PERF_END(PeiServices,DXEIPL_TOK, NULL,0);
+ (*PeiServices)->InstallPpi(PeiServices,EndOfPpiList);
+#ifdef EFI_DEBUG
+ if (!GetName((VOID*)DxeCoreAddress,sName)) Sprintf_s(sName,sizeof(sName),"DXE-Core");
+ PeiTrace(TRACE_DXEIPL, PeiServices, "%s.Entry(%X)\n", sName, DxeCoreEntry);
+#endif
+ PEI_PROGRESS_CODE(PeiServices,DXE_CORE_STARTED);
+#ifdef x64_BUILD_SUPPORT
+ InitLongMode(
+ PeiServices, (VOID*)(UINTN)DxeCoreEntry, HobList
+ );
+#else
+ ((DXE_ENTRY_POINT )DxeCoreEntry)(HobList);
+#endif
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: PeiInitDxeIpl
+//
+// Description:
+// DXE loader entry point
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader - pointer to FFS file header
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - EFI_DXE_IPL_PPI installed successfully
+// EFI_ERROR - error occured during execution
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiInitDxeIpl (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ return (*PeiServices)->InstallPpi(PeiServices,PpiList);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_PEI/PciCfg.c b/Core/CORE_PEI/PciCfg.c
new file mode 100644
index 0000000..c831953
--- /dev/null
+++ b/Core/CORE_PEI/PciCfg.c
@@ -0,0 +1,491 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PeiMain/PciCfg.c 12 8/12/11 12:24p Artems $
+//
+// $Revision: 12 $
+//
+// $Date: 8/12/11 12:24p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PeiMain/PciCfg.c $
+//
+// 12 8/12/11 12:24p Artems
+// EIP 64107: Added changes for module to be compliant with PI
+// specification v 1.2
+//
+// 11 3/22/11 5:15p Felixp
+// Method of invocation of the in-memory entry point has changed
+// from LOAD_HOB to eLink registered under PeiCoreMemoryInstalled.
+// This is more efficient.
+//
+// 10 2/05/11 3:44p Artems
+// Changed functions calling interfaces to meet PI 1.0 specification
+// requirements
+//
+// 9 11/05/09 5:01p Oleksiyy
+// EIP 27821 Support for 64 bit operations in PciRead and PciWrite added.
+// To use this functions CpuIo.c, IA32CLib.c, x64AsmLib.asm files should
+// be updated also.
+//
+// 8 7/08/09 5:53p Vyacheslava
+// Updated according to the coding standards.
+//
+// 7 6/16/05 10:56a Felixp
+// 1. Once memory is available, PEI Core PEIMs that created PEIM_LOAD_HOB
+// are reallocated to memory.
+// 2. ImagePei.c removed
+// 3. FileLoader moved from DxeIpl to PEI Core
+//
+// 6 6/06/05 7:49p Felixp
+//
+// 5 6/06/05 1:25p Felixp
+//
+// 4 6/03/05 3:45p Felixp
+// Updated to support changes introduced in PEI CIS 0.91
+//
+// 3 3/04/05 9:43a Mandal
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 8 1/28/04 3:24a Felixp
+//
+// 7 1/27/04 3:58a Felixp
+// Bug fixes and improvements as a part of PEI CORE integration
+//
+// 6 12/29/03 5:25p Felixp
+// preffix 'EFI_' added to the names of the PEIM descriptor structures and
+// flags
+//
+// 5 12/15/03 4:35p Robert
+//
+// 4 12/15/03 4:25p Robert
+//
+// 3 12/15/03 12:41p Robert
+// changed position of GUID definition below PPI include
+//
+// 2 12/15/03 11:54a Robert
+// Updated the definitions of PPI includes and removed the entry point
+// definitions
+//
+// 1 12/11/03 5:34p Robert
+// Initial Check in
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PciCfg.c
+//
+// Description: This file contains the implementation of the PCI Cfg I/O
+// specification. For questions about the specification refer to the
+// PEI CIS specification chapter 9
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+// Module specific Includes
+#include <AmiPeiLib.h>
+// PPI Produced
+#include <PPI/PciCfg2.h>
+
+// Module specific macros
+// Make a PCI Access address out of the value that is passed in. Clear the lowest 2 bits
+// PCI accesses are always 4 byte aligned
+#define GET_PCI_ADDRESS(x) \
+(0x080000000 | (((UINTN)x & 0x0FF000000) >> 8) | (((UINTN)x & 0x0FF0000)>> 5) | (x & 0x0700) | (x & 0x0FC))
+
+// Function Prototypes
+EFI_STATUS PciRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS PciWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS PciModify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+#if PI_SPECIFICATION_VERSION<0x00010000
+ IN UINTN SetBits,
+ IN UINTN ClearBits
+#else
+ IN VOID *SetBits,
+ IN VOID *ClearBits
+#endif
+);
+
+
+// Local Definitions
+EFI_PEI_PCI_CFG2_PPI mPciCfgPpi = {
+ PciRead,
+ PciWrite,
+ PciModify
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPciCfg2PpiGuid,
+ &mPciCfgPpi
+ }
+};
+
+// Function Definitions
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciCfgMemInit
+//
+// Description: This function installs the PCI Configuration PPI and exits
+//
+// Input:
+// *FfsHeader - pointer to the header of the current firmware file system
+// **PeiServices - pointer to the Pei Services function and data structure
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI PciCfgMemInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ // update PCI Config pointer
+ (*PeiServices)->PciCfg = &mPciCfgPpi;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciCfgInit
+//
+// Description: This function installs the PCI Configuration PPI and exits
+//
+// Input:
+// *FfsHeader - pointer to the header of the current firmware file system
+// **PeiServices - pointer to the Pei Services function and data structure
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI PciCfgInit (
+ IN EFI_PEI_FILE_HANDLE FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+
+ // Install the PCI Config Ppi
+ (*PeiServices)->PciCfg = &mPciCfgPpi;
+ Status = (*PeiServices)->InstallPpi( PeiServices, mPpiList );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciRead
+//
+// Description: This function Reads a value from the PCI Config space and
+// returns that value in Buffer.
+//
+// Input:
+// **PeiServices - Pointer to the PEI Core data Structure
+// *This - Pointer to the instance of the PCI Config PPI
+// Width - Size of the data to be read from the configuration space
+// Address - PCI address of the register to be read(Bus/Dev/Func/Reg)
+// *Buffer - The data read from the requested PCI Configuration register
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS PciRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+)
+{
+ UINT64 IoAddr;
+ UINT32 PciAddr;
+ EFI_PEI_CPU_IO_PPI *CpuIo = (*PeiServices)->CpuIo;
+ EFI_PEI_PCI_CFG_PPI_WIDTH TmpWidth;
+ UINT8 *Buffer8=(UINT8*)Buffer;
+
+ if (((Width & 3) == EfiPeiPciCfgWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiPeiPciCfgWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+ // Make a usable PCI address out of the Address passed in
+ PciAddr = (UINT32)GET_PCI_ADDRESS(Address);
+
+ // Access 0xCF8 and use corrected address to enable the read to PCI
+ IoAddr = 0x0CF8;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+
+ // Access 0xCFC to get the data requested. Increment IoAddr to
+ // read the correct register from the PCI Config space
+ IoAddr = 0x0CFC + (Address & 0x03);
+
+ TmpWidth=Width;
+
+ if ((Width & 3) > EfiPeiPciCfgWidthUint32)TmpWidth=Width-1;
+ // Read the register requested. Use the passed in Width value to
+ // indicate the number of bytes to read. If Width = 8 bytes - split into two reads
+ CpuIo->Io.Read(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)Buffer8
+ );
+ // no formatting should be needed on the output data. Read the correct
+ // register and the correct width should format the data properly
+
+ if (Width == TmpWidth) return EFI_SUCCESS;
+
+ IoAddr = 0x0CF8;
+ PciAddr = PciAddr + 4;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+ // Read the next 4 bytes
+ IoAddr = 0x0CFC;
+ CpuIo->Io.Read(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)(Buffer8+4)
+ );
+
+
+
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciWrite
+//
+// Description: This function writes a value to the PCI Config space
+//
+// Input:
+// **PeiServices - Pointer to the PEI Core data Structure
+// *This - Pointer to the instance of the PCI Config PPI
+// Width - Size of the data to write to the configuration space
+// Address - PCI address of the register to write to (Bus/Dev/Func/Reg)
+// *Buffer - The data to write to the requested PCI Configuration register
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS PciWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+)
+{
+ UINT64 IoAddr;
+ UINT32 PciAddr;
+ EFI_PEI_CPU_IO_PPI *CpuIo = (*PeiServices)->CpuIo;
+ EFI_PEI_PCI_CFG_PPI_WIDTH TmpWidth;
+ UINT8 *Buffer8=(UINT8*)Buffer;
+ if (((Width & 3) == EfiPeiPciCfgWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiPeiPciCfgWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ // Make a usable PCI address out of the Address passed in
+ PciAddr = (UINT32)GET_PCI_ADDRESS(Address);
+
+ // Access 0xCF8 and use corrected address to enable the read to PCI
+ IoAddr = 0x0CF8;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+
+ // Access 0xCFC to get the data requested. Increment IoAddr to
+ // read the correct register from the PCI Config space
+ IoAddr = 0x0CFC + (Address & 0x03);
+
+ TmpWidth=Width;
+
+ if ((Width & 3) > EfiPeiPciCfgWidthUint32) TmpWidth = Width - 1;
+ // Write the register requested. Use the passed in Width value to
+ // indicate the number of bytes to read. If Width = 8 bytes - split into two writes
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)Buffer8
+ );
+
+
+ if (Width == TmpWidth) return EFI_SUCCESS;
+
+ // Access 0xCF8 and use next 4 bytes address to enable the read to PCI
+ IoAddr = 0x0CF8;
+ PciAddr = PciAddr + 4;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+
+ // Write the next 4 bytes
+ IoAddr = 0x0CFC;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)(Buffer8+4)
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciModify
+//
+// Description: This function modifies a value in the PCI Config space.
+// This function uses the SetBits and ClearBits values to modify the
+// register. First the ClearBits value is used to clear the unwanted bits
+// then the SetBits value is used to set the wanted bits.
+//
+// Input:
+// **PeiServices - Pointer to the PEI Core data Structure
+// *This - Pointer to the instance of the PCI Config PPI
+// Width - Size of the data to write to the configuration space
+// Address - PCI address of the register to write to (Bus/Dev/Func/Reg)
+// SetBits - The bits in the register that need to be set
+// ClearBits - The bits in the register that should be cleared
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS PciModify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+#if PI_SPECIFICATION_VERSION<0x00010000
+ IN UINTN SetBits,
+ IN UINTN ClearBits
+#else
+ IN VOID *SetBits,
+ IN VOID *ClearBits
+#endif
+)
+{
+ EFI_STATUS Status;
+ UINTN Data;
+ if (((Width & 3) == EfiPeiPciCfgWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiPeiPciCfgWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ Status = PciRead (
+ PeiServices,
+ This,
+ Width,
+ Address,
+ &Data
+ );
+#if PI_SPECIFICATION_VERSION<0x00010000
+ Data = SetBits | (Data & (~ClearBits));
+#else
+ Data = *(UINTN*)SetBits | (Data & (~*(UINTN*)ClearBits));
+#endif
+ Status = PciWrite (
+ PeiServices,
+ This,
+ Width,
+ Address,
+ &Data
+ );
+
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CORE_PEI/PeiPerf.c b/Core/CORE_PEI/PeiPerf.c
new file mode 100644
index 0000000..4922163
--- /dev/null
+++ b/Core/CORE_PEI/PeiPerf.c
@@ -0,0 +1,30 @@
+/*++
+
+Copyright (c) 2004 - 2005, 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:
+
+ Perf.c
+
+Abstract:
+
+ Support for performance primitives.
+
+--*/
+#include <AmiLib.h>
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ )
+{
+ *TimerValue = GetCpuTimer();
+ return EFI_SUCCESS;
+}