[coreboot-gerrit] Patch set updated for coreboot: TPM: Merge of two TPM API's into one API.
Philipp Deppenwiese (zaolin.daisuki@googlemail.com)
gerrit at coreboot.org
Sat Feb 6 15:36:41 CET 2016
Philipp Deppenwiese (zaolin.daisuki at googlemail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/10542
-gerrit
commit 2f786e5ffa9832daf3c9ff61ef47ff1ece3a825e
Author: Philipp Deppenwiese <zaolin at das-labor.org>
Date: Sat Jun 13 23:35:37 2015 +0200
TPM: Merge of two TPM API's into one API.
Currently coreboot includes two TPM software implementations.
Following changes are done:
+ Splited LPC/I2C tpm driver implementation into two directories in src/drivers/tpm/ .
+ Moved pc80/tpm to tpm directory because it's not pc80 specific.
+ Use Google's lib/tlcl.* small tpm software stack as the main one.
+ Remove the old one drivers/pc80/tpm/romstage.c which can't be used for vboot2.
+ Split & Merge implementations into TSS and TSPI.
-> Rename tlcl* files into tss which is the common name.
-> Move init_tpm(void) function from drivers/pc80/tpm/romstage.c into
the lib/tpm/tspi.c which is also the common name for highlevel tpm functions based on tss.
-> Put the tss and tspi files into tpm folders in lib/ and include/ .
-> Change header includes so that tpm.h can be found in include/pc80/
and software stack related stuff in include/tpm.
+ Revert pragma once statements from previous commit.
Compile:
VBOOT2 Feature = yes
Coreboot TPM Feature = yes
Run:
VBOOT2 Feature = not tested
Coreboot TPM Feature = yes
Change-Id: I8cbcd723d83ffcc0c1c47c58438dccdb16bb7cf7
Signed-off-by: Philipp Deppenwiese <zaolin at das-labor.org>
---
src/cpu/intel/haswell/romstage.c | 2 +-
src/drivers/i2c/tpm/Kconfig | 13 -
src/drivers/i2c/tpm/Makefile.inc | 4 -
src/drivers/i2c/tpm/tis.c | 194 ------
src/drivers/i2c/tpm/tpm.c | 551 ---------------
src/drivers/i2c/tpm/tpm.h | 128 ----
src/drivers/intel/fsp1_1/romstage.c | 2 +-
src/drivers/pc80/Kconfig | 2 -
src/drivers/pc80/Makefile.inc | 2 +-
src/drivers/pc80/tpm/Kconfig | 54 --
src/drivers/pc80/tpm/Makefile.inc | 4 -
src/drivers/pc80/tpm/acpi/tpm.asl | 206 ------
src/drivers/pc80/tpm/chip.h | 31 -
src/drivers/pc80/tpm/romstage.c | 251 -------
src/drivers/pc80/tpm/tpm.c | 769 ---------------------
src/drivers/tpm/Kconfig | 24 +
src/drivers/tpm/Makefile.inc | 1 +
src/drivers/tpm/acpi/tpm.asl | 206 ++++++
src/drivers/tpm/i2c/Kconfig | 13 +
src/drivers/tpm/i2c/Makefile.inc | 4 +
src/drivers/tpm/i2c/chip.h | 98 +++
src/drivers/tpm/i2c/tpm.c | 721 +++++++++++++++++++
src/drivers/tpm/lpc/Kconfig | 32 +
src/drivers/tpm/lpc/Makefile.inc | 4 +
src/drivers/tpm/lpc/chip.h | 31 +
src/drivers/tpm/lpc/tpm.c | 769 +++++++++++++++++++++
src/include/antirollback.h | 2 +-
src/include/tpm.h | 67 --
src/include/tpm/tpm.h | 71 ++
src/include/tpm/tspi.h | 29 +
src/include/tpm/tss.h | 136 ++++
src/include/tpm/tss_constants.h | 98 +++
src/include/tpm_lite/tlcl.h | 137 ----
src/include/tpm_lite/tss_constants.h | 96 ---
src/lib/Makefile.inc | 8 +-
src/lib/mocked_tlcl.c | 132 ----
src/lib/tlcl.c | 327 ---------
src/lib/tlcl_internal.h | 61 --
src/lib/tlcl_structures.h | 138 ----
src/lib/tpm/Makefile.inc | 13 +
src/lib/tpm/mocked_tss.c | 132 ++++
src/lib/tpm/tspi.c | 95 +++
src/lib/tpm/tss.c | 331 +++++++++
src/lib/tpm/tss_internal.h | 61 ++
src/lib/tpm/tss_structures.h | 138 ++++
src/mainboard/google/auron/acpi/mainboard.asl | 2 +-
src/mainboard/google/auron/devicetree.cb | 2 +-
src/mainboard/google/cyan/acpi/mainboard.asl | 2 +-
src/mainboard/google/cyan/devicetree.cb | 2 +-
src/mainboard/google/glados/acpi/mainboard.asl | 2 +-
src/mainboard/google/glados/devicetree.cb | 2 +-
src/mainboard/google/jecht/acpi/mainboard.asl | 2 +-
src/mainboard/google/link/romstage.c | 2 +-
src/mainboard/google/parrot/romstage.c | 2 +-
src/mainboard/google/samus/acpi/mainboard.asl | 2 +-
src/mainboard/google/samus/devicetree.cb | 2 +-
src/mainboard/google/stout/romstage.c | 2 +-
src/mainboard/intel/emeraldlake2/romstage.c | 2 +-
src/mainboard/intel/kunimitsu/acpi/mainboard.asl | 2 +-
src/mainboard/intel/strago/acpi/mainboard.asl | 2 +-
src/mainboard/intel/strago/devicetree.cb | 2 +-
src/mainboard/lenovo/t420s/devicetree.cb | 2 +-
src/mainboard/lenovo/t420s/dsdt.asl | 2 +-
src/mainboard/lenovo/t430s/devicetree.cb | 2 +-
src/mainboard/lenovo/t430s/dsdt.asl | 2 +-
src/mainboard/lenovo/t520/devicetree.cb | 2 +-
src/mainboard/lenovo/t520/dsdt.asl | 2 +-
src/mainboard/lenovo/t530/devicetree.cb | 2 +-
src/mainboard/lenovo/t530/dsdt.asl | 2 +-
src/mainboard/lenovo/x201/devicetree.cb | 2 +-
src/mainboard/lenovo/x201/dsdt.asl | 2 +-
src/mainboard/lenovo/x201/romstage.c | 2 +-
src/mainboard/lenovo/x220/devicetree.cb | 2 +-
src/mainboard/lenovo/x220/dsdt.asl | 2 +-
src/mainboard/lenovo/x230/devicetree.cb | 2 +-
src/mainboard/lenovo/x230/dsdt.asl | 2 +-
src/mainboard/samsung/lumpy/romstage.c | 2 +-
src/mainboard/samsung/stumpy/romstage.c | 2 +-
src/northbridge/intel/sandybridge/romstage.c | 2 +-
src/soc/intel/baytrail/romstage/romstage.c | 2 +-
src/soc/intel/braswell/romstage/romstage.c | 2 +-
src/soc/intel/broadwell/romstage/romstage.c | 2 +-
.../google/chromeos/vboot2/antirollback.c | 4 +-
83 files changed, 3051 insertions(+), 3215 deletions(-)
diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c
index 6da7fd9..2340819 100644
--- a/src/cpu/intel/haswell/romstage.c
+++ b/src/cpu/intel/haswell/romstage.c
@@ -40,7 +40,7 @@
#include "northbridge/intel/haswell/raminit.h"
#include "southbridge/intel/lynxpoint/pch.h"
#include "southbridge/intel/lynxpoint/me.h"
-#include <tpm.h>
+#include <tpm/tspi.h>
static inline void reset_system(void)
{
diff --git a/src/drivers/i2c/tpm/Kconfig b/src/drivers/i2c/tpm/Kconfig
deleted file mode 100644
index f2b969f..0000000
--- a/src/drivers/i2c/tpm/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-config I2C_TPM
- bool "I2C TPM"
- depends on !PC80_SYSTEM # for now
-
-config DRIVER_TPM_I2C_BUS
- hex "I2C TPM chip bus"
- default 9 # FIXME, workaround for Kconfig BS
- depends on I2C_TPM
-
-config DRIVER_TPM_I2C_ADDR
- hex "I2C TPM chip address"
- default 2 # FIXME, workaround for Kconfig BS
- depends on I2C_TPM
diff --git a/src/drivers/i2c/tpm/Makefile.inc b/src/drivers/i2c/tpm/Makefile.inc
deleted file mode 100644
index 4f5913f..0000000
--- a/src/drivers/i2c/tpm/Makefile.inc
+++ /dev/null
@@ -1,4 +0,0 @@
-ramstage-$(CONFIG_I2C_TPM) += tis.c tpm.c
-romstage-$(CONFIG_I2C_TPM) += tis.c tpm.c
-verstage-$(CONFIG_I2C_TPM) += tis.c tpm.c
-bootblock-$(CONFIG_I2C_TPM) += tis.c tpm.c
diff --git a/src/drivers/i2c/tpm/tis.c b/src/drivers/i2c/tpm/tis.c
deleted file mode 100644
index 0404109..0000000
--- a/src/drivers/i2c/tpm/tis.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2011 Infineon Technologies
- * Copyright 2013 Google Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include <delay.h>
-#include <device/i2c.h>
-#include <endian.h>
-#include <tpm.h>
-#include "tpm.h"
-#include <timer.h>
-
-#include <console/console.h>
-
-/* global structure for tpm chip data */
-struct tpm_chip g_chip;
-
-#define TPM_CMD_COUNT_BYTE 2
-#define TPM_CMD_ORDINAL_BYTE 6
-#define TPM_VALID_STATUS (1 << 7)
-
-int tis_open(void)
-{
- int rc;
-
- if (g_chip.is_open) {
- printk(BIOS_DEBUG, "tis_open() called twice.\n");
- return -1;
- }
-
- rc = tpm_vendor_init(CONFIG_DRIVER_TPM_I2C_BUS,
- CONFIG_DRIVER_TPM_I2C_ADDR);
-
- if (rc < 0)
- g_chip.is_open = 0;
-
- if (rc) {
- return -1;
- }
-
- return 0;
-}
-
-int tis_close(void)
-{
- if (g_chip.is_open) {
- tpm_vendor_cleanup(&g_chip);
- g_chip.is_open = 0;
- }
-
- return 0;
-}
-
-int tis_init(void)
-{
- int bus = CONFIG_DRIVER_TPM_I2C_BUS;
- int chip = CONFIG_DRIVER_TPM_I2C_ADDR;
- struct stopwatch sw;
- uint8_t buf = 0;
- int ret;
- long sw_run_duration = 750;
-
- /*
- * Probe TPM. Check if the TPM_ACCESS register's ValidSts bit is set(1)
- * If the bit remains clear(0) then claim that init has failed.
- */
- stopwatch_init_msecs_expire(&sw, sw_run_duration);
- do {
- ret = i2c_readb(bus, chip, 0, &buf);
- if (!ret && (buf & TPM_VALID_STATUS)) {
- sw_run_duration = stopwatch_duration_msecs(&sw);
- break;
- }
- } while (!stopwatch_expired(&sw));
-
- printk(BIOS_INFO,
- "%s: ValidSts bit %s(%d) in TPM_ACCESS register after %ld ms\n",
- __func__, (buf & TPM_VALID_STATUS) ? "set" : "clear",
- (buf & TPM_VALID_STATUS) >> 7, sw_run_duration);
-
- /*
- * Claim failure if the ValidSts (bit 7) is clear.
- */
- if (!(buf & TPM_VALID_STATUS))
- return -1;
-
- return 0;
-}
-
-static ssize_t tpm_transmit(const uint8_t *buf, size_t bufsiz)
-{
- int rc;
- uint32_t count, ordinal;
-
- struct tpm_chip *chip = &g_chip;
-
- memcpy(&count, buf + TPM_CMD_COUNT_BYTE, sizeof(count));
- count = be32_to_cpu(count);
- memcpy(&ordinal, buf + TPM_CMD_ORDINAL_BYTE, sizeof(ordinal));
- ordinal = be32_to_cpu(ordinal);
-
- if (count == 0) {
- printk(BIOS_DEBUG, "tpm_transmit: no data\n");
- return -1;
- }
- if (count > bufsiz) {
- printk(BIOS_DEBUG, "tpm_transmit: invalid count value %x %zx\n",
- count, bufsiz);
- return -1;
- }
-
- ASSERT(chip->vendor.send);
- rc = chip->vendor.send(chip, (uint8_t *) buf, count);
- if (rc < 0) {
- printk(BIOS_DEBUG, "tpm_transmit: tpm_send error\n");
- goto out;
- }
-
- if (chip->vendor.irq)
- goto out_recv;
-
- int timeout = 2 * 60 * 1000; /* two minutes timeout */
- while (timeout) {
- ASSERT(chip->vendor.status);
- uint8_t status = chip->vendor.status(chip);
- if ((status & chip->vendor.req_complete_mask) ==
- chip->vendor.req_complete_val) {
- goto out_recv;
- }
-
- if ((status == chip->vendor.req_canceled)) {
- printk(BIOS_DEBUG, "tpm_transmit: Operation Canceled\n");
- rc = -1;
- goto out;
- }
- mdelay(TPM_TIMEOUT);
- timeout--;
- }
-
- ASSERT(chip->vendor.cancel);
- chip->vendor.cancel(chip);
- printk(BIOS_DEBUG, "tpm_transmit: Operation Timed out\n");
- rc = -1; //ETIME;
- goto out;
-
-out_recv:
-
- rc = chip->vendor.recv(chip, (uint8_t *) buf, TPM_BUFSIZE);
- if (rc < 0)
- printk(BIOS_DEBUG, "tpm_transmit: tpm_recv: error %d\n", rc);
-out:
- return rc;
-}
-
-int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
- uint8_t *recvbuf, size_t *rbuf_len)
-{
- uint8_t buf[TPM_BUFSIZE];
-
- if (sizeof(buf) < sbuf_size)
- return -1;
-
- memcpy(buf, sendbuf, sbuf_size);
-
- int len = tpm_transmit(buf, sbuf_size);
-
- if (len < 10) {
- *rbuf_len = 0;
- return -1;
- }
-
- if (len > *rbuf_len) {
- *rbuf_len = len;
- return -1;
- }
-
- memcpy(recvbuf, buf, len);
- *rbuf_len = len;
-
- return 0;
-}
diff --git a/src/drivers/i2c/tpm/tpm.c b/src/drivers/i2c/tpm/tpm.c
deleted file mode 100644
index 306005f..0000000
--- a/src/drivers/i2c/tpm/tpm.c
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * Copyright (C) 2011 Infineon Technologies
- *
- * Authors:
- * Peter Huewe <huewe.external at infineon.com>
- *
- * Description:
- * Device driver for TCG/TCPA TPM (trusted platform module).
- * Specifications at www.trustedcomputinggroup.org
- *
- * This device driver implements the TPM interface as defined in
- * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
- * Infineon I2C Protocol Stack Specification v0.20.
- *
- * It is based on the Linux kernel driver tpm.c from Leendert van
- * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
- *
- * Version: 2.1.1
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <types.h>
-#include <delay.h>
-#include <console/console.h>
-#include <device/i2c.h>
-#include <endian.h>
-#include "tpm.h"
-
-/* Address of the TPM on the I2C bus */
-#define TPM_I2C_ADDR 0x20
-
-/* max. number of iterations after I2C NAK */
-#define MAX_COUNT 3
-
-#define SLEEP_DURATION 60 /* in usec */
-
-/* max. number of iterations after I2C NAK for 'long' commands
- * we need this especially for sending TPM_READY, since the cleanup after the
- * transtion to the ready state may take some time, but it is unpredictable
- * how long it will take.
- */
-#define MAX_COUNT_LONG 50
-
-#define SLEEP_DURATION_LONG 210 /* in usec */
-
-/* expected value for DIDVID register */
-#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
-#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
-
-enum i2c_chip_type {
- SLB9635,
- SLB9645,
- UNKNOWN,
-};
-
-static const char * const chip_name[] = {
- [SLB9635] = "slb9635tt",
- [SLB9645] = "slb9645tt",
- [UNKNOWN] = "unknown/fallback to slb9635",
-};
-
-/* Structure to store I2C TPM specific stuff */
-struct tpm_inf_dev {
- int bus;
- unsigned int addr;
- uint8_t buf[TPM_BUFSIZE + sizeof(uint8_t)]; // max. buffer size + addr
- enum i2c_chip_type chip_type;
-};
-
-static struct tpm_inf_dev tpm_dev = {
- .bus = -1,
- .addr = TPM_I2C_ADDR
-};
-
-/*
- * iic_tpm_read() - read from TPM register
- * @addr: register address to read from
- * @buffer: provided by caller
- * @len: number of bytes to read
- *
- * Read len bytes from TPM register and put them into
- * buffer (little-endian format, i.e. first byte is put into buffer[0]).
- *
- * NOTE: TPM is big-endian for multi-byte values. Multi-byte
- * values have to be swapped.
- *
- * Return -1 on error, 0 on success.
- */
-static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len)
-{
- int rc;
- int count;
-
- if (tpm_dev.bus < 0)
- return -1;
- if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
- /* slb9635 protocol should work in both cases */
- for (count = 0; count < MAX_COUNT; count++) {
- rc = i2c_write_raw(tpm_dev.bus, tpm_dev.addr, &addr, 1);
- if (rc == 0)
- break; /* success, break to skip sleep */
-
- udelay(SLEEP_DURATION);
- }
-
- if (rc)
- return -1;
-
- /* After the TPM has successfully received the register address
- * it needs some time, thus we're sleeping here again, before
- * retrieving the data
- */
- for (count = 0; count < MAX_COUNT; count++) {
- udelay(SLEEP_DURATION);
- rc = i2c_read_raw(tpm_dev.bus, tpm_dev.addr,
- buffer, len);
- if (rc == 0)
- break; /* success, break to skip sleep */
-
- }
- } else {
- /* use a combined read for newer chips
- * unfortunately the smbus functions are not suitable due to
- * the 32 byte limit of the smbus.
- * retries should usually not be needed, but are kept just to
- * be safe on the safe side.
- */
- struct i2c_seg aseg = { .read = 0, .chip = tpm_dev.addr,
- .buf = &addr, .len = 1 };
- struct i2c_seg dseg = { .read = 1, .chip = tpm_dev.addr,
- .buf = buffer, .len = len };
- for (count = 0; count < MAX_COUNT; count++) {
- rc = i2c_transfer(tpm_dev.bus, &aseg, 1) ||
- i2c_transfer(tpm_dev.bus, &dseg, 1);
- if (rc == 0)
- break; /* break here to skip sleep */
- udelay(SLEEP_DURATION);
- }
- }
-
- /* take care of 'guard time' */
- udelay(SLEEP_DURATION);
- if (rc)
- return -1;
-
- return 0;
-}
-
-static int iic_tpm_write_generic(uint8_t addr, uint8_t *buffer, size_t len,
- unsigned int sleep_time,
- uint8_t max_count)
-{
- int rc = 0;
- int count;
-
- if (len > TPM_BUFSIZE) {
- printk(BIOS_DEBUG, "%s: Length %zd is too large\n", __func__, len);
- return -1;
- }
-
- /* prepare send buffer */
- tpm_dev.buf[0] = addr;
- memcpy(&(tpm_dev.buf[1]), buffer, len);
-
- if (tpm_dev.bus < 0)
- return -1;
- for (count = 0; count < max_count; count++) {
- rc = i2c_write_raw(tpm_dev.bus, tpm_dev.addr,
- tpm_dev.buf, len + 1);
- if (rc == 0)
- break; /* success, break to skip sleep */
-
- udelay(sleep_time);
- }
-
- /* take care of 'guard time' */
- udelay(SLEEP_DURATION);
- if (rc)
- return -1;
-
- return 0;
-}
-
-/*
- * iic_tpm_write() - write to TPM register
- * @addr: register address to write to
- * @buffer: containing data to be written
- * @len: number of bytes to write
- *
- * Write len bytes from provided buffer to TPM register (little
- * endian format, i.e. buffer[0] is written as first byte).
- *
- * NOTE: TPM is big-endian for multi-byte values. Multi-byte
- * values have to be swapped.
- *
- * NOTE: use this function instead of the iic_tpm_write_generic function.
- *
- * Return -EIO on error, 0 on success
- */
-static int iic_tpm_write(uint8_t addr, uint8_t *buffer, size_t len)
-{
- return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION,
- MAX_COUNT);
-}
-
-/*
- * This function is needed especially for the cleanup situation after
- * sending TPM_READY
- * */
-static int iic_tpm_write_long(uint8_t addr, uint8_t *buffer, size_t len)
-{
- return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
- MAX_COUNT_LONG);
-}
-
-#define TPM_HEADER_SIZE 10
-
-enum tis_access {
- TPM_ACCESS_VALID = 0x80,
- TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
- TPM_ACCESS_REQUEST_PENDING = 0x04,
- TPM_ACCESS_REQUEST_USE = 0x02,
-};
-
-enum tis_status {
- TPM_STS_VALID = 0x80,
- TPM_STS_COMMAND_READY = 0x40,
- TPM_STS_GO = 0x20,
- TPM_STS_DATA_AVAIL = 0x10,
- TPM_STS_DATA_EXPECT = 0x08,
-};
-
-#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
-#define TPM_STS(l) (0x0001 | ((l) << 4))
-#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
-#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
-
-static int check_locality(struct tpm_chip *chip, int loc)
-{
- uint8_t buf;
-
- if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
- return -1;
-
- if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
- (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
- chip->vendor.locality = loc;
- return loc;
- }
-
- return -1;
-}
-
-static void release_locality(struct tpm_chip *chip, int loc, int force)
-{
- uint8_t buf;
- if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
- return;
-
- if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
- (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
- buf = TPM_ACCESS_ACTIVE_LOCALITY;
- iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
- }
-}
-
-static int request_locality(struct tpm_chip *chip, int loc)
-{
- uint8_t buf = TPM_ACCESS_REQUEST_USE;
-
- if (check_locality(chip, loc) >= 0)
- return loc; /* we already have the locality */
-
- iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
-
- /* wait for burstcount */
- int timeout = 2 * 1000; /* 2s timeout */
- while (timeout) {
- if (check_locality(chip, loc) >= 0)
- return loc;
- mdelay(TPM_TIMEOUT);
- timeout--;
- }
-
- return -1;
-}
-
-static uint8_t tpm_tis_i2c_status(struct tpm_chip *chip)
-{
- /* NOTE: Since I2C read may fail, return 0 in this case --> time-out */
- uint8_t buf;
- if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
- return 0;
- else
- return buf;
-}
-
-static void tpm_tis_i2c_ready(struct tpm_chip *chip)
-{
- /* this causes the current command to be aborted */
- uint8_t buf = TPM_STS_COMMAND_READY;
- iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
-}
-
-static ssize_t get_burstcount(struct tpm_chip *chip)
-{
- ssize_t burstcnt;
- uint8_t buf[3];
-
- /* wait for burstcount */
- int timeout = 2 * 1000; /* 2s timeout */
- while (timeout) {
- /* Note: STS is little endian */
- if (iic_tpm_read(TPM_STS(chip->vendor.locality) + 1, buf, 3) < 0)
- burstcnt = 0;
- else
- burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
-
- if (burstcnt)
- return burstcnt;
- mdelay(TPM_TIMEOUT);
- timeout--;
- }
- return -1;
-}
-
-static int wait_for_stat(struct tpm_chip *chip, uint8_t mask, int *status)
-{
- unsigned long timeout = 2 * 1024;
- while (timeout) {
- *status = tpm_tis_i2c_status(chip);
- if ((*status & mask) == mask)
- return 0;
- mdelay(TPM_TIMEOUT);
- timeout--;
- }
-
- return -1;
-}
-
-static int recv_data(struct tpm_chip *chip, uint8_t *buf, size_t count)
-{
- size_t size = 0;
-
- while (size < count) {
- ssize_t burstcnt = get_burstcount(chip);
- int rc;
-
- /* burstcount < 0 = TPM is busy */
- if (burstcnt < 0)
- return burstcnt;
-
- /* limit received data to max. left */
- if (burstcnt > (count - size))
- burstcnt = count - size;
-
- rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
- &(buf[size]),
- burstcnt);
- if (rc == 0)
- size += burstcnt;
-
- }
- return size;
-}
-
-static int tpm_tis_i2c_recv(struct tpm_chip *chip, uint8_t *buf, size_t count)
-{
- int size = 0;
- uint32_t expected;
- int status;
-
- if (count < TPM_HEADER_SIZE) {
- size = -1;
- goto out;
- }
-
- /* read first 10 bytes, including tag, paramsize, and result */
- size = recv_data(chip, buf, TPM_HEADER_SIZE);
- if (size < TPM_HEADER_SIZE) {
- printk(BIOS_DEBUG, "tpm_tis_i2c_recv: Unable to read header\n");
- goto out;
- }
-
- memcpy(&expected, buf + TPM_RSP_SIZE_BYTE, sizeof(expected));
- expected = be32_to_cpu(expected);
- if ((size_t)expected > count) {
- size = -1;
- goto out;
- }
-
- size += recv_data(chip, &buf[TPM_HEADER_SIZE],
- expected - TPM_HEADER_SIZE);
- if (size < expected) {
- printk(BIOS_DEBUG, "tpm_tis_i2c_recv: Unable to "
- "read remainder of result\n");
- size = -1;
- goto out;
- }
-
- wait_for_stat(chip, TPM_STS_VALID, &status);
- if (status & TPM_STS_DATA_AVAIL) { /* retry? */
- printk(BIOS_DEBUG, "tpm_tis_i2c_recv: Error left over data\n");
- size = -1;
- goto out;
- }
-
-out:
- tpm_tis_i2c_ready(chip);
-
- return size;
-}
-
-static int tpm_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
-{
- int status;
- size_t count = 0;
- uint8_t sts = TPM_STS_GO;
-
- if (len > TPM_BUFSIZE)
- return -1; /* command is too long for our TPM, sorry */
-
- status = tpm_tis_i2c_status(chip);
- if ((status & TPM_STS_COMMAND_READY) == 0) {
- tpm_tis_i2c_ready(chip);
- if (wait_for_stat(chip, TPM_STS_COMMAND_READY, &status) < 0)
- goto out_err;
- }
-
- while (count < len - 1) {
- ssize_t burstcnt = get_burstcount(chip);
-
- /* burstcount < 0 = TPM is busy */
- if (burstcnt < 0)
- return burstcnt;
-
- if (burstcnt > (len-1-count))
- burstcnt = len-1-count;
-
-#ifdef CONFIG_TPM_I2C_BURST_LIMITATION
- if (burstcnt > CONFIG_TPM_I2C_BURST_LIMITATION)
- burstcnt = CONFIG_TPM_I2C_BURST_LIMITATION;
-#endif /* CONFIG_TPM_I2C_BURST_LIMITATION */
-
- if (iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
- &(buf[count]), burstcnt) == 0)
- count += burstcnt;
-
- wait_for_stat(chip, TPM_STS_VALID, &status);
- if ((status & TPM_STS_DATA_EXPECT) == 0)
- goto out_err;
- }
-
- /* write last byte */
- iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
-
- wait_for_stat(chip, TPM_STS_VALID, &status);
- if ((status & TPM_STS_DATA_EXPECT) != 0)
- goto out_err;
-
- /* go and do it */
- iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
-
- return len;
-
-out_err:
- tpm_tis_i2c_ready(chip);
-
- return -1;
-}
-
-static struct tpm_vendor_specific tpm_tis_i2c = {
- .status = tpm_tis_i2c_status,
- .recv = tpm_tis_i2c_recv,
- .send = tpm_tis_i2c_send,
- .cancel = tpm_tis_i2c_ready,
- .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
- .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
- .req_canceled = TPM_STS_COMMAND_READY,
-};
-
-/* Initialization of I2C TPM */
-
-int tpm_vendor_init(unsigned bus, uint32_t dev_addr)
-{
- uint32_t vendor;
- unsigned int old_addr;
- struct tpm_chip *chip;
- extern struct tpm_chip g_chip;
-
- old_addr = tpm_dev.addr;
- if (dev_addr != 0)
- tpm_dev.addr = dev_addr;
- tpm_dev.bus = bus;
-
- chip = &g_chip;
- memcpy(&chip->vendor, &tpm_tis_i2c, sizeof(struct tpm_vendor_specific));
- chip->is_open = 1;
-
- /* Disable interrupts (not supported) */
- chip->vendor.irq = 0;
-
- if (request_locality(chip, 0) != 0)
- goto out_err;
-
- /* Read four bytes from DID_VID register */
- if (iic_tpm_read(TPM_DID_VID(0), (uint8_t *)&vendor, 4) < 0)
- goto out_release;
-
- if (vendor == TPM_TIS_I2C_DID_VID_9645) {
- tpm_dev.chip_type = SLB9645;
- } else if (be32_to_cpu(vendor) == TPM_TIS_I2C_DID_VID_9635) {
- tpm_dev.chip_type = SLB9635;
- } else {
- printk(BIOS_DEBUG, "Vendor ID 0x%08x not recognized.\n", vendor);
- goto out_release;
- }
-
- printk(BIOS_DEBUG, "1.2 TPM (chip type %s device-id 0x%X)\n",
- chip_name[tpm_dev.chip_type], vendor >> 16);
-
- /*
- * A timeout query to TPM can be placed here.
- * Standard timeout values are used so far
- */
-
- return 0;
-
-out_release:
- release_locality(chip, 0, 1);
-
-out_err:
- tpm_dev.addr = old_addr;
- return -1;
-}
-
-void tpm_vendor_cleanup(struct tpm_chip *chip)
-{
- release_locality(chip, chip->vendor.locality, 1);
-}
diff --git a/src/drivers/i2c/tpm/tpm.h b/src/drivers/i2c/tpm/tpm.h
deleted file mode 100644
index 625679d..0000000
--- a/src/drivers/i2c/tpm/tpm.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2011 Infineon Technologies
- *
- * Authors:
- * Peter Huewe <huewe.external at infineon.com>
- *
- * Version: 2.1.1
- *
- * Description:
- * Device driver for TCG/TCPA TPM (trusted platform module).
- * Specifications at www.trustedcomputinggroup.org
- *
- * It is based on the Linux kernel driver tpm.c from Leendert van
- * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __DRIVERS_TPM_SLB9635_I2C_TPM_H__
-#define __DRIVERS_TPM_SLB9635_I2C_TPM_H__
-
-#include <stdint.h>
-
-enum tpm_timeout {
- TPM_TIMEOUT = 1, /* msecs */
-};
-
-/* Size of external transmit buffer (used for stack buffer in tpm_sendrecv) */
-#define TPM_BUFSIZE 1260
-
-/* Index of fields in TPM command buffer */
-#define TPM_CMD_SIZE_BYTE 2
-#define TPM_CMD_ORDINAL_BYTE 6
-
-/* Index of Count field in TPM response buffer */
-#define TPM_RSP_SIZE_BYTE 2
-#define TPM_RSP_RC_BYTE 6
-
-struct tpm_chip;
-
-struct tpm_vendor_specific {
- const uint8_t req_complete_mask;
- const uint8_t req_complete_val;
- const uint8_t req_canceled;
- int irq;
- int (*recv)(struct tpm_chip *, uint8_t *, size_t);
- int (*send)(struct tpm_chip *, uint8_t *, size_t);
- void (*cancel)(struct tpm_chip *);
- uint8_t(*status)(struct tpm_chip *);
- int locality;
-};
-
-struct tpm_chip {
- int is_open;
- struct tpm_vendor_specific vendor;
-};
-
-struct tpm_input_header {
- uint16_t tag;
- uint32_t length;
- uint32_t ordinal;
-} __attribute__ ((packed));
-
-struct tpm_output_header {
- uint16_t tag;
- uint32_t length;
- uint32_t return_code;
-} __attribute__ ((packed));
-
-struct timeout_t {
- uint32_t a;
- uint32_t b;
- uint32_t c;
- uint32_t d;
-} __attribute__ ((packed));
-
-struct duration_t {
- uint32_t tpm_short;
- uint32_t tpm_medium;
- uint32_t tpm_long;
-} __attribute__ ((packed));
-
-typedef union {
- struct timeout_t timeout;
- struct duration_t duration;
-} cap_t;
-
-struct tpm_getcap_params_in {
- uint32_t cap;
- uint32_t subcap_size;
- uint32_t subcap;
-} __attribute__ ((packed));
-
-struct tpm_getcap_params_out {
- uint32_t cap_size;
- cap_t cap;
-} __attribute__ ((packed));
-
-typedef union {
- struct tpm_input_header in;
- struct tpm_output_header out;
-} tpm_cmd_header;
-
-typedef union {
- struct tpm_getcap_params_out getcap_out;
- struct tpm_getcap_params_in getcap_in;
-} tpm_cmd_params;
-
-struct tpm_cmd_t {
- tpm_cmd_header header;
- tpm_cmd_params params;
-} __attribute__ ((packed));
-
-/* ---------- Interface for TPM vendor ------------ */
-
-int tpm_vendor_init(unsigned bus, uint32_t dev_addr);
-
-void tpm_vendor_cleanup(struct tpm_chip *chip);
-
-#endif /* __DRIVERS_TPM_SLB9635_I2C_TPM_H__ */
diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c
index 7466575..fef885d 100644
--- a/src/drivers/intel/fsp1_1/romstage.c
+++ b/src/drivers/intel/fsp1_1/romstage.c
@@ -33,7 +33,7 @@
#include <soc/intel/common/mrc_cache.h>
#include <stage_cache.h>
#include <timestamp.h>
-#include <tpm.h>
+#include <tpm/tpm.h>
#include <vendorcode/google/chromeos/chromeos.h>
asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
diff --git a/src/drivers/pc80/Kconfig b/src/drivers/pc80/Kconfig
index 18c626c..b099dbc 100644
--- a/src/drivers/pc80/Kconfig
+++ b/src/drivers/pc80/Kconfig
@@ -22,6 +22,4 @@ config DRIVERS_MC146818
default y if ARCH_X86
select RTC
-source src/drivers/pc80/tpm/Kconfig
-
endif
diff --git a/src/drivers/pc80/Makefile.inc b/src/drivers/pc80/Makefile.inc
index 0788cc7..838f336 100644
--- a/src/drivers/pc80/Makefile.inc
+++ b/src/drivers/pc80/Makefile.inc
@@ -13,7 +13,7 @@ romstage-$(CONFIG_DRIVERS_MC146818) += mc146818rtc_early.c
romstage-$(CONFIG_SPKMODEM) += spkmodem.c
-subdirs-y += tpm vga
+subdirs-y += vga
cbfs-files-$(CONFIG_HAVE_CMOS_DEFAULT) += cmos.default
cmos.default-file = $(CONFIG_CMOS_DEFAULT_FILE):nvramtool
diff --git a/src/drivers/pc80/tpm/Kconfig b/src/drivers/pc80/tpm/Kconfig
deleted file mode 100644
index 0e8a020..0000000
--- a/src/drivers/pc80/tpm/Kconfig
+++ /dev/null
@@ -1,54 +0,0 @@
-config MAINBOARD_HAS_LPC_TPM
- bool
- default n
- help
- Board has TPM support
-
-config LPC_TPM
- bool "Enable TPM support"
- depends on MAINBOARD_HAS_LPC_TPM
- default n
- help
- Enable this option to enable LPC TPM support in coreboot.
-
- If unsure, say N.
-
-config TPM_TIS_BASE_ADDRESS
- hex
- default 0xfed40000
- depends on LPC_TPM
- help
- This can be used to adjust the TPM memory base address.
- The default is specified by the TCG PC Client Specific TPM
- Interface Specification 1.2 and should not be changed unless
- the TPM being used does not conform to TPM TIS 1.2.
-
-config TPM_PIRQ
- hex
- default 0
- depends on LPC_TPM
- help
- This can be used to specify a PIRQ to use instead of SERIRQ,
- which is needed for SPI TPM interrupt support on x86.
-
-config TPM_INIT_FAILURE_IS_FATAL
- bool
- default n
- depends on LPC_TPM
- help
- What to do if TPM init failed. If true, force a hard reset,
- otherwise just log error message to console.
-
-config SKIP_TPM_STARTUP_ON_NORMAL_BOOT
- bool
- default n
- depends on LPC_TPM
- help
- Skip TPM init on normal boot. Useful if payload does TPM init.
-
-config TPM_DEACTIVATE
- bool "Deactivate TPM"
- default n
- depends on LPC_TPM
- help
- Deactivate TPM by issuing deactivate command.
diff --git a/src/drivers/pc80/tpm/Makefile.inc b/src/drivers/pc80/tpm/Makefile.inc
deleted file mode 100644
index 697842f..0000000
--- a/src/drivers/pc80/tpm/Makefile.inc
+++ /dev/null
@@ -1,4 +0,0 @@
-verstage-$(CONFIG_LPC_TPM) += tpm.c
-romstage-$(CONFIG_LPC_TPM) += tpm.c
-ramstage-$(CONFIG_LPC_TPM) += tpm.c
-romstage-$(CONFIG_LPC_TPM) += romstage.c
diff --git a/src/drivers/pc80/tpm/acpi/tpm.asl b/src/drivers/pc80/tpm/acpi/tpm.asl
deleted file mode 100644
index 7755e9b..0000000
--- a/src/drivers/pc80/tpm/acpi/tpm.asl
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/* Trusted Platform Module */
-
-Device (TPM)
-{
- Name (_HID, EISAID ("PNP0C31"))
- Name (_CID, 0x310cd041)
- Name (_UID, 1)
-
- Method (_STA, 0)
- {
-#if CONFIG_LPC_TPM && !CONFIG_TPM_DEACTIVATE
- Return (0xf)
-#else
- Return (0x0)
-#endif
- }
-
- Name (IBUF, ResourceTemplate ()
- {
- /* Updated based on TPM interrupt for Locality 0 */
- Interrupt (ResourceConsumer, Edge, ActiveHigh,
- Exclusive, , , TIRQ) { 0 }
- })
-
- Name (RBUF, ResourceTemplate ()
- {
- IO (Decode16, 0x2e, 0x2e, 0x01, 0x02)
- Memory32Fixed (ReadWrite, CONFIG_TPM_TIS_BASE_ADDRESS, 0x5000)
- })
-
- Method (_CRS, 0, Serialized)
- {
- OperationRegion (TREG, SystemMemory,
- CONFIG_TPM_TIS_BASE_ADDRESS, 0x5000)
- Field (TREG, ByteAcc, NoLock, Preserve)
- {
- /* TPM_INT_ENABLE_0 */
- Offset (0x0008),
- , 3,
- ITPL, 2, /* Interrupt type and polarity */
-
- /* TPM_INT_VECTOR_0 */
- Offset (0x000C),
- IVEC, 4, /* SERIRQ vector */
- }
-
- CreateField (^IBUF, ^TIRQ._INT, 32, TVEC)
- CreateBitField (^IBUF, ^TIRQ._HE, TTYP)
- CreateBitField (^IBUF, ^TIRQ._LL, TPOL)
- CreateBitField (^IBUF, ^TIRQ._SHR, TSHR)
-
- If (LGreater (CONFIG_TPM_PIRQ, 0)) {
- /*
- * PIRQ: Update interrupt vector with configured PIRQ
- */
- Store (CONFIG_TPM_PIRQ, TVEC)
-
- /* Active-Low Level-Triggered Shared */
- Store (One, TPOL)
- Store (Zero, TTYP)
- Store (One, TSHR)
-
- /* Merge IRQ with base address */
- Return (ConcatenateResTemplate (RBUF, IBUF))
- } ElseIf (LGreater (IVEC, 0)) {
- /*
- * SERIRQ: Update interrupt vector based on TPM register
- */
- Store (IVEC, TVEC)
-
- If (LEqual (ITPL, 0x0)) {
- /* Active-High Level-Triggered Shared */
- Store (Zero, TPOL)
- Store (Zero, TTYP)
- Store (One, TSHR)
- } ElseIf (LEqual (ITPL, 0x1)) {
- /* Active-Low Level-Triggered Shared */
- Store (One, TPOL)
- Store (Zero, TTYP)
- Store (One, TSHR)
- } ElseIf (LEqual (ITPL, 0x2)) {
- /* Active-High Edge-Triggered Exclusive */
- Store (Zero, TPOL)
- Store (One, TTYP)
- Store (Zero, TSHR)
- } ElseIf (LEqual (ITPL, 0x3)) {
- /* Active-Low Edge-Triggered Exclusive */
- Store (One, TPOL)
- Store (One, TTYP)
- Store (Zero, TSHR)
- }
-
- /* Merge IRQ with base address */
- Return (ConcatenateResTemplate (RBUF, IBUF))
- } Else {
- Return (RBUF)
- }
- }
-
- /* Dummy _DSM to make Bitlocker work. */
- Method (_DSM, 4, Serialized)
- {
- /* Physical presence interface.
- This is used to submit commands like "Clear TPM" to
- be run at next reboot provided that user confirms them.
- Spec allows user to cancel all commands and/or
- configure BIOS to reject commands. So we pretend that
- user did just this: cancelled everything. If user
- really wants to clear TPM the only option now is to do it manually
- in payload.
- */
- If (LEqual (Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
- {
- If (LEqual (Arg2, 0))
- {
- /* Functions 1-8. */
- Return (Buffer (2) { 0xFF, 0x01 })
- }
-
- /* Interface version: 1.2 */
- If (LEqual (Arg2, 1))
- {
- Return ("1.2")
- }
-
- /* Submit operations: drop on the floor and return success. */
- If (LEqual (Arg2, 2))
- {
- Return (0x00)
- }
-
- /* Pending operation: none. */
- If (LEqual (Arg2, 3))
- {
- Return (Package (2) { 0, 0 })
- }
-
- /* Pre-OS transition method: reboot. */
- If (LEqual (Arg2, 4))
- {
- Return (2)
- }
-
- /* Operation response: no operation executed. */
- If (LEqual (Arg2, 5))
- {
- Return (Package (3) { 0, 0, 0 })
- }
-
- /* Set preffered user language: deprecated and must return 3 aka "not implemented". */
- If (LEqual (Arg2, 6))
- {
- Return (3)
- }
-
- /* Submit operations: deny. */
- If (LEqual (Arg2, 7))
- {
- Return (3)
- }
-
- /* All actions are forbidden. */
- If (LEqual (Arg2, 8))
- {
- Return (1)
- }
-
- Return (1)
- }
-
- /* Memory clearing on boot: just a dummy. */
- If (LEqual (Arg0, ToUUID("376054ed-cc13-4675-901c-4756d7f2d45d")))
- {
- If (LEqual (Arg2, 0))
- {
- /* Function 1. */
- Return (Buffer (1) { 3 })
- }
-
- /* Just return success. */
- If (LEqual (Arg2, 1))
- {
- Return (0)
- }
-
- Return (1)
- }
-
- Return (Buffer (1) { 0 })
- }
-}
diff --git a/src/drivers/pc80/tpm/chip.h b/src/drivers/pc80/tpm/chip.h
deleted file mode 100644
index b13d23c..0000000
--- a/src/drivers/pc80/tpm/chip.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef DRIVERS_PC80_TPM_CHIP_H
-#define DRIVERS_PC80_TPM_CHIP_H
-
-typedef struct drivers_pc80_tpm_config {
- /*
- * TPM Interrupt polarity:
- *
- * High Level 0
- * Low Level 1
- * Rising Edge 2
- * Falling Edge 3
- */
- u8 irq_polarity;
-} tpm_config_t;
-
-#endif /* DRIVERS_PC80_TPM_CHIP_H */
diff --git a/src/drivers/pc80/tpm/romstage.c b/src/drivers/pc80/tpm/romstage.c
deleted file mode 100644
index b8b9b36..0000000
--- a/src/drivers/pc80/tpm/romstage.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <types.h>
-#include <console/cbmem_console.h>
-#include <console/console.h>
-#include <arch/acpi.h>
-#include <tpm.h>
-#include <reset.h>
-
-//#define EXTRA_LOGGING
-
-#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
-
-#define TPM_SUCCESS ((u32)0x00000000)
-
-#define TPM_E_IOERROR ((u32)0x0000001f)
-#define TPM_E_COMMUNICATION_ERROR ((u32)0x00005004)
-#define TPM_E_NON_FATAL ((u32)0x00000800)
-#define TPM_E_INVALID_POSTINIT ((u32)0x00000026)
-
-#define TPM_E_NEEDS_SELFTEST ((u32)(TPM_E_NON_FATAL + 1))
-#define TPM_E_DOING_SELFTEST ((u32)(TPM_E_NON_FATAL + 2))
-
-static const struct {
- u8 buffer[12];
-} tpm_resume_cmd = {
- { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x2 }
-};
-
-static const struct {
- u8 buffer[12];
-} tpm_startup_cmd = {
- {0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1 }
-};
-
-static const struct {
- u8 buffer[12];
-} tpm_deactivate_cmd = {
- {0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x3 }
-};
-
-static const struct {
- u8 buffer[10];
-} tpm_continueselftest_cmd = {
- { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53 }
-};
-
-static inline void FromTpmUint32(const u8 * buffer, u32 * x)
-{
- *x = ((buffer[0] << 24) |
- (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]);
-}
-
-static inline int TpmCommandSize(const u8 * buffer)
-{
- u32 size;
- FromTpmUint32(buffer + sizeof(u16), &size);
- return (int)size;
-}
-
-/* Gets the code field of a TPM command. */
-static inline int TpmCommandCode(const u8 * buffer)
-{
- u32 code;
- FromTpmUint32(buffer + sizeof(u16) + sizeof(u32), &code);
- return code;
-}
-
-/* Gets the return code field of a TPM result. */
-static inline int TpmReturnCode(const u8 * buffer)
-{
- return TpmCommandCode(buffer);
-}
-
-/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or
- * DOING_SELFTEST errors are returned.
- */
-static u32 TlclSendReceiveNoRetry(const u8 * request,
- u8 * response, int max_length)
-{
- size_t response_length = max_length;
- u32 result;
-
-#ifdef EXTRA_LOGGING
- printk(BIOS_DEBUG, "TPM: command: %x%x %x%x%x%x %x%x%x%x\n",
- request[0], request[1],
- request[2], request[3], request[4], request[5],
- request[6], request[7], request[8], request[9]);
-#endif
-
- result = TPM_SUCCESS;
- if (tis_sendrecv
- (request, TpmCommandSize(request), response, &response_length))
- result = TPM_E_IOERROR;
-
- if (0 != result) {
- /* Communication with TPM failed, so response is garbage */
- printk(BIOS_DEBUG,
- "TPM: command 0x%x send/receive failed: 0x%x\n",
- TpmCommandCode(request), result);
- return TPM_E_COMMUNICATION_ERROR;
- }
- /* Otherwise, use the result code from the response */
- result = TpmReturnCode(response);
-
-/* TODO: add paranoia about returned response_length vs. max_length
- * (and possibly expected length from the response header). See
- * crosbug.com/17017 */
-
-#ifdef EXTRA_LOGGING
- printk(BIOS_DEBUG, "TPM: response: %x%x %x%x%x%x %x%x%x%x\n",
- response[0], response[1],
- response[2], response[3], response[4], response[5],
- response[6], response[7], response[8], response[9]);
-#endif
-
- printk(BIOS_DEBUG, "TPM: command 0x%x returned 0x%x\n",
- TpmCommandCode(request), result);
-
- return result;
-}
-
-static inline u32 TlclContinueSelfTest(void)
-{
- u8 response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- printk(BIOS_DEBUG, "TPM: Continue self test\n");
- /* Call the No Retry version of SendReceive to avoid recursion. */
- return TlclSendReceiveNoRetry(tpm_continueselftest_cmd.buffer,
- response, sizeof(response));
-}
-
-/* Sends a TPM command and gets a response. Returns 0 if success or the TPM
- * error code if error. In the firmware, waits for the self test to complete
- * if needed. In the host, reports the first error without retries. */
-static u32 TlclSendReceive(const u8 * request, u8 * response, int max_length)
-{
- u32 result = TlclSendReceiveNoRetry(request, response, max_length);
- /* When compiling for the firmware, hide command failures due to the self
- * test not having run or completed. */
- /* If the command fails because the self test has not completed, try it
- * again after attempting to ensure that the self test has completed. */
- if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) {
- result = TlclContinueSelfTest();
- if (result != TPM_SUCCESS) {
- return result;
- }
-#if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE)
- /* Retry only once */
- result = TlclSendReceiveNoRetry(request, response, max_length);
-#else
- /* This needs serious testing. The TPM specification says:
- * "iii. The caller MUST wait for the actions of
- * TPM_ContinueSelfTest to complete before reissuing the
- * command C1." But, if ContinueSelfTest is non-blocking, how
- * do we know that the actions have completed other than trying
- * again? */
- do {
- result =
- TlclSendReceiveNoRetry(request, response,
- max_length);
- } while (result == TPM_E_DOING_SELFTEST);
-#endif
- }
-
- return result;
-}
-
-void init_tpm(int s3resume)
-{
- u32 result;
- u8 response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
-
- if (CONFIG_TPM_DEACTIVATE) {
- printk(BIOS_SPEW, "TPM: Deactivate\n");
- result = TlclSendReceive(tpm_deactivate_cmd.buffer,
- response, sizeof(response));
- if (result == TPM_SUCCESS) {
- printk(BIOS_SPEW, "TPM: OK.\n");
- return;
- }
-
- printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result);
- return;
- }
-
- /* Doing TPM startup when we're not coming in on the S3 resume path
- * saves us roughly 20ms in boot time only. This does not seem to
- * be worth an API change to vboot_reference-firmware right now, so
- * let's keep the code around, but just bail out early:
- */
- if (s3resume ? CONFIG_NO_TPM_RESUME
- : CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT)
- return;
-
- printk(BIOS_DEBUG, "TPM initialization.\n");
-
- printk(BIOS_SPEW, "TPM: Init\n");
- if (tis_init())
- return;
-
- printk(BIOS_SPEW, "TPM: Open\n");
- if (tis_open())
- return;
-
-
- if (s3resume) {
- /* S3 Resume */
- printk(BIOS_SPEW, "TPM: Resume\n");
- result = TlclSendReceive(tpm_resume_cmd.buffer,
- response, sizeof(response));
- if (result == TPM_E_INVALID_POSTINIT) {
- /* We're on a platform where the TPM maintains power
- * in S3, so it's already initialized.
- */
- printk(BIOS_DEBUG, "TPM: Already initialized.\n");
- return;
- }
- } else {
- printk(BIOS_SPEW, "TPM: Startup\n");
- result = TlclSendReceive(tpm_startup_cmd.buffer,
- response, sizeof(response));
- }
-
- if (result == TPM_SUCCESS) {
- printk(BIOS_SPEW, "TPM: OK.\n");
- return;
- }
-
- printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result);
-
- if (CONFIG_TPM_INIT_FAILURE_IS_FATAL) {
- printk(BIOS_ERR, "Hard reset!\n");
- post_code(POST_TPM_FAILURE);
- if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART))
- cbmem_dump_console();
- hard_reset();
- }
-}
diff --git a/src/drivers/pc80/tpm/tpm.c b/src/drivers/pc80/tpm/tpm.c
deleted file mode 100644
index 064cb99..0000000
--- a/src/drivers/pc80/tpm/tpm.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/*
- * The code in this file has been heavily based on the article "Writing a TPM
- * Device Driver" published on http://ptgmedia.pearsoncmg.com and the
- * submission by Stefan Berger on Qemu-devel mailing list.
- *
- * One principal difference is that in the simplest config the other than 0
- * TPM localities do not get mapped by some devices (for instance, by
- * Infineon slb9635), so this driver provides access to locality 0 only.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <delay.h>
-#include <arch/io.h>
-#include <console/console.h>
-#include <tpm.h>
-#include <arch/early_variables.h>
-#include <device/pnp.h>
-#include "chip.h"
-
-#define PREFIX "lpc_tpm: "
-
-/* coreboot wrapper for TPM driver (start) */
-#define TPM_DEBUG(fmt, args...) \
- if (CONFIG_DEBUG_TPM) { \
- printk(BIOS_DEBUG, PREFIX); \
- printk(BIOS_DEBUG, fmt , ##args); \
- }
-#define TPM_DEBUG_IO_READ(reg_, val_) \
- TPM_DEBUG("Read reg 0x%x returns 0x%x\n", (reg_), (val_))
-#define TPM_DEBUG_IO_WRITE(reg_, val_) \
- TPM_DEBUG("Write reg 0x%x with 0x%x\n", (reg_), (val_))
-#define printf(x...) printk(BIOS_ERR, x)
-
-/* coreboot wrapper for TPM driver (end) */
-
-/* the macro accepts the locality value, but only locality 0 is operational */
-#define TIS_REG(LOCALITY, REG) \
- (void *)(CONFIG_TPM_TIS_BASE_ADDRESS + (LOCALITY << 12) + REG)
-
-/* hardware registers' offsets */
-#define TIS_REG_ACCESS 0x0
-#define TIS_REG_INT_ENABLE 0x8
-#define TIS_REG_INT_VECTOR 0xc
-#define TIS_REG_INT_STATUS 0x10
-#define TIS_REG_INTF_CAPABILITY 0x14
-#define TIS_REG_STS 0x18
-#define TIS_REG_BURST_COUNT 0x19
-#define TIS_REG_DATA_FIFO 0x24
-#define TIS_REG_DID_VID 0xf00
-#define TIS_REG_RID 0xf04
-
-/* Some registers' bit field definitions */
-#define TIS_STS_VALID (1 << 7) /* 0x80 */
-#define TIS_STS_COMMAND_READY (1 << 6) /* 0x40 */
-#define TIS_STS_TPM_GO (1 << 5) /* 0x20 */
-#define TIS_STS_DATA_AVAILABLE (1 << 4) /* 0x10 */
-#define TIS_STS_EXPECT (1 << 3) /* 0x08 */
-#define TIS_STS_RESPONSE_RETRY (1 << 1) /* 0x02 */
-
-#define TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */
-#define TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */
-#define TIS_ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */
-#define TIS_ACCESS_SEIZE (1 << 3) /* 0x08 */
-#define TIS_ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */
-#define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */
-#define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
-
-/*
- * Error value returned if a tpm register does not enter the expected state
- * after continuous polling. No actual TPM register reading ever returns ~0,
- * so this value is a safe error indication to be mixed with possible status
- * register values.
- */
-#define TPM_TIMEOUT_ERR (~0)
-
-/* Error value returned on various TPM driver errors */
-#define TPM_DRIVER_ERR (~0)
-
- /* 1 second is plenty for anything TPM does.*/
-#define MAX_DELAY_US (1000 * 1000)
-
-/*
- * Structures defined below allow creating descriptions of TPM vendor/device
- * ID information for run time discovery. The only device the system knows
- * about at this time is Infineon slb9635
- */
-struct device_name {
- u16 dev_id;
- const char * const dev_name;
-};
-
-struct vendor_name {
- u16 vendor_id;
- const char * vendor_name;
- const struct device_name* dev_names;
-};
-
-static const struct device_name atmel_devices[] = {
- {0x3204, "AT97SC3204"},
- {0xffff}
-};
-
-static const struct device_name infineon_devices[] = {
- {0x000b, "SLB9635 TT 1.2"},
- {0x001a, "SLB9660 TT 1.2"},
- {0x001b, "SLB9670 TT 1.2"},
- {0xffff}
-};
-
-static const struct device_name nuvoton_devices[] = {
- {0x00fe, "NPCT420AA V2"},
- {0xffff}
-};
-
-static const struct device_name stmicro_devices[] = {
- {0x0000, "ST33ZP24" },
- {0xffff}
-};
-
-static const struct vendor_name vendor_names[] = {
- {0x1114, "Atmel", atmel_devices},
- {0x15d1, "Infineon", infineon_devices},
- {0x1050, "Nuvoton", nuvoton_devices},
- {0x104a, "ST Microelectronics", stmicro_devices},
-};
-
-/*
- * Cached vendor/device ID pair to indicate that the device has been already
- * discovered
- */
-static u32 vendor_dev_id CAR_GLOBAL;
-
-static inline u8 tpm_read_status(int locality)
-{
- u8 value = read8(TIS_REG(locality, TIS_REG_STS));
- TPM_DEBUG_IO_READ(TIS_REG_STS, value);
- return value;
-}
-
-static inline void tpm_write_status(u8 sts, int locality)
-{
- TPM_DEBUG_IO_WRITE(TIS_REG_STS, sts);
- write8(TIS_REG(locality, TIS_REG_STS), sts);
-}
-
-static inline u8 tpm_read_data(int locality)
-{
- u8 value = read8(TIS_REG(locality, TIS_REG_DATA_FIFO));
- TPM_DEBUG_IO_READ(TIS_REG_DATA_FIFO, value);
- return value;
-}
-
-static inline void tpm_write_data(u8 data, int locality)
-{
- TPM_DEBUG_IO_WRITE(TIS_REG_STS, data);
- write8(TIS_REG(locality, TIS_REG_DATA_FIFO), data);
-}
-
-static inline u16 tpm_read_burst_count(int locality)
-{
- u16 count;
- count = read8(TIS_REG(locality, TIS_REG_BURST_COUNT));
- count |= read8(TIS_REG(locality, TIS_REG_BURST_COUNT + 1)) << 8;
- TPM_DEBUG_IO_READ(TIS_REG_BURST_COUNT, count);
- return count;
-}
-
-static inline u8 tpm_read_access(int locality)
-{
- u8 value = read8(TIS_REG(locality, TIS_REG_ACCESS));
- TPM_DEBUG_IO_READ(TIS_REG_ACCESS, value);
- return value;
-}
-
-static inline void tpm_write_access(u8 data, int locality)
-{
- TPM_DEBUG_IO_WRITE(TIS_REG_ACCESS, data);
- write8(TIS_REG(locality, TIS_REG_ACCESS), data);
-}
-
-static inline u32 tpm_read_did_vid(int locality)
-{
- u32 value = read32(TIS_REG(locality, TIS_REG_DID_VID));
- TPM_DEBUG_IO_READ(TIS_REG_DID_VID, value);
- return value;
-}
-
-static inline void tpm_write_int_vector(int vector, int locality)
-{
- TPM_DEBUG_IO_WRITE(TIS_REG_INT_VECTOR, vector);
- write8(TIS_REG(locality, TIS_REG_INT_VECTOR), vector & 0xf);
-}
-
-static inline void tpm_write_int_polarity(int polarity, int locality)
-{
- /* Set polarity and leave all other bits at 0 */
- u32 value = (polarity & 0x3) << 3;
- TPM_DEBUG_IO_WRITE(TIS_REG_INT_ENABLE, value);
- write32(TIS_REG(locality, TIS_REG_INT_ENABLE), value);
-}
-
-/*
- * tis_wait_sts()
- *
- * Wait for at least a second for a status to change its state to match the
- * expected state. Normally the transition happens within microseconds.
- *
- * @locality - locality
- * @mask - bitmask for the bitfield(s) to watch
- * @expected - value the field(s) are supposed to be set to
- *
- * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
- */
-static int tis_wait_sts(int locality, u8 mask, u8 expected)
-{
- u32 time_us = MAX_DELAY_US;
- while (time_us > 0) {
- u8 value = tpm_read_status(locality);
- if ((value & mask) == expected)
- return 0;
- udelay(1); /* 1 us */
- time_us--;
- }
- return TPM_TIMEOUT_ERR;
-}
-
-static inline int tis_wait_ready(int locality)
-{
- return tis_wait_sts(locality, TIS_STS_COMMAND_READY,
- TIS_STS_COMMAND_READY);
-}
-
-static inline int tis_wait_valid(int locality)
-{
- return tis_wait_sts(locality, TIS_STS_VALID, TIS_STS_VALID);
-}
-
-static inline int tis_wait_valid_data(int locality)
-{
- const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
- return tis_wait_sts(locality, has_data, has_data);
-}
-
-static inline int tis_has_valid_data(int locality)
-{
- const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
- return (tpm_read_status(locality) & has_data) == has_data;
-}
-
-static inline int tis_expect_data(int locality)
-{
- return !!(tpm_read_status(locality) & TIS_STS_EXPECT);
-}
-
-/*
- * tis_wait_access()
- *
- * Wait for at least a second for a access to change its state to match the
- * expected state. Normally the transition happens within microseconds.
- *
- * @locality - locality
- * @mask - bitmask for the bitfield(s) to watch
- * @expected - value the field(s) are supposed to be set to
- *
- * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
- */
-static int tis_wait_access(int locality, u8 mask, u8 expected)
-{
- u32 time_us = MAX_DELAY_US;
- while (time_us > 0) {
- u8 value = tpm_read_access(locality);
- if ((value & mask) == expected)
- return 0;
- udelay(1); /* 1 us */
- time_us--;
- }
- return TPM_TIMEOUT_ERR;
-}
-
-static inline int tis_wait_dropped_access(int locality)
-{
- return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY, 0);
-}
-
-static inline int tis_wait_received_access(int locality)
-{
- return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY,
- TIS_ACCESS_ACTIVE_LOCALITY);
-}
-
-static inline int tis_has_access(int locality)
-{
- return !!(tpm_read_access(locality) & TIS_ACCESS_ACTIVE_LOCALITY);
-}
-
-static inline void tis_request_access(int locality)
-{
- tpm_write_access(TIS_ACCESS_REQUEST_USE, locality);
-}
-
-static inline void tis_drop_access(int locality)
-{
- tpm_write_access(TIS_ACCESS_ACTIVE_LOCALITY, locality);
-}
-
-/*
- * PC Client Specific TPM Interface Specification section 11.2.12:
- *
- * Software must be prepared to send two writes of a "1" to command ready
- * field: the first to indicate successful read of all the data, thus
- * clearing the data from the ReadFIFO and freeing the TPM's resources,
- * and the second to indicate to the TPM it is about to send a new command.
- *
- * In practice not all TPMs behave the same so it is necessary to be
- * flexible when trying to set command ready.
- *
- * Returns 0 on success if the TPM is ready for transactions.
- * Returns TPM_TIMEOUT_ERR if the command ready bit does not get set.
- */
-static int tis_command_ready(u8 locality)
-{
- u32 status;
-
- /* 1st attempt to set command ready */
- tpm_write_status(TIS_STS_COMMAND_READY, locality);
-
- /* Wait for response */
- status = tpm_read_status(locality);
-
- /* Check if command ready is set yet */
- if (status & TIS_STS_COMMAND_READY)
- return 0;
-
- /* 2nd attempt to set command ready */
- tpm_write_status(TIS_STS_COMMAND_READY, locality);
-
- return tis_wait_ready(locality);
-}
-
-/*
- * Probe the TPM device and try determining its manufacturer/device name.
- *
- * Returns 0 on success (the device is found or was found during an earlier
- * invocation) or TPM_DRIVER_ERR if the device is not found.
- */
-static u32 tis_probe(void)
-{
- const char *device_name = "unknown";
- const char *vendor_name = device_name;
- const struct device_name *dev;
- u32 didvid;
- u16 vid, did;
- int i;
-
- if (car_get_var(vendor_dev_id))
- return 0; /* Already probed. */
-
- didvid = tpm_read_did_vid(0);
- if (!didvid || (didvid == 0xffffffff)) {
- printf("%s: No TPM device found\n", __FUNCTION__);
- return TPM_DRIVER_ERR;
- }
-
- car_set_var(vendor_dev_id, didvid);
-
- vid = didvid & 0xffff;
- did = (didvid >> 16) & 0xffff;
- for (i = 0; i < ARRAY_SIZE(vendor_names); i++) {
- int j = 0;
- u16 known_did;
- if (vid == vendor_names[i].vendor_id) {
- vendor_name = vendor_names[i].vendor_name;
- } else {
- continue;
- }
- dev = &vendor_names[i].dev_names[j];
- while ((known_did = dev->dev_id) != 0xffff) {
- if (known_did == did) {
- device_name = dev->dev_name;
- break;
- }
- j++;
- dev = &vendor_names[i].dev_names[j];
- }
- break;
- }
- /* this will have to be converted into debug printout */
- printk(BIOS_INFO, "Found TPM %s by %s\n", device_name, vendor_name);
- return 0;
-}
-
-/*
- * tis_senddata()
- *
- * send the passed in data to the TPM device.
- *
- * @data - address of the data to send, byte by byte
- * @len - length of the data to send
- *
- * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does
- * not accept the entire command).
- */
-static u32 tis_senddata(const u8 * const data, u32 len)
-{
- u32 offset = 0;
- u16 burst = 0;
- u32 max_cycles = 0;
- u8 locality = 0;
-
- if (tis_wait_ready(locality)) {
- printf("%s:%d - failed to get 'command_ready' status\n",
- __FILE__, __LINE__);
- return TPM_DRIVER_ERR;
- }
- burst = tpm_read_burst_count(locality);
-
- while (1) {
- unsigned count;
-
- /* Wait till the device is ready to accept more data. */
- while (!burst) {
- if (max_cycles++ == MAX_DELAY_US) {
- printf("%s:%d failed to feed %d bytes of %d\n",
- __FILE__, __LINE__, len - offset, len);
- return TPM_DRIVER_ERR;
- }
- udelay(1);
- burst = tpm_read_burst_count(locality);
- }
-
- max_cycles = 0;
-
- /*
- * Calculate number of bytes the TPM is ready to accept in one
- * shot.
- *
- * We want to send the last byte outside of the loop (hence
- * the -1 below) to make sure that the 'expected' status bit
- * changes to zero exactly after the last byte is fed into the
- * FIFO.
- */
- count = min(burst, len - offset - 1);
- while (count--)
- tpm_write_data(data[offset++], locality);
-
- if (tis_wait_valid(locality) || !tis_expect_data(locality)) {
- printf("%s:%d TPM command feed overflow\n",
- __FILE__, __LINE__);
- return TPM_DRIVER_ERR;
- }
-
- burst = tpm_read_burst_count(locality);
- if ((offset == (len - 1)) && burst)
- /*
- * We need to be able to send the last byte to the
- * device, so burst size must be nonzero before we
- * break out.
- */
- break;
- }
-
- /* Send the last byte. */
- tpm_write_data(data[offset++], locality);
-
- /*
- * Verify that TPM does not expect any more data as part of this
- * command.
- */
- if (tis_wait_valid(locality) || tis_expect_data(locality)) {
- printf("%s:%d unexpected TPM status 0x%x\n",
- __FILE__, __LINE__, tpm_read_status(locality));
- return TPM_DRIVER_ERR;
- }
-
- /* OK, sitting pretty, let's start the command execution. */
- tpm_write_status(TIS_STS_TPM_GO, locality);
-
- return 0;
-}
-
-/*
- * tis_readresponse()
- *
- * read the TPM device response after a command was issued.
- *
- * @buffer - address where to read the response, byte by byte.
- * @len - pointer to the size of buffer
- *
- * On success stores the number of received bytes to len and returns 0. On
- * errors (misformatted TPM data or synchronization problems) returns
- * TPM_DRIVER_ERR.
- */
-static u32 tis_readresponse(u8 *buffer, size_t *len)
-{
- u16 burst_count;
- u32 offset = 0;
- u8 locality = 0;
- u32 expected_count = *len;
- int max_cycles = 0;
-
- /* Wait for the TPM to process the command */
- if (tis_wait_valid_data(locality)) {
- printf("%s:%d failed processing command\n", __FILE__, __LINE__);
- return TPM_DRIVER_ERR;
- }
-
- do {
- while ((burst_count = tpm_read_burst_count(locality)) == 0) {
- if (max_cycles++ == MAX_DELAY_US) {
- printf("%s:%d TPM stuck on read\n",
- __FILE__, __LINE__);
- return TPM_DRIVER_ERR;
- }
- udelay(1);
- }
-
- max_cycles = 0;
-
- while (burst_count-- && (offset < expected_count)) {
- buffer[offset++] = tpm_read_data(locality);
- if (offset == 6) {
- /*
- * We got the first six bytes of the reply,
- * let's figure out how many bytes to expect
- * total - it is stored as a 4 byte number in
- * network order, starting with offset 2 into
- * the body of the reply.
- */
- u32 real_length;
- memcpy(&real_length,
- buffer + 2,
- sizeof(real_length));
- expected_count = be32_to_cpu(real_length);
-
- if ((expected_count < offset) ||
- (expected_count > *len)) {
- printf("%s:%d bad response size %d\n",
- __FILE__, __LINE__,
- expected_count);
- return TPM_DRIVER_ERR;
- }
- }
- }
-
- /* Wait for the next portion */
- if (tis_wait_valid(locality)) {
- printf("%s:%d failed to read response\n",
- __FILE__, __LINE__);
- return TPM_DRIVER_ERR;
- }
-
- if (offset == expected_count)
- break; /* We got all we need */
-
- } while (tis_has_valid_data(locality));
-
- /* * Make sure we indeed read all there was. */
- if (tis_has_valid_data(locality)) {
- printf("%s:%d wrong receive status: %x %d bytes left\n",
- __FILE__, __LINE__, tpm_read_status(locality),
- tpm_read_burst_count(locality));
- return TPM_DRIVER_ERR;
- }
-
- /* Tell the TPM that we are done. */
- if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
- return TPM_DRIVER_ERR;
-
- *len = offset;
- return 0;
-}
-
-/*
- * tis_init()
- *
- * Initialize the TPM device. Returns 0 on success or TPM_DRIVER_ERR on
- * failure (in case device probing did not succeed).
- */
-int tis_init(void)
-{
- if (tis_probe())
- return TPM_DRIVER_ERR;
- return 0;
-}
-
-/*
- * tis_open()
- *
- * Requests access to locality 0 for the caller. After all commands have been
- * completed the caller is supposed to call tis_close().
- *
- * Returns 0 on success, TPM_DRIVER_ERR on failure.
- */
-int tis_open(void)
-{
- u8 locality = 0; /* we use locality zero for everything */
-
- if (tis_close())
- return TPM_DRIVER_ERR;
-
- /* now request access to locality */
- tis_request_access(locality);
-
- /* did we get a lock? */
- if (tis_wait_received_access(locality)) {
- printf("%s:%d - failed to lock locality %d\n",
- __FILE__, __LINE__, locality);
- return TPM_DRIVER_ERR;
- }
-
- /* Certain TPMs seem to need some delay here or they hang... */
- udelay(10);
-
- if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
- return TPM_DRIVER_ERR;
-
- return 0;
-}
-
-/*
- * tis_close()
- *
- * terminate the current session with the TPM by releasing the locked
- * locality. Returns 0 on success of TPM_DRIVER_ERR on failure (in case lock
- * removal did not succeed).
- */
-int tis_close(void)
-{
- u8 locality = 0;
- if (tis_has_access(locality)) {
- tis_drop_access(locality);
- if (tis_wait_dropped_access(locality)) {
- printf("%s:%d - failed to release locality %d\n",
- __FILE__, __LINE__, locality);
- return TPM_DRIVER_ERR;
- }
- }
- return 0;
-}
-
-/*
- * tis_sendrecv()
- *
- * Send the requested data to the TPM and then try to get its response
- *
- * @sendbuf - buffer of the data to send
- * @send_size size of the data to send
- * @recvbuf - memory to save the response to
- * @recv_len - pointer to the size of the response buffer
- *
- * Returns 0 on success (and places the number of response bytes at recv_len)
- * or TPM_DRIVER_ERR on failure.
- */
-int tis_sendrecv(const uint8_t *sendbuf, size_t send_size,
- uint8_t *recvbuf, size_t *recv_len)
-{
- if (tis_senddata(sendbuf, send_size)) {
- printf("%s:%d failed sending data to TPM\n",
- __FILE__, __LINE__);
- return TPM_DRIVER_ERR;
- }
-
- return tis_readresponse(recvbuf, recv_len);
-}
-
-#ifdef __RAMSTAGE__
-
-/*
- * tis_setup_interrupt()
- *
- * Set up the interrupt vector and polarity for locality 0 and
- * disable all interrupts so they are unused in firmware but can
- * be enabled by the OS.
- *
- * The values used here must match what is passed in the TPM ACPI
- * device if ACPI is used on the platform.
- *
- * @vector - TPM interrupt vector
- * @polarity - TPM interrupt polarity
- *
- * Returns 0 on success, TPM_DRIVER_ERR on failure.
- */
-static int tis_setup_interrupt(int vector, int polarity)
-{
- u8 locality = 0;
- int has_access = tis_has_access(locality);
-
- /* Open connection and request access if not already granted */
- if (!has_access && tis_open() < 0)
- return TPM_DRIVER_ERR;
-
- /* Set TPM interrupt vector */
- tpm_write_int_vector(vector, locality);
-
- /* Set TPM interupt polarity and disable interrupts */
- tpm_write_int_polarity(polarity, locality);
-
- /* Close connection if it was opened */
- if (!has_access && tis_close() < 0)
- return TPM_DRIVER_ERR;
-
- return 0;
-}
-
-static void lpc_tpm_read_resources(struct device *dev)
-{
- /* Static 5K memory region specified in Kconfig */
- mmio_resource(dev, 0, CONFIG_TPM_TIS_BASE_ADDRESS >> 10, 0x5000 >> 10);
-}
-
-static void lpc_tpm_set_resources(struct device *dev)
-{
- tpm_config_t *config = (tpm_config_t *)dev->chip_info;
- struct resource *res;
-
- for (res = dev->resource_list; res; res = res->next) {
- if (!(res->flags & IORESOURCE_ASSIGNED))
- continue;
-
- if (res->flags & IORESOURCE_IRQ) {
- /* Set interrupt vector */
- tis_setup_interrupt((int)res->base,
- config->irq_polarity);
- } else {
- continue;
- }
-
- res->flags |= IORESOURCE_STORED;
- report_resource_stored(dev, res, " <tpm>");
- }
-}
-
-static struct device_operations lpc_tpm_ops = {
- .read_resources = &lpc_tpm_read_resources,
- .set_resources = &lpc_tpm_set_resources,
-};
-
-static struct pnp_info pnp_dev_info[] = {
- { .flags = PNP_IRQ0 }
-};
-
-static void enable_dev(struct device *dev)
-{
- pnp_enable_devices(dev, &lpc_tpm_ops,
- ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
-}
-
-struct chip_operations drivers_pc80_tpm_ops = {
- CHIP_NAME("LPC TPM")
- .enable_dev = enable_dev
-};
-
-#endif /* __RAMSTAGE__ */
diff --git a/src/drivers/tpm/Kconfig b/src/drivers/tpm/Kconfig
new file mode 100644
index 0000000..5e8df7b
--- /dev/null
+++ b/src/drivers/tpm/Kconfig
@@ -0,0 +1,24 @@
+source src/drivers/tpm/lpc/Kconfig
+source src/drivers/tpm/i2c/Kconfig
+
+config TPM_INIT_FAILURE_IS_FATAL
+ bool
+ default n
+ depends on LPC_TPM || I2C_TPM
+ help
+ What to do if TPM init failed. If true, force a hard reset,
+ otherwise just log error message to console.
+
+config SKIP_TPM_STARTUP_ON_NORMAL_BOOT
+ bool
+ default n
+ depends on LPC_TPM || I2C_TPM
+ help
+ Skip TPM init on normal boot. Useful if payload does TPM init.
+
+config TPM_DEACTIVATE
+ bool "Deactivate TPM"
+ default n
+ depends on LPC_TPM || I2C_TPM
+ help
+ Deactivate TPM by issuing deactivate command.
diff --git a/src/drivers/tpm/Makefile.inc b/src/drivers/tpm/Makefile.inc
new file mode 100644
index 0000000..a7fad64
--- /dev/null
+++ b/src/drivers/tpm/Makefile.inc
@@ -0,0 +1 @@
+subdirs-y = i2c lpc
\ No newline at end of file
diff --git a/src/drivers/tpm/acpi/tpm.asl b/src/drivers/tpm/acpi/tpm.asl
new file mode 100644
index 0000000..7755e9b
--- /dev/null
+++ b/src/drivers/tpm/acpi/tpm.asl
@@ -0,0 +1,206 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Trusted Platform Module */
+
+Device (TPM)
+{
+ Name (_HID, EISAID ("PNP0C31"))
+ Name (_CID, 0x310cd041)
+ Name (_UID, 1)
+
+ Method (_STA, 0)
+ {
+#if CONFIG_LPC_TPM && !CONFIG_TPM_DEACTIVATE
+ Return (0xf)
+#else
+ Return (0x0)
+#endif
+ }
+
+ Name (IBUF, ResourceTemplate ()
+ {
+ /* Updated based on TPM interrupt for Locality 0 */
+ Interrupt (ResourceConsumer, Edge, ActiveHigh,
+ Exclusive, , , TIRQ) { 0 }
+ })
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ IO (Decode16, 0x2e, 0x2e, 0x01, 0x02)
+ Memory32Fixed (ReadWrite, CONFIG_TPM_TIS_BASE_ADDRESS, 0x5000)
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ OperationRegion (TREG, SystemMemory,
+ CONFIG_TPM_TIS_BASE_ADDRESS, 0x5000)
+ Field (TREG, ByteAcc, NoLock, Preserve)
+ {
+ /* TPM_INT_ENABLE_0 */
+ Offset (0x0008),
+ , 3,
+ ITPL, 2, /* Interrupt type and polarity */
+
+ /* TPM_INT_VECTOR_0 */
+ Offset (0x000C),
+ IVEC, 4, /* SERIRQ vector */
+ }
+
+ CreateField (^IBUF, ^TIRQ._INT, 32, TVEC)
+ CreateBitField (^IBUF, ^TIRQ._HE, TTYP)
+ CreateBitField (^IBUF, ^TIRQ._LL, TPOL)
+ CreateBitField (^IBUF, ^TIRQ._SHR, TSHR)
+
+ If (LGreater (CONFIG_TPM_PIRQ, 0)) {
+ /*
+ * PIRQ: Update interrupt vector with configured PIRQ
+ */
+ Store (CONFIG_TPM_PIRQ, TVEC)
+
+ /* Active-Low Level-Triggered Shared */
+ Store (One, TPOL)
+ Store (Zero, TTYP)
+ Store (One, TSHR)
+
+ /* Merge IRQ with base address */
+ Return (ConcatenateResTemplate (RBUF, IBUF))
+ } ElseIf (LGreater (IVEC, 0)) {
+ /*
+ * SERIRQ: Update interrupt vector based on TPM register
+ */
+ Store (IVEC, TVEC)
+
+ If (LEqual (ITPL, 0x0)) {
+ /* Active-High Level-Triggered Shared */
+ Store (Zero, TPOL)
+ Store (Zero, TTYP)
+ Store (One, TSHR)
+ } ElseIf (LEqual (ITPL, 0x1)) {
+ /* Active-Low Level-Triggered Shared */
+ Store (One, TPOL)
+ Store (Zero, TTYP)
+ Store (One, TSHR)
+ } ElseIf (LEqual (ITPL, 0x2)) {
+ /* Active-High Edge-Triggered Exclusive */
+ Store (Zero, TPOL)
+ Store (One, TTYP)
+ Store (Zero, TSHR)
+ } ElseIf (LEqual (ITPL, 0x3)) {
+ /* Active-Low Edge-Triggered Exclusive */
+ Store (One, TPOL)
+ Store (One, TTYP)
+ Store (Zero, TSHR)
+ }
+
+ /* Merge IRQ with base address */
+ Return (ConcatenateResTemplate (RBUF, IBUF))
+ } Else {
+ Return (RBUF)
+ }
+ }
+
+ /* Dummy _DSM to make Bitlocker work. */
+ Method (_DSM, 4, Serialized)
+ {
+ /* Physical presence interface.
+ This is used to submit commands like "Clear TPM" to
+ be run at next reboot provided that user confirms them.
+ Spec allows user to cancel all commands and/or
+ configure BIOS to reject commands. So we pretend that
+ user did just this: cancelled everything. If user
+ really wants to clear TPM the only option now is to do it manually
+ in payload.
+ */
+ If (LEqual (Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
+ {
+ If (LEqual (Arg2, 0))
+ {
+ /* Functions 1-8. */
+ Return (Buffer (2) { 0xFF, 0x01 })
+ }
+
+ /* Interface version: 1.2 */
+ If (LEqual (Arg2, 1))
+ {
+ Return ("1.2")
+ }
+
+ /* Submit operations: drop on the floor and return success. */
+ If (LEqual (Arg2, 2))
+ {
+ Return (0x00)
+ }
+
+ /* Pending operation: none. */
+ If (LEqual (Arg2, 3))
+ {
+ Return (Package (2) { 0, 0 })
+ }
+
+ /* Pre-OS transition method: reboot. */
+ If (LEqual (Arg2, 4))
+ {
+ Return (2)
+ }
+
+ /* Operation response: no operation executed. */
+ If (LEqual (Arg2, 5))
+ {
+ Return (Package (3) { 0, 0, 0 })
+ }
+
+ /* Set preffered user language: deprecated and must return 3 aka "not implemented". */
+ If (LEqual (Arg2, 6))
+ {
+ Return (3)
+ }
+
+ /* Submit operations: deny. */
+ If (LEqual (Arg2, 7))
+ {
+ Return (3)
+ }
+
+ /* All actions are forbidden. */
+ If (LEqual (Arg2, 8))
+ {
+ Return (1)
+ }
+
+ Return (1)
+ }
+
+ /* Memory clearing on boot: just a dummy. */
+ If (LEqual (Arg0, ToUUID("376054ed-cc13-4675-901c-4756d7f2d45d")))
+ {
+ If (LEqual (Arg2, 0))
+ {
+ /* Function 1. */
+ Return (Buffer (1) { 3 })
+ }
+
+ /* Just return success. */
+ If (LEqual (Arg2, 1))
+ {
+ Return (0)
+ }
+
+ Return (1)
+ }
+
+ Return (Buffer (1) { 0 })
+ }
+}
diff --git a/src/drivers/tpm/i2c/Kconfig b/src/drivers/tpm/i2c/Kconfig
new file mode 100644
index 0000000..82317d7
--- /dev/null
+++ b/src/drivers/tpm/i2c/Kconfig
@@ -0,0 +1,13 @@
+config I2C_TPM
+ bool "Enable TPM support"
+ depends on !PC80_SYSTEM # for now
+
+config DRIVER_TPM_I2C_BUS
+ hex "I2C TPM chip bus"
+ default 9 # FIXME, workaround for Kconfig BS
+ depends on I2C_TPM
+
+config DRIVER_TPM_I2C_ADDR
+ hex "I2C TPM chip address"
+ default 2 # FIXME, workaround for Kconfig BS
+ depends on I2C_TPM
diff --git a/src/drivers/tpm/i2c/Makefile.inc b/src/drivers/tpm/i2c/Makefile.inc
new file mode 100644
index 0000000..b415478
--- /dev/null
+++ b/src/drivers/tpm/i2c/Makefile.inc
@@ -0,0 +1,4 @@
+ramstage-$(CONFIG_I2C_TPM) += tpm.c
+romstage-$(CONFIG_I2C_TPM) += tpm.c
+verstage-$(CONFIG_I2C_TPM) += tpm.c
+bootblock-$(CONFIG_I2C_TPM) += tpm.c
diff --git a/src/drivers/tpm/i2c/chip.h b/src/drivers/tpm/i2c/chip.h
new file mode 100644
index 0000000..9ab688e
--- /dev/null
+++ b/src/drivers/tpm/i2c/chip.h
@@ -0,0 +1,98 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef DRIVERS_TPM_I2C_CHIP_H
+#define DRIVERS_TPM_I2C_CHIP_H
+
+
+enum tpm_timeout {
+ TPM_TIMEOUT = 1, /* msecs */
+};
+
+/* Size of external transmit buffer (used for stack buffer in tpm_sendrecv) */
+#define TPM_BUFSIZE 1260
+
+/* Index of fields in TPM command buffer */
+#define TPM_CMD_SIZE_BYTE 2
+#define TPM_CMD_ORDINAL_BYTE 6
+
+/* Index of Count field in TPM response buffer */
+#define TPM_RSP_SIZE_BYTE 2
+#define TPM_RSP_RC_BYTE 6
+
+struct tpm_chip;
+
+struct tpm_vendor_specific {
+ const uint8_t req_complete_mask;
+ const uint8_t req_complete_val;
+ const uint8_t req_canceled;
+ int irq;
+ int (*recv)(struct tpm_chip *, uint8_t *, size_t);
+ int (*send)(struct tpm_chip *, uint8_t *, size_t);
+ void (*cancel)(struct tpm_chip *);
+ uint8_t(*status)(struct tpm_chip *);
+ int locality;
+};
+
+struct tpm_chip {
+ int is_open;
+ struct tpm_vendor_specific vendor;
+};
+
+struct tpm_input_header {
+ uint16_t tag;
+ uint32_t length;
+ uint32_t ordinal;
+} __attribute__ ((packed));
+
+struct tpm_output_header {
+ uint16_t tag;
+ uint32_t length;
+ uint32_t return_code;
+} __attribute__ ((packed));
+
+struct timeout_t {
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ uint32_t d;
+} __attribute__ ((packed));
+
+struct duration_t {
+ uint32_t tpm_short;
+ uint32_t tpm_medium;
+ uint32_t tpm_long;
+} __attribute__ ((packed));
+
+typedef union {
+ struct timeout_t timeout;
+ struct duration_t duration;
+} cap_t;
+
+struct tpm_getcap_params_in {
+ uint32_t cap;
+ uint32_t subcap_size;
+ uint32_t subcap;
+} __attribute__ ((packed));
+
+struct tpm_getcap_params_out {
+ uint32_t cap_size;
+ cap_t cap;
+} __attribute__ ((packed));
+
+typedef union {
+ struct tpm_input_header in;
+ struct tpm_output_header out;
+} tpm_cmd_header;
+
+typedef union {
+ struct tpm_getcap_params_out getcap_out;
+ struct tpm_getcap_params_in getcap_in;
+} tpm_cmd_params;
+
+struct tpm_cmd_t {
+ tpm_cmd_header header;
+ tpm_cmd_params params;
+} __attribute__ ((packed));
+
+#endif
\ No newline at end of file
diff --git a/src/drivers/tpm/i2c/tpm.c b/src/drivers/tpm/i2c/tpm.c
new file mode 100644
index 0000000..ee97e9e
--- /dev/null
+++ b/src/drivers/tpm/i2c/tpm.c
@@ -0,0 +1,721 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external at infineon.com>
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
+ * Infineon I2C Protocol Stack Specification v0.20.
+ *
+ * It is based on the Linux kernel driver tpm.c from Leendert van
+ * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
+ *
+ * Version: 2.1.1
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <types.h>
+#include <delay.h>
+#include <console/console.h>
+#include <device/i2c.h>
+#include <endian.h>
+#include <timer.h>
+#include <assert.h>
+#include "chip.h"
+#include <tpm/tpm.h>
+
+/* Address of the TPM on the I2C bus */
+#define TPM_I2C_ADDR 0x20
+
+/* max. number of iterations after I2C NAK */
+#define MAX_COUNT 3
+
+#define SLEEP_DURATION 60 /* in usec */
+
+/* max. number of iterations after I2C NAK for 'long' commands
+ * we need this especially for sending TPM_READY, since the cleanup after the
+ * transtion to the ready state may take some time, but it is unpredictable
+ * how long it will take.
+ */
+#define MAX_COUNT_LONG 50
+
+#define SLEEP_DURATION_LONG 210 /* in usec */
+
+/* expected value for DIDVID register */
+#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
+#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
+
+#define TPM_CMD_COUNT_BYTE 2
+#define TPM_CMD_ORDINAL_BYTE 6
+#define TPM_VALID_STATUS (1 << 7)
+
+/* global structure for tpm chip data */
+struct tpm_chip g_chip;
+
+enum i2c_chip_type {
+ SLB9635,
+ SLB9645,
+ UNKNOWN,
+};
+
+static const char * const chip_name[] = {
+ [SLB9635] = "slb9635tt",
+ [SLB9645] = "slb9645tt",
+ [UNKNOWN] = "unknown/fallback to slb9635",
+};
+
+/* Structure to store I2C TPM specific stuff */
+struct tpm_inf_dev {
+ int bus;
+ unsigned int addr;
+ uint8_t buf[TPM_BUFSIZE + sizeof(uint8_t)]; // max. buffer size + addr
+ enum i2c_chip_type chip_type;
+};
+
+static struct tpm_inf_dev tpm_dev = {
+ .bus = -1,
+ .addr = TPM_I2C_ADDR
+};
+
+/*
+ * iic_tpm_read() - read from TPM register
+ * @addr: register address to read from
+ * @buffer: provided by caller
+ * @len: number of bytes to read
+ *
+ * Read len bytes from TPM register and put them into
+ * buffer (little-endian format, i.e. first byte is put into buffer[0]).
+ *
+ * NOTE: TPM is big-endian for multi-byte values. Multi-byte
+ * values have to be swapped.
+ *
+ * Return -1 on error, 0 on success.
+ */
+static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len)
+{
+ int rc;
+ int count;
+
+ if (tpm_dev.bus < 0)
+ return -1;
+ if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
+ /* slb9635 protocol should work in both cases */
+ for (count = 0; count < MAX_COUNT; count++) {
+ rc = i2c_write_raw(tpm_dev.bus, tpm_dev.addr, &addr, 1);
+ if (rc == 0)
+ break; /* success, break to skip sleep */
+
+ udelay(SLEEP_DURATION);
+ }
+
+ if (rc)
+ return -1;
+
+ /* After the TPM has successfully received the register address
+ * it needs some time, thus we're sleeping here again, before
+ * retrieving the data
+ */
+ for (count = 0; count < MAX_COUNT; count++) {
+ udelay(SLEEP_DURATION);
+ rc = i2c_read_raw(tpm_dev.bus, tpm_dev.addr,
+ buffer, len);
+ if (rc == 0)
+ break; /* success, break to skip sleep */
+
+ }
+ } else {
+ /* use a combined read for newer chips
+ * unfortunately the smbus functions are not suitable due to
+ * the 32 byte limit of the smbus.
+ * retries should usually not be needed, but are kept just to
+ * be safe on the safe side.
+ */
+ struct i2c_seg aseg = { .read = 0, .chip = tpm_dev.addr,
+ .buf = &addr, .len = 1 };
+ struct i2c_seg dseg = { .read = 1, .chip = tpm_dev.addr,
+ .buf = buffer, .len = len };
+ for (count = 0; count < MAX_COUNT; count++) {
+ rc = i2c_transfer(tpm_dev.bus, &aseg, 1) ||
+ i2c_transfer(tpm_dev.bus, &dseg, 1);
+ if (rc == 0)
+ break; /* break here to skip sleep */
+ udelay(SLEEP_DURATION);
+ }
+ }
+
+ /* take care of 'guard time' */
+ udelay(SLEEP_DURATION);
+ if (rc)
+ return -1;
+
+ return 0;
+}
+
+static int iic_tpm_write_generic(uint8_t addr, uint8_t *buffer, size_t len,
+ unsigned int sleep_time,
+ uint8_t max_count)
+{
+ int rc = 0;
+ int count;
+
+ if (len > TPM_BUFSIZE) {
+ printk(BIOS_DEBUG, "%s: Length %zd is too large\n", __func__, len);
+ return -1;
+ }
+
+ /* prepare send buffer */
+ tpm_dev.buf[0] = addr;
+ memcpy(&(tpm_dev.buf[1]), buffer, len);
+
+ if (tpm_dev.bus < 0)
+ return -1;
+ for (count = 0; count < max_count; count++) {
+ rc = i2c_write_raw(tpm_dev.bus, tpm_dev.addr,
+ tpm_dev.buf, len + 1);
+ if (rc == 0)
+ break; /* success, break to skip sleep */
+
+ udelay(sleep_time);
+ }
+
+ /* take care of 'guard time' */
+ udelay(SLEEP_DURATION);
+ if (rc)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * iic_tpm_write() - write to TPM register
+ * @addr: register address to write to
+ * @buffer: containing data to be written
+ * @len: number of bytes to write
+ *
+ * Write len bytes from provided buffer to TPM register (little
+ * endian format, i.e. buffer[0] is written as first byte).
+ *
+ * NOTE: TPM is big-endian for multi-byte values. Multi-byte
+ * values have to be swapped.
+ *
+ * NOTE: use this function instead of the iic_tpm_write_generic function.
+ *
+ * Return -EIO on error, 0 on success
+ */
+static int iic_tpm_write(uint8_t addr, uint8_t *buffer, size_t len)
+{
+ return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION,
+ MAX_COUNT);
+}
+
+/*
+ * This function is needed especially for the cleanup situation after
+ * sending TPM_READY
+ * */
+static int iic_tpm_write_long(uint8_t addr, uint8_t *buffer, size_t len)
+{
+ return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
+ MAX_COUNT_LONG);
+}
+
+#define TPM_HEADER_SIZE 10
+
+enum tis_access {
+ TPM_ACCESS_VALID = 0x80,
+ TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
+ TPM_ACCESS_REQUEST_PENDING = 0x04,
+ TPM_ACCESS_REQUEST_USE = 0x02,
+};
+
+enum tis_status {
+ TPM_STS_VALID = 0x80,
+ TPM_STS_COMMAND_READY = 0x40,
+ TPM_STS_GO = 0x20,
+ TPM_STS_DATA_AVAIL = 0x10,
+ TPM_STS_DATA_EXPECT = 0x08,
+};
+
+#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
+#define TPM_STS(l) (0x0001 | ((l) << 4))
+#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
+#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
+
+static int check_locality(struct tpm_chip *chip, int loc)
+{
+ uint8_t buf;
+
+ if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
+ return -1;
+
+ if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
+ chip->vendor.locality = loc;
+ return loc;
+ }
+
+ return -1;
+}
+
+static void release_locality(struct tpm_chip *chip, int loc, int force)
+{
+ uint8_t buf;
+ if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
+ return;
+
+ if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
+ buf = TPM_ACCESS_ACTIVE_LOCALITY;
+ iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+ }
+}
+
+static int request_locality(struct tpm_chip *chip, int loc)
+{
+ uint8_t buf = TPM_ACCESS_REQUEST_USE;
+
+ if (check_locality(chip, loc) >= 0)
+ return loc; /* we already have the locality */
+
+ iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+
+ /* wait for burstcount */
+ int timeout = 2 * 1000; /* 2s timeout */
+ while (timeout) {
+ if (check_locality(chip, loc) >= 0)
+ return loc;
+ mdelay(TPM_TIMEOUT);
+ timeout--;
+ }
+
+ return -1;
+}
+
+static uint8_t tpm_tis_i2c_status(struct tpm_chip *chip)
+{
+ /* NOTE: Since I2C read may fail, return 0 in this case --> time-out */
+ uint8_t buf;
+ if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
+ return 0;
+ else
+ return buf;
+}
+
+static void tpm_tis_i2c_ready(struct tpm_chip *chip)
+{
+ /* this causes the current command to be aborted */
+ uint8_t buf = TPM_STS_COMMAND_READY;
+ iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
+}
+
+static ssize_t get_burstcount(struct tpm_chip *chip)
+{
+ ssize_t burstcnt;
+ uint8_t buf[3];
+
+ /* wait for burstcount */
+ int timeout = 2 * 1000; /* 2s timeout */
+ while (timeout) {
+ /* Note: STS is little endian */
+ if (iic_tpm_read(TPM_STS(chip->vendor.locality) + 1, buf, 3) < 0)
+ burstcnt = 0;
+ else
+ burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
+
+ if (burstcnt)
+ return burstcnt;
+ mdelay(TPM_TIMEOUT);
+ timeout--;
+ }
+ return -1;
+}
+
+static int wait_for_stat(struct tpm_chip *chip, uint8_t mask, int *status)
+{
+ unsigned long timeout = 2 * 1024;
+ while (timeout) {
+ *status = tpm_tis_i2c_status(chip);
+ if ((*status & mask) == mask)
+ return 0;
+ mdelay(TPM_TIMEOUT);
+ timeout--;
+ }
+
+ return -1;
+}
+
+static int recv_data(struct tpm_chip *chip, uint8_t *buf, size_t count)
+{
+ size_t size = 0;
+
+ while (size < count) {
+ ssize_t burstcnt = get_burstcount(chip);
+ int rc;
+
+ /* burstcount < 0 = TPM is busy */
+ if (burstcnt < 0)
+ return burstcnt;
+
+ /* limit received data to max. left */
+ if (burstcnt > (count - size))
+ burstcnt = count - size;
+
+ rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
+ &(buf[size]),
+ burstcnt);
+ if (rc == 0)
+ size += burstcnt;
+
+ }
+ return size;
+}
+
+static int tpm_tis_i2c_recv(struct tpm_chip *chip, uint8_t *buf, size_t count)
+{
+ int size = 0;
+ uint32_t expected;
+ int status;
+
+ if (count < TPM_HEADER_SIZE) {
+ size = -1;
+ goto out;
+ }
+
+ /* read first 10 bytes, including tag, paramsize, and result */
+ size = recv_data(chip, buf, TPM_HEADER_SIZE);
+ if (size < TPM_HEADER_SIZE) {
+ printk(BIOS_DEBUG, "tpm_tis_i2c_recv: Unable to read header\n");
+ goto out;
+ }
+
+ memcpy(&expected, buf + TPM_RSP_SIZE_BYTE, sizeof(expected));
+ expected = be32_to_cpu(expected);
+ if ((size_t)expected > count) {
+ size = -1;
+ goto out;
+ }
+
+ size += recv_data(chip, &buf[TPM_HEADER_SIZE],
+ expected - TPM_HEADER_SIZE);
+ if (size < expected) {
+ printk(BIOS_DEBUG, "tpm_tis_i2c_recv: Unable to "
+ "read remainder of result\n");
+ size = -1;
+ goto out;
+ }
+
+ wait_for_stat(chip, TPM_STS_VALID, &status);
+ if (status & TPM_STS_DATA_AVAIL) { /* retry? */
+ printk(BIOS_DEBUG, "tpm_tis_i2c_recv: Error left over data\n");
+ size = -1;
+ goto out;
+ }
+
+out:
+ tpm_tis_i2c_ready(chip);
+
+ return size;
+}
+
+static int tpm_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
+{
+ int status;
+ size_t count = 0;
+ uint8_t sts = TPM_STS_GO;
+
+ if (len > TPM_BUFSIZE)
+ return -1; /* command is too long for our TPM, sorry */
+
+ status = tpm_tis_i2c_status(chip);
+ if ((status & TPM_STS_COMMAND_READY) == 0) {
+ tpm_tis_i2c_ready(chip);
+ if (wait_for_stat(chip, TPM_STS_COMMAND_READY, &status) < 0)
+ goto out_err;
+ }
+
+ while (count < len - 1) {
+ ssize_t burstcnt = get_burstcount(chip);
+
+ /* burstcount < 0 = TPM is busy */
+ if (burstcnt < 0)
+ return burstcnt;
+
+ if (burstcnt > (len-1-count))
+ burstcnt = len-1-count;
+
+#ifdef CONFIG_TPM_I2C_BURST_LIMITATION
+ if (burstcnt > CONFIG_TPM_I2C_BURST_LIMITATION)
+ burstcnt = CONFIG_TPM_I2C_BURST_LIMITATION;
+#endif /* CONFIG_TPM_I2C_BURST_LIMITATION */
+
+ if (iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
+ &(buf[count]), burstcnt) == 0)
+ count += burstcnt;
+
+ wait_for_stat(chip, TPM_STS_VALID, &status);
+ if ((status & TPM_STS_DATA_EXPECT) == 0)
+ goto out_err;
+ }
+
+ /* write last byte */
+ iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
+
+ wait_for_stat(chip, TPM_STS_VALID, &status);
+ if ((status & TPM_STS_DATA_EXPECT) != 0)
+ goto out_err;
+
+ /* go and do it */
+ iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
+
+ return len;
+
+out_err:
+ tpm_tis_i2c_ready(chip);
+
+ return -1;
+}
+
+static struct tpm_vendor_specific tpm_tis_i2c = {
+ .status = tpm_tis_i2c_status,
+ .recv = tpm_tis_i2c_recv,
+ .send = tpm_tis_i2c_send,
+ .cancel = tpm_tis_i2c_ready,
+ .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_canceled = TPM_STS_COMMAND_READY,
+};
+
+int tis_open(void)
+{
+ int rc;
+
+ if (g_chip.is_open) {
+ printk(BIOS_DEBUG, "tis_open() called twice.\n");
+ return -1;
+ }
+
+ rc = tpm_vendor_init(CONFIG_DRIVER_TPM_I2C_BUS,
+ CONFIG_DRIVER_TPM_I2C_ADDR);
+
+ if (rc < 0)
+ g_chip.is_open = 0;
+
+ if (rc) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int tis_close(void)
+{
+ if (g_chip.is_open) {
+ tpm_vendor_cleanup(&g_chip);
+ g_chip.is_open = 0;
+ }
+
+ return 0;
+}
+
+int tis_init(void)
+{
+ int bus = CONFIG_DRIVER_TPM_I2C_BUS;
+ int chip = CONFIG_DRIVER_TPM_I2C_ADDR;
+ struct stopwatch sw;
+ uint8_t buf = 0;
+ int ret;
+ long sw_run_duration = 750;
+
+ /*
+ * Probe TPM. Check if the TPM_ACCESS register's ValidSts bit is set(1)
+ * If the bit remains clear(0) then claim that init has failed.
+ */
+ stopwatch_init_msecs_expire(&sw, sw_run_duration);
+ do {
+ ret = i2c_readb(bus, chip, 0, &buf);
+ if (!ret && (buf & TPM_VALID_STATUS)) {
+ sw_run_duration = stopwatch_duration_msecs(&sw);
+ break;
+ }
+ } while (!stopwatch_expired(&sw));
+
+ printk(BIOS_INFO,
+ "%s: ValidSts bit %s(%d) in TPM_ACCESS register after %ld ms\n",
+ __func__, (buf & TPM_VALID_STATUS) ? "set" : "clear",
+ (buf & TPM_VALID_STATUS) >> 7, sw_run_duration);
+
+ /*
+ * Claim failure if the ValidSts (bit 7) is clear.
+ */
+ if (!(buf & TPM_VALID_STATUS))
+ return -1;
+
+ return 0;
+}
+
+static ssize_t tpm_transmit(const uint8_t *buf, size_t bufsiz)
+{
+ int rc;
+ uint32_t count, ordinal;
+
+ struct tpm_chip *chip = &g_chip;
+
+ memcpy(&count, buf + TPM_CMD_COUNT_BYTE, sizeof(count));
+ count = be32_to_cpu(count);
+ memcpy(&ordinal, buf + TPM_CMD_ORDINAL_BYTE, sizeof(ordinal));
+ ordinal = be32_to_cpu(ordinal);
+
+ if (count == 0) {
+ printk(BIOS_DEBUG, "tpm_transmit: no data\n");
+ return -1;
+ }
+ if (count > bufsiz) {
+ printk(BIOS_DEBUG, "tpm_transmit: invalid count value %x %zx\n",
+ count, bufsiz);
+ return -1;
+ }
+
+ ASSERT(chip->vendor.send);
+ rc = chip->vendor.send(chip, (uint8_t *) buf, count);
+ if (rc < 0) {
+ printk(BIOS_DEBUG, "tpm_transmit: tpm_send error\n");
+ goto out;
+ }
+
+ if (chip->vendor.irq)
+ goto out_recv;
+
+ int timeout = 2 * 60 * 1000; /* two minutes timeout */
+ while (timeout) {
+ ASSERT(chip->vendor.status);
+ uint8_t status = chip->vendor.status(chip);
+ if ((status & chip->vendor.req_complete_mask) ==
+ chip->vendor.req_complete_val) {
+ goto out_recv;
+ }
+
+ if ((status == chip->vendor.req_canceled)) {
+ printk(BIOS_DEBUG, "tpm_transmit: Operation Canceled\n");
+ rc = -1;
+ goto out;
+ }
+ mdelay(TPM_TIMEOUT);
+ timeout--;
+ }
+
+ ASSERT(chip->vendor.cancel);
+ chip->vendor.cancel(chip);
+ printk(BIOS_DEBUG, "tpm_transmit: Operation Timed out\n");
+ rc = -1; //ETIME;
+ goto out;
+
+out_recv:
+
+ rc = chip->vendor.recv(chip, (uint8_t *) buf, TPM_BUFSIZE);
+ if (rc < 0)
+ printk(BIOS_DEBUG, "tpm_transmit: tpm_recv: error %d\n", rc);
+out:
+ return rc;
+}
+
+int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
+ uint8_t *recvbuf, size_t *rbuf_len)
+{
+ uint8_t buf[TPM_BUFSIZE];
+
+ if (sizeof(buf) < sbuf_size)
+ return -1;
+
+ memcpy(buf, sendbuf, sbuf_size);
+
+ int len = tpm_transmit(buf, sbuf_size);
+
+ if (len < 10) {
+ *rbuf_len = 0;
+ return -1;
+ }
+
+ if (len > *rbuf_len) {
+ *rbuf_len = len;
+ return -1;
+ }
+
+ memcpy(recvbuf, buf, len);
+ *rbuf_len = len;
+
+ return 0;
+}
+
+/* Initialization of I2C TPM */
+
+int tpm_vendor_init(unsigned bus, uint32_t dev_addr)
+{
+ uint32_t vendor;
+ unsigned int old_addr;
+ struct tpm_chip *chip;
+
+ old_addr = tpm_dev.addr;
+ if (dev_addr != 0)
+ tpm_dev.addr = dev_addr;
+ tpm_dev.bus = bus;
+
+ chip = &g_chip;
+ memcpy(&chip->vendor, &tpm_tis_i2c, sizeof(struct tpm_vendor_specific));
+ chip->is_open = 1;
+
+ /* Disable interrupts (not supported) */
+ chip->vendor.irq = 0;
+
+ if (request_locality(chip, 0) != 0)
+ goto out_err;
+
+ /* Read four bytes from DID_VID register */
+ if (iic_tpm_read(TPM_DID_VID(0), (uint8_t *)&vendor, 4) < 0)
+ goto out_release;
+
+ if (vendor == TPM_TIS_I2C_DID_VID_9645) {
+ tpm_dev.chip_type = SLB9645;
+ } else if (be32_to_cpu(vendor) == TPM_TIS_I2C_DID_VID_9635) {
+ tpm_dev.chip_type = SLB9635;
+ } else {
+ printk(BIOS_DEBUG, "Vendor ID 0x%08x not recognized.\n", vendor);
+ goto out_release;
+ }
+
+ printk(BIOS_DEBUG, "1.2 TPM (chip type %s device-id 0x%X)\n",
+ chip_name[tpm_dev.chip_type], vendor >> 16);
+
+ /*
+ * A timeout query to TPM can be placed here.
+ * Standard timeout values are used so far
+ */
+
+ return 0;
+
+out_release:
+ release_locality(chip, 0, 1);
+
+out_err:
+ tpm_dev.addr = old_addr;
+ return -1;
+}
+
+void tpm_vendor_cleanup(struct tpm_chip *chip)
+{
+ release_locality(chip, chip->vendor.locality, 1);
+}
diff --git a/src/drivers/tpm/lpc/Kconfig b/src/drivers/tpm/lpc/Kconfig
new file mode 100644
index 0000000..e377e99
--- /dev/null
+++ b/src/drivers/tpm/lpc/Kconfig
@@ -0,0 +1,32 @@
+config MAINBOARD_HAS_LPC_TPM
+ bool
+ default n
+ help
+ Board has TPM support
+
+config LPC_TPM
+ bool "Enable TPM support"
+ depends on MAINBOARD_HAS_LPC_TPM
+ default n
+ help
+ Enable this option to enable LPC TPM support in coreboot.
+
+ If unsure, say N.
+
+config TPM_TIS_BASE_ADDRESS
+ hex
+ default 0xfed40000
+ depends on LPC_TPM
+ help
+ This can be used to adjust the TPM memory base address.
+ The default is specified by the TCG PC Client Specific TPM
+ Interface Specification 1.2 and should not be changed unless
+ the TPM being used does not conform to TPM TIS 1.2.
+
+config TPM_PIRQ
+ hex
+ default 0
+ depends on LPC_TPM
+ help
+ This can be used to specify a PIRQ to use instead of SERIRQ,
+ which is needed for SPI TPM interrupt support on x86.
diff --git a/src/drivers/tpm/lpc/Makefile.inc b/src/drivers/tpm/lpc/Makefile.inc
new file mode 100644
index 0000000..a592639
--- /dev/null
+++ b/src/drivers/tpm/lpc/Makefile.inc
@@ -0,0 +1,4 @@
+ramstage-$(CONFIG_LPC_TPM) += tpm.c
+romstage-$(CONFIG_LPC_TPM) += tpm.c
+verstage-$(CONFIG_LPC_TPM) += tpm.c
+bootblock-$(CONFIG_LPC_TPM) += tpm.c
diff --git a/src/drivers/tpm/lpc/chip.h b/src/drivers/tpm/lpc/chip.h
new file mode 100644
index 0000000..6b5b2c8
--- /dev/null
+++ b/src/drivers/tpm/lpc/chip.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef DRIVERS_TPM_LPC_CHIP_H
+#define DRIVERS_TPM_LPC_CHIP_H
+
+typedef struct drivers_tpm_config {
+ /*
+ * TPM Interrupt polarity:
+ *
+ * High Level 0
+ * Low Level 1
+ * Rising Edge 2
+ * Falling Edge 3
+ */
+ u8 irq_polarity;
+} tpm_config_t;
+
+#endif /* DRIVERS_TPM_LPC_CHIP_H */
diff --git a/src/drivers/tpm/lpc/tpm.c b/src/drivers/tpm/lpc/tpm.c
new file mode 100644
index 0000000..f5b9f53
--- /dev/null
+++ b/src/drivers/tpm/lpc/tpm.c
@@ -0,0 +1,769 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * The code in this file has been heavily based on the article "Writing a TPM
+ * Device Driver" published on http://ptgmedia.pearsoncmg.com and the
+ * submission by Stefan Berger on Qemu-devel mailing list.
+ *
+ * One principal difference is that in the simplest config the other than 0
+ * TPM localities do not get mapped by some devices (for instance, by
+ * Infineon slb9635), so this driver provides access to locality 0 only.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <delay.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <tpm/tpm.h>
+#include <arch/early_variables.h>
+#include <device/pnp.h>
+#include "chip.h"
+
+#define PREFIX "lpc_tpm: "
+
+/* coreboot wrapper for TPM driver (start) */
+#define TPM_DEBUG(fmt, args...) \
+ if (CONFIG_DEBUG_TPM) { \
+ printk(BIOS_DEBUG, PREFIX); \
+ printk(BIOS_DEBUG, fmt , ##args); \
+ }
+#define TPM_DEBUG_IO_READ(reg_, val_) \
+ TPM_DEBUG("Read reg 0x%x returns 0x%x\n", (reg_), (val_))
+#define TPM_DEBUG_IO_WRITE(reg_, val_) \
+ TPM_DEBUG("Write reg 0x%x with 0x%x\n", (reg_), (val_))
+#define printf(x...) printk(BIOS_ERR, x)
+
+/* coreboot wrapper for TPM driver (end) */
+
+/* the macro accepts the locality value, but only locality 0 is operational */
+#define TIS_REG(LOCALITY, REG) \
+ (void *)(CONFIG_TPM_TIS_BASE_ADDRESS + (LOCALITY << 12) + REG)
+
+/* hardware registers' offsets */
+#define TIS_REG_ACCESS 0x0
+#define TIS_REG_INT_ENABLE 0x8
+#define TIS_REG_INT_VECTOR 0xc
+#define TIS_REG_INT_STATUS 0x10
+#define TIS_REG_INTF_CAPABILITY 0x14
+#define TIS_REG_STS 0x18
+#define TIS_REG_BURST_COUNT 0x19
+#define TIS_REG_DATA_FIFO 0x24
+#define TIS_REG_DID_VID 0xf00
+#define TIS_REG_RID 0xf04
+
+/* Some registers' bit field definitions */
+#define TIS_STS_VALID (1 << 7) /* 0x80 */
+#define TIS_STS_COMMAND_READY (1 << 6) /* 0x40 */
+#define TIS_STS_TPM_GO (1 << 5) /* 0x20 */
+#define TIS_STS_DATA_AVAILABLE (1 << 4) /* 0x10 */
+#define TIS_STS_EXPECT (1 << 3) /* 0x08 */
+#define TIS_STS_RESPONSE_RETRY (1 << 1) /* 0x02 */
+
+#define TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */
+#define TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */
+#define TIS_ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */
+#define TIS_ACCESS_SEIZE (1 << 3) /* 0x08 */
+#define TIS_ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */
+#define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */
+#define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
+
+/*
+ * Error value returned if a tpm register does not enter the expected state
+ * after continuous polling. No actual TPM register reading ever returns ~0,
+ * so this value is a safe error indication to be mixed with possible status
+ * register values.
+ */
+#define TPM_TIMEOUT_ERR (~0)
+
+/* Error value returned on various TPM driver errors */
+#define TPM_DRIVER_ERR (~0)
+
+ /* 1 second is plenty for anything TPM does.*/
+#define MAX_DELAY_US (1000 * 1000)
+
+/*
+ * Structures defined below allow creating descriptions of TPM vendor/device
+ * ID information for run time discovery. The only device the system knows
+ * about at this time is Infineon slb9635
+ */
+struct device_name {
+ u16 dev_id;
+ const char * const dev_name;
+};
+
+struct vendor_name {
+ u16 vendor_id;
+ const char * vendor_name;
+ const struct device_name* dev_names;
+};
+
+static const struct device_name atmel_devices[] = {
+ {0x3204, "AT97SC3204"},
+ {0xffff}
+};
+
+static const struct device_name infineon_devices[] = {
+ {0x000b, "SLB9635 TT 1.2"},
+ {0x001a, "SLB9660 TT 1.2"},
+ {0x001b, "SLB9670 TT 1.2"},
+ {0xffff}
+};
+
+static const struct device_name nuvoton_devices[] = {
+ {0x00fe, "NPCT420AA V2"},
+ {0xffff}
+};
+
+static const struct device_name stmicro_devices[] = {
+ {0x0000, "ST33ZP24" },
+ {0xffff}
+};
+
+static const struct vendor_name vendor_names[] = {
+ {0x1114, "Atmel", atmel_devices},
+ {0x15d1, "Infineon", infineon_devices},
+ {0x1050, "Nuvoton", nuvoton_devices},
+ {0x104a, "ST Microelectronics", stmicro_devices},
+};
+
+/*
+ * Cached vendor/device ID pair to indicate that the device has been already
+ * discovered
+ */
+static u32 vendor_dev_id CAR_GLOBAL;
+
+static inline u8 tpm_read_status(int locality)
+{
+ u8 value = read8(TIS_REG(locality, TIS_REG_STS));
+ TPM_DEBUG_IO_READ(TIS_REG_STS, value);
+ return value;
+}
+
+static inline void tpm_write_status(u8 sts, int locality)
+{
+ TPM_DEBUG_IO_WRITE(TIS_REG_STS, sts);
+ write8(TIS_REG(locality, TIS_REG_STS), sts);
+}
+
+static inline u8 tpm_read_data(int locality)
+{
+ u8 value = read8(TIS_REG(locality, TIS_REG_DATA_FIFO));
+ TPM_DEBUG_IO_READ(TIS_REG_DATA_FIFO, value);
+ return value;
+}
+
+static inline void tpm_write_data(u8 data, int locality)
+{
+ TPM_DEBUG_IO_WRITE(TIS_REG_STS, data);
+ write8(TIS_REG(locality, TIS_REG_DATA_FIFO), data);
+}
+
+static inline u16 tpm_read_burst_count(int locality)
+{
+ u16 count;
+ count = read8(TIS_REG(locality, TIS_REG_BURST_COUNT));
+ count |= read8(TIS_REG(locality, TIS_REG_BURST_COUNT + 1)) << 8;
+ TPM_DEBUG_IO_READ(TIS_REG_BURST_COUNT, count);
+ return count;
+}
+
+static inline u8 tpm_read_access(int locality)
+{
+ u8 value = read8(TIS_REG(locality, TIS_REG_ACCESS));
+ TPM_DEBUG_IO_READ(TIS_REG_ACCESS, value);
+ return value;
+}
+
+static inline void tpm_write_access(u8 data, int locality)
+{
+ TPM_DEBUG_IO_WRITE(TIS_REG_ACCESS, data);
+ write8(TIS_REG(locality, TIS_REG_ACCESS), data);
+}
+
+static inline u32 tpm_read_did_vid(int locality)
+{
+ u32 value = read32(TIS_REG(locality, TIS_REG_DID_VID));
+ TPM_DEBUG_IO_READ(TIS_REG_DID_VID, value);
+ return value;
+}
+
+static inline void tpm_write_int_vector(int vector, int locality)
+{
+ TPM_DEBUG_IO_WRITE(TIS_REG_INT_VECTOR, vector);
+ write8(TIS_REG(locality, TIS_REG_INT_VECTOR), vector & 0xf);
+}
+
+static inline void tpm_write_int_polarity(int polarity, int locality)
+{
+ /* Set polarity and leave all other bits at 0 */
+ u32 value = (polarity & 0x3) << 3;
+ TPM_DEBUG_IO_WRITE(TIS_REG_INT_ENABLE, value);
+ write32(TIS_REG(locality, TIS_REG_INT_ENABLE), value);
+}
+
+/*
+ * tis_wait_sts()
+ *
+ * Wait for at least a second for a status to change its state to match the
+ * expected state. Normally the transition happens within microseconds.
+ *
+ * @locality - locality
+ * @mask - bitmask for the bitfield(s) to watch
+ * @expected - value the field(s) are supposed to be set to
+ *
+ * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
+ */
+static int tis_wait_sts(int locality, u8 mask, u8 expected)
+{
+ u32 time_us = MAX_DELAY_US;
+ while (time_us > 0) {
+ u8 value = tpm_read_status(locality);
+ if ((value & mask) == expected)
+ return 0;
+ udelay(1); /* 1 us */
+ time_us--;
+ }
+ return TPM_TIMEOUT_ERR;
+}
+
+static inline int tis_wait_ready(int locality)
+{
+ return tis_wait_sts(locality, TIS_STS_COMMAND_READY,
+ TIS_STS_COMMAND_READY);
+}
+
+static inline int tis_wait_valid(int locality)
+{
+ return tis_wait_sts(locality, TIS_STS_VALID, TIS_STS_VALID);
+}
+
+static inline int tis_wait_valid_data(int locality)
+{
+ const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
+ return tis_wait_sts(locality, has_data, has_data);
+}
+
+static inline int tis_has_valid_data(int locality)
+{
+ const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
+ return (tpm_read_status(locality) & has_data) == has_data;
+}
+
+static inline int tis_expect_data(int locality)
+{
+ return !!(tpm_read_status(locality) & TIS_STS_EXPECT);
+}
+
+/*
+ * tis_wait_access()
+ *
+ * Wait for at least a second for a access to change its state to match the
+ * expected state. Normally the transition happens within microseconds.
+ *
+ * @locality - locality
+ * @mask - bitmask for the bitfield(s) to watch
+ * @expected - value the field(s) are supposed to be set to
+ *
+ * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
+ */
+static int tis_wait_access(int locality, u8 mask, u8 expected)
+{
+ u32 time_us = MAX_DELAY_US;
+ while (time_us > 0) {
+ u8 value = tpm_read_access(locality);
+ if ((value & mask) == expected)
+ return 0;
+ udelay(1); /* 1 us */
+ time_us--;
+ }
+ return TPM_TIMEOUT_ERR;
+}
+
+static inline int tis_wait_dropped_access(int locality)
+{
+ return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY, 0);
+}
+
+static inline int tis_wait_received_access(int locality)
+{
+ return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY,
+ TIS_ACCESS_ACTIVE_LOCALITY);
+}
+
+static inline int tis_has_access(int locality)
+{
+ return !!(tpm_read_access(locality) & TIS_ACCESS_ACTIVE_LOCALITY);
+}
+
+static inline void tis_request_access(int locality)
+{
+ tpm_write_access(TIS_ACCESS_REQUEST_USE, locality);
+}
+
+static inline void tis_drop_access(int locality)
+{
+ tpm_write_access(TIS_ACCESS_ACTIVE_LOCALITY, locality);
+}
+
+/*
+ * PC Client Specific TPM Interface Specification section 11.2.12:
+ *
+ * Software must be prepared to send two writes of a "1" to command ready
+ * field: the first to indicate successful read of all the data, thus
+ * clearing the data from the ReadFIFO and freeing the TPM's resources,
+ * and the second to indicate to the TPM it is about to send a new command.
+ *
+ * In practice not all TPMs behave the same so it is necessary to be
+ * flexible when trying to set command ready.
+ *
+ * Returns 0 on success if the TPM is ready for transactions.
+ * Returns TPM_TIMEOUT_ERR if the command ready bit does not get set.
+ */
+static int tis_command_ready(u8 locality)
+{
+ u32 status;
+
+ /* 1st attempt to set command ready */
+ tpm_write_status(TIS_STS_COMMAND_READY, locality);
+
+ /* Wait for response */
+ status = tpm_read_status(locality);
+
+ /* Check if command ready is set yet */
+ if (status & TIS_STS_COMMAND_READY)
+ return 0;
+
+ /* 2nd attempt to set command ready */
+ tpm_write_status(TIS_STS_COMMAND_READY, locality);
+
+ return tis_wait_ready(locality);
+}
+
+/*
+ * Probe the TPM device and try determining its manufacturer/device name.
+ *
+ * Returns 0 on success (the device is found or was found during an earlier
+ * invocation) or TPM_DRIVER_ERR if the device is not found.
+ */
+static u32 tis_probe(void)
+{
+ const char *device_name = "unknown";
+ const char *vendor_name = device_name;
+ const struct device_name *dev;
+ u32 didvid;
+ u16 vid, did;
+ int i;
+
+ if (car_get_var(vendor_dev_id))
+ return 0; /* Already probed. */
+
+ didvid = tpm_read_did_vid(0);
+ if (!didvid || (didvid == 0xffffffff)) {
+ printf("%s: No TPM device found\n", __FUNCTION__);
+ return TPM_DRIVER_ERR;
+ }
+
+ car_set_var(vendor_dev_id, didvid);
+
+ vid = didvid & 0xffff;
+ did = (didvid >> 16) & 0xffff;
+ for (i = 0; i < ARRAY_SIZE(vendor_names); i++) {
+ int j = 0;
+ u16 known_did;
+ if (vid == vendor_names[i].vendor_id) {
+ vendor_name = vendor_names[i].vendor_name;
+ } else {
+ continue;
+ }
+ dev = &vendor_names[i].dev_names[j];
+ while ((known_did = dev->dev_id) != 0xffff) {
+ if (known_did == did) {
+ device_name = dev->dev_name;
+ break;
+ }
+ j++;
+ dev = &vendor_names[i].dev_names[j];
+ }
+ break;
+ }
+ /* this will have to be converted into debug printout */
+ printk(BIOS_INFO, "Found TPM %s by %s\n", device_name, vendor_name);
+ return 0;
+}
+
+/*
+ * tis_senddata()
+ *
+ * send the passed in data to the TPM device.
+ *
+ * @data - address of the data to send, byte by byte
+ * @len - length of the data to send
+ *
+ * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does
+ * not accept the entire command).
+ */
+static u32 tis_senddata(const u8 * const data, u32 len)
+{
+ u32 offset = 0;
+ u16 burst = 0;
+ u32 max_cycles = 0;
+ u8 locality = 0;
+
+ if (tis_wait_ready(locality)) {
+ printf("%s:%d - failed to get 'command_ready' status\n",
+ __FILE__, __LINE__);
+ return TPM_DRIVER_ERR;
+ }
+ burst = tpm_read_burst_count(locality);
+
+ while (1) {
+ unsigned count;
+
+ /* Wait till the device is ready to accept more data. */
+ while (!burst) {
+ if (max_cycles++ == MAX_DELAY_US) {
+ printf("%s:%d failed to feed %d bytes of %d\n",
+ __FILE__, __LINE__, len - offset, len);
+ return TPM_DRIVER_ERR;
+ }
+ udelay(1);
+ burst = tpm_read_burst_count(locality);
+ }
+
+ max_cycles = 0;
+
+ /*
+ * Calculate number of bytes the TPM is ready to accept in one
+ * shot.
+ *
+ * We want to send the last byte outside of the loop (hence
+ * the -1 below) to make sure that the 'expected' status bit
+ * changes to zero exactly after the last byte is fed into the
+ * FIFO.
+ */
+ count = min(burst, len - offset - 1);
+ while (count--)
+ tpm_write_data(data[offset++], locality);
+
+ if (tis_wait_valid(locality) || !tis_expect_data(locality)) {
+ printf("%s:%d TPM command feed overflow\n",
+ __FILE__, __LINE__);
+ return TPM_DRIVER_ERR;
+ }
+
+ burst = tpm_read_burst_count(locality);
+ if ((offset == (len - 1)) && burst)
+ /*
+ * We need to be able to send the last byte to the
+ * device, so burst size must be nonzero before we
+ * break out.
+ */
+ break;
+ }
+
+ /* Send the last byte. */
+ tpm_write_data(data[offset++], locality);
+
+ /*
+ * Verify that TPM does not expect any more data as part of this
+ * command.
+ */
+ if (tis_wait_valid(locality) || tis_expect_data(locality)) {
+ printf("%s:%d unexpected TPM status 0x%x\n",
+ __FILE__, __LINE__, tpm_read_status(locality));
+ return TPM_DRIVER_ERR;
+ }
+
+ /* OK, sitting pretty, let's start the command execution. */
+ tpm_write_status(TIS_STS_TPM_GO, locality);
+
+ return 0;
+}
+
+/*
+ * tis_readresponse()
+ *
+ * read the TPM device response after a command was issued.
+ *
+ * @buffer - address where to read the response, byte by byte.
+ * @len - pointer to the size of buffer
+ *
+ * On success stores the number of received bytes to len and returns 0. On
+ * errors (misformatted TPM data or synchronization problems) returns
+ * TPM_DRIVER_ERR.
+ */
+static u32 tis_readresponse(u8 *buffer, size_t *len)
+{
+ u16 burst_count;
+ u32 offset = 0;
+ u8 locality = 0;
+ u32 expected_count = *len;
+ int max_cycles = 0;
+
+ /* Wait for the TPM to process the command */
+ if (tis_wait_valid_data(locality)) {
+ printf("%s:%d failed processing command\n", __FILE__, __LINE__);
+ return TPM_DRIVER_ERR;
+ }
+
+ do {
+ while ((burst_count = tpm_read_burst_count(locality)) == 0) {
+ if (max_cycles++ == MAX_DELAY_US) {
+ printf("%s:%d TPM stuck on read\n",
+ __FILE__, __LINE__);
+ return TPM_DRIVER_ERR;
+ }
+ udelay(1);
+ }
+
+ max_cycles = 0;
+
+ while (burst_count-- && (offset < expected_count)) {
+ buffer[offset++] = tpm_read_data(locality);
+ if (offset == 6) {
+ /*
+ * We got the first six bytes of the reply,
+ * let's figure out how many bytes to expect
+ * total - it is stored as a 4 byte number in
+ * network order, starting with offset 2 into
+ * the body of the reply.
+ */
+ u32 real_length;
+ memcpy(&real_length,
+ buffer + 2,
+ sizeof(real_length));
+ expected_count = be32_to_cpu(real_length);
+
+ if ((expected_count < offset) ||
+ (expected_count > *len)) {
+ printf("%s:%d bad response size %d\n",
+ __FILE__, __LINE__,
+ expected_count);
+ return TPM_DRIVER_ERR;
+ }
+ }
+ }
+
+ /* Wait for the next portion */
+ if (tis_wait_valid(locality)) {
+ printf("%s:%d failed to read response\n",
+ __FILE__, __LINE__);
+ return TPM_DRIVER_ERR;
+ }
+
+ if (offset == expected_count)
+ break; /* We got all we need */
+
+ } while (tis_has_valid_data(locality));
+
+ /* * Make sure we indeed read all there was. */
+ if (tis_has_valid_data(locality)) {
+ printf("%s:%d wrong receive status: %x %d bytes left\n",
+ __FILE__, __LINE__, tpm_read_status(locality),
+ tpm_read_burst_count(locality));
+ return TPM_DRIVER_ERR;
+ }
+
+ /* Tell the TPM that we are done. */
+ if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
+ return TPM_DRIVER_ERR;
+
+ *len = offset;
+ return 0;
+}
+
+/*
+ * tis_init()
+ *
+ * Initialize the TPM device. Returns 0 on success or TPM_DRIVER_ERR on
+ * failure (in case device probing did not succeed).
+ */
+int tis_init(void)
+{
+ if (tis_probe())
+ return TPM_DRIVER_ERR;
+ return 0;
+}
+
+/*
+ * tis_open()
+ *
+ * Requests access to locality 0 for the caller. After all commands have been
+ * completed the caller is supposed to call tis_close().
+ *
+ * Returns 0 on success, TPM_DRIVER_ERR on failure.
+ */
+int tis_open(void)
+{
+ u8 locality = 0; /* we use locality zero for everything */
+
+ if (tis_close())
+ return TPM_DRIVER_ERR;
+
+ /* now request access to locality */
+ tis_request_access(locality);
+
+ /* did we get a lock? */
+ if (tis_wait_received_access(locality)) {
+ printf("%s:%d - failed to lock locality %d\n",
+ __FILE__, __LINE__, locality);
+ return TPM_DRIVER_ERR;
+ }
+
+ /* Certain TPMs seem to need some delay here or they hang... */
+ udelay(10);
+
+ if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
+ return TPM_DRIVER_ERR;
+
+ return 0;
+}
+
+/*
+ * tis_close()
+ *
+ * terminate the current session with the TPM by releasing the locked
+ * locality. Returns 0 on success of TPM_DRIVER_ERR on failure (in case lock
+ * removal did not succeed).
+ */
+int tis_close(void)
+{
+ u8 locality = 0;
+ if (tis_has_access(locality)) {
+ tis_drop_access(locality);
+ if (tis_wait_dropped_access(locality)) {
+ printf("%s:%d - failed to release locality %d\n",
+ __FILE__, __LINE__, locality);
+ return TPM_DRIVER_ERR;
+ }
+ }
+ return 0;
+}
+
+/*
+ * tis_sendrecv()
+ *
+ * Send the requested data to the TPM and then try to get its response
+ *
+ * @sendbuf - buffer of the data to send
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at recv_len)
+ * or TPM_DRIVER_ERR on failure.
+ */
+int tis_sendrecv(const uint8_t *sendbuf, size_t send_size,
+ uint8_t *recvbuf, size_t *recv_len)
+{
+ if (tis_senddata(sendbuf, send_size)) {
+ printf("%s:%d failed sending data to TPM\n",
+ __FILE__, __LINE__);
+ return TPM_DRIVER_ERR;
+ }
+
+ return tis_readresponse(recvbuf, recv_len);
+}
+
+#ifdef __RAMSTAGE__
+
+/*
+ * tis_setup_interrupt()
+ *
+ * Set up the interrupt vector and polarity for locality 0 and
+ * disable all interrupts so they are unused in firmware but can
+ * be enabled by the OS.
+ *
+ * The values used here must match what is passed in the TPM ACPI
+ * device if ACPI is used on the platform.
+ *
+ * @vector - TPM interrupt vector
+ * @polarity - TPM interrupt polarity
+ *
+ * Returns 0 on success, TPM_DRIVER_ERR on failure.
+ */
+static int tis_setup_interrupt(int vector, int polarity)
+{
+ u8 locality = 0;
+ int has_access = tis_has_access(locality);
+
+ /* Open connection and request access if not already granted */
+ if (!has_access && tis_open() < 0)
+ return TPM_DRIVER_ERR;
+
+ /* Set TPM interrupt vector */
+ tpm_write_int_vector(vector, locality);
+
+ /* Set TPM interupt polarity and disable interrupts */
+ tpm_write_int_polarity(polarity, locality);
+
+ /* Close connection if it was opened */
+ if (!has_access && tis_close() < 0)
+ return TPM_DRIVER_ERR;
+
+ return 0;
+}
+
+static void lpc_tpm_read_resources(struct device *dev)
+{
+ /* Static 5K memory region specified in Kconfig */
+ mmio_resource(dev, 0, CONFIG_TPM_TIS_BASE_ADDRESS >> 10, 0x5000 >> 10);
+}
+
+static void lpc_tpm_set_resources(struct device *dev)
+{
+ tpm_config_t *config = (tpm_config_t *)dev->chip_info;
+ struct resource *res;
+
+ for (res = dev->resource_list; res; res = res->next) {
+ if (!(res->flags & IORESOURCE_ASSIGNED))
+ continue;
+
+ if (res->flags & IORESOURCE_IRQ) {
+ /* Set interrupt vector */
+ tis_setup_interrupt((int)res->base,
+ config->irq_polarity);
+ } else {
+ continue;
+ }
+
+ res->flags |= IORESOURCE_STORED;
+ report_resource_stored(dev, res, " <tpm>");
+ }
+}
+
+static struct device_operations lpc_tpm_ops = {
+ .read_resources = &lpc_tpm_read_resources,
+ .set_resources = &lpc_tpm_set_resources,
+};
+
+static struct pnp_info pnp_dev_info[] = {
+ { .flags = PNP_IRQ0 }
+};
+
+static void enable_dev(struct device *dev)
+{
+ pnp_enable_devices(dev, &lpc_tpm_ops,
+ ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
+}
+
+struct chip_operations drivers_tpm_ops = {
+ CHIP_NAME("LPC TPM")
+ .enable_dev = enable_dev
+};
+
+#endif /* __RAMSTAGE__ */
diff --git a/src/include/antirollback.h b/src/include/antirollback.h
index 5ba36f7..9d3c3fd 100644
--- a/src/include/antirollback.h
+++ b/src/include/antirollback.h
@@ -9,7 +9,7 @@
#ifndef ANTIROLLBACK_H_
#define ANTIROLLBACK_H_
-#include "tpm_lite/tss_constants.h"
+#include <tpm/tss_constants.h>
struct vb2_context;
enum vb2_pcr_digest;
diff --git a/src/include/tpm.h b/src/include/tpm.h
deleted file mode 100644
index b15ca6e..0000000
--- a/src/include/tpm.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2011 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef TPM_H_
-#define TPM_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-/*
- * tis_init()
- *
- * Initialize the TPM device. Returns 0 on success or -1 on
- * failure (in case device probing did not succeed).
- */
-int tis_init(void);
-
-/*
- * tis_open()
- *
- * Requests access to locality 0 for the caller. After all commands have been
- * completed the caller is supposed to call tis_close().
- *
- * Returns 0 on success, -1 on failure.
- */
-int tis_open(void);
-
-/*
- * tis_close()
- *
- * terminate the currect session with the TPM by releasing the locked
- * locality. Returns 0 on success of -1 on failure (in case lock
- * removal did not succeed).
- */
-int tis_close(void);
-
-/*
- * tis_sendrecv()
- *
- * Send the requested data to the TPM and then try to get its response
- *
- * @sendbuf - buffer of the data to send
- * @send_size size of the data to send
- * @recvbuf - memory to save the response to
- * @recv_len - pointer to the size of the response buffer
- *
- * Returns 0 on success (and places the number of response bytes at recv_len)
- * or -1 on failure.
- */
-int tis_sendrecv(const u8 *sendbuf, size_t send_size, u8 *recvbuf,
- size_t *recv_len);
-
-void init_tpm(int s3resume);
-
-#endif /* TPM_H_ */
diff --git a/src/include/tpm/tpm.h b/src/include/tpm/tpm.h
new file mode 100644
index 0000000..0bc757e
--- /dev/null
+++ b/src/include/tpm/tpm.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2011 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef TPM_TPM_H
+#define TPM_TPM_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct tpm_chip;
+
+/*
+ * tis_init()
+ *
+ * Initialize the TPM device. Returns 0 on success or -1 on
+ * failure (in case device probing did not succeed).
+ */
+int tis_init(void);
+
+/*
+ * tis_open()
+ *
+ * Requests access to locality 0 for the caller. After all commands have been
+ * completed the caller is supposed to call tis_close().
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int tis_open(void);
+
+/*
+ * tis_close()
+ *
+ * terminate the currect session with the TPM by releasing the locked
+ * locality. Returns 0 on success of -1 on failure (in case lock
+ * removal did not succeed).
+ */
+int tis_close(void);
+
+/*
+ * tis_sendrecv()
+ *
+ * Send the requested data to the TPM and then try to get its response
+ *
+ * @sendbuf - buffer of the data to send
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at recv_len)
+ * or -1 on failure.
+ */
+int tis_sendrecv(const u8 *sendbuf, size_t send_size, u8 *recvbuf,
+ size_t *recv_len);
+
+int tpm_vendor_init(unsigned bus, uint32_t dev_addr);
+
+void tpm_vendor_cleanup(struct tpm_chip *chip);
+
+#endif /* PC80_TPM_H */
diff --git a/src/include/tpm/tspi.h b/src/include/tpm/tspi.h
new file mode 100644
index 0000000..8e1b5f0
--- /dev/null
+++ b/src/include/tpm/tspi.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 The Chromium OS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#ifndef TPM_TSPI_H
+#define TPM_TSPI_H
+
+/**
+ * TSPI Implementation for coreboot without vboot2
+ */
+void init_tpm(int s3resume);
+
+
+#endif /* TPM_TSPI_H */
\ No newline at end of file
diff --git a/src/include/tpm/tss.h b/src/include/tpm/tss.h
new file mode 100644
index 0000000..c6c4b1a
--- /dev/null
+++ b/src/include/tpm/tss.h
@@ -0,0 +1,136 @@
+/* Copyright (c) 2013 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.
+ */
+
+/*
+ * TPM Lightweight Command Library.
+ *
+ * A low-level library for interfacing to TPM hardware or an emulator.
+ */
+
+#ifndef TPM_TSS_H
+#define TPM_TSS_H
+
+#include "tss_constants.h"
+
+/*****************************************************************************/
+/* Functions implemented in tlcl.c */
+
+/**
+ * Call this first. Returns 0 if success, nonzero if error.
+ */
+uint32_t tlcl_lib_init(void);
+
+/**
+ * Perform a raw TPM request/response transaction.
+ */
+uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
+ int max_length);
+
+/* Commands */
+
+/**
+ * Send a TPM_Startup(ST_CLEAR). The TPM error code is returned (0 for
+ * success).
+ */
+uint32_t tlcl_startup(void);
+
+/**
+ * Resume by sending a TPM_Startup(ST_STATE). The TPM error code is returned
+ * (0 for success).
+ */
+uint32_t tlcl_resume(void);
+
+/**
+ * Run the self test.
+ *
+ * Note---this is synchronous. To run this in parallel with other firmware,
+ * use ContinueSelfTest(). The TPM error code is returned.
+ */
+uint32_t tlcl_self_test_full(void);
+
+/**
+ * Run the self test in the background.
+ */
+uint32_t tlcl_continue_self_test(void);
+
+/**
+ * Define a space with permission [perm]. [index] is the index for the space,
+ * [size] the usable data size. The TPM error code is returned.
+ */
+uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size);
+
+/**
+ * Write [length] bytes of [data] to space at [index]. The TPM error code is
+ * returned.
+ */
+uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length);
+
+/**
+ * Read [length] bytes from space at [index] into [data]. The TPM error code
+ * is returned.
+ */
+uint32_t tlcl_read(uint32_t index, void *data, uint32_t length);
+
+/**
+ * Assert physical presence in software. The TPM error code is returned.
+ */
+uint32_t tlcl_assert_physical_presence(void);
+
+/**
+ * Enable the physical presence command. The TPM error code is returned.
+ */
+uint32_t tlcl_physical_presence_cmd_enable(void);
+
+/**
+ * Finalize the physical presence settings: sofware PP is enabled, hardware PP
+ * is disabled, and the lifetime lock is set. The TPM error code is returned.
+ */
+uint32_t tlcl_finalize_physical_presence(void);
+
+/**
+ * Set the nvLocked bit. The TPM error code is returned.
+ */
+uint32_t tlcl_set_nv_locked(void);
+
+/**
+ * Issue a ForceClear. The TPM error code is returned.
+ */
+uint32_t tlcl_force_clear(void);
+
+/**
+ * Issue a PhysicalEnable. The TPM error code is returned.
+ */
+uint32_t tlcl_set_enable(void);
+
+/**
+ * Issue a SetDeactivated. Pass 0 to activate. Returns result code.
+ */
+uint32_t tlcl_set_deactivated(uint8_t flag);
+
+/**
+ * Get flags of interest. Pointers for flags you aren't interested in may
+ * be NULL. The TPM error code is returned.
+ */
+uint32_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated,
+ uint8_t *nvlocked);
+
+/**
+ * Set the bGlobalLock flag, which only a reboot can clear. The TPM error
+ * code is returned.
+ */
+uint32_t tlcl_set_global_lock(void);
+
+/**
+ * Perform a TPM_Extend.
+ */
+uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
+ uint8_t *out_digest);
+
+/**
+ * Get the entire set of permanent flags.
+ */
+uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags);
+
+#endif
\ No newline at end of file
diff --git a/src/include/tpm/tss_constants.h b/src/include/tpm/tss_constants.h
new file mode 100644
index 0000000..9cfbe2d
--- /dev/null
+++ b/src/include/tpm/tss_constants.h
@@ -0,0 +1,98 @@
+/* Copyright (c) 2013 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.
+ *
+ * Some TPM constants and type definitions for standalone compilation for use
+ * in the firmware
+ */
+
+#ifndef TPM_TSS_CONSTANTS_H
+#define TPM_TSS_CONSTANTS_H
+
+#include <stdint.h>
+
+#define TPM_MAX_COMMAND_SIZE 4096
+#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
+#define TPM_PUBEK_SIZE 256
+#define TPM_PCR_DIGEST 20
+
+#define TPM_E_NON_FATAL 0x800
+
+#define TPM_SUCCESS ((uint32_t)0x00000000)
+
+#define TPM_E_AREA_LOCKED ((uint32_t)0x0000003c)
+#define TPM_E_BADINDEX ((uint32_t)0x00000002)
+#define TPM_E_BAD_PRESENCE ((uint32_t)0x0000002d)
+#define TPM_E_IOERROR ((uint32_t)0x0000001f)
+#define TPM_E_INVALID_POSTINIT ((uint32_t)0x00000026)
+#define TPM_E_MAXNVWRITES ((uint32_t)0x00000048)
+#define TPM_E_OWNER_SET ((uint32_t)0x00000014)
+
+#define TPM_E_NEEDS_SELFTEST ((uint32_t)(TPM_E_NON_FATAL + 1))
+#define TPM_E_DOING_SELFTEST ((uint32_t)(TPM_E_NON_FATAL + 2))
+
+#define TPM_E_ALREADY_INITIALIZED ((uint32_t)0x00005000) /* vboot local */
+#define TPM_E_INTERNAL_INCONSISTENCY ((uint32_t)0x00005001) /* vboot local */
+#define TPM_E_MUST_REBOOT ((uint32_t)0x00005002) /* vboot local */
+#define TPM_E_CORRUPTED_STATE ((uint32_t)0x00005003) /* vboot local */
+#define TPM_E_COMMUNICATION_ERROR ((uint32_t)0x00005004) /* vboot local */
+#define TPM_E_RESPONSE_TOO_LARGE ((uint32_t)0x00005005) /* vboot local */
+#define TPM_E_NO_DEVICE ((uint32_t)0x00005006) /* vboot local */
+#define TPM_E_INPUT_TOO_SMALL ((uint32_t)0x00005007) /* vboot local */
+#define TPM_E_WRITE_FAILURE ((uint32_t)0x00005008) /* vboot local */
+#define TPM_E_READ_EMPTY ((uint32_t)0x00005009) /* vboot local */
+#define TPM_E_READ_FAILURE ((uint32_t)0x0000500a) /* vboot local */
+
+#define TPM_NV_INDEX0 ((uint32_t)0x00000000)
+#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
+#define TPM_NV_PER_GLOBALLOCK (((uint32_t)1)<<15)
+#define TPM_NV_PER_PPWRITE (((uint32_t)1)<<0)
+#define TPM_NV_PER_READ_STCLEAR (((uint32_t)1)<<31)
+#define TPM_NV_PER_WRITE_STCLEAR (((uint32_t)1)<<14)
+
+#define TPM_TAG_RQU_COMMAND ((uint16_t) 0xc1)
+#define TPM_TAG_RQU_AUTH1_COMMAND ((uint16_t) 0xc2)
+#define TPM_TAG_RQU_AUTH2_COMMAND ((uint16_t) 0xc3)
+
+#define TPM_TAG_RSP_COMMAND ((uint16_t) 0xc4)
+#define TPM_TAG_RSP_AUTH1_COMMAND ((uint16_t) 0xc5)
+#define TPM_TAG_RSP_AUTH2_COMMAND ((uint16_t) 0xc6)
+
+typedef uint8_t TSS_BOOL;
+typedef uint16_t TPM_STRUCTURE_TAG;
+
+typedef struct tdTPM_PERMANENT_FLAGS
+{
+ TPM_STRUCTURE_TAG tag;
+ TSS_BOOL disable;
+ TSS_BOOL ownership;
+ TSS_BOOL deactivated;
+ TSS_BOOL readPubek;
+ TSS_BOOL disableOwnerClear;
+ TSS_BOOL allowMaintenance;
+ TSS_BOOL physicalPresenceLifetimeLock;
+ TSS_BOOL physicalPresenceHWEnable;
+ TSS_BOOL physicalPresenceCMDEnable;
+ TSS_BOOL CEKPUsed;
+ TSS_BOOL TPMpost;
+ TSS_BOOL TPMpostLock;
+ TSS_BOOL FIPS;
+ TSS_BOOL Operator;
+ TSS_BOOL enableRevokeEK;
+ TSS_BOOL nvLocked;
+ TSS_BOOL readSRKPub;
+ TSS_BOOL tpmEstablished;
+ TSS_BOOL maintenanceDone;
+ TSS_BOOL disableFullDALogicInfo;
+} TPM_PERMANENT_FLAGS;
+
+typedef struct tdTPM_STCLEAR_FLAGS{
+ TPM_STRUCTURE_TAG tag;
+ TSS_BOOL deactivated;
+ TSS_BOOL disableForceClear;
+ TSS_BOOL physicalPresence;
+ TSS_BOOL physicalPresenceLock;
+ TSS_BOOL bGlobalLock;
+} TPM_STCLEAR_FLAGS;
+
+#endif /* TPM_TSS_CONSTANTS_H */
\ No newline at end of file
diff --git a/src/include/tpm_lite/tlcl.h b/src/include/tpm_lite/tlcl.h
deleted file mode 100644
index 7724592..0000000
--- a/src/include/tpm_lite/tlcl.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Copyright (c) 2013 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.
- */
-
-/*
- * TPM Lightweight Command Library.
- *
- * A low-level library for interfacing to TPM hardware or an emulator.
- */
-
-#ifndef TPM_LITE_TLCL_H_
-#define TPM_LITE_TLCL_H_
-#include <stdint.h>
-
-#include "tss_constants.h"
-
-/*****************************************************************************/
-/* Functions implemented in tlcl.c */
-
-/**
- * Call this first. Returns 0 if success, nonzero if error.
- */
-uint32_t tlcl_lib_init(void);
-
-/**
- * Perform a raw TPM request/response transaction.
- */
-uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
- int max_length);
-
-/* Commands */
-
-/**
- * Send a TPM_Startup(ST_CLEAR). The TPM error code is returned (0 for
- * success).
- */
-uint32_t tlcl_startup(void);
-
-/**
- * Resume by sending a TPM_Startup(ST_STATE). The TPM error code is returned
- * (0 for success).
- */
-uint32_t tlcl_resume(void);
-
-/**
- * Run the self test.
- *
- * Note---this is synchronous. To run this in parallel with other firmware,
- * use ContinueSelfTest(). The TPM error code is returned.
- */
-uint32_t tlcl_self_test_full(void);
-
-/**
- * Run the self test in the background.
- */
-uint32_t tlcl_continue_self_test(void);
-
-/**
- * Define a space with permission [perm]. [index] is the index for the space,
- * [size] the usable data size. The TPM error code is returned.
- */
-uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size);
-
-/**
- * Write [length] bytes of [data] to space at [index]. The TPM error code is
- * returned.
- */
-uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length);
-
-/**
- * Read [length] bytes from space at [index] into [data]. The TPM error code
- * is returned.
- */
-uint32_t tlcl_read(uint32_t index, void *data, uint32_t length);
-
-/**
- * Assert physical presence in software. The TPM error code is returned.
- */
-uint32_t tlcl_assert_physical_presence(void);
-
-/**
- * Enable the physical presence command. The TPM error code is returned.
- */
-uint32_t tlcl_physical_presence_cmd_enable(void);
-
-/**
- * Finalize the physical presence settings: sofware PP is enabled, hardware PP
- * is disabled, and the lifetime lock is set. The TPM error code is returned.
- */
-uint32_t tlcl_finalize_physical_presence(void);
-
-/**
- * Set the nvLocked bit. The TPM error code is returned.
- */
-uint32_t tlcl_set_nv_locked(void);
-
-/**
- * Issue a ForceClear. The TPM error code is returned.
- */
-uint32_t tlcl_force_clear(void);
-
-/**
- * Issue a PhysicalEnable. The TPM error code is returned.
- */
-uint32_t tlcl_set_enable(void);
-
-/**
- * Issue a SetDeactivated. Pass 0 to activate. Returns result code.
- */
-uint32_t tlcl_set_deactivated(uint8_t flag);
-
-/**
- * Get flags of interest. Pointers for flags you aren't interested in may
- * be NULL. The TPM error code is returned.
- */
-uint32_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated,
- uint8_t *nvlocked);
-
-/**
- * Set the bGlobalLock flag, which only a reboot can clear. The TPM error
- * code is returned.
- */
-uint32_t tlcl_set_global_lock(void);
-
-/**
- * Perform a TPM_Extend.
- */
-uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
- uint8_t *out_digest);
-
-/**
- * Get the entire set of permanent flags.
- */
-uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags);
-
-#endif /* TPM_LITE_TLCL_H_ */
diff --git a/src/include/tpm_lite/tss_constants.h b/src/include/tpm_lite/tss_constants.h
deleted file mode 100644
index 883a5ad..0000000
--- a/src/include/tpm_lite/tss_constants.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright (c) 2013 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.
- *
- * Some TPM constants and type definitions for standalone compilation for use
- * in the firmware
- */
-#ifndef VBOOT_REFERENCE_TSS_CONSTANTS_H_
-#define VBOOT_REFERENCE_TSS_CONSTANTS_H_
-#include <stdint.h>
-
-#define TPM_MAX_COMMAND_SIZE 4096
-#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
-#define TPM_PUBEK_SIZE 256
-#define TPM_PCR_DIGEST 20
-
-#define TPM_E_NON_FATAL 0x800
-
-#define TPM_SUCCESS ((uint32_t)0x00000000)
-
-#define TPM_E_AREA_LOCKED ((uint32_t)0x0000003c)
-#define TPM_E_BADINDEX ((uint32_t)0x00000002)
-#define TPM_E_BAD_PRESENCE ((uint32_t)0x0000002d)
-#define TPM_E_IOERROR ((uint32_t)0x0000001f)
-#define TPM_E_INVALID_POSTINIT ((uint32_t)0x00000026)
-#define TPM_E_MAXNVWRITES ((uint32_t)0x00000048)
-#define TPM_E_OWNER_SET ((uint32_t)0x00000014)
-
-#define TPM_E_NEEDS_SELFTEST ((uint32_t)(TPM_E_NON_FATAL + 1))
-#define TPM_E_DOING_SELFTEST ((uint32_t)(TPM_E_NON_FATAL + 2))
-
-#define TPM_E_ALREADY_INITIALIZED ((uint32_t)0x00005000) /* vboot local */
-#define TPM_E_INTERNAL_INCONSISTENCY ((uint32_t)0x00005001) /* vboot local */
-#define TPM_E_MUST_REBOOT ((uint32_t)0x00005002) /* vboot local */
-#define TPM_E_CORRUPTED_STATE ((uint32_t)0x00005003) /* vboot local */
-#define TPM_E_COMMUNICATION_ERROR ((uint32_t)0x00005004) /* vboot local */
-#define TPM_E_RESPONSE_TOO_LARGE ((uint32_t)0x00005005) /* vboot local */
-#define TPM_E_NO_DEVICE ((uint32_t)0x00005006) /* vboot local */
-#define TPM_E_INPUT_TOO_SMALL ((uint32_t)0x00005007) /* vboot local */
-#define TPM_E_WRITE_FAILURE ((uint32_t)0x00005008) /* vboot local */
-#define TPM_E_READ_EMPTY ((uint32_t)0x00005009) /* vboot local */
-#define TPM_E_READ_FAILURE ((uint32_t)0x0000500a) /* vboot local */
-
-#define TPM_NV_INDEX0 ((uint32_t)0x00000000)
-#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
-#define TPM_NV_PER_GLOBALLOCK (((uint32_t)1)<<15)
-#define TPM_NV_PER_PPWRITE (((uint32_t)1)<<0)
-#define TPM_NV_PER_READ_STCLEAR (((uint32_t)1)<<31)
-#define TPM_NV_PER_WRITE_STCLEAR (((uint32_t)1)<<14)
-
-#define TPM_TAG_RQU_COMMAND ((uint16_t) 0xc1)
-#define TPM_TAG_RQU_AUTH1_COMMAND ((uint16_t) 0xc2)
-#define TPM_TAG_RQU_AUTH2_COMMAND ((uint16_t) 0xc3)
-
-#define TPM_TAG_RSP_COMMAND ((uint16_t) 0xc4)
-#define TPM_TAG_RSP_AUTH1_COMMAND ((uint16_t) 0xc5)
-#define TPM_TAG_RSP_AUTH2_COMMAND ((uint16_t) 0xc6)
-
-typedef uint8_t TSS_BOOL;
-typedef uint16_t TPM_STRUCTURE_TAG;
-
-typedef struct tdTPM_PERMANENT_FLAGS
-{
- TPM_STRUCTURE_TAG tag;
- TSS_BOOL disable;
- TSS_BOOL ownership;
- TSS_BOOL deactivated;
- TSS_BOOL readPubek;
- TSS_BOOL disableOwnerClear;
- TSS_BOOL allowMaintenance;
- TSS_BOOL physicalPresenceLifetimeLock;
- TSS_BOOL physicalPresenceHWEnable;
- TSS_BOOL physicalPresenceCMDEnable;
- TSS_BOOL CEKPUsed;
- TSS_BOOL TPMpost;
- TSS_BOOL TPMpostLock;
- TSS_BOOL FIPS;
- TSS_BOOL Operator;
- TSS_BOOL enableRevokeEK;
- TSS_BOOL nvLocked;
- TSS_BOOL readSRKPub;
- TSS_BOOL tpmEstablished;
- TSS_BOOL maintenanceDone;
- TSS_BOOL disableFullDALogicInfo;
-} TPM_PERMANENT_FLAGS;
-
-typedef struct tdTPM_STCLEAR_FLAGS{
- TPM_STRUCTURE_TAG tag;
- TSS_BOOL deactivated;
- TSS_BOOL disableForceClear;
- TSS_BOOL physicalPresence;
- TSS_BOOL physicalPresenceLock;
- TSS_BOOL bGlobalLock;
-} TPM_STCLEAR_FLAGS;
-
-#endif /* VBOOT_REFERENCE_TSS_CONSTANTS_H_ */
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 7d1d146..1656028 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -12,7 +12,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
-subdirs-y += loaders
+subdirs-y += loaders tpm
ifneq ($(CONFIG_BOOTBLOCK_CUSTOM),y)
@@ -51,12 +51,6 @@ verstage-y += boot_device.c
verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
-ifeq ($(MOCK_TPM),1)
-libverstage-y += mocked_tlcl.c
-else
-libverstage-y += tlcl.c
-endif
-
verstage-$(CONFIG_GENERIC_UDELAY) += timer.c
verstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
diff --git a/src/lib/mocked_tlcl.c b/src/lib/mocked_tlcl.c
deleted file mode 100644
index 8dfcfab..0000000
--- a/src/lib/mocked_tlcl.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2015 The ChromiumOS Authors. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <tpm_lite/tlcl.h>
-
-#ifdef FOR_TEST
-#include <stdio.h>
-#define VBDEBUG(format, args...) printf(format, ## args)
-#else
-#include <console/console.h>
-#define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args)
-#endif
-
-uint32_t tlcl_lib_init(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_startup(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_resume(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_self_test_full(void)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_continue_self_test(void)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_write(uint32_t index, const void* data, uint32_t length)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_read(uint32_t index, void* data, uint32_t length)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-
-uint32_t tlcl_assert_physical_presence(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_physical_presence_cmd_enable(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_finalize_physical_presence(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_set_nv_locked(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_force_clear(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_set_enable(void) {
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_set_deactivated(uint8_t flag)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS* pflags)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_get_flags(uint8_t* disable, uint8_t* deactivated,
- uint8_t *nvlocked)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_set_global_lock(void)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
-
-uint32_t tlcl_extend(int pcr_num, const uint8_t* in_digest,
- uint8_t* out_digest)
-{
- VBDEBUG("MOCK_TPM: %s\n", __func__);
- return TPM_E_NO_DEVICE;
-}
diff --git a/src/lib/tlcl.c b/src/lib/tlcl.c
deleted file mode 100644
index ccf4e80..0000000
--- a/src/lib/tlcl.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/* Copyright (c) 2012 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.
- */
-
-/* A lightweight TPM command library.
- *
- * The general idea is that TPM commands are array of bytes whose
- * fields are mostly compile-time constant. The goal is to build much
- * of the commands at compile time (or build time) and change some of
- * the fields at run time as needed. The code in
- * utility/tlcl_generator.c builds structures containing the commands,
- * as well as the offsets of the fields that need to be set at run
- * time.
- */
-
-#include <assert.h>
-#include <string.h>
-#include <tpm_lite/tlcl.h>
-#include <tpm.h>
-#include <vb2_api.h>
-#include "tlcl_internal.h"
-#include "tlcl_structures.h"
-
-#ifdef FOR_TEST
-#include <stdio.h>
-#define VBDEBUG(format, args...) printf(format, ## args)
-#else
-#include <console/console.h>
-#define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args)
-#endif
-
-static int tpm_send_receive(const uint8_t *request,
- uint32_t request_length,
- uint8_t *response,
- uint32_t *response_length)
-{
- size_t len = *response_length;
- if (tis_sendrecv(request, request_length, response, &len))
- return VB2_ERROR_UNKNOWN;
- /* check 64->32bit overflow and (re)check response buffer overflow */
- if (len > *response_length)
- return VB2_ERROR_UNKNOWN;
- *response_length = len;
- return VB2_SUCCESS;
-}
-
-/* Sets the size field of a TPM command. */
-static inline void set_tpm_command_size(uint8_t* buffer, uint32_t size) {
- to_tpm_uint32(buffer + sizeof(uint16_t), size);
-}
-
-/* Gets the size field of a TPM command. */
-__attribute__((unused))
-static inline int tpm_command_size(const uint8_t* buffer) {
- uint32_t size;
- from_tpm_uint32(buffer + sizeof(uint16_t), &size);
- return (int) size;
-}
-
-/* Gets the code field of a TPM command. */
-static inline int tpm_command_code(const uint8_t* buffer) {
- uint32_t code;
- from_tpm_uint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
- return code;
-}
-
-/* Gets the return code field of a TPM result. */
-static inline int tpm_return_code(const uint8_t* buffer) {
- return tpm_command_code(buffer);
-}
-
-/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or
- * DOING_SELFTEST errors are returned.
- */
-static uint32_t tlcl_send_receive_no_retry(const uint8_t* request,
- uint8_t* response, int max_length) {
- uint32_t response_length = max_length;
- uint32_t result;
-
- result = tpm_send_receive(request, tpm_command_size(request),
- response, &response_length);
- if (0 != result) {
- /* Communication with TPM failed, so response is garbage */
- VBDEBUG("TPM: command 0x%x send/receive failed: 0x%x\n",
- tpm_command_code(request), result);
- return result;
- }
- /* Otherwise, use the result code from the response */
- result = tpm_return_code(response);
-
- /* TODO: add paranoia about returned response_length vs. max_length
- * (and possibly expected length from the response header). See
- * crosbug.com/17017 */
-
- VBDEBUG("TPM: command 0x%x returned 0x%x\n",
- tpm_command_code(request), result);
-
-return result;
-}
-
-
-/* Sends a TPM command and gets a response. Returns 0 if success or the TPM
- * error code if error. Waits for the self test to complete if needed. */
-uint32_t tlcl_send_receive(const uint8_t* request, uint8_t* response,
- int max_length) {
- uint32_t result = tlcl_send_receive_no_retry(request, response,
- max_length);
- /* If the command fails because the self test has not completed, try it
- * again after attempting to ensure that the self test has completed. */
- if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) {
- result = tlcl_continue_self_test();
- if (result != TPM_SUCCESS)
- return result;
-#if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE)
- /* Retry only once */
- result = tlcl_send_receive_no_retry(request, response,
- max_length);
-#else
- /* This needs serious testing. The TPM specification says: "iii.
- * The caller MUST wait for the actions of TPM_ContinueSelfTest
- * to complete before reissuing the command C1." But, if
- * ContinueSelfTest is non-blocking, how do we know that the
- * actions have completed other than trying again? */
- do {
- result = tlcl_send_receive_no_retry(request, response,
- max_length);
- } while (result == TPM_E_DOING_SELFTEST);
-#endif
- }
- return result;
-}
-
-/* Sends a command and returns the error code. */
-static uint32_t send(const uint8_t* command) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- return tlcl_send_receive(command, response, sizeof(response));
-}
-
-/* Exported functions. */
-
-uint32_t tlcl_lib_init(void) {
- if (tis_init())
- return VB2_ERROR_UNKNOWN;
- if (tis_open())
- return VB2_ERROR_UNKNOWN;
- return VB2_SUCCESS;
-}
-
-uint32_t tlcl_startup(void) {
- VBDEBUG("TPM: Startup\n");
- return send(tpm_startup_cmd.buffer);
-}
-
-uint32_t tlcl_resume(void) {
- VBDEBUG("TPM: Resume\n");
- return send(tpm_resume_cmd.buffer);
-}
-
-uint32_t tlcl_self_test_full(void)
-{
- VBDEBUG("TPM: Self test full\n");
- return send(tpm_selftestfull_cmd.buffer);
-}
-
-uint32_t tlcl_continue_self_test(void)
-{
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- VBDEBUG("TPM: Continue self test\n");
- /* Call the No Retry version of SendReceive to avoid recursion. */
- return tlcl_send_receive_no_retry(tpm_continueselftest_cmd.buffer,
- response, sizeof(response));
-}
-
-uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size)
-{
- struct s_tpm_nv_definespace_cmd cmd;
- VBDEBUG("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size);
- memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd));
- to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.index, index);
- to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm);
- to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.size, size);
- return send(cmd.buffer);
-}
-
-uint32_t tlcl_write(uint32_t index, const void* data, uint32_t length)
-{
- struct s_tpm_nv_write_cmd cmd;
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- const int total_length =
- kTpmRequestHeaderLength + kWriteInfoLength + length;
-
- VBDEBUG("TPM: tlcl_write(0x%x, %d)\n", index, length);
- memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd));
- assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
- set_tpm_command_size(cmd.buffer, total_length);
-
- to_tpm_uint32(cmd.buffer + tpm_nv_write_cmd.index, index);
- to_tpm_uint32(cmd.buffer + tpm_nv_write_cmd.length, length);
- memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length);
-
- return tlcl_send_receive(cmd.buffer, response, sizeof(response));
-}
-
-uint32_t tlcl_read(uint32_t index, void* data, uint32_t length)
-{
- struct s_tpm_nv_read_cmd cmd;
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t result_length;
- uint32_t result;
-
- VBDEBUG("TPM: tlcl_read(0x%x, %d)\n", index, length);
- memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd));
- to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.index, index);
- to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.length, length);
-
- result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
- if (result == TPM_SUCCESS && length > 0) {
- uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
- from_tpm_uint32(nv_read_cursor, &result_length);
- nv_read_cursor += sizeof(uint32_t);
- memcpy(data, nv_read_cursor, result_length);
- }
-
- return result;
-}
-
-
-uint32_t tlcl_assert_physical_presence(void) {
- VBDEBUG("TPM: Asserting physical presence\n");
- return send(tpm_ppassert_cmd.buffer);
-}
-
-uint32_t tlcl_physical_presence_cmd_enable(void) {
- VBDEBUG("TPM: Enable the physical presence command\n");
- return send(tpm_ppenable_cmd.buffer);
-}
-
-uint32_t tlcl_finalize_physical_presence(void) {
- VBDEBUG("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n");
- return send(tpm_finalizepp_cmd.buffer);
-}
-
-uint32_t tlcl_set_nv_locked(void) {
- VBDEBUG("TPM: Set NV locked\n");
- return tlcl_define_space(TPM_NV_INDEX_LOCK, 0, 0);
-}
-
-uint32_t tlcl_force_clear(void) {
- VBDEBUG("TPM: Force clear\n");
- return send(tpm_forceclear_cmd.buffer);
-}
-
-uint32_t tlcl_set_enable(void) {
- VBDEBUG("TPM: Enabling TPM\n");
- return send(tpm_physicalenable_cmd.buffer);
-}
-
-uint32_t tlcl_set_deactivated(uint8_t flag)
-{
- struct s_tpm_physicalsetdeactivated_cmd cmd;
- VBDEBUG("TPM: SetDeactivated(%d)\n", flag);
- memcpy(&cmd, &tpm_physicalsetdeactivated_cmd, sizeof(cmd));
- *(cmd.buffer + cmd.deactivated) = flag;
- return send(cmd.buffer);
-}
-
-uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS* pflags)
-{
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t size;
- uint32_t result = tlcl_send_receive(tpm_getflags_cmd.buffer, response,
- sizeof(response));
- if (result != TPM_SUCCESS)
- return result;
- from_tpm_uint32(response + kTpmResponseHeaderLength, &size);
- assert(size == sizeof(TPM_PERMANENT_FLAGS));
- memcpy(pflags, response + kTpmResponseHeaderLength + sizeof(size),
- sizeof(TPM_PERMANENT_FLAGS));
- return result;
-}
-
-uint32_t tlcl_get_flags(uint8_t* disable, uint8_t* deactivated,
- uint8_t *nvlocked)
-{
- TPM_PERMANENT_FLAGS pflags;
- uint32_t result = tlcl_get_permanent_flags(&pflags);
- if (result == TPM_SUCCESS) {
- if (disable)
- *disable = pflags.disable;
- if (deactivated)
- *deactivated = pflags.deactivated;
- if (nvlocked)
- *nvlocked = pflags.nvLocked;
- VBDEBUG("TPM: flags disable=%d, deactivated=%d, nvlocked=%d\n",
- pflags.disable, pflags.deactivated, pflags.nvLocked);
- }
- return result;
-}
-
-uint32_t tlcl_set_global_lock(void)
-{
- uint32_t x;
- VBDEBUG("TPM: Set global lock\n");
- return tlcl_write(TPM_NV_INDEX0, (uint8_t*) &x, 0);
-}
-
-uint32_t tlcl_extend(int pcr_num, const uint8_t* in_digest,
- uint8_t* out_digest)
-{
- struct s_tpm_extend_cmd cmd;
- uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength];
- uint32_t result;
-
- memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd));
- to_tpm_uint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num);
- memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength);
-
- result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
- if (result != TPM_SUCCESS)
- return result;
-
- if (out_digest)
- memcpy(out_digest, response + kTpmResponseHeaderLength,
- kPcrDigestLength);
- return result;
-}
diff --git a/src/lib/tlcl_internal.h b/src/lib/tlcl_internal.h
deleted file mode 100644
index 8261b0d..0000000
--- a/src/lib/tlcl_internal.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (c) 2010 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.
- */
-
-#ifndef TPM_LITE_TLCL_INTERNAL_H_
-#define TPM_LITE_TLCL_INTERNAL_H_
-
-/*
- * These numbers derive from adding the sizes of command fields as shown in the
- * TPM commands manual.
- */
-#define kTpmRequestHeaderLength 10
-#define kTpmResponseHeaderLength 10
-#define kTpmReadInfoLength 12
-#define kEncAuthLength 20
-#define kPcrDigestLength 20
-
-
-/*
- * Conversion functions. to_tpm_TYPE puts a value of type TYPE into a TPM
- * command buffer. from_tpm_TYPE gets a value of type TYPE from a TPM command
- * buffer into a variable.
- */
-__attribute__((unused))
-static inline void to_tpm_uint32(uint8_t *buffer, uint32_t x) {
- buffer[0] = (uint8_t)(x >> 24);
- buffer[1] = (uint8_t)((x >> 16) & 0xff);
- buffer[2] = (uint8_t)((x >> 8) & 0xff);
- buffer[3] = (uint8_t)(x & 0xff);
-}
-
-/*
- * See comment for above function.
- */
-__attribute__((unused))
-static inline void from_tpm_uint32(const uint8_t *buffer, uint32_t *x) {
- *x = ((buffer[0] << 24) |
- (buffer[1] << 16) |
- (buffer[2] << 8) |
- buffer[3]);
-}
-
-/*
- * See comment for above function.
- */
-__attribute__((unused))
-static inline void to_tpm_uint16(uint8_t *buffer, uint16_t x) {
- buffer[0] = (uint8_t)(x >> 8);
- buffer[1] = (uint8_t)(x & 0xff);
-}
-
-/*
- * See comment for above function.
- */
-__attribute__((unused))
-static inline void from_tpm_uint16(const uint8_t *buffer, uint16_t *x) {
- *x = (buffer[0] << 8) | buffer[1];
-}
-
-#endif /* TPM_LITE_TLCL_INTERNAL_H_ */
diff --git a/src/lib/tlcl_structures.h b/src/lib/tlcl_structures.h
deleted file mode 100644
index 36c1bb9..0000000
--- a/src/lib/tlcl_structures.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* This file is automatically generated */
-
-const struct s_tpm_extend_cmd{
- uint8_t buffer[34];
- uint16_t pcrNum;
- uint16_t inDigest;
-} tpm_extend_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14, },
-10, 14, };
-
-const struct s_tpm_get_random_cmd{
- uint8_t buffer[14];
- uint16_t bytesRequested;
-} tpm_get_random_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x46, },
-10, };
-
-const struct s_tpm_getownership_cmd{
- uint8_t buffer[22];
-} tpm_getownership_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x11, },
-};
-
-const struct s_tpm_getpermissions_cmd{
- uint8_t buffer[22];
- uint16_t index;
-} tpm_getpermissions_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x4, },
-18, };
-
-const struct s_tpm_getstclearflags_cmd{
- uint8_t buffer[22];
-} tpm_getstclearflags_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x9, },
-};
-
-const struct s_tpm_getflags_cmd{
- uint8_t buffer[22];
-} tpm_getflags_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x8, },
-};
-
-const struct s_tpm_physicalsetdeactivated_cmd{
- uint8_t buffer[11];
- uint16_t deactivated;
-} tpm_physicalsetdeactivated_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, },
-10, };
-
-const struct s_tpm_physicalenable_cmd{
- uint8_t buffer[10];
-} tpm_physicalenable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f, },
-};
-
-const struct s_tpm_physicaldisable_cmd{
- uint8_t buffer[10];
-} tpm_physicaldisable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70, },
-};
-
-const struct s_tpm_forceclear_cmd{
- uint8_t buffer[10];
-} tpm_forceclear_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d, },
-};
-
-const struct s_tpm_readpubek_cmd{
- uint8_t buffer[30];
-} tpm_readpubek_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c, },
-};
-
-const struct s_tpm_continueselftest_cmd{
- uint8_t buffer[10];
-} tpm_continueselftest_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53, },
-};
-
-const struct s_tpm_selftestfull_cmd{
- uint8_t buffer[10];
-} tpm_selftestfull_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, },
-};
-
-const struct s_tpm_resume_cmd{
- uint8_t buffer[12];
-} tpm_resume_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x2, },
-};
-
-const struct s_tpm_savestate_cmd{
- uint8_t buffer[10];
-} tpm_savestate_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x98, },
-};
-
-const struct s_tpm_startup_cmd{
- uint8_t buffer[12];
-} tpm_startup_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1, },
-};
-
-const struct s_tpm_finalizepp_cmd{
- uint8_t buffer[12];
-} tpm_finalizepp_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0, },
-};
-
-const struct s_tpm_pplock_cmd{
- uint8_t buffer[12];
-} tpm_pplock_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x4, },
-};
-
-const struct s_tpm_ppenable_cmd{
- uint8_t buffer[12];
-} tpm_ppenable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x20, },
-};
-
-const struct s_tpm_ppassert_cmd{
- uint8_t buffer[12];
-} tpm_ppassert_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x8, },
-};
-
-const struct s_tpm_pcr_read_cmd{
- uint8_t buffer[14];
- uint16_t pcrNum;
-} tpm_pcr_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15, },
-10, };
-
-const struct s_tpm_nv_read_cmd{
- uint8_t buffer[22];
- uint16_t index;
- uint16_t length;
-} tpm_nv_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf, },
-10, 18, };
-
-const struct s_tpm_nv_write_cmd{
- uint8_t buffer[256];
- uint16_t index;
- uint16_t length;
- uint16_t data;
-} tpm_nv_write_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, },
-10, 18, 22, };
-
-const struct s_tpm_nv_definespace_cmd{
- uint8_t buffer[101];
- uint16_t index;
- uint16_t perm;
- uint16_t size;
-} tpm_nv_definespace_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0xcc, 0x0, 0x18, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x17, },
-12, 70, 77, };
-
-const int kWriteInfoLength = 12;
-const int kNvDataPublicPermissionsOffset = 60;
diff --git a/src/lib/tpm/Makefile.inc b/src/lib/tpm/Makefile.inc
new file mode 100644
index 0000000..81a3eb9
--- /dev/null
+++ b/src/lib/tpm/Makefile.inc
@@ -0,0 +1,13 @@
+ifneq ($(CONFIG_CHROMEOS),y)
+romstage-$(CONFIG_LPC_TPM) += tss.c tspi.c
+ramstage-$(CONFIG_LPC_TPM) += tss.c tspi.c
+else
+romstage-$(CONFIG_LPC_TPM) += tspi.c
+endif
+
+ifeq ($(MOCK_TPM),1)
+libverstage-y += mocked_tss.c
+else
+libverstage-y += tss.c
+endif
+
diff --git a/src/lib/tpm/mocked_tss.c b/src/lib/tpm/mocked_tss.c
new file mode 100644
index 0000000..3c559d0
--- /dev/null
+++ b/src/lib/tpm/mocked_tss.c
@@ -0,0 +1,132 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <tpm/tss.h>
+
+#ifdef FOR_TEST
+#include <stdio.h>
+#define VBDEBUG(format, args...) printf(format, ## args)
+#else
+#include <console/console.h>
+#define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args)
+#endif
+
+uint32_t tlcl_lib_init(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_startup(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_resume(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_self_test_full(void)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_continue_self_test(void)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_write(uint32_t index, const void* data, uint32_t length)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_read(uint32_t index, void* data, uint32_t length)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+
+uint32_t tlcl_assert_physical_presence(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_physical_presence_cmd_enable(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_finalize_physical_presence(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_set_nv_locked(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_force_clear(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_set_enable(void) {
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_set_deactivated(uint8_t flag)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS* pflags)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_get_flags(uint8_t* disable, uint8_t* deactivated,
+ uint8_t *nvlocked)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_set_global_lock(void)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
+
+uint32_t tlcl_extend(int pcr_num, const uint8_t* in_digest,
+ uint8_t* out_digest)
+{
+ VBDEBUG("MOCK_TPM: %s\n", __func__);
+ return TPM_E_NO_DEVICE;
+}
diff --git a/src/lib/tpm/tspi.c b/src/lib/tpm/tspi.c
new file mode 100644
index 0000000..00848f1
--- /dev/null
+++ b/src/lib/tpm/tspi.c
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 The Chromium OS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <console/cbmem_console.h>
+#include <console/console.h>
+#include <reset.h>
+
+#include <tpm/tss.h>
+#include <tpm/tspi.h>
+
+void init_tpm(int s3resume)
+{
+ u32 result = 0;
+
+ if (CONFIG_TPM_DEACTIVATE) {
+ printk(BIOS_SPEW, "TPM: Deactivate\n");
+
+ result = tlcl_set_deactivated(1);
+ if(result != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result);
+ return;
+ }
+ }
+
+ /* Doing TPM startup when we're not coming in on the S3 resume path
+ * saves us roughly 20ms in boot time only. This does not seem to
+ * be worth an API change to vboot_reference-firmware right now, so
+ * let's keep the code around, but just bail out early:
+ */
+ if (s3resume ? CONFIG_NO_TPM_RESUME
+ : CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT)
+ return;
+
+ printk(BIOS_DEBUG, "TPM initialization.\n");
+
+ if(tlcl_lib_init() != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result);
+ return;
+ }
+
+ if (s3resume) {
+ /* S3 Resume */
+ printk(BIOS_SPEW, "TPM: Resume\n");
+
+ result = tlcl_resume();
+ if(result == TPM_E_INVALID_POSTINIT) {
+ /* We're on a platform where the TPM maintains power
+ * in S3, so it's already initialized.
+ */
+ printk(BIOS_DEBUG, "TPM: Already initialized.\n");
+ return;
+ } else if(result != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result);
+ return;
+ }
+ } else {
+ printk(BIOS_SPEW, "TPM: Startup\n");
+ result = tlcl_startup();
+ if(result != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result);
+ return;
+ }
+ }
+
+ if (result == TPM_SUCCESS) {
+ printk(BIOS_SPEW, "TPM: OK.\n");
+ return;
+ }
+
+ printk(BIOS_ERR, "TPM: Error code 0x%x.\n", result);
+
+ if (CONFIG_TPM_INIT_FAILURE_IS_FATAL) {
+ printk(BIOS_ERR, "Hard reset!\n");
+ post_code(POST_TPM_FAILURE);
+ if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART))
+ cbmem_dump_console();
+ hard_reset();
+ }
+}
\ No newline at end of file
diff --git a/src/lib/tpm/tss.c b/src/lib/tpm/tss.c
new file mode 100644
index 0000000..5ffe991
--- /dev/null
+++ b/src/lib/tpm/tss.c
@@ -0,0 +1,331 @@
+/* Copyright (c) 2012 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.
+ */
+
+/* A lightweight TPM command library.
+ *
+ * The general idea is that TPM commands are array of bytes whose
+ * fields are mostly compile-time constant. The goal is to build much
+ * of the commands at compile time (or build time) and change some of
+ * the fields at run time as needed. The code in
+ * utility/tlcl_generator.c builds structures containing the commands,
+ * as well as the offsets of the fields that need to be set at run
+ * time.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <tpm/tss.h>
+#include <tpm/tpm.h>
+#include <console/cbmem_console.h>
+#include <console/console.h>
+#include <reset.h>
+#include "tss_internal.h"
+#include "tss_structures.h"
+
+#ifdef FOR_TEST
+#include <stdio.h>
+#define VBDEBUG(format, args...) printf(format, ## args)
+#else
+#include <console/console.h>
+#define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args)
+#endif
+
+#define UNKNOWN_ERROR 0x10000001 // see VBOOT2 error codes..
+
+static int tpm_send_receive(const uint8_t *request,
+ uint32_t request_length,
+ uint8_t *response,
+ uint32_t *response_length)
+{
+ size_t len = *response_length;
+ if (tis_sendrecv(request, request_length, response, &len))
+ return UNKNOWN_ERROR;
+ /* check 64->32bit overflow and (re)check response buffer overflow */
+ if (len > *response_length)
+ return UNKNOWN_ERROR;
+ *response_length = len;
+ return TPM_SUCCESS;
+}
+
+/* Sets the size field of a TPM command. */
+static inline void set_tpm_command_size(uint8_t* buffer, uint32_t size) {
+ to_tpm_uint32(buffer + sizeof(uint16_t), size);
+}
+
+/* Gets the size field of a TPM command. */
+__attribute__((unused))
+static inline int tpm_command_size(const uint8_t* buffer) {
+ uint32_t size;
+ from_tpm_uint32(buffer + sizeof(uint16_t), &size);
+ return (int) size;
+}
+
+/* Gets the code field of a TPM command. */
+static inline int tpm_command_code(const uint8_t* buffer) {
+ uint32_t code;
+ from_tpm_uint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
+ return code;
+}
+
+/* Gets the return code field of a TPM result. */
+static inline int tpm_return_code(const uint8_t* buffer) {
+ return tpm_command_code(buffer);
+}
+
+/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or
+ * DOING_SELFTEST errors are returned.
+ */
+static uint32_t tlcl_send_receive_no_retry(const uint8_t* request,
+ uint8_t* response, int max_length) {
+ uint32_t response_length = max_length;
+ uint32_t result;
+
+ result = tpm_send_receive(request, tpm_command_size(request),
+ response, &response_length);
+ if (0 != result) {
+ /* Communication with TPM failed, so response is garbage */
+ VBDEBUG("TPM: command 0x%x send/receive failed: 0x%x\n",
+ tpm_command_code(request), result);
+ return result;
+ }
+ /* Otherwise, use the result code from the response */
+ result = tpm_return_code(response);
+
+ /* TODO: add paranoia about returned response_length vs. max_length
+ * (and possibly expected length from the response header). See
+ * crosbug.com/17017 */
+
+ VBDEBUG("TPM: command 0x%x returned 0x%x\n",
+ tpm_command_code(request), result);
+
+return result;
+}
+
+
+/* Sends a TPM command and gets a response. Returns 0 if success or the TPM
+ * error code if error. Waits for the self test to complete if needed. */
+uint32_t tlcl_send_receive(const uint8_t* request, uint8_t* response,
+ int max_length) {
+ uint32_t result = tlcl_send_receive_no_retry(request, response,
+ max_length);
+ /* If the command fails because the self test has not completed, try it
+ * again after attempting to ensure that the self test has completed. */
+ if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) {
+ result = tlcl_continue_self_test();
+ if (result != TPM_SUCCESS)
+ return result;
+#if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE)
+ /* Retry only once */
+ result = tlcl_send_receive_no_retry(request, response,
+ max_length);
+#else
+ /* This needs serious testing. The TPM specification says: "iii.
+ * The caller MUST wait for the actions of TPM_ContinueSelfTest
+ * to complete before reissuing the command C1." But, if
+ * ContinueSelfTest is non-blocking, how do we know that the
+ * actions have completed other than trying again? */
+ do {
+ result = tlcl_send_receive_no_retry(request, response,
+ max_length);
+ } while (result == TPM_E_DOING_SELFTEST);
+#endif
+ }
+ return result;
+}
+
+/* Sends a command and returns the error code. */
+static uint32_t send(const uint8_t* command) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ return tlcl_send_receive(command, response, sizeof(response));
+}
+
+/* Exported functions. */
+
+uint32_t tlcl_lib_init(void) {
+ if (tis_init())
+ return UNKNOWN_ERROR;
+ if (tis_open())
+ return UNKNOWN_ERROR;
+ return TPM_SUCCESS;
+}
+
+uint32_t tlcl_startup(void) {
+ VBDEBUG("TPM: Startup\n");
+ return send(tpm_startup_cmd.buffer);
+}
+
+uint32_t tlcl_resume(void) {
+ VBDEBUG("TPM: Resume\n");
+ return send(tpm_resume_cmd.buffer);
+}
+
+uint32_t tlcl_self_test_full(void)
+{
+ VBDEBUG("TPM: Self test full\n");
+ return send(tpm_selftestfull_cmd.buffer);
+}
+
+uint32_t tlcl_continue_self_test(void)
+{
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ VBDEBUG("TPM: Continue self test\n");
+ /* Call the No Retry version of SendReceive to avoid recursion. */
+ return tlcl_send_receive_no_retry(tpm_continueselftest_cmd.buffer,
+ response, sizeof(response));
+}
+
+uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+ struct s_tpm_nv_definespace_cmd cmd;
+ VBDEBUG("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size);
+ memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd));
+ to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.index, index);
+ to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm);
+ to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.size, size);
+ return send(cmd.buffer);
+}
+
+uint32_t tlcl_write(uint32_t index, const void* data, uint32_t length)
+{
+ struct s_tpm_nv_write_cmd cmd;
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ const int total_length =
+ kTpmRequestHeaderLength + kWriteInfoLength + length;
+
+ VBDEBUG("TPM: tlcl_write(0x%x, %d)\n", index, length);
+ memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd));
+ assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ set_tpm_command_size(cmd.buffer, total_length);
+
+ to_tpm_uint32(cmd.buffer + tpm_nv_write_cmd.index, index);
+ to_tpm_uint32(cmd.buffer + tpm_nv_write_cmd.length, length);
+ memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length);
+
+ return tlcl_send_receive(cmd.buffer, response, sizeof(response));
+}
+
+uint32_t tlcl_read(uint32_t index, void* data, uint32_t length)
+{
+ struct s_tpm_nv_read_cmd cmd;
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint32_t result_length;
+ uint32_t result;
+
+ VBDEBUG("TPM: tlcl_read(0x%x, %d)\n", index, length);
+ memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd));
+ to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.index, index);
+ to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.length, length);
+
+ result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+ if (result == TPM_SUCCESS && length > 0) {
+ uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
+ from_tpm_uint32(nv_read_cursor, &result_length);
+ nv_read_cursor += sizeof(uint32_t);
+ memcpy(data, nv_read_cursor, result_length);
+ }
+
+ return result;
+}
+
+
+uint32_t tlcl_assert_physical_presence(void) {
+ VBDEBUG("TPM: Asserting physical presence\n");
+ return send(tpm_ppassert_cmd.buffer);
+}
+
+uint32_t tlcl_physical_presence_cmd_enable(void) {
+ VBDEBUG("TPM: Enable the physical presence command\n");
+ return send(tpm_ppenable_cmd.buffer);
+}
+
+uint32_t tlcl_finalize_physical_presence(void) {
+ VBDEBUG("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n");
+ return send(tpm_finalizepp_cmd.buffer);
+}
+
+uint32_t tlcl_set_nv_locked(void) {
+ VBDEBUG("TPM: Set NV locked\n");
+ return tlcl_define_space(TPM_NV_INDEX_LOCK, 0, 0);
+}
+
+uint32_t tlcl_force_clear(void) {
+ VBDEBUG("TPM: Force clear\n");
+ return send(tpm_forceclear_cmd.buffer);
+}
+
+uint32_t tlcl_set_enable(void) {
+ VBDEBUG("TPM: Enabling TPM\n");
+ return send(tpm_physicalenable_cmd.buffer);
+}
+
+uint32_t tlcl_set_deactivated(uint8_t flag)
+{
+ struct s_tpm_physicalsetdeactivated_cmd cmd;
+ VBDEBUG("TPM: SetDeactivated(%d)\n", flag);
+ memcpy(&cmd, &tpm_physicalsetdeactivated_cmd, sizeof(cmd));
+ *(cmd.buffer + cmd.deactivated) = flag;
+ return send(cmd.buffer);
+}
+
+uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS* pflags)
+{
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint32_t size;
+ uint32_t result = tlcl_send_receive(tpm_getflags_cmd.buffer, response,
+ sizeof(response));
+ if (result != TPM_SUCCESS)
+ return result;
+ from_tpm_uint32(response + kTpmResponseHeaderLength, &size);
+ assert(size == sizeof(TPM_PERMANENT_FLAGS));
+ memcpy(pflags, response + kTpmResponseHeaderLength + sizeof(size),
+ sizeof(TPM_PERMANENT_FLAGS));
+ return result;
+}
+
+uint32_t tlcl_get_flags(uint8_t* disable, uint8_t* deactivated,
+ uint8_t *nvlocked)
+{
+ TPM_PERMANENT_FLAGS pflags;
+ uint32_t result = tlcl_get_permanent_flags(&pflags);
+ if (result == TPM_SUCCESS) {
+ if (disable)
+ *disable = pflags.disable;
+ if (deactivated)
+ *deactivated = pflags.deactivated;
+ if (nvlocked)
+ *nvlocked = pflags.nvLocked;
+ VBDEBUG("TPM: flags disable=%d, deactivated=%d, nvlocked=%d\n",
+ pflags.disable, pflags.deactivated, pflags.nvLocked);
+ }
+ return result;
+}
+
+uint32_t tlcl_set_global_lock(void)
+{
+ uint32_t x;
+ VBDEBUG("TPM: Set global lock\n");
+ return tlcl_write(TPM_NV_INDEX0, (uint8_t*) &x, 0);
+}
+
+uint32_t tlcl_extend(int pcr_num, const uint8_t* in_digest,
+ uint8_t* out_digest)
+{
+ struct s_tpm_extend_cmd cmd;
+ uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength];
+ uint32_t result;
+
+ memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd));
+ to_tpm_uint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num);
+ memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength);
+
+ result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+ if (result != TPM_SUCCESS)
+ return result;
+
+ if (out_digest)
+ memcpy(out_digest, response + kTpmResponseHeaderLength,
+ kPcrDigestLength);
+ return result;
+}
diff --git a/src/lib/tpm/tss_internal.h b/src/lib/tpm/tss_internal.h
new file mode 100644
index 0000000..bc56b12
--- /dev/null
+++ b/src/lib/tpm/tss_internal.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2010 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.
+ */
+
+#ifndef LIB_TPM_TSS_INTERNAL_H
+#define LIB_TPM_TSS_INTERNAL_H
+
+/*
+ * These numbers derive from adding the sizes of command fields as shown in the
+ * TPM commands manual.
+ */
+#define kTpmRequestHeaderLength 10
+#define kTpmResponseHeaderLength 10
+#define kTpmReadInfoLength 12
+#define kEncAuthLength 20
+#define kPcrDigestLength 20
+
+
+/*
+ * Conversion functions. to_tpm_TYPE puts a value of type TYPE into a TPM
+ * command buffer. from_tpm_TYPE gets a value of type TYPE from a TPM command
+ * buffer into a variable.
+ */
+__attribute__((unused))
+static inline void to_tpm_uint32(uint8_t *buffer, uint32_t x) {
+ buffer[0] = (uint8_t)(x >> 24);
+ buffer[1] = (uint8_t)((x >> 16) & 0xff);
+ buffer[2] = (uint8_t)((x >> 8) & 0xff);
+ buffer[3] = (uint8_t)(x & 0xff);
+}
+
+/*
+ * See comment for above function.
+ */
+__attribute__((unused))
+static inline void from_tpm_uint32(const uint8_t *buffer, uint32_t *x) {
+ *x = ((buffer[0] << 24) |
+ (buffer[1] << 16) |
+ (buffer[2] << 8) |
+ buffer[3]);
+}
+
+/*
+ * See comment for above function.
+ */
+__attribute__((unused))
+static inline void to_tpm_uint16(uint8_t *buffer, uint16_t x) {
+ buffer[0] = (uint8_t)(x >> 8);
+ buffer[1] = (uint8_t)(x & 0xff);
+}
+
+/*
+ * See comment for above function.
+ */
+__attribute__((unused))
+static inline void from_tpm_uint16(const uint8_t *buffer, uint16_t *x) {
+ *x = (buffer[0] << 8) | buffer[1];
+}
+
+#endif /* LIB_TPM_TSS_INTERNAL_H */
\ No newline at end of file
diff --git a/src/lib/tpm/tss_structures.h b/src/lib/tpm/tss_structures.h
new file mode 100644
index 0000000..36c1bb9
--- /dev/null
+++ b/src/lib/tpm/tss_structures.h
@@ -0,0 +1,138 @@
+/* This file is automatically generated */
+
+const struct s_tpm_extend_cmd{
+ uint8_t buffer[34];
+ uint16_t pcrNum;
+ uint16_t inDigest;
+} tpm_extend_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14, },
+10, 14, };
+
+const struct s_tpm_get_random_cmd{
+ uint8_t buffer[14];
+ uint16_t bytesRequested;
+} tpm_get_random_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x46, },
+10, };
+
+const struct s_tpm_getownership_cmd{
+ uint8_t buffer[22];
+} tpm_getownership_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x11, },
+};
+
+const struct s_tpm_getpermissions_cmd{
+ uint8_t buffer[22];
+ uint16_t index;
+} tpm_getpermissions_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x4, },
+18, };
+
+const struct s_tpm_getstclearflags_cmd{
+ uint8_t buffer[22];
+} tpm_getstclearflags_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x9, },
+};
+
+const struct s_tpm_getflags_cmd{
+ uint8_t buffer[22];
+} tpm_getflags_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x8, },
+};
+
+const struct s_tpm_physicalsetdeactivated_cmd{
+ uint8_t buffer[11];
+ uint16_t deactivated;
+} tpm_physicalsetdeactivated_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, },
+10, };
+
+const struct s_tpm_physicalenable_cmd{
+ uint8_t buffer[10];
+} tpm_physicalenable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f, },
+};
+
+const struct s_tpm_physicaldisable_cmd{
+ uint8_t buffer[10];
+} tpm_physicaldisable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70, },
+};
+
+const struct s_tpm_forceclear_cmd{
+ uint8_t buffer[10];
+} tpm_forceclear_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d, },
+};
+
+const struct s_tpm_readpubek_cmd{
+ uint8_t buffer[30];
+} tpm_readpubek_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c, },
+};
+
+const struct s_tpm_continueselftest_cmd{
+ uint8_t buffer[10];
+} tpm_continueselftest_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53, },
+};
+
+const struct s_tpm_selftestfull_cmd{
+ uint8_t buffer[10];
+} tpm_selftestfull_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, },
+};
+
+const struct s_tpm_resume_cmd{
+ uint8_t buffer[12];
+} tpm_resume_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x2, },
+};
+
+const struct s_tpm_savestate_cmd{
+ uint8_t buffer[10];
+} tpm_savestate_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x98, },
+};
+
+const struct s_tpm_startup_cmd{
+ uint8_t buffer[12];
+} tpm_startup_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1, },
+};
+
+const struct s_tpm_finalizepp_cmd{
+ uint8_t buffer[12];
+} tpm_finalizepp_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0, },
+};
+
+const struct s_tpm_pplock_cmd{
+ uint8_t buffer[12];
+} tpm_pplock_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x4, },
+};
+
+const struct s_tpm_ppenable_cmd{
+ uint8_t buffer[12];
+} tpm_ppenable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x20, },
+};
+
+const struct s_tpm_ppassert_cmd{
+ uint8_t buffer[12];
+} tpm_ppassert_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x8, },
+};
+
+const struct s_tpm_pcr_read_cmd{
+ uint8_t buffer[14];
+ uint16_t pcrNum;
+} tpm_pcr_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15, },
+10, };
+
+const struct s_tpm_nv_read_cmd{
+ uint8_t buffer[22];
+ uint16_t index;
+ uint16_t length;
+} tpm_nv_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf, },
+10, 18, };
+
+const struct s_tpm_nv_write_cmd{
+ uint8_t buffer[256];
+ uint16_t index;
+ uint16_t length;
+ uint16_t data;
+} tpm_nv_write_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, },
+10, 18, 22, };
+
+const struct s_tpm_nv_definespace_cmd{
+ uint8_t buffer[101];
+ uint16_t index;
+ uint16_t perm;
+ uint16_t size;
+} tpm_nv_definespace_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0xcc, 0x0, 0x18, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x17, },
+12, 70, 77, };
+
+const int kWriteInfoLength = 12;
+const int kNvDataPublicPermissionsOffset = 60;
diff --git a/src/mainboard/google/auron/acpi/mainboard.asl b/src/mainboard/google/auron/acpi/mainboard.asl
index 2e4352e..f974124 100644
--- a/src/mainboard/google/auron/acpi/mainboard.asl
+++ b/src/mainboard/google/auron/acpi/mainboard.asl
@@ -44,7 +44,7 @@ Scope (\_SB)
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
Scope (\_SB.PCI0.I2C0)
diff --git a/src/mainboard/google/auron/devicetree.cb b/src/mainboard/google/auron/devicetree.cb
index 77e71b8..ea71cf6 100644
--- a/src/mainboard/google/auron/devicetree.cb
+++ b/src/mainboard/google/auron/devicetree.cb
@@ -90,7 +90,7 @@ chip soc/intel/broadwell
device pci 1d.0 on end # USB2 EHCI
device pci 1e.0 off end # PCI bridge
device pci 1f.0 on
- chip drivers/pc80/tpm
+ chip drivers/tpm
# Rising edge interrupt
register "irq_polarity" = "2"
device pnp 0c31.0 on
diff --git a/src/mainboard/google/cyan/acpi/mainboard.asl b/src/mainboard/google/cyan/acpi/mainboard.asl
index c9f4017..e8f0a8e 100644
--- a/src/mainboard/google/cyan/acpi/mainboard.asl
+++ b/src/mainboard/google/cyan/acpi/mainboard.asl
@@ -42,7 +42,7 @@ Scope (\_SB)
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
Scope (\_SB.I2C1)
diff --git a/src/mainboard/google/cyan/devicetree.cb b/src/mainboard/google/cyan/devicetree.cb
index 9d14ba6..e486fa5 100644
--- a/src/mainboard/google/cyan/devicetree.cb
+++ b/src/mainboard/google/cyan/devicetree.cb
@@ -126,7 +126,7 @@ chip soc/intel/braswell
device pci 1e.6 on end # 8086 2290 - SPI 2
device pci 1e.7 on end # 8086 22ac - SPI 3
device pci 1f.0 on # 8086 229c - LPC bridge
- chip drivers/pc80/tpm
+ chip drivers/tpm
# Rising edge interrupt
register "irq_polarity" = "2"
device pnp 0c31.0 on
diff --git a/src/mainboard/google/glados/acpi/mainboard.asl b/src/mainboard/google/glados/acpi/mainboard.asl
index 1b37329..0d7acb2 100644
--- a/src/mainboard/google/glados/acpi/mainboard.asl
+++ b/src/mainboard/google/glados/acpi/mainboard.asl
@@ -50,7 +50,7 @@ Scope (\_SB)
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/*
diff --git a/src/mainboard/google/glados/devicetree.cb b/src/mainboard/google/glados/devicetree.cb
index 894f0e1..93a0769 100644
--- a/src/mainboard/google/glados/devicetree.cb
+++ b/src/mainboard/google/glados/devicetree.cb
@@ -213,7 +213,7 @@ chip soc/intel/skylake
device pci 1e.5 off end # SDIO
device pci 1e.6 on end # SDCard
device pci 1f.0 on
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
chip ec/google/chromeec
diff --git a/src/mainboard/google/jecht/acpi/mainboard.asl b/src/mainboard/google/jecht/acpi/mainboard.asl
index b069446..a1988ed 100644
--- a/src/mainboard/google/jecht/acpi/mainboard.asl
+++ b/src/mainboard/google/jecht/acpi/mainboard.asl
@@ -29,7 +29,7 @@ Scope (\_SB)
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/*
diff --git a/src/mainboard/google/link/romstage.c b/src/mainboard/google/link/romstage.c
index a0970df..6ce8c25 100644
--- a/src/mainboard/google/link/romstage.c
+++ b/src/mainboard/google/link/romstage.c
@@ -37,7 +37,7 @@
#include <cpu/x86/msr.h>
#include <halt.h>
#include "gpio.h"
-#include <tpm.h>
+#include <tpm/tspi.h>
#include <cbfs.h>
#include <southbridge/intel/bd82x6x/chip.h>
diff --git a/src/mainboard/google/parrot/romstage.c b/src/mainboard/google/parrot/romstage.c
index 029805b..b86826b 100644
--- a/src/mainboard/google/parrot/romstage.c
+++ b/src/mainboard/google/parrot/romstage.c
@@ -36,7 +36,7 @@
#include <halt.h>
#include "gpio.h"
#include <cbfs.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include "ec/compal/ene932/ec.h"
static void pch_enable_lpc(void)
diff --git a/src/mainboard/google/samus/acpi/mainboard.asl b/src/mainboard/google/samus/acpi/mainboard.asl
index 17f6257..b36ee72 100644
--- a/src/mainboard/google/samus/acpi/mainboard.asl
+++ b/src/mainboard/google/samus/acpi/mainboard.asl
@@ -40,7 +40,7 @@ Scope (\_SB)
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/*
diff --git a/src/mainboard/google/samus/devicetree.cb b/src/mainboard/google/samus/devicetree.cb
index d12762d..104af07 100644
--- a/src/mainboard/google/samus/devicetree.cb
+++ b/src/mainboard/google/samus/devicetree.cb
@@ -94,7 +94,7 @@ chip soc/intel/broadwell
device pci 1d.0 off end # USB2 EHCI
device pci 1e.0 off end # PCI bridge
device pci 1f.0 on
- chip drivers/pc80/tpm
+ chip drivers/tpm
# Rising edge interrupt
register "irq_polarity" = "2"
device pnp 0c31.0 on
diff --git a/src/mainboard/google/stout/romstage.c b/src/mainboard/google/stout/romstage.c
index 030dee7..c602403 100644
--- a/src/mainboard/google/stout/romstage.c
+++ b/src/mainboard/google/stout/romstage.c
@@ -36,7 +36,7 @@
#include <halt.h>
#include "gpio.h"
#include <bootmode.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include <cbfs.h>
#include <ec/quanta/it8518/ec.h>
#include "ec.h"
diff --git a/src/mainboard/intel/emeraldlake2/romstage.c b/src/mainboard/intel/emeraldlake2/romstage.c
index 5cf24b2..d22bb2b 100644
--- a/src/mainboard/intel/emeraldlake2/romstage.c
+++ b/src/mainboard/intel/emeraldlake2/romstage.c
@@ -35,7 +35,7 @@
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
#include <halt.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include "gpio.h"
#define SIO_PORT 0x164e
diff --git a/src/mainboard/intel/kunimitsu/acpi/mainboard.asl b/src/mainboard/intel/kunimitsu/acpi/mainboard.asl
index 8692c58..d5592ae 100644
--- a/src/mainboard/intel/kunimitsu/acpi/mainboard.asl
+++ b/src/mainboard/intel/kunimitsu/acpi/mainboard.asl
@@ -95,7 +95,7 @@ Scope (\_SB)
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/*
diff --git a/src/mainboard/intel/strago/acpi/mainboard.asl b/src/mainboard/intel/strago/acpi/mainboard.asl
index 0353eed..6383f0f 100644
--- a/src/mainboard/intel/strago/acpi/mainboard.asl
+++ b/src/mainboard/intel/strago/acpi/mainboard.asl
@@ -41,7 +41,7 @@ Scope (\_SB)
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
Scope (\_SB.I2C1)
{
diff --git a/src/mainboard/intel/strago/devicetree.cb b/src/mainboard/intel/strago/devicetree.cb
index 9133787..e09435d 100644
--- a/src/mainboard/intel/strago/devicetree.cb
+++ b/src/mainboard/intel/strago/devicetree.cb
@@ -127,7 +127,7 @@ chip soc/intel/braswell
device pci 1e.6 off end # 8086 2290 - SPI 2
device pci 1e.7 off end # 8086 22ac - SPI 3
device pci 1f.0 on # 8086 229c - LPC bridge
- chip drivers/pc80/tpm
+ chip drivers/tpm
# Rising edge interrupt
register "irq_polarity" = "2"
device pnp 0c31.0 on
diff --git a/src/mainboard/lenovo/t420s/devicetree.cb b/src/mainboard/lenovo/t420s/devicetree.cb
index ca02455..d81df00 100644
--- a/src/mainboard/lenovo/t420s/devicetree.cb
+++ b/src/mainboard/lenovo/t420s/devicetree.cb
@@ -110,7 +110,7 @@ chip northbridge/intel/sandybridge
register "dock_event_enable" = "0x01"
end
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
diff --git a/src/mainboard/lenovo/t420s/dsdt.asl b/src/mainboard/lenovo/t420s/dsdt.asl
index 827a2ea..e2ad559 100644
--- a/src/mainboard/lenovo/t420s/dsdt.asl
+++ b/src/mainboard/lenovo/t420s/dsdt.asl
@@ -57,7 +57,7 @@ DefinitionBlock(
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/* Chipset specific sleep states */
diff --git a/src/mainboard/lenovo/t430s/devicetree.cb b/src/mainboard/lenovo/t430s/devicetree.cb
index 7b83fbc..9e453fd 100644
--- a/src/mainboard/lenovo/t430s/devicetree.cb
+++ b/src/mainboard/lenovo/t430s/devicetree.cb
@@ -114,7 +114,7 @@ chip northbridge/intel/sandybridge
register "dock_event_enable" = "0x01"
end
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
diff --git a/src/mainboard/lenovo/t430s/dsdt.asl b/src/mainboard/lenovo/t430s/dsdt.asl
index 827a2ea..e2ad559 100644
--- a/src/mainboard/lenovo/t430s/dsdt.asl
+++ b/src/mainboard/lenovo/t430s/dsdt.asl
@@ -57,7 +57,7 @@ DefinitionBlock(
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/* Chipset specific sleep states */
diff --git a/src/mainboard/lenovo/t520/devicetree.cb b/src/mainboard/lenovo/t520/devicetree.cb
index 379a95d..3fbbe74 100644
--- a/src/mainboard/lenovo/t520/devicetree.cb
+++ b/src/mainboard/lenovo/t520/devicetree.cb
@@ -91,7 +91,7 @@ chip northbridge/intel/sandybridge
register "dock_event_enable" = "0x01"
end
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
diff --git a/src/mainboard/lenovo/t520/dsdt.asl b/src/mainboard/lenovo/t520/dsdt.asl
index aaa0338..c51bde3 100644
--- a/src/mainboard/lenovo/t520/dsdt.asl
+++ b/src/mainboard/lenovo/t520/dsdt.asl
@@ -56,7 +56,7 @@ DefinitionBlock(
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/* Chipset specific sleep states */
diff --git a/src/mainboard/lenovo/t530/devicetree.cb b/src/mainboard/lenovo/t530/devicetree.cb
index 7db65c7..374a399 100644
--- a/src/mainboard/lenovo/t530/devicetree.cb
+++ b/src/mainboard/lenovo/t530/devicetree.cb
@@ -96,7 +96,7 @@ chip northbridge/intel/sandybridge
register "dock_event_enable" = "0x01"
end
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
diff --git a/src/mainboard/lenovo/t530/dsdt.asl b/src/mainboard/lenovo/t530/dsdt.asl
index aaa0338..c51bde3 100644
--- a/src/mainboard/lenovo/t530/dsdt.asl
+++ b/src/mainboard/lenovo/t530/dsdt.asl
@@ -56,7 +56,7 @@ DefinitionBlock(
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/* Chipset specific sleep states */
diff --git a/src/mainboard/lenovo/x201/devicetree.cb b/src/mainboard/lenovo/x201/devicetree.cb
index 2374554..7ac1678 100644
--- a/src/mainboard/lenovo/x201/devicetree.cb
+++ b/src/mainboard/lenovo/x201/devicetree.cb
@@ -150,7 +150,7 @@ chip northbridge/intel/nehalem
# DLPC, not connected
device pnp 164e.19 off end
end
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
end
diff --git a/src/mainboard/lenovo/x201/dsdt.asl b/src/mainboard/lenovo/x201/dsdt.asl
index 19096fd..52ffb8b 100644
--- a/src/mainboard/lenovo/x201/dsdt.asl
+++ b/src/mainboard/lenovo/x201/dsdt.asl
@@ -90,7 +90,7 @@ DefinitionBlock(
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/* Chipset specific sleep states */
diff --git a/src/mainboard/lenovo/x201/romstage.c b/src/mainboard/lenovo/x201/romstage.c
index 53032f6..ebc9395 100644
--- a/src/mainboard/lenovo/x201/romstage.c
+++ b/src/mainboard/lenovo/x201/romstage.c
@@ -33,7 +33,7 @@
#include <timestamp.h>
#include <arch/acpi.h>
#include <cbmem.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include "gpio.h"
#include "dock.h"
diff --git a/src/mainboard/lenovo/x220/devicetree.cb b/src/mainboard/lenovo/x220/devicetree.cb
index 9f25658..31618de 100644
--- a/src/mainboard/lenovo/x220/devicetree.cb
+++ b/src/mainboard/lenovo/x220/devicetree.cb
@@ -126,7 +126,7 @@ chip northbridge/intel/sandybridge
register "dock_event_enable" = "0x01"
end
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
diff --git a/src/mainboard/lenovo/x220/dsdt.asl b/src/mainboard/lenovo/x220/dsdt.asl
index aaa0338..c51bde3 100644
--- a/src/mainboard/lenovo/x220/dsdt.asl
+++ b/src/mainboard/lenovo/x220/dsdt.asl
@@ -56,7 +56,7 @@ DefinitionBlock(
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
/* Chipset specific sleep states */
diff --git a/src/mainboard/lenovo/x230/devicetree.cb b/src/mainboard/lenovo/x230/devicetree.cb
index 37d53d4..9676156 100644
--- a/src/mainboard/lenovo/x230/devicetree.cb
+++ b/src/mainboard/lenovo/x230/devicetree.cb
@@ -126,7 +126,7 @@ chip northbridge/intel/sandybridge
register "dock_event_enable" = "0x01"
end
- chip drivers/pc80/tpm
+ chip drivers/tpm
device pnp 0c31.0 on end
end
diff --git a/src/mainboard/lenovo/x230/dsdt.asl b/src/mainboard/lenovo/x230/dsdt.asl
index b9575f0..109ccd2 100644
--- a/src/mainboard/lenovo/x230/dsdt.asl
+++ b/src/mainboard/lenovo/x230/dsdt.asl
@@ -55,7 +55,7 @@ DefinitionBlock(
*/
Scope (\_SB.PCI0.LPCB)
{
- #include <drivers/pc80/tpm/acpi/tpm.asl>
+ #include <drivers/tpm/acpi/tpm.asl>
}
diff --git a/src/mainboard/samsung/lumpy/romstage.c b/src/mainboard/samsung/lumpy/romstage.c
index 5f37583..267b4d9 100644
--- a/src/mainboard/samsung/lumpy/romstage.c
+++ b/src/mainboard/samsung/lumpy/romstage.c
@@ -28,7 +28,7 @@
#include <cbmem.h>
#include <console/console.h>
#include <bootmode.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <northbridge/intel/sandybridge/raminit.h>
#include <southbridge/intel/bd82x6x/pch.h>
diff --git a/src/mainboard/samsung/stumpy/romstage.c b/src/mainboard/samsung/stumpy/romstage.c
index bf1ddb3..90a1827 100644
--- a/src/mainboard/samsung/stumpy/romstage.c
+++ b/src/mainboard/samsung/stumpy/romstage.c
@@ -37,7 +37,7 @@
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
#include <halt.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include "gpio.h"
#if CONFIG_DRIVERS_UART_8250IO
#include <superio/smsc/lpc47n207/lpc47n207.h>
diff --git a/src/northbridge/intel/sandybridge/romstage.c b/src/northbridge/intel/sandybridge/romstage.c
index 34d759f..8bb3442 100644
--- a/src/northbridge/intel/sandybridge/romstage.c
+++ b/src/northbridge/intel/sandybridge/romstage.c
@@ -28,7 +28,7 @@
#include <device/pci_def.h>
#include <device/device.h>
#include <halt.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include "raminit_native.h"
#include <northbridge/intel/sandybridge/chip.h>
#include "southbridge/intel/bd82x6x/pch.h"
diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c
index 60146b5..d41e8f4 100644
--- a/src/soc/intel/baytrail/romstage/romstage.c
+++ b/src/soc/intel/baytrail/romstage/romstage.c
@@ -29,7 +29,7 @@
#include <romstage_handoff.h>
#include <stage_cache.h>
#include <timestamp.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include <vendorcode/google/chromeos/chromeos.h>
#include <soc/gpio.h>
#include <soc/iomap.h>
diff --git a/src/soc/intel/braswell/romstage/romstage.c b/src/soc/intel/braswell/romstage/romstage.c
index 5f2a1ce..7a13f78 100644
--- a/src/soc/intel/braswell/romstage/romstage.c
+++ b/src/soc/intel/braswell/romstage/romstage.c
@@ -42,7 +42,7 @@
#include <soc/romstage.h>
#include <soc/smm.h>
#include <soc/spi.h>
-#include <tpm.h>
+#include <tpm/tsṕi.h>
void program_base_addresses(void)
{
diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c
index 762758d..a92f263 100644
--- a/src/soc/intel/broadwell/romstage/romstage.c
+++ b/src/soc/intel/broadwell/romstage/romstage.c
@@ -25,7 +25,7 @@
#include <cbmem.h>
#include <cpu/x86/mtrr.h>
#include <elog.h>
-#include <tpm.h>
+#include <tpm/tspi.h>
#include <romstage_handoff.h>
#include <stage_cache.h>
#include <timestamp.h>
diff --git a/src/vendorcode/google/chromeos/vboot2/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c
index 654fd34..1f6c696 100644
--- a/src/vendorcode/google/chromeos/vboot2/antirollback.c
+++ b/src/vendorcode/google/chromeos/vboot2/antirollback.c
@@ -9,8 +9,8 @@
#include <antirollback.h>
#include <stdlib.h>
#include <string.h>
-#include <tpm_lite/tlcl.h>
-#include <tpm_lite/tss_constants.h>
+#include <tpm/tss.h>
+#include <tpm/tss_constants.h>
#include <vb2_api.h>
#ifndef offsetof
More information about the coreboot-gerrit
mailing list