FindPeiCore.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /** @file
  2. Locate the entry point for the PEI Core
  3. Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <PiPei.h>
  7. #include "SecMain.h"
  8. /**
  9. Find core image base.
  10. @param FirmwareVolumePtr Point to the firmware volume for finding core image.
  11. @param FileType The FileType for searching, either SecCore or PeiCore.
  12. @param CoreImageBase The base address of the core image.
  13. **/
  14. EFI_STATUS
  15. EFIAPI
  16. FindImageBase (
  17. IN EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumePtr,
  18. IN EFI_FV_FILETYPE FileType,
  19. OUT EFI_PHYSICAL_ADDRESS *CoreImageBase
  20. )
  21. {
  22. EFI_PHYSICAL_ADDRESS CurrentAddress;
  23. EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
  24. EFI_FFS_FILE_HEADER *File;
  25. UINT32 Size;
  26. EFI_PHYSICAL_ADDRESS EndOfFile;
  27. EFI_COMMON_SECTION_HEADER *Section;
  28. EFI_PHYSICAL_ADDRESS EndOfSection;
  29. *CoreImageBase = 0;
  30. CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)FirmwareVolumePtr;
  31. EndOfFirmwareVolume = CurrentAddress + FirmwareVolumePtr->FvLength;
  32. //
  33. // Loop through the FFS files in the Boot Firmware Volume
  34. //
  35. for (EndOfFile = CurrentAddress + FirmwareVolumePtr->HeaderLength; ; ) {
  36. CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
  37. if (CurrentAddress > EndOfFirmwareVolume) {
  38. return EFI_NOT_FOUND;
  39. }
  40. File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;
  41. if (IS_FFS_FILE2 (File)) {
  42. Size = FFS_FILE2_SIZE (File);
  43. if (Size <= 0x00FFFFFF) {
  44. return EFI_NOT_FOUND;
  45. }
  46. } else {
  47. Size = FFS_FILE_SIZE (File);
  48. if (Size < sizeof (EFI_FFS_FILE_HEADER)) {
  49. return EFI_NOT_FOUND;
  50. }
  51. }
  52. EndOfFile = CurrentAddress + Size;
  53. if (EndOfFile > EndOfFirmwareVolume) {
  54. return EFI_NOT_FOUND;
  55. }
  56. //
  57. // Look for particular Core file (either SEC Core or PEI Core)
  58. //
  59. if (File->Type != FileType) {
  60. continue;
  61. }
  62. //
  63. // Loop through the FFS file sections within the FFS file
  64. //
  65. if (IS_FFS_FILE2 (File)) {
  66. EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)((UINT8 *)File + sizeof (EFI_FFS_FILE_HEADER2));
  67. } else {
  68. EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)((UINT8 *)File + sizeof (EFI_FFS_FILE_HEADER));
  69. }
  70. for ( ; ;) {
  71. CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
  72. Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
  73. if (IS_SECTION2 (Section)) {
  74. Size = SECTION2_SIZE (Section);
  75. if (Size <= 0x00FFFFFF) {
  76. return EFI_NOT_FOUND;
  77. }
  78. } else {
  79. Size = SECTION_SIZE (Section);
  80. if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) {
  81. return EFI_NOT_FOUND;
  82. }
  83. }
  84. EndOfSection = CurrentAddress + Size;
  85. if (EndOfSection > EndOfFile) {
  86. return EFI_NOT_FOUND;
  87. }
  88. //
  89. // Look for executable sections
  90. //
  91. if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {
  92. if (File->Type == FileType) {
  93. if (IS_SECTION2 (Section)) {
  94. *CoreImageBase = (PHYSICAL_ADDRESS)(UINTN)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
  95. } else {
  96. *CoreImageBase = (PHYSICAL_ADDRESS)(UINTN)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
  97. }
  98. }
  99. break;
  100. }
  101. }
  102. //
  103. // Either SEC Core or PEI Core images found
  104. //
  105. if (*CoreImageBase != 0) {
  106. return EFI_SUCCESS;
  107. }
  108. }
  109. }
  110. /**
  111. Find and return Pei Core entry point.
  112. It also find SEC and PEI Core file debug information. It will report them if
  113. remote debug is enabled.
  114. @param SecCoreFirmwareVolumePtr Point to the firmware volume for finding SecCore.
  115. @param PeiCoreFirmwareVolumePtr Point to the firmware volume for finding PeiCore.
  116. @param PeiCoreEntryPoint The entry point of the PEI core.
  117. **/
  118. VOID
  119. EFIAPI
  120. FindAndReportEntryPoints (
  121. IN EFI_FIRMWARE_VOLUME_HEADER *SecCoreFirmwareVolumePtr,
  122. IN EFI_FIRMWARE_VOLUME_HEADER *PeiCoreFirmwareVolumePtr,
  123. OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
  124. )
  125. {
  126. EFI_STATUS Status;
  127. EFI_PHYSICAL_ADDRESS SecCoreImageBase;
  128. EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
  129. PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
  130. //
  131. // Find SEC Core image base
  132. //
  133. Status = FindImageBase (SecCoreFirmwareVolumePtr, EFI_FV_FILETYPE_SECURITY_CORE, &SecCoreImageBase);
  134. ASSERT_EFI_ERROR (Status);
  135. ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
  136. //
  137. // Report SEC Core debug information when remote debug is enabled
  138. //
  139. ImageContext.ImageAddress = SecCoreImageBase;
  140. ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
  141. PeCoffLoaderRelocateImageExtraAction (&ImageContext);
  142. //
  143. // Find PEI Core image base
  144. //
  145. Status = FindImageBase (PeiCoreFirmwareVolumePtr, EFI_FV_FILETYPE_PEI_CORE, &PeiCoreImageBase);
  146. ASSERT_EFI_ERROR (Status);
  147. //
  148. // Report PEI Core debug information when remote debug is enabled
  149. //
  150. ImageContext.ImageAddress = PeiCoreImageBase;
  151. ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
  152. PeCoffLoaderRelocateImageExtraAction (&ImageContext);
  153. //
  154. // Find PEI Core entry point
  155. //
  156. Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint);
  157. if (EFI_ERROR (Status)) {
  158. *PeiCoreEntryPoint = 0;
  159. }
  160. return;
  161. }