/* SPDX-License-Identifier: BSD-3-Clause */
/* This is a driver for a SPI interfaced TPM2 device.
 *
 * It assumes that the required SPI interface has been initialized before the
 * driver is started. A 'struct spi_slave' pointer passed at initialization is
 * used to direct traffic to the correct SPI interface. This driver does not
 * provide a way to instantiate multiple TPM devices. Also, to keep things
 * simple, the driver unconditionally uses of TPM locality zero.
 *
 * References to documentation are based on the TCG issued "TPM Profile (PTP)
 * Specification Revision 00.43".
 */

#include <assert.h>
#include <commonlib/endian.h>
#include <console/console.h>
#include <delay.h>
#include <drivers/tpm/cr50.h>
#include <endian.h>
#include <security/tpm/tis.h>
#include <string.h>
#include <timer.h>
#include <types.h>

#include "tpm.h"

/* Assorted TPM2 registers for interface type FIFO. */
#define TPM_ACCESS_REG    (TPM_LOCALITY_0_SPI_BASE + 0)
#define TPM_STS_REG       (TPM_LOCALITY_0_SPI_BASE + 0x18)
#define TPM_DATA_FIFO_REG (TPM_LOCALITY_0_SPI_BASE + 0x24)
#define TPM_INTF_ID_REG   (TPM_LOCALITY_0_SPI_BASE + 0x30)
#define TPM_DID_VID_REG   (TPM_LOCALITY_0_SPI_BASE + 0xf00)
#define TPM_RID_REG       (TPM_LOCALITY_0_SPI_BASE + 0xf04)
#define TPM_FW_VER	  (TPM_LOCALITY_0_SPI_BASE + 0xf90)
#define CR50_BOARD_CFG     (TPM_LOCALITY_0_SPI_BASE + 0xfe0)

#define CR50_TIMEOUT_INIT_MS 30000 /* Very long timeout for TPM init */

/* SPI slave structure for TPM device. */
static struct spi_slave spi_slave;

/* Cached TPM device identification. */
static struct tpm2_info tpm_info;

/*
 * TODO(vbendeb): make CONFIG(DEBUG_TPM) an int to allow different level of
 * debug traces. Right now it is either 0 or 1.
 */
static const int debug_level_ = CONFIG(DEBUG_TPM);

/*
 * SPI frame header for TPM transactions is 4 bytes in size, it is described
 * in section "6.4.6 Spi Bit Protocol".
 */
typedef struct {
	unsigned char body[4];
} spi_frame_header;

void tpm2_get_info(struct tpm2_info *info)
{
	*info = tpm_info;
}

/*
 * Each TPM2 SPI transaction starts the same: CS is asserted, the 4 byte
 * header is sent to the TPM, the master waits til TPM is ready to continue.
 */
static enum cb_err start_transaction(int read_write, size_t bytes, unsigned int addr)
{
	spi_frame_header header, header_resp;
	uint8_t byte;
	int i;
	int ret;
	struct stopwatch sw;
	static int tpm_sync_needed;
	static struct stopwatch wake_up_sw;

	if (CONFIG(TPM_GOOGLE)) {
		/*
		 * First Cr50 access in each coreboot stage where TPM is used will be
		 * prepended by a wake up pulse on the CS line.
		 */
		int wakeup_needed = 1;

		/* Wait for TPM to finish previous transaction if needed */
		if (tpm_sync_needed) {
			if (cr50_wait_tpm_ready() != CB_SUCCESS)
				printk(BIOS_ERR, "Timeout waiting for TPM IRQ!\n");

			/*
			 * During the first invocation of this function on each stage
			 * this if () clause code does not run (as tpm_sync_needed
			 * value is zero), during all following invocations the
			 * stopwatch below is guaranteed to be started.
			 */
			if (!stopwatch_expired(&wake_up_sw))
				wakeup_needed = 0;
		} else {
			tpm_sync_needed = 1;
		}

		if (wakeup_needed) {
			/* Just in case Cr50 is asleep. */
			spi_claim_bus(&spi_slave);
			udelay(1);
			spi_release_bus(&spi_slave);
			udelay(100);
		}

		/*
		 * The Cr50 on H1 does not go to sleep for 1 second after any
		 * SPI slave activity, let's be conservative and limit the
		 * window to 900 ms.
		 */
		stopwatch_init_msecs_expire(&wake_up_sw, 900);
	}

