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

📄 go.c

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

/************************************************************************
 *
 *  go.c
 *
 *  Shell go command
 *
 *  go [<address> [<args>]] [. <args>]
 *
 *
 * ######################################################################
 *
 * 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 <syscon_api.h>
#include <string.h>
#include <stdio.h>
#include <shell_api.h>
#include <yamon_api.h>
#include <string.h>
#include <mips.h>
#include <sys_api.h>
#include <excep_api.h>
#include <env_api.h>
#include "shell.h"

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


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

UINT32 shell_argc_appl; 
char   *(shell_argv_appl[SHELL_APPL_MAX_ARGS]);

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

static char *go_string = "go";

static t_gdb_regs   shell_context;
static t_gdb_regs   user_context;

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

static UINT32 
get_options(
    UINT32 argc,
    char   **argv,
    void   **address );

static void
shell_exception( void );

static void
user_exception( void );

static void
return_exception( void );

static void
update_epc(
    t_gdb_regs *regs );


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

/************************************************************************
 *                          go
 ************************************************************************/
static MON_FUNC(go)
{
    void   *address;
    UINT32 rc;

    /* Options */
    rc = get_options( argc, argv, &address );

    if( rc != OK )
        return rc;
    else
    {
        /**** Setup startup conditions ****/
	shell_setup_default_cpu( &user_context,
				 (UINT32)address );

	/**** Shift to user application ****/
        shell_shift_to_user( FALSE, NULL );
    }

    return OK;
}


/************************************************************************
 *                          get_options
 ************************************************************************/
static UINT32
get_options(
    UINT32 argc,
    char   **argv,
    void   **address )
{
    char	   *token;
    bool           ok   = TRUE;
    bool	   args = FALSE;
    bool	   addr_valid;
    t_shell_option decode;
    UINT32	   arg;
    UINT32	   error = SHELL_ERROR_SYNTAX;

    /* Defaults */
    if( shell_load_addr_valid )
    {
        *address   = shell_load_addr;
	addr_valid = TRUE;
    }
    else
        addr_valid = FALSE;

    shell_argc_appl    = 1;
    shell_argv_appl[0] = go_string;
    
    for( arg = 1; 
	          ok && 
	          (arg < argc) && 
		  (token = argv[arg]);
         arg++ )
    {
        if( args )
	{
	    if( shell_argc_appl == SHELL_APPL_MAX_ARGS )
	    {
	        return SHELL_ERROR_ARGV;
	    }
	    else
	    {
	        shell_argv_appl[shell_argc_appl] = token;
	        shell_argc_appl++;
	    }
        }
	else
	{
	    if( *token == '-' )
	    {
	        error		 = SHELL_ERROR_OPTION;
		shell_error_data = token;
		ok		 = FALSE;
	    }
            else if( strcmp( token, "." ) == 0 )
	    {
	        args = TRUE;
	    }
            else
	    {
		ok = shell_decode_number( &decode, NULL, token );

		if( ok )
		{
	            *address   = (void *)decode.number;
		    addr_valid = TRUE;
	            args       = TRUE;
		}
	    }
	}
    }

    if( !ok )
    {
	return error;
    }

    if( !addr_valid )
    {
	return SHELL_ERROR_ADDRESS_UNKNOWN;
    }

    return sys_validate_range( (UINT32)(*address), 
			       sizeof(UINT32), 
			       sizeof(UINT32),
			       FALSE );
}

/************************************************************************
 *                          shell_exception
 ************************************************************************/
static void
shell_exception( void )
{
    /* Called from exception handler (EXCEP_gdb_regs holds context) */

    /* Store shell context */
    memcpy( &shell_context, &EXCEP_gdb_regs, sizeof( t_gdb_regs ));

    /* increment EPC in order to skip instruction that caused
     * exception.
     */
    update_epc( &shell_context );

    return_exception();
}


/************************************************************************
 *                          user_exception
 ************************************************************************/
static void
user_exception( void )
{
    UINT64 epc;

    /* Called from exception handler (EXCEP_gdb_regs holds context) */

    /* Deregister default exc handler */
    EXCEP_register_esr( EXCEP_DEFAULT_HANDLER,
			FALSE,
			NULL, 
			NULL,
			NULL );

    /* Store user context */
    memcpy( &user_context, &EXCEP_gdb_regs, sizeof( t_gdb_regs ));

    /* Move user return value (v0) to shell context */
    SYS_CPUREG(&shell_context, SYS_CPUREG_V0) = 
        SYS_CPUREG(&user_context, SYS_CPUREG_V0);

    /*  Determine whether we arrived here :
     *  A) Due to an exception in the user application
     *  B) Due to a 'return' or call to exit()
     *  C) Due to a function vector call
     *
     *  Store result in v1
     */

    epc = *shell_get_epc( &user_context );

    if( sys_64bit )
    {
        if( !EXCEP_ejtag &&
	    (epc == (INT64)((INT32)shell_force_break)) )
	{
	    /* Function call or return. Code is stored in t0 */
            SYS_CPUREG(&shell_context, SYS_CPUREG_V1) = 
	        SYS_CPUREG(&user_context, SYS_CPUREG_T0);
	}
	else
	{
	    /* Exception */
            SYS_CPUREG(&shell_context, SYS_CPUREG_V1) = 
	        SHELL_FUNC_COUNT;
	}
    }
    else
    {
        if( !EXCEP_ejtag && 
	    ((UINT32)epc == (UINT32)shell_force_break) )
	{
	    /* Function call or return. Code is stored in t0 */
            SYS_CPUREG(&shell_context, SYS_CPUREG_V1) = 
	        SYS_CPUREG(&user_context, SYS_CPUREG_T0);
        }
	else
	{
	    /* Exception */
            SYS_CPUREG(&shell_context, SYS_CPUREG_V1) = 
	        SHELL_FUNC_COUNT;
        }
    }

    if( EXCEP_ejtag )
    {
        /* EJTAG exception is user application, so prepare for DERET */
	shell_context.cp0_depc = shell_context.cp0_epc;
    }

    /* Return to shell context */
    EXCEP_exc_handler_ret( &shell_context );
}

/************************************************************************
 *                          return_exception
 ************************************************************************/
static void
return_exception( void )
{
    /* Register BREAK exc handler */
    EXCEP_register_esr( C0_CAUSE_CODE_BP,
			FALSE,
			user_exception,
			NULL,
			NULL );

    /* Register default exc handler */
    EXCEP_register_esr( EXCEP_DEFAULT_HANDLER,
			FALSE,
			user_exception,
			NULL,
			NULL );

    /* Shift to user application */
    EXCEP_exc_handler_ret( &user_context );
}

/************************************************************************
 *				update_epc
 ************************************************************************/
static void
update_epc(
    t_gdb_regs *regs )
{
    *shell_get_epc( regs ) +=
        ((UINT32)regs->cp0_cause & C0_CAUSE_BD_BIT ) ?
	    8 : 4;
}


/* Command definition for help */
static t_cmd cmd_def =
{
    "go",
     go,
    "go [.|<address> [<args>]]",

    "Execute application code. If a target address is not specified, the\n"
    "address obtained from the last successful 'load' command (if any) is\n"
    "used as the target address. If arguments for the user program need\n"
    "to be specified, the default execution address can be referenced\n"
    "by a '.'.\n"
    "\n"
    "<args> is broken up in substrings and passed to the application.\n"
    "The first argument (argv[0]) will be the string 'go'.\n"
    "\n"
    "a0 is set to the number of substrings (argc).\n"
    "a1 is set to the address of an array of pointers to the substrings (argv).\n"

⌨️ 快捷键说明

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