tpm: move buffer size definition to common code
[depthcharge.git] / src / drivers / tpm / slb9635_i2c.c
1 /*
2  * Copyright (C) 2011 Infineon Technologies
3  *
4  * Authors:
5  * Peter Huewe <huewe.external@infineon.com>
6  *
7  * Description:
8  * Device driver for TCG/TCPA TPM (trusted platform module).
9  * Specifications at www.trustedcomputinggroup.org
10  *
11  * This device driver implements the TPM interface as defined in
12  * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
13  * Infineon I2C Protocol Stack Specification v0.20.
14  *
15  * It is based on the Linux kernel driver tpm.c from Leendert van
16  * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
17  *
18  * Version: 2.1.1
19  *
20  * See file CREDITS for list of people who contributed to this
21  * project.
22  *
23  * This program is free software; you can redistribute it and/or
24  * modify it under the terms of the GNU General Public License as
25  * published by the Free Software Foundation, version 2 of the
26  * License.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  * GNU General Public License for more details.
32  */
33
34 #include <config.h>
35 #include <endian.h>
36 #include <libpayload.h>
37
38 #include "drivers/bus/i2c/i2c.h"
39 #include "drivers/tpm/i2c.h"
40 #include "drivers/tpm/slb9635_i2c.h"
41
42 enum {
43         TpmTimeout = 1 // msecs
44 };
45
46 // Expected value for DIDVID register.
47 enum {
48         TPM_TIS_I2C_DID_VID_9635 = 0x000b15d1L,
49         TPM_TIS_I2C_DID_VID_9645 = 0x001a15d1L
50 };
51
52 static const char * const chip_name[] = {
53         [SLB9635] = "slb9635tt",
54         [SLB9645] = "slb9645tt",
55         [UNKNOWN] = "unknown/fallback to slb9635",
56 };
57
58 /*
59  * iic_tpm_read() - read from TPM register
60  *
61  * @tpm: pointer to TPM structure
62  * @addr: register address to read from
63  * @buffer: provided by caller
64  * @len: number of bytes to read
65  *
66  * Read len bytes from TPM register and put them into buffer.
67  *
68  * NOTE: TPM is big-endian for multi-byte values. Multi-byte values have to
69  * be swapped.
70  *
71  * Return nonzero on error, 0 on success.
72  */
73 static int iic_tpm_read(Slb9635I2c *tpm, uint8_t addr, uint8_t *buffer,
74                         size_t len)
75 {
76         int rc;
77         int count;
78
79         if (!tpm->base.bus)
80                 return -1;
81         if ((tpm->chip_type == SLB9635) || (tpm->chip_type == UNKNOWN)) {
82                 // slb9635 protocol should work in both cases.
83                 for (count = 0; count < 50; count++) {
84                         rc = i2c_write_raw(tpm->base.bus, tpm->base.addr,
85                                            &addr, 1);
86                         if (rc == 0)
87                                 break;
88
89                         udelay(200);
90                 }
91
92                 if (rc)
93                         return -rc;
94
95                 /*
96                  * After the TPM has successfully received the register address
97                  * it needs some time, thus we're sleeping here again, before
98                  * retrieving the data
99                  */
100                 for (count = 0; count < 50; count++) {
101                         udelay(200);
102                         rc = i2c_read_raw(tpm->base.bus, tpm->base.addr,
103                                           buffer, len);
104                         if (rc == 0)
105                                 break;
106                 }
107         } else {
108                 /*
109                  * use a combined read for newer chips
110                  * unfortunately the smbus functions are not suitable due to
111                  * the 32 byte limit of the smbus.
112                  * retries should usually not be needed, but are kept just to
113                  * be safe on the safe side.
114                  */
115                 I2cSeg aseg = { .read = 0, .chip = tpm->base.addr,
116                                 .buf = &addr, .len = 1 };
117                 I2cSeg dseg = { .read = 1, .chip = tpm->base.addr,
118                                 .buf = buffer, .len = len };
119                 for (count = 0; count < 50; count++) {
120                         rc = tpm->base.bus->transfer(tpm->base.bus, &aseg, 1) ||
121                              tpm->base.bus->transfer(tpm->base.bus, &dseg, 1);
122                         if (rc == 0)
123                                 break;
124                         udelay(200);
125                 }
126         }
127
128         // Take care of 'guard time'.
129         udelay(60);
130         if (rc)
131                 return -rc;
132
133         return 0;
134 }
135
136 /*
137  * iic_tpm_write() - write to TPM register
138  *
139  * @tpm: pointer to TPM structure
140  * @addr: register address to write to
141  * @buffer: containing data to be written
142  * @len: number of bytes to write
143  *
144  * Write len bytes from provided buffer to TPM register (little
145  * endian format, i.e. buffer[0] is written as first byte).
146  *
147  * NOTE: TPM is big-endian for multi-byte values. Multi-byte
148  * values have to be swapped.
149  *
150  * Return nonzero on error, 0 on success
151  */
152 static int iic_tpm_write(Slb9635I2c *tpm, uint8_t addr, const uint8_t *buffer,
153                          size_t len)
154 {
155         int rc = 0;
156         int count;
157
158         if (len > TpmMaxBufSize) {
159                 printf("%s: Length %zd is too large\n", __func__, len);
160                 return -1;
161         }
162
163         // Prepare send buffer.
164         tpm->buf[0] = addr;
165         memcpy(&tpm->buf[1], buffer, len);
166
167         if (!tpm->base.bus)
168                 return -1;
169         for (count = 0; count < 50; count++) {
170                 rc = i2c_write_raw(tpm->base.bus, tpm->base.addr,
171                                    tpm->buf, len + 1);
172                 if (rc == 0)
173                         break;
174
175                 udelay(200);
176         }
177
178         // Take care of 'guard time'.
179         udelay(60);
180         if (rc)
181                 return -rc;
182
183         return 0;
184 }
185
186 #define TPM_HEADER_SIZE 10
187
188 enum {
189         TpmAccessValid = 0x80,
190         TpmAccessActiveLocality = 0x20,
191         TpmAccessRequestPending = 0x04,
192         TpmAccessRequestUse = 0x02,
193 };
194
195 enum {
196         TpmStsValid = 0x80,
197         TpmStsCommandReady = 0x40,
198         TpmStsGo = 0x20,
199         TpmStsDataAvail = 0x10,
200         TpmStsDataExpect = 0x08,
201 };
202
203 static inline uint8_t tpm_access(uint8_t locality)
204 {
205         return 0x0 | (locality << 4);
206 }
207
208 static inline uint8_t tpm_sts(uint8_t locality)
209 {
210         return 0x1 | (locality << 4);
211 }
212
213 static inline uint8_t tpm_data_fifo(uint8_t locality)
214 {
215         return 0x5 | (locality << 4);
216 }
217
218 static inline uint8_t tpm_did_vid(uint8_t locality)
219 {
220         return 0x6 | (locality << 4);
221 }
222
223 static int check_locality(Slb9635I2c *tpm, int loc)
224 {
225         uint8_t buf;
226         int rc;
227
228         rc = iic_tpm_read(tpm, tpm_access(loc), &buf, 1);
229         if (rc < 0)
230                 return rc;
231
232         if ((buf & (TpmAccessActiveLocality | TpmAccessValid)) ==
233                 (TpmAccessActiveLocality | TpmAccessValid)) {
234                 tpm->base.locality = loc;
235                 return loc;
236         }
237
238         return -1;
239 }
240
241 static void release_locality(Slb9635I2c *tpm, int loc, int force)
242 {
243         uint8_t buf;
244         if (iic_tpm_read(tpm, tpm_access(loc), &buf, 1) < 0)
245                 return;
246
247         if (force || (buf & (TpmAccessRequestPending | TpmAccessValid)) ==
248                         (TpmAccessRequestPending | TpmAccessValid)) {
249                 buf = TpmAccessActiveLocality;
250                 iic_tpm_write(tpm, tpm_access(loc), &buf, 1);
251         }
252 }
253
254 static int request_locality(Slb9635I2c *tpm, int loc)
255 {
256         uint8_t buf = TpmAccessRequestUse;
257
258         if (check_locality(tpm, loc) >= 0)
259                 return loc; // We already have the locality.
260
261         iic_tpm_write(tpm, tpm_access(loc), &buf, 1);
262
263         // Wait for burstcount.
264         uint64_t start = timer_us(0);
265         while (timer_us(start) < 2 * 1000 * 1000) { // Two second timeout.
266                 if (check_locality(tpm, loc) >= 0)
267                         return loc;
268                 mdelay(TpmTimeout);
269         }
270
271         return -1;
272 }
273
274 static uint8_t tpm_status(I2cTpmChipOps *me)
275 {
276         Slb9635I2c *tpm = container_of(me, Slb9635I2c, base.chip_ops);
277         // NOTE: since i2c read may fail, return 0 in this case --> time-out
278         uint8_t buf;
279         if (iic_tpm_read(tpm, tpm_sts(tpm->base.locality), &buf, 1) < 0)
280                 return 0;
281         else
282                 return buf;
283 }
284
285 static void tpm_ready(I2cTpmChipOps *me)
286 {
287         Slb9635I2c *tpm = container_of(me, Slb9635I2c, base.chip_ops);
288         // This causes the current command to be aborted.
289         uint8_t buf = TpmStsCommandReady;
290         iic_tpm_write(tpm, tpm_sts(tpm->base.locality), &buf, 1);
291 }
292
293 static ssize_t get_burstcount(Slb9635I2c *tpm)
294 {
295         ssize_t burstcnt;
296         uint8_t buf[3];
297
298         // Wait for burstcount.
299         uint64_t start = timer_us(0);
300         while (timer_us(start) < 2 * 1000 * 1000) { // Two second timeout.
301                 // Note: STS is little endian.
302                 if (iic_tpm_read(tpm, tpm_sts(tpm->base.locality) + 1,
303                                  buf, 3) < 0)
304                         burstcnt = 0;
305                 else
306                         burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
307
308                 if (burstcnt)
309                         return burstcnt;
310                 mdelay(TpmTimeout);
311         }
312         return -1;
313 }
314
315 static int wait_for_stat(Slb9635I2c *tpm, uint8_t mask, int *status)
316 {
317         uint64_t start = timer_us(0);
318         while (timer_us(start) < 2 * 1000 * 1000) { // Two second timeout.
319                 // Check current status.
320                 *status = tpm_status(&tpm->base.chip_ops);
321                 if ((*status & mask) == mask)
322                         return 0;
323                 mdelay(TpmTimeout);
324         }
325
326         return -1;
327 }
328
329 static int recv_data(Slb9635I2c *tpm, uint8_t *buf, size_t count)
330 {
331         size_t size = 0;
332         ssize_t burstcnt;
333         int rc;
334
335         while (size < count) {
336                 burstcnt = get_burstcount(tpm);
337
338                 // Burstcount < 0 means the tpm is busy.
339                 if (burstcnt < 0)
340                         return burstcnt;
341
342                 // Limit received data to max left.
343                 if (burstcnt > (count - size))
344                         burstcnt = count - size;
345
346                 rc = iic_tpm_read(tpm, tpm_data_fifo(tpm->base.locality),
347                                   &buf[size], burstcnt);
348                 if (rc == 0)
349                         size += burstcnt;
350
351         }
352         return size;
353 }
354
355 static int tpm_recv(I2cTpmChipOps *me, uint8_t *buf, size_t count)
356 {
357         Slb9635I2c *tpm = container_of(me, Slb9635I2c, base.chip_ops);
358
359         int size = 0;
360         uint32_t expected;
361         int status;
362
363         if (count < TPM_HEADER_SIZE) {
364                 size = -1;
365                 goto out;
366         }
367
368         // Read first 10 bytes, including tag, paramsize, and result.
369         size = recv_data(tpm, buf, TPM_HEADER_SIZE);
370         if (size < TPM_HEADER_SIZE) {
371                 printf("tpm_tis_i2c_recv: Unable to read header\n");
372                 goto out;
373         }
374
375         memcpy(&expected, buf + TpmCmdCountOffset, sizeof(expected));
376         expected = betohl(expected);
377         if ((size_t)expected > count) {
378                 size = -1;
379                 goto out;
380         }
381
382         size += recv_data(tpm, &buf[TPM_HEADER_SIZE],
383                           expected - TPM_HEADER_SIZE);
384         if (size < expected) {
385                 printf("tpm_tis_i2c_recv: Unable to "
386                         "read remainder of result\n");
387                 size = -1;
388                 goto out;
389         }
390
391         wait_for_stat(tpm, TpmStsValid, &status);
392         if (status & TpmStsDataAvail) { // retry?
393                 printf("tpm_tis_i2c_recv: Error left over data\n");
394                 size = -1;
395                 goto out;
396         }
397
398 out:
399         tpm_ready(&tpm->base.chip_ops);
400
401         return size;
402 }
403
404 static int tpm_send(I2cTpmChipOps *me, const uint8_t *buf, size_t len)
405 {
406         Slb9635I2c *tpm = container_of(me, Slb9635I2c, base.chip_ops);
407         int rc, status;
408         ssize_t burstcnt;
409         size_t count = 0;
410         uint8_t sts = TpmStsGo;
411
412         if (len > TpmMaxBufSize)
413                 return -1; // Command is too long for our tpm, sorry.
414
415         status = tpm->base.chip_ops.status(&tpm->base.chip_ops);
416         if ((status & TpmStsCommandReady) == 0) {
417                 tpm_ready(&tpm->base.chip_ops);
418                 if (wait_for_stat(tpm, TpmStsCommandReady, &status) < 0) {
419                         rc = -1;
420                         goto out_err;
421                 }
422         }
423
424         while (count < len - 1) {
425                 burstcnt = get_burstcount(tpm);
426
427                 // Burstcount < 0 means the tpm is busy.
428                 if (burstcnt < 0)
429                         return burstcnt;
430
431                 if (burstcnt > (len - 1 - count))
432                         burstcnt = len - 1 - count;
433
434                 rc = iic_tpm_write(tpm, tpm_data_fifo(tpm->base.locality),
435                                    &(buf[count]), burstcnt);
436                 if (rc == 0)
437                         count += burstcnt;
438
439                 wait_for_stat(tpm, TpmStsValid, &status);
440
441                 if ((status & TpmStsDataExpect) == 0) {
442                         rc = -1;
443                         goto out_err;
444                 }
445
446         }
447
448         // Write last byte.
449         iic_tpm_write(tpm, tpm_data_fifo(tpm->base.locality),
450                       &buf[count], 1);
451         wait_for_stat(tpm, TpmStsValid, &status);
452         if ((status & TpmStsDataExpect) != 0) {
453                 rc = -1;
454                 goto out_err;
455         }
456
457         // Go and do it.
458         iic_tpm_write(tpm, tpm_sts(tpm->base.locality), &sts, 1);
459
460         return len;
461 out_err:
462         tpm_ready(&tpm->base.chip_ops);
463
464         return rc;
465 }
466
467 static int tpm_init(I2cTpmChipOps *me)
468 {
469         Slb9635I2c *tpm = container_of(me, Slb9635I2c, base.chip_ops);
470
471         if (request_locality(tpm, 0) != 0)
472                 return -1;
473
474         // Read four bytes from DID_VID register.
475         uint32_t vendor;
476         if (iic_tpm_read(tpm, tpm_did_vid(0), (uint8_t *)&vendor, 4) < 0) {
477                 release_locality(tpm, 0, 1);
478                 return -1;
479         }
480
481         if (vendor == TPM_TIS_I2C_DID_VID_9645) {
482                 tpm->chip_type = SLB9645;
483         } else if (betohl(vendor) == TPM_TIS_I2C_DID_VID_9635) {
484                 tpm->chip_type = SLB9635;
485         } else {
486                 printf("Vendor ID 0x%08x not recognized.\n", vendor);
487                 release_locality(tpm, 0, 1);
488                 return -1;
489         }
490
491         printf("1.2 TPM (chip type %s device-id 0x%X)\n",
492                  chip_name[tpm->chip_type], vendor >> 16);
493
494         return 0;
495 }
496
497 static int tpm_cleanup(I2cTpmChipOps *me)
498 {
499         Slb9635I2c *tpm = container_of(me, Slb9635I2c, base.chip_ops);
500         release_locality(tpm, tpm->base.locality, 1);
501         return 0;
502 }
503
504 Slb9635I2c *new_slb9635_i2c(I2cOps *bus, uint8_t addr)
505 {
506         Slb9635I2c *tpm = xmalloc(sizeof(*tpm));
507         i2ctpm_fill_in(&tpm->base, bus, addr, TpmStsDataAvail | TpmStsValid,
508                        TpmStsDataAvail | TpmStsValid, TpmStsCommandReady);
509
510         tpm->base.chip_ops.init = &tpm_init;
511         tpm->base.chip_ops.cleanup = &tpm_cleanup;
512
513         tpm->base.chip_ops.recv = &tpm_recv;
514         tpm->base.chip_ops.send = &tpm_send;
515         tpm->base.chip_ops.cancel = &tpm_ready;
516         tpm->base.chip_ops.status = &tpm_status;
517
518         return tpm;
519 }