📄 gdb.c
字号:
/************************************************************************
*
* gdb.c
*
* Shell gdb command
*
* gdb [-v][-c] [. <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 <syserror.h>
#include <shell_api.h>
#include "shell.h"
#include <gdb_stub.h>
#include <string.h>
#include <mips.h>
#include <syscon_api.h>
#include <sys_api.h>
#include <ctype.h>
#include <stdio.h>
#include <mips.h>
/************************************************************************
* Definitions
************************************************************************/
#define GDB_OK 0
#define GDB_BREAK 1
#define GDB_ERROR_CSUM 2
#define GDB_CONTINUE 3
#define GDB_KILL 4
#define GDB_ERROR_GENERAL 5
#define GDB_ERROR_ADDRESS 6
#define GDB_APPL_DONE 7
/************************************************************************
* Public variables
************************************************************************/
/************************************************************************
* Static variables
************************************************************************/
#define DEBUG_PROTOCOL 1
/* OPTIONS */
static t_cmd_option options[] =
{
#define OPTION_VERBOSE 0
{ "v", "Display messages from and to GDB host" },
#define OPTION_CHECKSUM_OFF 1
{ "c", "Disable check of GDB checksum" }
};
#define OPTION_COUNT (sizeof(options)/sizeof(t_cmd_option))
/* Application context */
static t_gdb_regs context;
/* Arguments for application */
static char *gdb_string = "gdb";
/* Single stepping */
static UINT32 ss_count;
static UINT32 ss_addr[2];
static UINT32 ss_instr[2];
/* Verbose or not */
static bool verbose;
/* Enable checksum verification */
static bool checksum_on;
/* Extended protocol */
static bool extended;
/* Error codes */
static char *msg_e01 = "$E01 : Illegal format.";
static char *msg_e02 = "$E02 : Illegal address.";
static char *msg_e03 = "$E03 : Structural error in GDB-stub.";
/************************************************************************
* Static function prototypes
************************************************************************/
/************************************************************************
* Implementation : Static functions
************************************************************************/
static UINT32
get_options(
UINT32 argc,
char **argv );
static UINT32
get_packet(
char *buf );
static void
init_data( void );
static UINT32
determine_reply(
char *in_buf,
char *out_buf,
bool *ss );
static void
put_packet(
char *buf );
static bool
setup_single_step( void );
static bool
cleanup_single_step( void );
static char
get_char(
bool *ctrl_c );
static bool
valid_hex(
char ch );
static UINT64
gethex(
char *in_buf,
char **ptr,
UINT32 *rc );
static UINT32
getval(
char **in_buf,
UINT64 *val,
UINT8 size,
bool strict );
static void
setval(
char **out_buf,
UINT64 val,
UINT8 size );
static UINT8
char2hex(
char ch );
static char
hex2char(
UINT8 val );
static UINT32
write_regs(
char *in_buf,
UINT32 size );
static void
read_regs(
char *out_buf,
UINT32 size );
extern int printf3();
/************************************************************************
* gdb
************************************************************************/
static MON_FUNC(gdb)
{
#define MAXBUF 2048
char input_buffer[MAXBUF];
char output_buffer[MAXBUF];
bool ss;
UINT32 rc;
extended = FALSE;
rc = get_options( argc, argv );
if( rc != OK )
return rc;
printf( "Press Ctrl-C ");
printf("to return to YAMON\n" );
/* Flush input UART fifo */
while( GETCHAR( GDB_PORT, input_buffer ) );
/* Remote unit may have an output fifo, so
* give it a chance to empty it and flush again.
*/
sys_wait_ms(100);
while( GETCHAR( GDB_PORT, input_buffer ) );
init_data();
do
{
/* Get packet from GDB */
rc = get_packet( input_buffer );
//printf3("packet received, rc = %d\n",rc);
switch( rc )
{
case GDB_OK :
put_packet( "+" ); /* Transfer OK */
//printf3("ACK\n");
rc = determine_reply( input_buffer,
output_buffer,
&ss );
switch( rc )
{
case GDB_ERROR_GENERAL :
strcpy( output_buffer, msg_e01 );
//printf3("%s\n",msg_e01);
break;
case GDB_ERROR_ADDRESS :
strcpy( output_buffer, msg_e02 );
//printf3("%s\n",msg_e02);
break;
case GDB_KILL :
//printf3("Kill\n");
case GDB_OK :
/* output_buffer was written by determine_reply() */
break;
case GDB_CONTINUE :
/* Interrupts should be disabled */
//printf3("continue\n");
(UINT32)context.cp0_status &= ~C0_STATUS_IE_BIT;
/* Shift to user context */
if( shell_shift_to_user( TRUE, &context ) )
{
/* Application ended */
//printf3("Application exited\n");
sprintf( output_buffer, "$W%02x",
(UINT8)SYS_CPUREG(&context, SYS_CPUREG_V0) );
rc = GDB_APPL_DONE;
}
else
{
/* Exception */
if( REGFIELD( (UINT32)context.cp0_cause, C0_CAUSE_CODE ) ==
C0_CAUSE_CODE_BP )
{
/* Breakpoint */
//printf3("At breakpoint.\n");
strcpy( output_buffer, "$S05" );
}
else
{
/* Other exception */
//printf3("at exception.\n");
strcpy( output_buffer, "$X0f" );
}
}
if( ss )
{
/* Break due to single step */
if( !cleanup_single_step() )
{
strcpy( output_buffer, msg_e02 );
}
}
break;
default : /* Should not happen */
strcpy( output_buffer, msg_e03 );
break;
}
break;
case GDB_ERROR_CSUM :
//printf3("Checksum ");
case GDB_ERROR_GENERAL :
//printf3("error\n");
strcpy( output_buffer, "-$" );
break;
case GDB_BREAK :
//printf3("Break\n");
break;
default : /* Should not happen */
//printf3("huh?\n");
break;
}
if( rc != GDB_BREAK )
{
/* Write reply */
put_packet( output_buffer );
}
}
while( (rc != GDB_BREAK) &&
(rc != GDB_KILL) &&
(rc != GDB_APPL_DONE) );
if( verbose )
printf( "\n" );
return OK;
}
/************************************************************************
* get_options
************************************************************************/
static UINT32
get_options(
UINT32 argc,
char **argv )
{
UINT32 arg, i;
bool ok = TRUE;
UINT32 error = SHELL_ERROR_SYNTAX;
bool args = FALSE;
char *token;
/* Setup defaults */
verbose = FALSE;
checksum_on = TRUE;
shell_argc_appl = 1;
shell_argv_appl[0] = gdb_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( strcmp( token, "-v" ) == 0 )
{
verbose = TRUE;
}
else if( strcmp( token, "-c" ) == 0 )
{
checksum_on = FALSE;
}
else if( *token == '-' )
{
error = SHELL_ERROR_OPTION;
shell_error_data = token;
ok = FALSE;
}
else if( strcmp( token, "." ) == 0 )
{
args = TRUE;
}
else
ok = FALSE;
}
}
return ok ? OK : error;
}
/************************************************************************
* init_data
************************************************************************/
static void
init_data( void )
{
/* Setup initial context including EPC */
shell_setup_default_cpu( &context,
shell_load_addr_valid ?
(UINT32)shell_load_addr :
0 );
}
/************************************************************************
* get_packet
************************************************************************/
static UINT32
get_packet(
char *buf )
{
char ch[2];
char *rcv;
UINT8 csum_calc, csum_rcv;
UINT8 i;
bool ctrl_c;
UINT32 rc = GDB_OK;
/* Wait for '$' */
do
{
ch[0] = get_char( &ctrl_c );
if( ctrl_c )
{
rc = GDB_BREAK;
break;
}
}
while( (ch[0] != '$') );
/* Get packet contents, excluding cheksum bytes */
if( rc == GDB_OK )
{
rcv = buf;
csum_calc = 0;
do
{
ch[0] = get_char( &ctrl_c );
if( ctrl_c )
{
rc = GDB_BREAK;
break;
}
switch( ch[0] )
{
case '$' :
/* Start again */
rcv = buf;
csum_calc = 0;
break;
case '#' :
/* End */
*rcv = '\0';
break;
default :
/* Packet */
*rcv = ch[0];
csum_calc += (UINT8)ch[0];
rcv++;
break;
}
}
while( ch[0] != '#' );
}
/* Get checksum bytes */
if( rc == GDB_OK )
{
for(i=0; i<2; i++)
{
ch[i] = get_char( &ctrl_c );
if( ctrl_c )
{
rc = GDB_BREAK;
break;
}
}
}
/* Validate checksum (if not disabled by the -c command option) */
if( (rc == GDB_OK) && checksum_on )
{
csum_rcv = 0;
for(i=0; i<2; i++)
{
csum_rcv <<= 4;
if( !valid_hex( ch[i] ) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -