Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: drivers/tpm/slb9635_i2c/tpm_proto.c

Issue 6683023: Add Infineon v05 TPM driver (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/u-boot-next.git@chromeos-v2010.09
Patch Set: Fix nits Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « drivers/tpm/slb9635_i2c/tpm.c ('k') | drivers/tpm/slb9635_i2c/tpm_tis_i2c.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 */ 4 */
5 5
6 #include <config.h> 6 #include <config.h>
7 #include <common.h> 7 #include <common.h>
8 #include <i2c.h> 8 #include <i2c.h>
9 9
10 #define INFINEON_TPM_CHIP (CONFIG_INFINEON_TPM_CHIP_ADDRESS)
11 10
12 /* infineon prototype i2c tpm's internal registers 11 /* infineon prototype i2c tpm's internal registers
13 */ 12 */
13 #define INFINEON_TPM_CHIP (0x1A)
14 #define REG_RDATA (0xA4) 14 #define REG_RDATA (0xA4)
15 #define REG_WDATA (0xA5) 15 #define REG_WDATA (0xA5)
16 #define REG_STAT (0xA7) 16 #define REG_STAT (0xA7)
17 /* i2c timeout value and polling period 17 /* i2c timeout value and polling period
18 */ 18 */
19 #define I2CBUSY_WAIT_US» (1000ul) 19 #define I2CBUSY_WAIT_MS» (1ul)
20 #define TIMEOUT_REG_US (1000000ul) 20 #define TIMEOUT_REG_MS (1000ul)
21 21
22 /* error code follows u-boot standard 22 /* error code follows u-boot standard
23 * 0 : success 23 * 0 : success
24 * non zero : failed 24 * non zero : failed
25 */ 25 */
26 enum { 26 enum {
27 E_TIMEOUT = -7, 27 E_TIMEOUT = -7,
28 E_CHECKSUM = -6, 28 E_CHECKSUM = -6,
29 E_SIZE = -5, 29 E_SIZE = -5,
30 E_MEMORY = -4, 30 E_MEMORY = -4,
31 E_DATA = -3, 31 E_DATA = -3,
32 E_PARAMETER = -2, 32 E_PARAMETER = -2,
33 E_GENERAL = -1, 33 E_GENERAL = -1,
34 S_OK = 0, 34 S_OK = 0,
35 E_WARNING = 1 35 E_WARNING = 1
36 }; 36 };
37 37
38 /* tpm chip timeout value on read/write 38 /* tpm chip timeout value on read/write
39 * TODO: 39 * TODO:
40 * find the correct timeout when tpm in i2c mode. but since this is the 40 * find the correct timeout when tpm in i2c mode. but since this is the
41 * prototype i2c tpm chip, spec is not as clear as lpc tpm chip. just use 41 * prototype i2c tpm chip, spec is not as clear as lpc tpm chip. just use
42 * the maximum wait time as the timeout value. 42 * the maximum wait time as the timeout value.
43 */ 43 */
44 #define TIMEOUT_READ_US (3000000ul) 44 #define TIMEOUT_READ_MS (3000ul)
45 #define TIMEOUT_WRITE_US (1000000ul) 45 #define TIMEOUT_WRITE_MS (1000ul)
46 46
47 /* tpm stat register bits 47 /* tpm stat register bits
48 */ 48 */
49 #define TPM_RECEIVE_DATA_AVAILABLE (1u) 49 #define TPM_RECEIVE_DATA_AVAILABLE (1u)
50 #define TPM_TRANSMIT_FIFO_NOTFULL (1u << 7) 50 #define TPM_TRANSMIT_FIFO_NOTFULL (1u << 7)
51 51
52 /* tpm transport and vendor layers 52 /* tpm transport and vendor layers
53 */ 53 */
54 enum { 54 enum {
55 TSPT_VER = 0, 55 TSPT_VER = 0,
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 *pcopy_size = data_len; 217 *pcopy_size = data_len;
218 tpm_i2c_debug_dump(from, 0, DATA_START + data_len + 1); 218 tpm_i2c_debug_dump(from, 0, DATA_START + data_len + 1);
219 return 0; 219 return 0;
220 } 220 }
221 221
222 static int tpm_i2c_reg(uint8_t *reg) 222 static int tpm_i2c_reg(uint8_t *reg)
223 { 223 {
224 ulong stime = get_timer(0); 224 ulong stime = get_timer(0);
225 while (i2c_write_data((uchar)INFINEON_TPM_CHIP, reg, 1)) { 225 while (i2c_write_data((uchar)INFINEON_TPM_CHIP, reg, 1)) {
226 /* i2c busy, wait 1ms */ 226 /* i2c busy, wait 1ms */
227 » » udelay(I2CBUSY_WAIT_US); 227 » » udelay(I2CBUSY_WAIT_MS * 1000);
228 » » if (get_timer(stime) > TIMEOUT_REG_US) 228 » » if (get_timer(stime) > TIMEOUT_REG_MS)
229 return E_TIMEOUT; 229 return E_TIMEOUT;
230 } 230 }
231 return 0; 231 return 0;
232 } 232 }
233 233
234 static int tpm_i2c_read_status(t_inf_stat_reg *preg) 234 static int tpm_i2c_read_status(t_inf_stat_reg *preg)
235 { 235 {
236 uint8_t s_reg[8]; 236 uint8_t s_reg[8];
237 uint8_t stat[4]; 237 uint8_t stat[4];
238 s_reg[0] = (uchar)REG_STAT; 238 s_reg[0] = (uchar)REG_STAT;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 TPM_CHECK(tpm_i2c_read_status(&st_reg)); 328 TPM_CHECK(tpm_i2c_read_status(&st_reg));
329 } while ((get_timer(stime) < timeout_us) && 329 } while ((get_timer(stime) < timeout_us) &&
330 (st_reg.status & TPM_RECEIVE_DATA_AVAILABLE) == 0); 330 (st_reg.status & TPM_RECEIVE_DATA_AVAILABLE) == 0);
331 331
332 return (st_reg.status & TPM_RECEIVE_DATA_AVAILABLE) == 0 ? 332 return (st_reg.status & TPM_RECEIVE_DATA_AVAILABLE) == 0 ?
333 E_TIMEOUT : 0; 333 E_TIMEOUT : 0;
334 } 334 }
335 335
336 /* TPM API 336 /* TPM API
337 */ 337 */
338 int tpm_status(int *ready_write, int *ready_read, size_t *p_len) 338 int tpm_status_v03(int *ready_write, int *ready_read, size_t *p_len)
339 { 339 {
340 t_inf_stat_reg reg; 340 t_inf_stat_reg reg;
341 341
342 TPM_CHECK(tpm_i2c_read_status(&reg)); 342 TPM_CHECK(tpm_i2c_read_status(&reg));
343 /* exception case in prototype spec, error 343 /* exception case in prototype spec, error
344 */ 344 */
345 if (reg.status == 0xff && reg.len_h == 0xff && reg.len_l == 0xff) 345 if (reg.status == 0xff && reg.len_h == 0xff && reg.len_l == 0xff)
346 return E_GENERAL; 346 return E_GENERAL;
347 /* verify status checksum 347 /* verify status checksum
348 */ 348 */
349 if ((reg.status ^ reg.len_h ^ reg.len_l) != reg.checksum) 349 if ((reg.status ^ reg.len_h ^ reg.len_l) != reg.checksum)
350 return E_CHECKSUM; 350 return E_CHECKSUM;
351 /* data available 351 /* data available
352 » */ 352 » */
353 if (ready_read) 353 if (ready_read)
354 *ready_read = (reg.status & TPM_RECEIVE_DATA_AVAILABLE) ? 1 : 0; 354 *ready_read = (reg.status & TPM_RECEIVE_DATA_AVAILABLE) ? 1 : 0;
355 /* data length 355 /* data length
356 */ 356 */
357 if (p_len) { 357 if (p_len) {
358 if (*ready_read) 358 if (*ready_read)
359 *p_len = ((size_t)reg.len_h << 8) + (size_t)reg.len_l; 359 *p_len = ((size_t)reg.len_h << 8) + (size_t)reg.len_l;
360 else 360 else
361 *p_len = 0; 361 *p_len = 0;
362 } 362 }
363 /* device writable 363 /* device writable
364 */ 364 */
365 if (ready_write) 365 if (ready_write)
366 *ready_write = (reg.status & TPM_TRANSMIT_FIFO_NOTFULL) ? 1 : 0; 366 *ready_write = (reg.status & TPM_TRANSMIT_FIFO_NOTFULL) ? 1 : 0;
367 return 0; 367 return 0;
368 } 368 }
369 369
370 370
371 int tpm_init(void) 371 int tpm_init_v03(void)
372 { 372 {
373 int ready_write = 0, ready_read = 0; 373 int ready_write = 0, ready_read = 0;
374 size_t read_len = 0; 374 size_t read_len = 0;
375 int ret_code; 375 int ret_code;
376 #if defined(CONFIG_I2C_MULTI_BUS) 376 #if defined(CONFIG_I2C_MULTI_BUS)
377 i2c_set_bus_num(CONFIG_INFINEON_TPM_I2C_BUS); 377 i2c_set_bus_num(CONFIG_INFINEON_TPM_I2C_BUS);
378 #endif 378 #endif
379 ret_code = i2c_probe(INFINEON_TPM_CHIP); 379 ret_code = i2c_probe(INFINEON_TPM_CHIP);
380 #ifdef VBOOT_DEBUG 380 #ifdef VBOOT_DEBUG
381 » printf("probe : %d\n", ret_code); 381 » printf("v03 probe : %s\n", ret_code ? "N/A" : "found");
382 #endif /* VBOOT_DEBUG */ 382 #endif /* VBOOT_DEBUG */
383 if (ret_code) 383 if (ret_code)
384 return ret_code; 384 return ret_code;
385 » ret_code = tpm_status(&ready_write, &ready_read, &read_len); 385 » ret_code = tpm_status_v03(&ready_write, &ready_read, &read_len);
386 #ifdef VBOOT_DEBUG 386 #ifdef VBOOT_DEBUG
387 printf("status : %d\n\tw[%c] r[%c : %u]\n", ret_code, 387 printf("status : %d\n\tw[%c] r[%c : %u]\n", ret_code,
388 ready_write ? 'y' : 'n', 388 ready_write ? 'y' : 'n',
389 ready_read ? 'y' : 'n', read_len); 389 ready_read ? 'y' : 'n', read_len);
390 #endif /* VBOOT_DEBUG */ 390 #endif /* VBOOT_DEBUG */
391 if (ret_code) 391 if (ret_code)
392 return ret_code; 392 return ret_code;
393 » TPM_CHECK(tpm_prepare_write(TIMEOUT_WRITE_US)); 393 » TPM_CHECK(tpm_prepare_write(TIMEOUT_WRITE_MS));
394 return 0; 394 return 0;
395 } 395 }
396 396
397 int tpm_send(const uint8_t *pdata, size_t length) 397 int tpm_sendrecv_v03(const uint8_t *sendbuf, size_t buf_size, uint8_t *recvbuf,
398 » size_t *recv_len)
398 { 399 {
399 » TPM_CHECK(tpm_prepare_write(TIMEOUT_WRITE_US)); 400 » int ready_write = 0, ready_read = 0;
400 » TPM_CHECK(tpm_i2c_write_data(pdata, length)); 401 » size_t read_length = 0;
402 » TPM_CHECK(tpm_prepare_write(TIMEOUT_WRITE_MS));
403 » TPM_CHECK(tpm_i2c_write_data(sendbuf, buf_size));
404 » TPM_CHECK(tpm_prepare_read(TIMEOUT_READ_MS));
405 » TPM_CHECK(tpm_status_v03(&ready_write, &ready_read, &read_length));
406 » if (read_length == 0)
407 » » return E_GENERAL;
408 » if (recv_len) {
409 » » /* *recv_len sets the maximum data can be feched
410 » » * if *recv_len == 0, means the buffer is large enough to read a ny tpm
411 » » * response
412 » » */
413 » » if (*recv_len != 0 && *recv_len < read_length)
414 » » » return E_SIZE;
415 » }
416 » if (recvbuf) {
417 » » TPM_CHECK(tpm_i2c_read_data(recvbuf, read_length, NULL));
418 » » /* update recv_len only on success */
419 » » if (recv_len)
420 » » » *recv_len = read_length;
421 » } else {
422 » » /* discard data in read buffer */
423 » » TPM_CHECK(tpm_prepare_write(TIMEOUT_WRITE_MS));
424 » }
401 return 0; 425 return 0;
402 } 426 }
403 427
404 int tpm_receive(uint8_t *pdata, size_t max_length)
405 {
406 int ready_write = 0, ready_read = 0;
407 size_t read_length = 0;
408 TPM_CHECK(tpm_prepare_read(TIMEOUT_READ_US));
409 TPM_CHECK(tpm_status(&ready_write, &ready_read, &read_length));
410 if (read_length == 0)
411 return E_GENERAL;
412 if (max_length < read_length)
413 return E_SIZE;
414 TPM_CHECK(tpm_i2c_read_data(pdata, read_length, NULL));
415 return 0;
416 }
OLDNEW
« no previous file with comments | « drivers/tpm/slb9635_i2c/tpm.c ('k') | drivers/tpm/slb9635_i2c/tpm_tis_i2c.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698