select SPL_HASH
select SPL_OF_LIBFDT
+config VPL_FIT
+ bool "Support Flattened Image Tree within VPL"
+ depends on VPL
+ select VPL_HASH
+ select VPL_OF_LIBFDT
+
+config TPL_FIT
+ bool "Support Flattened Image Tree within TPL"
+ depends on TPL
+ select TPL_HASH
+ select TPL_OF_LIBFDT
+
config SPL_FIT_PRINT
bool "Support FIT printing within SPL"
depends on SPL_FIT
particular it can handle selecting from multiple device tree
and passing the correct one to U-Boot.
+config TPL_LOAD_FIT
+ bool "Enable TPL loading U-Boot as a FIT (basic fitImage features)"
+ depends on TPL
+ select TPL_FIT
+ help
+ Normally with the SPL framework a legacy image is generated as part
+ of the build. This contains U-Boot along with information as to
+ where it should be loaded. This option instead enables generation
+ of a FIT (Flat Image Tree) which provides more flexibility. In
+ particular it can handle selecting from multiple device tree
+ and passing the correct one to U-Boot.
+
+ This path has the following limitations:
+
+ 1. "loadables" images, other than FDTs, which do not have a "load"
+ property will not be loaded. This limitation also applies to FPGA
+ images with the correct "compatible" string.
+ 2. For FPGA images, the supported "compatible" list is in the
+ doc/uImage.FIT/source_file_format.txt.
+ 3. FDTs are only loaded for images with an "os" property of "u-boot".
+ "linux" images are also supported with Falcon boot mode.
+
config SPL_FIT_IMAGE_POST_PROCESS
bool "Enable post-processing of FIT artifacts after loading by the SPL"
depends on SPL_LOAD_FIT
select VPL_HASH
select VPL_OF_LIBFDT
+config VPL_LOAD_FIT
+ bool "Enable VPL loading U-Boot as a FIT (basic fitImage features)"
+ select VPL_FIT
+ default y
+
+config VPL_LOAD_FIT_FULL
+ bool "Enable SPL loading U-Boot as a FIT (full fitImage features)"
+ select VPL_FIT
+ help
+ Normally with the SPL framework a legacy image is generated as part
+ of the build. This contains U-Boot along with information as to
+ where it should be loaded. This option instead enables generation
+ of a FIT (Flat Image Tree) which provides more flexibility. In
+ particular it can handle selecting from multiple device tree
+ and passing the correct one to U-Boot.
+
config VPL_FIT_PRINT
bool "Support FIT printing within VPL"
depends on VPL_FIT
supports selection of various firmware components, selection of an OS to
boot as well as updating these using fwupd.
+config TPL_BOOTMETH_VBE
+ bool "Bootdev support for Verified Boot for Embedded (TPL)"
+ depends on TPL
+ default y
+ help
+ Enables support for VBE boot. This is a standard boot method which
+ supports selection of various firmware components, seleciton of an OS to
+ boot as well as updating these using fwupd.
+
if BOOTMETH_VBE
config BOOTMETH_VBE_REQUEST
config BOOTMETH_VBE_SIMPLE
bool "Bootdev support for VBE 'simple' method"
default y
+ imply SPL_CRC8 if SPL
+ imply VPL_CRC8 if VPL
help
Enables support for VBE 'simple' boot. This allows updating a single
firmware image in boot media such as MMC. It does not support any sort
This option enabled for VPL, since it is the phase where the SPL
decision is made.
-endif # BOOTMETH_VBE
+config TPL_BOOTMETH_VBE_SIMPLE_FW
+ bool "Bootdev support for VBE 'simple' method firmware phase (TPL)"
+ depends on VPL
+ default y
+ help
+ Enables support for the firmware parts of VBE 'simple' boot, in TPL.
+ TPL loads a FIT containing the VPL binary and a suitable devicetree.
+
+endif # BOOTMETH_VBE_SIMPLE
config EXPO
bool "Support for expos - groups of scenes displaying a UI"
#include <malloc.h>
#include <part.h>
#include <sort.h>
+#include <spl.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
int ret, len;
len = bootdev_get_suffix_start(blk, ".blk");
- snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name,
- "bootdev");
+ if (xpl_phase() < PHASE_BOARD_R) {
+ strlcpy(dev_name, blk->name, sizeof(dev_name) - 5);
+ strcat(dev_name, ".sib");
+ } else {
+ snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name,
+ "bootdev");
+ }
parent = dev_get_parent(blk);
ret = device_find_child_by_name(parent, dev_name, &dev);
images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
if (confs_noffset < 0 || images_noffset < 0) {
debug("Can't find configurations or images nodes.\n");
- return -1;
+ return -EINVAL;
}
fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
if (!fdt_compat) {
debug("Fdt for comparison has no \"compatible\" property.\n");
- return -1;
+ return -ENXIO;
}
/*
}
if (!best_match_offset) {
debug("No match found.\n");
- return -1;
+ return -ENOENT;
}
return best_match_offset;
* fit_conf_get_node() will try to find default config node
*/
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
- if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
- cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
- } else {
- cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
- }
- if (cfg_noffset < 0) {
+ ret = -ENXIO;
+ if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config)
+ ret = fit_conf_find_compat(fit, gd_fdt_blob());
+ if (ret < 0 && ret != -EINVAL)
+ ret = fit_conf_get_node(fit, fit_uname_config);
+ if (ret < 0) {
puts("Could not find configuration node\n");
bootstage_error(bootstage_id +
BOOTSTAGE_SUB_NO_UNIT_NAME);
return -ENOENT;
}
+ cfg_noffset = ret;
fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
printf(" Using '%s' configuration\n", fit_base_uname_config);
data = map_to_sysmem(buf);
load = data;
if (load_op == FIT_LOAD_IGNORED) {
+ log_debug("load_op: not loading\n");
/* Don't load */
} else if (fit_image_get_load(fit, noffset, &load)) {
if (load_op == FIT_LOAD_REQUIRED) {
/* Kernel images get decompressed later in bootm_load_os(). */
if (!fit_image_get_comp(fit, noffset, &comp) &&
comp != IH_COMP_NONE &&
+ load_op != FIT_LOAD_IGNORED &&
!(image_type == IH_TYPE_KERNEL ||
image_type == IH_TYPE_KERNEL_NOLOAD ||
image_type == IH_TYPE_RAMDISK)) {
ulong max_decomp_len = len * 20;
+
+ log_debug("decompressing image\n");
if (load == data) {
loadbuf = malloc(max_decomp_len);
load = map_to_sysmem(loadbuf);
}
len = load_end - load;
} else if (load != data) {
+ log_debug("copying\n");
loadbuf = map_sysmem(load, len);
memcpy(loadbuf, buf, len);
}
" please fix your .its file!\n");
/* verify that image data is a proper FDT blob */
- if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
- puts("Subimage data is not a FDT");
+ if (load_op != FIT_LOAD_IGNORED && image_type == IH_TYPE_FLATDT &&
+ fdt_check_header(loadbuf)) {
+ puts("Subimage data is not a FDT\n");
return -ENOEXEC;
}
and the algorithms it supports are defined in common/hash.c. See
also CMD_HASH for command-line access.
+config HASH_CRC8
+ bool "Make crc8 available via the hash API"
+ depends on HASH && CRC8
+ help
+ Most times, the crc8() function is called directly. To make it also
+ available via the hash API, e.g. in hash_block(), enable this
+ option.
+
config AVB_VERIFY
bool "Build Android Verified Boot operations"
depends on LIBAVB
.hash_update = hash_update_crc16_ccitt,
.hash_finish = hash_finish_crc16_ccitt,
},
+#if CONFIG_IS_ENABLED(CRC8) && IS_ENABLED(CONFIG_HASH_CRC8)
+ {
+ .name = "crc8",
+ .digest_size = 1,
+ .chunk_size = CHUNKSZ_CRC32,
+ .hash_func_ws = crc8_wd_buf,
+ },
+#endif
#if CONFIG_IS_ENABLED(CRC32)
{
.name = "crc32",
log_debug("size=%lx, ptr=%lx, limit=%x: ", (ulong)bytes, new_ptr,
gd->malloc_limit);
if (new_ptr > gd->malloc_limit) {
- log_err("alloc space exhausted\n");
+ log_err("alloc space exhausted ptr %lx limit %x\n", new_ptr,
+ gd->malloc_limit);
return NULL;
}
lines). This enables the drivers in drivers/mtd/spi as part of a
VPL build. This normally requires VPL_SPI_SUPPORT.
+config VPL_SYS_MALLOC_SIMPLE
+ bool "Only use malloc_simple functions in the VPL"
+ default y
+ help
+ Say Y here to only use the *_simple malloc functions from
+ malloc_simple.c, rather then using the versions from dlmalloc.c;
+ this will make the VPL binary smaller at the cost of more heap
+ usage as the *_simple malloc functions do not re-use free-ed mem.
+
config VPL_TEXT_BASE
hex "VPL Text Base"
default 0x0
help
The address in memory that VPL will be running from.
+config VPL_MAX_SIZE
+ hex "Maximum size (in bytes) for the VPL stage"
+ default 0x2e000 if ROCKCHIP_RK3399
+ default 0x0
+ help
+ The maximum size (in bytes) of the TPL stage. This size is determined
+ by the amount of internal SRAM memory.
+
config VPL_BINMAN_SYMBOLS
bool "Declare binman symbols in VPL"
depends on VPL_FRAMEWORK && BINMAN
"Unsupported Boot Device!\n");
}
}
- if (loader &&
- !spl_load_image(spl_image, loader)) {
- spl_image->boot_device = bootdev;
- return 0;
+ if (loader) {
+ ret = spl_load_image(spl_image, loader);
+ if (!ret) {
+ spl_image->boot_device = bootdev;
+ return 0;
+ }
+ printf("Error: %d\n", ret);
}
}
}
*/
void preloader_console_init(void)
{
-#ifdef CONFIG_SPL_SERIAL
+#if CONFIG_IS_ENABLED(SERIAL)
gd->baudrate = CONFIG_BAUDRATE;
serial_init(); /* serial communications setup */
*/
ulong spl_relocate_stack_gd(void)
{
-#ifdef CONFIG_SPL_STACK_R
+#if CONFIG_IS_ENABLED(STACK_R)
gd_t *new_gd;
ulong ptr = CONFIG_SPL_STACK_R_ADDR;
struct entry_point_info bl31_ep_info;
};
-struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
static struct bl2_to_bl31_params_mem bl31_params_mem;
struct bl31_params *bl2_to_bl31_params;
return bl2_to_bl31_params;
}
-__weak struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+__weak struct bl31_params *bl2_plat_get_bl31_params(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
return bl2_plat_get_bl31_params_default(bl32_entry, bl33_entry,
fdt_addr);
}
-struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+struct bl_params *bl2_plat_get_bl31_params_v2_default(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
static struct bl2_to_bl31_params_mem_v2 bl31_params_mem;
struct bl_params *bl_params;
return bl_params;
}
-__weak struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+__weak struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
return bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry,
fdt_addr);
typedef void __noreturn (*atf_entry_t)(struct bl31_params *params, void *plat_params);
-static void __noreturn bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry,
- uintptr_t bl33_entry, uintptr_t fdt_addr)
+static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry,
+ ulong bl33_entry, ulong fdt_addr)
{
atf_entry_t atf_entry = (atf_entry_t)bl31_entry;
void *bl31_params;
return -FDT_ERR_NOTFOUND;
}
-uintptr_t spl_fit_images_get_entry(void *blob, int node)
+ulong spl_fit_images_get_entry(void *blob, int node)
{
ulong val;
int ret;
void __noreturn spl_invoke_atf(struct spl_image_info *spl_image)
{
- uintptr_t bl32_entry = 0;
- uintptr_t bl33_entry = CONFIG_TEXT_BASE;
+ ulong bl32_entry = 0;
+ ulong bl33_entry = CONFIG_TEXT_BASE;
void *blob = spl_image->fdt_addr;
- uintptr_t platform_param = (uintptr_t)blob;
+ ulong platform_param = (ulong)blob;
int node;
/*
/**
* load_simple_fit(): load the image described in a certain FIT node
* @info: points to information about the device to load data from
- * @sector: the start sector of the FIT image on the device
+ * @fit_offset: the offset of the FIT image on the device
* @ctx: points to the FIT context structure
* @node: offset of the DT node describing the image to load (relative
* to @fit)
if (!fit_image_get_data_position(fit, node, &offset)) {
external_data = true;
} else if (!fit_image_get_data_offset(fit, node, &offset)) {
+ log_debug("read offset %x = offset from fit %lx\n",
+ offset, (ulong)offset + ctx->ext_data_offset);
offset += ctx->ext_data_offset;
external_data = true;
}
if (external_data) {
+ ulong read_offset;
void *src_ptr;
/* External data */
overhead = get_aligned_image_overhead(info, offset);
size = get_aligned_image_size(info, length, offset);
+ read_offset = fit_offset + get_aligned_image_offset(info,
+ offset);
+ log_debug("reading from offset %x / %lx size %lx to %p: ",
+ offset, read_offset, size, src_ptr);
if (info->read(info,
fit_offset +
else
image_info->entry_point = FDT_ERROR;
}
+ log_debug("- done loading\n");
upl_add_image(fit, node, load_addr, length);
{
struct bootm_headers images;
const char *fit_uname_config = NULL;
- uintptr_t fdt_hack;
+ ulong fdt_hack;
const char *uname;
ulong fw_data = 0, dt_data = 0, img_data = 0;
ulong fw_len = 0, dt_len = 0, img_len = 0;
#define LZMA_LEN (1 << 20)
-static void spl_parse_legacy_validate(uintptr_t start, uintptr_t size)
+static void spl_parse_legacy_validate(ulong start, ulong size)
{
- uintptr_t spl_start = (uintptr_t)_start;
- uintptr_t spl_end = (uintptr_t)&_image_binary_end;
- uintptr_t end = start + size;
+ ulong spl_start = (ulong)_start;
+ ulong spl_end = (ulong)&_image_binary_end;
+ ulong end = start + size;
if ((start >= spl_start && start < spl_end) ||
(end > spl_start && end <= spl_end) ||
struct uclass *uc;
log_debug("Selecting MMC dev %d; seqs:\n", mmc_dev);
- uclass_id_foreach_dev(UCLASS_MMC, dev, uc)
- log_debug("%d: %s\n", dev_seq(dev), dev->name);
+ if (_LOG_DEBUG) {
+ uclass_id_foreach_dev(UCLASS_MMC, dev, uc)
+ log_debug("%d: %s\n", dev_seq(dev), dev->name);
+ }
ret = mmc_init_device(mmc_dev);
#else
ret = mmc_initialize(NULL);
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_BEST_MATCH=y
CONFIG_SPL_LOAD_FIT=y
+# CONFIG_TPL_BOOTMETH_VBE is not set
+# CONFIG_TPL_BOOTMETH_VBE_SIMPLE_FW is not set
CONFIG_UPL=y
CONFIG_UPL_IN=y
CONFIG_BOOTSTAGE=y
int fit_image_get_data_and_size(const void *fit, int noffset,
const void **data, size_t *size);
+/**
+ * fit_image_get_phase() - Get the phase from a FIT image
+ *
+ * @fit: FIT to read from
+ * @offset: offset node to read
+ * @phasep: Returns phase, if any
+ * Return: 0 if read OK and *phasep is value, -ENOENT if there was no phase
+ * property in the node, other -ve value on other error
+ */
+int fit_image_get_phase(const void *fit, int offset,
+ enum image_phase_t *phasep);
+
/**
* fit_get_data_node() - Get verified image data for an image
* @fit: Pointer to the FIT format image header
* copied into the configuration node in the FIT image. This is required to
* match configurations with compressed FDTs.
*
- * Returns: offset to the configuration to use if one was found, -1 otherwise
+ * Returns: offset to the configuration to use if one was found, -EINVAL if
+ * there a /configurations or /images node is missing, -ENOENT if no match was
+ * found, -ENXIO if the FDT node has no compatible string
*/
int fit_conf_find_compat(const void *fit, const void *fdt);
struct spl_image_info {
const char *name;
u8 os;
- uintptr_t load_addr;
- uintptr_t entry_point;
+ ulong load_addr;
+ ulong entry_point;
#if CONFIG_IS_ENABLED(LOAD_FIT) || CONFIG_IS_ENABLED(LOAD_FIT_FULL)
void *fdt_addr;
#endif
*
* Return: bl31 params structure pointer
*/
-struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr);
+struct bl31_params *bl2_plat_get_bl31_params(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr);
/**
* bl2_plat_get_bl31_params_default() - prepare params for bl31.
*
* Return: bl31 params structure pointer
*/
-struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr);
+struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr);
/**
* bl2_plat_get_bl31_params_v2() - return params for bl31
*
* Return: bl31 params structure pointer
*/
-struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr);
+struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr);
/**
* bl2_plat_get_bl31_params_v2_default() - prepare params for bl31.
*
* Return: bl31 params structure pointer
*/
-struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr);
+struct bl_params *bl2_plat_get_bl31_params_v2_default(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr);
/**
* spl_optee_entry - entry function for optee
*
*/
unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len);
+void crc8_wd_buf(const unsigned char *input, unsigned int len,
+ unsigned char output[1], unsigned int chunk_sz);
+
/* lib/crc16.c - 16 bit CRC with polynomial x^16 + x^15 + x^2 + 1 */
uint16_t crc16(uint16_t crc, const unsigned char *buffer, size_t len);
checksum with feedback to produce an 8-bit result. The code is small
and it does not require a lookup table (unlike CRC32).
+config TPL_CRC8
+ bool "Support CRC8 in TPL"
+ depends on TPL
+ help
+ Enables CRC8 support in TPL. This is not normally required. CRC8 is
+ a simple and fast checksumming algorithm which does a bytewise
+ checksum with feedback to produce an 8-bit result. The code is small
+ and it does not require a lookup table (unlike CRC32).
+
+config VPL_CRC8
+ bool "Support CRC8 in VPL"
+ depends on VPL
+ help
+ Enables CRC8 support in VPL. This is not normally required. CRC8 is
+ a simple and fast checksumming algorithm which does a bytewise
+ checksum with feedback to produce an 8-bit result. The code is small
+ and it does not require a lookup table (unlike CRC32).
+
config SPL_CRC16
bool "Support CRC16 in SPL"
depends on SPL
fast compression and decompression speed. It belongs to the LZ77
family of byte-oriented compression schemes.
+config TPL_LZ4
+ bool "Enable LZ4 decompression support in TPL"
+ depends on TPL
+ help
+ This enables support for the LZ4 decompression algorithm in TPL. LZ4
+ is a lossless data compression algorithm that is focused on
+ fast compression and decompression speed. It belongs to the LZ77
+ family of byte-oriented compression schemes.
+
+config VPL_LZ4
+ bool "Enable LZ4 decompression support in VPL"
+ depends on VPL
+ help
+ This enables support for the LZ4 decompression algorithm in VPL. LZ4
+ is a lossless data compression algorithm that is focused on
+ fast compression and decompression speed. It belongs to the LZ77
+ family of byte-oriented compression schemes.
+
config SPL_LZMA
bool "Enable LZMA decompression support for SPL build"
depends on SPL
help
This enables support for LZMA compression algorithm for SPL boot.
+config TPL_LZMA
+ bool "Enable LZMA decompression support for TPL build"
+ depends on TPL
+ help
+ This enables support for LZMA compression algorithm for TPL boot.
+
config VPL_LZMA
bool "Enable LZMA decompression support for VPL build"
default y if LZMA
help
This enables support for the GZIP compression algorithm for SPL boot.
+config TPL_GZIP
+ bool "Enable gzip decompression support for SPL build"
+ select TPL_ZLIB
+ help
+ This enables support for the GZIP compression algorithm for TPL
+
config SPL_ZLIB
bool
help
This enables compression lib for SPL boot.
+config TPL_ZLIB
+ bool
+ help
+ This enables compression lib for TPL
+
config SPL_ZSTD
bool "Enable Zstandard decompression support in SPL"
depends on SPL
obj-$(CONFIG_CRYPT_PW) += crypt/
obj-$(CONFIG_$(XPL_)ASN1_DECODER_LEGACY) += asn1_decoder.o
-obj-$(CONFIG_$(XPL_)ZLIB) += zlib/
-obj-$(CONFIG_$(XPL_)ZSTD) += zstd/
-obj-$(CONFIG_$(XPL_)GZIP) += gunzip.o
-obj-$(CONFIG_$(XPL_)LZO) += lzo/
-obj-$(CONFIG_$(XPL_)LZMA) += lzma/
-obj-$(CONFIG_$(XPL_)LZ4) += lz4_wrapper.o
+obj-$(CONFIG_$(PHASE_)ZLIB) += zlib/
+obj-$(CONFIG_$(PHASE_)ZSTD) += zstd/
+obj-$(CONFIG_$(PHASE_)GZIP) += gunzip.o
+obj-$(CONFIG_$(PHASE_)LZO) += lzo/
+obj-$(CONFIG_$(PHASE_)LZMA) += lzma/
+obj-$(CONFIG_$(PHASE_)LZ4) += lz4_wrapper.o
obj-$(CONFIG_$(XPL_)LIB_RATIONAL) += rational.o
return crc;
}
+
+void crc8_wd_buf(const unsigned char *input, unsigned int len,
+ unsigned char output[1], unsigned int chunk_sz)
+{
+ *output = crc8(0, input, len);
+}