summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/lib/ec_sync.c34
-rw-r--r--firmware/lib/ec_sync_all.c22
-rw-r--r--firmware/lib/include/ec_sync.h13
-rw-r--r--tests/ec_sync_tests.c60
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)