From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 358C5C433F5 for ; Sat, 13 Nov 2021 18:15:48 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 85EB760F46 for ; Sat, 13 Nov 2021 18:15:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 85EB760F46 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9738D83300; Sat, 13 Nov 2021 19:15:23 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="W3w4Thpq"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4F149831EF; Sat, 13 Nov 2021 19:14:51 +0100 (CET) Received: from mail-ua1-x92c.google.com (mail-ua1-x92c.google.com [IPv6:2607:f8b0:4864:20::92c]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id AD35883072 for ; Sat, 13 Nov 2021 19:14:38 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@google.com Received: by mail-ua1-x92c.google.com with SMTP id y5so7849587ual.7 for ; Sat, 13 Nov 2021 10:14:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=YbJspt4lrioZcfVfMSaaF81gI8OvI0xnH+8pJepfAPU=; b=W3w4ThpqR7e/Qs8gUFe6BcTcObKmpWVYOtdlo6KT21jVOSvT8Wb17QZRgL5D9JwwJW /AayGXZ4uS695DEwIuMTZ2kBMlrvxjFtD64lIJY48WrFAZ4M1JOYo+BQNxIMUCcgVust /Oafh4Hehga7WzpPLEnrOKfcUWf7FyisXf7xU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=YbJspt4lrioZcfVfMSaaF81gI8OvI0xnH+8pJepfAPU=; b=rSZTtP4W1tIxzIJV7lGY4afRvGsj5+Jb+NqkwYT14Xm75tlqPuxBnpa+p9lyfaTLoC /z+x5O1VxrUb5hLrSicfH7m/AQTtez28bH+jAdfmK6tSfxubgtui/r87U5vk5cm85Lle nwqUsujT26MC9hEZHPARhPkkcM19BJO6s2lKPcs9fpMqonbUiWzsvq1q8LD+miGVNiOG 4G8xH63rn/L8ItsDD9dVceJw4SJ6LGhTwQBgKhl8m7lPLFZTYVitXDtHHsY+c5zEqAPS 6iqf/kfcU+UhtBEb1HIn5M6wgFNCUhOi8aMNPbRvMWCcYRU76jeJB422h/63RMskXSf1 LJZg== X-Gm-Message-State: AOAM530Cf+8CpCZxa2Rp2lsA/vyom53Ejq8pwXCWCksBNNcBTCxrxAK0 OPmlp1+PkSo5OoNgmT7x10ZHY8G4dh3z/IYr4cHeuQ== X-Google-Smtp-Source: ABdhPJyauAQSap65nGIxRSCsj+ZogPM6BUr63qF52QTr6Zy5Z44p5x9gIIZA60riueXEdapIYJNeXScq7ZM+fx7MiZI= X-Received: by 2002:a67:db0b:: with SMTP id z11mr23349954vsj.59.1636827277195; Sat, 13 Nov 2021 10:14:37 -0800 (PST) MIME-Version: 1.0 References: <20211109070223.76456-1-ilias.apalodimas@linaro.org> <20211109070223.76456-4-ilias.apalodimas@linaro.org> In-Reply-To: <20211109070223.76456-4-ilias.apalodimas@linaro.org> From: Simon Glass Date: Sat, 13 Nov 2021 11:14:24 -0700 Message-ID: Subject: Re: [PATCH 3/8 v7] tpm2: Introduce TIS tpm core To: Ilias Apalodimas Cc: u-boot@lists.denx.de, trini@konsulko.com, Rick Chen , Sean Anderson , Heinrich Schuchardt , Masahisa Kojima Content-Type: text/plain; charset="UTF-8" X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean On Tue, 9 Nov 2021 at 00:02, Ilias Apalodimas wrote: > > There's a lot of code duplication in U-Boot right now. All the TPM TIS > compatible drivers we have at the moment have their own copy of a TIS > implementation. > > So let's create a common layer which implements the core TIS functions. > Any driver added from now own, which is compatible with the TIS spec, will > only have to provide the underlying bus communication mechanisms. > > Signed-off-by: Ilias Apalodimas > --- > drivers/tpm/tpm2_tis_core.c | 463 ++++++++++++++++++++++++++++++++++++ > drivers/tpm/tpm_tis.h | 136 +++++++++++ > include/tpm-v2.h | 1 + > 3 files changed, 600 insertions(+) > create mode 100644 drivers/tpm/tpm2_tis_core.c > > diff --git a/drivers/tpm/tpm2_tis_core.c b/drivers/tpm/tpm2_tis_core.c > new file mode 100644 > index 000000000000..ec8c730fe906 > --- /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 > +#include > +#include > +#include > +#include > +#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/tpm_tis.h b/drivers/tpm/tpm_tis.h > index 2a160fe05c9a..93f622f29104 100644 > --- a/drivers/tpm/tpm_tis.h > +++ b/drivers/tpm/tpm_tis.h > @@ -21,6 +21,73 @@ > #include > #include > > +/** > + * 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/include/tpm-v2.h b/include/tpm-v2.h > index 947458b0bdfd..ceff7d245ed2 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 { > -- > 2.33.1 >