📄 gdb_c_test.c
字号:
* * * RETURN VALUE: None. * * * USED GLOBAL VARIABLES: * * * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: * * * NOTES: * * *---------------------------------------------------------------------------*/static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue ){ if ( p_queue ) /* Sanity check. */ { if ( c & 0x000000FF ) /* We don't allow NULL characters to be added to a queue. */ { /* Insert the new character at the tail of the queue. */ p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF); /* Increment the tail index. */ if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) ) { p_queue->tail_index = 0; } /* Check for wrapping (i.e. overflow). */ if ( p_queue->head_index == p_queue->tail_index ) { /* If the tail has caught up to the head record the overflow . . . */ ++(p_queue->overflows); /* . . . then increment the head index. */ if ( MAX_RS232_CHARS <= ++(p_queue->head_index) ) { p_queue->head_index = 0; } } } /* End of 'if ( c & 0x000000FF )'. */ } /* End of 'if ( p_queue )'. */ return;}/* end of 'lan_add_to_queue' *===========================================================================*//*----------------------------------------------------------------------------- * * FUNCTION NAME: lan_next_queue_char * * DESCRIPTION: * * RETURN VALUE: * * USED GLOBAL VARIABLES: * * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: * * NOTES: * *---------------------------------------------------------------------------*/static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue ){ UCHAR c; c = 0; if ( p_queue ) { if ( p_queue->head_index != p_queue->tail_index ) { /* Return the 'oldest' character in the queue. */ c = p_queue->buf[ p_queue->head_index ]; /* Increment the head index. */ if ( MAX_RS232_CHARS <= ++(p_queue->head_index) ) { p_queue->head_index = 0; } } } /* End of 'if ( p_queue )'. */ return( c );}/* end of 'lan_next_queue_char' *===========================================================================*//*----------------------------------------------------------------------------- * * FUNCTION NAME: lan_util_menu * * DESCRIPTION: Prints out a brief help on the LAN UART control utility. * * RETURN VALUE: None. * * USED GLOBAL VARIABLES: None. * * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None. * * NOTES: None. * *---------------------------------------------------------------------------*/static void lan_util_menu( void ){ /* * Multiply calling printp() below is made due to the limitations * of printp(), incapable of handling long formatting constants: */ printp( "\n -- Options --\n\n" ); printp( " %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE ); printp( " %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );/*** printp( " %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );***/ printp( " <rate>: 4800 <mode>: E - enable <action>: C - clear/reset\n" ); printp( " 9600 D - disable D - display\n" ); printp( " 19200 F - fetch next char\n" ); printp( " 38400\n" );}/* end of 'lan_util_menu' *===========================================================================*//* Thu Feb 5 17:14:41 EST 1998 CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */static long get_gdb_input( long c, T_RS232_QUEUE * p_input_q ){ /* Now to detect when we've got a gdb packet... */ if ( '$' == c ) { /* char marks beginning of a packet */ if ( -1 != p_input_q->gdb_packet_start || -1 != p_input_q->gdb_packet_end || -1 != p_input_q->gdb_packet_csum1 || -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */ /* NEW: Actually, this probably means that we muffed a packet, and GDB has already resent it. The thing to do now is to throw away the one we WERE working on, but immediately start accepting the new one. Don't NAK, or GDB will have to try and send it yet a third time! */ /*NACK_PKT( );*/ /*<ETHERNET>*/ discard_packet( ); /* throw away old packet */ lan_add_to_queue ('$', p_input_q); /* put the new "$" back in */ return 0; } else { /* match new "$" */ p_input_q->gdb_packet_start = p_input_q->tail_index; p_input_q->gdb_packet_end = p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1; } } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */ if ( -1 == p_input_q->gdb_packet_start || -1 != p_input_q->gdb_packet_end || -1 != p_input_q->gdb_packet_csum1 || -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */ /* Garbled packet. Discard, but do not NAK. */ /*NACK_PKT( );*/ /*<ETHERNET>*/ discard_packet( ); return -1; } p_input_q->gdb_packet_end = p_input_q->tail_index; p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1; } else if ( -1 != p_input_q->gdb_packet_start && -1 != p_input_q->gdb_packet_end) { if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */ if ( -1 == p_input_q->gdb_packet_csum1 && LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) == p_input_q->tail_index ) { /* first checksum digit */ p_input_q->gdb_packet_csum1 = p_input_q->tail_index; p_input_q->gdb_packet_csum2 = -1; } else if ( -1 == p_input_q->gdb_packet_csum2 && LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) == p_input_q->tail_index ) { /* second checksum digit: packet is complete! */ p_input_q->gdb_packet_csum2 = p_input_q->tail_index; getpacket(); /* got a packet -- extract it */ } else { /* probably can't happen (um... three hex digits?) */ /* PROTOCOL ERROR */ /* Not sure how this can happen, but ... discard it, but do not NAK it. */ /*NACK_PKT( );*/ /*<ETHERNET>*/ discard_packet( ); return -1; } } else { /* '#' followed by non-hex char */ /* PROTOCOL ERROR */ /* Bad packet -- discard but do not NAK */ /*NACK_PKT( );*/ /*<ETHERNET>*/ discard_packet( ); return -1; } } return 0;}#ifdef STANDALONE/* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone Enable stand-alone build, for ease of debugging stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */long write_to_protected_mem (addr, word) void *addr; unsigned short word;{ return 0;}char dummy_memory[0x4000];int main ( void ){ long c; lan_init_queue( &lan_input_queue ); printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) ); printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory); while ( (c = getc( stdin ) ) != EOF ) { if ( c == '\\' ) /* escape char */ break; lan_add_to_queue( c, &lan_input_queue ); get_gdb_input (c, &lan_input_queue); fflush( stdout ); } printf( "Goodbye!\n" ); exit( 0 );}#define SRAM_START ((void *) (&dummy_memory[0] + 0x00000000))#define SRAM_END ((void *) (&dummy_memory[0] + 0x00000400))#define RO_AREA_START ((void *) (&dummy_memory[0] + 0x00000100))#define RO_AREA_END ((void *) (&dummy_memory[0] + 0x00000300))#define NVD_START ((void *) (&dummy_memory[0] + 0x00003000))#define NVD_END ((void *) (&dummy_memory[0] + 0x00003100))#else /* normal stub (not stand-alone) */#define SRAM_START ((void *) 0x00000000)#define SRAM_END ((void *) 0x00400000)#define RO_AREA_START ((void *) 0x00100000)#define RO_AREA_END ((void *) 0x00300000)#define NVD_START ((void *) 0x03000000)#define NVD_END ((void *) 0x03100000)#endif /* STANDALONE *//* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb Here begins the gdb stub section. gdb gdb The following functions were added by Cygnus, gdb gdb to make this thing act like a gdb stub. gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb *//* ------------------- global defines and data decl's -------------------- */#define hexchars "0123456789abcdef"/* there are 180 bytes of registers on a 68020 w/68881 *//* many of the fpa registers are 12 byte (96 bit) registers */#define NUMREGBYTES 180#define NUMREGS 29#define REGISTER_BYTE(regno) regnoenum regnames { D0, D1, D2, D3, D4, D5, D6, D7, A0, A1, A2, A3, A4, A5, A6, A7, PS, PC, FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7, FPCONTROL, FPSTATUS, FPIADDR };unsigned long registers[NUMREGBYTES/4];static long remote_debug;#define BUFMAX MAX_IO_BUF_SIZEstatic char inbuffer[BUFMAX], outbuffer[BUFMAX];static char spare_buffer[BUFMAX];struct stub_trace_frame{ int valid; unsigned long frame_id; unsigned long tdp_id; FRAME_DEF *frame_data; COLLECTION_FORMAT_DEF *format; unsigned long traceregs[NUMREGBYTES/4]; unsigned char *stack_data; unsigned char *memrange_data;} curframe;/* ------------------- function prototypes -------------------- */void handle_request ( char * );/* ------------------- Implementation -------------------- */static voiddiscard_packet( void ){ lan_input_queue.head_index = lan_input_queue.tail_index; lan_input_queue.gdb_packet_start = lan_input_queue.gdb_packet_end = lan_input_queue.gdb_packet_csum1 = lan_input_queue.gdb_packet_csum2 = -1;}/* Utility function: convert an ASCII isxdigit to a hex nybble */static longhex( char ch ){ if ( (ch >= 'A') && (ch <= 'F') ) return ch - 'A' + 10; if ( (ch >= 'a') && (ch <= 'f') ) return ch - 'a' + 10; if ( (ch >= '0') && (ch <= '9') ) return ch - '0'; return -1;}static voidgetpacket( void ){ unsigned char our_checksum, their_checksum; char *copy = inbuffer; unsigned char c; our_checksum = 0; /* first find the '$' */ while ((c = lan_next_queue_char ( &lan_input_queue )) != '$') if (c == 0) /* ??? Protocol error? (paranoia) */ { /* PROTOCOL ERROR (missing '$') */ /*NACK_PKT( );*/ /*<ETHERNET>*/ return; } /* Now copy the message (up to the '#') */ for (c = lan_next_queue_char ( &lan_input_queue ); /* skip the '$' */ c != 0 && c != '#'; /* stop at the '#' */ c = lan_next_queue_char ( &lan_input_queue )) { *copy++ = c; our_checksum += c; } *copy++ = '\0'; /* terminate the copy */ if (c == 0) /* ??? Protocol error? (paranoia) */ { /* PROTOCOL ERROR (missing '#') */ /*NACK_PKT( );*/ /*<ETHERNET>*/ return; } their_checksum = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4; their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) ); /* Now reset the queue packet-recognition bits */ discard_packet( ); if ( remote_debug || our_checksum == their_checksum ) { ACK_PKT( ); /* good packet */ /* Parse and process the packet */ handle_request( inbuffer ); } else /* PROTOCOL ERROR (bad check sum) */ NACK_PKT( );}/* EMC will provide a better implementation (perhaps just of LAN_PUT_CHAR) that does not block. For now, this works. */static voidputpacket( char *str ){ unsigned char checksum; /* '$'<packet>'#'<checksum> */ if ( VIA_ETHERNET == gdb_host_comm ) { char *p_out; long length; p_out = eth_outbuffer; length = 0; if ( YES == gdb_cat_ack )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -