Enhance DxeIpl module to support EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE ffs type,...
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 31 Oct 2006 08:22:25 +0000 (08:22 +0000)
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 31 Oct 2006 08:22:25 +0000 (08:22 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1875 6f19259b-4bc3-4df7-8a09-765794883524

EdkModulePkg/Core/DxeIplX64Peim/DxeIpl.h
EdkModulePkg/Core/DxeIplX64Peim/DxeLoadX64.c

index 53ee7e2..5068cb6 100644 (file)
@@ -103,7 +103,7 @@ DxeLoadCore (
 EFI_STATUS\r
 PeiProcessFile (\r
   IN      UINT16                 SectionType,\r
-  IN OUT  EFI_FFS_FILE_HEADER    **RealFfsFileHeader,\r
+  IN      EFI_FFS_FILE_HEADER    *FfsFileHeader,\r
   OUT     VOID                   **Pe32Data,\r
   IN      EFI_PEI_HOB_POINTERS   *OrigHob\r
   );\r
index 33ca3bb..c7d6dd7 100644 (file)
@@ -207,7 +207,9 @@ Returns:
   EFI_PHYSICAL_ADDRESS                                      BaseOfStack;\r
   EFI_PHYSICAL_ADDRESS                                      BspStore;\r
   EFI_GUID                                                  DxeCoreFileName;\r
+  EFI_GUID                                                  FirmwareFileName;\r
   VOID                                                      *DxeCorePe32Data;\r
+  VOID                                                      *FvImageData;     \r
   EFI_PHYSICAL_ADDRESS                                      DxeCoreAddress;\r
   UINT64                                                    DxeCoreSize;\r
   EFI_PHYSICAL_ADDRESS                                      DxeCoreEntryPoint;\r
@@ -288,6 +290,18 @@ Returns:
     }\r
   }\r
 \r
+  //\r
+  // Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file\r
+  // The file found will be processed by PeiProcessFile: It will first be decompressed to\r
+  // a normal FV, then a corresponding FV type hob will be built. \r
+  //\r
+  Status = PeiFindFile (\r
+            EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
+            EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+            &FirmwareFileName,\r
+            &FvImageData\r
+            );\r
+\r
   //\r
   // Find the DXE Core in a Firmware Volume\r
   //\r
@@ -418,10 +432,11 @@ Returns:
   FwVolHeader   = NULL;\r
   FfsFileHeader = NULL;\r
   SectionData   = NULL;\r
+  Status        = EFI_SUCCESS;\r
 \r
   //\r
-  // Foreach Firmware Volume, look for a specified type\r
-  // of file and break out when one is found\r
+  // For each Firmware Volume, look for a specified type\r
+  // of file and break out until no one is found \r
   //\r
   Hob.Raw = GetHobList ();\r
   while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {\r
@@ -434,12 +449,14 @@ Returns:
     if (!EFI_ERROR (Status)) {\r
       Status = PeiProcessFile (\r
                  SectionType,\r
-                 &FfsFileHeader,\r
+                 FfsFileHeader,\r
                  Pe32Data,\r
                  &Hob\r
                  );\r
       CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));\r
-      return Status;\r
+      if (!EFI_ERROR (Status)) {\r
+        return EFI_SUCCESS;\r
+      }\r
     }\r
     Hob.Raw = GET_NEXT_HOB (Hob);\r
   }\r
@@ -650,7 +667,7 @@ Returns:
   //\r
   Status = PeiProcessFile (\r
             EFI_SECTION_PE32,\r
-            &FfsHeader,\r
+            FfsHeader,\r
             &Pe32Data,\r
             NULL\r
             );\r
@@ -676,7 +693,7 @@ Returns:
 EFI_STATUS\r
 PeiProcessFile (\r
   IN      UINT16                 SectionType,\r
-  IN OUT  EFI_FFS_FILE_HEADER    **RealFfsFileHeader,\r
+  IN      EFI_FFS_FILE_HEADER    *FfsFileHeader,\r
   OUT     VOID                   **Pe32Data,\r
   IN      EFI_PEI_HOB_POINTERS   *OrigHob\r
   )\r
@@ -726,9 +743,7 @@ Returns:
   EFI_GUID                        TempGuid;\r
   EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;\r
   EFI_COMPRESSION_SECTION         *CompressionSection;\r
