]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFv/GenFvInternalLib.c
Sync EDKII BaseTools to BaseTools project r2006.
[mirror_edk2.git] / BaseTools / Source / C / GenFv / GenFvInternalLib.c
index ad3e7a6e080ccf2022f6be12f7d2e09fcc0b44e8..189dc431ebda71baf86514f0b87541003f00822b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
+Copyright (c) 2004 - 2010, 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
@@ -159,6 +159,9 @@ UINT8                                   m64kRecoveryStartupApDataArray[SIZEOF_ST
 FV_INFO                     mFvDataInfo;\r
 CAP_INFO                    mCapDataInfo;\r
 \r
+EFI_PHYSICAL_ADDRESS mFvBaseAddress[0x10];\r
+UINT32               mFvBaseAddressNumber = 0;\r
+\r
 EFI_STATUS\r
 ParseFvInf (\r
   IN  MEMORY_FILE  *InfFile,\r
@@ -184,7 +187,8 @@ Returns:
 {\r
   CHAR8       Value[_MAX_PATH];\r
   UINT64      Value64;\r
-  UINTN       Index, Number, Index1;\r
+  UINTN       Index;\r
+  UINTN       Number;\r
   EFI_STATUS  Status;\r
   EFI_GUID    GuidValue;\r
 \r
@@ -228,22 +232,11 @@ Returns:
   }\r
 \r
   //\r
-  // Read the FV Name Guid\r
+  // Read the FV Extension Header File Name\r
   //\r
-  if (!FvInfo->FvNameGuidSet) {\r
-    Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FV_NAMEGUID_STRING, 0, Value);\r
-    if (Status == EFI_SUCCESS) {\r
-      //\r
-      // Get the guid value\r
-      //\r
-      Status = StringToGuid (Value, &GuidValue);\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_NAMEGUID_STRING, Value);\r
-        return EFI_ABORTED;\r
-      }\r
-      memcpy (&FvInfo->FvNameGuid, &GuidValue, sizeof (EFI_GUID));\r
-      FvInfo->FvNameGuidSet = TRUE;\r
-    }\r
+  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FV_EXT_HEADER_FILE_NAME, 0, Value);\r
+  if (Status == EFI_SUCCESS) {\r
+    strcpy (FvInfo->FvExtHeaderFile, Value);\r
   }\r
 \r
   //\r
@@ -371,7 +364,7 @@ Returns:
       // Add the file\r
       //\r
       strcpy (FvInfo->FvFiles[Number + Index], Value);\r
-      DebugMsg (NULL, 0, 9, "FV component file", "the %dth name is %s", Index, Value);\r
+      DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index, Value);\r
     } else {\r
       break;\r
     }\r
