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

📄 load.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

/************************************************************************
 *
 *  load.c
 *
 *  Shell load command
 * 
 *  load [-r]
 *       ([tftp:][//<ipaddr>][/<filename>]) |
 *       ([asc:] [//(tty0|tty1)])
 *
 *
 * ######################################################################
 *
 * Copyright (c) 1999-2000 MIPS Technologies, Inc. All rights reserved. 
 * 
 * Unpublished rights reserved under the Copyright Laws of the United States of 
 * America. 
 * 
 * This document contains information that is proprietary to MIPS Technologies, 
 * Inc. ("MIPS Technologies"). Any copying, modifying or use of this information 
 * (in whole or in part) which is not expressly permitted in writing by MIPS 
 * Technologies or a contractually-authorized third party is strictly 
 * prohibited. At a minimum, this information is protected under unfair 
 * competition laws and the expression of the information contained herein is 
 * protected under federal copyright laws. Violations thereof may result in 
 * criminal penalties and fines. 
 * MIPS Technologies or any contractually-authorized third party reserves the 
 * right to change the information contained in this document to improve 
 * function, design or otherwise. MIPS Technologies does not assume any 
 * liability arising out of the application or use of this information. Any 
 * license under patent rights or any other intellectual property rights owned 
 * by MIPS Technologies or third parties shall be conveyed by MIPS Technologies 
 * or any contractually-authorized third party in a separate license agreement 
 * between the parties. 
 * The information contained in this document constitutes one or more of the 
 * following: commercial computer software, commercial computer software 
 * documentation or other commercial items. If the user of this information, or 
 * any related documentation of any kind, including related technical data or 
 * manuals, is an agency, department, or other entity of the United States 
 * government ("Government"), the use, duplication, reproduction, release, 
 * modification, disclosure, or transfer of this information, or any related 
 * documentation of any kind, is restricted in accordance with Federal 
 * Acquisition Regulation 12.212 for civilian agencies and Defense Federal 
 * Acquisition Regulation Supplement 227.7202 for military agencies. The use of 
 * this information by the Government is further restricted in accordance with 
 * the terms of the license agreement(s) and/or applicable contract terms and 
 * conditions covering this information from MIPS Technologies or any 
 * contractually-authorized third party. 
 *
 ************************************************************************/


/************************************************************************
 *  Include files
 ************************************************************************/

#include <sysdefs.h>
#include <string.h>
#include <stdio.h>
#include <loader_api.h>
#include <shell_api.h>
#include <env_api.h>
#include <net_api.h>
#include "shell.h"

/************************************************************************
 *  Definitions
 ************************************************************************/

#define MSG_LOAD "Start = 0x$xxxxxxx, range = (0x$xxxxxxx,0x$xxxxxxx), format = $xxxxxxx"
#define MSG_LOAD_LEN	80

/* State event machine states */
#define ST_START		0
#define ST_GET_PROTOCOL		1
#define ST_GOT_PROTOCOL		2
#define ST_GET_SRC_OR_NAME	3
#define ST_GET_SRC		4
#define ST_GET_NAME		5
#define ST_DONE			6
#define ST_ERROR		7

/************************************************************************
 *  Public variables
 ************************************************************************/

void *shell_load_addr;
bool shell_load_addr_valid = FALSE;

/************************************************************************
 *  Static variables
 ************************************************************************/

/* load, min, max address */
static     void*  load_adr_context[3] ;

/* OPTIONS */
static t_cmd_option options[] =
{ 
  { "r",  "Retry on ARP timeout (until load succeeds or Ctrl-c is typed)" }
};
#define OPTION_COUNT	(sizeof(options)/sizeof(t_cmd_option))

static char arg_copy[SHELL_MAX_TOKEN_LEN+1];

static char *msg_hint_filename = "Filename must be preceeded with '/'";

/************************************************************************
 *  Static function prototypes
 ************************************************************************/

static UINT32 
get_options(
    UINT32 argc,
    char   **argv,
    bool   sdb,
    char   **s,
    bool   *retry );

static UINT32
parse(
    char   *s,
    UINT32 *protocol,
    UINT32 *src,
    char   **filename );

