summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/lib/vboot_api_kernel.c39
-rw-r--r--tests/vboot_api_kernel3_tests.c5
2 files changed, 32 insertions, 12 deletions
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 4cf2a946..18d00ae7 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -779,20 +779,23 @@ VbError_t VbEcSoftwareSync(VbCommonParams *cparams)
}
rv = VbExEcUpdateRW(expected, expected_size);
- if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
+
+ if (rv != VBERROR_SUCCESS) {
+ VBDEBUG(("VbEcSoftwareSync() - "
+ "VbExEcUpdateRW() returned %d\n", rv));
+
/*
- * Reboot required. May need to unprotect RW before
- * updating, or may need to reboot after RW updated.
- * Either way, it's not an error requiring recovery
+ * The EC may know it needs a reboot. It may need to
+ * unprotect RW before updating, or may need to reboot
+ * after RW updated. Either way, it's not an error
+ * requiring recovery mode.
+ *
+ * If we fail for any other reason, trigger recovery
* mode.
*/
- VBDEBUG(("VbEcSoftwareSync() - "
- "VbExEcUpdateRW() needs reboot\n"));
- return rv;
- } else if (rv != VBERROR_SUCCESS) {
- VBDEBUG(("VbEcSoftwareSync() - "
- "VbExEcUpdateRW() returned %d\n", rv));
- VbSetRecoveryRequest(VBNV_RECOVERY_EC_UPDATE);
+ if (rv != VBERROR_EC_REBOOT_TO_RO_REQUIRED)
+ VbSetRecoveryRequest(VBNV_RECOVERY_EC_UPDATE);
+
return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
}
@@ -810,12 +813,24 @@ VbError_t VbEcSoftwareSync(VbCommonParams *cparams)
/* Tell EC to jump to its RW image */
VBDEBUG(("VbEcSoftwareSync() jumping to EC-RW\n"));
rv = VbExEcJumpToRW();
+
if (rv != VBERROR_SUCCESS) {
VBDEBUG(("VbEcSoftwareSync() - "
"VbExEcJumpToRW() returned %d\n", rv));
- VbSetRecoveryRequest(VBNV_RECOVERY_EC_JUMP_RW);
+
+ /*
+ * If the EC booted RO-normal and a previous AP boot has called
+ * VbExEcStayInRO(), we need to reboot the EC to unlock the
+ * ability to jump to the RW firmware.
+ *
+ * All other errors trigger recovery mode.
+ */
+ if (rv != VBERROR_EC_REBOOT_TO_RO_REQUIRED)
+ VbSetRecoveryRequest(VBNV_RECOVERY_EC_JUMP_RW);
+
return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
}
+
VBDEBUG(("VbEcSoftwareSync() jumped to EC-RW\n"));
rv = VbExEcDisableJump();
diff --git a/tests/vboot_api_kernel3_tests.c b/tests/vboot_api_kernel3_tests.c
index cefbf416..49bc7aad 100644
--- a/tests/vboot_api_kernel3_tests.c
+++ b/tests/vboot_api_kernel3_tests.c
@@ -340,6 +340,11 @@ static void VbSoftwareSyncTest(void)
VBNV_RECOVERY_EC_JUMP_RW, "Jump to RW fail");
ResetMocks();
+ run_retval = VBERROR_EC_REBOOT_TO_RO_REQUIRED;
+ test_ssync(VBERROR_EC_REBOOT_TO_RO_REQUIRED,
+ 0, "Jump to RW fail because locked");
+
+ ResetMocks();
protect_retval = VBERROR_SIMULATED;
test_ssync(VBERROR_SIMULATED,
VBNV_RECOVERY_EC_PROTECT, "Protect error");