	/*
	 * The first byte of the frame header encodes the transaction type
	 * (read or write) and transfer size (set to length - 1), limited to
	 * 64 bytes.
	 */
	header.body[0] = (read_write ? 0x80 : 0) | 0x40 | (bytes - 1);

	/* The rest of the frame header is the TPM register address. */
	for (i = 0; i < 3; i++)
		header.body[i + 1] = (addr >> (8 * (2 - i))) & 0xff;

	/* CS assert wakes up the slave. */
	spi_claim_bus(&spi_slave);

	/*
	 * The TCG TPM over SPI specification introduces the notion of SPI
	 * flow control (Section "6.4.5 Flow Control").
	 *
	 * Again, the slave (TPM device) expects each transaction to start
	 * with a 4 byte header transmitted by master. The header indicates if
	 * the master needs to read or write a register, and the register
	 * address.
	 *
	 * If the slave needs to stall the transaction (for instance it is not
	 * ready to send the register value to the master), it sets the MOSI
	 * line to 0 during the last clock of the 4 byte header. In this case
	 * the master is supposed to start polling the SPI bus, one byte at
	 * time, until the last bit in the received byte (transferred during
	 * the last clock of the byte) is set to 1.
	 *
	 * Due to some SPI controllers' shortcomings (Rockchip comes to
	 * mind...) we transmit the 4 byte header without checking the byte
	 * transmitted by the TPM during the transaction's last byte.
	 *
	 * We know that cr50 is guaranteed to set the flow control bit to 0
	 * during the header transfer. Real TPM2 are fast enough to not require
	 * to stall the master. They might still use this feature, so test the
	 * last bit after shifting in the address bytes.
	 * crosbug.com/p/52132 has been opened to track this.
	 */

	header_resp.body[3] = 0;
	if (CONFIG(TPM_GOOGLE))
		ret = spi_xfer(&spi_slave, header.body, sizeof(header.body), NULL, 0);
	else
		ret = spi_xfer(&spi_slave, header.body, sizeof(header.body),
			       header_resp.body, sizeof(header_resp.body));
	if (ret) {
		printk(BIOS_ERR, "SPI-TPM: transfer error\n");
		spi_release_bus(&spi_slave);
		return CB_ERR;
	}

	if (header_resp.body[3] & 1)
		return CB_SUCCESS;

	/*
	 * Now poll the bus until TPM removes the stall bit. Give it up to 100
	 * ms to sort it out - it could be saving stuff in nvram at some point.
	 */
	stopwatch_init_msecs_expire(&sw, 100);
	do {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "TPM flow control failure\n");
			spi_release_bus(&spi_slave);
			return CB_ERR;
		}
		spi_xfer(&spi_slave, NULL, 0, &byte, 1);
	} while (!(byte & 1));

	return CB_SUCCESS;
}

/*
 * Print out the contents of a buffer, if debug is enabled. Skip registers
 * other than FIFO, unless debug_level_ is 2.
 */
static void trace_dump(const char *prefix, uint32_t reg,
		       size_t bytes, const uint8_t *buffer,
		       int force)
{
	static char prev_prefix;
	static unsigned int prev_reg;
	static int current_char;
	const int BYTES_PER_LINE = 32;

	if (!force) {
		if (!debug_level_)
			return;

		if ((debug_level_ < 2) && (reg != TPM_DATA_FIFO_REG))
			return;
	}

	/*
	 * Do not print register address again if the last dump print was for
	 * that register.
	 */
	if (prev_prefix != *prefix || (prev_reg != reg)) {
		prev_prefix = *prefix;
		prev_reg = reg;
		printk(BIOS_DEBUG, "\n%s %2.2x:", prefix, reg);
		current_char = 0;
	}

	if ((reg != TPM_DATA_FIFO_REG) && (bytes == 4)) {
		/*
		 * This must be a regular register address, print the 32 bit
		 * value.
		 */
		printk(BIOS_DEBUG, " %8.8x", *(const uint32_t *)buffer);
	} else {
		int i;

		/*
		 * Data read from or written to FIFO or not in 4 byte
		 * quantities is printed byte at a time.
		 */
		for (i = 0; i < bytes; i++) {
			if (current_char &&
				!(current_char % BYTES_PER_LINE)) {
				printk(BIOS_DEBUG, "\n     ");
				current_char = 0;
			}
			(current_char)++;
			printk(BIOS_DEBUG, " %2.2x", buffer[i]);
		}
	}
}

