OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [testsuite/] [gdb.trace/] [gdb_c_test.c] - Blame information for rev 157

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/*
2
 ******************************************************************************
3
 ******************************************************************************
4
 *
5
 * COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved.
6
 * DESCRIPTION: This module has been provided for the purpose of testing GDB.
7
 *
8
 * NOTES:
9
 *
10
 ******************************************************************************
11
 *****************************************************************************/
12
 
13
/*=============================================================================
14
 *                                  INCLUDE  FILES
15
 *===========================================================================*/
16
 
17
 
18
#ifdef DO_IT_BY_THE_BOOK
19
 
20
 
21
#include "symtypes_defs.h"
22
#include "printp.h"
23
 
24
#include "adbg_expression.h"
25
#include "common_hw_ds.h"
26
#include "common_hw_defs.h"
27
#include "evnttrac.h"
28
#include "sym_scratch_ds.h"
29
#include "symglob_ds.h"
30
#include "sym_protglob_ds.h"
31
 
32
#include "ether.h"
33
 
34
#include <ctype.h>
35
 
36
 
37
#else
38
 
39
#include "adbg_dtc.h"
40
 
41
#define YES             1
42
#define NO              0
43
 
44
#define TRUE            1
45
#define FALSE           0
46
 
47
#define ENABLED         1
48
#define DISABLED        0
49
 
50
#define CONTROL_C       3   /* ASCII 'ETX' */
51
 
52
 
53
/*
54
 * Faked after ctype.h
55
 */
56
 
57
#define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
58
                     ((X) >= 'A' && (X) <= 'F') || \
59
                     ((X) >= 'a' && (X) <= 'f'))
60
/*
61
 * Borrowed from string.h
62
 */
63
 
64
extern unsigned int strlen ( const char * );
65
 
66
/*
67
 * Extracted from symtypes.h:
68
 */
69
 
70
typedef char                    BOOL;     /*  8 Bits */
71
typedef unsigned char           UCHAR;    /*  8 Bits */
72
typedef unsigned short          USHORT;   /* 16 Bits */
73
typedef unsigned long           ULONG;    /* 32 Bits */
74
 
75
/*
76
 * for struct t_expr_tag and
77
 * decl of build_and_add_expression
78
 */
79
#include "adbg_expression.h"
80
#define NULL    0
81
 
82
/*
83
 * Extracted from printp.h:
84
 */
85
 
86
extern void printp ( const char * fptr, ... );
87
extern void sprintp ( const char * fptr, ... );
88
 
89
/*
90
 * Extracted from ether.h:
91
 */
92
 
93
extern long eth_to_gdb ( UCHAR *buf, long length );
94
 
95
 
96
/*
97
 * Derived from hwequs.s:
98
 */
99
 
100
#define CS_CODE_START           0x100000
101
#define CS_CODE_SIZE            0x200000
102
#define LAST_CS_WORD            (CS_CODE_START + CS_CODE_SIZE - 2)
103
 
104
#define sh_genstat1             (*((volatile ULONG *) 0xFFFFFE54))
105
 
106
#define rs232_mode1             0               /* rs-232 mode 1 reg. */
107
#define rs232_mode2             rs232_mode1     /* rs-232 mode 2 reg. */
108
#define rs232_stat              4               /* rs-232 status reg. */
109
#define rs232_clk               rs232_stat      /* rs-232 clock select reg. */
110
#define rs232_cmd               8               /* rs-232 command reg */
111
#define rs232_transmit          12              /* rs-232 transmit reg. */
112
#define rs232_receive           rs232_transmit  /* rs-232 transmit reg. */
113
#define rs232_aux               16              /* rs-232 aux control reg. */
114
#define rs232_isr               20              /* rs-232 interrupt status reg. */
115
#define rs232_imr               rs232_isr       /* rs-232 interrupt mask reg. */
116
#define rs232_tc_high           24              /* rs-232 timer/counter high reg. */
117
#define rs232_tc_low            28              /* rs-232 timer/counter low reg.  */
118
 
119
 
120
#endif
121
 
122
 
123
/*============================================================================
124
 *                                 MODULE  DEFINES
125
 *===========================================================================*/
126
 
127
#define P_RST_LAN_UART_REG      ((volatile UCHAR  *) 0xFFFFFE45)
128
#define M_RST_LAN_UART          0x80          /* Bit  7 */
129
 
130
#define P_LAN0TR_REG            P_RST_LAN_UART_REG
131
#define M_LAN0TR                0x20          /* Bit  5 */
132
 
133
#define M_SH_GENCON_LAN0TR      0x00200000    /* Bit 21 */
134
 
135
#define MAX_RS232_CHARS         512
136
 
137
#define LAN_Q_MOD(X)            ((X) % MAX_RS232_CHARS)
138
 
139
/*---------------------------------------*
140
 *           LAN  UART  Registers        *
141
 *---------------------------------------*/
142
 
143
#define LAN_UART_BASE               ((ULONG) 0xfffffc22)
144
 
145
/*  Write-Read  */
146
 
147
#define P_LAN_MR1                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode1   )))
148
#define P_LAN_MR2                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode2   )))
149
 
150
/*  Write-Only  */
151
 
152
#define P_LAN_ACR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux     )))
153
#define P_LAN_CR                    ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_cmd     )))
154
#define P_LAN_CSR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_clk     )))
155
#define P_LAN_CTLR                  ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_low  )))
156
#define P_LAN_CTUR                  ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_high )))
157
#define P_LAN_IMR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr     )))
158
 
159
/*  Read-Only */
160
 
161
#define P_LAN_SR                    ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_stat    )))
162
#define P_LAN_ISR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_isr     )))
163
#define P_LAN_XMT                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit)))
164
#define P_LAN_RCV                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive )))
165
 
166
/*
167
 *   Bit Values for Write-Read and Write-Only Registers
168
 */
169
 
170
#define DEFAULT_LAN_MR1             ((UCHAR) 0x13)
171
#define DEFAULT_LAN_MR2             ((UCHAR) 0x07)
172
#define DEFAULT_LAN_CSR             ((UCHAR) 0xcc)
173
#define DEFAULT_LAN_ACR             ((UCHAR) 0x38)
174
#define DEFAULT_LAN_CTUR            ((UCHAR) 0xff)
175
#define DEFAULT_LAN_CTLR            ((UCHAR) 0xff)
176
 
177
#define LAN_ACR_SELECT_BRG_0        DEFAULT_LAN_ACR
178
#define LAN_ACR_SELECT_BRG_1        (DEFAULT_LAN_ACR | 0x80)
179
 
180
#define UART_CR_RESET_MR_PTR        ((UCHAR) 0x10) /* Reset MR pointer (points to MR1). */
181
#define UART_CR_RESET_RVCR          ((UCHAR) 0x20) /* Reset receiver (disabled).        */
182
#define UART_CR_RESET_XMTR          ((UCHAR) 0x30) /* Reset transmitter (disabled).     */
183
#define UART_CR_RESET_ERROR_STATUS  ((UCHAR) 0x40) /* Reset error status.               */
184
#define UART_CR_RESET_BRK_CHG_INT   ((UCHAR) 0x50) /* Reset break change interrupt.     */
185
#define UART_CR_START_CNTR_TIMER    ((UCHAR) 0x80) /* Start counter/timer.              */
186
#define UART_CR_STOP_CNTR           ((UCHAR) 0x90) /* Stop counter.                     */
187
 
188
#define UART_CR_DISABLE_XMTR        ((UCHAR) 0x08) /* Disable transmitter.              */
189
#define UART_CR_ENABLE_XMTR         ((UCHAR) 0x04) /* Enable transmitter.               */
190
#define UART_CR_DISABLE_RCVR        ((UCHAR) 0x02) /* Disable receiver.                 */
191
#define UART_CR_ENABLE_RCVR         ((UCHAR) 0x01) /* Enable receiver.                  */
192
 
193
#define UART_CSR_BR_4800            ((UCHAR) 0x99) /* With either BRG Set selected (via ACR). */
194
#define UART_CSR_BR_9600            ((UCHAR) 0xbb) /* With either BRG Set selected (via ACR). */
195
#define UART_CSR_BR_19200           ((UCHAR) 0xcc) /* With BRG Set '1' selected (via ACR). */
196
#define UART_CSR_BR_38400           ((UCHAR) 0xcc) /* With BRG Set '0' selected (via ACR). */
197
 
198
#define UART_IMR_RxRDY              ((UCHAR) 0x04) /* Enable 'RxRDY' interrupt. */
199
#define UART_IMR_TxEMT              ((UCHAR) 0x02) /* Enable 'TxEMT' interrupt. */
200
#define UART_IMR_TxRDY              ((UCHAR) 0x01) /* Enable 'TxRDY' interrupt. */
201
 
202
/*
203
 *   Bit Masks for Read-Only Registers
204
 */
205
 
206
#define M_UART_SR_RCVD_BRK      0x80    /* Bit 7 */
207
#define M_UART_SR_FE            0x40    /* Bit 6 */
208
#define M_UART_SR_PE            0x20    /* Bit 5 */
209
#define M_UART_SR_OE            0x10    /* Bit 4 */
210
#define M_UART_SR_TxEMT         0x08    /* Bit 3 */
211
#define M_UART_SR_TxRDY         0x04    /* Bit 2 */
212
#define M_UART_SR_FFULL         0x02    /* Bit 1 */
213
#define M_UART_SR_RxRDY         0x01    /* Bit 0 */
214
 
215
#define M_UART_ISR_RxRDY        0x04    /* Bit 2 */
216
#define M_UART_ISR_TxEMT        0x02    /* Bit 1 */
217
#define M_UART_ISR_TxRDY        0x01    /* Bit 0 */
218
 
219
/*---------------------------------------*
220
 *       Support for 'Utility 83'.       *
221
 *---------------------------------------*/
222
 
223
#define LAN_UTIL_CODE           0x83
224
 
225
#define LAN_INIT                ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T'))
226
#define LAN_BAUD                ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D'))
227
#define LAN_INTR                ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R'))
228
#define LAN_XMT                 ((ULONG)               (('X' << 16) | ('M' << 8) | 'T'))
229
#define LAN_ECHO                ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O'))
230
#define LAN_STAT                ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T'))
231
#define LAN_IN                  ((ULONG)                             (('I' << 8) | 'N'))
232
#define LAN_OUT                 ((ULONG)               (('O' << 16) | ('U' << 8) | 'T'))
233
 
234
#define LAN_PUTC                ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
235
#define LAN_WPM                 ((ULONG)               (('W' << 16) | ('P' << 8) | 'M'))
236
 
237
#define STATUS(X)               ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
238
 
239
#define XMT_VIA_BP_ENABLED()    ( *P_LAN0TR_REG & M_LAN0TR  ?  1 : 0 )
240
 
241
#define TRAP_1_INST             0x4E41
242
 
243
/*
244
 *   Bit #13 of shared genstat 1 indicates
245
 *   which processor we are as follows.
246
 *
247
 *           0 => X (side A)
248
 *           1 => Y (side B)
249
 */
250
 
251
#define M_PROC_ID               0x00002000
252
 
253
#define IS_SIDE_A()             ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
254
#define IS_SIDE_B()             ( (sh_genstat1) & M_PROC_ID )
255
 
256
 
257
#ifdef STANDALONE       /* Compile this module stand-alone for debugging */
258
#define LAN_PUT_CHAR(X) printf("%c", X)
259
#else
260
#define LAN_PUT_CHAR(X) while ( lan_put_char( X ) )
261
#endif
262
 
263
 
264
 
265
 
266
#define VIA_RS232             0
267
#define VIA_ETHERNET          1
268
 
269
#define MAX_IO_BUF_SIZE       400
270
 
271
#define MAX_BYTE_CODES        200 /* maximum length for bytecode string */
272
 
273
 
274
static  ULONG           gdb_host_comm;
275
 
276
static  ULONG           gdb_cat_ack;
277
 
278
static  char            eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
279
 
280
 
281
#ifdef STANDALONE
282
 
283
#define ACK_PKT()       LAN_PUT_CHAR( '+' )
284
#define NACK_PKT()      LAN_PUT_CHAR( '-' )
285
 
286
#else
287
 
288
#define ACK_PKT()       {                                             \
289
                          if ( VIA_ETHERNET == gdb_host_comm )        \
290
                          {                                           \
291
                            gdb_cat_ack = YES;                        \
292
                          }                                           \
293
                          else                                        \
294
                          {                                           \
295
                            LAN_PUT_CHAR( '+' );                      \
296
                          }                                           \
297
                        }
298
 
299
 
300
 
301
#define NACK_PKT()      {                                             \
302
                          if ( VIA_ETHERNET == gdb_host_comm )        \
303
                          {                                           \
304
                            eth_outbuffer[ 0 ] = '-';                 \
305
                            eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
306
                          }                                           \
307
                          else                                        \
308
                          {                                           \
309
                            LAN_PUT_CHAR( '-' );                      \
310
                          }                                           \
311
                        }
312
 
313
#endif
314
 
315
 
316
 
317
 
318
/*============================================================================
319
 *                                 MODULE  TYPEDEFS
320
 *===========================================================================*/
321
 
322
typedef struct rs232_queue {
323
 
324
  long    head_index;
325
 
326
  long    tail_index;
327
 
328
  ULONG   overflows;
329
 
330
  long    gdb_packet_start;
331
  long    gdb_packet_end;
332
  long    gdb_packet_csum1;
333
  long    gdb_packet_csum2;
334
 
335
  UCHAR   buf[ MAX_RS232_CHARS ];
336
 
337
} T_RS232_QUEUE;
338
 
339
 
340
 
341
 
342
/*=============================================================================
343
 *                        EXTERNAL GLOBAL VARIABLES
344
 *===========================================================================*/
345
 
346
extern volatile UCHAR         sss_trace_flag;
347
 
348
 
349
/*=============================================================================
350
 *                           STATIC  MODULE  DECLARATIONS
351
 *===========================================================================*/
352
 
353
static  T_RS232_QUEUE lan_input_queue,
354
                      lan_output_queue;
355
 
356
static  BOOL          test_echo;
357
 
358
#if 0
359
/* The stub no longer seems to use this.  */
360
static  BOOL          write_access_enabled;
361
#endif
362
 
363
static  int           baud_rate_idx;
364
 
365
static  ULONG         tx_by_intr,
366
                      tx_by_poll;
367
 
368
static  UCHAR         lan_shadow_imr;
369
 
370
 
371
/*=============================================================================
372
 *                        EXTERNAL FUNCTION PROTOTYPES
373
 *===========================================================================*/
374
 
375
extern  long  write_to_protected_mem( void *address, unsigned short value );
376
 
377
 
378
/*=============================================================================
379
 *                      MODULE GLOBAL FUNCTIONS PROTOTYPES
380
 *===========================================================================*/
381
 
382
ULONG gdb_c_test( ULONG *parm );
383
 
384
 
385
void  lan_init( void );
386
 
387
void  lan_isr( void );
388
 
389
long  lan_get_char( void );
390
 
391
long  lan_put_char( UCHAR c );
392
 
393
ULONG lan_util( ULONG *parm );
394
 
395
 
396
/*=============================================================================
397
 *                      MODULE LOCAL FUNCTION PROTOTYPES
398
 *===========================================================================*/
399
 
400
static  void  lan_reset( void );
401
 
402
static  void  lan_configure( void );
403
 
404
static  void  lan_init_queue( T_RS232_QUEUE *p_queue );
405
 
406
static  void  lan_add_to_queue( long c, T_RS232_QUEUE *p_queue );
407
 
408
static  UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue );
409
 
410
static  void  lan_util_menu( void );
411
 
412
static  long  get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
413
 
414
 
415
/*=============================================================================
416
 *                      GDB STUB FUNCTION PROTOTYPES
417
 *===========================================================================*/
418
 
