summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2017-12-06 09:30:08 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-12-08 16:36:56 +0000
commita776696d079e1fa8507802a3749951bec98143df (patch)
treeb28ba1281a9ba057d5af852250b43d5405b634ff
parentf39d959d4647868b06b27e449cff26ddd5eda458 (diff)
downloadvboot-a776696d079e1fa8507802a3749951bec98143df.tar.gz
vboot_ui: Let keyboard power button shut down system
This patch allows a power button on a keyboard to shut down the system when waiting for a user interaction at a firmware screen. The firmware menu, which is implemented by vboot_ui_menu, shouldn't be affected. BUG=b:70244028 BRANCH=none TEST=Verify power button on Fizz can shut down the system at recovery screen, broken screen, todev scree, and user confirmation screen using a USB keyboard and a servo. Verify recovery button can confirm dev mode transition. Run 'make runmisctests' successfully. Change-Id: Icc7d7a774da19acac3d2938d5748ad2323ba4856 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/811444 Reviewed-by: Randall Spangler <rspangler@chromium.org> (cherry picked from commit eb13c06d2ba27f09996168409472cade82807414) Reviewed-on: https://chromium-review.googlesource.com/817756
-rw-r--r--firmware/lib/vboot_ui.c35
-rw-r--r--tests/vboot_api_kernel2_tests.c36
2 files changed, 54 insertions, 17 deletions
diff --git a/firmware/lib/vboot_ui.c b/firmware/lib/vboot_ui.c
index a99945e5..c44b70b1 100644
--- a/firmware/lib/vboot_ui.c
+++ b/firmware/lib/vboot_ui.c
@@ -39,10 +39,13 @@ static void VbAllowUsbBoot(struct vb2_context *ctx)
*
* Returns true if a shutdown is required and false if no shutdown is required.
*/
-static int VbWantShutdown(uint32_t gbb_flags)
+static int VbWantShutdown(uint32_t gbb_flags, uint32_t key)
{
uint32_t shutdown_request = VbExIsShutdownRequested();
+ if (key == VB_BUTTON_POWER_SHORT_PRESS)
+ shutdown_request |= VB_SHUTDOWN_REQUEST_POWER_BUTTON;
+
/* If desired, ignore shutdown request due to lid closure. */
if (gbb_flags & GBB_FLAG_DISABLE_LID_SHUTDOWN)
shutdown_request &= ~VB_SHUTDOWN_REQUEST_LID_CLOSED;
@@ -92,20 +95,19 @@ int VbUserConfirms(struct vb2_context *ctx, VbCommonParams *cparams,
uint32_t confirm_flags)
{
VbSharedDataHeader *shared =
- (VbSharedDataHeader *)cparams->shared_data_blob;
+ (VbSharedDataHeader *)cparams->shared_data_blob;
uint32_t key;
uint32_t key_flags;
- uint32_t button;
+ uint32_t btn;
int rec_button_was_pressed = 0;
VB2_DEBUG("Entering(%x)\n", confirm_flags);
/* Await further instructions */
while (1) {
- if (VbWantShutdown(cparams->gbb->flags))
- return -1;
key = VbExKeyboardReadWithFlags(&key_flags);
- button = VbExGetSwitches(VB_INIT_FLAG_REC_BUTTON_PRESSED);
+ if (VbWantShutdown(cparams->gbb->flags, key))
+ return -1;
switch (key) {
case '\r':
/* If we require a trusted keyboard for confirmation,
@@ -116,8 +118,7 @@ int VbUserConfirms(struct vb2_context *ctx, VbCommonParams *cparams,
!(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD)) {
VbExBeep(120, 400);
break;
- }
-
+ }
VB2_DEBUG("Yes (1)\n");
return 1;
break;
@@ -135,10 +136,11 @@ int VbUserConfirms(struct vb2_context *ctx, VbCommonParams *cparams,
/* If the recovery button is physical, and is pressed,
* this is also a YES, but must wait for release.
*/
+ btn = VbExGetSwitches(VB_INIT_FLAG_REC_BUTTON_PRESSED);
if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL)) {
- if (button) {
+ if (btn) {
VB2_DEBUG("Rec button pressed\n");
- rec_button_was_pressed = 1;
+ rec_button_was_pressed = 1;
} else if (rec_button_was_pressed) {
VB2_DEBUG("Rec button (1)\n");
return 1;
@@ -243,15 +245,13 @@ VbError_t vb2_developer_ui(struct vb2_context *ctx, VbCommonParams *cparams)
/* We'll loop until we finish the delay or are interrupted */
do {
- uint32_t key;
-
- if (VbWantShutdown(gbb->flags)) {
+ uint32_t key = VbExKeyboardRead();
+ if (VbWantShutdown(gbb->flags, key)) {
VB2_DEBUG("VbBootDeveloper() - shutdown requested!\n");
VbAudioClose(audio);
return VBERROR_SHUTDOWN_REQUESTED;
}
- key = VbExKeyboardRead();
switch (key) {
case 0:
/* nothing pressed */
@@ -445,8 +445,9 @@ static VbError_t recovery_ui(struct vb2_context *ctx, VbCommonParams *cparams)
VbDisplayScreen(ctx, cparams, VB_SCREEN_OS_BROKEN, 0);
VB2_DEBUG("VbBootRecovery() waiting for manual recovery\n");
while (1) {
- VbCheckDisplayKey(ctx, cparams, VbExKeyboardRead());
- if (VbWantShutdown(cparams->gbb->flags))
+ key = VbExKeyboardRead();
+ VbCheckDisplayKey(ctx, cparams, key);
+ if (VbWantShutdown(cparams->gbb->flags, key))
return VBERROR_SHUTDOWN_REQUESTED;
VbExSleepMs(REC_KEY_DELAY);
}
@@ -543,7 +544,7 @@ static VbError_t recovery_ui(struct vb2_context *ctx, VbCommonParams *cparams)
} else {
VbCheckDisplayKey(ctx, cparams, key);
}
- if (VbWantShutdown(cparams->gbb->flags))
+ if (VbWantShutdown(cparams->gbb->flags, key))
return VBERROR_SHUTDOWN_REQUESTED;
VbExSleepMs(REC_KEY_DELAY);
}
diff --git a/tests/vboot_api_kernel2_tests.c b/tests/vboot_api_kernel2_tests.c
index 02a9087a..384c978d 100644
--- a/tests/vboot_api_kernel2_tests.c
+++ b/tests/vboot_api_kernel2_tests.c
@@ -215,6 +215,10 @@ static void VbUserConfirmsTest(void)
TEST_EQ(VbUserConfirms(&ctx, &cparams, 0), -1, "Shutdown requested");
ResetMocks();
+ mock_keypress[0] = VB_BUTTON_POWER_SHORT_PRESS;
+ TEST_EQ(VbUserConfirms(&ctx, &cparams, 0), -1, "Shutdown requested");
+
+ ResetMocks();
mock_keypress[0] = '\r';
TEST_EQ(VbUserConfirms(&ctx, &cparams, 0), 1, "Enter");
@@ -351,6 +355,13 @@ static void VbBootDevTest(void)
"Shutdown requested");
TEST_NEQ(audio_looping_calls_left, 0, " aborts audio");
+ /* Shutdown requested by keyboard in loop */
+ ResetMocks();
+ mock_keypress[0] = VB_BUTTON_POWER_SHORT_PRESS;
+ TEST_EQ(VbBootDeveloper(&ctx, &cparams),
+ VBERROR_SHUTDOWN_REQUESTED,
+ "Shutdown requested by keyboard");
+
/* Space goes straight to recovery if no virtual dev switch */
ResetMocks();
mock_keypress[0] = ' ';
@@ -428,6 +439,14 @@ static void VbBootDevTest(void)
TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
" tonorm screen");
+ /* Shutdown requested by keyboard at tonorm screen */
+ ResetMocks();
+ shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
+ mock_keypress[0] = VB_BUTTON_POWER_SHORT_PRESS;
+ TEST_EQ(VbBootDeveloper(&ctx, &cparams),
+ VBERROR_SHUTDOWN_REQUESTED,
+ "Shutdown requested by keyboard at nonorm");
+
/* Ctrl+D dismisses warning */
ResetMocks();
mock_keypress[0] = 0x04;
@@ -534,6 +553,15 @@ static void VbBootDevTest(void)
TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_TO_NORM,
" tonorm screen");
+ /* Shutdown requested by keyboard when dev disabled */
+ ResetMocks();
+ shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
+ VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
+ mock_keypress[0] = VB_BUTTON_POWER_SHORT_PRESS;
+ TEST_EQ(VbBootDeveloper(&ctx, &cparams),
+ VBERROR_SHUTDOWN_REQUESTED,
+ "Shutdown requested by keyboard when dev disabled");
+
printf("...done.\n");
}
@@ -555,6 +583,14 @@ static void VbBootRecTest(void)
TEST_EQ(screens_displayed[0], VB_SCREEN_OS_BROKEN,
" broken screen");
+ /* Shutdown requested by keyboard */
+ ResetMocks();
+ VbExEcEnteringMode(0, VB_EC_RECOVERY);
+ mock_keypress[0] = VB_BUTTON_POWER_SHORT_PRESS;
+ TEST_EQ(VbBootRecovery(&ctx, &cparams),
+ VBERROR_SHUTDOWN_REQUESTED,
+ "Shutdown requested by keyboard");
+
/* Remove disks */
ResetMocks();
shutdown_request_calls_left = 100;