[Skiboot] [PATCH v2 13/31] libstb/drivers/tpm_i2c_nuvoton.c: check command ready
Stewart Smith
stewart at linux.vnet.ibm.com
Wed Oct 5 15:50:23 AEDT 2016
Claudio Carvalho <cclaudio at linux.vnet.ibm.com> writes:
> This adds the 1/5 step performed by the TPM I2C Nuvoton driver to
> transmit a command to the TPM device. In this step the driver
> checks if the TPM device is ready to receive a new command.
>
> Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
> ---
> libstb/drivers/Makefile.inc | 2 +-
> libstb/drivers/tpm_i2c_nuvoton.c | 134 +++++++++++++++++++++++++++++++++++++++
> libstb/status_codes.h | 3 +
> 3 files changed, 138 insertions(+), 1 deletion(-)
> create mode 100644 libstb/drivers/tpm_i2c_nuvoton.c
>
> diff --git a/libstb/drivers/Makefile.inc b/libstb/drivers/Makefile.inc
> index f0f3d70..2817378 100644
> --- a/libstb/drivers/Makefile.inc
> +++ b/libstb/drivers/Makefile.inc
> @@ -4,7 +4,7 @@ DRIVERS_DIR = libstb/drivers
>
> SUBDIRS += $(DRIVERS_DIR)
>
> -DRIVERS_SRCS = romcode.c tpm_i2c_interface.c
> +DRIVERS_SRCS = romcode.c tpm_i2c_interface.c tpm_i2c_nuvoton.c
> DRIVERS_OBJS = $(DRIVERS_SRCS:%.c=%.o)
> DRIVERS = $(DRIVERS_DIR)/built-in.o
>
> diff --git a/libstb/drivers/tpm_i2c_nuvoton.c b/libstb/drivers/tpm_i2c_nuvoton.c
> new file mode 100644
> index 0000000..ead0f15
> --- /dev/null
> +++ b/libstb/drivers/tpm_i2c_nuvoton.c
> @@ -0,0 +1,134 @@
> +/* Copyright 2013-2016 IBM Corp.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> + * implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +/****************************************************************************
> + * THIS DRIVER WAS DEVELOPED BASED ON:
> + * https://github.com/open-power/hostboot/blob/master-p8/src/usr/i2c/tpmdd.C
> + ****************************************************************************/
> +
> +#include <timebase.h>
> +#include <skiboot.h>
> +#include <i2c.h>
> +#include "../status_codes.h"
> +#include "../tpm_chip.h"
> +#include "tpm_i2c_interface.h"
> +
> +//#define DBG(fmt, ...) prlog(PR_DEBUG, fmt, ##__VA_ARGS__)
> +#define DBG(fmt, ...)
> +
> +/*
> + * Timings between various states or transitions within the interface protocol
> + * as defined in the TCG PC Client Platform TPM Profile specification, Revision
> + * 00.43.
> + */
> +#define TCG_PTP_TIMEOUT_B 2000
> +
> +/* I2C interface offsets */
> +#define NUVOTON_TPM_STS 0x00
> +
> +/* Bit masks for the TPM STATUS register */
> +#define TCG_PTP_STS_COMMAND_READY 0x40
> +
> +/* TPM Driver values */
> +#define TPM_TIMEOUT_INTERVAL 10
> +
> +static struct tpm_dev *tpm_device = NULL;
> +
> +static int tpm_status_write_byte(uint8_t byte)
> +{
> + uint8_t value = byte;
> + return tpm_i2c_request_send(tpm_device->bus_id, tpm_device->xscom_base,
> + SMBUS_WRITE, NUVOTON_TPM_STS, 1, &value,
> + sizeof(value));
> +}
> +
> +static bool tpm_is_command_ready(int* rc)
> +{
> + uint8_t value = 0;
> + *rc = tpm_i2c_request_send(tpm_device->bus_id, tpm_device->xscom_base,
> + SMBUS_READ, NUVOTON_TPM_STS, 1, &value,
> + sizeof(value));
> + if (*rc == 0 &&
> + ((value & TCG_PTP_STS_COMMAND_READY) == TCG_PTP_STS_COMMAND_READY)){
> + DBG("---- TPM is command ready\n");
> + return true;
> + }
> + return false;
> +}
> +
> +static int tpm_poll_for_command_ready(void)
> +{
> + int rc, polls, delay;
> + /*
> + * The first write to command ready may just abort an
> + * outstanding command, so we poll twice
> + */
> + for (polls=0; polls<2; polls++) {
> + rc = tpm_status_write_byte(TCG_PTP_STS_COMMAND_READY);
> + if (rc < 0) {
> + return rc;
> + }
> + for (delay = 0; delay < TCG_PTP_TIMEOUT_B;
> + delay += TPM_TIMEOUT_INTERVAL) {
> + if (tpm_is_command_ready(&rc))
> + return rc;
> + time_wait_ms(TPM_TIMEOUT_INTERVAL);
> + }
> + DBG("--- Command ready polling, delay %d/%d\n",
> + delay, TCG_PTP_TIMEOUT_B);
> + }
> + /**
> + * @fwts-label TPMCommandReadyBitTimeout
> + * @fwts-advice The command ready bit of the tpm status register is
> + * taking longer to be settled. Either the wait time need to be
> + * increased or the TPM device is not functional.
> + */
> + prlog(PR_ERR, "TPM: command ready polling timeout\n");
> + return STB_TPM_TIMEOUT;
> +}
> +
> +static int tpm_transmit(struct tpm_dev *dev, uint8_t* buf, size_t cmdlen,
> + size_t* buflen)
Unused parameters buf, cmdlen, buflen cause build to fail:
as does defining tpm_transit without using it.
I'm thinking that the individual commits for the nouvoton driver can
just be squashed into a single commit.
--
Stewart Smith
OPAL Architect, IBM.
More information about the Skiboot
mailing list