/*
 * Once transaction is initiated and the TPM indicated that it is ready to go,
 * write the actual bytes to the register.
 */
static void write_bytes(const void *buffer, size_t bytes)
{
	spi_xfer(&spi_slave, buffer, bytes, NULL, 0);
}

/*
 * Once transaction is initiated and the TPM indicated that it is ready to go,
 * read the actual bytes from the register.
 */
static void read_bytes(void *buffer, size_t bytes)
{
	spi_xfer(&spi_slave, NULL, 0, buffer, bytes);
}

/*
 * To write a register, start transaction, transfer data to the TPM, deassert
 * CS when done.
 */
static enum cb_err tpm2_write_reg(unsigned int reg_number, const void *buffer, size_t bytes)
{
	trace_dump("W", reg_number, bytes, buffer, 0);
	if (start_transaction(false, bytes, reg_number) != CB_SUCCESS)
		return CB_ERR;
	write_bytes(buffer, bytes);
	spi_release_bus(&spi_slave);
	return CB_SUCCESS;
}

/*
 * To read a register, start transaction, transfer data from the TPM, deassert
 * CS when done.
 *
 * In case of failure zero out the user buffer.
 */
static enum cb_err tpm2_read_reg(unsigned int reg_number, void *buffer, size_t bytes)
{
	if (start_transaction(true, bytes, reg_number) != CB_SUCCESS) {
		memset(buffer, 0, bytes);
		return CB_ERR;
	}
	read_bytes(buffer, bytes);
	spi_release_bus(&spi_slave);
	trace_dump("R", reg_number, bytes, buffer, 0);
	return CB_SUCCESS;
}

/*
 * Status register is accessed often, wrap reading and writing it into
 * dedicated functions.
 */
static enum cb_err read_tpm_sts(uint32_t *status)
{
	return tpm2_read_reg(TPM_STS_REG, status, sizeof(*status));
}

static enum cb_err __must_check write_tpm_sts(uint32_t status)
{
	return tpm2_write_reg(TPM_STS_REG, &status, sizeof(status));
}

/*
 * The TPM may limit the transaction bytes count (burst count) below the 64
 * bytes max. The current value is available as a field of the status
 * register.
 */
static uint32_t get_burst_count(void)
{
	uint32_t status;

	read_tpm_sts(&status);
	return (status & TPM_STS_BURST_COUNT_MASK) >> TPM_STS_BURST_COUNT_SHIFT;
}

static uint8_t tpm2_read_access_reg(void)
{
	uint8_t access;
	tpm2_read_reg(TPM_ACCESS_REG, &access, sizeof(access));
	/* We do not care about access establishment bit state. Ignore it. */
	return access & ~TPM_ACCESS_ESTABLISHMENT;
}

static void tpm2_write_access_reg(uint8_t cmd)
{
	/* Writes to access register can set only 1 bit at a time. */
	assert(!(cmd & (cmd - 1)));

	tpm2_write_reg(TPM_ACCESS_REG, &cmd, sizeof(cmd));
}

static enum cb_err tpm2_claim_locality(void)
{
	uint8_t access;
	struct stopwatch sw;

