aboutsummaryrefslogtreecommitdiff
path: root/src/drivers/spi/tpm/tis.c
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2016-04-09 18:33:49 -0700
committerMartin Roth <martinroth@google.com>2016-06-23 17:14:16 +0200
commite31d24366ca5f344e8aed14bb6892ba1b8507f94 (patch)
tree876a7b63f82d6c3128cebd7051a7e25925517b97 /src/drivers/spi/tpm/tis.c
parent50df52244ebeb019c9e4f78a1197d7200f759b51 (diff)
tpm2: add SPI TPM driver
This introduces a SPI TPM driver compliant with the TCG issued "TPM Profile (PTP) Specification Revision 00.43" which can be found by googling its title. The driver implements both the hardware flow control protocol and the TPM state machine. The hardware flow control allows to map SPI based TPM devices to the LPC address space on x86 platforms, on all other platforms it needs to be implemented in the driver software. The tis layer is somewhat superficial, it might have to be expanded later. A lot more implementation details can be found in the code comments. Also, it is worth mentioning that this is not a complete version of the driver: its robustness needs to be improved, delay loops need to be bound, error conditions need to propagate up the call stack. BRANCH=none BUG=chrome-os-partner:52132, chrome-os-partner:50645, chrome-os-partner:54141 TEST=with the rest of the patches applied coreboot is able complete Chrome OS factory initialization of the TPM2 device. Change-Id: I967bc5c689f6e6f345755f08cb088ad37abd5d1c Signed-off-by: Martin Roth <martinroth@chromium.org> Original-Commit-Id: 5611c6f7d7fe6d37da668f337f0e70263913d63e Original-Change-Id: I17d732e66bd231c2289ec289994dd819c6276855 Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/350124 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/15298 Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@googlemail.com> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/drivers/spi/tpm/tis.c')
-rw-r--r--src/drivers/spi/tpm/tis.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/drivers/spi/tpm/tis.c b/src/drivers/spi/tpm/tis.c
new file mode 100644
index 0000000000..9facb5208b
--- /dev/null
+++ b/src/drivers/spi/tpm/tis.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <arch/early_variables.h>
+#include <console/console.h>
+#include <string.h>
+#include <tpm.h>
+
+#include "tpm.h"
+
+static unsigned tpm_is_open CAR_GLOBAL;
+
+static const struct {
+ uint16_t vid;
+ uint16_t did;
+ const char *device_name;
+} dev_map[] = {
+ { 0x15d1, 0x001b, "SLB9670" },
+ { 0x1ae0, 0x0028, "CR50" },
+};
+
+static const char *tis_get_dev_name(struct tpm2_info *info)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dev_map); i++)
+ if ((dev_map[i].vid == info->vendor_id) &&
+ (dev_map[i].did == info->device_id))
+ return dev_map[i].device_name;
+ return "Unknown";
+}
+
+int tis_open(void)
+{
+ if (car_get_var(tpm_is_open)) {
+ printk(BIOS_ERR, "tis_open() called twice.\n");
+ return -1;
+ }
+ return 0;
+}
+
+int tis_close(void)
+{
+ if (car_get_var(tpm_is_open)) {
+
+ /*
+ * Do we need to do something here, like waiting for a
+ * transaction to stop?
+ */
+ car_set_var(tpm_is_open, 0);
+ }
+
+ return 0;
+}
+
+int tis_init(void)
+{
+ struct tpm2_info info;
+
+ if (tpm2_init(spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS,
+ CONFIG_DRIVER_TPM_SPI_CHIP))) {
+ printk(BIOS_ERR, "Failed to initialize TPM SPI intierface\n");
+ return -1;
+ }
+
+ tpm2_get_info(&info);
+
+ printk(BIOS_INFO, "Initialized TPM device %s revision %d\n",
+ tis_get_dev_name(&info), info.revision);
+
+ return 0;
+}
+
+
+int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
+ uint8_t *recvbuf, size_t *rbuf_len)
+{
+ int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len);
+ *rbuf_len = len;
+ return 0;
+}