@@ -85,63 +85,115 @@ static bool is_amd_cpu(void)
8585
8686#define TPM_LOC_REG (loc , reg ) (0x1000 * (loc) + (reg))
8787
88- #define TPM_ACCESS_ (x ) TPM_LOC_REG(x, 0x00)
89- #define ACCESS_REQUEST_USE (1 << 1)
90- #define ACCESS_ACTIVE_LOCALITY (1 << 5)
91- #define TPM_INTF_CAPABILITY_ (x ) TPM_LOC_REG(x, 0x14)
92- #define INTF_VERSION_MASK 0x70000000
93- #define TPM_STS_ (x ) TPM_LOC_REG(x, 0x18)
94- #define TPM_FAMILY_MASK 0x0C000000
95- #define STS_EXPECT_DATA (1 << 3)
96- #define STS_DATA_AVAIL (1 << 4)
97- #define STS_TPM_GO (1 << 5)
98- #define STS_COMMAND_READY (1 << 6)
99- #define STS_VALID (1 << 7)
100- #define TPM_BURST_COUNT_ (x ) TPM_LOC_REG(x, 0x19)
101- #define TPM_DATA_FIFO_ (x ) TPM_LOC_REG(x, 0x24)
102-
10388#define swap16 (x ) __builtin_bswap16(x)
10489#define swap32 (x ) __builtin_bswap32(x)
10590
106- static inline volatile uint32_t tis_read32 (unsigned reg )
91+ /******************************** MMIO helpers ********************************/
92+
93+ static inline uint32_t tpm_read32 (unsigned reg )
10794{
108- return * (volatile uint32_t * )__va (TPM_TIS_BASE + reg );
95+ return * (volatile uint32_t * )__va (TPM_BASE + reg );
10996}
11097
111- static inline volatile uint16_t tis_read16 (unsigned reg )
98+ static inline uint16_t tpm_read16 (unsigned reg )
11299{
113- return * (volatile uint16_t * )__va (TPM_TIS_BASE + reg );
100+ return * (volatile uint16_t * )__va (TPM_BASE + reg );
114101}
115102
116- static inline volatile uint8_t tis_read8 (unsigned reg )
103+ static inline uint8_t tpm_read8 (unsigned reg )
117104{
118- return * (volatile uint8_t * )__va (TPM_TIS_BASE + reg );
105+ return * (volatile uint8_t * )__va (TPM_BASE + reg );
119106}
120107
121- static inline void tis_write8 (unsigned reg , uint8_t val )
108+ static inline void tpm_write32 (unsigned reg , uint32_t val )
122109{
123- * (volatile uint8_t * )__va (TPM_TIS_BASE + reg ) = val ;
110+ * (volatile uint32_t * )__va (TPM_BASE + reg ) = val ;
124111}
125112
126- static inline void request_locality (unsigned loc )
113+ static inline void tpm_write8 (unsigned reg , uint8_t val )
114+ {
115+ * (volatile uint8_t * )__va (TPM_BASE + reg ) = val ;
116+ }
117+
118+ /************************** Interface detection *******************************/
119+
120+ #define TPM_INTF_ID_ (x ) TPM_LOC_REG(x, 0x30)
121+ #define INTF_TYPE_MASK 0x0000000fU
122+ #define INTF_TYPE_TIS 0x00
123+ #define INTF_TYPE_CRB 0x01
124+
125+ /*
126+ * No static caching: the early 32-bit binary (tpm_early.bin) is built with
127+ * "objcopy -j .text", which omits .bss/.data.
128+ */
129+ static inline bool tpm_is_crb (void )
130+ {
131+ return (tpm_read32 (TPM_INTF_ID_ (0 )) & INTF_TYPE_MASK ) == INTF_TYPE_CRB ;
132+ }
133+
134+ /************************** TIS register definitions **************************/
135+
136+ #define TIS_ACCESS_ (x ) TPM_LOC_REG(x, 0x00)
137+ #define ACCESS_REQUEST_USE (1 << 1)
138+ #define ACCESS_ACTIVE_LOCALITY (1 << 5)
139+ #define TIS_INTF_CAPABILITY_ (x ) TPM_LOC_REG(x, 0x14)
140+ #define INTF_VERSION_MASK 0x70000000
141+ #define TIS_STS_ (x ) TPM_LOC_REG(x, 0x18)
142+ #define STS_FAMILY_MASK 0x0C000000
143+ #define STS_EXPECT_DATA (1 << 3)
144+ #define STS_DATA_AVAIL (1 << 4)
145+ #define STS_TPM_GO (1 << 5)
146+ #define STS_COMMAND_READY (1 << 6)
147+ #define STS_VALID (1 << 7)
148+ #define TIS_BURST_COUNT_ (x ) TPM_LOC_REG(x, 0x19)
149+ #define TIS_DATA_FIFO_ (x ) TPM_LOC_REG(x, 0x24)
150+
151+ /************************** CRB register definitions **************************/
152+
153+ #define CRB_LOC_STATE_ (x ) TPM_LOC_REG(x, 0x00)
154+ #define CRB_LOC_STATE_LOC_ASSIGNED (1 << 1)
155+ #define CRB_LOC_STATE_REG_VALID_STS (1 << 7)
156+ #define CRB_LOC_CTRL_ (x ) TPM_LOC_REG(x, 0x08)
157+ #define CRB_LOC_CTRL_REQUEST_ACCESS (1 << 0)
158+ #define CRB_LOC_CTRL_RELINQUISH (1 << 1)
159+ #define CRB_CTRL_REQ_ (x ) TPM_LOC_REG(x, 0x40)
160+ #define CRB_CTRL_REQ_CMD_READY (1 << 0)
161+ #define CRB_CTRL_REQ_GO_IDLE (1 << 1)
162+ #define CRB_CTRL_STS_ (x ) TPM_LOC_REG(x, 0x44)
163+ #define CRB_CTRL_STS_ERROR (1 << 0)
164+ #define CRB_CTRL_CANCEL_ (x ) TPM_LOC_REG(x, 0x48)
165+ #define CRB_CTRL_CANCEL_INVOKE (1 << 0)
166+ #define CRB_CTRL_START_ (x ) TPM_LOC_REG(x, 0x4C)
167+ #define CRB_CTRL_START_INVOKE (1 << 0)
168+ #define CRB_CTRL_CMD_SIZE_ (x ) TPM_LOC_REG(x, 0x58)
169+ #define CRB_CTRL_CMD_LADDR_ (x ) TPM_LOC_REG(x, 0x5C)
170+ #define CRB_CTRL_CMD_HADDR_ (x ) TPM_LOC_REG(x, 0x60)
171+ #define CRB_CTRL_RSP_SIZE_ (x ) TPM_LOC_REG(x, 0x64)
172+ #define CRB_CTRL_RSP_ADDR_ (x ) TPM_LOC_REG(x, 0x68)
173+ #define CRB_DATA_BUFFER_ (x ) TPM_LOC_REG(x, 0x80)
174+ #define CRB_DATA_BUFFER_SIZE 0x0F80
175+
176+ /************************** TIS locality & command ****************************/
177+
178+ static inline void tis_request_locality (unsigned loc )
127179{
128- tis_write8 ( TPM_ACCESS_ (loc ), ACCESS_REQUEST_USE );
180+ tpm_write8 ( TIS_ACCESS_ (loc ), ACCESS_REQUEST_USE );
129181 /* Check that locality was actually activated. */
130- while ( (tis_read8 ( TPM_ACCESS_ (loc )) & ACCESS_ACTIVE_LOCALITY ) == 0 );
182+ while ( (tpm_read8 ( TIS_ACCESS_ (loc )) & ACCESS_ACTIVE_LOCALITY ) == 0 );
131183}
132184
133- static inline void relinquish_locality (unsigned loc )
185+ static inline void tis_relinquish_locality (unsigned loc )
134186{
135- tis_write8 ( TPM_ACCESS_ (loc ), ACCESS_ACTIVE_LOCALITY );
187+ tpm_write8 ( TIS_ACCESS_ (loc ), ACCESS_ACTIVE_LOCALITY );
136188}
137189
138- static inline uint16_t get_burst_count (unsigned loc )
190+ static inline uint16_t tis_get_burst_count (unsigned loc )
139191{
140- return tis_read16 ( TPM_BURST_COUNT_ (loc ));
192+ return tpm_read16 ( TIS_BURST_COUNT_ (loc ));
141193}
142194
143- static void send_cmd (unsigned loc , uint8_t * buf , unsigned i_size ,
144- unsigned * o_size )
195+ static void tis_send_cmd (unsigned loc , uint8_t * buf , unsigned i_size ,
196+ unsigned * o_size )
145197{
146198 /*
147199 * Values of "expect data" and "data available" bits counts only when
@@ -154,65 +206,170 @@ static void send_cmd(unsigned loc, uint8_t *buf, unsigned i_size,
154206 unsigned burst_count ;
155207
156208 /* Make sure TPM can accept a command. */
157- if ( (tis_read8 ( TPM_STS_ (loc )) & STS_COMMAND_READY ) == 0 )
209+ if ( (tpm_read8 ( TIS_STS_ (loc )) & STS_COMMAND_READY ) == 0 )
158210 {
159211 /* Abort current command. */
160- tis_write8 ( TPM_STS_ (loc ), STS_COMMAND_READY );
212+ tpm_write8 ( TIS_STS_ (loc ), STS_COMMAND_READY );
161213 /* Wait until TPM is ready for a new one. */
162- while ( (tis_read8 ( TPM_STS_ (loc )) & STS_COMMAND_READY ) == 0 );
214+ while ( (tpm_read8 ( TIS_STS_ (loc )) & STS_COMMAND_READY ) == 0 );
163215 }
164216
165217 i = 0 ;
166218 while ( i < i_size )
167219 {
168220 do
169- burst_count = get_burst_count (loc );
221+ burst_count = tis_get_burst_count (loc );
170222 while ( burst_count == 0 );
171223
172224 while ( burst_count -- > 0 && i < i_size )
173- tis_write8 ( TPM_DATA_FIFO_ (loc ), buf [i ++ ]);
225+ tpm_write8 ( TIS_DATA_FIFO_ (loc ), buf [i ++ ]);
174226
175227 if ( i < i_size )
176- while ( (tis_read8 ( TPM_STS_ (loc )) & expect_data ) != expect_data );
228+ while ( (tpm_read8 ( TIS_STS_ (loc )) & expect_data ) != expect_data );
177229 }
178230
179- tis_write8 ( TPM_STS_ (loc ), STS_TPM_GO );
231+ tpm_write8 ( TIS_STS_ (loc ), STS_TPM_GO );
180232
181233 /* Wait for the first byte of response. */
182- while ( (tis_read8 ( TPM_STS_ (loc )) & data_avail ) != data_avail );
234+ while ( (tpm_read8 ( TIS_STS_ (loc )) & data_avail ) != data_avail );
183235
184236 i = 0 ;
185237 do {
186238 do
187- burst_count = get_burst_count (loc );
239+ burst_count = tis_get_burst_count (loc );
188240 while ( burst_count == 0 );
189241
190242 while ( burst_count -- > 0 && i < * o_size )
191- buf [i ++ ] = tis_read8 ( TPM_DATA_FIFO_ (loc ));
243+ buf [i ++ ] = tpm_read8 ( TIS_DATA_FIFO_ (loc ));
192244
193- while ( (tis_read8 ( TPM_STS_ (loc )) & STS_VALID ) == 0 );
245+ while ( (tpm_read8 ( TIS_STS_ (loc )) & STS_VALID ) == 0 );
194246 } while ( i < * o_size &&
195- (tis_read8 ( TPM_STS_ (loc )) & data_avail ) == data_avail );
247+ (tpm_read8 ( TIS_STS_ (loc )) & data_avail ) == data_avail );
196248
197249 if ( i < * o_size )
198250 * o_size = i ;
199251
200- tis_write8 (TPM_STS_ (loc ), STS_COMMAND_READY );
252+ tpm_write8 (TIS_STS_ (loc ), STS_COMMAND_READY );
253+ }
254+
255+ /************************** CRB locality & command ****************************/
256+
257+ static void crb_request_locality (unsigned loc )
258+ {
259+ const uint32_t mask = CRB_LOC_STATE_LOC_ASSIGNED |
260+ CRB_LOC_STATE_REG_VALID_STS ;
261+
262+ tpm_write32 (CRB_LOC_CTRL_ (loc ), CRB_LOC_CTRL_REQUEST_ACCESS );
263+ while ( (tpm_read32 (CRB_LOC_STATE_ (loc )) & mask ) != mask );
264+ }
265+
266+ static void crb_relinquish_locality (unsigned loc )
267+ {
268+ tpm_write32 (CRB_LOC_CTRL_ (loc ), CRB_LOC_CTRL_RELINQUISH );
269+ while ( tpm_read32 (CRB_LOC_STATE_ (loc )) & CRB_LOC_STATE_LOC_ASSIGNED );
270+ }
271+
272+ static void crb_cmd_ready (unsigned loc )
273+ {
274+ tpm_write32 (CRB_CTRL_REQ_ (loc ), CRB_CTRL_REQ_CMD_READY );
275+ while ( tpm_read32 (CRB_CTRL_REQ_ (loc )) & CRB_CTRL_REQ_CMD_READY );
276+ }
277+
278+ static void crb_go_idle (unsigned loc )
279+ {
280+ tpm_write32 (CRB_CTRL_REQ_ (loc ), CRB_CTRL_REQ_GO_IDLE );
281+ while ( tpm_read32 (CRB_CTRL_REQ_ (loc )) & CRB_CTRL_REQ_GO_IDLE );
282+ }
283+
284+ static void crb_send_cmd (unsigned loc , uint8_t * buf , unsigned i_size ,
285+ unsigned * o_size )
286+ {
287+ uint32_t data_buf_pa = TPM_BASE + CRB_DATA_BUFFER_ (loc );
288+ unsigned expected ;
289+
290+ crb_cmd_ready (loc );
291+
292+ tpm_write32 (CRB_CTRL_CANCEL_ (loc ), 0 );
293+
294+ tpm_write32 (CRB_CTRL_CMD_LADDR_ (loc ), data_buf_pa );
295+ tpm_write32 (CRB_CTRL_CMD_HADDR_ (loc ), 0 );
296+ tpm_write32 (CRB_CTRL_CMD_SIZE_ (loc ), CRB_DATA_BUFFER_SIZE );
297+ tpm_write32 (CRB_CTRL_RSP_SIZE_ (loc ), CRB_DATA_BUFFER_SIZE );
298+ /* RSP_ADDR is 64-bit. */
299+ tpm_write32 (CRB_CTRL_RSP_ADDR_ (loc ), data_buf_pa );
300+ tpm_write32 (CRB_CTRL_RSP_ADDR_ (loc ) + 4 , 0 );
301+
302+ memcpy (__va (data_buf_pa ), buf , i_size );
303+
304+ tpm_write32 (CRB_CTRL_START_ (loc ), CRB_CTRL_START_INVOKE );
305+ while ( tpm_read32 (CRB_CTRL_START_ (loc )) & CRB_CTRL_START_INVOKE );
306+
307+ if ( tpm_read32 (CRB_CTRL_STS_ (loc )) & CRB_CTRL_STS_ERROR )
308+ {
309+ * o_size = 0 ;
310+ crb_go_idle (loc );
311+ return ;
312+ }
313+
314+ /* Read header to learn the response length. */
315+ memcpy (buf , __va (data_buf_pa ), sizeof (struct tpm_rsp_hdr ));
316+ expected = swap32 (((struct tpm_rsp_hdr * )buf )-> paramSize );
317+ if ( expected > * o_size )
318+ expected = * o_size ;
319+ if ( expected > CRB_DATA_BUFFER_SIZE )
320+ expected = CRB_DATA_BUFFER_SIZE ;
321+
322+ memcpy (buf , __va (data_buf_pa ), expected );
323+
324+ * o_size = expected ;
325+ crb_go_idle (loc );
326+ }
327+
328+ /************************** Interface dispatch ********************************/
329+
330+ static inline void request_locality (unsigned loc )
331+ {
332+ if ( tpm_is_crb () )
333+ crb_request_locality (loc );
334+ else
335+ tis_request_locality (loc );
336+ }
337+
338+ static inline void relinquish_locality (unsigned loc )
339+ {
340+ if ( tpm_is_crb () )
341+ crb_relinquish_locality (loc );
342+ else
343+ tis_relinquish_locality (loc );
344+ }
345+
346+ static void send_cmd (unsigned loc , uint8_t * buf , unsigned i_size ,
347+ unsigned * o_size )
348+ {
349+ if ( tpm_is_crb () )
350+ crb_send_cmd (loc , buf , i_size , o_size );
351+ else
352+ tis_send_cmd (loc , buf , i_size , o_size );
201353}
202354
203355static inline bool is_tpm12 (void )
204356{
357+ uint32_t intf_version ;
358+
359+ /* CRB interface is always TPM 2.0. */
360+ if ( tpm_is_crb () )
361+ return false;
362+
205363 /*
206364 * If one of these conditions is true:
207365 * - INTF_CAPABILITY_x.interfaceVersion is 0 (TIS <= 1.21)
208366 * - INTF_CAPABILITY_x.interfaceVersion is 2 (TIS == 1.3)
209367 * - STS_x.tpmFamily is 0
210368 * we're dealing with TPM1.2.
211369 */
212- uint32_t intf_version = tis_read32 (TPM_INTF_CAPABILITY_ (0 ))
213- & INTF_VERSION_MASK ;
370+ intf_version = tpm_read32 (TIS_INTF_CAPABILITY_ (0 )) & INTF_VERSION_MASK ;
214371 return (intf_version == 0x00000000 || intf_version == 0x20000000 ||
215- (tis_read32 ( TPM_STS_ (0 )) & TPM_FAMILY_MASK ) == 0 );
372+ (tpm_read32 ( TIS_STS_ (0 )) & STS_FAMILY_MASK ) == 0 );
216373}
217374
218375/****************************** TPM1.2 & TPM2.0 *******************************/
0 commit comments