	/*
	 * Locality is released by TPM reset.
	 *
	 * If locality is taken at this point, this could be due to the fact
	 * that the TPM is performing a long operation and has not processed
	 * reset request yet. We'll wait up to CR50_TIMEOUT_INIT_MS and see if
	 * it releases locality when reset is processed.
	 */
	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_INIT_MS);
	do {
		access = tpm2_read_access_reg();
		if (access & TPM_ACCESS_ACTIVE_LOCALITY) {
			/*
			 * Don't bombard the chip with traffic, let it keep
			 * processing the command.
			 */
			mdelay(2);
			continue;
		}

		/*
		 * Ok, the locality is free, TPM must be reset, let's claim
		 * it.
		 */

		tpm2_write_access_reg(TPM_ACCESS_REQUEST_USE);
		access = tpm2_read_access_reg();
		if (access != (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
			break;
		}

		printk(BIOS_INFO, "TPM ready after %lld ms\n",
		       stopwatch_duration_msecs(&sw));

		return CB_SUCCESS;
	} while (!stopwatch_expired(&sw));

	printk(BIOS_ERR,
	       "Failed to claim locality 0 after %lld ms, status: %#x\n",
	       stopwatch_duration_msecs(&sw), access);

	return CB_ERR;
}

/* Device/vendor ID values of the TPM devices this driver supports. */
static const uint32_t supported_did_vids[] = {
	0x00281ae0,  /* H1 based Cr50 security chip. */
	0x504a6666,  /* H1D3C based Ti50 security chip. */
	0x0000104a   /* ST33HTPH2E32 */
};

tpm_result_t tpm2_init(struct spi_slave *spi_if)
{
	uint32_t did_vid, status, intf_id;
	uint8_t cmd;
	int retries;

	memcpy(&spi_slave, spi_if, sizeof(*spi_if));

	/* Clear any pending IRQs. */
	if (CONFIG(TPM_GOOGLE))
		cr50_plat_irq_status();

	/*
	 * 150 ms should be enough to synchronize with the TPM even under the
	 * worst nested reset request conditions. In vast majority of cases
	 * there would be no wait at all.
	 */
	printk(BIOS_INFO, "Probing TPM: ");
	for (retries = 15; retries > 0; retries--) {
		int i;

		/* In case of failure to read div_vid is set to zero. */
		tpm2_read_reg(TPM_DID_VID_REG, &did_vid, sizeof(did_vid));

		for (i = 0; i < ARRAY_SIZE(supported_did_vids); i++)
			if (did_vid == supported_did_vids[i])
				break; /* TPM is up and ready. */

		if (i < ARRAY_SIZE(supported_did_vids))
			break;

		/* TPM might be resetting, let's retry in a bit. */
		mdelay(10);
		printk(BIOS_INFO, ".");
	}

	if (!retries) {
		printk(BIOS_ERR, "\n%s: Failed to connect to the TPM\n",
		       __func__);
		return TPM_CB_FAIL;
	}

	printk(BIOS_INFO, " done!\n");

	/* Google TPMs haven't always been 100% accurate in reflecting the spec (particularly
	 * on older versions) and are always TPM 2.0. */
	if (!CONFIG(TPM_GOOGLE)) {
		if (tpm2_read_reg(TPM_INTF_ID_REG, &intf_id, sizeof(intf_id)) != CB_SUCCESS) {
			printk(BIOS_ERR, "\n%s: Failed to read interface ID register\n",
			       __func__);
			return TPM_CB_FAIL;
		}
		if ((be32toh(intf_id) & 0xF) == 0xF) {
			printk(BIOS_DEBUG, "\n%s: Not a TPM2 device\n", __func__);
			return TPM_CB_FAIL;
		}
	}

	// FIXME: Move this to tpm_setup()
	if (tpm_first_access_this_boot())
		/*
		 * Claim locality 0, do it only during the first
		 * initialization after reset.
		 */
		if (tpm2_claim_locality() != CB_SUCCESS)
			return TPM_CB_FAIL;

	if (read_tpm_sts(&status) != CB_SUCCESS) {
		printk(BIOS_ERR, "Reading status reg failed\n");
		return TPM_CB_FAIL;
	}
	if ((status & TPM_STS_FAMILY_MASK) != TPM_STS_FAMILY_TPM_2_0) {
		printk(BIOS_ERR, "unexpected TPM family value, status: %#x\n",
		       status);
		return TPM_CB_FAIL;
	}

	/*
	 * Locality claimed, read the revision value and set up the tpm_info
	 * structure.
	 */
	tpm2_read_reg(TPM_RID_REG, &cmd, sizeof(cmd));
	tpm_info.vendor_id = did_vid & 0xffff;
	tpm_info.device_id = did_vid >> 16;
	tpm_info.revision = cmd;

	printk(BIOS_INFO, "Connected to device vid:did:rid of %4.4x:%4.4x:%2.2x\n",
	       tpm_info.vendor_id, tpm_info.device_id, tpm_info.revision);

	/* Do some GSC-specific things here. */
	if (CONFIG(TPM_GOOGLE)) {
		if (tpm_first_access_this_boot()) {
			/* This is called for the side-effect of printing the firmware version
			   string */
			cr50_get_firmware_version(NULL);
                        cr50_set_board_cfg();
		}
	}
	return TPM_SUCCESS;
}

