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:78577893
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>
Reviewed-on: https://chromium-review.googlesource.com/1033630
Commit-Queue: Furquan Shaikh <furquan@chromium.org>
Tested-by: Furquan Shaikh <furquan@chromium.org>
Trybot-Ready: Furquan Shaikh <furquan@chromium.org>
diff --git a/firmware/2lib/2nvstorage.c b/firmware/2lib/2nvstorage.c
index 71a0dbb..b0810c3 100644
--- a/firmware/2lib/2nvstorage.c
+++ b/firmware/2lib/2nvstorage.c
@@ -152,6 +152,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);
 
@@ -326,6 +329,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 1a65469..55b1612 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 0ed3325..9f9f0e4 100644
--- a/firmware/2lib/include/2nvstorage_fields.h
+++ b/firmware/2lib/include/2nvstorage_fields.h
@@ -61,13 +61,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 3411de7..aec76e6 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 4503ffa..7a0f0cf 100644
--- a/firmware/include/gbb_header.h
+++ b/firmware/include/gbb_header.h
@@ -76,6 +76,8 @@
 #define GBB_FLAG_ENABLE_SERIAL				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 5a75861..8cdfe8d 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -502,6 +502,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")) {
@@ -702,6 +704,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 911d585..a6ee1f0 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 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"},