summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@google.com>2017-05-12 16:46:41 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-08-22 22:33:44 +0000
commita84d085b72acd6df881bcced0062bf7db6f332e8 (patch)
tree6dd301d6cfb8c9510af66c73d6626ee92b642cc0
parent406b14d78f27d3143f3a7cd384c8159e33be44c1 (diff)
downloadvboot-a84d085b72acd6df881bcced0062bf7db6f332e8.tar.gz
call depthcharge hooks for auxiliary FW update.
this adds calls to depthcharge (using callbacks) to do auxiliary firmware updates. in particular, this is intended to trigger TCPC updates, but other programmables could also be updated. no firmware updates take place until a board file has actually registered a firmware update "driver". board file updates to follow. TEST="COV=1 make" passes. depthcharge boots on snappy. with additional follow-on CLs, we can update the ps8751. the companion depthcharge changes are here: https://chromium-review.googlesource.com/c/498150/ the working design doc is here: https://docs.google.com/a/google.com/document/d/1uzS0b3O3Us1QI2Sx7LDkjEfHmuhYB2BolrAoNwCVoc0/edit?usp=sharing these features depend on vboot API updates: CQ-DEPEND=CL:498150 BUG=b:35586896 BRANCH=none Signed-off-by: Caveh Jalali <caveh@google.com> Reviewed-on: https://chromium-review.googlesource.com/505260 Reviewed-by: Stefan Reinauer <reinauer@chromium.org> (cherry picked from commit 3dd580298b42d9d77e1f37733e4df2b6d5c302c6) Change-Id: I553f7a184c0872c1b9bd046677b641a1eab1893e Reviewed-on: https://chromium-review.googlesource.com/611644 Commit-Queue: Caveh Jalali <caveh@google.com> Reviewed-by: Caveh Jalali <caveh@google.com> Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Tested-by: Caveh Jalali <caveh@google.com>
-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 77687a40..a81baa0e 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"
@@ -426,8 +427,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;
@@ -435,10 +443,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 a32d34dd..43c2bb5c 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)