]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
SecurityPkg: Debug code to audit BIOS TPM extend operations
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Pei / Tcg2Pei.c
index 2cffed4464b82500eee8cbb4e71c8347121a7074..622989aff34f1798adddb7b84eed9bd2edb9ec69 100644 (file)
@@ -1,14 +1,9 @@
 /** @file\r
   Initialize TPM2 device and measure FVs before handing off control to DXE.\r
 \r
-Copyright (c) 2015 - 2016, 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
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -17,15 +12,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <IndustryStandard/UefiTcgPlatform.h>\r
 #include <Ppi/FirmwareVolumeInfo.h>\r
 #include <Ppi/FirmwareVolumeInfo2.h>\r
-#include <Ppi/LockPhysicalPresence.h>\r
 #include <Ppi/TpmInitialized.h>\r
 #include <Ppi/FirmwareVolume.h>\r
 #include <Ppi/EndOfPeiPhase.h>\r
 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>\r
+#include <Ppi/FirmwareVolumeInfoPrehashedFV.h>\r
+#include <Ppi/Tcg.h>\r
 \r
 #include <Guid/TcgEventHob.h>\r
 #include <Guid/MeasuredFvHob.h>\r
 #include <Guid/TpmInstance.h>\r
+#include <Guid/MigratedFvInfo.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -41,22 +38,23 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/PerformanceLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/ReportStatusCodeLib.h>\r
-#include <Library/Tcg2PhysicalPresenceLib.h>\r
+#include <Library/ResetSystemLib.h>\r
+#include <Library/PrintLib.h>\r
 \r
 #define PERF_ID_TCG2_PEI  0x3080\r
 \r
 typedef struct {\r
-  EFI_GUID                   *EventGuid;\r
-  EFI_TCG2_EVENT_LOG_FORMAT  LogFormat;\r
+  EFI_GUID                     *EventGuid;\r
+  EFI_TCG2_EVENT_LOG_FORMAT    LogFormat;\r
 } TCG2_EVENT_INFO_STRUCT;\r
 \r
-TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = {\r
-  {&gTcgEventEntryHobGuid,   EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2},\r
-  {&gTcgEvent2EntryHobGuid,  EFI_TCG2_EVENT_LOG_FORMAT_TCG_2},\r
+TCG2_EVENT_INFO_STRUCT  mTcg2EventInfo[] = {\r
+  { &gTcgEventEntryHobGuid,  EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 },\r
+  { &gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2   },\r
 };\r
 \r
-BOOLEAN                 mImageInMemory  = FALSE;\r
-EFI_PEI_FILE_HANDLE     mFileHandle;\r
+BOOLEAN              mImageInMemory = FALSE;\r
+EFI_PEI_FILE_HANDLE  mFileHandle;\r
 \r
 EFI_PEI_PPI_DESCRIPTOR  mTpmInitializedPpiList = {\r
   EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
@@ -70,14 +68,75 @@ EFI_PEI_PPI_DESCRIPTOR  mTpmInitializationDonePpiList = {
   NULL\r
 };\r
 \r
-EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;\r
-UINT32 mMeasuredBaseFvIndex = 0;\r
+/**\r
+  Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
+  and build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
+  added into the Event Log.\r
+\r
+  @param[in]      This          Indicates the calling context\r
+  @param[in]      Flags         Bitmap providing additional information.\r
+  @param[in]      HashData      If BIT0 of Flags is 0, it is physical address of the\r
+                                start of the data buffer to be hashed, extended, and logged.\r
+                                If BIT0 of Flags is 1, it is physical address of the\r
+                                start of the pre-hash data buffter to be extended, and logged.\r
+                                The pre-hash data format is TPML_DIGEST_VALUES.\r
+  @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData.\r
+  @param[in]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.\r
+  @param[in]      NewEventData  Pointer to the new event data.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
 \r
-EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;\r
-UINT32 mMeasuredChildFvIndex = 0;\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashLogExtendEvent (\r
+  IN      EDKII_TCG_PPI      *This,\r
+  IN      UINT64             Flags,\r
+  IN      UINT8              *HashData,\r
+  IN      UINTN              HashDataLen,\r
+  IN      TCG_PCR_EVENT_HDR  *NewEventHdr,\r
+  IN      UINT8              *NewEventData\r
+  );\r
+\r
+EDKII_TCG_PPI  mEdkiiTcgPpi = {\r
+  HashLogExtendEvent\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mTcgPpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gEdkiiTcgPpiGuid,\r
+  &mEdkiiTcgPpi\r
+};\r
+\r
+//\r
+// Number of firmware blobs to grow by each time we run out of room\r
+//\r
+#define FIRMWARE_BLOB_GROWTH_STEP  4\r
+\r
+EFI_PLATFORM_FIRMWARE_BLOB  *mMeasuredBaseFvInfo;\r
+UINT32                      mMeasuredMaxBaseFvIndex = 0;\r
+UINT32                      mMeasuredBaseFvIndex    = 0;\r
+\r
+EFI_PLATFORM_FIRMWARE_BLOB  *mMeasuredChildFvInfo;\r
+UINT32                      mMeasuredMaxChildFvIndex = 0;\r
+UINT32                      mMeasuredChildFvIndex    = 0;\r
+\r
+#pragma pack (1)\r
+\r
+#define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"\r
+typedef struct {\r
+  UINT8                   BlobDescriptionSize;\r
+  UINT8                   BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)];\r
+  EFI_PHYSICAL_ADDRESS    BlobBase;\r
+  UINT64                  BlobLength;\r
+} FV_HANDOFF_TABLE_POINTERS2;\r
+\r
+#pragma pack ()\r
 \r
 /**\r
-  Measure and record the Firmware Volum Information once FvInfoPPI install.\r
+  Measure and record the Firmware Volume Information once FvInfoPPI install.\r
 \r
   @param[in] PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
   @param[in] NotifyDescriptor  Address of the notification descriptor data structure.\r
@@ -89,14 +148,14 @@ UINT32 mMeasuredChildFvIndex = 0;
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-FirmwareVolmeInfoPpiNotifyCallback (\r
-  IN EFI_PEI_SERVICES              **PeiServices,\r
-  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
-  IN VOID                          *Ppi\r
+FirmwareVolumeInfoPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
   );\r
 \r
 /**\r
-  Record all measured Firmware Volum Information into a Guid Hob\r
+  Record all measured Firmware Volume Information into a Guid Hob\r
 \r
   @param[in] PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
   @param[in] NotifyDescriptor  Address of the notification descriptor data structure.\r
@@ -109,21 +168,21 @@ FirmwareVolmeInfoPpiNotifyCallback (
 EFI_STATUS\r
 EFIAPI\r
 EndofPeiSignalNotifyCallBack (\r
-  IN EFI_PEI_SERVICES              **PeiServices,\r
-  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
-  IN VOID                          *Ppi\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
   );\r
 \r
-EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {\r
+EFI_PEI_NOTIFY_DESCRIPTOR  mNotifyList[] = {\r
   {\r
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
     &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
-    FirmwareVolmeInfoPpiNotifyCallback \r
+    FirmwareVolumeInfoPpiNotifyCallback\r
   },\r
   {\r
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
     &gEfiPeiFirmwareVolumeInfo2PpiGuid,\r
-    FirmwareVolmeInfoPpiNotifyCallback \r
+    FirmwareVolumeInfoPpiNotifyCallback\r
   },\r
   {\r
     (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
@@ -132,46 +191,9 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
   }\r
 };\r
 \r
-EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;\r
-\r
 /**\r
-  This function get digest from digest list.\r
-\r
-  @param HashAlg    digest algorithm\r
-  @param DigestList digest list\r
-  @param Digest     digest\r
-\r
-  @retval EFI_SUCCESS   Sha1Digest is found and returned.\r
-  @retval EFI_NOT_FOUND Sha1Digest is not found.\r
-**/\r
-EFI_STATUS\r
-Tpm2GetDigestFromDigestList (\r
-  IN TPMI_ALG_HASH      HashAlg,\r
-  IN TPML_DIGEST_VALUES *DigestList,\r
-  IN VOID               *Digest\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-\r
-  DigestSize = GetHashSizeFromAlgo (HashAlg);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    if (DigestList->digests[Index].hashAlg == HashAlg) {\r
-      CopyMem (\r
-        Digest,\r
-        &DigestList->digests[Index].digest,\r
-        DigestSize\r
-        );\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
-  Record all measured Firmware Volum Information into a Guid Hob\r
-  Guid Hob payload layout is \r
+  Record all measured Firmware Volume Information into a Guid Hob\r
+  Guid Hob payload layout is\r
 \r
      UINT32 *************************** FIRMWARE_BLOB number\r
      EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array\r
@@ -187,24 +209,26 @@ Tpm2GetDigestFromDigestList (
 EFI_STATUS\r
 EFIAPI\r
 EndofPeiSignalNotifyCallBack (\r
-  IN EFI_PEI_SERVICES              **PeiServices,\r
-  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
-  IN VOID                          *Ppi\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
   )\r
-{  \r
-  MEASURED_HOB_DATA *MeasuredHobData;\r
+{\r
+  MEASURED_HOB_DATA  *MeasuredHobData;\r
 \r
   MeasuredHobData = NULL;\r
 \r
+  PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid);\r
+\r
   //\r
-  // Create a Guid hob to save all measured Fv \r
+  // Create a Guid hob to save all measured Fv\r
   //\r
-  MeasuredHobData = BuildGuidHob(\r
+  MeasuredHobData = BuildGuidHob (\r
                       &gMeasuredFvHobGuid,\r
-                      sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)\r
+                      sizeof (UINTN) + sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)\r
                       );\r
 \r
-  if (MeasuredHobData != NULL){\r
+  if (MeasuredHobData != NULL) {\r
     //\r
     // Save measured FV info enty number\r
     //\r
@@ -213,205 +237,102 @@ EndofPeiSignalNotifyCallBack (
     //\r
     // Save measured base Fv info\r
     //\r
-    CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));\r
+    CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));\r
 \r
     //\r
     // Save measured child Fv info\r
     //\r
-    CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));\r
+    CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex], mMeasuredChildFvInfo, sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));\r
   }\r
 \r
