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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [testsuite/] [gdb.trace/] [gdb_c_test.c] - Blame information for rev 1183

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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