diff options
Diffstat (limited to 'common/tpm_registers.c')
-rw-r--r-- | common/tpm_registers.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/common/tpm_registers.c b/common/tpm_registers.c index d0ae42e904..429e895283 100644 --- a/common/tpm_registers.c +++ b/common/tpm_registers.c @@ -21,6 +21,7 @@ #include "system_chip.h" #include "task.h" #include "tpm_manufacture.h" +#include "tpm_nvmem_ops.h" #include "tpm_registers.h" #include "util.h" #include "watchdog.h" @@ -850,8 +851,21 @@ void tpm_reinstate_nvmem_commits(void) task_set_event(TASK_ID_TPM, TPM_EVENT_COMMIT, 0); } -static void tpm_reset_now(int wipe_first) +/* + * Reset TPM stack state. + * Called at boot, when AP resets (TPM_RESET_EVENT) and when a TPM data wipe + * is requested. + * + * Parameters: + * wipe_first - wipe TPM nvmem as a part of reset. + * can_preserve_orderly - preserve orderly nvmem spaces over a possibly + * unorderly shutdown (unless wipe_first is requested). This is a GSC + * specific modification to TPM behavior. + */ +static void tpm_reset_now(int wipe_first, int can_preserve_orderly) { + char orderly_state_copy[TPM_ORDERLY_STATE_SIZE]; + if_stop(); /* This is more related to TPM task activity than TPM transactions */ @@ -874,6 +888,9 @@ static void tpm_reset_now(int wipe_first) */ nvmem_enable_commits(); + if (can_preserve_orderly && !wipe_first) + tpm_orderly_state_capture(orderly_state_copy); + /* * Clear the TPM library's zero-init data. Note that the linker script * includes this file's .bss in the same section, so it will be cleared @@ -889,6 +906,9 @@ static void tpm_reset_now(int wipe_first) /* Re-initialize our registers */ tpm_init(); + if (can_preserve_orderly && !wipe_first) + tpm_orderly_state_restore(orderly_state_copy); + if (waiting_for_reset != TASK_ID_INVALID) { /* Wake the waiting task, if any */ task_set_event(waiting_for_reset, TPM_EVENT_RESET, 0); @@ -908,7 +928,7 @@ static void tpm_reset_now(int wipe_first) int tpm_sync_reset(int wipe_first) { - tpm_reset_now(wipe_first); + tpm_reset_now(wipe_first, 1); return wipe_result; } @@ -957,7 +977,7 @@ void tpm_task(void *u) __func__, __LINE__, evt); } - tpm_reset_now(0); + tpm_reset_now(0, 0); while (1) { uint8_t *response = NULL; unsigned response_size; @@ -971,7 +991,7 @@ void tpm_task(void *u) evt = task_wait_event(-1); if (evt & TPM_EVENT_RESET) { - tpm_reset_now(wipe_requested); + tpm_reset_now(wipe_requested, 1); if (evt & TPM_EVENT_ALT_EXTENSION) { /* * Need to tell the waiting task that |