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