vboot_logic: Set VB2_CONTEXT_EC_TRUSTED in verstage_main

vboot_reference is introducing a new field (ctx) to store the current
boot mode in crrev/c/2944250 (ctx->bootmode), which will be leveraged
in both vboot flow and elog_add_boot_reason in coreboot.

In current steps of deciding bootmode, a function vb2ex_ec_trusted
is required. This function checks gpio EC_IN_RW pin and will return
'trusted' only if EC is not in RW. Therefore, we need to implement
similar utilities in coreboot.

We will deprecate vb2ex_ec_trusted and use the flag,
VB2_CONTEXT_EC_TRUSTED, in vboot, vb2api_fw_phase1 and set that flag
in coreboot, verstage_main.

Also add a help function get_ec_is_trusted which needed to be
implemented per mainboard.

BUG=b:177196147, b:181931817
BRANCH=none
TEST=Test on trogdor if manual recovery works

Signed-off-by: Hsuan Ting Chen <roccochen@chromium.org>
Change-Id: I479c8f80e45cc524ba87db4293d19b29bdfa2192
Reviewed-on: https://review.coreboot.org/c/coreboot/+/57048
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/include/bootmode.h b/src/include/bootmode.h
index aadecba..da2dbf6 100644
--- a/src/include/bootmode.h
+++ b/src/include/bootmode.h
@@ -11,6 +11,7 @@
 int clear_recovery_mode_switch(void);
 int get_wipeout_mode_switch(void);
 int get_lid_switch(void);
+int get_ec_is_trusted(void);
 
 /* Return 1 if display initialization is required. 0 if not. */
 int display_init_required(void);
