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.
This commit is contained in:
Tom Rini 2022-05-02 19:02:44 -04:00
commit edb6982b58
44 changed files with 1169 additions and 60 deletions

View file

@ -245,6 +245,9 @@ stages:
sandbox_spl: sandbox_spl:
TEST_PY_BD: "sandbox_spl" TEST_PY_BD: "sandbox_spl"
TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_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: sandbox_noinst:
TEST_PY_BD: "sandbox_noinst" TEST_PY_BD: "sandbox_noinst"
TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl"

View file

@ -260,6 +260,12 @@ sandbox_noinst_test.py:
TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl"
<<: *buildman_and_testpy_dfn <<: *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: evb-ast2500 test.py:
variables: variables:
TEST_PY_BD: "evb-ast2500" TEST_PY_BD: "evb-ast2500"

10
Kconfig
View file

@ -319,6 +319,16 @@ config VALGRIND
it can be handled accurately by Valgrind. If you aren't planning on it can be handled accurately by Valgrind. If you aren't planning on
using valgrind to debug U-Boot, say 'n'. 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 menuconfig EXPERT
bool "Configure standard U-Boot features (expert users)" bool "Configure standard U-Boot features (expert users)"
default y default y

View file

@ -846,7 +846,7 @@ libs-y += drivers/usb/ulpi/
ifdef CONFIG_POST ifdef CONFIG_POST
libs-y += post/ libs-y += post/
endif endif
libs-$(CONFIG_UNIT_TEST) += test/ libs-$(CONFIG_$(SPL_TPL_)UNIT_TEST) += test/
libs-$(CONFIG_UT_ENV) += test/env/ libs-$(CONFIG_UT_ENV) += test/env/
libs-$(CONFIG_UT_OPTEE) += test/optee/ libs-$(CONFIG_UT_OPTEE) += test/optee/
libs-$(CONFIG_UT_OVERLAY) += test/overlay/ libs-$(CONFIG_UT_OVERLAY) += test/overlay/
@ -911,6 +911,12 @@ else
TPL_SIZE_CHECK = TPL_SIZE_CHECK =
endif 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) # Statically apply RELA-style relocations (currently arm64 only)
# This is useful for arm64 where static relocation needs to be performed on # 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 # 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
endif endif
INPUTS-$(CONFIG_TPL) += tpl/u-boot-tpl.bin 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 # 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) 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-dtb.hex: spl/u-boot-spl
@: @:
spl/u-boot-spl: tools prepare \ spl/u-boot-spl: tools prepare $(if $(CONFIG_SPL_OF_CONTROL),dts/dt.dtb)
$(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)
$(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
spl/sunxi-spl.bin: spl/u-boot-spl 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 spl/boot.bin: spl/u-boot-spl
@: @:
tpl/u-boot-tpl.bin: tools prepare \ tpl/u-boot-tpl.bin: tpl/u-boot-tpl
$(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_SIZE_CHECK) $(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) TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include)
FIND := find FIND := find

View file

@ -29,6 +29,14 @@ config SANDBOX_SPL
bool "Enable SPL for sandbox" bool "Enable SPL for sandbox"
select SUPPORT_SPL 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 config SYS_CONFIG_NAME
default "sandbox_spl" if SANDBOX_SPL default "sandbox_spl" if SANDBOX_SPL
default "sandbox" if !SANDBOX_SPL default "sandbox" if !SANDBOX_SPL

View file

