📄 loader.c
字号:
/* 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 UINT32load_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_37 3#define OFFSET_COUNT_28 4#define OFFSET_COUNT_19 5#define OFFSET_ADDRESS 4#define OFFSET_DATA 8 UINT32 type, ch; UINT32 checksum; UINT32 rc, offset, offset_count, bytecount, my_addr; UINT8 data[MAX_LINE_SIZE]; /* Must be UINT32 alligned */ UINT32 val; t_FLASH_write_descriptor flash_write ; UINT32 count = 0; UINT32 dot_count = 0; UINT32 ix; *imageformat = MOTOROLA_S3; addr[0] = (UINT32*)0 ; addr[1] = (UINT32*)0xffffffff ; addr[2] = (UINT32*)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 )) { rc = ERROR_LOAD_BREAK; goto done; } } } count++; /* Read type */ type = sdata[1] ; /* Read line */ if (type == '3') offset_count = OFFSET_COUNT_37; else if (type == '7') offset_count = OFFSET_COUNT_37; else if (type == '2') offset_count = OFFSET_COUNT_28; else if (type == '8') offset_count = OFFSET_COUNT_28; else if (type == '1') offset_count = OFFSET_COUNT_19; else if (type == '9') offset_count = OFFSET_COUNT_19; else if (type == '0') offset_count = 0; else if (type == '5') offset_count = 0; else { rc = ERROR_LOAD_ILLEGAL_FORMAT; goto done; } checksum = 0; offset = offset_count; ix = 2; /* Convert line */ while (TRUE) { ch = sdata[ix++] ; /* get next character */ val = char2val[ch] ; /* convert character */ if ( val & NO_HEX ) { if ( val == NO_HEX ) { rc = ERROR_LOAD_ILLEGAL_CHARACTER ; goto done; } /* check rest of line, must contain VALID_SPACE only */ while (ch) { ch = sdata[ix++] ; /* get char */ if ( char2val[ch] != VALID_SPACE ) { rc = ERROR_LOAD_ILLEGAL_FORMAT; goto done; } } break; } ch = sdata[ix++] ; /* get next character */ ch = char2val[ch] ; /* convert character */ if ( ch & NO_HEX ) { rc = ( ch == NO_HEX ) ? ERROR_LOAD_ILLEGAL_CHARACTER : ERROR_LOAD_ILLEGAL_FORMAT; goto done; } /* Store value */ val = (val << 4) | ch ; data[offset++] = val; checksum += val; } /* Do various checks (don't perform checks for S0/S5 since * they are discarded anyway. */ if( offset_count ) { /* Check count */ if( offset - offset_count - 1 != data[offset_count] ) { rc = ERROR_LOAD_ILLEGAL_FORMAT; goto done; } /* Check that enough data is available */ if( offset < OFFSET_DATA + 1 ) { rc = ERROR_LOAD_ILLEGAL_FORMAT; goto done; } /* Check checksum */ if( (checksum & 0xff) != 0xff) { rc = ERROR_LOAD_CHECKSUM ; goto done; } /* Address */ if ( type != '3' ) { if ( type == '2' ) { /* 3-byte address is kept in 5-7 */ data[OFFSET_ADDRESS] = 0 ; } else if ( type == '8' ) { /* 3-byte address is kept in 5-7 */ data[OFFSET_ADDRESS] = 0 ; } else if ( type == '1' ) { /* 2-byte address is kept in 6-7 */ data[OFFSET_ADDRESS] = 0 ; data[OFFSET_ADDRESS+1] = 0 ; } else if ( type == '9' ) { /* 2-byte address is kept in 6-7 */ data[OFFSET_ADDRESS] = 0 ; data[OFFSET_ADDRESS+1] = 0 ; } }#ifdef EL my_addr = SWAPEND32( *(UINT32*)&data[OFFSET_ADDRESS] );#else my_addr = (*(UINT32 *)&data[OFFSET_ADDRESS]);#endif /* Decode line */ bytecount = offset - OFFSET_DATA - 1; if (type <= '3') { /* S3, S2 or S1 record (data record) */ if(bytecount) { /* Write data to RAM/FLASH * * dst addr = (UINT32)*addr * src addr = &data[OFFSET_DATA] */ /* check range context to return this at load end */ if ( (UINT32)addr[1] > my_addr ) addr[1] = (void *)my_addr ; if ( (UINT32)addr[2] < (my_addr+bytecount-1) ) addr[2] = (void *)(my_addr+bytecount-1) ; /* Validate address */ rc = sys_validate_range( my_addr, bytecount, sizeof(UINT8), TRUE ); if (rc != OK) goto done; flash_write.adr = my_addr; flash_write.length = bytecount ; flash_write.buffer = &data[OFFSET_DATA] ; rc = IO_write( SYS_MAJOR_FLASH_STRATA, 0, &flash_write ) ; if (rc != OK) goto done; /* indicate address in alpha-display */ DISP( my_addr ) ; } } else { /* S7, S8 or S9 record (end record) */ if( port == PORT_NET ) { /* This just to guarantee proper report */ printf("\n") ; } if (bytecount != 0 ) { rc = ERROR_LOAD_ILLEGAL_FORMAT; goto done; } /* return last address read */ addr[0] = (void *)my_addr; rc = OK; goto done; } } /* read next line */ rc = loader_readline( port ) ; if ( rc != OK ) goto done; ch = sdata[0] ; if( toupper(ch) != 'S' ) { rc = ERROR_LOAD_ILLEGAL_FORMAT; goto done; } }done: *error_pos = line_number ; *raw_error = rc ; return rc;}/************************************************************************ * loader_readline ************************************************************************/static UINT32 loader_readline( UINT32 port ) { UINT8 ch8; UINT32 ch ; UINT32 sid ; UINT32 rc ; /* adjust line number counter */ /* line number is increased here and by leading LF */ if (eol_was_cr) { /* previous line ended with CR, so await leading LF */ eol_was_cr = FALSE ; } else { line_number++; } /* clear actual line */ sid = 0 ; /* do read lines until any not empty found */ rc = OK; while ( sid == 0 ) { do { while( !GETCHAR( port, &ch8 ) ) { /* check for user break */ if (port != DEFAULT_PORT ) { if (GETCHAR_CTRLC( DEFAULT_PORT )) { rc = ERROR_LOAD_BREAK; goto out; } } } ch = ch8; if ( char2val[ch] & NO_HEX ) { /* check for user break */ if (( ch == CTRL_C ) && (port != PORT_NET)) { rc = ERROR_LOAD_BREAK ; goto out; } if ( ch == (EOF_SREC & 0xff) ) { /* check for End Of File; used by TFTP */ sid = 0 ; /* clear current line */ rc = ERROR_LOAD_NO_S7_RECORD; goto out; } if ( ch == (UART_ERROR & 0xff) ) { /* UART communication error */ rc = ERROR_LOAD_UART_COMM_ERROR; goto out; } /* Check for NULL chars */ if ( ch == 0 ) { /* raw null characters are never expected */ /* turned into '?' to make them printable */ ch = '?'; } /* Check for unexpected chars */ if ( char2val[ch] == NO_HEX ) { /* turn not-printable into '?' */ if (!isprint(ch)) { ch = '?'; } } if ( sid == 0 ) { /* line is still empty */ if ( ch == LF ) { /* leading NL increments line counter */ line_number++; } if ( char2val[ch] == VALID_SPACE ) { /* ignore lading white space characters */ continue; } } } /* check line size */ if (sid >= MAX_LINE_SIZE) { /* terminate line and return error */ rc = ERROR_LOAD_LINE_TOO_LONG; goto out; } /* save character */ sdata[sid++] = ch ; if ( ch == CR ) { /* We got CR as eol - return and make ready for next call */ eol_was_cr = TRUE ; break; } } while( ch != LF ) ; } rc = OK;out: sdata[sid] = 0 ; /* remember to allocate space for the NUL-termination */ return rc;}staticINT32 loader_error_lookup( t_sys_error_string *p_param ){ UINT32 t, i ; i = 0 ; p_param->count = 0 ; t = SYSERROR_ID( p_param->syserror ) ; /* check for recognized error code */ if (t < sizeof(loader_error_string)/sizeof(char*) ) { /* fill in mandatory error message string */ p_param->strings[SYSCON_ERRORMSG_IDX] = loader_error_string[t] ; i++ ; /* check for diagnose message */ if ( sdata[0] != 0 ) { /* fill in optional diagnose message string */ sprintf( loader_diag_msg,"Line %d, %s", line_number, sdata ) ; p_param->strings[SYSCON_DIAGMSG_IDX] = loader_diag_msg ; i++ ; } /* check for hint message */ if ( loader_error_hint_string[t] != NULL) { /* fill in optional hint message string */ p_param->strings[SYSCON_HINTMSG_IDX] = loader_error_hint_string[t] ; i++ ; } } p_param->count = i ; return(OK) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -