diff options
-rw-r--r-- | firmware/lib/vboot_api_kernel.c | 39 | ||||
-rw-r--r-- | tests/vboot_api_kernel3_tests.c | 5 |
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"); |