/*
 * This is in seconds, certain TPM commands, like key generation, can take
 * long time to complete.
 */
#define MAX_STATUS_TIMEOUT 120
static enum cb_err wait_for_status(uint32_t status_mask, uint32_t status_expected)
{
	uint32_t status;
	struct stopwatch sw;

	stopwatch_init_usecs_expire(&sw, MAX_STATUS_TIMEOUT * 1000 * 1000);
	do {
		udelay(1000);
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "failed to get expected status %#x\n",
			       status_expected);
			return CB_ERR;
		}
		read_tpm_sts(&status);
	} while ((status & status_mask) != status_expected);

	return CB_SUCCESS;
}

enum fifo_transfer_direction {
	fifo_transmit = 0,
	fifo_receive = 1
};

/* Union allows to avoid casting away 'const' on transmit buffers. */
union fifo_transfer_buffer {
	uint8_t *rx_buffer;
	const uint8_t *tx_buffer;
};

/*
 * Transfer requested number of bytes to or from TPM FIFO, accounting for the
 * current burst count value.
 */
static enum cb_err __must_check fifo_transfer(size_t transfer_size,
					   union fifo_transfer_buffer buffer,
					   enum fifo_transfer_direction direction)
{
	size_t transaction_size;
	size_t burst_count;
	size_t handled_so_far = 0;

	do {
		do {
			/* Could be zero when TPM is busy. */
			burst_count = get_burst_count();
		} while (!burst_count);

		transaction_size = transfer_size - handled_so_far;
		transaction_size = MIN(transaction_size, burst_count);

		/*
		 * The SPI frame header does not allow to pass more than 64
		 * bytes.
		 */
		transaction_size = MIN(transaction_size, 64);

		if (direction == fifo_receive) {
			if (tpm2_read_reg(TPM_DATA_FIFO_REG,
					  buffer.rx_buffer + handled_so_far,
					  transaction_size) != CB_SUCCESS)
				return CB_ERR;
		} else {
			if (tpm2_write_reg(TPM_DATA_FIFO_REG,
					   buffer.tx_buffer + handled_so_far,
					   transaction_size) != CB_SUCCESS)
				return CB_ERR;
		}

		handled_so_far += transaction_size;

	} while (handled_so_far != transfer_size);

	return CB_SUCCESS;
}

