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/init.h>
19 #include <linux/pnp.h>
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
33 /* These values will be filled after PnP-call */
34 static int TPM_INF_DATA
;
35 static int TPM_INF_ADDR
;
36 static int TPM_INF_BASE
;
37 static int TPM_INF_ADDR_LEN
;
38 static int TPM_INF_PORT_LEN
;
40 /* TPM header definitions */
41 enum infineon_tpm_header
{
43 TPM_VL_CHANNEL_CONTROL
= 0x07,
44 TPM_VL_CHANNEL_PERSONALISATION
= 0x0A,
45 TPM_VL_CHANNEL_TPM
= 0x0B,
46 TPM_VL_CONTROL
= 0x00,
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,
55 TPM_CTRL_DATA_CHA
= 0x84,
56 TPM_CTRL_DATA_CHA_ACK
= 0xC4
59 enum infineon_tpm_register
{
66 enum infineon_tpm_command_bits
{
73 enum infineon_tpm_status_bits
{
82 /* some outgoing values */
83 enum infineon_tpm_values
{
87 RESET_LP_IRQC_DISABLE
= 0x41,
88 ENABLE_REGISTER_PAIR
= 0x55,
91 DISABLE_REGISTER_PAIR
= 0xAA,
98 static int number_of_wtx
;
100 static int empty_fifo(struct tpm_chip
*chip
, int clear_wrfifo
)
107 for (i
= 0; i
< 4096; i
++) {
108 status
= inb(chip
->vendor
.base
+ WRFIFO
);
109 if (status
== 0xff) {
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
128 status
= inb(chip
->vendor
.base
+ RDFIFO
);
129 status
= inb(chip
->vendor
.base
+ STAT
);
131 if (i
== TPM_MAX_TRIES
)
133 } while ((status
& (1 << STAT_RDA
)) != 0);
137 static int wait(struct tpm_chip
*chip
, int wait_for_bit
)
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
)
146 msleep(TPM_MSLEEP_TIME
);
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");
158 static void wait_and_send(struct tpm_chip
*chip
, u8 sendbyte
)
160 wait(chip
, STAT_XFE
);
161 outb(sendbyte
, chip
->vendor
.base
+ WRFIFO
);
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.
172 static void tpm_wtx(struct tpm_chip
*chip
)
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
);
184 static void tpm_wtx_abort(struct tpm_chip
*chip
)
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);
192 msleep(TPM_WTX_MSLEEP_TIME
);
195 static int tpm_inf_recv(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
203 /* start receiving header */
204 for (i
= 0; i
< 4; i
++) {
205 ret
= wait(chip
, STAT_RDA
);
208 buf
[i
] = inb(chip
->vendor
.base
+ RDFIFO
);
211 if (buf
[0] != TPM_VL_VER
) {
213 "Wrong transport protocol implementation!\n");
217 if (buf
[1] == TPM_CTRL_DATA
) {
218 /* size of the data received */
219 size
= ((buf
[2] << 8) | buf
[3]);
221 for (i
= 0; i
< size
; i
++) {
222 wait(chip
, STAT_RDA
);
223 buf
[i
] = inb(chip
->vendor
.base
+ RDFIFO
);
226 if ((size
== 0x6D00) && (buf
[1] == 0x80)) {
227 dev_err(chip
->dev
, "Error handling on vendor layer!\n");
231 for (i
= 0; i
< size
; i
++)
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
) {
249 if (buf
[1] == TPM_CTRL_WTX_ABORT_ACK
) {
250 dev_info(chip
->dev
, "WTX-abort acknowledged\n");
254 if (buf
[1] == TPM_CTRL_ERROR
) {
255 dev_err(chip
->dev
, "ERROR-package received:\n");
256 if (buf
[4] == TPM_INF_NAK
)
258 "-> Negative acknowledgement"
259 " - retransmit command!\n");
265 static int tpm_inf_send(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
269 u8 count_high
, count_low
, count_4
, count_3
, count_2
, count_1
;
271 /* Disabling Reset, LP and IRQC */
272 outb(RESET_LP_IRQC_DISABLE
, chip
->vendor
.base
+ CMD
);
274 ret
= empty_fifo(chip
, 1);
276 dev_err(chip
->dev
, "Timeout while clearing FIFO\n");
280 ret
= wait(chip
, STAT_XFE
);
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);
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
);
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
);
306 for (i
= 0; i
< count
; i
++) {
307 wait_and_send(chip
, buf
[i
]);
312 static void tpm_inf_cancel(struct tpm_chip
*chip
)
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.
321 static u8
tpm_inf_status(struct tpm_chip
*chip
)
323 return inb(chip
->vendor
.base
+ STAT
);
326 static DEVICE_ATTR(pubek
, S_IRUGO
, tpm_show_pubek
, NULL
);
327 static DEVICE_ATTR(pcrs
, S_IRUGO
, tpm_show_pcrs
, NULL
);
328 static DEVICE_ATTR(caps
, S_IRUGO
, tpm_show_caps
, NULL
);
329 static DEVICE_ATTR(cancel
, S_IWUSR
| S_IWGRP
, NULL
, tpm_store_cancel
);
331 static struct attribute
*inf_attrs
[] = {
332 &dev_attr_pubek
.attr
,
335 &dev_attr_cancel
.attr
,
339 static struct attribute_group inf_attr_grp
= {.attrs
= inf_attrs
};
341 static const struct file_operations inf_ops
= {
342 .owner
= THIS_MODULE
,
347 .release
= tpm_release
,
350 static 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
,},
361 static const struct pnp_device_id tpm_pnp_tbl
[] = {
368 MODULE_DEVICE_TABLE(pnp
, tpm_pnp_tbl
);
370 static int __devinit
tpm_inf_pnp_probe(struct pnp_dev
*dev
,
371 const struct pnp_device_id
*dev_id
)
379 struct tpm_chip
*chip
;
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)) {
393 dev_info(&dev
->dev
, "Found %s with ID %s\n",
394 dev
->name
, dev_id
->id
);
395 if (!((TPM_INF_BASE
>> 8) & 0xff)) {
399 /* publish my base address and request region */
401 (TPM_INF_BASE
, TPM_INF_PORT_LEN
, "tpm_infineon0") == NULL
) {
406 (TPM_INF_ADDR
, TPM_INF_ADDR_LEN
, "tpm_infineon0") == NULL
) {
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
);
430 switch ((productid
[0] << 8) | productid
[1]) {
432 snprintf(chipname
, sizeof(chipname
), " (SLD 9630 TT 1.1)");
435 snprintf(chipname
, sizeof(chipname
), " (SLB 9635 TT 1.2)");
438 snprintf(chipname
, sizeof(chipname
), " (unknown chip)");
442 if ((vendorid
[0] << 8 | vendorid
[1]) == (TPM_INFINEON_DEV_VEN_VALUE
)) {
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
);
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
);
456 if ((ioh
<< 8 | iol
) != TPM_INF_BASE
) {
458 "Could not set IO-ports to 0x%x\n",
461 goto err_release_region
;
464 /* activate register */
465 outb(TPM_DAR
, TPM_INF_ADDR
);
466 outb(0x01, TPM_INF_DATA
);
467 outb(DISABLE_REGISTER_PAIR
, TPM_INF_ADDR
);
469 /* disable RESET, LP and IRQC */
470 outb(RESET_LP_IRQC_DISABLE
, TPM_INF_BASE
+ CMD
);
472 /* Finally, we're done, print some infos */
473 dev_info(&dev
->dev
, "TPM found: "
476 "chip version 0x%02x%02x, "
477 "vendor id 0x%x%x (Infineon), "
478 "product id 0x%02x%02x"
482 version
[0], version
[1],
483 vendorid
[0], vendorid
[1],
484 productid
[0], productid
[1], chipname
);
486 if (!(chip
= tpm_register_hardware(&dev
->dev
, &tpm_inf
))) {
487 goto err_release_region
;
489 chip
->vendor
.base
= TPM_INF_BASE
;
493 goto err_release_region
;
497 release_region(TPM_INF_BASE
, TPM_INF_PORT_LEN
);
498 release_region(TPM_INF_ADDR
, TPM_INF_ADDR_LEN
);
504 static __devexit
void tpm_inf_pnp_remove(struct pnp_dev
*dev
)
506 struct tpm_chip
*chip
= pnp_get_drvdata(dev
);
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
);
515 static struct pnp_driver tpm_inf_pnp
= {
516 .name
= "tpm_inf_pnp",
518 .owner
= THIS_MODULE
,
519 .suspend
= tpm_pm_suspend
,
520 .resume
= tpm_pm_resume
,
522 .id_table
= tpm_pnp_tbl
,
523 .probe
= tpm_inf_pnp_probe
,
524 .remove
= __devexit_p(tpm_inf_pnp_remove
),
527 static int __init
init_inf(void)
529 return pnp_register_driver(&tpm_inf_pnp
);
532 static void __exit
cleanup_inf(void)
534 pnp_unregister_driver(&tpm_inf_pnp
);
537 module_init(init_inf
);
538 module_exit(cleanup_inf
);
540 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
541 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
542 MODULE_VERSION("1.8");
543 MODULE_LICENSE("GPL");