@@ -514,6 +507,7 @@ EFI_STATUS
 AddPadFile (\r
   IN OUT MEMORY_FILE  *FvImage,\r
   IN UINT32           DataAlignment,\r
+  IN VOID             *FvEnd,\r
   IN EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHeader\r
   )\r
 /*++\r
@@ -525,9 +519,10 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  FvImage         The memory image of the FV to add it to.  The current offset\r
-                  must be valid.\r
+  FvImage         The memory image of the FV to add it to.\r
+                  The current offset must be valid.\r
   DataAlignment   The data alignment of the next FFS file.\r
+  FvEnd           End of the empty data in FvImage.\r
   ExtHeader       PI FvExtHeader Optional \r
 \r
 Returns:\r
@@ -556,30 +551,6 @@ Returns:
     return EFI_SUCCESS;\r
   }\r
 \r
-  //\r
-  // Write pad file header\r
-  //\r
-  PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;\r
-\r
-  //\r
-  // Verify that we have enough space for the file header\r
-  //\r
-  if (ExtHeader != NULL) {\r
-    if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER) + ExtHeader->ExtHeaderSize) >= (UINTN) FvImage->Eof) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }    \r
-  } else {\r
-    if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-  }\r
-\r
-  //\r
-  // write PadFile FFS header with PadType, don't need to set PAD file guid in its header.\r
-  //\r
-  PadFile->Type       = EFI_FV_FILETYPE_FFS_PAD;\r
-  PadFile->Attributes = 0;\r
-\r
   //\r
   // Calculate the pad file size\r
   //\r
@@ -587,11 +558,7 @@ Returns:
   // This is the earliest possible valid offset (current plus pad file header\r
   // plus the next file header)\r
   //\r
-  if (ExtHeader != NULL) {\r
-    PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2) + ExtHeader->ExtHeaderSize;\r
-  } else {\r
-    PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2);\r
-  }\r
+  PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2);\r
 \r
   //\r
   // Add whatever it takes to get to the next aligned address\r
@@ -609,6 +576,31 @@ Returns:
   //\r
   PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage;\r
   \r
+  //\r
+  // Append extension header size\r
+  //\r
+  if (ExtHeader != NULL) {\r
+    PadFileSize = PadFileSize + ExtHeader->ExtHeaderSize;\r
+  }\r
+\r
+  //\r
+  // Verify that we have enough space for the file header\r
+  //\r
+  if (((UINTN) FvImage->CurrentFilePointer + PadFileSize) > (UINTN) FvEnd) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Write pad file header\r
+  //\r
+  PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;\r
+\r
+  //\r
+  // Write PadFile FFS header with PadType, don't need to set PAD file guid in its header.\r
+  //\r
+  PadFile->Type       = EFI_FV_FILETYPE_FFS_PAD;\r
+  PadFile->Attributes = 0;\r
+\r
   //\r
   // Write pad file size (calculated size minus next file header size)\r
   //\r
@@ -630,26 +622,26 @@ Returns:
     (EFI_FFS_FILE_HEADER *) PadFile,\r
     (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage\r
     );\r
-  \r
+\r
+  //\r
+  // Update the current FV pointer\r
+  //\r
+  FvImage->CurrentFilePointer += PadFileSize;\r
+\r
   if (ExtHeader != NULL) {\r
     //\r
     // Copy Fv Extension Header and Set Fv Extension header offset\r
     //\r
     memcpy (PadFile + 1, ExtHeader, ExtHeader->ExtHeaderSize);\r
     ((EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage)->ExtHeaderOffset = (UINT16) ((UINTN) (PadFile + 1) - (UINTN) FvImage->FileImage);\r
+         //\r
+         // Make next file start at QWord Boundry\r
+         //\r
+         while (((UINTN) FvImage->CurrentFilePointer & (EFI_FFS_FILE_HEADER_ALIGNMENT - 1)) != 0) {\r
+           FvImage->CurrentFilePointer++;\r
+         }\r
   }\r
 \r
-  //\r
-  // Verify that we have enough space (including the padding)\r
-  //\r
-  if (((UINTN)PadFile + PadFileSize) >= (UINTN) FvImage->Eof) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // Update the current FV pointer\r
-  //\r
-  FvImage->CurrentFilePointer += PadFileSize;\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -685,7 +677,7 @@ EFI_STATUS
 WriteMapFile (\r
   IN OUT FILE                  *FvMapFile,\r
   IN     CHAR8                 *FileName,\r
-  IN     EFI_GUID              *FileGuidPtr\r
+  IN     EFI_FFS_FILE_HEADER   *FfsFile\r
   IN     EFI_PHYSICAL_ADDRESS  ImageBaseAddress,\r
   IN     PE_COFF_LOADER_IMAGE_CONTEXT *pImageContext\r
   )\r
@@ -700,7 +692,7 @@ Arguments:
 \r
   FvMapFile             A pointer to FvMap File\r
   FileName              Ffs File PathName\r
-  FileGuidPtr           Guid Value of Ffs file\r
+  FfsFile               A pointer to Ffs file image.\r
   ImageBaseAddress      PeImage Base Address.\r
   pImageContext         Image Context Information.\r
 \r
@@ -726,7 +718,11 @@ Returns:
   EFI_IMAGE_OPTIONAL_HEADER_UNION     *ImgHdr;\r
   EFI_TE_IMAGE_HEADER                 *TEImageHeader;\r
   EFI_IMAGE_SECTION_HEADER            *SectionHeader;\r
-  \r
+  unsigned long long                  TempLongAddress;\r
+  UINT32                              TextVirtualAddress;\r
+  UINT32                              DataVirtualAddress;\r
+  EFI_PHYSICAL_ADDRESS                LinkTimeBaseAddress;\r
+\r
   //\r
   // Init local variable\r
   //\r
@@ -734,7 +730,7 @@ Returns:
   //\r
   // Print FileGuid to string buffer. \r
   //\r
-  PrintGuidToBuffer (FileGuidPtr, (UINT8 *)FileGuidName, MAX_LINE_LEN, TRUE);\r
+  PrintGuidToBuffer (&FfsFile->Name, (UINT8 *)FileGuidName, MAX_LINE_LEN, TRUE);\r
   \r
   //\r
   // Construct Map file Name \r
@@ -800,29 +796,44 @@ Returns:
     SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
     Index = TEImageHeader->NumberOfSections;\r
   }\r
-  \r
+\r
   //\r
   // module information output\r
   //\r
   if (ImageBaseAddress == 0) {\r
     fprintf (FvMapFile, "%s (dummy) (", KeyWord);\r
-    fprintf (FvMapFile, "BaseAddress=%08lx, ", ImageBaseAddress);\r
+    fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress);\r
   } else {\r
-    fprintf (FvMapFile, "%s (", KeyWord);\r
-    fprintf (FvMapFile, "BaseAddress=%08lx, ", ImageBaseAddress + Offset);\r
+    fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord);\r
+    fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset));\r
+  }\r
+\r
+  if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && pImageContext->Machine == EFI_IMAGE_MACHINE_IA64) {\r
+    //\r
+    // Process IPF PLABEL to get the real address after the image has been rebased. \r
+    // PLABEL structure is got by AddressOfEntryPoint offset to ImageBuffer stored in pImageContext->Handle.\r
+    //\r
+    fprintf (FvMapFile, "EntryPoint=0x%010llx", (unsigned long long) (*(UINT64 *)((UINTN) pImageContext->Handle + (UINTN) AddressOfEntryPoint)));\r
+  } else {\r
+    fprintf (FvMapFile, "EntryPoint=0x%010llx", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));\r
   }\r
-  fprintf (FvMapFile, "EntryPoint=%08lx, ", ImageBaseAddress + AddressOfEntryPoint);\r
-  fprintf (FvMapFile, "GUID=%s", FileGuidName);\r
   fprintf (FvMapFile, ")\n"); \r
   \r
+  fprintf (FvMapFile, "(GUID=%s", FileGuidName);\r
+  TextVirtualAddress = 0;\r
+  DataVirtualAddress = 0;\r
   for (; Index > 0; Index --, SectionHeader ++) {\r
-        if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {\r
-               fprintf (FvMapFile, ".textbaseaddress=%08lx ",ImageBaseAddress + SectionHeader->VirtualAddress);\r
+    if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {\r
+               TextVirtualAddress = SectionHeader->VirtualAddress;\r
        } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".data") == 0) {\r
-         fprintf (FvMapFile, ".databaseaddress=%08lx ",ImageBaseAddress + SectionHeader->VirtualAddress);\r
+         DataVirtualAddress = SectionHeader->VirtualAddress;\r
+       } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".sdata") == 0) {\r
+         DataVirtualAddress = SectionHeader->VirtualAddress;\r
        }\r
   }\r
-  fprintf (FvMapFile, "\n\n"); \r
+  fprintf (FvMapFile, " .textbaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + TextVirtualAddress));\r
+  fprintf (FvMapFile, " .databaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + DataVirtualAddress));\r
+  fprintf (FvMapFile, ")\n\n");\r
    \r
   //\r
   // Open PeMapFile\r
@@ -837,6 +848,7 @@ Returns:
   //\r
   // Output Functions information into Fv Map file\r
   //\r
+  LinkTimeBaseAddress = 0;\r
   while (fgets (Line, MAX_LINE_LEN, PeMapFile) != NULL) {\r
     //\r
     // Skip blank line\r
@@ -862,6 +874,9 @@ Returns:
         //\r
         FunctionType = 2;\r
         fgets (Line, MAX_LINE_LEN, PeMapFile);\r
+      } else if (stricmp (KeyWord, "Preferred") ==0) {\r
+        sscanf (Line + strlen (" Preferred load address is"), "%llx", &TempLongAddress);\r
+        LinkTimeBaseAddress = (UINT64) TempLongAddress;\r
       }\r
       continue;\r
     }\r
@@ -869,25 +884,17 @@ Returns:
     // Printf Function Information\r
     //\r
     if (FunctionType == 1) {\r
-      sscanf (Line, "%s %s %lx %s", KeyWord, FunctionName, &FunctionAddress, FunctionTypeName);\r
+      sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);\r
+      FunctionAddress = (UINT64) TempLongAddress;\r
       if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {\r
-        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
-        fprintf (FvMapFile, "(%08lx) F  ", FunctionAddress - Offset);\r
-        fprintf (FvMapFile, "%s\n", FunctionName);\r
-    } else {\r
-        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
-        fprintf (FvMapFile, "(%08lx)    ", FunctionAddress - Offset);\r
+        fprintf (FvMapFile, "  0x%010llx    ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));\r
         fprintf (FvMapFile, "%s\n", FunctionName);\r
       }\r
     } else if (FunctionType == 2) {\r
-      sscanf (Line, "%s %s %lx %s", KeyWord, FunctionName, &FunctionAddress, FunctionTypeName);\r
+      sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);\r
+      FunctionAddress = (UINT64) TempLongAddress;\r
       if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {\r
-        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
-        fprintf (FvMapFile, "(%08lx) FS ", FunctionAddress - Offset);\r
-        fprintf (FvMapFile, "%s\n", FunctionName);\r
-      } else {\r
-        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
-        fprintf (FvMapFile, "(%08lx)    ", FunctionAddress - Offset);\r
+        fprintf (FvMapFile, "  0x%010llx    ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));\r
         fprintf (FvMapFile, "%s\n", FunctionName);\r
       }\r
     }\r
@@ -907,7 +914,8 @@ AddFile (
   IN FV_INFO                  *FvInfo,\r
   IN UINTN                    Index,\r
   IN OUT EFI_FFS_FILE_HEADER  **VtfFileImage,\r
-  IN FILE                     *FvMapFile  \r
+  IN FILE                     *FvMapFile,\r
+  IN FILE                     *FvReportFile\r
   )\r
 /*++\r
 \r
@@ -925,6 +933,7 @@ Arguments:
   VtfFileImage  A pointer to the VTF file within the FvImage.  If this is equal\r
                 to the end of the FvImage then no VTF previously found.\r
   FvMapFile     Pointer to FvMap File\r
+  FvReportFile  Pointer to FvReport File\r
 \r
 Returns:\r
 \r
@@ -942,6 +951,7 @@ Returns:
   UINT32                CurrentFileAlignment;\r
   EFI_STATUS            Status;\r
   UINTN                 Index1;\r
+  UINT8                 FileGuidString[PRINTED_GUID_BUFFER_SIZE];\r
   \r
   Index1 = 0;\r
   //\r
@@ -1028,7 +1038,7 @@ Returns:
   //\r
   for (Index1 = 0; Index1 < Index; Index1 ++) {\r
     if (CompareGuid ((EFI_GUID *) FileBuffer, &mFileGuidArray [Index1]) == 0) {\r
-      Error (NULL, 0, 2000, "Invalid parameter", "the %dth file and %dth file have the same file GUID.", Index1 + 1, Index + 1);\r
+      Error (NULL, 0, 2000, "Invalid parameter", "the %dth file and %uth file have the same file GUID.", (unsigned) Index1 + 1, (unsigned) Index + 1);\r
       PrintGuid ((EFI_GUID *) FileBuffer);\r
       return EFI_INVALID_PARAMETER;\r
     }\r
@@ -1067,7 +1077,7 @@ Returns:
       // Sanity check. The file MUST align appropriately\r
       //\r
       if (((UINTN) *VtfFileImage + sizeof (EFI_FFS_FILE_HEADER) - (UINTN) FvImage->FileImage) % (1 << CurrentFileAlignment)) {\r
-        Error (NULL, 0, 3000, "Invalid", "VTF file cannot be aligned on a %d-byte boundary.", 1 << CurrentFileAlignment);\r
+        Error (NULL, 0, 3000, "Invalid", "VTF file cannot be aligned on a %u-byte boundary.", (unsigned) (1 << CurrentFileAlignment));\r
         free (FileBuffer);\r
         return EFI_ABORTED;\r
       }\r
@@ -1080,6 +1090,10 @@ Returns:
       // copy VTF File\r
       //\r
       memcpy (*VtfFileImage, FileBuffer, FileSize);\r
+      \r
+      PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE); \r
+      fprintf (FvReportFile, "0x%08X %s\n", (unsigned)(UINTN) (((UINT8 *)*VtfFileImage) - (UINTN)FvImage->FileImage), FileGuidString);\r
+\r
       free (FileBuffer);\r
       DebugMsg (NULL, 0, 9, "Add VTF FFS file in FV image", NULL);\r
       return EFI_SUCCESS;\r
@@ -1096,7 +1110,7 @@ Returns:
   //\r
   // Add pad file if necessary\r
   //\r
-  Status = AddPadFile (FvImage, 1 << CurrentFileAlignment, NULL);\r
+  Status = AddPadFile (FvImage, 1 << CurrentFileAlignment, *VtfFileImage, NULL);\r
   if (EFI_ERROR (Status)) {\r
     Error (NULL, 0, 4002, "Resource", "FV space is full, could not add pad file for data alignment property.");\r
     free (FileBuffer);\r
@@ -1105,7 +1119,7 @@ Returns:
   //\r
   // Add file\r
   //\r
-  if ((FvImage->CurrentFilePointer + FileSize) < FvImage->Eof) {\r
+  if ((UINTN) (FvImage->CurrentFilePointer + FileSize) <= (UINTN) (*VtfFileImage)) {\r
     //\r
     // Rebase the PE or TE image in FileBuffer of FFS file for XIP. \r
     // Rebase Bs and Rt drivers for the debug genfvmap tool.\r
@@ -1115,6 +1129,8 @@ Returns:
     // Copy the file\r
     //\r
     memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);\r
+    PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE); \r
+    fprintf (FvReportFile, "0x%08X %s\n", (unsigned) (FvImage->CurrentFilePointer - FvImage->FileImage), FileGuidString);\r
     FvImage->CurrentFilePointer += FileSize;\r
   } else {\r
     Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add file %s.", FvInfo->FvFiles[Index]);\r
@@ -1174,6 +1190,10 @@ Returns:
     return EFI_SUCCESS;\r
   }\r
 \r
+  if ((UINTN) VtfFileImage < (UINTN) FvImage->CurrentFilePointer) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   //\r
   // Pad file starts at beginning of free space\r
   //\r
@@ -1261,11 +1281,12 @@ Returns:
   UINT8                     *BytePointer2;\r
   UINT16                    *WordPointer;\r
   UINT16                    CheckSum;\r
+  UINT32                    IpiVector;\r
   UINTN                     Index;\r
   EFI_FFS_FILE_STATE        SavedState;\r
   UINT64                    FitAddress;\r
   FIT_TABLE                 *FitTablePtr;\r
-  UINT32                    IpiVector;\r
+  BOOLEAN                   Vtf0Detected;\r
 \r
   //\r
   // Verify input parameters\r
@@ -1286,11 +1307,32 @@ Returns:
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if (\r
+      (((UINTN)FvImage->Eof - (UINTN)FvImage->FileImage) >=\r
+        IA32_X64_VTF_SIGNATURE_OFFSET) &&\r
+      (*(UINT32 *)(VOID*)((UINTN) FvImage->Eof -\r
+                                  IA32_X64_VTF_SIGNATURE_OFFSET) ==\r
+        IA32_X64_VTF0_SIGNATURE)\r
+     ) {\r
+    Vtf0Detected = TRUE;\r
+  } else {\r
+    Vtf0Detected = FALSE;\r
+  }\r
+\r
   //\r
   // Find the Sec Core\r
   //\r
   Status = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &SecCoreFile);\r
   if (EFI_ERROR (Status) || SecCoreFile == NULL) {\r
+    if (Vtf0Detected) {\r
+      //\r
+      // If the SEC core file is not found, but the VTF-0 signature\r
+      // is found, we'll treat it as a VTF-0 'Volume Top File'.\r
+      // This means no modifications are required to the VTF.\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
     Error (NULL, 0, 3000, "Invalid", "could not find the SEC core file in the FV.");\r
     return EFI_ABORTED;\r
   }\r
@@ -1319,13 +1361,26 @@ Returns:
     return EFI_ABORTED;\r
   }  \r
 \r
+  if (\r
+       Vtf0Detected &&\r
+       (MachineType == EFI_IMAGE_MACHINE_IA32 ||\r
+        MachineType == EFI_IMAGE_MACHINE_X64)\r
+     ) {\r
+    //\r
+    // If the SEC core code is IA32 or X64 and the VTF-0 signature\r
+    // is found, we'll treat it as a VTF-0 'Volume Top File'.\r
+    // This means no modifications are required to the VTF.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   //\r
   // Physical address is FV base + offset of PE32 + offset of the entry point\r
   //\r
   SecCorePhysicalAddress = FvInfo->BaseAddress;\r
   SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;\r
   SecCorePhysicalAddress += EntryPoint;\r
-  DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%X", SecCorePhysicalAddress); \r
+  DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%llX", (unsigned long long) SecCorePhysicalAddress); \r
 \r
   //\r
   // Find the PEI Core\r
@@ -1365,7 +1420,7 @@ Returns:
   PeiCorePhysicalAddress = FvInfo->BaseAddress;\r
   PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;\r
   PeiCorePhysicalAddress += EntryPoint;\r
-  DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%X", PeiCorePhysicalAddress);\r
+  DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);\r
 \r
   if (MachineType == EFI_IMAGE_MACHINE_IA64) {\r
     //\r
@@ -1381,8 +1436,8 @@ Returns:
     //\r
     if (PeiCorePhysicalAddress & 0xF) {\r
       Error (NULL, 0, 3000, "Invalid",\r
-        "PEI_CORE entry point is not aligned on a 16 byte boundary, address specified is %Xh.",\r
-        PeiCorePhysicalAddress\r
+        "PEI_CORE entry point is not aligned on a 16 byte boundary, address specified is %llXh.",\r
+        (unsigned long long) PeiCorePhysicalAddress\r
         );\r
       return EFI_ABORTED;\r
     }\r
@@ -1411,8 +1466,8 @@ Returns:
     //\r
     if (SecCorePhysicalAddress & 0xF) {\r
       Error (NULL, 0, 3000, "Invalid",\r
-        "SALE_ENTRY entry point is not aligned on a 16 byte boundary, address specified is %Xh.",\r
-        SecCorePhysicalAddress\r
+        "SALE_ENTRY entry point is not aligned on a 16 byte boundary, address specified is %llXh.",\r
+        (unsigned long long) SecCorePhysicalAddress\r
         );\r
       return EFI_ABORTED;\r
     }\r
@@ -1422,16 +1477,6 @@ Returns:
     SecCoreEntryAddressPtr  = (EFI_PHYSICAL_ADDRESS *) ((UINTN) FvImage->Eof - IPF_SALE_ENTRY_ADDRESS_OFFSET);\r
     *SecCoreEntryAddressPtr = SecCorePhysicalAddress;\r
 \r
-  } else if (\r
-    (MachineType == EFI_IMAGE_MACHINE_IA32 ||\r
-     MachineType == EFI_IMAGE_MACHINE_X64) &&\r
-    (((UINTN)FvImage->Eof - (UINTN)FvImage->FileImage) >= IA32_X64_VTF_SIGNATURE_OFFSET) &&\r
-    (*(UINT32 *)(VOID*)((UINTN) FvImage->Eof - IA32_X64_VTF_SIGNATURE_OFFSET) ==\r
-      IA32_X64_VTF0_SIGNATURE)\r
-    ) {\r
-    //\r
-    // If VTF-0 signature is found, then no modifications are needed.\r
-    //\r
   } else if (MachineType == EFI_IMAGE_MACHINE_IA32 || MachineType == EFI_IMAGE_MACHINE_X64) {\r
     //\r
     // Get the location to update\r
@@ -1448,7 +1493,7 @@ Returns:
     // \r
     Ia32ResetAddressPtr  = (UINT32 *) ((UINTN) FvImage->Eof - IA32_SEC_CORE_ENTRY_OFFSET);\r
     \r
-    Ia32SecEntryOffset   = SecCorePhysicalAddress - (FV_IMAGES_TOP_ADDRESS - IA32_SEC_CORE_ENTRY_OFFSET + 2);\r
+    Ia32SecEntryOffset   = (INT32) (SecCorePhysicalAddress - (FV_IMAGES_TOP_ADDRESS - IA32_SEC_CORE_ENTRY_OFFSET + 2));\r
     if (Ia32SecEntryOffset <= -65536) {\r
       Error (NULL, 0, 3000, "Invalid", "The SEC EXE file size is too large, it must be less than 64K.");\r
       return STATUS_ERROR;\r
@@ -1461,7 +1506,7 @@ Returns:
     //\r
     Ia32ResetAddressPtr   = (UINT32 *) ((UINTN) FvImage->Eof - 4);\r
     *Ia32ResetAddressPtr  = (UINT32) (FvInfo->BaseAddress);\r
-    DebugMsg (NULL, 0, 9, "update BFV base address in the top FV image", "BFV base address = 0x%X.", FvInfo->BaseAddress);\r
+    DebugMsg (NULL, 0, 9, "update BFV base address in the top FV image", "BFV base address = 0x%llX.", (unsigned long long) FvInfo->BaseAddress);\r
 \r
     //\r
     // Update the Startup AP in the FVH header block ZeroVector region.\r
@@ -1507,9 +1552,9 @@ Returns:
     //\r
     // IpiVector at the 4k aligned address in the top 2 blocks in the PEI FV. \r
     //\r
-    IpiVector  = FV_IMAGES_TOP_ADDRESS - ((UINTN) FvImage->Eof - (UINTN) BytePointer);\r
-    DebugMsg (NULL, 0, 9, "Startup AP Vector address", "IpiVector at 0x%X", IpiVector);\r
-    if (IpiVector & 0xFFF != 0) {\r
+    IpiVector  = (UINT32) (FV_IMAGES_TOP_ADDRESS - ((UINTN) FvImage->Eof - (UINTN) BytePointer));\r
+    DebugMsg (NULL, 0, 9, "Startup AP Vector address", "IpiVector at 0x%X", (unsigned) IpiVector);\r
+    if ((IpiVector & 0xFFF) != 0) {\r
       Error (NULL, 0, 3000, "Invalid", "Startup AP Vector address are not 4K aligned, because the FV size is not 4K aligned");\r
       return EFI_ABORTED;\r
     }\r
@@ -1527,7 +1572,7 @@ Returns:
     // Volume Top File, but if you have one for some reason don't crash...\r
     //\r
   } else {\r
-    Error (NULL, 0, 3000, "Invalid", "machine type=0x%X in PEI core.", (UINT32) MachineType);\r
+    Error (NULL, 0, 3000, "Invalid", "machine type=0x%X in PEI core.", MachineType);\r
     return EFI_ABORTED;\r
   }\r
 \r
@@ -1539,8 +1584,8 @@ Returns:
   VtfFile->State                        = 0;\r
   if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
     VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
-                                              (UINT8 *) VtfFile,\r
-                                              GetLength (VtfFile->Size)\r
+                                              (UINT8 *) (VtfFile + 1),\r
+                                              GetLength (VtfFile->Size) - sizeof (EFI_FFS_FILE_HEADER)\r
                                               );\r
   } else {\r
     VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
@@ -1575,7 +1620,7 @@ Routine Description:
   FIQ              +24\r
 \r
   We support two schemes on ARM.\r
-  1) Begining of the FV is the reset vector\r
+  1) Beginning of the FV is the reset vector\r
   2) Reset vector is data bytes FDF file and that code branches to reset vector \r
     in the beginning of the FV (fixed size offset).\r
 \r
@@ -1671,7 +1716,7 @@ Returns:
       PeiCorePhysicalAddress = FvInfo->BaseAddress;\r
       PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;\r
       PeiCorePhysicalAddress += EntryPoint;\r
-      DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%X", PeiCorePhysicalAddress);\r
+      DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);\r
 \r
       if (MachineType == EFI_IMAGE_MACHINE_ARMT) {\r
         memset (ResetVector, 0, sizeof (ResetVector));\r
@@ -1726,7 +1771,7 @@ Returns:
   SecCorePhysicalAddress = FvInfo->BaseAddress;\r
   SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;\r
   SecCorePhysicalAddress += EntryPoint;\r
-  DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%X", SecCorePhysicalAddress); \r
+  DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%llX", (unsigned long long) SecCorePhysicalAddress); \r
 \r
   //\r
   // Find the PEI Core. It may not exist if SEC loads DXE core directly\r
@@ -1764,7 +1809,7 @@ Returns:
     PeiCorePhysicalAddress = FvInfo->BaseAddress;\r
     PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;\r
     PeiCorePhysicalAddress += EntryPoint;\r
-    DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%X", PeiCorePhysicalAddress);\r
+    DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);\r
   }\r
   \r
   \r
@@ -1778,7 +1823,7 @@ Returns:
   }\r
   \r
   // Add opcode for an uncondional branch with no link. AKA B SecEntryPoint\r
-  ResetVector[0] |= 0xEA000000;\r
+  ResetVector[0] |= 0xEB000000;\r
   \r
   \r
   // Address of PEI Core, if we have one\r
@@ -1880,7 +1925,7 @@ Returns:
     // Verify NT header is expected\r
     //\r
     if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
-      Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", ImgHdr->Pe32.Signature);\r
+      Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature);\r
       return EFI_UNSUPPORTED;\r
     }\r
     //\r
@@ -1932,23 +1977,28 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS                  Status;\r
-  MEMORY_FILE                 InfMemoryFile;\r
-  MEMORY_FILE                 FvImageMemoryFile;\r
-  UINTN                       Index;\r
-  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;\r
-  EFI_FFS_FILE_HEADER         *VtfFileImage;\r
-  UINT8                       *FvBufferHeader; // to make sure fvimage header 8 type alignment.\r
-  UINT8                       *FvImage;\r
-  UINTN                       FvImageSize;\r
-  FILE                        *FvFile;\r
-  CHAR8                       FvMapName [_MAX_PATH];\r
-  FILE                        *FvMapFile;\r
-  EFI_FIRMWARE_VOLUME_EXT_HEADER FvExtHeader;\r
+  EFI_STATUS                      Status;\r
+  MEMORY_FILE                     InfMemoryFile;\r
+  MEMORY_FILE                     FvImageMemoryFile;\r
+  UINTN                           Index;\r
+  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;\r
+  EFI_FFS_FILE_HEADER             *VtfFileImage;\r
+  UINT8                           *FvBufferHeader; // to make sure fvimage header 8 type alignment.\r
+  UINT8                           *FvImage;\r
+  UINTN                           FvImageSize;\r
+  FILE                            *FvFile;\r
+  CHAR8                           FvMapName [_MAX_PATH];\r
+  FILE                            *FvMapFile;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FvExtHeader;\r
+  FILE                            *FvExtHeaderFile;\r
+  UINTN                           FileSize;\r
+  CHAR8                           FvReportName[_MAX_PATH];\r
+  FILE                            *FvReportFile;\r
 \r
   FvBufferHeader = NULL;\r
   FvFile         = NULL;\r
   FvMapFile      = NULL;\r
+  FvReportFile   = NULL;\r
 \r
   if (InfFileImage != NULL) {\r
     //\r
@@ -1990,7 +2040,7 @@ Returns:
   //\r
   if (mFvDataInfo.FvFileSystemGuidSet) {\r
     DebugMsg (NULL, 0, 9, "FV File System Guid", "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
-                  mFvDataInfo.FvFileSystemGuid.Data1,\r
+                  (unsigned) mFvDataInfo.FvFileSystemGuid.Data1,\r
                   mFvDataInfo.FvFileSystemGuid.Data2,\r
                   mFvDataInfo.FvFileSystemGuid.Data3,\r
                   mFvDataInfo.FvFileSystemGuid.Data4[0],\r
@@ -2002,12 +2052,64 @@ Returns:
                   mFvDataInfo.FvFileSystemGuid.Data4[6],\r
                   mFvDataInfo.FvFileSystemGuid.Data4[7]);\r
   }\r
+\r
+  //\r
+  // Add PI FV extension header\r
+  //\r
+  FvExtHeader = NULL;\r
+  FvExtHeaderFile = NULL;\r
+  if (mFvDataInfo.FvExtHeaderFile[0] != 0) {\r
+    //\r
+    // Open the FV Extension Header file\r
+    //\r
+    FvExtHeaderFile = fopen (mFvDataInfo.FvExtHeaderFile, "rb");\r
+\r
+    //\r
+    // Get the file size\r
+    //\r
+    FileSize = _filelength (fileno (FvExtHeaderFile));\r
+\r
+    //\r
+    // Allocate a buffer for the FV Extension Header\r
+    //\r
+    FvExtHeader = malloc(FileSize);\r
+    if (FvExtHeader == NULL) {\r
+      fclose (FvExtHeaderFile);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    //\r
+    // Read the FV Extension Header\r
+    //\r
+    fread (FvExtHeader, sizeof (UINT8), FileSize, FvExtHeaderFile);\r
+    fclose (FvExtHeaderFile);\r
+\r
+    //\r
+    // See if there is an override for the FV Name GUID\r
+    //\r
+    if (mFvDataInfo.FvNameGuidSet) {\r
+      memcpy (&FvExtHeader->FvName, &mFvDataInfo.FvNameGuid, sizeof (EFI_GUID));\r
+    }\r
+    memcpy (&mFvDataInfo.FvNameGuid, &FvExtHeader->FvName, sizeof (EFI_GUID));\r
+    mFvDataInfo.FvNameGuidSet = TRUE;\r
+  } else if (mFvDataInfo.FvNameGuidSet) {\r
+    //\r
+    // Allocate a buffer for the FV Extension Header\r
+    //\r
+    FvExtHeader = malloc(sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER));\r
+    if (FvExtHeader == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    memcpy (&FvExtHeader->FvName, &mFvDataInfo.FvNameGuid, sizeof (EFI_GUID));\r
+    FvExtHeader->ExtHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);\r
+  }\r
+\r
   //\r
   // Debug message Fv Name Guid\r
   //\r
   if (mFvDataInfo.FvNameGuidSet) {\r
       DebugMsg (NULL, 0, 9, "FV Name Guid", "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
-                  mFvDataInfo.FvNameGuid.Data1,\r
+                  (unsigned) mFvDataInfo.FvNameGuid.Data1,\r
                   mFvDataInfo.FvNameGuid.Data2,\r
                   mFvDataInfo.FvNameGuid.Data3,\r
                   mFvDataInfo.FvNameGuid.Data4[0],\r
@@ -2035,6 +2137,12 @@ Returns:
   }\r
   VerboseMsg ("FV Map file name is %s", FvMapName);\r
 \r
+  //\r
+  // FvReport file to log the FV information in one Fvimage\r
+  //\r
+  strcpy (FvReportName, FvFileName);\r
+  strcat (FvReportName, ".txt");\r
+\r
   //\r
   // Calculate the FV size and Update Fv Size based on the actual FFS files.\r
   // And Update mFvDataInfo data.\r
@@ -2043,7 +2151,7 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return Status;    \r
   }\r
-  VerboseMsg ("the generated FV image size is %d bytes", mFvDataInfo.Size);\r
+  VerboseMsg ("the generated FV image size is %u bytes", (unsigned) mFvDataInfo.Size);\r
   \r
   //\r
   // support fv image and empty fv image\r
@@ -2120,7 +2228,7 @@ Returns:
   //\r
   // If there is no FFS file, generate one empty FV\r
   //\r
-  if (mFvDataInfo.FvFiles[0][0] == 0) {\r
+  if (mFvDataInfo.FvFiles[0][0] == 0 && !mFvDataInfo.FvNameGuidSet) {\r
     goto WriteFile;\r
   }\r
 \r
@@ -2150,29 +2258,45 @@ Returns:
     return EFI_ABORTED;\r
   }\r
   \r
+  //\r
+  // Open FvReport file\r
+  //\r
+  FvReportFile = fopen(FvReportName, "w");\r
+  if (FvReportFile == NULL) {\r
+    Error (NULL, 0, 0001, "Error opening file", FvReportName);\r
+    return EFI_ABORTED;\r
+  }\r
   //\r
   // record FV size information into FvMap file.\r
   //\r
   if (mFvTotalSize != 0) {\r
     fprintf (FvMapFile, EFI_FV_TOTAL_SIZE_STRING);\r
-    fprintf (FvMapFile, " = 0x%x\n", mFvTotalSize);\r
+    fprintf (FvMapFile, " = 0x%x\n", (unsigned) mFvTotalSize);\r
   }\r
   if (mFvTakenSize != 0) {\r
     fprintf (FvMapFile, EFI_FV_TAKEN_SIZE_STRING);\r
-    fprintf (FvMapFile, " = 0x%x\n", mFvTakenSize);\r
+    fprintf (FvMapFile, " = 0x%x\n", (unsigned) mFvTakenSize);\r
   }\r
   if (mFvTotalSize != 0 && mFvTakenSize != 0) {\r
     fprintf (FvMapFile, EFI_FV_SPACE_SIZE_STRING);\r
-    fprintf (FvMapFile, " = 0x%x\n\n", mFvTotalSize - mFvTakenSize);\r
+    fprintf (FvMapFile, " = 0x%x\n\n", (unsigned) (mFvTotalSize - mFvTakenSize));\r
   }\r
 \r
   //\r
-  // Set PI FV extension header\r
+  // record FV size information to FvReportFile.\r
   //\r
-  if (mFvDataInfo.FvNameGuidSet) {\r
-    memcpy (&FvExtHeader.FvName, &mFvDataInfo.FvNameGuid, sizeof (EFI_GUID));\r
-    FvExtHeader.ExtHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);\r
-    AddPadFile (&FvImageMemoryFile, 8, &FvExtHeader);\r
+  fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);\r
+  fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);\r
+\r
+  //\r
+  // Add PI FV extension header\r
+  //\r
+  if (FvExtHeader != NULL) {\r
+    //\r
+    // Add FV Extended Header contents to the FV as a PAD file\r
+    //\r
+    AddPadFile (&FvImageMemoryFile, 4, VtfFileImage, FvExtHeader);\r
+\r
     //\r
     // Fv Extension header change update Fv Header Check sum\r
     //\r
@@ -2187,7 +2311,7 @@ Returns:
     //\r
     // Add the file\r
     //\r
-    Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile);\r
+    Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile, FvReportFile);\r
 \r
     //\r
     // Exit if error detected while adding the file\r
@@ -2276,15 +2400,25 @@ Finish:
   if (FvBufferHeader != NULL) {\r
     free (FvBufferHeader);\r
   }\r
+\r
+  if (FvExtHeader != NULL) {\r
+    free (FvExtHeader);\r
+  }\r
   \r
   if (FvFile != NULL) {\r
+    fflush (FvFile);\r
     fclose (FvFile);\r
   }\r
   \r
   if (FvMapFile != NULL) {\r
+    fflush (FvMapFile);\r
     fclose (FvMapFile);\r
   }\r
 \r
+  if (FvReportFile != NULL) {\r
+    fflush (FvReportFile);\r
+    fclose (FvReportFile);\r
+  }\r
   return Status;\r
 }\r
 \r
@@ -2379,10 +2513,14 @@ Returns:
   UINTN               Index;\r
   FILE                *fpin;\r
   UINTN               FfsFileSize;\r
+  UINTN               FvExtendHeaderSize;\r
   UINT32              FfsAlignment;\r
   EFI_FFS_FILE_HEADER FfsHeader;\r
   BOOLEAN             VtfFileFlag;\r
+  UINTN               VtfFileSize;\r
   \r
+  FvExtendHeaderSize = 0;\r
+  VtfFileSize = 0;\r
   VtfFileFlag = FALSE;\r
   fpin  = NULL;\r
   Index = 0;\r
@@ -2410,7 +2548,17 @@ Returns:
   //\r
   // Calculate PI extension header\r
   //\r
-  if (CompareGuid (&mFvDataInfo.FvNameGuid, &mZeroGuid) != 0) {\r
+  if (mFvDataInfo.FvExtHeaderFile[0] != '\0') {\r
+    fpin = fopen (mFvDataInfo.FvExtHeaderFile, "rb");\r
+    if (fpin == NULL) {\r
+      Error (NULL, 0, 0001, "Error opening file", mFvDataInfo.FvExtHeaderFile);\r
+      return EFI_ABORTED;\r
+    }\r
+    FvExtendHeaderSize = _filelength (fileno (fpin));\r
+    fclose (fpin);\r
+    CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize;\r
+    CurrentOffset = (CurrentOffset + 7) & (~7);\r
+  } else if (mFvDataInfo.FvNameGuidSet) {\r
     CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);\r
     CurrentOffset = (CurrentOffset + 7) & (~7);\r
   }\r
@@ -2453,24 +2601,22 @@ Returns:
                return EFI_ABORTED;\r
              }\r
              VtfFileFlag = TRUE;\r
-             //\r
-             // The space between Vft File and the latest file must be able to contain \r
-             // one ffs file header in order to add one pad file.\r
-             //\r
-             CurrentOffset += sizeof (EFI_FFS_FILE_HEADER);\r
-           }\r
-           //\r
-           // Get the alignment of FFS file \r
-           //\r
-           ReadFfsAlignment (&FfsHeader, &FfsAlignment);\r
-           FfsAlignment = 1 << FfsAlignment;\r
-           //\r
-           // Add Pad file\r
-           //\r
-           if (((CurrentOffset + sizeof (EFI_FFS_FILE_HEADER)) % FfsAlignment) != 0) {\r
-             CurrentOffset = (CurrentOffset + sizeof (EFI_FFS_FILE_HEADER) * 2 + FfsAlignment - 1) & ~(FfsAlignment - 1);\r
-             CurrentOffset -= sizeof (EFI_FFS_FILE_HEADER);\r
-           }\r
+        VtfFileSize = FfsFileSize;\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Get the alignment of FFS file \r
+      //\r
+      ReadFfsAlignment (&FfsHeader, &FfsAlignment);\r
+      FfsAlignment = 1 << FfsAlignment;\r
+      //\r
+      // Add Pad file\r
+      //\r
+      if (((CurrentOffset + sizeof (EFI_FFS_FILE_HEADER)) % FfsAlignment) != 0) {\r
+        CurrentOffset = (CurrentOffset + sizeof (EFI_FFS_FILE_HEADER) * 2 + FfsAlignment - 1) & ~(FfsAlignment - 1);\r
+        CurrentOffset -= sizeof (EFI_FFS_FILE_HEADER);\r
+      }\r
          }\r
 \r
     //\r
@@ -2489,8 +2635,8 @@ Returns:
        CurrentOffset = (CurrentOffset + EFI_FFS_FILE_HEADER_ALIGNMENT - 1) & ~(EFI_FFS_FILE_HEADER_ALIGNMENT - 1);\r
     }\r
   }\r
-  \r
-  DebugMsg (NULL, 0, 9, "FvImage size", "The caculated fv image size is 0x%x and the current set fv image size is 0x%x", CurrentOffset, FvInfoPtr->Size);\r
+  CurrentOffset += VtfFileSize;\r
+  DebugMsg (NULL, 0, 9, "FvImage size", "The caculated fv image size is 0x%x and the current set fv image size is 0x%x", (unsigned) CurrentOffset, (unsigned) FvInfoPtr->Size);\r
   \r
   if (FvInfoPtr->Size == 0) { \r
     //\r
@@ -2504,7 +2650,7 @@ Returns:
     //\r
     // Not invalid\r
     //\r
-    Error (NULL, 0, 3000, "Invalid", "the required fv image size 0x%x exceeds the set fv image size 0x%x", CurrentOffset, FvInfoPtr->Size);\r
+    Error (NULL, 0, 3000, "Invalid", "the required fv image size 0x%x exceeds the set fv image size 0x%x", (unsigned) CurrentOffset, (unsigned) FvInfoPtr->Size);\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r
@@ -2560,6 +2706,54 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+GetChildFvFromFfs (\r
+  IN      FV_INFO               *FvInfo, \r
+  IN      EFI_FFS_FILE_HEADER   *FfsFile,\r
+  IN      UINTN                 XipOffset\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function gets all child FvImages in the input FfsFile, and records\r
+  their base address to the parent image.\r
+\r
+Arguments:\r
+  FvInfo            A pointer to FV_INFO struture.\r
+  FfsFile           A pointer to Ffs file image that may contain FvImage.\r
+  XipOffset         The offset address to the parent FvImage base.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Base address of child Fv image is recorded.\r
+--*/\r
+{\r
+  EFI_STATUS                          Status;\r
+  UINTN                               Index;\r
+  EFI_FILE_SECTION_POINTER            SubFvSection;\r
+  EFI_FIRMWARE_VOLUME_HEADER          *SubFvImageHeader;\r
+  EFI_PHYSICAL_ADDRESS                SubFvBaseAddress;\r
+\r
+  for (Index = 1;; Index++) {\r
+    //\r
+    // Find FV section \r
+    //\r
+    Status = GetSectionByType (FfsFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, Index, &SubFvSection);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + sizeof (EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
+    //\r
+    // Rebase on Flash\r
+    //\r
+    SubFvBaseAddress = FvInfo->BaseAddress + (UINTN) SubFvImageHeader - (UINTN) FfsFile + XipOffset;\r
+    mFvBaseAddress[mFvBaseAddressNumber ++ ] = SubFvBaseAddress;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 EFI_STATUS\r
 FfsRebase ( \r
   IN OUT  FV_INFO               *FvInfo, \r
@@ -2604,7 +2798,6 @@ Returns:
   EFI_FFS_FILE_STATE                    SavedState;\r
   EFI_IMAGE_OPTIONAL_HEADER_UNION       *ImgHdr;\r
   EFI_TE_IMAGE_HEADER                   *TEImageHeader;\r
-  UINT8                                 Flags;\r
   UINT8                                 *MemoryImagePointer;\r
   EFI_IMAGE_SECTION_HEADER              *SectionHeader;\r
   CHAR8                                 PeFileName [_MAX_PATH];\r
@@ -2625,26 +2818,12 @@ Returns:
   PeFileBuffer       = NULL;\r
 \r
   //\r
-  // Check XipAddress, BootAddress and RuntimeAddress\r
+  // Don't need to relocate image when BaseAddress is not set.\r
   //\r
-  Flags = 0;\r
-\r
-  if (FvInfo->BaseAddress != 0) {\r
-    Flags  |= REBASE_XIP_FILE;\r
-    XipBase = FvInfo->BaseAddress + XipOffset;\r
-  }\r
-  if (FvInfo->BootBaseAddress != 0) {\r
-    Flags  |= REBASE_BOOTTIME_FILE;\r
-  }\r
-  if (FvInfo->RuntimeBaseAddress != 0) {\r
-    Flags  |= REBASE_RUNTIME_FILE;\r
+  if (FvInfo->BaseAddress == 0) {\r
+    return EFI_SUCCESS;\r
   }\r
-\r
-  //\r
-  //  Don't Rebase this FFS.\r
-  //  Only copy the original map file into the FvMap file \r
-  //  for the image that is not required to be relocated.\r
-  //\r
+  XipBase = FvInfo->BaseAddress + XipOffset;\r
 \r
   //\r
   // We only process files potentially containing PE32 sections.\r
@@ -2657,6 +2836,16 @@ Returns:
     case EFI_FV_FILETYPE_DRIVER:\r
     case EFI_FV_FILETYPE_DXE_CORE:\r
       break;\r
+    case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
+      //\r
+      // Rebase the inside FvImage.\r
+      //\r
+      GetChildFvFromFfs (FvInfo, FfsFile, XipOffset);\r
+\r
+      //\r
+      // Search PE/TE section in FV sectin.\r
+      //\r
+      break;\r
     default:\r
       return EFI_SUCCESS;\r
   }\r
@@ -2686,7 +2875,7 @@ Returns:
     ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
     Status                  = PeCoffLoaderGetImageInfo (&ImageContext);\r
     if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, Status);\r
+      Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);\r
       return Status;\r
     }\r
 \r
@@ -2717,13 +2906,6 @@ Returns:
       case EFI_FV_FILETYPE_PEI_CORE:\r
       case EFI_FV_FILETYPE_PEIM:\r
       case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
-        if ((Flags & REBASE_XIP_FILE) == 0) {\r
-          //\r
-          // We aren't relocating XIP code, so skip it.\r
-          //\r
-          goto WritePeMap;\r
-        }\r
-        \r
         //\r
         // Check if section-alignment and file-alignment match or not\r
         //\r
@@ -2785,7 +2967,7 @@ Returns:
           ImageContext.Handle = PeFileBuffer;\r
           Status              = PeCoffLoaderGetImageInfo (&ImageContext);\r
           if (EFI_ERROR (Status)) {\r
-            Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, Status);\r
+            Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);\r
             return Status;\r
           }\r
           ImageContext.RelocationsStripped = FALSE;\r
