1 /* SPDX-License-Identifier: GPL-2.0-or-later */
6 #include <commonlib/endian.h>
7 #include <console/console.h>
9 #include <device/i2c_simple.h>
12 #include <security/tpm/tis.h>
16 /* global structure for tpm chip data */
17 static struct tpm_chip chip
;
19 #define TPM_CMD_COUNT_BYTE 2
20 #define TPM_CMD_ORDINAL_BYTE 6
22 static ssize_t
tpm_transmit(const uint8_t *sbuf
, size_t sbufsiz
, void *rbuf
,
28 memcpy(&count
, sbuf
+ TPM_CMD_COUNT_BYTE
, sizeof(count
));
29 count
= be32_to_cpu(count
);
31 if (!chip
.send
|| !chip
.status
|| !chip
.cancel
)
35 printk(BIOS_DEBUG
, "%s: no data\n", __func__
);
38 if (count
> sbufsiz
) {
39 printk(BIOS_DEBUG
, "%s: invalid count value %#x %zx\n", __func__
,
45 rc
= chip
.send((uint8_t *)sbuf
, count
);
47 printk(BIOS_DEBUG
, "%s: tpm_send error\n", __func__
);
51 int timeout
= 2 * 60 * 1000; /* two minutes timeout */
54 uint8_t status
= chip
.status();
55 if ((status
& chip
.req_complete_mask
) == chip
.req_complete_val
) {
59 if (status
== chip
.req_canceled
) {
61 "%s: Operation Canceled\n", __func__
);
71 printk(BIOS_DEBUG
, "%s: Operation Timed out\n", __func__
);
76 rc
= chip
.recv((uint8_t *)rbuf
, rbufsiz
);
78 printk(BIOS_DEBUG
, "%s: tpm_recv: error %d\n", __func__
, rc
);
83 static tpm_result_t
i2c_tpm_sendrecv(const uint8_t *sendbuf
, size_t sbuf_size
,
84 uint8_t *recvbuf
, size_t *rbuf_len
)
86 ASSERT(sbuf_size
>= 10);
88 /* Display the TPM command */
89 if (CONFIG(DRIVER_TPM_DISPLAY_TIS_BYTES
)) {
90 printk(BIOS_DEBUG
, "TPM Command: 0x%08x\n",
91 read_at_be32(sendbuf
, sizeof(uint16_t)
93 hexdump(sendbuf
, sbuf_size
);
96 int len
= tpm_transmit(sendbuf
, sbuf_size
, recvbuf
, *rbuf_len
);
103 if (len
> *rbuf_len
) {
110 /* Display the TPM response */
111 if (CONFIG(DRIVER_TPM_DISPLAY_TIS_BYTES
)) {
112 printk(BIOS_DEBUG
, "TPM Response: 0x%08x\n",
113 read_at_be32(recvbuf
, sizeof(uint16_t)
114 + sizeof(uint32_t)));
115 hexdump(recvbuf
, *rbuf_len
);
121 tis_sendrecv_fn
i2c_tis_probe(enum tpm_family
*family
)
123 if (tpm_vendor_probe(CONFIG_DRIVER_TPM_I2C_BUS
, CONFIG_DRIVER_TPM_I2C_ADDR
, family
))
126 if (tpm_vendor_init(&chip
, CONFIG_DRIVER_TPM_I2C_BUS
, CONFIG_DRIVER_TPM_I2C_ADDR
))
129 return &i2c_tpm_sendrecv
;