--- /dev/null
+/** @file\r
+ Locate the entry point for the PEI Core\r
+\r
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+\r
+#include "SecMain.h"\r
+\r
+/**\r
+ Find core image base.\r
+ \r
+ @param BootFirmwareVolumePtr Point to the boot firmware volume.\r
+ @param SecCoreImageBase The base address of the SEC core image.\r
+ @param PeiCoreImageBase The base address of the PEI core image.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FindImageBase (\r
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,\r
+ OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase,\r
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS CurrentAddress;\r
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;\r
+ EFI_FFS_FILE_HEADER *File;\r
+ UINT32 Size;\r
+ EFI_PHYSICAL_ADDRESS EndOfFile;\r
+ EFI_COMMON_SECTION_HEADER *Section;\r
+ EFI_PHYSICAL_ADDRESS EndOfSection;\r
+\r
+ *SecCoreImageBase = 0;\r
+ *PeiCoreImageBase = 0;\r
+\r
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;\r
+ EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;\r
+\r
+ //\r
+ // Loop through the FFS files in the Boot Firmware Volume\r
+ //\r
+ for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {\r
+\r
+ CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;\r
+ if (CurrentAddress > EndOfFirmwareVolume) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;\r
+ if (IS_FFS_FILE2 (File)) {\r
+ Size = FFS_FILE2_SIZE (File);\r
+ if (Size <= 0x00FFFFFF) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else {\r
+ Size = FFS_FILE_SIZE (File);\r
+ if (Size < sizeof (EFI_FFS_FILE_HEADER)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ EndOfFile = CurrentAddress + Size;\r
+ if (EndOfFile > EndOfFirmwareVolume) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Look for SEC Core / PEI Core files\r
+ //\r
+ if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
+ File->Type != EFI_FV_FILETYPE_PEI_CORE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Loop through the FFS file sections within the FFS file\r
+ //\r
+ if (IS_FFS_FILE2 (File)) {\r
+ EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2));\r
+ } else {\r
+ EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER));\r
+ }\r
+ for (;;) {\r
+ CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;\r
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;\r
+\r
+ if (IS_SECTION2 (Section)) {\r
+ Size = SECTION2_SIZE (Section);\r
+ if (Size <= 0x00FFFFFF) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else {\r
+ Size = SECTION_SIZE (Section);\r
+ if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ EndOfSection = CurrentAddress + Size;\r
+ if (EndOfSection > EndOfFile) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Look for executable sections\r
+ //\r
+ if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {\r
+ if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {\r
+ if (IS_SECTION2 (Section)) {\r
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));\r
+ } else {\r
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
+ }\r
+ } else {\r
+ if (IS_SECTION2 (Section)) {\r
+ *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));\r
+ } else {\r
+ *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Both SEC Core and PEI Core images found\r
+ //\r
+ if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Find and return Pei Core entry point.\r
+\r
+ It also find SEC and PEI Core file debug inforamtion. It will report them if\r
+ remote debug is enabled.\r
+ \r
+ @param BootFirmwareVolumePtr Point to the boot firmware volume.\r
+ @param PeiCoreEntryPoint The entry point of the PEI core.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FindAndReportEntryPoints (\r
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,\r
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS SecCoreImageBase;\r
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+\r
+ //\r
+ // Find SEC Core and PEI Core image base\r
+ //\r
+ Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));\r
+ //\r
+ // Report SEC Core debug information when remote debug is enabled\r
+ //\r
+ ImageContext.ImageAddress = SecCoreImageBase;\r
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);\r
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
+\r
+ //\r
+ // Report PEI Core debug information when remote debug is enabled\r
+ //\r
+ ImageContext.ImageAddress = PeiCoreImageBase;\r
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);\r
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
+\r
+ //\r
+ // Find PEI Core entry point\r
+ //\r
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);\r
+ if (EFI_ERROR (Status)) {\r
+ *PeiCoreEntryPoint = 0;\r
+ }\r
+\r
+ return;\r
+}\r
+\r