• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Basic TIS (TPM Interface Specification) functions.
3 
4 Copyright (c) 2005 - 2012, 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
TisPcPresenceCheck(IN TIS_PC_REGISTERS_PTR TisReg)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
TisPcWaitRegisterBits(IN UINT8 * Register,IN UINT8 BitSet,IN UINT8 BitClear,IN UINT32 TimeOut)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
TisPcReadBurstCount(IN TIS_PC_REGISTERS_PTR TisReg,OUT UINT16 * BurstCount)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
TisPcPrepareCommand(IN TIS_PC_REGISTERS_PTR TisReg)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_A.
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
TisPcRequestUseTpm(IN TIS_PC_REGISTERS_PTR TisReg)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   //
174   // No locality set before, ACCESS_X.activeLocality MUST be valid within TIMEOUT_A
175   //
176   Status = TisPcWaitRegisterBits (
177              &TisReg->Access,
178              (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
179              0,
180              TIS_TIMEOUT_A
181              );
182   return Status;
183 }
184