1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 08:42:12 +02:00

spl: dm: Make it possible for the SPL to pick its own DTB from a FIT

u-boot can be embedded within a FIT image with multiple DTBs. It then
selects at run-time  which one is best suited for the platform.
Use the same principle here for the SPL: put the DTBs in a FIT image,
compress it (LZO, GZIP, or no compression) and append it at the end of the
SPL.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
[trini: Move default y of SPL_MULTI_DTB_FIT_DYN_ALLOC to it being the
default choice if SYS_MALLOC_F, drop spl.h include from lib/fdtdec.c
it's unused.]
Signed-off-by Tom Rini <trini@konsulko.com>
This commit is contained in:
Jean-Jacques Hiblot
2017-09-15 12:57:32 +02:00
committed by Tom Rini
parent 035d64025c
commit 2f57c95100
4 changed files with 248 additions and 13 deletions

View File

@@ -15,6 +15,7 @@
#include <serial.h>
#include <asm/sections.h>
#include <linux/ctype.h>
#include <linux/lzo.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -1203,9 +1204,66 @@ int fdtdec_setup_memory_banksize(void)
}
#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\
CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO)
static int uncompress_blob(const void *src, ulong sz_src, void **dstp)
{
size_t sz_out = CONFIG_SPL_MULTI_DTB_FIT_UNCOMPRESS_SZ;
ulong sz_in = sz_src;
void *dst;
int rc;
if (CONFIG_IS_ENABLED(GZIP))
if (gzip_parse_header(src, sz_in) < 0)
return -1;
if (CONFIG_IS_ENABLED(LZO))
if (!lzop_is_valid_header(src))
return -EBADMSG;
if (CONFIG_IS_ENABLED(MULTI_DTB_FIT_DYN_ALLOC)) {
dst = malloc(sz_out);
if (!dst) {
puts("uncompress_blob: Unable to allocate memory\n");
return -ENOMEM;
}
} else {
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_USER_DEFINED_AREA)
dst = (void *)CONFIG_VAL(MULTI_DTB_FIT_USER_DEF_ADDR);
# else
return -ENOTSUPP;
# endif
}
if (CONFIG_IS_ENABLED(GZIP))
rc = gunzip(dst, sz_out, (u8 *)src, &sz_in);
else if (CONFIG_IS_ENABLED(LZO))
rc = lzop_decompress(src, sz_in, dst, &sz_out);
if (rc < 0) {
/* not a valid compressed blob */
puts("uncompress_blob: Unable to uncompress\n");
if (CONFIG_IS_ENABLED(MULTI_DTB_FIT_DYN_ALLOC))
free(dst);
return -EBADMSG;
}
*dstp = dst;
return 0;
}
# else
static int uncompress_blob(const void *src, ulong sz_src, void **dstp)
{
return -ENOTSUPP;
}
# endif
#endif
int fdtdec_setup(void)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
void *fdt_blob;
# endif
# ifdef CONFIG_OF_EMBED
/* Get a pointer to the FDT */
gd->fdt_blob = __dtb_dt_begin;
@@ -1216,15 +1274,6 @@ int fdtdec_setup(void)
gd->fdt_blob = (ulong *)&_image_binary_end;
else
gd->fdt_blob = (ulong *)&__bss_end;
# elif defined CONFIG_MULTI_DTB_FIT
gd->fdt_blob = locate_dtb_in_fit(&_end);
if (gd->fdt_blob == NULL || gd->fdt_blob <= ((void *)&_end)) {
puts("Failed to find proper dtb in embedded FIT Image\n");
return -1;
}
# else
/* FDT is at end of image */
gd->fdt_blob = (ulong *)&_end;
@@ -1243,7 +1292,27 @@ int fdtdec_setup(void)
gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
(uintptr_t)gd->fdt_blob);
# endif
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
/*
* Try and uncompress the blob.
* Unfortunately there is no way to know how big the input blob really
* is. So let us set the maximum input size arbitrarily high. 16MB
* ought to be more than enough for packed DTBs.
*/
if (uncompress_blob(gd->fdt_blob, 0x1000000, &fdt_blob) == 0)
gd->fdt_blob = fdt_blob;
/*
* Check if blob is a FIT images containings DTBs.
* If so, pick the most relevant
*/
fdt_blob = locate_dtb_in_fit(gd->fdt_blob);
if (fdt_blob)
gd->fdt_blob = fdt_blob;
# endif
#endif
return fdtdec_prepare_fdt();
}