size_t tpm2_process_command(const void *tpm2_command, size_t command_size,
			    void *tpm2_response, size_t max_response)
{
	uint32_t status;
	uint32_t expected_status_bits;
	size_t payload_size;
	size_t bytes_to_go;
	const uint8_t *cmd_body = tpm2_command;
	uint8_t *rsp_body = tpm2_response;
	union fifo_transfer_buffer fifo_buffer;
	const int HEADER_SIZE = 6;

	/* Do not try using an uninitialized TPM. */
	if (!tpm_info.vendor_id)
		return 0;

	/* Skip the two byte tag, read the size field. */
	payload_size = read_be32(cmd_body + 2);

	/* Sanity check. */
	if (payload_size != command_size) {
		printk(BIOS_ERR,
		       "Command size mismatch: encoded %zd != requested %zd\n",
		       payload_size, command_size);
		trace_dump("W", TPM_DATA_FIFO_REG, command_size, cmd_body, 1);
		printk(BIOS_DEBUG, "\n");
		return 0;
	}

	/* Let the TPM know that the command is coming. */
	if (write_tpm_sts(TPM_STS_COMMAND_READY) != CB_SUCCESS) {
		printk(BIOS_ERR, "TPM_STS_COMMAND_READY failed\n");
		return 0;
	}

	/*
	 * TPM commands and responses written to and read from the FIFO
	 * register (0x24) are datagrams of variable size, prepended by a 6
	 * byte header.
	 *
	 * The specification description of the state machine is a bit vague,
	 * but from experience it looks like there is no need to wait for the
	 * sts.expect bit to be set, at least with the 9670 and cr50 devices.
	 * Just write the command into FIFO, making sure not to exceed the
	 * burst count or the maximum PDU size, whatever is smaller.
	 */
	fifo_buffer.tx_buffer = cmd_body;
	if (fifo_transfer(command_size, fifo_buffer, fifo_transmit) != CB_SUCCESS) {
		printk(BIOS_ERR, "fifo_transfer %zd command bytes failed\n",
		       command_size);
		return 0;
	}

	/* Now tell the TPM it can start processing the command. */
	if (write_tpm_sts(TPM_STS_GO) != CB_SUCCESS) {
		printk(BIOS_ERR, "TPM_STS_GO failed\n");
		return 0;
	}

	/* Now wait for it to report that the response is ready. */
	expected_status_bits = TPM_STS_VALID | TPM_STS_DATA_AVAIL;
	if (wait_for_status(expected_status_bits, expected_status_bits) != CB_SUCCESS) {
		/*
		 * If timed out, which should never happen, let's at least
		 * print out the offending command.
		 */
		trace_dump("W", TPM_DATA_FIFO_REG, command_size, cmd_body, 1);
		printk(BIOS_DEBUG, "\n");
		return 0;
	}

	/*
	 * The response is ready, let's read it. First we read the FIFO
	 * payload header, to see how much data to expect. The response header
	 * size is fixed to six bytes, the total payload size is stored in
	 * network order in the last four bytes.
	 */
	tpm2_read_reg(TPM_DATA_FIFO_REG, rsp_body, HEADER_SIZE);

	/* Find out the total payload size, skipping the two byte tag. */
	payload_size = read_be32(rsp_body + 2);

	if (payload_size > max_response) {
		/*
		 * TODO(vbendeb): at least drain the FIFO here or somehow let
		 * the TPM know that the response can be dropped.
		 */
		printk(BIOS_ERR, " TPM response too long (%zd bytes)",
		       payload_size);
		return 0;
	}

	/*
	 * Now let's read all but the last byte in the FIFO to make sure the
	 * status register is showing correct flow control bits: 'more data'
	 * until the last byte and then 'no more data' once the last byte is
	 * read.
	 */
	bytes_to_go = payload_size - 1 - HEADER_SIZE;
	fifo_buffer.rx_buffer = rsp_body + HEADER_SIZE;
	if (fifo_transfer(bytes_to_go, fifo_buffer, fifo_receive) != CB_SUCCESS) {
		printk(BIOS_ERR, "fifo_transfer %zd receive bytes failed\n",
		       bytes_to_go);
		return 0;
	}

	/* Verify that there is still data to read. */
	read_tpm_sts(&status);
	if ((status & expected_status_bits) != expected_status_bits) {
		printk(BIOS_ERR, "unexpected intermediate status %#x\n",
		       status);
		return 0;
	}

	/* Read the last byte of the PDU. */
	tpm2_read_reg(TPM_DATA_FIFO_REG, rsp_body + payload_size - 1, 1);

	/* Terminate the dump, if enabled. */
	if (debug_level_)
		printk(BIOS_DEBUG, "\n");

	/* Verify that 'data available' is not asserted any more. */
	read_tpm_sts(&status);
	if ((status & expected_status_bits) != TPM_STS_VALID) {
		printk(BIOS_ERR, "unexpected final status %#x\n", status);
		return 0;
	}

	/* Move the TPM back to idle state. */
	if (write_tpm_sts(TPM_STS_COMMAND_READY) != CB_SUCCESS) {
		printk(BIOS_ERR, "TPM_STS_COMMAND_READY failed\n");
		return 0;
	}

	return payload_size;
}

enum cb_err tis_vendor_write(unsigned int addr, const void *buffer, size_t bytes)
{
	return tpm2_write_reg(addr, buffer, bytes);
}

enum cb_err tis_vendor_read(unsigned int addr, void *buffer, size_t bytes)
{
	return tpm2_read_reg(addr, buffer, bytes);
}
