1 /*
2  ******************************************************************************
3  ******************************************************************************
4  *
5  * COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved.
6  * $Id: gdb_c_test.c,v 1.3 2004/12/27 14:01:00 kettenis Exp $
7  * DESCRIPTION: This module has been provided for the purpose of testing GDB.
8  *
9  * NOTES:
10  *
11  ******************************************************************************
12  *****************************************************************************/
13 
14 /*=============================================================================
15  *                                  INCLUDE  FILES
16  *===========================================================================*/
17 
18 
19 #ifdef DO_IT_BY_THE_BOOK
20 
21 
22 #include "symtypes_defs.h"
23 #include "printp.h"
24 
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"
32 
33 #include "ether.h"
34 
35 #include <ctype.h>
36 
37 
38 #else
39 
40 #include "adbg_dtc.h"
41 
42 #define YES             1
43 #define NO              0
44 
45 #define TRUE            1
46 #define FALSE           0
47 
48 #define ENABLED         1
49 #define DISABLED        0
50 
51 #define CONTROL_C       3   /* ASCII 'ETX' */
52 
53 
54 /*
55  * Faked after ctype.h
56  */
57 
58 #define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
59                      ((X) >= 'A' && (X) <= 'F') || \
60                      ((X) >= 'a' && (X) <= 'f'))
61 /*
62  * Borrowed from string.h
63  */
64 
65 extern unsigned int strlen ( const char * );
66 
67 /*
68  * Extracted from symtypes.h:
69  */
70 
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 */
75 
76 /*
77  * for struct t_expr_tag and
78  * decl of build_and_add_expression
79  */
80 #include "adbg_expression.h"
81 #define NULL	0
82 
83 /*
84  * Extracted from printp.h:
85  */
86 
87 extern void printp ( const char * fptr, ... );
88 extern void sprintp ( const char * fptr, ... );
89 
90 /*
91  * Extracted from ether.h:
92  */
93 
94 extern long eth_to_gdb ( UCHAR *buf, long length );
95 
96 
97 /*
98  * Derived from hwequs.s:
99  */
100 
101 #define CS_CODE_START           0x100000
102 #define CS_CODE_SIZE            0x200000
103 #define LAST_CS_WORD            (CS_CODE_START + CS_CODE_SIZE - 2)
104 
105 #define sh_genstat1             (*((volatile ULONG *) 0xFFFFFE54))
106 
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.  */
119 
120 
121 #endif
122 
123 
124 /*============================================================================
125  *                                 MODULE  DEFINES
126  *===========================================================================*/
127 
128 #define P_RST_LAN_UART_REG      ((volatile UCHAR  *) 0xFFFFFE45)
129 #define M_RST_LAN_UART          0x80          /* Bit  7 */
130 
131 #define P_LAN0TR_REG            P_RST_LAN_UART_REG
132 #define M_LAN0TR                0x20          /* Bit  5 */
133 
134 #define M_SH_GENCON_LAN0TR      0x00200000    /* Bit 21 */
135 
136 #define MAX_RS232_CHARS         512
137 
138 #define LAN_Q_MOD(X)            ((X) % MAX_RS232_CHARS)
139 
140 /*---------------------------------------*
141  *           LAN  UART  Registers        *
142  *---------------------------------------*/
143 
144 #define LAN_UART_BASE               ((ULONG) 0xfffffc22)
145 
146 /*  Write-Read  */
147 
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   )))
150 
151 /*  Write-Only  */
152 
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     )))
159 
160 /*  Read-Only */
161 
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 )))
166 
167 /*
168  *   Bit Values for Write-Read and Write-Only Registers
169  */
170 
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)
177 
178 #define LAN_ACR_SELECT_BRG_0        DEFAULT_LAN_ACR
179 #define LAN_ACR_SELECT_BRG_1        (DEFAULT_LAN_ACR | 0x80)
180 
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.                     */
188 
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.                  */
193 
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). */
198 
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. */
202 
203 /*
204  *   Bit Masks for Read-Only Registers
205  */
206 
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 */
215 
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 */
219 
220 /*---------------------------------------*
221  *       Support for 'Utility 83'.       *
222  *---------------------------------------*/
223 
224 #define LAN_UTIL_CODE           0x83
225 
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'))
234 
235 #define LAN_PUTC                ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
236 #define LAN_WPM                 ((ULONG)               (('W' << 16) | ('P' << 8) | 'M'))
237 
238 #define STATUS(X)               ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
239 
240 #define XMT_VIA_BP_ENABLED()    ( *P_LAN0TR_REG & M_LAN0TR  ?  1 : 0 )
241 
242 #define TRAP_1_INST             0x4E41
243 
244 /*
245  *   Bit #13 of shared genstat 1 indicates
246  *   which processor we are as follows.
247  *
248  *           0 => X (side A)
249  *           1 => Y (side B)
250  */
251 
252 #define M_PROC_ID               0x00002000
253 
254 #define IS_SIDE_A()             ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
255 #define IS_SIDE_B()             ( (sh_genstat1) & M_PROC_ID )
256 
257 
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
263 
264 
265 
266 
267 #define VIA_RS232             0
268 #define VIA_ETHERNET          1
269 
270 #define MAX_IO_BUF_SIZE       400
271 
272 #define MAX_BYTE_CODES        200 /* maximum length for bytecode string */
273 
274 
275 static  ULONG           gdb_host_comm;
276 
277 static  ULONG           gdb_cat_ack;
278 
279 static  char            eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
280 
281 
282 #ifdef STANDALONE
283 
284 #define ACK_PKT()       LAN_PUT_CHAR( '+' )
285 #define NACK_PKT()      LAN_PUT_CHAR( '-' )
286 
287 #else
288 
289 #define ACK_PKT()       {                                             \
290                           if ( VIA_ETHERNET == gdb_host_comm )        \
291                           {                                           \
292                             gdb_cat_ack = YES;                        \
293                           }                                           \
294                           else                                        \
295                           {                                           \
296                             LAN_PUT_CHAR( '+' );                      \
297                           }                                           \
298                         }
299 
300 
301 
302 #define NACK_PKT()      {                                             \
303                           if ( VIA_ETHERNET == gdb_host_comm )        \
304                           {                                           \
305                             eth_outbuffer[ 0 ] = '-';                 \
306                             eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
307                           }                                           \
308                           else                                        \
309                           {                                           \
310                             LAN_PUT_CHAR( '-' );                      \
311                           }                                           \
312                         }
313 
314 #endif
315 
316 
317 
318 
319 /*============================================================================
320  *                                 MODULE  TYPEDEFS
321  *===========================================================================*/
322 
323 typedef struct rs232_queue {
324 
325   long    head_index;
326 
327   long    tail_index;
328 
329   ULONG   overflows;
330 
331   long    gdb_packet_start;
332   long    gdb_packet_end;
333   long    gdb_packet_csum1;
334   long    gdb_packet_csum2;
335 
336   UCHAR   buf[ MAX_RS232_CHARS ];
337 
338 } T_RS232_QUEUE;
339 
340 
341 
342 
343 /*=============================================================================
344  *                        EXTERNAL GLOBAL VARIABLES
345  *===========================================================================*/
346 
347 extern volatile UCHAR         sss_trace_flag;
348 
349 
350 /*=============================================================================
351  *                           STATIC  MODULE  DECLARATIONS
352  *===========================================================================*/
353 
354 static  T_RS232_QUEUE lan_input_queue,
355                       lan_output_queue;
356 
357 static  BOOL          test_echo;
358 
359 #if 0
360 /* The stub no longer seems to use this.  */
361 static  BOOL          write_access_enabled;
362 #endif
363 
364 static  int           baud_rate_idx;
365 
366 static  ULONG         tx_by_intr,
367                       tx_by_poll;
368 
369 static  UCHAR         lan_shadow_imr;
370 
371 
372 /*=============================================================================
373  *                        EXTERNAL FUNCTION PROTOTYPES
374  *===========================================================================*/
375 
376 extern  long  write_to_protected_mem( void *address, unsigned short value );
377 
378 
379 /*=============================================================================
380  *                      MODULE GLOBAL FUNCTIONS PROTOTYPES
381  *===========================================================================*/
382 
383 ULONG gdb_c_test( ULONG *parm );
384 
385 
386 void  lan_init( void );
387 
388 void  lan_isr( void );
389 
390 long  lan_get_char( void );
391 
392 long  lan_put_char( UCHAR c );
393 
394 ULONG lan_util( ULONG *parm );
395 
396 
397 /*=============================================================================
398  *                      MODULE LOCAL FUNCTION PROTOTYPES
399  *===========================================================================*/
400 
401 static  void  lan_reset( void );
402 
403 static  void  lan_configure( void );
404 
405 static  void  lan_init_queue( T_RS232_QUEUE *p_queue );
406 
407 static  void  lan_add_to_queue( long c, T_RS232_QUEUE *p_queue );
408 
409 static  UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue );
410 
411 static  void  lan_util_menu( void );
412 
413 static  long  get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
414 
415 
416 /*=============================================================================
417  *                      GDB STUB FUNCTION PROTOTYPES
418  *===========================================================================*/
419 
420 void  gdb_trap_1_handler( void );
421 void  gdb_trace_handler ( void );
422 
423 void  gdb_get_eth_input( unsigned char *buf, long length );
424 
425 static void getpacket ( void );
426 static void putpacket ( char * );
427 static void discard_packet ( void );
428 
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 */
433 
434 
435 /*=============================================================================
436  *                              MODULE BODY
437  *===========================================================================*/
438 
439 /* ------------------- Things that belong in a header file --------------- */
440 extern char *memset (char *, int, int);
441 
442                   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
443                   *                                     *
444                   *       Global Module Functions       *
445                   *                                     *
446                   *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
447 
448 
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
454 {
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;
462 
463 static union GDB_UNION_TEST
464 {
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;
472 
473 void gdb_recursion_test (int, int, int, int,  int,  int,  int);
474 
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 */
484 
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 */
493 }
494 
495 
496 ULONG   gdb_c_test( ULONG *parm )
497 
498 {
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;
506 
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;
515 
516    printp ("\n$Id: gdb_c_test.c,v 1.3 2004/12/27 14:01:00 kettenis Exp $\n");
517 
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 ] );
520 
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;
535 
536    gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
537 		       (long) parm[4], (long) parm[5], (long) parm[6]);
538 
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 );
547 }
548 
549 
550 /*-----------------------------------------------------------------------------
551  *
552  * FUNCTION NAME:   lan_init
553  *
554  *
555  * DESCRIPTION:
556  *
557  *
558  * RETURN VALUE:
559  *
560  *
561  * USED GLOBAL VARIABLES:
562  *
563  *
564  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
565  *
566  *
567  * NOTES:
568  *
569  *
570  *
571  *---------------------------------------------------------------------------*/
572 
573 void    lan_init( void )
574 
575 {
576 
577   if ( IS_SIDE_A( ) )
578   {
579 
580     lan_reset( );
581 
582     lan_init_queue( &lan_input_queue );
583 
584     lan_init_queue( &lan_output_queue );
585 
586     lan_configure( );
587   }
588 
589   return;
590 }
591 /* end of 'lan_init'
592  *===========================================================================*/
593 
594 
595 /*-----------------------------------------------------------------------------
596  *
597  * FUNCTION NAME:   lan_isr
598  *
599  *
600  * DESCRIPTION:
601  *
602  *
603  * RETURN VALUE:    None.
604  *
605  *
606  * USED GLOBAL VARIABLES:
607  *
608  *
609  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
610  *
611  *
612  * NOTES:
613  *
614  *
615  *---------------------------------------------------------------------------*/
616 
617 void      lan_isr( void )
618 
619 {
620   UCHAR   c;
621 
622 
623   lan_shadow_imr = 0;           /*  Disable all UART interrupts.  */
624   *P_LAN_IMR = lan_shadow_imr;
625 
626 
627   if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
628   {
629 
630     gdb_host_comm = VIA_RS232;
631 
632     c = *P_LAN_RCV;
633 
634     if ( test_echo )
635     {
636       /* ????? */
637     }
638 
639     if ( c == CONTROL_C )
640     {
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 */
644     }
645 
646     else
647     {
648       lan_add_to_queue( (long) c, &lan_input_queue );
649       get_gdb_input( (long) c, &lan_input_queue );
650     }
651 
652   }
653 
654   if ( XMT_VIA_BP_ENABLED( ) )
655   {
656 
657     c = 0;
658 
659     while ( (*P_LAN_ISR & M_UART_ISR_TxRDY)  &&  (c = lan_next_queue_char( &lan_output_queue )) )
660     {
661       *P_LAN_XMT = c;
662       ++tx_by_intr;
663     }
664 
665     if ( c )
666     {
667       lan_shadow_imr |= UART_IMR_TxRDY;   /*  (Re-)Enable 'TxRDY' interrupt from UART.  */
668     }
669 
670   }
671 
672 
673   lan_shadow_imr |= UART_IMR_RxRDY;       /*  Re-Enable 'RxRDY' interrupt from UART.  */
674   *P_LAN_IMR = lan_shadow_imr;
675 
676 
677 
678   return;
679 }
680 /* end of 'lan_isr'
681  *===========================================================================*/
682 
683 
684 /*-----------------------------------------------------------------------------
685  *
686  * FUNCTION NAME:   lan_get_char
687  *
688  *
689  * DESCRIPTION:     Fetches a character from the UART.
690  *
691  *
692  * RETURN VALUE:    0 on success, -1 on failure.
693  *
694  *
695  * USED GLOBAL VARIABLES:
696  *
697  *
698  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
699  *
700  *
701  * NOTES:
702  *
703  *
704  *---------------------------------------------------------------------------*/
705 
706 long    lan_get_char( void )
707 
708 {
709   long status = -2; /* AGD: nothing found in rcv buffer */
710 
711   if ( *P_LAN_SR & M_UART_SR_RxRDY )
712   {
713     char c = (char) *P_LAN_RCV;
714 
715     if ( test_echo )
716     {
717       LAN_PUT_CHAR ( c );
718     }
719 
720     if ( c == CONTROL_C )
721     {
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 */
726     }
727 
728     else
729     {
730       lan_add_to_queue( (long) c, &lan_input_queue );
731       status = get_gdb_input( (long) c, &lan_input_queue );
732     }
733 
734   }
735 
736   return( status );
737 }
738 /* end of 'lan_get_char'
739  *===========================================================================*/
740 
741 
742 /*-----------------------------------------------------------------------------
743  *
744  * FUNCTION NAME:   lan_put_char
745  *
746  * DESCRIPTION:     Puts a character out via the UART.
747  *
748  * RETURN VALUE:    0 on success, -1 on failure.
749  *
750  * USED GLOBAL VARIABLES: none.
751  *
752  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
753  *
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  *        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
760  *
761  *---------------------------------------------------------------------------*/
762 
763 long    lan_put_char( UCHAR c )
764 
765 {
766   long    status = -1;
767 
768   if ( XMT_VIA_BP_ENABLED( ) )
769   {
770 
771     if ( *P_LAN_SR & M_UART_SR_TxRDY )
772     {
773       lan_add_to_queue( (long) c, &lan_output_queue );
774 
775       c = lan_next_queue_char( &lan_output_queue );
776 
777       *P_LAN_XMT = c;
778       ++tx_by_poll;
779       status = 0;
780     }
781 #if 0
782     else
783     {
784       status = 0;
785       lan_shadow_imr |= UART_IMR_TxRDY;   /*  Enable 'TxRDY' interrupt from UART. */
786       *P_LAN_IMR = lan_shadow_imr;
787     }
788 #endif
789   }
790 
791   else
792   {
793     status = 0;   /* You lose: input character goes to the bit bucket. */
794   }
795 
796   return( status );
797 }
798 /* end of 'lan_put_char'
799  *===========================================================================*/
800 
801 
802 /*-----------------------------------------------------------------------------
803  *
804  * FUNCTION NAME:   lan_util
805  *
806  * DESCRIPTION:
807  *
808  * RETURN VALUE:
809  *
810  * USED GLOBAL VARIABLES:
811  *
812  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
813  *
814  * NOTES:
815  *
816  *---------------------------------------------------------------------------*/
817 
818 ULONG   lan_util( ULONG *parm )
819 
820 {
821 
822 
823   static const struct {
824 
825     ULONG rate_code;
826     UCHAR acr_setting;
827     UCHAR csr_setting;
828 
829   } baud_rate_setting [] = {
830 
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  }
835   };
836 
837 
838 #define BOGUS_P1        0xE1
839 #define BOGUS_P2        0xE2
840 
841   ULONG   not_done_code;
842 
843 
844   ULONG   opcode;
845   ULONG   parm_1;
846   ULONG   parm_2;
847 
848   int     i;
849   UCHAR   c;
850 
851 
852   not_done_code = 0;
853 
854   opcode = parm[ 1 ];
855   parm_1 = parm[ 2 ];
856   parm_2 = parm[ 3 ];
857 
858 
859   switch ( opcode )
860   {
861 
862     case LAN_INIT:
863       {
864 
865         lan_init( );
866         printp( "\n\n  Interface (Re)Initialized ...\n\n" );
867 
868         break;
869       }
870 
871 
872     case LAN_BAUD:
873       {
874 
875         for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
876         {
877           if ( baud_rate_setting[i].rate_code == parm_1 )
878           {
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 );
884           }
885         }
886 
887         printp( "\n\n  *** SYNTAX Error  -  Invalid baudrate (P2)\n\n" );
888         not_done_code = BOGUS_P2;
889 
890         break;
891       }
892 
893 
894     case LAN_INTR:
895       {
896 
897         switch ( parm_1 )
898         {
899 
900           case 0x0D: /* Disable 'RxRDY' Interrupts */
901             {
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;
906             }
907 
908           case 0x0E: /* Enable 'RxRDY' Interrupts */
909             {
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;
914             }
915 
916           default:
917             {
918               printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
919               not_done_code = BOGUS_P2;
920             }
921         }
922 
923         break;
924       }
925 
926 
927     case LAN_XMT:
928       {
929 
930         switch ( parm_1 )
931         {
932 
933           case 0x0E: /* Enable Transmission-via-Backplane */
934             {
935               if ( !(*P_LAN0TR_REG & M_LAN0TR) )
936               {
937                 *P_LAN0TR_REG |= M_LAN0TR;  /* 0 -> 1 */
938               }
939 
940               printp( "\n\n  Transmit-via-Backplane ENABLED ...\n\n" );
941               break;
942             }
943 
944           case 0x0D: /* Disable Transmission-via-Backplane */
945             {
946               if ( *P_LAN0TR_REG & M_LAN0TR )
947               {
948                 *P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */
949               }
950 
951               printp( "\n\n  Transmit-via-Backplane DISABLED ...\n\n" );
952               break;
953             }
954 
955           default:
956             {
957               printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
958               not_done_code = BOGUS_P2;
959               lan_util_menu( );
960             }
961         }
962 
963         break;
964       }
965 
966 
967     case LAN_STAT:
968       {
969 
970       printp( "\n              -- Status --\n\n" );
971 
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 ) );
977 
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 );
981 
982         printp( "    Input Overflows: %d\n\n", lan_input_queue.overflows );
983 
984         printp( "         Tx by Intr: %d\n", tx_by_intr  );
985         printp( "         Tx by Poll: %d\n\n", tx_by_poll );
986 
987         printp( "         *  Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE );
988 
989         break;
990       }
991 
992 
993     case LAN_IN:
994       {
995 
996         switch ( parm_1 )
997         {
998 
999           case 0x0C: /* Clear and Reset Queue */
1000             {
1001               lan_init_queue( &lan_input_queue );
1002               printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
1003               break;
1004             }
1005 
1006           case 0x0D: /* Display Queue */
1007             {
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 );
1011 
1012               for ( i = 0; i < MAX_RS232_CHARS; ++i )
1013               {
1014                 printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
1015 
1016                 if ( 15 == (i % 16) )
1017                 {
1018                   int j;
1019 
1020                   printp ( "    " );
1021                   for ( j = i - 15; j <= i; j++ )
1022                     {
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 ( "." );
1028                     }
1029                   printp( "\n    " );
1030                 }
1031 
1032                 else if ( 7 == (i % 8) )
1033                 {
1034                   printp( " " );
1035                 }
1036 
1037               }
1038 
1039               printp( "\n" );
1040 
1041               break;
1042             }
1043 
1044           case 0x0F: /* Fetch next character in Queue */
1045             {
1046               c = lan_next_queue_char( &lan_input_queue );
1047 
1048               if ( c )
1049               {
1050                 printp( "\n\n  Next Character: " );
1051                 if (  0x21 <= c  &&  c <= 0x7F )
1052                 {
1053                   printp( "%c\n\n", (ULONG) c );
1054                 }
1055 
1056                 else if ( 0x20 == ((UCHAR) c) )
1057                 {
1058                   printp( "<space>\n\n" );
1059                 }
1060 
1061                 else
1062                 {
1063                   printp( "%02X\n\n", (ULONG) c );
1064                 }
1065               }
1066 
1067               else
1068               {
1069                 printp( "\n\n  Input Queue EMPTY ...\n\n" );
1070               }
1071 
1072             break;
1073             }
1074 
1075           default:
1076             {
1077             printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
1078             not_done_code = BOGUS_P2;
1079             break;
1080             }
1081         }
1082 
1083       break;
1084       }
1085 
1086 
1087     case LAN_OUT:
1088       {
1089 
1090         switch ( parm_1 )
1091         {
1092 
1093           case 0x0C: /* Clear and Reset Queue */
1094             {
1095               lan_init_queue( &lan_output_queue );
1096               printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
1097               break;
1098             }
1099 
1100           case 0x0D: /* Display Queue */
1101             {
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 );
1105 
1106               for ( i = 0; i < MAX_RS232_CHARS; ++i )
1107               {
1108                 printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
1109 
1110                 if ( 15 == (i % 16) )
1111                 {
1112                   int j;
1113 
1114                   printp ( "    " );
1115                   for ( j = i - 15; j <= i; j++ )
1116                     {
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 ( "." );
1122                     }
1123                   printp( "\n    " );
1124                 }
1125 
1126                 else if ( 7 == (i % 8) )
1127                 {
1128                   printp( " " );
1129                 }
1130 
1131               }
1132 
1133               printp( "\n" );
1134 
1135               break;
1136             }
1137 
1138           case 0x0F: /* Fetch next character in Queue */
1139             {
1140               c = lan_next_queue_char( &lan_output_queue );
1141 
1142               if ( c )
1143               {
1144                 printp( "\n\n  Next Character: " );
1145                 if (  0x21 <= c  &&  c <= 0x7F )
1146                 {
1147                   printp( "%c\n\n", (ULONG) c );
1148                 }
1149 
1150                 else if ( 0x20 == c )
1151                 {
1152                   printp( "<space>\n\n" );
1153                 }
1154 
1155                 else
1156                 {
1157                   printp( "%02X\n\n", (ULONG) c );
1158                 }
1159               }
1160 
1161               else
1162               {
1163                 printp( "\n\n  Input Queue EMPTY ...\n\n" );
1164               }
1165 
1166               break;
1167             }
1168 
1169           default:
1170             {
1171             printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
1172             not_done_code = BOGUS_P2;
1173             break;
1174             }
1175         }
1176 
1177         break;
1178       }
1179 
1180 
1181     case LAN_ECHO:
1182       {
1183 
1184         switch ( parm_1 )
1185         {
1186 
1187           case 0x0E:
1188             {
1189               test_echo = ENABLED;
1190               printp( "\n\n  Test echo ENABLED ...\n\n" );
1191               break;
1192             }
1193 
1194           case 0x0D:
1195             {
1196               test_echo = DISABLED;
1197               printp( "\n\n  Test echo DISABLED ...\n\n" );
1198               break;
1199             }
1200 
1201           default:
1202             {
1203               printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
1204               not_done_code = BOGUS_P2;
1205               break;
1206             }
1207         }
1208 
1209         break;
1210       }
1211 
1212 
1213     case LAN_PUTC:
1214       {
1215 
1216         if ( 0x20 < parm_1  &&  parm_1 < 0x7F )
1217         {
1218           if ( lan_put_char( (UCHAR) parm_1 ) )
1219           {
1220             printp( "\n\n  *** 'lan_put_char' Error ...\n" );
1221           }
1222 
1223           else
1224           {
1225             printp( "\n\n  O.K. ...\n" );
1226           }
1227 
1228         }
1229 
1230         else
1231         {
1232           printp( "\n\n  *** Error  -  character must be in the 0x21-0x7E range ...\n" );
1233           not_done_code = BOGUS_P2;
1234         }
1235 
1236         break;
1237       }
1238 
1239 /***
1240     case LAN_WPM:
1241       {
1242 
1243         if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) )
1244         {
1245           printp( "\n  Write to protected memory FAILED ...\n" );
1246         }
1247 
1248         break;
1249       }
1250 ***/
1251 
1252     case 0: /* no argument -- print menu */
1253       {
1254         lan_util_menu( );
1255         break;
1256       }
1257 
1258 
1259     default:
1260       {
1261         parm_2 = 0;  /* to supress compiler warning with 'LAN_WPM' case disabled */
1262 
1263         printp( "\n\n  *** SYNTAX Error  -  Invalid P1 ...\n\n" );
1264         not_done_code = BOGUS_P1;
1265         break;
1266       }
1267 
1268 
1269   } /*  End of 'switch ( opcode )'. */
1270 
1271 
1272 return( not_done_code );
1273 }
1274 /* end of 'lan_util'
1275  *===========================================================================*/
1276 
1277 
1278                   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
1279                   *                                     *
1280                   *         Local Module Functions      *
1281                   *                                     *
1282                   *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1283 
1284 /*-----------------------------------------------------------------------------
1285  *
1286  * FUNCTION NAME:   lan_reset
1287  *
1288  * DESCRIPTION:     Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the
1289  *                  Shared Control 1 area.
1290  *
1291  *                             1 _|       ______
1292  *                                |      |      |
1293  *                          Bit   |      |      |
1294  *                                |      |      |
1295  *                             0 _|______|      |______
1296  *                                |---------------------> t
1297  *
1298  * RETURN VALUE:    None.
1299  *
1300  * USED GLOBAL VARIABLES:
1301  *
1302  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1303  *
1304  * NOTES:           H/W configuration requires that a byte in the shared
1305  *                  control 1 area must be read before being written.
1306  *
1307  *---------------------------------------------------------------------------*/
1308 
1309 static  void    lan_reset( void )
1310 
1311 {
1312 
1313   while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
1314   {
1315     *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
1316   }
1317 
1318   while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) )
1319   {
1320     *P_RST_LAN_UART_REG |= M_RST_LAN_UART;      /* 1 */
1321   }
1322 
1323   while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
1324   {
1325     *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
1326   }
1327 
1328 }
1329 /* end of 'lan_reset'
1330  *===========================================================================*/
1331 
1332 
1333 /*-----------------------------------------------------------------------------
1334  *
1335  * FUNCTION NAME:   lan_configure
1336  *
1337  *
1338  * DESCRIPTION:
1339  *
1340  *
1341  * RETURN VALUE:
1342  *
1343  *
1344  * USED GLOBAL VARIABLES:
1345  *
1346  *
1347  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1348  *
1349  *
1350  * NOTES:
1351  *
1352  *
1353  *
1354  *---------------------------------------------------------------------------*/
1355 
1356 static  void    lan_configure( void )
1357 
1358 {
1359 
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;
1365 
1366   *P_LAN_MR1 = DEFAULT_LAN_MR1;
1367   *P_LAN_MR2 = DEFAULT_LAN_MR2;
1368 
1369   *P_LAN_ACR = DEFAULT_LAN_ACR;
1370 
1371   *P_LAN_CSR = UART_CSR_BR_9600;
1372   baud_rate_idx = 2;
1373 
1374   *P_LAN_CTUR = DEFAULT_LAN_CTUR;
1375   *P_LAN_CTLR = DEFAULT_LAN_CTLR;
1376 
1377   *P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
1378 
1379   lan_shadow_imr = UART_IMR_RxRDY;        /*  Enable only 'RxRDY' interrupt from UART. */
1380   *P_LAN_IMR = lan_shadow_imr;
1381 
1382   tx_by_intr = 0;
1383   tx_by_poll = 0;
1384 
1385   return;
1386 }
1387 /* end of 'lan_configure'
1388  *===========================================================================*/
1389 
1390 
1391 /*-----------------------------------------------------------------------------
1392  *
1393  * FUNCTION NAME:   lan_init_queue
1394  *
1395  * DESCRIPTION:
1396  *
1397  * RETURN VALUE:    None.
1398  *
1399  * USED GLOBAL VARIABLES:
1400  *
1401  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1402  *
1403  * NOTES:
1404  *
1405  *---------------------------------------------------------------------------*/
1406 
1407 static  void    lan_init_queue( T_RS232_QUEUE *p_queue )
1408 
1409 {
1410   long i;
1411 
1412     /*
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.
1416     */
1417 
1418   p_queue->head_index = 0;
1419   p_queue->tail_index = 0;
1420 
1421   p_queue->overflows = 0;
1422 
1423   p_queue->gdb_packet_start = -1;
1424   p_queue->gdb_packet_end   = -1;
1425 
1426   p_queue->gdb_packet_csum1 = -1;
1427   p_queue->gdb_packet_csum2 = -1;
1428 
1429   for ( i = 0; i < MAX_RS232_CHARS; ++i )
1430   {
1431     p_queue->buf[ i ] = 0;
1432   }
1433 
1434   return;
1435 }
1436 /* end of 'lan_init_queue'
1437  *===========================================================================*/
1438 
1439 
1440 /*-----------------------------------------------------------------------------
1441  *
1442  * FUNCTION NAME:   lan_add_to_queue
1443  *
1444  *
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.
1450  *
1451  *
1452  * RETURN VALUE:    None.
1453  *
1454  *
1455  * USED GLOBAL VARIABLES:
1456  *
1457  *
1458  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1459  *
1460  *
1461  * NOTES:
1462  *
1463  *
1464  *---------------------------------------------------------------------------*/
1465 
1466 static  void    lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
1467 
1468 {
1469 
1470   if ( p_queue )    /*  Sanity check. */
1471   {
1472 
1473     if ( c & 0x000000FF )   /*  We don't allow NULL characters to be added to a queue.  */
1474     {
1475         /*  Insert the new character at the tail of the queue.  */
1476 
1477       p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
1478 
1479         /*  Increment the tail index. */
1480 
1481       if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
1482       {
1483         p_queue->tail_index = 0;
1484       }
1485 
1486         /*  Check for wrapping (i.e. overflow). */
1487 
1488       if ( p_queue->head_index == p_queue->tail_index )
1489       {
1490           /*  If the tail has caught up to the head record the overflow . . . */
1491 
1492         ++(p_queue->overflows);
1493 
1494           /*  . . . then increment the head index.  */
1495 
1496         if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
1497         {
1498           p_queue->head_index = 0;
1499         }
1500 
1501       }
1502 
1503     } /*  End of 'if ( c & 0x000000FF )'. */
1504 
1505   } /*  End of 'if ( p_queue )'.  */
1506 
1507 
1508   return;
1509 }
1510 /* end of 'lan_add_to_queue'
1511  *===========================================================================*/
1512 
1513 
1514 /*-----------------------------------------------------------------------------
1515  *
1516  * FUNCTION NAME:   lan_next_queue_char
1517  *
1518  * DESCRIPTION:
1519  *
1520  * RETURN VALUE:
1521  *
1522  * USED GLOBAL VARIABLES:
1523  *
1524  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1525  *
1526  * NOTES:
1527  *
1528  *---------------------------------------------------------------------------*/
1529 
1530 static  UCHAR   lan_next_queue_char( T_RS232_QUEUE *p_queue )
1531 
1532 {
1533   UCHAR   c;
1534 
1535 
1536   c = 0;
1537 
1538   if ( p_queue )
1539   {
1540 
1541     if ( p_queue->head_index != p_queue->tail_index )
1542     {
1543         /*  Return the 'oldest' character in the queue. */
1544 
1545       c = p_queue->buf[ p_queue->head_index ];
1546 
1547         /*  Increment the head index. */
1548 
1549       if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
1550       {
1551         p_queue->head_index = 0;
1552       }
1553 
1554     }
1555 
1556   } /*  End of 'if ( p_queue )'.  */
1557 
1558 
1559   return( c );
1560 }
1561 
1562 /* end of 'lan_next_queue_char'
1563  *===========================================================================*/
1564 
1565 
1566 /*-----------------------------------------------------------------------------
1567  *
1568  * FUNCTION NAME:   lan_util_menu
1569  *
1570  * DESCRIPTION:     Prints out a brief help on the LAN UART control utility.
1571  *
1572  * RETURN VALUE:    None.
1573  *
1574  * USED GLOBAL VARIABLES: None.
1575  *
1576  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None.
1577  *
1578  * NOTES: None.
1579  *
1580  *---------------------------------------------------------------------------*/
1581 
1582 static  void    lan_util_menu( void )
1583 
1584 {
1585 
1586   /*
1587    * Multiply calling printp() below is made due to the limitations
1588    * of printp(), incapable of handling long formatting constants:
1589    */
1590 
1591  printp( "\n               -- Options --\n\n" );
1592 
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 );
1601 
1602   printp( "    %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );
1603 
1604 /***
1605   printp( "    %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );
1606 ***/
1607 
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" );
1612 }
1613 /* end of 'lan_util_menu'
1614  *===========================================================================*/
1615 
1616 
1617 /* Thu Feb  5 17:14:41 EST 1998  CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */
1618 
1619 
1620 static  long    get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
1621 
1622 {
1623 
1624   /* Now to detect when we've got a gdb packet... */
1625 
1626   if ( '$' == c ) { /* char marks beginning of a packet */
1627 
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 */
1632 
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!  */
1638 
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;
1648       }
1649     } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */
1650 
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 */
1655 
1656           /* Garbled packet.  Discard, but do not NAK.  */
1657 
1658           /*NACK_PKT( );*/    /*<ETHERNET>*/
1659           discard_packet( );
1660           return -1;
1661       }
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;
1664 
1665   } else if ( -1 != p_input_q->gdb_packet_start &&
1666               -1 != p_input_q->gdb_packet_end) {
1667 
1668     if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */
1669 
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 ) {
1673 
1674         /* first checksum digit */
1675 
1676         p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
1677         p_input_q->gdb_packet_csum2 = -1;
1678 
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 ) {
1682 
1683         /* second checksum digit: packet is complete! */
1684 
1685         p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
1686         getpacket();    /* got a packet -- extract it */
1687 
1688       } else { /* probably can't happen (um... three hex digits?) */
1689 
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;
1696       }
1697 
1698     } else { /* '#' followed by non-hex char */
1699 
1700       /* PROTOCOL ERROR */
1701       /* Bad packet -- discard but do not NAK */
1702       /*NACK_PKT( );*/    /*<ETHERNET>*/
1703       discard_packet( );
1704       return -1;
1705     }
1706   }
1707 
1708   return 0;
1709 }
1710 
1711 
1712 
1713 
1714 #ifdef    STANDALONE
1715 
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 */
1721 
1722 long write_to_protected_mem (addr, word)
1723      void *addr;
1724      unsigned short word;
1725 {
1726   return 0;
1727 }
1728 
1729 
1730 char dummy_memory[0x4000];
1731 
1732 int main ( void )
1733 {
1734   long c;
1735 
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 )
1740     {
1741       if ( c == '\\' )  /* escape char */
1742         break;
1743 
1744       lan_add_to_queue( c, &lan_input_queue );
1745       get_gdb_input (c, &lan_input_queue);
1746       fflush( stdout );
1747     }
1748 
1749   printf( "Goodbye!\n" );
1750   exit( 0 );
1751 }
1752 
1753 #define SRAM_START      ((void *) (&dummy_memory[0] + 0x00000000))
1754 #define SRAM_END        ((void *) (&dummy_memory[0] + 0x00000400))
1755 
1756 #define RO_AREA_START   ((void *) (&dummy_memory[0] + 0x00000100))
1757 #define RO_AREA_END     ((void *) (&dummy_memory[0] + 0x00000300))
1758 
1759 #define NVD_START       ((void *) (&dummy_memory[0] + 0x00003000))
1760 #define NVD_END         ((void *) (&dummy_memory[0] + 0x00003100))
1761 
1762 #else   /* normal stub (not stand-alone) */
1763 
1764 #define SRAM_START              ((void *) 0x00000000)
1765 #define SRAM_END                ((void *) 0x00400000)
1766 
1767 #define RO_AREA_START           ((void *) 0x00100000)
1768 #define RO_AREA_END             ((void *) 0x00300000)
1769 
1770 #define NVD_START               ((void *) 0x03000000)
1771 #define NVD_END                 ((void *) 0x03100000)
1772 
1773 #endif /* STANDALONE */
1774 
1775 
1776 
1777 
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 */
1785 
1786 
1787 /* ------------------- global defines and data decl's -------------------- */
1788 
1789 #define hexchars        "0123456789abcdef"
1790 
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
1796 
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
1805               };
1806 
1807 unsigned long registers[NUMREGBYTES/4];
1808 
1809 static long remote_debug;
1810 
1811 #define BUFMAX                MAX_IO_BUF_SIZE
1812 static char inbuffer[BUFMAX], outbuffer[BUFMAX];
1813 static char spare_buffer[BUFMAX];
1814 
1815 
1816 struct stub_trace_frame
1817 {
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;
1827 
1828 /* -------------------      function prototypes       -------------------- */
1829 
1830 void handle_request ( char * );
1831 
1832 /* -------------------         Implementation         -------------------- */
1833 
1834 static void
1835 discard_packet( void )
1836 {
1837   lan_input_queue.head_index = lan_input_queue.tail_index;
1838 
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;
1843 }
1844 
1845 /* Utility function: convert an ASCII isxdigit to a hex nybble */
1846 
1847 static long
1848 hex( char ch )
1849 {
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;
1857 }
1858 
1859 static void
1860 getpacket( void )
1861 {
1862   unsigned char our_checksum, their_checksum;
1863   char *copy = inbuffer;
1864   unsigned char c;
1865 
1866   our_checksum = 0;
1867 
1868   /* first find the '$' */
1869   while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
1870     if (c == 0)                 /* ??? Protocol error? (paranoia) */
1871       {
1872           /* PROTOCOL ERROR (missing '$') */
1873         /*NACK_PKT( );*/    /*<ETHERNET>*/
1874         return;
1875       }
1876 
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 ))
1881     {
1882       *copy++ = c;
1883       our_checksum += c;
1884     }
1885   *copy++ = '\0';               /* terminate the copy */
1886 
1887   if (c == 0)                   /* ??? Protocol error? (paranoia) */
1888     {
1889         /* PROTOCOL ERROR (missing '#') */
1890       /*NACK_PKT( );*/    /*<ETHERNET>*/
1891       return;
1892     }
1893   their_checksum  = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
1894   their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
1895 
1896   /* Now reset the queue packet-recognition bits */
1897   discard_packet( );
1898 
1899   if ( remote_debug ||
1900       our_checksum == their_checksum )
1901     {
1902       ACK_PKT( );      /* good packet */
1903       /* Parse and process the packet */
1904       handle_request( inbuffer );
1905     }
1906   else
1907       /* PROTOCOL ERROR (bad check sum) */
1908     NACK_PKT( );
1909 }
1910 
1911 /* EMC will provide a better implementation
1912    (perhaps just of LAN_PUT_CHAR) that does not block.
1913    For now, this works.  */
1914 
1915 
1916 static void
1917 putpacket( char *str )
1918 {
1919   unsigned char checksum;
1920 
1921   /* '$'<packet>'#'<checksum> */
1922 
1923   if ( VIA_ETHERNET == gdb_host_comm )
1924   {
1925     char  *p_out;
1926     long  length;
1927 
1928     p_out  = eth_outbuffer;
1929     length = 0;
1930 
1931 
1932     if ( YES == gdb_cat_ack )
1933     {
1934       *p_out++ = '+';
1935       ++length;
1936     }
1937 
1938     gdb_cat_ack = NO;
1939 
1940 
1941     *p_out++ = '$';
1942     ++length;
1943 
1944     checksum = 0;
1945 
1946     while ( *str )
1947     {
1948       *p_out++ = *str;
1949       ++length;
1950       checksum += *str++;
1951     }
1952 
1953     *p_out++ = '#';
1954     *p_out++ = hexchars[checksum >> 4];
1955     *p_out = hexchars[checksum % 16];
1956     length += 3;
1957 
1958     eth_to_gdb( (UCHAR *) eth_outbuffer, length );
1959   }
1960 
1961   else
1962   {
1963 
1964       /* via RS-232 */
1965     do {
1966       LAN_PUT_CHAR( '$' );
1967       checksum = 0;
1968 
1969       while ( *str )
1970         {
1971           LAN_PUT_CHAR( *str );
1972           checksum += *str++;
1973         }
1974 
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. */
1980 
1981   }
1982 
1983 }
1984 
1985 
1986 /*-----------------------------------------------------------------------------
1987  *
1988  * FUNCTION NAME:   gdb_get_eth_input
1989  *
1990  *
1991  * DESCRIPTION:
1992  *
1993  *
1994  * RETURN VALUE:    None.
1995  *
1996  *
1997  * USED GLOBAL VARIABLES:
1998  *
1999  *
2000  * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
2001  *
2002  *
2003  * NOTES:
2004  *
2005  *
2006  *---------------------------------------------------------------------------*/
2007 
2008 void    gdb_get_eth_input( unsigned char *buf, long length )
2009 
2010 {
2011 
2012   gdb_host_comm = VIA_ETHERNET;
2013 
2014   for ( ; 0 < length; ++buf, --length)
2015   {
2016 
2017     if ( *buf == CONTROL_C )
2018     {
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 */
2022     }
2023 
2024     else
2025     {
2026       lan_add_to_queue( (long) *buf, &lan_input_queue );
2027       get_gdb_input( (long) *buf, &lan_input_queue );
2028     }
2029 
2030   }
2031 
2032 
2033   return;
2034 }
2035 /* end of 'gdb_get_eth_input'
2036  *===========================================================================*/
2037 
2038 
2039 
2040 
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.
2043 
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.
2053 
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)
2058  */
2059 
2060 #if 0 /* avoid compiler warning while this is not used */
2061 
2062 /* Function: gdb_putchar(int)
2063    Make gdb write a char to stdout.
2064    Returns: the char */
2065 
2066 static int
2067 gdb_putchar( long ch )
2068 {
2069   char buf[4];
2070 
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;
2077 }
2078 #endif
2079 
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 */
2083 
2084 static int
2085 gdb_write( char *data, long len )
2086 {
2087   char *buf, *cpy;
2088   long i;
2089 
2090   buf = outbuffer;
2091   buf[0] = 'O';
2092   i = 0;
2093   while ( i < len )
2094     {
2095       for ( cpy = buf+1;
2096            i < len && cpy < buf + BUFMAX - 3;
2097            i++ )
2098         {
2099           *cpy++ = hexchars[data[i] >> 4];
2100           *cpy++ = hexchars[data[i] & 0x0F];
2101         }
2102       *cpy = 0;
2103       putpacket( buf );
2104     }
2105   return len;
2106 }
2107 
2108 /* Function: gdb_puts(char *)
2109    Make gdb write a null-terminated string to stdout.
2110    Returns: the length of the string */
2111 
2112 static int
2113 gdb_puts( char *str )
2114 {
2115   return gdb_write( str, strlen( str ) );
2116 }
2117 
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.  */
2122 
2123 #if 0
2124 static void
2125 gdb_error( char *format, char *parm )
2126 {
2127   static char buf[400];
2128   char *cpy;
2129   long len;
2130 
2131   if ( remote_debug )
2132     {
2133       if ( format && *format )
2134         len = strlen( format );
2135       else
2136         return;             /* empty input */
2137 
2138       if ( parm && *parm )
2139         len += strlen( parm );
2140 
2141       for ( cpy = buf; *format; )
2142         {
2143           if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */
2144             {
2145               format += 2;          /* advance two chars instead of just one */
2146               while ( parm && *parm )
2147                 *cpy++ = *parm++;
2148             }
2149           else
2150             *cpy++ = *format++;
2151         }
2152       *cpy = '\0';
2153       gdb_puts( buf );
2154     }
2155 }
2156 #endif
2157 
2158 static void gdb_note (char *, int);
2159 static int  error_ret (int, char *, int);
2160 
2161 static unsigned long
2162 elinum_to_index (unsigned long elinum)
2163 {
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;
2170 }
2171 
2172 static long
2173 index_to_elinum (unsigned long index)
2174 {
2175   if (index <= 7)
2176     return index + 0xd0;
2177   else if (index <= 15)
2178     return (index - 8) + 0xa0;
2179   else
2180     return -1;
2181 }
2182 
2183 
2184 /*
2185   READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
2186 
2187   The following code pertains to reading memory from the target.
2188   Some sort of exception handling should be added to make it safe.
2189 
2190   READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
2191 
2192   Safe Memory Access:
2193 
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).
2197 
2198   */
2199 
2200 enum { SUCCESS = 0, FAIL = -1 };
2201 
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 *);
2210 
2211 static int
2212 dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
2213 {
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));
2219 
2220   gdb_puts (spare_buffer);
2221   return ret;
2222 }
2223 
2224 
2225 #if 0
2226 /* I think this function is unnecessary since the introduction of
2227    adbg_find_memory_addr_in_frame.  */
2228 
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)
2233 {
2234   CFD *format;
2235   T_EXPR *expr;
2236   int num_exprs;
2237 
2238   /* Get the format from the frame.  */
2239   get_frame_format_pointer (frame, &format);
2240 
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++;
2246 
2247   return num_exprs;
2248 }
2249 #endif
2250 
2251 #if 0
2252 /* Function: get_frame_addr
2253  *
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.  */
2258 
2259 unsigned char *
2260 get_frame_addr ( const unsigned char *addr )
2261 {
2262   unsigned char *base, *regs, *stack, *mem;
2263   CFD *dummy;
2264   DTC_RESPONSE ret;
2265 
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)
2270     {
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);
2283     }
2284 
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.  */
2288   {
2289     int num_exprs = count_frame_exprs (curframe.frame_data);
2290     int expr, block;
2291 
2292     /* Try each expression in turn.  */
2293     for (expr = 0; expr < num_exprs; expr++)
2294       {
2295 	for (block = 0; ; block++)
2296 	  {
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))
2305 	      {
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')
2309 		  {
2310 		    gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
2311 		    return (unsigned char *) -1;
2312 		  }
2313 		else
2314 		  {
2315 		    if (remote_debug > 1)
2316 		      {
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);
2321 		      }
2322 
2323 		    return (((unsigned char *) &data->data)
2324 			    + (addr - (unsigned char *) data->address));
2325 		  }
2326 	      }
2327 	  }
2328       }
2329   }
2330 
2331   /* not found, return error */
2332   return (unsigned char *) -1;
2333 }
2334 
2335 /*============================================================*/
2336 
2337 static long get_uchar ( const unsigned char * addr )
2338 {
2339   unsigned char *frame_addr;
2340 
2341   if ( read_access_violation ( addr ) )
2342     return ( -1 ); /* Access error */
2343 
2344   if (curframe.valid)   /* if debugging a trace frame? */
2345     {
2346       /* If the requested address was collected in the current frame,
2347        * then fetch and return the data from the trace buffer.
2348        */
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.)
2354        */
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) */
2360     }
2361   else
2362     /* Not debugging a trace frame, read the data from live memory. */
2363     return ( *addr ); /* Meaningful result >= 0 */
2364 }
2365 #endif
2366 
2367 /*============================================================*/
2368 
2369 static long set_uchar ( unsigned char * addr, unsigned char val )
2370 {
2371   long check_result = write_access_violation ( addr );
2372 
2373   if ( check_result != 0L )
2374     return ( check_result ); /* Access error */
2375 
2376   return ( *addr = val );    /* Successful writing */
2377 }
2378 
2379 /*============================================================*/
2380 
2381 /*
2382  * Function read_access_violation() below returns TRUE if dereferencing
2383  * its argument for reading would cause a bus error - and FALSE otherwise:
2384  */
2385 
2386 static long read_access_violation ( const void * addr )
2387 {
2388   return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
2389            ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) );
2390 }
2391 
2392 /*============================================================*/
2393 
2394 /*
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:
2400  */
2401 
2402 static long write_access_violation ( const void * addr )
2403 {
2404   /*
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:
2408    */
2409 
2410   if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
2411     return ( -1 ); /* soft error */
2412 
2413   if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
2414        ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) )
2415     return ( -2 ); /* hard error */
2416 
2417   return ( 0 );
2418 }
2419 
2420 
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)
2427 {
2428   if ((addr >= SRAM_START) && (addr < SRAM_END))
2429     {
2430       if ((char *)addr + count < (char *)SRAM_END)
2431 	return (count);
2432       else
2433 	return ((char *)SRAM_END - (char *)addr);
2434     }
2435   else if (((char *)addr >= (char *)NVD_START) &&
2436 	   ((char *)addr < (char *)NVD_END))
2437     {
2438       if ((char *)addr + count < (char *)NVD_END)
2439 	return (count);
2440       else
2441 	return ((char *)NVD_END - (char *)addr);
2442     }
2443   else
2444     return (0);
2445 }
2446 
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.  */
2451 
2452 static long
2453 mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
2454 {
2455   long ndx;
2456   long ndx2;
2457   long ch;
2458   long incr;
2459   unsigned char *location;
2460   DTC_RESPONSE status;
2461 
2462   if (may_fault)
2463     {
2464       for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
2465 	{
2466 	  status = find_memory(mem, count - ndx, &location, &incr);
2467 
2468 	  if (status == OK_TARGET_RESPONSE)
2469 	    {
2470 	      if (incr > 0)
2471 		{
2472 		  for (ndx2 = 0; ndx2 < incr; ndx2++)
2473 		    {
2474 		      ch = *location++;
2475 		      *buf++ = hexchars[ch >> 4];
2476 		      *buf++ = hexchars[ch & 0xf];
2477 		    }
2478 		  mem += incr;
2479 		}
2480 	      else if (incr <= 0) /* should never happen */
2481 		{
2482 		  *buf = 0;
2483 		  return (0);
2484 		}
2485 	    }
2486 	  else if (status == NOT_FOUND_TARGET_RESPONSE)
2487 	    {
2488 	      *buf = 0;
2489 	      return (ndx);	/* return amount copied */
2490 	    }
2491 	  else
2492 	    {
2493 	      *buf = 0;
2494 	      return (0);	/* XXX: how do we tell the user the status? */
2495 	    }
2496 	}
2497       *buf = 0;
2498       return (count);
2499     }
2500   else
2501     {
2502       for (ndx = 0; ndx < count; ndx++)
2503 	{
2504 	  ch = *mem++;
2505 	  *buf++ = hexchars[ch >> 4];
2506 	  *buf++ = hexchars[ch & 0xf];
2507 	}
2508       *buf = 0;
2509       return (count);		/* we copied everything */
2510     }
2511 }
2512 
2513 static DTC_RESPONSE
2514 find_memory(unsigned char *mem, long count,
2515 	    unsigned char **location, long *incr)
2516 {
2517   DTC_RESPONSE retval;
2518   long length;
2519 
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);
2524 
2525   if (curframe.valid)
2526     {
2527       unsigned char *mem_block;
2528       unsigned char *mem_addr;
2529       unsigned long mem_size;
2530       unsigned long mem_stamp;
2531 
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);
2536 
2537       switch (retval)
2538 	{
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);
2546 
2547 	  if (length < count)
2548 	    *incr = length;
2549 	  else
2550 	    *incr = count;
2551 
2552 	  break;
2553 
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))
2562 	    {
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;
2574 	    }
2575 	  else
2576 	    retval = NOT_FOUND_TARGET_RESPONSE;
2577 
2578 	  break;
2579 
2580 	default:
2581 #if 0
2582 	  printp("BAD RETURN: %d\n", retval);
2583 #endif
2584 	  retval = NOT_FOUND_TARGET_RESPONSE;
2585 	  break;
2586 	}
2587     }
2588   else
2589     {
2590       *location = mem;
2591       *incr = count;
2592       retval = OK_TARGET_RESPONSE;
2593     }
2594 
2595   return (retval);
2596 }
2597 
2598 /* Convert the hex array pointed to by buf into binary to be placed in mem.
2599    Return SUCCESS or FAIL.  */
2600 
2601 static long
2602 hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
2603 {
2604   long i, ch;
2605 
2606   for ( i=0; i<count; i++ )
2607     {
2608       ch = hex( *buf++ ) << 4;
2609       ch = ch + hex( *buf++ );
2610       if ( may_fault )
2611         {
2612           ch = set_uchar( mem++, ch );
2613           if ( ch < 0 )    /* negative return indicates error */
2614             return FAIL;
2615         }
2616       else
2617         *mem++ = ch;
2618     }
2619   return SUCCESS;
2620 }
2621 
2622 /**********************************************/
2623 /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
2624 /* RETURN NUMBER OF CHARS PROCESSED           */
2625 /**********************************************/
2626 
2627 static int
2628 hexToInt( char **ptr, unsigned long *intValue )
2629 {
2630   long numChars = 0;
2631   long hexValue;
2632 
2633   *intValue = 0;
2634   while ( **ptr )
2635     {
2636       hexValue = hex( **ptr );
2637       if ( hexValue >=0 )
2638         {
2639           *intValue = (*intValue << 4) | hexValue;
2640           numChars ++;
2641         }
2642       else
2643         break;
2644       (*ptr)++;
2645     }
2646   return numChars;
2647 }
2648 
2649 static volatile long gdb_handling_trap1;
2650 static volatile long gdb_handling_sstrace;
2651 static volatile long gdb_signo;
2652 
2653 /*
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.
2657 
2658    May be further broken up as we go along, with individual requests
2659    broken out as separate functions.
2660  */
2661 
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 *);
2668 
2669 void
2670 handle_request( char *request )
2671 {
2672 #if 0
2673   remote_debug = 2;
2674 #endif
2675   switch( *request++ )
2676     {
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;
2688 
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.  */
2694 
2695       putpacket( "OK" );
2696       break;
2697 
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.  */
2704       {
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.
2713          */
2714 
2715         /* all registers default to zero */
2716         memset (outbuffer, '0', NUMREGBYTES);
2717         outbuffer[NUMREGBYTES] = '\0';
2718 
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 );
2724 
2725         putpacket( outbuffer );
2726       }
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
2734         {
2735           /* Write the values into the local registers cache...
2736              Note that no actual registers are being changed.  */
2737 
2738           hex2mem( request,
2739                   (unsigned char *) registers, NUMREGBYTES, 0 );
2740           putpacket( "OK" );
2741         }
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).  */
2747 
2748       if (curframe.valid)
2749         putpacket ("E03");      /* can't write regs into a trace frame! */
2750       else
2751         {
2752           unsigned long regno;
2753 
2754           if ( hexToInt( &request, &regno ) && *(request++) == '=' )
2755             {
2756               if ( regno < NUMREGS )
2757                 {
2758                   hexToInt( &request,
2759                            (unsigned long *) &registers[REGISTER_BYTE(regno)]);
2760 
2761                   putpacket( "OK" );
2762                 }
2763               else
2764                 putpacket( "E01" );   /* bad packet or regno */
2765             }
2766         }
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.  */
2772       {
2773         unsigned long addr, len;
2774 
2775         if ( hexToInt( &request, &addr )    &&
2776              *(request++) == ','            &&
2777              hexToInt( &request, &len ) )
2778           {
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 */
2786           }
2787         else
2788           putpacket( "E01" );           /* badly formed read request */
2789 
2790       }
2791       break;
2792     case 'M':           /* Write memory.
2793     Maaaaaaaa,llll:xxxx    aaaaaaaa is address, llll is length;
2794                            xxxx is data to write.  */
2795 
2796       {
2797         unsigned long addr, len;
2798 
2799         if (curframe.valid)     /* can't write memory into a trace frame! */
2800           putpacket ("E03");    /* "access denied" */
2801         else /*** if ( write_access_enabled ) ***/
2802           {
2803             if ( hexToInt( &request, &addr )  &&
2804                  *(request++) == ','          &&
2805                  hexToInt( &request, &len )   &&
2806                  *(request++) == ':' )
2807               {
2808                 if (len == 2 &&
2809                     addr >= CS_CODE_START &&
2810                     addr <= LAST_CS_WORD)
2811                   {
2812                     unsigned long val;
2813 
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 */
2819                   }
2820                 else
2821                   {
2822                     if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
2823                       putpacket( "E03" );   /* write fault (access denied) */
2824                     else
2825                       putpacket( "OK" );    /* write succeeded */
2826                   }
2827               }
2828             else
2829                 putpacket( "E02" );     /* badly formed write request */
2830           }
2831       }
2832       break;
2833     case 'c':           /* Continue.
2834     cAAAAAAAA              AAAAAAAA is address from which to resume.
2835                            If omitted, resume at current PC.  */
2836 
2837       {
2838         unsigned long addr;
2839 
2840 	if (curframe.valid)
2841 	  {
2842 	    /* Don't continue if debugging a trace frame! */
2843 	    gdb_puts ("Error: can't continue!\n");
2844 	    putpacket ("S03");
2845 	  }
2846 	else
2847 	  {
2848 	    gdb_signo = 3;
2849 	    if (isxdigit(request[0]))
2850 	      {
2851 		hexToInt(&request, &addr);
2852 		registers[REGISTER_BYTE(PC)] = addr;
2853 	      }
2854 
2855 	    gdb_handling_trap1 = FALSE;
2856 	    gdb_handling_sstrace = FALSE;
2857 	    sss_trace_flag = '\0';
2858 	  }
2859       }
2860       break;
2861     case 's':           /* Step.
2862     sAAAAAAAA              AAAAAAAA is address from which to begin stepping.
2863                            If omitted, begin stepping at current PC.  */
2864       {
2865         unsigned long addr;
2866 
2867 	if (curframe.valid)
2868 	  {
2869 	    /* Don't step if debugging a trace frame! */
2870 	    gdb_puts ("Error: can't step!\n");
2871 	    putpacket ("S03");
2872 	  }
2873 	else
2874 	  {
2875 	    gdb_signo = 3;
2876 	    if (isxdigit(request[0]))
2877 	      {
2878 		hexToInt(&request, &addr);
2879 		registers[REGISTER_BYTE(PC)] = addr;
2880 	      }
2881 
2882 	    gdb_handling_trap1 = FALSE;
2883 	    gdb_handling_sstrace = FALSE;
2884 	    sss_trace_flag = 't';
2885 	  }
2886       }
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.   */
2892 
2893       {
2894         unsigned long addr = 0;
2895 
2896         if (!gdb_handling_trap1 || curframe.valid)
2897           {
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?) */
2902           }
2903         else
2904           {
2905 	    gdb_signo = 3;
2906             if ( isxdigit( *request ) )
2907               {
2908                 hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
2909                 request += 2;
2910                 if ( *request == ';' && isxdigit( *++request ) )
2911                   {
2912                     hexToInt( &request, &addr );
2913                     registers[REGISTER_BYTE(PC)] = addr;
2914                   }
2915               }
2916             gdb_handling_trap1 = FALSE;
2917             gdb_handling_sstrace = FALSE;
2918             sss_trace_flag = '\0';
2919           }
2920       }
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.   */
2926       {
2927         unsigned long addr = 0;
2928 
2929         if (!gdb_handling_trap1 || curframe.valid)
2930           {
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?) */
2935           }
2936         else
2937           {
2938 	    gdb_signo = 3;
2939             if ( isxdigit( *request ) )
2940               {
2941                 hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
2942                 request += 2;
2943                 if ( *request == ';' && isxdigit( *++request ) )
2944                   {
2945                     hexToInt( &request, &addr );
2946                     registers[REGISTER_BYTE(PC)] = addr;
2947                   }
2948               }
2949             gdb_handling_trap1 = FALSE;
2950             gdb_handling_sstrace = FALSE;
2951             sss_trace_flag = 't';
2952           }
2953       }
2954       break;
2955     case '?':           /* Query the latest reason for stopping.
2956                            Should be same reply as was last generated
2957                            for step or continue.  */
2958 
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;
2967 
2968     case 'd':           /* Toggle debug mode
2969                            I'm sure we can think of something interesting.  */
2970 
2971       remote_debug = !remote_debug;
2972       putpacket( "" );  /* return empty packet */
2973       break;
2974 
2975     case 'q':           /* general query */
2976       switch (*request++)
2977         {
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;
2992         }
2993       break;
2994 
2995     case 'Q':                   /* general set */
2996       switch (*request++)
2997         {
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;
3004         }
3005       break;
3006 
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;
3013     }
3014 }
3015 
3016 static TDP_SETUP_INFO tdp_temp;
3017 static int trace_running;
3018 
3019 /*
3020  * Function msgcmp:
3021  *
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.
3025  *
3026  * Return: zero for DIFFERENT, non-zero for SUCCESS
3027  */
3028 
3029 static int
3030 msgcmp (char **msgp, char *str)
3031 {
3032   char *next;
3033 
3034   if (msgp != 0 && str != 0)    /* input validation */
3035     if ((next = *msgp) != 0)
3036       {
3037         for (;
3038              *next && *str && *next == *str;
3039              next++, str++)
3040           ;
3041 
3042         if (*str == 0)                  /* matched all of str in msg */
3043           return (int) (*msgp = next);  /* advance msg ptr past str  */
3044       }
3045   return 0;                             /* failure */
3046 }
3047 
3048 static char *
3049 handle_trace_query (char *request)
3050 {
3051   if (msgcmp (&request, "Status"))
3052     {
3053       if (adbg_check_if_active ())
3054 	{
3055 	  gdb_puts ("Target trace is running.\n");
3056 	  return "T1";
3057 	}
3058       else
3059 	{
3060 	  gdb_puts ("Target trace not running.\n");
3061 	  trace_running = 0;
3062 	  return "T0";
3063 	}
3064     }
3065   else                  /* unknown trace query */
3066     {
3067       return "";
3068     }
3069 }
3070 
3071 static void
3072 gdb_note (char *fmt, int arg1)
3073 {
3074   if (remote_debug > 1)
3075     {
3076       sprintp (spare_buffer, fmt, arg1);
3077       gdb_puts (spare_buffer);
3078     }
3079 }
3080 
3081 static int
3082 error_ret (int ret, char *fmt, int arg1)
3083 {
3084   if (remote_debug > 0)
3085     {
3086       sprintp (spare_buffer, fmt, arg1);
3087       gdb_puts (spare_buffer);
3088     }
3089   return ret;
3090 }
3091 
3092 static int
3093 handle_format (char **request, COLLECTION_FORMAT_DEF *format)
3094 {
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;
3101 
3102   if (format->id == 0)
3103     {
3104       if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
3105 	return dtc_error_ret (-1, "get_unused_format_id", ret);
3106 
3107       if (**request == 'R')
3108 	{
3109 	  (*request)++;
3110 	  hexToInt (request, &format->regs_mask);
3111 	}
3112       gdb_note ("STUB: call define_format (id = %d, ", format->id);
3113       gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
3114 
3115       if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
3116 	{
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;
3123 	}
3124     }
3125 
3126   while ((**request == 'M') || (**request == 'X'))
3127     {
3128       switch (**request)
3129 	{
3130 	case 'M':		/* M<regnum>,<offset>,<size> */
3131 	  (*request)++;
3132 	  hexToInt(request, &regnum);
3133 
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);
3142 
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);
3149 
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)
3156 	    {
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;
3163 	    }
3164 	  break;
3165 
3166 	case 'X':		/* X<length>,<bytecodes> */
3167 	  {
3168 	    unsigned long length;
3169 
3170 	    (*request)++;
3171 	    hexToInt(request, &length);
3172 
3173 	    if ((length <= 0) || (length > MAX_BYTE_CODES))
3174 	      return error_ret (-1,
3175 				"Bytecode expression length (%d) too large\n",
3176 				length);
3177 
3178 	    if (*(*request)++ != ',')
3179 	      return error_ret (-1,
3180 				"Malformed bytecode expr (comma#%d missing)\n",
3181 				1);
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;
3186 
3187 	    hex2mem(*request, &t_expr->expr[0], length, 0);
3188 	    *request += 2 * length;
3189 	    build_and_add_expression(format->id, t_expr);
3190 	  }
3191 	  break;
3192 	}
3193     }
3194   return 0;
3195 }
3196 
3197 static char *
3198 handle_trace_set (char *request)
3199 {
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];
3206 
3207   if (msgcmp (&request, "init"))
3208     {
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
3214         {
3215           sprintp (retbuf, "E2%x", ret);
3216           return (char *) dtc_error_ret ((int) &retbuf,
3217                                          "clear_trace_state",
3218                                          ret);
3219         }
3220     }
3221   else if (msgcmp (&request, "Start"))
3222     {
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
3230         {
3231           sprintp (retbuf, "E2%x", ret);
3232           return (char *) dtc_error_ret ((int) &retbuf,
3233                                          "start_trace_experiment",
3234                                          ret);
3235         }
3236     }
3237   else if (msgcmp (&request, "Stop"))
3238     {
3239       trace_running = 0;
3240       if (adbg_check_if_active ())
3241 	{
3242 	  gdb_note ("STUB: call end_trace_experiment();\n", 0);
3243 	  if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
3244 	    return "OK";
3245 	  else
3246 	    {
3247 	      sprintp (retbuf, "E2%x", ret);
3248 	      return (char *) dtc_error_ret ((int) &retbuf,
3249 					     "end_trace_experiment",
3250 					     ret);
3251 	    }
3252 	}
3253       else return "OK";
3254     }
3255   /* "TDP:" (The 'T' was consumed in handle_request.)  */
3256   else if (msgcmp (&request, "DP:"))
3257     {
3258       /* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format>
3259                                                      {S{R[M,X]+}}<tp-format>
3260 
3261 	 D -- disable tracepoint (illegal from EMC's point of view)
3262 	 E -- enable tracepoint?
3263 
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.
3268 	 */
3269 
3270       /* state variable, required for splitting TDP packets. */
3271       static int doing_step_formats;
3272 
3273       /*
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
3286        */
3287 
3288       if (*request == '-')	/* this is a continuation of a
3289 				   trace definition in progress */
3290 	{
3291 	  unsigned long temp_id, temp_addr;
3292 
3293 	  request++;
3294 	  if (!(hexToInt (&request, &temp_id) &&
3295 		*request++ == ':'))
3296 	    return "E11";           /* badly formed packet, field 1 */
3297 
3298 	  if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
3299 		*request++ == ':'))
3300 	    return "E12";           /* badly formed packet, field 2 */
3301 
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 */
3306 	}
3307       else			/* This is a new TDP definition */
3308 	{
3309 	  memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
3310 	  memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3311 	  doing_step_formats = FALSE;
3312 
3313 	  if (!(hexToInt (&request, &tdp_temp.id) &&
3314 		*request++ == ':'))
3315 	    return "E11";           /* badly formed packet, field 1 */
3316 
3317 	  if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
3318 		*request++ == ':'))
3319 	    return "E12";           /* badly formed packet, field 2 */
3320 
3321 	  if (!(((enable = *request++) == 'D' || enable == 'E') &&
3322 		*request++ == ':'))
3323 	    return "E13";           /* badly formed packet, field 3 */
3324 #if 0
3325 	  if (enable == 'D')
3326 	    {
3327 	      gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
3328 	      return "E20";
3329 	    }
3330 #endif
3331 	  if (!(hexToInt (&request, &tdp_temp.stepcount) &&
3332 		*request++ == ':'))
3333 	    return "E14";           /* badly formed packet, field 4 */
3334 
3335 	  if (!hexToInt (&request, &tdp_temp.pass_limit))
3336 	    return "E15";           /* badly formed packet, field 5 */
3337 
3338 	}
3339 
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.
3344 
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.  */
3348 
3349       if (*request == 'R' || *request == 'M' || *request == 'X')
3350         {
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;
3357         }
3358 
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')
3363 	{
3364 	  doing_step_formats = TRUE;
3365 	  /* discard prev format and start a new one */
3366 	  memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3367 	  request++;
3368 
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')
3373 	    {
3374 	      if (handle_format (&request, &tempfmt1))
3375 		return "E17";
3376 	      /* new format ID is tp_format */
3377 	      tdp_temp.tp_format_p = tempfmt1.id;
3378 	    }
3379 	}
3380 
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!) */
3384 	{
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);
3391 
3392 	  ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
3393 
3394 	  if (ret == OK_TARGET_RESPONSE)
3395 	    {
3396 	      sprintp (retbuf, "OK");
3397 	    }
3398 	  else
3399 	    {
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);
3406 	    }
3407 	  /* Redundant, but let's try to make sure this state gets discarded. */
3408 	  {
3409 	    memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
3410 	    memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3411 	  }
3412 	}
3413       else /* ADBG_DTC does not support disabled tracepoints -- ignore it.  */
3414 	gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
3415 
3416       return retbuf;
3417     }
3418   else if (msgcmp (&request, "Frame:"))
3419     {
3420       ret = OK_TARGET_RESPONSE;
3421 
3422       if (msgcmp (&request, "pc:"))
3423         {
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);
3433         }
3434       else if (msgcmp (&request, "tdp:"))
3435         {
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);
3445         }
3446       else if (msgcmp (&request, "range:"))
3447         {
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);
3462         }
3463       else if (msgcmp (&request, "outside:"))
3464         {
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);
3479         }
3480       else /* simple TFind by frame number: */
3481         {
3482           if (!hexToInt (&request, &frameno))
3483             return "E10";       /* badly formed packet */
3484           if (frameno != (unsigned long) -1)
3485             {
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
3493             }
3494           else  /* discard any trace frame, debug "the real world" */
3495             {
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";
3501             }
3502         }
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;
3508 
3509           memset ((char *) &curframe.traceregs, 0,
3510                   sizeof (curframe.traceregs));
3511           curframe.traceregs[PC] = (unsigned long)
3512             curframe.frame_data->program_counter;
3513 
3514           if (curframe.format)
3515             {
3516               unsigned long regs_mask = curframe.format->regs_mask;
3517               unsigned long *regs, *stack, *mem;
3518               unsigned long regno, index = 0;
3519               CFD *dummy;
3520 
3521               if ((ret = get_addr_to_frame_regs_stack_mem
3522                    (curframe.frame_data, &dummy, &regs, &stack, &mem))
3523                   != OK_TARGET_RESPONSE)
3524                 {
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);
3531                 }
3532 
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);
3543                 }
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 */
3549                   {
3550                     curframe.traceregs[regno] = regs[index++];
3551                     if (remote_debug > 1)
3552                       {
3553                         sprintp (spare_buffer,
3554                                  "      Collected 0x%08x for register %d.\n",
3555                                  curframe.traceregs[regno], regno);
3556                         gdb_puts (spare_buffer);
3557                       }
3558                   }
3559               if (remote_debug > 1)
3560                 {
3561                   long           midx, ridx, len;
3562                   MEMRANGE_DEF  *mrange;
3563                   unsigned char *data, *base;
3564 
3565                   if (curframe.format->stack_size > 0)
3566                     {
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);
3572 
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);
3581                     }
3582 		  else
3583 		    gdb_puts ("Stack not collected\n");
3584 
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++)
3592                     {
3593                       if ((mrange->typecode == 0) ||
3594                           (mrange->typecode == (unsigned long) -1))
3595                         {
3596                           sprintp (spare_buffer,
3597                                    "      Collected %d bytes at MEM: 0x%x:\n",
3598                                    mrange->size, mrange->offset);
3599                           base = (unsigned char *) mrange->offset;
3600                         }
3601                       else
3602                         {
3603                           if ((ridx = elinum_to_index (mrange->typecode)) > 0)
3604                             base = (unsigned char *) curframe.traceregs[ridx]
3605                               + (long) mrange->offset;
3606                           else
3607                             {
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;
3616                             }
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);
3623                         }
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);
3632                     }
3633                 }
3634             }
3635           sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
3636           return   retbuf;
3637         }
3638       else if (ret == NOT_FOUND_TARGET_RESPONSE)
3639         {
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"?
3644            */
3645           return "F-1";
3646         }
3647       else
3648         {
3649           sprintp (retbuf, "E2%x", ret);
3650           return (char *) dtc_error_ret ((int) &retbuf,
3651                                          "fetch_trace_frame[...]",
3652                                          ret);
3653         }
3654     }
3655   else                  /* unknown trace command */
3656     {
3657       return "";
3658     }
3659 }
3660 
3661 /* Table used by the crc32 function to calcuate the checksum. */
3662 static unsigned long crc32_table[256];
3663 
3664 static int crc_mem_err;
3665 
3666 static unsigned long
3667 crc32 (buf, len, crc)
3668      unsigned char *buf;
3669      int len;
3670      unsigned long crc;
3671 {
3672   crc_mem_err = FALSE;
3673 
3674   if (! crc32_table[1])
3675     {
3676       /* Initialize the CRC table and the decoding table. */
3677       int i, j;
3678       unsigned int c;
3679 
3680       for (i = 0; i < 256; i++)
3681 	{
3682 	  for (c = i << 24, j = 8; j > 0; --j)
3683 	    c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
3684 	  crc32_table[i] = c;
3685 	}
3686     }
3687 
3688   while (len--)
3689     {
3690       if (read_access_violation (buf))
3691 	{
3692 	  crc_mem_err = TRUE;
3693 	  return -1;
3694 	}
3695       crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
3696     }
3697   return crc;
3698 }
3699 
3700 static char *
3701 crc_query (cmd)
3702      char *cmd;
3703 {
3704   unsigned long startmem, len, crc;
3705   static char buf[32];
3706 
3707   if (hexToInt (&cmd, &startmem) &&
3708       *cmd++ == ','              &&
3709       hexToInt (&cmd, &len))
3710     {
3711       crc = crc32  ((unsigned char *) startmem, len, 0xffffffff);
3712       if (!crc_mem_err)
3713 	{
3714 	  sprintp (buf, "C%08x", crc);
3715 	  return buf;
3716 	}
3717       /* else error, fall thru */
3718     }
3719   sprintp (buf, "E01");
3720   return buf;
3721 }
3722 
3723 
3724 static char *
3725 handle_test (request)
3726      char *request;
3727 {
3728   ULONG args[7];
3729   int i;
3730 
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)
3736       {
3737 	if (! hexToInt (&request, &args[i++]))
3738 	  return "E01";
3739 	if (*request == '\0')
3740 	  break;
3741 	if (*request++ != ',')
3742 	  return "E01";
3743       }
3744 
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;
3749 
3750   gdb_c_test (args);
3751 
3752   return "OK";
3753 }
3754 
3755 
3756 /* GDB_TRAP_1_HANDLER
3757 
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.
3760 
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.
3764 
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.)   */
3770 
3771 void  gdb_trap_1_handler( void )
3772 {
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 )
3778     ;
3779   return;
3780 }
3781 
3782 void  gdb_trace_handler( void )
3783 {
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 )
3790     ;
3791   return;
3792 }
3793