summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2016-08-05 10:25:42 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-09-24 13:53:26 -0700
commitb94747d501ad7e4347b50c3ea55e615422d96212 (patch)
treeb2c078ca5b87a8af29827474789475903f5b316f
parent5fa727805ca3222e9268755c54c15bbf87c5b2bd (diff)
downloadchrome-ec-b94747d501ad7e4347b50c3ea55e615422d96212.tar.gz
cr50: reset only the TPM state on SYS_RST_L
Rather than doing a full cr50 reset when the system reset SYS_RST_L is asserted, just reset the state of the TPM task and library. Re-clear .bss for those modules, then re-initialize. BRANCH=none BUG=chrome-os-partner:52366 CQ-DEPEND=CL:366792 TEST=make buildall; test on Gru Trigger a SYS_RST_L by using the AP's reboot command, power off/on, log in/out/in. See that the Cr50 does not reboot and the firmware and userspace are still happy about the TPM. Change-Id: I32cd2bb72316f68c74db77a20a8d09112b402d4b Signed-off-by: Randall Spangler <rspangler@chromium.org> Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/361680
-rw-r--r--board/cr50/board.c4
-rw-r--r--board/cr50/board.h3
-rw-r--r--board/cr50/build.mk2
-rw-r--r--chip/g/sps_tpm.c9
-rw-r--r--common/tpm_registers.c38
-rw-r--r--core/cortex-m/ec.lds.S16
-rw-r--r--include/link_defs.h6
-rw-r--r--include/tpm_registers.h2
8 files changed, 76 insertions, 4 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 3f365350da..31a8d2fef1 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -394,8 +394,8 @@ void sys_rst_asserted(enum gpio_signal signal)
if (usb_spi_update_in_progress() || is_sys_rst_asserted())
return;
- cflush();
- system_reset(0);
+ /* Re-initialize the TPM software state */
+ task_set_event(TASK_ID_TPM, TPM_EVENT_RESET, 0);
}
void assert_sys_rst(void)
diff --git a/board/cr50/board.h b/board/cr50/board.h
index 7d11abd60d..cc7589e750 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -136,6 +136,9 @@ void assert_ec_rst(void);
void deassert_ec_rst(void);
int is_ec_rst_asserted(void);
+/* Event to request a reset/re-initialization of the TPM task */
+#define TPM_EVENT_RESET (TASK_EVENT_CUSTOM(1))
+
#endif /* !__ASSEMBLER__ */
/* USB interface indexes (use define rather than enum to expand them) */
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index f7cc0370b6..6028e34de2 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -79,6 +79,6 @@ $(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: $(out)/tpm2/libtpm2.a
# Force the external build each time, so it can look for changed sources.
.PHONY: $(out)/tpm2/libtpm2.a
$(out)/tpm2/libtpm2.a:
- $(MAKE) obj=$(realpath $(out))/tpm2 EMBEDDED_MODE=1 -C $(EXTLIB)
+ $(MAKE) obj=$(realpath $(out))/tpm2 EMBEDDED_MODE=1 OBJ_PREFIX=Tpm2_ -C $(EXTLIB)
endif # BOARD_MK_INCLUDED_ONCE is nonempty
diff --git a/chip/g/sps_tpm.c b/chip/g/sps_tpm.c
index 2c3f6876e7..3ef12994e6 100644
--- a/chip/g/sps_tpm.c
+++ b/chip/g/sps_tpm.c
@@ -271,3 +271,12 @@ void sps_tpm_enable(void)
sps_register_rx_handler(SPS_GENERIC_MODE, tpm_rx_handler, 3);
init_new_cycle();
}
+
+void sps_tpm_disable(void)
+{
+ sps_tpm_state = SPS_TPM_STATE_PONDERING;
+ sps_unregister_rx_handler();
+ /* We don't care anymore, so we can sleep whenever */
+ delay_sleep_by(0);
+ enable_sleep(SLEEP_MASK_SPI);
+}
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index 2f656096aa..6fcd6eb839 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 "link_defs.h"
#include "nvmem.h"
#include "printf.h"
#include "signed_header.h"
@@ -493,6 +494,9 @@ void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size)
static void tpm_init(void)
{
+ /* This is more related to TPM task activity than TPM transactions */
+ cprints(CC_TASK, "%s", __func__);
+
set_tpm_state(tpm_state_idle);
tpm_.regs.access = tpm_reg_valid_sts;
/*
@@ -566,6 +570,33 @@ static void call_extension_command(struct tpm_cmd_header *tpmh,
}
#endif
+static void tpm_reset(void)
+{
+ /* This is more related to TPM task activity than TPM transactions */
+ cprints(CC_TASK, "%s", __func__);
+
+ sps_tpm_disable();
+
+ /*
+ * 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
+ * at the same time.
+ */
+ memset(__bss_libtpm2_start, __bss_libtpm2_end - __bss_libtpm2_start, 0);
+
+ /*
+ * TPM reset currently only clears BSS for the TPM library. It does
+ * not reset any initialized variables in data. So, make sure there
+ * aren't any.
+ */
+ ASSERT(__data_libtpm2_start == __data_libtpm2_end);
+
+ /* Re-initialize our registers */
+ tpm_init();
+
+ sps_tpm_enable();
+}
+
void tpm_task(void)
{
if (system_rolling_reboot_suspected())
@@ -578,9 +609,14 @@ void tpm_task(void)
unsigned response_size;
uint32_t command_code;
struct tpm_cmd_header *tpmh;
+ uint32_t evt;
/* Wait for the next command event */
- task_wait_event(-1);
+ evt = task_wait_event(-1);
+ if (evt & TPM_EVENT_RESET) {
+ tpm_reset();
+ continue;
+ }
tpmh = (struct tpm_cmd_header *)tpm_.regs.data_fifo;
command_code = be32toh(tpmh->command_code);
CPRINTF("%s: received fifo command 0x%04x\n",
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S
index 2b70535fa6..5b756cec58 100644
--- a/core/cortex-m/ec.lds.S
+++ b/core/cortex-m/ec.lds.S
@@ -243,6 +243,14 @@ SECTIONS
. = ALIGN(8);
*(.bss.system_stack)
/* Rest of .bss takes care of its own alignment */
+
+ /* Group libtpm2 data so it can be cleared on system reset */
+ __bss_libtpm2_start = .;
+ Tpm2_*(.bss)
+ /* TPM registers should be cleared at the same time */
+ STRINGIFY(OUTDIR/common/tpm_registers.o*)(.bss)
+ __bss_libtpm2_end = .;
+
*(.bss)
/*
@@ -284,6 +292,14 @@ SECTIONS
. = ALIGN(4);
__data_start = .;
*(.data.tasks)
+
+ /* Group libtpm2 data so it can be reinitialized on system reset */
+ __data_libtpm2_start = .;
+ Tpm2_*(.data)
+ /* TPM registers should be reinitialized at the same time */
+ STRINGIFY(OUTDIR/common/tpm_registers.o*)(.data)
+ __data_libtpm2_end = .;
+
*(.data)
#ifdef CONFIG_MPU
/* It has to be aligned by 32 bytes to be a valid MPU region. */
diff --git a/include/link_defs.h b/include/link_defs.h
index 69b964d1d8..e55da8bd50 100644
--- a/include/link_defs.h
+++ b/include/link_defs.h
@@ -87,6 +87,12 @@ extern const void *__irqhandler[];
/* Shared memory buffer. Use via shared_mem.h interface. */
extern uint8_t __shared_mem_buf[];
+/* Image sections used by the TPM2 library */
+extern uint8_t *__bss_libtpm2_start;
+extern uint8_t *__bss_libtpm2_end;
+extern uint8_t *__data_libtpm2_start;
+extern uint8_t *__data_libtpm2_end;
+
/* Image sections. */
extern const void *__ro_end;
extern const void *__data_start;
diff --git a/include/tpm_registers.h b/include/tpm_registers.h
index 3416492f03..35f6dff471 100644
--- a/include/tpm_registers.h
+++ b/include/tpm_registers.h
@@ -25,6 +25,8 @@ void tpm_register_get(uint32_t regaddr, uint8_t *dest, uint32_t data_size);
/* Enable SPS TPM driver. */
void sps_tpm_enable(void);
+/* Disable SPS TPM driver. */
+void sps_tpm_disable(void);
/* Get the current value of the burst size field of the status register. */
size_t tpm_get_burst_size(void);