Enable PeiCore to dispatch the encapsulated fv images with depex expression. This...
authorlgao4 <lgao4@de2fecce-e211-0410-80a6-f3fac2684e05>
Thu, 6 Dec 2007 09:52:27 +0000 (09:52 +0000)
committerlgao4 <lgao4@de2fecce-e211-0410-80a6-f3fac2684e05>
Thu, 6 Dec 2007 09:52:27 +0000 (09:52 +0000)
git-svn-id: https://edk2.tianocore.org/svn/edk2/trunk@4366 de2fecce-e211-0410-80a6-f3fac2684e05

edk2/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
edk2/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
edk2/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
edk2/MdeModulePkg/Core/Pei/FwVol/FwVol.c
edk2/MdeModulePkg/Core/Pei/Image/Image.c
edk2/MdeModulePkg/Core/Pei/PeiMain.h
edk2/MdeModulePkg/Core/Pei/PeiMain.inf

index e82cf38..bd7e905 100644 (file)
@@ -54,7 +54,6 @@ Abstract:
 #include <Library/PeCoffLib.h>\r
 #include <Library/S3Lib.h>\r
 #include <Library/RecoveryLib.h>\r
-#include <Library/PeiPiLib.h>\r
 \r
 #define STACK_SIZE      0x20000\r
 #define BSP_STORE_SIZE  0x4000\r
@@ -73,16 +72,7 @@ PeiLoadFile (
 ;\r
 \r
 EFI_STATUS\r
-DxeIplAddEncapsulatedFirmwareVolumes (\r
-  VOID\r
-  )\r
-;\r
-\r
-EFI_STATUS\r
-DxeIplFindFirmwareVolumeInstance (\r
-  IN OUT UINTN              *Instance,\r
-  IN  EFI_FV_FILETYPE       SeachType,\r
-  OUT EFI_PEI_FV_HANDLE     *VolumeHandle,\r
+DxeIplFindDxeCore (\r
   OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
   )\r
 ;\r
index 898e67e..b9b4b32 100644 (file)
   DebugLib\r
   S3Lib\r
   RecoveryLib\r
-  PeiPiLib\r
-\r
-[Protocols]\r
-  gEfiCustomizedDecompressProtocolGuid          # PROTOCOL SOMETIMES_PRODUCED\r
-  gEfiTianoDecompressProtocolGuid               # PROTOCOL SOMETIMES_PRODUCED\r
-  gEfiDecompressProtocolGuid                    # PROTOCOL SOMETIMES_PRODUCED\r
-\r
+  PerformanceLib\r
 \r
 [Ppis]\r
   gEfiPeiSecurityPpiGuid                        # PPI SOMETIMES_CONSUMED\r
index b7caded..65d0e86 100644 (file)
@@ -135,11 +135,11 @@ PeimInitializeDxeIpl (
   }\r
   \r
   //\r
-  // Install FvFileLoader and DxeIpl PPIs.\r
+  // Install DxeIpl and Decompress PPIs.\r
   //\r
   Status = PeiServicesInstallPpi (mPpiList);\r
-  ASSERT_EFI_ERROR(Status);  \r
-       \r
+  ASSERT_EFI_ERROR(Status);\r
+\r
   return Status;\r
 }\r
 \r
@@ -167,9 +167,7 @@ DxeLoadCore (
   UINT64                                    DxeCoreSize;\r
   EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;\r
   EFI_BOOT_MODE                             BootMode;\r
-  EFI_PEI_FV_HANDLE                         VolumeHandle;\r
   EFI_PEI_FILE_HANDLE                       FileHandle;\r
-  UINTN                                     Instance;\r
   EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;\r
   UINTN                                     DataSize;\r
   EFI_MEMORY_TYPE_INFORMATION               MemoryData [EfiMaxMemoryType + 1];\r
@@ -194,7 +192,7 @@ DxeLoadCore (
     // Now should have a HOB with the DXE core w/ the old HOB destroyed\r
     //\r
   }\r
-  \r
+\r
   Status = PeiServicesLocatePpi (\r
              &gEfiPeiReadOnlyVariable2PpiGuid,\r
              0,\r
@@ -223,16 +221,12 @@ DxeLoadCore (
       DataSize\r
       );\r
   }\r
-  //\r
-  // If any FV contains an encapsulated FV extract that FV\r
-  //\r
-  DxeIplAddEncapsulatedFirmwareVolumes ();\r
-  \r
+\r
   //\r
   // Look in all the FVs present in PEI and find the DXE Core\r
   //\r
-  Instance = 0;\r
-  Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
+  FileHandle = NULL;\r
+  Status = DxeIplFindDxeCore (&FileHandle);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));\r
@@ -297,171 +291,38 @@ DxeLoadCore (
   return EFI_OUT_OF_RESOURCES;\r
 }\r
 \r
-\r
-STATIC\r
-EFI_STATUS\r
-GetFvAlignment (\r
-  IN    EFI_FIRMWARE_VOLUME_HEADER   *FvHeader,\r
-  OUT   UINT32                      *FvAlignment\r
-  )\r
-{\r
-  //\r
-  // Because FvLength in FvHeader is UINT64 type, \r
-  // so FvHeader must meed at least 8 bytes alignment.\r
-  // Get the appropriate alignment requirement.\r
-  // \r
-  if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  \r
-   *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
-   return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-   Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand \r
-   as memory FV \r
-    \r
-   @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV\r
-   @return EFI_SUCESS           Sucess to find the FV \r
-**/\r
-EFI_STATUS\r
-DxeIplAddEncapsulatedFirmwareVolumes (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  EFI_STATUS                  VolumeStatus;\r
-  UINTN                       Index;\r
-  EFI_FV_INFO                 VolumeInfo; \r
-  EFI_PEI_FV_HANDLE           VolumeHandle;\r
-  EFI_PEI_FILE_HANDLE         FileHandle;\r
-  UINT32                      SectionLength;\r
-  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;\r
-  EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;\r
-  VOID                        *DstBuffer;\r
-  UINT32                       FvAlignment;\r
-\r
-  Status = EFI_NOT_FOUND;\r
-  Index  = 0;\r
-\r
-  do {\r
-    VolumeStatus = DxeIplFindFirmwareVolumeInstance (\r
-                    &Index, \r
-                    EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
-                    &VolumeHandle, \r
-                    &FileHandle\r
-                    );\r
-                    \r
-    if (!EFI_ERROR (VolumeStatus)) {\r
-         Status = PeiServicesFfsFindSectionData (\r
-                    EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \r
-                    (EFI_FFS_FILE_HEADER *)FileHandle, \r
-                    (VOID **)&FvHeader\r
-                    );\r
-                    \r
-      if (!EFI_ERROR (Status)) {\r
-        if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
-          //\r
-          // Because FvLength in FvHeader is UINT64 type, \r
-          // so FvHeader must meed at least 8 bytes alignment.\r
-          // If current FvImage base address doesn't meet its alignment,\r
-          // we need to reload this FvImage to another correct memory address.\r
-          //\r
-          Status = GetFvAlignment(FvHeader, &FvAlignment); \r
-          if (EFI_ERROR(Status)) {\r
-            return Status;\r
-          }\r
-          if (((UINTN) FvHeader % FvAlignment) != 0) {\r
-            SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
-            SectionLength =  *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;\r
-            \r
-            DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);\r
-            if (DstBuffer == NULL) {\r
-              return EFI_OUT_OF_RESOURCES;\r
-            }\r
-            CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
-            FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;  \r
-          }\r
-\r
-          //\r
-          // This new Firmware Volume comes from a firmware file within a firmware volume.\r
-          // Record the original Firmware Volume Name.\r
-          //\r
-          PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);\r
-\r
-          PiLibInstallFvInfoPpi (\r
-            NULL,\r
-            FvHeader,\r
-            (UINT32) FvHeader->FvLength,\r
-            &(VolumeInfo.FvName),\r
-            &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name)\r
-            );\r
-\r
-          //\r
-          // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
-          //\r
-          BuildFvHob (\r
-            (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-            FvHeader->FvLength\r
-          );\r
-            \r
-          ASSERT_EFI_ERROR (Status);\r
-\r
-          //\r
-          // Makes the encapsulated volume show up in DXE phase to skip processing of\r
-          // encapsulated file again.\r
-          //\r
-          BuildFv2Hob (\r
-            (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
-            FvHeader->FvLength, \r
-            &VolumeInfo.FvName,\r
-            &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
-            );\r
-          return Status;\r
-        }\r
-      }\r
-    }\r
-  } while (!EFI_ERROR (VolumeStatus));\r
-  \r
-  return Status;\r
-}\r
-\r
 /**\r
-   Find the First Volume that contains the first FileType.\r
+   Find DxeCore driver from all First Volumes.\r
 \r
-   @param Instance      The Fv instance.\r
-   @param SeachType     The type of file to search.\r
-   @param VolumeHandle  Pointer to Fv which contains the file to search. \r
    @param FileHandle    Pointer to FFS file to search.\r
    \r
    @return EFI_SUCESS   Success to find the FFS in specificed FV\r
    @return others       Fail to find the FFS in specificed FV\r
  */\r
 EFI_STATUS\r
