summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsuan Ting Chen <roccochen@chromium.org>2020-07-30 13:52:34 +0800
committerCommit Bot <commit-bot@chromium.org>2020-09-03 09:58:22 +0000
commit8196d4e598a86c31ac07c60de151d9e9c2f9502c (patch)
treed4c0cf6406fadc642509c5ac19064a7e399228fc
parentac15a1562c185f3c48a5f988ca7beef974d22f44 (diff)
downloadvboot-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.c6
-rw-r--r--firmware/2lib/2ui_screens.c99
-rw-r--r--firmware/2lib/include/2api.h16
-rw-r--r--tests/vb2_ui_tests.c55
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();