]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg/Tcg2Dxe: Add PcdTcgPfpMeasurementRevision in SpecId event.
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
index 9080e4703233dbe5f196071f294f8c3730e3fe0c..6d17616c1ce4236509dbf76f3a0d1a2bea60d1cb 100644 (file)
@@ -1,15 +1,9 @@
 /** @file\r
   This module implements Tcg2 Protocol.\r
 /** @file\r
   This module implements Tcg2 Protocol.\r
-  \r
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
 \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 - 2019, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 **/\r
 \r
@@ -31,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/VariableWrite.h>\r
 #include <Protocol/Tcg2Protocol.h>\r
 #include <Protocol/TrEEProtocol.h>\r
 #include <Protocol/VariableWrite.h>\r
 #include <Protocol/Tcg2Protocol.h>\r
 #include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/ResetNotification.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -80,6 +75,7 @@ typedef struct {
   UINT8                             *LastEvent;\r
   BOOLEAN                           EventLogStarted;\r
   BOOLEAN                           EventLogTruncated;\r
   UINT8                             *LastEvent;\r
   BOOLEAN                           EventLogStarted;\r
   BOOLEAN                           EventLogTruncated;\r
+  UINTN                             Next800155EventOffset;\r
 } TCG_EVENT_LOG_AREA_STRUCT;\r
 \r
 typedef struct _TCG_DXE_DATA {\r
 } TCG_EVENT_LOG_AREA_STRUCT;\r
 \r
 typedef struct _TCG_DXE_DATA {\r
@@ -132,7 +128,7 @@ EFI_HANDLE mImageHandle;
   @param[in]  PCRIndex       TPM PCR index\r
   @param[in]  ImageAddress   Start address of image buffer.\r
   @param[in]  ImageSize      Image size\r
   @param[in]  PCRIndex       TPM PCR index\r
   @param[in]  ImageAddress   Start address of image buffer.\r
   @param[in]  ImageSize      Image size\r
-  @param[out] DigestList     Digeest list of this image.\r
+  @param[out] DigestList     Digest list of this image.\r
 \r
   @retval EFI_SUCCESS            Successfully measure image.\r
   @retval EFI_OUT_OF_RESOURCES   No enough resource to measure image.\r
 \r
   @retval EFI_SUCCESS            Successfully measure image.\r
   @retval EFI_OUT_OF_RESOURCES   No enough resource to measure image.\r
@@ -166,6 +162,82 @@ InternalDumpData (
   }\r
 }\r
 \r
   }\r
 }\r
 \r
