[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