419
void  gdb_trap_1_handler( void );
420
void  gdb_trace_handler ( void );
421
 
422
void  gdb_get_eth_input( unsigned char *buf, long length );
423
 
424
static void getpacket ( void );
425
static void putpacket ( char * );
426
static void discard_packet ( void );
427
 
428
#ifdef    STANDALONE    /* Compile this module stand-alone for debugging */
429
#include <stdio.h>
430
#define printp printf   /* easier than declaring a local varargs stub func.  */
431
#endif /* STANDALONE */
432
 
433
 
434
/*=============================================================================
435
 *                              MODULE BODY
436
 *===========================================================================*/
437
 
438
/* ------------------- Things that belong in a header file --------------- */
439
extern char *memset (char *, int, int);
440
 
441
                  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
442
                  *                                     *
443
                  *       Global Module Functions       *
444
                  *                                     *
445
                  *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
446
 
447
 
448
static char   gdb_char_test;
449
static short  gdb_short_test;
450
static long   gdb_long_test;
451
static char   gdb_arr_test[25];
452
static struct GDB_STRUCT_TEST
453
{
454
  char   c;
455
  short  s;
456
  long   l;
457
  int    bfield : 11;   /* collect bitfield */
458
  char   arr[25];
459
  struct GDB_STRUCT_TEST *next;
460
} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
461
 
462
static union GDB_UNION_TEST
463
{
464
  char   c;
465
  short  s;
466
  long   l;
467
  int    bfield : 11;   /* collect bitfield */
468
  char   arr[4];
469
  union GDB_UNION_TEST *next;
470
} gdb_union1_test;
471
 
472
void gdb_recursion_test (int, int, int, int,  int,  int,  int);
473
 
474
void gdb_recursion_test (int depth,
475
                         int q1,
476
                         int q2,
477
                         int q3,
478
                         int q4,
479
                         int q5,
480
                         int q6)
481
{       /* gdb_recursion_test line 0 */
482
  int q = q1;                                           /* gdbtestline 1 */
483
 
484
  q1 = q2;                                              /* gdbtestline 2 */
485
  q2 = q3;                                              /* gdbtestline 3 */
486
  q3 = q4;                                              /* gdbtestline 4 */
487
  q4 = q5;                                              /* gdbtestline 5 */
488
  q5 = q6;                                              /* gdbtestline 6 */
489
  q6 = q;                                               /* gdbtestline 7 */
490
  if (depth--)                                          /* gdbtestline 8 */
491
    gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */
492
}
493
 
494
 
495
ULONG   gdb_c_test( ULONG *parm )
496
 
497
{
498
   char *p = "gdb_c_test";
499
   char *ridiculously_long_variable_name_with_equally_long_string_assignment;
500
   register long local_reg = 7;
501
   static unsigned long local_static, local_static_sizeof;
502
   long local_long;
503
   unsigned long *stack_ptr;
504
   unsigned long end_of_stack;
505
 
506
   ridiculously_long_variable_name_with_equally_long_string_assignment =
507
     "ridiculously long variable name with equally long string assignment";
508
   local_static = 9;
509
   local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
510
   local_long = local_reg + 1;
511
   stack_ptr  = (unsigned long *) &local_long;
512
   end_of_stack =
513
     (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
514
 
515
   printp ("\n$Id: gdb_c_test.c 131 2010-06-18 14:14:57Z jeremybennett $\n");
516
 
517
   printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n",
518
           p, parm[ 1 ], parm[ 2 ], parm[ 3 ], parm[ 4 ], parm[ 5 ], parm[ 6 ] );
519
 
520
   gdb_char_test   = gdb_struct1_test.c = (char)   ((long) parm[1] & 0xff);
521
   gdb_short_test  = gdb_struct1_test.s = (short)  ((long) parm[2] & 0xffff);
522
   gdb_long_test   = gdb_struct1_test.l = (long)   ((long) parm[3] & 0xffffffff);
523
   gdb_union1_test.l = (long) parm[4];
524
   gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff);
525
   gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff);
526
   gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff);
527
   gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff);
528
   gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff);
529
   gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff);
530
   gdb_struct1_test.bfield = 144;
531
   gdb_struct1_test.next = &gdb_struct2_test;
532
   gdb_structp_test      = &gdb_struct1_test;
533
   gdb_structpp_test     = &gdb_structp_test;
534
 
535
   gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
536
                       (long) parm[4], (long) parm[5], (long) parm[6]);
537
 
538
   gdb_char_test = gdb_short_test = gdb_long_test = 0;
539
   gdb_structp_test  = (void *) 0;
540
   gdb_structpp_test = (void *) 0;
541
   memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
542
   memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
543
   local_static_sizeof = 0;
544
   local_static = 0;
545
   return ( (ULONG) 0 );
546
}
547
 
548
 
549
/*-----------------------------------------------------------------------------
550
 *
551
 * FUNCTION NAME:   lan_init
552
 *
553
 *
554
 * DESCRIPTION:
555
 *
556
 *
557
 * RETURN VALUE:
558
 *
559
 *
560
 * USED GLOBAL VARIABLES:
561
 *
562
 *
563
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
564
 *
565
 *
566
 * NOTES:
567
 *
568
 *
569
 *
570
 *---------------------------------------------------------------------------*/
571
 
572
void    lan_init( void )
573
 
574
{
575
 
576
  if ( IS_SIDE_A( ) )
577
  {
578
 
579
    lan_reset( );
580
 
581
    lan_init_queue( &lan_input_queue );
582
 
583
    lan_init_queue( &lan_output_queue );
584
 
585
    lan_configure( );
586
  }
587
 
588
  return;
589
}
590
/* end of 'lan_init'
591
 *===========================================================================*/
592
 
593
 
594
/*-----------------------------------------------------------------------------
595
 *
596
 * FUNCTION NAME:   lan_isr
597
 *
598
 *
599
 * DESCRIPTION:
600
 *
601
 *
602
 * RETURN VALUE:    None.
603
 *
604
 *
605
 * USED GLOBAL VARIABLES:
606
 *
607
 *
608
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
609
 *
610
 *
611
 * NOTES:
612
 *
613
 *
614
 *---------------------------------------------------------------------------*/
615
 
616
void      lan_isr( void )
617
 
618
{
619
  UCHAR   c;
620
 
621
 
622
  lan_shadow_imr = 0;           /*  Disable all UART interrupts.  */
623
  *P_LAN_IMR = lan_shadow_imr;
624
 
625
 
626
  if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
627
  {
628
 
629
    gdb_host_comm = VIA_RS232;
630
 
631
    c = *P_LAN_RCV;
632
 
633
    if ( test_echo )
634
    {
635
      /* ????? */
636
    }
637
 
638
    if ( c == CONTROL_C )
639
    {
640
        /* can't stop the target, but we can tell gdb to stop waiting... */
641
      discard_packet( );
642
      putpacket( "S03" );       /* send back SIGINT to the debugger */
643
    }
644
 
645
    else
646
    {
647
      lan_add_to_queue( (long) c, &lan_input_queue );
648
      get_gdb_input( (long) c, &lan_input_queue );
649
    }
650
 
651
  }
652
 
653
  if ( XMT_VIA_BP_ENABLED( ) )
654
  {
655
 
656
    c = 0;
657
 
658
    while ( (*P_LAN_ISR & M_UART_ISR_TxRDY)  &&  (c = lan_next_queue_char( &lan_output_queue )) )
659
    {
660
      *P_LAN_XMT = c;
661
      ++tx_by_intr;
662
    }
663
 
664
    if ( c )
665
    {
666
      lan_shadow_imr |= UART_IMR_TxRDY;   /*  (Re-)Enable 'TxRDY' interrupt from UART.  */
667
    }
668
 
669
  }
670
 
671
 
672
  lan_shadow_imr |= UART_IMR_RxRDY;       /*  Re-Enable 'RxRDY' interrupt from UART.  */
673
  *P_LAN_IMR = lan_shadow_imr;
674
 
675
 
676
 
677
  return;
678
}
679
/* end of 'lan_isr'
680
 *===========================================================================*/
681
 
682
 
683
/*-----------------------------------------------------------------------------
684
 *
685
 * FUNCTION NAME:   lan_get_char
686
 *
687
 *
688
 * DESCRIPTION:     Fetches a character from the UART.
689
 *
690
 *
691
 * RETURN VALUE:    0 on success, -1 on failure.
692
 *
693
 *
694
 * USED GLOBAL VARIABLES:
695
 *
696
 *
697
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
698
 *
699
 *
700
 * NOTES:
701
 *
702
 *
703
 *---------------------------------------------------------------------------*/
704
 
705
long    lan_get_char( void )
706
 
707
{
708
  long status = -2; /* AGD: nothing found in rcv buffer */
709
 
710
  if ( *P_LAN_SR & M_UART_SR_RxRDY )
711
  {
712
    char c = (char) *P_LAN_RCV;
713
 
714
    if ( test_echo )
715
    {
716
      LAN_PUT_CHAR ( c );
717
    }
718
 
719
    if ( c == CONTROL_C )
720
    {
721
        /* can't stop the target, but we can tell gdb to stop waiting... */
722
      discard_packet( );
723
      putpacket( "S03" );       /* send back SIGINT to the debugger */
724
      status = 0;               /* success */
725
    }
726
 
727
    else
728
    {
729
      lan_add_to_queue( (long) c, &lan_input_queue );
730
      status = get_gdb_input( (long) c, &lan_input_queue );
731
    }
732
 
733
  }
734
 
735
  return( status );
736
}
737
/* end of 'lan_get_char'
738
 *===========================================================================*/
739
 
740
 
741
/*-----------------------------------------------------------------------------
742
 *
743
 * FUNCTION NAME:   lan_put_char
744
 *
745
 * DESCRIPTION:     Puts a character out via the UART.
746
 *
747
 * RETURN VALUE:    0 on success, -1 on failure.
748
 *
749
 * USED GLOBAL VARIABLES: none.
750
 *
751
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
752
 *
753
 * NOTES: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
754
 *        !!                                                                  !!
755
 *        !!  If 'XMT_VIA_BP_ENABLED()' is FALSE then output is THROWN AWAY.  !!
756
 *        !!  This prevents anyone infinite-looping on this function.         !!
757
 *        !!                                                                  !!
758
 *        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
759
 *
760
 *---------------------------------------------------------------------------*/
761
 
762
long    lan_put_char( UCHAR c )
763
 
764
{
765
  long    status = -1;
766
 
767
  if ( XMT_VIA_BP_ENABLED( ) )
768
  {
769
 
770
    if ( *P_LAN_SR & M_UART_SR_TxRDY )
771
    {
772
      lan_add_to_queue( (long) c, &lan_output_queue );
773
 
774
      c = lan_next_queue_char( &lan_output_queue );
775
 
776
      *P_LAN_XMT = c;
777
      ++tx_by_poll;
778
      status = 0;
779
    }
780
#if 0
781
    else
782
    {
783
      status = 0;
784
      lan_shadow_imr |= UART_IMR_TxRDY;   /*  Enable 'TxRDY' interrupt from UART. */
785
      *P_LAN_IMR = lan_shadow_imr;
786
    }
787
#endif
788
  }
789
 
790
  else
791
  {
792
    status = 0;   /* You lose: input character goes to the bit bucket. */
793
  }
794
 
795
  return( status );
796
}
797
/* end of 'lan_put_char'
798
 *===========================================================================*/
799
 
800
 
801
/*-----------------------------------------------------------------------------
802
 *
803
 * FUNCTION NAME:   lan_util
804
 *
805
 * DESCRIPTION:
806
 *
807
 * RETURN VALUE:
808
 *
809
 * USED GLOBAL VARIABLES:
810
 *
811
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
812
 *
813
 * NOTES:
814
 *
815
 *---------------------------------------------------------------------------*/
816
 
817
ULONG   lan_util( ULONG *parm )
818
 
