tpm_infineon.c revision 397c718299d848ff305ecd955838a9bd32f1f881
1/* 2 * Description: 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 6 * 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 11 * 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 15 * License. 16 */ 17 18#include <linux/init.h> 19#include <linux/pnp.h> 20#include "tpm.h" 21 22/* Infineon specific definitions */ 23/* maximum number of WTX-packages */ 24#define TPM_MAX_WTX_PACKAGES 50 25/* msleep-Time for WTX-packages */ 26#define TPM_WTX_MSLEEP_TIME 20 27/* msleep-Time --> Interval to check status register */ 28#define TPM_MSLEEP_TIME 3 29/* gives number of max. msleep()-calls before throwing timeout */ 30#define TPM_MAX_TRIES 5000 31#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 32 33/* These values will be filled after PnP-call */ 34static int TPM_INF_DATA; 35static int TPM_INF_ADDR; 36static int TPM_INF_BASE; 37static int TPM_INF_ADDR_LEN; 38static int TPM_INF_PORT_LEN; 39 40/* TPM header definitions */ 41enum infineon_tpm_header { 42 TPM_VL_VER = 0x01, 43 TPM_VL_CHANNEL_CONTROL = 0x07, 44 TPM_VL_CHANNEL_PERSONALISATION = 0x0A, 45 TPM_VL_CHANNEL_TPM = 0x0B, 46 TPM_VL_CONTROL = 0x00, 47 TPM_INF_NAK = 0x15, 48 TPM_CTRL_WTX = 0x10, 49 TPM_CTRL_WTX_ABORT = 0x18, 50 TPM_CTRL_WTX_ABORT_ACK = 0x18, 51 TPM_CTRL_ERROR = 0x20, 52 TPM_CTRL_CHAININGACK = 0x40, 53 TPM_CTRL_CHAINING = 0x80, 54 TPM_CTRL_DATA = 0x04, 55 TPM_CTRL_DATA_CHA = 0x84, 56 TPM_CTRL_DATA_CHA_ACK = 0xC4 57}; 58 59enum infineon_tpm_register { 60 WRFIFO = 0x00, 61 RDFIFO = 0x01, 62 STAT = 0x02, 63 CMD = 0x03 64}; 65 66enum infineon_tpm_command_bits { 67 CMD_DIS = 0x00, 68 CMD_LP = 0x01, 69 CMD_RES = 0x02, 70 CMD_IRQC = 0x06 71}; 72 73enum infineon_tpm_status_bits { 74 STAT_XFE = 0x00, 75 STAT_LPA = 0x01, 76 STAT_FOK = 0x02, 77 STAT_TOK = 0x03, 78 STAT_IRQA = 0x06, 79 STAT_RDA = 0x07 80}; 81 82/* some outgoing values */ 83enum infineon_tpm_values { 84 CHIP_ID1 = 0x20, 85 CHIP_ID2 = 0x21, 86 TPM_DAR = 0x30, 87 RESET_LP_IRQC_DISABLE = 0x41, 88 ENABLE_REGISTER_PAIR = 0x55, 89 IOLIMH = 0x60, 90 IOLIML = 0x61, 91 DISABLE_REGISTER_PAIR = 0xAA, 92 IDVENL = 0xF1, 93 IDVENH = 0xF2, 94 IDPDL = 0xF3, 95 IDPDH = 0xF4 96}; 97 98static int number_of_wtx; 99 100static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) 101{ 102 int status; 103 int check = 0; 104 int i; 105 106 if (clear_wrfifo) { 107 for (i = 0; i < 4096; i++) { 108 status = inb(chip->vendor.base + WRFIFO); 109 if (status == 0xff) { 110 if (check == 5) 111 break; 112 else 113 check++; 114 } 115 } 116 } 117 /* Note: The values which are currently in the FIFO of the TPM 118 are thrown away since there is no usage for them. Usually, 119 this has nothing to say, since the TPM will give its answer 120 immediately or will be aborted anyway, so the data here is 121 usually garbage and useless. 122 We have to clean this, because the next communication with 123 the TPM would be rubbish, if there is still some old data 124 in the Read FIFO. 125 */ 126 i = 0; 127 do { 128 status = inb(chip->vendor.base + RDFIFO); 129 status = inb(chip->vendor.base + STAT); 130 i++; 131 if (i == TPM_MAX_TRIES) 132 return -EIO; 133 } while ((status & (1 << STAT_RDA)) != 0); 134 return 0; 135} 136 137static int wait(struct tpm_chip *chip, int wait_for_bit) 138{ 139 int status; 140 int i; 141 for (i = 0; i < TPM_MAX_TRIES; i++) { 142 status = inb(chip->vendor.base + STAT); 143 /* check the status-register if wait_for_bit is set */ 144 if (status & 1 << wait_for_bit) 145 break; 146 msleep(TPM_MSLEEP_TIME); 147 } 148 if (i == TPM_MAX_TRIES) { /* timeout occurs */ 149 if (wait_for_bit == STAT_XFE) 150 dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n"); 151 if (wait_for_bit == STAT_RDA) 152 dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n"); 153 return -EIO; 154 } 155 return 0; 156}; 157 158static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) 159{ 160 wait(chip, STAT_XFE); 161 outb(sendbyte, chip->vendor.base + WRFIFO); 162} 163 164 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more 165 calculation time, it sends a WTX-package, which has to be acknowledged 166 or aborted. This usually occurs if you are hammering the TPM with key 167 creation. Set the maximum number of WTX-packages in the definitions 168 above, if the number is reached, the waiting-time will be denied 169 and the TPM command has to be resend. 170 */ 171 172static void tpm_wtx(struct tpm_chip *chip) 173{ 174 number_of_wtx++; 175 dev_info(chip->dev, "Granting WTX (%02d / %02d)\n", 176 number_of_wtx, TPM_MAX_WTX_PACKAGES); 177 wait_and_send(chip, TPM_VL_VER); 178 wait_and_send(chip, TPM_CTRL_WTX); 179 wait_and_send(chip, 0x00); 180 wait_and_send(chip, 0x00); 181 msleep(TPM_WTX_MSLEEP_TIME); 182} 183 184static void tpm_wtx_abort(struct tpm_chip *chip) 185{ 186 dev_info(chip->dev, "Aborting WTX\n"); 187 wait_and_send(chip, TPM_VL_VER); 188 wait_and_send(chip, TPM_CTRL_WTX_ABORT); 189 wait_and_send(chip, 0x00); 190 wait_and_send(chip, 0x00); 191 number_of_wtx = 0; 192 msleep(TPM_WTX_MSLEEP_TIME); 193} 194 195static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) 196{ 197 int i; 198 int ret; 199 u32 size = 0; 200 number_of_wtx = 0; 201 202recv_begin: 203 /* start receiving header */ 204 for (i = 0; i < 4; i++) { 205 ret = wait(chip, STAT_RDA); 206 if (ret) 207 return -EIO; 208 buf[i] = inb(chip->vendor.base + RDFIFO); 209 } 210 211 if (buf[0] != TPM_VL_VER) { 212 dev_err(chip->dev, 213 "Wrong transport protocol implementation!\n"); 214 return -EIO; 215 } 216 217 if (buf[1] == TPM_CTRL_DATA) { 218 /* size of the data received */ 219 size = ((buf[2] << 8) | buf[3]); 220 221 for (i = 0; i < size; i++) { 222 wait(chip, STAT_RDA); 223 buf[i] = inb(chip->vendor.base + RDFIFO); 224 } 225 226 if ((size == 0x6D00) && (buf[1] == 0x80)) { 227 dev_err(chip->dev, "Error handling on vendor layer!\n"); 228 return -EIO; 229 } 230 231 for (i = 0; i < size; i++) 232 buf[i] = buf[i + 6]; 233 234 size = size - 6; 235 return size; 236 } 237 238 if (buf[1] == TPM_CTRL_WTX) { 239 dev_info(chip->dev, "WTX-package received\n"); 240 if (number_of_wtx < TPM_MAX_WTX_PACKAGES) { 241 tpm_wtx(chip); 242 goto recv_begin; 243 } else { 244 tpm_wtx_abort(chip); 245 goto recv_begin; 246 } 247 } 248 249 if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) { 250 dev_info(chip->dev, "WTX-abort acknowledged\n"); 251 return size; 252 } 253 254 if (buf[1] == TPM_CTRL_ERROR) { 255 dev_err(chip->dev, "ERROR-package received:\n"); 256 if (buf[4] == TPM_INF_NAK) 257 dev_err(chip->dev, 258 "-> Negative acknowledgement" 259 " - retransmit command!\n"); 260 return -EIO; 261 } 262 return -EIO; 263} 264 265static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) 266{ 267 int i; 268 int ret; 269 u8 count_high, count_low, count_4, count_3, count_2, count_1; 270 271 /* Disabling Reset, LP and IRQC */ 272 outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD); 273 274 ret = empty_fifo(chip, 1); 275 if (ret) { 276 dev_err(chip->dev, "Timeout while clearing FIFO\n"); 277 return -EIO; 278 } 279 280 ret = wait(chip, STAT_XFE); 281 if (ret) 282 return -EIO; 283 284 count_4 = (count & 0xff000000) >> 24; 285 count_3 = (count & 0x00ff0000) >> 16; 286 count_2 = (count & 0x0000ff00) >> 8; 287 count_1 = (count & 0x000000ff); 288 count_high = ((count + 6) & 0xffffff00) >> 8; 289 count_low = ((count + 6) & 0x000000ff); 290 291 /* Sending Header */ 292 wait_and_send(chip, TPM_VL_VER); 293 wait_and_send(chip, TPM_CTRL_DATA); 294 wait_and_send(chip, count_high); 295 wait_and_send(chip, count_low); 296 297 /* Sending Data Header */ 298 wait_and_send(chip, TPM_VL_VER); 299 wait_and_send(chip, TPM_VL_CHANNEL_TPM); 300 wait_and_send(chip, count_4); 301 wait_and_send(chip, count_3); 302 wait_and_send(chip, count_2); 303 wait_and_send(chip, count_1); 304 305 /* Sending Data */ 306 for (i = 0; i < count; i++) { 307 wait_and_send(chip, buf[i]); 308 } 309 return count; 310} 311 312static void tpm_inf_cancel(struct tpm_chip *chip) 313{ 314 /* 315 Since we are using the legacy mode to communicate 316 with the TPM, we have no cancel functions, but have 317 a workaround for interrupting the TPM through WTX. 318 */ 319} 320 321static u8 tpm_inf_status(struct tpm_chip *chip) 322{ 323 return inb(chip->vendor.base + STAT); 324} 325 326static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); 327static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); 328static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); 329static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); 330 331static struct attribute *inf_attrs[] = { 332 &dev_attr_pubek.attr, 333 &dev_attr_pcrs.attr, 334 &dev_attr_caps.attr, 335 &dev_attr_cancel.attr, 336 NULL, 337}; 338 339static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; 340 341static struct file_operations inf_ops = { 342 .owner = THIS_MODULE, 343 .llseek = no_llseek, 344 .open = tpm_open, 345 .read = tpm_read, 346 .write = tpm_write, 347 .release = tpm_release, 348}; 349 350static const struct tpm_vendor_specific tpm_inf = { 351 .recv = tpm_inf_recv, 352 .send = tpm_inf_send, 353 .cancel = tpm_inf_cancel, 354 .status = tpm_inf_status, 355 .req_complete_mask = 0, 356 .req_complete_val = 0, 357 .attr_group = &inf_attr_grp, 358 .miscdev = {.fops = &inf_ops,}, 359}; 360 361static const struct pnp_device_id tpm_pnp_tbl[] = { 362 /* Infineon TPMs */ 363 {"IFX0101", 0}, 364 {"IFX0102", 0}, 365 {"", 0} 366}; 367 368MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); 369 370static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, 371 const struct pnp_device_id *dev_id) 372{ 373 int rc = 0; 374 u8 iol, ioh; 375 int vendorid[2]; 376 int version[2]; 377 int productid[2]; 378 char chipname[20]; 379 struct tpm_chip *chip; 380 381 /* read IO-ports through PnP */ 382 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && 383 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { 384 TPM_INF_ADDR = pnp_port_start(dev, 0); 385 TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); 386 TPM_INF_DATA = (TPM_INF_ADDR + 1); 387 TPM_INF_BASE = pnp_port_start(dev, 1); 388 TPM_INF_PORT_LEN = pnp_port_len(dev, 1); 389 if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { 390 rc = -EINVAL; 391 goto err_last; 392 } 393 dev_info(&dev->dev, "Found %s with ID %s\n", 394 dev->name, dev_id->id); 395 if (!((TPM_INF_BASE >> 8) & 0xff)) { 396 rc = -EINVAL; 397 goto err_last; 398 } 399 /* publish my base address and request region */ 400 if (request_region 401 (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { 402 rc = -EINVAL; 403 goto err_last; 404 } 405 if (request_region 406 (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) { 407 rc = -EINVAL; 408 goto err_last; 409 } 410 } else { 411 rc = -EINVAL; 412 goto err_last; 413 } 414 415 /* query chip for its vendor, its version number a.s.o. */ 416 outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); 417 outb(IDVENL, TPM_INF_ADDR); 418 vendorid[1] = inb(TPM_INF_DATA); 419 outb(IDVENH, TPM_INF_ADDR); 420 vendorid[0] = inb(TPM_INF_DATA); 421 outb(IDPDL, TPM_INF_ADDR); 422 productid[1] = inb(TPM_INF_DATA); 423 outb(IDPDH, TPM_INF_ADDR); 424 productid[0] = inb(TPM_INF_DATA); 425 outb(CHIP_ID1, TPM_INF_ADDR); 426 version[1] = inb(TPM_INF_DATA); 427 outb(CHIP_ID2, TPM_INF_ADDR); 428 version[0] = inb(TPM_INF_DATA); 429 430 switch ((productid[0] << 8) | productid[1]) { 431 case 6: 432 snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)"); 433 break; 434 case 11: 435 snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)"); 436 break; 437 default: 438 snprintf(chipname, sizeof(chipname), " (unknown chip)"); 439 break; 440 } 441 442 if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { 443 444 /* configure TPM with IO-ports */ 445 outb(IOLIMH, TPM_INF_ADDR); 446 outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA); 447 outb(IOLIML, TPM_INF_ADDR); 448 outb((TPM_INF_BASE & 0xff), TPM_INF_DATA); 449 450 /* control if IO-ports are set correctly */ 451 outb(IOLIMH, TPM_INF_ADDR); 452 ioh = inb(TPM_INF_DATA); 453 outb(IOLIML, TPM_INF_ADDR); 454 iol = inb(TPM_INF_DATA); 455 456 if ((ioh << 8 | iol) != TPM_INF_BASE) { 457 dev_err(&dev->dev, 458 "Could not set IO-ports to 0x%x\n", 459 TPM_INF_BASE); 460 rc = -EIO; 461 goto err_release_region; 462 } 463 464 /* activate register */ 465 outb(TPM_DAR, TPM_INF_ADDR); 466 outb(0x01, TPM_INF_DATA); 467 outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); 468 469 /* disable RESET, LP and IRQC */ 470 outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD); 471 472 /* Finally, we're done, print some infos */ 473 dev_info(&dev->dev, "TPM found: " 474 "config base 0x%x, " 475 "io base 0x%x, " 476 "chip version 0x%02x%02x, " 477 "vendor id 0x%x%x (Infineon), " 478 "product id 0x%02x%02x" 479 "%s\n", 480 TPM_INF_ADDR, 481 TPM_INF_BASE, 482 version[0], version[1], 483 vendorid[0], vendorid[1], 484 productid[0], productid[1], chipname); 485 486 if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) { 487 goto err_release_region; 488 } 489 chip->vendor.base = TPM_INF_BASE; 490 return 0; 491 } else { 492 rc = -ENODEV; 493 goto err_release_region; 494 } 495 496err_release_region: 497 release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); 498 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); 499 500err_last: 501 return rc; 502} 503 504static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) 505{ 506 struct tpm_chip *chip = pnp_get_drvdata(dev); 507 508 if (chip) { 509 release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); 510 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); 511 tpm_remove_hardware(chip->dev); 512 } 513} 514 515static struct pnp_driver tpm_inf_pnp = { 516 .name = "tpm_inf_pnp", 517 .driver = { 518 .owner = THIS_MODULE, 519 .suspend = tpm_pm_suspend, 520 .resume = tpm_pm_resume, 521 }, 522 .id_table = tpm_pnp_tbl, 523 .probe = tpm_inf_pnp_probe, 524 .remove = __devexit_p(tpm_inf_pnp_remove), 525}; 526 527static int __init init_inf(void) 528{ 529 return pnp_register_driver(&tpm_inf_pnp); 530} 531 532static void __exit cleanup_inf(void) 533{ 534 pnp_unregister_driver(&tpm_inf_pnp); 535} 536 537module_init(init_inf); 538module_exit(cleanup_inf); 539 540MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); 541MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); 542MODULE_VERSION("1.8"); 543MODULE_LICENSE("GPL"); 544