]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/TcgPei/TcgPei.c
SecurityPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / SecurityPkg / Tcg / TcgPei / TcgPei.c
index ae905f7653b6d5c28281482be78d61993f7c47e7..0adfcc50c5098f783415556c2c39cd92a6332eb3 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   Initialize TPM device and measure FVs before handing off control to DXE.\r
 \r
-Copyright (c) 2005 - 2013, 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) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -32,13 +26,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/PeiServicesLib.h>\r
 #include <Library/PeimEntryPoint.h>\r
-#include <Library/TpmCommLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/PeiServicesTablePointerLib.h>\r
 #include <Library/BaseLib.h>\r
-\r
-#include "TpmComm.h"\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/Tpm12DeviceLib.h>\r
+#include <Library/Tpm12CommandLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+#include <Library/PerformanceLib.h>\r
 \r
 BOOLEAN                 mImageInMemory  = FALSE;\r
 \r
@@ -48,10 +45,23 @@ EFI_PEI_PPI_DESCRIPTOR  mTpmInitializedPpiList = {
   NULL\r
 };\r
 \r
-EFI_PLATFORM_FIRMWARE_BLOB mMeasuredBaseFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
+EFI_PEI_PPI_DESCRIPTOR  mTpmInitializationDonePpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gPeiTpmInitializationDonePpiGuid,\r
+  NULL\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[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
+EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;\r
+UINT32 mMeasuredMaxChildFvIndex = 0;\r
 UINT32 mMeasuredChildFvIndex = 0;\r
 \r
 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;\r
@@ -121,12 +131,12 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
   {\r
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
     &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
-    FirmwareVolmeInfoPpiNotifyCallback \r
+    FirmwareVolmeInfoPpiNotifyCallback\r
   },\r
   {\r
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
     &gEfiPeiFirmwareVolumeInfo2PpiGuid,\r
-    FirmwareVolmeInfoPpiNotifyCallback \r
+    FirmwareVolmeInfoPpiNotifyCallback\r
   },\r
   {\r
     (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
@@ -137,7 +147,7 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
 \r
 /**\r
   Record all measured Firmware Volum Information into a Guid Hob\r
-  Guid Hob payload layout is \r
+  Guid Hob payload layout is\r
 \r
      UINT32 *************************** FIRMWARE_BLOB number\r
      EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array\r
@@ -157,13 +167,15 @@ EndofPeiSignalNotifyCallBack (
   IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
   IN VOID                          *Ppi\r
   )\r
-{  \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
                       &gMeasuredFvHobGuid,\r
@@ -187,6 +199,42 @@ EndofPeiSignalNotifyCallBack (
     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
+Single function calculates SHA1 digest value for all raw data. It\r
+combines Sha1Init(), Sha1Update() and Sha1Final().\r
+\r
+@param[in]  Data          Raw data to be digested.\r
+@param[in]  DataLen       Size of the raw data.\r
+@param[out] Digest        Pointer to a buffer that stores the final digest.\r
+\r
+@retval     EFI_SUCCESS   Always successfully calculate the final digest.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TpmCommHashAll (\r
+  IN  CONST UINT8       *Data,\r
+  IN        UINTN       DataLen,\r
+  OUT       TPM_DIGEST  *Digest\r
+  )\r
+{\r
+  VOID   *Sha1Ctx;\r
+  UINTN  CtxSize;\r
+\r
+  CtxSize = Sha1GetContextSize ();\r
+  Sha1Ctx = AllocatePool (CtxSize);\r
+  ASSERT (Sha1Ctx != NULL);\r
+\r
+  Sha1Init (Sha1Ctx);\r
+  Sha1Update (Sha1Ctx, Data, DataLen);\r
+  Sha1Final (Sha1Ctx, (UINT8 *)Digest);\r
+\r
+  FreePool (Sha1Ctx);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -196,12 +244,11 @@ EndofPeiSignalNotifyCallBack (
   added into the Event Log.\r
 \r
   @param[in]      PeiServices   Describes the list of possible PEI Services.\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
-  @param[in]      TpmHandle     TPM handle.\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
@@ -213,7 +260,6 @@ HashLogExtendEvent (
   IN      EFI_PEI_SERVICES          **PeiServices,\r
   IN      UINT8                     *HashData,\r
   IN      UINTN                     HashDataLen,\r
-  IN      TIS_TPM_HANDLE            TpmHandle,\r
   IN      TCG_PCR_EVENT_HDR         *NewEventHdr,\r
   IN      UINT8                     *NewEventData\r
   )\r
@@ -221,6 +267,10 @@ HashLogExtendEvent (
   EFI_STATUS                        Status;\r
   VOID                              *HobData;\r
 \r
+  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
   HobData = NULL;\r
   if (HashDataLen != 0) {\r
     Status = TpmCommHashAll (\r
@@ -228,37 +278,50 @@ HashLogExtendEvent (
                HashDataLen,\r
                &NewEventHdr->Digest\r
                );\r
-    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
   }\r
 \r
-  Status = TpmCommExtend (\r
-             PeiServices,\r
-             TpmHandle,\r
+  Status = Tpm12Extend (\r
              &NewEventHdr->Digest,\r
              NewEventHdr->PCRIndex,\r
              NULL\r
              );\r
-  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
 \r
   HobData = BuildGuidHob (\r
              &gTcgEventEntryHobGuid,\r
              sizeof (*NewEventHdr) + NewEventHdr->EventSize\r
              );\r
   if (HobData == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
   }\r
 \r
   CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));\r
   HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));\r
   CopyMem (HobData, NewEventData, NewEventHdr->EventSize);\r
-  return EFI_SUCCESS;\r
+\r
+Done:\r
+  if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) {\r
+    DEBUG ((EFI_D_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
+      );\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+  return Status;\r
 }\r
 \r
 /**\r
   Measure CRTM version.\r
 \r
   @param[in]      PeiServices   Describes the list of possible PEI Services.\r
-  @param[in]      TpmHandle     TPM handle.\r
 \r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
@@ -268,8 +331,7 @@ HashLogExtendEvent (
 EFI_STATUS\r
 EFIAPI\r
 MeasureCRTMVersion (\r
-  IN      EFI_PEI_SERVICES          **PeiServices,\r
-  IN      TIS_TPM_HANDLE            TpmHandle\r
+  IN      EFI_PEI_SERVICES          **PeiServices\r
   )\r
 {\r
   TCG_PCR_EVENT_HDR                 TcgEventHdr;\r
@@ -287,20 +349,19 @@ MeasureCRTMVersion (
            PeiServices,\r
            (UINT8*)PcdGetPtr (PcdFirmwareVersionString),\r
            TcgEventHdr.EventSize,\r
-           TpmHandle,\r
            &TcgEventHdr,\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
+  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
@@ -317,9 +378,6 @@ MeasureFvImage (
   EFI_STATUS                        Status;\r
   EFI_PLATFORM_FIRMWARE_BLOB        FvBlob;\r
   TCG_PCR_EVENT_HDR                 TcgEventHdr;\r
-  TIS_TPM_HANDLE                    TpmHandle;\r
-\r
-  TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;\r
 \r
   //\r
   // Check if it is in Excluded FV list\r
@@ -342,7 +400,7 @@ MeasureFvImage (
       return EFI_SUCCESS;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Measure and record the FV to the TPM\r
   //\r
@@ -360,22 +418,27 @@ MeasureFvImage (
              (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),\r
              (UINT8*) (UINTN) FvBlob.BlobBase,\r
              (UINTN) FvBlob.BlobLength,\r
-             TpmHandle,\r
              &TcgEventHdr,\r
              (UINT8*) &FvBlob\r
              );\r
-  ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // Add new FV into the measured FV list.\r
   //\r
-  ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
-  if (mMeasuredBaseFvIndex < FixedPcdGet32 (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
@@ -383,7 +446,6 @@ MeasureFvImage (
   Measure main BIOS.\r
 \r
   @param[in]      PeiServices   Describes the list of possible PEI Services.\r
-  @param[in]      TpmHandle     TPM handle.\r
 \r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
@@ -393,8 +455,7 @@ MeasureFvImage (
 EFI_STATUS\r
 EFIAPI\r
 MeasureMainBios (\r
-  IN      EFI_PEI_SERVICES          **PeiServices,\r
-  IN      TIS_TPM_HANDLE            TpmHandle\r
+  IN      EFI_PEI_SERVICES          **PeiServices\r
   )\r
 {\r
   EFI_STATUS                        Status;\r
@@ -402,7 +463,7 @@ MeasureMainBios (
   EFI_PEI_FV_HANDLE                 VolumeHandle;\r
   EFI_FV_INFO                       VolumeInfo;\r
   EFI_PEI_FIRMWARE_VOLUME_PPI       *FvPpi;\r
-  \r
+\r
   FvInstances    = 0;\r
   while (TRUE) {\r
     //\r
@@ -414,7 +475,7 @@ MeasureMainBios (
     if (EFI_ERROR (Status)) {\r
       break;\r
     }\r
-  \r
+\r
     //\r
     // Measure and record the firmware volume that is dispatched by PeiCore\r
     //\r
@@ -424,8 +485,8 @@ MeasureMainBios (
     // Locate the corresponding FV_PPI according to founded FV's format guid\r
     //\r
     Status = PeiServicesLocatePpi (\r
-               &VolumeInfo.FvFormat, \r
-               0, \r
+               &VolumeInfo.FvFormat,\r
+               0,\r
                NULL,\r
                (VOID**)&FvPpi\r
                );\r
@@ -461,6 +522,7 @@ FirmwareVolmeInfoPpiNotifyCallback (
   EFI_PEI_FIRMWARE_VOLUME_INFO_PPI  *Fv;\r
   EFI_STATUS                        Status;\r
   EFI_PEI_FIRMWARE_VOLUME_PPI       *FvPpi;\r
+  UINTN                             Index;\r
 \r
   Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;\r
 \r
@@ -468,27 +530,41 @@ FirmwareVolmeInfoPpiNotifyCallback (
   // 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
              );\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 < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
-    if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
-      mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase   = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;\r
-      mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
-      mMeasuredChildFvIndex++;\r
+\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
+    // 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
+    }\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
@@ -517,15 +593,11 @@ PhysicalPresencePpiNotifyCallback (
   )\r
 {\r
   EFI_STATUS                        Status;\r
+  TPM_PERMANENT_FLAGS               TpmPermanentFlags;\r
   PEI_LOCK_PHYSICAL_PRESENCE_PPI    *LockPhysicalPresencePpi;\r
-  BOOLEAN                           LifetimeLock;\r
-  BOOLEAN                           CmdEnable;\r
-  TIS_TPM_HANDLE                    TpmHandle;\r
   TPM_PHYSICAL_PRESENCE             PhysicalPresenceValue;\r
 \r
-  TpmHandle        = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;\r
-\r
-  Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);\r
+  Status = Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -533,36 +605,35 @@ PhysicalPresencePpiNotifyCallback (
   //\r
   // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.\r
   //\r
-  if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !LifetimeLock) {\r
+  if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !TpmPermanentFlags.physicalPresenceLifetimeLock) {\r
     //\r
-    // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet. \r
+    // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.\r
     //\r
     PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK;\r
+    TpmPermanentFlags.physicalPresenceLifetimeLock = TRUE;\r
 \r
     if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) {\r
       PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE;\r
-      CmdEnable = TRUE;\r
+      TpmPermanentFlags.physicalPresenceCMDEnable = TRUE;\r
     } else {\r
       PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE;\r
-      CmdEnable = FALSE;\r
+      TpmPermanentFlags.physicalPresenceCMDEnable = FALSE;\r
     }\r
 \r
     if (PcdGetBool (PcdPhysicalPresenceHwEnable)) {\r
       PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE;\r
     } else {\r
       PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE;\r
-    }      \r
-     \r
-    Status = TpmCommPhysicalPresence (\r
-               PeiServices,\r
-               TpmHandle,\r
+    }\r
+\r
+    Status = Tpm12PhysicalPresence (\r
                PhysicalPresenceValue\r
                );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // 2. Lock physical presence if it is required.\r
   //\r
@@ -571,8 +642,8 @@ PhysicalPresencePpiNotifyCallback (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (!CmdEnable) {\r
-    if (LifetimeLock) {\r
+  if (!TpmPermanentFlags.physicalPresenceCMDEnable) {\r
+    if (TpmPermanentFlags.physicalPresenceLifetimeLock) {\r
       //\r
       // physicalPresenceCMDEnable is locked, can't change.\r
       //\r
@@ -583,9 +654,7 @@ PhysicalPresencePpiNotifyCallback (
     // Enable physical presence command\r
     // It is necessary in order to lock physical presence\r
     //\r
-    Status = TpmCommPhysicalPresence (\r
-               PeiServices,\r
-               TpmHandle,\r
+    Status = Tpm12PhysicalPresence (\r
                TPM_PHYSICAL_PRESENCE_CMD_ENABLE\r
                );\r
     if (EFI_ERROR (Status)) {\r
@@ -595,10 +664,8 @@ PhysicalPresencePpiNotifyCallback (
 \r
   //\r
   // Lock physical presence\r
-  // \r
-  Status = TpmCommPhysicalPresence (\r
-              PeiServices,\r
-              TpmHandle,\r
+  //\r
+  Status = Tpm12PhysicalPresence (\r
               TPM_PHYSICAL_PRESENCE_LOCK\r
               );\r
   return Status;\r
@@ -608,27 +675,24 @@ PhysicalPresencePpiNotifyCallback (
   Check if TPM chip is activeated or not.\r
 \r
   @param[in]      PeiServices   Describes the list of possible PEI Services.\r
-  @param[in]      TpmHandle     TPM handle.\r
 \r
   @retval TRUE    TPM is activated.\r
   @retval FALSE   TPM is deactivated.\r
 \r
 **/\r
 BOOLEAN\r
-EFIAPI\r
 IsTpmUsable (\r
-  IN      EFI_PEI_SERVICES          **PeiServices,\r
-  IN      TIS_TPM_HANDLE            TpmHandle\r
+  VOID\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  BOOLEAN                           Deactivated;\r
+  EFI_STATUS           Status;\r
+  TPM_PERMANENT_FLAGS  TpmPermanentFlags;\r
 \r
-  Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);\r
+  Status = Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags);\r
   if (EFI_ERROR (Status)) {\r
     return FALSE;\r
   }\r
-  return (BOOLEAN)(!Deactivated); \r
+  return (BOOLEAN)(!TpmPermanentFlags.deactivated);\r
 }\r
 \r
 /**\r
@@ -648,36 +712,33 @@ PeimEntryMP (
   )\r
 {\r
   EFI_STATUS                        Status;\r
-  TIS_TPM_HANDLE                    TpmHandle;\r
 \r
   Status = PeiServicesLocatePpi (\r
-               &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, \r
-               0, \r
+               &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,\r
+               0,\r
                NULL,\r
                (VOID**)&mMeasurementExcludedFvPpi\r
                );\r
   // Do not check status, because it is optional\r
 \r
-  TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
-  Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
+  Status = Tpm12RequestUseTpm ();\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  if (IsTpmUsable (PeiServices, TpmHandle)) {\r
+  if (IsTpmUsable ()) {\r
     if (PcdGet8 (PcdTpmScrtmPolicy) == 1) {\r
-      Status = MeasureCRTMVersion (PeiServices, TpmHandle);\r
-      ASSERT_EFI_ERROR (Status);\r
+      Status = MeasureCRTMVersion (PeiServices);\r
     }\r
 \r
-    Status = MeasureMainBios (PeiServices, TpmHandle);\r
-  }  \r
+    Status = MeasureMainBios (PeiServices);\r
+  }\r
 \r
   //\r
   // Post callbacks:\r
   // 1). for the FvInfoPpi services to measure and record\r
   // the additional Fvs to TPM\r
-  // 2). for the OperatorPresencePpi service to determine whether to \r
+  // 2). for the OperatorPresencePpi service to determine whether to\r
   // lock the TPM\r
   //\r
   Status = PeiServicesNotifyPpi (&mNotifyList[0]);\r
@@ -703,16 +764,17 @@ PeimEntryMA (
   )\r
 {\r
   EFI_STATUS                        Status;\r
+  EFI_STATUS                        Status2;\r
   EFI_BOOT_MODE                     BootMode;\r
-  TIS_TPM_HANDLE                    TpmHandle;\r
 \r
   if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
     DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {\r
-    return EFI_UNSUPPORTED;\r
+  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+    DEBUG ((EFI_D_ERROR, "TPM error!\n"));\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   //\r
@@ -734,17 +796,20 @@ PeimEntryMA (
   }\r
 \r
   if (!mImageInMemory) {\r
-    TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
-    Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
+    Status = Tpm12RequestUseTpm ();\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));\r
-      return Status;\r
+      goto Done;\r
     }\r
 \r
     if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {\r
-      Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);\r
+      if (BootMode == BOOT_ON_S3_RESUME) {\r
+        Status = Tpm12Startup (TPM_ST_STATE);\r
+      } else {\r
+        Status = Tpm12Startup (TPM_ST_CLEAR);\r
+      }\r
       if (EFI_ERROR (Status) ) {\r
-        return Status;\r
+        goto Done;\r
       }\r
     }\r
 \r
@@ -752,22 +817,39 @@ PeimEntryMA (
     // TpmSelfTest is optional on S3 path, skip it to save S3 time\r
     //\r
     if (BootMode != BOOT_ON_S3_RESUME) {\r
-      Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);\r
+      Status = Tpm12ContinueSelfTest ();\r
       if (EFI_ERROR (Status)) {\r
-        return Status;\r
+        goto Done;\r
       }\r
     }\r
 \r
+    //\r
+    // Only intall 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
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+    return Status;\r
   }\r
 \r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "TPM 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
+  // Always intall TpmInitializationDonePpi no matter success or fail.\r
+  // Other driver can know TPM initialization state by TpmInitializedPpi.\r
+  //\r
+  Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);\r
+  ASSERT_EFI_ERROR (Status2);\r
+\r
   return Status;\r
 }\r