⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 2 页
字号:
        /* 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 + -