10c18794ea4289f03fefc7117b56740414cc0536cgdong/** @file
20c18794ea4289f03fefc7117b56740414cc0536cgdong  Utility functions used by TPM PEI driver.
30c18794ea4289f03fefc7117b56740414cc0536cgdong
46f785cfcc304c48ec04e542ee429df95e7b51bc5Yao, JiewenCopyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
50c18794ea4289f03fefc7117b56740414cc0536cgdongThis program and the accompanying materials
60c18794ea4289f03fefc7117b56740414cc0536cgdongare licensed and made available under the terms and conditions of the BSD License
70c18794ea4289f03fefc7117b56740414cc0536cgdongwhich accompanies this distribution.  The full text of the license may be found at
80c18794ea4289f03fefc7117b56740414cc0536cgdonghttp://opensource.org/licenses/bsd-license.php
90c18794ea4289f03fefc7117b56740414cc0536cgdong
100c18794ea4289f03fefc7117b56740414cc0536cgdongTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
110c18794ea4289f03fefc7117b56740414cc0536cgdongWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
120c18794ea4289f03fefc7117b56740414cc0536cgdong
130c18794ea4289f03fefc7117b56740414cc0536cgdong**/
140c18794ea4289f03fefc7117b56740414cc0536cgdong
150c18794ea4289f03fefc7117b56740414cc0536cgdong#include "TpmComm.h"
160c18794ea4289f03fefc7117b56740414cc0536cgdong
170c18794ea4289f03fefc7117b56740414cc0536cgdong/**
180c18794ea4289f03fefc7117b56740414cc0536cgdong  Send a command to TPM for execution and return response data.
190c18794ea4289f03fefc7117b56740414cc0536cgdong
200c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]      PeiServices   Describes the list of possible PEI Services.
210c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]      TisReg        TPM register space base address.
220c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]      BufferIn      Buffer for command data.
230c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]      SizeIn        Size of command data.
240c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in, out] BufferOut     Buffer for response data.
250c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in, out] SizeOut       size of response data.
260c18794ea4289f03fefc7117b56740414cc0536cgdong
270c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_SUCCESS           Operation completed successfully.
280c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
290c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
300c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_DEVICE_ERROR      Unexpected device behavior.
310c18794ea4289f03fefc7117b56740414cc0536cgdong
320c18794ea4289f03fefc7117b56740414cc0536cgdong**/
330c18794ea4289f03fefc7117b56740414cc0536cgdongEFI_STATUS
340c18794ea4289f03fefc7117b56740414cc0536cgdongTisTpmCommand (
350c18794ea4289f03fefc7117b56740414cc0536cgdong  IN     EFI_PEI_SERVICES           **PeiServices,
360c18794ea4289f03fefc7117b56740414cc0536cgdong  IN     TIS_PC_REGISTERS_PTR       TisReg,
370c18794ea4289f03fefc7117b56740414cc0536cgdong  IN     UINT8                      *BufferIn,
380c18794ea4289f03fefc7117b56740414cc0536cgdong  IN     UINT32                     SizeIn,
390c18794ea4289f03fefc7117b56740414cc0536cgdong  IN OUT UINT8                      *BufferOut,
400c18794ea4289f03fefc7117b56740414cc0536cgdong  IN OUT UINT32                     *SizeOut
410c18794ea4289f03fefc7117b56740414cc0536cgdong  );
420c18794ea4289f03fefc7117b56740414cc0536cgdong
430c18794ea4289f03fefc7117b56740414cc0536cgdong/**
440c18794ea4289f03fefc7117b56740414cc0536cgdong  Send TPM_Startup command to TPM.
450c18794ea4289f03fefc7117b56740414cc0536cgdong
460c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] PeiServices        Describes the list of possible PEI Services.
470c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] TpmHandle          TPM handle.
480c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] BootMode           Boot mode.
490c18794ea4289f03fefc7117b56740414cc0536cgdong
500c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_SUCCESS           Operation completed successfully.
510c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
520c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
530c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_DEVICE_ERROR      Unexpected device behavior.
540c18794ea4289f03fefc7117b56740414cc0536cgdong
550c18794ea4289f03fefc7117b56740414cc0536cgdong**/
560c18794ea4289f03fefc7117b56740414cc0536cgdongEFI_STATUS
570c18794ea4289f03fefc7117b56740414cc0536cgdongTpmCommStartup (
580c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      EFI_PEI_SERVICES          **PeiServices,
590c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TIS_TPM_HANDLE            TpmHandle,
600c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      EFI_BOOT_MODE             BootMode
610c18794ea4289f03fefc7117b56740414cc0536cgdong  )
620c18794ea4289f03fefc7117b56740414cc0536cgdong{
630c18794ea4289f03fefc7117b56740414cc0536cgdong  EFI_STATUS                        Status;
640c18794ea4289f03fefc7117b56740414cc0536cgdong  TPM_STARTUP_TYPE                  TpmSt;
650c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmRecvSize;
660c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmSendSize;
670c18794ea4289f03fefc7117b56740414cc0536cgdong  TPM_CMD_START_UP                  SendBuffer;
680c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT8                             RecvBuffer[20];
690c18794ea4289f03fefc7117b56740414cc0536cgdong
700c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmSt = TPM_ST_CLEAR;
710c18794ea4289f03fefc7117b56740414cc0536cgdong  if (BootMode == BOOT_ON_S3_RESUME) {
720c18794ea4289f03fefc7117b56740414cc0536cgdong    TpmSt = TPM_ST_STATE;
730c18794ea4289f03fefc7117b56740414cc0536cgdong  }
740c18794ea4289f03fefc7117b56740414cc0536cgdong  //
750c18794ea4289f03fefc7117b56740414cc0536cgdong  // send Tpm command TPM_ORD_Startup
760c18794ea4289f03fefc7117b56740414cc0536cgdong  //
770c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmRecvSize               = 20;
780c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmSendSize               = sizeof (TPM_CMD_START_UP);
790c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
800c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
810c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Startup);
820c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.TpmSt          = SwapBytes16 (TpmSt);
830c18794ea4289f03fefc7117b56740414cc0536cgdong  Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
840c18794ea4289f03fefc7117b56740414cc0536cgdong  return Status;
850c18794ea4289f03fefc7117b56740414cc0536cgdong}
860c18794ea4289f03fefc7117b56740414cc0536cgdong
870c18794ea4289f03fefc7117b56740414cc0536cgdong/**
880c18794ea4289f03fefc7117b56740414cc0536cgdong  Send TPM_ContinueSelfTest command to TPM.
890c18794ea4289f03fefc7117b56740414cc0536cgdong
900c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] PeiServices        Describes the list of possible PEI Services.
910c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] TpmHandle          TPM handle.
920c18794ea4289f03fefc7117b56740414cc0536cgdong
930c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_SUCCESS           Operation completed successfully.
940c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
950c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
960c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_DEVICE_ERROR      Unexpected device behavior.
970c18794ea4289f03fefc7117b56740414cc0536cgdong
980c18794ea4289f03fefc7117b56740414cc0536cgdong**/
990c18794ea4289f03fefc7117b56740414cc0536cgdongEFI_STATUS
1000c18794ea4289f03fefc7117b56740414cc0536cgdongTpmCommContinueSelfTest (
1010c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      EFI_PEI_SERVICES          **PeiServices,
1020c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TIS_TPM_HANDLE            TpmHandle
1030c18794ea4289f03fefc7117b56740414cc0536cgdong  )
1040c18794ea4289f03fefc7117b56740414cc0536cgdong{
1050c18794ea4289f03fefc7117b56740414cc0536cgdong  EFI_STATUS                        Status;
1060c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmRecvSize;
1070c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmSendSize;
1080c18794ea4289f03fefc7117b56740414cc0536cgdong  TPM_CMD_SELF_TEST                 SendBuffer;
1090c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT8                             RecvBuffer[20];
1100c18794ea4289f03fefc7117b56740414cc0536cgdong
1110c18794ea4289f03fefc7117b56740414cc0536cgdong  //
1120c18794ea4289f03fefc7117b56740414cc0536cgdong  // send Tpm command TPM_ORD_ContinueSelfTest
1130c18794ea4289f03fefc7117b56740414cc0536cgdong  //
1140c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmRecvSize               = 20;
1150c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmSendSize               = sizeof (TPM_CMD_SELF_TEST);
1160c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
1170c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
1180c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_ContinueSelfTest);
1190c18794ea4289f03fefc7117b56740414cc0536cgdong  Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
1200c18794ea4289f03fefc7117b56740414cc0536cgdong  return Status;
1210c18794ea4289f03fefc7117b56740414cc0536cgdong}
1220c18794ea4289f03fefc7117b56740414cc0536cgdong
1230c18794ea4289f03fefc7117b56740414cc0536cgdong/**
1240c18794ea4289f03fefc7117b56740414cc0536cgdong  Get TPM capability flags.
1250c18794ea4289f03fefc7117b56740414cc0536cgdong
1260c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]  PeiServices       Describes the list of possible PEI Services.
1270c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]  TpmHandle         TPM handle.
1280c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[out] Deactivated       Returns deactivated flag.
1290c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[out] LifetimeLock      Returns physicalPresenceLifetimeLock permanent flag.
1300c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[out] CmdEnable         Returns physicalPresenceCMDEnable permanent flag.
1310c18794ea4289f03fefc7117b56740414cc0536cgdong
1320c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_SUCCESS           Operation completed successfully.
1330c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
1340c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
1350c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_DEVICE_ERROR      Unexpected device behavior.
1360c18794ea4289f03fefc7117b56740414cc0536cgdong
1370c18794ea4289f03fefc7117b56740414cc0536cgdong**/
1380c18794ea4289f03fefc7117b56740414cc0536cgdongEFI_STATUS
1390c18794ea4289f03fefc7117b56740414cc0536cgdongTpmCommGetCapability (
1400c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      EFI_PEI_SERVICES          **PeiServices,
1410c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TIS_TPM_HANDLE            TpmHandle,
1420c18794ea4289f03fefc7117b56740414cc0536cgdong     OUT  BOOLEAN                   *Deactivated, OPTIONAL
1430c18794ea4289f03fefc7117b56740414cc0536cgdong     OUT  BOOLEAN                   *LifetimeLock, OPTIONAL
1440c18794ea4289f03fefc7117b56740414cc0536cgdong     OUT  BOOLEAN                   *CmdEnable OPTIONAL
1450c18794ea4289f03fefc7117b56740414cc0536cgdong  )
1460c18794ea4289f03fefc7117b56740414cc0536cgdong{
1470c18794ea4289f03fefc7117b56740414cc0536cgdong  EFI_STATUS                        Status;
1480c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmRecvSize;
1490c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmSendSize;
1500c18794ea4289f03fefc7117b56740414cc0536cgdong  TPM_CMD_GET_CAPABILITY            SendBuffer;
1510c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT8                             RecvBuffer[40];
1520c18794ea4289f03fefc7117b56740414cc0536cgdong  TPM_PERMANENT_FLAGS               *TpmPermanentFlags;
1530c18794ea4289f03fefc7117b56740414cc0536cgdong
1540c18794ea4289f03fefc7117b56740414cc0536cgdong  //
1550c18794ea4289f03fefc7117b56740414cc0536cgdong  // send Tpm command TPM_ORD_GetCapability
1560c18794ea4289f03fefc7117b56740414cc0536cgdong  //
1570c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmRecvSize                   = 40;
1580c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmSendSize                   = sizeof (TPM_CMD_GET_CAPABILITY);
1590c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.tag            = SwapBytes16 (TPM_TAG_RQU_COMMAND);
1600c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.paramSize      = SwapBytes32 (TpmSendSize);
1610c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.ordinal        = SwapBytes32 (TPM_ORD_GetCapability);
1620c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Capability         = SwapBytes32 (TPM_CAP_FLAG);
1630c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.CapabilityFlagSize = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT));
1640c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.CapabilityFlag     = SwapBytes32 (TPM_CAP_FLAG_PERMANENT);
1650c18794ea4289f03fefc7117b56740414cc0536cgdong  Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
1660c18794ea4289f03fefc7117b56740414cc0536cgdong  if (EFI_ERROR (Status)) {
1670c18794ea4289f03fefc7117b56740414cc0536cgdong    return Status;
1680c18794ea4289f03fefc7117b56740414cc0536cgdong  }
1690c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
1700c18794ea4289f03fefc7117b56740414cc0536cgdong  if (Deactivated != NULL) {
1710c18794ea4289f03fefc7117b56740414cc0536cgdong    *Deactivated      = TpmPermanentFlags->deactivated;
1720c18794ea4289f03fefc7117b56740414cc0536cgdong  }
1730c18794ea4289f03fefc7117b56740414cc0536cgdong
1740c18794ea4289f03fefc7117b56740414cc0536cgdong  if (LifetimeLock != NULL) {
1750c18794ea4289f03fefc7117b56740414cc0536cgdong    *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;
1760c18794ea4289f03fefc7117b56740414cc0536cgdong  }
1770c18794ea4289f03fefc7117b56740414cc0536cgdong
1780c18794ea4289f03fefc7117b56740414cc0536cgdong  if (CmdEnable != NULL) {
1790c18794ea4289f03fefc7117b56740414cc0536cgdong    *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;
1800c18794ea4289f03fefc7117b56740414cc0536cgdong  }
1810c18794ea4289f03fefc7117b56740414cc0536cgdong  return Status;
1820c18794ea4289f03fefc7117b56740414cc0536cgdong}
1830c18794ea4289f03fefc7117b56740414cc0536cgdong
1840c18794ea4289f03fefc7117b56740414cc0536cgdong/**
1850c18794ea4289f03fefc7117b56740414cc0536cgdong  Extend a TPM PCR.
1860c18794ea4289f03fefc7117b56740414cc0536cgdong
1870c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]  PeiServices       Describes the list of possible PEI Services.
1880c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]  TpmHandle         TPM handle.
1890c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]  DigestToExtend    The 160 bit value representing the event to be recorded.
1900c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in]  PcrIndex          The PCR to be updated.
1910c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[out] NewPcrValue       New PCR value after extend.
1920c18794ea4289f03fefc7117b56740414cc0536cgdong
1930c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_SUCCESS           Operation completed successfully.
1940c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
1950c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
1960c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_DEVICE_ERROR      Unexpected device behavior.
1970c18794ea4289f03fefc7117b56740414cc0536cgdong
1980c18794ea4289f03fefc7117b56740414cc0536cgdong**/
1990c18794ea4289f03fefc7117b56740414cc0536cgdongEFI_STATUS
2000c18794ea4289f03fefc7117b56740414cc0536cgdongTpmCommExtend (
2010c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      EFI_PEI_SERVICES          **PeiServices,
2020c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TIS_TPM_HANDLE            TpmHandle,
2030c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TPM_DIGEST                *DigestToExtend,
2040c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TPM_PCRINDEX              PcrIndex,
2050c18794ea4289f03fefc7117b56740414cc0536cgdong     OUT  TPM_DIGEST                *NewPcrValue
2060c18794ea4289f03fefc7117b56740414cc0536cgdong  )
2070c18794ea4289f03fefc7117b56740414cc0536cgdong{
2080c18794ea4289f03fefc7117b56740414cc0536cgdong  EFI_STATUS                        Status;
2090c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmSendSize;
2100c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmRecvSize;
2110c18794ea4289f03fefc7117b56740414cc0536cgdong  TPM_CMD_EXTEND                    SendBuffer;
2120c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT8                             RecvBuffer[10 + sizeof(TPM_DIGEST)];
2130c18794ea4289f03fefc7117b56740414cc0536cgdong
2140c18794ea4289f03fefc7117b56740414cc0536cgdong  //
2150c18794ea4289f03fefc7117b56740414cc0536cgdong  // send Tpm command TPM_ORD_Extend
2160c18794ea4289f03fefc7117b56740414cc0536cgdong  //
2170c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmRecvSize               = sizeof (TPM_RSP_COMMAND_HDR) + sizeof (TPM_DIGEST);
2180c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmSendSize               = sizeof (TPM_CMD_EXTEND);
2190c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
2200c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
2210c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Extend);
2220c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.PcrIndex       = SwapBytes32 (PcrIndex);
2230c18794ea4289f03fefc7117b56740414cc0536cgdong  CopyMem (&SendBuffer.TpmDigest, (UINT8 *)DigestToExtend, sizeof (TPM_DIGEST));
2240c18794ea4289f03fefc7117b56740414cc0536cgdong  Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
2256f785cfcc304c48ec04e542ee429df95e7b51bc5Yao, Jiewen  if (EFI_ERROR (Status)) {
2266f785cfcc304c48ec04e542ee429df95e7b51bc5Yao, Jiewen    return Status;
2276f785cfcc304c48ec04e542ee429df95e7b51bc5Yao, Jiewen  }
2280c18794ea4289f03fefc7117b56740414cc0536cgdong
2290c18794ea4289f03fefc7117b56740414cc0536cgdong  if(NewPcrValue != NULL) {
2300c18794ea4289f03fefc7117b56740414cc0536cgdong    CopyMem ((UINT8*)NewPcrValue, &RecvBuffer[10], sizeof (TPM_DIGEST));
2310c18794ea4289f03fefc7117b56740414cc0536cgdong  }
2320c18794ea4289f03fefc7117b56740414cc0536cgdong
2330c18794ea4289f03fefc7117b56740414cc0536cgdong  return Status;
2340c18794ea4289f03fefc7117b56740414cc0536cgdong}
2350c18794ea4289f03fefc7117b56740414cc0536cgdong
2360c18794ea4289f03fefc7117b56740414cc0536cgdong
2370c18794ea4289f03fefc7117b56740414cc0536cgdong/**
2380c18794ea4289f03fefc7117b56740414cc0536cgdong  Send TSC_PhysicalPresence command to TPM.
2390c18794ea4289f03fefc7117b56740414cc0536cgdong
2400c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] PeiServices        Describes the list of possible PEI Services.
2410c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] TpmHandle          TPM handle.
2420c18794ea4289f03fefc7117b56740414cc0536cgdong  @param[in] PhysicalPresence   The state to set the TPMs Physical Presence flags.
2430c18794ea4289f03fefc7117b56740414cc0536cgdong
2440c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_SUCCESS           Operation completed successfully.
2450c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
2460c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
2470c18794ea4289f03fefc7117b56740414cc0536cgdong  @retval EFI_DEVICE_ERROR      Unexpected device behavior.
2480c18794ea4289f03fefc7117b56740414cc0536cgdong
2490c18794ea4289f03fefc7117b56740414cc0536cgdong**/
2500c18794ea4289f03fefc7117b56740414cc0536cgdongEFI_STATUS
2510c18794ea4289f03fefc7117b56740414cc0536cgdongTpmCommPhysicalPresence (
2520c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      EFI_PEI_SERVICES          **PeiServices,
2530c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TIS_TPM_HANDLE            TpmHandle,
2540c18794ea4289f03fefc7117b56740414cc0536cgdong  IN      TPM_PHYSICAL_PRESENCE     PhysicalPresence
2550c18794ea4289f03fefc7117b56740414cc0536cgdong  )
2560c18794ea4289f03fefc7117b56740414cc0536cgdong{
2570c18794ea4289f03fefc7117b56740414cc0536cgdong  EFI_STATUS                        Status;
2580c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmSendSize;
2590c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT32                            TpmRecvSize;
2600c18794ea4289f03fefc7117b56740414cc0536cgdong  TPM_CMD_PHYSICAL_PRESENCE         SendBuffer;
2610c18794ea4289f03fefc7117b56740414cc0536cgdong  UINT8                             RecvBuffer[10];
2620c18794ea4289f03fefc7117b56740414cc0536cgdong
2630c18794ea4289f03fefc7117b56740414cc0536cgdong  //
2640c18794ea4289f03fefc7117b56740414cc0536cgdong  // send Tpm command TSC_ORD_PhysicalPresence
2650c18794ea4289f03fefc7117b56740414cc0536cgdong  //
2660c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmRecvSize                 = 10;
2670c18794ea4289f03fefc7117b56740414cc0536cgdong  TpmSendSize                 = sizeof (TPM_CMD_PHYSICAL_PRESENCE);
2680c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.tag          = SwapBytes16 (TPM_TAG_RQU_COMMAND);
2690c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.paramSize    = SwapBytes32 (TpmSendSize);
2700c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.Hdr.ordinal      = SwapBytes32 (TSC_ORD_PhysicalPresence);
2710c18794ea4289f03fefc7117b56740414cc0536cgdong  SendBuffer.PhysicalPresence = SwapBytes16 (PhysicalPresence);
2720c18794ea4289f03fefc7117b56740414cc0536cgdong  Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
2730c18794ea4289f03fefc7117b56740414cc0536cgdong  return Status;
2740c18794ea4289f03fefc7117b56740414cc0536cgdong}
275