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>
This commit is contained in:
Daisuke Nojiri
2017-12-06 09:30:08 -08:00
committed by chrome-bot
parent f6780a36ff
commit eb13c06d2b
2 changed files with 54 additions and 17 deletions

View File

@@ -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);
}

View File

@@ -214,6 +214,10 @@ static void VbUserConfirmsTest(void)
shutdown_request_calls_left = 1;
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;