summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.