@@ -2797,70 +2979,18 @@ Returns:
 \r
       case EFI_FV_FILETYPE_DRIVER:\r
       case EFI_FV_FILETYPE_DXE_CORE:\r
-        switch (ImgHdr->Pe32.OptionalHeader.Subsystem) {\r
-          case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
-                                               if ((Flags & REBASE_XIP_FILE) == REBASE_XIP_FILE) {\r
-                               //\r
-                               // Check if section-alignment and file-alignment match or not\r
-                               //\r
-                               if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {\r
-                                 //\r
-                                 // Xip module has the same section alignment and file alignment.\r
-                                 //\r
-                                 Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);\r
-                                 return EFI_ABORTED;\r
-                               }\r
-                               NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;\r
-                               BaseToUpdate = &XipBase;                        \r
-                 } else if ((Flags & REBASE_RUNTIME_FILE) == REBASE_RUNTIME_FILE) {\r
-                   //\r
-                   // make sure image base address at the section alignment\r
-                   //\r
-                   FvInfo->RuntimeBaseAddress = (FvInfo->RuntimeBaseAddress - ImageContext.ImageSize) & (~(ImageContext.SectionAlignment - 1));\r
-                   FvInfo->RuntimeBaseAddress = FvInfo->RuntimeBaseAddress & (~(EFI_PAGE_SIZE - 1));\r
-                   NewPe32BaseAddress = FvInfo->RuntimeBaseAddress;\r
-                   BaseToUpdate = &(FvInfo->RuntimeBaseAddress);\r
-                 } else {\r
-              //\r
-              // RT drivers aren't supposed to be relocated\r
-              //\r
-              goto WritePeMap;\r
-            }\r
-            break;\r
-\r
-          default:\r
-            //\r
-            // We treat all other subsystems the same as BS_DRIVER\r
-            //\r
-                                               if ((Flags & REBASE_XIP_FILE) == REBASE_XIP_FILE) {\r
-                               //\r
-                               // Check if section-alignment and file-alignment match or not\r
-                               //\r
-                               if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {\r
-                                 //\r
-                                 // Xip module has the same section alignment and file alignment.\r
-                                 //\r
-                                 Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);\r
-                                 return EFI_ABORTED;\r
-                               }\r
-                               NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;\r
-                               BaseToUpdate = &XipBase;                        \r
-                 } else if ((Flags & REBASE_BOOTTIME_FILE) == REBASE_BOOTTIME_FILE) {\r
-                   //\r
-                   // make sure image base address at the Section and Page alignment\r
-                   //\r
-                   FvInfo->BootBaseAddress = (FvInfo->BootBaseAddress - ImageContext.ImageSize) & (~(ImageContext.SectionAlignment - 1));\r
-                   FvInfo->BootBaseAddress = FvInfo->BootBaseAddress & (~(EFI_PAGE_SIZE - 1));\r
-                   NewPe32BaseAddress = FvInfo->BootBaseAddress;\r
-                   BaseToUpdate = &(FvInfo->BootBaseAddress);\r
-                 } else {\r
-              //\r
-              // Skip all BS_DRIVER's\r
-              //\r
-              goto WritePeMap;\r
-            }\r
-            break;\r
+        //\r
+        // Check if section-alignment and file-alignment match or not\r
+        //\r
+        if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {\r
+          //\r
+          // Xip module has the same section alignment and file alignment.\r
+          //\r
+          Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);\r
+          return EFI_ABORTED;\r
         }\r
