summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-05-02 19:02:44 -0400
committerTom Rini <trini@konsulko.com>2022-05-02 19:02:44 -0400
commitedb6982b5800603a67ff3710ef074ff7ac86e5ea (patch)
treefc34fe0a38d6f3884c60993ce06fb0f58536d60a
parent2406a91734eb4eeeb50fdfaeff65d0b7f464dba9 (diff)
parenta31eff3015afc80429e2734781eaf52e48ab6663 (diff)
Merge branch '2022-05-02-add-verifying-program-loader'
To quote the author: 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.
-rw-r--r--.azure-pipelines.yml3
-rw-r--r--.gitlab-ci.yml6
-rw-r--r--Kconfig10
-rw-r--r--Makefile28
-rw-r--r--arch/sandbox/Kconfig8
-rw-r--r--arch/sandbox/cpu/spl.c12
-rw-r--r--arch/sandbox/dts/sandbox.dtsi10
-rw-r--r--board/sandbox/MAINTAINERS7
-rw-r--r--common/Kconfig71
-rw-r--r--common/Makefile2
-rw-r--r--common/spl/Kconfig234
-rw-r--r--common/spl/spl.c25
-rw-r--r--configs/sandbox_vpl_defconfig251
-rw-r--r--doc/arch/sandbox.rst13
-rw-r--r--doc/develop/index.rst1
-rw-r--r--doc/develop/spl.rst (renamed from doc/README.SPL)75
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/block/Kconfig12
-rw-r--r--drivers/clk/Kconfig26
-rw-r--r--drivers/core/Kconfig54
-rw-r--r--drivers/core/Makefile2
-rw-r--r--drivers/gpio/Kconfig11
-rw-r--r--drivers/i2c/Kconfig11
-rw-r--r--drivers/misc/Kconfig28
-rw-r--r--drivers/pinctrl/Kconfig18
-rw-r--r--drivers/rtc/Kconfig9
-rw-r--r--drivers/serial/Kconfig20
-rw-r--r--drivers/sysreset/Kconfig10
-rw-r--r--drivers/timer/Kconfig10
-rw-r--r--drivers/tpm/Kconfig30
-rw-r--r--dts/Kconfig17
-rw-r--r--include/bootstage.h2
-rw-r--r--include/linux/kconfig.h3
-rw-r--r--include/spl.h22
-rw-r--r--lib/Kconfig62
-rw-r--r--scripts/Kbuild.include4
-rw-r--r--scripts/Makefile.autoconf12
-rw-r--r--scripts/Makefile.build4
-rw-r--r--scripts/Makefile.lib5
-rw-r--r--scripts/Makefile.spl37
-rw-r--r--test/py/conftest.py7
-rw-r--r--test/py/tests/test_help.py14
-rw-r--r--test/py/tests/test_vpl.py34
-rw-r--r--test/py/u_boot_console_sandbox.py7
44 files changed, 1169 insertions, 60 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 48a587a59e..4e5c4b785a 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 f193ffd3cb..c6a608f7e2 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"
diff --git a/Kconfig b/Kconfig
index bdae59e06f..8bbb988790 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/Makefile b/Makefile
index ccc87c3a5c..ea80f00716 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/
@@ -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)
@@ -2095,9 +2102,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,11 +2117,20 @@ 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)
- $(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
+
+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/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 477c51960d..5f55c7f28e 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 3f107b8acb..fe5d44d36e 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 29306ac04d..aa22b8765c 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 d32561cd1d..9f5073bf28 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/common/Kconfig b/common/Kconfig
index 8f8a9064d5..a96842a5c1 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
@@ -762,7 +821,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,12 +830,20 @@ 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
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/Makefile b/common/Makefile
index cc2ba30c63..75c24e3249 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
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index ac61b25a06..84f2847c72 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
@@ -186,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
@@ -302,6 +312,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
@@ -1619,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/common/spl/spl.c b/common/spl/spl.c
index c9750ee163..c8c463f80b 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/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig
new file mode 100644
index 0000000000..2cc16233cf
--- /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 e1119492b4..bc670b98b7 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
---------------------------
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index d32ec49022..fe3564a9fb 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
index 011fd42537..aec7b562fa 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.
@@ -66,16 +66,57 @@ 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 (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
+ 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
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 +139,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'
diff --git a/drivers/Makefile b/drivers/Makefile
index 4e7cf28440..67c8af7442 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/
@@ -62,6 +63,7 @@ obj-$(CONFIG_SPL_THERMAL) += thermal/
endif
endif
+endif
ifdef CONFIG_TPL_BUILD
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index c54b58110c..d6d1c6e32c 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 6dc271f71b..a62b81a123 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 5c3400417f..408a8d8e28 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 7099073a53..bce0a3f65c 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 89068c7800..886cdbcdba 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 5482a4a470..d25c5736ef 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 dab7a99c68..9af806a20a 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 13033198f9..563d96d4f5 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 7a6c6efb4b..2396327192 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 1e595d0600..5dcf5c019d 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 25dd02c704..a0acffa4b0 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 92050179c2..2eda3bcca5 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 406ee8716e..eceff27d5f 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 b19912d10d..f1d05cc080 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/include/bootstage.h b/include/bootstage.h
index 99a334ad54..bca9438418 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 d20da615b9..2bc704e110 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 6134aba857..83ac583e0b 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/lib/Kconfig b/lib/Kconfig
index 858be14f09..e2697ab2ce 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
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 09506cb9a7..9c14310ad4 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 0b3ffa08bf..3fa4d50f1e 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 5df8f61aa5..3b8c9d8c31 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 2ff39d39dc..3db2550085 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 6ad82cecfb..f047d4e094 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/
@@ -109,7 +120,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))
@@ -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
diff --git a/test/py/conftest.py b/test/py/conftest.py
index 16e445cd8e..2ba34479e0 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_help.py b/test/py/tests/test_help.py
index d50295e5bd..bac0a29f5a 100644
--- a/test/py/tests/test_help.py
+++ b/test/py/tests/test_help.py
@@ -2,7 +2,21 @@
# Copyright (c) 2015 Stephen Warren
# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+import pytest
+
def test_help(u_boot_console):
"""Test that the "help" command can be executed."""
u_boot_console.run_command('help')
+
+@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()
diff --git a/test/py/tests/test_vpl.py b/test/py/tests/test_vpl.py
new file mode 100644
index 0000000000..4af578b917
--- /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 ce4ca7e55e..cef416d738 100644
--- a/test/py/u_boot_console_sandbox.py
+++ b/test/py/u_boot_console_sandbox.py
@@ -43,7 +43,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: