Add new NV and GBB flag to control UDC

This change adds a new NV and GBB flag for controlling USB device
mode behavior, adding an additional step to enable UDC on systems
that support it.

Users of this feature will need to first enable developer mode and
then enable UDC separately by running "crossystem dev_enable_udc=1".

Alternatively those without write protect enabled can set a GBB
flag to have UDC enabled by default while in developer mode.

This is based on the security reviewed proposal at
https://docs.google.com/document/d/1b6avd9xvhvljN_NKtctWrClj4mSYZ_uPmp7MmAnPwqs

BUG=b:74339386
BRANCH=poppy
TEST=manual testing on Eve device

Change-Id: I6f440320f28b033639b53246d3034bc8acc37a33
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1010769
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
(cherry picked from commit 534194ead77895dd131ed59b968b21a2ae36f133)
Reviewed-on: https://chromium-review.googlesource.com/1017400
diff --git a/firmware/2lib/2nvstorage.c b/firmware/2lib/2nvstorage.c
index 1e24d2d..9090608 100644
--- a/firmware/2lib/2nvstorage.c
+++ b/firmware/2lib/2nvstorage.c
@@ -167,6 +167,9 @@
 		return (p[VB2_NV_OFFS_DEV] & VB2_NV_DEV_FLAG_DEFAULT_BOOT)
 			>> VB2_NV_DEV_DEFAULT_BOOT_SHIFT;
 
+	case VB2_NV_DEV_ENABLE_UDC:
+		return GETBIT(VB2_NV_OFFS_DEV, VB2_NV_DEV_FLAG_UDC);
+
 	case VB2_NV_DISABLE_DEV_REQUEST:
 		return GETBIT(VB2_NV_OFFS_BOOT, VB2_NV_BOOT_DISABLE_DEV);
 
@@ -351,6 +354,10 @@
 			(uint8_t)(value << VB2_NV_DEV_DEFAULT_BOOT_SHIFT);
 		break;
 
+	case VB2_NV_DEV_ENABLE_UDC:
+		SETBIT(VB2_NV_OFFS_DEV, VB2_NV_DEV_FLAG_UDC);
+		break;
+
 	case VB2_NV_DISABLE_DEV_REQUEST:
 		SETBIT(VB2_NV_OFFS_BOOT, VB2_NV_BOOT_DISABLE_DEV);
 		break;
diff --git a/firmware/2lib/include/2nvstorage.h b/firmware/2lib/include/2nvstorage.h
index 654bcab..f4f3e04 100644
--- a/firmware/2lib/include/2nvstorage.h
+++ b/firmware/2lib/include/2nvstorage.h
@@ -59,6 +59,8 @@
 	VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP,
 	/* Set default boot mode (see vb2_dev_default_boot) */
 	VB2_NV_DEV_DEFAULT_BOOT,
+	/* Enable USB Device Controller */
+	VB2_NV_DEV_ENABLE_UDC,
 	/*
 	 * Set by userspace to request that RO firmware disable dev-mode on the
 	 * next boot. This is likely only possible if the dev-switch is
diff --git a/firmware/2lib/include/2nvstorage_fields.h b/firmware/2lib/include/2nvstorage_fields.h
index d67ad5d..16626b8 100644
--- a/firmware/2lib/include/2nvstorage_fields.h
+++ b/firmware/2lib/include/2nvstorage_fields.h
@@ -87,13 +87,14 @@
 #define VB2_NV_BOOT2_PREV_RESULT_SHIFT 4  /* Number of bits to shift result */
 #define VB2_NV_BOOT2_PREV_TRIED                0x40
 
