@ -159,19 +159,81 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
return ( data_size + info - > bl_len - 1 ) / info - > bl_len ;
}
/**
* spl_load_fit_image ( ) : 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 : points to the flattened device tree blob describing the FIT
* image
* @ base_offset : the beginning of the data area containing the actual
* image data , relative to the beginning of the FIT
* @ node : offset of the DT node describing the image to load ( relative
* to @ fit )
* @ image_info : will be filled with information about the loaded image
* If the FIT node does not contain a " load " ( address ) property ,
* the image gets loaded to the address pointed to by the
* load_addr member in this struct .
*
* Return : 0 on success or a negative error number .
*/
static int spl_load_fit_image ( struct spl_load_info * info , ulong sector ,
void * fit , ulong base_offset , int node ,
struct spl_image_info * image_info )
{
ulong offset ;
size_t length ;
ulong load_addr , load_ptr ;
void * src ;
ulong overhead ;
int nr_sectors ;
int align_len = ARCH_DMA_MINALIGN - 1 ;
offset = fdt_getprop_u32 ( fit , node , " data-offset " ) ;
if ( offset = = FDT_ERROR )
return - ENOENT ;
offset + = base_offset ;
length = fdt_getprop_u32 ( fit , node , " data-size " ) ;
if ( length = = FDT_ERROR )
return - ENOENT ;
load_addr = fdt_getprop_u32 ( fit , node , " load " ) ;
if ( load_addr = = FDT_ERROR & & image_info )
load_addr = image_info - > load_addr ;
load_ptr = ( load_addr + align_len ) & ~ align_len ;
overhead = get_aligned_image_overhead ( info , offset ) ;
nr_sectors = get_aligned_image_size ( info , length , offset ) ;
if ( info - > read ( info , sector + get_aligned_image_offset ( info , offset ) ,
nr_sectors , ( void * ) load_ptr ) ! = nr_sectors )
return - EIO ;
debug ( " image: dst=%lx, offset=%lx, size=%lx \n " , load_ptr , offset ,
( unsigned long ) length ) ;
src = ( void * ) load_ptr + overhead ;
# ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
board_fit_image_post_process ( & src , & length ) ;
# endif
memcpy ( ( void * ) load_addr , src , length ) ;
if ( image_info ) {
image_info - > load_addr = load_addr ;
image_info - > size = length ;
image_info - > entry_point = fdt_getprop_u32 ( fit , node , " entry " ) ;
}
return 0 ;
}
int spl_load_simple_fit ( struct spl_image_info * spl_image ,
struct spl_load_info * info , ulong sector , void * fit )
{
int sectors ;
ulong size , load ;
ulong size ;
unsigned long count ;
int node , images ;
void * load_ptr ;
int fdt_offset , fdt_len ;
int data_offset , data_size ;
struct spl_image_info image_info ;
int node , images , ret ;
int base_offset , align_len = ARCH_DMA_MINALIGN - 1 ;
int src_sector ;
void * dst , * src ;
/*
* Figure out where the external images start . This is the base for the
@ -223,46 +285,13 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
return - 1 ;
}
/* Get its information and set up the spl_image structure */
data_offset = fdt_getprop_u32 ( fit , node , " data-offset " ) ;
if ( data_offset = = FDT_ERROR )
return - ENOENT ;
data_size = fdt_getprop_u32 ( fit , node , " data-size " ) ;
if ( data_size = = FDT_ERROR )
return - ENOENT ;
load = fdt_getprop_u32 ( fit , node , " load " ) ;
debug ( " data_offset=%x, data_size=%x \n " , data_offset , data_size ) ;
spl_image - > load_addr = load ;
spl_image - > entry_point = load ;
spl_image - > os = IH_OS_U_BOOT ;
/*
* Work out where to place the image . We read it so that the first
* byte will be at ' load ' . This may mean we need to load it starting
* before then , since we can only read whole blocks .
*/
data_offset + = base_offset ;
sectors = get_aligned_image_size ( info , data_size , data_offset ) ;
load_ptr = ( void * ) load ;
debug ( " U-Boot size %x, data %p \n " , data_size , load_ptr ) ;
dst = load_ptr ;
/* Read the image */
src_sector = sector + get_aligned_image_offset ( info , data_offset ) ;
debug ( " Aligned image read: dst=%p, src_sector=%x, sectors=%x \n " ,
dst , src_sector , sectors ) ;
count = info - > read ( info , src_sector , sectors , dst ) ;
if ( count ! = sectors )
return - EIO ;
debug ( " image: dst=%p, data_offset=%x, size=%x \n " , dst , data_offset ,
data_size ) ;
src = dst + get_aligned_image_overhead ( info , data_offset ) ;
/* Load the image and set up the spl_image structure */
ret = spl_load_fit_image ( info , sector , fit , base_offset , node ,
spl_image ) ;
if ( ret )
return ret ;
# ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
board_fit_image_post_process ( ( void * * ) & src , ( size_t * ) & data_size ) ;
# endif
memcpy ( dst , src , data_size ) ;
spl_image - > os = IH_OS_U_BOOT ;
/* Figure out which device tree the board wants to use */
node = spl_fit_get_image_node ( fit , images , FIT_FDT_PROP , 0 ) ;
@ -270,43 +299,12 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
debug ( " %s: cannot find FDT node \n " , __func__ ) ;
return node ;
}
fdt_offset = fdt_getprop_u32 ( fit , node , " data-offset " ) ;
fdt_len = fdt_getprop_u32 ( fit , node , " data-size " ) ;
if ( fdt_offset = = FDT_ERROR | | fdt_len = = FDT_ERROR ) {
debug ( " %s: cannot load FDT data \n " __func__ ) ;
return - ENOENT ;
}
/*
* Read the device tree and place it after the image . There may be
* some extra data before it since we can only read entire blocks .
* And also align the destination address to ARCH_DMA_MINALIGN .
* Read the device tree and place it after the image .
* Align the destination address to ARCH_DMA_MINALIGN .
*/
dst = ( void * ) ( ( load + data_size + align_len ) & ~ align_len ) ;
fdt_offset + = base_offset ;
sectors = get_aligned_image_size ( info , fdt_len , fdt_offset ) ;
src_sector = sector + get_aligned_image_offset ( info , fdt_offset ) ;
count = info - > read ( info , src_sector , sectors , dst ) ;
debug ( " Aligned fdt read: dst %p, src_sector = %x, sectors %x \n " ,
dst , src_sector , sectors ) ;
if ( count ! = sectors )
return - EIO ;
/*
* Copy the device tree so that it starts immediately after the image .
* After this we will have the U - Boot image and its device tree ready
* for us to start .
*/
debug ( " fdt: dst=%p, data_offset=%x, size=%x \n " , dst , fdt_offset ,
fdt_len ) ;
src = dst + get_aligned_image_overhead ( info , fdt_offset ) ;
dst = load_ptr + data_size ;
# ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
board_fit_image_post_process ( ( void * * ) & src , ( size_t * ) & fdt_len ) ;
# endif
memcpy ( dst , src , fdt_len ) ;
return 0 ;
image_info . load_addr = spl_image - > load_addr + spl_image - > size ;
return spl_load_fit_image ( info , sector , fit , base_offset , node ,
& image_info ) ;
}