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 *) ®s,
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, ®no ) && *(request++) == '=' )
2755b725ae77Skettenis {
2756b725ae77Skettenis if ( regno < NUMREGS )
2757b725ae77Skettenis {
2758b725ae77Skettenis hexToInt( &request,
2759b725ae77Skettenis (unsigned long *) ®isters[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, ®num);
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, ®s, &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