nand: Disable SPI GPT in recovery mode

Recovery mode must not read data in read-write until it gets onto the
verified USB stick, as that could lead to a bricked device case. This
includes the GPT held on SPI NOR flash. This patch disables the GPT
on SPI, which would otherwise happen when reading the partition table
into the device tree.

BUG=chromium:448620
TEST=Hacked src/vboot/stages.c to simulate a recovery mode and found
that the GPT on SPI is not read when booting from either USB or internal
storage with the recovery mode simulation, but normal GPT reading is
still working without that.
BRANCH=none

Change-Id: I829b01ceebc10a53941dd12bc8c353e60a0d3dbb
Signed-off-by: Dan Ehrenberg <dehrenberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/243460
diff --git a/src/drivers/storage/spi_gpt.c b/src/drivers/storage/spi_gpt.c
index 896adce..78d0ca0 100644
--- a/src/drivers/storage/spi_gpt.c
+++ b/src/drivers/storage/spi_gpt.c
@@ -33,6 +33,7 @@
 #include "base/device_tree.h"
 #include "drivers/flash/flash.h"
 #include "drivers/storage/spi_gpt.h"
+#include "vboot/stages.h"
 
 /* Block size is arbitrarily chosen; any size would work once buffering
  * is implemented. Partitions have to be aligned to the size of an
@@ -123,6 +124,12 @@
 	ctrlr->block_ctrlr.ops.update(&ctrlr->block_ctrlr.ops);
 	SpiGptDev *dev = ctrlr->dev;
 
+	/* If in recovery mode, don't add the GPT from SPI to the dt
+	 * because this would violate the requirement that recovery
+	 * doesn't read internal storage from RW. */
+	if (vboot_in_recovery())
+		return 0;
+
 	uint32_t addrc, sizec;
 	DeviceTreeNode *nand = dt_find_node_by_path(tree->root,
 						    ctrlr->dt_path,
diff --git a/src/vboot/stages.c b/src/vboot/stages.c
index f5428a6..b37beff 100644
--- a/src/vboot/stages.c
+++ b/src/vboot/stages.c
@@ -44,6 +44,8 @@
 #include "vboot/util/flag.h"
 #include "vboot/util/memory.h"
 
+static uint32_t vboot_out_flags;
+
 int vboot_init(void)
 {
 	VbInitParams iparams = {
@@ -98,6 +100,11 @@
 	return vboot_do_init_out_flags(iparams.out_flags);
 };
 
+int vboot_in_recovery(void)
+{
+	return vboot_out_flags & VB_INIT_OUT_ENABLE_RECOVERY;
+}
+
 int vboot_do_init_out_flags(uint32_t out_flags)
 {
 	if (out_flags & VB_INIT_OUT_CLEAR_RAM) {
@@ -113,6 +120,8 @@
 			 VB_INIT_OUT_ENABLE_RECOVERY))
 		input_enable();
 
+	vboot_out_flags = out_flags;
+
 	return 0;
 }
 
diff --git a/src/vboot/stages.h b/src/vboot/stages.h
index 04574ea..19fa198 100644
--- a/src/vboot/stages.h
+++ b/src/vboot/stages.h
@@ -29,5 +29,6 @@
 int vboot_select_firmware(void);
 int vboot_select_and_load_kernel(void);
 int vboot_do_init_out_flags(uint32_t out_flags);
+int vboot_in_recovery(void);
 
 #endif /* __VBOOT_STAGES_H__ */