]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/TpmCommLib/TisPc.c
Add security package to repository.
[mirror_edk2.git] / SecurityPkg / Library / TpmCommLib / TisPc.c
diff --git a/SecurityPkg/Library/TpmCommLib/TisPc.c b/SecurityPkg/Library/TpmCommLib/TisPc.c
new file mode 100644 (file)
index 0000000..3d74a01
--- /dev/null
@@ -0,0 +1,180 @@
+/** @file\r
+  Basic TIS (TPM Interface Specification) functions.\r
+\r
+Copyright (c) 2005 - 2011, 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
+\r
+**/\r
+\r
+#include "CommonHeader.h"\r
+\r
+/**\r
+  Check whether TPM chip exist.\r
+\r
+  @param[in] TisReg  Pointer to TIS register.\r
+\r
+  @retval    TRUE    TPM chip exists.\r
+  @retval    FALSE   TPM chip is not found.\r
+**/\r
+BOOLEAN\r
+TisPcPresenceCheck (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg\r
+  )\r
+{\r
+  UINT8                             RegRead;\r
+  \r
+  RegRead = MmioRead8 ((UINTN)&TisReg->Access);\r
+  return (BOOLEAN)(RegRead != (UINT8)-1);\r
+}\r
+\r
+/**\r
+  Check whether the value of a TPM chip register satisfies the input BIT setting.\r
+\r
+  @param[in]  Register     Address port of register to be checked.\r
+  @param[in]  BitSet       Check these data bits are set.\r
+  @param[in]  BitClear     Check these data bits are clear.\r
+  @param[in]  TimeOut      The max wait time (unit MicroSecond) when checking register.\r
+\r
+  @retval     EFI_SUCCESS  The register satisfies the check bit.\r
+  @retval     EFI_TIMEOUT  The register can't run into the expected status in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TisPcWaitRegisterBits (\r
+  IN      UINT8                     *Register,\r
+  IN      UINT8                     BitSet,\r
+  IN      UINT8                     BitClear,\r
+  IN      UINT32                    TimeOut\r
+  )\r
+{\r
+  UINT8                             RegRead;\r
+  UINT32                            WaitTime;\r
+\r
+  for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){\r
+    RegRead = MmioRead8 ((UINTN)Register);\r
+    if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)\r
+      return EFI_SUCCESS;\r
+    MicroSecondDelay (30);\r
+  }\r
+  return EFI_TIMEOUT;\r
+}\r
+\r
+/**\r
+  Get BurstCount by reading the burstCount field of a TIS regiger \r
+  in the time of default TIS_TIMEOUT_D.\r
+\r
+  @param[in]  TisReg                Pointer to TIS register.\r
+  @param[out] BurstCount            Pointer to a buffer to store the got BurstConut.\r
+\r
+  @retval     EFI_SUCCESS           Get BurstCount.\r
+  @retval     EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.\r
+  @retval     EFI_TIMEOUT           BurstCount can't be got in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TisPcReadBurstCount (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg,\r
+     OUT  UINT16                    *BurstCount\r
+  )\r
+{\r
+  UINT32                            WaitTime;\r
+  UINT8                             DataByte0;\r
+  UINT8                             DataByte1;\r
+\r
+  if (BurstCount == NULL || TisReg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  WaitTime = 0;\r
+  do {\r
+    //\r
+    // TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,\r
+    // so it needs to use MmioRead8 to read two times\r
+    //\r
+    DataByte0   = MmioRead8 ((UINTN)&TisReg->BurstCount);\r
+    DataByte1   = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);\r
+    *BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);\r
+    if (*BurstCount != 0) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    MicroSecondDelay (30);\r
+    WaitTime += 30;\r
+  } while (WaitTime < TIS_TIMEOUT_D);\r
+\r
+  return EFI_TIMEOUT;\r
+}\r
+\r
+/**\r
+  Set TPM chip to ready state by sending ready command TIS_PC_STS_READY \r
+  to Status Register in time.\r
+\r
+  @param[in] TisReg                Pointer to TIS register.\r
+\r
+  @retval    EFI_SUCCESS           TPM chip enters into ready state.\r
+  @retval    EFI_INVALID_PARAMETER TisReg is NULL.\r
+  @retval    EFI_TIMEOUT           TPM chip can't be set to ready state in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TisPcPrepareCommand (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+\r
+  if (TisReg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);\r
+  Status = TisPcWaitRegisterBits (\r
+             &TisReg->Status,\r
+             TIS_PC_STS_READY,\r
+             0,\r
+             TIS_TIMEOUT_B\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE \r
+  to ACCESS Register in the time of default TIS_TIMEOUT_D.\r
+\r
+  @param[in] TisReg                Pointer to TIS register.\r
+\r
+  @retval    EFI_SUCCESS           Get the control of TPM chip.\r
+  @retval    EFI_INVALID_PARAMETER TisReg is NULL.\r
+  @retval    EFI_NOT_FOUND         TPM chip doesn't exit.\r
+  @retval    EFI_TIMEOUT           Can't get the TPM control in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TisPcRequestUseTpm (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  \r
+  if (TisReg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  if (!TisPcPresenceCheck (TisReg)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);\r
+  Status = TisPcWaitRegisterBits (\r
+             &TisReg->Access,\r
+             (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),\r
+             0,\r
+             TIS_TIMEOUT_D\r
+             );\r
+  return Status;\r
+}\r