@ -15,6 +15,7 @@
# include <serial.h>
# include <serial.h>
# include <asm/sections.h>
# include <asm/sections.h>
# include <linux/ctype.h>
# include <linux/ctype.h>
# include <linux/lzo.h>
DECLARE_GLOBAL_DATA_PTR ;
DECLARE_GLOBAL_DATA_PTR ;
@ -1203,9 +1204,66 @@ int fdtdec_setup_memory_banksize(void)
}
}
# endif
# 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 )
int fdtdec_setup ( void )
{
{
# if CONFIG_IS_ENABLED(OF_CONTROL)
# if CONFIG_IS_ENABLED(OF_CONTROL)
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
void * fdt_blob ;
# endif
# ifdef CONFIG_OF_EMBED
# ifdef CONFIG_OF_EMBED
/* Get a pointer to the FDT */
/* Get a pointer to the FDT */
gd - > fdt_blob = __dtb_dt_begin ;
gd - > fdt_blob = __dtb_dt_begin ;
@ -1216,15 +1274,6 @@ int fdtdec_setup(void)
gd - > fdt_blob = ( ulong * ) & _image_binary_end ;
gd - > fdt_blob = ( ulong * ) & _image_binary_end ;
else
else
gd - > fdt_blob = ( ulong * ) & __bss_end ;
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
# else
/* FDT is at end of image */
/* FDT is at end of image */
gd - > fdt_blob = ( ulong * ) & _end ;
gd - > fdt_blob = ( ulong * ) & _end ;
@ -1243,7 +1292,27 @@ int fdtdec_setup(void)
gd - > fdt_blob = ( void * ) env_get_ulong ( " fdtcontroladdr " , 16 ,
gd - > fdt_blob = ( void * ) env_get_ulong ( " fdtcontroladdr " , 16 ,
( uintptr_t ) gd - > fdt_blob ) ;
( uintptr_t ) gd - > fdt_blob ) ;
# endif
# 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 . 16 MB
* 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
# endif
return fdtdec_prepare_fdt ( ) ;
return fdtdec_prepare_fdt ( ) ;
}
}