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/scripts/Kbuild.include b/scripts/Kbuild.include
index 09506cb..9c14310 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -322,11 +322,15 @@
 
 ifdef CONFIG_SPL_BUILD
 SPL_ := SPL_
+ifeq ($(CONFIG_VPL_BUILD),y)
+SPL_TPL_ := VPL_
+else
 ifeq ($(CONFIG_TPL_BUILD),y)
 SPL_TPL_ := TPL_
 else
 SPL_TPL_ := SPL_
 endif
+endif
 else
 SPL_ :=
 SPL_TPL_ :=
diff --git a/scripts/Makefile.autoconf b/scripts/Makefile.autoconf
index 0b3ffa0..3fa4d50 100644
--- a/scripts/Makefile.autoconf
+++ b/scripts/Makefile.autoconf
@@ -18,6 +18,10 @@
 __all: tpl/include/autoconf.mk
 endif
 
+ifeq ($(shell grep -q '^CONFIG_VPL=y' include/config/auto.conf 2>/dev/null && echo y),y)
+__all: vpl/include/autoconf.mk
+endif
+
 include include/config/auto.conf
 
 include scripts/Kbuild.include
@@ -85,6 +89,10 @@
 	$(Q)mkdir -p $(dir $@)
 	$(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD -DCONFIG_TPL_BUILD)
 
+vpl/u-boot.cfg: include/config.h FORCE
+	$(Q)mkdir -p $(dir $@)
+	$(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD -DCONFIG_VPL_BUILD)
+
 include/autoconf.mk: u-boot.cfg
 	$(call cmd,autoconf)
 
@@ -96,6 +104,10 @@
 	$(Q)mkdir -p $(dir $@)
 	$(call cmd,autoconf)
 
+vpl/include/autoconf.mk: vpl/u-boot.cfg
+	$(Q)mkdir -p $(dir $@)
+	$(call cmd,autoconf)
+
 # include/config.h
 # Prior to Kconfig, it was generated by mkconfig. Now it is created here.
 define filechk_config_h
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 5df8f61..3b8c9d8 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -4,6 +4,9 @@
 # ==========================================================================
 
 # Modified for U-Boot
+prefix := vpl
+src := $(patsubst $(prefix)/%,%,$(obj))
+ifeq ($(obj),$(src))
 prefix := tpl
 src := $(patsubst $(prefix)/%,%,$(obj))
 ifeq ($(obj),$(src))
@@ -13,6 +16,7 @@
 prefix := .
 endif
 endif
+endif
 
 PHONY := __build
 __build:
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 2ff39d3..3db2550 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -581,16 +581,21 @@
 # 'u-boot,dm-pre-reloc' property and thus are not needed by SPL. The second
 # pass removes various unused properties from the remaining nodes.
 # The output is typically a much smaller device tree file.
+ifeq ($(CONFIG_VPL_BUILD),y)
+fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-vpl
+else
 ifeq ($(CONFIG_TPL_BUILD),y)
 fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-tpl
 else
 fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-spl
 endif
+endif
 quiet_cmd_fdtgrep = FDTGREP $@
       cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \
 		-n /chosen -n /config -O dtb | \
 	$(objtree)/tools/fdtgrep -r -O dtb - -o $@ \
 		-P u-boot,dm-pre-reloc -P u-boot,dm-spl -P u-boot,dm-tpl \
+		 -P u-boot,dm-vpl \
 		$(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS)))
 
 # fdt_rm_props
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 30672a6..f047d4e 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -27,8 +27,16 @@
 KBUILD_CPPFLAGS += -DCONFIG_SPL_BUILD
 ifeq ($(CONFIG_TPL_BUILD),y)
 KBUILD_CPPFLAGS += -DCONFIG_TPL_BUILD
+else
+ifeq ($(CONFIG_VPL_BUILD),y)
+KBUILD_CPPFLAGS += -DCONFIG_VPL_BUILD
+endif
 endif
 
+ifeq ($(CONFIG_VPL_BUILD),y)
+SPL_BIN := u-boot-vpl
+SPL_NAME := vpl
+else
 ifeq ($(CONFIG_TPL_BUILD),y)
 SPL_BIN := u-boot-tpl
 SPL_NAME := tpl
@@ -36,16 +44,21 @@
 SPL_BIN := u-boot-spl
 SPL_NAME := spl
 endif
+endif
 
 export SPL_NAME
 
 ifdef CONFIG_SPL_BUILD
 SPL_ := SPL_
+ifeq ($(CONFIG_VPL_BUILD),y)
+SPL_TPL_ := VPL_
+else
 ifeq ($(CONFIG_TPL_BUILD),y)
 SPL_TPL_ := TPL_
 else
 SPL_TPL_ := SPL_
 endif
+endif
 else
 SPL_ :=
 SPL_TPL_ :=
@@ -57,6 +70,9 @@
 ifeq ($(obj)$(CONFIG_SUPPORT_TPL),tpl)
 $(error You cannot build TPL without enabling CONFIG_SUPPORT_TPL)
 endif
+ifeq ($(obj)$(CONFIG_SUPPORT_VPL),vpl)
+$(error You cannot build VPL without enabling CONFIG_SUPPORT_VPL)
+endif
 
 include $(srctree)/config.mk
 include $(srctree)/arch/$(ARCH)/Makefile
@@ -90,17 +106,12 @@
 endif
 libs-y += common/init/
 
-# Special handling for a few options which support SPL/TPL
-ifeq ($(CONFIG_TPL_BUILD),y)
-libs-$(CONFIG_TPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
-libs-$(CONFIG_TPL_LIBGENERIC_SUPPORT) += lib/
-else
-libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
-libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
+# Special handling for a few options which support SPL/TPL/VPL
+libs-$(CONFIG_$(SPL_TPL_)LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
+libs-$(CONFIG_$(SPL_TPL_)LIBGENERIC_SUPPORT) += lib/
 ifdef CONFIG_SPL_FRAMEWORK
 libs-$(CONFIG_PARTITIONS) += disk/
 endif
-endif
 
 libs-y += drivers/
 libs-$(CONFIG_SPL_USB_GADGET) += drivers/usb/dwc3/
@@ -182,7 +193,7 @@
 	  sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
 
 # Turn various CONFIG symbols into IMAGE symbols for easy reuse of
-# the scripts between SPL and TPL.
+# the scripts between SPL, TPL and VPL.
 ifneq ($(CONFIG_$(SPL_TPL_)MAX_SIZE),)
 LDPPFLAGS += -DIMAGE_MAX_SIZE=$(CONFIG_$(SPL_TPL_)MAX_SIZE)
 endif
@@ -264,6 +275,7 @@
 INPUTS-y	+= $(obj)/boot.bin
 endif
 
+ifndef CONFIG_VPL_BUILD
 ifdef CONFIG_TPL_BUILD
 INPUTS-$(CONFIG_TPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-tpl.bin \
 	$(obj)/u-boot-x86-reset16-tpl.bin
@@ -271,6 +283,7 @@
 INPUTS-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-spl.bin \
 	$(obj)/u-boot-x86-reset16-spl.bin
 endif
+endif
 
 INPUTS-$(CONFIG_ARCH_ZYNQ)		+= $(obj)/boot.bin
 INPUTS-$(CONFIG_ARCH_ZYNQMP)	+= $(obj)/boot.bin
@@ -307,7 +320,7 @@
 
 ifneq ($(build_dtb),)
 $(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin \
-		$(if $(CONFIG_SPL_SEPARATE_BSS),,$(obj)/$(SPL_BIN)-pad.bin) \
+		$(if $(CONFIG_$(SPL_TPL_)SEPARATE_BSS),,$(obj)/$(SPL_BIN)-pad.bin) \
 		$(FINAL_DTB_CONTAINER)  FORCE
 	$(call if_changed,cat)
 
@@ -398,7 +411,7 @@
 
 LDFLAGS_$(SPL_BIN) += --build-id=none
 
-# Pick the best-match (i.e. SPL_TEXT_BASE for SPL, TPL_TEXT_BASE for TPL)
+# Pick the best match (e.g. SPL_TEXT_BASE for SPL, TPL_TEXT_BASE for TPL)
 ifneq ($(CONFIG_$(SPL_TPL_)TEXT_BASE),)
 LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_$(SPL_TPL_)TEXT_BASE)
 endif