diff --git a/src/mainboard/google/asurada/chromeos.c b/src/mainboard/google/asurada/chromeos.c
index 6f8f242..1aa8876 100644
--- a/src/mainboard/google/asurada/chromeos.c
+++ b/src/mainboard/google/asurada/chromeos.c
@@ -40,3 +40,9 @@
 {
 	return gpio_eint_poll(GPIO_H1_AP_INT);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. This is active low. */
+	return !!gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/auron/chromeos.c b/src/mainboard/google/auron/chromeos.c
index 50eeddc..f449c9c 100644
--- a/src/mainboard/google/auron/chromeos.c
+++ b/src/mainboard/google/auron/chromeos.c
@@ -8,6 +8,13 @@
 /* SPI Write protect is GPIO 16 */
 #define CROS_WP_GPIO	58
 
+/* EC_IN_RW is GPIO 25 in samus and 14 otherwise */
+#if CONFIG(BOARD_GOOGLE_SAMUS)
+#define EC_IN_RW_GPIO	25
+#else
+#define EC_IN_RW_GPIO	14
+#endif
+
 void fill_lb_gpios(struct lb_gpios *gpios)
 {
 	struct lb_gpio chromeos_gpios[] = {
@@ -32,3 +39,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !get_gpio(EC_IN_RW_GPIO);
+}
diff --git a/src/mainboard/google/beltino/chromeos.c b/src/mainboard/google/beltino/chromeos.c
index a33caca..5c49649 100644
--- a/src/mainboard/google/beltino/chromeos.c
+++ b/src/mainboard/google/beltino/chromeos.c
@@ -65,3 +65,10 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/brya/chromeos.c b/src/mainboard/google/brya/chromeos.c
index add73464..184cd52 100644
--- a/src/mainboard/google/brya/chromeos.c
+++ b/src/mainboard/google/brya/chromeos.c
@@ -29,3 +29,9 @@
 	gpios = variant_cros_gpios(&num);
 	chromeos_acpi_gpio_generate(gpios, num);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/butterfly/chromeos.c b/src/mainboard/google/butterfly/chromeos.c
index 356e97b..960dd87 100644
--- a/src/mainboard/google/butterfly/chromeos.c
+++ b/src/mainboard/google/butterfly/chromeos.c
@@ -77,3 +77,10 @@
 
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/cherry/chromeos.c b/src/mainboard/google/cherry/chromeos.c
index 748e06e..13b673c 100644
--- a/src/mainboard/google/cherry/chromeos.c
+++ b/src/mainboard/google/cherry/chromeos.c
@@ -59,3 +59,9 @@
 {
 	return gpio_eint_poll(GPIO_GSC_AP_INT);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. This is active low. */
+	return !!gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/cyan/chromeos.c b/src/mainboard/google/cyan/chromeos.c
index b88862c..4a48aeb 100644
--- a/src/mainboard/google/cyan/chromeos.c
+++ b/src/mainboard/google/cyan/chromeos.c
@@ -12,6 +12,8 @@
 
 #define WP_GPIO			GP_E_22
 
+#define EC_IN_RW_GPIO		GP_SW_77
+
 #define ACTIVE_LOW	0
 #define ACTIVE_HIGH	1
 
@@ -62,3 +64,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(EC_IN_RW_GPIO);
+}
diff --git a/src/mainboard/google/daisy/chromeos.c b/src/mainboard/google/daisy/chromeos.c
index 7599295..9cb57f8 100644
--- a/src/mainboard/google/daisy/chromeos.c
+++ b/src/mainboard/google/daisy/chromeos.c
@@ -37,3 +37,9 @@
 {
 	return !gpio_get_value(GPIO_D16);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get_value(GPIO_D17);
+}
diff --git a/src/mainboard/google/dedede/chromeos.c b/src/mainboard/google/dedede/chromeos.c
index fb904cc..6be7652 100644
--- a/src/mainboard/google/dedede/chromeos.c
+++ b/src/mainboard/google/dedede/chromeos.c
@@ -30,3 +30,9 @@
 	gpios = variant_cros_gpios(&num);
 	chromeos_acpi_gpio_generate(gpios, num);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/deltaur/chromeos.c b/src/mainboard/google/deltaur/chromeos.c
index 9d3929e..b2c34a2 100644
--- a/src/mainboard/google/deltaur/chromeos.c
+++ b/src/mainboard/google/deltaur/chromeos.c
@@ -111,3 +111,10 @@
 	if (ENV_RAMSTAGE)
 		pmc_soc_set_afterg3_en(true);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/drallion/chromeos.c b/src/mainboard/google/drallion/chromeos.c
index d92ebb1..607f7c3 100644
--- a/src/mainboard/google/drallion/chromeos.c
+++ b/src/mainboard/google/drallion/chromeos.c
@@ -110,3 +110,10 @@
 	pmc_soc_set_afterg3_en(true);
 #endif
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/eve/chromeos.c b/src/mainboard/google/eve/chromeos.c
index 11931c6..10a837d 100644
--- a/src/mainboard/google/eve/chromeos.c
+++ b/src/mainboard/google/eve/chromeos.c
@@ -34,3 +34,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/fizz/chromeos.c b/src/mainboard/google/fizz/chromeos.c
index a74c2f7..593982b 100644
--- a/src/mainboard/google/fizz/chromeos.c
+++ b/src/mainboard/google/fizz/chromeos.c
@@ -34,3 +34,9 @@
 	gpios = variant_cros_gpios(&num);
 	chromeos_acpi_gpio_generate(gpios, num);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/foster/chromeos.c b/src/mainboard/google/foster/chromeos.c
index 38d12cb..8ed41cd 100644
--- a/src/mainboard/google/foster/chromeos.c
+++ b/src/mainboard/google/foster/chromeos.c
@@ -26,3 +26,10 @@
 {
 	return 0;
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/gale/chromeos.c b/src/mainboard/google/gale/chromeos.c
index 4674581..ac464b4 100644
--- a/src/mainboard/google/gale/chromeos.c
+++ b/src/mainboard/google/gale/chromeos.c
@@ -157,3 +157,10 @@
 {
 	return !read_gpio(get_wp_status_gpio_pin());
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/glados/chromeos.c b/src/mainboard/google/glados/chromeos.c
index 6a1f0b4..70b4f64 100644
--- a/src/mainboard/google/glados/chromeos.c
+++ b/src/mainboard/google/glados/chromeos.c
@@ -33,3 +33,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/gru/chromeos.c b/src/mainboard/google/gru/chromeos.c
index 688c0dd..479ca3d 100644
--- a/src/mainboard/google/gru/chromeos.c
+++ b/src/mainboard/google/gru/chromeos.c
@@ -49,3 +49,9 @@
 	return gpio_irq_status(GPIO_TPM_IRQ);
 }
 #endif
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/guybrush/chromeos.c b/src/mainboard/google/guybrush/chromeos.c
index f129957..c1621d9 100644
--- a/src/mainboard/google/guybrush/chromeos.c
+++ b/src/mainboard/google/guybrush/chromeos.c
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
 #include <baseboard/gpio.h>
+#include <boardid.h>
 #include <boot/coreboot_tables.h>
 #include <gpio.h>
 #include <vendorcode/google/chromeos/chromeos.h>
@@ -24,3 +25,14 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Board versions 1 & 2 support H1 DB, but the EC_IN_RW signal is not
+	   routed. So emulate EC is trusted. */
+	if (CONFIG(BOARD_GOOGLE_GUYBRUSH) &&
+	    (board_id() == UNDEFINED_STRAPPING_ID || board_id() < 3))
+		return 1;
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/hatch/chromeos.c b/src/mainboard/google/hatch/chromeos.c
index ee54ade..400a3fa 100644
--- a/src/mainboard/google/hatch/chromeos.c
+++ b/src/mainboard/google/hatch/chromeos.c
@@ -34,3 +34,9 @@
 
 	chromeos_acpi_gpio_generate(cros_gpios, num_gpios);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/herobrine/chromeos.c b/src/mainboard/google/herobrine/chromeos.c
index 643dcc2..319f929 100644
--- a/src/mainboard/google/herobrine/chromeos.c
+++ b/src/mainboard/google/herobrine/chromeos.c
@@ -18,3 +18,9 @@
 
 	lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Stub GPIO. */
+	return 0;
+}
diff --git a/src/mainboard/google/jecht/chromeos.c b/src/mainboard/google/jecht/chromeos.c
index cf59636..bc00994 100644
--- a/src/mainboard/google/jecht/chromeos.c
+++ b/src/mainboard/google/jecht/chromeos.c
@@ -67,3 +67,10 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/kahlee/chromeos.c b/src/mainboard/google/kahlee/chromeos.c
index b85f976..1f81f22 100644
--- a/src/mainboard/google/kahlee/chromeos.c
+++ b/src/mainboard/google/kahlee/chromeos.c
@@ -32,3 +32,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/kukui/chromeos.c b/src/mainboard/google/kukui/chromeos.c
index 3f15a3f..4c4a8be 100644
--- a/src/mainboard/google/kukui/chromeos.c
+++ b/src/mainboard/google/kukui/chromeos.c
@@ -37,3 +37,9 @@
 {
 	return gpio_eint_poll(CR50_IRQ);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(EC_IN_RW);
+}
diff --git a/src/mainboard/google/link/chromeos.c b/src/mainboard/google/link/chromeos.c
index 540803c..ce9a33d 100644
--- a/src/mainboard/google/link/chromeos.c
+++ b/src/mainboard/google/link/chromeos.c
@@ -6,6 +6,8 @@
 #include <southbridge/intel/common/gpio.h>
 #include <vendorcode/google/chromeos/chromeos.h>
 
+#define GPIO_EC_IN_RW 21
+
 void fill_lb_gpios(struct lb_gpios *gpios)
 {
 	struct lb_gpio chromeos_gpios[] = {
@@ -37,3 +39,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !get_gpio(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/mistral/chromeos.c b/src/mainboard/google/mistral/chromeos.c
index c827c7d..171a8ee 100644
--- a/src/mainboard/google/mistral/chromeos.c
+++ b/src/mainboard/google/mistral/chromeos.c
@@ -1,8 +1,16 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
 #include <boot/coreboot_tables.h>
+#include <vendorcode/google/chromeos/chromeos.h>
 
 void fill_lb_gpios(struct lb_gpios *gpios)
 {
 
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/nyan/chromeos.c b/src/mainboard/google/nyan/chromeos.c
index 7fe877b..9aaad2f 100644
--- a/src/mainboard/google/nyan/chromeos.c
+++ b/src/mainboard/google/nyan/chromeos.c
@@ -19,3 +19,9 @@
 {
 	return !gpio_get(GPIO(R1));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO(U4));
+}
diff --git a/src/mainboard/google/nyan_big/chromeos.c b/src/mainboard/google/nyan_big/chromeos.c
index 7fe877b..9aaad2f 100644
--- a/src/mainboard/google/nyan_big/chromeos.c
+++ b/src/mainboard/google/nyan_big/chromeos.c
@@ -19,3 +19,9 @@
 {
 	return !gpio_get(GPIO(R1));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO(U4));
+}
diff --git a/src/mainboard/google/nyan_blaze/chromeos.c b/src/mainboard/google/nyan_blaze/chromeos.c
index 7fe877b..9aaad2f 100644
--- a/src/mainboard/google/nyan_blaze/chromeos.c
+++ b/src/mainboard/google/nyan_blaze/chromeos.c
@@ -19,3 +19,9 @@
 {
 	return !gpio_get(GPIO(R1));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO(U4));
+}
diff --git a/src/mainboard/google/oak/chromeos.c b/src/mainboard/google/oak/chromeos.c
index 9e7af27..739df2e 100644
--- a/src/mainboard/google/oak/chromeos.c
+++ b/src/mainboard/google/oak/chromeos.c
@@ -34,3 +34,9 @@
 {
 	return !gpio_get(WRITE_PROTECT);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(EC_IN_RW);
+}
diff --git a/src/mainboard/google/octopus/chromeos.c b/src/mainboard/google/octopus/chromeos.c
index 03d3b4f..4a7f040 100644
--- a/src/mainboard/google/octopus/chromeos.c
+++ b/src/mainboard/google/octopus/chromeos.c
@@ -33,3 +33,9 @@
 	gpios = variant_cros_gpios(&num);
 	chromeos_acpi_gpio_generate(gpios, num);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/parrot/chromeos.c b/src/mainboard/google/parrot/chromeos.c
index 03b0d47..346fe76 100644
--- a/src/mainboard/google/parrot/chromeos.c
+++ b/src/mainboard/google/parrot/chromeos.c
@@ -68,3 +68,10 @@
 
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/peach_pit/chromeos.c b/src/mainboard/google/peach_pit/chromeos.c
index ebbfdd3..3d4f51c 100644
--- a/src/mainboard/google/peach_pit/chromeos.c
+++ b/src/mainboard/google/peach_pit/chromeos.c
@@ -37,3 +37,9 @@
 {
 	return !gpio_get_value(GPIO_X30);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get_value(GPIO_X23);
+}
diff --git a/src/mainboard/google/poppy/chromeos.c b/src/mainboard/google/poppy/chromeos.c
index 5dd1e98..35a9323 100644
--- a/src/mainboard/google/poppy/chromeos.c
+++ b/src/mainboard/google/poppy/chromeos.c
@@ -38,3 +38,9 @@
 	gpios = variant_cros_gpios(&num);
 	chromeos_acpi_gpio_generate(gpios, num);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/rambi/chromeos.c b/src/mainboard/google/rambi/chromeos.c
index f9a1718..edc714e 100644
--- a/src/mainboard/google/rambi/chromeos.c
+++ b/src/mainboard/google/rambi/chromeos.c
@@ -8,6 +8,9 @@
 /* The WP status pin lives on GPIO_SSUS_6 which is pad 36 in the SUS well. */
 #define WP_STATUS_PAD	36
 
+/* The EC_IN_RW lives on SCGPIO59 */
+#define EC_IN_RW_PAD	59
+
 void fill_lb_gpios(struct lb_gpios *gpios)
 {
 	struct lb_gpio chromeos_gpios[] = {
@@ -43,3 +46,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !score_get_gpio(EC_IN_RW_PAD);
+}
diff --git a/src/mainboard/google/reef/chromeos.c b/src/mainboard/google/reef/chromeos.c
index 94d76b9..f87d935 100644
--- a/src/mainboard/google/reef/chromeos.c
+++ b/src/mainboard/google/reef/chromeos.c
@@ -33,3 +33,9 @@
 	gpios = variant_cros_gpios(&num);
 	chromeos_acpi_gpio_generate(gpios, num);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/sarien/chromeos.c b/src/mainboard/google/sarien/chromeos.c
index f49b639..36825b5 100644
--- a/src/mainboard/google/sarien/chromeos.c
+++ b/src/mainboard/google/sarien/chromeos.c
@@ -107,3 +107,10 @@
 	if (ENV_RAMSTAGE)
 		pmc_soc_set_afterg3_en(true);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/slippy/chromeos.c b/src/mainboard/google/slippy/chromeos.c
index 4fffd45..11d41cd 100644
--- a/src/mainboard/google/slippy/chromeos.c
+++ b/src/mainboard/google/slippy/chromeos.c
@@ -30,3 +30,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !get_gpio(14);
+}
diff --git a/src/mainboard/google/smaug/chromeos.c b/src/mainboard/google/smaug/chromeos.c
index 13a69bc..d74df82 100644
--- a/src/mainboard/google/smaug/chromeos.c
+++ b/src/mainboard/google/smaug/chromeos.c
@@ -19,3 +19,9 @@
 {
 	return !gpio_get(WRITE_PROTECT_L);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(EC_IN_RW);
+}
diff --git a/src/mainboard/google/storm/chromeos.c b/src/mainboard/google/storm/chromeos.c
index 21cf94f..51a0c5c 100644
--- a/src/mainboard/google/storm/chromeos.c
+++ b/src/mainboard/google/storm/chromeos.c
@@ -128,3 +128,10 @@
 {
 	return !read_gpio(WP_SW);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/trogdor/chromeos.c b/src/mainboard/google/trogdor/chromeos.c
index 9006000..718df33 100644
--- a/src/mainboard/google/trogdor/chromeos.c
+++ b/src/mainboard/google/trogdor/chromeos.c
@@ -55,3 +55,9 @@
 {
 	return gpio_irq_status(GPIO_H1_AP_INT);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. This is active low. */
+	return !!gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/veyron/chromeos.c b/src/mainboard/google/veyron/chromeos.c
index b99df04..411b14e 100644
--- a/src/mainboard/google/veyron/chromeos.c
+++ b/src/mainboard/google/veyron/chromeos.c
@@ -56,3 +56,9 @@
 {
 	return !gpio_get(GPIO_WP);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_ECINRW);
+}
diff --git a/src/mainboard/google/veyron_mickey/chromeos.c b/src/mainboard/google/veyron_mickey/chromeos.c
index a3ba752..f3587a3 100644
--- a/src/mainboard/google/veyron_mickey/chromeos.c
+++ b/src/mainboard/google/veyron_mickey/chromeos.c
@@ -34,3 +34,10 @@
 {
 	return !gpio_get(GPIO_WP);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/veyron_rialto/chromeos.c b/src/mainboard/google/veyron_rialto/chromeos.c
index 95158bf..33f0ee4 100644
--- a/src/mainboard/google/veyron_rialto/chromeos.c
+++ b/src/mainboard/google/veyron_rialto/chromeos.c
@@ -43,3 +43,10 @@
 {
 	return !gpio_get(GPIO_WP);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* Do not have a Chrome EC involved in entering recovery mode;
+	   Always return trusted. */
+	return 1;
+}
diff --git a/src/mainboard/google/volteer/chromeos.c b/src/mainboard/google/volteer/chromeos.c
index abd50c5..cdf418d 100644
--- a/src/mainboard/google/volteer/chromeos.c
+++ b/src/mainboard/google/volteer/chromeos.c
@@ -32,3 +32,9 @@
 	gpios = variant_cros_gpios(&num);
 	chromeos_acpi_gpio_generate(gpios, num);
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/mainboard/google/zork/chromeos.c b/src/mainboard/google/zork/chromeos.c
index b581b90..3c60f98 100644
--- a/src/mainboard/google/zork/chromeos.c
+++ b/src/mainboard/google/zork/chromeos.c
@@ -31,3 +31,9 @@
 {
 	chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
 }
+
+int get_ec_is_trusted(void)
+{
+	/* EC is trusted if not in RW. */
+	return !gpio_get(GPIO_EC_IN_RW);
+}
diff --git a/src/security/vboot/bootmode.c b/src/security/vboot/bootmode.c
index 6c05109..3c50e4e 100644
--- a/src/security/vboot/bootmode.c
+++ b/src/security/vboot/bootmode.c
@@ -57,6 +57,16 @@
 	return 0;
 }
 
+int __weak get_ec_is_trusted(void)
+{
+	/*
+	 * If board doesn't override this, by default we always assume EC is in
+	 * RW and untrusted. However, newer platforms are supposed to use cr50
+	 * BOOT_MODE to report this and won't need to override this anymore.
+	 */
+	return 0;
+}
+
 #if CONFIG(VBOOT_NO_BOARD_SUPPORT)
 /**
  * TODO: Create flash protection interface which implements get_write_protect_state.
diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c
index 10993d3..ff93d0b 100644
--- a/src/security/vboot/vboot_logic.c
+++ b/src/security/vboot/vboot_logic.c
@@ -327,6 +327,9 @@
 	if (CONFIG(TPM_CR50))
 		check_boot_mode(ctx);
 
+	if (get_ec_is_trusted())
+		ctx->flags |= VB2_CONTEXT_EC_TRUSTED;
+
 	/* Do early init (set up secdata and NVRAM, load GBB) */
 	printk(BIOS_INFO, "Phase 1\n");
 	rv = vb2api_fw_phase1(ctx);
diff --git a/src/soc/intel/alderlake/Makefile.inc b/src/soc/intel/alderlake/Makefile.inc
index c7e0abc..1c578f21 100644
--- a/src/soc/intel/alderlake/Makefile.inc
+++ b/src/soc/intel/alderlake/Makefile.inc
@@ -46,6 +46,8 @@
 ramstage-y += xhci.c
 ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c
 
+verstage-y += gpio.c
+
 smm-y += elog.c
 smm-y += gpio.c
 smm-y += p2sb.c
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 49707da..3b17607 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -92,11 +92,13 @@
 romstage-y += gpio_glk.c
 smm-y += gpio_glk.c
 ramstage-y += gpio_glk.c
+verstage-y += gpio_glk.c
 else
 bootblock-y += gpio_apl.c
 romstage-y += gpio_apl.c
 smm-y += gpio_apl.c
 ramstage-y += gpio_apl.c
+verstage-y += gpio_apl.c
 endif
 
 CPPFLAGS_common += -I$(src)/soc/intel/apollolake/include
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index c191aac..51700b3 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -20,6 +20,7 @@
 bootblock-y += lpc.c
 bootblock-y += uart.c
 
+verstage-y += gpio.c
 verstage-y += gspi.c
 verstage-y += pmutil.c
 verstage-y += i2c.c