819
{
820
 
821
 
822
  static const struct {
823
 
824
    ULONG rate_code;
825
    UCHAR acr_setting;
826
    UCHAR csr_setting;
827
 
828
  } baud_rate_setting [] = {
829
 
830
    { 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 },
831
    { 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 },
832
    { 0x9600,  LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600  },
833
    { 0x4800,  LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800  }
834
  };
835
 
836
 
837
#define BOGUS_P1        0xE1
838
#define BOGUS_P2        0xE2
839
 
840
  ULONG   not_done_code;
841
 
842
 
843
  ULONG   opcode;
844
  ULONG   parm_1;
845
  ULONG   parm_2;
846
 
847
  int     i;
848
  UCHAR   c;
849
 
850
 
851
  not_done_code = 0;
852
 
853
  opcode = parm[ 1 ];
854
  parm_1 = parm[ 2 ];
855
  parm_2 = parm[ 3 ];
856
 
857
 
858
  switch ( opcode )
859
  {
860
 
861
    case LAN_INIT:
862
      {
863
 
864
        lan_init( );
865
        printp( "\n\n  Interface (Re)Initialized ...\n\n" );
866
 
867
        break;
868
      }
869
 
870
 
871
    case LAN_BAUD:
872
      {
873
 
874
        for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
875
        {
876
          if ( baud_rate_setting[i].rate_code == parm_1 )
877
          {
878
            baud_rate_idx = i;
879
            *P_LAN_ACR = baud_rate_setting[i].acr_setting;
880
            *P_LAN_CSR = baud_rate_setting[i].csr_setting;
881
            printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code );
882
            return( not_done_code );
883
          }
884
        }
885
 
886
        printp( "\n\n  *** SYNTAX Error  -  Invalid baudrate (P2)\n\n" );
887
        not_done_code = BOGUS_P2;
888
 
889
        break;
890
      }
891
 
892
 
893
    case LAN_INTR:
894
      {
895
 
896
        switch ( parm_1 )
897
        {
898
 
899
          case 0x0D: /* Disable 'RxRDY' Interrupts */
900
            {
901
              lan_shadow_imr &= ~UART_IMR_RxRDY;
902
              *P_LAN_IMR = lan_shadow_imr;
903
              printp( "\n\n  Receive Ready Interrupts DISABLED ...\n\n" );
904
              break;
905
            }
906
 
907
          case 0x0E: /* Enable 'RxRDY' Interrupts */
908
            {
909
              lan_shadow_imr |= UART_IMR_RxRDY;
910
              *P_LAN_IMR = lan_shadow_imr;
911
              printp( "\n\n  Receive Ready Interrupts ENABLED ...\n\n" );
912
              break;
913
            }
914
 
915
          default:
916
            {
917
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
918
              not_done_code = BOGUS_P2;
919
            }
920
        }
921
 
922
        break;
923
      }
924
 
925
 
926
    case LAN_XMT:
927
      {
928
 
929
        switch ( parm_1 )
930
        {
931
 
932
          case 0x0E: /* Enable Transmission-via-Backplane */
933
            {
934
              if ( !(*P_LAN0TR_REG & M_LAN0TR) )
935
              {
936
                *P_LAN0TR_REG |= M_LAN0TR;  /* 0 -> 1 */
937
              }
938
 
939
              printp( "\n\n  Transmit-via-Backplane ENABLED ...\n\n" );
940
              break;
941
            }
942
 
943
          case 0x0D: /* Disable Transmission-via-Backplane */
944
            {
945
              if ( *P_LAN0TR_REG & M_LAN0TR )
946
              {
947
                *P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */
948
              }
949
 
950
              printp( "\n\n  Transmit-via-Backplane DISABLED ...\n\n" );
951
              break;
952
            }
953
 
954
          default:
955
            {
956
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
957
              not_done_code = BOGUS_P2;
958
              lan_util_menu( );
959
            }
960
        }
961
 
962
        break;
963
      }
964
 
965
 
966
    case LAN_STAT:
967
      {
968
 
969
      printp( "\n              -- Status --\n\n" );
970
 
971
        printp( "          Baud Rate: %X *\n",   baud_rate_setting[ baud_rate_idx ].rate_code );
972
        printp( "         Xmt-via-BP: %s *\n",   STATUS( XMT_VIA_BP_ENABLED( ) ) );
973
        printp( "         RxRdy Intr: %s *\n",   STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) );
974
   /*** printp( "         TxRdy Intr: %s\n",     STATUS( (lan_shadow_imr & M_UART_ISR_TxRDY) ) ); ***/
975
        printp( "               Echo: %s *\n\n", STATUS( test_echo ) );
976
 
977
        printp( "                IMR: %02X\n", (ULONG) lan_shadow_imr );
978
        printp( "                ISR: %02X\n", (ULONG) *P_LAN_ISR );
979
        printp( "                 SR: %02X\n\n", (ULONG) *P_LAN_SR );
980
 
981
        printp( "    Input Overflows: %d\n\n", lan_input_queue.overflows );
982
 
983
        printp( "         Tx by Intr: %d\n", tx_by_intr  );
984
        printp( "         Tx by Poll: %d\n\n", tx_by_poll );
985
 
986
        printp( "         *  Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE );
987
 
988
        break;
989
      }
990
 
991
 
992
    case LAN_IN:
993
      {
994
 
995
        switch ( parm_1 )
996
        {
997
 
998
          case 0x0C: /* Clear and Reset Queue */
999
            {
1000
              lan_init_queue( &lan_input_queue );
1001
              printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
1002
              break;
1003
            }
1004
 
1005
          case 0x0D: /* Display Queue */
1006
            {
1007
              printp( "\n                        -- Input Queue --\n" );
1008
              printp( "\n        Head Index: %8X     Tail Index: %8X\n\n    ",
1009
                     (ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index );
1010
 
1011
              for ( i = 0; i < MAX_RS232_CHARS; ++i )
1012
              {
1013
                printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
1014
 
1015
                if ( 15 == (i % 16) )
1016
                {
1017
                  int j;
1018
 
1019
                  printp ( "    " );
1020
                  for ( j = i - 15; j <= i; j++ )
1021
                    {
1022
                      if ( lan_input_queue.buf[ j ] >= ' ' &&
1023
                          lan_input_queue.buf[ j ] < 127 )
1024
                        printp ( "%c", lan_input_queue.buf[ j ] );
1025
                      else
1026
                        printp ( "." );
1027
                    }
1028
                  printp( "\n    " );
1029
                }
1030
 
1031
                else if ( 7 == (i % 8) )
1032
                {
1033
                  printp( " " );
1034
                }
1035
 
1036
              }
1037
 
1038
              printp( "\n" );
1039
 
1040
              break;
1041
            }
1042
 
1043
          case 0x0F: /* Fetch next character in Queue */
1044
            {
1045
              c = lan_next_queue_char( &lan_input_queue );
1046
 
1047
              if ( c )
1048
              {
1049
                printp( "\n\n  Next Character: " );
1050
                if (  0x21 <= c  &&  c <= 0x7F )
1051
                {
1052
                  printp( "%c\n\n", (ULONG) c );
1053
                }
1054
 
1055
                else if ( 0x20 == ((UCHAR) c) )
1056
                {
1057
                  printp( "<space>\n\n" );
1058
                }
1059
 
1060
                else
1061
                {
1062
                  printp( "%02X\n\n", (ULONG) c );
1063
                }
1064
              }
1065
 
1066
              else
1067
              {
1068
                printp( "\n\n  Input Queue EMPTY ...\n\n" );
1069
              }
1070
 
1071
            break;
1072
            }
1073
 
1074
          default:
1075
            {
1076
            printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
1077
            not_done_code = BOGUS_P2;
1078
            break;
1079
            }
1080
        }
1081
 
1082
      break;
1083
      }
1084
 
1085
 
1086
    case LAN_OUT:
1087
      {
1088
 
1089
        switch ( parm_1 )
1090
        {
1091
 
1092
          case 0x0C: /* Clear and Reset Queue */
1093
            {
1094
              lan_init_queue( &lan_output_queue );
1095
              printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
1096
              break;
1097
            }
1098
 
1099
          case 0x0D: /* Display Queue */
1100
            {
1101
              printp( "\n                       -- Output Queue --\n" );
1102
              printp( "\n        Head Index: %8X     Tail Index: %8X\n\n    ",
1103
                     (ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index );
1104
 
1105
              for ( i = 0; i < MAX_RS232_CHARS; ++i )
1106
              {
1107
                printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
1108
 
1109
                if ( 15 == (i % 16) )
1110
                {
1111
                  int j;
1112
 
1113
                  printp ( "    " );
1114
                  for ( j = i - 15; j <= i; j++ )
1115
                    {
1116
                      if ( lan_output_queue.buf[ j ] >= ' ' &&
1117
                          lan_output_queue.buf[ j ] < 127 )
1118
                        printp ( "%c", lan_output_queue.buf[ j ] );
1119
                      else
1120
                        printp ( "." );
1121
                    }
1122
                  printp( "\n    " );
1123
                }
1124
 
1125
                else if ( 7 == (i % 8) )
1126
                {
1127
                  printp( " " );
1128
                }
1129
 
1130
              }
1131
 
1132
              printp( "\n" );
1133
 
1134
              break;
1135
            }
1136
 
1137
          case 0x0F: /* Fetch next character in Queue */
1138
            {
1139
              c = lan_next_queue_char( &lan_output_queue );
1140
 
1141
              if ( c )
1142
              {
1143
                printp( "\n\n  Next Character: " );
1144
                if (  0x21 <= c  &&  c <= 0x7F )
1145
                {
1146
                  printp( "%c\n\n", (ULONG) c );
1147
                }
1148
 
1149
                else if ( 0x20 == c )
1150
                {
1151
                  printp( "<space>\n\n" );
1152
                }
1153
 
1154
                else
1155
                {
1156
                  printp( "%02X\n\n", (ULONG) c );
1157
                }
1158
              }
1159
 
1160
              else
1161
              {
1162
                printp( "\n\n  Input Queue EMPTY ...\n\n" );
1163
              }
1164
 
1165
              break;
1166
            }
1167
 
1168
          default:
1169
            {
1170
            printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
1171
            not_done_code = BOGUS_P2;
1172
            break;
1173
            }
1174
        }
1175
 
1176
        break;
1177
      }
1178
 
1179
 
1180
    case LAN_ECHO:
1181
      {
1182
 
1183
        switch ( parm_1 )
1184
        {
1185
 
1186
          case 0x0E:
1187
            {
1188
              test_echo = ENABLED;
1189
              printp( "\n\n  Test echo ENABLED ...\n\n" );
1190
              break;
1191
            }
1192
 
1193
          case 0x0D:
1194
            {
1195
              test_echo = DISABLED;
1196
              printp( "\n\n  Test echo DISABLED ...\n\n" );
1197
              break;
1198
            }
1199
 
1200
          default:
1201
            {
1202
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
1203
              not_done_code = BOGUS_P2;
1204
              break;
1205
            }
1206
        }
1207
 
1208
        break;
1209
      }
1210
 
1211
 
1212
    case LAN_PUTC:
1213
      {
1214
 
1215
        if ( 0x20 < parm_1  &&  parm_1 < 0x7F )
1216
        {
1217
          if ( lan_put_char( (UCHAR) parm_1 ) )
1218
          {
1219
            printp( "\n\n  *** 'lan_put_char' Error ...\n" );
1220
          }
1221
 
1222
          else
1223
          {
1224
            printp( "\n\n  O.K. ...\n" );
1225
          }
1226
 
1227
        }
1228
 
1229
        else
1230
        {
1231
          printp( "\n\n  *** Error  -  character must be in the 0x21-0x7E range ...\n" );
1232
          not_done_code = BOGUS_P2;
1233
        }
1234
 
1235
        break;
1236
      }
1237
 
1238
/***
1239
    case LAN_WPM:
1240
      {
1241
 
1242
        if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) )
1243
        {
1244
          printp( "\n  Write to protected memory FAILED ...\n" );
1245
        }
1246
 
1247
        break;
1248
      }
1249
***/
1250
 
1251
    case 0: /* no argument -- print menu */
1252
      {
1253
        lan_util_menu( );
1254
        break;
1255
      }
1256
 
1257
 
1258
    default:
1259
      {
1260
        parm_2 = 0;  /* to supress compiler warning with 'LAN_WPM' case disabled */
1261
 
1262
        printp( "\n\n  *** SYNTAX Error  -  Invalid P1 ...\n\n" );
1263
        not_done_code = BOGUS_P1;
1264
        break;
1265
      }
1266
 
1267
 
1268
  } /*  End of 'switch ( opcode )'. */
1269
 
1270
 
1271
return( not_done_code );
1272
}
1273
/* end of 'lan_util'
1274
 *===========================================================================*/
1275
 
1276
 
1277
                  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
1278
                  *                                     *
1279
                  *         Local Module Functions      *
1280
                  *                                     *
1281
                  *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1282
 
1283
/*-----------------------------------------------------------------------------
1284
 *
1285
 * FUNCTION NAME:   lan_reset
1286
 *
1287
 * DESCRIPTION:     Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the
1288
 *                  Shared Control 1 area.
1289
 *
1290
 *                             1 _|       ______
1291
 *                                |      |      |
1292
 *                          Bit   |      |      |
1293
 *                                |      |      |
1294
 *                             0 _|______|      |______
1295
 *                                |---------------------> t
1296
 *
1297
 * RETURN VALUE:    None.
1298
 *
1299
 * USED GLOBAL VARIABLES:
1300
 *
1301
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1302
 *
1303
 * NOTES:           H/W configuration requires that a byte in the shared
1304
 *                  control 1 area must be read before being written.
1305
 *
1306
 *---------------------------------------------------------------------------*/
1307
 
1308
static  void    lan_reset( void )
1309
 
1310
{
1311
 
1312
  while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
1313
  {
1314
    *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
1315
  }
1316
 
1317
  while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) )
1318
  {
1319
    *P_RST_LAN_UART_REG |= M_RST_LAN_UART;      /* 1 */
1320
  }
1321
 
1322
  while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
1323
  {
1324
    *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
1325
  }
1326
 
1327
}
1328
/* end of 'lan_reset'
1329
 *===========================================================================*/
1330
 
1331
 
1332
/*-----------------------------------------------------------------------------
1333
 *
1334
 * FUNCTION NAME:   lan_configure
1335
 *
1336
 *
1337
 * DESCRIPTION:
1338
 *
1339
 *
1340
 * RETURN VALUE:
1341
 *
1342
 *
1343
 * USED GLOBAL VARIABLES:
1344
 *
1345
 *
1346
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1347
 *
1348
 *
1349
 * NOTES:
1350
 *
1351
 *
1352
 *
1353
 *---------------------------------------------------------------------------*/
1354
 
1355
static  void    lan_configure( void )
1356
 
1357
{
1358
 
1359
  *P_LAN_CR = UART_CR_RESET_MR_PTR;       /*  Points to MR1.        */
1360
  *P_LAN_CR = UART_CR_RESET_RVCR;         /*  Receiver disabled.    */
1361
  *P_LAN_CR = UART_CR_RESET_XMTR;         /*  Transmitter disabled. */
1362
  *P_LAN_CR = UART_CR_RESET_ERROR_STATUS;
1363
  *P_LAN_CR = UART_CR_RESET_BRK_CHG_INT;
1364
 
1365
  *P_LAN_MR1 = DEFAULT_LAN_MR1;
1366
  *P_LAN_MR2 = DEFAULT_LAN_MR2;
1367
 
1368
  *P_LAN_ACR = DEFAULT_LAN_ACR;
1369
 
1370
  *P_LAN_CSR = UART_CSR_BR_9600;
1371
  baud_rate_idx = 2;
1372
 
1373
  *P_LAN_CTUR = DEFAULT_LAN_CTUR;
1374
  *P_LAN_CTLR = DEFAULT_LAN_CTLR;
1375
 
1376
  *P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
1377
 
1378
  lan_shadow_imr = UART_IMR_RxRDY;        /*  Enable only 'RxRDY' interrupt from UART. */
1379
  *P_LAN_IMR = lan_shadow_imr;
1380
 
1381
  tx_by_intr = 0;
1382
  tx_by_poll = 0;
1383
 
1384
  return;
1385
}
1386
/* end of 'lan_configure'
1387
 *===========================================================================*/
1388
 
1389
 
1390
/*-----------------------------------------------------------------------------
1391
 *
1392
 * FUNCTION NAME:   lan_init_queue
1393
 *
1394
 * DESCRIPTION:
1395
 *
1396
 * RETURN VALUE:    None.
1397
 *
1398
 * USED GLOBAL VARIABLES:
1399
 *
1400
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1401
 *
1402
 * NOTES:
1403
 *
1404
 *---------------------------------------------------------------------------*/
1405
 
1406
static  void    lan_init_queue( T_RS232_QUEUE *p_queue )
1407
 
1408
{
1409
  long i;
1410
 
1411
    /*
1412
    *   We set "head" equal to "tail" implying the queue is empty,
1413
    *   BUT the "head" and "tail" should each point to valid queue
1414
    *   positions.
1415
    */
1416
 
1417
  p_queue->head_index = 0;
1418
  p_queue->tail_index = 0;
1419
 
1420
  p_queue->overflows = 0;
1421
 
1422
  p_queue->gdb_packet_start = -1;
1423
  p_queue->gdb_packet_end   = -1;
1424
 
1425
  p_queue->gdb_packet_csum1 = -1;
1426
  p_queue->gdb_packet_csum2 = -1;
1427
 
1428
  for ( i = 0; i < MAX_RS232_CHARS; ++i )
1429
  {
1430
    p_queue->buf[ i ] = 0;
1431
  }
1432
 
1433
  return;
1434
}
1435
/* end of 'lan_init_queue'
1436
 *===========================================================================*/
1437
 
1438
 
1439
/*-----------------------------------------------------------------------------
1440
 *
1441
 * FUNCTION NAME:   lan_add_to_queue
1442
 *
1443
 *
1444
 * DESCRIPTION:     Adds the specified character to the tail of the
1445
 *                  specified queue.  Observes "oldest thrown on floor"
1446
 *                  rule (i.e. the queue is allowed to "wrap" and the
1447
 *                  input character is unconditionally placed at the
1448
 *                  tail of the queue.
1449
 *
1450
 *
1451
 * RETURN VALUE:    None.
1452
 *
1453
 *
1454
 * USED GLOBAL VARIABLES:
1455
 *
1456
 *
1457
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1458
 *
1459
 *
1460
 * NOTES:
1461
 *
1462
 *
1463
 *---------------------------------------------------------------------------*/
1464
 
1465
static  void    lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
1466
 
1467
{
1468
 
1469
  if ( p_queue )    /*  Sanity check. */
1470
  {
1471
 
1472
    if ( c & 0x000000FF )   /*  We don't allow NULL characters to be added to a queue.  */
1473
    {
1474
        /*  Insert the new character at the tail of the queue.  */
1475
 
1476
      p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
1477
 
1478
        /*  Increment the tail index. */
1479
 
1480
      if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
1481
      {
1482
        p_queue->tail_index = 0;
1483
      }
1484
 
1485
        /*  Check for wrapping (i.e. overflow). */
1486
 
1487
      if ( p_queue->head_index == p_queue->tail_index )
1488
      {
1489
          /*  If the tail has caught up to the head record the overflow . . . */
1490
 
1491
        ++(p_queue->overflows);
1492
 
1493
          /*  . . . then increment the head index.  */
1494
 
1495
        if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
1496
        {
1497
          p_queue->head_index = 0;
1498
        }
1499
 
1500
      }
1501
 
1502
    } /*  End of 'if ( c & 0x000000FF )'. */
1503
 
1504
  } /*  End of 'if ( p_queue )'.  */
1505
 
1506
 
1507
  return;
1508
}
1509
/* end of 'lan_add_to_queue'
1510
 *===========================================================================*/