+/**\r
+\r
+  This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event\r
+  The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types\r
+\r
+  @param[in, out]   NoActionEvent  Event Header of EV_NO_ACTION Event\r
+  @param[in]        EventSize      Event Size of the EV_NO_ACTION Event\r
+\r
+**/\r
+VOID\r
+InitNoActionEvent (\r
+  IN OUT TCG_PCR_EVENT2_HDR  *NoActionEvent,\r
+  IN UINT32                  EventSize\r
+ )\r
+{\r
+  UINT32          DigestListCount;\r
+  TPMI_ALG_HASH   HashAlgId;\r
+  UINT8           *DigestBuffer;\r
+\r
+  DigestBuffer    = (UINT8 *)NoActionEvent->Digests.digests;\r
+  DigestListCount = 0;\r
+\r
+  NoActionEvent->PCRIndex  = 0;\r
+  NoActionEvent->EventType = EV_NO_ACTION;\r
+\r
+  //\r
+  // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0\r
+  //\r
+  ZeroMem (&NoActionEvent->Digests, sizeof(NoActionEvent->Digests));\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+     HashAlgId = TPM_ALG_SHA1;\r
+     CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+     DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+     DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+     HashAlgId = TPM_ALG_SHA256;\r
+     CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+     DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+     DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+    HashAlgId = TPM_ALG_SHA384;\r
+    CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+    DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+    HashAlgId = TPM_ALG_SHA512;\r
+    CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+    DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
+    HashAlgId = TPM_ALG_SM3_256;\r
+    CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+    DigestListCount++;\r
+  }\r
+\r
+  //\r
+  // Set Digests Count\r
+  //\r
+  WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);\r
+\r
+  //\r
+  // Set Event Size\r
+  //\r
+  WriteUnaligned32((UINT32 *)DigestBuffer, EventSize);\r
+}\r
+\r
 /**\r
 \r
   This function dump raw data with colume format.\r
 /**\r
 \r
   This function dump raw data with colume format.\r
@@ -295,11 +367,11 @@ GetProcessorsCpuLocation (
 \r
   @retval EFI_SUCCESS            Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
 \r
   @retval EFI_SUCCESS            Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
-                                 The ProtocolCapability variable will not be populated. \r
+                                 The ProtocolCapability variable will not be populated.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
                                  The ProtocolCapability variable will not be populated.\r
   @retval EFI_BUFFER_TOO_SMALL   The ProtocolCapability variable is too small to hold the full response.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
                                  The ProtocolCapability variable will not be populated.\r
   @retval EFI_BUFFER_TOO_SMALL   The ProtocolCapability variable is too small to hold the full response.\r
-                                 It will be partially populated (required Size field will be set). \r
+                                 It will be partially populated (required Size field will be set).\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -313,7 +385,7 @@ Tcg2GetCapability (
   if ((This == NULL) || (ProtocolCapability == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if ((This == NULL) || (ProtocolCapability == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));\r
   DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));\r
 \r
   DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));\r
   DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));\r
 \r
@@ -321,7 +393,7 @@ Tcg2GetCapability (
     //\r
     // Handle the case that firmware support 1.1 but OS only support 1.0.\r
     //\r
     //\r
     // Handle the case that firmware support 1.1 but OS only support 1.0.\r
     //\r
-    if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) || \r
+    if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||\r
         ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {\r
       if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {\r
         CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));\r
         ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {\r
       if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {\r
         CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));\r
@@ -486,7 +558,7 @@ DumpEvent2 (
 \r
 /**\r
   This function returns size of TCG PCR event 2.\r
 \r
 /**\r
   This function returns size of TCG PCR event 2.\r
-  \r
+\r
   @param[in]  TcgPcrEvent2     TCG PCR event 2 structure.\r
 \r
   @return size of TCG PCR event 2.\r
   @param[in]  TcgPcrEvent2     TCG PCR event 2 structure.\r
 \r
   @return size of TCG PCR event 2.\r
@@ -546,7 +618,7 @@ DumpEventLog (
   UINTN                     NumberOfEvents;\r
 \r
   DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
   UINTN                     NumberOfEvents;\r
 \r
   DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
-  \r
+\r
   switch (EventLogFormat) {\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
   switch (EventLogFormat) {\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
@@ -570,7 +642,7 @@ DumpEventLog (
     break;\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
     //\r
     break;\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
     //\r
-    // Dump first event        \r
+    // Dump first event\r
     //\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
     DumpEvent (EventHdr);\r
     //\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
     DumpEvent (EventHdr);\r
@@ -605,7 +677,7 @@ DumpEventLog (
 \r
 /**\r
   The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to\r
 \r
 /**\r
   The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to\r
-  retrieve the address of a given event log and its last entry. \r
+  retrieve the address of a given event log and its last entry.\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  EventLogFormat     The type of the event log for which the information is requested.\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  EventLogFormat     The type of the event log for which the information is requested.\r
@@ -700,26 +772,51 @@ Tcg2GetEventLog (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Return if this is a Tcg800155PlatformIdEvent.\r
+\r
+  @param[in]      NewEventHdr         Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
+  @param[in]      NewEventHdrSize     New event header size.\r
+  @param[in]      NewEventData        Pointer to the new event data.\r
+  @param[in]      NewEventSize        New event data size.\r
+\r
+  @retval TRUE   This is a Tcg800155PlatformIdEvent.\r
+  @retval FALSE  This is NOT a Tcg800155PlatformIdEvent.\r
+\r
+**/\r
+BOOLEAN\r
+Is800155Event (\r
+  IN      VOID                      *NewEventHdr,\r
+  IN      UINT32                    NewEventHdrSize,\r
+  IN      UINT8                     *NewEventData,\r
+  IN      UINT32                    NewEventSize\r
+  )\r
+{\r
+  if ((((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType == EV_NO_ACTION) &&\r
+      (NewEventSize >= sizeof(TCG_Sp800_155_PlatformId_Event2)) &&\r
+      (CompareMem (NewEventData, TCG_Sp800_155_PlatformId_Event2_SIGNATURE,\r
+        sizeof(TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1) == 0)) {\r
+    return TRUE;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   Add a new entry to the Event Log.\r
 \r
 /**\r
   Add a new entry to the Event Log.\r
 \r
-  @param[in, out] EventLogPtr     Pointer to the Event Log data.  \r
-  @param[in, out] LogSize         Size of the Event Log.  \r
-  @param[in]      MaxSize         Maximum size of the Event Log.\r
-  @param[in]      NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.  \r
-  @param[in]      NewEventHdrSize New event header size.\r
-  @param[in]      NewEventData    Pointer to the new event data.  \r
-  @param[in]      NewEventSize    New event data size.\r
-  \r
+  @param[in, out] EventLogAreaStruct  The event log area data structure\r
+  @param[in]      NewEventHdr         Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
+  @param[in]      NewEventHdrSize     New event header size.\r
+  @param[in]      NewEventData        Pointer to the new event data.\r
+  @param[in]      NewEventSize        New event data size.\r
+\r
   @retval EFI_SUCCESS           The new event log entry was added.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
 \r
 **/\r
 EFI_STATUS\r
 TcgCommLogEvent (\r
   @retval EFI_SUCCESS           The new event log entry was added.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
 \r
 **/\r
 EFI_STATUS\r
 TcgCommLogEvent (\r
-  IN OUT  UINT8                     **EventLogPtr,\r
-  IN OUT  UINTN                     *LogSize,\r
-  IN      UINTN                     MaxSize,\r
+  IN OUT  TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct,\r
   IN      VOID                      *NewEventHdr,\r
   IN      UINT32                    NewEventHdrSize,\r
   IN      UINT8                     *NewEventData,\r
   IN      VOID                      *NewEventHdr,\r
   IN      UINT32                    NewEventHdrSize,\r
   IN      UINT8                     *NewEventData,\r
@@ -727,6 +824,7 @@ TcgCommLogEvent (
   )\r
 {\r
   UINTN                            NewLogSize;\r
   )\r
 {\r
   UINTN                            NewLogSize;\r
+  BOOLEAN                          Record800155Event;\r
 \r
   if (NewEventSize > MAX_ADDRESS -  NewEventHdrSize) {\r
     return EFI_OUT_OF_RESOURCES;\r
 \r
   if (NewEventSize > MAX_ADDRESS -  NewEventHdrSize) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -734,23 +832,55 @@ TcgCommLogEvent (
 \r
   NewLogSize = NewEventHdrSize + NewEventSize;\r
 \r
 \r
   NewLogSize = NewEventHdrSize + NewEventSize;\r
 \r
-  if (NewLogSize > MAX_ADDRESS -  *LogSize) {\r
+  if (NewLogSize > MAX_ADDRESS -  EventLogAreaStruct->EventLogSize) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  if (NewLogSize + *LogSize > MaxSize) {\r
-    DEBUG ((EFI_D_INFO, "  MaxSize    - 0x%x\n", MaxSize));\r
-    DEBUG ((EFI_D_INFO, "  NewLogSize - 0x%x\n", NewLogSize));\r
-    DEBUG ((EFI_D_INFO, "  LogSize    - 0x%x\n", *LogSize));\r
-    DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
+  if (NewLogSize + EventLogAreaStruct->EventLogSize > EventLogAreaStruct->Laml) {\r
+    DEBUG ((DEBUG_INFO, "  Laml       - 0x%x\n", EventLogAreaStruct->Laml));\r
+    DEBUG ((DEBUG_INFO, "  NewLogSize - 0x%x\n", NewLogSize));\r
+    DEBUG ((DEBUG_INFO, "  LogSize    - 0x%x\n", EventLogAreaStruct->EventLogSize));\r
+    DEBUG ((DEBUG_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  *EventLogPtr += *LogSize;\r
-  *LogSize += NewLogSize;\r
-  CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);\r
+  //\r
+  // Check 800-155 event\r
+  // Record to 800-155 event offset only.\r
+  // If the offset is 0, no need to record.\r
+  //\r
+  Record800155Event = Is800155Event (NewEventHdr, NewEventHdrSize, NewEventData, NewEventSize);\r
+  if (Record800155Event) {\r
+    if (EventLogAreaStruct->Next800155EventOffset != 0) {\r
+      CopyMem (\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewLogSize,\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,\r
+        EventLogAreaStruct->EventLogSize - EventLogAreaStruct->Next800155EventOffset\r
+        );\r
+\r
+      CopyMem (\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,\r
+        NewEventHdr,\r
+        NewEventHdrSize\r
+        );\r
+      CopyMem (\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewEventHdrSize,\r
+        NewEventData,\r
+        NewEventSize\r
+        );\r
+\r
+      EventLogAreaStruct->Next800155EventOffset += NewLogSize;\r
+      EventLogAreaStruct->LastEvent += NewLogSize;\r
+      EventLogAreaStruct->EventLogSize += NewLogSize;\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  EventLogAreaStruct->LastEvent = (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->EventLogSize;\r
+  EventLogAreaStruct->EventLogSize += NewLogSize;\r
+  CopyMem (EventLogAreaStruct->LastEvent, NewEventHdr, NewEventHdrSize);\r
   CopyMem (\r
   CopyMem (\r
-    *EventLogPtr + NewEventHdrSize,\r
+    EventLogAreaStruct->LastEvent + NewEventHdrSize,\r
     NewEventData,\r
     NewEventSize\r
     );\r
     NewEventData,\r
     NewEventSize\r
     );\r
@@ -761,9 +891,9 @@ TcgCommLogEvent (
   Add a new entry to the Event Log.\r
 \r
   @param[in] EventLogFormat  The type of the event log for which the information is requested.\r
   Add a new entry to the Event Log.\r
 \r
   @param[in] EventLogFormat  The type of the event log for which the information is requested.\r
-  @param[in] NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.  \r
+  @param[in] NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
   @param[in] NewEventHdrSize New event header size.\r
   @param[in] NewEventHdrSize New event header size.\r
-  @param[in] NewEventData    Pointer to the new event data.  \r
+  @param[in] NewEventData    Pointer to the new event data.\r
   @param[in] NewEventSize    New event data size.\r
 \r
   @retval EFI_SUCCESS           The new event log entry was added.\r
   @param[in] NewEventSize    New event data size.\r
 \r
   @retval EFI_SUCCESS           The new event log entry was added.\r
@@ -782,7 +912,7 @@ TcgDxeLogEvent (
   EFI_STATUS                Status;\r
   UINTN                     Index;\r
   TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;\r
   EFI_STATUS                Status;\r
   UINTN                     Index;\r
   TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;\r
-  \r
+\r
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
       break;\r
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
       break;\r
@@ -802,17 +932,14 @@ TcgDxeLogEvent (
     return EFI_VOLUME_FULL;\r
   }\r
 \r
     return EFI_VOLUME_FULL;\r
   }\r
 \r
-  EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
   Status = TcgCommLogEvent (\r
   Status = TcgCommLogEvent (\r
-             &EventLogAreaStruct->LastEvent,\r
-             &EventLogAreaStruct->EventLogSize,\r
-             (UINTN)EventLogAreaStruct->Laml,\r
+             EventLogAreaStruct,\r
              NewEventHdr,\r
              NewEventHdrSize,\r
              NewEventData,\r
              NewEventSize\r
              );\r
              NewEventHdr,\r
              NewEventHdrSize,\r
              NewEventData,\r
              NewEventSize\r
              );\r
-  \r
+\r
   if (Status == EFI_OUT_OF_RESOURCES) {\r
     EventLogAreaStruct->EventLogTruncated = TRUE;\r
     return EFI_VOLUME_FULL;\r
   if (Status == EFI_OUT_OF_RESOURCES) {\r
     EventLogAreaStruct->EventLogTruncated = TRUE;\r
     return EFI_VOLUME_FULL;\r
@@ -836,11 +963,8 @@ TcgDxeLogEvent (
       return EFI_VOLUME_FULL;\r
     }\r
 \r
       return EFI_VOLUME_FULL;\r
     }\r
 \r
-    EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
     Status = TcgCommLogEvent (\r
     Status = TcgCommLogEvent (\r
-               &EventLogAreaStruct->LastEvent,\r
-               &EventLogAreaStruct->EventLogSize,\r
-               (UINTN)EventLogAreaStruct->Laml,\r
+               EventLogAreaStruct,\r
                NewEventHdr,\r
                NewEventHdrSize,\r
                NewEventData,\r
                NewEventHdr,\r
                NewEventHdrSize,\r
                NewEventData,\r
@@ -856,38 +980,13 @@ TcgDxeLogEvent (
       //\r
       (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;\r
       DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));\r
       //\r
       (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;\r
       DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));\r
-      DEBUG ((EFI_D_INFO, "  Size - 0x%x\n", (UINTN)EventLogAreaStruct->LastEvent - (UINTN)mTcgDxeData.FinalEventsTable[Index]));\r
+      DEBUG ((EFI_D_INFO, "  Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));\r
     }\r
   }\r
 \r
   return Status;\r
 }\r
 \r
     }\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-/**\r
-  Get TPML_DIGEST_VALUES data size.\r
-\r
-  @param[in]     DigestList    TPML_DIGEST_VALUES data.\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
-  }\r
-\r
-  return TotalSize;\r
-}\r
-\r
 /**\r
   Get TPML_DIGEST_VALUES compact binary buffer size.\r
 \r
 /**\r
   Get TPML_DIGEST_VALUES compact binary buffer size.\r
 \r
@@ -923,79 +1022,55 @@ GetDigestListBinSize (
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Return if hash alg is supported in TPM PCR bank.\r
+  Copy TPML_DIGEST_VALUES compact binary into a buffer\r
 \r
 \r
-  @param HashAlg  Hash algorithm to be checked.\r
+  @param[in,out]    Buffer                  Buffer to hold copied TPML_DIGEST_VALUES compact binary.\r
+  @param[in]        DigestListBin           TPML_DIGEST_VALUES compact binary buffer.\r
+  @param[in]        HashAlgorithmMask       HASH bits corresponding to the desired digests to copy.\r
+  @param[out]       HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.\r
 \r
 \r
-  @retval TRUE  Hash algorithm is supported.\r
-  @retval FALSE Hash algorithm is not supported.\r
+  @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.\r
 **/\r
 **/\r
-BOOLEAN\r
-IsHashAlgSupportedInPcrBank (\r
-  IN TPMI_ALG_HASH  HashAlg\r
+VOID *\r
+CopyDigestListBinToBuffer (\r
+  IN OUT VOID                       *Buffer,\r
+  IN VOID                           *DigestListBin,\r
+  IN UINT32                         HashAlgorithmMask,\r
+  OUT UINT32                        *HashAlgorithmMaskCopied\r
   )\r
 {\r
   )\r
 {\r
-  switch (HashAlg) {\r
-  case TPM_ALG_SHA1:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA256:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA384:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA512:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SM3_256:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
+  UINTN         Index;\r
+  UINT16        DigestSize;\r
+  UINT32        Count;\r
+  TPMI_ALG_HASH HashAlg;\r
+  UINT32        DigestListCount;\r
+  UINT32        *DigestListCountPtr;\r
 \r
 \r
-/**\r
-  Copy TPML_DIGEST_VALUES into a buffer\r
+  DigestListCountPtr = (UINT32 *) Buffer;\r
+  DigestListCount = 0;\r
+  (*HashAlgorithmMaskCopied) = 0;\r
 \r
 \r
-  @param[in,out] Buffer        Buffer to hold TPML_DIGEST_VALUES.\r
-  @param[in]     DigestList    TPML_DIGEST_VALUES to be copied.\r
+  Count = ReadUnaligned32 (DigestListBin);\r
+  Buffer = (UINT8 *)Buffer + sizeof(Count);\r
+  DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);\r
+  for (Index = 0; Index < Count; Index++) {\r
+    HashAlg = ReadUnaligned16 (DigestListBin);\r
+    DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);\r
+    DigestSize = GetHashSizeFromAlgo (HashAlg);\r
 \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
+    if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg, HashAlgorithmMask)) {\r
+      CopyMem (Buffer, &HashAlg, sizeof(HashAlg));\r
+      Buffer = (UINT8 *)Buffer + sizeof(HashAlg);\r
+      CopyMem (Buffer, DigestListBin, DigestSize);\r
+      Buffer = (UINT8 *)Buffer + DigestSize;\r
+      DigestListCount++;\r
+      (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);\r
+    } else {\r
+      DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));\r
     }\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
+    DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
   }\r
   }\r
+  WriteUnaligned32 (DigestListCountPtr, DigestListCount);\r
 \r
   return Buffer;\r
 }\r
 \r
   return Buffer;\r
 }\r
@@ -1023,6 +1098,7 @@ TcgDxeLogHashEvent (
   EFI_STATUS                        RetStatus;\r
   TCG_PCR_EVENT2                    TcgPcrEvent2;\r
   UINT8                             *DigestBuffer;\r
   EFI_STATUS                        RetStatus;\r
   TCG_PCR_EVENT2                    TcgPcrEvent2;\r
   UINT8                             *DigestBuffer;\r
+  UINT32                            *EventSizePtr;\r
 \r
   DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
 \r
 \r
   DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
 \r
@@ -1059,9 +1135,8 @@ TcgDxeLogHashEvent (
         TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;\r
         TcgPcrEvent2.EventType = NewEventHdr->EventType;\r
         DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;\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(NewEventHdr->EventSize));\r
-        DigestBuffer = DigestBuffer + sizeof(NewEventHdr->EventSize);\r
+        EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, mTcgDxeData.BsCap.ActivePcrBanks);\r
+        CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));\r
 \r
         //\r
         // Enter critical region\r
 \r
         //\r
         // Enter critical region\r
@@ -1070,7 +1145,7 @@ TcgDxeLogHashEvent (
         Status = TcgDxeLogEvent (\r
                    mTcg2EventInfo[Index].LogFormat,\r
                    &TcgPcrEvent2,\r
         Status = TcgDxeLogEvent (\r
                    mTcg2EventInfo[Index].LogFormat,\r
                    &TcgPcrEvent2,\r
-                   sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2.EventSize),\r
+                   sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof(TcgPcrEvent2.EventSize),\r
                    NewEventData,\r
                    NewEventHdr->EventSize\r
                    );\r
                    NewEventData,\r
                    NewEventHdr->EventSize\r
                    );\r
@@ -1094,11 +1169,11 @@ TcgDxeLogHashEvent (
   and add an entry to the Event Log.\r
 \r
   @param[in]      Flags         Bitmap providing additional information.\r
   and add an entry to the Event Log.\r
 \r
   @param[in]      Flags         Bitmap providing additional information.\r
-  @param[in]      HashData      Physical address of the start of the data buffer \r
+  @param[in]      HashData      Physical address of the start of the data buffer\r
                                 to be hashed, extended, and logged.\r
   @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData\r
                                 to be hashed, extended, and logged.\r
   @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData\r
-  @param[in, out] NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.  \r
-  @param[in]      NewEventData  Pointer to the new event data.  \r
+  @param[in, out] 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
 \r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
@@ -1116,11 +1191,25 @@ TcgDxeHashLogExtendEvent (
 {\r
   EFI_STATUS                        Status;\r
   TPML_DIGEST_VALUES                DigestList;\r
 {\r
   EFI_STATUS                        Status;\r
   TPML_DIGEST_VALUES                DigestList;\r
+  TCG_PCR_EVENT2_HDR                NoActionEvent;\r
 \r
   if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
 \r
   if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  if (NewEventHdr->EventType == EV_NO_ACTION) {\r
+    //\r
+    // Do not do TPM extend for EV_NO_ACTION\r
+    //\r
+    Status = EFI_SUCCESS;\r
+    InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);\r
+    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
+      Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);\r
+    }\r
+\r
+    return Status;\r
+  }\r
+\r
   Status = HashAndExtend (\r
              NewEventHdr->PCRIndex,\r
              HashData,\r
   Status = HashAndExtend (\r
              NewEventHdr->PCRIndex,\r
              HashData,\r
@@ -1148,13 +1237,13 @@ TcgDxeHashLogExtendEvent (
 /**\r
   The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
   an opportunity to extend and optionally log events without requiring\r
 /**\r
   The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
   an opportunity to extend and optionally log events without requiring\r
-  knowledge of actual TPM commands. \r
+  knowledge of actual TPM commands.\r
   The extend operation will occur even if this function cannot create an event\r
   The extend operation will occur even if this function cannot create an event\r
-  log entry (e.g. due to the event log being full). \r
+  log entry (e.g. due to the event log being full).\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  Flags              Bitmap providing additional information.\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  Flags              Bitmap providing additional information.\r
-  @param[in]  DataToHash         Physical address of the start of the data buffer to be hashed. \r
+  @param[in]  DataToHash         Physical address of the start of the data buffer to be hashed.\r
   @param[in]  DataToHashLen      The length in bytes of the buffer referenced by DataToHash.\r
   @param[in]  Event              Pointer to data buffer containing information about the event.\r
 \r
   @param[in]  DataToHashLen      The length in bytes of the buffer referenced by DataToHash.\r
   @param[in]  Event              Pointer to data buffer containing information about the event.\r
 \r
@@ -1180,7 +1269,13 @@ Tcg2HashLogExtendEvent (
 \r
   DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));\r
 \r
 \r
   DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));\r
 \r
-  if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {\r
+  if ((This == NULL) || (Event == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Do not check hash data size for EV_NO_ACTION event.\r
+  //\r
+  if ((Event->Header.EventType != EV_NO_ACTION) && (DataToHash == 0)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1244,7 +1339,7 @@ Tcg2HashLogExtendEvent (
   @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.\r
   @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
   @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.\r
   @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
-  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small. \r
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1294,7 +1389,7 @@ Tcg2SubmitCommand (
   @param[out] ActivePcrBanks  Pointer to the variable receiving the bitmap of currently active PCR banks.\r
 \r
   @retval EFI_SUCCESS           The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
   @param[out] ActivePcrBanks  Pointer to the variable receiving the bitmap of currently active PCR banks.\r
 \r
   @retval EFI_SUCCESS           The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
-  @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. \r
+  @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1384,7 +1479,7 @@ Tcg2GetResultOfSetActivePcrBanks (
   if ((OperationPresent == NULL) || (Response == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if ((OperationPresent == NULL) || (Response == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
   if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
     return EFI_SUCCESS;\r
   ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
   if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
     return EFI_SUCCESS;\r
@@ -1420,15 +1515,22 @@ SetupEventLog (
   EFI_PEI_HOB_POINTERS            GuidHob;\r
   EFI_PHYSICAL_ADDRESS            Lasa;\r
   UINTN                           Index;\r
   EFI_PEI_HOB_POINTERS            GuidHob;\r
   EFI_PHYSICAL_ADDRESS            Lasa;\r
   UINTN                           Index;\r
+  VOID                            *DigestListBin;\r
+  TPML_DIGEST_VALUES              TempDigestListBin;\r
   UINT32                          DigestListBinSize;\r
   UINT32                          DigestListBinSize;\r
+  UINT8                           *Event;\r
   UINT32                          EventSize;\r
   UINT32                          EventSize;\r
+  UINT32                          *EventSizePtr;\r
+  UINT32                          HashAlgorithmMaskCopied;\r
   TCG_EfiSpecIDEventStruct        *TcgEfiSpecIdEventStruct;\r
   UINT8                           TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
   TCG_EfiSpecIDEventStruct        *TcgEfiSpecIdEventStruct;\r
   UINT8                           TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
-  TCG_PCR_EVENT_HDR               FirstPcrEvent;\r
+  TCG_PCR_EVENT_HDR               SpecIdEvent;\r
+  TCG_PCR_EVENT2_HDR              NoActionEvent;\r
   TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
   TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
   UINT8                           *VendorInfoSize;\r
   UINT32                          NumberOfAlgorithms;\r
   TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
   TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
   UINT8                           *VendorInfoSize;\r
   UINT32                          NumberOfAlgorithms;\r
+  TCG_EfiStartupLocalityEvent     StartupLocalityEvent;\r
 \r
   DEBUG ((EFI_D_INFO, "SetupEventLog\n"));\r
 \r
 \r
   DEBUG ((EFI_D_INFO, "SetupEventLog\n"));\r
 \r
@@ -1438,20 +1540,40 @@ SetupEventLog (
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
-      Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
-      Status = gBS->AllocatePages (\r
-                      AllocateMaxAddress,\r
-                      EfiBootServicesData,\r
-                      EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
-                      &Lasa\r
-                      );\r
+      if (PcdGet8(PcdTpm2AcpiTableRev) >= 4) {\r
+        Status = gBS->AllocatePages (\r
+                        AllocateAnyPages,\r
+                        EfiACPIMemoryNVS,\r
+                        EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
+                        &Lasa\r
+                        );\r
+      } else {\r
+        Status = gBS->AllocatePages (\r
+                        AllocateAnyPages,\r
+                        EfiBootServicesData,\r
+                        EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
+                        &Lasa\r
+                        );\r
+      }\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
       mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
       mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
       mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
       mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
+      mTcgDxeData.EventLogAreaStruct[Index].Next800155EventOffset = 0;\r
+\r
+      if ((PcdGet8(PcdTpm2AcpiTableRev) >= 4) ||\r
+          (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)) {\r
+        //\r
+        // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.\r
+        // Ignore the return status, because those fields are optional.\r
+        //\r
+        PcdSet32S(PcdTpm2AcpiTableLaml, (UINT32)mTcgDxeData.EventLogAreaStruct[Index].Laml);\r
+        PcdSet64S(PcdTpm2AcpiTableLasa, mTcgDxeData.EventLogAreaStruct[Index].Lasa);\r
+      }\r
+\r
       //\r
       //\r
-      // To initialize them as 0xFF is recommended \r
+      // To initialize them as 0xFF is recommended\r
       // because the OS can know the last entry for that.\r
       //\r
       SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
       // because the OS can know the last entry for that.\r
       //\r
       SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
@@ -1467,7 +1589,7 @@ SetupEventLog (
         TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
         TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
         TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
         TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
         TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
         TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
-        TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;\r
+        TcgEfiSpecIdEventStruct->specErrata = (UINT8)PcdGet32(PcdTcgPfpMeasurementRevision);\r
         TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);\r
         NumberOfAlgorithms = 0;\r
         DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
         TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);\r
         NumberOfAlgorithms = 0;\r
         DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
@@ -1512,24 +1634,79 @@ SetupEventLog (
         VendorInfoSize = (UINT8 *)TempDigestSize;\r
         *VendorInfoSize = 0;\r
 \r
         VendorInfoSize = (UINT8 *)TempDigestSize;\r
         *VendorInfoSize = 0;\r
 \r
-        //\r
-        // FirstPcrEvent\r
-        //\r
-        FirstPcrEvent.PCRIndex = 0;\r
-        FirstPcrEvent.EventType = EV_NO_ACTION;\r
-        ZeroMem (&FirstPcrEvent.Digest, sizeof(FirstPcrEvent.Digest));\r
-        FirstPcrEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
+        SpecIdEvent.PCRIndex = 0;\r
+        SpecIdEvent.EventType = EV_NO_ACTION;\r
+        ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));\r
+        SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
 \r
         //\r
 \r
         //\r
-        // Record\r
+        // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.\r
+        //   TCG EFI Protocol Spec. Section 5.3 Event Log Header\r
+        //   TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log\r
         //\r
         Status = TcgDxeLogEvent (\r
                    mTcg2EventInfo[Index].LogFormat,\r
         //\r
         Status = TcgDxeLogEvent (\r
                    mTcg2EventInfo[Index].LogFormat,\r
-                   &FirstPcrEvent,\r
-                   sizeof(FirstPcrEvent),\r
+                   &SpecIdEvent,\r
+                   sizeof(SpecIdEvent),\r
                    (UINT8 *)TcgEfiSpecIdEventStruct,\r
                    (UINT8 *)TcgEfiSpecIdEventStruct,\r
-                   FirstPcrEvent.EventSize\r
+                   SpecIdEvent.EventSize\r
                    );\r
                    );\r
+        //\r
+        // record the offset at the end of 800-155 event.\r
+        // the future 800-155 event can be inserted here.\r
+        //\r
+        mTcgDxeData.EventLogAreaStruct[Index].Next800155EventOffset = \\r
+          mTcgDxeData.EventLogAreaStruct[Index].EventLogSize;\r
+\r
+        //\r
+        // Tcg800155PlatformIdEvent. Event format is TCG_PCR_EVENT2\r
+        //\r
+        GuidHob.Guid = GetFirstGuidHob (&gTcg800155PlatformIdEventHobGuid);\r
+        while (GuidHob.Guid != NULL) {\r
+          InitNoActionEvent(&NoActionEvent, GET_GUID_HOB_DATA_SIZE (GuidHob.Guid));\r
+\r
+          Status = TcgDxeLogEvent (\r
+                     mTcg2EventInfo[Index].LogFormat,\r
+                     &NoActionEvent,\r
+                     sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
+                     GET_GUID_HOB_DATA (GuidHob.Guid),\r
+                     GET_GUID_HOB_DATA_SIZE (GuidHob.Guid)\r
+                     );\r
+\r
+          GuidHob.Guid = GET_NEXT_HOB (GuidHob);\r
+          GuidHob.Guid = GetNextGuidHob (&gTcg800155PlatformIdEventHobGuid, GuidHob.Guid);\r
+        }\r
+\r
+        //\r
+        // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2\r
+        //\r
+        GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
+        if (GuidHob.Guid != NULL) {\r
+          //\r
+          // Get Locality Indicator from StartupLocality HOB\r
+          //\r
+          StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
+          CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));\r
+          DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));\r
+\r
+          //\r
+          // Initialize StartupLocalityEvent\r
+          //\r
+          InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));\r
+\r
+          //\r
+          // Log EfiStartupLocalityEvent as the second Event\r
+          //   TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event\r
+          //\r
+          Status = TcgDxeLogEvent (\r
+                     mTcg2EventInfo[Index].LogFormat,\r
+                     &NoActionEvent,\r
+                     sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
+                     (UINT8 *)&StartupLocalityEvent,\r
+                     sizeof(StartupLocalityEvent)\r
+                     );\r
+\r
+        }\r
       }\r
     }\r
   }\r
       }\r
     }\r
   }\r
@@ -1540,9 +1717,8 @@ SetupEventLog (
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
-        Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
         Status = gBS->AllocatePages (\r
         Status = gBS->AllocatePages (\r
-                        AllocateMaxAddress,\r
+                        AllocateAnyPages,\r
                         EfiACPIMemoryNVS,\r
                         EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),\r
                         &Lasa\r
                         EfiACPIMemoryNVS,\r
                         EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),\r
                         &Lasa\r
@@ -1566,9 +1742,10 @@ SetupEventLog (
         mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;\r
 \r
         //\r
 \r
         //\r
-        // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 \r
+        // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2\r
         //\r
         Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
         if (EFI_ERROR (Status)) {\r
         //\r
         Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
         if (EFI_ERROR (Status)) {\r
@@ -1586,10 +1763,11 @@ SetupEventLog (
         mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;\r
       }\r
     }\r
   }\r
       }\r
     }\r
   }\r
-  \r
+\r
   //\r
   // 3. Sync data from PEI to DXE\r
   //\r
   //\r
   // 3. Sync data from PEI to DXE\r
   //\r
@@ -1598,9 +1776,10 @@ SetupEventLog (
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       GuidHob.Raw = GetHobList ();\r
       Status = EFI_SUCCESS;\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       GuidHob.Raw = GetHobList ();\r
       Status = EFI_SUCCESS;\r
-      while (!EFI_ERROR (Status) && \r
+      while (!EFI_ERROR (Status) &&\r
              (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
              (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
-        TcgEvent    = GET_GUID_HOB_DATA (GuidHob.Guid);\r
+        TcgEvent    = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));\r
+        ASSERT (TcgEvent != NULL);\r
         GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
         switch (mTcg2EventInfo[Index].LogFormat) {\r
         case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
         GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
         switch (mTcg2EventInfo[Index].LogFormat) {\r
         case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
@@ -1613,17 +1792,47 @@ SetupEventLog (
                      );\r
           break;\r
         case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
                      );\r
           break;\r
         case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
-          DigestListBinSize = GetDigestListBinSize ((UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE));\r
-          CopyMem (&EventSize, (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize, sizeof(UINT32));\r
+          DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);\r
+          DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
+          //\r
+          // Save event size.\r
+          //\r
+          CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));\r
+          Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);\r
+          //\r
+          // Filter inactive digest in the event2 log from PEI HOB.\r
+          //\r
+          CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));\r
+          EventSizePtr = CopyDigestListBinToBuffer (\r
+                           DigestListBin,\r
+                           &TempDigestListBin,\r
+                           mTcgDxeData.BsCap.ActivePcrBanks,\r
+                           &HashAlgorithmMaskCopied\r
+                           );\r
+          if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {\r
+            DEBUG ((\r
+              DEBUG_ERROR,\r
+              "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",\r
+              HashAlgorithmMaskCopied,\r
+              mTcgDxeData.BsCap.ActivePcrBanks\r
+              ));\r
+          }\r
+          //\r
+          // Restore event size.\r
+          //\r
+          CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));\r
+          DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
+\r
           Status = TcgDxeLogEvent (\r
                      mTcg2EventInfo[Index].LogFormat,\r
                      TcgEvent,\r
                      sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
           Status = TcgDxeLogEvent (\r
                      mTcg2EventInfo[Index].LogFormat,\r
                      TcgEvent,\r
                      sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
-                     (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
+                     Event,\r
                      EventSize\r
                      );\r
           break;\r
         }\r
                      EventSize\r
                      );\r
           break;\r
         }\r
+        FreePool (TcgEvent);\r
       }\r
     }\r
   }\r
       }\r
     }\r
   }\r
@@ -1632,22 +1841,24 @@ SetupEventLog (
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Measure and log an action string, and extend the measurement result into PCR[5].\r
+  Measure and log an action string, and extend the measurement result into PCR[PCRIndex].\r
+\r
+  @param[in] PCRIndex         PCRIndex to extend\r
+  @param[in] String           A specific string that indicates an Action event.\r
 \r
 \r
-  @param[in] String           A specific string that indicates an Action event.  \r
-  \r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
 \r
 **/\r
 EFI_STATUS\r
 TcgMeasureAction (\r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
 \r
 **/\r
 EFI_STATUS\r
 TcgMeasureAction (\r
-  IN      CHAR8                     *String\r
+  IN      TPM_PCRINDEX       PCRIndex,\r
+  IN      CHAR8              *String\r
   )\r
 {\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
 \r
   )\r
 {\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
 \r
-  TcgEvent.PCRIndex  = 5;\r
+  TcgEvent.PCRIndex  = PCRIndex;\r
   TcgEvent.EventType = EV_EFI_ACTION;\r
   TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
   return TcgDxeHashLogExtendEvent (\r
   TcgEvent.EventType = EV_EFI_ACTION;\r
   TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
   return TcgDxeHashLogExtendEvent (\r
@@ -1682,7 +1893,7 @@ MeasureHandoffTables (
 \r
   if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
     //\r
 \r
   if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
     //\r
-    // Tcg Server spec. \r
+    // Tcg Server spec.\r
     // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
     //\r
     Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
     // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
     //\r
     Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
@@ -1714,7 +1925,7 @@ MeasureHandoffTables (
 /**\r
   Measure and log Separator event, and extend the measurement result into a specific PCR.\r
 \r
 /**\r
   Measure and log Separator event, 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
 \r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
@@ -1746,13 +1957,13 @@ MeasureSeparatorEvent (
 /**\r
   Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
 \r
 /**\r
   Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
 \r
-  @param[in]  PCRIndex          PCR Index.  \r
-  @param[in]  EventType         Event type.  \r
+  @param[in]  PCRIndex          PCR Index.\r
+  @param[in]  EventType         Event type.\r
   @param[in]  VarName           A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]  VendorGuid        A unique identifier for the vendor.\r
   @param[in]  VarName           A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]  VendorGuid        A unique identifier for the vendor.\r
-  @param[in]  VarData           The content of the variable data.  \r
-  @param[in]  VarSize           The size of the variable data.  \r
\r
+  @param[in]  VarData           The content of the variable data.\r
+  @param[in]  VarSize           The size of the variable data.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -1771,7 +1982,7 @@ MeasureVariable (
   EFI_STATUS                        Status;\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
   UINTN                             VarNameLength;\r
   EFI_STATUS                        Status;\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
   UINTN                             VarNameLength;\r
-  EFI_VARIABLE_DATA_TREE            *VarLog;\r
+  UEFI_VARIABLE_DATA                *VarLog;\r
 \r
   DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
   DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
 \r
   DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
   DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
@@ -1783,7 +1994,7 @@ MeasureVariable (
   TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
                         - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
 \r
   TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
                         - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
 \r
-  VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize);\r
+  VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);\r
   if (VarLog == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   if (VarLog == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -1806,7 +2017,7 @@ MeasureVariable (
 \r
   if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
     //\r
 \r
   if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
     //\r
-    // Digest is the event data (EFI_VARIABLE_DATA)\r
+    // Digest is the event data (UEFI_VARIABLE_DATA)\r
     //\r
     Status = TcgDxeHashLogExtendEvent (\r
                0,\r
     //\r
     Status = TcgDxeHashLogExtendEvent (\r
                0,\r
@@ -1816,6 +2027,7 @@ MeasureVariable (
                (UINT8*)VarLog\r
                );\r
   } else {\r
                (UINT8*)VarLog\r
                );\r
   } else {\r
+    ASSERT (VarData != NULL);\r
     Status = TcgDxeHashLogExtendEvent (\r
                0,\r
                (UINT8*)VarData,\r
     Status = TcgDxeHashLogExtendEvent (\r
                0,\r
                (UINT8*)VarData,\r
@@ -1831,13 +2043,13 @@ MeasureVariable (
 /**\r
   Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
 \r
 /**\r
   Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
 \r
-  @param[in]  PCRIndex          PCR Index.  \r
-  @param[in]  EventType         Event type.  \r
+  @param[in]  PCRIndex          PCR Index.\r
+  @param[in]  EventType         Event type.\r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
-  @param[out]  VarSize          The size of the variable data.  \r
-  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @param[out]  VarSize          The size of the variable data.\r
+  @param[out]  VarData          Pointer to the content of the variable.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -1885,13 +2097,14 @@ ReadAndMeasureVariable (
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].\r
+  Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].\r
+according to TCG PC Client PFP spec 0021 Section 2.4.4.2\r
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
-  @param[out]  VarSize          The size of the variable data.  \r
-  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @param[out]  VarSize          The size of the variable data.\r
+  @param[out]  VarData          Pointer to the content of the variable.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -1906,7 +2119,7 @@ ReadAndMeasureBootVariable (
   )\r
 {\r
   return ReadAndMeasureVariable (\r
   )\r
 {\r
   return ReadAndMeasureVariable (\r
-           5,\r
+           1,\r
            EV_EFI_VARIABLE_BOOT,\r
            VarName,\r
            VendorGuid,\r
            EV_EFI_VARIABLE_BOOT,\r
            VarName,\r
            VendorGuid,\r
@@ -1920,9 +2133,9 @@ ReadAndMeasureBootVariable (
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
-  @param[out]  VarSize          The size of the variable data.  \r
-  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @param[out]  VarSize          The size of the variable data.\r
+  @param[out]  VarData          Pointer to the content of the variable.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -2039,6 +2252,24 @@ MeasureAllSecureVariables (
     }\r
   }\r
 \r
     }\r
   }\r
 \r
+  //\r
+  // Measure DBT if present and not empty\r
+  //\r
+  Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);\r
+  if (!EFI_ERROR(Status)) {\r
+    Status = MeasureVariable (\r
+               7,\r
+               EV_EFI_VARIABLE_DRIVER_CONFIG,\r
+               EFI_IMAGE_SECURITY_DATABASE2,\r
+               &gEfiImageSecurityDatabaseGuid,\r
+               Data,\r
+               DataSize\r
+               );\r
+    FreePool(Data);\r
+  } else {\r
+    DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -2163,6 +2394,7 @@ OnReadyToBoot (
     // 1. This is the first boot attempt.\r
     //\r
     Status = TcgMeasureAction (\r
     // 1. This is the first boot attempt.\r
     //\r
     Status = TcgMeasureAction (\r
+               4,\r
                EFI_CALLING_EFI_APPLICATION\r
                );\r
     if (EFI_ERROR (Status)) {\r
                EFI_CALLING_EFI_APPLICATION\r
                );\r
     if (EFI_ERROR (Status)) {\r
@@ -2176,7 +2408,7 @@ OnReadyToBoot (
     for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
       Status = MeasureSeparatorEvent (PcrIndex);\r
       if (EFI_ERROR (Status)) {\r
     for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
       Status = MeasureSeparatorEvent (PcrIndex);\r
       if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));\r
+        DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));\r
       }\r
     }\r
 \r
       }\r
     }\r
 \r
@@ -2196,10 +2428,23 @@ OnReadyToBoot (
     // 6. Not first attempt, meaning a return from last attempt\r
     //\r
     Status = TcgMeasureAction (\r
     // 6. Not first attempt, meaning a return from last attempt\r
     //\r
     Status = TcgMeasureAction (\r
-               EFI_RETURNING_FROM_EFI_APPLICATOIN\r
+               4,\r
+               EFI_RETURNING_FROM_EFI_APPLICATION\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));\r
+    }\r
+\r
+    //\r
+    // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again\r
+    // TCG PC Client PFP spec Section 2.4.4.5 Step 4\r
+    //\r
+    Status = TcgMeasureAction (\r
+               4,\r
+               EFI_CALLING_EFI_APPLICATION\r
                );\r
     if (EFI_ERROR (Status)) {\r
                );\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
+      DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
     }\r
   }\r
 \r
     }\r
   }\r
 \r
@@ -2233,6 +2478,7 @@ OnExitBootServices (
   // Measure invocation of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
   // Measure invocation of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_INVOCATION\r
              );\r
   if (EFI_ERROR (Status)) {\r
              EFI_EXIT_BOOT_SERVICES_INVOCATION\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2243,6 +2489,7 @@ OnExitBootServices (
   // Measure success of ExitBootServices\r
   //\r
   Status = TcgMeasureAction (\r
   // Measure success of ExitBootServices\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
              );\r
   if (EFI_ERROR (Status)) {\r
              EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2272,6 +2519,7 @@ OnExitBootServicesFailed (
   // Measure Failure of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
   // Measure Failure of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_FAILED\r
              );\r
   if (EFI_ERROR (Status)) {\r
              EFI_EXIT_BOOT_SERVICES_FAILED\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2280,9 +2528,68 @@ OnExitBootServicesFailed (
 \r
 }\r
 \r
 \r
 }\r
 \r
+/**\r
+  This routine is called to properly shutdown the TPM before system reset.\r
+  It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+  Part 1: Architecture, Revision 01.16.\r
+\r
+  @param[in]  ResetType         The type of reset to perform.\r
+  @param[in]  ResetStatus       The status code for the reset.\r
+  @param[in]  DataSize          The size, in bytes, of ResetData.\r
+  @param[in]  ResetData         For a ResetType of EfiResetCold, EfiResetWarm, or\r
+                                EfiResetShutdown the data buffer starts with a Null-terminated\r
+                                string, optionally followed by additional binary data.\r
+                                The string is a description that the caller may use to further\r
+                                indicate the reason for the system reset.\r
+                                For a ResetType of EfiResetPlatformSpecific the data buffer\r
+                                also starts with a Null-terminated string that is followed\r
+                                by an EFI_GUID that describes the specific type of reset to perform.\r
+**/\r
+VOID\r
+EFIAPI\r
+ShutdownTpmOnReset (\r
+  IN EFI_RESET_TYPE           ResetType,\r
+  IN EFI_STATUS               ResetStatus,\r
+  IN UINTN                    DataSize,\r
+  IN VOID                     *ResetData OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
+  DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
+}\r
+\r
+/**\r
+  Hook the system reset to properly shutdown TPM.\r
+  It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+  Part 1: Architecture, Revision 01.16.\r
+\r
+  @param[in]  Event     Event whose notification function is being invoked\r
+  @param[in]  Context   Pointer to the notification function's context\r
+**/\r
+VOID\r
+EFIAPI\r
+OnResetNotificationInstall (\r
+  IN EFI_EVENT                      Event,\r
+  IN VOID                           *Context\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_RESET_NOTIFICATION_PROTOCOL   *ResetNotify;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
+    ASSERT_EFI_ERROR (Status);\r
+    DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
+\r
+    gBS->CloseEvent (Event);\r
+  }\r
+}\r
+\r
 /**\r
   The function install Tcg2 protocol.\r
 /**\r
   The function install Tcg2 protocol.\r
-  \r
+\r
   @retval EFI_SUCCESS     Tcg2 protocol is installed.\r
   @retval other           Some error occurs.\r
 **/\r
   @retval EFI_SUCCESS     Tcg2 protocol is installed.\r
   @retval other           Some error occurs.\r
 **/\r
@@ -2307,9 +2614,9 @@ InstallTcg2 (
 /**\r
   The driver's entry point. It publishes EFI Tcg2 Protocol.\r
 \r
 /**\r
   The driver's entry point. It publishes EFI Tcg2 Protocol.\r
 \r
-  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  \r
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable  A pointer to the EFI System Table.\r
   @param[in] SystemTable  A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS     The entry point is executed successfully.\r
   @retval other           Some error occurs when executing this entry point.\r
 **/\r
   @retval EFI_SUCCESS     The entry point is executed successfully.\r
   @retval other           Some error occurs when executing this entry point.\r
 **/\r
@@ -2325,7 +2632,6 @@ DriverEntry (
   VOID                              *Registration;\r
   UINT32                            MaxCommandSize;\r
   UINT32                            MaxResponseSize;\r
   VOID                              *Registration;\r
   UINT32                            MaxCommandSize;\r
   UINT32                            MaxResponseSize;\r
-  TPML_PCR_SELECTION                Pcrs;\r
   UINTN                             Index;\r
   EFI_TCG2_EVENT_ALGORITHM_BITMAP   TpmHashAlgorithmBitmap;\r
   UINT32                            ActivePCRBanks;\r
   UINTN                             Index;\r
   EFI_TCG2_EVENT_ALGORITHM_BITMAP   TpmHashAlgorithmBitmap;\r
   UINT32                            ActivePCRBanks;\r
@@ -2335,7 +2641,7 @@ DriverEntry (
 \r
   if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
       CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
 \r
   if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
       CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
-    DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));\r
+    DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -2343,18 +2649,18 @@ DriverEntry (
     DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
     return EFI_DEVICE_ERROR;\r
   }\r
     DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  \r
+\r
   Status = Tpm2RequestUseTpm ();\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
     return Status;\r
   }\r
   Status = Tpm2RequestUseTpm ();\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Fill information\r
   //\r
   ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
   //\r
   // Fill information\r
   //\r
   ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
-  \r
+\r
   mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
   mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
   mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
   mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
   mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
   mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
@@ -2395,51 +2701,9 @@ DriverEntry (
   //\r
   // Get supported PCR and current Active PCRs\r
   //\r
   //\r
   // Get supported PCR and current Active PCRs\r
   //\r
-  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));\r
-    TpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-    ActivePCRBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-  } else {\r
-    DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));\r
-    TpmHashAlgorithmBitmap = 0;\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
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-        if (!IsZeroBuffer (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
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
-        if (!IsZeroBuffer (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
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
-        if (!IsZeroBuffer (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
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
-        if (!IsZeroBuffer (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
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
-        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
-        }\r
-        break;\r
-      }\r
-    }\r
-  }\r
+  Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
   mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
 \r
   mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
   mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
 \r
@@ -2503,7 +2767,7 @@ DriverEntry (
                     );\r
 \r
     //\r
                     );\r
 \r
     //\r
-    // Measure Exit Boot Service failed \r
+    // Measure Exit Boot Service failed\r
     //\r
     Status = gBS->CreateEventEx (\r
                     EVT_NOTIFY_SIGNAL,\r
     //\r
     Status = gBS->CreateEventEx (\r
                     EVT_NOTIFY_SIGNAL,\r
@@ -2520,6 +2784,11 @@ DriverEntry (
     // may update SecureBoot value based on last setting.\r
     //\r
     EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
     // may update SecureBoot value based on last setting.\r
     //\r
     EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
+\r
+    //\r
+    // Hook the system reset to properly shutdown TPM.\r
+    //\r
+    EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r