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