SARIEN ONLY: do not wait for power button release

In order to be compatible with the current cr50 firmware this change
will make the user confirmation screen not wait for power button
release and instead return true when it is pressed.

Since it is no longer looking for power button release it also reads
and ignores the power button on recovery ui start, in case the power
button was held down too long when doing Refresh+Power.

BUG=b:129471321
BRANCH=sarien (ONLY)
TEST=successfully enter developer mode on sarien

Change-Id: I0b4d1e336b4fdfca102058543ca5d7d0dc055fff
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1626930
Reviewed-by: Julius Werner <jwerner@chromium.org>
diff --git a/firmware/lib/vboot_ui.c b/firmware/lib/vboot_ui.c
index a6688f7..700c29a 100644
--- a/firmware/lib/vboot_ui.c
+++ b/firmware/lib/vboot_ui.c
@@ -27,16 +27,13 @@
 #include "vboot_kernel.h"
 #include "vboot_ui_common.h"
 
-/* Global variables */
-enum {
-	POWER_BUTTON_HELD_SINCE_BOOT = 0,
-	POWER_BUTTON_RELEASED,
-	POWER_BUTTON_PRESSED, /* must have been previously released */
-} power_button_state;
-
 void vb2_init_ui(void)
 {
-	power_button_state = POWER_BUTTON_HELD_SINCE_BOOT;
+	/*
+	 * Read and ignore the current power button state in
+	 * case it was held down at boot.
+	 */
+	VbExIsShutdownRequested();
 }
 
 static void VbAllowUsbBoot(struct vb2_context *ctx)
@@ -59,22 +56,6 @@
 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
 	uint32_t shutdown_request = VbExIsShutdownRequested();
 
-	/*
-	 * Ignore power button push until after we have seen it released.
-	 * This avoids shutting down immediately if the power button is still
-	 * being held on startup. After we've recognized a valid power button
-	 * push then don't report the event until after the button is released.
-	 */
-	if (shutdown_request & VB_SHUTDOWN_REQUEST_POWER_BUTTON) {
-		shutdown_request &= ~VB_SHUTDOWN_REQUEST_POWER_BUTTON;
-		if (power_button_state == POWER_BUTTON_RELEASED)
-			power_button_state = POWER_BUTTON_PRESSED;
-	} else {
-		if (power_button_state == POWER_BUTTON_PRESSED)
-			shutdown_request |= VB_SHUTDOWN_REQUEST_POWER_BUTTON;
-		power_button_state = POWER_BUTTON_RELEASED;
-	}
-
 	if (key == VB_BUTTON_POWER_SHORT_PRESS)
 		shutdown_request |= VB_SHUTDOWN_REQUEST_POWER_BUTTON;
 
@@ -114,8 +95,6 @@
 	VbSharedDataHeader *shared = sd->vbsd;
 	uint32_t key;
 	uint32_t key_flags;
-	uint32_t btn;
-	int phys_presence_button_was_pressed = 0;
 	int shutdown_requested = 0;
 
 	VB2_DEBUG("Entering(%x)\n", confirm_flags);
@@ -123,7 +102,14 @@
 	/* Await further instructions */
 	do {
 		key = VbExKeyboardReadWithFlags(&key_flags);
-		shutdown_requested = VbWantShutdown(ctx, key);
+
+		/* Do not use untrusted keyboard input */
+		if (confirm_flags & VB_CONFIRM_MUST_TRUST_KEYBOARD &&
+		    !(key_flags & VB_KEY_FLAG_TRUSTED_KEYBOARD))
+			shutdown_requested = VbWantShutdown(ctx, 0);
+		else
+			shutdown_requested = VbWantShutdown(ctx, key);
+
 		switch (key) {
 		case VB_KEY_ENTER:
 			/* If we require a trusted keyboard for confirmation,
@@ -154,21 +140,17 @@
 			break;
 		default:
 			/* If the physical presence button is physical, and is
-			 * pressed, this is also a YES, but must wait for
-			 * release.
+			 * pressed, this is also a YES.
+			 *
+			 * HACK for sarien: do not wait for release
+			 * https://issuetracker.google.com/129471321
 			 */
-			btn = VbExGetSwitches(
-				VB_SWITCH_FLAG_PHYS_PRESENCE_PRESSED);
-			if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL)) {
-				if (btn) {
-					VB2_DEBUG("Presence button pressed, "
-						  "awaiting release\n");
-					phys_presence_button_was_pressed = 1;
-				} else if (phys_presence_button_was_pressed) {
-					VB2_DEBUG("Presence button released "
-						  "(1)\n");
-					return 1;
-				}
+			if (!(shared->flags & VBSD_BOOT_REC_SWITCH_VIRTUAL) &&
+			    (confirm_flags & VB_CONFIRM_MUST_TRUST_KEYBOARD) &&
+			    (shutdown_requested &
+					VB_SHUTDOWN_REQUEST_POWER_BUTTON)) {
+				VB2_DEBUG("Presence button pressed (1)\n");
+				return 1;
 			}
 			VbCheckDisplayKey(ctx, key, NULL);
 		}
