[PATCH v8 00/13] vpl: Introduce a verifying program loader

U-Boot provides a verified-boot feature based around FIT, but there is no standard way of implementing it for a board. At present the various required pieces must be built up separately, to produce a working implementation. In particular, there is no built-in support for selecting A/B boot or recovery mode.
This series introduces VPL, a verified program loader phase for U-Boot. Its purpose is to run the verified-boot process and decide which SPL binary should be run. It is critical that this decision happens before SPL runs, since SPL sets up SDRAM and we need to be able to update the SDRAM-init code in the field.
Adding VPL into the boot flow provides a standard place to implement verified boot. This series includes the phase itself, some useful Kconfig options and a sandbox_vpl build for sandbox. No verfied-boot support is provided in this series.
Most of the patches in this series are fixes and improvements to docs and various Kconfig conditions for SPL.
This series requires the earlier sandbox fix patches[1] to be applied first. A test is included to make sure that VPL runs correctly for sandbox, i.e. that the TPL -> VPL -> SPL -> U-Boot flow works.
Future work will add an implementation of verified boot into VPL.
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=297248
Changes in v8: - Rename the VPL symbols in spl.c - Support SYSCON and REGMAP too - Update defconfig to account for option changes - Drop reference to old OF_HOSTFILE option - Add new patch to support running vpl tests
Changes in v7: - Add a few more options - Rebase to master - Update some options based on settings in master
Changes in v6: - Add docs for sandbox_vpl build - Drop TPL_HASH_SUPPORT patch since we only have SPL_HASH now
Changes in v5: - Rebase this patch on mainline (for GPIO and MISC Kconfig renames)
Changes in v4: - Add new patch to correct bloblist Kconfig dependencies - Add new patch to avoid building avb in SPL - Update spl_phase_prefix() for VPL - Tidy up some of the Makefile rules - Add options for blk, core, misc and tpl also - Add VPL_SIZE_LIMIT - Add a sandbox_vpl build - Update cover letter
Changes in v3: - Move VPL Kconfig options to a separate patch - Add full build support for VPL - Add a VPL size check (Kconfig option in next patch)
Changes in v2: - Add some more VPL Kconfig options
Simon Glass (13): doc: Convert SPL documentation to ReST doc: Expand SPL docs to explain the phase and config test: Tidy up test building with SPL bloblist: Correct Kconfig dependencies avb: Don't build in SPL Makefile: Simplify devicetree rules for SPL/TPL Makefile: Tidy up the TPL build rules Introduce Verifying Program Loader (VPL) vpl: Add Kconfig options for VPL sandbox: Add a build for VPL vpl: Support running vpl tests vpl: Test that VPL runs correctly through to U-Boot proper CI: Run VPL tests
.azure-pipelines.yml | 3 + .gitlab-ci.yml | 6 + Kconfig | 10 ++ Makefile | 28 +++- arch/sandbox/Kconfig | 8 + arch/sandbox/cpu/spl.c | 12 +- arch/sandbox/dts/sandbox.dtsi | 10 +- board/sandbox/MAINTAINERS | 7 + common/Kconfig | 71 +++++++- common/Makefile | 2 +- common/spl/Kconfig | 234 +++++++++++++++++++++++++- common/spl/spl.c | 25 ++- configs/sandbox_vpl_defconfig | 251 ++++++++++++++++++++++++++++ doc/arch/sandbox.rst | 13 ++ doc/develop/index.rst | 1 + doc/{README.SPL => develop/spl.rst} | 75 +++++++-- drivers/Makefile | 2 + drivers/block/Kconfig | 12 ++ drivers/clk/Kconfig | 26 +++ drivers/core/Kconfig | 54 +++++- drivers/core/Makefile | 2 +- drivers/gpio/Kconfig | 11 ++ drivers/i2c/Kconfig | 11 ++ drivers/misc/Kconfig | 28 ++++ drivers/pinctrl/Kconfig | 18 +- drivers/rtc/Kconfig | 9 + drivers/serial/Kconfig | 20 +++ drivers/sysreset/Kconfig | 10 ++ drivers/timer/Kconfig | 10 ++ drivers/tpm/Kconfig | 30 ++++ dts/Kconfig | 17 ++ include/bootstage.h | 2 + include/linux/kconfig.h | 3 + include/spl.h | 22 ++- lib/Kconfig | 62 +++++++ scripts/Kbuild.include | 4 + scripts/Makefile.autoconf | 12 ++ scripts/Makefile.build | 4 + scripts/Makefile.lib | 5 + scripts/Makefile.spl | 37 ++-- test/py/conftest.py | 7 +- test/py/tests/test_help.py | 12 ++ test/py/tests/test_vpl.py | 34 ++++ test/py/u_boot_console_sandbox.py | 7 +- 44 files changed, 1167 insertions(+), 60 deletions(-) create mode 100644 configs/sandbox_vpl_defconfig rename doc/{README.SPL => develop/spl.rst} (68%) create mode 100644 test/py/tests/test_vpl.py

Move this documentation over to .rst format.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/develop/index.rst | 1 + doc/{README.SPL => develop/spl.rst} | 36 +++++++++++++++-------------- 2 files changed, 20 insertions(+), 17 deletions(-) rename doc/{README.SPL => develop/spl.rst} (86%)
diff --git a/doc/develop/index.rst b/doc/develop/index.rst index d32ec490221..fe3564a9fbf 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -25,6 +25,7 @@ Implementation menus printf smbios + spl uefi/index version
diff --git a/doc/README.SPL b/doc/develop/spl.rst similarity index 86% rename from doc/README.SPL rename to doc/develop/spl.rst index 011fd42537a..4d6f394bed9 100644 --- a/doc/README.SPL +++ b/doc/develop/spl.rst @@ -20,19 +20,19 @@ u-boot-spl.map. A config option named CONFIG_SPL_BUILD is enabled by Kconfig for SPL. Source files can therefore be compiled for SPL with different settings.
-For example: +For example::
-ifeq ($(CONFIG_SPL_BUILD),y) -obj-y += board_spl.o -else -obj-y += board.o -endif + ifeq ($(CONFIG_SPL_BUILD),y) + obj-y += board_spl.o + else + obj-y += board.o + endif
-obj-$(CONFIG_SPL_BUILD) += foo.o + obj-$(CONFIG_SPL_BUILD) += foo.o
-#ifdef CONFIG_SPL_BUILD - foo(); -#endif + #ifdef CONFIG_SPL_BUILD + foo(); + #endif
The building of SPL images can be enabled by CONFIG_SPL option in Kconfig. @@ -71,11 +71,13 @@ Device tree The U-Boot device tree is filtered by the fdtgrep tools during the build process to generate a much smaller device tree used in SPL (spl/u-boot-spl.dtb) with: + - the mandatory nodes (/alias, /chosen, /config) - the nodes with one pre-relocation property: 'u-boot,dm-pre-reloc' or 'u-boot,dm-spl'
fdtgrep is also used to remove: + - the properties defined in CONFIG_OF_SPL_REMOVE_PROPS - all the pre-relocation properties ('u-boot,dm-pre-reloc', 'u-boot,dm-spl' and 'u-boot,dm-tpl') @@ -98,14 +100,14 @@ stack usage at various points in run sequence of SPL. The -fstack-usage option to gcc will produce '.su' files (such as arch/arm/cpu/armv7/syslib.su) that will give stack usage information and cflow can construct program flow.
-Must have gcc 4.6 or later, which supports -fstack-usage +Must have gcc 4.6 or later, which supports -fstack-usage:
-1) Build normally -2) Perform the following shell command to generate a list of C files used in -SPL: -$ find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list -3) Execute cflow: -$ cflow --main=board_init_r `cat used-spl.list` 2>&1 | $PAGER +#. Build normally +#. Perform the following shell command to generate a list of C files used in + SPL: +#. `find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list` +#. Execute cflow: + `$ cflow --main=board_init_r $(cat used-spl.list) 2>&1 | $PAGER`
cflow will spit out a number of warnings as it does not parse the config files and picks functions based on #ifdef. Parsing the '.i'

On Sat, Apr 30, 2022 at 12:56:45AM -0600, Simon Glass wrote:
Move this documentation over to .rst format.
Signed-off-by: Simon Glass sjg@chromium.org
For the series, applied to u-boot/master, thanks!

Add a bit more information about how to use SPL.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/develop/spl.rst | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/doc/develop/spl.rst b/doc/develop/spl.rst index 4d6f394bed9..1059b2fb9c0 100644 --- a/doc/develop/spl.rst +++ b/doc/develop/spl.rst @@ -66,6 +66,40 @@ CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o) CONFIG_SPL_RAM_DEVICE (common/spl/spl.c) CONFIG_SPL_WATCHDOG (drivers/watchdog/libwatchdog.o)
+Adding SPL-specific code +------------------------ + +To check whether a feature is enabled, use CONFIG_IS_ENABLED():: + + if (CONFIG_IS_ENABLED(CLK)) + ... + +This checks CONFIG_CLK for the main build, CONFIG_SPL_CLK for the SPL build, +CONFIG_TPL_CLK for the TPL build, etc. + +U-Boot Phases +------------- + +U-Boot boots through the following phases: + +TPL + Very early init, as tiny as possible. This loads SPL. + +SPL + Secondary program loader. Sets up SDRAM and loads U-Boot proper. It may also + load other firmware components. + +U-Boot + U-Boot proper, containing the command line and boot logic. + + +Checking the boot phase +----------------------- + +Use `spl_phase()` to find the current U-Boot phase, e.g. `PHASE_SPL`. You can +also find the previous and next phase and get the phase name. + + Device tree ----------- The U-Boot device tree is filtered by the fdtgrep tools during the build

We can in principle add tests to any SPL build, e.g. TPL or VPL. Update the build rules to handle this.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 2 +- scripts/Makefile.spl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile index ccc87c3a5cd..3f28333e644 100644 --- a/Makefile +++ b/Makefile @@ -846,7 +846,7 @@ libs-y += drivers/usb/ulpi/ ifdef CONFIG_POST libs-y += post/ endif -libs-$(CONFIG_UNIT_TEST) += test/ +libs-$(CONFIG_$(SPL_TPL_)UNIT_TEST) += test/ libs-$(CONFIG_UT_ENV) += test/env/ libs-$(CONFIG_UT_OPTEE) += test/optee/ libs-$(CONFIG_UT_OVERLAY) += test/overlay/ diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 6ad82cecfb7..30672a61179 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -109,7 +109,7 @@ libs-y += dts/ libs-y += fs/ libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/ libs-$(CONFIG_SPL_NET) += net/ -libs-$(CONFIG_SPL_UNIT_TEST) += test/ +libs-$(CONFIG_$(SPL_TPL_)UNIT_TEST) += test/
head-y := $(addprefix $(obj)/,$(head-y)) libs-y := $(addprefix $(obj)/,$(libs-y))

This feature is not available in SPL unless common/ and lib/ are built. Update the Kconfig to avoid build errors.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v4)
Changes in v4: - Add new patch to correct bloblist Kconfig dependencies
common/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig index 8f8a9064d50..f55b4211bb2 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -762,7 +762,7 @@ config BLOBLIST
config SPL_BLOBLIST bool "Support for a bloblist in SPL" - depends on BLOBLIST + depends on BLOBLIST && SPL_LIBGENERIC_SUPPORT && SPL_LIBCOMMON_SUPPORT default y if SPL help This enables a bloblist in SPL. If this is the first part of U-Boot @@ -771,7 +771,7 @@ config SPL_BLOBLIST
config TPL_BLOBLIST bool "Support for a bloblist in TPL" - depends on BLOBLIST + depends on BLOBLIST && TPL_LIBGENERIC_SUPPORT && TPL_LIBCOMMON_SUPPORT default y if TPL help This enables a bloblist in TPL. The bloblist is set up in TPL and

This feature is not used in SPL at present. Update the Makefile to avoid it being built.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v4)
Changes in v4: - Add new patch to avoid building avb in SPL
common/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/Makefile b/common/Makefile index cc2ba30c631..75c24e32492 100644 --- a/common/Makefile +++ b/common/Makefile @@ -112,7 +112,7 @@ obj-y += s_record.o obj-$(CONFIG_CMD_LOADB) += xyzModem.o obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
-obj-$(CONFIG_AVB_VERIFY) += avb_verify.o +obj-$(CONFIG_$(SPL_TPL_)AVB_VERIFY) += avb_verify.o obj-$(CONFIG_$(SPL_TPL_)STACKPROTECTOR) += stackprot.o obj-$(CONFIG_SCP03) += scp03.o

The current logic checks several options to decide whether SPL/TPL need the U-Boot devicetree to be built. In fact we can check OF_CONTROL, which is enabled in all cases that matter.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile index 3f28333e644..9f220de3202 100644 --- a/Makefile +++ b/Makefile @@ -2095,9 +2095,7 @@ spl/u-boot-spl-dtb.bin: spl/u-boot-spl spl/u-boot-spl-dtb.hex: spl/u-boot-spl @:
-spl/u-boot-spl: tools prepare \ - $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb) \ - $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_TPL_OF_PLATDATA),dts/dt.dtb) +spl/u-boot-spl: tools prepare $(if $(CONFIG_SPL_OF_CONTROL),dts/dt.dtb) $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
spl/sunxi-spl.bin: spl/u-boot-spl @@ -2112,8 +2110,7 @@ spl/u-boot-spl.sfp: spl/u-boot-spl spl/boot.bin: spl/u-boot-spl @:
-tpl/u-boot-tpl.bin: tools prepare \ - $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb) +tpl/u-boot-tpl.bin: tools prepare $(if $(CONFIG_TPL_OF_CONTROL),dts/dt.dtb) $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all $(TPL_SIZE_CHECK)

