From 94801a71980ddf3295a7849bbe575327d295595d Mon Sep 17 00:00:00 2001 From: Meng-Huan Yu Date: Tue, 18 Aug 2020 18:05:19 +0800 Subject: minidiag: Add diagnostic menu screen BRANCH=none BUG=b:156692539, b:156693348 TEST=emerge-hatch vboot_reference TEST=unittest passed: ( export CC=x86_64-pc-linux-gnu-clang DEBUG=1 MENU_UI=0 DIAGNOSTIC_UI=0 MINIMAL=1 TPM2_MODE= MOCK_TPM=; make clean && make -j32 test_setup && make runtests; echo $? ) ( export CC=x86_64-pc-linux-gnu-clang DEBUG=1 MENU_UI=1 DIAGNOSTIC_UI=0 MINIMAL=1 TPM2_MODE= MOCK_TPM=; make clean && make -j32 test_setup && make runtests; echo $? ) ( export CC=x86_64-pc-linux-gnu-clang DEBUG=1 MENU_UI=0 DIAGNOSTIC_UI=1 MINIMAL=1 TPM2_MODE= MOCK_TPM=; make clean && make -j32 test_setup && make runtests; echo $? ) ( export CC=x86_64-pc-linux-gnu-clang DEBUG=1 MENU_UI=1 DIAGNOSTIC_UI=1 MINIMAL=1 TPM2_MODE= MOCK_TPM=; make clean && make -j32 test_setup && make runtests; echo $? ) Cq-Depend: chromium:2193314, chromium:2328704 Signed-off-by: Meng-Huan Yu Change-Id: I4f3c64ce53b14437cb14d3c1109e14608d082141 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2318590 Commit-Queue: Yu-Ping Wu Reviewed-by: Yu-Ping Wu --- firmware/2lib/2ui.c | 8 +++++++ firmware/2lib/2ui_screens.c | 24 +++++++++++++++++++ firmware/2lib/include/2api.h | 2 ++ firmware/2lib/include/2ui.h | 11 +++++++++ firmware/lib/vboot_api_kernel.c | 20 ++++++++-------- tests/vb2_ui_tests.c | 51 +++++++++++++++++++++++++++++++++++++++++ tests/vboot_api_kernel4_tests.c | 19 +++++++++++---- 7 files changed, 122 insertions(+), 13 deletions(-) diff --git a/firmware/2lib/2ui.c b/firmware/2lib/2ui.c index 85c00672..d80002d5 100644 --- a/firmware/2lib/2ui.c +++ b/firmware/2lib/2ui.c @@ -469,3 +469,11 @@ vb2_error_t manual_recovery_action(struct vb2_ui_context *ui) return VB2_REQUEST_UI_CONTINUE; } + +/*****************************************************************************/ +/* Diagnostics */ + +vb2_error_t vb2_diagnostic_menu(struct vb2_context *ctx) +{ + return ui_loop(ctx, VB2_SCREEN_DIAGNOSTICS, NULL); +} diff --git a/firmware/2lib/2ui_screens.c b/firmware/2lib/2ui_screens.c index 6728fe72..b8ff3a5c 100644 --- a/firmware/2lib/2ui_screens.c +++ b/firmware/2lib/2ui_screens.c @@ -906,6 +906,29 @@ static const struct vb2_screen_info developer_invalid_disk_screen = { .menu = MENU_ITEMS(developer_invalid_disk_items), }; +/******************************************************************************/ +/* VB2_SCREEN_DIAGNOSTICS */ + +static const struct vb2_menu_item diagnostics_items[] = { + LANGUAGE_SELECT_ITEM, + { + .text = "Storage", + }, + { + .text = "Quick memory check", + }, + { + .text = "Full memory check", + }, + POWER_OFF_ITEM, +}; + +static const struct vb2_screen_info diagnostics_screen = { + .id = VB2_SCREEN_DIAGNOSTICS, + .name = "Diagnostic tools", + .menu = MENU_ITEMS(diagnostics_items), +}; + /******************************************************************************/ /* * TODO(chromium:1035800): Refactor UI code across vboot and depthcharge. @@ -933,6 +956,7 @@ static const struct vb2_screen_info *screens[] = { &developer_to_norm_screen, &developer_boot_external_screen, &developer_invalid_disk_screen, + &diagnostics_screen, }; const struct vb2_screen_info *vb2_get_screen_info(enum vb2_screen id) diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index ad484825..a6c76764 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -1316,6 +1316,8 @@ enum vb2_screen { VB2_SCREEN_DEVELOPER_BOOT_EXTERNAL = 0x320, /* Invalid external disk inserted */ VB2_SCREEN_DEVELOPER_INVALID_DISK = 0x330, + /* Diagnostic tools */ + VB2_SCREEN_DIAGNOSTICS = 0x400, }; enum vb2_ui_error { diff --git a/firmware/2lib/include/2ui.h b/firmware/2lib/include/2ui.h index 790301ef..cc21f580 100644 --- a/firmware/2lib/include/2ui.h +++ b/firmware/2lib/include/2ui.h @@ -229,4 +229,15 @@ vb2_error_t vb2_broken_recovery_menu(struct vb2_context *ctx); */ vb2_error_t vb2_manual_recovery_menu(struct vb2_context *ctx); +/** + * UI for a diagnostic tools boot. + * + * Enter the diagnostic tools menu, which provides debug information and + * diagnostic tests of various hardware components. + * + * @param ctx Vboot context + * @returns VB2_SUCCESS, or non-zero error code. + */ +vb2_error_t vb2_diagnostic_menu(struct vb2_context *ctx); + #endif /* VBOOT_REFERENCE_2UI_H_ */ diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c index eeabde8e..a910b552 100644 --- a/firmware/lib/vboot_api_kernel.c +++ b/firmware/lib/vboot_api_kernel.c @@ -240,18 +240,20 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx, } else { VB2_TRY(VbBootRecoveryLegacyClamshell(ctx)); } - } else if (DIAGNOSTIC_UI && !MENU_UI && - vb2api_diagnostic_ui_enabled(ctx) && + } else if (DIAGNOSTIC_UI && vb2api_diagnostic_ui_enabled(ctx) && vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST)) { vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 0); - /* - * Diagnostic boot. This has a UI but only power button - * is used for input so no detachable-specific UI is - * needed. This mode is also 1-shot so it's placed - * before developer mode. - */ - VB2_TRY(VbBootDiagnosticLegacyClamshell(ctx)); + /* Diagnostic boot. This has UI. */ + if (MENU_UI) + VB2_TRY(vb2_diagnostic_menu(ctx)); + else + /* + * Only power button is used for input so no + * detachable-specific UI is needed. This mode is also + * 1-shot so it's placed before developer mode. + */ + VB2_TRY(VbBootDiagnosticLegacyClamshell(ctx)); /* * The diagnostic menu should either boot a rom, or * return either of reboot or shutdown. diff --git a/tests/vb2_ui_tests.c b/tests/vb2_ui_tests.c index c29f7f77..00c6e935 100644 --- a/tests/vb2_ui_tests.c +++ b/tests/vb2_ui_tests.c @@ -236,6 +236,7 @@ enum reset_type { FOR_DEVELOPER, FOR_BROKEN_RECOVERY, FOR_MANUAL_RECOVERY, + FOR_DIAGNOSTICS, }; /* Reset mock data (for use before each test) */ @@ -1548,6 +1549,55 @@ static void manual_recovery_screen_tests(void) VB2_DEBUG("...done.\n"); } +static void diagnostics_screen_tests(void) +{ + VB2_DEBUG("Testing diagnostic screens...\n"); + + /* Diagnostics screen */ + reset_common_data(FOR_DIAGNOSTICS); + + /* #0: Language menu */ + add_mock_keypress(VB_KEY_UP); + add_mock_keypress(VB_KEY_ENTER); + /* #1: Storage (no-op) */ + add_mock_keypress(VB_KEY_ESC); + add_mock_keypress(VB_KEY_DOWN); + /* #2: Quick memory test (no-op) */ + add_mock_keypress(VB_KEY_DOWN); + /* #3: Full memory test (no-op) */ + add_mock_keypress(VB_KEY_DOWN); + /* #4: Power off (End of menu) */ + add_mock_keypress(VB_KEY_DOWN); + add_mock_keypress(VB_KEY_ENTER); + mock_calls_until_shutdown = -1; + TEST_EQ(vb2_diagnostic_menu(ctx), VB2_REQUEST_SHUTDOWN, + "diagnostic screen"); + + DISPLAYED_EQ("default on first button of menu", + VB2_SCREEN_DIAGNOSTICS, MOCK_IGNORE, 1, 0x0, MOCK_IGNORE); + /* #0: Language menu */ + DISPLAYED_EQ("language selection", + VB2_SCREEN_DIAGNOSTICS, MOCK_IGNORE, 0, 0x0, MOCK_IGNORE); + DISPLAYED_EQ("#0: language menu", VB2_SCREEN_LANGUAGE_SELECT, + MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); + /* #1: Storage (no-op) */ + DISPLAYED_PASS(); + DISPLAYED_EQ("storage button", + VB2_SCREEN_DIAGNOSTICS, MOCK_IGNORE, 1, 0x0, MOCK_IGNORE); + /* #2: Quick memory test (no-op) */ + DISPLAYED_EQ("quick memory test button", + VB2_SCREEN_DIAGNOSTICS, MOCK_IGNORE, 2, 0x0, MOCK_IGNORE); + /* #3: Full memory test (no-op) */ + DISPLAYED_EQ("full memory test button", + VB2_SCREEN_DIAGNOSTICS, MOCK_IGNORE, 3, 0x0, MOCK_IGNORE); + /* #4: Power of (End of menu) */ + DISPLAYED_EQ("power off", + VB2_SCREEN_DIAGNOSTICS, MOCK_IGNORE, 4, 0x0, MOCK_IGNORE); + DISPLAYED_NO_EXTRA(); + + VB2_DEBUG("...done.\n"); +} + int main(void) { developer_tests(); @@ -1560,6 +1610,7 @@ int main(void) developer_screen_tests(); broken_recovery_screen_tests(); manual_recovery_screen_tests(); + diagnostics_screen_tests(); return gTestSuccess ? 0 : 255; } diff --git a/tests/vboot_api_kernel4_tests.c b/tests/vboot_api_kernel4_tests.c index 8076d837..1e687484 100644 --- a/tests/vboot_api_kernel4_tests.c +++ b/tests/vboot_api_kernel4_tests.c @@ -177,6 +177,15 @@ vb2_error_t vb2_broken_recovery_menu(struct vb2_context *c) return vbboot_retval; } +vb2_error_t vb2_diagnostic_menu(struct vb2_context *c) +{ + TEST_TRUE(MENU_UI, "Using menu_ui"); + if (vbboot_retval == -5) + return VB2_ERROR_MOCK; + + return vbboot_retval; +} + vb2_error_t VbBootRecoveryLegacyClamshell(struct vb2_context *c) { rec_check(c); @@ -197,6 +206,7 @@ vb2_error_t VbBootRecoveryLegacyMenu(struct vb2_context *c) vb2_error_t VbBootDiagnosticLegacyClamshell(struct vb2_context *c) { + TEST_TRUE(!MENU_UI, "Not using menu_ui"); if (vbboot_retval == -5) return VB2_ERROR_MOCK; @@ -268,20 +278,21 @@ static void select_and_load_kernel_tests(void) test_slk(VB2_ERROR_MOCK, 0, "Normal boot bad"); /* Check that NV_DIAG_REQUEST triggers diagnostic UI */ - if (DIAGNOSTIC_UI && !MENU_UI) { + if (DIAGNOSTIC_UI) { reset_common_data(); mock_diagnostic_ui_enabled = 1; vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1); vbboot_retval = -5; test_slk(VB2_ERROR_MOCK, 0, "Normal boot with diag enabled"); - TEST_EQ(vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST), - 0, " diag not requested"); + TEST_EQ(vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST), 0, + " diag not requested"); reset_common_data(); vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1); test_slk(VB2_REQUEST_REBOOT, 0, - "Normal boot with diag disabled (reboot to unset)"); + "Normal boot with diag disabled (reboot to " + "unset)"); } /* Boot normal - phase1 failure */ -- cgit v1.2.1