-  EFI_FFS_FILE_HEADER             *FfsFileHeader;\r
-  \r
-  FfsFileHeader = *RealFfsFileHeader;\r
+  UINT32                          FvAlignment;\r
 \r
   Status = PeiServicesFfsFindSectionData (\r
              EFI_SECTION_COMPRESSION,\r
@@ -737,7 +752,7 @@ Returns:
              );\r
 \r
   //\r
-  // Upon finding a DXE Core file, see if there is first a compression section\r
+  // First process the compression section\r
   //\r
   if (!EFI_ERROR (Status)) {\r
     //\r
@@ -913,37 +928,64 @@ Returns:
                     );\r
 \r
         CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
-        if (CmpSection->Type == EFI_SECTION_RAW) {\r
+        if (CmpSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+          // \r
+          // Firmware Volume Image in this Section\r
+          // Skip the section header to get FvHeader\r
           //\r
-          // Skip the section header and\r
-          // adjust the pointer alignment to 16\r
-          //\r
-          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);\r
-\r
-          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
-            FfsFileHeader = NULL;\r
-            BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
-            Status = PeiServicesFfsFindNextFile (\r
-                       EFI_FV_FILETYPE_DXE_CORE,\r
-                       FvHeader,\r
-                       &FfsFileHeader\r
-                       );\r
+          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
 \r
-            if (EFI_ERROR (Status)) {\r
-              return EFI_NOT_FOUND;\r
+          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {            \r
+            //\r
+            // Adjust Fv Base Address Alignment based on Align Attributes in Fv Header\r
+            //\r
+            \r
+            //\r
+            // When FvImage support Alignment, we need to check whether \r
+            // its alignment is correct. \r
+            //\r
+            if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) {\r
+              \r
+              //\r
+              // Calculate the mini alignment for this FvImage\r
+              //\r
+              FvAlignment = 1 << (LowBitSet32 (FvHeader->Attributes >> 16) + 1);\r
+              \r
+              //\r
+              // If current FvImage base address doesn't meet the its alignment,\r
+              // we need to reload this FvImage to another correct memory address.\r
+              //\r
+              if (((UINTN) FvHeader % FvAlignment) != 0) {\r
+                DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), FvAlignment);\r
+                if (DstBuffer == NULL) {\r
+                  return EFI_OUT_OF_RESOURCES;\r
+                }\r
+                CopyMem (DstBuffer, FvHeader, (UINTN) FvHeader->FvLength);\r
+                FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;  \r
+              }\r
             }\r
-\r
+            //\r
+            // Build new FvHob for new decompressed Fv image.\r
+            //\r
+            BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
+            \r
+            //\r
+            // Set the original FvHob to unused.\r
+            //\r
             if (OrigHob != NULL) {\r
-              //\r
-              // \r
               OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
             }\r
             \r
             //\r
-            // Reture the FfsHeader that contain Pe32Data.\r
+            // when search FvImage Section return true.\r
             //\r
-            *RealFfsFileHeader = FfsFileHeader;\r
-            return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data, OrigHob);\r
+            if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+              *Pe32Data = (VOID *) FvHeader;\r
+              return EFI_SUCCESS;\r
+            } else {\r
+              return EFI_NOT_FOUND;\r
+            }\r
+\r
           }\r
         }\r
         //\r
@@ -966,6 +1008,9 @@ Returns:
           CmpSection                = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);\r
         } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);\r
       }\r
+      //\r
+      // End of the decompression activity\r
+      //\r
 \r
       Section   = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
       FileSize  = FfsFileHeader->Size[0] & 0xFF;\r
@@ -973,11 +1018,17 @@ Returns:
       FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;\r
       FileSize &= 0x00FFFFFF;\r
     } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);\r
-\r
+    \r
     //\r
-    // End of the decompression activity\r
+    // search all sections (compression and non compression) in this FFS, don't \r
+    // find expected section.\r
     //\r
+    return EFI_NOT_FOUND;\r
   } else {\r
+    //\r
+    // For those FFS that doesn't contain compression section, directly search \r
+    // PE or TE section in this FFS.\r
+    //\r
 \r
     Status = PeiServicesFfsFindSectionData (\r
                EFI_SECTION_PE32,\r