These should follow the same pattern as SPL, for consistency. Fix them.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile index 9f220de3202..82c35a94ae6 100644 --- a/Makefile +++ b/Makefile @@ -2110,10 +2110,13 @@ spl/u-boot-spl.sfp: spl/u-boot-spl spl/boot.bin: spl/u-boot-spl @:
-tpl/u-boot-tpl.bin: tools prepare $(if $(CONFIG_TPL_OF_CONTROL),dts/dt.dtb) - $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all +tpl/u-boot-tpl.bin: tpl/u-boot-tpl + @: $(TPL_SIZE_CHECK)
+tpl/u-boot-tpl: tools prepare $(if $(CONFIG_TPL_OF_CONTROL),dts/dt.dtb) + $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all + TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include)
FIND := find

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 ---
Changes in v8: - Rename the VPL symbols in spl.c
Changes in v4: - Update spl_phase_prefix() for VPL - Tidy up some of the Makefile rules
Changes in v3: - Move VPL Kconfig options to a separate patch - Add full build support for VPL - Add a VPL size check (Kconfig option in next patch)
Changes in v2: - Add some more VPL Kconfig options
Makefile | 14 ++++++++++++++ common/spl/Kconfig | 15 ++++++++++++++- common/spl/spl.c | 25 ++++++++++++++++++++++--- doc/develop/spl.rst | 7 ++++++- drivers/Makefile | 2 ++ include/bootstage.h | 2 ++ include/linux/kconfig.h | 3 +++ include/spl.h | 22 +++++++++++++++++++--- scripts/Kbuild.include | 4 ++++ scripts/Makefile.autoconf | 12 ++++++++++++ scripts/Makefile.build | 4 ++++ scripts/Makefile.lib | 5 +++++ scripts/Makefile.spl | 35 ++++++++++++++++++++++++----------- 13 files changed, 131 insertions(+), 19 deletions(-)
diff --git a/Makefile b/Makefile index 82c35a94ae6..ea80f00716d 100644 --- a/Makefile +++ b/Makefile @@ -911,6 +911,12 @@ else TPL_SIZE_CHECK = endif
+ifneq ($(CONFIG_VPL_SIZE_LIMIT),0x0) +VPL_SIZE_CHECK = @$(call size_check,$@,$(CONFIG_VPL_SIZE_LIMIT)) +else +VPL_SIZE_CHECK = +endif + # Statically apply RELA-style relocations (currently arm64 only) # This is useful for arm64 where static relocation needs to be performed on # the raw binary, but certain simulators only accept an ELF file (but don't @@ -951,6 +957,7 @@ INPUTS-$(CONFIG_SPL_FRAMEWORK) += u-boot.img endif endif INPUTS-$(CONFIG_TPL) += tpl/u-boot-tpl.bin +INPUTS-$(CONFIG_VPL) += vpl/u-boot-vpl.bin
# Allow omitting the .dtb output if it is not normally used INPUTS-$(CONFIG_OF_SEPARATE) += $(if $(CONFIG_OF_OMIT_DTB),dts/dt.dtb,u-boot.dtb) @@ -2117,6 +2124,13 @@ tpl/u-boot-tpl.bin: tpl/u-boot-tpl tpl/u-boot-tpl: tools prepare $(if $(CONFIG_TPL_OF_CONTROL),dts/dt.dtb) $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all
+vpl/u-boot-vpl.bin: vpl/u-boot-vpl + @: + $(VPL_SIZE_CHECK) + +vpl/u-boot-vpl: tools prepare $(if $(CONFIG_TPL_OF_CONTROL),dts/dt.dtb) + $(Q)$(MAKE) obj=vpl -f $(srctree)/scripts/Makefile.spl all + TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include)
FIND := find diff --git a/common/spl/Kconfig b/common/spl/Kconfig index ac61b25a066..be098668f0e 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_SPL config SUPPORT_TPL bool
+config SUPPORT_VPL + bool + config SPL_DFU_NO_RESET bool
@@ -302,6 +305,16 @@ config SPL_READ_ONLY 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 c9750ee1637..c8c463f80bd 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -61,6 +61,11 @@ binman_sym_declare(ulong, u_boot_spl, image_pos); 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 @@ void spl_fixup_fdt(void *fdt_blob) #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_size(void)
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 @@ static enum bootstage_id get_bootstage_id(bool start)
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; } diff --git a/doc/develop/spl.rst b/doc/develop/spl.rst index 1059b2fb9c0..aec7b562faa 100644 --- a/doc/develop/spl.rst +++ b/doc/develop/spl.rst @@ -83,7 +83,12 @@ U-Boot Phases U-Boot boots through the following phases:
TPL - Very early init, as tiny as possible. This loads SPL. + Very early init, as tiny as possible. This loads SPL (or VPL if enabled). + +VPL + Optional verification step, which can select one of several SPL binaries, + if A/B verified boot is enabled. Implementation of the VPL logic is + work-in-progress. For now it just boots into SPL.
SPL Secondary program loader. Sets up SDRAM and loads U-Boot proper. It may also diff --git a/drivers/Makefile b/drivers/Makefile index 4e7cf284405..67c8af74424 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_XEN) += xen/ obj-$(CONFIG_$(SPL_)FPGA) += fpga/
ifndef CONFIG_TPL_BUILD +ifndef CONFIG_VPL_BUILD ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_CPU) += cpu/ @@ -60,6 +61,7 @@ obj-$(CONFIG_SPL_SATA) += ata/ scsi/ obj-$(CONFIG_HAVE_BLOCK_DEVICE) += block/ obj-$(CONFIG_SPL_THERMAL) += thermal/
+endif endif endif
diff --git a/include/bootstage.h b/include/bootstage.h index 99a334ad54b..bca9438418f 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -176,6 +176,8 @@ enum bootstage_id { BOOTSTAGE_ID_END_TPL, BOOTSTAGE_ID_START_SPL, BOOTSTAGE_ID_END_SPL, + BOOTSTAGE_ID_START_VPL, + BOOTSTAGE_ID_END_VPL, BOOTSTAGE_ID_START_UBOOT_F, BOOTSTAGE_ID_START_UBOOT_R, BOOTSTAGE_ID_USB_START, diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index d20da615b96..2bc704e1104 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -38,6 +38,8 @@ #define _CONFIG_PREFIX TOOLS_ #elif defined(CONFIG_TPL_BUILD) #define _CONFIG_PREFIX TPL_ +#elif defined(CONFIG_VPL_BUILD) +#define _CONFIG_PREFIX VPL_ #elif defined(CONFIG_SPL_BUILD) #define _CONFIG_PREFIX SPL_ #else @@ -54,6 +56,7 @@ * CONFIG_FOO if CONFIG_SPL_BUILD is undefined, * CONFIG_SPL_FOO if CONFIG_SPL_BUILD is defined. * CONFIG_TPL_FOO if CONFIG_TPL_BUILD is defined. + * CONFIG_VPL_FOO if CONFIG_VPL_BUILD is defined. */ #define CONFIG_VAL(option) config_val(option)
diff --git a/include/spl.h b/include/spl.h index 6134aba8571..83ac583e0b4 100644 --- a/include/spl.h +++ b/include/spl.h @@ -62,6 +62,7 @@ static inline bool u_boot_first_phase(void) enum u_boot_phase { PHASE_NONE, /* Invalid phase, signifying before U-Boot */ PHASE_TPL, /* Running in TPL */ + PHASE_VPL, /* Running in VPL */ PHASE_SPL, /* Running in SPL */ PHASE_BOARD_F, /* Running in U-Boot before relocation */ PHASE_BOARD_R, /* Running in U-Boot after relocation */ @@ -114,7 +115,9 @@ static inline enum u_boot_phase spl_phase(void) { #ifdef CONFIG_TPL_BUILD return PHASE_TPL; -#elif CONFIG_SPL_BUILD +#elif defined(CONFIG_VPL_BUILD) + return PHASE_VPL; +#elif defined(CONFIG_SPL_BUILD) return PHASE_SPL; #else DECLARE_GLOBAL_DATA_PTR; @@ -136,10 +139,15 @@ static inline enum u_boot_phase spl_prev_phase(void) { #ifdef CONFIG_TPL_BUILD return PHASE_NONE; +#elif defined(CONFIG_VPL_BUILD) + return PHASE_TPL; /* VPL requires TPL */ #elif defined(CONFIG_SPL_BUILD) - return IS_ENABLED(CONFIG_TPL) ? PHASE_TPL : PHASE_NONE; + return IS_ENABLED(CONFIG_VPL) ? PHASE_VPL : + IS_ENABLED(CONFIG_TPL) ? PHASE_TPL : + PHASE_NONE; #else - return IS_ENABLED(CONFIG_SPL) ? PHASE_SPL : PHASE_NONE; + return IS_ENABLED(CONFIG_SPL) ? PHASE_SPL : + PHASE_NONE; #endif }
@@ -152,6 +160,8 @@ static inline enum u_boot_phase spl_prev_phase(void) static inline enum u_boot_phase spl_next_phase(void) { #ifdef CONFIG_TPL_BUILD + return IS_ENABLED(CONFIG_VPL) ? PHASE_VPL : PHASE_SPL; +#elif defined(CONFIG_VPL_BUILD) return PHASE_SPL; #else return PHASE_BOARD_F; @@ -168,6 +178,8 @@ static inline const char *spl_phase_name(enum u_boot_phase phase) switch (phase) { case PHASE_TPL: return "TPL"; + case PHASE_VPL: + return "VPL"; case PHASE_SPL: return "SPL"; case PHASE_BOARD_F: @@ -189,6 +201,8 @@ static inline const char *spl_phase_prefix(enum u_boot_phase phase) switch (phase) { case PHASE_TPL: return "tpl"; + case PHASE_VPL: + return "vpl"; case PHASE_SPL: return "spl"; case PHASE_BOARD_F: @@ -203,6 +217,8 @@ static inline const char *spl_phase_prefix(enum u_boot_phase phase) #ifdef CONFIG_SPL_BUILD # ifdef CONFIG_TPL_BUILD # define SPL_TPL_NAME "TPL" +# elif defined(CONFIG_VPL_BUILD) +# define SPL_TPL_NAME "VPL" # else # define SPL_TPL_NAME "SPL" # endif diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 09506cb9a7e..9c14310ad40 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -322,11 +322,15 @@ endif
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 0b3ffa08bfa..3fa4d50f1ea 100644 --- a/scripts/Makefile.autoconf +++ b/scripts/Makefile.autoconf @@ -18,6 +18,10 @@ ifeq ($(shell grep -q '^CONFIG_TPL=y' include/config/auto.conf 2>/dev/null && ec __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 @@ tpl/u-boot.cfg: include/config.h FORCE $(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 @@ tpl/include/autoconf.mk: tpl/u-boot.cfg $(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 5df8f61aa58..3b8c9d8c319 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 @@ ifeq ($(obj),$(src)) prefix := . endif endif +endif
PHONY := __build __build: diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2ff39d39dc8..3db2550085a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -581,16 +581,21 @@ cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \ # '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 30672a61179..f047d4e0941 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -27,8 +27,16 @@ UBOOTINCLUDE := -I$(obj)/include $(UBOOTINCLUDE) 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 @@ else 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 @@ endif 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 @@ libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/ 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 @@ LDPPFLAGS += \ 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 @@ ifeq ($(CONFIG_SYS_SOC),"at91") 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 @@ else 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 @@ endif
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) += $(call ld-option, --no-dynamic-linker)
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

Add VPL versions of commonly used Kconfig options.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v8: - Support SYSCON and REGMAP too
Changes in v7: - Add a few more options
Changes in v5: - Rebase this patch on mainline (for GPIO and MISC Kconfig renames)
Changes in v4: - Add options for blk, core, misc and tpl also - Add VPL_SIZE_LIMIT
Kconfig | 10 ++ common/Kconfig | 67 ++++++++++++ common/spl/Kconfig | 219 +++++++++++++++++++++++++++++++++++++++ drivers/block/Kconfig | 12 +++ drivers/clk/Kconfig | 26 +++++ drivers/core/Kconfig | 54 +++++++++- drivers/core/Makefile | 2 +- drivers/gpio/Kconfig | 11 ++ drivers/i2c/Kconfig | 11 ++ drivers/misc/Kconfig | 28 +++++ drivers/pinctrl/Kconfig | 18 +++- drivers/rtc/Kconfig | 9 ++ drivers/serial/Kconfig | 20 ++++ drivers/sysreset/Kconfig | 10 ++ drivers/timer/Kconfig | 10 ++ drivers/tpm/Kconfig | 30 ++++++ dts/Kconfig | 17 +++ lib/Kconfig | 62 +++++++++++ 18 files changed, 612 insertions(+), 4 deletions(-)
diff --git a/Kconfig b/Kconfig index bdae59e06f4..8bbb988790b 100644 --- a/Kconfig +++ b/Kconfig @@ -319,6 +319,16 @@ config VALGRIND it can be handled accurately by Valgrind. If you aren't planning on using valgrind to debug U-Boot, say 'n'.
+config VPL_SYS_MALLOC_F_LEN + hex "Size of malloc() pool in VPL before relocation" + depends on SYS_MALLOC_F && VPL + default SYS_MALLOC_F_LEN + help + Before relocation, memory is very limited on many platforms. Still, + we can provide a small malloc() pool if needed. Driver model in + particular needs this to operate, so that it can allocate the + initial serial device and any others that are needed. + menuconfig EXPERT bool "Configure standard U-Boot features (expert users)" default y diff --git a/common/Kconfig b/common/Kconfig index f55b4211bb2..a96842a5c11 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -89,6 +89,15 @@ config TPL_LOGLEVEL int default LOGLEVEL
+config VPL_LOGLEVEL + int "loglevel for VPL" + default LOGLEVEL + help + All Messages with a loglevel smaller than the console loglevel will + be compiled in to VPL. See LOGLEVEL for a list of available log + levels. Setting this to a value above 4 may increase the code size + significantly. + config SILENT_CONSOLE bool "Support a silent console" help @@ -262,6 +271,15 @@ config LOG
if LOG
+config VPL_LOG + bool "Enable logging support in VPL" + depends on LOG + help + This enables support for logging of status and debug messages. These + can be displayed on the console, recorded in a memory buffer, or + discarded if not needed. Logging supports various categories and + levels of severity. + config LOG_MAX_LEVEL int "Maximum log level to record" default 6 @@ -431,6 +449,47 @@ config TPL_LOG_CONSOLE
endif
+config VPL_LOG + bool "Enable logging support in VPL" + depends on LOG + help + This enables support for logging of status and debug messages. These + can be displayed on the console, recorded in a memory buffer, or + discarded if not needed. Logging supports various categories and + levels of severity. + +if VPL_LOG + +config VPL_LOG_MAX_LEVEL + int "Maximum log level to record in VPL" + default 3 + help + This selects the maximum log level that will be recorded. Any value + higher than this will be ignored. If possible log statements below + this level will be discarded at build time. Levels: + + 0 - emergency + 1 - alert + 2 - critical + 3 - error + 4 - warning + 5 - note + 6 - info + 7 - debug + 8 - debug content + 9 - debug hardware I/O + +config VPL_LOG_CONSOLE + bool "Allow log output to the console in VPL" + default y + help + Enables a log driver which writes log records to the console. + Generally the console is the serial port or LCD display. Only the + log message is shown - other details like level, category, file and + line number are omitted. + +endif + config LOG_ERROR_RETURN bool "Log all functions which return an error" help @@ -777,6 +836,14 @@ config TPL_BLOBLIST This enables a bloblist in TPL. The bloblist is set up in TPL and passed to SPL and U-Boot proper.
+config VPL_BLOBLIST + bool "Support for a bloblist in VPL" + depends on BLOBLIST && VPL_LIBGENERIC_SUPPORT && VPL_LIBCOMMON_SUPPORT + default y if VPL + help + This enables a bloblist in VPL. The bloblist is set up in VPL and + passed to SPL and U-Boot proper. + if BLOBLIST
choice diff --git a/common/spl/Kconfig b/common/spl/Kconfig index be098668f0e..84f2847c724 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -189,6 +189,13 @@ config SPL_BOARD_INIT spl_board_init() from board_init_r(). This function should be provided by the board.
+config VPL_BOARD_INIT + bool "Call board-specific initialization in VPL" + help + If this option is enabled, U-Boot will call the function + spl_board_init() from board_init_r(). This function should be + provided by the board. + config SPL_BOOTROM_SUPPORT bool "Support returning to the BOOTROM" help @@ -1632,6 +1639,218 @@ config TPL_YMODEM_SUPPORT
endif # TPL
+config VPL + bool + depends on SUPPORT_SPL + prompt "Enable VPL" + help + If you want to build VPL as well as the normal image, TPL and SPL, + say Y. + +if VPL + +config VPL_BANNER_PRINT + bool "Enable output of the VPL banner 'U-Boot VPL ...'" + depends on VPL + default y + help + If this option is enabled, VPL will print the banner with version + info. Disabling this option could be useful to reduce VPL boot time + (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud). + +config VPL_BOARD_INIT + bool "Call board-specific initialization in VPL" + help + If this option is enabled, U-Boot will call the function + spl_board_init() from board_init_r(). This function should be + provided by the board. + +config VPL_CACHE + depends on CACHE + bool "Support cache drivers in VPL" + help + Enable support for cache drivers in VPL. + +config VPL_CRC32 + bool "Support CRC32 in VPL" + default y if VPL_ENV_SUPPORT || VPL_BLOBLIST + help + Enable this to support CRC32 in uImages or FIT images within VPL. + This is a 32-bit checksum value that can be used to verify images. + For FIT images, this is the least secure type of checksum, suitable + for detected accidental image corruption. For secure applications you + should consider SHA1 or SHA256. + +config VPL_DM_SPI + bool "Support SPI DM drivers in VPL" + help + Enable support for SPI DM drivers in VPL. + +config VPL_DM_SPI_FLASH + bool "Support SPI DM FLASH drivers in VPL" + help + Enable support for SPI DM flash drivers in VPL. + +config VPL_FRAMEWORK + bool "Support VPL based upon the common SPL framework" + default y + help + Enable the SPL framework under common/spl/ for VPL builds. + This framework supports MMC, NAND and YMODEM and other methods + loading of U-Boot's next stage. If unsure, say Y. + +config VPL_HANDOFF + bool "Pass hand-off information from VPL to SPL" + depends on HANDOFF && VPL_BLOBLIST + default y + help + This option enables VPL to write handoff information. This can be + used to pass information like the size of SDRAM from VPL to SPL. Also + VPL can receive information from TPL in the same place if that is + enabled. + +config VPL_LIBCOMMON_SUPPORT + bool "Support common libraries" + default y if SPL_LIBCOMMON_SUPPORT + help + Enable support for common U-Boot libraries within VPL. See + SPL_LIBCOMMON_SUPPORT for details. + +config VPL_LIBGENERIC_SUPPORT + bool "Support generic libraries" + default y if SPL_LIBGENERIC_SUPPORT + help + Enable support for generic U-Boot libraries within VPL. These + libraries include generic code to deal with device tree, hashing, + printf(), compression and the like. This option is enabled on many + boards. Enable this option to build the code in lib/ as part of a + VPL build. + +config VPL_DRIVERS_MISC + bool "Support misc drivers" + default y if TPL_DRIVERS_MISC + help + Enable miscellaneous drivers in VPL. These drivers perform various + tasks that don't fall nicely into other categories, Enable this + option to build the drivers in drivers/misc as part of a VPL + build, for those that support building in VPL (not all drivers do). + +config VPL_ENV_SUPPORT + bool "Support an environment" + help + Enable environment support in VPL. The U-Boot environment provides + a number of settings (essentially name/value pairs) which can + control many aspects of U-Boot's operation. Enabling this option will + make env_get() and env_set() available in VSPL. + +config VPL_GPIO + bool "Support GPIO in VPL" + default y if SPL_GPIO + help + Enable support for GPIOs (General-purpose Input/Output) in VPL. + GPIOs allow U-Boot to read the state of an input line (high or + low) and set the state of an output line. This can be used to + drive LEDs, control power to various system parts and read user + input. GPIOs can be useful in VPL to enable a 'sign-of-life' LED, + for example. Enable this option to build the drivers in + drivers/gpio as part of a VPL build. + +config VPL_HANDOFF + bool "Pass hand-off information from VPL to SPL and U-Boot proper" + depends on HANDOFF && VPL_BLOBLIST + default y + help + This option enables VPL to write handoff information. This can be + used to pass information like the size of SDRAM from VPL to U-Boot + proper. The information is also available to VPL if it is useful + there. + +config VPL_HASH + bool "Support hashing drivers in VPL" + depends on VPL + select SHA1 + select SHA256 + help + Enable hashing drivers in VPL. These drivers can be used to + accelerate secure boot processing in secure applications. Enable + this option to build system-specific drivers for hash acceleration + as part of a VPL build. + +config VPL_I2C_SUPPORT + bool "Support I2C in VPL" + default y if SPL_I2C_SUPPORT + help + Enable support for the I2C bus in VPL. Vee SPL_I2C_SUPPORT for + details. + +config VPL_PCH_SUPPORT + bool "Support PCH drivers" + default y if TPL_PCH_SUPPORT + help + Enable support for PCH (Platform Controller Hub) devices in VPL. + These are used to set up GPIOs and the SPI peripheral early in + boot. This enables the drivers in drivers/pch as part of a VPL + build. + +config VPL_PCI + bool "Support PCI drivers" + default y if SPL_PCI + help + Enable support for PCI in VPL. For platforms that need PCI to boot, + or must perform some init using PCI in VPL, this provides the + necessary driver support. This enables the drivers in drivers/pci + as part of a VPL build. + +config VPL_RTC + bool "Support RTC drivers" + help + Enable RTC (Real-time Clock) support in VPL. This includes support + for reading and setting the time. Some RTC devices also have some + non-volatile (battery-backed) memory which is accessible if + needed. This enables the drivers in drivers/rtc as part of a VPL + build. + +config VPL_SERIAL + bool "Support serial" + default y if TPL_SERIAL + select VPL_PRINTF + select VPL_STRTO + help + Enable support for serial in VPL. See SPL_SERIAL_SUPPORT for + details. + +config VPL_SIZE_LIMIT + hex "Maximum size of VPL image" + depends on VPL + default 0x0 + help + Specifies the maximum length of the U-Boot VPL image. + If this value is zero, it is ignored. + +config VPL_SPI + bool "Support SPI drivers" + help + Enable support for using SPI in VPL. See SPL_SPI_SUPPORT for + details. + +config VPL_SPI_FLASH_SUPPORT + bool "Support SPI flash drivers" + help + Enable support for using SPI flash in VPL, and loading U-Boot from + SPI flash. SPI flash (Serial Peripheral Bus flash) is named after + the SPI bus that is used to connect it to a system. It is a simple + but fast bidirectional 4-wire bus (clock, chip select and two data + lines). This enables the drivers in drivers/mtd/spi as part of a + VPL build. This normally requires VPL_SPI_SUPPORT. + +config VPL_TEXT_BASE + hex "VPL Text Base" + default 0x0 + help + The address in memory that VPL will be running from. + +endif # VPL + config SPL_AT91_MCK_BYPASS bool "Use external clock signal as a source of main clock for AT91 platforms" depends on ARCH_AT91 diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index c54b58110cf..d6d1c6e32cc 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -39,6 +39,18 @@ config TPL_BLK be partitioned into several areas, called 'partitions' in U-Boot. A filesystem can be placed in each partition.
+config VPL_BLK + bool "Support block devices in VPL" + depends on VPL_DM && BLK + default y + help + Enable support for block devices, such as SCSI, MMC and USB + flash sticks. These provide a block-level interface which permits + reading, writing and (in some cases) erasing blocks. Block + devices often have a partition table which allows the device to + be partitioned into several areas, called 'partitions' in U-Boot. + A filesystem can be placed in each partition. + config BLOCK_CACHE bool "Use block device cache" depends on BLK diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 6dc271f71b1..a62b81a1232 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -30,6 +30,32 @@ config TPL_CLK setting up clocks within TPL, and allows the same drivers to be used as U-Boot proper.
+config VPL_CLK + bool "Enable clock support in VPL" + depends on CLK && VPL_DM + help + The clock subsystem adds a small amount of overhead to the image. + If this is acceptable and you have a need to use clock drivers in + SPL, enable this option. It might provide a cleaner interface to + setting up clocks within TPL, and allows the same drivers to be + used as U-Boot proper. + +config CLK_BCM6345 + bool "Clock controller driver for BCM6345" + depends on CLK && ARCH_BMIPS + default y + help + This clock driver adds support for enabling and disabling peripheral + clocks on BCM6345 SoCs. HW has no rate changing capabilities. + +config CLK_BOSTON + def_bool y if TARGET_BOSTON + depends on CLK + select REGMAP + select SYSCON + help + Enable this to support the clocks + config SPL_CLK_CCF bool "SPL Common Clock Framework [CCF] support " depends on SPL diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 5c3400417f9..408a8d8e28b 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -35,6 +35,16 @@ config TPL_DM CONFIG_SPL_SYS_MALLOC_F_LEN for more details on how to enable it. Disable this for very small implementations.
+config VPL_DM + bool "Enable Driver Model for VPL" + depends on DM && VPL + default y if SPL_DM + help + Enable driver model in VPL. You will need to provide a + suitable malloc() implementation. If you are not using the + full malloc() enabled by CONFIG_SYS_SPL_MALLOC_START, + consider using CONFIG_SYS_MALLOC_SIMPLE. + config DM_WARN bool "Enable warnings in driver model" depends on DM @@ -121,6 +131,15 @@ config SPL_DM_SEQ_ALIAS numbered devices (e.g. serial0 = &serial0). This feature can be disabled if it is not required, to save code space in SPL.
+config VPL_DM_SEQ_ALIAS + bool "Support numbered aliases in device tree in VPL" + depends on VPL_DM + default y + help + Most boards will have a '/aliases' node containing the path to + numbered devices (e.g. serial0 = &serial0). This feature can be + disabled if it is not required, to save code space in VPL. + config SPL_DM_INLINE_OFNODE bool "Inline some ofnode functions which are seldom used in SPL" depends on SPL_DM @@ -176,6 +195,16 @@ config TPL_REGMAP support any bus type (I2C, SPI) but so far this only supports direct memory access.
+config VPL_REGMAP + bool "Support register maps in VPL" + depends on VPL_DM + help + Hardware peripherals tend to have one or more sets of registers + which can be accessed to control the hardware. A register map + models this with a simple read/write interface. It can in principle + support any bus type (I2C, SPI) but so far this only supports + direct memory access. + config SYSCON bool "Support system controllers" depends on REGMAP @@ -196,7 +225,16 @@ config SPL_SYSCON
config TPL_SYSCON bool "Support system controllers in TPL" - depends on TPL_REGMAP + depends on SPL_REGMAP + help + Many SoCs have a number of system controllers which are dealt with + as a group by a single driver. Some common functionality is provided + by this uclass, including accessing registers via regmap and + assigning a unique number to each. + +config VPL_SYSCON + bool "Support system controllers in VPL" + depends on VPL_REGMAP help Many SoCs have a number of system controllers which are dealt with as a group by a single driver. Some common functionality is provided @@ -292,6 +330,20 @@ config SPL_OF_TRANSLATE used for the address translation. This function is faster and smaller in size than fdt_translate_address().
+config VPL_OF_TRANSLATE + bool "Translate addresses using fdt_translate_address in SPL" + depends on SPL_DM && VPL_OF_CONTROL + help + If this option is enabled, the reg property will be translated + using the fdt_translate_address() function. This is necessary + on some platforms (e.g. MVEBU) using complex "ranges" + properties in many nodes. As this translation is not handled + correctly in the default simple_bus_translate() function. + + If this option is not enabled, simple_bus_translate() will be + used for the address translation. This function is faster and + smaller in size than fdt_translate_address(). + config TRANSLATION_OFFSET bool "Platforms specific translation offset" depends on DM && OF_CONTROL diff --git a/drivers/core/Makefile b/drivers/core/Makefile index 7099073a533..bce0a3f65cb 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -5,7 +5,7 @@ obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o tag.o obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o obj-$(CONFIG_$(SPL_TPL_)DEVRES) += devres.o -obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o +obj-$(CONFIG_$(SPL_TPL_)DM_DEVICE_REMOVE) += device-remove.o obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o obj-$(CONFIG_DM) += dump.o diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 89068c7800d..886cdbcdbaa 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -48,6 +48,17 @@ config TPL_DM_GPIO particular GPIOs that they provide. The uclass interface is defined in include/asm-generic/gpio.h.
+config VPL_DM_GPIO + bool "Enable Driver Model for GPIO drivers in VPL" + depends on DM_GPIO && VPL_DM && VPL_GPIO + default y + help + Enable driver model for GPIO access in VPL. The standard GPIO + interface (gpio_get_value(), etc.) is then implemented by + the GPIO uclass. Drivers provide methods to query the + particular GPIOs that they provide. The uclass interface + is defined in include/asm-generic/gpio.h. + config GPIO_HOG bool "Enable GPIO hog support" depends on DM_GPIO diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 5482a4a470b..d25c5736ef0 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -47,6 +47,17 @@ config SPL_DM_I2C device (bus child) info is kept as parent platdata. The interface is defined in include/i2c.h.
+config VPL_DM_I2C + bool "Enable Driver Model for I2C drivers in VPL" + depends on VPL_DM && DM_I2C + default y + help + Enable driver model for I2C. The I2C uclass interface: probe, read, + write and speed, is implemented with the bus drivers operations, + which provide methods for bus setting and data transfer. Each chip + device (bus child) info is kept as parent platdata. The interface + is defined in include/i2c.h. + config SYS_I2C_LEGACY bool "Enable legacy I2C subsystem and drivers" depends on !DM_I2C diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index dab7a99c68c..9af806a20ae 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -131,6 +131,16 @@ config TPL_CROS_EC control access to the battery and main PMIC depending on the device. You can use the 'crosec' command to access it.
+config VPL_CROS_EC + bool "Enable Chrome OS EC in VPL" + depends on VPL + help + Enable access to the Chrome OS EC in VPL. This is a separate + microcontroller typically available on a SPI bus on Chromebooks. It + provides access to the keyboard, some internal storage and may + control access to the battery and main PMIC depending on the + device. You can use the 'crosec' command to access it. + config CROS_EC_I2C bool "Enable Chrome OS EC I2C driver" depends on CROS_EC @@ -167,6 +177,15 @@ config TPL_CROS_EC_LPC through a legacy port interface, so on x86 machines the main function of the EC is power and thermal management.
+config VPL_CROS_EC_LPC + bool "Enable Chrome OS EC LPC driver in VPL" + depends on CROS_EC + help + Enable I2C access to the Chrome OS EC. This is used on x86 + Chromebooks such as link and falco. The keyboard is provided + through a legacy port interface, so on x86 machines the main + function of the EC is power and thermal management. + config CROS_EC_SANDBOX bool "Enable Chrome OS EC sandbox driver" depends on CROS_EC && SANDBOX @@ -194,6 +213,15 @@ config TPL_CROS_EC_SANDBOX EC flash read/write/erase support and a few other things. It is enough to perform a Chrome OS verified boot on sandbox.
+config VPL_CROS_EC_SANDBOX + bool "Enable Chrome OS EC sandbox driver in VPL" + depends on VPL_CROS_EC && SANDBOX + help + Enable a sandbox emulation of the Chrome OS EC in VPL. This supports + keyboard (use the -l flag to enable the LCD), verified boot context, + EC flash read/write/erase support and a few other things. It is + enough to perform a Chrome OS verified boot on sandbox. + config CROS_EC_SPI bool "Enable Chrome OS EC SPI driver" depends on CROS_EC diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 13033198f96..563d96d4f5d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -89,20 +89,34 @@ config TPL_PINCTRL This option is an TPL variant of the PINCTRL option. See the help of PINCTRL for details.
+config VPL_PINCTRL + bool "Support pin controllers in VPL" + depends on VPL && VPL_DM + help + This option is an VPL variant of the PINCTRL option. + See the help of PINCTRL for details. + config SPL_PINCTRL_FULL bool "Support full pin controllers in SPL" depends on SPL_PINCTRL && SPL_OF_CONTROL default n if TARGET_STM32F746_DISCO default y help - This option is an SPL-variant of the PINCTRL_FULL option. + This option is an SPL variant of the PINCTRL_FULL option. See the help of PINCTRL_FULL for details.
config TPL_PINCTRL_FULL bool "Support full pin controllers in TPL" depends on TPL_PINCTRL && TPL_OF_CONTROL help - This option is an TPL-variant of the PINCTRL_FULL option. + This option is a TPL variant of the PINCTRL_FULL option. + See the help of PINCTRL_FULL for details. + +config VPL_PINCTRL_FULL + bool "Support full pin controllers in VPL" + depends on VPL_PINCTRL && VPL_OF_CONTROL + help + This option is a VPL variant of the PINCTRL_FULL option. See the help of PINCTRL_FULL for details.
config SPL_PINCTRL_GENERIC diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 7a6c6efb4b0..23963271928 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -32,6 +32,15 @@ config TPL_DM_RTC drivers to perform the actual functions. See rtc.h for a description of the API.
+config VPL_DM_RTC + bool "Enable Driver Model for RTC drivers in VPL" + depends on VPL_DM + help + Enable drver model for real-time-clock drivers. The RTC uclass + then provides the rtc_get()/rtc_set() interface, delegating to + drivers to perform the actual functions. See rtc.h for a + description of the API. + config RTC_ENABLE_32KHZ_OUTPUT bool "Enable RTC 32Khz output" help diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1e595d06004..5dcf5c019da 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -74,6 +74,16 @@ config TPL_SERIAL_PRESENT This option enables the full UART in TPL, so if is it disabled, the full UART driver will be omitted, thus saving space.
+config VPL_SERIAL_PRESENT + bool "Provide a serial driver in VPL" + depends on DM_SERIAL && VPL + default y + help + In very space-constrained devices even the full UART driver is too + large. In this case the debug UART can still be used in some cases. + This option enables the full UART in TPL, so if is it disabled, + the full UART driver will be omitted, thus saving space. + # Logic to allow us to use the imply keyword to set what the default port # should be. The default is otherwise 1. config CONS_INDEX_0 @@ -195,6 +205,16 @@ config TPL_DM_SERIAL implements serial_putc() etc. The uclass interface is defined in include/serial.h.
+config VPL_DM_SERIAL + bool "Enable Driver Model for serial drivers in VPL" + depends on DM_SERIAL + default y if VPL && DM_SERIAL + help + Enable driver model for serial in VPL. This replaces + drivers/serial/serial.c with the serial uclass, which + implements serial_putc() etc. The uclass interface is + defined in include/serial.h. + config DEBUG_UART bool "Enable an early debug UART for debugging" help diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 25dd02c7049..a0acffa4b07 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -31,6 +31,16 @@ config TPL_SYSRESET to effect a reset. The uclass will try all available drivers when reset_walk() is called.
+config VPL_SYSRESET + bool "Enable support for system reset drivers in VPL mode" + depends on SYSRESET && VPL_DM + default y if TPL_SYSRESET + help + Enable system reset drivers which can be used to reset the CPU or + board. Each driver can provide a reset method which will be called + to effect a reset. The uclass will try all available drivers when + reset_walk() is called. + if SYSRESET
config SYSRESET_CMD_RESET diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 92050179c28..2eda3bcca5b 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -27,6 +27,16 @@ config TPL_TIMER function. This enables the drivers in drivers/timer as part of an TPL build.
+config VPL_TIMER + bool "Enable driver model for timer drivers in VPL" + depends on TIMER && VPL + default y if TPL_TIMER + help + Enable support for timer drivers in VPL. These can be used to get + a timer value when in VPL, or perhaps for implementing a delay + function. This enables the drivers in drivers/timer as part of an + TPL build. + config TIMER_EARLY bool "Allow timer to be used early in U-Boot" depends on TIMER diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig index 406ee8716e1..eceff27d5f8 100644 --- a/drivers/tpm/Kconfig +++ b/drivers/tpm/Kconfig @@ -137,6 +137,36 @@ config TPM2_CR50_I2C trust for a device, It operates like a TPM and can be used with verified boot. Cr50 is used on recent Chromebooks (since 2017).
+config SPL_TPM2_CR50_I2C + bool "Enable support for Google cr50 TPM" + depends on DM_I2C && SPL_TPM + help + Cr50 is an implementation of a TPM on Google's H1 security chip. + This uses the same open-source firmware as the Chromium OS EC. + While Cr50 has other features, its primary role is as the root of + trust for a device, It operates like a TPM and can be used with + verified boot. Cr50 is used on recent Chromebooks (since 2017). + +config TPL_TPM2_CR50_I2C + bool "Enable support for Google cr50 TPM" + depends on DM_I2C && TPL_TPM + help + Cr50 is an implementation of a TPM on Google's H1 security chip. + This uses the same open-source firmware as the Chromium OS EC. + While Cr50 has other features, its primary role is as the root of + trust for a device, It operates like a TPM and can be used with + verified boot. Cr50 is used on recent Chromebooks (since 2017). + +config VPL_TPM2_CR50_I2C + bool "Enable support for Google cr50 TPM" + depends on DM_I2C && VPL_TPM + help + Cr50 is an implementation of a TPM on Google's H1 security chip. + This uses the same open-source firmware as the Chromium OS EC. + While Cr50 has other features, its primary role is as the root of + trust for a device, It operates like a TPM and can be used with + verified boot. Cr50 is used on recent Chromebooks (since 2017). + config TPM2_TIS_SANDBOX bool "Enable sandbox TPMv2.x driver" depends on TPM_V2 && SANDBOX diff --git a/dts/Kconfig b/dts/Kconfig index b19912d10dd..f1d05cc0803 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -65,6 +65,15 @@ config TPL_OF_CONTROL which is not enough to support device tree. Enable this option to allow such boards to be supported by U-Boot TPL.
+config VPL_OF_CONTROL + bool "Enable run-time configuration via Device Tree in VPL" + depends on VPL && OF_CONTROL + default y if SPL_OF_CONTROL + help + Some boards use device tree in U-Boot but only have 4KB of SRAM + which is not enough to support device tree. Enable this option to + allow such boards to be supported by U-Boot VPL. + config OF_LIVE bool "Enable use of a live tree" depends on DM && OF_CONTROL @@ -523,4 +532,12 @@ config TPL_OF_PLATDATA_DRIVER_RT
endif
+config VPL_OF_REAL + def_bool y + help + Indicates that a real devicetree is available which can be accessed + at runtime. This means that dev_read_...() functions can be used to + read data from the devicetree for each device. This is true if + TPL_OF_CONTROL is enabled and not TPL_OF_PLATDATA + endmenu diff --git a/lib/Kconfig b/lib/Kconfig index 858be14f091..e2697ab2ceb 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -90,6 +90,11 @@ config TPL_PRINTF select TPL_SPRINTF select TPL_STRTO if !TPL_USE_TINY_PRINTF
+config VPL_PRINTF + bool + select VPL_SPRINTF + select VPL_STRTO if !VPL_USE_TINY_PRINTF + config SPRINTF bool default y @@ -100,6 +105,9 @@ config SPL_SPRINTF config TPL_SPRINTF bool
+config VPL_SPRINTF + bool + config SSCANF bool
@@ -113,6 +121,9 @@ config SPL_STRTO config TPL_STRTO bool
+config VPL_STRTO + bool + config IMAGE_SPARSE bool
@@ -165,6 +176,17 @@ config TPL_USE_TINY_PRINTF
The supported format specifiers are %c, %s, %u/%d and %x.
+config VPL_USE_TINY_PRINTF + bool "Enable tiny printf() version for VPL" + depends on VPL + help + This option enables a tiny, stripped down printf version. + This should only be used in space limited environments, + like SPL versions with hard memory limits. This version + reduces the code size by about 2.5KiB on armv7. + + The supported format specifiers are %c, %s, %u/%d and %x. + config PANIC_HANG bool "Do not reset the system on fatal error" help @@ -371,6 +393,17 @@ config TPL_TPM for the low-level TPM interface, but only one TPM is supported at a time by the TPM library.
+config VPL_TPM + bool "Trusted Platform Module (TPM) Support in VPL" + depends on VPL_DM + help + This enables support for TPMs which can be used to provide security + features for your board. The TPM can be connected via LPC or I2C + and a sandbox TPM is provided for testing purposes. Use the 'tpm' + command to interactive the TPM. Driver model support is provided + for the low-level TPM interface, but only one TPM is supported at + a time by the TPM library. + endmenu
menu "Android Verified Boot" @@ -625,6 +658,12 @@ config SPL_LZMA help This enables support for LZMA compression algorithm for SPL boot.
+config VPL_LZMA + bool "Enable LZMA decompression support for VPL build" + default y if LZMA + help + This enables support for LZMA compression algorithm for VPL boot. + config SPL_LZO bool "Enable LZO decompression support in SPL" help @@ -704,6 +743,7 @@ config OF_LIBFDT_OVERLAY
config SPL_OF_LIBFDT bool "Enable the FDT library for SPL" + depends on SPL_LIBGENERIC_SUPPORT default y if SPL_OF_CONTROL help This enables the FDT library (libfdt). It provides functions for @@ -725,6 +765,7 @@ config SPL_OF_LIBFDT_ASSUME_MASK
config TPL_OF_LIBFDT bool "Enable the FDT library for TPL" + depends on TPL_LIBGENERIC_SUPPORT default y if TPL_OF_CONTROL help This enables the FDT library (libfdt). It provides functions for @@ -744,6 +785,27 @@ config TPL_OF_LIBFDT_ASSUME_MASK 0xff means all assumptions are made and any invalid data may cause unsafe execution. See FDT_ASSUME_PERFECT, etc. in libfdt_internal.h
+config VPL_OF_LIBFDT + bool "Enable the FDT library for VPL" + default y if VPL_OF_CONTROL && !VPL_OF_PLATDATA + help + This enables the FDT library (libfdt). It provides functions for + accessing binary device tree images in memory, such as adding and + removing nodes and properties, scanning through the tree and finding + particular compatible nodes. The library operates on a flattened + version of the device tree. + +config VPL_OF_LIBFDT_ASSUME_MASK + hex "Mask of conditions to assume for libfdt" + depends on VPL_OF_LIBFDT || FIT + default 0xff + help + Use this to change the assumptions made by libfdt in SPL about the + device tree it is working with. A value of 0 means that no assumptions + are made, and libfdt is able to deal with malicious data. A value of + 0xff means all assumptions are made and any invalid data may cause + unsafe execution. See FDT_ASSUME_PERFECT, etc. in libfdt_internal.h + config FDT_FIXUP_PARTITIONS bool "overwrite MTD partitions in DTS through defined in 'mtdparts'" depends on OF_LIBFDT

Add an initial VPL build for sandbox. This includes the flow:
TPL (with of-platdata) -> VPL -> SPL -> U-Boot
To run it:
./tpl/u-boot-tpl -D
The -D is needed to get the default device tree, which includes the serial console info.
Add a Makefile check for OF_HOSTFILE which is the option that enables devicetree control on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v8: - Update defconfig to account for option changes - Drop reference to old OF_HOSTFILE option
Changes in v7: - Rebase to master - Update some options based on settings in master
Changes in v6: - Add docs for sandbox_vpl build - Drop TPL_HASH_SUPPORT patch since we only have SPL_HASH now
Changes in v4: - Add a sandbox_vpl build - Update cover letter
arch/sandbox/Kconfig | 8 ++ arch/sandbox/cpu/spl.c | 12 +- arch/sandbox/dts/sandbox.dtsi | 10 +- board/sandbox/MAINTAINERS | 7 + configs/sandbox_vpl_defconfig | 251 ++++++++++++++++++++++++++++++++++ doc/arch/sandbox.rst | 13 ++ 6 files changed, 294 insertions(+), 7 deletions(-) create mode 100644 configs/sandbox_vpl_defconfig
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig index 477c51960da..5f55c7f28e1 100644 --- a/arch/sandbox/Kconfig +++ b/arch/sandbox/Kconfig @@ -29,6 +29,14 @@ config SANDBOX_SPL bool "Enable SPL for sandbox" select SUPPORT_SPL
+config SANDBOX_TPL + bool "Enable TPL for sandbox" + select SUPPORT_TPL + +config SANDBOX_VPL + bool "Enable VPL for sandbox" + select SUPPORT_VPL + config SYS_CONFIG_NAME default "sandbox_spl" if SANDBOX_SPL default "sandbox" if !SANDBOX_SPL diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index 3f107b8acbd..fe5d44d36ed 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -32,13 +32,21 @@ int sandbox_find_next_phase(char *fname, int maxlen, bool use_img) return 0; }
-/* SPL / TPL init function */ +/* SPL / TPL / VPL init function */ void board_init_f(ulong flag) { struct sandbox_state *state = state_get_current(); + int ret;
gd->arch.ram_buf = state->ram_buf; gd->ram_size = state->ram_size; + + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + preloader_console_init(); }
u32 spl_boot_device(void) @@ -75,8 +83,6 @@ void spl_board_init(void) { struct sandbox_state *state = state_get_current();
- preloader_console_init(); - if (state->run_unittests) { struct unit_test *tests = UNIT_TEST_ALL_START(); const int count = UNIT_TEST_ALL_COUNT(); diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index 29306ac04da..aa22b8765c8 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -254,7 +254,7 @@ };
spl-test { - u-boot,dm-pre-reloc; + u-boot,dm-spl; compatible = "sandbox,spl-test"; boolval; intval = <1>; @@ -268,7 +268,7 @@ };
spl-test2 { - u-boot,dm-pre-reloc; + u-boot,dm-spl; compatible = "sandbox,spl-test"; intval = <3>; intarray = <5>; @@ -280,14 +280,14 @@ };
spl-test3 { - u-boot,dm-pre-reloc; + u-boot,dm-spl; compatible = "sandbox,spl-test"; stringarray = "one"; maybe-empty-int = <1>; };
spl-test5 { - u-boot,dm-tpl; + u-boot,dm-vpl; compatible = "sandbox,spl-test"; stringarray = "tpl"; }; @@ -334,6 +334,8 @@ /* Needs to be available prior to relocation */ uart0: serial { u-boot,dm-spl; + u-boot,dm-tpl; + u-boot,dm-vpl; compatible = "sandbox,serial"; sandbox,text-colour = "cyan"; pinctrl-names = "default"; diff --git a/board/sandbox/MAINTAINERS b/board/sandbox/MAINTAINERS index d32561cd1d0..9f5073bf287 100644 --- a/board/sandbox/MAINTAINERS +++ b/board/sandbox/MAINTAINERS @@ -33,3 +33,10 @@ S: Maintained F: board/sandbox/ F: include/configs/sandbox.h F: configs/sandbox_flattree_defconfig + +SANDBOX VPL BOARD +M: Simon Glass sjg@chromium.org +S: Maintained +F: board/sandbox/ +F: include/configs/sandbox_spl.h +F: configs/sandbox_vpl_defconfig diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig new file mode 100644 index 00000000000..2cc16233cf7 --- /dev/null +++ b/configs/sandbox_vpl_defconfig @@ -0,0 +1,251 @@ +CONFIG_SYS_TEXT_BASE=0x200000 +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="sandbox" +CONFIG_SPL_SERIAL=y +CONFIG_TPL_LIBCOMMON_SUPPORT=y +CONFIG_TPL_LIBGENERIC_SUPPORT=y +CONFIG_TPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SYS_MALLOC_F_LEN=0x8000 +CONFIG_SPL=y +CONFIG_BOOTSTAGE_STASH_ADDR=0x0 +CONFIG_SYS_LOAD_ADDR=0x0 +CONFIG_SANDBOX_SPL=y +CONFIG_SANDBOX_TPL=y +CONFIG_SANDBOX_VPL=y +CONFIG_DEBUG_UART=y +CONFIG_SYS_MEMTEST_START=0x00100000 +CONFIG_SYS_MEMTEST_END=0x00101000 +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_LOAD_FIT=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_BOOTSTAGE=y +CONFIG_BOOTSTAGE_REPORT=y +CONFIG_BOOTSTAGE_FDT=y +CONFIG_BOOTSTAGE_STASH=y +CONFIG_BOOTSTAGE_STASH_SIZE=0x4096 +CONFIG_CONSOLE_RECORD=y +CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000 +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_HANDOFF=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_TPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_I2C=y +CONFIG_SPL_RTC=y +CONFIG_TPL=y +CONFIG_TPL_DRIVERS_MISC=y +CONFIG_TPL_ENV_SUPPORT=y +CONFIG_TPL_I2C=y +CONFIG_TPL_RTC=y +CONFIG_VPL=y +CONFIG_VPL_ENV_SUPPORT=y +CONFIG_CMD_CPU=y +CONFIG_CMD_LICENSE=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_BOOTEFI_HELLO=y +# CONFIG_CMD_ELF is not set +CONFIG_CMD_ASKENV=y +CONFIG_CMD_GREPENV=y +CONFIG_CMD_ERASEENV=y +CONFIG_CMD_ENV_CALLBACK=y +CONFIG_CMD_ENV_FLAGS=y +CONFIG_CMD_NVEDIT_INFO=y +CONFIG_CMD_NVEDIT_LOAD=y +CONFIG_CMD_NVEDIT_SELECT=y +CONFIG_LOOPW=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MX_CYCLIC=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_DEMO=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_IDE=y +CONFIG_CMD_I2C=y +CONFIG_CMD_OSD=y +CONFIG_CMD_PCI=y +CONFIG_CMD_REMOTEPROC=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_BOOTP_DNS2=y +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_TFTPSRV=y +CONFIG_CMD_RARP=y +CONFIG_CMD_CDP=y +CONFIG_CMD_SNTP=y +CONFIG_CMD_DNS=y +CONFIG_CMD_LINK_LOCAL=y +CONFIG_CMD_BMP=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_SOUND=y +CONFIG_CMD_BOOTSTAGE=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_TPM=y +CONFIG_CMD_TPM_TEST=y +CONFIG_CMD_CBFS=y +CONFIG_CMD_CRAMFS=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_MAC_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_TPL_OF_CONTROL=y +CONFIG_TPL_OF_PLATDATA=y +CONFIG_TPL_OF_PLATDATA_INST=y +CONFIG_ENV_IS_NOWHERE=y +CONFIG_ENV_IS_IN_EXT4=y +CONFIG_ENV_EXT4_INTERFACE="host" +CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0" +CONFIG_BOOTP_SEND_HOSTNAME=y +CONFIG_NETCONSOLE=y +CONFIG_IP_DEFRAG=y +CONFIG_SPL_DM=y +CONFIG_TPL_DM=y +CONFIG_DM_DMA=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_VPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_VPL_SYSCON=y +CONFIG_DEVRES=y +CONFIG_DEBUG_DEVRES=y +# CONFIG_SPL_SIMPLE_BUS is not set +CONFIG_ADC=y +CONFIG_ADC_SANDBOX=y +CONFIG_SYS_SATA_MAX_DEVICE=2 +CONFIG_AXI=y +CONFIG_AXI_SANDBOX=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_TPL_CLK=y +CONFIG_CPU=y +CONFIG_DM_DEMO=y +CONFIG_DM_DEMO_SIMPLE=y +CONFIG_DM_DEMO_SHAPE=y +CONFIG_SPL_FIRMWARE=y +CONFIG_GPIO_HOG=y +CONFIG_PM8916_GPIO=y +CONFIG_SANDBOX_GPIO=y +CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_I2C_CROS_EC_LDO=y +CONFIG_DM_I2C_GPIO=y +CONFIG_SYS_I2C_SANDBOX=y +CONFIG_I2C_MUX=y +CONFIG_I2C_ARB_GPIO_CHALLENGE=y +CONFIG_CROS_EC_KEYB=y +CONFIG_I8042_KEYB=y +CONFIG_IOMMU=y +CONFIG_LED=y +CONFIG_LED_BLINK=y +CONFIG_LED_GPIO=y +CONFIG_DM_MAILBOX=y +CONFIG_SANDBOX_MBOX=y +CONFIG_MISC=y +CONFIG_TPL_MISC=y +CONFIG_CROS_EC=y +CONFIG_CROS_EC_I2C=y +CONFIG_CROS_EC_LPC=y +CONFIG_CROS_EC_SANDBOX=y +CONFIG_CROS_EC_SPI=y +CONFIG_P2SB=y +CONFIG_PWRSEQ=y +CONFIG_SPL_PWRSEQ=y +CONFIG_MMC_SANDBOX=y +CONFIG_SPI_FLASH_SANDBOX=y +CONFIG_SPI_FLASH_ATMEL=y +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_DM_ETH=y +CONFIG_NVME=y +CONFIG_PCI=y +CONFIG_PCI_SANDBOX=y +CONFIG_PHY=y +CONFIG_PHY_SANDBOX=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_SANDBOX=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_ACT8846=y +CONFIG_DM_PMIC_PFUZE100=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_PMIC_MC34708=y +CONFIG_PMIC_PM8916=y +CONFIG_PMIC_RK8XX=y +CONFIG_PMIC_S2MPS11=y +CONFIG_DM_PMIC_SANDBOX=y +CONFIG_PMIC_S5M8767=y +CONFIG_PMIC_TPS65090=y +CONFIG_DM_REGULATOR=y +CONFIG_REGULATOR_ACT8846=y +CONFIG_DM_REGULATOR_PFUZE100=y +CONFIG_DM_REGULATOR_MAX77686=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_REGULATOR_S5M8767=y +CONFIG_DM_REGULATOR_SANDBOX=y +CONFIG_REGULATOR_TPS65090=y +CONFIG_DM_PWM=y +CONFIG_PWM_CROS_EC=y +CONFIG_PWM_SANDBOX=y +CONFIG_RAM=y +CONFIG_REMOTEPROC_SANDBOX=y +CONFIG_DM_RESET=y +CONFIG_SANDBOX_RESET=y +CONFIG_DM_RTC=y +CONFIG_SPL_DM_RTC=y +CONFIG_TPL_DM_RTC=y +CONFIG_SANDBOX_SERIAL=y +CONFIG_SOUND=y +CONFIG_SOUND_SANDBOX=y +CONFIG_SOC_DEVICE=y +CONFIG_SANDBOX_SPI=y +CONFIG_SPMI=y +CONFIG_SPMI_SANDBOX=y +CONFIG_SYSINFO=y +CONFIG_SYSINFO_SANDBOX=y +CONFIG_SYSINFO_GPIO=y +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_TPL_SYSRESET=y +CONFIG_TIMER=y +CONFIG_TIMER_EARLY=y +CONFIG_SANDBOX_TIMER=y +CONFIG_USB=y +CONFIG_USB_EMUL=y +CONFIG_USB_KEYBOARD=y +CONFIG_DM_VIDEO=y +CONFIG_CONSOLE_ROTATION=y +CONFIG_CONSOLE_TRUETYPE=y +CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y +CONFIG_VIDEO_SANDBOX_SDL=y +CONFIG_OSD=y +CONFIG_SANDBOX_OSD=y +CONFIG_SPLASH_SCREEN_ALIGN=y +CONFIG_FS_CBFS=y +CONFIG_FS_CRAMFS=y +# CONFIG_SPL_USE_TINY_PRINTF is not set +CONFIG_CMD_DHRYSTONE=y +CONFIG_RSA_VERIFY_WITH_PKEY=y +CONFIG_TPM=y +CONFIG_LZ4=y +CONFIG_ERRNO_STR=y +CONFIG_UNIT_TEST=y +CONFIG_SPL_UNIT_TEST=y +CONFIG_UT_TIME=y +CONFIG_UT_DM=y diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst index e1119492b45..bc670b98b7e 100644 --- a/doc/arch/sandbox.rst +++ b/doc/arch/sandbox.rst @@ -420,6 +420,19 @@ state_setprop() which does this automatically and avoids running out of space. See existing code for examples.
+VPL (Verifying Program Loader) +------------------------------ + +Sandbox provides an example build of vpl called `sandbox_vpl`. This can be run +using:: + + /path/to/sandbox_vpl/tpl/u-boot-tpl -D + +It starts up TPL (first-stage init), then VPL, then runs SPL and finally U-Boot +proper, following the normal flow for a verified boot. At present, no +verification is actually implemented. + + Debugging the init sequence ---------------------------

Add support for these to the pytest system.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v8: - Add new patch to support running vpl tests
test/py/conftest.py | 7 +++++-- test/py/tests/test_vpl.py | 34 +++++++++++++++++++++++++++++++ test/py/u_boot_console_sandbox.py | 7 ++++++- 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 test/py/tests/test_vpl.py
diff --git a/test/py/conftest.py b/test/py/conftest.py index 16e445cd8ee..2ba34479e03 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -322,8 +322,11 @@ def pytest_generate_tests(metafunc): if fn == 'ut_subtest': generate_ut_subtest(metafunc, fn, '/u-boot.sym') continue - if fn == 'ut_spl_subtest': - generate_ut_subtest(metafunc, fn, '/spl/u-boot-spl.sym') + m_subtest = re.match('ut_(.)pl_subtest', fn) + if m_subtest: + spl_name = m_subtest.group(1) + generate_ut_subtest( + metafunc, fn, f'/{spl_name}pl/u-boot-{spl_name}pl.sym') continue generate_config(metafunc, fn)
diff --git a/test/py/tests/test_vpl.py b/test/py/tests/test_vpl.py new file mode 100644 index 00000000000..4af578b9173 --- /dev/null +++ b/test/py/tests/test_vpl.py @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright 2022 Google LLC +# Written by Simon Glass sjg@chromium.org + +import os.path +import pytest + +def test_vpl(u_boot_console, ut_vpl_subtest): + """Execute a "ut" subtest. + + The subtests are collected in function generate_ut_subtest() from linker + generated lists by applying a regular expression to the lines of file + vpl/u-boot-vpl.sym. The list entries are created using the C macro + UNIT_TEST(). + + Strict naming conventions have to be followed to match the regular + expression. Use UNIT_TEST(foo_test_bar, _flags, foo_test) for a test bar in + test suite foo that can be executed via command 'ut foo bar' and is + implemented in C function foo_test_bar(). + + Args: + u_boot_console (ConsoleBase): U-Boot console + ut_subtest (str): VPL test to be executed (e.g. 'dm platdata_phandle') + """ + try: + cons = u_boot_console + cons.restart_uboot_with_flags(['-u', '-k', ut_vpl_subtest.split()[1]]) + output = cons.get_spawn_output().replace('\r', '') + assert 'Failures: 0' in output + finally: + # Restart afterward in case a non-VPL test is run next. This should not + # happen since VPL tests are run in their own invocation of test.py, but + # the cost of doing this is not too great at present. + u_boot_console.restart_uboot() diff --git a/test/py/u_boot_console_sandbox.py b/test/py/u_boot_console_sandbox.py index b79ec817957..27c6db8d719 100644 --- a/test/py/u_boot_console_sandbox.py +++ b/test/py/u_boot_console_sandbox.py @@ -44,7 +44,12 @@ class ConsoleSandbox(ConsoleBase):
bcfg = self.config.buildconfig config_spl = bcfg.get('config_spl', 'n') == 'y' - fname = '/spl/u-boot-spl' if config_spl else '/u-boot' + config_vpl = bcfg.get('config_vpl', 'n') == 'y' + if config_vpl: + # Run TPL first, which runs VPL + fname = '/tpl/u-boot-tpl' + else: + fname = '/spl/u-boot-spl' if config_spl else '/u-boot' print(fname) cmd = [] if self.config.gdbserver:

Check the TPL -> VPL -> SPL -> U-Boot path by running the 'help' command in U-Boot.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
test/py/tests/test_help.py | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/test/py/tests/test_help.py b/test/py/tests/test_help.py index 03b9d91c117..153133cf28f 100644 --- a/test/py/tests/test_help.py +++ b/test/py/tests/test_help.py @@ -20,3 +20,15 @@ def test_help_no_devicetree(u_boot_console): finally: # Restart afterward to get the normal device tree back u_boot_console.restart_uboot() + +@pytest.mark.boardspec('sandbox_vpl') +def test_vpl_help(u_boot_console): + try: + cons = u_boot_console + cons.restart_uboot() + cons.run_command('help') + output = cons.get_spawn_output().replace('\r', '') + assert 'print command description/usage' in output + finally: + # Restart afterward to get the normal device tree back + u_boot_console.restart_uboot()

Add tests for VPL into the mix. For now this just runs the help test and a few SPL ones.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
.azure-pipelines.yml | 3 +++ .gitlab-ci.yml | 6 ++++++ 2 files changed, 9 insertions(+)
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 48a587a59ea..4e5c4b785a7 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -245,6 +245,9 @@ stages: sandbox_spl: TEST_PY_BD: "sandbox_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" + sandbox_vpl: + TEST_PY_BD: "sandbox_vpl" + TEST_PY_TEST_SPEC: "test_vpl_help or test_spl" sandbox_noinst: TEST_PY_BD: "sandbox_noinst" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f193ffd3cbc..c6a608f7e2a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -260,6 +260,12 @@ sandbox_noinst_test.py: TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" <<: *buildman_and_testpy_dfn
+sandbox_vpl test.py: + variables: + TEST_PY_BD: "sandbox_vpl" + TEST_PY_TEST_SPEC: "test_vpl_help or test_spl" + <<: *buildman_and_testpy_dfn + evb-ast2500 test.py: variables: TEST_PY_BD: "evb-ast2500"
participants (2)
-
Simon Glass
-
Tom Rini