summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott <scollyer@chromium.org>2016-06-23 12:39:46 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-06-24 14:49:14 -0700
commit4ddf54d7b0d9a36908f0c361bb003b02fc9ed1c9 (patch)
tree5f26a01879d40c2900692180f395d32b7557dbb2
parent8c65294108db43a3717c5afa3017058c826f27b5 (diff)
downloadchrome-ec-4ddf54d7b0d9a36908f0c361bb003b02fc9ed1c9.tar.gz
Cr50: Added TPM register write/read to extract FW version
Created a new TPM register define at the beginning of the vendor defined configuration register space 0xF90 - 0xFFF. Note that this same space is defined for each locality. In order to retrieve the FW version string, the TPM register at offset 0xF90 needs to be written. This will initialize a the pointer index to 0. The same register is then read by the AP and each read will return up to 4 bytes of the FW version string. Once Cr50 detects the string termination character, it stops incrementing the index so that 0s continue to be returned for each subsequent read. In addition there is a max value of reads for the case when the version string is corrupt and doesn't have a '\0' character. BRANCH=none BUG=chrome-os-partner:54723 TEST=Manual Added a routine in /coreboot/src/drivers/spi/tpm.c tpm_init() that does the write/read sequence described above. This test routine produced the folloiwng AP console output: Reading TPM EC Version!! scollyer@ code goes here Read 1: cr50 0x30 Read 2: _v1. 0x2e Read 3: 1.47 0x37 Read 4: 81-1 0x31 Read 5: 3619 0x39 Read 6: 95-d 0x64 Read 7: irty 0x79 Read 7: 0x0 Cr50 FW Version: cr50_v1.1.4781-1361995-dirty Read Count = 29 Initialized TPM device CR50 revision 0 Change-Id: I5d68a037f7a508e3109c35e841dbcb3a893ce22f Signed-off-by: Scott <scollyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/355701 Commit-Ready: Vadim Bendebury <vbendeb@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--common/tpm_registers.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index 0796b9b3c4..455f94d44f 100644
--- a/common/tpm_registers.c
+++ b/common/tpm_registers.c
@@ -12,6 +12,7 @@
#include "byteorder.h"
#include "console.h"
#include "extension.h"
+#include "system.h"
#include "task.h"
#include "tpm_registers.h"
#include "util.h"
@@ -38,6 +39,7 @@
#define TPM_INTERFACE_ID (TPM_LOCALITY_0_SPI_BASE + 0x30)
#define TPM_DID_VID (TPM_LOCALITY_0_SPI_BASE + 0xf00)
#define TPM_RID (TPM_LOCALITY_0_SPI_BASE + 0xf04)
+#define TPM_FW_VER (TPM_LOCALITY_0_SPI_BASE + 0xf90)
#define GOOGLE_VID 0x1ae0
#define GOOGLE_DID 0x0028
@@ -101,6 +103,12 @@ enum tpm_sts_bits {
response_retry = (1 << 1),
};
+#define TPM_FW_VER_MAX_SIZE 64
+/* Used to count bytes read in version string */
+static int tpm_fw_ver_index;
+/* Pointer to version string */
+static const uint8_t *tpm_fw_ver_ptr;
+
static void set_tpm_state(enum tpm_states state)
{
CPRINTF("state transition from %d to %d\n", tpm_.state, state);
@@ -347,6 +355,10 @@ void tpm_register_put(uint32_t regaddr, const uint8_t *data, uint32_t data_size)
case TPM_DATA_FIFO:
fifo_reg_write(data, data_size);
break;
+ case TPM_FW_VER:
+ /* Reset read byte count */
+ tpm_fw_ver_index = 0;
+ break;
default:
CPRINTF("%s(0x%06x, %d bytes:", __func__, regaddr, data_size);
for (i = 0; i < data_size; i++)
@@ -378,6 +390,8 @@ void fifo_reg_read(uint8_t *dest, uint32_t data_size)
* it should be. Return 0x00 or 0xff or whatever the spec says instead. */
void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size)
{
+ int i;
+
CPRINTF("%s(0x%06x, %d)", __func__, regaddr, data_size);
switch (regaddr) {
case TPM_DID_VID:
@@ -399,6 +413,29 @@ void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size)
case TPM_DATA_FIFO:
fifo_reg_read(dest, data_size);
break;
+ case TPM_FW_VER:
+ /* Make sure no more than 4 bytes are read */
+ data_size = MIN(4, data_size);
+ for (i = 0; i < data_size; i++) {
+ /*
+ * Only read while the index remains less than the
+ * maximum allowed version string size.
+ */
+ if (tpm_fw_ver_index < TPM_FW_VER_MAX_SIZE) {
+ *dest++ = tpm_fw_ver_ptr[tpm_fw_ver_index];
+ /*
+ * If reached end of string, then don't update
+ * the index so that it will keep pointing at
+ * the end of string character and continue to
+ * fill *dest with 0s.
+ */
+ if (tpm_fw_ver_ptr[tpm_fw_ver_index] != '\0')
+ tpm_fw_ver_index++;
+ } else
+ /* Not in a valid state, just stuff 0s */
+ *dest++ = 0;
+ }
+ break;
default:
CPRINTS("%s(0x%06x, %d) => ??", __func__, regaddr, data_size);
return;
@@ -413,6 +450,8 @@ static void tpm_init(void)
tpm_.regs.access = tpm_reg_valid_sts;
tpm_.regs.sts = (tpm_family_tpm2 << tpm_family_shift) |
(64 << burst_count_shift) | sts_valid;
+ /* Set FW version pointer to start of version string */
+ tpm_fw_ver_ptr = system_get_version(SYSTEM_IMAGE_RW);
/* TPM2 library functions. */
_plat__Signal_PowerOn();