-/* Fields in VB2_NV_OFFS_DEV (unused = 0xc0) */
+/* Fields in VB2_NV_OFFS_DEV (unused = 0x80) */
 #define VB2_NV_DEV_FLAG_USB                    0x01
 #define VB2_NV_DEV_FLAG_SIGNED_ONLY            0x02
 #define VB2_NV_DEV_FLAG_LEGACY                 0x04
 #define VB2_NV_DEV_FLAG_FASTBOOT_FULL_CAP      0x08
 #define VB2_NV_DEV_FLAG_DEFAULT_BOOT           0x30
 #define VB2_NV_DEV_DEFAULT_BOOT_SHIFT 4  /* Number of bits to shift */
+#define VB2_NV_DEV_FLAG_UDC                    0x40
 
 /* Fields in VB2_NV_OFFS_TPM (unused = 0xf8) */
 #define VB2_NV_TPM_CLEAR_OWNER_REQUEST         0x01
diff --git a/firmware/2lib/include/2struct.h b/firmware/2lib/include/2struct.h
index d118559..1d5b353 100644
--- a/firmware/2lib/include/2struct.h
+++ b/firmware/2lib/include/2struct.h
@@ -301,6 +301,9 @@
 
 	/* Disable FWMP */
 	VB2_GBB_FLAG_DISABLE_FWMP = (1 << 15),
+
+	/* Enable USB Device Controller */
+	VB2_GBB_FLAG_ENABLE_UDC = (1 << 16),
 };
 
 struct vb2_gbb_header {
diff --git a/firmware/include/gbb_header.h b/firmware/include/gbb_header.h
index 11586e9..b880468 100644
--- a/firmware/include/gbb_header.h
+++ b/firmware/include/gbb_header.h
@@ -76,6 +76,8 @@
 #define GBB_FLAG_FORCE_MANUAL_RECOVERY			0x00004000
 /* Disable using FWMP */
 #define GBB_FLAG_DISABLE_FWMP                           0x00008000
+/* Enable USB Device Controller */
+#define GBB_FLAG_ENABLE_UDC                             0x00010000
 
 
 #ifdef __cplusplus
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index f379d22..e8c48d8 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -508,6 +508,8 @@
 		value = vb2_get_nv_storage(VB2_NV_DEV_BOOT_SIGNED_ONLY);
 	} else if (!strcasecmp(name,"dev_boot_fastboot_full_cap")) {
 		value = vb2_get_nv_storage(VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP);
+	} else if (!strcasecmp(name,"dev_enable_udc")) {
+		value = vb2_get_nv_storage(VB2_NV_DEV_ENABLE_UDC);
 	} else if (!strcasecmp(name,"oprom_needed")) {
 		value = vb2_get_nv_storage(VB2_NV_OPROM_NEEDED);
 	} else if (!strcasecmp(name,"recovery_subcode")) {
@@ -708,6 +710,9 @@
 	} else if (!strcasecmp(name, "fastboot_unlock_in_fw")) {
 		return vb2_set_nv_storage_with_backup(
 		    VB2_NV_FASTBOOT_UNLOCK_IN_FW, value);
+	} else if (!strcasecmp(name, "dev_enable_udc")) {
+		return vb2_set_nv_storage_with_backup(
+		    VB2_NV_DEV_ENABLE_UDC, value);
 	} else if (!strcasecmp(name, "boot_on_ac_detect")) {
 		return vb2_set_nv_storage_with_backup(
 		    VB2_NV_BOOT_ON_AC_DETECT, value);
diff --git a/utility/crossystem.c b/utility/crossystem.c
index 825b58b..82ee9d7 100644
--- a/utility/crossystem.c
+++ b/utility/crossystem.c
@@ -50,6 +50,7 @@
    "Enable developer mode boot only from official kernels (writable)"},
   {"dev_default_boot", IS_STRING|CAN_WRITE,
    "default boot from disk, legacy or usb (writable)"},
+  {"dev_enable_udc", CAN_WRITE, "Enable USB Device Controller"},
   {"devsw_boot", 0, "Developer switch position at boot"},
   {"devsw_cur",  0, "Developer switch current position"},
   {"disable_dev_request", CAN_WRITE, "Disable virtual dev-mode on next boot"},