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:
committed by
Tom Rini
parent
035d64025c
commit
2f57c95100
87
lib/fdtdec.c
87
lib/fdtdec.c
@@ -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();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user