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 #define TPM_INF_IO_PORT 0x0
34 #define TPM_INF_IO_MEM 0x1
36 #define TPM_INF_ADDR 0x0
37 #define TPM_INF_DATA 0x1
42 void __iomem
*mem_base
; /* MMIO ioremap'd addr */
43 unsigned long map_base
; /* phys MMIO base */
44 unsigned long map_size
; /* MMIO region size */
45 unsigned int index_off
; /* index register offset */
47 unsigned int data_regs
; /* Data registers */
48 unsigned int data_size
;
50 unsigned int config_port
; /* IO Port config index reg */
51 unsigned int config_size
;
54 static struct tpm_inf_dev tpm_dev
;
56 static inline void tpm_data_out(unsigned char data
, unsigned char offset
)
58 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
59 outb(data
, tpm_dev
.data_regs
+ offset
);
61 writeb(data
, tpm_dev
.mem_base
+ tpm_dev
.data_regs
+ offset
);
64 static inline unsigned char tpm_data_in(unsigned char offset
)
66 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
67 return inb(tpm_dev
.data_regs
+ offset
);
69 return readb(tpm_dev
.mem_base
+ tpm_dev
.data_regs
+ offset
);
72 static inline void tpm_config_out(unsigned char data
, unsigned char offset
)
74 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
75 outb(data
, tpm_dev
.config_port
+ offset
);
77 writeb(data
, tpm_dev
.mem_base
+ tpm_dev
.index_off
+ offset
);
80 static inline unsigned char tpm_config_in(unsigned char offset
)
82 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
83 return inb(tpm_dev
.config_port
+ offset
);
85 return readb(tpm_dev
.mem_base
+ tpm_dev
.index_off
+ offset
);
88 /* TPM header definitions */
89 enum infineon_tpm_header
{
91 TPM_VL_CHANNEL_CONTROL
= 0x07,
92 TPM_VL_CHANNEL_PERSONALISATION
= 0x0A,
93 TPM_VL_CHANNEL_TPM
= 0x0B,
94 TPM_VL_CONTROL
= 0x00,
97 TPM_CTRL_WTX_ABORT
= 0x18,
98 TPM_CTRL_WTX_ABORT_ACK
= 0x18,
99 TPM_CTRL_ERROR
= 0x20,
100 TPM_CTRL_CHAININGACK
= 0x40,
101 TPM_CTRL_CHAINING
= 0x80,
102 TPM_CTRL_DATA
= 0x04,
103 TPM_CTRL_DATA_CHA
= 0x84,
104 TPM_CTRL_DATA_CHA_ACK
= 0xC4
107 enum infineon_tpm_register
{
114 enum infineon_tpm_command_bits
{
121 enum infineon_tpm_status_bits
{
130 /* some outgoing values */
131 enum infineon_tpm_values
{
135 RESET_LP_IRQC_DISABLE
= 0x41,
136 ENABLE_REGISTER_PAIR
= 0x55,
139 DISABLE_REGISTER_PAIR
= 0xAA,
146 static int number_of_wtx
;
148 static int empty_fifo(struct tpm_chip
*chip
, int clear_wrfifo
)
155 for (i
= 0; i
< 4096; i
++) {
156 status
= tpm_data_in(WRFIFO
);
157 if (status
== 0xff) {
165 /* Note: The values which are currently in the FIFO of the TPM
166 are thrown away since there is no usage for them. Usually,
167 this has nothing to say, since the TPM will give its answer
168 immediately or will be aborted anyway, so the data here is
169 usually garbage and useless.
170 We have to clean this, because the next communication with
171 the TPM would be rubbish, if there is still some old data
176 status
= tpm_data_in(RDFIFO
);
177 status
= tpm_data_in(STAT
);
179 if (i
== TPM_MAX_TRIES
)
181 } while ((status
& (1 << STAT_RDA
)) != 0);
185 static int wait(struct tpm_chip
*chip
, int wait_for_bit
)
189 for (i
= 0; i
< TPM_MAX_TRIES
; i
++) {
190 status
= tpm_data_in(STAT
);
191 /* check the status-register if wait_for_bit is set */
192 if (status
& 1 << wait_for_bit
)
194 msleep(TPM_MSLEEP_TIME
);
196 if (i
== TPM_MAX_TRIES
) { /* timeout occurs */
197 if (wait_for_bit
== STAT_XFE
)
198 dev_err(chip
->dev
, "Timeout in wait(STAT_XFE)\n");
199 if (wait_for_bit
== STAT_RDA
)
200 dev_err(chip
->dev
, "Timeout in wait(STAT_RDA)\n");
206 static void wait_and_send(struct tpm_chip
*chip
, u8 sendbyte
)
208 wait(chip
, STAT_XFE
);
209 tpm_data_out(sendbyte
, WRFIFO
);
212 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
213 calculation time, it sends a WTX-package, which has to be acknowledged
214 or aborted. This usually occurs if you are hammering the TPM with key
215 creation. Set the maximum number of WTX-packages in the definitions
216 above, if the number is reached, the waiting-time will be denied
217 and the TPM command has to be resend.
220 static void tpm_wtx(struct tpm_chip
*chip
)
223 dev_info(chip
->dev
, "Granting WTX (%02d / %02d)\n",
224 number_of_wtx
, TPM_MAX_WTX_PACKAGES
);
225 wait_and_send(chip
, TPM_VL_VER
);
226 wait_and_send(chip
, TPM_CTRL_WTX
);
227 wait_and_send(chip
, 0x00);
228 wait_and_send(chip
, 0x00);
229 msleep(TPM_WTX_MSLEEP_TIME
);
232 static void tpm_wtx_abort(struct tpm_chip
*chip
)
234 dev_info(chip
->dev
, "Aborting WTX\n");
235 wait_and_send(chip
, TPM_VL_VER
);
236 wait_and_send(chip
, TPM_CTRL_WTX_ABORT
);
237 wait_and_send(chip
, 0x00);
238 wait_and_send(chip
, 0x00);
240 msleep(TPM_WTX_MSLEEP_TIME
);
243 static int tpm_inf_recv(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
251 /* start receiving header */
252 for (i
= 0; i
< 4; i
++) {
253 ret
= wait(chip
, STAT_RDA
);
256 buf
[i
] = tpm_data_in(RDFIFO
);
259 if (buf
[0] != TPM_VL_VER
) {
261 "Wrong transport protocol implementation!\n");
265 if (buf
[1] == TPM_CTRL_DATA
) {
266 /* size of the data received */
267 size
= ((buf
[2] << 8) | buf
[3]);
269 for (i
= 0; i
< size
; i
++) {
270 wait(chip
, STAT_RDA
);
271 buf
[i
] = tpm_data_in(RDFIFO
);
274 if ((size
== 0x6D00) && (buf
[1] == 0x80)) {
275 dev_err(chip
->dev
, "Error handling on vendor layer!\n");
279 for (i
= 0; i
< size
; i
++)
286 if (buf
[1] == TPM_CTRL_WTX
) {
287 dev_info(chip
->dev
, "WTX-package received\n");
288 if (number_of_wtx
< TPM_MAX_WTX_PACKAGES
) {
297 if (buf
[1] == TPM_CTRL_WTX_ABORT_ACK
) {
298 dev_info(chip
->dev
, "WTX-abort acknowledged\n");
302 if (buf
[1] == TPM_CTRL_ERROR
) {
303 dev_err(chip
->dev
, "ERROR-package received:\n");
304 if (buf
[4] == TPM_INF_NAK
)
306 "-> Negative acknowledgement"
307 " - retransmit command!\n");
313 static int tpm_inf_send(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
317 u8 count_high
, count_low
, count_4
, count_3
, count_2
, count_1
;
319 /* Disabling Reset, LP and IRQC */
320 tpm_data_out(RESET_LP_IRQC_DISABLE
, CMD
);
322 ret
= empty_fifo(chip
, 1);
324 dev_err(chip
->dev
, "Timeout while clearing FIFO\n");
328 ret
= wait(chip
, STAT_XFE
);
332 count_4
= (count
& 0xff000000) >> 24;
333 count_3
= (count
& 0x00ff0000) >> 16;
334 count_2
= (count
& 0x0000ff00) >> 8;
335 count_1
= (count
& 0x000000ff);
336 count_high
= ((count
+ 6) & 0xffffff00) >> 8;
337 count_low
= ((count
+ 6) & 0x000000ff);
340 wait_and_send(chip
, TPM_VL_VER
);
341 wait_and_send(chip
, TPM_CTRL_DATA
);
342 wait_and_send(chip
, count_high
);
343 wait_and_send(chip
, count_low
);
345 /* Sending Data Header */
346 wait_and_send(chip
, TPM_VL_VER
);
347 wait_and_send(chip
, TPM_VL_CHANNEL_TPM
);
348 wait_and_send(chip
, count_4
);
349 wait_and_send(chip
, count_3
);
350 wait_and_send(chip
, count_2
);
351 wait_and_send(chip
, count_1
);
354 for (i
= 0; i
< count
; i
++) {
355 wait_and_send(chip
, buf
[i
]);
360 static void tpm_inf_cancel(struct tpm_chip
*chip
)
363 Since we are using the legacy mode to communicate
364 with the TPM, we have no cancel functions, but have
365 a workaround for interrupting the TPM through WTX.
369 static u8
tpm_inf_status(struct tpm_chip
*chip
)
371 return tpm_data_in(STAT
);
374 static DEVICE_ATTR(pubek
, S_IRUGO
, tpm_show_pubek
, NULL
);
375 static DEVICE_ATTR(pcrs
, S_IRUGO
, tpm_show_pcrs
, NULL
);
376 static DEVICE_ATTR(caps
, S_IRUGO
, tpm_show_caps
, NULL
);
377 static DEVICE_ATTR(cancel
, S_IWUSR
| S_IWGRP
, NULL
, tpm_store_cancel
);
379 static struct attribute
*inf_attrs
[] = {
380 &dev_attr_pubek
.attr
,
383 &dev_attr_cancel
.attr
,
387 static struct attribute_group inf_attr_grp
= {.attrs
= inf_attrs
};
389 static const struct file_operations inf_ops
= {
390 .owner
= THIS_MODULE
,
395 .release
= tpm_release
,
398 static const struct tpm_vendor_specific tpm_inf
= {
399 .recv
= tpm_inf_recv
,
400 .send
= tpm_inf_send
,
401 .cancel
= tpm_inf_cancel
,
402 .status
= tpm_inf_status
,
403 .req_complete_mask
= 0,
404 .req_complete_val
= 0,
405 .attr_group
= &inf_attr_grp
,
406 .miscdev
= {.fops
= &inf_ops
,},
409 static const struct pnp_device_id tpm_pnp_tbl
[] = {
416 MODULE_DEVICE_TABLE(pnp
, tpm_pnp_tbl
);
418 static int __devinit
tpm_inf_pnp_probe(struct pnp_dev
*dev
,
419 const struct pnp_device_id
*dev_id
)
427 struct tpm_chip
*chip
;
429 /* read IO-ports through PnP */
430 if (pnp_port_valid(dev
, 0) && pnp_port_valid(dev
, 1) &&
431 !(pnp_port_flags(dev
, 0) & IORESOURCE_DISABLED
)) {
433 tpm_dev
.iotype
= TPM_INF_IO_PORT
;
435 tpm_dev
.config_port
= pnp_port_start(dev
, 0);
436 tpm_dev
.config_size
= pnp_port_len(dev
, 0);
437 tpm_dev
.data_regs
= pnp_port_start(dev
, 1);
438 tpm_dev
.data_size
= pnp_port_len(dev
, 1);
439 if ((tpm_dev
.data_size
< 4) || (tpm_dev
.config_size
< 2)) {
443 dev_info(&dev
->dev
, "Found %s with ID %s\n",
444 dev
->name
, dev_id
->id
);
445 if (!((tpm_dev
.data_regs
>> 8) & 0xff)) {
449 /* publish my base address and request region */
450 if (request_region(tpm_dev
.data_regs
, tpm_dev
.data_size
,
451 "tpm_infineon0") == NULL
) {
455 if (request_region(tpm_dev
.config_port
, tpm_dev
.config_size
,
456 "tpm_infineon0") == NULL
) {
457 release_region(tpm_dev
.data_regs
, tpm_dev
.data_size
);
461 } else if (pnp_mem_valid(dev
, 0) &&
462 !(pnp_mem_flags(dev
, 0) & IORESOURCE_DISABLED
)) {
464 tpm_dev
.iotype
= TPM_INF_IO_MEM
;
466 tpm_dev
.map_base
= pnp_mem_start(dev
, 0);
467 tpm_dev
.map_size
= pnp_mem_len(dev
, 0);
469 dev_info(&dev
->dev
, "Found %s with ID %s\n",
470 dev
->name
, dev_id
->id
);
472 /* publish my base address and request region */
473 if (request_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
,
474 "tpm_infineon0") == NULL
) {
479 tpm_dev
.mem_base
= ioremap(tpm_dev
.map_base
, tpm_dev
.map_size
);
480 if (tpm_dev
.mem_base
== NULL
) {
481 release_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
);
487 * The only known MMIO based Infineon TPM system provides
488 * a single large mem region with the device config
489 * registers at the default TPM_ADDR. The data registers
490 * seem like they could be placed anywhere within the MMIO
491 * region, but lets just put them at zero offset.
493 tpm_dev
.index_off
= TPM_ADDR
;
494 tpm_dev
.data_regs
= 0x0;
500 /* query chip for its vendor, its version number a.s.o. */
501 tpm_config_out(ENABLE_REGISTER_PAIR
, TPM_INF_ADDR
);
502 tpm_config_out(IDVENL
, TPM_INF_ADDR
);
503 vendorid
[1] = tpm_config_in(TPM_INF_DATA
);
504 tpm_config_out(IDVENH
, TPM_INF_ADDR
);
505 vendorid
[0] = tpm_config_in(TPM_INF_DATA
);
506 tpm_config_out(IDPDL
, TPM_INF_ADDR
);
507 productid
[1] = tpm_config_in(TPM_INF_DATA
);
508 tpm_config_out(IDPDH
, TPM_INF_ADDR
);
509 productid
[0] = tpm_config_in(TPM_INF_DATA
);
510 tpm_config_out(CHIP_ID1
, TPM_INF_ADDR
);
511 version
[1] = tpm_config_in(TPM_INF_DATA
);
512 tpm_config_out(CHIP_ID2
, TPM_INF_ADDR
);
513 version
[0] = tpm_config_in(TPM_INF_DATA
);
515 switch ((productid
[0] << 8) | productid
[1]) {
517 snprintf(chipname
, sizeof(chipname
), " (SLD 9630 TT 1.1)");
520 snprintf(chipname
, sizeof(chipname
), " (SLB 9635 TT 1.2)");
523 snprintf(chipname
, sizeof(chipname
), " (unknown chip)");
527 if ((vendorid
[0] << 8 | vendorid
[1]) == (TPM_INFINEON_DEV_VEN_VALUE
)) {
529 /* configure TPM with IO-ports */
530 tpm_config_out(IOLIMH
, TPM_INF_ADDR
);
531 tpm_config_out((tpm_dev
.data_regs
>> 8) & 0xff, TPM_INF_DATA
);
532 tpm_config_out(IOLIML
, TPM_INF_ADDR
);
533 tpm_config_out((tpm_dev
.data_regs
& 0xff), TPM_INF_DATA
);
535 /* control if IO-ports are set correctly */
536 tpm_config_out(IOLIMH
, TPM_INF_ADDR
);
537 ioh
= tpm_config_in(TPM_INF_DATA
);
538 tpm_config_out(IOLIML
, TPM_INF_ADDR
);
539 iol
= tpm_config_in(TPM_INF_DATA
);
541 if ((ioh
<< 8 | iol
) != tpm_dev
.data_regs
) {
543 "Could not set IO-data registers to 0x%x\n",
546 goto err_release_region
;
549 /* activate register */
550 tpm_config_out(TPM_DAR
, TPM_INF_ADDR
);
551 tpm_config_out(0x01, TPM_INF_DATA
);
552 tpm_config_out(DISABLE_REGISTER_PAIR
, TPM_INF_ADDR
);
554 /* disable RESET, LP and IRQC */
555 tpm_data_out(RESET_LP_IRQC_DISABLE
, CMD
);
557 /* Finally, we're done, print some infos */
558 dev_info(&dev
->dev
, "TPM found: "
559 "config base 0x%lx, "
561 "chip version 0x%02x%02x, "
562 "vendor id 0x%x%x (Infineon), "
563 "product id 0x%02x%02x"
565 tpm_dev
.iotype
== TPM_INF_IO_PORT
?
566 tpm_dev
.config_port
:
567 tpm_dev
.map_base
+ tpm_dev
.index_off
,
568 tpm_dev
.iotype
== TPM_INF_IO_PORT
?
570 tpm_dev
.map_base
+ tpm_dev
.data_regs
,
571 version
[0], version
[1],
572 vendorid
[0], vendorid
[1],
573 productid
[0], productid
[1], chipname
);
575 if (!(chip
= tpm_register_hardware(&dev
->dev
, &tpm_inf
)))
576 goto err_release_region
;
581 goto err_release_region
;
585 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
) {
586 release_region(tpm_dev
.data_regs
, tpm_dev
.data_size
);
587 release_region(tpm_dev
.config_port
, tpm_dev
.config_size
);
589 iounmap(tpm_dev
.mem_base
);
590 release_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
);
597 static __devexit
void tpm_inf_pnp_remove(struct pnp_dev
*dev
)
599 struct tpm_chip
*chip
= pnp_get_drvdata(dev
);
602 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
) {
603 release_region(tpm_dev
.data_regs
, tpm_dev
.data_size
);
604 release_region(tpm_dev
.config_port
,
605 tpm_dev
.config_size
);
607 iounmap(tpm_dev
.mem_base
);
608 release_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
);
610 tpm_remove_hardware(chip
->dev
);
614 static struct pnp_driver tpm_inf_pnp
= {
615 .name
= "tpm_inf_pnp",
617 .owner
= THIS_MODULE
,
618 .suspend
= tpm_pm_suspend
,
619 .resume
= tpm_pm_resume
,
621 .id_table
= tpm_pnp_tbl
,
622 .probe
= tpm_inf_pnp_probe
,
623 .remove
= __devexit_p(tpm_inf_pnp_remove
),
626 static int __init
init_inf(void)
628 return pnp_register_driver(&tpm_inf_pnp
);
631 static void __exit
cleanup_inf(void)
633 pnp_unregister_driver(&tpm_inf_pnp
);
636 module_init(init_inf
);
637 module_exit(cleanup_inf
);
639 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
640 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
641 MODULE_VERSION("1.9");
642 MODULE_LICENSE("GPL");