static UINT32
do_load(
    UINT32 port,
    UINT32 ip,
    char   *filename,
    bool   retry );

static UINT32
do_loaddata(
    UINT32 port,
    UINT32 ip,
    char   *filename,
    bool   retry );

static void
load_message(
    UINT32 protocol,
    UINT32 src,
    char   *filename );

/************************************************************************
 *  Implementation : Static functions
 ************************************************************************/

 /************************************************************************
 *                          loaddata
 ************************************************************************/
static MON_FUNC(loaddata)
{
    /* Options */
    char   *s;
    UINT32 protocol;
    UINT32 src;
    char   *filename;
    bool   retry;
    UINT32 rc;

    SHELL_DISABLE_MORE;
    
    rc = get_options( argc, argv, FALSE, &s, &retry );

    if( rc != OK )
        return rc;

    rc = parse( s, &protocol, &src, &filename );
    
    if( rc != OK )
        return rc;

    /* All OK */
    load_message( protocol, src, filename );

    rc = do_loaddata( (protocol == PROTOCOL_TFTP) ?
		   PORT_NET : src,
		   src, filename, retry );

    printf( "\n" );

    return rc;
}


 /************************************************************************
 *                          load
 ************************************************************************/
static MON_FUNC(load)
{
    /* Options */
    char   *s;
    UINT32 protocol;
    UINT32 src;
    char   *filename;
    bool   retry;
    UINT32 rc;

    SHELL_DISABLE_MORE;
    
    rc = get_options( argc, argv, FALSE, &s, &retry );

    if( rc != OK )
        return rc;

    rc = parse( s, &protocol, &src, &filename );
    
    if( rc != OK )
        return rc;

    /* All OK */
    load_message( protocol, src, filename );

    rc = do_load( (protocol == PROTOCOL_TFTP) ?
		   PORT_NET : src,
		   src, filename, retry );

    printf( "\n" );

    return rc;
}


/************************************************************************
 *                          load_sdb
 ************************************************************************/
static MON_FUNC(load_sdb)
{
    UINT32 rc;

    rc = get_options( argc, argv, TRUE, NULL, NULL );

    if( rc != OK )
        return rc;

    load_message( PROTOCOL_ASC, DEFAULT_PORT, NULL );

    rc = do_load( DEFAULT_PORT, 0, NULL, FALSE );

    printf( "\n" );
    return rc;
}



/************************************************************************
 *                          get_options
 ************************************************************************/
static UINT32 
get_options(
    UINT32 argc,
    char   **argv,
    bool   sdb,
    char   **s,
    bool   *retry )
{
    UINT32 i;

    if( !sdb )
    {
        *s     = NULL;
        *retry = FALSE;
    }

    for( i=1; i<argc; i++ )
    {
        if( *(argv[i]) == '-' )
	{
	    if( !sdb && (strcmp( argv[i], "-r" ) == 0) )
	    { 
	        *retry = TRUE;
	    }
	    else
	    {
		shell_error_data = argv[i];
		return SHELL_ERROR_OPTION;
	    }
	}
	else
	{
	    if( !sdb && !(*s) )
	    {
	        *s = arg_copy;
		strcpy( *s, argv[i] );
	    }
	    else
	        return SHELL_ERROR_SYNTAX;
	}
    }

    if( !sdb && !(*s) )
        *s = "";

    return OK;
}


/************************************************************************
 *                          load_message
 ************************************************************************/
static void
load_message(
    UINT32 protocol,
    UINT32 src,
    char   *filename )
{
    /* Protocol */
    printf( "About to load %s://", (protocol == PROTOCOL_TFTP) ?
				       "tftp" : "asc" );

    if( protocol == PROTOCOL_TFTP )
    {
        /* IP address */
        printf( "%d.%d.%d.%d/%s\n", 
                    (UINT32)(CPU_TO_BE32(src) >> 24),
                    (UINT32)(CPU_TO_BE32(src) >> 16) & 0xFF,
                    (UINT32)(CPU_TO_BE32(src) >> 8)  & 0xFF,
                    (UINT32)CPU_TO_BE32(src)         & 0xFF,
		    filename );
    }
    else
    {
        printf( (src == PORT_TTY0) ? "tty0\n" : "tty1\n" );
    }
}