@@ -969,6 +951,7 @@
 
 VbError_t VbBootRecovery(struct vb2_context *ctx)
 {
+	vb2_init_ui();
 	VbError_t retval = recovery_ui(ctx);
 	VbDisplayScreen(ctx, VB_SCREEN_BLANK, 0, NULL);
 	return retval;
diff --git a/tests/vboot_api_kernel2_tests.c b/tests/vboot_api_kernel2_tests.c
index cb2471f..8cf1291 100644
--- a/tests/vboot_api_kernel2_tests.c
+++ b/tests/vboot_api_kernel2_tests.c
@@ -131,7 +131,9 @@
 	uint32_t result = 0;
 	if (mock_gpio_count >= ARRAY_SIZE(mock_gpio))
 		return 0;
-	if (mock_gpio[mock_gpio_count].gpio_flags & GPIO_SHUTDOWN)
+	/* Tread power button as presence */
+	if (mock_gpio[mock_gpio_count].gpio_flags &
+	    (GPIO_SHUTDOWN | GPIO_PRESENCE))
 		result |= VB_SHUTDOWN_REQUEST_POWER_BUTTON;
 	if (mock_gpio[mock_gpio_count].gpio_flags & GPIO_LID_CLOSED)
 		result |= VB_SHUTDOWN_REQUEST_LID_CLOSED;
@@ -376,42 +378,26 @@
 	 *   B means both shutdown and presence gpio
 	 *
 	 *  1: ______ppp______ -> confirm
-	 *  2: ______sss______ -> shutdown
 	 *  3: ___pppsss______ -> confirm
-	 *  4: ___sssppp______ -> shutdown
 	 *  5: ___pppBBB______ -> confirm
-	 *  6: ___pppBBBppp___ -> shutdown
 	 *  7: ___pppBBBsss___ -> confirm
 	 *  8: ___sssBBB______ -> confirm
-	 *  9: ___sssBBBppp___ -> shutdown
 	 * 10: ___sssBBBsss___ -> confirm
 	 * 11: ______BBB______ -> confirm
 	 * 12: ______BBBsss___ -> confirm
-	 * 13: ______BBBppp___ -> shutdown
 	 */
 
 	/* 1: presence means confirm */
 	VbUserConfirmsTestGpio(GPIO_PRESENCE, 0, 0, 1, "presence");
 
-	/* 2: shutdown means shutdown */
-	VbUserConfirmsTestGpio(GPIO_SHUTDOWN, 0, 0, 0, "shutdown");
-
 	/* 3: presence then shutdown means confirm */
 	VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_SHUTDOWN, 0, 1,
 			       "presence then shutdown");
 
-	/* 4: shutdown then presence means shutdown */
-	VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE, 0, 0,
-			       "shutdown then presence");
-
 	/* 5: presence then shutdown+presence then none mean confirm */
 	VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN,
 			       0, 1, "presence, both, none");
 
-	/* 6: presence then shutdown+presence then presence means shutdown */
-	VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN,
-			       GPIO_PRESENCE, 0, "presence, both, presence");
-
 	/* 7: presence then shutdown+presence then shutdown means confirm */
 	VbUserConfirmsTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN,
 			       GPIO_SHUTDOWN, 1, "presence, both, shutdown");
@@ -420,10 +406,6 @@
 	VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN,
 			       0, 1, "shutdown, both, none");
 
-	/* 9: shutdown then shutdown+presence then presence means shutdown */
-	VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN,
-			       GPIO_PRESENCE, 0, "shutdown, both, presence");
-
 	/* 10: shutdown then shutdown+presence then shutdown means confirm */
 	VbUserConfirmsTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN,
 			       GPIO_SHUTDOWN, 1, "shutdown, both, shutdown");
@@ -436,10 +418,6 @@
 	VbUserConfirmsTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN,
 			       GPIO_SHUTDOWN, 0, 1, "both, shutdown");
 
-	/* 13: shutdown+presence then presence means shutdown */
-	VbUserConfirmsTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN,
-			       GPIO_PRESENCE, 0, 0, "both, presence");
-
 	ResetMocks();
 	mock_keypress[0] = VB_KEY_ENTER;
 	mock_keypress[1] = 'y';
@@ -450,7 +428,7 @@
 	TEST_EQ(VbUserConfirms(&ctx,
 			       VB_CONFIRM_SPACE_MEANS_NO |
 			       VB_CONFIRM_MUST_TRUST_KEYBOARD),
-		0, "Recovery button stuck");
+		-1, "Recovery button stuck (shutdown)");
 	printf("...done.\n");
 }
 
@@ -1068,14 +1046,14 @@
 		VBERROR_SHUTDOWN_REQUESTED,
 		"Shutdown requested by keyboard");
 
-	/* Ignore power button held on boot */
+	/* Ignore first read of power button held on boot */
 	ResetMocks();
 	mock_gpio[0].gpio_flags = GPIO_SHUTDOWN;
