diff options
author | Aseda Aboagye <aaboagye@google.com> | 2017-02-14 19:31:25 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-02-18 17:26:59 -0800 |
commit | 4ed404432904c3f8e6c9d64e8bb306daf3c687f5 (patch) | |
tree | 7b524aceeb143d5ed9a2bd120978c50cac8dd9db | |
parent | 2062c99cd2bfe1642433b2cae33c617e02c27cdd (diff) | |
download | chrome-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.c | 4 | ||||
-rw-r--r-- | board/cr50/tpm2/post_reset.c | 3 | ||||
-rw-r--r-- | board/cr50/wp.c | 3 | ||||
-rw-r--r-- | chip/g/system.c | 19 | ||||
-rw-r--r-- | chip/g/system_chip.h | 7 | ||||
-rw-r--r-- | common/system.c | 2 | ||||
-rw-r--r-- | include/system.h | 10 |
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. |