summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsuan Ting Chen <roccochen@chromium.org>2020-09-23 14:55:24 +0800
committerCommit Bot <commit-bot@chromium.org>2020-11-12 12:40:03 +0000
commit58894ec1de7fa63948a04f72434931081f0458e4 (patch)
tree279443064ae7c06da339f14c656721e1be97a98e
parent7991ecdb219a5290e2e5a9663b19fce8e5b15145 (diff)
downloadvboot-58894ec1de7fa63948a04f72434931081f0458e4.tar.gz
vboot/ui: Remove extra delay for long iteration time
If an iteration takes longer than KEY_DELAY_MS, no extra delay. Otherwise, delay until the iteration time reaches KEY_DELAY_MS. BUG=b:168776970 BRANCH=none TEST=Build locally Signed-off-by: Hsuan Ting Chen <roccochen@chromium.org> Change-Id: Ia78dbe1cc87d08c02f99f4fc9269929c12c18b77 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2424373
-rw-r--r--firmware/2lib/2ui.c7
-rw-r--r--tests/vb2_ui_action_tests.c85
2 files changed, 91 insertions, 1 deletions
diff --git a/firmware/2lib/2ui.c b/firmware/2lib/2ui.c
index 24f74736..10de1760 100644
--- a/firmware/2lib/2ui.c
+++ b/firmware/2lib/2ui.c
@@ -300,6 +300,7 @@ vb2_error_t ui_loop(struct vb2_context *ctx, enum vb2_screen root_screen_id,
const struct vb2_menu *menu;
const struct vb2_screen_info *root_info;
uint32_t key_flags;
+ uint32_t start_time_ms, elapsed_ms;
vb2_error_t rv;
memset(&ui, 0, sizeof(ui));
@@ -316,6 +317,8 @@ vb2_error_t ui_loop(struct vb2_context *ctx, enum vb2_screen root_screen_id,
prev_error_code = VB2_UI_ERROR_NONE;
while (1) {
+ start_time_ms = vb2ex_mtime();
+
/* Draw if there are state changes. */
if (memcmp(&prev_state, ui.state, sizeof(*ui.state)) ||
/* Redraw when timer is disabled. */
@@ -392,7 +395,9 @@ vb2_error_t ui_loop(struct vb2_context *ctx, enum vb2_screen root_screen_id,
}
/* Delay. */
- vb2ex_msleep(KEY_DELAY_MS);
+ elapsed_ms = vb2ex_mtime() - start_time_ms;
+ if (elapsed_ms < KEY_DELAY_MS)
+ vb2ex_msleep(KEY_DELAY_MS - elapsed_ms);
}
return VB2_SUCCESS;
diff --git a/tests/vb2_ui_action_tests.c b/tests/vb2_ui_action_tests.c
index 84bb9e04..f6f18dcc 100644
--- a/tests/vb2_ui_action_tests.c
+++ b/tests/vb2_ui_action_tests.c
@@ -71,6 +71,9 @@ static int mock_vbexlegacy_called;
static enum VbAltFwIndex_t mock_altfw_num_last;
static uint32_t mock_bootloader_count;
+static uint32_t mock_time_ms;
+static const uint32_t mock_time_start_ms = 31ULL * VB2_MSEC_PER_SEC;
+
/* Mock actions */
static uint32_t mock_action_called;
static uint32_t mock_action_countdown_limit;
@@ -114,6 +117,13 @@ static vb2_error_t mock_action_flag2(struct vb2_ui_context *ui)
return VB2_REQUEST_UI_CONTINUE;
}
+static uint32_t mock_action_delay_ms;
+static vb2_error_t mock_action_msleep(struct vb2_ui_context *ui)
+{
+ vb2ex_msleep(mock_action_delay_ms);
+ return VB2_REQUEST_UI_CONTINUE;
+}
+
/* Mock screens */
struct vb2_screen_info mock_screen_temp;
const struct vb2_screen_info mock_screen_blank = {
@@ -339,6 +349,7 @@ static void reset_common_data(void)
mock_action_called = 0;
mock_action_countdown_limit = 1;
mock_action_flags = 0;
+ mock_action_delay_ms = 0;
/* For chagen_screen and vb2_get_screen_info */
mock_get_screen_info_called = 0;
@@ -355,6 +366,9 @@ static void reset_common_data(void)
mock_vbexlegacy_called = 0;
mock_altfw_num_last = -100;
mock_bootloader_count = 2;
+
+ /* For vb2ex_mtime and vb2ex_msleep */
+ mock_time_ms = mock_time_start_ms;
}
/* Mock functions */
@@ -499,6 +513,16 @@ uint32_t vb2ex_get_bootloader_count(void)
return mock_bootloader_count;
}
+uint32_t vb2ex_mtime(void)
+{
+ return mock_time_ms;
+}
+
+void vb2ex_msleep(uint32_t msec)
+{
+ mock_time_ms += msec;
+}
+
/* Tests */
static void menu_prev_tests(void)
{
@@ -962,6 +986,66 @@ static void ui_loop_tests(void)
VB2_DEBUG("...done.\n");
}
+static void ui_loop_delay_tests(void)
+{
+ VB2_DEBUG("Testing ui_loop delay...\n");
+
+ /* Sleep for 20 ms each iteration */
+ reset_common_data();
+ mock_calls_until_shutdown = 1;
+ TEST_EQ(ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
+ VB2_REQUEST_SHUTDOWN, " sleep for 20 ms in each iteration");
+ TEST_EQ(mock_time_ms - mock_time_start_ms, KEY_DELAY_MS,
+ " delay 20 ms in total");
+
+ /* Complement to 20 ms */
+ reset_common_data();
+ mock_calls_until_shutdown = 1;
+ mock_action_delay_ms = KEY_DELAY_MS / 2;
+ TEST_EQ(ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
+ VB2_REQUEST_SHUTDOWN, " complement to 20 ms");
+ TEST_EQ(mock_time_ms - mock_time_start_ms, KEY_DELAY_MS,
+ " delay 10 ms in total");
+
+ /* No extra sleep if an iteration takes longer than KEY_DELAY_MS */
+ reset_common_data();
+ mock_calls_until_shutdown = 1;
+ mock_action_delay_ms = 1234;
+ TEST_EQ(ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
+ VB2_REQUEST_SHUTDOWN, " no extra sleep time");
+ TEST_EQ(mock_time_ms - mock_time_start_ms, mock_action_delay_ms,
+ " no extra delay");
+
+ /* Integer overflow */
+ reset_common_data();
+ mock_calls_until_shutdown = 1;
+ mock_time_ms = UINT32_MAX;
+ TEST_EQ(ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
+ VB2_REQUEST_SHUTDOWN, " integer overflow #1");
+ TEST_EQ(mock_time_ms - UINT32_MAX, KEY_DELAY_MS,
+ " delay 20 ms in total");
+
+ reset_common_data();
+ mock_calls_until_shutdown = 1;
+ mock_time_ms = UINT32_MAX;
+ mock_action_delay_ms = KEY_DELAY_MS / 2;
+ TEST_EQ(ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
+ VB2_REQUEST_SHUTDOWN, " integer overflow #2");
+ TEST_EQ(mock_time_ms - UINT32_MAX, KEY_DELAY_MS,
+ " delay 10 ms in total");
+
+ reset_common_data();
+ mock_calls_until_shutdown = 1;
+ mock_time_ms = UINT32_MAX;
+ mock_action_delay_ms = 1234;
+ TEST_EQ(ui_loop(ctx, MOCK_SCREEN_BASE, mock_action_msleep),
+ VB2_REQUEST_SHUTDOWN, " integer overflow #3");
+ TEST_EQ(mock_time_ms - UINT32_MAX, mock_action_delay_ms,
+ " no extra delay");
+
+ VB2_DEBUG("...done.\n");
+}
+
int main(void)
{
/* Input actions */
@@ -977,6 +1061,7 @@ int main(void)
/* Core UI loop */
ui_loop_tests();
+ ui_loop_delay_tests();
return gTestSuccess ? 0 : 255;
}