+  PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Check if buffer is all zero.\r
-\r
-  @param[in] Buffer      Buffer to be checked.\r
-  @param[in] BufferSize  Size of buffer to be checked.\r
-\r
-  @retval TRUE  Buffer is all zero.\r
-  @retval FALSE Buffer is not all zero.\r
+  Make sure that the current PCR allocations, the TPM supported PCRs,\r
+  and the PcdTpm2HashMask are all in agreement.\r
 **/\r
-BOOLEAN\r
-InternalIsZeroBuffer (\r
-  IN VOID  *Buffer,\r
-  IN UINTN BufferSize\r
+VOID\r
+SyncPcrAllocationsAndPcrMask (\r
+  VOID\r
   )\r
 {\r
-  UINT8 *BufferData;\r
-  UINTN Index;\r
-\r
-  BufferData = Buffer;\r
-  for (Index = 0; Index < BufferSize; Index++) {\r
-    if (BufferData[Index] != 0) {\r
-      return FALSE;\r
-    }\r
-  }\r
-  return TRUE;\r
-}\r
+  EFI_STATUS                       Status;\r
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP  TpmHashAlgorithmBitmap;\r
+  UINT32                           TpmActivePcrBanks;\r
+  UINT32                           NewTpmActivePcrBanks;\r
+  UINT32                           Tpm2PcrMask;\r
+  UINT32                           NewTpm2PcrMask;\r
 \r
-/**\r
-  Get TPML_DIGEST_VALUES data size.\r
+  DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));\r
 \r
-  @param[in]     DigestList    TPML_DIGEST_VALUES data.\r
+  //\r
+  // Determine the current TPM support and the Platform PCR mask.\r
+  //\r
+  Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &TpmActivePcrBanks);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  @return TPML_DIGEST_VALUES data size.\r
-**/\r
-UINT32\r
-GetDigestListSize (\r
-  IN TPML_DIGEST_VALUES             *DigestList\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-  UINT32 TotalSize;\r
-\r
-  TotalSize = sizeof(DigestList->count);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
-    TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;\r
+  Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);\r
+  if (Tpm2PcrMask == 0) {\r
+    //\r
+    // if PcdTPm2HashMask is zero, use ActivePcr setting\r
+    //\r
+    PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);\r
+    Tpm2PcrMask = TpmActivePcrBanks;\r
   }\r
 \r