+        NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;\r
+        BaseToUpdate = &XipBase;                       \r
         break;\r
 \r
       default:\r
@@ -2871,81 +3001,82 @@ Returns:
     }\r
     \r
     //\r
-    // Relocation exist and rebase\r
+    // Relocation doesn't exist\r
     //\r
-    if (!ImageContext.RelocationsStripped) {  \r
-      //\r
-      // Load and Relocate Image Data\r
-      //\r
-      MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-      if (MemoryImagePointer == NULL) {\r
-        Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-      memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-      ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
-      \r
-      Status =  PeCoffLoaderLoadImage (&ImageContext);\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
-        free ((VOID *) MemoryImagePointer);\r
-        return Status;\r
-      }\r
-           \r
-      ImageContext.DestinationAddress = NewPe32BaseAddress;\r
-      Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
-        free ((VOID *) MemoryImagePointer);\r
-        return Status;\r
-      }\r
+    if (ImageContext.RelocationsStripped) {\r
+      Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);\r
+      continue;\r
+    }\r
 \r
-      //\r
-      // Copy Relocated data to raw image file.\r
-      //\r
-      SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
-                         (UINTN) ImgHdr +\r
-                         sizeof (UINT32) + \r
-                         sizeof (EFI_IMAGE_FILE_HEADER) +  \r
-                         ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
-                         );\r
-      \r
-      for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
-        CopyMem (\r
-          (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData, \r
-          (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
-          SectionHeader->SizeOfRawData\r
-          );\r
-      }\r
-  \r
+    //\r
+    // Relocation exist and rebase\r
+    //\r
+    //\r
+    // Load and Relocate Image Data\r
+    //\r
+    MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+    if (MemoryImagePointer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+    ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
+    \r
+    Status =  PeCoffLoaderLoadImage (&ImageContext);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
       free ((VOID *) MemoryImagePointer);\r
-      MemoryImagePointer = NULL;\r
-      if (PeFileBuffer != NULL) {\r
-        free (PeFileBuffer);\r
-        PeFileBuffer = NULL;\r
-      }\r
+      return Status;\r
+    }\r
+         \r
+    ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+    Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
+      free ((VOID *) MemoryImagePointer);\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Copy Relocated data to raw image file.\r
+    //\r
+    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+                       (UINTN) ImgHdr +\r
+                       sizeof (UINT32) + \r
+                       sizeof (EFI_IMAGE_FILE_HEADER) +  \r
+                       ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
+                       );\r
+    \r
+    for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+      CopyMem (\r
+        (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData, \r
+        (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
+        SectionHeader->SizeOfRawData\r
+        );\r
+    }\r
+\r
+    free ((VOID *) MemoryImagePointer);\r
+    MemoryImagePointer = NULL;\r
+    if (PeFileBuffer != NULL) {\r
+      free (PeFileBuffer);\r
+      PeFileBuffer = NULL;\r
     }\r
     \r
     //\r
     // Update Image Base Address\r
     //\r
     if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
-      ImgHdr->Pe32.OptionalHeader.ImageBase     = (UINT32) NewPe32BaseAddress;\r
+      ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
     } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