1511
 
1512
 
1513
/*-----------------------------------------------------------------------------
1514
 *
1515
 * FUNCTION NAME:   lan_next_queue_char
1516
 *
1517
 * DESCRIPTION:
1518
 *
1519
 * RETURN VALUE:
1520
 *
1521
 * USED GLOBAL VARIABLES:
1522
 *
1523
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
1524
 *
1525
 * NOTES:
1526
 *
1527
 *---------------------------------------------------------------------------*/
1528
 
1529
static  UCHAR   lan_next_queue_char( T_RS232_QUEUE *p_queue )
1530
 
1531
{
1532
  UCHAR   c;
1533
 
1534
 
1535
  c = 0;
1536
 
1537
  if ( p_queue )
1538
  {
1539
 
1540
    if ( p_queue->head_index != p_queue->tail_index )
1541
    {
1542
        /*  Return the 'oldest' character in the queue. */
1543
 
1544
      c = p_queue->buf[ p_queue->head_index ];
1545
 
1546
        /*  Increment the head index. */
1547
 
1548
      if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
1549
      {
1550
        p_queue->head_index = 0;
1551
      }
1552
 
1553
    }
1554
 
1555
  } /*  End of 'if ( p_queue )'.  */
1556
 
1557
 
1558
  return( c );
1559
}
1560
 
1561
/* end of 'lan_next_queue_char'
1562
 *===========================================================================*/
1563
 
1564
 
1565
/*-----------------------------------------------------------------------------
1566
 *
1567
 * FUNCTION NAME:   lan_util_menu
1568
 *
1569
 * DESCRIPTION:     Prints out a brief help on the LAN UART control utility.
1570
 *
1571
 * RETURN VALUE:    None.
1572
 *
1573
 * USED GLOBAL VARIABLES: None.
1574
 *
1575
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None.
1576
 *
1577
 * NOTES: None.
1578
 *
1579
 *---------------------------------------------------------------------------*/
1580
 
1581
static  void    lan_util_menu( void )
1582
 
1583
{
1584
 
1585
  /*
1586
   * Multiply calling printp() below is made due to the limitations
1587
   * of printp(), incapable of handling long formatting constants:
1588
   */
1589
 
1590
 printp( "\n               -- Options --\n\n" );
1591
 
1592
  printp( "    %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE );
1593
  printp( "    %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE );
1594
  printp( "    %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE );
1595
  printp( "    %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE );
1596
  printp( "    %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE );
1597
  printp( "    %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE );
1598
  printp( "    %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE );
1599
  printp( "    %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE );
1600
 
1601
  printp( "    %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );
1602
 
1603
/***
1604
  printp( "    %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );
1605
***/
1606
 
1607
  printp( "    <rate>:  4800  <mode>:  E - enable   <action>:  C - clear/reset\n" );
1608
  printp( "             9600           D - disable             D - display\n" );
1609
  printp( "            19200                                   F - fetch next char\n" );
1610
  printp( "            38400\n" );
1611
}
1612
/* end of 'lan_util_menu'
1613
 *===========================================================================*/
1614
 
1615
 
1616
/* Thu Feb  5 17:14:41 EST 1998  CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */
1617
 
1618
 
1619
static  long    get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
1620
 
1621
{
1622
 
1623
  /* Now to detect when we've got a gdb packet... */
1624
 
1625
  if ( '$' == c ) { /* char marks beginning of a packet */
1626
 
1627
      if ( -1 != p_input_q->gdb_packet_start ||
1628
           -1 != p_input_q->gdb_packet_end   ||
1629
           -1 != p_input_q->gdb_packet_csum1 ||
1630
           -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
1631
 
1632
        /* NEW: Actually, this probably means that we muffed a packet,
1633
           and GDB has already resent it.  The thing to do now is to
1634
           throw away the one we WERE working on, but immediately start
1635
           accepting the new one.  Don't NAK, or GDB will have to try
1636
           and send it yet a third time!  */
1637
 
1638
          /*NACK_PKT( );*/    /*<ETHERNET>*/
1639
          discard_packet( );                    /* throw away old packet */
1640
          lan_add_to_queue ('$', p_input_q);    /* put the new "$" back in */
1641
          return 0;
1642
      } else {          /* match new "$" */
1643
        p_input_q->gdb_packet_start = p_input_q->tail_index;
1644
        p_input_q->gdb_packet_end =
1645
          p_input_q->gdb_packet_csum1 =
1646
            p_input_q->gdb_packet_csum2 = -1;
1647
      }
1648
    } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */
1649
 
1650
      if ( -1 == p_input_q->gdb_packet_start ||
1651
           -1 != p_input_q->gdb_packet_end   ||
1652
           -1 != p_input_q->gdb_packet_csum1 ||
1653
           -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
1654
 
1655
          /* Garbled packet.  Discard, but do not NAK.  */
1656
 
1657
          /*NACK_PKT( );*/    /*<ETHERNET>*/
1658
          discard_packet( );
1659
          return -1;
1660
      }
1661
      p_input_q->gdb_packet_end = p_input_q->tail_index;
1662
      p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1;
1663
 
1664
  } else if ( -1 != p_input_q->gdb_packet_start &&
1665
              -1 != p_input_q->gdb_packet_end) {
1666
 
1667
    if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */
1668
 
1669
      if ( -1 == p_input_q->gdb_packet_csum1 &&
1670
           LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) ==
1671
           p_input_q->tail_index ) {
1672
 
1673
        /* first checksum digit */
1674
 
1675
        p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
1676
        p_input_q->gdb_packet_csum2 = -1;
1677
 
1678
      } else if ( -1 == p_input_q->gdb_packet_csum2 &&
1679
                  LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) ==
1680
                  p_input_q->tail_index ) {
1681
 
1682
        /* second checksum digit: packet is complete! */
1683
 
1684
        p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
1685
        getpacket();    /* got a packet -- extract it */
1686
 
1687
      } else { /* probably can't happen (um... three hex digits?) */
1688
 
1689
        /* PROTOCOL ERROR */
1690
        /* Not sure how this can happen, but ...
1691
           discard it, but do not NAK it.  */
1692
        /*NACK_PKT( );*/    /*<ETHERNET>*/
1693
        discard_packet( );
1694
        return -1;
1695
      }
1696
 
1697
    } else { /* '#' followed by non-hex char */
1698
 
1699
      /* PROTOCOL ERROR */
1700
      /* Bad packet -- discard but do not NAK */
1701
      /*NACK_PKT( );*/    /*<ETHERNET>*/
1702
      discard_packet( );
1703
      return -1;
1704
    }
1705
  }
1706
 
1707
  return 0;
1708
}
1709
 
1710
 
1711
 
1712
 
1713
#ifdef    STANDALONE
1714
 
1715
/* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone
1716
   stand-alone                                                 stand-alone
1717
   stand-alone Enable stand-alone build, for ease of debugging stand-alone
1718
   stand-alone                                                 stand-alone
1719
   stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */
1720
 
1721
long write_to_protected_mem (addr, word)
1722
     void *addr;
1723
     unsigned short word;
1724
{
1725
  return 0;
1726
}
1727
 
1728
 
1729
char dummy_memory[0x4000];
1730
 
1731
int main ( void )
1732
{
1733
  long c;
1734
 
1735
  lan_init_queue( &lan_input_queue );
1736
  printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) );
1737
  printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory);
1738
  while ( (c = getc( stdin ) ) != EOF )
1739
    {
1740
      if ( c == '\\' )  /* escape char */
1741
        break;
1742
 
1743
      lan_add_to_queue( c, &lan_input_queue );
1744
      get_gdb_input (c, &lan_input_queue);
1745
      fflush( stdout );
1746
    }
1747
 
1748
  printf( "Goodbye!\n" );
1749
  exit( 0 );
1750
}
1751
 
1752
#define SRAM_START      ((void *) (&dummy_memory[0] + 0x00000000))
1753
#define SRAM_END        ((void *) (&dummy_memory[0] + 0x00000400))
1754
 
1755
#define RO_AREA_START   ((void *) (&dummy_memory[0] + 0x00000100))
1756
#define RO_AREA_END     ((void *) (&dummy_memory[0] + 0x00000300))
1757
 
1758
#define NVD_START       ((void *) (&dummy_memory[0] + 0x00003000))
1759
#define NVD_END         ((void *) (&dummy_memory[0] + 0x00003100))
1760
 
1761
#else   /* normal stub (not stand-alone) */
1762
 
1763
#define SRAM_START              ((void *) 0x00000000)
1764
#define SRAM_END                ((void *) 0x00400000)
1765
 
1766
#define RO_AREA_START           ((void *) 0x00100000)
1767
#define RO_AREA_END             ((void *) 0x00300000)
1768
 
1769
#define NVD_START               ((void *) 0x03000000)
1770
#define NVD_END                 ((void *) 0x03100000)
1771
 
1772
#endif /* STANDALONE */
1773
 
1774
 
1775
 
1776
 
1777
/* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb
1778
   gdb                                                                 gdb
1779
   gdb                Here begins the gdb stub section.                gdb
1780
   gdb          The following functions were added by Cygnus,          gdb
1781
   gdb             to make this thing act like a gdb stub.             gdb
1782
   gdb                                                                 gdb
1783
   gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb */
1784
 
1785
 
1786
/* ------------------- global defines and data decl's -------------------- */
1787
 
1788
#define hexchars        "0123456789abcdef"
1789
 
1790
/* there are 180 bytes of registers on a 68020 w/68881      */
1791
/* many of the fpa registers are 12 byte (96 bit) registers */
1792
#define NUMREGBYTES          180
1793
#define NUMREGS              29
1794
#define REGISTER_BYTE(regno) regno
1795
 
1796
enum regnames { D0, D1, D2, D3, D4, D5, D6, D7,
1797
                A0, A1, A2, A3, A4, A5, A6, A7,
1798
                PS, PC,
1799
                FP0, FP1,
1800
                FP2, FP3,
1801
                FP4, FP5,
1802
                FP6, FP7,
1803
                FPCONTROL, FPSTATUS, FPIADDR
1804
              };
1805
 
1806
unsigned long registers[NUMREGBYTES/4];
1807
 
1808
static long remote_debug;
1809
 
1810
#define BUFMAX                MAX_IO_BUF_SIZE
1811
static char inbuffer[BUFMAX], outbuffer[BUFMAX];
1812
static char spare_buffer[BUFMAX];
1813
 
1814
 
1815
struct stub_trace_frame
1816
{
1817
  int                    valid;
1818
  unsigned long          frame_id;
1819
  unsigned long          tdp_id;
1820
  FRAME_DEF             *frame_data;
1821
  COLLECTION_FORMAT_DEF *format;
1822
  unsigned long          traceregs[NUMREGBYTES/4];
1823
  unsigned char         *stack_data;
1824
  unsigned char         *memrange_data;
1825
} curframe;
1826
 
1827
/* -------------------      function prototypes       -------------------- */
1828
 
1829
void handle_request ( char * );
1830
 
1831
/* -------------------         Implementation         -------------------- */
1832
 
1833
static void
1834
discard_packet( void )
1835
{
1836
  lan_input_queue.head_index = lan_input_queue.tail_index;
1837
 
1838
  lan_input_queue.gdb_packet_start =
1839
    lan_input_queue.gdb_packet_end   =
1840
      lan_input_queue.gdb_packet_csum1 =
1841
        lan_input_queue.gdb_packet_csum2 = -1;
1842
}
1843
 
1844
/* Utility function: convert an ASCII isxdigit to a hex nybble */
1845
 
1846
static long
1847
hex( char ch )
1848
{
1849
  if ( (ch >= 'A') && (ch <= 'F') )
1850
    return ch - 'A' + 10;
1851
  if ( (ch >= 'a') && (ch <= 'f') )
1852
    return ch - 'a' + 10;
1853
  if ( (ch >= '0') && (ch <= '9') )
1854
    return ch - '0';
1855
  return -1;
1856
}
1857
 
1858
static void
1859
getpacket( void )
1860
{
1861
  unsigned char our_checksum, their_checksum;
1862
  char *copy = inbuffer;
1863
  unsigned char c;
1864
 
1865
  our_checksum = 0;
1866
 
1867
  /* first find the '$' */
1868
  while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
1869
    if (c == 0)                 /* ??? Protocol error? (paranoia) */
1870
      {
1871
          /* PROTOCOL ERROR (missing '$') */
1872
        /*NACK_PKT( );*/    /*<ETHERNET>*/
1873
        return;
1874
      }
1875
 
1876
  /* Now copy the message (up to the '#') */
1877
  for (c = lan_next_queue_char ( &lan_input_queue );    /* skip  the   '$' */
1878
       c != 0 && c != '#';              /* stop at the '#' */
1879
       c = lan_next_queue_char ( &lan_input_queue ))
1880
    {
1881
      *copy++ = c;
1882
      our_checksum += c;
1883
    }
1884
  *copy++ = '\0';               /* terminate the copy */
1885
 
1886
  if (c == 0)                   /* ??? Protocol error? (paranoia) */
1887
    {
1888
        /* PROTOCOL ERROR (missing '#') */
1889
      /*NACK_PKT( );*/    /*<ETHERNET>*/
1890
      return;
1891
    }
1892
  their_checksum  = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
1893
  their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
1894
 
1895
  /* Now reset the queue packet-recognition bits */
1896
  discard_packet( );
1897
 
1898
  if ( remote_debug ||
1899
      our_checksum == their_checksum )
1900
    {
1901
      ACK_PKT( );      /* good packet */
1902
      /* Parse and process the packet */
1903
      handle_request( inbuffer );
1904
    }
1905
  else
1906
      /* PROTOCOL ERROR (bad check sum) */
1907
    NACK_PKT( );
1908
}
1909
 
1910
/* EMC will provide a better implementation
1911
   (perhaps just of LAN_PUT_CHAR) that does not block.
1912
   For now, this works.  */
1913
 
1914
 
1915
static void
1916
putpacket( char *str )
1917
{
1918
  unsigned char checksum;
1919
 
1920
  /* '$'<packet>'#'<checksum> */
1921
 
1922
  if ( VIA_ETHERNET == gdb_host_comm )
1923
  {
1924
    char  *p_out;
1925
    long  length;
1926
 
1927
    p_out  = eth_outbuffer;
1928
    length = 0;
1929
 
1930
 
1931
    if ( YES == gdb_cat_ack )
1932
    {
1933
      *p_out++ = '+';
1934
      ++length;
1935
    }
1936
 
1937
    gdb_cat_ack = NO;
1938
 
1939
 
1940
    *p_out++ = '$';
1941
    ++length;
1942
 
1943
    checksum = 0;
1944
 
1945
    while ( *str )
1946
    {
1947
      *p_out++ = *str;
1948
      ++length;
1949
      checksum += *str++;
1950
    }
1951
 
1952
    *p_out++ = '#';
1953
    *p_out++ = hexchars[checksum >> 4];
1954
    *p_out = hexchars[checksum % 16];
1955
    length += 3;
1956
 
1957
    eth_to_gdb( (UCHAR *) eth_outbuffer, length );
1958
  }
1959
 
1960
  else
1961
  {
1962
 
1963
      /* via RS-232 */
1964
    do {
1965
      LAN_PUT_CHAR( '$' );
1966
      checksum = 0;
1967
 
1968
      while ( *str )
1969
        {
1970
          LAN_PUT_CHAR( *str );
1971
          checksum += *str++;
1972
        }
1973
 
1974
      LAN_PUT_CHAR( '#' );
1975
      LAN_PUT_CHAR( hexchars[checksum >> 4] );
1976
      LAN_PUT_CHAR( hexchars[checksum % 16] );
1977
    } while ( 0 /* get_debug_char( ) != '+' */ );
1978
    /* XXX FIXME: not waiting for the ack. */
1979
 
1980
  }
1981
 
1982
}
1983
 
1984
 
1985
/*-----------------------------------------------------------------------------
1986
 *
1987
 * FUNCTION NAME:   gdb_get_eth_input
1988
 *
1989
 *
1990
 * DESCRIPTION:
1991
 *
1992
 *
1993
 * RETURN VALUE:    None.
1994
 *
1995
 *
1996
 * USED GLOBAL VARIABLES:
1997
 *
1998
 *
1999
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
2000
 *
2001
 *
2002
 * NOTES:
2003
 *
2004
 *
2005
 *---------------------------------------------------------------------------*/
2006
 
2007
void    gdb_get_eth_input( unsigned char *buf, long length )
2008
 
2009
{
2010
 
2011
  gdb_host_comm = VIA_ETHERNET;
2012
 
2013
  for ( ; 0 < length; ++buf, --length)
2014
  {
2015
 
2016
    if ( *buf == CONTROL_C )
2017
    {
2018
        /* can't stop the target, but we can tell gdb to stop waiting... */
2019
      discard_packet( );
2020
      putpacket( "S03" );       /* send back SIGINT to the debugger */
2021
    }
2022
 
2023
    else
2024
    {
2025
      lan_add_to_queue( (long) *buf, &lan_input_queue );
2026
      get_gdb_input( (long) *buf, &lan_input_queue );
2027
    }
2028
 
2029
  }
2030
 
2031
 
2032
  return;
2033
}
2034
/* end of 'gdb_get_eth_input'
2035
 *===========================================================================*/
2036
 
2037
 
2038
 
2039
 
2040
/* STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT
2041
   Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
2042
 
2043
   Dear reader:
2044
       This code is based on the premise that if GDB receives a packet
2045
   from the stub that begins with the character CAPITAL-OH, GDB will
2046
   echo the rest of the packet to GDB's console / stdout.  This gives
2047
   the stub a way to send a message directly to the user.  In practice,
2048
   (as currently implemented), GDB will only accept such a packet when
2049
   it believes the target to be running (ie. when you say STEP or
2050
   CONTINUE); at other times it does not expect it.  This will probably
2051
   change as a side effect of the "asynchronous" behavior.
2052
 
2053
   Functions: gdb_putchar(char ch)
2054
              gdb_write(char *str, int len)
2055
              gdb_puts(char *str)
2056
              gdb_error(char *format, char *parm)
2057
 */
2058
 
2059
#if 0 /* avoid compiler warning while this is not used */
2060
 
2061
/* Function: gdb_putchar(int)
2062
   Make gdb write a char to stdout.
2063
   Returns: the char */
2064
 
2065
static int
2066
gdb_putchar( long ch )
2067
{
2068
  char buf[4];
2069
 
2070
  buf[0] = 'O';
2071
  buf[1] = hexchars[ch >> 4];
2072
  buf[2] = hexchars[ch & 0x0F];
2073
  buf[3] = 0;
2074
  putpacket( buf );
2075
  return ch;
2076
}
2077
#endif
2078
 
2079
/* Function: gdb_write(char *, int)
2080
   Make gdb write n bytes to stdout (not assumed to be null-terminated).
2081
   Returns: number of bytes written */
2082
 
2083
static int
2084
gdb_write( char *data, long len )
2085
{
2086
  char *buf, *cpy;
2087
  long i;
2088
 
2089
  buf = outbuffer;
2090
  buf[0] = 'O';
2091
  i = 0;
2092
  while ( i < len )
2093
    {
2094
      for ( cpy = buf+1;
2095
           i < len && cpy < buf + BUFMAX - 3;
2096
           i++ )
2097
        {
2098
          *cpy++ = hexchars[data[i] >> 4];
2099
          *cpy++ = hexchars[data[i] & 0x0F];
2100
        }
2101
      *cpy = 0;
2102
      putpacket( buf );
2103
    }
2104
  return len;
2105
}
2106
 
2107
/* Function: gdb_puts(char *)
2108
   Make gdb write a null-terminated string to stdout.
2109
   Returns: the length of the string */
2110
 
2111
static int
2112
gdb_puts( char *str )
2113
{
2114
  return gdb_write( str, strlen( str ) );
2115
}
2116
 
2117
/* Function: gdb_error(char *, char *)
2118
   Send an error message to gdb's stdout.
2119
   First string may have 1 (one) optional "%s" in it, which
2120
   will cause the optional second string to be inserted.  */
2121
 
2122
#if 0
2123
static void
2124
gdb_error( char *format, char *parm )
2125
{
2126
  static char buf[400];
2127
  char *cpy;
2128
  long len;
2129
 
2130
  if ( remote_debug )
2131
    {
2132
      if ( format && *format )
2133
        len = strlen( format );
2134
      else
2135
        return;             /* empty input */
2136
 
2137
      if ( parm && *parm )
2138
        len += strlen( parm );
2139
 
2140
      for ( cpy = buf; *format; )
2141
        {
2142
          if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */
2143
            {
2144
              format += 2;          /* advance two chars instead of just one */
2145
              while ( parm && *parm )
2146
                *cpy++ = *parm++;
2147
            }
2148
          else
2149
            *cpy++ = *format++;
2150
        }
2151
      *cpy = '\0';
2152
      gdb_puts( buf );
2153
    }
2154
}
2155
#endif
2156
 
2157
static void gdb_note (char *, int);
2158
static int  error_ret (int, char *, int);
2159
 
2160
static unsigned long
2161
elinum_to_index (unsigned long elinum)
2162
{
2163
  if ((elinum & 0xf0) == 0xd0)
2164
    return (elinum & 0x0f);
2165
  else if ((elinum & 0xf0) == 0xa0)
2166
    return (elinum & 0x0f) + 8;
2167
  else
2168
    return -1;
2169
}
2170
 
2171
static long
2172
index_to_elinum (unsigned long index)
2173
{
2174
  if (index <= 7)
2175
    return index + 0xd0;
2176
  else if (index <= 15)
2177
    return (index - 8) + 0xa0;
2178
  else
2179
    return -1;
2180
}
2181
 
2182
 
2183
/*
2184
  READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
2185
 
2186
  The following code pertains to reading memory from the target.
2187
  Some sort of exception handling should be added to make it safe.
2188
 
2189
  READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
2190
 
2191
  Safe Memory Access:
2192
 
2193
  All reads and writes into the application's memory will pass thru
2194
  get_uchar() or set_uchar(), which check whether accessing their
2195
  argument is legal before actual access (thus avoiding a bus error).
2196
 
2197
  */
2198
 
2199
enum { SUCCESS = 0, FAIL = -1 };
2200
 
2201
#if 0
2202
static long get_uchar ( const unsigned char * );
2203
#endif
2204
static long set_uchar ( unsigned char *, unsigned char );
2205
static long read_access_violation ( const void * );
2206
static long write_access_violation ( const void * );
2207
static long read_access_range(const void *, long);
2208
static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *);
2209
 
2210
static int
2211
dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
2212
{
2213
  if (src)
2214
    sprintp (spare_buffer,
2215
             "'%s' returned DTC error '%s'.\n", src, get_err_text (code));
2216
  else
2217
    sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code));
