@ -39,22 +39,12 @@
# include <libfdt.h>
# include <fdt_support.h>
static void fdt_error ( const char * msg ) ;
static int boot_get_fdt ( cmd_tbl_t * cmdtp , int flag , int argc , char * argv [ ] ,
bootm_headers_t * images , char * * of_flat_tree , ulong * of_size ) ;
static int boot_relocate_fdt ( struct lmb * lmb , ulong bootmap_base ,
cmd_tbl_t * cmdtp , int flag , int argc , char * argv [ ] ,
char * * of_flat_tree , ulong * of_size ) ;
# endif
# ifdef CFG_INIT_RAM_LOCK
# include <asm/cache.h>
# endif
# ifndef CFG_FDT_PAD
# define CFG_FDT_PAD 0x3000
# endif
DECLARE_GLOBAL_DATA_PTR ;
extern int do_reset ( cmd_tbl_t * cmdtp , int flag , int argc , char * argv [ ] ) ;
@ -82,11 +72,11 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
void ( * kernel ) ( bd_t * , ulong r4 , ulong r5 , ulong r6 ,
ulong r7 , ulong r8 , ulong r9 ) ;
int ret ;
ulong of_size = 0 ;
ulong of_size = images - > ft_len ;
struct lmb * lmb = images - > lmb ;
# if defined(CONFIG_OF_LIBFDT)
char * of_flat_tree = NULL ;
char * of_flat_tree = images - > ft_addr ;
# endif
kernel = ( void ( * ) ( bd_t * , ulong , ulong , ulong ,
@ -128,14 +118,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
sp - = 1024 ;
lmb_reserve ( lmb , sp , ( CFG_SDRAM_BASE + get_effective_memsize ( ) - sp ) ) ;
# if defined(CONFIG_OF_LIBFDT)
/* find flattened device tree */
ret = boot_get_fdt ( cmdtp , flag , argc , argv , images , & of_flat_tree , & of_size ) ;
if ( ret )
goto error ;
# endif
if ( ! of_size ) {
/* allocate space and init command line */
ret = boot_get_cmdline ( lmb , & cmd_start , & cmd_end , bootmap_base ) ;
@ -156,8 +138,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
rd_len = images - > rd_end - images - > rd_start ;
# if defined(CONFIG_OF_LIBFDT)
ret = boot_relocate_fdt ( lmb , bootmap_base ,
cmdtp , flag , argc , argv , & of_flat_tree , & of_size ) ;
ret = boot_relocate_fdt ( lmb , bootmap_base , & of_flat_tree , & of_size ) ;
if ( ret )
goto error ;
/*
* Add the chosen node if it doesn ' t exist , add the env and bd_t
@ -166,7 +149,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
if ( of_size ) {
/* pass in dummy initrd info, we'll fix up later */
if ( fdt_chosen ( of_flat_tree , images - > rd_start , images - > rd_end , 0 ) < 0 ) {
fdt_error ( " /chosen node create failed " ) ;
puts ( " ERROR: " ) ;
puts ( " /chosen node create failed " ) ;
puts ( " - must RESET the board to recover. \n " ) ;
goto error ;
}
# ifdef CONFIG_OF_BOARD_SETUP
@ -339,464 +324,3 @@ static void set_clocks_in_mhz (bd_t *kbd)
# endif /* CONFIG_MPC5xxx */
}
}
# if defined(CONFIG_OF_LIBFDT)
static void fdt_error ( const char * msg )
{
puts ( " ERROR: " ) ;
puts ( msg ) ;
puts ( " - must RESET the board to recover. \n " ) ;
}
static image_header_t * image_get_fdt ( ulong fdt_addr )
{
image_header_t * fdt_hdr = ( image_header_t * ) fdt_addr ;
image_print_contents ( fdt_hdr ) ;
puts ( " Verifying Checksum ... " ) ;
if ( ! image_check_hcrc ( fdt_hdr ) ) {
fdt_error ( " fdt header checksum invalid " ) ;
return NULL ;
}
if ( ! image_check_dcrc ( fdt_hdr ) ) {
fdt_error ( " fdt checksum invalid " ) ;
return NULL ;
}
puts ( " OK \n " ) ;
if ( ! image_check_type ( fdt_hdr , IH_TYPE_FLATDT ) ) {
fdt_error ( " uImage is not a fdt " ) ;
return NULL ;
}
if ( image_get_comp ( fdt_hdr ) ! = IH_COMP_NONE ) {
fdt_error ( " uImage is compressed " ) ;
return NULL ;
}
if ( fdt_check_header ( ( char * ) image_get_data ( fdt_hdr ) ) ! = 0 ) {
fdt_error ( " uImage data is not a fdt " ) ;
return NULL ;
}
return fdt_hdr ;
}
/**
* fit_check_fdt - verify FIT format FDT subimage
* @ fit_hdr : pointer to the FIT header
* fdt_noffset : FDT subimage node offset within FIT image
* @ verify : data CRC verification flag
*
* fit_check_fdt ( ) verifies integrity of the FDT subimage and from
* specified FIT image .
*
* returns :
* 1 , on success
* 0 , on failure
*/
# if defined(CONFIG_FIT)
static int fit_check_fdt ( const void * fit , int fdt_noffset , int verify )
{
fit_image_print ( fit , fdt_noffset , " " ) ;
if ( verify ) {
puts ( " Verifying Hash Integrity ... " ) ;
if ( ! fit_image_check_hashes ( fit , fdt_noffset ) ) {
fdt_error ( " Bad Data Hash " ) ;
return 0 ;
}
puts ( " OK \n " ) ;
}
if ( ! fit_image_check_type ( fit , fdt_noffset , IH_TYPE_FLATDT ) ) {
fdt_error ( " Not a FDT image " ) ;
return 0 ;
}
if ( ! fit_image_check_comp ( fit , fdt_noffset , IH_COMP_NONE ) ) {
fdt_error ( " FDT image is compressed " ) ;
return 0 ;
}
return 1 ;
}
# endif /* CONFIG_FIT */
static int boot_get_fdt ( cmd_tbl_t * cmdtp , int flag , int argc , char * argv [ ] ,
bootm_headers_t * images , char * * of_flat_tree , ulong * of_size )
{
ulong fdt_addr ;
image_header_t * fdt_hdr ;
char * fdt_blob = NULL ;
ulong image_start , image_end ;
ulong load_start , load_end ;
# if defined(CONFIG_FIT)
void * fit_hdr ;
const char * fit_uname_config = NULL ;
const char * fit_uname_fdt = NULL ;
ulong default_addr ;
int cfg_noffset ;
int fdt_noffset ;
const void * data ;
size_t size ;
# endif
* of_flat_tree = NULL ;
* of_size = 0 ;
if ( argc > 3 | | genimg_has_config ( images ) ) {
# if defined(CONFIG_FIT)
if ( argc > 3 ) {
/*
* If the FDT blob comes from the FIT image and the
* FIT image address is omitted in the command line
* argument , try to use ramdisk or os FIT image
* address or default load address .
*/
if ( images - > fit_uname_rd )
default_addr = ( ulong ) images - > fit_hdr_rd ;
else if ( images - > fit_uname_os )
default_addr = ( ulong ) images - > fit_hdr_os ;
else
default_addr = load_addr ;
if ( fit_parse_conf ( argv [ 3 ] , default_addr ,
& fdt_addr , & fit_uname_config ) ) {
debug ( " * fdt: config '%s' from image at 0x%08lx \n " ,
fit_uname_config , fdt_addr ) ;
} else if ( fit_parse_subimage ( argv [ 3 ] , default_addr ,
& fdt_addr , & fit_uname_fdt ) ) {
debug ( " * fdt: subimage '%s' from image at 0x%08lx \n " ,
fit_uname_fdt , fdt_addr ) ;
} else
# endif
{
fdt_addr = simple_strtoul ( argv [ 3 ] , NULL , 16 ) ;
debug ( " * fdt: cmdline image address = 0x%08lx \n " ,
fdt_addr ) ;
}
# if defined(CONFIG_FIT)
} else {
/* use FIT configuration provided in first bootm
* command argument
*/
fdt_addr = ( ulong ) images - > fit_hdr_os ;
fit_uname_config = images - > fit_uname_cfg ;
debug ( " * fdt: using config '%s' from image at 0x%08lx \n " ,
fit_uname_config , fdt_addr ) ;
/*
* Check whether configuration has FDT blob defined ,
* if not quit silently .
*/
fit_hdr = ( void * ) fdt_addr ;
cfg_noffset = fit_conf_get_node ( fit_hdr ,
fit_uname_config ) ;
if ( cfg_noffset < 0 ) {
debug ( " * fdt: no such config \n " ) ;
return 0 ;
}
fdt_noffset = fit_conf_get_fdt_node ( fit_hdr ,
cfg_noffset ) ;
if ( fdt_noffset < 0 ) {
debug ( " * fdt: no fdt in config \n " ) ;
return 0 ;
}
}
# endif
debug ( " ## Checking for 'FDT'/'FDT Image' at %08lx \n " ,
fdt_addr ) ;
/* copy from dataflash if needed */
fdt_addr = genimg_get_image ( fdt_addr ) ;
/*
* Check if there is an FDT image at the
* address provided in the second bootm argument
* check image type , for FIT images get a FIT node .
*/
switch ( genimg_get_format ( ( void * ) fdt_addr ) ) {
case IMAGE_FORMAT_LEGACY :
/* verify fdt_addr points to a valid image header */
printf ( " ## Flattened Device Tree from Legacy Image at %08lx \n " ,
fdt_addr ) ;
fdt_hdr = image_get_fdt ( fdt_addr ) ;
if ( ! fdt_hdr )
goto error ;
/*
* move image data to the load address ,
* make sure we don ' t overwrite initial image
*/
image_start = ( ulong ) fdt_hdr ;
image_end = image_get_image_end ( fdt_hdr ) ;
load_start = image_get_load ( fdt_hdr ) ;
load_end = load_start + image_get_data_size ( fdt_hdr ) ;
if ( ( load_start < image_end ) & & ( load_end > image_start ) ) {
fdt_error ( " fdt overwritten " ) ;
goto error ;
}
debug ( " Loading FDT from 0x%08lx to 0x%08lx \n " ,
image_get_data ( fdt_hdr ) , load_start ) ;
memmove ( ( void * ) load_start ,
( void * ) image_get_data ( fdt_hdr ) ,
image_get_data_size ( fdt_hdr ) ) ;
fdt_blob = ( char * ) load_start ;
break ;
case IMAGE_FORMAT_FIT :
/*
* This case will catch both : new uImage format
* ( libfdt based ) and raw FDT blob ( also libfdt
* based ) .
*/
# if defined(CONFIG_FIT)
/* check FDT blob vs FIT blob */
if ( fit_check_format ( ( const void * ) fdt_addr ) ) {
/*
* FIT image
*/
fit_hdr = ( void * ) fdt_addr ;
printf ( " ## Flattened Device Tree from FIT Image at %08lx \n " ,
fdt_addr ) ;
if ( ! fit_uname_fdt ) {
/*
* no FDT blob image node unit name ,
* try to get config node first . If
* config unit node name is NULL
* fit_conf_get_node ( ) will try to
* find default config node
*/
cfg_noffset = fit_conf_get_node ( fit_hdr ,
fit_uname_config ) ;
if ( cfg_noffset < 0 ) {
fdt_error ( " Could not find configuration node \n " ) ;
goto error ;
}
fit_uname_config = fdt_get_name ( fit_hdr ,
cfg_noffset , NULL ) ;
printf ( " Using '%s' configuration \n " ,
fit_uname_config ) ;
fdt_noffset = fit_conf_get_fdt_node ( fit_hdr ,
cfg_noffset ) ;
fit_uname_fdt = fit_get_name ( fit_hdr ,
fdt_noffset , NULL ) ;
} else {
/* get FDT component image node offset */
fdt_noffset = fit_image_get_node ( fit_hdr ,
fit_uname_fdt ) ;
}
if ( fdt_noffset < 0 ) {
fdt_error ( " Could not find subimage node \n " ) ;
goto error ;
}
printf ( " Trying '%s' FDT blob subimage \n " ,
fit_uname_fdt ) ;
if ( ! fit_check_fdt ( fit_hdr , fdt_noffset ,
images - > verify ) )
goto error ;
/* get ramdisk image data address and length */
if ( fit_image_get_data ( fit_hdr , fdt_noffset ,
& data , & size ) ) {
fdt_error ( " Could not find FDT subimage data " ) ;
goto error ;
}
/* verift that image data is a proper FDT blob */
if ( fdt_check_header ( ( char * ) data ) ! = 0 ) {
fdt_error ( " Subimage data is not a FTD " ) ;
goto error ;
}
/*
* move image data to the load address ,
* make sure we don ' t overwrite initial image
*/
image_start = ( ulong ) fit_hdr ;
image_end = fit_get_end ( fit_hdr ) ;
if ( fit_image_get_load ( fit_hdr , fdt_noffset ,
& load_start ) = = 0 ) {
load_end = load_start + size ;
if ( ( load_start < image_end ) & &
( load_end > image_start ) ) {
fdt_error ( " FDT overwritten " ) ;
goto error ;
}
printf ( " Loading FDT from 0x%08lx to 0x%08lx \n " ,
( ulong ) data , load_start ) ;
memmove ( ( void * ) load_start ,
( void * ) data , size ) ;
fdt_blob = ( char * ) load_start ;
} else {
fdt_blob = ( char * ) data ;
}
images - > fit_hdr_fdt = fit_hdr ;
images - > fit_uname_fdt = fit_uname_fdt ;
images - > fit_noffset_fdt = fdt_noffset ;
break ;
} else
# endif
{
/*
* FDT blob
*/
fdt_blob = ( char * ) fdt_addr ;
debug ( " * fdt: raw FDT blob \n " ) ;
printf ( " ## Flattened Device Tree blob at %08lx \n " , ( long ) fdt_blob ) ;
}
break ;
default :
fdt_error ( " Did not find a cmdline Flattened Device Tree " ) ;
goto error ;
}
printf ( " Booting using the fdt blob at 0x%x \n " , ( int ) fdt_blob ) ;
} else if ( images - > legacy_hdr_valid & &
image_check_type ( & images - > legacy_hdr_os_copy , IH_TYPE_MULTI ) ) {
ulong fdt_data , fdt_len ;
/*
* Now check if we have a legacy multi - component image ,
* get second entry data start address and len .
*/
printf ( " ## Flattened Device Tree from multi "
" component Image at %08lX \n " ,
( ulong ) images - > legacy_hdr_os ) ;
image_multi_getimg ( images - > legacy_hdr_os , 2 , & fdt_data , & fdt_len ) ;
if ( fdt_len ) {
fdt_blob = ( char * ) fdt_data ;
printf ( " Booting using the fdt at 0x%x \n " , ( int ) fdt_blob ) ;
if ( fdt_check_header ( fdt_blob ) ! = 0 ) {
fdt_error ( " image is not a fdt " ) ;
goto error ;
}
if ( be32_to_cpu ( fdt_totalsize ( fdt_blob ) ) ! = fdt_len ) {
fdt_error ( " fdt size != image size " ) ;
goto error ;
}
} else {
debug ( " ## No Flattened Device Tree \n " ) ;
return 0 ;
}
} else {
debug ( " ## No Flattened Device Tree \n " ) ;
return 0 ;
}
* of_flat_tree = fdt_blob ;
* of_size = be32_to_cpu ( fdt_totalsize ( fdt_blob ) ) ;
debug ( " of_flat_tree at 0x%08lx size 0x%08lx \n " ,
* of_flat_tree , * of_size ) ;
return 0 ;
error :
do_reset ( cmdtp , flag , argc , argv ) ;
return 1 ;
}
static int boot_relocate_fdt ( struct lmb * lmb , ulong bootmap_base ,
cmd_tbl_t * cmdtp , int flag , int argc , char * argv [ ] ,
char * * of_flat_tree , ulong * of_size )
{
char * fdt_blob = * of_flat_tree ;
ulong relocate = 0 ;
ulong of_len = 0 ;
/* nothing to do */
if ( * of_size = = 0 )
return 0 ;
if ( fdt_check_header ( fdt_blob ) ! = 0 ) {
fdt_error ( " image is not a fdt " ) ;
goto error ;
}
# ifndef CFG_NO_FLASH
/* move the blob if it is in flash (set relocate) */
if ( addr2info ( ( ulong ) fdt_blob ) ! = NULL )
relocate = 1 ;
# endif
/*
* The blob needs to be inside the boot mapping .
*/
if ( fdt_blob < ( char * ) bootmap_base )
relocate = 1 ;
if ( ( fdt_blob + * of_size + CFG_FDT_PAD ) > =
( ( char * ) CFG_BOOTMAPSZ + bootmap_base ) )
relocate = 1 ;
/* move flattend device tree if needed */
if ( relocate ) {
int err ;
ulong of_start = 0 ;
/* position on a 4K boundary before the alloc_current */
/* Pad the FDT by a specified amount */
of_len = * of_size + CFG_FDT_PAD ;
of_start = ( unsigned long ) lmb_alloc_base ( lmb , of_len , 0x1000 ,
( CFG_BOOTMAPSZ + bootmap_base ) ) ;
if ( of_start = = 0 ) {
puts ( " device tree - allocation error \n " ) ;
goto error ;
}
debug ( " ## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX) \n " ,
( ulong ) fdt_blob , ( ulong ) fdt_blob + * of_size - 1 ,
of_len , of_len ) ;
printf ( " Loading Device Tree to %08lx, end %08lx ... " ,
of_start , of_start + of_len - 1 ) ;
err = fdt_open_into ( fdt_blob , ( void * ) of_start , of_len ) ;
if ( err ! = 0 ) {
fdt_error ( " fdt move failed " ) ;
goto error ;
}
puts ( " OK \n " ) ;
* of_flat_tree = ( char * ) of_start ;
* of_size = of_len ;
} else {
* of_flat_tree = fdt_blob ;
of_len = ( CFG_BOOTMAPSZ + bootmap_base ) - ( ulong ) fdt_blob ;
lmb_reserve ( lmb , ( ulong ) fdt_blob , of_len ) ;
fdt_set_totalsize ( * of_flat_tree , of_len ) ;
* of_size = of_len ;
}
return 0 ;
error :
return 1 ;
}
# endif