-      ImgHdr->Pe32Plus.OptionalHeader.ImageBase     = NewPe32BaseAddress;\r
+      ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
     } else {\r
       Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
-        (UINT32) ImgHdr->Pe32.OptionalHeader.Magic,\r
+        ImgHdr->Pe32.OptionalHeader.Magic,\r
         FileName\r
         );\r
       return EFI_ABORTED;\r
     }\r
 \r
-    //\r
-    // Update BASE address by add one page size.\r
-    //\r
-    *BaseToUpdate -= EFI_PAGE_SIZE;\r
-\r
     //\r
     // Now update file checksum\r
     //\r
@@ -2953,22 +3084,17 @@ Returns:
       SavedState  = FfsFile->State;\r
       FfsFile->IntegrityCheck.Checksum.File = 0;\r
       FfsFile->State                        = 0;\r
-      if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
-        FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
-                                                  (UINT8 *) FfsFile,\r
-                                                  GetLength (FfsFile->Size)\r
-                                                  );\r
-      } else {\r
-        FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
-      }\r
-\r
+      FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
+                                                (UINT8 *) (FfsFile + 1),\r
+                                                GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_HEADER)\r
+                                                );\r
       FfsFile->State = SavedState;\r
     }\r
 \r
     //\r
     // Get this module function address from ModulePeMapFile and add them into FvMap file\r
     //\r
