diff options
author | Tom Rini <trini@konsulko.com> | 2021-11-13 18:13:35 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-11-13 18:13:35 -0500 |
commit | b8a156f54ecd1e9a74f48a09a0735b4a41c90eba (patch) | |
tree | 7eda0ea12d5af71faaca35ca3f4bd55d4bfb723f | |
parent | a51673eb75de328d3471b742e593f04b166591c4 (diff) | |
parent | 2a10e06e07540694d82838793ee7cb34f4dbc59c (diff) | |
download | u-boot-b8a156f54ecd1e9a74f48a09a0735b4a41c90eba.zip u-boot-b8a156f54ecd1e9a74f48a09a0735b4a41c90eba.tar.gz u-boot-b8a156f54ecd1e9a74f48a09a0735b4a41c90eba.tar.bz2 |
Merge tag 'efi-2022-01-rc2-2' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request for efi-2022-01-rc2-2
UEFI:
* fix measurement of BootOrder variable for TCG2 protocol
TPM:
* TIS mmio driver. This driver supports QEMU's emulated TPM.
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | configs/qemu_arm64_defconfig | 2 | ||||
-rw-r--r-- | configs/qemu_arm_defconfig | 2 | ||||
-rw-r--r-- | doc/board/emulation/qemu-arm.rst | 25 | ||||
-rw-r--r-- | drivers/tpm/Kconfig | 9 | ||||
-rw-r--r-- | drivers/tpm/Makefile | 3 | ||||
-rw-r--r-- | drivers/tpm/tpm2_tis_core.c | 463 | ||||
-rw-r--r-- | drivers/tpm/tpm2_tis_mmio.c | 157 | ||||
-rw-r--r-- | drivers/tpm/tpm2_tis_spi.c | 447 | ||||
-rw-r--r-- | drivers/tpm/tpm_tis.h | 136 | ||||
-rw-r--r-- | drivers/tpm/tpm_tis_infineon.c | 34 | ||||
-rw-r--r-- | drivers/tpm/tpm_tis_lpc.c | 4 | ||||
-rw-r--r-- | include/tpm-v2.h | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_tcg2.c | 4 |
14 files changed, 854 insertions, 438 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 00ff572..6db5354 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1187,6 +1187,11 @@ F: configs/am65x_hs_evm_a53_defconfig F: configs/j721e_hs_evm_r5_defconfig F: configs/j721e_hs_evm_a72_defconfig +TPM DRIVERS +M: Ilias Apalodimas <ilias.apalodimas@linaro.org> +S: Maintained +F: drivers/tpm/ + TQ GROUP #M: Martin Krause <martin.krause@tq-systems.de> S: Orphaned (Since 2016-02) diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 003717e..83d7ae5 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -49,6 +49,8 @@ CONFIG_SCSI=y CONFIG_DM_SCSI=y CONFIG_SYSRESET=y CONFIG_SYSRESET_PSCI=y +CONFIG_TPM2_MMIO=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y +CONFIG_TPM=y diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index 27b0e49..ab55748 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -51,6 +51,8 @@ CONFIG_SCSI=y CONFIG_DM_SCSI=y CONFIG_SYSRESET=y CONFIG_SYSRESET_PSCI=y +CONFIG_TPM2_MMIO=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y +CONFIG_TPM=y diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst index 8d7fda1..584ef0a 100644 --- a/doc/board/emulation/qemu-arm.rst +++ b/doc/board/emulation/qemu-arm.rst @@ -81,6 +81,31 @@ can be enabled with the following command line parameters: These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well. +Enabling TPMv2 support +---------------------- + +To emulate a TPM the swtpm package may be used. It can be built from the +following repositories: + + https://github.com/stefanberger/swtpm.git + +Swtpm provides a socket for the TPM emulation which can be consumed by QEMU. + +In a first console invoke swtpm with:: + + swtpm socket --tpmstate dir=/tmp/mytpm1 \ + --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --log level=20 + +In a second console invoke qemu-system-aarch64 with:: + + -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ + -tpmdev emulator,id=tpm0,chardev=chrtpm \ + -device tpm-tis-device,tpmdev=tpm0 + +Enable the TPM on U-Boot's command line with:: + + tpm2 startup TPM2_SU_CLEAR + Debug UART ---------- diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig index 9eebab5..406ee87 100644 --- a/drivers/tpm/Kconfig +++ b/drivers/tpm/Kconfig @@ -161,6 +161,15 @@ config TPM2_FTPM_TEE help This driver supports firmware TPM running in TEE. +config TPM2_MMIO + bool "MMIO based TPM2 Interface" + depends on TPM_V2 + help + This driver supports firmware TPM2.0 MMIO interface. + The usual TPM operations and the 'tpm' command can be used to talk + to the device using the standard TPM Interface Specification (TIS) + protocol. + endif # TPM_V2 endmenu diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile index c65be52..5172523 100644 --- a/drivers/tpm/Makefile +++ b/drivers/tpm/Makefile @@ -12,5 +12,6 @@ obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o obj-$(CONFIG_$(SPL_TPL_)TPM2_CR50_I2C) += cr50_i2c.o obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o sandbox_common.o -obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_spi.o +obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_core.o tpm2_tis_spi.o obj-$(CONFIG_TPM2_FTPM_TEE) += tpm2_ftpm_tee.o +obj-$(CONFIG_TPM2_MMIO) += tpm2_tis_core.o tpm2_tis_mmio.o diff --git a/drivers/tpm/tpm2_tis_core.c b/drivers/tpm/tpm2_tis_core.c new file mode 100644 index 0000000..ec8c730 --- /dev/null +++ b/drivers/tpm/tpm2_tis_core.c @@ -0,0 +1,463 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020, Linaro Limited + * + * Based on the Linux TIS core interface and U-Boot original SPI TPM driver + */ + +#include <common.h> +#include <dm.h> +#include <tpm-v2.h> +#include <linux/delay.h> +#include <linux/unaligned/be_byteshift.h> +#include "tpm_tis.h" + +int tpm_tis_get_desc(struct udevice *dev, char *buf, int size) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + if (size < 80) + return -ENOSPC; + + return snprintf(buf, size, + "%s v2.0: VendorID 0x%04x, DeviceID 0x%04x, RevisionID 0x%02x [%s]", + dev->name, chip->vend_dev & 0xFFFF, + chip->vend_dev >> 16, chip->rid, + (chip->is_open ? "open" : "closed")); +} + +/** + * tpm_tis_check_locality - Check the current TPM locality + * + * @dev: TPM device + * @loc: locality + * + * Return: True if the tested locality matches + */ +static bool tpm_tis_check_locality(struct udevice *dev, int loc) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + u8 locality; + + phy_ops->read_bytes(dev, TPM_ACCESS(loc), 1, &locality); + if ((locality & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID | + TPM_ACCESS_REQUEST_USE)) == + (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) { + chip->locality = loc; + return true; + } + + return false; +} + +/** + * tpm_tis_request_locality - Request a locality from the TPM + * + * @dev: TPM device + * @loc: requested locality + * + * Return: 0 on success -1 on failure + */ +int tpm_tis_request_locality(struct udevice *dev, int loc) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + u8 buf = TPM_ACCESS_REQUEST_USE; + unsigned long start, stop; + + if (tpm_tis_check_locality(dev, loc)) + return 0; + + phy_ops->write_bytes(dev, TPM_ACCESS(loc), 1, &buf); + start = get_timer(0); + stop = chip->timeout_a; + do { + if (tpm_tis_check_locality(dev, loc)) + return 0; + mdelay(TPM_TIMEOUT_MS); + } while (get_timer(start) < stop); + + return -1; +} + +/** + * tpm_tis_status - Check the current device status + * + * @dev: TPM device + * @status: return value of status + * + * Return: 0 on success, negative on failure + */ +static int tpm_tis_status(struct udevice *dev, u8 *status) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + + if (chip->locality < 0) + return -EINVAL; + + phy_ops->read_bytes(dev, TPM_STS(chip->locality), 1, status); + + if ((*status & TPM_STS_READ_ZERO)) { + log_err("TPM returned invalid status\n"); + return -EINVAL; + } + + return 0; +} + +/** + * tpm_tis_release_locality - Release the requested locality + * + * @dev: TPM device + * @loc: requested locality + * + * Return: 0 on success, negative on failure + */ +int tpm_tis_release_locality(struct udevice *dev, int loc) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + u8 buf = TPM_ACCESS_ACTIVE_LOCALITY; + int ret; + + if (chip->locality < 0) + return 0; + + ret = phy_ops->write_bytes(dev, TPM_ACCESS(loc), 1, &buf); + chip->locality = -1; + + return ret; +} + +/** + * tpm_tis_wait_for_stat - Wait for TPM to become ready + * + * @dev: TPM device + * @mask: mask to match + * @timeout: timeout for retries + * @status: current status + * + * Return: 0 on success, negative on failure + */ +static int tpm_tis_wait_for_stat(struct udevice *dev, u8 mask, + unsigned long timeout, u8 *status) +{ + unsigned long start = get_timer(0); + unsigned long stop = timeout; + int ret; + + do { + mdelay(TPM_TIMEOUT_MS); + ret = tpm_tis_status(dev, status); + if (ret) + return ret; + + if ((*status & mask) == mask) + return 0; + } while (get_timer(start) < stop); + + return -ETIMEDOUT; +} + +/** + * tpm_tis_get_burstcount - Get the burstcount for the data FIFO + * + * @dev: TPM device + * @burstcount: current burstcount + * + * Return: 0 on success, negative on failure + */ +static int tpm_tis_get_burstcount(struct udevice *dev, size_t *burstcount) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + unsigned long start, stop; + u32 burst; + + if (chip->locality < 0) + return -EINVAL; + + /* wait for burstcount */ + start = get_timer(0); + /* + * This is the TPMv2 defined timeout. Change this in case you want to + * make the driver compatile to TPMv1 + */ + stop = chip->timeout_a; + do { + phy_ops->read32(dev, TPM_STS(chip->locality), &burst); + *burstcount = (burst >> 8) & 0xFFFF; + if (*burstcount) + return 0; + + mdelay(TPM_TIMEOUT_MS); + } while (get_timer(start) < stop); + + return -ETIMEDOUT; +} + +/** + * tpm_tis_ready - Cancel pending comands and get the device on a ready state + * + * @dev: TPM device + * + * Return: 0 on success, negative on failure + */ +static int tpm_tis_ready(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + u8 data = TPM_STS_COMMAND_READY; + + /* This will cancel any pending commands */ + return phy_ops->write_bytes(dev, TPM_STS(chip->locality), 1, &data); +} + +int tpm_tis_send(struct udevice *dev, const u8 *buf, size_t len) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + size_t burstcnt, wr_size, sent = 0; + u8 data = TPM_STS_GO; + u8 status; + int ret; + + if (!chip) + return -ENODEV; + + ret = tpm_tis_request_locality(dev, 0); + if (ret < 0) + return -EBUSY; + + ret = tpm_tis_status(dev, &status); + if (ret) + goto release_locality; + + if (!(status & TPM_STS_COMMAND_READY)) { + ret = tpm_tis_ready(dev); + if (ret) { + log_err("Can't cancel previous TPM operation\n"); + goto release_locality; + } + ret = tpm_tis_wait_for_stat(dev, TPM_STS_COMMAND_READY, + chip->timeout_b, &status); + if (ret) { + log_err("TPM not ready\n"); + goto release_locality; + } + } + + while (len > 0) { + ret = tpm_tis_get_burstcount(dev, &burstcnt); + if (ret) + goto release_locality; + + wr_size = min(len, burstcnt); + ret = phy_ops->write_bytes(dev, TPM_DATA_FIFO(chip->locality), + wr_size, buf + sent); + if (ret < 0) + goto release_locality; + + ret = tpm_tis_wait_for_stat(dev, TPM_STS_VALID, + chip->timeout_c, &status); + if (ret) + goto release_locality; + + sent += wr_size; + len -= wr_size; + /* make sure the TPM expects more data */ + if (len && !(status & TPM_STS_DATA_EXPECT)) { + ret = -EIO; + goto release_locality; + } + } + + /* + * Make a final check ensuring everything is ok and the TPM expects no + * more data + */ + ret = tpm_tis_wait_for_stat(dev, TPM_STS_VALID, chip->timeout_c, + &status); + if (ret) + goto release_locality; + + if (status & TPM_STS_DATA_EXPECT) { + ret = -EIO; + goto release_locality; + } + + ret = phy_ops->write_bytes(dev, TPM_STS(chip->locality), 1, &data); + if (ret) + goto release_locality; + + return sent; + +release_locality: + tpm_tis_ready(dev); + tpm_tis_release_locality(dev, chip->locality); + + return ret; +} + +static int tpm_tis_recv_data(struct udevice *dev, u8 *buf, size_t count) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + int size = 0, len, ret; + size_t burstcnt; + u8 status; + + while (size < count && + tpm_tis_wait_for_stat(dev, TPM_STS_DATA_AVAIL | TPM_STS_VALID, + chip->timeout_c, &status) == 0) { + ret = tpm_tis_get_burstcount(dev, &burstcnt); + if (ret) + return ret; + + len = min_t(int, burstcnt, count - size); + ret = phy_ops->read_bytes(dev, TPM_DATA_FIFO(chip->locality), + len, buf + size); + if (ret < 0) + return ret; + + size += len; + } + + return size; +} + +/** + * tpm_tis_recv - Receive data from a device + * + * @dev: TPM device + * @buf: buffer to copy data + * @size: buffer size + * + * Return: bytes read or negative on failure + */ +int tpm_tis_recv(struct udevice *dev, u8 *buf, size_t count) +{ + struct tpm_chip *chip = dev_get_priv(dev); + int size, expected; + + if (count < TPM_HEADER_SIZE) + return -E2BIG; + + size = tpm_tis_recv_data(dev, buf, TPM_HEADER_SIZE); + if (size < TPM_HEADER_SIZE) { + log_err("TPM error, unable to read header\n"); + goto out; + } + + expected = get_unaligned_be32(buf + TPM_CMD_COUNT_OFFSET); + if (expected > count) { + size = -EIO; + log_warning("Too much data: %d > %zu\n", expected, count); + goto out; + } + + size += tpm_tis_recv_data(dev, &buf[TPM_HEADER_SIZE], + expected - TPM_HEADER_SIZE); + if (size < expected) { + log(LOGC_NONE, LOGL_ERR, + "TPM error, unable to read remaining bytes of result\n"); + size = -EIO; + goto out; + } + +out: + tpm_tis_ready(dev); + /* acquired in tpm_tis_send */ + tpm_tis_release_locality(dev, chip->locality); + + return size; +} + +int tpm_tis_cleanup(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + tpm_tis_ready(dev); + tpm_tis_release_locality(dev, chip->locality); + + return 0; +} + +int tpm_tis_open(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + int ret; + + if (chip->is_open) + return -EBUSY; + + ret = tpm_tis_request_locality(dev, 0); + if (!ret) + chip->is_open = 1; + + return ret; +} + +void tpm_tis_ops_register(struct udevice *dev, struct tpm_tis_phy_ops *ops) +{ + struct tpm_chip *chip = dev_get_priv(dev); + + chip->phy_ops = ops; +} + +static bool tis_check_ops(struct tpm_tis_phy_ops *phy_ops) +{ + if (!phy_ops || !phy_ops->read_bytes || !phy_ops->write_bytes || + !phy_ops->read32 || !phy_ops->write32) + return false; + + return true; +} + +int tpm_tis_init(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + struct tpm_tis_phy_ops *phy_ops = chip->phy_ops; + int ret; + u32 tmp; + + if (!tis_check_ops(phy_ops)) { + log_err("Driver bug. No bus ops defined\n"); + return -1; + } + ret = tpm_tis_request_locality(dev, 0); + if (ret) + return ret; + + chip->timeout_a = TIS_SHORT_TIMEOUT_MS; + chip->timeout_b = TIS_LONG_TIMEOUT_MS; + chip->timeout_c = TIS_SHORT_TIMEOUT_MS; + chip->timeout_d = TIS_SHORT_TIMEOUT_MS; + + /* Disable interrupts */ + phy_ops->read32(dev, TPM_INT_ENABLE(chip->locality), &tmp); + tmp |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | + TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; + tmp &= ~TPM_GLOBAL_INT_ENABLE; + phy_ops->write32(dev, TPM_INT_ENABLE(chip->locality), tmp); + + phy_ops->read_bytes(dev, TPM_RID(chip->locality), 1, &chip->rid); + phy_ops->read32(dev, TPM_DID_VID(chip->locality), &chip->vend_dev); + + return tpm_tis_release_locality(dev, chip->locality); +} + +int tpm_tis_close(struct udevice *dev) +{ + struct tpm_chip *chip = dev_get_priv(dev); + int ret = 0; + + if (chip->is_open) { + ret = tpm_tis_release_locality(dev, chip->locality); + chip->is_open = 0; + } + + return ret; +} diff --git a/drivers/tpm/tpm2_tis_mmio.c b/drivers/tpm/tpm2_tis_mmio.c new file mode 100644 index 0000000..9cedff2 --- /dev/null +++ b/drivers/tpm/tpm2_tis_mmio.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * driver for mmio TCG/TIS TPM (trusted platform module). + * + * Specifications at www.trustedcomputinggroup.org + */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <tpm-v2.h> +#include <linux/bitops.h> +#include <linux/compiler.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/io.h> +#include <linux/unaligned/be_byteshift.h> +#include "tpm_tis.h" +#include "tpm_internal.h" + +/** + * struct tpm_tis_chip_data - Information about an MMIO TPM + * @pcr_count: Number of PCR per bank + * @pcr_select_min: Minimum size in bytes of the pcrSelect array + * @iobase: Base address + */ +struct tpm_tis_chip_data { + unsigned int pcr_count; + unsigned int pcr_select_min; + void __iomem *iobase; +}; + +static int mmio_read_bytes(struct udevice *dev, u32 addr, u16 len, + u8 *result) +{ + struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); + + while (len--) + *result++ = ioread8(drv_data->iobase + addr); + + return 0; +} + +static int mmio_write_bytes(struct udevice *dev, u32 addr, u16 len, + const u8 *value) +{ + struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); + + while (len--) + iowrite8(*value++, drv_data->iobase + addr); + + return 0; +} + +static int mmio_read32(struct udevice *dev, u32 addr, u32 *result) +{ + struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); + + *result = ioread32(drv_data->iobase + addr); + + return 0; +} + +static int mmio_write32(struct udevice *dev, u32 addr, u32 value) +{ + struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); + + iowrite32(value, drv_data->iobase + addr); + + return 0; +} + +static struct tpm_tis_phy_ops phy_ops = { + .read_bytes = mmio_read_bytes, + .write_bytes = mmio_write_bytes, + .read32 = mmio_read32, + .write32 = mmio_write32, +}; + +static int tpm_tis_probe(struct udevice *dev) +{ + struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); + struct tpm_chip_priv *priv = dev_get_uclass_priv(dev); + int ret = 0; + fdt_addr_t ioaddr; + u64 sz; + + ioaddr = dev_read_addr(dev); + if (ioaddr == FDT_ADDR_T_NONE) + return log_msg_ret("ioaddr", -EINVAL); + + ret = dev_read_u64(dev, "reg", &sz); + if (ret) + return -EINVAL; + + drv_data->iobase = ioremap(ioaddr, sz); + tpm_tis_ops_register(dev, &phy_ops); + ret = tpm_tis_init(dev); + if (ret) + goto iounmap; + + priv->pcr_count = drv_data->pcr_count; + priv->pcr_select_min = drv_data->pcr_select_min; + /* + * Although the driver probably works with a TPMv1 our Kconfig + * limits the driver to TPMv2 only + */ + priv->version = TPM_V2; + + return ret; +iounmap: + iounmap(drv_data->iobase); + + return -EINVAL; +} + +static int tpm_tis_remove(struct udevice *dev) +{ + struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); + + iounmap(drv_data->iobase); + + return tpm_tis_cleanup(dev); +} + +static const struct tpm_ops tpm_tis_ops = { + .open = tpm_tis_open, + .close = tpm_tis_close, + .get_desc = tpm_tis_get_desc, + .send = tpm_tis_send, + .recv = tpm_tis_recv, + .cleanup = tpm_tis_cleanup, +}; + +static const struct tpm_tis_chip_data tpm_tis_std_chip_data = { + .pcr_count = 24, + .pcr_select_min = 3, +}; + +static const struct udevice_id tpm_tis_ids[] = { + { + .compatible = "tcg,tpm-tis-mmio", + .data = (ulong)&tpm_tis_std_chip_data, + }, + { } +}; + +U_BOOT_DRIVER(tpm_tis_mmio) = { + .name = "tpm_tis_mmio", + .id = UCLASS_TPM, + .of_match = tpm_tis_ids, + .ops = &tpm_tis_ops, + .probe = tpm_tis_probe, + .remove = tpm_tis_remove, + .priv_auto = sizeof(struct tpm_chip), +}; diff --git a/drivers/tpm/tpm2_tis_spi.c b/drivers/tpm/tpm2_tis_spi.c index 1d24d32..58b6f33 100644 --- a/drivers/tpm/tpm2_tis_spi.c +++ b/drivers/tpm/tpm2_tis_spi.c @@ -30,13 +30,6 @@ #include "tpm_tis.h" #include "tpm_internal.h" -#define TPM_ACCESS(l) (0x0000 | ((l) << 12)) -#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12)) -#define TPM_STS(l) (0x0018 | ((l) << 12)) -#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12)) -#define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) -#define TPM_RID(l) (0x0F04 | ((l) << 12)) - #define MAX_SPI_FRAMESIZE 64 /* Number of wait states to wait for */ @@ -165,7 +158,7 @@ release_bus: return ret; } -static int tpm_tis_spi_read(struct udevice *dev, u16 addr, u8 *in, u16 len) +static int tpm_tis_spi_read(struct udevice *dev, u32 addr, u16 len, u8 *in) { return tpm_tis_spi_xfer(dev, addr, NULL, in, len); } @@ -175,382 +168,24 @@ static int tpm_tis_spi_read32(struct udevice *dev, u32 addr, u32 *result) __le32 result_le; int ret; - ret = tpm_tis_spi_read(dev, addr, (u8 *)&result_le, sizeof(u32)); + ret = tpm_tis_spi_read(dev, addr, sizeof(u32), (u8 *)&result_le); if (!ret) *result = le32_to_cpu(result_le); return ret; } -static int tpm_tis_spi_write(struct udevice *dev, u16 addr, const u8 *out, - u16 len) -{ - return tpm_tis_spi_xfer(dev, addr, out, NULL, len); -} - -static int tpm_tis_spi_check_locality(struct udevice *dev, int loc) -{ - const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID; - struct tpm_chip *chip = dev_get_priv(dev); - u8 buf; - int ret; - - ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1); - if (ret) - return ret; - - if ((buf & mask) == mask) { - chip->locality = loc; - return 0; - } - - return -ENOENT; -} - -static void tpm_tis_spi_release_locality(struct udevice *dev, int loc, - bool force) -{ - const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID; - u8 buf; - if (tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1) < 0) - return; - - if (force || (buf & mask) == mask) { - buf = TPM_ACCESS_ACTIVE_LOCALITY; - tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1); - } -} - -static int tpm_tis_spi_request_locality(struct udevice *dev, int loc) +static int tpm_tis_spi_write(struct udevice *dev, u32 addr, u16 len, const u8 *out) { - struct tpm_chip *chip = dev_get_priv(dev); - unsigned long start, stop; - u8 buf = TPM_ACCESS_REQUEST_USE; - int ret; - - ret = tpm_tis_spi_check_locality(dev, loc); - if (!ret) - return 0; - - if (ret != -ENOENT) { - log(LOGC_NONE, LOGL_ERR, "%s: Failed to get locality: %d\n", - __func__, ret); - return ret; - } - - ret = tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1); - if (ret) { - log(LOGC_NONE, LOGL_ERR, "%s: Failed to write to TPM: %d\n", - __func__, ret); - return ret; - } - - start = get_timer(0); - stop = chip->timeout_a; - do { - ret = tpm_tis_spi_check_locality(dev, loc); - if (!ret) - return 0; - - if (ret != -ENOENT) { - log(LOGC_NONE, LOGL_ERR, - "%s: Failed to get locality: %d\n", __func__, ret); - return ret; - } - - mdelay(TPM_TIMEOUT_MS); - } while (get_timer(start) < stop); - - log(LOGC_NONE, LOGL_ERR, "%s: Timeout getting locality: %d\n", __func__, - ret); - - return ret; -} - -static u8 tpm_tis_spi_status(struct udevice *dev, u8 *status) -{ - struct tpm_chip *chip = dev_get_priv(dev); - - return tpm_tis_spi_read(dev, TPM_STS(chip->locality), status, 1); -} - -static int tpm_tis_spi_wait_for_stat(struct udevice *dev, u8 mask, - unsigned long timeout, u8 *status) -{ - unsigned long start = get_timer(0); - unsigned long stop = timeout; - int ret; - - do { - mdelay(TPM_TIMEOUT_MS); - ret = tpm_tis_spi_status(dev, status); - if (ret) - return ret; - - if ((*status & mask) == mask) - return 0; - } while (get_timer(start) < stop); - - return -ETIMEDOUT; -} - -static u8 tpm_tis_spi_valid_status(struct udevice *dev, u8 *status) -{ - struct tpm_chip *chip = dev_get_priv(dev); - - return tpm_tis_spi_wait_for_stat(dev, TPM_STS_VALID, - chip->timeout_c, status); -} - -static int tpm_tis_spi_get_burstcount(struct udevice *dev) -{ - struct tpm_chip *chip = dev_get_priv(dev); - unsigned long start, stop; - u32 burstcount, ret; - - /* wait for burstcount */ - start = get_timer(0); - stop = chip->timeout_d; - do { - ret = tpm_tis_spi_read32(dev, TPM_STS(chip->locality), - &burstcount); - if (ret) - return -EBUSY; - - burstcount = (burstcount >> 8) & 0xFFFF; - if (burstcount) - return burstcount; - - mdelay(TPM_TIMEOUT_MS); - } while (get_timer(start) < stop); - - return -EBUSY; -} - -static int tpm_tis_spi_cancel(struct udevice *dev) -{ - struct tpm_chip *chip = dev_get_priv(dev); - u8 data = TPM_STS_COMMAND_READY; - - return tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1); -} - -static int tpm_tis_spi_recv_data(struct udevice *dev, u8 *buf, size_t count) -{ - struct tpm_chip *chip = dev_get_priv(dev); - int size = 0, burstcnt, len, ret; - u8 status; - - while (size < count && - tpm_tis_spi_wait_for_stat(dev, - TPM_STS_DATA_AVAIL | TPM_STS_VALID, - chip->timeout_c, &status) == 0) { - burstcnt = tpm_tis_spi_get_burstcount(dev); - if (burstcnt < 0) - return burstcnt; - - len = min_t(int, burstcnt, count - size); - ret = tpm_tis_spi_read(dev, TPM_DATA_FIFO(chip->locality), - buf + size, len); - if (ret < 0) - return ret; - - size += len; - } - - return size; -} - -static int tpm_tis_spi_recv(struct udevice *dev, u8 *buf, size_t count) -{ - struct tpm_chip *chip = dev_get_priv(dev); - int size, expected; - - if (!chip) - return -ENODEV; - - if (count < TPM_HEADER_SIZE) { - size = -EIO; - goto out; - } - - size = tpm_tis_spi_recv_data(dev, buf, TPM_HEADER_SIZE); - if (size < TPM_HEADER_SIZE) { - log(LOGC_NONE, LOGL_ERR, "TPM error, unable to read header\n"); - goto out; - } - - expected = get_unaligned_be32(buf + 2); - if (expected > count) { - size = -EIO; - goto out; - } - - size += tpm_tis_spi_recv_data(dev, &buf[TPM_HEADER_SIZE], - expected - TPM_HEADER_SIZE); - if (size < expected) { - log(LOGC_NONE, LOGL_ERR, - "TPM error, unable to read remaining bytes of result\n"); - size = -EIO; - goto out; - } - -out: - tpm_tis_spi_cancel(dev); - tpm_tis_spi_release_locality(dev, chip->locality, false); - - return size; -} - -static int tpm_tis_spi_send(struct udevice *dev, const u8 *buf, size_t len) -{ - struct tpm_chip *chip = dev_get_priv(dev); - u32 i, size; - u8 status; - int burstcnt, ret; - u8 data; - - if (!chip) - return -ENODEV; - - if (len > TPM_DEV_BUFSIZE) - return -E2BIG; /* Command is too long for our tpm, sorry */ - - ret = tpm_tis_spi_request_locality(dev, 0); - if (ret < 0) - return -EBUSY; - - /* - * Check if the TPM is ready. If not, if not, cancel the pending command - * and poll on the status to be finally ready. - */ - ret = tpm_tis_spi_status(dev, &status); - if (ret) - return ret; - - if (!(status & TPM_STS_COMMAND_READY)) { - /* Force the transition, usually this will be done at startup */ - ret = tpm_tis_spi_cancel(dev); - if (ret) { - log(LOGC_NONE, LOGL_ERR, - "%s: Could not cancel previous operation\n", - __func__); - goto out_err; - } - - ret = tpm_tis_spi_wait_for_stat(dev, TPM_STS_COMMAND_READY, - chip->timeout_b, &status); - if (ret < 0 || !(status & TPM_STS_COMMAND_READY)) { - log(LOGC_NONE, LOGL_ERR, - "status %d after wait for stat returned %d\n", - status, ret); - goto out_err; - } - } - - for (i = 0; i < len - 1;) { - burstcnt = tpm_tis_spi_get_burstcount(dev); - if (burstcnt < 0) - return burstcnt; - - size = min_t(int, len - i - 1, burstcnt); - ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality), - buf + i, size); - if (ret < 0) - goto out_err; - - i += size; - } - - ret = tpm_tis_spi_valid_status(dev, &status); - if (ret) - goto out_err; - - if ((status & TPM_STS_DATA_EXPECT) == 0) { - ret = -EIO; - goto out_err; - } - - ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality), - buf + len - 1, 1); - if (ret) - goto out_err; - - ret = tpm_tis_spi_valid_status(dev, &status); - if (ret) - goto out_err; - - if ((status & TPM_STS_DATA_EXPECT) != 0) { - ret = -EIO; - goto out_err; - } - - data = TPM_STS_GO; - ret = tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1); - if (ret) - goto out_err; - - return len; - -out_err: - tpm_tis_spi_cancel(dev); - tpm_tis_spi_release_locality(dev, chip->locality, false); - - return ret; -} - -static int tpm_tis_spi_cleanup(struct udevice *dev) -{ - struct tpm_chip *chip = dev_get_priv(dev); - - tpm_tis_spi_cancel(dev); - /* - * The TPM needs some time to clean up here, - * so we sleep rather than keeping the bus busy - */ - mdelay(2); - tpm_tis_spi_release_locality(dev, chip->locality, false); - - return 0; -} - -static int tpm_tis_spi_open(struct udevice *dev) -{ - struct tpm_chip *chip = dev_get_priv(dev); - - if (chip->is_open) - return -EBUSY; - - chip->is_open = 1; - - return 0; -} - -static int tpm_tis_spi_close(struct udevice *dev) -{ - struct tpm_chip *chip = dev_get_priv(dev); - - if (chip->is_open) { - tpm_tis_spi_release_locality(dev, chip->locality, true); - chip->is_open = 0; - } - - return 0; + return tpm_tis_spi_xfer(dev, addr, out, NULL, len); } -static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size) +static int tpm_tis_spi_write32(struct udevice *dev, u32 addr, u32 value) { - struct tpm_chip *chip = dev_get_priv(dev); - - if (size < 80) - return -ENOSPC; + __le32 value_le = cpu_to_le32(value); - return snprintf(buf, size, - "%s v2.0: VendorID 0x%04x, DeviceID 0x%04x, RevisionID 0x%02x [%s]", - dev->name, chip->vend_dev & 0xFFFF, - chip->vend_dev >> 16, chip->rid, - (chip->is_open ? "open" : "closed")); + return tpm_tis_spi_write(dev, addr, sizeof(value), (u8 *)&value_le); } static int tpm_tis_wait_init(struct udevice *dev, int loc) @@ -565,7 +200,7 @@ static int tpm_tis_wait_init(struct udevice *dev, int loc) do { mdelay(TPM_TIMEOUT_MS); - ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &status, 1); + ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), 1, &status); if (ret) break; @@ -576,6 +211,13 @@ static int tpm_tis_wait_init(struct udevice *dev, int loc) return -EIO; } +static struct tpm_tis_phy_ops phy_ops = { + .read_bytes = tpm_tis_spi_read, + .write_bytes = tpm_tis_spi_write, + .read32 = tpm_tis_spi_read32, + .write32 = tpm_tis_spi_write32, +}; + static int tpm_tis_spi_probe(struct udevice *dev) { struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); @@ -611,65 +253,38 @@ init: /* Ensure a minimum amount of time elapsed since reset of the TPM */ mdelay(drv_data->time_before_first_cmd_ms); - chip->locality = 0; - chip->timeout_a = TIS_SHORT_TIMEOUT_MS; - chip->timeout_b = TIS_LONG_TIMEOUT_MS; - chip->timeout_c = TIS_SHORT_TIMEOUT_MS; - chip->timeout_d = TIS_SHORT_TIMEOUT_MS; - priv->pcr_count = drv_data->pcr_count; - priv->pcr_select_min = drv_data->pcr_select_min; - ret = tpm_tis_wait_init(dev, chip->locality); if (ret) { log(LOGC_DM, LOGL_ERR, "%s: no device found\n", __func__); return ret; } - ret = tpm_tis_spi_request_locality(dev, chip->locality); - if (ret) { - log(LOGC_NONE, LOGL_ERR, "%s: could not request locality %d\n", - __func__, chip->locality); - return ret; - } - - ret = tpm_tis_spi_read32(dev, TPM_DID_VID(chip->locality), - &chip->vend_dev); - if (ret) { - log(LOGC_NONE, LOGL_ERR, - "%s: could not retrieve VendorID/DeviceID\n", __func__); - return ret; - } - - ret = tpm_tis_spi_read(dev, TPM_RID(chip->locality), &chip->rid, 1); - if (ret) { - log(LOGC_NONE, LOGL_ERR, "%s: could not retrieve RevisionID\n", - __func__); - return ret; - } + tpm_tis_ops_register(dev, &phy_ops); + ret = tpm_tis_init(dev); + if (ret) + goto err; - log(LOGC_NONE, LOGL_ERR, - "SPI TPMv2.0 found (vid:%04x, did:%04x, rid:%02x)\n", - chip->vend_dev & 0xFFFF, chip->vend_dev >> 16, chip->rid); + priv->pcr_count = drv_data->pcr_count; + priv->pcr_select_min = drv_data->pcr_select_min; + priv->version = TPM_V2; return 0; +err: + return -EINVAL; } -static int tpm_tis_spi_remove(struct udevice *dev) +static int tpm_tis_spi_remove(struct udevice *udev) { - struct tpm_chip *chip = dev_get_priv(dev); - - tpm_tis_spi_release_locality(dev, chip->locality, true); - - return 0; + return tpm_tis_cleanup(udev); } static const struct tpm_ops tpm_tis_spi_ops = { - .open = tpm_tis_spi_open, - .close = tpm_tis_spi_close, + .open = tpm_tis_open, + .close = tpm_tis_close, .get_desc = tpm_tis_get_desc, - .send = tpm_tis_spi_send, - .recv = tpm_tis_spi_recv, - .cleanup = tpm_tis_spi_cleanup, + .send = tpm_tis_send, + .recv = tpm_tis_recv, + .cleanup = tpm_tis_cleanup, }; static const struct tpm_tis_chip_data tpm_tis_std_chip_data = { diff --git a/drivers/tpm/tpm_tis.h b/drivers/tpm/tpm_tis.h index 2a160fe..93f622f 100644 --- a/drivers/tpm/tpm_tis.h +++ b/drivers/tpm/tpm_tis.h @@ -21,6 +21,73 @@ #include <linux/compiler.h> #include <linux/types.h> +/** + * struct tpm_tis_phy_ops - low-level TPM bus operations + */ +struct tpm_tis_phy_ops { + /* read_bytes() - Read a number of bytes from the device + * + * @udev: TPM device + * @addr: offset from device base + * @len: len to read + * @result: data read + * + * @return: 0 on success, negative on failure + */ + int (*read_bytes)(struct udevice *udev, u32 addr, u16 len, + u8 *result); + /* write_bytes() - Read a number of bytes from the device + * + * @udev: TPM device + * @addr: offset from device base + * @len: len to read + * @value: data to write + * + * @return: 0 on success, negative on failure + */ + int (*write_bytes)(struct udevice *udev, u32 addr, u16 len, + const u8 *value); + /* read32() - Read a 32bit value of the device + * + * @udev: TPM device + * @addr: offset from device base + * @result: data read + * + * @return: 0 on success, negative on failure + */ + int (*read32)(struct udevice *udev, u32 addr, u32 *result); + /* write32() - write a 32bit value to the device + * + * @udev: TPM device + * @addr: offset from device base + * @src: data to write + * + * @return: 0 on success, negative on failure + */ + int (*write32)(struct udevice *udev, u32 addr, u32 src); +}; + +enum tis_int_flags { + TPM_GLOBAL_INT_ENABLE = 0x80000000, + TPM_INTF_BURST_COUNT_STATIC = 0x100, + TPM_INTF_CMD_READY_INT = 0x080, + TPM_INTF_INT_EDGE_FALLING = 0x040, + TPM_INTF_INT_EDGE_RISING = 0x020, + TPM_INTF_INT_LEVEL_LOW = 0x010, + TPM_INTF_INT_LEVEL_HIGH = 0x008, + TPM_INTF_LOCALITY_CHANGE_INT = 0x004, + TPM_INTF_STS_VALID_INT = 0x002, + TPM_INTF_DATA_AVAIL_INT = 0x001, +}; + +#define TPM_ACCESS(l) (0x0000 | ((l) << 12)) +#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12)) +#define TPM_STS(l) (0x0018 | ((l) << 12)) +#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12)) +#define TPM_DID_VID(l) (0x0f00 | ((l) << 12)) +#define TPM_RID(l) (0x0f04 | ((l) << 12)) +#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12)) + enum tpm_timeout { TPM_TIMEOUT_MS = 5, TIS_SHORT_TIMEOUT_MS = 750, @@ -43,6 +110,7 @@ struct tpm_chip { u8 rid; unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */ ulong chip_type; + struct tpm_tis_phy_ops *phy_ops; }; struct tpm_input_header { @@ -130,4 +198,72 @@ enum tis_status { }; #endif +/** + * tpm_tis_open - Open the device and request locality 0 + * + * @dev: TPM device + * + * @return: 0 on success, negative on failure + */ +int tpm_tis_open(struct udevice *udev); +/** + * tpm_tis_close - Close the device and release locality + * + * @dev: TPM device + * + * @return: 0 on success, negative on failure + */ +int tpm_tis_close(struct udevice *udev); +/** tpm_tis_cleanup - Get the device in ready state and release locality + * + * @dev: TPM device + * + * @return: always 0 + */ +int tpm_tis_cleanup(struct udevice *udev); +/** + * tpm_tis_send - send data to the device + * + * @dev: TPM device + * @buf: buffer to send + * @len: size of the buffer + * + * @return: number of bytes sent or negative on failure + */ +int tpm_tis_send(struct udevice *udev, const u8 *buf, size_t len); +/** + * tpm_tis_recv_data - Receive data from a device. Wrapper for tpm_tis_recv + * + * @dev: TPM device + * @buf: buffer to copy data + * @size: buffer size + * + * @return: bytes read or negative on failure + */ +int tpm_tis_recv(struct udevice *udev, u8 *buf, size_t count); +/** + * tpm_tis_get_desc - Get the TPM description + * + * @dev: TPM device + * @buf: buffer to fill data + * @size: buffer size + * + * @return: Number of characters written (or would have been written) in buffer + */ +int tpm_tis_get_desc(struct udevice *udev, char *buf, int size); +/** + * tpm_tis_init - inititalize the device + * + * @dev: TPM device + * + * @return: 0 on success, negative on failure + */ +int tpm_tis_init(struct udevice *udev); +/** + * tpm_tis_ops_register - register the PHY ops for the device + * + * @dev: TPM device + * @ops: tpm_tis_phy_ops ops for the device + */ +void tpm_tis_ops_register(struct udevice *udev, struct tpm_tis_phy_ops *ops); #endif diff --git a/drivers/tpm/tpm_tis_infineon.c b/drivers/tpm/tpm_tis_infineon.c index f414e56..525ad72 100644 --- a/drivers/tpm/tpm_tis_infineon.c +++ b/drivers/tpm/tpm_tis_infineon.c @@ -50,10 +50,10 @@ static const char * const chip_name[] = { [UNKNOWN] = "unknown/fallback to slb9635", }; -#define TPM_ACCESS(l) (0x0000 | ((l) << 4)) -#define TPM_STS(l) (0x0001 | ((l) << 4)) -#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4)) -#define TPM_DID_VID(l) (0x0006 | ((l) << 4)) +#define TPM_INFINEON_ACCESS(l) (0x0000 | ((l) << 4)) +#define TPM_INFINEON_STS(l) (0x0001 | ((l) << 4)) +#define TPM_INFINEON_DATA_FIFO(l) (0x0005 | ((l) << 4)) +#define TPM_INFINEON_DID_VID(l) (0x0006 | ((l) << 4)) /* * tpm_tis_i2c_read() - read from TPM register @@ -197,7 +197,7 @@ static int tpm_tis_i2c_check_locality(struct udevice *dev, int loc) u8 buf; int rc; - rc = tpm_tis_i2c_read(dev, TPM_ACCESS(loc), &buf, 1); + rc = tpm_tis_i2c_read(dev, TPM_INFINEON_ACCESS(loc), &buf, 1); if (rc < 0) return rc; @@ -215,12 +215,12 @@ static void tpm_tis_i2c_release_locality(struct udevice *dev, int loc, const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID; u8 buf; - if (tpm_tis_i2c_read(dev, TPM_ACCESS(loc), &buf, 1) < 0) + if (tpm_tis_i2c_read(dev, TPM_INFINEON_ACCESS(loc), &buf, 1) < 0) return; if (force || (buf & mask) == mask) { buf = TPM_ACCESS_ACTIVE_LOCALITY; - tpm_tis_i2c_write(dev, TPM_ACCESS(loc), &buf, 1); + tpm_tis_i2c_write(dev, TPM_INFINEON_ACCESS(loc), &buf, 1); } } @@ -240,7 +240,7 @@ static int tpm_tis_i2c_request_locality(struct udevice *dev, int loc) return rc; } - rc = tpm_tis_i2c_write(dev, TPM_ACCESS(loc), &buf, 1); + rc = tpm_tis_i2c_write(dev, TPM_INFINEON_ACCESS(loc), &buf, 1); if (rc) { debug("%s: Failed to write to TPM: %d\n", __func__, rc); return rc; @@ -271,7 +271,7 @@ static u8 tpm_tis_i2c_status(struct udevice *dev) /* NOTE: Since i2c read may fail, return 0 in this case --> time-out */ u8 buf; - if (tpm_tis_i2c_read(dev, TPM_STS(chip->locality), &buf, 1) < 0) + if (tpm_tis_i2c_read(dev, TPM_INFINEON_STS(chip->locality), &buf, 1) < 0) return 0; else return buf; @@ -286,7 +286,7 @@ static int tpm_tis_i2c_ready(struct udevice *dev) u8 buf = TPM_STS_COMMAND_READY; debug("%s\n", __func__); - rc = tpm_tis_i2c_write_long(dev, TPM_STS(chip->locality), &buf, 1); + rc = tpm_tis_i2c_write_long(dev, TPM_INFINEON_STS(chip->locality), &buf, 1); if (rc) debug("%s: rc=%d\n", __func__, rc); @@ -306,7 +306,7 @@ static ssize_t tpm_tis_i2c_get_burstcount(struct udevice *dev) stop = chip->timeout_d; do { /* Note: STS is little endian */ - addr = TPM_STS(chip->locality) + 1; + addr = TPM_INFINEON_STS(chip->locality) + 1; if (tpm_tis_i2c_read(dev, addr, buf, 3) < 0) burstcnt = 0; else @@ -360,7 +360,7 @@ static int tpm_tis_i2c_recv_data(struct udevice *dev, u8 *buf, size_t count) if (burstcnt > (count - size)) burstcnt = count - size; - rc = tpm_tis_i2c_read(dev, TPM_DATA_FIFO(chip->locality), + rc = tpm_tis_i2c_read(dev, TPM_INFINEON_DATA_FIFO(chip->locality), &(buf[size]), burstcnt); if (rc == 0) size += burstcnt; @@ -462,7 +462,7 @@ static int tpm_tis_i2c_send(struct udevice *dev, const u8 *buf, size_t len) burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION_LEN; #endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */ - rc = tpm_tis_i2c_write(dev, TPM_DATA_FIFO(chip->locality), + rc = tpm_tis_i2c_write(dev, TPM_INFINEON_DATA_FIFO(chip->locality), &(buf[count]), burstcnt); if (rc == 0) count += burstcnt; @@ -482,7 +482,7 @@ static int tpm_tis_i2c_send(struct udevice *dev, const u8 *buf, size_t len) } /* Go and do it */ - rc = tpm_tis_i2c_write(dev, TPM_STS(chip->locality), &sts, 1); + rc = tpm_tis_i2c_write(dev, TPM_INFINEON_STS(chip->locality), &sts, 1); if (rc < 0) return rc; debug("%s: done, rc=%d\n", __func__, rc); @@ -525,7 +525,7 @@ static int tpm_tis_i2c_init(struct udevice *dev) return rc; /* Read four bytes from DID_VID register */ - if (tpm_tis_i2c_read(dev, TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) { + if (tpm_tis_i2c_read(dev, TPM_INFINEON_DID_VID(0), (uchar *)&vendor, 4) < 0) { tpm_tis_i2c_release_locality(dev, 0, 1); return -EIO; } @@ -583,7 +583,7 @@ static int tpm_tis_i2c_close(struct udevice *dev) return 0; } -static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size) +static int tpm_tis_i2c_get_desc(struct udevice *dev, char *buf, int size) { struct tpm_chip *chip = dev_get_priv(dev); @@ -615,7 +615,7 @@ static int tpm_tis_i2c_probe(struct udevice *dev) static const struct tpm_ops tpm_tis_i2c_ops = { .open = tpm_tis_i2c_open, .close = tpm_tis_i2c_close, - .get_desc = tpm_tis_get_desc, + .get_desc = tpm_tis_i2c_get_desc, .send = tpm_tis_i2c_send, .recv = tpm_tis_i2c_recv, .cleanup = tpm_tis_i2c_cleanup, diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c index 003c0d8..13a133d 100644 --- a/drivers/tpm/tpm_tis_lpc.c +++ b/drivers/tpm/tpm_tis_lpc.c @@ -443,7 +443,7 @@ static int tpm_tis_lpc_open(struct udevice *dev) return 0; } -static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size) +static int tpm_tis_lpc_get_desc(struct udevice *dev, char *buf, int size) { ulong chip_type = dev_get_driver_data(dev); @@ -458,7 +458,7 @@ static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size) static const struct tpm_ops tpm_tis_lpc_ops = { .open = tpm_tis_lpc_open, .close = tpm_tis_lpc_close, - .get_desc = tpm_tis_get_desc, + .get_desc = tpm_tis_lpc_get_desc, .send = tis_senddata, .recv = tis_readresponse, }; diff --git a/include/tpm-v2.h b/include/tpm-v2.h index 947458b..ceff7d2 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -396,6 +396,7 @@ enum { TPM_STS_DATA_EXPECT = 1 << 3, TPM_STS_SELF_TEST_DONE = 1 << 2, TPM_STS_RESPONSE_RETRY = 1 << 1, + TPM_STS_READ_ZERO = 0x23 }; enum { diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 586f73a..189e4a5 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -1452,8 +1452,8 @@ static efi_status_t tcg2_measure_boot_variable(struct udevice *dev) boot_order = efi_get_var(var_name, &efi_global_variable_guid, &var_data_size); if (!boot_order) { - ret = EFI_NOT_FOUND; - goto error; + /* If "BootOrder" is not defined, skip the boot variable measurement */ + return EFI_SUCCESS; } ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2, var_name, |