summaryrefslogtreecommitdiff
path: root/chip/g
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@google.com>2018-03-28 11:35:05 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-03-30 16:53:00 -0700
commit7a756993ea81451738fe9256fdd4025045955f1c (patch)
tree2a8625cc47ac3b08a435550d8c1903cf2fe05dfd /chip/g
parent7c46ac84e1e64c283a9981451cb4fecd6549a54c (diff)
downloadchrome-ec-7a756993ea81451738fe9256fdd4025045955f1c.tar.gz
g: use reset_count to determine system_rollback_detected
Use the reset count to determine if there was a rollback in system_rollback_detected. Before system.c was checking if the inactive header was newer than active one to determine if the system rolled back. This wasn't accurate. Cr50 rollback isn't the only reason why a newer image may be rejected. The image may have been rejected because it wasn't signed correctly or it's corrupted, so we shouldn't be using the newer header as a sign that there was a rollback. The reset count is cleared when the AP boots. This means the rollback state will be lost the first deep sleep resume after the AP has booted. BUG=none BRANCH=cr50 TEST=manual flash a dbg image with version 4.0 that has two infomap bits erased. Check sysinfo to see that it doesn't think cr50 rolledback flash a dbg image with version 4.4 that has one infomap bit erased. Make sure that 4.4 image is rejected and cr50 is still running 4.0 Check sysinfo to see that it doesn't think cr50 rolledback flash a dbg image with version 4.4 that has two infomap bits erased. Make sure cr50 jumps to that image rollback to the 4.0 image Make sure sysinfo shows there was a rollback. Boot the system Make sure sysinfo shows there was a rollback. Change-Id: I85f2e001ffed9e2185a276dfa916e9b0a05ff7bf Signed-off-by: Mary Ruthven <mruthven@google.com> Reviewed-on: https://chromium-review.googlesource.com/985029 Commit-Ready: Mary Ruthven <mruthven@chromium.org> Tested-by: Mary Ruthven <mruthven@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'chip/g')
-rw-r--r--chip/g/system.c43
-rw-r--r--chip/g/system_chip.h6
2 files changed, 32 insertions, 17 deletions
diff --git a/chip/g/system.c b/chip/g/system.c
index 012d5372cb..0ee2640b71 100644
--- a/chip/g/system.c
+++ b/chip/g/system.c
@@ -16,13 +16,24 @@
#include "task.h"
#include "version.h"
+/*
+ * Value of the retry counter which, if exceeded, indicates that the currently
+ * running RW image is not well and is rebooting before bringing the system
+ * manages to come up.
+ */
+#define RW_BOOT_MAX_RETRY_COUNT 5
+
static uint8_t pinhold_on_reset;
+static uint8_t rollback_detected_at_boot;
static void check_reset_cause(void)
{
uint32_t g_rstsrc = GR_PMU_RSTSRC;
uint32_t flags = 0;
+ rollback_detected_at_boot = (GREG32(PMU, LONG_LIFE_SCRATCH0) >
+ RW_BOOT_MAX_RETRY_COUNT);
+
/* Clear the reset source now we have recorded it */
GR_PMU_CLRRST = 1;
@@ -444,6 +455,9 @@ static int a_is_newer_than_b(const struct SignedHeader *a,
return 1; /* All else being equal, consider A to be newer. */
}
+/* Used to track if cr50 has corrupted the inactive header */
+static uint8_t header_corrupted;
+
/*
* Corrupt the 'magic' field of the passed in header. This prevents the
* apparently failing image from being considered as a candidate to load and
@@ -473,16 +487,9 @@ static int corrupt_header(volatile struct SignedHeader *header)
ccprintf("%s: magic after: %x\n",
__func__, header->magic);
+ header_corrupted = !rv;
return rv;
}
-
-/*
- * Value of the retry counter which, if exceeded, indicates that the currently
- * running RW image is not well and is rebooting before bringing the system
- * manages to come up.
- */
-#define RW_BOOT_MAX_RETRY_COUNT 5
-
/*
* Check if the current running image is newer. Set the passed in pointer, if
* supplied, to point to the newer image in case the running image is the
@@ -514,28 +521,32 @@ static int current_image_is_newer(struct SignedHeader **newer_image)
int system_rollback_detected(void)
{
- return !current_image_is_newer(NULL);
+ return rollback_detected_at_boot;
}
int system_process_retry_counter(void)
{
- unsigned retry_counter;
struct SignedHeader *newer_image;
- retry_counter = GREG32(PMU, LONG_LIFE_SCRATCH0);
+ ccprintf("%s: retry counter %d\n", __func__,
+ GREG32(PMU, LONG_LIFE_SCRATCH0));
system_clear_retry_counter();
- ccprintf("%s:retry counter %d\n", __func__, retry_counter);
-
- if (retry_counter <= RW_BOOT_MAX_RETRY_COUNT)
+ if (!system_rollback_detected())
return EC_SUCCESS;
if (current_image_is_newer(&newer_image)) {
ccprintf("%s: "
- "this is odd, I am newer, but retry counter was %d\n",
- __func__, retry_counter);
+ "this is odd, I am newer, but retry counter indicates "
+ "the system rolledback\n", __func__);
return EC_SUCCESS;
}
+
+ if (header_corrupted) {
+ ccprintf("%s: header already corrupted\n", __func__);
+ return EC_SUCCESS;
+ }
+
/*
* let's corrupt the newer image so that the next restart is happening
* straight into the current version.
diff --git a/chip/g/system_chip.h b/chip/g/system_chip.h
index b5b9f4cbea..3547bf58c7 100644
--- a/chip/g/system_chip.h
+++ b/chip/g/system_chip.h
@@ -39,7 +39,11 @@ void system_decrement_retry_counter(void);
int system_rolling_reboot_suspected(void);
/**
- * Compare the rw headers to check if there was a rollback.
+ * Returns True if a rollback was detected during system_preinit.
+ *
+ * system_rollback_detected only returns True from rollback until the AP boots
+ * and then enters deep sleep. The system won't know that it rolled back on
+ * resume from deep sleep.
*
* @return a boolean, set to True if a rollback is detected.
*/