-WritePeMap:\r
+\r
     //\r
     // Default use FileName as map file path\r
     //\r
@@ -2976,13 +3102,14 @@ WritePeMap:
       PdbPointer = FileName;\r
     }\r
 \r
-    WriteMapFile (FvMapFile, PdbPointer, (EFI_GUID *) FfsFile, NewPe32BaseAddress, &OrigImageContext);\r
+    WriteMapFile (FvMapFile, PdbPointer, FfsFile, NewPe32BaseAddress, &OrigImageContext);\r
   }\r
 \r
   if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
       FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&\r
       FfsFile->Type != EFI_FV_FILETYPE_PEIM &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\r
+      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&\r
+      FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
       ) {\r
     //\r
     // Only Peim code may have a TE section\r
@@ -3018,7 +3145,7 @@ WritePeMap:
     ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
     Status                  = PeCoffLoaderGetImageInfo (&ImageContext);\r
     if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, Status);\r
+      Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status);\r
       return Status;\r
     }\r
 \r
@@ -3035,13 +3162,6 @@ WritePeMap:
     // Get File PdbPointer\r
     //\r
     PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);\r
-    \r
-    if ((Flags & REBASE_XIP_FILE) == 0) {\r
-      //\r
-      // For none XIP PEIM module, their map info also are collected.\r
-      //\r
-      goto WriteTeMap;\r
-    }\r
 \r
     //\r
     // Set new rebased address.\r
