diff options
author | Hsuan Ting Chen <roccochen@chromium.org> | 2020-07-30 13:52:34 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-09-03 09:58:22 +0000 |
commit | 8196d4e598a86c31ac07c60de151d9e9c2f9502c (patch) | |
tree | d4c0cf6406fadc642509c5ac19064a7e399228fc | |
parent | ac15a1562c185f3c48a5f988ca7beef974d22f44 (diff) | |
download | vboot-8196d4e598a86c31ac07c60de151d9e9c2f9502c.tar.gz |
vboot/ui: Implement firmware log screen
Implement firmware log screen which can be accessed from advanced
options menu.
The screen displays a snapshot for the firmware log using the same
layout of debug info screen.
BRANCH=puff, zork
BUG=b:146399181, b:146105976
TEST=CC=x86_64-pc-linux-gnu-clang;
make clean && make runtests
TEST=USE="menu_ui" emerge-puff depthcharge
TEST=USE="menu_ui" emerge-zork depthcharge
TEST=select "advanced options",
and navigate to firmware log screen
Cq-Depend: chromium:2334490
Signed-off-by: Hsuan Ting Chen <roccochen@chromium.org>
Change-Id: I3cb5800d71925aa20ca4d5636172885e23fd0099
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2328241
Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
-rw-r--r-- | firmware/2lib/2stub.c | 6 | ||||
-rw-r--r-- | firmware/2lib/2ui_screens.c | 99 | ||||
-rw-r--r-- | firmware/2lib/include/2api.h | 16 | ||||
-rw-r--r-- | tests/vb2_ui_tests.c | 55 |
4 files changed, 166 insertions, 10 deletions
diff --git a/firmware/2lib/2stub.c b/firmware/2lib/2stub.c index 738092db..90041cbc 100644 --- a/firmware/2lib/2stub.c +++ b/firmware/2lib/2stub.c @@ -81,6 +81,12 @@ const char *vb2ex_get_debug_info(struct vb2_context *ctx) } __attribute__((weak)) +const char *vb2ex_get_firmware_log(void) +{ + return NULL; +} + +__attribute__((weak)) uint32_t vb2ex_prepare_log_screen(const char *str) { return 1; diff --git a/firmware/2lib/2ui_screens.c b/firmware/2lib/2ui_screens.c index a2cd60ff..6728fe72 100644 --- a/firmware/2lib/2ui_screens.c +++ b/firmware/2lib/2ui_screens.c @@ -240,6 +240,10 @@ static const struct vb2_menu_item advanced_options_items[] = { .text = "Debug info", .target = VB2_SCREEN_DEBUG_INFO, }, + { + .text = "Firmware log", + .target = VB2_SCREEN_FIRMWARE_LOG, + }, BACK_ITEM, POWER_OFF_ITEM, }; @@ -261,8 +265,14 @@ static const struct vb2_screen_info advanced_options_screen = { static vb2_error_t debug_info_init(struct vb2_ui_context *ui) { const char *log_string = vb2ex_get_debug_info(ui->ctx); + if (!log_string) { + VB2_DEBUG("ERROR: Failed to retrieve debug info\n"); + ui->error_code = VB2_UI_ERROR_DEBUG_LOG; + return vb2_ui_screen_back(ui); + } ui->state->page_count = vb2ex_prepare_log_screen(log_string); if (ui->state->page_count == 0) { + VB2_DEBUG("ERROR: Failed to prepare debug info screen\n"); ui->error_code = VB2_UI_ERROR_DEBUG_LOG; return vb2_ui_screen_back(ui); } @@ -276,8 +286,14 @@ static vb2_error_t debug_info_init(struct vb2_ui_context *ui) static vb2_error_t debug_info_reinit(struct vb2_ui_context *ui) { const char *log_string = vb2ex_get_debug_info(ui->ctx); + if (!log_string) { + VB2_DEBUG("ERROR: Failed to retrieve debug info\n"); + ui->error_code = VB2_UI_ERROR_DEBUG_LOG; + return vb2_ui_screen_back(ui); + } ui->state->page_count = vb2ex_prepare_log_screen(log_string); if (ui->state->page_count == 0) { + VB2_DEBUG("ERROR: Failed to prepare debug info screen\n"); ui->error_code = VB2_UI_ERROR_DEBUG_LOG; return vb2_ui_screen_back(ui); } @@ -322,6 +338,88 @@ static const struct vb2_screen_info debug_info_screen = { }; /******************************************************************************/ +/* VB2_SCREEN_FIRMWARE_LOG */ + +#define FIRMWARE_LOG_ITEM_PAGE_UP 1 +#define FIRMWARE_LOG_ITEM_PAGE_DOWN 2 +#define FIRMWARE_LOG_ITEM_BACK 3 + +static vb2_error_t firmware_log_init(struct vb2_ui_context *ui) +{ + const char *log_string = vb2ex_get_firmware_log(); + if (!log_string) { + VB2_DEBUG("ERROR: Failed to retrieve firmware log\n"); + ui->error_code = VB2_UI_ERROR_FIRMWARE_LOG; + return vb2_ui_screen_back(ui); + } + ui->state->page_count = vb2ex_prepare_log_screen(log_string); + if (ui->state->page_count == 0) { + VB2_DEBUG("ERROR: Failed to prepare firmware log screen\n"); + ui->error_code = VB2_UI_ERROR_FIRMWARE_LOG; + return vb2_ui_screen_back(ui); + } + + return log_page_init(ui, + FIRMWARE_LOG_ITEM_PAGE_UP, + FIRMWARE_LOG_ITEM_PAGE_DOWN, + FIRMWARE_LOG_ITEM_BACK); +} + +static vb2_error_t firmware_log_reinit(struct vb2_ui_context *ui) +{ + const char *log_string = vb2ex_get_firmware_log(); + if (!log_string) { + VB2_DEBUG("ERROR: Failed to retrieve firmware log\n"); + ui->error_code = VB2_UI_ERROR_FIRMWARE_LOG; + return vb2_ui_screen_back(ui); + } + ui->state->page_count = vb2ex_prepare_log_screen(log_string); + if (ui->state->page_count == 0) { + VB2_DEBUG("ERROR: Failed to prepare firmware log screen\n"); + ui->error_code = VB2_UI_ERROR_FIRMWARE_LOG; + return vb2_ui_screen_back(ui); + } + + return VB2_REQUEST_UI_CONTINUE; +} + +static vb2_error_t firmware_log_page_prev_action(struct vb2_ui_context *ui) +{ + return log_page_prev(ui, + FIRMWARE_LOG_ITEM_PAGE_UP, + FIRMWARE_LOG_ITEM_PAGE_DOWN); +} + +static vb2_error_t firmware_log_page_next_action(struct vb2_ui_context *ui) +{ + return log_page_next(ui, + FIRMWARE_LOG_ITEM_PAGE_UP, + FIRMWARE_LOG_ITEM_PAGE_DOWN); +} + +static const struct vb2_menu_item firmware_log_items[] = { + LANGUAGE_SELECT_ITEM, + [FIRMWARE_LOG_ITEM_PAGE_UP] = { + .text = "Page up", + .action = firmware_log_page_prev_action, + }, + [FIRMWARE_LOG_ITEM_PAGE_DOWN] = { + .text = "Page down", + .action = firmware_log_page_next_action, + }, + [FIRMWARE_LOG_ITEM_BACK] = BACK_ITEM, + POWER_OFF_ITEM, +}; + +static const struct vb2_screen_info firmware_log_screen = { + .id = VB2_SCREEN_FIRMWARE_LOG, + .name = "Firmware log", + .init = firmware_log_init, + .reinit = firmware_log_reinit, + .menu = MENU_ITEMS(firmware_log_items), +}; + +/******************************************************************************/ /* VB2_SCREEN_RECOVERY_SELECT */ #define RECOVERY_SELECT_ITEM_PHONE 1 @@ -822,6 +920,7 @@ static const struct vb2_screen_info *screens[] = { &recovery_broken_screen, &advanced_options_screen, &debug_info_screen, + &firmware_log_screen, &recovery_select_screen, &recovery_invalid_screen, &recovery_to_dev_screen, diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index c2f636e8..ad484825 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -1293,6 +1293,8 @@ enum vb2_screen { VB2_SCREEN_LANGUAGE_SELECT = 0x130, /* Debug info */ VB2_SCREEN_DEBUG_INFO = 0x140, + /* Firmware log */ + VB2_SCREEN_FIRMWARE_LOG = 0x150, /* First recovery screen to select recovering from disk or phone */ VB2_SCREEN_RECOVERY_SELECT = 0x200, /* Invalid recovery media inserted */ @@ -1323,6 +1325,8 @@ enum vb2_ui_error { VB2_UI_ERROR_DEV_MODE_ALREADY_ENABLED, /* Debug info screen initialization failed */ VB2_UI_ERROR_DEBUG_LOG, + /* Firmware log screen initialization failed */ + VB2_UI_ERROR_FIRMWARE_LOG, /* Untrusted confirmation */ VB2_UI_ERROR_UNTRUSTED_CONFIRMATION, }; @@ -1412,6 +1416,18 @@ const char *vb2ex_get_debug_info(struct vb2_context *ctx); char *vb2api_get_debug_info(struct vb2_context *ctx); /** + * Get the full firmware log string. + * + * Return a pointer to the full firmware log string which is guaranteed to be + * null-terminated. The function implementation should snapshot the full + * firmware log when it is called the first time. Subsequent calls should + * return the same pointer. + * + * @return The pointer to the full firmware log string. NULL on error. + */ +const char *vb2ex_get_firmware_log(void); + +/** * Specify the string to be used for an upcoming log screen display. * * Before a vb2ex_display_ui() call is made for a screen which displays logs, diff --git a/tests/vb2_ui_tests.c b/tests/vb2_ui_tests.c index 2dca5467..c29f7f77 100644 --- a/tests/vb2_ui_tests.c +++ b/tests/vb2_ui_tests.c @@ -515,7 +515,12 @@ void vb2_enable_developer_mode(struct vb2_context *c) const char *vb2ex_get_debug_info(struct vb2_context *c) { - return NULL; + return "mocked debug info"; +} + +const char *vb2ex_get_firmware_log(void) +{ + return "mocked firmware log"; } uint32_t vb2ex_prepare_log_screen(const char *str) @@ -1261,7 +1266,11 @@ static void developer_screen_tests(void) add_mock_keypress(VB_KEY_ESC); add_mock_keypress(VB_KEY_DOWN); add_mock_keypress(VB_KEY_ENTER); - /* #3: Back */ + /* #3: Firmware log */ + add_mock_keypress(VB_KEY_ESC); + add_mock_keypress(VB_KEY_DOWN); + add_mock_keypress(VB_KEY_ENTER); + /* #4: Back */ add_mock_keypress(VB_KEY_ESC); add_mock_keypress(VB_KEY_DOWN); add_mock_keypress(VB_KEY_ENTER); @@ -1286,11 +1295,17 @@ static void developer_screen_tests(void) MOCK_IGNORE, 2, 0x2, MOCK_IGNORE); DISPLAYED_EQ("#2: debug info", VB2_SCREEN_DEBUG_INFO, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); - /* #3: Back */ + /* #3: Firmware log */ DISPLAYED_PASS(); DISPLAYED_EQ("advanced options", VB2_SCREEN_ADVANCED_OPTIONS, MOCK_IGNORE, 3, 0x2, MOCK_IGNORE); - DISPLAYED_EQ("#3: back", VB2_SCREEN_DEVELOPER_MODE, + DISPLAYED_EQ("#3: firmware log", VB2_SCREEN_FIRMWARE_LOG, + MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); + /* #4: Back */ + DISPLAYED_PASS(); + DISPLAYED_EQ("advanced options", VB2_SCREEN_ADVANCED_OPTIONS, + MOCK_IGNORE, 4, 0x2, MOCK_IGNORE); + DISPLAYED_EQ("#4: back", VB2_SCREEN_DEVELOPER_MODE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); /* End of menu */ DISPLAYED_EQ("end of menu", VB2_SCREEN_ADVANCED_OPTIONS, @@ -1344,7 +1359,11 @@ static void broken_recovery_screen_tests(void) add_mock_keypress(VB_KEY_ESC); add_mock_keypress(VB_KEY_DOWN); add_mock_keypress(VB_KEY_ENTER); - /* #3: Back */ + /* #3: Firmware log */ + add_mock_keypress(VB_KEY_ESC); + add_mock_keypress(VB_KEY_DOWN); + add_mock_keypress(VB_KEY_ENTER); + /* #4: Back */ add_mock_keypress(VB_KEY_ESC); add_mock_keypress(VB_KEY_DOWN); add_mock_keypress(VB_KEY_ENTER); @@ -1367,11 +1386,17 @@ static void broken_recovery_screen_tests(void) MOCK_IGNORE, 2, 0x2, MOCK_IGNORE); DISPLAYED_EQ("#2: debug info", VB2_SCREEN_DEBUG_INFO, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); - /* #3: Back */ + /* #3: Firmware log */ DISPLAYED_PASS(); DISPLAYED_EQ("advanced options", VB2_SCREEN_ADVANCED_OPTIONS, MOCK_IGNORE, 3, 0x2, MOCK_IGNORE); - DISPLAYED_EQ("#3: back", VB2_SCREEN_RECOVERY_BROKEN, + DISPLAYED_EQ("#3: firmware log", VB2_SCREEN_FIRMWARE_LOG, + MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); + /* #4: Back */ + DISPLAYED_PASS(); + DISPLAYED_EQ("advanced options", VB2_SCREEN_ADVANCED_OPTIONS, + MOCK_IGNORE, 4, 0x2, MOCK_IGNORE); + DISPLAYED_EQ("#4: back", VB2_SCREEN_RECOVERY_BROKEN, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); /* End of menu */ DISPLAYED_EQ("end of menu", VB2_SCREEN_ADVANCED_OPTIONS, @@ -1465,7 +1490,11 @@ static void manual_recovery_screen_tests(void) add_mock_keypress(VB_KEY_ESC); add_mock_keypress(VB_KEY_DOWN); add_mock_keypress(VB_KEY_ENTER); - /* #3: Back */ + /* #3: Firmware log */ + add_mock_keypress(VB_KEY_ESC); + add_mock_keypress(VB_KEY_DOWN); + add_mock_keypress(VB_KEY_ENTER); + /* #4: Back */ add_mock_keypress(VB_KEY_ESC); add_mock_keypress(VB_KEY_DOWN); add_mock_keypress(VB_KEY_ENTER); @@ -1498,11 +1527,17 @@ static void manual_recovery_screen_tests(void) MOCK_IGNORE, 2, 0x0, MOCK_IGNORE); DISPLAYED_EQ("#2: debug info", VB2_SCREEN_DEBUG_INFO, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); - /* #3: Back */ + /* #3: Firmware log */ DISPLAYED_PASS(); DISPLAYED_EQ("advanced options", VB2_SCREEN_ADVANCED_OPTIONS, MOCK_IGNORE, 3, 0x0, MOCK_IGNORE); - DISPLAYED_EQ("#3: back", VB2_SCREEN_RECOVERY_SELECT, + DISPLAYED_EQ("#3: firmware log", VB2_SCREEN_FIRMWARE_LOG, + MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); + /* #4: Back */ + DISPLAYED_PASS(); + DISPLAYED_EQ("advanced options", VB2_SCREEN_ADVANCED_OPTIONS, + MOCK_IGNORE, 4, 0x0, MOCK_IGNORE); + DISPLAYED_EQ("#4: back", VB2_SCREEN_RECOVERY_SELECT, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE, MOCK_IGNORE); /* End of menu */ DISPLAYED_PASS(); |