Introduce Verifying Program Loader (VPL)

Add support for VPL, a new phase of U-Boot. This runs after TPL. It is
responsible for selecting which SPL binary to run, based on a
verified-boot process.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index ac61b25..be09866 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1,4 +1,4 @@
-menu "SPL / TPL"
+menu "SPL / TPL / VPL"
 
 config SUPPORT_SPL
 	bool
@@ -6,6 +6,9 @@
 config SUPPORT_TPL
 	bool
 
+config SUPPORT_VPL
+	bool
+
 config SPL_DFU_NO_RESET
 	bool
 
@@ -302,6 +305,16 @@
 	  writeable memory) of anything it wants to modify, such as
 	  device-private data.
 
+config TPL_SEPARATE_BSS
+	bool "BSS section is in a different memory region from text"
+	default y if SPL_SEPARATE_BSS
+	help
+	  Some platforms need a large BSS region in TPL and can provide this
+	  because RAM is already set up. In this case BSS can be moved to RAM.
+	  This option should then be enabled so that the correct device tree
+	  location is used. Normally we put the device tree at the end of BSS
+	  but with this option enabled, it goes at _image_binary_end.
+
 config SPL_BANNER_PRINT
 	bool "Enable output of the SPL banner 'U-Boot SPL ...'"
 	default y
diff --git a/common/spl/spl.c b/common/spl/spl.c
index c9750ee..c8c463f 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -61,6 +61,11 @@
 binman_sym_declare(ulong, u_boot_spl, size);
 #endif
 
+#ifdef CONFIG_VPL
+binman_sym_declare(ulong, u_boot_vpl, image_pos);
+binman_sym_declare(ulong, u_boot_vpl, size);
+#endif
+
 /* Define board data structure */
 static struct bd_info bdata __attribute__ ((section(".data")));
 
@@ -146,14 +151,22 @@
 #if CONFIG_IS_ENABLED(BINMAN_SYMBOLS)
 ulong spl_get_image_pos(void)
 {
-	return spl_phase() == PHASE_TPL ?
+#ifdef CONFIG_VPL
+	if (spl_next_phase() == PHASE_VPL)
+		return binman_sym(ulong, u_boot_vpl, image_pos);
+#endif
+	return spl_next_phase() == PHASE_SPL ?
 		binman_sym(ulong, u_boot_spl, image_pos) :
 		binman_sym(ulong, u_boot_any, image_pos);
 }
 
 ulong spl_get_image_size(void)
 {
-	return spl_phase() == PHASE_TPL ?
+#ifdef CONFIG_VPL
+	if (spl_next_phase() == PHASE_VPL)
+		return binman_sym(ulong, u_boot_vpl, size);
+#endif
+	return spl_next_phase() == PHASE_SPL ?
 		binman_sym(ulong, u_boot_spl, size) :
 		binman_sym(ulong, u_boot_any, size);
 }
@@ -161,7 +174,11 @@
 
 ulong spl_get_image_text_base(void)
 {
-	return spl_phase() == PHASE_TPL ? CONFIG_SPL_TEXT_BASE :
+#ifdef CONFIG_VPL
+	if (spl_next_phase() == PHASE_VPL)
+		return CONFIG_VPL_TEXT_BASE;
+#endif
+	return spl_next_phase() == PHASE_SPL ? CONFIG_SPL_TEXT_BASE :
 		CONFIG_SYS_TEXT_BASE;
 }
 
@@ -466,6 +483,8 @@
 
 	if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
 		return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL;
+	else if (IS_ENABLED(CONFIG_VPL_BUILD) && phase == PHASE_VPL)
+		return start ? BOOTSTAGE_ID_START_VPL : BOOTSTAGE_ID_END_VPL;
 	else
 		return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
 }