-	mock_gpio[0].count = 10;
+	mock_gpio[0].count = 0;
 	mock_gpio[1].gpio_flags = 0;
-	mock_gpio[1].count = 10;
+	mock_gpio[1].count = 0;
 	mock_gpio[2].gpio_flags = GPIO_SHUTDOWN;
-	mock_gpio[2].count = 10;
+	mock_gpio[2].count = 0;
 	mock_gpio[3].gpio_flags = 0;
 	mock_gpio[3].count = 100;
 	shared->flags = VBSD_BOOT_REC_SWITCH_ON;
@@ -1083,11 +1061,11 @@
 	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
 	TEST_EQ(VbBootRecovery(&ctx),
 		VBERROR_SHUTDOWN_REQUESTED,
-		"Ignore power button held on boot");
+		"Ignore first power button press on boot");
 	TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
 		"  insert screen");
-	/* Shutdown should happen while we're sending the 2nd block of events */
-	TEST_EQ(mock_gpio_count, 3, "  ignore held button");
+	/* The second power button read (in first block) will shutdown */
+	TEST_EQ(mock_gpio_count, 3, "  ignore first power button press");
 
 	/* Broken screen */
 	ResetMocks();
@@ -1259,45 +1237,27 @@
 	 *   B means both shutdown and presence gpio
 	 *
 	 *  1: ______ppp______ -> confirm
-	 *  2: ______sss______ -> shutdown
 	 *  3: ___pppsss______ -> confirm
-	 *  4: ___sssppp______ -> shutdown
 	 *  5: ___pppBBB______ -> confirm
-	 *  6: ___pppBBBppp___ -> shutdown
 	 *  7: ___pppBBBsss___ -> confirm
 	 *  8: ___sssBBB______ -> confirm
-	 *  9: ___sssBBBppp___ -> shutdown
 	 * 10: ___sssBBBsss___ -> confirm
 	 * 11: ______BBB______ -> confirm
 	 * 12: ______BBBsss___ -> confirm
-	 * 13: ______BBBppp___ -> shutdown
 	 */
 
 	/* 1: Ctrl+D then presence means enable */
 	VbBootRecTestGpio(GPIO_PRESENCE, 0, 0, 1,
 			  "Ctrl+D todev confirm via presence");
 
-	/* 2: Ctrl+D then shutdown means shutdown */
-	VbBootRecTestGpio(GPIO_SHUTDOWN, 0, 0, 0,
-			  "Ctrl+D todev then shutdown");
-
 	/* 3: Ctrl+D then presence then shutdown means confirm */
 	VbBootRecTestGpio(GPIO_PRESENCE, GPIO_SHUTDOWN, 0, 1,
 			  "Ctrl+D todev confirm via presence then shutdown");
 
-	/* 4: Ctrl+D then 2+ instance shutdown then presence means shutdown */
-	VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE, 0, 0,
-			  "Ctrl+D todev then 2+ shutdown then presence");
-
 	/* 5: Ctrl+D then presence then shutdown+presence then none */
 	VbBootRecTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN, 0, 1,
 			  "Ctrl+D todev confirm via presence, both, none");
 
-	/* 6: Ctrl+D then presence then shutdown+presence then presence */
-	VbBootRecTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN,
-			  GPIO_PRESENCE, 0,
-			  "Ctrl+D todev confirm via presence, both, presence");
-
 	/* 7: Ctrl+D then presence then shutdown+presence then shutdown */
 	VbBootRecTestGpio(GPIO_PRESENCE, GPIO_PRESENCE | GPIO_SHUTDOWN,
 			  GPIO_SHUTDOWN, 1,
@@ -1307,11 +1267,6 @@
 	VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN, 0, 1,
 			  "Ctrl+D todev then 2+ shutdown, both, none");
 
-	/* 9: Ctrl+D then shutdown then shutdown+presence then presence */
-	VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN,
-			  GPIO_PRESENCE, 0,
-			  "Ctrl+D todev then 2+ shutdown, both, presence");
-
 	/* 10: Ctrl+D then shutdown then shutdown+presence then shutdown */
 	VbBootRecTestGpio(GPIO_SHUTDOWN, GPIO_PRESENCE | GPIO_SHUTDOWN,
 			  GPIO_SHUTDOWN, 1,
@@ -1325,10 +1280,6 @@
 	VbBootRecTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_SHUTDOWN, 0, 1,
 			  "Ctrl+D todev confirm via both then shutdown");
 
-	/* 13: Ctrl+D then shutdown+presence then presence */
-	VbBootRecTestGpio(GPIO_PRESENCE | GPIO_SHUTDOWN, GPIO_PRESENCE, 0, 0,
-			  "Ctrl+D todev confirm via both then presence");
-
 	/* Handle TPM error in enabling dev mode */
 	ResetMocks();
 	shared->flags = VBSD_BOOT_REC_SWITCH_ON;