diff options
Diffstat (limited to 'common/tpm_registers.c')
-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(); |