summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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();