📄 loader.c
字号:
/* 237: */ INVALID_CHAR,
/* 238: */ INVALID_CHAR,
/* 239: */ INVALID_CHAR,
/* 240: */ INVALID_CHAR,
/* 241: */ INVALID_CHAR,
/* 242: */ INVALID_CHAR,
/* 243: */ INVALID_CHAR,
/* 244: */ INVALID_CHAR,
/* 245: */ INVALID_CHAR,
/* 246: */ INVALID_CHAR,
/* 247: */ INVALID_CHAR,
/* 248: */ INVALID_CHAR,
/* 249: */ INVALID_CHAR,
/* 250: */ INVALID_CHAR,
/* 251: */ INVALID_CHAR,
/* 252: */ INVALID_CHAR,
/* 253: */ INVALID_CHAR,
/* 254: */ INVALID_CHAR,
/* 255: */ INVALID_CHAR
} ;
/************************************************************************
* Static function prototypes
************************************************************************/
static UINT32 loader_readline( UINT32 port ) ;
static INT32 loader_error_lookup( t_sys_error_string *p_param ) ;
static UINT32
load_srec(
UINT32 port, /* Port number */
UINT32 ip, /* IP address (valid for NET) */
char *filename, /* valid for net */
void **addr, /* Start address */
t_image_format *imageformat, /* Output : Format */
UINT32 *error_pos, /* Output : Position of error */
UINT32 *raw_error ); /* Output : Raw error of subsys */
/************************************************************************
* Implementation : Public functions
************************************************************************/
/************************************************************************
*
* loader_init
* Description :
* -------------
*
* Init load module
*
* Return values :
* ---------------
*
* None
*
************************************************************************/
void
loader_init( void )
{
t_sys_error_lookup_registration registration ;
/* register lookup syserror */
registration.prefix = SYSERROR_DOMAIN( ERROR_LOADER ) ;
registration.lookup = loader_error_lookup ;
SYSCON_write( SYSCON_ERROR_REGISTER_LOOKUP_ID,
®istration,
sizeof( registration ) );
formats[0].func = load_srec;
}
/************************************************************************
*
* loader_data
* Description :
* -------------
*
* Load data from serial port or Ethernet
*
* Return values :
* ---------------
*
* OK if no error, else error code (see loader_api.h)
*
************************************************************************/
UINT32
loader_data(
UINT32 port, /* Port number */
UINT32 ip, /* IP addr (valid for PORT_NET) */
char *filename, /* valid for PORT_NET */
void **addr, /* Output : Start address */
t_image_format *imageformat, /* Output : Format */
UINT32 *error_pos, /* Output : Position of error */
UINT32 *raw_error ) /* Output : Raw error from subs */
{
bool fit[LOAD_FORMATS];
UINT32 pos = 0;
UINT32 maxid = 0;
t_load_format *format = NULL;
UINT32 f, rc;
char ch;
/* clear error context */
loader_last_error = OK ;
sid = 0 ;
sdata[0] = 0 ;
failing_line_no = 0 ;
failing_line_no_adjust = 0 ;
line_termination_is_linefeed = FALSE ; /* default to expect */
*raw_error = OK ; /* default completion */
UINT8 *pdest = 0xA0100000;
UINT32 size = 0x04000000;
if( (port != PORT_TTY0) && (port != PORT_TTY1) && (port != PORT_NET) )
{
*raw_error = ERROR_LOAD_UNSUPPORTED_PORT ;
return ERROR_LOAD_UNSUPPORTED_PORT;
}
/* If we are loading from net, open file */
if (port==PORT_NET)
{
*raw_error = net_open( ip, filename ) ;
if (*raw_error != OK)
{
if (*raw_error == ERROR_NET_USER_BREAK)
return( ERROR_LOAD_BREAK ) ;
return( ERROR_LOAD_NET );
}
}
*raw_error = NET_file_read(ip, filename, pdest, &size ) ;
if ( *raw_error != OK ) return( *raw_error ) ;
{
/* Flush and invalidate DCACHE, so that
* old writeback data will not corrupt the new
* image
*/
sys_dcache_flush_all();
return OK;
}
} // END NEW FUNCTION
/************************************************************************
*
* loader_image
* Description :
* -------------
*
* Load image from serial port or Ethernet
*
* Return values :
* ---------------
*
* OK if no error, else error code (see loader_api.h)
*
************************************************************************/
UINT32
loader_image(
UINT32 port, /* Port number */
UINT32 ip, /* IP addr (valid for PORT_NET) */
char *filename, /* valid for PORT_NET */
void **addr, /* Output : Start address */
t_image_format *imageformat, /* Output : Format */
UINT32 *error_pos, /* Output : Position of error */
UINT32 *raw_error ) /* Output : Raw error from subs */
{
bool fit[LOAD_FORMATS];
UINT32 pos = 0;
UINT32 maxid = 0;
t_load_format *format = NULL;
UINT32 f, rc;
char ch;
/* clear error context */
loader_last_error = OK ;
sid = 0 ;
sdata[0] = 0 ;
failing_line_no = 0 ;
failing_line_no_adjust = 0 ;
line_termination_is_linefeed = FALSE ; /* default to expect */
*raw_error = OK ; /* default completion */
if( (port != PORT_TTY0) && (port != PORT_TTY1) && (port != PORT_NET) )
{
*raw_error = ERROR_LOAD_UNSUPPORTED_PORT ;
return ERROR_LOAD_UNSUPPORTED_PORT;
}
/* First identify the format */
for(f=0; f<LOAD_FORMATS; f++)
{
maxid = MAX(maxid, strlen(formats[f].id));
fit[f] = TRUE;
}
/* If we are loading from net, open file */
if (port==PORT_NET)
{
*raw_error = net_open( ip, filename ) ;
if (*raw_error != OK)
{
if (*raw_error == ERROR_NET_USER_BREAK)
return( ERROR_LOAD_BREAK ) ;
return( ERROR_LOAD_NET );
}
}
/* read line */
*raw_error = loader_readline( port ) ;
*error_pos = failing_line_no ;
if ( *raw_error != OK ) return( *raw_error ) ;
/* check format */
ch = sdata[sid++] ;
for(f=0; f<LOAD_FORMATS; f++)
{
if( (strlen(formats[f].id) > pos) &&
(ch != formats[f].id[pos]) )
{
fit[f] = FALSE;
}
}
for(f=0; f<LOAD_FORMATS; f++)
{
if( fit[f] )
{
if( format )
{
*raw_error = ERROR_LOAD_AMBIGUOUS_TYPE ;
return ERROR_LOAD_AMBIGUOUS_TYPE;
}
else
{
format = &formats[f];
}
}
}
if( !format || !format->func )
{
*raw_error = ERROR_LOAD_UNKNOWN_TYPE ;
return ERROR_LOAD_UNKNOWN_TYPE;
}
else
{
if( (port == PORT_TTY0) || (port == PORT_TTY1) )
{
/* Disable any not critical but time consuming
* polling operations while we are loading in
* order not to risk overflow in UART buffers.
*/
sys_poll_enable( FALSE );
}
/* Flush and invalidate DCACHE, so that
* old writeback data will not corrupt the new
* image
*/
sys_dcache_flush_all();
/* Run the load protocol */
rc = format->func(
port,
ip,
filename,
addr,
imageformat,
error_pos,
raw_error );
/* Flush caches */
sys_flush_caches();
if( (port == PORT_TTY0) || (port == PORT_TTY1) )
{
/* Reenable polling */
sys_poll_enable( TRUE );
}
/* Hack to return net derived error */
if (port==PORT_NET)
{
if (net_last_error != OK)
{
*raw_error = net_last_error ;
if (*raw_error == ERROR_NET_USER_BREAK)
return( ERROR_LOAD_BREAK ) ;
return( ERROR_LOAD_NET );
}
}
return rc;
}
}
/************************************************************************
* Implementation : Static functions
************************************************************************/
/************************************************************************
* load_srec
************************************************************************/
static UINT32
load_srec(
UINT32 port, /* Port number */
UINT32 ip, /* IP address (valid for NET) */
char *filename, /* valid for net */
void **addr, /* Start address */
t_image_format *imageformat, /* Output : Format */
UINT32 *error_pos, /* Output : Position of error */
UINT32 *raw_error ) /* Output : Raw error of subsys */
{
#define OFFSET_COUNT 3
#define OFFSET_ADDRESS 4
#define OFFSET_DATA_S37 8
#define OFFSET_DATA_S28 7
#define OFFSET_DATA_S19 6
UINT8 type, ch;
UINT8 checksum;
UINT32 rc, offset, offset_data;
UINT8 data[MAX_LINE_SIZE]; /* Must be UINT32 alligned */
UINT8 val = 0;
UINT8 ch_val ;
bool odd = TRUE;
t_FLASH_write_descriptor flash_write ;
UINT32 count = 0;
UINT32 dot_count = 0;
char disp_msg[10];
*imageformat = MOTOROLA_S3;
rc = 0xffffffff ;
(UINT32)addr[0] = 0 ;
(UINT32)addr[1] = rc ;
(UINT32)addr[2] = 0 ;
/* Layout for S3
*
* 0..2 : Not used
* 3 : count
* 4..7 : address
* 8..8+count-1 : data
* 8+count : checksum
*/
SHELL_DISABLE_MORE;
while(TRUE)
{
if( !(count % COUNT_DISP_INTERVAL) )
{
if( port == PORT_NET )
{
if(!dot_count)
printf("\n") ;
if(shell_print_dot( &dot_count ))
return ERROR_LOAD_BREAK;
}
}
count++;
/* Read type */
type = sdata[sid++] ;
if( (type == '3') || (type == '7') ||
(type == '2') || (type == '8') ||
(type == '1') || (type == '9') ||
(type == '0') || (type == '5') )
{
/* Read line */
offset = OFFSET_COUNT;
offset_data = 0 ;
if ( (type == '3') || (type == '7') )
{
offset_data = OFFSET_DATA_S37; /* Only relevant for S3/S7 records */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -