1 /* This file is part of the coreboot project. */
2 /* SPDX-License-Identifier: GPL-2.0-or-later */
7 #include <commonlib/endian.h>
8 #include <console/console.h>
10 #include <device/i2c_simple.h>
13 #include <security/tpm/tis.h>
17 /* global structure for tpm chip data */
18 static struct tpm_chip chip
;
20 #define TPM_CMD_COUNT_BYTE 2
21 #define TPM_CMD_ORDINAL_BYTE 6
28 printk(BIOS_DEBUG
, "tis_open() called twice.\n");
32 rc
= tpm_vendor_init(&chip
, CONFIG_DRIVER_TPM_I2C_BUS
,
33 CONFIG_DRIVER_TPM_I2C_ADDR
);
46 tpm_vendor_cleanup(&chip
);
55 return tpm_vendor_probe(CONFIG_DRIVER_TPM_I2C_BUS
,
56 CONFIG_DRIVER_TPM_I2C_ADDR
);
59 static ssize_t
tpm_transmit(const uint8_t *sbuf
, size_t sbufsiz
, void *rbuf
,
65 memcpy(&count
, sbuf
+ TPM_CMD_COUNT_BYTE
, sizeof(count
));
66 count
= be32_to_cpu(count
);
68 if (!chip
.vendor
.send
|| !chip
.vendor
.status
|| !chip
.vendor
.cancel
)
72 printk(BIOS_DEBUG
, "tpm_transmit: no data\n");
75 if (count
> sbufsiz
) {
76 printk(BIOS_DEBUG
, "tpm_transmit: invalid count value %x %zx\n",
81 ASSERT(chip
.vendor
.send
);
82 rc
= chip
.vendor
.send(&chip
, (uint8_t *) sbuf
, count
);
84 printk(BIOS_DEBUG
, "tpm_transmit: tpm_send error\n");
88 int timeout
= 2 * 60 * 1000; /* two minutes timeout */
90 ASSERT(chip
.vendor
.status
);
91 uint8_t status
= chip
.vendor
.status(&chip
);
92 if ((status
& chip
.vendor
.req_complete_mask
) ==
93 chip
.vendor
.req_complete_val
) {
97 if (status
== chip
.vendor
.req_canceled
) {
99 "tpm_transmit: Operation Canceled\n");
107 ASSERT(chip
.vendor
.cancel
);
108 chip
.vendor
.cancel(&chip
);
109 printk(BIOS_DEBUG
, "tpm_transmit: Operation Timed out\n");
115 rc
= chip
.vendor
.recv(&chip
, (uint8_t *) rbuf
, rbufsiz
);
117 printk(BIOS_DEBUG
, "tpm_transmit: tpm_recv: error %d\n", rc
);
122 int tis_sendrecv(const uint8_t *sendbuf
, size_t sbuf_size
,
123 uint8_t *recvbuf
, size_t *rbuf_len
)
125 ASSERT(sbuf_size
>= 10);
127 /* Display the TPM command */
128 if (CONFIG(DRIVER_TPM_DISPLAY_TIS_BYTES
)) {
129 printk(BIOS_DEBUG
, "TPM Command: 0x%08x\n",
130 read_at_be32(sendbuf
, sizeof(uint16_t)
131 + sizeof(uint32_t)));
132 hexdump(sendbuf
, sbuf_size
);
135 int len
= tpm_transmit(sendbuf
, sbuf_size
, recvbuf
, *rbuf_len
);
142 if (len
> *rbuf_len
) {
149 /* Display the TPM response */
150 if (CONFIG(DRIVER_TPM_DISPLAY_TIS_BYTES
)) {
151 printk(BIOS_DEBUG
, "TPM Response: 0x%08x\n",
152 read_at_be32(recvbuf
, sizeof(uint16_t)
153 + sizeof(uint32_t)));
154 hexdump(recvbuf
, *rbuf_len
);