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