@ -32,13 +32,21 @@ int sandbox_find_next_phase(char *fname, int maxlen, bool use_img)
return 0; return 0;
} }
/* SPL / TPL init function */ /* SPL / TPL / VPL init function */
void board_init_f(ulong flag) void board_init_f(ulong flag)
{ {
struct sandbox_state *state = state_get_current(); struct sandbox_state *state = state_get_current();
int ret;
gd->arch.ram_buf = state->ram_buf; gd->arch.ram_buf = state->ram_buf;
gd->ram_size = state->ram_size; 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) u32 spl_boot_device(void)
@ -75,8 +83,6 @@ void spl_board_init(void)
{ {
struct sandbox_state *state = state_get_current(); struct sandbox_state *state = state_get_current();
preloader_console_init();
if (state->run_unittests) { if (state->run_unittests) {
struct unit_test *tests = UNIT_TEST_ALL_START(); struct unit_test *tests = UNIT_TEST_ALL_START();
const int count = UNIT_TEST_ALL_COUNT(); const int count = UNIT_TEST_ALL_COUNT();

View file

@ -254,7 +254,7 @@
}; };
spl-test { spl-test {
u-boot,dm-pre-reloc; u-boot,dm-spl;
compatible = "sandbox,spl-test"; compatible = "sandbox,spl-test";
boolval; boolval;
intval = <1>; intval = <1>;
@ -268,7 +268,7 @@
}; };
spl-test2 { spl-test2 {
u-boot,dm-pre-reloc; u-boot,dm-spl;
compatible = "sandbox,spl-test"; compatible = "sandbox,spl-test";
intval = <3>; intval = <3>;
intarray = <5>; intarray = <5>;
@ -280,14 +280,14 @@
}; };
spl-test3 { spl-test3 {
u-boot,dm-pre-reloc; u-boot,dm-spl;
compatible = "sandbox,spl-test"; compatible = "sandbox,spl-test";
stringarray = "one"; stringarray = "one";
maybe-empty-int = <1>; maybe-empty-int = <1>;
}; };
spl-test5 { spl-test5 {
u-boot,dm-tpl; u-boot,dm-vpl;
compatible = "sandbox,spl-test"; compatible = "sandbox,spl-test";
stringarray = "tpl"; stringarray = "tpl";
}; };
@ -334,6 +334,8 @@
/* Needs to be available prior to relocation */ /* Needs to be available prior to relocation */
uart0: serial { uart0: serial {
u-boot,dm-spl; u-boot,dm-spl;
u-boot,dm-tpl;
u-boot,dm-vpl;
compatible = "sandbox,serial"; compatible = "sandbox,serial";
sandbox,text-colour = "cyan"; sandbox,text-colour = "cyan";
pinctrl-names = "default"; pinctrl-names = "default";

View file

@ -33,3 +33,10 @@ S: Maintained
F: board/sandbox/ F: board/sandbox/
F: include/configs/sandbox.h F: include/configs/sandbox.h
F: configs/sandbox_flattree_defconfig 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

View file

@ -89,6 +89,15 @@ config TPL_LOGLEVEL
int int
default LOGLEVEL 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 config SILENT_CONSOLE
bool "Support a silent console" bool "Support a silent console"
help help
@ -262,6 +271,15 @@ config LOG
if 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 config LOG_MAX_LEVEL
int "Maximum log level to record" int "Maximum log level to record"
default 6 default 6
@ -431,6 +449,47 @@ config TPL_LOG_CONSOLE
endif 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 config LOG_ERROR_RETURN
bool "Log all functions which return an error" bool "Log all functions which return an error"
help help
@ -762,7 +821,7 @@ config BLOBLIST
config SPL_BLOBLIST config SPL_BLOBLIST
bool "Support for a bloblist in SPL" bool "Support for a bloblist in SPL"
depends on BLOBLIST depends on BLOBLIST && SPL_LIBGENERIC_SUPPORT && SPL_LIBCOMMON_SUPPORT
default y if SPL default y if SPL
help help
This enables a bloblist in SPL. If this is the first part of U-Boot 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 config TPL_BLOBLIST
bool "Support for a bloblist in TPL" bool "Support for a bloblist in TPL"
depends on BLOBLIST depends on BLOBLIST && TPL_LIBGENERIC_SUPPORT && TPL_LIBCOMMON_SUPPORT
default y if TPL default y if TPL
help help
This enables a bloblist in TPL. The bloblist is set up in TPL and This enables a bloblist in TPL. The bloblist is set up in TPL and
passed to SPL and U-Boot proper. 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 if BLOBLIST
choice choice

View file

@ -112,7 +112,7 @@ obj-y += s_record.o
obj-$(CONFIG_CMD_LOADB) += xyzModem.o obj-$(CONFIG_CMD_LOADB) += xyzModem.o
obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += 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_$(SPL_TPL_)STACKPROTECTOR) += stackprot.o
obj-$(CONFIG_SCP03) += scp03.o obj-$(CONFIG_SCP03) += scp03.o

View file

@ -1,4 +1,4 @@
menu "SPL / TPL" menu "SPL / TPL / VPL"
config SUPPORT_SPL config SUPPORT_SPL
bool bool
@ -6,6 +6,9 @@ config SUPPORT_SPL
config SUPPORT_TPL config SUPPORT_TPL
bool bool
config SUPPORT_VPL
bool
config SPL_DFU_NO_RESET config SPL_DFU_NO_RESET
bool bool
@ -186,6 +189,13 @@ config SPL_BOARD_INIT
spl_board_init() from board_init_r(). This function should be spl_board_init() from board_init_r(). This function should be
provided by the board. 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 config SPL_BOOTROM_SUPPORT
bool "Support returning to the BOOTROM" bool "Support returning to the BOOTROM"
help help
@ -302,6 +312,16 @@ config SPL_READ_ONLY
writeable memory) of anything it wants to modify, such as writeable memory) of anything it wants to modify, such as
device-private data. 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 config SPL_BANNER_PRINT
bool "Enable output of the SPL banner 'U-Boot SPL ...'" bool "Enable output of the SPL banner 'U-Boot SPL ...'"
default y default y
@ -1619,6 +1639,218 @@ config TPL_YMODEM_SUPPORT
endif # TPL 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 config SPL_AT91_MCK_BYPASS
bool "Use external clock signal as a source of main clock for AT91 platforms" bool "Use external clock signal as a source of main clock for AT91 platforms"
depends on ARCH_AT91 depends on ARCH_AT91

View file

@ -61,6 +61,11 @@ binman_sym_declare(ulong, u_boot_spl, image_pos);
binman_sym_declare(ulong, u_boot_spl, size); binman_sym_declare(ulong, u_boot_spl, size);
#endif #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 */ /* Define board data structure */
static struct bd_info bdata __attribute__ ((section(".data"))); 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) #if CONFIG_IS_ENABLED(BINMAN_SYMBOLS)
ulong spl_get_image_pos(void) 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_spl, image_pos) :
binman_sym(ulong, u_boot_any, image_pos); binman_sym(ulong, u_boot_any, image_pos);
} }
ulong spl_get_image_size(void) 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_spl, size) :
binman_sym(ulong, u_boot_any, 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) 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; 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) if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_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 else
return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL; return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
} }

View file

@ -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

View file

@ -420,6 +420,19 @@ state_setprop() which does this automatically and avoids running out of
space. See existing code for examples. 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 Debugging the init sequence
--------------------------- ---------------------------

View file

@ -25,6 +25,7 @@ Implementation
menus menus
printf printf
smbios smbios
spl
uefi/index uefi/index
version version

View file

@ -20,19 +20,19 @@ u-boot-spl.map.
A config option named CONFIG_SPL_BUILD is enabled by Kconfig for SPL. A config option named CONFIG_SPL_BUILD is enabled by Kconfig for SPL.
Source files can therefore be compiled for SPL with different settings. Source files can therefore be compiled for SPL with different settings.
For example: For example::
ifeq ($(CONFIG_SPL_BUILD),y) ifeq ($(CONFIG_SPL_BUILD),y)
obj-y += board_spl.o obj-y += board_spl.o
else else
obj-y += board.o obj-y += board.o
endif endif
obj-$(CONFIG_SPL_BUILD) += foo.o obj-$(CONFIG_SPL_BUILD) += foo.o
#ifdef CONFIG_SPL_BUILD #ifdef CONFIG_SPL_BUILD
foo(); foo();
#endif #endif
The building of SPL images can be enabled by CONFIG_SPL option in Kconfig. 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_RAM_DEVICE (common/spl/spl.c)
CONFIG_SPL_WATCHDOG (drivers/watchdog/libwatchdog.o) 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 Device tree
----------- -----------
The U-Boot device tree is filtered by the fdtgrep tools during the build 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) process to generate a much smaller device tree used in SPL (spl/u-boot-spl.dtb)
with: with:
- the mandatory nodes (/alias, /chosen, /config) - the mandatory nodes (/alias, /chosen, /config)
- the nodes with one pre-relocation property: - the nodes with one pre-relocation property:
'u-boot,dm-pre-reloc' or 'u-boot,dm-spl' 'u-boot,dm-pre-reloc' or 'u-boot,dm-spl'
fdtgrep is also used to remove: fdtgrep is also used to remove:
- the properties defined in CONFIG_OF_SPL_REMOVE_PROPS - the properties defined in CONFIG_OF_SPL_REMOVE_PROPS
- all the pre-relocation properties - all the pre-relocation properties
('u-boot,dm-pre-reloc', 'u-boot,dm-spl' and 'u-boot,dm-tpl') ('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 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. 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 #. Build normally
2) Perform the following shell command to generate a list of C files used in #. Perform the following shell command to generate a list of C files used in
SPL: SPL:
$ find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list #. `find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list`
3) Execute cflow: #. Execute cflow:
$ cflow --main=board_init_r `cat used-spl.list` 2>&1 | $PAGER `$ 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 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' the config files and picks functions based on #ifdef. Parsing the '.i'

View file

@ -38,6 +38,7 @@ obj-$(CONFIG_XEN) += xen/
obj-$(CONFIG_$(SPL_)FPGA) += fpga/ obj-$(CONFIG_$(SPL_)FPGA) += fpga/
ifndef CONFIG_TPL_BUILD ifndef CONFIG_TPL_BUILD
ifndef CONFIG_VPL_BUILD
ifdef CONFIG_SPL_BUILD ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_CPU) += cpu/ obj-$(CONFIG_SPL_CPU) += cpu/
@ -60,6 +61,7 @@ obj-$(CONFIG_SPL_SATA) += ata/ scsi/
obj-$(CONFIG_HAVE_BLOCK_DEVICE) += block/ obj-$(CONFIG_HAVE_BLOCK_DEVICE) += block/
obj-$(CONFIG_SPL_THERMAL) += thermal/ obj-$(CONFIG_SPL_THERMAL) += thermal/
endif
endif endif
endif endif

View file

@ -39,6 +39,18 @@ config TPL_BLK
be partitioned into several areas, called 'partitions' in U-Boot. be partitioned into several areas, called 'partitions' in U-Boot.
A filesystem can be placed in each partition. 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 config BLOCK_CACHE
bool "Use block device cache" bool "Use block device cache"
depends on BLK depends on BLK

View file

@ -30,6 +30,32 @@ config TPL_CLK
setting up clocks within TPL, and allows the same drivers to be setting up clocks within TPL, and allows the same drivers to be
used as U-Boot proper. 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 config SPL_CLK_CCF
bool "SPL Common Clock Framework [CCF] support " bool "SPL Common Clock Framework [CCF] support "
depends on SPL depends on SPL

View file

@ -35,6 +35,16 @@ config TPL_DM
CONFIG_SPL_SYS_MALLOC_F_LEN for more details on how to enable it. CONFIG_SPL_SYS_MALLOC_F_LEN for more details on how to enable it.
Disable this for very small implementations. 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 config DM_WARN
bool "Enable warnings in driver model" bool "Enable warnings in driver model"
depends on DM depends on DM
@ -121,6 +131,15 @@ config SPL_DM_SEQ_ALIAS
numbered devices (e.g. serial0 = &serial0). This feature can be numbered devices (e.g. serial0 = &serial0). This feature can be
disabled if it is not required, to save code space in SPL. 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 config SPL_DM_INLINE_OFNODE
bool "Inline some ofnode functions which are seldom used in SPL" bool "Inline some ofnode functions which are seldom used in SPL"
depends on SPL_DM depends on SPL_DM
@ -176,6 +195,16 @@ config TPL_REGMAP
support any bus type (I2C, SPI) but so far this only supports support any bus type (I2C, SPI) but so far this only supports
direct memory access. 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 config SYSCON
bool "Support system controllers" bool "Support system controllers"
depends on REGMAP depends on REGMAP
@ -196,7 +225,16 @@ config SPL_SYSCON
config TPL_SYSCON config TPL_SYSCON
bool "Support system controllers in TPL" 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 help
Many SoCs have a number of system controllers which are dealt with Many SoCs have a number of system controllers which are dealt with
as a group by a single driver. Some common functionality is provided 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 used for the address translation. This function is faster and
smaller in size than fdt_translate_address(). 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 config TRANSLATION_OFFSET
bool "Platforms specific translation offset" bool "Platforms specific translation offset"
depends on DM && OF_CONTROL depends on DM && OF_CONTROL

View file

@ -5,7 +5,7 @@
obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o tag.o 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_)ACPIGEN) += acpi.o
obj-$(CONFIG_$(SPL_TPL_)DEVRES) += devres.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_$(SPL_)SIMPLE_BUS) += simple-bus.o
obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
obj-$(CONFIG_DM) += dump.o obj-$(CONFIG_DM) += dump.o

View file

@ -48,6 +48,17 @@ config TPL_DM_GPIO
particular GPIOs that they provide. The uclass interface particular GPIOs that they provide. The uclass interface
is defined in include/asm-generic/gpio.h. 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 config GPIO_HOG
bool "Enable GPIO hog support" bool "Enable GPIO hog support"
depends on DM_GPIO depends on DM_GPIO

View file

@ -47,6 +47,17 @@ config SPL_DM_I2C
device (bus child) info is kept as parent platdata. The interface device (bus child) info is kept as parent platdata. The interface
is defined in include/i2c.h. 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 config SYS_I2C_LEGACY
bool "Enable legacy I2C subsystem and drivers" bool "Enable legacy I2C subsystem and drivers"
depends on !DM_I2C depends on !DM_I2C

View file

@ -131,6 +131,16 @@ config TPL_CROS_EC
control access to the battery and main PMIC depending on the control access to the battery and main PMIC depending on the
device. You can use the 'crosec' command to access it. 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 config CROS_EC_I2C
bool "Enable Chrome OS EC I2C driver" bool "Enable Chrome OS EC I2C driver"
depends on CROS_EC depends on CROS_EC
@ -167,6 +177,15 @@ config TPL_CROS_EC_LPC
through a legacy port interface, so on x86 machines the main through a legacy port interface, so on x86 machines the main
function of the EC is power and thermal management. 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 config CROS_EC_SANDBOX
bool "Enable Chrome OS EC sandbox driver" bool "Enable Chrome OS EC sandbox driver"
depends on CROS_EC && SANDBOX 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 EC flash read/write/erase support and a few other things. It is
enough to perform a Chrome OS verified boot on sandbox. 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 config CROS_EC_SPI
bool "Enable Chrome OS EC SPI driver" bool "Enable Chrome OS EC SPI driver"
depends on CROS_EC depends on CROS_EC

View file

@ -89,20 +89,34 @@ config TPL_PINCTRL
This option is an TPL variant of the PINCTRL option. This option is an TPL variant of the PINCTRL option.
See the help of PINCTRL for details. 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 config SPL_PINCTRL_FULL
bool "Support full pin controllers in SPL" bool "Support full pin controllers in SPL"
depends on SPL_PINCTRL && SPL_OF_CONTROL depends on SPL_PINCTRL && SPL_OF_CONTROL
default n if TARGET_STM32F746_DISCO default n if TARGET_STM32F746_DISCO
default y default y
help 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. See the help of PINCTRL_FULL for details.
config TPL_PINCTRL_FULL config TPL_PINCTRL_FULL
bool "Support full pin controllers in TPL" bool "Support full pin controllers in TPL"
depends on TPL_PINCTRL && TPL_OF_CONTROL depends on TPL_PINCTRL && TPL_OF_CONTROL
help 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. See the help of PINCTRL_FULL for details.
config SPL_PINCTRL_GENERIC config SPL_PINCTRL_GENERIC

View file

@ -32,6 +32,15 @@ config TPL_DM_RTC
drivers to perform the actual functions. See rtc.h for a drivers to perform the actual functions. See rtc.h for a
description of the API. 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 config RTC_ENABLE_32KHZ_OUTPUT
bool "Enable RTC 32Khz output" bool "Enable RTC 32Khz output"
help help

View file

@ -74,6 +74,16 @@ config TPL_SERIAL_PRESENT
This option enables the full UART in TPL, so if is it disabled, This option enables the full UART in TPL, so if is it disabled,
the full UART driver will be omitted, thus saving space. 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 # Logic to allow us to use the imply keyword to set what the default port
# should be. The default is otherwise 1. # should be. The default is otherwise 1.
config CONS_INDEX_0 config CONS_INDEX_0
@ -195,6 +205,16 @@ config TPL_DM_SERIAL
implements serial_putc() etc. The uclass interface is implements serial_putc() etc. The uclass interface is
defined in include/serial.h. 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 config DEBUG_UART
bool "Enable an early debug UART for debugging" bool "Enable an early debug UART for debugging"
help help

View file

@ -31,6 +31,16 @@ config TPL_SYSRESET
to effect a reset. The uclass will try all available drivers when to effect a reset. The uclass will try all available drivers when
reset_walk() is called. 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 if SYSRESET
config SYSRESET_CMD_RESET config SYSRESET_CMD_RESET

View file

@ -27,6 +27,16 @@ config TPL_TIMER
function. This enables the drivers in drivers/timer as part of an function. This enables the drivers in drivers/timer as part of an
TPL build. 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 config TIMER_EARLY
bool "Allow timer to be used early in U-Boot" bool "Allow timer to be used early in U-Boot"
depends on TIMER depends on TIMER

View file

@ -137,6 +137,36 @@ config TPM2_CR50_I2C
trust for a device, It operates like a TPM and can be used with trust for a device, It operates like a TPM and can be used with
verified boot. Cr50 is used on recent Chromebooks (since 2017). 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 config TPM2_TIS_SANDBOX
bool "Enable sandbox TPMv2.x driver" bool "Enable sandbox TPMv2.x driver"
depends on TPM_V2 && SANDBOX depends on TPM_V2 && SANDBOX

View file

@ -65,6 +65,15 @@ config TPL_OF_CONTROL
which is not enough to support device tree. Enable this option to which is not enough to support device tree. Enable this option to
allow such boards to be supported by U-Boot TPL. 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 config OF_LIVE
bool "Enable use of a live tree" bool "Enable use of a live tree"
depends on DM && OF_CONTROL depends on DM && OF_CONTROL
@ -523,4 +532,12 @@ config TPL_OF_PLATDATA_DRIVER_RT
endif 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 endmenu

View file

@ -176,6 +176,8 @@ enum bootstage_id {
BOOTSTAGE_ID_END_TPL, BOOTSTAGE_ID_END_TPL,
BOOTSTAGE_ID_START_SPL, BOOTSTAGE_ID_START_SPL,
BOOTSTAGE_ID_END_SPL, BOOTSTAGE_ID_END_SPL,
BOOTSTAGE_ID_START_VPL,
BOOTSTAGE_ID_END_VPL,
BOOTSTAGE_ID_START_UBOOT_F, BOOTSTAGE_ID_START_UBOOT_F,
BOOTSTAGE_ID_START_UBOOT_R, BOOTSTAGE_ID_START_UBOOT_R,
BOOTSTAGE_ID_USB_START, BOOTSTAGE_ID_USB_START,

View file

@ -38,6 +38,8 @@
#define _CONFIG_PREFIX TOOLS_ #define _CONFIG_PREFIX TOOLS_
#elif defined(CONFIG_TPL_BUILD) #elif defined(CONFIG_TPL_BUILD)
#define _CONFIG_PREFIX TPL_ #define _CONFIG_PREFIX TPL_
#elif defined(CONFIG_VPL_BUILD)
#define _CONFIG_PREFIX VPL_
#elif defined(CONFIG_SPL_BUILD) #elif defined(CONFIG_SPL_BUILD)
#define _CONFIG_PREFIX SPL_ #define _CONFIG_PREFIX SPL_
#else #else
@ -54,6 +56,7 @@
* CONFIG_FOO if CONFIG_SPL_BUILD is undefined, * CONFIG_FOO if CONFIG_SPL_BUILD is undefined,
* CONFIG_SPL_FOO if CONFIG_SPL_BUILD is defined. * CONFIG_SPL_FOO if CONFIG_SPL_BUILD is defined.
* CONFIG_TPL_FOO if CONFIG_TPL_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) #define CONFIG_VAL(option) config_val(option)

View file

@ -62,6 +62,7 @@ static inline bool u_boot_first_phase(void)
enum u_boot_phase { enum u_boot_phase {
PHASE_NONE, /* Invalid phase, signifying before U-Boot */ PHASE_NONE, /* Invalid phase, signifying before U-Boot */
PHASE_TPL, /* Running in TPL */ PHASE_TPL, /* Running in TPL */
PHASE_VPL, /* Running in VPL */
PHASE_SPL, /* Running in SPL */ PHASE_SPL, /* Running in SPL */
PHASE_BOARD_F, /* Running in U-Boot before relocation */ PHASE_BOARD_F, /* Running in U-Boot before relocation */
PHASE_BOARD_R, /* Running in U-Boot after 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 #ifdef CONFIG_TPL_BUILD
return PHASE_TPL; return PHASE_TPL;
#elif CONFIG_SPL_BUILD #elif defined(CONFIG_VPL_BUILD)
return PHASE_VPL;
#elif defined(CONFIG_SPL_BUILD)
return PHASE_SPL; return PHASE_SPL;
#else #else
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -136,10 +139,15 @@ static inline enum u_boot_phase spl_prev_phase(void)
{ {
#ifdef CONFIG_TPL_BUILD #ifdef CONFIG_TPL_BUILD
return PHASE_NONE; return PHASE_NONE;
#elif defined(CONFIG_VPL_BUILD)
return PHASE_TPL; /* VPL requires TPL */
#elif defined(CONFIG_SPL_BUILD) #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 #else
return IS_ENABLED(CONFIG_SPL) ? PHASE_SPL : PHASE_NONE; return IS_ENABLED(CONFIG_SPL) ? PHASE_SPL :
PHASE_NONE;
#endif #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) static inline enum u_boot_phase spl_next_phase(void)
{ {
#ifdef CONFIG_TPL_BUILD #ifdef CONFIG_TPL_BUILD
return IS_ENABLED(CONFIG_VPL) ? PHASE_VPL : PHASE_SPL;
#elif defined(CONFIG_VPL_BUILD)
return PHASE_SPL; return PHASE_SPL;
#else #else
return PHASE_BOARD_F; return PHASE_BOARD_F;
@ -168,6 +178,8 @@ static inline const char *spl_phase_name(enum u_boot_phase phase)
switch (phase) { switch (phase) {
case PHASE_TPL: case PHASE_TPL:
return "TPL"; return "TPL";
case PHASE_VPL:
return "VPL";
case PHASE_SPL: case PHASE_SPL:
return "SPL"; return "SPL";
case PHASE_BOARD_F: case PHASE_BOARD_F:
@ -189,6 +201,8 @@ static inline const char *spl_phase_prefix(enum u_boot_phase phase)
switch (phase) { switch (phase) {
case PHASE_TPL: case PHASE_TPL:
return "tpl"; return "tpl";
case PHASE_VPL:
return "vpl";
case PHASE_SPL: case PHASE_SPL:
return "spl"; return "spl";
case PHASE_BOARD_F: 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_SPL_BUILD
# ifdef CONFIG_TPL_BUILD # ifdef CONFIG_TPL_BUILD
# define SPL_TPL_NAME "TPL" # define SPL_TPL_NAME "TPL"
# elif defined(CONFIG_VPL_BUILD)
# define SPL_TPL_NAME "VPL"
# else # else
# define SPL_TPL_NAME "SPL" # define SPL_TPL_NAME "SPL"
# endif # endif

View file

@ -90,6 +90,11 @@ config TPL_PRINTF
select TPL_SPRINTF select TPL_SPRINTF
select TPL_STRTO if !TPL_USE_TINY_PRINTF 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 config SPRINTF
bool bool
default y default y
@ -100,6 +105,9 @@ config SPL_SPRINTF
config TPL_SPRINTF config TPL_SPRINTF
bool bool
config VPL_SPRINTF
bool
config SSCANF config SSCANF
bool bool
@ -113,6 +121,9 @@ config SPL_STRTO
config TPL_STRTO config TPL_STRTO
bool bool
config VPL_STRTO
bool
config IMAGE_SPARSE config IMAGE_SPARSE
bool bool
@ -165,6 +176,17 @@ config TPL_USE_TINY_PRINTF
The supported format specifiers are %c, %s, %u/%d and %x. 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 config PANIC_HANG
bool "Do not reset the system on fatal error" bool "Do not reset the system on fatal error"
help help
@ -371,6 +393,17 @@ config TPL_TPM
for the low-level TPM interface, but only one TPM is supported at for the low-level TPM interface, but only one TPM is supported at
a time by the TPM library. 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 endmenu
menu "Android Verified Boot" menu "Android Verified Boot"
@ -625,6 +658,12 @@ config SPL_LZMA
help help
This enables support for LZMA compression algorithm for SPL boot. 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 config SPL_LZO
bool "Enable LZO decompression support in SPL" bool "Enable LZO decompression support in SPL"
help help
@ -704,6 +743,7 @@ config OF_LIBFDT_OVERLAY
config SPL_OF_LIBFDT config SPL_OF_LIBFDT
bool "Enable the FDT library for SPL" bool "Enable the FDT library for SPL"
depends on SPL_LIBGENERIC_SUPPORT
default y if SPL_OF_CONTROL default y if SPL_OF_CONTROL
help help
This enables the FDT library (libfdt). It provides functions for This enables the FDT library (libfdt). It provides functions for
@ -725,6 +765,7 @@ config SPL_OF_LIBFDT_ASSUME_MASK
config TPL_OF_LIBFDT config TPL_OF_LIBFDT
bool "Enable the FDT library for TPL" bool "Enable the FDT library for TPL"
depends on TPL_LIBGENERIC_SUPPORT
default y if TPL_OF_CONTROL default y if TPL_OF_CONTROL
help help
This enables the FDT library (libfdt). It provides functions for 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 0xff means all assumptions are made and any invalid data may cause
unsafe execution. See FDT_ASSUME_PERFECT, etc. in libfdt_internal.h 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 config FDT_FIXUP_PARTITIONS
bool "overwrite MTD partitions in DTS through defined in 'mtdparts'" bool "overwrite MTD partitions in DTS through defined in 'mtdparts'"
depends on OF_LIBFDT depends on OF_LIBFDT

View file

@ -322,11 +322,15 @@ endif
ifdef CONFIG_SPL_BUILD ifdef CONFIG_SPL_BUILD
SPL_ := SPL_ SPL_ := SPL_
ifeq ($(CONFIG_VPL_BUILD),y)
SPL_TPL_ := VPL_
else
ifeq ($(CONFIG_TPL_BUILD),y) ifeq ($(CONFIG_TPL_BUILD),y)
SPL_TPL_ := TPL_ SPL_TPL_ := TPL_
else else
SPL_TPL_ := SPL_ SPL_TPL_ := SPL_
endif endif
endif
else else
SPL_ := SPL_ :=
SPL_TPL_ := SPL_TPL_ :=

View file

@ -18,6 +18,10 @@ ifeq ($(shell grep -q '^CONFIG_TPL=y' include/config/auto.conf 2>/dev/null && ec
__all: tpl/include/autoconf.mk __all: tpl/include/autoconf.mk
endif 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 include/config/auto.conf
include scripts/Kbuild.include include scripts/Kbuild.include
@ -85,6 +89,10 @@ tpl/u-boot.cfg: include/config.h FORCE
$(Q)mkdir -p $(dir $@) $(Q)mkdir -p $(dir $@)
$(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD -DCONFIG_TPL_BUILD) $(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 include/autoconf.mk: u-boot.cfg
$(call cmd,autoconf) $(call cmd,autoconf)
@ -96,6 +104,10 @@ tpl/include/autoconf.mk: tpl/u-boot.cfg
$(Q)mkdir -p $(dir $@) $(Q)mkdir -p $(dir $@)
$(call cmd,autoconf) $(call cmd,autoconf)
vpl/include/autoconf.mk: vpl/u-boot.cfg
$(Q)mkdir -p $(dir $@)
$(call cmd,autoconf)
# include/config.h # include/config.h
# Prior to Kconfig, it was generated by mkconfig. Now it is created here. # Prior to Kconfig, it was generated by mkconfig. Now it is created here.
define filechk_config_h define filechk_config_h

View file

@ -4,6 +4,9 @@
# ========================================================================== # ==========================================================================
# Modified for U-Boot # Modified for U-Boot
prefix := vpl
src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src))
prefix := tpl prefix := tpl
src := $(patsubst $(prefix)/%,%,$(obj)) src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src)) ifeq ($(obj),$(src))
@ -13,6 +16,7 @@ ifeq ($(obj),$(src))
prefix := . prefix := .
endif endif
endif endif
endif
PHONY := __build PHONY := __build
__build: __build:

View file

@ -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 # 'u-boot,dm-pre-reloc' property and thus are not needed by SPL. The second
# pass removes various unused properties from the remaining nodes. # pass removes various unused properties from the remaining nodes.
# The output is typically a much smaller device tree file. # 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) ifeq ($(CONFIG_TPL_BUILD),y)
fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-tpl fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-tpl
else else
fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-spl fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-spl
endif endif
endif
quiet_cmd_fdtgrep = FDTGREP $@ quiet_cmd_fdtgrep = FDTGREP $@
cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \ cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \
-n /chosen -n /config -O dtb | \ -n /chosen -n /config -O dtb | \
$(objtree)/tools/fdtgrep -r -O dtb - -o $@ \ $(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-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))) $(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS)))
# fdt_rm_props # fdt_rm_props

View file

@ -27,8 +27,16 @@ UBOOTINCLUDE := -I$(obj)/include $(UBOOTINCLUDE)
KBUILD_CPPFLAGS += -DCONFIG_SPL_BUILD KBUILD_CPPFLAGS += -DCONFIG_SPL_BUILD
ifeq ($(CONFIG_TPL_BUILD),y) ifeq ($(CONFIG_TPL_BUILD),y)
KBUILD_CPPFLAGS += -DCONFIG_TPL_BUILD KBUILD_CPPFLAGS += -DCONFIG_TPL_BUILD
else
ifeq ($(CONFIG_VPL_BUILD),y)
KBUILD_CPPFLAGS += -DCONFIG_VPL_BUILD
endif
endif endif
ifeq ($(CONFIG_VPL_BUILD),y)
SPL_BIN := u-boot-vpl
SPL_NAME := vpl
else
ifeq ($(CONFIG_TPL_BUILD),y) ifeq ($(CONFIG_TPL_BUILD),y)
SPL_BIN := u-boot-tpl SPL_BIN := u-boot-tpl
SPL_NAME := tpl SPL_NAME := tpl
@ -36,16 +44,21 @@ else
SPL_BIN := u-boot-spl SPL_BIN := u-boot-spl
SPL_NAME := spl SPL_NAME := spl
endif endif
endif
export SPL_NAME export SPL_NAME
ifdef CONFIG_SPL_BUILD ifdef CONFIG_SPL_BUILD
SPL_ := SPL_ SPL_ := SPL_
ifeq ($(CONFIG_VPL_BUILD),y)
SPL_TPL_ := VPL_
else
ifeq ($(CONFIG_TPL_BUILD),y) ifeq ($(CONFIG_TPL_BUILD),y)
SPL_TPL_ := TPL_ SPL_TPL_ := TPL_
else else
SPL_TPL_ := SPL_ SPL_TPL_ := SPL_
endif endif
endif
else else
SPL_ := SPL_ :=
SPL_TPL_ := SPL_TPL_ :=
@ -57,6 +70,9 @@ endif
ifeq ($(obj)$(CONFIG_SUPPORT_TPL),tpl) ifeq ($(obj)$(CONFIG_SUPPORT_TPL),tpl)
$(error You cannot build TPL without enabling CONFIG_SUPPORT_TPL) $(error You cannot build TPL without enabling CONFIG_SUPPORT_TPL)
endif endif
ifeq ($(obj)$(CONFIG_SUPPORT_VPL),vpl)
$(error You cannot build VPL without enabling CONFIG_SUPPORT_VPL)
endif
include $(srctree)/config.mk include $(srctree)/config.mk
include $(srctree)/arch/$(ARCH)/Makefile include $(srctree)/arch/$(ARCH)/Makefile
@ -90,17 +106,12 @@ libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
endif endif
libs-y += common/init/ libs-y += common/init/
# Special handling for a few options which support SPL/TPL # Special handling for a few options which support SPL/TPL/VPL
ifeq ($(CONFIG_TPL_BUILD),y) libs-$(CONFIG_$(SPL_TPL_)LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
libs-$(CONFIG_TPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/ libs-$(CONFIG_$(SPL_TPL_)LIBGENERIC_SUPPORT) += lib/
libs-$(CONFIG_TPL_LIBGENERIC_SUPPORT) += lib/
else
libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
ifdef CONFIG_SPL_FRAMEWORK ifdef CONFIG_SPL_FRAMEWORK
libs-$(CONFIG_PARTITIONS) += disk/ libs-$(CONFIG_PARTITIONS) += disk/
endif endif
endif
libs-y += drivers/ libs-y += drivers/
libs-$(CONFIG_SPL_USB_GADGET) += drivers/usb/dwc3/ libs-$(CONFIG_SPL_USB_GADGET) += drivers/usb/dwc3/
@ -109,7 +120,7 @@ libs-y += dts/
libs-y += fs/ libs-y += fs/
libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/ libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/
libs-$(CONFIG_SPL_NET) += net/ libs-$(CONFIG_SPL_NET) += net/
libs-$(CONFIG_SPL_UNIT_TEST) += test/ libs-$(CONFIG_$(SPL_TPL_)UNIT_TEST) += test/
head-y := $(addprefix $(obj)/,$(head-y)) head-y := $(addprefix $(obj)/,$(head-y))
libs-y := $(addprefix $(obj)/,$(libs-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') 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 # 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),) ifneq ($(CONFIG_$(SPL_TPL_)MAX_SIZE),)
LDPPFLAGS += -DIMAGE_MAX_SIZE=$(CONFIG_$(SPL_TPL_)MAX_SIZE) LDPPFLAGS += -DIMAGE_MAX_SIZE=$(CONFIG_$(SPL_TPL_)MAX_SIZE)
endif endif
@ -264,6 +275,7 @@ ifeq ($(CONFIG_SYS_SOC),"at91")
INPUTS-y += $(obj)/boot.bin INPUTS-y += $(obj)/boot.bin
endif endif
ifndef CONFIG_VPL_BUILD
ifdef CONFIG_TPL_BUILD ifdef CONFIG_TPL_BUILD
INPUTS-$(CONFIG_TPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-tpl.bin \ INPUTS-$(CONFIG_TPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-tpl.bin \
$(obj)/u-boot-x86-reset16-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 \ INPUTS-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-spl.bin \
$(obj)/u-boot-x86-reset16-spl.bin $(obj)/u-boot-x86-reset16-spl.bin
endif endif
endif
INPUTS-$(CONFIG_ARCH_ZYNQ) += $(obj)/boot.bin INPUTS-$(CONFIG_ARCH_ZYNQ) += $(obj)/boot.bin
INPUTS-$(CONFIG_ARCH_ZYNQMP) += $(obj)/boot.bin INPUTS-$(CONFIG_ARCH_ZYNQMP) += $(obj)/boot.bin
@ -307,7 +320,7 @@ endif
ifneq ($(build_dtb),) ifneq ($(build_dtb),)
$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin \ $(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 $(FINAL_DTB_CONTAINER) FORCE
$(call if_changed,cat) $(call if_changed,cat)
@ -398,7 +411,7 @@ LDFLAGS_$(SPL_BIN) += $(call ld-option, --no-dynamic-linker)
LDFLAGS_$(SPL_BIN) += --build-id=none 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),) ifneq ($(CONFIG_$(SPL_TPL_)TEXT_BASE),)
LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_$(SPL_TPL_)TEXT_BASE) LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_$(SPL_TPL_)TEXT_BASE)
endif endif

View file

@ -322,8 +322,11 @@ def pytest_generate_tests(metafunc):
if fn == 'ut_subtest': if fn == 'ut_subtest':
generate_ut_subtest(metafunc, fn, '/u-boot.sym') generate_ut_subtest(metafunc, fn, '/u-boot.sym')
continue continue
if fn == 'ut_spl_subtest': m_subtest = re.match('ut_(.)pl_subtest', fn)
generate_ut_subtest(metafunc, fn, '/spl/u-boot-spl.sym') 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 continue
generate_config(metafunc, fn) generate_config(metafunc, fn)

View file

@ -2,7 +2,21 @@
# Copyright (c) 2015 Stephen Warren # Copyright (c) 2015 Stephen Warren
# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
import pytest
def test_help(u_boot_console): def test_help(u_boot_console):
"""Test that the "help" command can be executed.""" """Test that the "help" command can be executed."""
u_boot_console.run_command('help') 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()

34
test/py/tests/test_vpl.py Normal file
View file

@ -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()

View file

@ -43,7 +43,12 @@ class ConsoleSandbox(ConsoleBase):
bcfg = self.config.buildconfig bcfg = self.config.buildconfig
config_spl = bcfg.get('config_spl', 'n') == 'y' 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) print(fname)
cmd = [] cmd = []
if self.config.gdbserver: if self.config.gdbserver: