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
gdb_recursion_test(int depth,int q1,int q2,int q3,int q4,int q5,int q6)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
gdb_c_test(ULONG * parm)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
lan_init(void)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
lan_isr(void)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
lan_get_char(void)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
lan_put_char(UCHAR c)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
lan_util(ULONG * parm)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
lan_reset(void)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
lan_configure(void)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
lan_init_queue(T_RS232_QUEUE * p_queue)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
lan_add_to_queue(long c,T_RS232_QUEUE * p_queue)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
lan_next_queue_char(T_RS232_QUEUE * p_queue)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
lan_util_menu(void)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
get_gdb_input(long c,T_RS232_QUEUE * p_input_q)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
write_to_protected_mem(addr,word)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
main(void)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
discard_packet(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
hex(char ch)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
getpacket(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
putpacket(char * str)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
gdb_get_eth_input(unsigned char * buf,long length)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
gdb_write(char * data,long len)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
gdb_puts(char * str)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
elinum_to_index(unsigned long elinum)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
index_to_elinum(unsigned long index)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
dtc_error_ret(int ret,char * src,DTC_RESPONSE code)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 *) ®s,
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
set_uchar(unsigned char * addr,unsigned char val)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
read_access_violation(const void * addr)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
write_access_violation(const void * addr)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
read_access_range(const void * addr,long count)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
mem2hex(unsigned char * mem,char * buf,long count,long may_fault)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
find_memory(unsigned char * mem,long count,unsigned char ** location,long * incr)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
hex2mem(char * buf,unsigned char * mem,long count,long may_fault)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
hexToInt(char ** ptr,unsigned long * intValue)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
handle_request(char * request)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, ®no ) && *(request++) == '=' )
2755 {
2756 if ( regno < NUMREGS )
2757 {
2758 hexToInt( &request,
2759 (unsigned long *) ®isters[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
msgcmp(char ** msgp,char * str)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 *
handle_trace_query(char * request)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
gdb_note(char * fmt,int arg1)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
error_ret(int ret,char * fmt,int arg1)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
handle_format(char ** request,COLLECTION_FORMAT_DEF * format)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, ®num);
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 *
handle_trace_set(char * request)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, ®s, &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
crc32(buf,len,crc)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 *
crc_query(cmd)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 *
handle_test(request)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
gdb_trap_1_handler(void)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
gdb_trace_handler(void)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