diff options
-rw-r--r-- | firmware/lib/ec_sync.c | 34 | ||||
-rw-r--r-- | firmware/lib/ec_sync_all.c | 22 | ||||
-rw-r--r-- | firmware/lib/include/ec_sync.h | 13 | ||||
-rw-r--r-- | tests/ec_sync_tests.c | 60 |
4 files changed, 121 insertions, 8 deletions
diff --git a/firmware/lib/ec_sync.c b/firmware/lib/ec_sync.c index 21ed827b..3f90ba5f 100644 --- a/firmware/lib/ec_sync.c +++ b/firmware/lib/ec_sync.c @@ -13,6 +13,7 @@ #include "sysincludes.h" #include "ec_sync.h" #include "gbb_header.h" +#include "vboot_api.h" #include "vboot_common.h" #include "vboot_kernel.h" @@ -420,8 +421,15 @@ int ec_will_update_slowly(struct vb2_context *ctx, VbCommonParams *cparams) (shared->flags & VBSD_EC_SLOW_UPDATE)); } +/** + * determine if we can update the EC + * + * @param ctx Vboot2 context + * @param cparams Vboot common params + * @return boolean (true iff we can update the EC) + */ -VbError_t ec_sync_phase2(struct vb2_context *ctx, VbCommonParams *cparams) +static int ec_sync_allowed(struct vb2_context *ctx, VbCommonParams *cparams) { VbSharedDataHeader *shared = (VbSharedDataHeader *)cparams->shared_data_blob; @@ -429,10 +437,30 @@ VbError_t ec_sync_phase2(struct vb2_context *ctx, VbCommonParams *cparams) /* Reasons not to do sync at all */ if (!(shared->flags & VBSD_EC_SOFTWARE_SYNC)) - return VBERROR_SUCCESS; + return 0; if (cparams->gbb->flags & GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC) - return VBERROR_SUCCESS; + return 0; if (sd->recovery_reason) + return 0; + return 1; +} + +VbError_t ec_sync_check_aux_fw(struct vb2_context *ctx, + VbCommonParams *cparams, + VbAuxFwUpdateSeverity_t *severity) +{ + /* If we're not updating the EC, skip aux fw syncs as well */ + if (!ec_sync_allowed(ctx, cparams) || + (cparams->gbb->flags & GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC)) { + *severity = VB_AUX_FW_NO_UPDATE; + return VBERROR_SUCCESS; + } + return VbExCheckAuxFw(severity); +} + +VbError_t ec_sync_phase2(struct vb2_context *ctx, VbCommonParams *cparams) +{ + if (!ec_sync_allowed(ctx, cparams)) return VBERROR_SUCCESS; /* Handle updates and jumps for EC */ diff --git a/firmware/lib/ec_sync_all.c b/firmware/lib/ec_sync_all.c index f0e4291c..af06b0ec 100644 --- a/firmware/lib/ec_sync_all.c +++ b/firmware/lib/ec_sync_all.c @@ -21,10 +21,17 @@ VbError_t ec_sync_all(struct vb2_context *ctx, struct VbCommonParams *cparams) { VbSharedDataHeader *shared = (VbSharedDataHeader *)cparams->shared_data_blob; + VbAuxFwUpdateSeverity_t fw_update; + VbError_t rv; + + rv = ec_sync_check_aux_fw(ctx, cparams, &fw_update); + if (rv) + return rv; /* Do EC sync phase 1; this determines if we need an update */ VbError_t phase1_rv = ec_sync_phase1(ctx, cparams); - int need_wait_screen = ec_will_update_slowly(ctx, cparams); + int need_wait_screen = ec_will_update_slowly(ctx, cparams) || + (fw_update == VB_AUX_FW_SLOW_UPDATE); /* * Check if we need to reboot to load the VGA Option ROM before we can @@ -57,11 +64,20 @@ VbError_t ec_sync_all(struct vb2_context *ctx, struct VbCommonParams *cparams) * Do EC sync phase 2; this applies the update and/or jumps to the * correct EC image. */ - VbError_t rv = ec_sync_phase2(ctx, cparams); + rv = ec_sync_phase2(ctx, cparams); if (rv) return rv; /* + * Do software sync for devices tunneled throught the EC. + */ + if (fw_update != VB_AUX_FW_NO_UPDATE) { + rv = VbExUpdateAuxFw(); + if (rv) + return rv; + } + + /* * Reboot to unload VGA Option ROM if: * - we displayed the wait screen * - the system has slow EC update flag set @@ -77,7 +93,7 @@ VbError_t ec_sync_all(struct vb2_context *ctx, struct VbCommonParams *cparams) return VBERROR_VGA_OPROM_MISMATCH; } - /* Do EC sync phase 3; this completes synd and handles battery cutoff */ + /* Do EC sync phase 3; this completes sync and handles battery cutoff */ rv = ec_sync_phase3(ctx, cparams); if (rv) return rv; diff --git a/firmware/lib/include/ec_sync.h b/firmware/lib/include/ec_sync.h index b629b2d5..78b08a20 100644 --- a/firmware/lib/include/ec_sync.h +++ b/firmware/lib/include/ec_sync.h @@ -43,6 +43,18 @@ int ec_will_update_slowly(struct vb2_context *ctx, struct VbCommonParams *cparams); /** + * Check if auxiliary firmware blobs need to be updated. + * + * @param ctx Vboot2 context + * @param cparams Vboot common params + * @param severity VB_AUX_FW_{NO,FAST,SLOW}_UPDATE + * @return VBERROR_SUCCESS or non-zero error code. + */ +VbError_t ec_sync_check_aux_fw(struct vb2_context *ctx, + struct VbCommonParams *cparams, + VbAuxFwUpdateSeverity_t *severity); + +/** * EC sync, phase 2 * * This updates the EC if necessary, makes sure it has protected its image(s), @@ -60,7 +72,6 @@ int ec_will_update_slowly(struct vb2_context *ctx, VbError_t ec_sync_phase2(struct vb2_context *ctx, struct VbCommonParams *cparams); - /** * EC sync, phase 3 * diff --git a/tests/ec_sync_tests.c b/tests/ec_sync_tests.c index b632fb6c..66ea1ca2 100644 --- a/tests/ec_sync_tests.c +++ b/tests/ec_sync_tests.c @@ -60,6 +60,9 @@ static struct vb2_shared_data *sd; static uint32_t screens_displayed[8]; static uint32_t screens_count = 0; +static int ec_aux_fw_update_req; +static VbAuxFwUpdateSeverity_t ec_aux_fw_update_severity; + /* Reset mock data (for use before each test) */ static void ResetMocks(void) { @@ -71,7 +74,7 @@ static void ResetMocks(void) memset(&gbb, 0, sizeof(gbb)); gbb.major_version = GBB_MAJOR_VER; gbb.minor_version = GBB_MINOR_VER; - gbb.flags = GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC; + gbb.flags = 0; cparams.gbb = &gbb; memset(&ctx, 0, sizeof(ctx)); @@ -117,6 +120,9 @@ static void ResetMocks(void) memset(screens_displayed, 0, sizeof(screens_displayed)); screens_count = 0; + + ec_aux_fw_update_severity = VB_AUX_FW_NO_UPDATE; + ec_aux_fw_update_req = 0; } /* Mock functions */ @@ -213,6 +219,18 @@ VbError_t VbDisplayScreen(struct vb2_context *ctx, VbCommonParams *cparams, return VBERROR_SUCCESS; } +VbError_t VbExCheckAuxFw(VbAuxFwUpdateSeverity_t *severity) +{ + *severity = ec_aux_fw_update_severity; + return VBERROR_SUCCESS; +} + +VbError_t VbExUpdateAuxFw() +{ + ec_aux_fw_update_req = 1; + return VBERROR_SUCCESS; +} + static void test_ssync(VbError_t retval, int recovery_reason, const char *desc) { TEST_EQ(ec_sync_all(&ctx, &cparams), retval, desc); @@ -398,6 +416,46 @@ static void VbSoftwareSyncTest(void) mock_in_rw = 1; shutdown_request_calls_left = 0; test_ssync(0, 0, "AP-RW shutdown requested"); + + ResetMocks(); + cparams.gbb->flags |= GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC; + ec_aux_fw_update_severity = VB_AUX_FW_FAST_UPDATE; + test_ssync(VBERROR_SUCCESS, 0, + "GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC" + " disables auxiliary FW update request"); + TEST_EQ(ec_aux_fw_update_req, 0, " aux fw update disabled"); + + ResetMocks(); + cparams.gbb->flags |= GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC; + ec_aux_fw_update_severity = VB_AUX_FW_FAST_UPDATE; + test_ssync(VBERROR_SUCCESS, 0, + "GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC" + " disables auxiliary FW update request"); + TEST_EQ(ec_aux_fw_update_req, 0, " aux fw update disabled"); + + ResetMocks(); + ec_aux_fw_update_severity = VB_AUX_FW_NO_UPDATE; + test_ssync(VBERROR_SUCCESS, 0, + "No auxiliary FW update needed"); + TEST_EQ(screens_count, 0, + " wait screen skipped"); + TEST_EQ(ec_aux_fw_update_req, 0, " no aux fw update requested"); + + ResetMocks(); + ec_aux_fw_update_severity = VB_AUX_FW_FAST_UPDATE; + test_ssync(VBERROR_SUCCESS, 0, + "Fast auxiliary FW update needed"); + TEST_EQ(screens_count, 0, + " wait screen skipped"); + TEST_EQ(ec_aux_fw_update_req, 1, " aux fw update requested"); + + ResetMocks(); + ec_aux_fw_update_severity = VB_AUX_FW_SLOW_UPDATE; + test_ssync(VBERROR_SUCCESS, 0, + "Slow auxiliary FW update needed"); + TEST_EQ(ec_aux_fw_update_req, 1, " aux fw update requested"); + TEST_EQ(screens_displayed[0], VB_SCREEN_WAIT, + " wait screen forced"); } int main(void) |