3 * Device Driver for the Infineon Technologies
4 * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
5 * Specifications at www.trustedcomputinggroup.org
7 * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
8 * Sirrix AG - security technologies, http://www.sirrix.com and
9 * Applied Data Security Group, Ruhr-University Bochum, Germany
10 * Project-Homepage: http://www.prosec.rub.de/tpm
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation, version 2 of the
18 #include <linux/pnp.h>
21 /* Infineon specific definitions */
22 /* maximum number of WTX-packages */
23 #define TPM_MAX_WTX_PACKAGES 50
24 /* msleep-Time for WTX-packages */
25 #define TPM_WTX_MSLEEP_TIME 20
26 /* msleep-Time --> Interval to check status register */
27 #define TPM_MSLEEP_TIME 3
28 /* gives number of max. msleep()-calls before throwing timeout */
29 #define TPM_MAX_TRIES 5000
30 #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
32 /* These values will be filled after PnP-call */
33 static int TPM_INF_DATA;
34 static int TPM_INF_ADDR;
35 static int TPM_INF_BASE;
36 static int TPM_INF_PORT_LEN;
38 /* TPM header definitions */
39 enum infineon_tpm_header {
41 TPM_VL_CHANNEL_CONTROL = 0x07,
42 TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
43 TPM_VL_CHANNEL_TPM = 0x0B,
44 TPM_VL_CONTROL = 0x00,
47 TPM_CTRL_WTX_ABORT = 0x18,
48 TPM_CTRL_WTX_ABORT_ACK = 0x18,
49 TPM_CTRL_ERROR = 0x20,
50 TPM_CTRL_CHAININGACK = 0x40,
51 TPM_CTRL_CHAINING = 0x80,
53 TPM_CTRL_DATA_CHA = 0x84,
54 TPM_CTRL_DATA_CHA_ACK = 0xC4
57 enum infineon_tpm_register {
64 enum infineon_tpm_command_bits {
71 enum infineon_tpm_status_bits {
80 /* some outgoing values */
81 enum infineon_tpm_values {
85 RESET_LP_IRQC_DISABLE = 0x41,
86 ENABLE_REGISTER_PAIR = 0x55,
89 DISABLE_REGISTER_PAIR = 0xAA,
96 static int number_of_wtx;
98 static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
105 for (i = 0; i < 4096; i++) {
106 status = inb(chip->vendor->base + WRFIFO);
107 if (status == 0xff) {
115 /* Note: The values which are currently in the FIFO of the TPM
116 are thrown away since there is no usage for them. Usually,
117 this has nothing to say, since the TPM will give its answer
118 immediately or will be aborted anyway, so the data here is
119 usually garbage and useless.
120 We have to clean this, because the next communication with
121 the TPM would be rubbish, if there is still some old data
126 status = inb(chip->vendor->base + RDFIFO);
127 status = inb(chip->vendor->base + STAT);
129 if (i == TPM_MAX_TRIES)
131 } while ((status & (1 << STAT_RDA)) != 0);
135 static int wait(struct tpm_chip *chip, int wait_for_bit)
139 for (i = 0; i < TPM_MAX_TRIES; i++) {
140 status = inb(chip->vendor->base + STAT);
141 /* check the status-register if wait_for_bit is set */
142 if (status & 1 << wait_for_bit)
144 msleep(TPM_MSLEEP_TIME);
146 if (i == TPM_MAX_TRIES) { /* timeout occurs */
147 if (wait_for_bit == STAT_XFE)
148 dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
149 if (wait_for_bit == STAT_RDA)
150 dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
156 static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
158 wait(chip, STAT_XFE);
159 outb(sendbyte, chip->vendor->base + WRFIFO);
162 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
163 calculation time, it sends a WTX-package, which has to be acknowledged
164 or aborted. This usually occurs if you are hammering the TPM with key
165 creation. Set the maximum number of WTX-packages in the definitions
166 above, if the number is reached, the waiting-time will be denied
167 and the TPM command has to be resend.
170 static void tpm_wtx(struct tpm_chip *chip)
173 dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
174 number_of_wtx, TPM_MAX_WTX_PACKAGES);
175 wait_and_send(chip, TPM_VL_VER);
176 wait_and_send(chip, TPM_CTRL_WTX);
177 wait_and_send(chip, 0x00);
178 wait_and_send(chip, 0x00);
179 msleep(TPM_WTX_MSLEEP_TIME);
182 static void tpm_wtx_abort(struct tpm_chip *chip)
184 dev_info(chip->dev, "Aborting WTX\n");
185 wait_and_send(chip, TPM_VL_VER);
186 wait_and_send(chip, TPM_CTRL_WTX_ABORT);
187 wait_and_send(chip, 0x00);
188 wait_and_send(chip, 0x00);
190 msleep(TPM_WTX_MSLEEP_TIME);
193 static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
200 /* start receiving header */
201 for (i = 0; i < 4; i++) {
202 ret = wait(chip, STAT_RDA);
205 buf[i] = inb(chip->vendor->base + RDFIFO);
208 if (buf[0] != TPM_VL_VER) {
210 "Wrong transport protocol implementation!\n");
214 if (buf[1] == TPM_CTRL_DATA) {
215 /* size of the data received */
216 size = ((buf[2] << 8) | buf[3]);
218 for (i = 0; i < size; i++) {
219 wait(chip, STAT_RDA);
220 buf[i] = inb(chip->vendor->base + RDFIFO);
223 if ((size == 0x6D00) && (buf[1] == 0x80)) {
224 dev_err(chip->dev, "Error handling on vendor layer!\n");
228 for (i = 0; i < size; i++)
235 if (buf[1] == TPM_CTRL_WTX) {
236 dev_info(chip->dev, "WTX-package received\n");
237 if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
246 if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
247 dev_info(chip->dev, "WTX-abort acknowledged\n");
251 if (buf[1] == TPM_CTRL_ERROR) {
252 dev_err(chip->dev, "ERROR-package received:\n");
253 if (buf[4] == TPM_INF_NAK)
255 "-> Negative acknowledgement"
256 " - retransmit command!\n");
262 static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
266 u8 count_high, count_low, count_4, count_3, count_2, count_1;
268 /* Disabling Reset, LP and IRQC */
269 outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
271 ret = empty_fifo(chip, 1);
273 dev_err(chip->dev, "Timeout while clearing FIFO\n");
277 ret = wait(chip, STAT_XFE);
281 count_4 = (count & 0xff000000) >> 24;
282 count_3 = (count & 0x00ff0000) >> 16;
283 count_2 = (count & 0x0000ff00) >> 8;
284 count_1 = (count & 0x000000ff);
285 count_high = ((count + 6) & 0xffffff00) >> 8;
286 count_low = ((count + 6) & 0x000000ff);
289 wait_and_send(chip, TPM_VL_VER);
290 wait_and_send(chip, TPM_CTRL_DATA);
291 wait_and_send(chip, count_high);
292 wait_and_send(chip, count_low);
294 /* Sending Data Header */
295 wait_and_send(chip, TPM_VL_VER);
296 wait_and_send(chip, TPM_VL_CHANNEL_TPM);
297 wait_and_send(chip, count_4);
298 wait_and_send(chip, count_3);
299 wait_and_send(chip, count_2);
300 wait_and_send(chip, count_1);
303 for (i = 0; i < count; i++) {
304 wait_and_send(chip, buf[i]);
309 static void tpm_inf_cancel(struct tpm_chip *chip)
312 Since we are using the legacy mode to communicate
313 with the TPM, we have no cancel functions, but have
314 a workaround for interrupting the TPM through WTX.
318 static u8 tpm_inf_status(struct tpm_chip *chip)
320 return inb(chip->vendor->base + STAT);
323 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
324 static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
325 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
326 static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
328 static struct attribute *inf_attrs[] = {
329 &dev_attr_pubek.attr,
332 &dev_attr_cancel.attr,
336 static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
338 static struct file_operations inf_ops = {
339 .owner = THIS_MODULE,
344 .release = tpm_release,
347 static struct tpm_vendor_specific tpm_inf = {
348 .recv = tpm_inf_recv,
349 .send = tpm_inf_send,
350 .cancel = tpm_inf_cancel,
351 .status = tpm_inf_status,
352 .req_complete_mask = 0,
353 .req_complete_val = 0,
354 .attr_group = &inf_attr_grp,
355 .miscdev = {.fops = &inf_ops,},
358 static const struct pnp_device_id tpm_pnp_tbl[] = {
365 MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
367 static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
368 const struct pnp_device_id *dev_id)
377 /* read IO-ports through PnP */
378 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
379 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
380 TPM_INF_ADDR = pnp_port_start(dev, 0);
381 TPM_INF_DATA = (TPM_INF_ADDR + 1);
382 TPM_INF_BASE = pnp_port_start(dev, 1);
383 TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
384 if (!TPM_INF_PORT_LEN)
386 dev_info(&dev->dev, "Found %s with ID %s\n",
387 dev->name, dev_id->id);
388 if (!((TPM_INF_BASE >> 8) & 0xff))
390 /* publish my base address and request region */
391 tpm_inf.base = TPM_INF_BASE;
393 (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
394 release_region(tpm_inf.base, TPM_INF_PORT_LEN);
401 /* query chip for its vendor, its version number a.s.o. */
402 outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
403 outb(IDVENL, TPM_INF_ADDR);
404 vendorid[1] = inb(TPM_INF_DATA);
405 outb(IDVENH, TPM_INF_ADDR);
406 vendorid[0] = inb(TPM_INF_DATA);
407 outb(IDPDL, TPM_INF_ADDR);
408 productid[1] = inb(TPM_INF_DATA);
409 outb(IDPDH, TPM_INF_ADDR);
410 productid[0] = inb(TPM_INF_DATA);
411 outb(CHIP_ID1, TPM_INF_ADDR);
412 version[1] = inb(TPM_INF_DATA);
413 outb(CHIP_ID2, TPM_INF_ADDR);
414 version[0] = inb(TPM_INF_DATA);
416 switch ((productid[0] << 8) | productid[1]) {
418 snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");
421 snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");
424 snprintf(chipname, sizeof(chipname), " (unknown chip)");
428 if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
430 /* configure TPM with IO-ports */
431 outb(IOLIMH, TPM_INF_ADDR);
432 outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
433 outb(IOLIML, TPM_INF_ADDR);
434 outb((tpm_inf.base & 0xff), TPM_INF_DATA);
436 /* control if IO-ports are set correctly */
437 outb(IOLIMH, TPM_INF_ADDR);
438 ioh = inb(TPM_INF_DATA);
439 outb(IOLIML, TPM_INF_ADDR);
440 iol = inb(TPM_INF_DATA);
442 if ((ioh << 8 | iol) != tpm_inf.base) {
444 "Could not set IO-ports to %04x\n",
446 release_region(tpm_inf.base, TPM_INF_PORT_LEN);
450 /* activate register */
451 outb(TPM_DAR, TPM_INF_ADDR);
452 outb(0x01, TPM_INF_DATA);
453 outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
455 /* disable RESET, LP and IRQC */
456 outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
458 /* Finally, we're done, print some infos */
459 dev_info(&dev->dev, "TPM found: "
462 "chip version %02x%02x, "
463 "vendor id %x%x (Infineon), "
464 "product id %02x%02x"
468 version[0], version[1],
469 vendorid[0], vendorid[1],
470 productid[0], productid[1], chipname);
472 rc = tpm_register_hardware(&dev->dev, &tpm_inf);
474 release_region(tpm_inf.base, TPM_INF_PORT_LEN);
479 dev_info(&dev->dev, "No Infineon TPM found!\n");
484 static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
486 struct tpm_chip *chip = pnp_get_drvdata(dev);
489 release_region(chip->vendor->base, TPM_INF_PORT_LEN);
490 tpm_remove_hardware(chip->dev);
494 static struct pnp_driver tpm_inf_pnp = {
495 .name = "tpm_inf_pnp",
497 .owner = THIS_MODULE,
498 .suspend = tpm_pm_suspend,
499 .resume = tpm_pm_resume,
501 .id_table = tpm_pnp_tbl,
502 .probe = tpm_inf_pnp_probe,
503 .remove = tpm_inf_pnp_remove,
506 static int __init init_inf(void)
508 return pnp_register_driver(&tpm_inf_pnp);
511 static void __exit cleanup_inf(void)
513 pnp_unregister_driver(&tpm_inf_pnp);
516 module_init(init_inf);
517 module_exit(cleanup_inf);
519 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
520 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
521 MODULE_VERSION("1.6");
522 MODULE_LICENSE("GPL");