| /* Copyright 2019 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| * |
| * Tests for auxfw synchronization. |
| */ |
| |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #include "2common.h" |
| #include "2misc.h" |
| #include "2nvstorage.h" |
| #include "2sysincludes.h" |
| #include "host_common.h" |
| #include "load_kernel_fw.h" |
| #include "test_common.h" |
| #include "vboot_audio.h" |
| #include "vboot_kernel.h" |
| #include "vboot_struct.h" |
| #include "vboot_ui_legacy.h" |
| |
| /* Mock data */ |
| static struct vb2_context *ctx; |
| static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE] |
| __attribute__((aligned(VB2_WORKBUF_ALIGN))); |
| static struct vb2_shared_data *sd; |
| static struct vb2_gbb_header gbb; |
| |
| static vb2_error_t auxfw_retval; |
| static int auxfw_update_req; |
| static enum vb2_auxfw_update_severity auxfw_mock_severity; |
| static enum vb2_auxfw_update_severity auxfw_update_severity; |
| static int auxfw_mock_display_available; |
| static int auxfw_protected; |
| static vb2_error_t auxfw_done_retval; |
| |
| /* Reset mock data (for use before each test) */ |
| static void ResetMocks(void) |
| { |
| TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx), |
| "vb2api_init failed"); |
| |
| ctx->flags = VB2_CONTEXT_EC_SYNC_SUPPORTED; |
| vb2_nv_init(ctx); |
| |
| sd = vb2_get_sd(ctx); |
| |
| memset(&gbb, 0, sizeof(gbb)); |
| |
| auxfw_retval = VB2_SUCCESS; |
| auxfw_mock_severity = VB2_AUXFW_NO_UPDATE; |
| auxfw_update_severity = VB2_AUXFW_NO_UPDATE; |
| auxfw_mock_display_available = 1; |
| auxfw_update_req = 0; |
| auxfw_protected = 0; |
| auxfw_done_retval = VB2_SUCCESS; |
| } |
| |
| /* Mock functions */ |
| struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c) |
| { |
| return &gbb; |
| } |
| |
| vb2_error_t vb2ex_auxfw_check(enum vb2_auxfw_update_severity *severity) |
| { |
| *severity = auxfw_mock_severity; |
| auxfw_update_severity = auxfw_mock_severity; |
| if (*severity == VB2_AUXFW_SLOW_UPDATE) |
| if (!auxfw_mock_display_available) |
| return VB2_REQUEST_REBOOT; |
| return VB2_SUCCESS; |
| } |
| |
| vb2_error_t vb2ex_auxfw_update(void) |
| { |
| if (auxfw_update_severity != VB2_AUXFW_NO_DEVICE && |
| auxfw_update_severity != VB2_AUXFW_NO_UPDATE) |
| auxfw_update_req = 1; |
| return auxfw_retval; |
| } |
| |
| vb2_error_t vb2ex_auxfw_finalize(struct vb2_context *c) |
| { |
| auxfw_protected = auxfw_update_severity != VB2_AUXFW_NO_DEVICE; |
| return auxfw_done_retval; |
| } |
| |
| static void test_auxsync(vb2_error_t retval, int recovery_reason, |
| const char *desc) |
| { |
| TEST_EQ(vb2api_auxfw_sync(ctx), retval, desc); |
| TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST), |
| recovery_reason, " recovery reason"); |
| } |
| |
| /* Tests */ |
| |
| static void VbSoftwareSyncTest(void) |
| { |
| ResetMocks(); |
| gbb.flags |= VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC; |
| auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE; |
| test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0, |
| "VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC" |
| " does not disable auxfw update request"); |
| TEST_EQ(auxfw_update_req, 1, " auxfw update requested"); |
| TEST_EQ(auxfw_protected, 0, " auxfw protected"); |
| |
| ResetMocks(); |
| gbb.flags |= VB2_GBB_FLAG_DISABLE_AUXFW_SOFTWARE_SYNC; |
| auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE; |
| test_auxsync(VB2_SUCCESS, 0, |
| "VB2_GBB_FLAG_DISABLE_AUXFW_SOFTWARE_SYNC" |
| " disables auxfw update request"); |
| TEST_EQ(auxfw_update_req, 0, " auxfw update disabled"); |
| TEST_EQ(auxfw_protected, 1, " auxfw protected"); |
| |
| ResetMocks(); |
| auxfw_mock_severity = VB2_AUXFW_NO_DEVICE; |
| test_auxsync(VB2_SUCCESS, 0, |
| "No auxfw update needed"); |
| TEST_EQ(auxfw_update_req, 0, " no auxfw update requested"); |
| TEST_EQ(auxfw_protected, 0, " no auxfw protected"); |
| |
| ResetMocks(); |
| auxfw_mock_severity = VB2_AUXFW_NO_UPDATE; |
| test_auxsync(VB2_SUCCESS, 0, |
| "No auxfw update needed"); |
| TEST_EQ(auxfw_update_req, 0, " no auxfw update requested"); |
| TEST_EQ(auxfw_protected, 1, " auxfw protected"); |
| |
| ResetMocks(); |
| auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE; |
| test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0, |
| "Fast auxfw update needed"); |
| TEST_EQ(auxfw_update_req, 1, " auxfw update requested"); |
| TEST_EQ(auxfw_protected, 0, " auxfw protected"); |
| |
| ResetMocks(); |
| auxfw_mock_severity = VB2_AUXFW_SLOW_UPDATE; |
| auxfw_mock_display_available = 0; |
| test_auxsync(VB2_REQUEST_REBOOT, 0, |
| "Slow auxfw update needed - reboot for display"); |
| |
| ResetMocks(); |
| auxfw_mock_severity = VB2_AUXFW_SLOW_UPDATE; |
| test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0, |
| "Slow auxfw update needed"); |
| TEST_EQ(auxfw_update_req, 1, " auxfw update requested"); |
| TEST_EQ(auxfw_protected, 0, " auxfw protected"); |
| |
| ResetMocks(); |
| auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE; |
| auxfw_retval = VB2_ERROR_UNKNOWN; |
| test_auxsync(VB2_ERROR_UNKNOWN, VB2_RECOVERY_AUXFW_UPDATE, |
| "Error updating auxfw"); |
| } |
| |
| int main(void) |
| { |
| VbSoftwareSyncTest(); |
| |
| return gTestSuccess ? 0 : 255; |
| } |