summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2017-02-14 19:31:25 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-02-18 17:26:59 -0800
commit4ed404432904c3f8e6c9d64e8bb306daf3c687f5 (patch)
tree7b524aceeb143d5ed9a2bd120978c50cac8dd9db
parent2062c99cd2bfe1642433b2cae33c617e02c27cdd (diff)
downloadchrome-ec-4ed404432904c3f8e6c9d64e8bb306daf3c687f5.tar.gz
cr50: Decrement retry counter on manual reboots.
Currently, manually triggered reboots cause the retry counter to be incremented. However, if the system is responsive enough to process the reboot commands from either the console or TPM vendor command, we can assume that the image is "ok". This commit changes the Cr50 behaviour to decrement the retry counter when a reboot is issued on the console or the TPM vendor command is received. BUG=chrome-os-partner:62687 BRANCH=None TEST=Flash cr50. Flash an older image in the other slot. Enter the reboot command on the console over 10 times and verify that retry counter never exceeds RW_BOOT_MAX_RETRY_COUNT and older image is never executed. CQ-DEPEND=CL:444264 Change-Id: Ic35bdc63c4141834584a00a7ecceab2abe8dfc21 Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/443330 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--board/cr50/board.c4
-rw-r--r--board/cr50/tpm2/post_reset.c3
-rw-r--r--board/cr50/wp.c3
-rw-r--r--chip/g/system.c19
-rw-r--r--chip/g/system_chip.h7
-rw-r--r--common/system.c2
-rw-r--r--include/system.h10
7 files changed, 41 insertions, 7 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 695bd75d03..73a85e998a 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -628,7 +628,9 @@ static void deferred_tpm_rst_isr(void)
* committed before reboot.
*/
tpm_reset_request(1, 0);
- system_reset(SYSTEM_RESET_HARD); /* This will never return. */
+
+ /* This will never return. */
+ system_reset(SYSTEM_RESET_MANUALLY_TRIGGERED | SYSTEM_RESET_HARD);
}
/* This is the interrupt handler to react to TPM_RST_L */
diff --git a/board/cr50/tpm2/post_reset.c b/board/cr50/tpm2/post_reset.c
index cfb3608462..24a98a9470 100644
--- a/board/cr50/tpm2/post_reset.c
+++ b/board/cr50/tpm2/post_reset.c
@@ -30,7 +30,8 @@ static enum vendor_cmd_rc immediate_reset(enum vendor_cmd_cc code,
{
CPRINTS("%s: rebooting on host's request", __func__);
cflush(); /* Let the console drain. */
- system_reset(SYSTEM_RESET_HARD); /* This will never return. */
+ /* This will never return. */
+ system_reset(SYSTEM_RESET_MANUALLY_TRIGGERED | SYSTEM_RESET_HARD);
/* Never reached. */
return VENDOR_RC_SUCCESS;
diff --git a/board/cr50/wp.c b/board/cr50/wp.c
index e980efdf0b..2effdbb750 100644
--- a/board/cr50/wp.c
+++ b/board/cr50/wp.c
@@ -161,7 +161,8 @@ static void unlock_the_console(void)
*/
CPRINTS("%s: Couldn't wipe nvmem! (rc %d)", __func__, rc);
cflush();
- system_reset(SYSTEM_RESET_HARD);
+ system_reset(SYSTEM_RESET_MANUALLY_TRIGGERED |
+ SYSTEM_RESET_HARD);
}
CPRINTS("TPM is erased");
diff --git a/chip/g/system.c b/chip/g/system.c
index ad553168c5..47b3848146 100644
--- a/chip/g/system.c
+++ b/chip/g/system.c
@@ -12,6 +12,7 @@
#include "registers.h"
#include "signed_header.h"
#include "system.h"
+#include "system_chip.h"
#include "task.h"
#include "version.h"
@@ -95,6 +96,13 @@ void system_reset(int flags)
#ifdef BOARD_CR50
/*
+ * Decrement the retry counter on manually triggered reboots. We were
+ * able to process the console command, therefore we're probably okay.
+ */
+ if (flags & SYSTEM_RESET_MANUALLY_TRIGGERED)
+ system_decrement_retry_counter();
+
+ /*
* On CR50 we want every reset be hard reset, causing the entire
* chromebook to reboot: we don't want the TPM reset while the AP
* stays up.
@@ -336,6 +344,17 @@ void system_clear_retry_counter(void)
GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG0, 0);
}
+void system_decrement_retry_counter(void)
+{
+ uint32_t val = GREG32(PMU, LONG_LIFE_SCRATCH0);
+
+ if (val != 0) {
+ GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG0, 1);
+ GREG32(PMU, LONG_LIFE_SCRATCH0) = val - 1;
+ GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG0, 0);
+ }
+}
+
/*
* Check which of the two cr50 RW images is newer, return true if the first
* image is no older than the second one.
diff --git a/chip/g/system_chip.h b/chip/g/system_chip.h
index 5d2576a722..0f21ba066b 100644
--- a/chip/g/system_chip.h
+++ b/chip/g/system_chip.h
@@ -24,6 +24,13 @@ int system_process_retry_counter(void);
void system_clear_retry_counter(void);
/**
+ * A function provided by some platforms to decrement a retry counter.
+ *
+ * This should be used whenever a system reset is manually triggered.
+ */
+void system_decrement_retry_counter(void);
+
+/**
* A function provided by some platforms to hint that something is going
* wrong.
*
diff --git a/common/system.c b/common/system.c
index ddabe3aa3c..25acdbf544 100644
--- a/common/system.c
+++ b/common/system.c
@@ -1042,7 +1042,7 @@ DECLARE_CONSOLE_COMMAND(sysjump, command_sysjump,
static int command_reboot(int argc, char **argv)
{
- int flags = 0;
+ int flags = SYSTEM_RESET_MANUALLY_TRIGGERED;
int i;
for (i = 1; i < argc; i++) {
diff --git a/include/system.h b/include/system.h
index 9cb04844ed..50d1e29609 100644
--- a/include/system.h
+++ b/include/system.h
@@ -221,17 +221,21 @@ const char *system_get_build_info(void);
* Hard reset. Cuts power to the entire system. If not present, does a soft
* reset which just resets the core and on-chip peripherals.
*/
-#define SYSTEM_RESET_HARD (1 << 0)
+#define SYSTEM_RESET_HARD (1 << 0)
/*
* Preserve existing reset flags. Used by flash pre-init when it discovers it
* needs to do a hard reset to clear write protect registers.
*/
-#define SYSTEM_RESET_PRESERVE_FLAGS (1 << 1)
+#define SYSTEM_RESET_PRESERVE_FLAGS (1 << 1)
/*
* Leave AP off on next reboot, instead of powering it on to do EC software
* sync.
*/
-#define SYSTEM_RESET_LEAVE_AP_OFF (1 << 2)
+#define SYSTEM_RESET_LEAVE_AP_OFF (1 << 2)
+/*
+ * Indicate that this was a manually triggered reset.
+ */
+#define SYSTEM_RESET_MANUALLY_TRIGGERED (1 << 3)
/**
* Reset the system.