-DxeIplFindFirmwareVolumeInstance (\r
-  IN OUT UINTN              *Instance,\r
-  IN  EFI_FV_FILETYPE       SeachType,\r
-  OUT EFI_PEI_FV_HANDLE     *VolumeHandle,\r
+DxeIplFindDxeCore (\r
   OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  EFI_STATUS  VolumeStatus;\r
+  EFI_STATUS        Status;\r
+  EFI_STATUS        FileStatus;\r
+  UINTN             Instance;\r
+  EFI_PEI_FV_HANDLE VolumeHandle;\r
+  \r
+  Instance    = 0;\r
+  *FileHandle = NULL;\r
 \r
   do {\r
-    VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);\r
-    if (!EFI_ERROR (VolumeStatus)) {\r
-      *FileHandle = NULL;\r
-      Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);\r
-      if (!EFI_ERROR (Status)) {\r
-        return Status;\r
+    Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);\r
+    if (!EFI_ERROR (Status)) {\r
+      FileStatus = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, FileHandle);\r
+      if (!EFI_ERROR (FileStatus)) {\r
+        return FileStatus;\r
       }\r
     }\r
-    *Instance += 1;\r
-  } while (!EFI_ERROR (VolumeStatus));\r
+  } while (!EFI_ERROR (Status));\r
 \r