-  return TotalSize;\r
-}\r
-\r
-/**\r
-  Return if hash alg is supported in TPM PCR bank.\r
-\r
-  @param HashAlg  Hash algorithm to be checked.\r
+  //\r
+  // Find the intersection of Pcd support and TPM support.\r
+  // If banks are missing from the TPM support that are in the PCD, update the PCD.\r
+  // If banks are missing from the PCD that are active in the TPM, reallocate the banks and reboot.\r
+  //\r
 \r
-  @retval TRUE  Hash algorithm is supported.\r
-  @retval FALSE Hash algorithm is not supported.\r
-**/\r
-BOOLEAN\r
-IsHashAlgSupportedInPcrBank (\r
-  IN TPMI_ALG_HASH  HashAlg\r
-  )\r
-{\r
-  UINT32  ActivePcrBanks;\r
+  //\r
+  // If there are active PCR banks that are not supported by the Platform mask,\r
+  // update the TPM allocations and reboot the machine.\r
+  //\r
+  if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {\r
+    NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;\r
+\r
+    DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));\r
+    if (NewTpmActivePcrBanks == 0) {\r
+      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs active! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));\r
+      ASSERT (FALSE);\r
+    } else {\r
+      Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap, NewTpmActivePcrBanks);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // We can't do much here, but we hope that this doesn't happen.\r
+        //\r
+        DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n", __FUNCTION__));\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
 \r
-  ActivePcrBanks = PcdGet32 (PcdTpm2HashMask);\r
-  switch (HashAlg) {\r
-  case TPM_ALG_SHA1:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA256:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA384:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA512:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SM3_256:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
-      return TRUE;\r
+      //\r
+      // Need reset system, since we just called Tpm2PcrAllocateBanks().\r
+      //\r
+      ResetCold ();\r
     }\r
-    break;\r
   }\r
 \r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Copy TPML_DIGEST_VALUES into a buffer\r
-\r
-  @param[in,out] Buffer        Buffer to hold TPML_DIGEST_VALUES.\r
-  @param[in]     DigestList    TPML_DIGEST_VALUES to be copied.\r
+  //\r
+  // If there are any PCRs that claim support in the Platform mask that are\r
+  // not supported by the TPM, update the mask.\r
+  //\r
+  if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {\r
+    NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;\r
 \r
-  @return The end of buffer to hold TPML_DIGEST_VALUES.\r
-**/\r
-VOID *\r
-CopyDigestListToBuffer (\r
-  IN OUT VOID                       *Buffer,\r
-  IN TPML_DIGEST_VALUES             *DigestList\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-\r
-  CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count));\r
-  Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) {\r
-      DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));\r
-      continue;\r
+    DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));\r
+    if (NewTpm2PcrMask == 0) {\r
+      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));\r
+      ASSERT (FALSE);\r
     }\r
-    CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));\r
-    Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);\r
-    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
-    CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);\r
-    Buffer = (UINT8 *)Buffer + DigestSize;\r
-  }\r
 \r
-  return Buffer;\r
-}\r
-\r
-/**\r
-  Set Tpm2HashMask PCD value according to TPM2 PCR bank.\r
-**/\r
-VOID\r
-SetTpm2HashMask (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS           Status;\r
-  UINT32               ActivePcrBanks;\r
-  TPML_PCR_SELECTION   Pcrs;\r
-  UINTN                Index;\r
-\r
-  DEBUG ((EFI_D_ERROR, "SetTpm2HashMask!\n"));\r
-\r
-  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));\r
-    ActivePcrBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-  } else {\r
-    DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));\r
-    ActivePcrBanks = 0;\r
-    for (Index = 0; Index < Pcrs.count; Index++) {\r
-      DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));\r
-      switch (Pcrs.pcrSelections[Index].hash) {\r
-      case TPM_ALG_SHA1:\r
-        if (!InternalIsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-        }        \r
-        break;\r
-      case TPM_ALG_SHA256:\r
-        if (!InternalIsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
-        }\r
-        break;\r
-      case TPM_ALG_SHA384:\r
-        if (!InternalIsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
-        }\r
-        break;\r
-      case TPM_ALG_SHA512:\r
-        if (!InternalIsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
-        }\r
-        break;\r
-      case TPM_ALG_SM3_256:\r
-        if (!InternalIsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
-        }\r
-        break;\r
-      }\r
-    }\r
+    Status = PcdSet32S (PcdTpm2HashMask, NewTpm2PcrMask);\r
+    ASSERT_EFI_ERROR (Status);\r
   }\r
-  Status = PcdSet32S (PcdTpm2HashMask, ActivePcrBanks);\r
-  ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
 /**\r
@@ -426,62 +347,67 @@ SetTpm2HashMask (
 **/\r
 EFI_STATUS\r
 LogHashEvent (\r
-  IN TPML_DIGEST_VALUES             *DigestList,\r
-  IN OUT  TCG_PCR_EVENT_HDR         *NewEventHdr,\r
-  IN      UINT8                     *NewEventData\r
+  IN TPML_DIGEST_VALUES      *DigestList,\r
+  IN OUT  TCG_PCR_EVENT_HDR  *NewEventHdr,\r
+  IN      UINT8              *NewEventData\r
   )\r
 {\r
-  VOID                              *HobData;\r
-  EFI_STATUS                        Status;\r
-  UINTN                             Index;\r
-  EFI_STATUS                        RetStatus;\r
-  UINT32                            SupportedEventLogs;\r
-  TCG_PCR_EVENT2                    *TcgPcrEvent2;\r
-  UINT8                             *DigestBuffer;\r
+  VOID            *HobData;\r
+  EFI_STATUS      Status;\r
+  UINTN           Index;\r
+  EFI_STATUS      RetStatus;\r
+  UINT32          SupportedEventLogs;\r
+  TCG_PCR_EVENT2  *TcgPcrEvent2;\r
+  UINT8           *DigestBuffer;\r
 \r
   SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
 \r
   RetStatus = EFI_SUCCESS;\r
-  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+  for (Index = 0; Index < sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]); Index++) {\r
     if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
-      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
+      DEBUG ((DEBUG_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
       switch (mTcg2EventInfo[Index].LogFormat) {\r
-      case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
-        Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
-        if (!EFI_ERROR (Status)) {\r
+        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
+          Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
+          if (!EFI_ERROR (Status)) {\r
+            HobData = BuildGuidHob (\r
+                        &gTcgEventEntryHobGuid,\r
+                        sizeof (*NewEventHdr) + NewEventHdr->EventSize\r
+                        );\r
+            if (HobData == NULL) {\r
+              RetStatus = EFI_OUT_OF_RESOURCES;\r
+              break;\r
+            }\r
+\r
+            CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));\r
+            HobData = (VOID *)((UINT8 *)HobData + sizeof (*NewEventHdr));\r
+            CopyMem (HobData, NewEventData, NewEventHdr->EventSize);\r
+          }\r
+\r
+          break;\r
+        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
+          //\r
+          // Use GetDigestListSize (DigestList) in the GUID HOB DataLength calculation\r
+          // to reserve enough buffer to hold TPML_DIGEST_VALUES compact binary.\r
+          //\r
           HobData = BuildGuidHob (\r
-                     &gTcgEventEntryHobGuid,\r
-                     sizeof (*NewEventHdr) + NewEventHdr->EventSize\r
-                     );\r
+                      &gTcgEvent2EntryHobGuid,\r
+                      sizeof (TcgPcrEvent2->PCRIndex) + sizeof (TcgPcrEvent2->EventType) + GetDigestListSize (DigestList) + sizeof (TcgPcrEvent2->EventSize) + NewEventHdr->EventSize\r
+                      );\r
           if (HobData == NULL) {\r
             RetStatus = EFI_OUT_OF_RESOURCES;\r
             break;\r
           }\r
 \r
-          CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));\r
-          HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));\r
-          CopyMem (HobData, NewEventData, NewEventHdr->EventSize);\r
-        }\r
-        break;\r
-      case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
-        HobData = BuildGuidHob (\r
-                   &gTcgEvent2EntryHobGuid,\r
-                   sizeof(TcgPcrEvent2->PCRIndex) + sizeof(TcgPcrEvent2->EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2->EventSize) + NewEventHdr->EventSize\r
-                   );\r
-        if (HobData == NULL) {\r
-          RetStatus = EFI_OUT_OF_RESOURCES;\r
+          TcgPcrEvent2            = HobData;\r
+          TcgPcrEvent2->PCRIndex  = NewEventHdr->PCRIndex;\r
+          TcgPcrEvent2->EventType = NewEventHdr->EventType;\r
+          DigestBuffer            = (UINT8 *)&TcgPcrEvent2->Digest;\r
+          DigestBuffer            = CopyDigestListToBuffer (DigestBuffer, DigestList, PcdGet32 (PcdTpm2HashMask));\r
+          CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof (TcgPcrEvent2->EventSize));\r
+          DigestBuffer = DigestBuffer + sizeof (TcgPcrEvent2->EventSize);\r
+          CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize);\r
           break;\r
