2 TIS (TPM Interface Specification) functions used by TPM PEI driver.
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
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.
15 #include <IndustryStandard/Tpm12.h>
16 #include <IndustryStandard/UefiTcgPlatform.h>
17 #include <Library/TpmCommLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/IoLib.h>
21 #include <Library/BaseMemoryLib.h>
24 Send a command to TPM for execution and return response data.
26 @param[in] PeiServices Describes the list of possible PEI Services.
27 @param[in] TisReg TPM register space base address.
28 @param[in] BufferIn Buffer for command data.
29 @param[in] SizeIn Size of command data.
30 @param[in, out] BufferOut Buffer for response data.
31 @param[in, out] SizeOut Size of response data.
33 @retval EFI_SUCCESS Operation completed successfully.
34 @retval EFI_TIMEOUT The register can't run into the expected status in time.
35 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
36 @retval EFI_DEVICE_ERROR Unexpected device behavior.
41 IN EFI_PEI_SERVICES
**PeiServices
,
42 IN TIS_PC_REGISTERS_PTR TisReg
,
45 IN OUT UINT8
*BufferOut
,
46 IN OUT UINT32
*SizeOut
56 Status
= TisPcPrepareCommand (TisReg
);
57 if (EFI_ERROR (Status
)){
58 DEBUG ((DEBUG_ERROR
, "Tpm is not ready for command!\n"));
62 // Send the command data to Tpm
65 while (Index
< SizeIn
) {
66 Status
= TisPcReadBurstCount (TisReg
, &BurstCount
);
67 if (EFI_ERROR (Status
)) {
71 for (; BurstCount
> 0 && Index
< SizeIn
; BurstCount
--) {
72 MmioWrite8((UINTN
)&TisReg
->DataFifo
, *(BufferIn
+ Index
));
77 // Check the Tpm status STS_EXPECT change from 1 to 0
79 Status
= TisPcWaitRegisterBits (
85 if (EFI_ERROR (Status
)) {
86 DEBUG ((DEBUG_ERROR
, "The send buffer too small!\n"));
87 Status
= EFI_BUFFER_TOO_SMALL
;
91 // Executed the TPM command and waiting for the response data ready
93 MmioWrite8((UINTN
)&TisReg
->Status
, TIS_PC_STS_GO
);
94 Status
= TisPcWaitRegisterBits (
96 (UINT8
) (TIS_PC_VALID
| TIS_PC_STS_DATA
),
100 if (EFI_ERROR (Status
)) {
101 DEBUG ((DEBUG_ERROR
, "Wait for Tpm response data time out!!\n"));
102 Status
= EFI_TIMEOUT
;
106 // Get response data header
110 while (Index
< sizeof (TPM_RSP_COMMAND_HDR
)) {
111 Status
= TisPcReadBurstCount (TisReg
, &BurstCount
);
112 if (EFI_ERROR (Status
)) {
113 Status
= EFI_TIMEOUT
;
116 for (; BurstCount
> 0; BurstCount
--) {
117 *(BufferOut
+ Index
) = MmioRead8 ((UINTN
)&TisReg
->DataFifo
);
119 if (Index
== sizeof (TPM_RSP_COMMAND_HDR
)) break;
123 // Check the reponse data header (tag,parasize and returncode )
125 CopyMem (&Data16
, BufferOut
, sizeof (UINT16
));
126 if (SwapBytes16 (Data16
) != TPM_TAG_RSP_COMMAND
) {
127 Status
= EFI_DEVICE_ERROR
;
131 CopyMem (&Data32
, (BufferOut
+ 2), sizeof (UINT32
));
132 TpmOutSize
= SwapBytes32 (Data32
);
133 if (*SizeOut
< TpmOutSize
) {
134 Status
= EFI_BUFFER_TOO_SMALL
;
137 *SizeOut
= TpmOutSize
;
139 // Continue reading the remaining data
141 while ( Index
< TpmOutSize
) {
142 for (; BurstCount
> 0; BurstCount
--) {
143 *(BufferOut
+ Index
) = MmioRead8 ((UINTN
)&TisReg
->DataFifo
);
145 if (Index
== TpmOutSize
) {
146 Status
= EFI_SUCCESS
;
150 Status
= TisPcReadBurstCount (TisReg
, &BurstCount
);
151 if (EFI_ERROR (Status
)) {
152 Status
= EFI_TIMEOUT
;
157 MmioWrite8((UINTN
)&TisReg
->Status
, TIS_PC_STS_READY
);