-  return VolumeStatus;\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 /**\r
@@ -646,10 +507,16 @@ CustomGuidedSectionExtract (
     //\r
     // Allocate output buffer\r
     //\r
-    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));\r
+    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
     if (*OutputBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+    DEBUG ((EFI_D_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
+    //\r
+    // *OutputBuffer still is one section. Adjust *OutputBuffer offset, \r
+    // skip EFI section header to make section data at page alignment.\r
+    //\r
+    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
   }\r
   \r
   Status = ExtractGuidedSectionDecode (\r
@@ -728,13 +595,18 @@ Decompress (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
-    // Allocate destination buffer\r
+    // Allocate destination buffer, extra one page for adjustment \r
     //\r
-    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
     if (DstBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
+    // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
+    // to make section data at page alignment.\r
+    //\r
+    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+    //\r
     // Call decompress function\r
     //\r
     Status = UefiDecompress (\r
@@ -751,18 +623,21 @@ Decompress (
     }\r
     break;\r
 \r
-  // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
-\r
   case EFI_NOT_COMPRESSED:\r
     //\r
     // Allocate destination buffer\r
     //\r
     DstBufferSize = CompressionSection->UncompressedLength;\r
-    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
     if (DstBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
+    // Adjust DstBuffer offset, skip EFI section header\r
+    // to make section data at page alignment.\r
+    //\r
+    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+    //\r
     // stream is not actually compressed, just encapsulated.  So just copy it.\r
     //\r
     CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
index 164c2c8..5a140ed 100644 (file)
@@ -30,7 +30,6 @@ InvokePeiCore (
   VOID          *Context2\r
   );\r
 \r
-\r
 VOID\r
 DiscoverPeimsAndOrderWithApriori (\r
   IN  PEI_CORE_INSTANCE    *Private,\r
@@ -233,11 +232,13 @@ Returns:
   VOID                                *TopOfStack;\r
   PEI_CORE_PARAMETERS                 PeiCoreParameters;\r
   EFI_DEVICE_HANDLE_EXTENDED_DATA     ExtendedData;\r
+  EFI_FV_FILE_INFO                    FvFileInfo;\r
 \r
 \r
   PeiServices = &Private->PS;\r
   PeimEntryPoint = NULL;\r
   PeimFileHandle = NULL;\r
+  EntryPoint     = 0;\r
 \r
   if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
     //\r
@@ -327,16 +328,28 @@ Returns:
           if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {\r
             PeimNeedingDispatch = TRUE;\r
           } else {\r
-            Status = PeiLoadImage (\r
-                       PeiServices, \r
-                       PeimFileHandle,  \r
-                       &EntryPoint, \r
-                       &AuthenticationState\r
-                       );\r
+            Status = PeiFfsGetFileInfo (PeimFileHandle, &FvFileInfo);\r
+            ASSERT_EFI_ERROR (Status);\r
+            if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
+              //\r
+              // For Fv type file, Produce new FV PPI and FV hob\r
+              //\r
+              Status = ProcessFvFile (PeiServices, PeimFileHandle, &AuthenticationState);\r
+            } else {\r
+              //\r
+              // For PEIM driver, Load its entry point\r
+              //\r
+              Status = PeiLoadImage (\r
+                         PeiServices, \r
+                         PeimFileHandle,  \r
+                         &EntryPoint, \r
+                         &AuthenticationState\r
+                         );\r
+            }\r
+\r
             if ((Status == EFI_SUCCESS)) {\r
               //\r
-              // The PEIM has its dependencies satisfied, and its entry point\r
-              // has been found, so invoke it.\r
+              // The PEIM has its dependencies satisfied, and is processed.\r
               //\r
               PERF_START (0, "PEIM", NULL, 0);\r
 \r
@@ -355,12 +368,17 @@ Returns:
                 // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED\r
                 //\r
                 Private->Fv[FvCount].PeimState[PeimCount]++;\r
-\r
+                \r
+                if (FvFileInfo.FileType != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
+                  //\r
+                  // Call the PEIM entry point for PEIM driver\r
+                  //\r
+                  PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
+                  PeimEntryPoint (PeimFileHandle, PeiServices);\r
+                }\r
                 //\r
-                // Call the PEIM entry point\r
+                // One module has been dispatched.\r
                 //\r
-                PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
-                PeimEntryPoint (PeimFileHandle, PeiServices);\r
                 PeimDispatchOnThisPass = TRUE;\r
               }\r
 \r
@@ -572,8 +590,8 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS  Status;\r
-  VOID        *DepexData;\r
+  EFI_STATUS           Status;\r
+  VOID                 *DepexData;\r
 \r
   if (PeimCount < Private->AprioriCount) {\r
     //\r
@@ -581,8 +599,16 @@ Returns:
     //\r
     return TRUE;\r
   }\r
+  \r
+  //\r
+  // Depex section not in the encapsulated section. \r
+  //\r
+  Status = PeiServicesFfsFindSectionData (\r
+              EFI_SECTION_PEI_DEPEX,\r
+              FileHandle, \r
+              (VOID **)&DepexData\r
+              );\r
 \r
-  Status = PeiServicesFfsFindSectionData (EFI_SECTION_PEI_DEPEX, FileHandle, (VOID **) &DepexData);\r
   if (EFI_ERROR (Status)) {\r
     //\r
     // If there is no DEPEX, assume the module can be executed\r
@@ -675,3 +701,119 @@ InvokePeiCore (
   ASSERT (FALSE);\r
   CpuDeadLoop ();\r
 }\r
+\r
+/**\r
+  Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.\r
+\r
+       @param PeiServices          Pointer to the PEI Core Services Table.\r
+       @param FileHandle               File handle of a Fv type file.\r
+  @param AuthenticationState  Pointer to attestation authentication state of image.\r
+\r
+  \r
+  @retval EFI_NOT_FOUND                                FV image can't be found.\r
+  @retval EFI_SUCCESS                                          Successfully to process it.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessFvFile (\r
+  IN  EFI_PEI_SERVICES      **PeiServices,\r
+  IN  EFI_PEI_FILE_HANDLE   FvFileHandle,\r
+  OUT UINT32                *AuthenticationState\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PEI_FV_HANDLE     FvImageHandle;\r
+  EFI_FV_INFO           FvImageInfo;\r
+  UINT32                FvAlignment;\r
+  VOID                  *FvBuffer;\r
+  EFI_PEI_HOB_POINTERS  HobFv2;\r
+  \r
+  FvBuffer             = NULL;\r
+  *AuthenticationState = 0;\r
+\r
+  //\r
+  // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already \r
+  // been extracted.\r
+  //\r
+  HobFv2.Raw = GetHobList ();\r
+  while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {\r
+    if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {\r
+      //\r
+      // this FILE has been dispatched, it will not be dispatched again.\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+    HobFv2.Raw = GET_NEXT_HOB (HobFv2);\r
+  }\r
+  \r
+  //\r
+  // Find FvImage in FvFile\r
+  //\r
+  Status = PeiFfsFindSectionData (\r
+             (CONST EFI_PEI_SERVICES **) PeiServices,\r
+             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+             FvFileHandle,\r
+             (VOID **)&FvImageHandle\r
+             );\r
+  \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Collect FvImage Info.\r
+  //\r
+  Status = PeiFfsGetVolumeInfo (FvImageHandle, &FvImageInfo);\r
+  ASSERT_EFI_ERROR (Status);\r
+  //\r
+  // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
+  //\r
+  FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+  if (FvAlignment < 8) {\r
+    FvAlignment = 8;\r
+  }\r
+  // \r
+  // Check FvImage\r
+  //\r
+  if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) {\r
+    FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvImageInfo.FvSize), FvAlignment);\r
+    if (FvBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN) FvImageInfo.FvSize);\r
+    //\r
+    // Update FvImageInfo after reload FvImage to new aligned memory\r
+    //\r
+    PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo);\r
+  }\r
+  \r
+  //\r
+  // Install FvPpi and Build FvHob\r
+  //\r
+  PiLibInstallFvInfoPpi (\r
+    NULL,\r
+    FvImageInfo.FvStart,\r
+    (UINT32) FvImageInfo.FvSize,\r
+    &(FvImageInfo.FvName),\r
+    &(((EFI_FFS_FILE_HEADER*)FvFileHandle)->Name)\r
+    );\r
+\r
+  //\r
+  // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
+  //\r
+  BuildFvHob (\r
+    (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,\r
+    FvImageInfo.FvSize\r
+  );\r
+  //\r
+  // Makes the encapsulated volume show up in DXE phase to skip processing of\r
+  // encapsulated file again.\r
+  //\r
+  BuildFv2Hob (\r
+    (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,\r
+    FvImageInfo.FvSize,\r
+    &FvImageInfo.FvName,\r
+    &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)\r
+    );\r
+    \r
+  return EFI_SUCCESS;\r
+}\r
index 57b45d0..621fb16 100644 (file)
@@ -258,7 +258,8 @@ Returns:
         }\r
       } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r
         if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
-            (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { \r
+            (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||\r
+            (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { \r
           \r
           *FileHeader = FfsFileHeader;\r
           return EFI_SUCCESS;\r
@@ -366,8 +367,15 @@ Returns:
   UINT8                                 FvCount;\r
   EFI_PEI_FIRMWARE_VOLUME_INFO_PPI      *Fv;\r
   PEI_CORE_INSTANCE                     *PrivateData;\r
+  EFI_PEI_FILE_HANDLE                   FileHandle;\r
+  VOID                                  *DepexData;\r
+  UINT32                                AuthenticationStatus;\r
+  EFI_STATUS                            Status;\r
   \r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+  FileHandle   = NULL;\r
+  DepexData    = NULL;\r
+  Status       = EFI_SUCCESS;\r
+  PrivateData  = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
 \r
   if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
     ASSERT (FALSE);\r
@@ -375,19 +383,53 @@ Returns:
 \r
   Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;\r
 \r
-   if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {\r
-     for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {\r
-       if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {\r
-         return EFI_SUCCESS;\r
-       }\r
-     }\r
+  if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {\r
+    for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {\r
+      if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
     PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;\r
-  }\r
 \r
-  //\r
-  // Allways add to the All list\r
-  //\r
-  PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;\r
+    //\r
+    // Only add FileSystem2 Fv to the All list\r
+    //\r
+    PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;\r
+    \r
+    DEBUG ((EFI_D_INFO, "The %dth FvImage start address is 0x%10p and size is 0x%08x\n", PrivateData->AllFvCount, (VOID *) Fv->FvInfo, Fv->FvInfoSize));\r
+    //\r
+    // Preprocess all FV type files in this new FileSystem2 Fv image\r
+    //\r
+    do {\r
+      Status = PeiFindFileEx (\r
+                 (EFI_PEI_FV_HANDLE)Fv->FvInfo, \r
+                 NULL, \r
+                 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
+                 &FileHandle, \r
+                 NULL\r
+                 );\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = PeiFfsFindSectionData (\r
+                    (CONST EFI_PEI_SERVICES **) PeiServices,\r
+                    EFI_SECTION_PEI_DEPEX,\r
+                    FileHandle, \r
+                    (VOID **)&DepexData\r
+                    );\r
+        if (!EFI_ERROR (Status)) {\r
+          if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
+            //\r
+            // Dependency is not satisfied.\r
+            //\r
+            continue;\r
+          }\r
+        }\r
+        //\r
+        // Process FvFile to install FvInfo ppi and build FvHob\r
+        // \r
+        ProcessFvFile (PeiServices, FileHandle, &AuthenticationStatus);\r
+      }\r
+    } while (FileHandle != NULL);\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -398,25 +440,21 @@ PeiFfsProcessSection (
   IN EFI_SECTION_TYPE           SectionType,\r
   IN EFI_COMMON_SECTION_HEADER  *Section,\r
   IN UINTN                      SectionSize,\r
-  OUT VOID                      **OutputBuffer,\r
-  OUT UINTN                     *OutputSize,\r
-  OUT UINT32                    *Authentication\r
+  OUT VOID                      **OutputBuffer\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
   Go through the file to search SectionType section,\r
-  when meeting an encapsuled section, search recursively\r
+  when meeting an encapsuled section. \r
   \r
 Arguments:\r
-  PeiServices  - Pointer to the PEI Core Services Table.\r
+  PeiServices  - General purpose services available to every PEIM.\r
   SearchType   - Filter to find only section of this type.\r
   Section      - From where to search.\r
   SectionSize  - The file size to search.\r
   OutputBuffer - Pointer to the section to search.\r
-  OutputSize   - The size of the section to search.\r
-  Authentication -  Authenticate the section.\r
 \r
 Returns:\r
   EFI_STATUS\r
@@ -426,58 +464,95 @@ Returns:
   EFI_STATUS                              Status;\r
   UINT32                                  SectionLength;\r
   UINT32                                  ParsedLength;\r
-  EFI_GUID_DEFINED_SECTION                *GuidSection; \r
   EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI   *GuidSectionPpi;\r
-  EFI_COMPRESSION_SECTION                 *CompressionSection;\r
   EFI_PEI_DECOMPRESS_PPI                  *DecompressPpi;\r
   VOID                                    *PpiOutput;\r
   UINTN                                   PpiOutputSize;\r
+  UINTN                                   Index;\r
+  UINT32                                  Authentication;\r
+  PEI_CORE_INSTANCE                       *PrivateData;\r
 \r
+  PrivateData   = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
   *OutputBuffer = NULL;\r
-  ParsedLength = 0;\r
+  ParsedLength  = 0;\r
+  Index         = 0;\r
+  Status        = EFI_NOT_FOUND;\r
+  PpiOutput     = NULL;\r
+  PpiOutputSize = 0;\r
   while (ParsedLength < SectionSize) {\r
     if (Section->Type == SectionType) {\r
       *OutputBuffer = (VOID *)(Section + 1);\r
       return EFI_SUCCESS;\r
-    } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
-      GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;\r
-      Status = PeiServicesLocatePpi (&GuidSection->SectionDefinitionGuid, 0, NULL, (VOID **) &GuidSectionPpi);\r
-      if (!EFI_ERROR (Status)) {\r
-        Status = GuidSectionPpi->ExtractSection (\r
-                                  GuidSectionPpi,\r
-                                  Section,\r
-                                  &PpiOutput,\r
-                                  &PpiOutputSize,\r
-                                  Authentication\r
-                                  );\r
-        if (!EFI_ERROR (Status)) {\r
+    } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {\r
+      //\r
+      // Check the encapsulated section is extracted into the cache data.\r
+      //\r
+      for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {\r
+        if (Section == PrivateData->CacheSection.Section[Index]) {\r
+          PpiOutput     = PrivateData->CacheSection.SectionData[Index];\r
+          PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];\r
+          //\r
+          // Search section directly from the cache data.\r
+          //\r
           return PeiFfsProcessSection (\r
                   PeiServices,\r
                   SectionType, \r
                   PpiOutput, \r
                   PpiOutputSize, \r
-                  OutputBuffer, \r
-                  OutputSize, \r
-                  Authentication\r
+                  OutputBuffer \r
                   );\r
         }\r
       }\r
-    } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
-      CompressionSection = (EFI_COMPRESSION_SECTION *)Section;\r
-      Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
-      if (!EFI_ERROR (Status)) {\r
-        Status = DecompressPpi->Decompress (\r
-                                  DecompressPpi,\r
-                                  CompressionSection,\r
-                                  &PpiOutput,\r
-                                  &PpiOutputSize\r
-                                  );\r
+      \r
+      Status = EFI_NOT_FOUND;\r
+      if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
+        Status = PeiServicesLocatePpi (\r
+                   &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid, \r
+                   0, \r
+                   NULL, \r
+                   (VOID **) &GuidSectionPpi\r
+                   );\r
         if (!EFI_ERROR (Status)) {\r
-          return PeiFfsProcessSection (\r
-                  PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication\r
-                  );\r
+          Status = GuidSectionPpi->ExtractSection (\r
+                                    GuidSectionPpi,\r
+                                    Section,\r
+                                    &PpiOutput,\r
+                                    &PpiOutputSize,\r
+                                    &Authentication\r
+                                    );\r
+        }\r
+      } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
+        Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
+        if (!EFI_ERROR (Status)) {\r
+          Status = DecompressPpi->Decompress (\r
+                                    DecompressPpi,\r
+                                    (CONST EFI_COMPRESSION_SECTION*) Section,\r
+                                    &PpiOutput,\r
+                                    &PpiOutputSize\r
+                                    );\r
         }\r
       }\r
+      \r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Update cache section data.\r
+        //\r
+        if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {\r
+          PrivateData->CacheSection.AllSectionCount ++;\r
+        }\r
+        PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex]     = Section;\r
+        PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;\r
+        PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;\r
+        PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;\r
+        \r
+        return PeiFfsProcessSection (\r
+                PeiServices,\r
+                SectionType, \r
+                PpiOutput, \r
+                PpiOutputSize, \r
+                OutputBuffer \r
+                );\r
+      }\r
     }\r
 \r
     //\r
@@ -526,9 +601,6 @@ Returns:
   EFI_FFS_FILE_HEADER                     *FfsFileHeader;\r
   UINT32                                  FileSize;\r
   EFI_COMMON_SECTION_HEADER               *Section;\r
-  UINTN                                   OutputSize;\r
-  UINT32                                  AuthenticationStatus;\r
-\r
 \r
   FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);\r
 \r
@@ -542,13 +614,11 @@ Returns:
   FileSize -= sizeof (EFI_FFS_FILE_HEADER);\r
 \r
   return PeiFfsProcessSection (\r
-          PeiServices, \r
+          PeiServices,\r
           SectionType, \r
           Section, \r
           FileSize, \r
-          SectionData, \r
-          &OutputSize, \r
-          &AuthenticationStatus\r
+          SectionData\r
           );\r
 }\r
 \r
@@ -601,7 +671,7 @@ PeiFvFindNextVolume (
 \r
 Routine Description:\r
 \r
-  Return the BFV location\r
+  Return the firmware volumes.\r
 \r
   BugBug -- Move this to the location of this code to where the\r
   other FV and FFS support code lives.\r
@@ -761,21 +831,32 @@ Returns:
   \r
 --*/    \r
 {\r
-  EFI_FIRMWARE_VOLUME_HEADER             *FwVolHeader;\r
+  EFI_FIRMWARE_VOLUME_HEADER             FwVolHeader;\r
   EFI_FIRMWARE_VOLUME_EXT_HEADER         *FwVolExHeaderInfo;\r
 \r
   if (VolumeInfo == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+  \r
+  //\r
+  // VolumeHandle may not align at 8 byte, \r
+  // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. \r
+  // So, Copy FvHeader into the local FvHeader structure.\r
+  //\r
+  CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
+  //\r
+  // Check Fv Image Signature\r
+  //\r
+  if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  VolumeInfo->FvAttributes = FwVolHeader.Attributes;\r
+  VolumeInfo->FvStart = (VOID *) VolumeHandle;\r
+  VolumeInfo->FvSize = FwVolHeader.FvLength;\r
+  CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));\r
 \r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(VolumeHandle);\r