-        }\r
-\r
-        TcgPcrEvent2 = HobData;\r
-        TcgPcrEvent2->PCRIndex = NewEventHdr->PCRIndex;\r
-        TcgPcrEvent2->EventType = NewEventHdr->EventType;\r
-        DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest;\r
-        DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList);\r
-        CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(TcgPcrEvent2->EventSize));\r
-        DigestBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);\r
-        CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize);\r
-        break;\r
       }\r
     }\r
   }\r
@@ -494,12 +420,16 @@ LogHashEvent (
   and build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
   added into the Event Log.\r
 \r
+  @param[in]      This          Indicates the calling context\r
   @param[in]      Flags         Bitmap providing additional information.\r
-  @param[in]      HashData      Physical address of the start of the data buffer \r
-                                to be hashed, extended, and logged.\r
+  @param[in]      HashData      If BIT0 of Flags is 0, it is physical address of the\r
+                                start of the data buffer to be hashed, extended, and logged.\r
+                                If BIT0 of Flags is 1, it is physical address of the\r
+                                start of the pre-hash data buffter to be extended, and logged.\r
+                                The pre-hash data format is TPML_DIGEST_VALUES.\r
   @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData.\r
-  @param[in]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.  \r
-  @param[in]      NewEventData  Pointer to the new event data.  \r
+  @param[in]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.\r
+  @param[in]      NewEventData  Pointer to the new event data.\r
 \r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
@@ -507,36 +437,49 @@ LogHashEvent (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 HashLogExtendEvent (\r
-  IN      UINT64                    Flags,\r
-  IN      UINT8                     *HashData,\r
-  IN      UINTN                     HashDataLen,\r
-  IN      TCG_PCR_EVENT_HDR         *NewEventHdr,\r
-  IN      UINT8                     *NewEventData\r
+  IN      EDKII_TCG_PPI      *This,\r
+  IN      UINT64             Flags,\r
+  IN      UINT8              *HashData,\r
+  IN      UINTN              HashDataLen,\r
+  IN      TCG_PCR_EVENT_HDR  *NewEventHdr,\r
+  IN      UINT8              *NewEventData\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  TPML_DIGEST_VALUES                DigestList;\r
+  EFI_STATUS          Status;\r
+  TPML_DIGEST_VALUES  DigestList;\r
 \r
   if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  Status = HashAndExtend (\r
-             NewEventHdr->PCRIndex,\r
-             HashData,\r
-             HashDataLen,\r
-             &DigestList\r
-             );\r
-  if (!EFI_ERROR (Status)) {\r
-    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
-      Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
+  if (((Flags & EDKII_TCG_PRE_HASH) != 0) || ((Flags & EDKII_TCG_PRE_HASH_LOG_ONLY) != 0)) {\r
+    ZeroMem (&DigestList, sizeof (DigestList));\r
+    CopyMem (&DigestList, HashData, sizeof (DigestList));\r
+    Status = EFI_SUCCESS;\r
+    if ((Flags & EDKII_TCG_PRE_HASH) != 0 ) {\r
+      Status = Tpm2PcrExtend (\r
+                 NewEventHdr->PCRIndex,\r
+                 &DigestList\r
+                 );\r
     }\r
+  } else {\r
+    Status = HashAndExtend (\r
+               NewEventHdr->PCRIndex,\r
+               HashData,\r
+               HashDataLen,\r
+               &DigestList\r
+               );\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
   }\r
-  \r
+\r
   if (Status == EFI_DEVICE_ERROR) {\r
-    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));\r
-    BuildGuidHob (&gTpmErrorHobGuid,0);\r
+    DEBUG ((DEBUG_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));\r
+    BuildGuidHob (&gTpmErrorHobGuid, 0);\r
     REPORT_STATUS_CODE (\r
       EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
       (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
@@ -559,7 +502,7 @@ MeasureCRTMVersion (
   VOID\r
   )\r
 {\r
-  TCG_PCR_EVENT_HDR                 TcgEventHdr;\r
+  TCG_PCR_EVENT_HDR  TcgEventHdr;\r
 \r
   //\r
   // Use FirmwareVersion string to represent CRTM version.\r
@@ -568,25 +511,72 @@ MeasureCRTMVersion (
 \r
   TcgEventHdr.PCRIndex  = 0;\r
   TcgEventHdr.EventType = EV_S_CRTM_VERSION;\r
-  TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));\r
+  TcgEventHdr.EventSize = (UINT32)StrSize ((CHAR16 *)PcdGetPtr (PcdFirmwareVersionString));\r
 \r
   return HashLogExtendEvent (\r
+           &mEdkiiTcgPpi,\r
            0,\r
-           (UINT8*)PcdGetPtr (PcdFirmwareVersionString),\r
+           (UINT8 *)PcdGetPtr (PcdFirmwareVersionString),\r
            TcgEventHdr.EventSize,\r
            &TcgEventHdr,\r
-           (UINT8*)PcdGetPtr (PcdFirmwareVersionString)\r
+           (UINT8 *)PcdGetPtr (PcdFirmwareVersionString)\r
            );\r
 }\r
 \r
 /**\r
-  Measure FV image. \r
-  Add it into the measured FV list after the FV is measured successfully. \r
+  Get the FvName from the FV header.\r
+\r
+  Causion: The FV is untrusted input.\r
+\r
+  @param[in]  FvBase            Base address of FV image.\r
+  @param[in]  FvLength          Length of FV image.\r
+\r
+  @return FvName pointer\r
+  @retval NULL   FvName is NOT found\r
+**/\r
+VOID *\r
+GetFvName (\r
+  IN EFI_PHYSICAL_ADDRESS  FvBase,\r
+  IN UINT64                FvLength\r
+  )\r
+{\r
+  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FvExtHeader;\r
+\r
+  if (FvBase >= MAX_ADDRESS) {\r
+    return NULL;\r
+  }\r
+\r
+  if (FvLength >= MAX_ADDRESS - FvBase) {\r
+    return NULL;\r
+  }\r
+\r
+  if (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {\r
+    return NULL;\r
+  }\r
+\r
+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;\r
+  if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {\r
+    return NULL;\r
+  }\r
+\r
+  if (FvHeader->ExtHeaderOffset + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {\r
+    return NULL;\r
+  }\r
+\r
+  FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);\r
+\r
+  return &FvExtHeader->FvName;\r
+}\r
+\r
+/**\r
+  Measure FV image.\r
+  Add it into the measured FV list after the FV is measured successfully.\r
 \r
   @param[in]  FvBase            Base address of FV image.\r
   @param[in]  FvLength          Length of FV image.\r
 \r
-  @retval EFI_SUCCESS           Fv image is measured successfully \r
+  @retval EFI_SUCCESS           Fv image is measured successfully\r
                                 or it has been already measured.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
   @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
@@ -594,68 +584,217 @@ MeasureCRTMVersion (
 **/\r
 EFI_STATUS\r
 MeasureFvImage (\r
-  IN EFI_PHYSICAL_ADDRESS           FvBase,\r
-  IN UINT64                         FvLength\r
+  IN EFI_PHYSICAL_ADDRESS  FvBase,\r
+  IN UINT64                FvLength\r
   )\r
 {\r
-  UINT32                            Index;\r
-  EFI_STATUS                        Status;\r
-  EFI_PLATFORM_FIRMWARE_BLOB        FvBlob;\r
-  TCG_PCR_EVENT_HDR                 TcgEventHdr;\r
+  UINT32                                                 Index;\r
+  EFI_STATUS                                             Status;\r
+  EFI_PLATFORM_FIRMWARE_BLOB                             FvBlob;\r
+  FV_HANDOFF_TABLE_POINTERS2                             FvBlob2;\r
+  VOID                                                   *EventData;\r
+  VOID                                                   *FvName;\r
+  TCG_PCR_EVENT_HDR                                      TcgEventHdr;\r
+  UINT32                                                 Instance;\r
+  UINT32                                                 Tpm2HashMask;\r
+  TPML_DIGEST_VALUES                                     DigestList;\r
+  UINT32                                                 DigestCount;\r
+  EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI  *MeasurementExcludedFvPpi;\r
+  EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI        *PrehashedFvPpi;\r
+  HASH_INFO                                              *PreHashInfo;\r
+  UINT32                                                 HashAlgoMask;\r
+  EFI_PHYSICAL_ADDRESS                                   FvOrgBase;\r
+  EFI_PHYSICAL_ADDRESS                                   FvDataBase;\r
+  EFI_PEI_HOB_POINTERS                                   Hob;\r
+  EDKII_MIGRATED_FV_INFO                                 *MigratedFvInfo;\r
 \r
   //\r
-  // Check if it is in Excluded FV list\r
+  // Check Excluded FV list\r
   //\r
-  if (mMeasurementExcludedFvPpi != NULL) {\r
-    for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {\r
-      if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {\r
-        DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei starts at: 0x%x\n", FvBase));\r
-        DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei has the size: 0x%x\n", FvLength));\r
-        return EFI_SUCCESS;\r
+  Instance = 0;\r
+  do {\r
+    Status = PeiServicesLocatePpi (\r
+               &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,\r
+               Instance,\r
+               NULL,\r
+               (VOID **)&MeasurementExcludedFvPpi\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      for (Index = 0; Index < MeasurementExcludedFvPpi->Count; Index++) {\r
+        if (  (MeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase)\r
+           && (MeasurementExcludedFvPpi->Fv[Index].FvLength == FvLength))\r
+        {\r
+          DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei starts at: 0x%x\n", FvBase));\r
+          DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei has the size: 0x%x\n", FvLength));\r
+          return EFI_SUCCESS;\r
+        }\r
       }\r
+\r
+      Instance++;\r
     }\r
-  }\r
+  } while (!EFI_ERROR (Status));\r
 \r
   //\r
-  // Check whether FV is in the measured FV list.\r
+  // Check measured FV list\r
   //\r
-  for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {\r
-    if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {\r
+  for (Index = 0; Index < mMeasuredBaseFvIndex; Index++) {\r
+    if ((mMeasuredBaseFvInfo[Index].BlobBase == FvBase) && (mMeasuredBaseFvInfo[Index].BlobLength == FvLength)) {\r
+      DEBUG ((DEBUG_INFO, "The FV which is already measured by Tcg2Pei starts at: 0x%x\n", FvBase));\r
+      DEBUG ((DEBUG_INFO, "The FV which is already measured by Tcg2Pei has the size: 0x%x\n", FvLength));\r
       return EFI_SUCCESS;\r
     }\r
   }\r
-  \r
+\r
   //\r
-  // Measure and record the FV to the TPM\r
+  // Check pre-hashed FV list\r
   //\r
-  FvBlob.BlobBase   = FvBase;\r
-  FvBlob.BlobLength = FvLength;\r
+  Instance     = 0;\r
+  Tpm2HashMask = PcdGet32 (PcdTpm2HashMask);\r
+  do {\r
+    Status = PeiServicesLocatePpi (\r
+               &gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid,\r
+               Instance,\r
+               NULL,\r
+               (VOID **)&PrehashedFvPpi\r
+               );\r
+    if (!EFI_ERROR (Status) && (PrehashedFvPpi->FvBase == FvBase) && (PrehashedFvPpi->FvLength == FvLength)) {\r
+      ZeroMem (&DigestList, sizeof (TPML_DIGEST_VALUES));\r
 \r
-  DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei starts at: 0x%x\n", FvBlob.BlobBase));\r
-  DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei has the size: 0x%x\n", FvBlob.BlobLength));\r
+      //\r
+      // The FV is prehashed, check against TPM hash mask\r
+      //\r
+      PreHashInfo = (HASH_INFO *)(PrehashedFvPpi + 1);\r
+      for (Index = 0, DigestCount = 0; Index < PrehashedFvPpi->Count; Index++) {\r
+        DEBUG ((DEBUG_INFO, "Hash Algo ID in PrehashedFvPpi=0x%x\n", PreHashInfo->HashAlgoId));\r
+        HashAlgoMask = GetHashMaskFromAlgo (PreHashInfo->HashAlgoId);\r
+        if ((Tpm2HashMask & HashAlgoMask) != 0 ) {\r
+          //\r
+          // Hash is required, copy it to DigestList\r
+          //\r
+          WriteUnaligned16 (&(DigestList.digests[DigestCount].hashAlg), PreHashInfo->HashAlgoId);\r
+          CopyMem (\r
+            &DigestList.digests[DigestCount].digest,\r
+            PreHashInfo + 1,\r
+            PreHashInfo->HashSize\r
+            );\r
+          DigestCount++;\r
+          //\r
+          // Clean the corresponding Hash Algo mask bit\r
+          //\r
+          Tpm2HashMask &= ~HashAlgoMask;\r
+        }\r
 \r
-  TcgEventHdr.PCRIndex = 0;\r
-  TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
-  TcgEventHdr.EventSize = sizeof (FvBlob);\r
+        PreHashInfo = (HASH_INFO *)((UINT8 *)(PreHashInfo + 1) + PreHashInfo->HashSize);\r
+      }\r
 \r
-  Status = HashLogExtendEvent (\r
-             0,\r
-             (UINT8*) (UINTN) FvBlob.BlobBase,\r
-             (UINTN) FvBlob.BlobLength,\r
-             &TcgEventHdr,\r
-             (UINT8*) &FvBlob\r
-             );\r
+      WriteUnaligned32 (&DigestList.count, DigestCount);\r
+\r
+      break;\r
+    }\r
+\r
+    Instance++;\r
+  } while (!EFI_ERROR (Status));\r
+\r
+  //\r
+  // Search the matched migration FV info\r
+  //\r
+  FvOrgBase  = FvBase;\r
+  FvDataBase = FvBase;\r
+  Hob.Raw    = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);\r
+  while (Hob.Raw != NULL) {\r
+    MigratedFvInfo = GET_GUID_HOB_DATA (Hob);\r
+    if ((MigratedFvInfo->FvNewBase == (UINT32)FvBase) && (MigratedFvInfo->FvLength == (UINT32)FvLength)) {\r
+      //\r
+      // Found the migrated FV info\r
+      //\r
+      FvOrgBase  = (EFI_PHYSICAL_ADDRESS)(UINTN)MigratedFvInfo->FvOrgBase;\r
+      FvDataBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MigratedFvInfo->FvDataBase;\r
+      break;\r
+    }\r
+\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+    Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);\r
+  }\r
+\r
+  //\r
+  // Init the log event for FV measurement\r
+  //\r
+  if (PcdGet32 (PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105) {\r
+    FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription);\r
+    CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof (FvBlob2.BlobDescription));\r
+    FvName = GetFvName (FvBase, FvLength);\r
+    if (FvName != NULL) {\r
+      AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof (FvBlob2.BlobDescription), "Fv(%g)", FvName);\r
+    }\r
+\r
+    FvBlob2.BlobBase      = FvOrgBase;\r
+    FvBlob2.BlobLength    = FvLength;\r
+    TcgEventHdr.PCRIndex  = 0;\r
+    TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;\r
+    TcgEventHdr.EventSize = sizeof (FvBlob2);\r
+    EventData             = &FvBlob2;\r
+  } else {\r
+    FvBlob.BlobBase       = FvOrgBase;\r
+    FvBlob.BlobLength     = FvLength;\r
+    TcgEventHdr.PCRIndex  = 0;\r
+    TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
+    TcgEventHdr.EventSize = sizeof (FvBlob);\r
+    EventData             = &FvBlob;\r
+  }\r
+\r
+  if (Tpm2HashMask == 0) {\r
+    //\r
+    // FV pre-hash algos comply with current TPM hash requirement\r
+    // Skip hashing step in measure, only extend DigestList to PCR and log event\r
+    //\r
+    Status = HashLogExtendEvent (\r
+               &mEdkiiTcgPpi,\r
+               EDKII_TCG_PRE_HASH,\r
+               (UINT8 *)&DigestList,        // HashData\r
+               (UINTN)sizeof (DigestList),  // HashDataLen\r
+               &TcgEventHdr,                // EventHdr\r
+               EventData                    // EventData\r
+               );\r
+    DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei starts at: 0x%x\n", FvBase));\r
+    DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei has the size: 0x%x\n", FvLength));\r
+  } else {\r
+    //\r
+    // Hash the FV, extend digest to the TPM and log TCG event\r
+    //\r
+    Status = HashLogExtendEvent (\r
+               &mEdkiiTcgPpi,\r
+               0,\r
+               (UINT8 *)(UINTN)FvDataBase, // HashData\r
+               (UINTN)FvLength,            // HashDataLen\r
+               &TcgEventHdr,               // EventHdr\r
+               EventData                   // EventData\r
+               );\r
+    DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei starts at: 0x%x\n", FvBase));\r
+    DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei has the size: 0x%x\n", FvLength));\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: 0x%x\n", FvBase));\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Add new FV into the measured FV list.\r
   //\r
-  ASSERT (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
-  if (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
-    mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase   = FvBase;\r
-    mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;\r
-    mMeasuredBaseFvIndex++;\r
+  if (mMeasuredBaseFvIndex >= mMeasuredMaxBaseFvIndex) {\r
+    mMeasuredBaseFvInfo = ReallocatePool (\r
+                            sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * mMeasuredMaxBaseFvIndex,\r
+                            sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredMaxBaseFvIndex + FIRMWARE_BLOB_GROWTH_STEP),\r
+                            mMeasuredBaseFvInfo\r
+                            );\r
+    ASSERT (mMeasuredBaseFvInfo != NULL);\r
+    mMeasuredMaxBaseFvIndex = mMeasuredMaxBaseFvIndex + FIRMWARE_BLOB_GROWTH_STEP;\r
   }\r
 \r
+  mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase   = FvBase;\r
+  mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;\r
+  mMeasuredBaseFvIndex++;\r
+\r
   return Status;\r
 }\r
 \r
@@ -672,52 +811,49 @@ MeasureMainBios (
   VOID\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  UINT32                            FvInstances;\r
-  EFI_PEI_FV_HANDLE                 VolumeHandle;\r
-  EFI_FV_INFO                       VolumeInfo;\r
-  EFI_PEI_FIRMWARE_VOLUME_PPI       *FvPpi;\r
+  EFI_STATUS                   Status;\r
+  EFI_PEI_FV_HANDLE            VolumeHandle;\r
+  EFI_FV_INFO                  VolumeInfo;\r
+  EFI_PEI_FIRMWARE_VOLUME_PPI  *FvPpi;\r
 \r
   PERF_START_EX (mFileHandle, "EventRec", "Tcg2Pei", 0, PERF_ID_TCG2_PEI);\r
-  FvInstances    = 0;\r
-  while (TRUE) {\r
-    //\r
-    // Traverse all firmware volume instances of Static Core Root of Trust for Measurement\r
-    // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special\r
-    // platform for special CRTM TPM measuring.\r
-    //\r
-    Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-  \r
-    //\r
-    // Measure and record the firmware volume that is dispatched by PeiCore\r
-    //\r
-    Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);\r
-    ASSERT_EFI_ERROR (Status);\r
-    //\r
-    // Locate the corresponding FV_PPI according to founded FV's format guid\r
-    //\r
-    Status = PeiServicesLocatePpi (\r
-               &VolumeInfo.FvFormat, \r
-               0, \r
-               NULL,\r
-               (VOID**)&FvPpi\r
-               );\r
-    if (!EFI_ERROR (Status)) {\r
-      MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);\r
-    }\r
 \r
-    FvInstances++;\r
-  }\r
+  //\r
+  // Only measure BFV at the very beginning. Other parts of Static Core Root of\r
+  // Trust for Measurement(S-CRTM) will be measured later on FvInfoNotify.\r
+  // BFV is processed without installing FV Info Ppi. Other FVs either inside BFV or\r
+  // reported by platform will be installed with Fv Info Ppi\r
+  // This firmware volume measure policy can be modified/enhanced by special\r
+  // platform for special CRTM TPM measuring.\r
+  //\r
+  Status = PeiServicesFfsFindNextVolume (0, &VolumeHandle);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Measure and record the firmware volume that is dispatched by PeiCore\r
+  //\r
+  Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);\r
+  ASSERT_EFI_ERROR (Status);\r
+  //\r
+  // Locate the corresponding FV_PPI according to founded FV's format guid\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &VolumeInfo.FvFormat,\r
+             0,\r
+             NULL,\r
+             (VOID **)&FvPpi\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart, VolumeInfo.FvSize);\r
+\r
   PERF_END_EX (mFileHandle, "EventRec", "Tcg2Pei", 0, PERF_ID_TCG2_PEI + 1);\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 /**\r
-  Measure and record the Firmware Volum Information once FvInfoPPI install.\r
+  Measure and record the Firmware Volume Information once FvInfoPPI install.\r
 \r
   @param[in] PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
   @param[in] NotifyDescriptor  Address of the notification descriptor data structure.\r
@@ -729,10 +865,10 @@ MeasureMainBios (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-FirmwareVolmeInfoPpiNotifyCallback (\r
-  IN EFI_PEI_SERVICES               **PeiServices,\r
-  IN EFI_PEI_NOTIFY_DESCRIPTOR      *NotifyDescriptor,\r
-  IN VOID                           *Ppi\r
+FirmwareVolumeInfoPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
   )\r
 {\r
   EFI_PEI_FIRMWARE_VOLUME_INFO_PPI  *Fv;\r
@@ -740,45 +876,52 @@ FirmwareVolmeInfoPpiNotifyCallback (
   EFI_PEI_FIRMWARE_VOLUME_PPI       *FvPpi;\r
   UINTN                             Index;\r
 \r
-  Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;\r
+  Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;\r
 \r
   //\r
   // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.\r
   //\r
   Status = PeiServicesLocatePpi (\r
-             &Fv->FvFormat, \r
-             0, \r
+             &Fv->FvFormat,\r
+             0,\r
              NULL,\r
-             (VOID**)&FvPpi\r
+             (VOID **)&FvPpi\r
              );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   //\r
   // This is an FV from an FFS file, and the parent FV must have already been measured,\r
   // No need to measure twice, so just record the FV and return\r
   //\r
-  if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
-    \r
-    ASSERT (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
-    if (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
-      //\r
-      // Check whether FV is in the measured child FV list.\r
-      //\r
-      for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {\r
-        if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {\r
-          return EFI_SUCCESS;\r
-        }\r
+  if ((Fv->ParentFvName != NULL) || (Fv->ParentFileName != NULL)) {\r
+    if (mMeasuredChildFvIndex >= mMeasuredMaxChildFvIndex) {\r
+      mMeasuredChildFvInfo = ReallocatePool (\r
+                               sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * mMeasuredMaxChildFvIndex,\r
+                               sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP),\r
+                               mMeasuredChildFvInfo\r
+                               );\r
+      ASSERT (mMeasuredChildFvInfo != NULL);\r
+      mMeasuredMaxChildFvIndex = mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP;\r
+    }\r
+\r
+    //\r
+    // Check whether FV is in the measured child FV list.\r
+    //\r
+    for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {\r
+      if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo) {\r
+        return EFI_SUCCESS;\r
       }\r
-      mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase   = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;\r
-      mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
-      mMeasuredChildFvIndex++;\r
     }\r
+\r
+    mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase   = (EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo;\r
+    mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
+    mMeasuredChildFvIndex++;\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);\r
+  return MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo, Fv->FvInfoSize);\r
 }\r
 \r
 /**\r
@@ -793,29 +936,25 @@ FirmwareVolmeInfoPpiNotifyCallback (
 **/\r
 EFI_STATUS\r
 PeimEntryMP (\r
-  IN      EFI_PEI_SERVICES          **PeiServices\r
+  IN      EFI_PEI_SERVICES  **PeiServices\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
+  EFI_STATUS  Status;\r
 \r
-  Status = PeiServicesLocatePpi (\r
-               &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, \r
-               0, \r
-               NULL,\r
-               (VOID**)&mMeasurementExcludedFvPpi\r
-               );\r
-  // Do not check status, because it is optional\r
+  //\r
+  // install Tcg Services\r
+  //\r
+  Status = PeiServicesInstallPpi (&mTcgPpiList);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  mMeasuredBaseFvInfo  = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
-  ASSERT (mMeasuredBaseFvInfo != NULL);\r
-  mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
-  ASSERT (mMeasuredChildFvInfo != NULL);\r
-  \r
   if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) {\r
     Status = MeasureCRTMVersion ();\r
   }\r
 \r
   Status = MeasureMainBios ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Post callbacks:\r
@@ -831,7 +970,7 @@ PeimEntryMP (
 /**\r
   Measure and log Separator event with error, and extend the measurement result into a specific PCR.\r
 \r
-  @param[in] PCRIndex         PCR index.  \r
+  @param[in] PCRIndex         PCR index.\r
 \r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
@@ -839,20 +978,20 @@ PeimEntryMP (
 **/\r
 EFI_STATUS\r
 MeasureSeparatorEventWithError (\r
-  IN      TPM_PCRINDEX              PCRIndex\r
+  IN      TPM_PCRINDEX  PCRIndex\r
   )\r
 {\r
-  TCG_PCR_EVENT_HDR                 TcgEvent;\r
-  UINT32                            EventData;\r
+  TCG_PCR_EVENT_HDR  TcgEvent;\r
+  UINT32             EventData;\r
 \r
   //\r
   // Use EventData 0x1 to indicate there is error.\r
   //\r
-  EventData = 0x1;\r
+  EventData          = 0x1;\r
   TcgEvent.PCRIndex  = PCRIndex;\r
   TcgEvent.EventType = EV_SEPARATOR;\r
   TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
-  return HashLogExtendEvent(0,(UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent,(UINT8 *)&EventData);\r
+  return HashLogExtendEvent (&mEdkiiTcgPpi, 0, (UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent, (UINT8 *)&EventData);\r
 }\r
 \r
 /**\r
@@ -867,24 +1006,25 @@ MeasureSeparatorEventWithError (
 EFI_STATUS\r
 EFIAPI\r
 PeimEntryMA (\r
-  IN       EFI_PEI_FILE_HANDLE      FileHandle,\r
-  IN CONST EFI_PEI_SERVICES         **PeiServices\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  EFI_STATUS                        Status2;\r
-  EFI_BOOT_MODE                     BootMode;\r
-  TPM_PCRINDEX                      PcrIndex;\r
-  BOOLEAN                           S3ErrorReport;\r
-\r
-  if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
-      CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
-    DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));\r
+  EFI_STATUS     Status;\r
+  EFI_STATUS     Status2;\r
+  EFI_BOOT_MODE  BootMode;\r
+  TPM_PCRINDEX   PcrIndex;\r
+  BOOLEAN        S3ErrorReport;\r
+\r
+  if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
+      CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid))\r
+  {\r
+    DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
   if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
-    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
+    DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
@@ -895,10 +1035,10 @@ PeimEntryMA (
   // In S3 path, skip shadow logic. no measurement is required\r
   //\r
   if (BootMode != BOOT_ON_S3_RESUME) {\r
-    Status = (**PeiServices).RegisterForShadow(FileHandle);\r
+    Status = (**PeiServices).RegisterForShadow (FileHandle);\r
     if (Status == EFI_ALREADY_STARTED) {\r
       mImageInMemory = TRUE;\r
-      mFileHandle = FileHandle;\r
+      mFileHandle    = FileHandle;\r
     } else if (Status == EFI_NOT_FOUND) {\r
       ASSERT_EFI_ERROR (Status);\r
     }\r
@@ -918,24 +1058,25 @@ PeimEntryMA (
     if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {\r
       if (BootMode == BOOT_ON_S3_RESUME) {\r
         Status = Tpm2Startup (TPM_SU_STATE);\r
-        if (EFI_ERROR (Status) ) {\r
+        if (EFI_ERROR (Status)) {\r
           Status = Tpm2Startup (TPM_SU_CLEAR);\r
-          if (!EFI_ERROR(Status)) {\r
+          if (!EFI_ERROR (Status)) {\r
             S3ErrorReport = TRUE;\r
           }\r
         }\r
       } else {\r
         Status = Tpm2Startup (TPM_SU_CLEAR);\r
       }\r
-      if (EFI_ERROR (Status) ) {\r
+\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
     }\r
-    \r
+\r
     //\r
     // Update Tpm2HashMask according to PCR bank.\r
     //\r
-    SetTpm2HashMask ();\r
+    SyncPcrAllocationsAndPcrMask ();\r
 \r
     if (S3ErrorReport) {\r
       //\r
@@ -948,7 +1089,7 @@ PeimEntryMA (
       for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {\r
         Status = MeasureSeparatorEventWithError (PcrIndex);\r
         if (EFI_ERROR (Status)) {\r
-          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));\r
+          DEBUG ((DEBUG_ERROR, "Separator Event with Error not Measured. Error!\n"));\r
         }\r
       }\r
     }\r
@@ -965,29 +1106,37 @@ PeimEntryMA (
       }\r
     }\r
 \r
+    DEBUG_CODE_BEGIN ();\r
     //\r
-    // Only intall TpmInitializedPpi on success\r
+    // Peek into TPM PCR 00 before any BIOS measurement.\r
+    //\r
+    Tpm2PcrReadForActiveBank (00, NULL);\r
+    DEBUG_CODE_END ();\r
+\r
+    //\r
+    // Only install TpmInitializedPpi on success\r
     //\r
     Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);\r
     ASSERT_EFI_ERROR (Status);\r
   }\r
 \r
   if (mImageInMemory) {\r
-    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);\r
+    Status = PeimEntryMP ((EFI_PEI_SERVICES **)PeiServices);\r
     return Status;\r
   }\r
 \r
 Done:\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));\r
-    BuildGuidHob (&gTpmErrorHobGuid,0);\r
+    DEBUG ((DEBUG_ERROR, "TPM2 error! Build Hob\n"));\r
+    BuildGuidHob (&gTpmErrorHobGuid, 0);\r
     REPORT_STATUS_CODE (\r
       EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
       (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
       );\r
   }\r
+\r
   //\r
-  // Always intall TpmInitializationDonePpi no matter success or fail.\r
+  // Always install TpmInitializationDonePpi no matter success or fail.\r
   // Other driver can know TPM initialization state by TpmInitializedPpi.\r
   //\r
   Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);\r