@@ -3052,7 +3172,7 @@ WritePeMap:
     //\r
     // if reloc is stripped, try to get the original efi image to get reloc info.\r
     //\r
-    if (ImageContext.RelocationsStripped == TRUE) {\r
+    if (ImageContext.RelocationsStripped) {\r
       //\r
       // Construct the original efi file name \r
       //\r
@@ -3101,76 +3221,81 @@ WritePeMap:
         ImageContext.Handle = PeFileBuffer;\r
         Status              = PeCoffLoaderGetImageInfo (&ImageContext);\r
         if (EFI_ERROR (Status)) {\r
-          Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, Status);\r
+          Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status);\r
           return Status;\r
         }\r
         ImageContext.RelocationsStripped = FALSE;\r
       }\r
     }\r
+    //\r
+    // Relocation doesn't exist\r
+    //\r
+    if (ImageContext.RelocationsStripped) {\r
+      Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);\r
+      continue;\r
+    }\r
 \r
     //\r
     // Relocation exist and rebase\r
     //\r
-    if (!ImageContext.RelocationsStripped) {\r
-      //\r
-      // Load and Relocate Image Data\r
-      //\r
-      MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-      if (MemoryImagePointer == NULL) {\r
-        Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-      memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-      ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
-  \r
-      Status =  PeCoffLoaderLoadImage (&ImageContext);\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
-        free ((VOID *) MemoryImagePointer);\r
-        return Status;\r
-      }\r
-      //\r
-      // Reloacate TeImage\r
-      // \r
-      ImageContext.DestinationAddress = NewPe32BaseAddress;\r
-      Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);\r
-        free ((VOID *) MemoryImagePointer);\r
-        return Status;\r
-      }\r
-      \r
-      //\r
-      // Copy the relocated image into raw image file.\r
-      //\r
-      SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
-      for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {\r
-        if (!ImageContext.IsTeImage) {\r
-          CopyMem (\r
-            (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
-            (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
-            SectionHeader->SizeOfRawData\r
-            );\r
-        } else {\r
-          CopyMem (\r
-            (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
-            (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), \r
-            SectionHeader->SizeOfRawData\r
-            );\r
-        }\r
-      }\r
-      \r
-      //\r
-      // Free the allocated memory resource\r
-      //\r
+    //\r
+    // Load and Relocate Image Data\r
+    //\r
+    MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+    if (MemoryImagePointer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+    ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
+\r
+    Status =  PeCoffLoaderLoadImage (&ImageContext);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
       free ((VOID *) MemoryImagePointer);\r
-      MemoryImagePointer = NULL;\r
-      if (PeFileBuffer != NULL) {\r
-        free (PeFileBuffer);\r
-        PeFileBuffer = NULL;\r
+      return Status;\r
+    }\r
+    //\r
+    // Reloacate TeImage\r
+    // \r
+    ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+    Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);\r
+      free ((VOID *) MemoryImagePointer);\r
+      return Status;\r
+    }\r
+    \r
+    //\r
+    // Copy the relocated image into raw image file.\r
+    //\r
+    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
+    for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {\r
+      if (!ImageContext.IsTeImage) {\r
+        CopyMem (\r
+          (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
+          (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
+          SectionHeader->SizeOfRawData\r
+          );\r
+      } else {\r
+        CopyMem (\r
+          (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
+          (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), \r
+          SectionHeader->SizeOfRawData\r
+          );\r
       }\r
     }\r
     \r
+    //\r
+    // Free the allocated memory resource\r
+    //\r
+    free ((VOID *) MemoryImagePointer);\r
+    MemoryImagePointer = NULL;\r
+    if (PeFileBuffer != NULL) {\r
+      free (PeFileBuffer);\r
+      PeFileBuffer = NULL;\r
+    }\r
+    \r
     //\r
     // Update Image Base Address\r
     //\r
@@ -3183,21 +3308,16 @@ WritePeMap:
       SavedState  = FfsFile->State;\r
       FfsFile->IntegrityCheck.Checksum.File = 0;\r
       FfsFile->State                        = 0;\r
-      if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
-        FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
-                                                  (UINT8 *) FfsFile,\r
-                                                  GetLength (FfsFile->Size)\r
-                                                  );\r
-      } else {\r
-        FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
-      }\r
-\r
+      FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
+                                                (UINT8 *)(FfsFile + 1),\r
+                                                GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_HEADER)\r
+                                                );\r
       FfsFile->State = SavedState;\r
     }\r
     //\r
     // Get this module function address from ModulePeMapFile and add them into FvMap file\r
     //\r