-  VolumeInfo->FvAttributes = FwVolHeader->Attributes;\r
-  VolumeInfo->FvStart = FwVolHeader;\r
-  VolumeInfo->FvSize = FwVolHeader->FvLength;\r
-  CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));\r
-\r
-  if (FwVolHeader->ExtHeaderOffset != 0) {\r
-    FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);\r
+  if (FwVolHeader.ExtHeaderOffset != 0) {\r
+    FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);\r
     CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));\r
   }\r
   return EFI_SUCCESS;\r
index 0c627c1..2c7e584 100644 (file)
@@ -241,7 +241,7 @@ Returns:
   // When Image has no reloc section, it can't be relocated into memory.\r
   //\r
   if (ImageContext.RelocationsStripped) {\r
-    DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory", (UINTN) Pe32Data));\r
+    DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   //\r
index 61641b3..84d187e 100644 (file)
@@ -53,6 +53,7 @@ Revision History
 #include <IndustryStandard/PeImage.h>\r
 #include <Library/PeiServicesTablePointerLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
+#include <Library/PeiPiLib.h>\r
 #include <Guid/FirmwareFileSystem2.h>\r
 #include <Guid/AprioriFileName.h>\r
 \r
@@ -98,6 +99,15 @@ typedef struct {
   BOOLEAN                             ScanFv;\r
 } PEI_CORE_FV_HANDLE;\r
 \r
+#define CACHE_SETION_MAX_NUMBER       0x10\r
+typedef struct {\r
+  EFI_COMMON_SECTION_HEADER*          Section[CACHE_SETION_MAX_NUMBER];\r
+  VOID*                               SectionData[CACHE_SETION_MAX_NUMBER];\r
+  UINTN                               SectionSize[CACHE_SETION_MAX_NUMBER];\r
+  UINTN                               AllSectionCount;\r
+  UINTN                               SectionIndex;\r
+} CACHE_SECTION_DATA;\r
+\r
 //\r
 // Pei Core private data structure instance\r
 //\r
@@ -130,6 +140,7 @@ typedef struct{
   UINTN                              SizeOfCacheAsRam;\r
   VOID                               *MaxTopOfCarHeap;\r
   EFI_PEI_PPI_DESCRIPTOR             *XipLoadFile;\r
+  CACHE_SECTION_DATA                 CacheSection;\r
 } PEI_CORE_INSTANCE;\r
 \r
 //\r
@@ -1379,4 +1390,23 @@ Returns:
 --*/      \r
 ;\r
 \r
+/**\r
+  Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.\r
+\r
+       @param PeiServices          Pointer to the PEI Core Services Table.\r
+       @param FileHandle               File handle of a Fv type file.\r
+  @param AuthenticationState  Pointer to attestation authentication state of image.\r
+\r
+  \r
+  @retval EFI_NOT_FOUND                                FV image can't be found.\r
+  @retval EFI_SUCCESS                                          Successfully to process it.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessFvFile (\r
+  IN  EFI_PEI_SERVICES      **PeiServices,\r
+  IN  EFI_PEI_FILE_HANDLE   FvFileHandle,\r
+  OUT UINT32                *AuthenticationState\r
+  );\r
+\r
 #endif\r
index 360f027..0d58f95 100644 (file)
@@ -81,6 +81,7 @@
   MemoryAllocationLib\r
   CacheMaintenanceLib\r
   PeCoffLib\r
+  PeiPiLib\r
 \r
 [Guids]\r
   gPeiAprioriFileNameGuid\r
 \r
 [FeaturePcd.common]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst\r
-\r
-\r
-\r