TisPc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /** @file
  2. Basic TIS (TPM Interface Specification) functions.
  3. Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "CommonHeader.h"
  7. /**
  8. Check whether TPM chip exist.
  9. @param[in] TisReg Pointer to TIS register.
  10. @retval TRUE TPM chip exists.
  11. @retval FALSE TPM chip is not found.
  12. **/
  13. BOOLEAN
  14. TisPcPresenceCheck (
  15. IN TIS_PC_REGISTERS_PTR TisReg
  16. )
  17. {
  18. UINT8 RegRead;
  19. RegRead = MmioRead8 ((UINTN)&TisReg->Access);
  20. return (BOOLEAN)(RegRead != (UINT8)-1);
  21. }
  22. /**
  23. Check whether the value of a TPM chip register satisfies the input BIT setting.
  24. @param[in] Register Address port of register to be checked.
  25. @param[in] BitSet Check these data bits are set.
  26. @param[in] BitClear Check these data bits are clear.
  27. @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
  28. @retval EFI_SUCCESS The register satisfies the check bit.
  29. @retval EFI_TIMEOUT The register can't run into the expected status in time.
  30. **/
  31. EFI_STATUS
  32. EFIAPI
  33. TisPcWaitRegisterBits (
  34. IN UINT8 *Register,
  35. IN UINT8 BitSet,
  36. IN UINT8 BitClear,
  37. IN UINT32 TimeOut
  38. )
  39. {
  40. UINT8 RegRead;
  41. UINT32 WaitTime;
  42. for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
  43. RegRead = MmioRead8 ((UINTN)Register);
  44. if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)
  45. return EFI_SUCCESS;
  46. MicroSecondDelay (30);
  47. }
  48. return EFI_TIMEOUT;
  49. }
  50. /**
  51. Get BurstCount by reading the burstCount field of a TIS regiger
  52. in the time of default TIS_TIMEOUT_D.
  53. @param[in] TisReg Pointer to TIS register.
  54. @param[out] BurstCount Pointer to a buffer to store the got BurstCount.
  55. @retval EFI_SUCCESS Get BurstCount.
  56. @retval EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.
  57. @retval EFI_TIMEOUT BurstCount can't be got in time.
  58. **/
  59. EFI_STATUS
  60. EFIAPI
  61. TisPcReadBurstCount (
  62. IN TIS_PC_REGISTERS_PTR TisReg,
  63. OUT UINT16 *BurstCount
  64. )
  65. {
  66. UINT32 WaitTime;
  67. UINT8 DataByte0;
  68. UINT8 DataByte1;
  69. if (BurstCount == NULL || TisReg == NULL) {
  70. return EFI_INVALID_PARAMETER;
  71. }
  72. WaitTime = 0;
  73. do {
  74. //
  75. // TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,
  76. // so it needs to use MmioRead8 to read two times
  77. //
  78. DataByte0 = MmioRead8 ((UINTN)&TisReg->BurstCount);
  79. DataByte1 = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);
  80. *BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
  81. if (*BurstCount != 0) {
  82. return EFI_SUCCESS;
  83. }
  84. MicroSecondDelay (30);
  85. WaitTime += 30;
  86. } while (WaitTime < TIS_TIMEOUT_D);
  87. return EFI_TIMEOUT;
  88. }
  89. /**
  90. Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
  91. to Status Register in time.
  92. @param[in] TisReg Pointer to TIS register.
  93. @retval EFI_SUCCESS TPM chip enters into ready state.
  94. @retval EFI_INVALID_PARAMETER TisReg is NULL.
  95. @retval EFI_TIMEOUT TPM chip can't be set to ready state in time.
  96. **/
  97. EFI_STATUS
  98. EFIAPI
  99. TisPcPrepareCommand (
  100. IN TIS_PC_REGISTERS_PTR TisReg
  101. )
  102. {
  103. EFI_STATUS Status;
  104. if (TisReg == NULL) {
  105. return EFI_INVALID_PARAMETER;
  106. }
  107. MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
  108. Status = TisPcWaitRegisterBits (
  109. &TisReg->Status,
  110. TIS_PC_STS_READY,
  111. 0,
  112. TIS_TIMEOUT_B
  113. );
  114. return Status;
  115. }
  116. /**
  117. Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
  118. to ACCESS Register in the time of default TIS_TIMEOUT_A.
  119. @param[in] TisReg Pointer to TIS register.
  120. @retval EFI_SUCCESS Get the control of TPM chip.
  121. @retval EFI_INVALID_PARAMETER TisReg is NULL.
  122. @retval EFI_NOT_FOUND TPM chip doesn't exit.
  123. @retval EFI_TIMEOUT Can't get the TPM control in time.
  124. **/
  125. EFI_STATUS
  126. EFIAPI
  127. TisPcRequestUseTpm (
  128. IN TIS_PC_REGISTERS_PTR TisReg
  129. )
  130. {
  131. EFI_STATUS Status;
  132. if (TisReg == NULL) {
  133. return EFI_INVALID_PARAMETER;
  134. }
  135. if (!TisPcPresenceCheck (TisReg)) {
  136. return EFI_NOT_FOUND;
  137. }
  138. MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);
  139. //
  140. // No locality set before, ACCESS_X.activeLocality MUST be valid within TIMEOUT_A
  141. //
  142. Status = TisPcWaitRegisterBits (
  143. &TisReg->Access,
  144. (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
  145. 0,
  146. TIS_TIMEOUT_A
  147. );
  148. return Status;
  149. }