2218
 
2219
  gdb_puts (spare_buffer);
2220
  return ret;
2221
}
2222
 
2223
 
2224
#if 0
2225
/* I think this function is unnecessary since the introduction of
2226
   adbg_find_memory_addr_in_frame.  */
2227
 
2228
/* Return the number of expressions in the format associated with a
2229
   given trace frame.  */
2230
static int
2231
count_frame_exprs (FRAME_DEF *frame)
2232
{
2233
  CFD *format;
2234
  T_EXPR *expr;
2235
  int num_exprs;
2236
 
2237
  /* Get the format from the frame.  */
2238
  get_frame_format_pointer (frame, &format);
2239
 
2240
  /* Walk the linked list of expressions, and count the number of
2241
     expressions we find there.  */
2242
  num_exprs = 0;
2243
  for (expr = format->p_cfd_expr; expr; expr = expr->next)
2244
    num_exprs++;
2245
 
2246
  return num_exprs;
2247
}
2248
#endif
2249
 
2250
#if 0
2251
/* Function: get_frame_addr
2252
 *
2253
 * Description: If the input memory address was collected in the
2254
 *     current trace frame, then lookup and return the address
2255
 *     from within the trace buffer from which the collected byte
2256
 * may be retrieved.  Else return -1.  */
2257
 
2258
unsigned char *
2259
get_frame_addr ( const unsigned char *addr )
2260
{
2261
  unsigned char *base, *regs, *stack, *mem;
2262
  CFD *dummy;
2263
  DTC_RESPONSE ret;
2264
 
2265
  /* first, see if addr is on the saved piece of stack for curframe */
2266
  if (curframe.format->stack_size > 0 &&
2267
      (base = (unsigned char *) curframe.traceregs[A7]) <= addr  &&
2268
      addr < base + curframe.format->stack_size)
2269
    {
2270
      gdb_puts("STUB: get_frame_addr: call get_addr_to_frame_regs_stack_mem\n");
2271
      if ((ret = get_addr_to_frame_regs_stack_mem (curframe.frame_data,
2272
                                                   &dummy,
2273
                                                   (void *) &regs,
2274
                                                   (void *) &stack,
2275
                                                   (void *) &mem))
2276
          != OK_TARGET_RESPONSE)
2277
        return (void *) dtc_error_ret (-1,
2278
                                       "get_addr_to_frame_regs_stack_mem",
2279
                                       ret);
2280
      else
2281
        return stack + (addr - base);
2282
    }
2283
 
2284
  /* Next, try to find addr in the current frame's expression-
2285
     collected memory blocks.  I'm sure this is at least quadradic in
2286
     time.  */
2287
  {
2288
    int num_exprs = count_frame_exprs (curframe.frame_data);
2289
    int expr, block;
2290
 
2291
    /* Try each expression in turn.  */
2292
    for (expr = 0; expr < num_exprs; expr++)
2293
      {
2294
        for (block = 0; ; block++)
2295
          {
2296
            T_EXPR_DATA *data;
2297
            if (adbg_get_expr_data (curframe.frame_data,
2298
                                    'x', expr, block,
2299
                                    &data)
2300
                != OK_TARGET_RESPONSE)
2301
              break;
2302
            else if ((unsigned char *) data->address <= addr
2303
                     && addr < ((unsigned char *) data->address + data->size))
2304
              {
2305
                /* We have found the right block; is it valid data?
2306
                   Upper-case stamps mean bad data.  */
2307
                if ('A' <= data->stamp && data->stamp <= 'Z')
2308
                  {
2309
                    gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
2310
                    return (unsigned char *) -1;
2311
                  }
2312
                else
2313
                  {
2314
                    if (remote_debug > 1)
2315
                      {
2316
                        sprintp(spare_buffer,
2317
                                "STUB: get_frame_addr: got it [%x,%x)\n",
2318
                                data->address, data->address + data->size);
2319
                        gdb_puts(spare_buffer);
2320
                      }
2321
 
2322
                    return (((unsigned char *) &data->data)
2323
                            + (addr - (unsigned char *) data->address));
2324
                  }
2325
              }
2326
          }
2327
      }
2328
  }
2329
 
2330
  /* not found, return error */
2331
  return (unsigned char *) -1;
2332
}
2333
 
2334
/*============================================================*/
2335
 
2336
static long get_uchar ( const unsigned char * addr )
2337
{
2338
  unsigned char *frame_addr;
2339
 
2340
  if ( read_access_violation ( addr ) )
2341
    return ( -1 ); /* Access error */
2342
 
2343
  if (curframe.valid)   /* if debugging a trace frame? */
2344
    {
2345
      /* If the requested address was collected in the current frame,
2346
       * then fetch and return the data from the trace buffer.
2347
       */
2348
      if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1)
2349
        return ( *frame_addr );
2350
      /* If the requested address is in the Code Section,
2351
       * let's be magnanimous and read it anyway (else we shall
2352
       * not be able to disassemble, find function prologues, etc.)
2353
       */
2354
      else if (CS_CODE_START <= (unsigned long) addr &&
2355
               (unsigned long) addr < CS_CODE_START + CS_CODE_SIZE)
2356
        return (*addr);
2357
      else
2358
        return ( -1 );  /* "Access error" (the data was not collected) */
2359
    }
2360
  else
2361
    /* Not debugging a trace frame, read the data from live memory. */
2362
    return ( *addr ); /* Meaningful result >= 0 */
2363
}
2364
#endif
2365
 
2366
/*============================================================*/
2367
 
2368
static long set_uchar ( unsigned char * addr, unsigned char val )
2369
{
2370
  long check_result = write_access_violation ( addr );
2371
 
2372
  if ( check_result != 0L )
2373
    return ( check_result ); /* Access error */
2374
 
2375
  return ( *addr = val );    /* Successful writing */
2376
}
2377
 
2378
/*============================================================*/
2379
 
2380
/*
2381
 * Function read_access_violation() below returns TRUE if dereferencing
2382
 * its argument for reading would cause a bus error - and FALSE otherwise:
2383
 */
2384
 
2385
static long read_access_violation ( const void * addr )
2386
{
2387
  return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
2388
           ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) );
2389
}
2390
 
2391
/*============================================================*/
2392
 
2393
/*
2394
 * Function write_access_violation() below returns zero if dereferencing
2395
 * its argument for writing is safe, -1 on a soft error (the argument
2396
 * falls into the write-protected area), -2 on a hard error (the argument
2397
 * points to a non-existent memory location). In other words, it returns
2398
 * FALSE when no bus error is expected - and an error code otherwise:
2399
 */
2400
 
2401
static long write_access_violation ( const void * addr )
2402
{
2403
  /*
2404
   * The boundaries of the write-protected area have to be received via
2405
   * an API provided in the Symmetrix core code. For now, these limits
2406
   * are hard-coded:
2407
   */
2408
 
2409
  if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
2410
    return ( -1 ); /* soft error */
2411
 
2412
  if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
2413
       ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) )
2414
    return ( -2 ); /* hard error */
2415
 
2416
  return ( 0 );
2417
}
2418
 
2419
 
2420
/* read_access_range is like read_access_violation,
2421
   but returns the number of bytes we can read w/o faulting.
2422
   that is, it checks an address range and tells us what portion
2423
   (if any) of the prefix is safe to read without a bus error */
2424
static long
2425
read_access_range(const void *addr, long count)
2426
{
2427
  if ((addr >= SRAM_START) && (addr < SRAM_END))
2428
    {
2429
      if ((char *)addr + count < (char *)SRAM_END)
2430
        return (count);
2431
      else
2432
        return ((char *)SRAM_END - (char *)addr);
2433
    }
2434
  else if (((char *)addr >= (char *)NVD_START) &&
2435
           ((char *)addr < (char *)NVD_END))
2436
    {
2437
      if ((char *)addr + count < (char *)NVD_END)
2438
        return (count);
2439
      else
2440
        return ((char *)NVD_END - (char *)addr);
2441
    }
2442
  else
2443
    return (0);
2444
}
2445
 
2446
/* Convert the memory pointed to by mem into hex, placing result in buf.
2447
   Return SUCCESS or FAIL.
2448
   If MAY_FAULT is non-zero, then we should return FAIL in response to
2449
   a fault; if zero treat a fault like any other fault in the stub.  */
2450
 
2451
static long
2452
mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
2453
{
2454
  long ndx;
2455
  long ndx2;
2456
  long ch;
2457
  long incr;
2458
  unsigned char *location;
2459
  DTC_RESPONSE status;
2460
 
2461
  if (may_fault)
2462
    {
2463
      for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
2464
        {
2465
          status = find_memory(mem, count - ndx, &location, &incr);
2466
 
2467
          if (status == OK_TARGET_RESPONSE)
2468
            {
2469
              if (incr > 0)
2470
                {
2471
                  for (ndx2 = 0; ndx2 < incr; ndx2++)
2472
                    {
2473
                      ch = *location++;
2474
                      *buf++ = hexchars[ch >> 4];
2475
                      *buf++ = hexchars[ch & 0xf];
2476
                    }
2477
                  mem += incr;
2478
                }
2479
              else if (incr <= 0) /* should never happen */
2480
                {
2481
                  *buf = 0;
2482
                  return (0);
2483
                }
2484
            }
2485
          else if (status == NOT_FOUND_TARGET_RESPONSE)
2486
            {
2487
              *buf = 0;
2488
              return (ndx);     /* return amount copied */
2489
            }
2490
          else
2491
            {
2492
              *buf = 0;
2493
              return (0);        /* XXX: how do we tell the user the status? */
2494
            }
2495
        }
2496
      *buf = 0;
2497
      return (count);
2498
    }
2499
  else
2500
    {
2501
      for (ndx = 0; ndx < count; ndx++)
2502
        {
2503
          ch = *mem++;
2504
          *buf++ = hexchars[ch >> 4];
2505
          *buf++ = hexchars[ch & 0xf];
2506
        }
2507
      *buf = 0;
2508
      return (count);           /* we copied everything */
2509
    }
2510
}
2511
 
2512
static DTC_RESPONSE
2513
find_memory(unsigned char *mem, long count,
2514
            unsigned char **location, long *incr)
2515
{
2516
  DTC_RESPONSE retval;
2517
  long length;
2518
 
2519
  /* figure out how much of the memory range we can read w/o faulting */
2520
  count = read_access_range(mem, count);
2521
  if (count == 0)
2522
    return (NOT_FOUND_TARGET_RESPONSE);
2523
 
2524
  if (curframe.valid)
2525
    {
2526
      unsigned char *mem_block;
2527
      unsigned char *mem_addr;
2528
      unsigned long mem_size;
2529
      unsigned long mem_stamp;
2530
 
2531
      retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem,
2532
                                              (unsigned long **)&mem_block,
2533
                                              (unsigned long **)&mem_addr,
2534
                                              &mem_size, &mem_stamp);
2535
 
2536
      switch (retval)
2537
        {
2538
        case OK_TARGET_RESPONSE:
2539
#if 0
2540
          printp("FOUND: mem %x block %x addr %x size %d stamp %x\n",
2541
                 mem, mem_block, mem_addr, mem_size, mem_stamp);
2542
#endif
2543
          *location = mem_block + (mem - mem_addr);
2544
          length = mem_size - (mem - mem_addr);
2545
 
2546
          if (length < count)
2547
            *incr = length;
2548
          else
2549
            *incr = count;
2550
 
2551
          break;
2552
 
2553
        case NOT_FOUND_TARGET_RESPONSE:
2554
        case NEAR_FOUND_TARGET_RESPONSE:
2555
#if 0
2556
          printp("NOT FOUND: mem %x, checking code region\n", mem);
2557
#endif
2558
          /* check to see if it's in the code region */
2559
          if ((CS_CODE_START <= (long)mem) &&
2560
              ((long)mem < CS_CODE_START + CS_CODE_SIZE))
2561
            {
2562
              /* some or all of the address range is in the code */
2563
              *location = mem;
2564
              if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE)
2565
                *incr = count; /* it's totally in the code */
2566
              else
2567
                /* how much is in the code? */
2568
                *incr = CS_CODE_START + CS_CODE_SIZE - (long)mem;
2569
#if 0
2570
              printp("FOUND in code region: %x\n", mem);
2571
#endif
2572
              retval = OK_TARGET_RESPONSE;
2573
            }
2574
          else
2575
            retval = NOT_FOUND_TARGET_RESPONSE;
2576
 
2577
          break;
2578
 
2579
        default:
2580
#if 0
2581
          printp("BAD RETURN: %d\n", retval);
2582
#endif
2583
          retval = NOT_FOUND_TARGET_RESPONSE;
2584
          break;
2585
        }
2586
    }
2587
  else
2588
    {
2589
      *location = mem;
2590
      *incr = count;
2591
      retval = OK_TARGET_RESPONSE;
2592
    }
2593
 
2594
  return (retval);
2595
}
2596
 
2597
/* Convert the hex array pointed to by buf into binary to be placed in mem.
2598
   Return SUCCESS or FAIL.  */
2599
 
2600
static long
2601
hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
2602
{
2603
  long i, ch;
2604
 
2605
  for ( i=0; i<count; i++ )
2606
    {
2607
      ch = hex( *buf++ ) << 4;
2608
      ch = ch + hex( *buf++ );
2609
      if ( may_fault )
2610
        {
2611
          ch = set_uchar( mem++, ch );
2612
          if ( ch < 0 )    /* negative return indicates error */
2613
            return FAIL;
2614
        }
2615
      else
2616
        *mem++ = ch;
2617
    }
2618
  return SUCCESS;
2619
}
2620
 
2621
/**********************************************/
2622
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
2623
/* RETURN NUMBER OF CHARS PROCESSED           */
2624
/**********************************************/
2625
 
2626
static int
2627
hexToInt( char **ptr, unsigned long *intValue )
2628
{
2629
  long numChars = 0;
2630
  long hexValue;
2631
 
2632
  *intValue = 0;
2633
  while ( **ptr )
2634
    {
2635
      hexValue = hex( **ptr );
2636
      if ( hexValue >=0 )
2637
        {
2638
          *intValue = (*intValue << 4) | hexValue;
2639
          numChars ++;
2640
        }
2641
      else
2642
        break;
2643
      (*ptr)++;
2644
    }
2645
  return numChars;
2646
}
2647
 
2648
static volatile long gdb_handling_trap1;
2649
static volatile long gdb_handling_sstrace;
2650
static volatile long gdb_signo;
2651
 
2652
/*
2653
   Here is the "callable" stub entry point.
2654
   Call this function with a GDB request as an argument,
2655
   and it will service the request and return.
2656
 
2657
   May be further broken up as we go along, with individual requests
2658
   broken out as separate functions.
2659
 */
2660
 
2661
static char * handle_trace_query (char *);
2662
static char * handle_trace_set (char *);
2663
static int    handle_format (char **request, CFD *format);
2664
static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc);
2665
static char * crc_query (char *);
2666
static char * handle_test (char *);
2667
 
2668
void
2669
handle_request( char *request )
2670
{
2671
#if 0
2672
  remote_debug = 2;
2673
#endif
2674
  switch( *request++ )
2675
    {
2676
    case 'k':           /* "kill" */
2677
      curframe.valid = FALSE;
2678
      putpacket ("");
2679
      break;
2680
    case 'D':           /* "detach" */
2681
      curframe.valid = FALSE;
2682
      putpacket ("");
2683
      break;
2684
    default:            /* Unknown code.  Return an empty reply message. */
2685
      putpacket( "" );  /* return empty packet */
2686
      break;
2687
 
2688
    case 'H':           /* Set thread for subsequent operations.
2689
    Hct...                 c = 'c' for thread used in step and continue;
2690
                           t... can be -1 for all threads.
2691
                           c = 'g' for thread used in other operations.
2692
                           If zero, pick a thread, any thread.  */
2693
 
2694
      putpacket( "OK" );
2695
      break;
2696
 
2697
    case 'g':           /* Read registers.
2698
                           Each byte of register data is described by
2699
                           two hex digits.  registers are in the
2700
                           internal order for GDB, and the bytes in a
2701
                           register are in the same order the machine
2702
                           uses.  */
2703
      {
2704
        /* Return the values in (one of) the registers cache(s).
2705
           Several situations may pertain:
2706
           1) We're synchronous, in which case the "registers" array
2707
              should actually be current.
2708
           2) We're asynchronous, in which case the "registers" array
2709
              holds whatever was cached most recently.
2710
           3) We're looking at a trace frame that was collected earlier:
2711
              we will return those earlier registers.
2712
         */
2713
 
2714
        /* all registers default to zero */
2715
        memset (outbuffer, '0', NUMREGBYTES);
2716
        outbuffer[NUMREGBYTES] = '\0';
2717
 
2718
        if (curframe.valid)     /* debugging a trace frame */
2719
          mem2hex( (unsigned char*) curframe.traceregs,
2720
                  outbuffer, NUMREGBYTES, 0 );
2721
        else
2722
          mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 );
2723
 
2724
        putpacket( outbuffer );
2725
      }
2726
      break;
2727
    case 'G':           /* Write registers.
2728
    Gxxxxxxxx              Each byte of register data is described by
2729
                           two hex digits.  */
2730
      if (curframe.valid)       /* debugging a trace frame */
2731
        putpacket ("E03");      /* can't write regs into a trace frame! */
2732
      else
2733
        {
2734
          /* Write the values into the local registers cache...
2735
             Note that no actual registers are being changed.  */
2736
 
2737
          hex2mem( request,
2738
                  (unsigned char *) registers, NUMREGBYTES, 0 );
2739
          putpacket( "OK" );
2740
        }
2741
      break;
2742
    case 'P':           /* Write (single) register.
2743
    Pnn=xxxxxxxx           register nn gets value xxxxxxxx;
2744
                           two hex digits for each byte in the register
2745
                           (target byte order).  */
2746
 
2747
      if (curframe.valid)
2748
        putpacket ("E03");      /* can't write regs into a trace frame! */
2749
      else
2750
        {
2751
          unsigned long regno;
2752
 
2753
          if ( hexToInt( &request, &regno ) && *(request++) == '=' )
2754
            {
2755
              if ( regno < NUMREGS )
2756
                {
2757
                  hexToInt( &request,
2758
                           (unsigned long *) &registers[REGISTER_BYTE(regno)]);
2759
 
2760
                  putpacket( "OK" );
2761
                }
2762
              else
2763
                putpacket( "E01" );   /* bad packet or regno */
2764
            }
2765
        }
2766
      break;
2767
    case 'm':           /* Read memory.
2768
    mAAAAAAAA,LLLL         AAAAAAAA is address, LLLL is length.
2769
                           Reply can be fewer bytes than requested
2770
                           if able to read only part of the data.  */
2771
      {
2772
        unsigned long addr, len;
2773
 
2774
        if ( hexToInt( &request, &addr )    &&
2775
             *(request++) == ','            &&
2776
             hexToInt( &request, &len ) )
2777
          {
2778
            /* better not overwrite outbuffer! */
2779
            if ( len > (BUFMAX / 2) - 5 )
2780
              len = (BUFMAX / 2) - 5;
2781
            if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0) /* XXX: eventually use returned value */
2782
              putpacket( "E03" );       /* read fault (access denied) */
2783
            else
2784
              putpacket( outbuffer );   /* read succeeded */
2785
          }
2786
        else
2787
          putpacket( "E01" );           /* badly formed read request */
2788
 
2789
      }
2790
      break;
2791
    case 'M':           /* Write memory.
2792
    Maaaaaaaa,llll:xxxx    aaaaaaaa is address, llll is length;
2793
                           xxxx is data to write.  */
2794
 
2795
      {
2796
        unsigned long addr, len;
2797
 
2798
        if (curframe.valid)     /* can't write memory into a trace frame! */
2799
          putpacket ("E03");    /* "access denied" */
2800
        else /*** if ( write_access_enabled ) ***/
2801
          {
2802
            if ( hexToInt( &request, &addr )  &&
2803
                 *(request++) == ','          &&
2804
                 hexToInt( &request, &len )   &&
2805
                 *(request++) == ':' )
2806
              {
2807
                if (len == 2 &&
2808
                    addr >= CS_CODE_START &&
2809
                    addr <= LAST_CS_WORD)
2810
                  {
2811
                    unsigned long val;
2812
 
2813
                    if ( !hexToInt( &request, &val ) ||
2814
                         write_to_protected_mem( (void *)addr, val ) )
2815
                      putpacket( "E03" );   /* write fault (access denied) */
2816
                    else
2817
                      putpacket( "OK" );    /* write succeeded */
2818
                  }
2819
                else
2820
                  {
2821
                    if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
2822
                      putpacket( "E03" );   /* write fault (access denied) */
2823
                    else
2824
                      putpacket( "OK" );    /* write succeeded */
2825
                  }
2826
              }
2827
            else
2828
                putpacket( "E02" );     /* badly formed write request */
2829
          }
2830
      }
2831
      break;
2832
    case 'c':           /* Continue.
2833
    cAAAAAAAA              AAAAAAAA is address from which to resume.
2834
                           If omitted, resume at current PC.  */
2835
 
2836
      {
2837
        unsigned long addr;
2838
 
2839
        if (curframe.valid)
2840
          {
2841
            /* Don't continue if debugging a trace frame! */
2842
            gdb_puts ("Error: can't continue!\n");
2843
            putpacket ("S03");
2844
          }
2845
        else
2846
          {
2847
            gdb_signo = 3;
2848
            if (isxdigit(request[0]))
2849
              {
2850
                hexToInt(&request, &addr);
2851
                registers[REGISTER_BYTE(PC)] = addr;
2852
              }
2853
 
2854
            gdb_handling_trap1 = FALSE;
2855
            gdb_handling_sstrace = FALSE;
2856
            sss_trace_flag = '\0';
2857
          }
2858
      }
2859
      break;
2860
    case 's':           /* Step.
2861
    sAAAAAAAA              AAAAAAAA is address from which to begin stepping.
2862
                           If omitted, begin stepping at current PC.  */
2863
      {
2864
        unsigned long addr;
2865
 
2866
        if (curframe.valid)
2867
          {
2868
            /* Don't step if debugging a trace frame! */
2869
            gdb_puts ("Error: can't step!\n");
2870
            putpacket ("S03");
2871
          }
2872
        else
2873
          {
2874
            gdb_signo = 3;
2875
            if (isxdigit(request[0]))
2876
              {
2877
                hexToInt(&request, &addr);
2878
                registers[REGISTER_BYTE(PC)] = addr;
2879
              }
2880
 
2881
            gdb_handling_trap1 = FALSE;
2882
            gdb_handling_sstrace = FALSE;
2883
            sss_trace_flag = 't';
2884
          }
2885
      }
2886
      break;
2887
    case 'C':           /* Continue with signal.
2888
    Cxx;AAAAAAAA           xx is signal number in hex;
2889
                           AAAAAAAA is adddress from which to resume.
2890
                           If ;AAAAAAAA omitted, continue from PC.   */
2891
 
2892
      {
2893
        unsigned long addr = 0;
2894
 
2895
        if (!gdb_handling_trap1 || curframe.valid)
2896
          {
2897
            /* Don't continue if not currently in synchronous mode,
2898
               or if currently debugging a trace frame!  */
2899
            gdb_puts( "Error: can't continue!\n" );
2900
            putpacket( "S03" );       /* "sigquit"  (better idea?) */
2901
          }
2902
        else
2903
          {
2904
            gdb_signo = 3;
2905
            if ( isxdigit( *request ) )
2906
              {
2907
                hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
2908
                request += 2;
2909
                if ( *request == ';' && isxdigit( *++request ) )
2910
                  {
2911
                    hexToInt( &request, &addr );
2912
                    registers[REGISTER_BYTE(PC)] = addr;
2913
                  }
2914
              }
2915
            gdb_handling_trap1 = FALSE;
2916
            gdb_handling_sstrace = FALSE;
2917
            sss_trace_flag = '\0';
2918
          }
2919
      }
2920
      break;
2921
    case 'S':           /* Step with signal.
2922
    Sxx;AAAAAAAA           xx is signal number in hex;
2923
                           AAAAAAAA is adddress from which to begin stepping.
2924
                           If ;AAAAAAAA omitted, begin stepping from PC.   */
