1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License as 4 * published by the Free Software Foundation; either version 2 of 5 * the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 15 * MA 02111-1307 USA 16 */ 17 18 #include <common.h> 19 #include <tpm.h> 20 #include <i2c.h> 21 #include <asm/unaligned.h> 22 23 #define ATMEL_TPM_TIMEOUT_MS 5000 /* sufficient for anything but 24 generating/exporting keys */ 25 26 /* 27 * tis_init() 28 * 29 * Initialize the TPM device. Returns 0 on success or -1 on 30 * failure (in case device probing did not succeed). 31 */ 32 int tis_init(void) 33 { 34 return 0; 35 } 36 37 /* 38 * tis_open() 39 * 40 * Requests access to locality 0 for the caller. After all commands have been 41 * completed the caller is supposed to call tis_close(). 42 * 43 * Returns 0 on success, -1 on failure. 44 */ 45 int tis_open(void) 46 { 47 return 0; 48 } 49 50 /* 51 * tis_close() 52 * 53 * terminate the currect session with the TPM by releasing the locked 54 * locality. Returns 0 on success of -1 on failure (in case lock 55 * removal did not succeed). 56 */ 57 int tis_close(void) 58 { 59 return 0; 60 } 61 62 /* 63 * tis_sendrecv() 64 * 65 * Send the requested data to the TPM and then try to get its response 66 * 67 * @sendbuf - buffer of the data to send 68 * @send_size size of the data to send 69 * @recvbuf - memory to save the response to 70 * @recv_len - pointer to the size of the response buffer 71 * 72 * Returns 0 on success (and places the number of response bytes at recv_len) 73 * or -1 on failure. 74 */ 75 int tis_sendrecv(const uint8_t *sendbuf, size_t send_size, uint8_t *recvbuf, 76 size_t *recv_len) 77 { 78 int res; 79 unsigned long start; 80 81 #ifdef DEBUG 82 memset(recvbuf, 0xcc, *recv_len); 83 printf("send to TPM (%d bytes, recv_len=%d):\n", send_size, *recv_len); 84 print_buffer(0, (void *)sendbuf, 1, send_size, 0); 85 #endif 86 87 res = i2c_write(0x29, 0, 0, (uchar *)sendbuf, send_size); 88 if (res) { 89 printf("i2c_write returned %d\n", res); 90 return -1; 91 } 92 93 start = get_timer(0); 94 while ((res = i2c_read(0x29, 0, 0, recvbuf, 10))) { 95 if (get_timer(start) > ATMEL_TPM_TIMEOUT_MS) { 96 puts("tpm timed out\n"); 97 return -1; 98 } 99 udelay(100); 100 } 101 if (!res) { 102 *recv_len = get_unaligned_be32(recvbuf + 2); 103 if (*recv_len > 10) 104 res = i2c_read(0x29, 0, 0, recvbuf, *recv_len); 105 } 106 if (res) { 107 printf("i2c_read returned %d (rlen=%d)\n", res, *recv_len); 108 #ifdef DEBUG 109 print_buffer(0, recvbuf, 1, *recv_len, 0); 110 #endif 111 } 112 113 #ifdef DEBUG 114 if (!res) { 115 printf("read from TPM (%d bytes):\n", *recv_len); 116 print_buffer(0, recvbuf, 1, *recv_len, 0); 117 } 118 #endif 119 120 return res; 121 } 122