Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gdb6 / gdb / testsuite / gdb.trace / gdb_c_test.c
blobcef68e0e47024cc636cc083e11c203c1797dba80
1 /*
2 ******************************************************************************
3 ******************************************************************************
5 * COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved.
6 * $Id: gdb_c_test.c,v 1.1.1.1 2006/05/15 14:14:17 nathanw Exp $
7 * DESCRIPTION: This module has been provided for the purpose of testing GDB.
9 * NOTES:
11 ******************************************************************************
12 *****************************************************************************/
14 /*=============================================================================
15 * INCLUDE FILES
16 *===========================================================================*/
19 #ifdef DO_IT_BY_THE_BOOK
22 #include "symtypes_defs.h"
23 #include "printp.h"
25 #include "adbg_expression.h"
26 #include "common_hw_ds.h"
27 #include "common_hw_defs.h"
28 #include "evnttrac.h"
29 #include "sym_scratch_ds.h"
30 #include "symglob_ds.h"
31 #include "sym_protglob_ds.h"
33 #include "ether.h"
35 #include <ctype.h>
38 #else
40 #include "adbg_dtc.h"
42 #define YES 1
43 #define NO 0
45 #define TRUE 1
46 #define FALSE 0
48 #define ENABLED 1
49 #define DISABLED 0
51 #define CONTROL_C 3 /* ASCII 'ETX' */
55 * Faked after ctype.h
58 #define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
59 ((X) >= 'A' && (X) <= 'F') || \
60 ((X) >= 'a' && (X) <= 'f'))
62 * Borrowed from string.h
65 extern unsigned int strlen ( const char * );
68 * Extracted from symtypes.h:
71 typedef char BOOL; /* 8 Bits */
72 typedef unsigned char UCHAR; /* 8 Bits */
73 typedef unsigned short USHORT; /* 16 Bits */
74 typedef unsigned long ULONG; /* 32 Bits */
77 * for struct t_expr_tag and
78 * decl of build_and_add_expression
80 #include "adbg_expression.h"
81 #define NULL 0
84 * Extracted from printp.h:
87 extern void printp ( const char * fptr, ... );
88 extern void sprintp ( const char * fptr, ... );
91 * Extracted from ether.h:
94 extern long eth_to_gdb ( UCHAR *buf, long length );
98 * Derived from hwequs.s:
101 #define CS_CODE_START 0x100000
102 #define CS_CODE_SIZE 0x200000
103 #define LAST_CS_WORD (CS_CODE_START + CS_CODE_SIZE - 2)
105 #define sh_genstat1 (*((volatile ULONG *) 0xFFFFFE54))
107 #define rs232_mode1 0 /* rs-232 mode 1 reg. */
108 #define rs232_mode2 rs232_mode1 /* rs-232 mode 2 reg. */
109 #define rs232_stat 4 /* rs-232 status reg. */
110 #define rs232_clk rs232_stat /* rs-232 clock select reg. */
111 #define rs232_cmd 8 /* rs-232 command reg */
112 #define rs232_transmit 12 /* rs-232 transmit reg. */
113 #define rs232_receive rs232_transmit /* rs-232 transmit reg. */
114 #define rs232_aux 16 /* rs-232 aux control reg. */
115 #define rs232_isr 20 /* rs-232 interrupt status reg. */
116 #define rs232_imr rs232_isr /* rs-232 interrupt mask reg. */
117 #define rs232_tc_high 24 /* rs-232 timer/counter high reg. */
118 #define rs232_tc_low 28 /* rs-232 timer/counter low reg. */
121 #endif
124 /*============================================================================
125 * MODULE DEFINES
126 *===========================================================================*/
128 #define P_RST_LAN_UART_REG ((volatile UCHAR *) 0xFFFFFE45)
129 #define M_RST_LAN_UART 0x80 /* Bit 7 */
131 #define P_LAN0TR_REG P_RST_LAN_UART_REG
132 #define M_LAN0TR 0x20 /* Bit 5 */
134 #define M_SH_GENCON_LAN0TR 0x00200000 /* Bit 21 */
136 #define MAX_RS232_CHARS 512
138 #define LAN_Q_MOD(X) ((X) % MAX_RS232_CHARS)
140 /*---------------------------------------*
141 * LAN UART Registers *
142 *---------------------------------------*/
144 #define LAN_UART_BASE ((ULONG) 0xfffffc22)
146 /* Write-Read */
148 #define P_LAN_MR1 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode1 )))
149 #define P_LAN_MR2 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode2 )))
151 /* Write-Only */
153 #define P_LAN_ACR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux )))
154 #define P_LAN_CR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_cmd )))
155 #define P_LAN_CSR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_clk )))
156 #define P_LAN_CTLR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_low )))
157 #define P_LAN_CTUR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_high )))
158 #define P_LAN_IMR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr )))
160 /* Read-Only */
162 #define P_LAN_SR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_stat )))
163 #define P_LAN_ISR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_isr )))
164 #define P_LAN_XMT ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit)))
165 #define P_LAN_RCV ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive )))
168 * Bit Values for Write-Read and Write-Only Registers
171 #define DEFAULT_LAN_MR1 ((UCHAR) 0x13)
172 #define DEFAULT_LAN_MR2 ((UCHAR) 0x07)
173 #define DEFAULT_LAN_CSR ((UCHAR) 0xcc)
174 #define DEFAULT_LAN_ACR ((UCHAR) 0x38)
175 #define DEFAULT_LAN_CTUR ((UCHAR) 0xff)
176 #define DEFAULT_LAN_CTLR ((UCHAR) 0xff)
178 #define LAN_ACR_SELECT_BRG_0 DEFAULT_LAN_ACR
179 #define LAN_ACR_SELECT_BRG_1 (DEFAULT_LAN_ACR | 0x80)
181 #define UART_CR_RESET_MR_PTR ((UCHAR) 0x10) /* Reset MR pointer (points to MR1). */
182 #define UART_CR_RESET_RVCR ((UCHAR) 0x20) /* Reset receiver (disabled). */
183 #define UART_CR_RESET_XMTR ((UCHAR) 0x30) /* Reset transmitter (disabled). */
184 #define UART_CR_RESET_ERROR_STATUS ((UCHAR) 0x40) /* Reset error status. */
185 #define UART_CR_RESET_BRK_CHG_INT ((UCHAR) 0x50) /* Reset break change interrupt. */
186 #define UART_CR_START_CNTR_TIMER ((UCHAR) 0x80) /* Start counter/timer. */
187 #define UART_CR_STOP_CNTR ((UCHAR) 0x90) /* Stop counter. */
189 #define UART_CR_DISABLE_XMTR ((UCHAR) 0x08) /* Disable transmitter. */
190 #define UART_CR_ENABLE_XMTR ((UCHAR) 0x04) /* Enable transmitter. */
191 #define UART_CR_DISABLE_RCVR ((UCHAR) 0x02) /* Disable receiver. */
192 #define UART_CR_ENABLE_RCVR ((UCHAR) 0x01) /* Enable receiver. */
194 #define UART_CSR_BR_4800 ((UCHAR) 0x99) /* With either BRG Set selected (via ACR). */
195 #define UART_CSR_BR_9600 ((UCHAR) 0xbb) /* With either BRG Set selected (via ACR). */
196 #define UART_CSR_BR_19200 ((UCHAR) 0xcc) /* With BRG Set '1' selected (via ACR). */
197 #define UART_CSR_BR_38400 ((UCHAR) 0xcc) /* With BRG Set '0' selected (via ACR). */
199 #define UART_IMR_RxRDY ((UCHAR) 0x04) /* Enable 'RxRDY' interrupt. */
200 #define UART_IMR_TxEMT ((UCHAR) 0x02) /* Enable 'TxEMT' interrupt. */
201 #define UART_IMR_TxRDY ((UCHAR) 0x01) /* Enable 'TxRDY' interrupt. */
204 * Bit Masks for Read-Only Registers
207 #define M_UART_SR_RCVD_BRK 0x80 /* Bit 7 */
208 #define M_UART_SR_FE 0x40 /* Bit 6 */
209 #define M_UART_SR_PE 0x20 /* Bit 5 */
210 #define M_UART_SR_OE 0x10 /* Bit 4 */
211 #define M_UART_SR_TxEMT 0x08 /* Bit 3 */
212 #define M_UART_SR_TxRDY 0x04 /* Bit 2 */
213 #define M_UART_SR_FFULL 0x02 /* Bit 1 */
214 #define M_UART_SR_RxRDY 0x01 /* Bit 0 */
216 #define M_UART_ISR_RxRDY 0x04 /* Bit 2 */
217 #define M_UART_ISR_TxEMT 0x02 /* Bit 1 */
218 #define M_UART_ISR_TxRDY 0x01 /* Bit 0 */
220 /*---------------------------------------*
221 * Support for 'Utility 83'. *
222 *---------------------------------------*/
224 #define LAN_UTIL_CODE 0x83
226 #define LAN_INIT ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T'))
227 #define LAN_BAUD ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D'))
228 #define LAN_INTR ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R'))
229 #define LAN_XMT ((ULONG) (('X' << 16) | ('M' << 8) | 'T'))
230 #define LAN_ECHO ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O'))
231 #define LAN_STAT ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T'))
232 #define LAN_IN ((ULONG) (('I' << 8) | 'N'))
233 #define LAN_OUT ((ULONG) (('O' << 16) | ('U' << 8) | 'T'))
235 #define LAN_PUTC ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
236 #define LAN_WPM ((ULONG) (('W' << 16) | ('P' << 8) | 'M'))
238 #define STATUS(X) ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
240 #define XMT_VIA_BP_ENABLED() ( *P_LAN0TR_REG & M_LAN0TR ? 1 : 0 )
242 #define TRAP_1_INST 0x4E41
245 * Bit #13 of shared genstat 1 indicates
246 * which processor we are as follows.
248 * 0 => X (side A)
249 * 1 => Y (side B)
252 #define M_PROC_ID 0x00002000
254 #define IS_SIDE_A() ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
255 #define IS_SIDE_B() ( (sh_genstat1) & M_PROC_ID )
258 #ifdef STANDALONE /* Compile this module stand-alone for debugging */
259 #define LAN_PUT_CHAR(X) printf("%c", X)
260 #else
261 #define LAN_PUT_CHAR(X) while ( lan_put_char( X ) )
262 #endif
267 #define VIA_RS232 0
268 #define VIA_ETHERNET 1
270 #define MAX_IO_BUF_SIZE 400
272 #define MAX_BYTE_CODES 200 /* maximum length for bytecode string */
275 static ULONG gdb_host_comm;
277 static ULONG gdb_cat_ack;
279 static char eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
282 #ifdef STANDALONE
284 #define ACK_PKT() LAN_PUT_CHAR( '+' )
285 #define NACK_PKT() LAN_PUT_CHAR( '-' )
287 #else
289 #define ACK_PKT() { \
290 if ( VIA_ETHERNET == gdb_host_comm ) \
292 gdb_cat_ack = YES; \
294 else \
296 LAN_PUT_CHAR( '+' ); \
302 #define NACK_PKT() { \
303 if ( VIA_ETHERNET == gdb_host_comm ) \
305 eth_outbuffer[ 0 ] = '-'; \
306 eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
308 else \
310 LAN_PUT_CHAR( '-' ); \
314 #endif
319 /*============================================================================
320 * MODULE TYPEDEFS
321 *===========================================================================*/
323 typedef struct rs232_queue {
325 long head_index;
327 long tail_index;
329 ULONG overflows;
331 long gdb_packet_start;
332 long gdb_packet_end;
333 long gdb_packet_csum1;
334 long gdb_packet_csum2;
336 UCHAR buf[ MAX_RS232_CHARS ];
338 } T_RS232_QUEUE;
343 /*=============================================================================
344 * EXTERNAL GLOBAL VARIABLES
345 *===========================================================================*/
347 extern volatile UCHAR sss_trace_flag;
350 /*=============================================================================
351 * STATIC MODULE DECLARATIONS
352 *===========================================================================*/
354 static T_RS232_QUEUE lan_input_queue,
355 lan_output_queue;
357 static BOOL test_echo;
359 #if 0
360 /* The stub no longer seems to use this. */
361 static BOOL write_access_enabled;
362 #endif
364 static int baud_rate_idx;
366 static ULONG tx_by_intr,
367 tx_by_poll;
369 static UCHAR lan_shadow_imr;
372 /*=============================================================================
373 * EXTERNAL FUNCTION PROTOTYPES
374 *===========================================================================*/
376 extern long write_to_protected_mem( void *address, unsigned short value );
379 /*=============================================================================
380 * MODULE GLOBAL FUNCTIONS PROTOTYPES
381 *===========================================================================*/
383 ULONG gdb_c_test( ULONG *parm );
386 void lan_init( void );
388 void lan_isr( void );
390 long lan_get_char( void );
392 long lan_put_char( UCHAR c );
394 ULONG lan_util( ULONG *parm );
397 /*=============================================================================
398 * MODULE LOCAL FUNCTION PROTOTYPES
399 *===========================================================================*/
401 static void lan_reset( void );
403 static void lan_configure( void );
405 static void lan_init_queue( T_RS232_QUEUE *p_queue );
407 static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue );
409 static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue );
411 static void lan_util_menu( void );
413 static long get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
416 /*=============================================================================
417 * GDB STUB FUNCTION PROTOTYPES
418 *===========================================================================*/
420 void gdb_trap_1_handler( void );
421 void gdb_trace_handler ( void );
423 void gdb_get_eth_input( unsigned char *buf, long length );
425 static void getpacket ( void );
426 static void putpacket ( char * );
427 static void discard_packet ( void );
429 #ifdef STANDALONE /* Compile this module stand-alone for debugging */
430 #include <stdio.h>
431 #define printp printf /* easier than declaring a local varargs stub func. */
432 #endif /* STANDALONE */
435 /*=============================================================================
436 * MODULE BODY
437 *===========================================================================*/
439 /* ------------------- Things that belong in a header file --------------- */
440 extern char *memset (char *, int, int);
442 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
444 * Global Module Functions *
446 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
449 static char gdb_char_test;
450 static short gdb_short_test;
451 static long gdb_long_test;
452 static char gdb_arr_test[25];
453 static struct GDB_STRUCT_TEST
455 char c;
456 short s;
457 long l;
458 int bfield : 11; /* collect bitfield */
459 char arr[25];
460 struct GDB_STRUCT_TEST *next;
461 } gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
463 static union GDB_UNION_TEST
465 char c;
466 short s;
467 long l;
468 int bfield : 11; /* collect bitfield */
469 char arr[4];
470 union GDB_UNION_TEST *next;
471 } gdb_union1_test;
473 void gdb_recursion_test (int, int, int, int, int, int, int);
475 void gdb_recursion_test (int depth,
476 int q1,
477 int q2,
478 int q3,
479 int q4,
480 int q5,
481 int q6)
482 { /* gdb_recursion_test line 0 */
483 int q = q1; /* gdbtestline 1 */
485 q1 = q2; /* gdbtestline 2 */
486 q2 = q3; /* gdbtestline 3 */
487 q3 = q4; /* gdbtestline 4 */
488 q4 = q5; /* gdbtestline 5 */
489 q5 = q6; /* gdbtestline 6 */
490 q6 = q; /* gdbtestline 7 */
491 if (depth--) /* gdbtestline 8 */
492 gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */
496 ULONG gdb_c_test( ULONG *parm )
499 char *p = "gdb_c_test";
500 char *ridiculously_long_variable_name_with_equally_long_string_assignment;
501 register long local_reg = 7;
502 static unsigned long local_static, local_static_sizeof;
503 long local_long;
504 unsigned long *stack_ptr;
505 unsigned long end_of_stack;
507 ridiculously_long_variable_name_with_equally_long_string_assignment =
508 "ridiculously long variable name with equally long string assignment";
509 local_static = 9;
510 local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
511 local_long = local_reg + 1;
512 stack_ptr = (unsigned long *) &local_long;
513 end_of_stack =
514 (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
516 printp ("\n$Id: gdb_c_test.c,v 1.1.1.1 2006/05/15 14:14:17 nathanw Exp $\n");
518 printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n",
519 p, parm[ 1 ], parm[ 2 ], parm[ 3 ], parm[ 4 ], parm[ 5 ], parm[ 6 ] );
521 gdb_char_test = gdb_struct1_test.c = (char) ((long) parm[1] & 0xff);
522 gdb_short_test = gdb_struct1_test.s = (short) ((long) parm[2] & 0xffff);
523 gdb_long_test = gdb_struct1_test.l = (long) ((long) parm[3] & 0xffffffff);
524 gdb_union1_test.l = (long) parm[4];
525 gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff);
526 gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff);
527 gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff);
528 gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff);
529 gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff);
530 gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff);
531 gdb_struct1_test.bfield = 144;
532 gdb_struct1_test.next = &gdb_struct2_test;
533 gdb_structp_test = &gdb_struct1_test;
534 gdb_structpp_test = &gdb_structp_test;
536 gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
537 (long) parm[4], (long) parm[5], (long) parm[6]);
539 gdb_char_test = gdb_short_test = gdb_long_test = 0;
540 gdb_structp_test = (void *) 0;
541 gdb_structpp_test = (void *) 0;
542 memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
543 memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
544 local_static_sizeof = 0;
545 local_static = 0;
546 return ( (ULONG) 0 );
550 /*-----------------------------------------------------------------------------
552 * FUNCTION NAME: lan_init
555 * DESCRIPTION:
558 * RETURN VALUE:
561 * USED GLOBAL VARIABLES:
564 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
567 * NOTES:
571 *---------------------------------------------------------------------------*/
573 void lan_init( void )
577 if ( IS_SIDE_A( ) )
580 lan_reset( );
582 lan_init_queue( &lan_input_queue );
584 lan_init_queue( &lan_output_queue );
586 lan_configure( );
589 return;
591 /* end of 'lan_init'
592 *===========================================================================*/
595 /*-----------------------------------------------------------------------------
597 * FUNCTION NAME: lan_isr
600 * DESCRIPTION:
603 * RETURN VALUE: None.
606 * USED GLOBAL VARIABLES:
609 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
612 * NOTES:
615 *---------------------------------------------------------------------------*/
617 void lan_isr( void )
620 UCHAR c;
623 lan_shadow_imr = 0; /* Disable all UART interrupts. */
624 *P_LAN_IMR = lan_shadow_imr;
627 if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
630 gdb_host_comm = VIA_RS232;
632 c = *P_LAN_RCV;
634 if ( test_echo )
636 /* ????? */
639 if ( c == CONTROL_C )
641 /* can't stop the target, but we can tell gdb to stop waiting... */
642 discard_packet( );
643 putpacket( "S03" ); /* send back SIGINT to the debugger */
646 else
648 lan_add_to_queue( (long) c, &lan_input_queue );
649 get_gdb_input( (long) c, &lan_input_queue );
654 if ( XMT_VIA_BP_ENABLED( ) )
657 c = 0;
659 while ( (*P_LAN_ISR & M_UART_ISR_TxRDY) && (c = lan_next_queue_char( &lan_output_queue )) )
661 *P_LAN_XMT = c;
662 ++tx_by_intr;
665 if ( c )
667 lan_shadow_imr |= UART_IMR_TxRDY; /* (Re-)Enable 'TxRDY' interrupt from UART. */
673 lan_shadow_imr |= UART_IMR_RxRDY; /* Re-Enable 'RxRDY' interrupt from UART. */
674 *P_LAN_IMR = lan_shadow_imr;
678 return;
680 /* end of 'lan_isr'
681 *===========================================================================*/
684 /*-----------------------------------------------------------------------------
686 * FUNCTION NAME: lan_get_char
689 * DESCRIPTION: Fetches a character from the UART.
692 * RETURN VALUE: 0 on success, -1 on failure.
695 * USED GLOBAL VARIABLES:
698 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
701 * NOTES:
704 *---------------------------------------------------------------------------*/
706 long lan_get_char( void )
709 long status = -2; /* AGD: nothing found in rcv buffer */
711 if ( *P_LAN_SR & M_UART_SR_RxRDY )
713 char c = (char) *P_LAN_RCV;
715 if ( test_echo )
717 LAN_PUT_CHAR ( c );
720 if ( c == CONTROL_C )
722 /* can't stop the target, but we can tell gdb to stop waiting... */
723 discard_packet( );
724 putpacket( "S03" ); /* send back SIGINT to the debugger */
725 status = 0; /* success */
728 else
730 lan_add_to_queue( (long) c, &lan_input_queue );
731 status = get_gdb_input( (long) c, &lan_input_queue );
736 return( status );
738 /* end of 'lan_get_char'
739 *===========================================================================*/
742 /*-----------------------------------------------------------------------------
744 * FUNCTION NAME: lan_put_char
746 * DESCRIPTION: Puts a character out via the UART.
748 * RETURN VALUE: 0 on success, -1 on failure.
750 * USED GLOBAL VARIABLES: none.
752 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
754 * NOTES: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
755 * !! !!
756 * !! If 'XMT_VIA_BP_ENABLED()' is FALSE then output is THROWN AWAY. !!
757 * !! This prevents anyone infinite-looping on this function. !!
758 * !! !!
759 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
761 *---------------------------------------------------------------------------*/
763 long lan_put_char( UCHAR c )
766 long status = -1;
768 if ( XMT_VIA_BP_ENABLED( ) )
771 if ( *P_LAN_SR & M_UART_SR_TxRDY )
773 lan_add_to_queue( (long) c, &lan_output_queue );
775 c = lan_next_queue_char( &lan_output_queue );
777 *P_LAN_XMT = c;
778 ++tx_by_poll;
779 status = 0;
781 #if 0
782 else
784 status = 0;
785 lan_shadow_imr |= UART_IMR_TxRDY; /* Enable 'TxRDY' interrupt from UART. */
786 *P_LAN_IMR = lan_shadow_imr;
788 #endif
791 else
793 status = 0; /* You lose: input character goes to the bit bucket. */
796 return( status );
798 /* end of 'lan_put_char'
799 *===========================================================================*/
802 /*-----------------------------------------------------------------------------
804 * FUNCTION NAME: lan_util
806 * DESCRIPTION:
808 * RETURN VALUE:
810 * USED GLOBAL VARIABLES:
812 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
814 * NOTES:
816 *---------------------------------------------------------------------------*/
818 ULONG lan_util( ULONG *parm )
823 static const struct {
825 ULONG rate_code;
826 UCHAR acr_setting;
827 UCHAR csr_setting;
829 } baud_rate_setting [] = {
831 { 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 },
832 { 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 },
833 { 0x9600, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600 },
834 { 0x4800, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800 }
838 #define BOGUS_P1 0xE1
839 #define BOGUS_P2 0xE2
841 ULONG not_done_code;
844 ULONG opcode;
845 ULONG parm_1;
846 ULONG parm_2;
848 int i;
849 UCHAR c;
852 not_done_code = 0;
854 opcode = parm[ 1 ];
855 parm_1 = parm[ 2 ];
856 parm_2 = parm[ 3 ];
859 switch ( opcode )
862 case LAN_INIT:
865 lan_init( );
866 printp( "\n\n Interface (Re)Initialized ...\n\n" );
868 break;
872 case LAN_BAUD:
875 for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
877 if ( baud_rate_setting[i].rate_code == parm_1 )
879 baud_rate_idx = i;
880 *P_LAN_ACR = baud_rate_setting[i].acr_setting;
881 *P_LAN_CSR = baud_rate_setting[i].csr_setting;
882 printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code );
883 return( not_done_code );
887 printp( "\n\n *** SYNTAX Error - Invalid baudrate (P2)\n\n" );
888 not_done_code = BOGUS_P2;
890 break;
894 case LAN_INTR:
897 switch ( parm_1 )
900 case 0x0D: /* Disable 'RxRDY' Interrupts */
902 lan_shadow_imr &= ~UART_IMR_RxRDY;
903 *P_LAN_IMR = lan_shadow_imr;
904 printp( "\n\n Receive Ready Interrupts DISABLED ...\n\n" );
905 break;
908 case 0x0E: /* Enable 'RxRDY' Interrupts */
910 lan_shadow_imr |= UART_IMR_RxRDY;
911 *P_LAN_IMR = lan_shadow_imr;
912 printp( "\n\n Receive Ready Interrupts ENABLED ...\n\n" );
913 break;
916 default:
918 printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
919 not_done_code = BOGUS_P2;
923 break;
927 case LAN_XMT:
930 switch ( parm_1 )
933 case 0x0E: /* Enable Transmission-via-Backplane */
935 if ( !(*P_LAN0TR_REG & M_LAN0TR) )
937 *P_LAN0TR_REG |= M_LAN0TR; /* 0 -> 1 */
940 printp( "\n\n Transmit-via-Backplane ENABLED ...\n\n" );
941 break;
944 case 0x0D: /* Disable Transmission-via-Backplane */
946 if ( *P_LAN0TR_REG & M_LAN0TR )
948 *P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */
951 printp( "\n\n Transmit-via-Backplane DISABLED ...\n\n" );
952 break;
955 default:
957 printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
958 not_done_code = BOGUS_P2;
959 lan_util_menu( );
963 break;
967 case LAN_STAT:
970 printp( "\n -- Status --\n\n" );
972 printp( " Baud Rate: %X *\n", baud_rate_setting[ baud_rate_idx ].rate_code );
973 printp( " Xmt-via-BP: %s *\n", STATUS( XMT_VIA_BP_ENABLED( ) ) );
974 printp( " RxRdy Intr: %s *\n", STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) );
975 /*** printp( " TxRdy Intr: %s\n", STATUS( (lan_shadow_imr & M_UART_ISR_TxRDY) ) ); ***/
976 printp( " Echo: %s *\n\n", STATUS( test_echo ) );
978 printp( " IMR: %02X\n", (ULONG) lan_shadow_imr );
979 printp( " ISR: %02X\n", (ULONG) *P_LAN_ISR );
980 printp( " SR: %02X\n\n", (ULONG) *P_LAN_SR );
982 printp( " Input Overflows: %d\n\n", lan_input_queue.overflows );
984 printp( " Tx by Intr: %d\n", tx_by_intr );
985 printp( " Tx by Poll: %d\n\n", tx_by_poll );
987 printp( " * Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE );
989 break;
993 case LAN_IN:
996 switch ( parm_1 )
999 case 0x0C: /* Clear and Reset Queue */
1001 lan_init_queue( &lan_input_queue );
1002 printp( "\n\n Queue CLEARED/RESET ...\n\n" );
1003 break;
1006 case 0x0D: /* Display Queue */
1008 printp( "\n -- Input Queue --\n" );
1009 printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
1010 (ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index );
1012 for ( i = 0; i < MAX_RS232_CHARS; ++i )
1014 printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
1016 if ( 15 == (i % 16) )
1018 int j;
1020 printp ( " " );
1021 for ( j = i - 15; j <= i; j++ )
1023 if ( lan_input_queue.buf[ j ] >= ' ' &&
1024 lan_input_queue.buf[ j ] < 127 )
1025 printp ( "%c", lan_input_queue.buf[ j ] );
1026 else
1027 printp ( "." );
1029 printp( "\n " );
1032 else if ( 7 == (i % 8) )
1034 printp( " " );
1039 printp( "\n" );
1041 break;
1044 case 0x0F: /* Fetch next character in Queue */
1046 c = lan_next_queue_char( &lan_input_queue );
1048 if ( c )
1050 printp( "\n\n Next Character: " );
1051 if ( 0x21 <= c && c <= 0x7F )
1053 printp( "%c\n\n", (ULONG) c );
1056 else if ( 0x20 == ((UCHAR) c) )
1058 printp( "<space>\n\n" );
1061 else
1063 printp( "%02X\n\n", (ULONG) c );
1067 else
1069 printp( "\n\n Input Queue EMPTY ...\n\n" );
1072 break;
1075 default:
1077 printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
1078 not_done_code = BOGUS_P2;
1079 break;
1083 break;
1087 case LAN_OUT:
1090 switch ( parm_1 )
1093 case 0x0C: /* Clear and Reset Queue */
1095 lan_init_queue( &lan_output_queue );
1096 printp( "\n\n Queue CLEARED/RESET ...\n\n" );
1097 break;
1100 case 0x0D: /* Display Queue */
1102 printp( "\n -- Output Queue --\n" );
1103 printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
1104 (ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index );
1106 for ( i = 0; i < MAX_RS232_CHARS; ++i )
1108 printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
1110 if ( 15 == (i % 16) )
1112 int j;
1114 printp ( " " );
1115 for ( j = i - 15; j <= i; j++ )
1117 if ( lan_output_queue.buf[ j ] >= ' ' &&
1118 lan_output_queue.buf[ j ] < 127 )
1119 printp ( "%c", lan_output_queue.buf[ j ] );
1120 else
1121 printp ( "." );
1123 printp( "\n " );
1126 else if ( 7 == (i % 8) )
1128 printp( " " );
1133 printp( "\n" );
1135 break;
1138 case 0x0F: /* Fetch next character in Queue */
1140 c = lan_next_queue_char( &lan_output_queue );
1142 if ( c )
1144 printp( "\n\n Next Character: " );
1145 if ( 0x21 <= c && c <= 0x7F )
1147 printp( "%c\n\n", (ULONG) c );
1150 else if ( 0x20 == c )
1152 printp( "<space>\n\n" );
1155 else
1157 printp( "%02X\n\n", (ULONG) c );
1161 else
1163 printp( "\n\n Input Queue EMPTY ...\n\n" );
1166 break;
1169 default:
1171 printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
1172 not_done_code = BOGUS_P2;
1173 break;
1177 break;
1181 case LAN_ECHO:
1184 switch ( parm_1 )
1187 case 0x0E:
1189 test_echo = ENABLED;
1190 printp( "\n\n Test echo ENABLED ...\n\n" );
1191 break;
1194 case 0x0D:
1196 test_echo = DISABLED;
1197 printp( "\n\n Test echo DISABLED ...\n\n" );
1198 break;
1201 default:
1203 printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
1204 not_done_code = BOGUS_P2;
1205 break;
1209 break;
1213 case LAN_PUTC:
1216 if ( 0x20 < parm_1 && parm_1 < 0x7F )
1218 if ( lan_put_char( (UCHAR) parm_1 ) )
1220 printp( "\n\n *** 'lan_put_char' Error ...\n" );
1223 else
1225 printp( "\n\n O.K. ...\n" );
1230 else
1232 printp( "\n\n *** Error - character must be in the 0x21-0x7E range ...\n" );
1233 not_done_code = BOGUS_P2;
1236 break;
1239 /***
1240 case LAN_WPM:
1243 if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) )
1245 printp( "\n Write to protected memory FAILED ...\n" );
1248 break;
1250 ***/
1252 case 0: /* no argument -- print menu */
1254 lan_util_menu( );
1255 break;
1259 default:
1261 parm_2 = 0; /* to supress compiler warning with 'LAN_WPM' case disabled */
1263 printp( "\n\n *** SYNTAX Error - Invalid P1 ...\n\n" );
1264 not_done_code = BOGUS_P1;
1265 break;
1269 } /* End of 'switch ( opcode )'. */
1272 return( not_done_code );
1274 /* end of 'lan_util'
1275 *===========================================================================*/
1278 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
1280 * Local Module Functions *
1282 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1284 /*-----------------------------------------------------------------------------
1286 * FUNCTION NAME: lan_reset
1288 * DESCRIPTION: Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the
1289 * Shared Control 1 area.
1291 * 1 _| ______
1292 * | | |
1293 * Bit | | |
1294 * | | |
1295 * 0 _|______| |______
1296 * |---------------------> t
1298 * RETURN VALUE: None.
1300 * USED GLOBAL VARIABLES:
1302 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1304 * NOTES: H/W configuration requires that a byte in the shared
1305 * control 1 area must be read before being written.
1307 *---------------------------------------------------------------------------*/
1309 static void lan_reset( void )
1313 while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
1315 *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */
1318 while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) )
1320 *P_RST_LAN_UART_REG |= M_RST_LAN_UART; /* 1 */
1323 while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
1325 *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */
1329 /* end of 'lan_reset'
1330 *===========================================================================*/
1333 /*-----------------------------------------------------------------------------
1335 * FUNCTION NAME: lan_configure
1338 * DESCRIPTION:
1341 * RETURN VALUE:
1344 * USED GLOBAL VARIABLES:
1347 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1350 * NOTES:
1354 *---------------------------------------------------------------------------*/
1356 static void lan_configure( void )
1360 *P_LAN_CR = UART_CR_RESET_MR_PTR; /* Points to MR1. */
1361 *P_LAN_CR = UART_CR_RESET_RVCR; /* Receiver disabled. */
1362 *P_LAN_CR = UART_CR_RESET_XMTR; /* Transmitter disabled. */
1363 *P_LAN_CR = UART_CR_RESET_ERROR_STATUS;
1364 *P_LAN_CR = UART_CR_RESET_BRK_CHG_INT;
1366 *P_LAN_MR1 = DEFAULT_LAN_MR1;
1367 *P_LAN_MR2 = DEFAULT_LAN_MR2;
1369 *P_LAN_ACR = DEFAULT_LAN_ACR;
1371 *P_LAN_CSR = UART_CSR_BR_9600;
1372 baud_rate_idx = 2;
1374 *P_LAN_CTUR = DEFAULT_LAN_CTUR;
1375 *P_LAN_CTLR = DEFAULT_LAN_CTLR;
1377 *P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
1379 lan_shadow_imr = UART_IMR_RxRDY; /* Enable only 'RxRDY' interrupt from UART. */
1380 *P_LAN_IMR = lan_shadow_imr;
1382 tx_by_intr = 0;
1383 tx_by_poll = 0;
1385 return;
1387 /* end of 'lan_configure'
1388 *===========================================================================*/
1391 /*-----------------------------------------------------------------------------
1393 * FUNCTION NAME: lan_init_queue
1395 * DESCRIPTION:
1397 * RETURN VALUE: None.
1399 * USED GLOBAL VARIABLES:
1401 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1403 * NOTES:
1405 *---------------------------------------------------------------------------*/
1407 static void lan_init_queue( T_RS232_QUEUE *p_queue )
1410 long i;
1413 * We set "head" equal to "tail" implying the queue is empty,
1414 * BUT the "head" and "tail" should each point to valid queue
1415 * positions.
1418 p_queue->head_index = 0;
1419 p_queue->tail_index = 0;
1421 p_queue->overflows = 0;
1423 p_queue->gdb_packet_start = -1;
1424 p_queue->gdb_packet_end = -1;
1426 p_queue->gdb_packet_csum1 = -1;
1427 p_queue->gdb_packet_csum2 = -1;
1429 for ( i = 0; i < MAX_RS232_CHARS; ++i )
1431 p_queue->buf[ i ] = 0;
1434 return;
1436 /* end of 'lan_init_queue'
1437 *===========================================================================*/
1440 /*-----------------------------------------------------------------------------
1442 * FUNCTION NAME: lan_add_to_queue
1445 * DESCRIPTION: Adds the specified character to the tail of the
1446 * specified queue. Observes "oldest thrown on floor"
1447 * rule (i.e. the queue is allowed to "wrap" and the
1448 * input character is unconditionally placed at the
1449 * tail of the queue.
1452 * RETURN VALUE: None.
1455 * USED GLOBAL VARIABLES:
1458 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1461 * NOTES:
1464 *---------------------------------------------------------------------------*/
1466 static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
1470 if ( p_queue ) /* Sanity check. */
1473 if ( c & 0x000000FF ) /* We don't allow NULL characters to be added to a queue. */
1475 /* Insert the new character at the tail of the queue. */
1477 p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
1479 /* Increment the tail index. */
1481 if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
1483 p_queue->tail_index = 0;
1486 /* Check for wrapping (i.e. overflow). */
1488 if ( p_queue->head_index == p_queue->tail_index )
1490 /* If the tail has caught up to the head record the overflow . . . */
1492 ++(p_queue->overflows);
1494 /* . . . then increment the head index. */
1496 if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
1498 p_queue->head_index = 0;
1503 } /* End of 'if ( c & 0x000000FF )'. */
1505 } /* End of 'if ( p_queue )'. */
1508 return;
1510 /* end of 'lan_add_to_queue'
1511 *===========================================================================*/
1514 /*-----------------------------------------------------------------------------
1516 * FUNCTION NAME: lan_next_queue_char
1518 * DESCRIPTION:
1520 * RETURN VALUE:
1522 * USED GLOBAL VARIABLES:
1524 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1526 * NOTES:
1528 *---------------------------------------------------------------------------*/
1530 static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue )
1533 UCHAR c;
1536 c = 0;
1538 if ( p_queue )
1541 if ( p_queue->head_index != p_queue->tail_index )
1543 /* Return the 'oldest' character in the queue. */
1545 c = p_queue->buf[ p_queue->head_index ];
1547 /* Increment the head index. */
1549 if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
1551 p_queue->head_index = 0;
1556 } /* End of 'if ( p_queue )'. */
1559 return( c );
1562 /* end of 'lan_next_queue_char'
1563 *===========================================================================*/
1566 /*-----------------------------------------------------------------------------
1568 * FUNCTION NAME: lan_util_menu
1570 * DESCRIPTION: Prints out a brief help on the LAN UART control utility.
1572 * RETURN VALUE: None.
1574 * USED GLOBAL VARIABLES: None.
1576 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None.
1578 * NOTES: None.
1580 *---------------------------------------------------------------------------*/
1582 static void lan_util_menu( void )
1587 * Multiply calling printp() below is made due to the limitations
1588 * of printp(), incapable of handling long formatting constants:
1591 printp( "\n -- Options --\n\n" );
1593 printp( " %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE );
1594 printp( " %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE );
1595 printp( " %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE );
1596 printp( " %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE );
1597 printp( " %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE );
1598 printp( " %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE );
1599 printp( " %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE );
1600 printp( " %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE );
1602 printp( " %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );
1604 /***
1605 printp( " %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );
1606 ***/
1608 printp( " <rate>: 4800 <mode>: E - enable <action>: C - clear/reset\n" );
1609 printp( " 9600 D - disable D - display\n" );
1610 printp( " 19200 F - fetch next char\n" );
1611 printp( " 38400\n" );
1613 /* end of 'lan_util_menu'
1614 *===========================================================================*/
1617 /* Thu Feb 5 17:14:41 EST 1998 CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */
1620 static long get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
1624 /* Now to detect when we've got a gdb packet... */
1626 if ( '$' == c ) { /* char marks beginning of a packet */
1628 if ( -1 != p_input_q->gdb_packet_start ||
1629 -1 != p_input_q->gdb_packet_end ||
1630 -1 != p_input_q->gdb_packet_csum1 ||
1631 -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
1633 /* NEW: Actually, this probably means that we muffed a packet,
1634 and GDB has already resent it. The thing to do now is to
1635 throw away the one we WERE working on, but immediately start
1636 accepting the new one. Don't NAK, or GDB will have to try
1637 and send it yet a third time! */
1639 /*NACK_PKT( );*/ /*<ETHERNET>*/
1640 discard_packet( ); /* throw away old packet */
1641 lan_add_to_queue ('$', p_input_q); /* put the new "$" back in */
1642 return 0;
1643 } else { /* match new "$" */
1644 p_input_q->gdb_packet_start = p_input_q->tail_index;
1645 p_input_q->gdb_packet_end =
1646 p_input_q->gdb_packet_csum1 =
1647 p_input_q->gdb_packet_csum2 = -1;
1649 } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */
1651 if ( -1 == p_input_q->gdb_packet_start ||
1652 -1 != p_input_q->gdb_packet_end ||
1653 -1 != p_input_q->gdb_packet_csum1 ||
1654 -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
1656 /* Garbled packet. Discard, but do not NAK. */
1658 /*NACK_PKT( );*/ /*<ETHERNET>*/
1659 discard_packet( );
1660 return -1;
1662 p_input_q->gdb_packet_end = p_input_q->tail_index;
1663 p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1;
1665 } else if ( -1 != p_input_q->gdb_packet_start &&
1666 -1 != p_input_q->gdb_packet_end) {
1668 if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */
1670 if ( -1 == p_input_q->gdb_packet_csum1 &&
1671 LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) ==
1672 p_input_q->tail_index ) {
1674 /* first checksum digit */
1676 p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
1677 p_input_q->gdb_packet_csum2 = -1;
1679 } else if ( -1 == p_input_q->gdb_packet_csum2 &&
1680 LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) ==
1681 p_input_q->tail_index ) {
1683 /* second checksum digit: packet is complete! */
1685 p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
1686 getpacket(); /* got a packet -- extract it */
1688 } else { /* probably can't happen (um... three hex digits?) */
1690 /* PROTOCOL ERROR */
1691 /* Not sure how this can happen, but ...
1692 discard it, but do not NAK it. */
1693 /*NACK_PKT( );*/ /*<ETHERNET>*/
1694 discard_packet( );
1695 return -1;
1698 } else { /* '#' followed by non-hex char */
1700 /* PROTOCOL ERROR */
1701 /* Bad packet -- discard but do not NAK */
1702 /*NACK_PKT( );*/ /*<ETHERNET>*/
1703 discard_packet( );
1704 return -1;
1708 return 0;
1714 #ifdef STANDALONE
1716 /* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone
1717 stand-alone stand-alone
1718 stand-alone Enable stand-alone build, for ease of debugging stand-alone
1719 stand-alone stand-alone
1720 stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */
1722 long write_to_protected_mem (addr, word)
1723 void *addr;
1724 unsigned short word;
1726 return 0;
1730 char dummy_memory[0x4000];
1732 int main ( void )
1734 long c;
1736 lan_init_queue( &lan_input_queue );
1737 printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) );
1738 printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory);
1739 while ( (c = getc( stdin ) ) != EOF )
1741 if ( c == '\\' ) /* escape char */
1742 break;
1744 lan_add_to_queue( c, &lan_input_queue );
1745 get_gdb_input (c, &lan_input_queue);
1746 fflush( stdout );
1749 printf( "Goodbye!\n" );
1750 exit( 0 );
1753 #define SRAM_START ((void *) (&dummy_memory[0] + 0x00000000))
1754 #define SRAM_END ((void *) (&dummy_memory[0] + 0x00000400))
1756 #define RO_AREA_START ((void *) (&dummy_memory[0] + 0x00000100))
1757 #define RO_AREA_END ((void *) (&dummy_memory[0] + 0x00000300))
1759 #define NVD_START ((void *) (&dummy_memory[0] + 0x00003000))
1760 #define NVD_END ((void *) (&dummy_memory[0] + 0x00003100))
1762 #else /* normal stub (not stand-alone) */
1764 #define SRAM_START ((void *) 0x00000000)
1765 #define SRAM_END ((void *) 0x00400000)
1767 #define RO_AREA_START ((void *) 0x00100000)
1768 #define RO_AREA_END ((void *) 0x00300000)
1770 #define NVD_START ((void *) 0x03000000)
1771 #define NVD_END ((void *) 0x03100000)
1773 #endif /* STANDALONE */
1778 /* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb
1779 gdb gdb
1780 gdb Here begins the gdb stub section. gdb
1781 gdb The following functions were added by Cygnus, gdb
1782 gdb to make this thing act like a gdb stub. gdb
1783 gdb gdb
1784 gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb */
1787 /* ------------------- global defines and data decl's -------------------- */
1789 #define hexchars "0123456789abcdef"
1791 /* there are 180 bytes of registers on a 68020 w/68881 */
1792 /* many of the fpa registers are 12 byte (96 bit) registers */
1793 #define NUMREGBYTES 180
1794 #define NUMREGS 29
1795 #define REGISTER_BYTE(regno) regno
1797 enum regnames { D0, D1, D2, D3, D4, D5, D6, D7,
1798 A0, A1, A2, A3, A4, A5, A6, A7,
1799 PS, PC,
1800 FP0, FP1,
1801 FP2, FP3,
1802 FP4, FP5,
1803 FP6, FP7,
1804 FPCONTROL, FPSTATUS, FPIADDR
1807 unsigned long registers[NUMREGBYTES/4];
1809 static long remote_debug;
1811 #define BUFMAX MAX_IO_BUF_SIZE
1812 static char inbuffer[BUFMAX], outbuffer[BUFMAX];
1813 static char spare_buffer[BUFMAX];
1816 struct stub_trace_frame
1818 int valid;
1819 unsigned long frame_id;
1820 unsigned long tdp_id;
1821 FRAME_DEF *frame_data;
1822 COLLECTION_FORMAT_DEF *format;
1823 unsigned long traceregs[NUMREGBYTES/4];
1824 unsigned char *stack_data;
1825 unsigned char *memrange_data;
1826 } curframe;
1828 /* ------------------- function prototypes -------------------- */
1830 void handle_request ( char * );
1832 /* ------------------- Implementation -------------------- */
1834 static void
1835 discard_packet( void )
1837 lan_input_queue.head_index = lan_input_queue.tail_index;
1839 lan_input_queue.gdb_packet_start =
1840 lan_input_queue.gdb_packet_end =
1841 lan_input_queue.gdb_packet_csum1 =
1842 lan_input_queue.gdb_packet_csum2 = -1;
1845 /* Utility function: convert an ASCII isxdigit to a hex nybble */
1847 static long
1848 hex( char ch )
1850 if ( (ch >= 'A') && (ch <= 'F') )
1851 return ch - 'A' + 10;
1852 if ( (ch >= 'a') && (ch <= 'f') )
1853 return ch - 'a' + 10;
1854 if ( (ch >= '0') && (ch <= '9') )
1855 return ch - '0';
1856 return -1;
1859 static void
1860 getpacket( void )
1862 unsigned char our_checksum, their_checksum;
1863 char *copy = inbuffer;
1864 unsigned char c;
1866 our_checksum = 0;
1868 /* first find the '$' */
1869 while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
1870 if (c == 0) /* ??? Protocol error? (paranoia) */
1872 /* PROTOCOL ERROR (missing '$') */
1873 /*NACK_PKT( );*/ /*<ETHERNET>*/
1874 return;
1877 /* Now copy the message (up to the '#') */
1878 for (c = lan_next_queue_char ( &lan_input_queue ); /* skip the '$' */
1879 c != 0 && c != '#'; /* stop at the '#' */
1880 c = lan_next_queue_char ( &lan_input_queue ))
1882 *copy++ = c;
1883 our_checksum += c;
1885 *copy++ = '\0'; /* terminate the copy */
1887 if (c == 0) /* ??? Protocol error? (paranoia) */
1889 /* PROTOCOL ERROR (missing '#') */
1890 /*NACK_PKT( );*/ /*<ETHERNET>*/
1891 return;
1893 their_checksum = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
1894 their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
1896 /* Now reset the queue packet-recognition bits */
1897 discard_packet( );
1899 if ( remote_debug ||
1900 our_checksum == their_checksum )
1902 ACK_PKT( ); /* good packet */
1903 /* Parse and process the packet */
1904 handle_request( inbuffer );
1906 else
1907 /* PROTOCOL ERROR (bad check sum) */
1908 NACK_PKT( );
1911 /* EMC will provide a better implementation
1912 (perhaps just of LAN_PUT_CHAR) that does not block.
1913 For now, this works. */
1916 static void
1917 putpacket( char *str )
1919 unsigned char checksum;
1921 /* '$'<packet>'#'<checksum> */
1923 if ( VIA_ETHERNET == gdb_host_comm )
1925 char *p_out;
1926 long length;
1928 p_out = eth_outbuffer;
1929 length = 0;
1932 if ( YES == gdb_cat_ack )
1934 *p_out++ = '+';
1935 ++length;
1938 gdb_cat_ack = NO;
1941 *p_out++ = '$';
1942 ++length;
1944 checksum = 0;
1946 while ( *str )
1948 *p_out++ = *str;
1949 ++length;
1950 checksum += *str++;
1953 *p_out++ = '#';
1954 *p_out++ = hexchars[checksum >> 4];
1955 *p_out = hexchars[checksum % 16];
1956 length += 3;
1958 eth_to_gdb( (UCHAR *) eth_outbuffer, length );
1961 else
1964 /* via RS-232 */
1965 do {
1966 LAN_PUT_CHAR( '$' );
1967 checksum = 0;
1969 while ( *str )
1971 LAN_PUT_CHAR( *str );
1972 checksum += *str++;
1975 LAN_PUT_CHAR( '#' );
1976 LAN_PUT_CHAR( hexchars[checksum >> 4] );
1977 LAN_PUT_CHAR( hexchars[checksum % 16] );
1978 } while ( 0 /* get_debug_char( ) != '+' */ );
1979 /* XXX FIXME: not waiting for the ack. */
1986 /*-----------------------------------------------------------------------------
1988 * FUNCTION NAME: gdb_get_eth_input
1991 * DESCRIPTION:
1994 * RETURN VALUE: None.
1997 * USED GLOBAL VARIABLES:
2000 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
2003 * NOTES:
2006 *---------------------------------------------------------------------------*/
2008 void gdb_get_eth_input( unsigned char *buf, long length )
2012 gdb_host_comm = VIA_ETHERNET;
2014 for ( ; 0 < length; ++buf, --length)
2017 if ( *buf == CONTROL_C )
2019 /* can't stop the target, but we can tell gdb to stop waiting... */
2020 discard_packet( );
2021 putpacket( "S03" ); /* send back SIGINT to the debugger */
2024 else
2026 lan_add_to_queue( (long) *buf, &lan_input_queue );
2027 get_gdb_input( (long) *buf, &lan_input_queue );
2033 return;
2035 /* end of 'gdb_get_eth_input'
2036 *===========================================================================*/
2041 /* STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT
2042 Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
2044 Dear reader:
2045 This code is based on the premise that if GDB receives a packet
2046 from the stub that begins with the character CAPITAL-OH, GDB will
2047 echo the rest of the packet to GDB's console / stdout. This gives
2048 the stub a way to send a message directly to the user. In practice,
2049 (as currently implemented), GDB will only accept such a packet when
2050 it believes the target to be running (ie. when you say STEP or
2051 CONTINUE); at other times it does not expect it. This will probably
2052 change as a side effect of the "asynchronous" behavior.
2054 Functions: gdb_putchar(char ch)
2055 gdb_write(char *str, int len)
2056 gdb_puts(char *str)
2057 gdb_error(char *format, char *parm)
2060 #if 0 /* avoid compiler warning while this is not used */
2062 /* Function: gdb_putchar(int)
2063 Make gdb write a char to stdout.
2064 Returns: the char */
2066 static int
2067 gdb_putchar( long ch )
2069 char buf[4];
2071 buf[0] = 'O';
2072 buf[1] = hexchars[ch >> 4];
2073 buf[2] = hexchars[ch & 0x0F];
2074 buf[3] = 0;
2075 putpacket( buf );
2076 return ch;
2078 #endif
2080 /* Function: gdb_write(char *, int)
2081 Make gdb write n bytes to stdout (not assumed to be null-terminated).
2082 Returns: number of bytes written */
2084 static int
2085 gdb_write( char *data, long len )
2087 char *buf, *cpy;
2088 long i;
2090 buf = outbuffer;
2091 buf[0] = 'O';
2092 i = 0;
2093 while ( i < len )
2095 for ( cpy = buf+1;
2096 i < len && cpy < buf + BUFMAX - 3;
2097 i++ )
2099 *cpy++ = hexchars[data[i] >> 4];
2100 *cpy++ = hexchars[data[i] & 0x0F];
2102 *cpy = 0;
2103 putpacket( buf );
2105 return len;
2108 /* Function: gdb_puts(char *)
2109 Make gdb write a null-terminated string to stdout.
2110 Returns: the length of the string */
2112 static int
2113 gdb_puts( char *str )
2115 return gdb_write( str, strlen( str ) );
2118 /* Function: gdb_error(char *, char *)
2119 Send an error message to gdb's stdout.
2120 First string may have 1 (one) optional "%s" in it, which
2121 will cause the optional second string to be inserted. */
2123 #if 0
2124 static void
2125 gdb_error( char *format, char *parm )
2127 static char buf[400];
2128 char *cpy;
2129 long len;
2131 if ( remote_debug )
2133 if ( format && *format )
2134 len = strlen( format );
2135 else
2136 return; /* empty input */
2138 if ( parm && *parm )
2139 len += strlen( parm );
2141 for ( cpy = buf; *format; )
2143 if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */
2145 format += 2; /* advance two chars instead of just one */
2146 while ( parm && *parm )
2147 *cpy++ = *parm++;
2149 else
2150 *cpy++ = *format++;
2152 *cpy = '\0';
2153 gdb_puts( buf );
2156 #endif
2158 static void gdb_note (char *, int);
2159 static int error_ret (int, char *, int);
2161 static unsigned long
2162 elinum_to_index (unsigned long elinum)
2164 if ((elinum & 0xf0) == 0xd0)
2165 return (elinum & 0x0f);
2166 else if ((elinum & 0xf0) == 0xa0)
2167 return (elinum & 0x0f) + 8;
2168 else
2169 return -1;
2172 static long
2173 index_to_elinum (unsigned long index)
2175 if (index <= 7)
2176 return index + 0xd0;
2177 else if (index <= 15)
2178 return (index - 8) + 0xa0;
2179 else
2180 return -1;
2185 READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
2187 The following code pertains to reading memory from the target.
2188 Some sort of exception handling should be added to make it safe.
2190 READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
2192 Safe Memory Access:
2194 All reads and writes into the application's memory will pass thru
2195 get_uchar() or set_uchar(), which check whether accessing their
2196 argument is legal before actual access (thus avoiding a bus error).
2200 enum { SUCCESS = 0, FAIL = -1 };
2202 #if 0
2203 static long get_uchar ( const unsigned char * );
2204 #endif
2205 static long set_uchar ( unsigned char *, unsigned char );
2206 static long read_access_violation ( const void * );
2207 static long write_access_violation ( const void * );
2208 static long read_access_range(const void *, long);
2209 static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *);
2211 static int
2212 dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
2214 if (src)
2215 sprintp (spare_buffer,
2216 "'%s' returned DTC error '%s'.\n", src, get_err_text (code));
2217 else
2218 sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code));
2220 gdb_puts (spare_buffer);
2221 return ret;
2225 #if 0
2226 /* I think this function is unnecessary since the introduction of
2227 adbg_find_memory_addr_in_frame. */
2229 /* Return the number of expressions in the format associated with a
2230 given trace frame. */
2231 static int
2232 count_frame_exprs (FRAME_DEF *frame)
2234 CFD *format;
2235 T_EXPR *expr;
2236 int num_exprs;
2238 /* Get the format from the frame. */
2239 get_frame_format_pointer (frame, &format);
2241 /* Walk the linked list of expressions, and count the number of
2242 expressions we find there. */
2243 num_exprs = 0;
2244 for (expr = format->p_cfd_expr; expr; expr = expr->next)
2245 num_exprs++;
2247 return num_exprs;
2249 #endif
2251 #if 0
2252 /* Function: get_frame_addr
2254 * Description: If the input memory address was collected in the
2255 * current trace frame, then lookup and return the address
2256 * from within the trace buffer from which the collected byte
2257 * may be retrieved. Else return -1. */
2259 unsigned char *
2260 get_frame_addr ( const unsigned char *addr )
2262 unsigned char *base, *regs, *stack, *mem;
2263 CFD *dummy;
2264 DTC_RESPONSE ret;
2266 /* first, see if addr is on the saved piece of stack for curframe */
2267 if (curframe.format->stack_size > 0 &&
2268 (base = (unsigned char *) curframe.traceregs[A7]) <= addr &&
2269 addr < base + curframe.format->stack_size)
2271 gdb_puts("STUB: get_frame_addr: call get_addr_to_frame_regs_stack_mem\n");
2272 if ((ret = get_addr_to_frame_regs_stack_mem (curframe.frame_data,
2273 &dummy,
2274 (void *) &regs,
2275 (void *) &stack,
2276 (void *) &mem))
2277 != OK_TARGET_RESPONSE)
2278 return (void *) dtc_error_ret (-1,
2279 "get_addr_to_frame_regs_stack_mem",
2280 ret);
2281 else
2282 return stack + (addr - base);
2285 /* Next, try to find addr in the current frame's expression-
2286 collected memory blocks. I'm sure this is at least quadradic in
2287 time. */
2289 int num_exprs = count_frame_exprs (curframe.frame_data);
2290 int expr, block;
2292 /* Try each expression in turn. */
2293 for (expr = 0; expr < num_exprs; expr++)
2295 for (block = 0; ; block++)
2297 T_EXPR_DATA *data;
2298 if (adbg_get_expr_data (curframe.frame_data,
2299 'x', expr, block,
2300 &data)
2301 != OK_TARGET_RESPONSE)
2302 break;
2303 else if ((unsigned char *) data->address <= addr
2304 && addr < ((unsigned char *) data->address + data->size))
2306 /* We have found the right block; is it valid data?
2307 Upper-case stamps mean bad data. */
2308 if ('A' <= data->stamp && data->stamp <= 'Z')
2310 gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
2311 return (unsigned char *) -1;
2313 else
2315 if (remote_debug > 1)
2317 sprintp(spare_buffer,
2318 "STUB: get_frame_addr: got it [%x,%x)\n",
2319 data->address, data->address + data->size);
2320 gdb_puts(spare_buffer);
2323 return (((unsigned char *) &data->data)
2324 + (addr - (unsigned char *) data->address));
2331 /* not found, return error */
2332 return (unsigned char *) -1;
2335 /*============================================================*/
2337 static long get_uchar ( const unsigned char * addr )
2339 unsigned char *frame_addr;
2341 if ( read_access_violation ( addr ) )
2342 return ( -1 ); /* Access error */
2344 if (curframe.valid) /* if debugging a trace frame? */
2346 /* If the requested address was collected in the current frame,
2347 * then fetch and return the data from the trace buffer.
2349 if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1)
2350 return ( *frame_addr );
2351 /* If the requested address is in the Code Section,
2352 * let's be magnanimous and read it anyway (else we shall
2353 * not be able to disassemble, find function prologues, etc.)
2355 else if (CS_CODE_START <= (unsigned long) addr &&
2356 (unsigned long) addr < CS_CODE_START + CS_CODE_SIZE)
2357 return (*addr);
2358 else
2359 return ( -1 ); /* "Access error" (the data was not collected) */
2361 else
2362 /* Not debugging a trace frame, read the data from live memory. */
2363 return ( *addr ); /* Meaningful result >= 0 */
2365 #endif
2367 /*============================================================*/
2369 static long set_uchar ( unsigned char * addr, unsigned char val )
2371 long check_result = write_access_violation ( addr );
2373 if ( check_result != 0L )
2374 return ( check_result ); /* Access error */
2376 return ( *addr = val ); /* Successful writing */
2379 /*============================================================*/
2382 * Function read_access_violation() below returns TRUE if dereferencing
2383 * its argument for reading would cause a bus error - and FALSE otherwise:
2386 static long read_access_violation ( const void * addr )
2388 return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
2389 ( ( addr < NVD_START ) || ( addr >= NVD_END ) ) );
2392 /*============================================================*/
2395 * Function write_access_violation() below returns zero if dereferencing
2396 * its argument for writing is safe, -1 on a soft error (the argument
2397 * falls into the write-protected area), -2 on a hard error (the argument
2398 * points to a non-existent memory location). In other words, it returns
2399 * FALSE when no bus error is expected - and an error code otherwise:
2402 static long write_access_violation ( const void * addr )
2405 * The boundaries of the write-protected area have to be received via
2406 * an API provided in the Symmetrix core code. For now, these limits
2407 * are hard-coded:
2410 if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
2411 return ( -1 ); /* soft error */
2413 if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
2414 ( ( addr < NVD_START ) || ( addr >= NVD_END ) ) )
2415 return ( -2 ); /* hard error */
2417 return ( 0 );
2421 /* read_access_range is like read_access_violation,
2422 but returns the number of bytes we can read w/o faulting.
2423 that is, it checks an address range and tells us what portion
2424 (if any) of the prefix is safe to read without a bus error */
2425 static long
2426 read_access_range(const void *addr, long count)
2428 if ((addr >= SRAM_START) && (addr < SRAM_END))
2430 if ((char *)addr + count < (char *)SRAM_END)
2431 return (count);
2432 else
2433 return ((char *)SRAM_END - (char *)addr);
2435 else if (((char *)addr >= (char *)NVD_START) &&
2436 ((char *)addr < (char *)NVD_END))
2438 if ((char *)addr + count < (char *)NVD_END)
2439 return (count);
2440 else
2441 return ((char *)NVD_END - (char *)addr);
2443 else
2444 return (0);
2447 /* Convert the memory pointed to by mem into hex, placing result in buf.
2448 Return SUCCESS or FAIL.
2449 If MAY_FAULT is non-zero, then we should return FAIL in response to
2450 a fault; if zero treat a fault like any other fault in the stub. */
2452 static long
2453 mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
2455 long ndx;
2456 long ndx2;
2457 long ch;
2458 long incr;
2459 unsigned char *location;
2460 DTC_RESPONSE status;
2462 if (may_fault)
2464 for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
2466 status = find_memory(mem, count - ndx, &location, &incr);
2468 if (status == OK_TARGET_RESPONSE)
2470 if (incr > 0)
2472 for (ndx2 = 0; ndx2 < incr; ndx2++)
2474 ch = *location++;
2475 *buf++ = hexchars[ch >> 4];
2476 *buf++ = hexchars[ch & 0xf];
2478 mem += incr;
2480 else if (incr <= 0) /* should never happen */
2482 *buf = 0;
2483 return (0);
2486 else if (status == NOT_FOUND_TARGET_RESPONSE)
2488 *buf = 0;
2489 return (ndx); /* return amount copied */
2491 else
2493 *buf = 0;
2494 return (0); /* XXX: how do we tell the user the status? */
2497 *buf = 0;
2498 return (count);
2500 else
2502 for (ndx = 0; ndx < count; ndx++)
2504 ch = *mem++;
2505 *buf++ = hexchars[ch >> 4];
2506 *buf++ = hexchars[ch & 0xf];
2508 *buf = 0;
2509 return (count); /* we copied everything */
2513 static DTC_RESPONSE
2514 find_memory(unsigned char *mem, long count,
2515 unsigned char **location, long *incr)
2517 DTC_RESPONSE retval;
2518 long length;
2520 /* figure out how much of the memory range we can read w/o faulting */
2521 count = read_access_range(mem, count);
2522 if (count == 0)
2523 return (NOT_FOUND_TARGET_RESPONSE);
2525 if (curframe.valid)
2527 unsigned char *mem_block;
2528 unsigned char *mem_addr;
2529 unsigned long mem_size;
2530 unsigned long mem_stamp;
2532 retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem,
2533 (unsigned long **)&mem_block,
2534 (unsigned long **)&mem_addr,
2535 &mem_size, &mem_stamp);
2537 switch (retval)
2539 case OK_TARGET_RESPONSE:
2540 #if 0
2541 printp("FOUND: mem %x block %x addr %x size %d stamp %x\n",
2542 mem, mem_block, mem_addr, mem_size, mem_stamp);
2543 #endif
2544 *location = mem_block + (mem - mem_addr);
2545 length = mem_size - (mem - mem_addr);
2547 if (length < count)
2548 *incr = length;
2549 else
2550 *incr = count;
2552 break;
2554 case NOT_FOUND_TARGET_RESPONSE:
2555 case NEAR_FOUND_TARGET_RESPONSE:
2556 #if 0
2557 printp("NOT FOUND: mem %x, checking code region\n", mem);
2558 #endif
2559 /* check to see if it's in the code region */
2560 if ((CS_CODE_START <= (long)mem) &&
2561 ((long)mem < CS_CODE_START + CS_CODE_SIZE))
2563 /* some or all of the address range is in the code */
2564 *location = mem;
2565 if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE)
2566 *incr = count; /* it's totally in the code */
2567 else
2568 /* how much is in the code? */
2569 *incr = CS_CODE_START + CS_CODE_SIZE - (long)mem;
2570 #if 0
2571 printp("FOUND in code region: %x\n", mem);
2572 #endif
2573 retval = OK_TARGET_RESPONSE;
2575 else
2576 retval = NOT_FOUND_TARGET_RESPONSE;
2578 break;
2580 default:
2581 #if 0
2582 printp("BAD RETURN: %d\n", retval);
2583 #endif
2584 retval = NOT_FOUND_TARGET_RESPONSE;
2585 break;
2588 else
2590 *location = mem;
2591 *incr = count;
2592 retval = OK_TARGET_RESPONSE;
2595 return (retval);
2598 /* Convert the hex array pointed to by buf into binary to be placed in mem.
2599 Return SUCCESS or FAIL. */
2601 static long
2602 hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
2604 long i, ch;
2606 for ( i=0; i<count; i++ )
2608 ch = hex( *buf++ ) << 4;
2609 ch = ch + hex( *buf++ );
2610 if ( may_fault )
2612 ch = set_uchar( mem++, ch );
2613 if ( ch < 0 ) /* negative return indicates error */
2614 return FAIL;
2616 else
2617 *mem++ = ch;
2619 return SUCCESS;
2622 /**********************************************/
2623 /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
2624 /* RETURN NUMBER OF CHARS PROCESSED */
2625 /**********************************************/
2627 static int
2628 hexToInt( char **ptr, unsigned long *intValue )
2630 long numChars = 0;
2631 long hexValue;
2633 *intValue = 0;
2634 while ( **ptr )
2636 hexValue = hex( **ptr );
2637 if ( hexValue >=0 )
2639 *intValue = (*intValue << 4) | hexValue;
2640 numChars ++;
2642 else
2643 break;
2644 (*ptr)++;
2646 return numChars;
2649 static volatile long gdb_handling_trap1;
2650 static volatile long gdb_handling_sstrace;
2651 static volatile long gdb_signo;
2654 Here is the "callable" stub entry point.
2655 Call this function with a GDB request as an argument,
2656 and it will service the request and return.
2658 May be further broken up as we go along, with individual requests
2659 broken out as separate functions.
2662 static char * handle_trace_query (char *);
2663 static char * handle_trace_set (char *);
2664 static int handle_format (char **request, CFD *format);
2665 static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc);
2666 static char * crc_query (char *);
2667 static char * handle_test (char *);
2669 void
2670 handle_request( char *request )
2672 #if 0
2673 remote_debug = 2;
2674 #endif
2675 switch( *request++ )
2677 case 'k': /* "kill" */
2678 curframe.valid = FALSE;
2679 putpacket ("");
2680 break;
2681 case 'D': /* "detach" */
2682 curframe.valid = FALSE;
2683 putpacket ("");
2684 break;
2685 default: /* Unknown code. Return an empty reply message. */
2686 putpacket( "" ); /* return empty packet */
2687 break;
2689 case 'H': /* Set thread for subsequent operations.
2690 Hct... c = 'c' for thread used in step and continue;
2691 t... can be -1 for all threads.
2692 c = 'g' for thread used in other operations.
2693 If zero, pick a thread, any thread. */
2695 putpacket( "OK" );
2696 break;
2698 case 'g': /* Read registers.
2699 Each byte of register data is described by
2700 two hex digits. registers are in the
2701 internal order for GDB, and the bytes in a
2702 register are in the same order the machine
2703 uses. */
2705 /* Return the values in (one of) the registers cache(s).
2706 Several situations may pertain:
2707 1) We're synchronous, in which case the "registers" array
2708 should actually be current.
2709 2) We're asynchronous, in which case the "registers" array
2710 holds whatever was cached most recently.
2711 3) We're looking at a trace frame that was collected earlier:
2712 we will return those earlier registers.
2715 /* all registers default to zero */
2716 memset (outbuffer, '0', NUMREGBYTES);
2717 outbuffer[NUMREGBYTES] = '\0';
2719 if (curframe.valid) /* debugging a trace frame */
2720 mem2hex( (unsigned char*) curframe.traceregs,
2721 outbuffer, NUMREGBYTES, 0 );
2722 else
2723 mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 );
2725 putpacket( outbuffer );
2727 break;
2728 case 'G': /* Write registers.
2729 Gxxxxxxxx Each byte of register data is described by
2730 two hex digits. */
2731 if (curframe.valid) /* debugging a trace frame */
2732 putpacket ("E03"); /* can't write regs into a trace frame! */
2733 else
2735 /* Write the values into the local registers cache...
2736 Note that no actual registers are being changed. */
2738 hex2mem( request,
2739 (unsigned char *) registers, NUMREGBYTES, 0 );
2740 putpacket( "OK" );
2742 break;
2743 case 'P': /* Write (single) register.
2744 Pnn=xxxxxxxx register nn gets value xxxxxxxx;
2745 two hex digits for each byte in the register
2746 (target byte order). */
2748 if (curframe.valid)
2749 putpacket ("E03"); /* can't write regs into a trace frame! */
2750 else
2752 unsigned long regno;
2754 if ( hexToInt( &request, &regno ) && *(request++) == '=' )
2756 if ( regno < NUMREGS )
2758 hexToInt( &request,
2759 (unsigned long *) &registers[REGISTER_BYTE(regno)]);
2761 putpacket( "OK" );
2763 else
2764 putpacket( "E01" ); /* bad packet or regno */
2767 break;
2768 case 'm': /* Read memory.
2769 mAAAAAAAA,LLLL AAAAAAAA is address, LLLL is length.
2770 Reply can be fewer bytes than requested
2771 if able to read only part of the data. */
2773 unsigned long addr, len;
2775 if ( hexToInt( &request, &addr ) &&
2776 *(request++) == ',' &&
2777 hexToInt( &request, &len ) )
2779 /* better not overwrite outbuffer! */
2780 if ( len > (BUFMAX / 2) - 5 )
2781 len = (BUFMAX / 2) - 5;
2782 if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0) /* XXX: eventually use returned value */
2783 putpacket( "E03" ); /* read fault (access denied) */
2784 else
2785 putpacket( outbuffer ); /* read succeeded */
2787 else
2788 putpacket( "E01" ); /* badly formed read request */
2791 break;
2792 case 'M': /* Write memory.
2793 Maaaaaaaa,llll:xxxx aaaaaaaa is address, llll is length;
2794 xxxx is data to write. */
2797 unsigned long addr, len;
2799 if (curframe.valid) /* can't write memory into a trace frame! */
2800 putpacket ("E03"); /* "access denied" */
2801 else /*** if ( write_access_enabled ) ***/
2803 if ( hexToInt( &request, &addr ) &&
2804 *(request++) == ',' &&
2805 hexToInt( &request, &len ) &&
2806 *(request++) == ':' )
2808 if (len == 2 &&
2809 addr >= CS_CODE_START &&
2810 addr <= LAST_CS_WORD)
2812 unsigned long val;
2814 if ( !hexToInt( &request, &val ) ||
2815 write_to_protected_mem( (void *)addr, val ) )
2816 putpacket( "E03" ); /* write fault (access denied) */
2817 else
2818 putpacket( "OK" ); /* write succeeded */
2820 else
2822 if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
2823 putpacket( "E03" ); /* write fault (access denied) */
2824 else
2825 putpacket( "OK" ); /* write succeeded */
2828 else
2829 putpacket( "E02" ); /* badly formed write request */
2832 break;
2833 case 'c': /* Continue.
2834 cAAAAAAAA AAAAAAAA is address from which to resume.
2835 If omitted, resume at current PC. */
2838 unsigned long addr;
2840 if (curframe.valid)
2842 /* Don't continue if debugging a trace frame! */
2843 gdb_puts ("Error: can't continue!\n");
2844 putpacket ("S03");
2846 else
2848 gdb_signo = 3;
2849 if (isxdigit(request[0]))
2851 hexToInt(&request, &addr);
2852 registers[REGISTER_BYTE(PC)] = addr;
2855 gdb_handling_trap1 = FALSE;
2856 gdb_handling_sstrace = FALSE;
2857 sss_trace_flag = '\0';
2860 break;
2861 case 's': /* Step.
2862 sAAAAAAAA AAAAAAAA is address from which to begin stepping.
2863 If omitted, begin stepping at current PC. */
2865 unsigned long addr;
2867 if (curframe.valid)
2869 /* Don't step if debugging a trace frame! */
2870 gdb_puts ("Error: can't step!\n");
2871 putpacket ("S03");
2873 else
2875 gdb_signo = 3;
2876 if (isxdigit(request[0]))
2878 hexToInt(&request, &addr);
2879 registers[REGISTER_BYTE(PC)] = addr;
2882 gdb_handling_trap1 = FALSE;
2883 gdb_handling_sstrace = FALSE;
2884 sss_trace_flag = 't';
2887 break;
2888 case 'C': /* Continue with signal.
2889 Cxx;AAAAAAAA xx is signal number in hex;
2890 AAAAAAAA is adddress from which to resume.
2891 If ;AAAAAAAA omitted, continue from PC. */
2894 unsigned long addr = 0;
2896 if (!gdb_handling_trap1 || curframe.valid)
2898 /* Don't continue if not currently in synchronous mode,
2899 or if currently debugging a trace frame! */
2900 gdb_puts( "Error: can't continue!\n" );
2901 putpacket( "S03" ); /* "sigquit" (better idea?) */
2903 else
2905 gdb_signo = 3;
2906 if ( isxdigit( *request ) )
2908 hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
2909 request += 2;
2910 if ( *request == ';' && isxdigit( *++request ) )
2912 hexToInt( &request, &addr );
2913 registers[REGISTER_BYTE(PC)] = addr;
2916 gdb_handling_trap1 = FALSE;
2917 gdb_handling_sstrace = FALSE;
2918 sss_trace_flag = '\0';
2921 break;
2922 case 'S': /* Step with signal.
2923 Sxx;AAAAAAAA xx is signal number in hex;
2924 AAAAAAAA is adddress from which to begin stepping.
2925 If ;AAAAAAAA omitted, begin stepping from PC. */
2927 unsigned long addr = 0;
2929 if (!gdb_handling_trap1 || curframe.valid)
2931 /* Don't step if not currently in synchronous mode,
2932 or if currently debugging a trace frame! */
2933 gdb_puts( "Error: can't step!\n" );
2934 putpacket( "S03" ); /* "sigquit" (better idea?) */
2936 else
2938 gdb_signo = 3;
2939 if ( isxdigit( *request ) )
2941 hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
2942 request += 2;
2943 if ( *request == ';' && isxdigit( *++request ) )
2945 hexToInt( &request, &addr );
2946 registers[REGISTER_BYTE(PC)] = addr;
2949 gdb_handling_trap1 = FALSE;
2950 gdb_handling_sstrace = FALSE;
2951 sss_trace_flag = 't';
2954 break;
2955 case '?': /* Query the latest reason for stopping.
2956 Should be same reply as was last generated
2957 for step or continue. */
2959 if ( gdb_signo == 0 )
2960 gdb_signo = 3; /* default to SIGQUIT */
2961 outbuffer[ 0 ] = 'S';
2962 outbuffer[ 1 ] = hexchars[ gdb_signo >> 4 ];
2963 outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ];
2964 outbuffer[ 3 ] = 0;
2965 putpacket( outbuffer );
2966 break;
2968 case 'd': /* Toggle debug mode
2969 I'm sure we can think of something interesting. */
2971 remote_debug = !remote_debug;
2972 putpacket( "" ); /* return empty packet */
2973 break;
2975 case 'q': /* general query */
2976 switch (*request++)
2978 default:
2979 putpacket (""); /* nak a request which we don't handle */
2980 break;
2981 case 'T': /* trace query */
2982 putpacket (handle_trace_query (request));
2983 break;
2984 case 'C': /* crc query (?) */
2985 if (*request++ == 'R' &&
2986 *request++ == 'C' &&
2987 *request++ == ':')
2988 putpacket (crc_query (request));
2989 else
2990 putpacket (""); /* unknown query */
2991 break;
2993 break;
2995 case 'Q': /* general set */
2996 switch (*request++)
2998 default:
2999 putpacket (""); /* nak a request which we don't handle */
3000 break;
3001 case 'T': /* trace */
3002 putpacket (handle_trace_set (request));
3003 break;
3005 break;
3007 case 'T':
3008 /* call test function: TAAA,BBB,CCC
3009 A, B, and C are arguments to pass to gdb_c_test. Reply is
3010 "E01" (bad arguments) or "OK" (test function called). */
3011 putpacket (handle_test (request));
3012 break;
3016 static TDP_SETUP_INFO tdp_temp;
3017 static int trace_running;
3020 * Function msgcmp:
3022 * If second argument (str) is matched in first argument,
3023 * then advance first argument past end of str and return "SAME"
3024 * else return "DIFFERENT" without changing first argument.
3026 * Return: zero for DIFFERENT, non-zero for SUCCESS
3029 static int
3030 msgcmp (char **msgp, char *str)
3032 char *next;
3034 if (msgp != 0 && str != 0) /* input validation */
3035 if ((next = *msgp) != 0)
3037 for (;
3038 *next && *str && *next == *str;
3039 next++, str++)
3042 if (*str == 0) /* matched all of str in msg */
3043 return (int) (*msgp = next); /* advance msg ptr past str */
3045 return 0; /* failure */
3048 static char *
3049 handle_trace_query (char *request)
3051 if (msgcmp (&request, "Status"))
3053 if (adbg_check_if_active ())
3055 gdb_puts ("Target trace is running.\n");
3056 return "T1";
3058 else
3060 gdb_puts ("Target trace not running.\n");
3061 trace_running = 0;
3062 return "T0";
3065 else /* unknown trace query */
3067 return "";
3071 static void
3072 gdb_note (char *fmt, int arg1)
3074 if (remote_debug > 1)
3076 sprintp (spare_buffer, fmt, arg1);
3077 gdb_puts (spare_buffer);
3081 static int
3082 error_ret (int ret, char *fmt, int arg1)
3084 if (remote_debug > 0)
3086 sprintp (spare_buffer, fmt, arg1);
3087 gdb_puts (spare_buffer);
3089 return ret;
3092 static int
3093 handle_format (char **request, COLLECTION_FORMAT_DEF *format)
3095 MEMRANGE_DEF m;
3096 DTC_RESPONSE ret;
3097 int elinum;
3098 unsigned long regnum;
3099 long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4];
3100 struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes;
3102 if (format->id == 0)
3104 if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
3105 return dtc_error_ret (-1, "get_unused_format_id", ret);
3107 if (**request == 'R')
3109 (*request)++;
3110 hexToInt (request, &format->regs_mask);
3112 gdb_note ("STUB: call define_format (id = %d, ", format->id);
3113 gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
3115 if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
3117 sprintp (spare_buffer,
3118 "'define_format': DTC error '%s' for format id %d.\n",
3119 get_err_text (ret),
3120 format->id);
3121 gdb_puts (spare_buffer);
3122 return -1;
3126 while ((**request == 'M') || (**request == 'X'))
3128 switch (**request)
3130 case 'M': /* M<regnum>,<offset>,<size> */
3131 (*request)++;
3132 hexToInt(request, &regnum);
3134 if (regnum == 0 || regnum == (unsigned long) -1)
3135 m.typecode = -1;
3136 else if ((elinum = index_to_elinum (regnum)) > 0)
3137 m.typecode = elinum;
3138 else
3139 return error_ret (-1,
3140 "Memrange register %d is not between 0 and 15\n",
3141 regnum);
3143 if (*(*request)++ != ',')
3144 return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1);
3145 hexToInt(request, &m.offset);
3146 if (*(*request)++ != ',')
3147 return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2);
3148 hexToInt(request, &m.size);
3150 gdb_note ("STUB: call add_format_mem_range (typecode = 0x%x, ",
3151 m.typecode);
3152 gdb_note ("offset = 0x%X, ", m.offset);
3153 gdb_note ("size = %d);\n", m.size);
3154 if ((ret = add_format_mem_ranges (format->id, &m)) !=
3155 OK_TARGET_RESPONSE)
3157 dtc_error_ret (-1, "add_format_mem_ranges", ret);
3158 sprintp (spare_buffer,
3159 "format id %d: memrange (0x%x, 0x%x, 0x%x).\n",
3160 format->id, m.typecode, m.offset, m.size);
3161 gdb_puts (spare_buffer);
3162 return -1;
3164 break;
3166 case 'X': /* X<length>,<bytecodes> */
3168 unsigned long length;
3170 (*request)++;
3171 hexToInt(request, &length);
3173 if ((length <= 0) || (length > MAX_BYTE_CODES))
3174 return error_ret (-1,
3175 "Bytecode expression length (%d) too large\n",
3176 length);
3178 if (*(*request)++ != ',')
3179 return error_ret (-1,
3180 "Malformed bytecode expr (comma#%d missing)\n",
3182 t_expr->next = NULL;
3183 /* subtract one to account for expr[0] in header */
3184 t_expr->size = sizeof(struct t_expr_tag) + length - 1;
3185 t_expr->expr_size = length;
3187 hex2mem(*request, &t_expr->expr[0], length, 0);
3188 *request += 2 * length;
3189 build_and_add_expression(format->id, t_expr);
3191 break;
3194 return 0;
3197 static char *
3198 handle_trace_set (char *request)
3200 long n_frame;
3201 unsigned long frameno, tdp, pc, start, stop;
3202 DTC_RESPONSE ret = -1;
3203 static COLLECTION_FORMAT_DEF tempfmt1;
3204 static char enable;
3205 static char retbuf[20];
3207 if (msgcmp (&request, "init"))
3209 gdb_note ("STUB: call clear_trace_state();\n", 0);
3210 curframe.valid = 0; /* all old frames become invalid now */
3211 if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE)
3212 return "OK";
3213 else
3215 sprintp (retbuf, "E2%x", ret);
3216 return (char *) dtc_error_ret ((int) &retbuf,
3217 "clear_trace_state",
3218 ret);
3221 else if (msgcmp (&request, "Start"))
3223 trace_running = 1;
3224 curframe.valid = 0; /* all old frames become invalid now */
3225 gdb_note ("STUB: call start_trace_experiment();\n", 0);
3226 adbg_save_trace_in_nvd ();
3227 if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE)
3228 return "OK";
3229 else
3231 sprintp (retbuf, "E2%x", ret);
3232 return (char *) dtc_error_ret ((int) &retbuf,
3233 "start_trace_experiment",
3234 ret);
3237 else if (msgcmp (&request, "Stop"))
3239 trace_running = 0;
3240 if (adbg_check_if_active ())
3242 gdb_note ("STUB: call end_trace_experiment();\n", 0);
3243 if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
3244 return "OK";
3245 else
3247 sprintp (retbuf, "E2%x", ret);
3248 return (char *) dtc_error_ret ((int) &retbuf,
3249 "end_trace_experiment",
3250 ret);
3253 else return "OK";
3255 /* "TDP:" (The 'T' was consumed in handle_request.) */
3256 else if (msgcmp (&request, "DP:"))
3258 /* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format>
3259 {S{R[M,X]+}}<tp-format>
3261 D -- disable tracepoint (illegal from EMC's point of view)
3262 E -- enable tracepoint?
3264 R -- regs format: R<regs-mask>
3265 M -- memory format: M<regnum>,<offset>,<size>
3266 X -- expr format: X<size>,<bytecodes>
3267 S -- fencepost between trap formats and stepping formats.
3270 /* state variable, required for splitting TDP packets. */
3271 static int doing_step_formats;
3274 * TDP: packets may now be split into multiple packets.
3275 * If a TDP packet is to be continued in another packet, it
3276 * must end in a "-" character. The subsequent continuation
3277 * packet will then begin with a "-" character, between the
3278 * token "TDP:" and the tdp_id field. The ID and address
3279 * will be repeated in each sub-packet. The step_count,
3280 * pass_count, and 'enabled' field must appear in the first
3281 * packet. The boundary between sub-packets may not appear
3282 * between the "S" that denotes the start of stepping "formats",
3283 * and the regs_mask that follows it. The split may also not
3284 * occur in the middle of either a memrange description or a
3285 * bytecode string. -- MVS
3288 if (*request == '-') /* this is a continuation of a
3289 trace definition in progress */
3291 unsigned long temp_id, temp_addr;
3293 request++;
3294 if (!(hexToInt (&request, &temp_id) &&
3295 *request++ == ':'))
3296 return "E11"; /* badly formed packet, field 1 */
3298 if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
3299 *request++ == ':'))
3300 return "E12"; /* badly formed packet, field 2 */
3302 if (temp_id != tdp_temp.id)
3303 return "E11"; /* something wrong: field 1 doesn't match */
3304 if (temp_addr != (unsigned long) tdp_temp.addr)
3305 return "E12"; /* something wrong: field 2 doesn't match */
3307 else /* This is a new TDP definition */
3309 memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
3310 memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3311 doing_step_formats = FALSE;
3313 if (!(hexToInt (&request, &tdp_temp.id) &&
3314 *request++ == ':'))
3315 return "E11"; /* badly formed packet, field 1 */
3317 if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
3318 *request++ == ':'))
3319 return "E12"; /* badly formed packet, field 2 */
3321 if (!(((enable = *request++) == 'D' || enable == 'E') &&
3322 *request++ == ':'))
3323 return "E13"; /* badly formed packet, field 3 */
3324 #if 0
3325 if (enable == 'D')
3327 gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
3328 return "E20";
3330 #endif
3331 if (!(hexToInt (&request, &tdp_temp.stepcount) &&
3332 *request++ == ':'))
3333 return "E14"; /* badly formed packet, field 4 */
3335 if (!hexToInt (&request, &tdp_temp.pass_limit))
3336 return "E15"; /* badly formed packet, field 5 */
3340 /* Typically, the first group of collection descriptors
3341 refers to the trap collection. There is an "S" token
3342 to act as a fencepost between collection descriptors for
3343 the trap, and those for the single-stepping.
3345 However, when the packet is split up into several packets,
3346 this "S" token may already have been seen in a previous
3347 sub-packet; so we have to remember it in a state variable. */
3349 if (*request == 'R' || *request == 'M' || *request == 'X')
3351 if (handle_format (&request, &tempfmt1))
3352 return "E16";
3353 if (doing_step_formats)
3354 tdp_temp.tp_format_p = tempfmt1.id;
3355 else
3356 tdp_temp.tdp_format_p = tempfmt1.id;
3359 /* When we see the "S" token, we remember it in a state variable
3360 (in case the packet is split up and continued in another message),
3361 and discard all current state from the collection "format". */
3362 if (*request == 'S')
3364 doing_step_formats = TRUE;
3365 /* discard prev format and start a new one */
3366 memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3367 request++;
3369 /* Having seen the "S" fencepost, it is now possible that
3370 we will see some more collection descriptors pertaining
3371 to the stepping collection. */
3372 if (*request == 'R' || *request == 'M' || *request == 'X')
3374 if (handle_format (&request, &tempfmt1))
3375 return "E17";
3376 /* new format ID is tp_format */
3377 tdp_temp.tp_format_p = tempfmt1.id;
3381 if (*request == '-') /* this TDP definition will be continued. */
3382 sprintp (retbuf, "OK");
3383 else if (enable == 'E') /* end of TDP definition: pass to ADBG (if enabled!) */
3385 gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id);
3386 gdb_note ("addr 0x%X, ", (int) tdp_temp.addr);
3387 gdb_note ("passc %d, ", tdp_temp.pass_limit);
3388 gdb_note ("stepc %d, ", tdp_temp.stepcount);
3389 gdb_note ("TDP fmt #%d, ", tdp_temp.tdp_format_p);
3390 gdb_note ("TP fmt #%d);\n", tdp_temp.tp_format_p);
3392 ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
3394 if (ret == OK_TARGET_RESPONSE)
3396 sprintp (retbuf, "OK");
3398 else
3400 sprintp (spare_buffer,
3401 "'define_tdp' returned DTC error '%s' for tracepoint %d.\n",
3402 get_err_text (ret),
3403 tdp_temp.id);
3404 gdb_puts (spare_buffer);
3405 sprintp (retbuf, "E2%x", ret);
3407 /* Redundant, but let's try to make sure this state gets discarded. */
3409 memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
3410 memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3413 else /* ADBG_DTC does not support disabled tracepoints -- ignore it. */
3414 gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
3416 return retbuf;
3418 else if (msgcmp (&request, "Frame:"))
3420 ret = OK_TARGET_RESPONSE;
3422 if (msgcmp (&request, "pc:"))
3424 if (!hexToInt (&request, &pc))
3425 return "E10"; /* badly formed packet */
3426 n_frame = curframe.valid ? curframe.frame_id + 1 : 0;
3427 gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame);
3428 gdb_note ("pc 0x%X);\n", pc);
3429 ret = fetch_trace_frame_with_pc (&n_frame,
3430 (void *) pc,
3431 &curframe.format,
3432 &curframe.frame_data);
3434 else if (msgcmp (&request, "tdp:"))
3436 if (!hexToInt (&request, &tdp))
3437 return "E10"; /* badly formed packet */
3438 n_frame = curframe.valid ? curframe.frame_id + 1: 0;
3439 gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame);
3440 gdb_note ("tdp 0x%X);\n", tdp);
3441 ret = fetch_trace_frame_with_tdp (&n_frame,
3442 tdp,
3443 &curframe.format,
3444 &curframe.frame_data);
3446 else if (msgcmp (&request, "range:"))
3448 if (!(hexToInt (&request, &start) &&
3449 *request++ == ':'))
3450 return "E11"; /* badly formed packet, field 1 */
3451 else if (!hexToInt (&request, &stop))
3452 return "E12"; /* badly formed packet, field 2 */
3453 n_frame = curframe.valid ? curframe.frame_id + 1: 0;
3454 gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame);
3455 gdb_note ("start 0x%X, ", start);
3456 gdb_note ("stop 0x%X);\n", stop);
3457 ret = fetch_trace_frame_with_pc_in_range (&n_frame,
3458 (void *) start,
3459 (void *) stop,
3460 &curframe.format,
3461 &curframe.frame_data);
3463 else if (msgcmp (&request, "outside:"))
3465 if (!(hexToInt (&request, &start) &&
3466 *request++ == ':'))
3467 return "E11"; /* badly formed packet, field 1 */
3468 else if (!hexToInt (&request, &stop))
3469 return "E12"; /* badly formed packet, field 2 */
3470 n_frame = curframe.valid ? curframe.frame_id + 1: 0;
3471 gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame);
3472 gdb_note ("start 0x%X, ", start);
3473 gdb_note ("stop 0x%X);\n", stop);
3474 ret = fetch_trace_frame_with_pc_outside (&n_frame,
3475 (void *) start,
3476 (void *) stop,
3477 &curframe.format,
3478 &curframe.frame_data);
3480 else /* simple TFind by frame number: */
3482 if (!hexToInt (&request, &frameno))
3483 return "E10"; /* badly formed packet */
3484 if (frameno != (unsigned long) -1)
3486 gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno);
3487 ret = fetch_trace_frame (n_frame = frameno,
3488 &curframe.format,
3489 &curframe.frame_data);
3490 #if 0
3491 printp("STUB: fetch_trace_frame: return %d\n", ret);
3492 #endif
3494 else /* discard any trace frame, debug "the real world" */
3496 if (curframe.valid)
3497 gdb_note ("STUB: discard current trace frame #%d.\n",
3498 curframe.frame_id);
3499 curframe.valid = 0;
3500 return "OK";
3503 if (ret == OK_TARGET_RESPONSE) /* fetch_trace_frame succeeded */
3504 { /* setup for debugging the trace frame */
3505 curframe.valid = 1;
3506 curframe.frame_id = n_frame;
3507 curframe.tdp_id = curframe.frame_data->id;
3509 memset ((char *) &curframe.traceregs, 0,
3510 sizeof (curframe.traceregs));
3511 curframe.traceregs[PC] = (unsigned long)
3512 curframe.frame_data->program_counter;
3514 if (curframe.format)
3516 unsigned long regs_mask = curframe.format->regs_mask;
3517 unsigned long *regs, *stack, *mem;
3518 unsigned long regno, index = 0;
3519 CFD *dummy;
3521 if ((ret = get_addr_to_frame_regs_stack_mem
3522 (curframe.frame_data, &dummy, &regs, &stack, &mem))
3523 != OK_TARGET_RESPONSE)
3525 curframe.valid = 0;
3526 sprintp (retbuf, "E2%x", ret);
3527 return (char *)
3528 dtc_error_ret ((int) &retbuf,
3529 "get_addr_to_frame_regs_stack_mem",
3530 ret);
3533 if (remote_debug > 1)
3534 { /* echo what we've found to gdb console */
3535 sprintp (spare_buffer,
3536 "STUB: Found frame %d, TDP %d, format %d (%s):\n",
3537 curframe.frame_id,
3538 curframe.tdp_id & 0x7fffffff,
3539 curframe.format->id,
3540 curframe.tdp_id & 0x80000000 ?
3541 "trap frame" : "stepping frame");
3542 gdb_puts (spare_buffer);
3544 /* copy trace frame regs into stub's data format */
3545 for (regno = 0, index = 0;
3546 regno < 16;
3547 regno++, regs_mask >>= 1)
3548 if (regs_mask & 1) /* got a collected register */
3550 curframe.traceregs[regno] = regs[index++];
3551 if (remote_debug > 1)
3553 sprintp (spare_buffer,
3554 " Collected 0x%08x for register %d.\n",
3555 curframe.traceregs[regno], regno);
3556 gdb_puts (spare_buffer);
3559 if (remote_debug > 1)
3561 long midx, ridx, len;
3562 MEMRANGE_DEF *mrange;
3563 unsigned char *data, *base;
3565 if (curframe.format->stack_size > 0)
3567 len = curframe.format->stack_size;
3568 sprintp (spare_buffer,
3569 " Collected %d bytes of stack at 0x%x:\n",
3570 len, curframe.traceregs[A7]);
3571 gdb_puts (spare_buffer);
3573 /* print stack data, but stay under msg len */
3574 if (len >= (NUMREGBYTES/2 - 2))
3575 len = (NUMREGBYTES/2 - 3);
3576 mem2hex ((unsigned char *) stack,
3577 spare_buffer, len, 0);
3578 spare_buffer [len * 2] = '\n';
3579 spare_buffer [len * 2 + 1] = '\0'; /* EOS */
3580 gdb_puts (spare_buffer);
3582 else
3583 gdb_puts ("Stack not collected\n");
3585 for (midx = 0;
3586 get_addr_to_a_mem_range (curframe.frame_data,
3587 midx,
3588 &mrange,
3589 (void **) &data)
3590 == OK_TARGET_RESPONSE;
3591 midx++)
3593 if ((mrange->typecode == 0) ||
3594 (mrange->typecode == (unsigned long) -1))
3596 sprintp (spare_buffer,
3597 " Collected %d bytes at MEM: 0x%x:\n",
3598 mrange->size, mrange->offset);
3599 base = (unsigned char *) mrange->offset;
3601 else
3603 if ((ridx = elinum_to_index (mrange->typecode)) > 0)
3604 base = (unsigned char *) curframe.traceregs[ridx]
3605 + (long) mrange->offset;
3606 else
3608 sprintp (spare_buffer,
3609 "STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n",
3610 midx,
3611 mrange->typecode,
3612 mrange->offset,
3613 mrange->size);
3614 gdb_puts (spare_buffer);
3615 continue;
3617 sprintp (spare_buffer,
3618 " Collected %d bytes at 0x%x (REG %X + %d):\n",
3619 mrange->size,
3620 base,
3621 mrange->typecode,
3622 mrange->offset);
3624 gdb_puts (spare_buffer);
3625 len = mrange->size;
3626 if (len >= (NUMREGBYTES/2 - 2))
3627 len = (NUMREGBYTES/2 - 3);
3628 mem2hex (data, spare_buffer, len, 0);
3629 spare_buffer [len * 2] = '\n';
3630 spare_buffer [len * 2 + 1] = '\0'; /* EOS */
3631 gdb_puts (spare_buffer);
3635 sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
3636 return retbuf;
3638 else if (ret == NOT_FOUND_TARGET_RESPONSE)
3640 /* Here's a question: if the fetch_trace_frame call failed
3641 (which probably means a bad "TFIND" command from GDB),
3642 should we remain focused on the previous frame (if any),
3643 or should we revert to "no current frame"?
3645 return "F-1";
3647 else
3649 sprintp (retbuf, "E2%x", ret);
3650 return (char *) dtc_error_ret ((int) &retbuf,
3651 "fetch_trace_frame[...]",
3652 ret);
3655 else /* unknown trace command */
3657 return "";
3661 /* Table used by the crc32 function to calcuate the checksum. */
3662 static unsigned long crc32_table[256];
3664 static int crc_mem_err;
3666 static unsigned long
3667 crc32 (buf, len, crc)
3668 unsigned char *buf;
3669 int len;
3670 unsigned long crc;
3672 crc_mem_err = FALSE;
3674 if (! crc32_table[1])
3676 /* Initialize the CRC table and the decoding table. */
3677 int i, j;
3678 unsigned int c;
3680 for (i = 0; i < 256; i++)
3682 for (c = i << 24, j = 8; j > 0; --j)
3683 c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
3684 crc32_table[i] = c;
3688 while (len--)
3690 if (read_access_violation (buf))
3692 crc_mem_err = TRUE;
3693 return -1;
3695 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
3697 return crc;
3700 static char *
3701 crc_query (cmd)
3702 char *cmd;
3704 unsigned long startmem, len, crc;
3705 static char buf[32];
3707 if (hexToInt (&cmd, &startmem) &&
3708 *cmd++ == ',' &&
3709 hexToInt (&cmd, &len))
3711 crc = crc32 ((unsigned char *) startmem, len, 0xffffffff);
3712 if (!crc_mem_err)
3714 sprintp (buf, "C%08x", crc);
3715 return buf;
3717 /* else error, fall thru */
3719 sprintp (buf, "E01");
3720 return buf;
3724 static char *
3725 handle_test (request)
3726 char *request;
3728 ULONG args[7];
3729 int i;
3731 /* Parse the arguments, a comma-separated list of hex numbers, into
3732 ARGS. Parse at most six arguments. */
3733 i = 1;
3734 if (*request != '\0')
3735 while (i < 7)
3737 if (! hexToInt (&request, &args[i++]))
3738 return "E01";
3739 if (*request == '\0')
3740 break;
3741 if (*request++ != ',')
3742 return "E01";
3745 /* Fill the rest of the args array with zeros. This is what the
3746 INLINES command processor does with omitted arguments. */
3747 for (; i < 7; i++)
3748 args[i] = 0;
3750 gdb_c_test (args);
3752 return "OK";
3756 /* GDB_TRAP_1_HANDLER
3758 By the time this is called, the registers have been saved in "registers",
3759 and the interrupt priority has been set to permit serial UART interrupts.
3761 However, since no gdb request has yet been received, and there is no
3762 equivalent of getpacket for us to wait on, we can't sit here waiting
3763 for packets and processing them.
3765 In fact, the ONLY thing for us to do here is sit and wait.
3766 As gdb sends packet requests, they will handle themselves at the
3767 interrupt level. When gdb decides we can continue, it will reset
3768 the global variable "gdb_handling_trap1", and we will return
3769 (whereupon registers will be restored etc.) */
3771 void gdb_trap_1_handler( void )
3773 gdb_handling_trap1 = TRUE;
3774 sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */
3775 gdb_signo = 5;
3776 putpacket( "S05" );
3777 while ( gdb_handling_trap1 )
3779 return;
3782 void gdb_trace_handler( void )
3784 sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */
3785 gdb_handling_trap1 = TRUE;
3786 gdb_handling_sstrace = TRUE;
3787 gdb_signo = 5;
3788 putpacket( "S05" );
3789 while ( gdb_handling_trap1 )
3791 return;