2925
      {
2926
        unsigned long addr = 0;
2927
 
2928
        if (!gdb_handling_trap1 || curframe.valid)
2929
          {
2930
            /* Don't step if not currently in synchronous mode,
2931
               or if currently debugging a trace frame!  */
2932
            gdb_puts( "Error: can't step!\n" );
2933
            putpacket( "S03" );       /* "sigquit"  (better idea?) */
2934
          }
2935
        else
2936
          {
2937
            gdb_signo = 3;
2938
            if ( isxdigit( *request ) )
2939
              {
2940
                hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
2941
                request += 2;
2942
                if ( *request == ';' && isxdigit( *++request ) )
2943
                  {
2944
                    hexToInt( &request, &addr );
2945
                    registers[REGISTER_BYTE(PC)] = addr;
2946
                  }
2947
              }
2948
            gdb_handling_trap1 = FALSE;
2949
            gdb_handling_sstrace = FALSE;
2950
            sss_trace_flag = 't';
2951
          }
2952
      }
2953
      break;
2954
    case '?':           /* Query the latest reason for stopping.
2955
                           Should be same reply as was last generated
2956
                           for step or continue.  */
2957
 
2958
      if ( gdb_signo == 0 )
2959
        gdb_signo = 3;  /* default to SIGQUIT */
2960
      outbuffer[ 0 ] = 'S';
2961
      outbuffer[ 1 ] = hexchars[ gdb_signo >>  4 ];
2962
      outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ];
2963
      outbuffer[ 3 ] = 0;
2964
      putpacket( outbuffer );
2965
      break;
2966
 
2967
    case 'd':           /* Toggle debug mode
2968
                           I'm sure we can think of something interesting.  */
2969
 
2970
      remote_debug = !remote_debug;
2971
      putpacket( "" );  /* return empty packet */
2972
      break;
2973
 
2974
    case 'q':           /* general query */
2975
      switch (*request++)
2976
        {
2977
        default:
2978
          putpacket ("");       /* nak a request which we don't handle */
2979
          break;
2980
        case 'T':               /* trace query */
2981
          putpacket (handle_trace_query (request));
2982
          break;
2983
        case 'C':               /* crc query (?) */
2984
          if (*request++ == 'R' &&
2985
              *request++ == 'C' &&
2986
              *request++ == ':')
2987
            putpacket (crc_query (request));
2988
          else
2989
            putpacket ("");     /* unknown query */
2990
          break;
2991
        }
2992
      break;
2993
 
2994
    case 'Q':                   /* general set */
2995
      switch (*request++)
2996
        {
2997
        default:
2998
          putpacket ("");       /* nak a request which we don't handle */
2999
          break;
3000
        case 'T':               /* trace */
3001
          putpacket (handle_trace_set (request));
3002
          break;
3003
        }
3004
      break;
3005
 
3006
    case 'T':
3007
      /* call test function: TAAA,BBB,CCC
3008
         A, B, and C are arguments to pass to gdb_c_test.  Reply is
3009
         "E01" (bad arguments) or "OK" (test function called).  */
3010
      putpacket (handle_test (request));
3011
      break;
3012
    }
3013
}
3014
 
3015
static TDP_SETUP_INFO tdp_temp;
3016
static int trace_running;
3017
 
3018
/*
3019
 * Function msgcmp:
3020
 *
3021
 * If second argument (str) is matched in first argument,
3022
 *    then advance first argument past end of str and return "SAME"
3023
 * else return "DIFFERENT" without changing first argument.
3024
 *
3025
 * Return: zero for DIFFERENT, non-zero for SUCCESS
3026
 */
3027
 
3028
static int
3029
msgcmp (char **msgp, char *str)
3030
{
3031
  char *next;
3032
 
3033
  if (msgp != 0 && str != 0)    /* input validation */
3034
    if ((next = *msgp) != 0)
3035
      {
3036
        for (;
3037
             *next && *str && *next == *str;
3038
             next++, str++)
3039
          ;
3040
 
3041
        if (*str == 0)                  /* matched all of str in msg */
3042
          return (int) (*msgp = next);  /* advance msg ptr past str  */
3043
      }
3044
  return 0;                             /* failure */
3045
}
3046
 
3047
static char *
3048
handle_trace_query (char *request)
3049
{
3050
  if (msgcmp (&request, "Status"))
3051
    {
3052
      if (adbg_check_if_active ())
3053
        {
3054
          gdb_puts ("Target trace is running.\n");
3055
          return "T1";
3056
        }
3057
      else
3058
        {
3059
          gdb_puts ("Target trace not running.\n");
3060
          trace_running = 0;
3061
          return "T0";
3062
        }
3063
    }
3064
  else                  /* unknown trace query */
3065
    {
3066
      return "";
3067
    }
3068
}
3069
 
3070
static void
3071
gdb_note (char *fmt, int arg1)
3072
{
3073
  if (remote_debug > 1)
3074
    {
3075
      sprintp (spare_buffer, fmt, arg1);
3076
      gdb_puts (spare_buffer);
3077
    }
3078
}
3079
 
3080
static int
3081
error_ret (int ret, char *fmt, int arg1)
3082
{
3083
  if (remote_debug > 0)
3084
    {
3085
      sprintp (spare_buffer, fmt, arg1);
3086
      gdb_puts (spare_buffer);
3087
    }
3088
  return ret;
3089
}
3090
 
3091
static int
3092
handle_format (char **request, COLLECTION_FORMAT_DEF *format)
3093
{
3094
  MEMRANGE_DEF m;
3095
  DTC_RESPONSE ret;
3096
  int elinum;
3097
  unsigned long regnum;
3098
  long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4];
3099
  struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes;
3100
 
3101
  if (format->id == 0)
3102
    {
3103
      if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
3104
        return dtc_error_ret (-1, "get_unused_format_id", ret);
3105
 
3106
      if (**request == 'R')
3107
        {
3108
          (*request)++;
3109
          hexToInt (request, &format->regs_mask);
3110
        }
3111
      gdb_note ("STUB: call define_format (id = %d, ", format->id);
3112
      gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
3113
 
3114
      if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
3115
        {
3116
          sprintp (spare_buffer,
3117
                   "'define_format': DTC error '%s' for format id %d.\n",
3118
                   get_err_text (ret),
3119
                   format->id);
3120
          gdb_puts (spare_buffer);
3121
          return -1;
3122
        }
3123
    }
3124
 
3125
  while ((**request == 'M') || (**request == 'X'))
3126
    {
3127
      switch (**request)
3128
        {
3129
        case 'M':               /* M<regnum>,<offset>,<size> */
3130
          (*request)++;
3131
          hexToInt(request, &regnum);
3132
 
3133
          if (regnum == 0 || regnum == (unsigned long) -1)
3134
            m.typecode = -1;
3135
          else if ((elinum = index_to_elinum (regnum)) > 0)
3136
            m.typecode = elinum;
3137
          else
3138
            return error_ret (-1,
3139
                              "Memrange register %d is not between 0 and 15\n",
3140
                              regnum);
3141
 
3142
          if (*(*request)++ != ',')
3143
            return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1);
3144
          hexToInt(request, &m.offset);
3145
          if (*(*request)++ != ',')
3146
            return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2);
3147
          hexToInt(request, &m.size);
3148
 
3149
          gdb_note ("STUB: call add_format_mem_range (typecode =  0x%x, ",
3150
                    m.typecode);
3151
          gdb_note ("offset = 0x%X, ", m.offset);
3152
          gdb_note ("size = %d);\n", m.size);
3153
          if ((ret = add_format_mem_ranges (format->id, &m)) !=
3154
              OK_TARGET_RESPONSE)
3155
            {
3156
              dtc_error_ret (-1, "add_format_mem_ranges", ret);
3157
              sprintp (spare_buffer,
3158
                       "format id %d: memrange (0x%x, 0x%x, 0x%x).\n",
3159
                       format->id, m.typecode, m.offset, m.size);
3160
              gdb_puts (spare_buffer);
3161
              return -1;
3162
            }
3163
          break;
3164
 
3165
        case 'X':               /* X<length>,<bytecodes> */
3166
          {
3167
            unsigned long length;
3168
 
3169
            (*request)++;
3170
            hexToInt(request, &length);
3171
 
3172
            if ((length <= 0) || (length > MAX_BYTE_CODES))
3173
              return error_ret (-1,
3174
                                "Bytecode expression length (%d) too large\n",
3175
                                length);
3176
 
3177
            if (*(*request)++ != ',')
3178
              return error_ret (-1,
3179
                                "Malformed bytecode expr (comma#%d missing)\n",
3180
                                1);
3181
            t_expr->next = NULL;
3182
            /* subtract one to account for expr[0] in header */
3183
            t_expr->size = sizeof(struct t_expr_tag) + length - 1;
3184
            t_expr->expr_size = length;
3185
 
3186
            hex2mem(*request, &t_expr->expr[0], length, 0);
3187
            *request += 2 * length;
3188
            build_and_add_expression(format->id, t_expr);
3189
          }
3190
          break;
3191
        }
3192
    }
3193
  return 0;
3194
}
3195
 
3196
static char *
3197
handle_trace_set (char *request)
3198
{
3199
  long n_frame;
3200
  unsigned long frameno, tdp, pc, start, stop;
3201
  DTC_RESPONSE ret = -1;
3202
  static COLLECTION_FORMAT_DEF tempfmt1;
3203
  static char enable;
3204
  static char retbuf[20];
3205
 
3206
  if (msgcmp (&request, "init"))
3207
    {
3208
      gdb_note ("STUB: call clear_trace_state();\n", 0);
3209
      curframe.valid = 0;       /* all old frames become invalid now */
3210
      if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE)
3211
        return "OK";
3212
      else
3213
        {
3214
          sprintp (retbuf, "E2%x", ret);
3215
          return (char *) dtc_error_ret ((int) &retbuf,
3216
                                         "clear_trace_state",
3217
                                         ret);
3218
        }
3219
    }
3220
  else if (msgcmp (&request, "Start"))
3221
    {
3222
      trace_running = 1;
3223
      curframe.valid = 0;       /* all old frames become invalid now */
3224
      gdb_note ("STUB: call start_trace_experiment();\n", 0);
3225
      adbg_save_trace_in_nvd ();
3226
      if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE)
3227
        return "OK";
3228
      else
3229
        {
3230
          sprintp (retbuf, "E2%x", ret);
3231
          return (char *) dtc_error_ret ((int) &retbuf,
3232
                                         "start_trace_experiment",
3233
                                         ret);
3234
        }
3235
    }
3236
  else if (msgcmp (&request, "Stop"))
3237
    {
3238
      trace_running = 0;
3239
      if (adbg_check_if_active ())
3240
        {
3241
          gdb_note ("STUB: call end_trace_experiment();\n", 0);
3242
          if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
3243
            return "OK";
3244
          else
3245
            {
3246
              sprintp (retbuf, "E2%x", ret);
3247
              return (char *) dtc_error_ret ((int) &retbuf,
3248
                                             "end_trace_experiment",
3249
                                             ret);
3250
            }
3251
        }
3252
      else return "OK";
3253
    }
3254
  /* "TDP:" (The 'T' was consumed in handle_request.)  */
3255
  else if (msgcmp (&request, "DP:"))
3256
    {
3257
      /* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format>
3258
                                                     {S{R[M,X]+}}<tp-format>
3259
 
3260
         D -- disable tracepoint (illegal from EMC's point of view)
3261
         E -- enable tracepoint?
3262
 
3263
         R -- regs format: R<regs-mask>
3264
         M -- memory format: M<regnum>,<offset>,<size>
3265
         X -- expr format: X<size>,<bytecodes>
3266
         S -- fencepost between trap formats and stepping formats.
3267
         */
3268
 
3269
      /* state variable, required for splitting TDP packets. */
3270
      static int doing_step_formats;
3271
 
3272
      /*
3273
       * TDP: packets may now be split into multiple packets.
3274
       * If a TDP packet is to be continued in another packet, it
3275
       * must end in a "-" character.  The subsequent continuation
3276
       * packet will then begin with a "-" character, between the
3277
       * token "TDP:" and the tdp_id field.  The ID and address
3278
       * will be repeated in each sub-packet.  The step_count,
3279
       * pass_count, and 'enabled' field must appear in the first
3280
       * packet.  The boundary between sub-packets may not appear
3281
       * between the "S" that denotes the start of stepping "formats",
3282
       * and the regs_mask that follows it.  The split may also not
3283
       * occur in the middle of either a memrange description or a
3284
       * bytecode string.  -- MVS
3285
       */
3286
 
3287
      if (*request == '-')      /* this is a continuation of a
3288
                                   trace definition in progress */
3289
        {
3290
          unsigned long temp_id, temp_addr;
3291
 
3292
          request++;
3293
          if (!(hexToInt (&request, &temp_id) &&
3294
                *request++ == ':'))
3295
            return "E11";           /* badly formed packet, field 1 */
3296
 
3297
          if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
3298
                *request++ == ':'))
3299
            return "E12";           /* badly formed packet, field 2 */
3300
 
3301
          if (temp_id   != tdp_temp.id)
3302
            return "E11";       /* something wrong: field 1 doesn't match */
3303
          if (temp_addr != (unsigned long) tdp_temp.addr)
3304
            return "E12";       /* something wrong: field 2 doesn't match */
3305
        }
3306
      else                      /* This is a new TDP definition */
3307
        {
3308
          memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
3309
          memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3310
          doing_step_formats = FALSE;
3311
 
3312
          if (!(hexToInt (&request, &tdp_temp.id) &&
3313
                *request++ == ':'))
3314
            return "E11";           /* badly formed packet, field 1 */
3315
 
3316
          if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
3317
                *request++ == ':'))
3318
            return "E12";           /* badly formed packet, field 2 */
3319
 
3320
          if (!(((enable = *request++) == 'D' || enable == 'E') &&
3321
                *request++ == ':'))
3322
            return "E13";           /* badly formed packet, field 3 */
3323
#if 0
3324
          if (enable == 'D')
3325
            {
3326
              gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
3327
              return "E20";
3328
            }
3329
#endif
3330
          if (!(hexToInt (&request, &tdp_temp.stepcount) &&
3331
                *request++ == ':'))
3332
            return "E14";           /* badly formed packet, field 4 */
3333
 
3334
          if (!hexToInt (&request, &tdp_temp.pass_limit))
3335
            return "E15";           /* badly formed packet, field 5 */
3336
 
3337
        }
3338
 
3339
      /* Typically, the first group of collection descriptors
3340
         refers to the trap collection.  There is an "S" token
3341
         to act as a fencepost between collection descriptors for
3342
         the trap, and those for the single-stepping.
3343
 
3344
         However, when the packet is split up into several packets,
3345
         this "S" token may already have been seen in a previous
3346
         sub-packet; so we have to remember it in a state variable.  */
3347
 
3348
      if (*request == 'R' || *request == 'M' || *request == 'X')
3349
        {
3350
          if (handle_format (&request, &tempfmt1))
3351
            return "E16";
3352
          if (doing_step_formats)
3353
            tdp_temp.tp_format_p  = tempfmt1.id;
3354
          else
3355
            tdp_temp.tdp_format_p = tempfmt1.id;
3356
        }
3357
 
3358
      /* When we see the "S" token, we remember it in a state variable
3359
         (in case the packet is split up and continued in another message),
3360
         and discard all current state from the collection "format".  */
3361
      if (*request == 'S')
3362
        {
3363
          doing_step_formats = TRUE;
3364
          /* discard prev format and start a new one */
3365
          memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3366
          request++;
3367
 
3368
          /* Having seen the "S" fencepost, it is now possible that
3369
             we will see some more collection descriptors pertaining
3370
             to the stepping collection.  */
3371
          if (*request   == 'R' || *request == 'M' || *request == 'X')
3372
            {
3373
              if (handle_format (&request, &tempfmt1))
3374
                return "E17";
3375
              /* new format ID is tp_format */
3376
              tdp_temp.tp_format_p = tempfmt1.id;
3377
            }
3378
        }
