FwVol.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /** @file
  2. Firmware volume helper interfaces.
  3. Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
  4. Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "StandaloneMmCore.h"
  8. #include <Library/FvLib.h>
  9. #include <Library/ExtractGuidedSectionLib.h>
  10. //
  11. // List of file types supported by dispatcher
  12. //
  13. EFI_FV_FILETYPE mMmFileTypes[] = {
  14. EFI_FV_FILETYPE_MM,
  15. 0xE, // EFI_FV_FILETYPE_MM_STANDALONE,
  16. //
  17. // Note: DXE core will process the FV image file, so skip it in MM core
  18. // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
  19. //
  20. };
  21. EFI_STATUS
  22. MmAddToDriverList (
  23. IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
  24. IN VOID *Pe32Data,
  25. IN UINTN Pe32DataSize,
  26. IN VOID *Depex,
  27. IN UINTN DepexSize,
  28. IN EFI_GUID *DriverName
  29. );
  30. BOOLEAN
  31. FvHasBeenProcessed (
  32. IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
  33. );
  34. VOID
  35. FvIsBeingProcessed (
  36. IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
  37. );
  38. /**
  39. Given the pointer to the Firmware Volume Header find the
  40. MM driver and return its PE32 image.
  41. @param [in] FwVolHeader Pointer to memory mapped FV
  42. @retval EFI_SUCCESS Success.
  43. @retval EFI_INVALID_PARAMETER Invalid parameter.
  44. @retval EFI_NOT_FOUND Could not find section data.
  45. @retval EFI_OUT_OF_RESOURCES Out of resources.
  46. @retval EFI_VOLUME_CORRUPTED Firmware volume is corrupted.
  47. @retval EFI_UNSUPPORTED Operation not supported.
  48. **/
  49. EFI_STATUS
  50. MmCoreFfsFindMmDriver (
  51. IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
  52. )
  53. {
  54. EFI_STATUS Status;
  55. EFI_STATUS DepexStatus;
  56. EFI_FFS_FILE_HEADER *FileHeader;
  57. EFI_FV_FILETYPE FileType;
  58. VOID *Pe32Data;
  59. UINTN Pe32DataSize;
  60. VOID *Depex;
  61. UINTN DepexSize;
  62. UINTN Index;
  63. EFI_COMMON_SECTION_HEADER *Section;
  64. VOID *SectionData;
  65. UINTN SectionDataSize;
  66. UINT32 DstBufferSize;
  67. VOID *ScratchBuffer;
  68. UINT32 ScratchBufferSize;
  69. VOID *DstBuffer;
  70. UINT16 SectionAttribute;
  71. UINT32 AuthenticationStatus;
  72. EFI_FIRMWARE_VOLUME_HEADER *InnerFvHeader;
  73. DEBUG ((DEBUG_INFO, "MmCoreFfsFindMmDriver - 0x%x\n", FwVolHeader));
  74. if (FvHasBeenProcessed (FwVolHeader)) {
  75. return EFI_SUCCESS;
  76. }
  77. FvIsBeingProcessed (FwVolHeader);
  78. //
  79. // First check for encapsulated compressed firmware volumes
  80. //
  81. FileHeader = NULL;
  82. do {
  83. Status = FfsFindNextFile (
  84. EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
  85. FwVolHeader,
  86. &FileHeader
  87. );
  88. if (EFI_ERROR (Status)) {
  89. break;
  90. }
  91. Status = FfsFindSectionData (
  92. EFI_SECTION_GUID_DEFINED,
  93. FileHeader,
  94. &SectionData,
  95. &SectionDataSize
  96. );
  97. if (EFI_ERROR (Status)) {
  98. break;
  99. }
  100. Section = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1);
  101. Status = ExtractGuidedSectionGetInfo (
  102. Section,
  103. &DstBufferSize,
  104. &ScratchBufferSize,
  105. &SectionAttribute
  106. );
  107. if (EFI_ERROR (Status)) {
  108. break;
  109. }
  110. //
  111. // Allocate scratch buffer
  112. //
  113. ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
  114. if (ScratchBuffer == NULL) {
  115. return EFI_OUT_OF_RESOURCES;
  116. }
  117. //
  118. // Allocate destination buffer, extra one page for adjustment
  119. //
  120. DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
  121. if (DstBuffer == NULL) {
  122. return EFI_OUT_OF_RESOURCES;
  123. }
  124. //
  125. // Call decompress function
  126. //
  127. Status = ExtractGuidedSectionDecode (
  128. Section,
  129. &DstBuffer,
  130. ScratchBuffer,
  131. &AuthenticationStatus
  132. );
  133. FreePages (ScratchBuffer, EFI_SIZE_TO_PAGES (ScratchBufferSize));
  134. if (EFI_ERROR (Status)) {
  135. goto FreeDstBuffer;
  136. }
  137. DEBUG ((
  138. DEBUG_INFO,
  139. "Processing compressed firmware volume (AuthenticationStatus == %x)\n",
  140. AuthenticationStatus
  141. ));
  142. Status = FindFfsSectionInSections (
  143. DstBuffer,
  144. DstBufferSize,
  145. EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
  146. &Section
  147. );
  148. if (EFI_ERROR (Status)) {
  149. goto FreeDstBuffer;
  150. }
  151. InnerFvHeader = (VOID *)(Section + 1);
  152. Status = MmCoreFfsFindMmDriver (InnerFvHeader);
  153. if (EFI_ERROR (Status)) {
  154. goto FreeDstBuffer;
  155. }
  156. } while (TRUE);
  157. for (Index = 0; Index < sizeof (mMmFileTypes) / sizeof (mMmFileTypes[0]); Index++) {
  158. DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", mMmFileTypes[Index]));
  159. FileType = mMmFileTypes[Index];
  160. FileHeader = NULL;
  161. do {
  162. Status = FfsFindNextFile (FileType, FwVolHeader, &FileHeader);
  163. if (!EFI_ERROR (Status)) {
  164. Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize);
  165. DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data));
  166. DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize);
  167. if (!EFI_ERROR (DepexStatus)) {
  168. MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name);
  169. }
  170. }
  171. } while (!EFI_ERROR (Status));
  172. }
  173. return EFI_SUCCESS;
  174. FreeDstBuffer:
  175. FreePages (DstBuffer, EFI_SIZE_TO_PAGES (DstBufferSize));
  176. return Status;
  177. }