/* 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 'sruct 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 trasmitted 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
		 * quantiites 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 */
};

int 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 -1;
	}

	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 -1;
		}
		if ((be32toh(intf_id) & 0xF) == 0xF) {
			printk(BIOS_DEBUG, "\n%s: Not a TPM2 device\n", __func__);
			return -1;
		}
	}

	// 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 -1;

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

	/*
	 * 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 0;
}

/*
 * 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 asseretd 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);
}
