/*
* U - Boot - ldrinfo
*
* Copyright ( c ) 2010 Analog Devices Inc .
*
* See file CREDITS for list of people who contributed to this
* project .
*
* Licensed under the GPL - 2 or later .
*/
# include <config.h>
# include <common.h>
# include <command.h>
# include <asm/blackfin.h>
# include <asm/mach-common/bits/bootrom.h>
static uint32_t ldrinfo_header ( const void * addr )
{
uint32_t skip = 0 ;
# if defined(__ADSPBF561__)
/* BF56x has a 4 byte global header */
uint32_t header , sign ;
static const char * const spi_speed [ ] = {
" 500K " , " 1M " , " 2M " , " ?? " ,
} ;
memcpy ( & header , addr , sizeof ( header ) ) ;
sign = ( header & GFLAG_56X_SIGN_MASK ) > > GFLAG_56X_SIGN_SHIFT ;
printf ( " Header: %08X ( %s-bit-flash wait:%i hold:%i spi:%s %s) \n " ,
header ,
( header & GFLAG_56X_16BIT_FLASH ) ? " 16 " : " 8 " ,
( header & GFLAG_56X_WAIT_MASK ) > > GFLAG_56X_WAIT_SHIFT ,
( header & GFLAG_56X_HOLD_MASK ) > > GFLAG_56X_HOLD_SHIFT ,
spi_speed [ ( header & GFLAG_56X_SPI_MASK ) > > GFLAG_56X_SPI_SHIFT ] ,
sign = = GFLAG_56X_SIGN_MAGIC ? " " : " !!hdrsign!! " ) ;
skip = 4 ;
# endif
/* |Block @ 12345678: 12345678 12345678 12345678 12345678 | */
# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
defined ( __ADSPBF534__ ) | | defined ( __ADSPBF536__ ) | | defined ( __ADSPBF537__ ) | | \
defined ( __ADSPBF538__ ) | | defined ( __ADSPBF539__ ) | | defined ( __ADSPBF561__ )
printf ( " Address Count Flags \n " ) ;
# else
printf ( " BCode Address Count Argument \n " ) ;
# endif
return skip ;
}
struct ldr_flag {
uint16_t flag ;
const char * desc ;
} ;
static uint32_t ldrinfo_block ( const void * base_addr )
{
uint32_t count ;
printf ( " Block @ %08X: " , ( uint32_t ) base_addr ) ;
# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
defined ( __ADSPBF534__ ) | | defined ( __ADSPBF536__ ) | | defined ( __ADSPBF537__ ) | | \
defined ( __ADSPBF538__ ) | | defined ( __ADSPBF539__ ) | | defined ( __ADSPBF561__ )
uint32_t addr , pval ;
uint16_t flags ;
int i ;
static const struct ldr_flag ldr_flags [ ] = {
{ BFLAG_53X_ZEROFILL , " zerofill " } ,
{ BFLAG_53X_RESVECT , " resvect " } ,
{ BFLAG_53X_INIT , " init " } ,
{ BFLAG_53X_IGNORE , " ignore " } ,
{ BFLAG_53X_COMPRESSED , " compressed " } ,
{ BFLAG_53X_FINAL , " final " } ,
} ;
memcpy ( & addr , base_addr , sizeof ( addr ) ) ;
memcpy ( & count , base_addr + 4 , sizeof ( count ) ) ;
memcpy ( & flags , base_addr + 8 , sizeof ( flags ) ) ;
printf ( " %08X %08X %04X ( " , addr , count , flags ) ;
for ( i = 0 ; i < ARRAY_SIZE ( ldr_flags ) ; + + i )
if ( flags & ldr_flags [ i ] . flag )
printf ( " %s " , ldr_flags [ i ] . desc ) ;
pval = ( flags & BFLAG_53X_PFLAG_MASK ) > > BFLAG_53X_PFLAG_SHIFT ;
if ( pval )
printf ( " gpio%i " , pval ) ;
pval = ( flags & BFLAG_53X_PPORT_MASK ) > > BFLAG_53X_PPORT_SHIFT ;
if ( pval )
printf ( " port%c " , ' e ' + pval ) ;
if ( flags & BFLAG_53X_ZEROFILL )
count = 0 ;
if ( flags & BFLAG_53X_FINAL )
count = 0 ;
else
count + = sizeof ( addr ) + sizeof ( count ) + sizeof ( flags ) ;
# else
const uint8_t * raw8 = base_addr ;
uint32_t bcode , addr , arg , sign , chk ;
int i ;
static const struct ldr_flag ldr_flags [ ] = {
{ BFLAG_SAFE , " safe " } ,
{ BFLAG_AUX , " aux " } ,
{ BFLAG_FILL , " fill " } ,
{ BFLAG_QUICKBOOT , " quickboot " } ,
{ BFLAG_CALLBACK , " callback " } ,
{ BFLAG_INIT , " init " } ,
{ BFLAG_IGNORE , " ignore " } ,
{ BFLAG_INDIRECT , " indirect " } ,
{ BFLAG_FIRST , " first " } ,
{ BFLAG_FINAL , " final " } ,
} ;
memcpy ( & bcode , base_addr , sizeof ( bcode ) ) ;
memcpy ( & addr , base_addr + 4 , sizeof ( addr ) ) ;
memcpy ( & count , base_addr + 8 , sizeof ( count ) ) ;
memcpy ( & arg , base_addr + 12 , sizeof ( arg ) ) ;
printf ( " %08X %08X %08X %08X ( " , bcode , addr , count , arg ) ;
if ( addr % 4 )
printf ( " !!addralgn!! " ) ;
if ( count % 4 )
printf ( " !!cntalgn!! " ) ;
sign = ( bcode & BFLAG_HDRSIGN_MASK ) > > BFLAG_HDRSIGN_SHIFT ;
if ( sign ! = BFLAG_HDRSIGN_MAGIC )
printf ( " !!hdrsign!! " ) ;
chk = 0 ;
for ( i = 0 ; i < 16 ; + + i )
chk ^ = raw8 [ i ] ;
if ( chk )
printf ( " !!hdrchk!! " ) ;
printf ( " dma:%i " , bcode & BFLAG_DMACODE_MASK ) ;
for ( i = 0 ; i < ARRAY_SIZE ( ldr_flags ) ; + + i )
if ( bcode & ldr_flags [ i ] . flag )
printf ( " %s " , ldr_flags [ i ] . desc ) ;
if ( bcode & BFLAG_FILL )
count = 0 ;
if ( bcode & BFLAG_FINAL )
count = 0 ;
else
count + = sizeof ( bcode ) + sizeof ( addr ) + sizeof ( count ) + sizeof ( arg ) ;
# endif
printf ( " ) \n " ) ;
return count ;
}
static int do_ldrinfo ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
const void * addr ;
uint32_t skip ;
/* Get the address */
if ( argc < 2 )
addr = ( void * ) load_addr ;
else
addr = ( void * ) simple_strtoul ( argv [ 1 ] , NULL , 16 ) ;
/* Walk the LDR */
addr + = ldrinfo_header ( addr ) ;
do {
skip = ldrinfo_block ( addr ) ;
addr + = skip ;
} while ( skip ) ;
return 0 ;
}
U_BOOT_CMD (
ldrinfo , 2 , 0 , do_ldrinfo ,
" validate ldr image in memory " ,
" [addr] \n "
) ;