-WriteTeMap:\r
+\r
     //\r
     // Default use FileName as map file path\r
     //\r
@@ -3208,7 +3328,7 @@ WriteTeMap:
     WriteMapFile (\r
       FvMapFile, \r
       PdbPointer, \r
-      (EFI_GUID *) FfsFile,\r
+      FfsFile,\r
       NewPe32BaseAddress, \r
       &OrigImageContext\r
       );\r
@@ -3365,8 +3485,14 @@ Returns:
   if (Status == EFI_SUCCESS) {\r
     if (strstr (Value, "PopulateSystemTable") != NULL) {\r
       CapInfo->Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;\r
+      if (strstr (Value, "InitiateReset") != NULL) {\r
+        CapInfo->Flags |= CAPSULE_FLAGS_INITIATE_RESET;\r
+      }\r
     } else if (strstr (Value, "PersistAcrossReset") != NULL) {\r
       CapInfo->Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET; \r
+      if (strstr (Value, "InitiateReset") != NULL) {\r
+        CapInfo->Flags |= CAPSULE_FLAGS_INITIATE_RESET;\r
+      }\r
     } else {\r
       Error (NULL, 0, 2000, "Invalid parameter", "invalid Flag setting for %s.", EFI_CAPSULE_FLAGS_STRING);\r
       return EFI_ABORTED;\r
@@ -3403,7 +3529,7 @@ Returns:
       // Add the file\r
       //\r
       strcpy (CapInfo->CapFiles[Index], Value);\r
-      DebugMsg (NULL, 0, 9, "Capsule component file", "the %dth file name is %s", Index, CapInfo->CapFiles[Index]); \r
+      DebugMsg (NULL, 0, 9, "Capsule component file", "the %uth file name is %s", (unsigned) Index, CapInfo->CapFiles[Index]); \r
     } else {\r
       break;\r
     }\r
@@ -3568,7 +3694,7 @@ Returns:
   fwrite (CapBuffer, 1, CapSize, fpout);\r
   fclose (fpout);\r
   \r
-  VerboseMsg ("The size of the generated capsule image is %d bytes", CapSize);\r
+  VerboseMsg ("The size of the generated capsule image is %u bytes", (unsigned) CapSize);\r
 \r
   return EFI_SUCCESS;\r
 }\r