3379
 
3380
      if (*request == '-')      /* this TDP definition will be continued. */
3381
        sprintp (retbuf, "OK");
3382
      else if (enable == 'E')   /* end of TDP definition: pass to ADBG (if enabled!) */
3383
        {
3384
          gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id);
3385
          gdb_note ("addr 0x%X, ", (int) tdp_temp.addr);
3386
          gdb_note ("passc %d, ",        tdp_temp.pass_limit);
3387
          gdb_note ("stepc %d, ",        tdp_temp.stepcount);
3388
          gdb_note ("TDP fmt #%d, ",     tdp_temp.tdp_format_p);
3389
          gdb_note ("TP fmt #%d);\n",    tdp_temp.tp_format_p);
3390
 
3391
          ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
3392
 
3393
          if (ret == OK_TARGET_RESPONSE)
3394
            {
3395
              sprintp (retbuf, "OK");
3396
            }
3397
          else
3398
            {
3399
              sprintp (spare_buffer,
3400
                       "'define_tdp' returned DTC error '%s' for tracepoint %d.\n",
3401
                       get_err_text (ret),
3402
                       tdp_temp.id);
3403
              gdb_puts (spare_buffer);
3404
              sprintp (retbuf, "E2%x", ret);
3405
            }
3406
          /* Redundant, but let's try to make sure this state gets discarded. */
3407
          {
3408
            memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
3409
            memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
3410
          }
3411
        }
3412
      else /* ADBG_DTC does not support disabled tracepoints -- ignore it.  */
3413
        gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
3414
 
3415
      return retbuf;
3416
    }
3417
  else if (msgcmp (&request, "Frame:"))
3418
    {
3419
      ret = OK_TARGET_RESPONSE;
3420
 
3421
      if (msgcmp (&request, "pc:"))
3422
        {
3423
          if (!hexToInt (&request, &pc))
3424
            return "E10";       /* badly formed packet */
3425
          n_frame = curframe.valid ? curframe.frame_id + 1 : 0;
3426
          gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame);
3427
          gdb_note ("pc 0x%X);\n", pc);
3428
          ret = fetch_trace_frame_with_pc (&n_frame,
3429
                                           (void *) pc,
3430
                                           &curframe.format,
3431
                                           &curframe.frame_data);
3432
        }
3433
      else if (msgcmp (&request, "tdp:"))
3434
        {
3435
          if (!hexToInt (&request, &tdp))
3436
            return "E10";       /* badly formed packet */
3437
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
3438
          gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame);
3439
          gdb_note ("tdp 0x%X);\n", tdp);
3440
          ret = fetch_trace_frame_with_tdp (&n_frame,
3441
                                            tdp,
3442
                                            &curframe.format,
3443
                                            &curframe.frame_data);
3444
        }
3445
      else if (msgcmp (&request, "range:"))
3446
        {
3447
          if (!(hexToInt (&request, &start) &&
3448
                *request++ == ':'))
3449
            return "E11";      /* badly formed packet, field 1 */
3450
          else if (!hexToInt (&request, &stop))
3451
            return "E12";       /* badly formed packet, field 2 */
3452
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
3453
          gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame);
3454
          gdb_note ("start 0x%X, ",   start);
3455
          gdb_note ("stop  0x%X);\n", stop);
3456
          ret = fetch_trace_frame_with_pc_in_range (&n_frame,
3457
                                                    (void *) start,
3458
                                                    (void *) stop,
3459
                                                    &curframe.format,
3460
                                                    &curframe.frame_data);
3461
        }
3462
      else if (msgcmp (&request, "outside:"))
3463
        {
3464
          if (!(hexToInt (&request, &start) &&
3465
                *request++ == ':'))
3466
            return "E11";       /* badly formed packet, field 1 */
3467
          else if (!hexToInt (&request, &stop))
3468
            return "E12";       /* badly formed packet, field 2 */
3469
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
3470
          gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame);
3471
          gdb_note ("start 0x%X, ",   start);
3472
          gdb_note ("stop  0x%X);\n", stop);
3473
          ret = fetch_trace_frame_with_pc_outside (&n_frame,
3474
                                                   (void *) start,
3475
                                                   (void *) stop,
3476
                                                   &curframe.format,
3477
                                                   &curframe.frame_data);
3478
        }
3479
      else /* simple TFind by frame number: */
3480
        {
3481
          if (!hexToInt (&request, &frameno))
3482
            return "E10";       /* badly formed packet */
3483
          if (frameno != (unsigned long) -1)
3484
            {
3485
              gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno);
3486
              ret = fetch_trace_frame (n_frame = frameno,
3487
                                       &curframe.format,
3488
                                       &curframe.frame_data);
3489
#if 0
3490
              printp("STUB: fetch_trace_frame: return %d\n", ret);
3491
#endif
3492
            }
3493
          else  /* discard any trace frame, debug "the real world" */
3494
            {
3495
              if (curframe.valid)
3496
                gdb_note ("STUB: discard current trace frame #%d.\n",
3497
                          curframe.frame_id);
3498
              curframe.valid = 0;
3499
              return "OK";
3500
            }
3501
        }
3502
      if (ret == OK_TARGET_RESPONSE)    /* fetch_trace_frame succeeded */
3503
        { /* setup for debugging the trace frame */
3504
          curframe.valid    = 1;
3505
          curframe.frame_id = n_frame;
3506
          curframe.tdp_id   = curframe.frame_data->id;
3507
 
3508
          memset ((char *) &curframe.traceregs, 0,
3509
                  sizeof (curframe.traceregs));
3510
          curframe.traceregs[PC] = (unsigned long)
3511
            curframe.frame_data->program_counter;
3512
 
3513
          if (curframe.format)
3514
            {
3515
              unsigned long regs_mask = curframe.format->regs_mask;
3516
              unsigned long *regs, *stack, *mem;
3517
              unsigned long regno, index = 0;
3518
              CFD *dummy;
3519
 
3520
              if ((ret = get_addr_to_frame_regs_stack_mem
3521
                   (curframe.frame_data, &dummy, &regs, &stack, &mem))
3522
                  != OK_TARGET_RESPONSE)
3523
                {
3524
                  curframe.valid = 0;
3525
                  sprintp (retbuf, "E2%x", ret);
3526
                  return (char *)
3527
                    dtc_error_ret ((int) &retbuf,
3528
                                   "get_addr_to_frame_regs_stack_mem",
3529
                                   ret);
3530
                }
3531
 
3532
              if (remote_debug > 1)
3533
                { /* echo what we've found to gdb console */
3534
                  sprintp (spare_buffer,
3535
                           "STUB: Found frame %d, TDP %d, format %d (%s):\n",
3536
                           curframe.frame_id,
3537
                           curframe.tdp_id & 0x7fffffff,
3538
                           curframe.format->id,
3539
                           curframe.tdp_id & 0x80000000 ?
3540
                           "trap frame" : "stepping frame");
3541
                  gdb_puts (spare_buffer);
3542
                }
3543
              /* copy trace frame regs into stub's data format */
3544
              for (regno = 0, index = 0;
3545
                   regno < 16;
3546
                   regno++, regs_mask >>= 1)
3547
                if (regs_mask & 1)      /* got a collected register */
3548
                  {
3549
                    curframe.traceregs[regno] = regs[index++];
3550
                    if (remote_debug > 1)
3551
                      {
3552
                        sprintp (spare_buffer,
3553
                                 "      Collected 0x%08x for register %d.\n",
3554
                                 curframe.traceregs[regno], regno);
3555
                        gdb_puts (spare_buffer);
3556
                      }
3557
                  }
3558
              if (remote_debug > 1)
3559
                {
3560
                  long           midx, ridx, len;
3561
                  MEMRANGE_DEF  *mrange;
3562
                  unsigned char *data, *base;
3563
 
3564
                  if (curframe.format->stack_size > 0)
3565
                    {
3566
                      len = curframe.format->stack_size;
3567
                      sprintp (spare_buffer,
3568
                               "      Collected %d bytes of stack at 0x%x:\n",
3569
                               len, curframe.traceregs[A7]);
3570
                      gdb_puts (spare_buffer);
3571
 
3572
                      /* print stack data, but stay under msg len */
3573
                      if (len >= (NUMREGBYTES/2 - 2))
3574
                        len =    (NUMREGBYTES/2 - 3);
3575
                      mem2hex ((unsigned char *) stack,
3576
                               spare_buffer, len, 0);
3577
                      spare_buffer [len * 2] = '\n';
3578
                      spare_buffer [len * 2 + 1] = '\0'; /* EOS */
3579
                      gdb_puts (spare_buffer);
3580
                    }
3581
                  else
3582
                    gdb_puts ("Stack not collected\n");
3583
 
3584
                  for (midx = 0;
3585
                       get_addr_to_a_mem_range (curframe.frame_data,
3586
                                                midx,
3587
                                                &mrange,
3588
                                                (void **) &data)
3589
                       == OK_TARGET_RESPONSE;
3590
                       midx++)
3591
                    {
3592
                      if ((mrange->typecode == 0) ||
3593
                          (mrange->typecode == (unsigned long) -1))
3594
                        {
3595
                          sprintp (spare_buffer,
3596
                                   "      Collected %d bytes at MEM: 0x%x:\n",
3597
                                   mrange->size, mrange->offset);
3598
                          base = (unsigned char *) mrange->offset;
3599
                        }
3600
                      else
3601
                        {
3602
                          if ((ridx = elinum_to_index (mrange->typecode)) > 0)
3603
                            base = (unsigned char *) curframe.traceregs[ridx]
3604
                              + (long) mrange->offset;
3605
                          else
3606
                            {
3607
                              sprintp (spare_buffer,
3608
                   "STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n",
3609
                                       midx,
3610
                                       mrange->typecode,
3611
                                       mrange->offset,
3612
                                       mrange->size);
3613
                              gdb_puts (spare_buffer);
3614
                              continue;
3615
                            }
3616
                          sprintp (spare_buffer,
3617
                   "      Collected %d bytes at 0x%x (REG %X + %d):\n",
3618
                                   mrange->size,
3619
                                   base,
3620
                                   mrange->typecode,
3621
                                   mrange->offset);
3622
                        }
3623
                      gdb_puts (spare_buffer);
3624
                      len = mrange->size;
3625
                      if (len >= (NUMREGBYTES/2 - 2))
3626
                        len =    (NUMREGBYTES/2 - 3);
3627
                      mem2hex (data, spare_buffer, len, 0);
3628
                      spare_buffer [len * 2] = '\n';
3629
                      spare_buffer [len * 2 + 1] = '\0'; /* EOS */
3630
                      gdb_puts (spare_buffer);
3631
                    }
3632
                }
3633
            }
3634
          sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
3635
          return   retbuf;
3636
        }
3637
      else if (ret == NOT_FOUND_TARGET_RESPONSE)
3638
        {
3639
          /* Here's a question: if the fetch_trace_frame call failed
3640
             (which probably means a bad "TFIND" command from GDB),
3641
             should we remain focused on the previous frame (if any),
3642
             or should we revert to "no current frame"?
3643
           */
3644
          return "F-1";
3645
        }
3646
      else
3647
        {
3648
          sprintp (retbuf, "E2%x", ret);
3649
          return (char *) dtc_error_ret ((int) &retbuf,
3650
                                         "fetch_trace_frame[...]",
3651
                                         ret);
3652
        }
3653
    }
3654
  else                  /* unknown trace command */
3655
    {
3656
      return "";
3657
    }
3658
}
3659
 
3660
/* Table used by the crc32 function to calcuate the checksum. */
3661
static unsigned long crc32_table[256];
3662
 
3663
static int crc_mem_err;
3664
 
3665
static unsigned long
3666
crc32 (buf, len, crc)
3667
     unsigned char *buf;
3668
     int len;
3669
     unsigned long crc;
3670
{
3671
  crc_mem_err = FALSE;
3672
 
3673
  if (! crc32_table[1])
3674
    {
3675
      /* Initialize the CRC table and the decoding table. */
3676
      int i, j;
3677
      unsigned int c;
3678
 
3679
      for (i = 0; i < 256; i++)
3680
        {
3681
          for (c = i << 24, j = 8; j > 0; --j)
3682
            c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
3683
          crc32_table[i] = c;
3684
        }
3685
    }
3686
 
3687
  while (len--)
3688
    {
3689
      if (read_access_violation (buf))
3690
        {
3691
          crc_mem_err = TRUE;
3692
          return -1;
3693
        }
3694
      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
3695
    }
3696
  return crc;
3697
}
3698
 
3699
static char *
3700
crc_query (cmd)
3701
     char *cmd;
3702
{
3703
  unsigned long startmem, len, crc;
3704
  static char buf[32];
3705
 
3706
  if (hexToInt (&cmd, &startmem) &&
3707
      *cmd++ == ','              &&
3708
      hexToInt (&cmd, &len))
3709
    {
3710
      crc = crc32  ((unsigned char *) startmem, len, 0xffffffff);
3711
      if (!crc_mem_err)
3712
        {
3713
          sprintp (buf, "C%08x", crc);
3714
          return buf;
3715
        }
3716
      /* else error, fall thru */
3717
    }
3718
  sprintp (buf, "E01");
3719
  return buf;
3720
}
3721
 
3722
 
3723
static char *
3724
handle_test (request)
3725
     char *request;
3726
{
3727
  ULONG args[7];
3728
  int i;
3729
 
3730
  /* Parse the arguments, a comma-separated list of hex numbers, into
3731
     ARGS.  Parse at most six arguments.  */
3732
  i = 1;
3733
  if (*request != '\0')
3734
    while (i < 7)
3735
      {
3736
        if (! hexToInt (&request, &args[i++]))
3737
          return "E01";
3738
        if (*request == '\0')
3739
          break;
3740
        if (*request++ != ',')
3741
          return "E01";
3742
      }
3743
 
3744
  /* Fill the rest of the args array with zeros.  This is what the
3745
     INLINES command processor does with omitted arguments.  */
3746
  for (; i < 7; i++)
3747
    args[i] = 0;
3748
 
3749
  gdb_c_test (args);
3750
 
3751
  return "OK";
3752
}
3753
 
3754
 
3755
/* GDB_TRAP_1_HANDLER
3756
 
3757
   By the time this is called, the registers have been saved in "registers",
3758
   and the interrupt priority has been set to permit serial UART interrupts.
3759
 
3760
   However, since no gdb request has yet been received, and there is no
3761
   equivalent of getpacket for us to wait on, we can't sit here waiting
3762
   for packets and processing them.
3763
 
3764
   In fact, the ONLY thing for us to do here is sit and wait.
3765
   As gdb sends packet requests, they will handle themselves at the
3766
   interrupt level.  When gdb decides we can continue, it will reset
3767
   the global variable "gdb_handling_trap1", and we will return
3768
   (whereupon registers will be restored etc.)   */
3769
 
3770
void  gdb_trap_1_handler( void )
3771
{
3772
  gdb_handling_trap1 = TRUE;
3773
  sss_trace_flag = '\0';        /* shut off "trace bit" (indirectly) */
3774
  gdb_signo = 5;
3775
  putpacket( "S05" );
3776
  while ( gdb_handling_trap1 )
3777
    ;
3778
  return;
3779
}
3780
 
3781
void  gdb_trace_handler( void )
3782
{
3783
  sss_trace_flag = '\0';        /* shut off "trace bit" (indirectly) */
3784
  gdb_handling_trap1 = TRUE;
3785
  gdb_handling_sstrace = TRUE;
3786
  gdb_signo = 5;
3787
  putpacket( "S05" );
3788
  while ( gdb_handling_trap1 )
3789
    ;
3790
  return;
3791
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.