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