/************************************************************************
 *                          do_load
 ************************************************************************/
static UINT32
do_loaddata(
    UINT32 port,
    UINT32 ip,
    char   *filename,
    bool   retry )
{
    char	   *insert, *format_string;
    UINT32	   error_pos;
    UINT32         raw_error;
    char	   ch;
    t_image_format format;
    char	   msg[MSG_LOAD_LEN];
    bool	   first_error = TRUE;
    UINT32	   rc;

    if(SHELL_PUTS( shell_msg_ctrl_c )) return OK;

    if(port != PORT_NET)
    {
	if(SHELL_PUTS( "\nStart dump from terminal program\n" )) 
	    return OK;	
    }

    do
    {    
        if( GETCHAR_CTRLC( DEFAULT_PORT ) )
	    return SHELL_ERROR_CONTROL_C_DETECTED;

        rc = loader_data(
	         port,
	         ip,
	         filename,
	         load_adr_context,
	         &format,
                 &error_pos,
                 &raw_error );

        /* read out load address */
        shell_load_addr       = load_adr_context[0] ;
	shell_load_addr_valid = TRUE;

        switch( rc )
        {
          case ERROR_LOAD_NONE :
	    break;	       /* Done */
          case ERROR_LOAD_BREAK :
	    return SHELL_ERROR_CONTROL_C_DETECTED;
          default :
            if( !retry )
            {
	        return raw_error;
            }

            if( raw_error != ERROR_NET_ARP_TIME_OUT )
            {
	        return raw_error;
            }
	    else
	    {
	        if( first_error )
		{
                    printf( "\n" );
		    first_error = FALSE;
		}

	        shell_command_error( NULL, raw_error );
	    }

    	    break;
        }

	if( rc != ERROR_LOAD_NONE )
	{
	    /* Pause 1 sec */
	    sys_wait_ms( 1000 );
	}
    }
    while( rc != ERROR_LOAD_NONE );

    /* insert start address */
    strcpy( msg, MSG_LOAD );
    insert = strchr( msg, '$' );
    ch = insert[sizeof(UINT32)*2];	    
    sprintf( insert, "%08x", (UINT32)load_adr_context[0] );
    insert[sizeof(UINT32)*2] = ch;

    /* insert min address */
    insert = strchr( msg, '$' );
    ch = insert[sizeof(UINT32)*2];	    
    sprintf( insert, "%08x", (UINT32)load_adr_context[1] );
    insert[sizeof(UINT32)*2] = ch;

    /* insert max address */
    insert = strchr( msg, '$' );
    ch = insert[sizeof(UINT32)*2];	    
    sprintf( insert, "%08x", (UINT32)load_adr_context[2] );
    insert[sizeof(UINT32)*2] = ch;

    switch( format )
    { 
      case MOTOROLA_S3 :
	format_string = "SREC"; break;
      case MICROSOFT_BIN :
	format_string = "WINCEBIN"; break;
      default :
	format_string = "UNKNOWN"; break;
    }

    insert = strchr( insert, '$' );
    sprintf( insert, "%s", format_string );
    printf( msg );

    return OK;
}

/************************************************************************
 *                          do_load
 ************************************************************************/
static UINT32
do_load(
    UINT32 port,
    UINT32 ip,
    char   *filename,
    bool   retry )
{
    char	   *insert, *format_string;
    UINT32	   error_pos;
    UINT32         raw_error;
    char	   ch;
    t_image_format format;
    char	   msg[MSG_LOAD_LEN];
    bool	   first_error = TRUE;
    UINT32	   rc;

    if(SHELL_PUTS( shell_msg_ctrl_c )) return OK;

    if(port != PORT_NET)
    {
	if(SHELL_PUTS( "\nStart dump from terminal program\n" )) 
	    return OK;	
    }

    do
    {    
        if( GETCHAR_CTRLC( DEFAULT_PORT ) )
	    return SHELL_ERROR_CONTROL_C_DETECTED;

        rc = loader_image(
	         port,
	         ip,
	         filename,
	         load_adr_context,
	         &format,
                 &error_pos,
                 &raw_error );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -