diff options
author | Scott <scollyer@chromium.org> | 2016-06-23 12:39:46 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-06-24 14:49:14 -0700 |
commit | 4ddf54d7b0d9a36908f0c361bb003b02fc9ed1c9 (patch) | |
tree | 5f26a01879d40c2900692180f395d32b7557dbb2 | |
parent | 8c65294108db43a3717c5afa3017058c826f27b5 (diff) | |
download | chrome-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.c | 39 |
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(); |