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

📄 gdb.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	        rc = GDB_ERROR_GENERAL;
		break;
	    }

            csum_rcv += char2hex( ch[i] );
        }
    }

    if( verbose )
    {
        if( rc == GDB_BREAK )
        {
	    printf( "(Break)" );
        }
        else
        {
	    printf( "(From Host : %s#%c%c)", buf, ch[0], ch[1] );
	}
    }

    if( (rc == GDB_OK) && checksum_on && (csum_rcv != csum_calc) )
        rc = GDB_ERROR_CSUM;

    return rc;
}

/************************************************************************
 *                          determine_reply
 ************************************************************************/
static UINT32
determine_reply(
    char *in_buf,
    char *out_buf,
    bool *ss )
{
    char        msg[80];
    int		i,t;
    UINT32	count;
    UINT64	val;
    UINT8	data;
    char	ch;
    UINT32	address, addr_kseg0;
    char	*ptr;
    UINT32	reg, size;
    bool	binary   = FALSE;
    UINT32	rc;

    /* Defaults */
    *ss   = FALSE;

    /* Start sequence */
    strcpy( out_buf, "$" );
    out_buf+=1;

	//printf3("cmd: \"%s\"\n",in_buf);
    ch = *in_buf;
    in_buf++;

	//printf3("key = %c\n",ch);
    switch( ch )
    {
		case '!' :
			/*
			*  extended ops	   !	Use the extended remote protocol.
			*				Sticky -- only needs to be set once.
			*/

			extended = TRUE;
			strcpy( out_buf, "OK" );
			break;

		case '?' :

			/*
			 *  last signal     ?           Reply the current reason for stopping.
			 *                              This is the same reply as is generated
			 *				for step or cont : SAA where AA is the
			 *				signal number.
			 */

			/* We always indicate TRAP */
			strcpy( out_buf, "S05" );
			break;

		case 'G' :

			/*
			 *  write 32 bit regs  GXX..XX	Each byte of register data
			 *				is described by two hex digits.
			 *  reply	       OK	for success
			 *		       ENN	for an error
			 */

			rc = write_regs( in_buf, sizeof(UINT32) );
			if( rc != GDB_OK )
				return rc;

			strcpy( out_buf, "OK" );
			break;

		case 'H' :

			/*
			 *  Set Thread (Hg | Hc) or "Write 64 bit regs" command.
			 *
			 *  Set Thread request is ignored.
			 *
			 *  Write 64 bit regs  HXX..XX	Each byte of register data
			 *				is described by two hex digits.
			 *  reply	       OK	for success
			 *		       ENN	for an error
			 */

			if( (*in_buf == 'g') || (*in_buf == 'c') )
			{
				/* Possibly "set thread" command */
				if( strlen( in_buf ) <= 18 )
				{
					*out_buf = '\0';
				break;
				}
				}

			/* Write 64 bit regs command */

			rc = write_regs( in_buf, sizeof(UINT64) );
			if( rc != GDB_OK )
				return rc;

			strcpy( out_buf, "OK" );
			break;

		case 'g' :

			/*
			 *  read registers  g[S]	Registers of size S
			 *  reply	    XX....X	Each byte of register data
			 *				is described by two hex digits.
			 *				Registers are in the internal order
			 *				for GDB, and the bytes in a register
			 *				are in the same order the machine uses.
			 *		    or ENN	for an error.
			 */

			if( *in_buf != '\0' )
			{
				size = gethex( in_buf, &ptr, &rc );

				if( (rc != GDB_OK) || (*ptr != '\0') )
					{
					return GDB_ERROR_GENERAL;
					}

				if( (size != sizeof(UINT32)) &&
				(size != sizeof(UINT64)) )
				{
				return GDB_ERROR_GENERAL;
				}
				}
			else
				size = sizeof(UINT32);

			read_regs( out_buf, size );
			break;

		case 'r' :

				/*
			 *  Read single register (SDE extension)   rNN[:S]    Register NN
			 *						       of size S
			 */

			reg = gethex( in_buf, &ptr, &rc );

			if( (rc != GDB_OK) || ( (*ptr != '\0') && (*ptr != ':') ) )
				{
				return GDB_ERROR_GENERAL;
				}
			else
				{
				if( *ptr == ':' )
				{
					ptr++;

					size = gethex( ptr, &ptr, &rc );

				if( (rc != GDB_OK) || (*ptr != '\0') )
				{
					return GDB_ERROR_GENERAL;
				}

				if( (size != sizeof(UINT32)) &&
					(size != sizeof(UINT64)) )
				{
					return GDB_ERROR_GENERAL;
				}
					}
				else
					size = sizeof(UINT32);
				}

			setval( &out_buf, SYS_CPUREG(&context, reg), size );
			*out_buf = '\0';

			break;

		case 'R' :
			/*
			 *  Command depends on whether we are running extended
			 *  protocol (due to '!' command) or not.
			 *
			 *  Normal   : Identical to 'P', see below.
			 *  Extended : Restart (reinitialise registers)
			 */

			if(extended && (*in_buf == '\0') )
			{
				init_data();
				strcpy( out_buf, "OK" );
				break;
			}

			/* Fallthrough !! */

		case 'P' :

			/*
			 *  Write single register (SDE extension)   PNN[:S]=XX    Register NN
			 *						          of size S
			 */

			reg = gethex( in_buf, &ptr, &rc );

			if( rc != GDB_OK )
				return GDB_ERROR_GENERAL;

			size = sizeof(UINT32);  /* Default */

			switch( *ptr )
			{
				case ':' :
					ptr++;
					size = gethex( ptr, &ptr, &rc );
					if( (rc != GDB_OK) || (size != sizeof(UINT32)) || (*ptr != '=') )
					{
						return GDB_ERROR_GENERAL;
					}
					if( (size != sizeof(UINT32)) && (size != sizeof(UINT64)) )
					{
						return GDB_ERROR_GENERAL;
					}
					/* FALL THROUGH ! */

				case '=' :
					ptr++;
					val = gethex( ptr, &ptr, &rc );
#ifdef EL
					val = (val >> 24) & 0x000000ff		// endian reversal
						| (val >> 8) & 0x0000ff00
						| (val << 8) & 0x00ff0000
						| (val << 24) & 0xff000000;
#endif
					if( (rc != GDB_OK) || (*ptr != '\0') )
					{
						return GDB_ERROR_GENERAL;
					}
					break;
				default  :
					return GDB_ERROR_GENERAL;
			}

			//printf3("  register %d = %08x\n",reg,val);
			SYS_CPUREG(&context, reg) = val;
			strcpy( out_buf, "OK" );
			break;

		case 'm' :

			/*
			 *  read mem	mAA..AA,LLLL	AA..AA is address, LLLL is length.
			 *  reply	XX..XX		XX..XX is mem contents
			 *				Can be fewer bytes than requested
			 *				if able to read only part of the data.
			 *		or ENN		NN is errno
			 */

			 /**** Fall through !! ****/

		case 'M' :

			/*
			 *  write mem	MAA..AA,LLLL:XX..XX
			 *				AA..AA is address,
			 *				LLLL is number of bytes,
			 *				XX..XX is data
			 *  reply	OK		for success
			 *		ENN		for an error (this includes the case
			 *				where only part of the data was
			 *				written).
			 */

			/* Find the ',' */
			ptr = strchr( in_buf, ',' );
			if( ptr )
			{
				*ptr = '\0';
				ptr++;

				/* Get address */
				address = gethex( in_buf, NULL, &rc );

				if( rc != GDB_OK )
				{
					//printf3("bad address\n");
					return GDB_ERROR_GENERAL;
				}

				/* Get count */
				count = gethex( ptr, NULL, &rc );

				if( rc != GDB_OK )
				{
					//printf3("bad count\n");
					return GDB_ERROR_GENERAL;
				}
			}

			if( !ptr )
			{
				//printf3("Missing comma\n");
				return GDB_ERROR_GENERAL;
			}
			else
			{
				/* Validate range */
				if( sys_validate_range( address,
							count,
							sizeof(UINT8),
							FALSE ) != OK )
				{
					//printf3("invalid range: %08x:%08x\n",address,count);
					return GDB_ERROR_ADDRESS;
				}

				if( ch == 'm' )
				{
					/* Read */
					for( i=0; i<count; i++ )
					{
						setval( &out_buf, (UINT64)REG8(address), sizeof(UINT8) );
						address++;
					}
				}
				else
				{
					/* Write (M command) */

					/* Find the ':' */
					ptr = strchr( ptr, ':' );

					if( !ptr )
					{
						//printf3("missing colon\n");
						return GDB_ERROR_GENERAL;
					}
					else
						ptr++;

					//printf3(" write mem: %08x:%08x\n",address,count);
					for( i=0; i<count; i++ )
					{
						rc = getval( &ptr, &val, sizeof(UINT8), FALSE );
						if( rc != GDB_OK )
						{
							//printf3("bad value: %02x, rc = %d\n",val,rc);
							return rc;
						}

						/* Convert to KSEG0 */
						sys_kseg0( address, &addr_kseg0 );
						//printf3("  Set Byte %08x = %02x\n",addr_kseg0,val);

						REG8(addr_kseg0) = (UINT8)val;

						/*
						 *  Flush D-cache in order to store data in
						 *  physical memory.
						 *  Invalidate I-cache since new instructions may
						 *  have been stored;
						 */

						sys_flush_cache_line( (void *)addr_kseg0 );

						address++;
					}

					strcpy( out_buf, "OK" );
					out_buf += 2;
				}

				*out_buf = '\0';
			}
			break;

		case 'C' :

			/*
			 *  continue with	Csig;AA..AA	Continue with signal sig (hex signal
			 *  signal				number).  If ;AA..AA is omitted,
			 *					resume at same address.
			 */

		case 'S' :

			/*
			 *  step with		Ssig;AA..AA	Like 'C' but step not continue.
			 *  signal
			 */

			 /* skip sig; sequence */

			 ptr = strchr( in_buf, ';' );

			 if( ptr )
				 in_buf = ptr + 1;

			 /**** Fall through !! ****/

		case 'c' :

			/*
			 *  continue	cAA..AA  	AA..AA is address to resume
			 *				If AA..AA is omitted,
			 *				resume at same address.
			 */

		case 's' :

			/*
			 *  step	sAA..AA		AA..AA is address to resume
			 *				If AA..AA is omitted,
			 *				resume at same address.
			 */

			if( *in_buf != '\0' )
			{
				/* Get address */
					address = gethex( in_buf, NULL, &rc );

				if( rc != GDB_OK )
					return GDB_ERROR_GENERAL;
				else
				{
					/* Store address in epc */
					context.cp0_epc = (INT64)((INT32)address);

					/* Clear ERL and set EXL so that EPC will be used upon eret */
					(UINT32)context.cp0_status &= ~C0_STATUS_ERL_BIT;
					(UINT32)context.cp0_status |= C0_STATUS_EXL_BIT;
				}
			}

			if( (ch == 's') || (ch =='S') )
			{
				if( !setup_single_step() )
					return GDB_ERROR_ADDRESS;
				*ss = TRUE;
			}

			return GDB_CONTINUE;

		case 'D' :

			/* detach         D               Reply OK. */

		case 'k' :

			/* kill request	k */

			strcpy( out_buf, "OK" );	/* Reply ignored by GBD for kill */
			return GDB_KILL;

		default  : /* Other */
			*out_buf = '\0';
			break;
	}
    return GDB_OK;
}

/************************************************************************
 *                          put_packet
 ************************************************************************/
static void
put_packet(
    char *buf )
{
    UINT8 csum      = 0;
    bool  calc_csum = FALSE;
    char  ch[2];
    char  *s = buf;

    while( *buf != '\0' )
    {
        PUTCHAR( GDB_PORT, *buf );

	if( calc_csum )
	    csum += (UINT8)(*buf);

	if( *buf == '$' )
	    calc_csum = TRUE;

	buf++;
    }

    if( calc_csum )
    {
        ch[0] = hex2char( csum >> 4 );
	ch[1] = hex2char( csum & 0xF );

        PUTCHAR( GDB_PORT, '#' );
        PUTCHAR( GDB_PORT, ch[0] );
        PUTCHAR( GDB_PORT, ch[1] );

        if( verbose )
        {
            printf( "(To Host : %s#%c%c)", s, ch[0], ch[1] );
        }

⌨️ 快捷键说明

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