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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [testsuite/] [gdb.trace/] [gdb_c_test.c] - Diff between revs 107 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 107 Rev 1765
/*
/*
 ******************************************************************************
 ******************************************************************************
 ******************************************************************************
 ******************************************************************************
 *
 *
 * COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved.
 * COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved.
 * $Id: gdb_c_test.c,v 1.1.1.1 2001-05-18 11:18:40 markom Exp $
 * $Id: gdb_c_test.c,v 1.1.1.1 2001-05-18 11:18:40 markom Exp $
 * DESCRIPTION: This module has been provided for the purpose of testing GDB.
 * DESCRIPTION: This module has been provided for the purpose of testing GDB.
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 ******************************************************************************
 ******************************************************************************
 *****************************************************************************/
 *****************************************************************************/
 
 
/*=============================================================================
/*=============================================================================
 *                                  INCLUDE  FILES
 *                                  INCLUDE  FILES
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
#ifdef DO_IT_BY_THE_BOOK
#ifdef DO_IT_BY_THE_BOOK
 
 
 
 
#include "symtypes_defs.h"
#include "symtypes_defs.h"
#include "printp.h"
#include "printp.h"
 
 
#include "adbg_expression.h"
#include "adbg_expression.h"
#include "common_hw_ds.h"
#include "common_hw_ds.h"
#include "common_hw_defs.h"
#include "common_hw_defs.h"
#include "evnttrac.h"
#include "evnttrac.h"
#include "sym_scratch_ds.h"
#include "sym_scratch_ds.h"
#include "symglob_ds.h"
#include "symglob_ds.h"
#include "sym_protglob_ds.h"
#include "sym_protglob_ds.h"
 
 
#include "ether.h"
#include "ether.h"
 
 
#include <ctype.h>
#include <ctype.h>
 
 
 
 
#else
#else
 
 
#include "adbg_dtc.h"
#include "adbg_dtc.h"
 
 
#define YES             1
#define YES             1
#define NO              0
#define NO              0
 
 
#define TRUE            1
#define TRUE            1
#define FALSE           0
#define FALSE           0
 
 
#define ENABLED         1
#define ENABLED         1
#define DISABLED        0
#define DISABLED        0
 
 
#define CONTROL_C       3   /* ASCII 'ETX' */
#define CONTROL_C       3   /* ASCII 'ETX' */
 
 
 
 
/*
/*
 * Faked after ctype.h
 * Faked after ctype.h
 */
 */
 
 
#define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
#define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
                     ((X) >= 'A' && (X) <= 'F') || \
                     ((X) >= 'A' && (X) <= 'F') || \
                     ((X) >= 'a' && (X) <= 'f'))
                     ((X) >= 'a' && (X) <= 'f'))
/*
/*
 * Borrowed from string.h
 * Borrowed from string.h
 */
 */
 
 
extern unsigned int strlen ( const char * );
extern unsigned int strlen ( const char * );
 
 
/*
/*
 * Extracted from symtypes.h:
 * Extracted from symtypes.h:
 */
 */
 
 
typedef char                    BOOL;     /*  8 Bits */
typedef char                    BOOL;     /*  8 Bits */
typedef unsigned char           UCHAR;    /*  8 Bits */
typedef unsigned char           UCHAR;    /*  8 Bits */
typedef unsigned short          USHORT;   /* 16 Bits */
typedef unsigned short          USHORT;   /* 16 Bits */
typedef unsigned long           ULONG;    /* 32 Bits */
typedef unsigned long           ULONG;    /* 32 Bits */
 
 
/*
/*
 * for struct t_expr_tag and
 * for struct t_expr_tag and
 * decl of build_and_add_expression
 * decl of build_and_add_expression
 */
 */
#include "adbg_expression.h"
#include "adbg_expression.h"
#define NULL    0
#define NULL    0
 
 
/*
/*
 * Extracted from printp.h:
 * Extracted from printp.h:
 */
 */
 
 
extern void printp ( const char * fptr, ... );
extern void printp ( const char * fptr, ... );
extern void sprintp ( const char * fptr, ... );
extern void sprintp ( const char * fptr, ... );
 
 
/*
/*
 * Extracted from ether.h:
 * Extracted from ether.h:
 */
 */
 
 
extern long eth_to_gdb ( UCHAR *buf, long length );
extern long eth_to_gdb ( UCHAR *buf, long length );
 
 
 
 
/*
/*
 * Derived from hwequs.s:
 * Derived from hwequs.s:
 */
 */
 
 
#define CS_CODE_START           0x100000
#define CS_CODE_START           0x100000
#define CS_CODE_SIZE            0x200000
#define CS_CODE_SIZE            0x200000
#define LAST_CS_WORD            (CS_CODE_START + CS_CODE_SIZE - 2)
#define LAST_CS_WORD            (CS_CODE_START + CS_CODE_SIZE - 2)
 
 
#define sh_genstat1             (*((volatile ULONG *) 0xFFFFFE54))
#define sh_genstat1             (*((volatile ULONG *) 0xFFFFFE54))
 
 
#define rs232_mode1             0               /* rs-232 mode 1 reg. */
#define rs232_mode1             0               /* rs-232 mode 1 reg. */
#define rs232_mode2             rs232_mode1     /* rs-232 mode 2 reg. */
#define rs232_mode2             rs232_mode1     /* rs-232 mode 2 reg. */
#define rs232_stat              4               /* rs-232 status reg. */
#define rs232_stat              4               /* rs-232 status reg. */
#define rs232_clk               rs232_stat      /* rs-232 clock select reg. */
#define rs232_clk               rs232_stat      /* rs-232 clock select reg. */
#define rs232_cmd               8               /* rs-232 command reg */
#define rs232_cmd               8               /* rs-232 command reg */
#define rs232_transmit          12              /* rs-232 transmit reg. */
#define rs232_transmit          12              /* rs-232 transmit reg. */
#define rs232_receive           rs232_transmit  /* rs-232 transmit reg. */
#define rs232_receive           rs232_transmit  /* rs-232 transmit reg. */
#define rs232_aux               16              /* rs-232 aux control reg. */
#define rs232_aux               16              /* rs-232 aux control reg. */
#define rs232_isr               20              /* rs-232 interrupt status reg. */
#define rs232_isr               20              /* rs-232 interrupt status reg. */
#define rs232_imr               rs232_isr       /* rs-232 interrupt mask reg. */
#define rs232_imr               rs232_isr       /* rs-232 interrupt mask reg. */
#define rs232_tc_high           24              /* rs-232 timer/counter high reg. */
#define rs232_tc_high           24              /* rs-232 timer/counter high reg. */
#define rs232_tc_low            28              /* rs-232 timer/counter low reg.  */
#define rs232_tc_low            28              /* rs-232 timer/counter low reg.  */
 
 
 
 
#endif
#endif
 
 
 
 
/*============================================================================
/*============================================================================
 *                                 MODULE  DEFINES
 *                                 MODULE  DEFINES
 *===========================================================================*/
 *===========================================================================*/
 
 
#define P_RST_LAN_UART_REG      ((volatile UCHAR  *) 0xFFFFFE45)
#define P_RST_LAN_UART_REG      ((volatile UCHAR  *) 0xFFFFFE45)
#define M_RST_LAN_UART          0x80          /* Bit  7 */
#define M_RST_LAN_UART          0x80          /* Bit  7 */
 
 
#define P_LAN0TR_REG            P_RST_LAN_UART_REG
#define P_LAN0TR_REG            P_RST_LAN_UART_REG
#define M_LAN0TR                0x20          /* Bit  5 */
#define M_LAN0TR                0x20          /* Bit  5 */
 
 
#define M_SH_GENCON_LAN0TR      0x00200000    /* Bit 21 */
#define M_SH_GENCON_LAN0TR      0x00200000    /* Bit 21 */
 
 
#define MAX_RS232_CHARS         512
#define MAX_RS232_CHARS         512
 
 
#define LAN_Q_MOD(X)            ((X) % MAX_RS232_CHARS)
#define LAN_Q_MOD(X)            ((X) % MAX_RS232_CHARS)
 
 
/*---------------------------------------*
/*---------------------------------------*
 *           LAN  UART  Registers        *
 *           LAN  UART  Registers        *
 *---------------------------------------*/
 *---------------------------------------*/
 
 
#define LAN_UART_BASE               ((ULONG) 0xfffffc22)
#define LAN_UART_BASE               ((ULONG) 0xfffffc22)
 
 
/*  Write-Read  */
/*  Write-Read  */
 
 
#define P_LAN_MR1                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode1   )))
#define P_LAN_MR1                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode1   )))
#define P_LAN_MR2                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode2   )))
#define P_LAN_MR2                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode2   )))
 
 
/*  Write-Only  */
/*  Write-Only  */
 
 
#define P_LAN_ACR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux     )))
#define P_LAN_ACR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux     )))
#define P_LAN_CR                    ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_cmd     )))
#define P_LAN_CR                    ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_cmd     )))
#define P_LAN_CSR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_clk     )))
#define P_LAN_CSR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_clk     )))
#define P_LAN_CTLR                  ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_low  )))
#define P_LAN_CTLR                  ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_low  )))
#define P_LAN_CTUR                  ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_high )))
#define P_LAN_CTUR                  ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_high )))
#define P_LAN_IMR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr     )))
#define P_LAN_IMR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr     )))
 
 
/*  Read-Only */
/*  Read-Only */
 
 
#define P_LAN_SR                    ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_stat    )))
#define P_LAN_SR                    ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_stat    )))
#define P_LAN_ISR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_isr     )))
#define P_LAN_ISR                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_isr     )))
#define P_LAN_XMT                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit)))
#define P_LAN_XMT                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit)))
#define P_LAN_RCV                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive )))
#define P_LAN_RCV                   ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive )))
 
 
/*
/*
 *   Bit Values for Write-Read and Write-Only Registers
 *   Bit Values for Write-Read and Write-Only Registers
 */
 */
 
 
#define DEFAULT_LAN_MR1             ((UCHAR) 0x13)
#define DEFAULT_LAN_MR1             ((UCHAR) 0x13)
#define DEFAULT_LAN_MR2             ((UCHAR) 0x07)
#define DEFAULT_LAN_MR2             ((UCHAR) 0x07)
#define DEFAULT_LAN_CSR             ((UCHAR) 0xcc)
#define DEFAULT_LAN_CSR             ((UCHAR) 0xcc)
#define DEFAULT_LAN_ACR             ((UCHAR) 0x38)
#define DEFAULT_LAN_ACR             ((UCHAR) 0x38)
#define DEFAULT_LAN_CTUR            ((UCHAR) 0xff)
#define DEFAULT_LAN_CTUR            ((UCHAR) 0xff)
#define DEFAULT_LAN_CTLR            ((UCHAR) 0xff)
#define DEFAULT_LAN_CTLR            ((UCHAR) 0xff)
 
 
#define LAN_ACR_SELECT_BRG_0        DEFAULT_LAN_ACR
#define LAN_ACR_SELECT_BRG_0        DEFAULT_LAN_ACR
#define LAN_ACR_SELECT_BRG_1        (DEFAULT_LAN_ACR | 0x80)
#define LAN_ACR_SELECT_BRG_1        (DEFAULT_LAN_ACR | 0x80)
 
 
#define UART_CR_RESET_MR_PTR        ((UCHAR) 0x10) /* Reset MR pointer (points to MR1). */
#define UART_CR_RESET_MR_PTR        ((UCHAR) 0x10) /* Reset MR pointer (points to MR1). */
#define UART_CR_RESET_RVCR          ((UCHAR) 0x20) /* Reset receiver (disabled).        */
#define UART_CR_RESET_RVCR          ((UCHAR) 0x20) /* Reset receiver (disabled).        */
#define UART_CR_RESET_XMTR          ((UCHAR) 0x30) /* Reset transmitter (disabled).     */
#define UART_CR_RESET_XMTR          ((UCHAR) 0x30) /* Reset transmitter (disabled).     */
#define UART_CR_RESET_ERROR_STATUS  ((UCHAR) 0x40) /* Reset error status.               */
#define UART_CR_RESET_ERROR_STATUS  ((UCHAR) 0x40) /* Reset error status.               */
#define UART_CR_RESET_BRK_CHG_INT   ((UCHAR) 0x50) /* Reset break change interrupt.     */
#define UART_CR_RESET_BRK_CHG_INT   ((UCHAR) 0x50) /* Reset break change interrupt.     */
#define UART_CR_START_CNTR_TIMER    ((UCHAR) 0x80) /* Start counter/timer.              */
#define UART_CR_START_CNTR_TIMER    ((UCHAR) 0x80) /* Start counter/timer.              */
#define UART_CR_STOP_CNTR           ((UCHAR) 0x90) /* Stop counter.                     */
#define UART_CR_STOP_CNTR           ((UCHAR) 0x90) /* Stop counter.                     */
 
 
#define UART_CR_DISABLE_XMTR        ((UCHAR) 0x08) /* Disable transmitter.              */
#define UART_CR_DISABLE_XMTR        ((UCHAR) 0x08) /* Disable transmitter.              */
#define UART_CR_ENABLE_XMTR         ((UCHAR) 0x04) /* Enable transmitter.               */
#define UART_CR_ENABLE_XMTR         ((UCHAR) 0x04) /* Enable transmitter.               */
#define UART_CR_DISABLE_RCVR        ((UCHAR) 0x02) /* Disable receiver.                 */
#define UART_CR_DISABLE_RCVR        ((UCHAR) 0x02) /* Disable receiver.                 */
#define UART_CR_ENABLE_RCVR         ((UCHAR) 0x01) /* Enable receiver.                  */
#define UART_CR_ENABLE_RCVR         ((UCHAR) 0x01) /* Enable receiver.                  */
 
 
#define UART_CSR_BR_4800            ((UCHAR) 0x99) /* With either BRG Set selected (via ACR). */
#define UART_CSR_BR_4800            ((UCHAR) 0x99) /* With either BRG Set selected (via ACR). */
#define UART_CSR_BR_9600            ((UCHAR) 0xbb) /* With either BRG Set selected (via ACR). */
#define UART_CSR_BR_9600            ((UCHAR) 0xbb) /* With either BRG Set selected (via ACR). */
#define UART_CSR_BR_19200           ((UCHAR) 0xcc) /* With BRG Set '1' selected (via ACR). */
#define UART_CSR_BR_19200           ((UCHAR) 0xcc) /* With BRG Set '1' selected (via ACR). */
#define UART_CSR_BR_38400           ((UCHAR) 0xcc) /* With BRG Set '0' selected (via ACR). */
#define UART_CSR_BR_38400           ((UCHAR) 0xcc) /* With BRG Set '0' selected (via ACR). */
 
 
#define UART_IMR_RxRDY              ((UCHAR) 0x04) /* Enable 'RxRDY' interrupt. */
#define UART_IMR_RxRDY              ((UCHAR) 0x04) /* Enable 'RxRDY' interrupt. */
#define UART_IMR_TxEMT              ((UCHAR) 0x02) /* Enable 'TxEMT' interrupt. */
#define UART_IMR_TxEMT              ((UCHAR) 0x02) /* Enable 'TxEMT' interrupt. */
#define UART_IMR_TxRDY              ((UCHAR) 0x01) /* Enable 'TxRDY' interrupt. */
#define UART_IMR_TxRDY              ((UCHAR) 0x01) /* Enable 'TxRDY' interrupt. */
 
 
/*
/*
 *   Bit Masks for Read-Only Registers
 *   Bit Masks for Read-Only Registers
 */
 */
 
 
#define M_UART_SR_RCVD_BRK      0x80    /* Bit 7 */
#define M_UART_SR_RCVD_BRK      0x80    /* Bit 7 */
#define M_UART_SR_FE            0x40    /* Bit 6 */
#define M_UART_SR_FE            0x40    /* Bit 6 */
#define M_UART_SR_PE            0x20    /* Bit 5 */
#define M_UART_SR_PE            0x20    /* Bit 5 */
#define M_UART_SR_OE            0x10    /* Bit 4 */
#define M_UART_SR_OE            0x10    /* Bit 4 */
#define M_UART_SR_TxEMT         0x08    /* Bit 3 */
#define M_UART_SR_TxEMT         0x08    /* Bit 3 */
#define M_UART_SR_TxRDY         0x04    /* Bit 2 */
#define M_UART_SR_TxRDY         0x04    /* Bit 2 */
#define M_UART_SR_FFULL         0x02    /* Bit 1 */
#define M_UART_SR_FFULL         0x02    /* Bit 1 */
#define M_UART_SR_RxRDY         0x01    /* Bit 0 */
#define M_UART_SR_RxRDY         0x01    /* Bit 0 */
 
 
#define M_UART_ISR_RxRDY        0x04    /* Bit 2 */
#define M_UART_ISR_RxRDY        0x04    /* Bit 2 */
#define M_UART_ISR_TxEMT        0x02    /* Bit 1 */
#define M_UART_ISR_TxEMT        0x02    /* Bit 1 */
#define M_UART_ISR_TxRDY        0x01    /* Bit 0 */
#define M_UART_ISR_TxRDY        0x01    /* Bit 0 */
 
 
/*---------------------------------------*
/*---------------------------------------*
 *       Support for 'Utility 83'.       *
 *       Support for 'Utility 83'.       *
 *---------------------------------------*/
 *---------------------------------------*/
 
 
#define LAN_UTIL_CODE           0x83
#define LAN_UTIL_CODE           0x83
 
 
#define LAN_INIT                ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T'))
#define LAN_INIT                ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T'))
#define LAN_BAUD                ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D'))
#define LAN_BAUD                ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D'))
#define LAN_INTR                ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R'))
#define LAN_INTR                ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R'))
#define LAN_XMT                 ((ULONG)               (('X' << 16) | ('M' << 8) | 'T'))
#define LAN_XMT                 ((ULONG)               (('X' << 16) | ('M' << 8) | 'T'))
#define LAN_ECHO                ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O'))
#define LAN_ECHO                ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O'))
#define LAN_STAT                ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T'))
#define LAN_STAT                ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T'))
#define LAN_IN                  ((ULONG)                             (('I' << 8) | 'N'))
#define LAN_IN                  ((ULONG)                             (('I' << 8) | 'N'))
#define LAN_OUT                 ((ULONG)               (('O' << 16) | ('U' << 8) | 'T'))
#define LAN_OUT                 ((ULONG)               (('O' << 16) | ('U' << 8) | 'T'))
 
 
#define LAN_PUTC                ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
#define LAN_PUTC                ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
#define LAN_WPM                 ((ULONG)               (('W' << 16) | ('P' << 8) | 'M'))
#define LAN_WPM                 ((ULONG)               (('W' << 16) | ('P' << 8) | 'M'))
 
 
#define STATUS(X)               ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
#define STATUS(X)               ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
 
 
#define XMT_VIA_BP_ENABLED()    ( *P_LAN0TR_REG & M_LAN0TR  ?  1 : 0 )
#define XMT_VIA_BP_ENABLED()    ( *P_LAN0TR_REG & M_LAN0TR  ?  1 : 0 )
 
 
#define TRAP_1_INST             0x4E41
#define TRAP_1_INST             0x4E41
 
 
/*
/*
 *   Bit #13 of shared genstat 1 indicates
 *   Bit #13 of shared genstat 1 indicates
 *   which processor we are as follows.
 *   which processor we are as follows.
 *
 *
 *           0 => X (side A)
 *           0 => X (side A)
 *           1 => Y (side B)
 *           1 => Y (side B)
 */
 */
 
 
#define M_PROC_ID               0x00002000
#define M_PROC_ID               0x00002000
 
 
#define IS_SIDE_A()             ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
#define IS_SIDE_A()             ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
#define IS_SIDE_B()             ( (sh_genstat1) & M_PROC_ID )
#define IS_SIDE_B()             ( (sh_genstat1) & M_PROC_ID )
 
 
 
 
#ifdef STANDALONE       /* Compile this module stand-alone for debugging */
#ifdef STANDALONE       /* Compile this module stand-alone for debugging */
#define LAN_PUT_CHAR(X) printf("%c", X)
#define LAN_PUT_CHAR(X) printf("%c", X)
#else
#else
#define LAN_PUT_CHAR(X) while ( lan_put_char( X ) )
#define LAN_PUT_CHAR(X) while ( lan_put_char( X ) )
#endif
#endif
 
 
 
 
 
 
 
 
#define VIA_RS232             0
#define VIA_RS232             0
#define VIA_ETHERNET          1
#define VIA_ETHERNET          1
 
 
#define MAX_IO_BUF_SIZE       400
#define MAX_IO_BUF_SIZE       400
 
 
#define MAX_BYTE_CODES        200 /* maximum length for bytecode string */
#define MAX_BYTE_CODES        200 /* maximum length for bytecode string */
 
 
 
 
static  ULONG           gdb_host_comm;
static  ULONG           gdb_host_comm;
 
 
static  ULONG           gdb_cat_ack;
static  ULONG           gdb_cat_ack;
 
 
static  char            eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
static  char            eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
 
 
 
 
#ifdef STANDALONE
#ifdef STANDALONE
 
 
#define ACK_PKT()       LAN_PUT_CHAR( '+' )
#define ACK_PKT()       LAN_PUT_CHAR( '+' )
#define NACK_PKT()      LAN_PUT_CHAR( '-' )
#define NACK_PKT()      LAN_PUT_CHAR( '-' )
 
 
#else
#else
 
 
#define ACK_PKT()       {                                             \
#define ACK_PKT()       {                                             \
                          if ( VIA_ETHERNET == gdb_host_comm )        \
                          if ( VIA_ETHERNET == gdb_host_comm )        \
                          {                                           \
                          {                                           \
                            gdb_cat_ack = YES;                        \
                            gdb_cat_ack = YES;                        \
                          }                                           \
                          }                                           \
                          else                                        \
                          else                                        \
                          {                                           \
                          {                                           \
                            LAN_PUT_CHAR( '+' );                      \
                            LAN_PUT_CHAR( '+' );                      \
                          }                                           \
                          }                                           \
                        }
                        }
 
 
 
 
 
 
#define NACK_PKT()      {                                             \
#define NACK_PKT()      {                                             \
                          if ( VIA_ETHERNET == gdb_host_comm )        \
                          if ( VIA_ETHERNET == gdb_host_comm )        \
                          {                                           \
                          {                                           \
                            eth_outbuffer[ 0 ] = '-';                 \
                            eth_outbuffer[ 0 ] = '-';                 \
                            eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
                            eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
                          }                                           \
                          }                                           \
                          else                                        \
                          else                                        \
                          {                                           \
                          {                                           \
                            LAN_PUT_CHAR( '-' );                      \
                            LAN_PUT_CHAR( '-' );                      \
                          }                                           \
                          }                                           \
                        }
                        }
 
 
#endif
#endif
 
 
 
 
 
 
 
 
/*============================================================================
/*============================================================================
 *                                 MODULE  TYPEDEFS
 *                                 MODULE  TYPEDEFS
 *===========================================================================*/
 *===========================================================================*/
 
 
typedef struct rs232_queue {
typedef struct rs232_queue {
 
 
  long    head_index;
  long    head_index;
 
 
  long    tail_index;
  long    tail_index;
 
 
  ULONG   overflows;
  ULONG   overflows;
 
 
  long    gdb_packet_start;
  long    gdb_packet_start;
  long    gdb_packet_end;
  long    gdb_packet_end;
  long    gdb_packet_csum1;
  long    gdb_packet_csum1;
  long    gdb_packet_csum2;
  long    gdb_packet_csum2;
 
 
  UCHAR   buf[ MAX_RS232_CHARS ];
  UCHAR   buf[ MAX_RS232_CHARS ];
 
 
} T_RS232_QUEUE;
} T_RS232_QUEUE;
 
 
 
 
 
 
 
 
/*=============================================================================
/*=============================================================================
 *                        EXTERNAL GLOBAL VARIABLES
 *                        EXTERNAL GLOBAL VARIABLES
 *===========================================================================*/
 *===========================================================================*/
 
 
extern volatile UCHAR         sss_trace_flag;
extern volatile UCHAR         sss_trace_flag;
 
 
 
 
/*=============================================================================
/*=============================================================================
 *                           STATIC  MODULE  DECLARATIONS
 *                           STATIC  MODULE  DECLARATIONS
 *===========================================================================*/
 *===========================================================================*/
 
 
static  T_RS232_QUEUE lan_input_queue,
static  T_RS232_QUEUE lan_input_queue,
                      lan_output_queue;
                      lan_output_queue;
 
 
static  BOOL          test_echo;
static  BOOL          test_echo;
 
 
#if 0
#if 0
/* The stub no longer seems to use this.  */
/* The stub no longer seems to use this.  */
static  BOOL          write_access_enabled;
static  BOOL          write_access_enabled;
#endif
#endif
 
 
static  int           baud_rate_idx;
static  int           baud_rate_idx;
 
 
static  ULONG         tx_by_intr,
static  ULONG         tx_by_intr,
                      tx_by_poll;
                      tx_by_poll;
 
 
static  UCHAR         lan_shadow_imr;
static  UCHAR         lan_shadow_imr;
 
 
 
 
/*=============================================================================
/*=============================================================================
 *                        EXTERNAL FUNCTION PROTOTYPES
 *                        EXTERNAL FUNCTION PROTOTYPES
 *===========================================================================*/
 *===========================================================================*/
 
 
extern  long  write_to_protected_mem( void *address, unsigned short value );
extern  long  write_to_protected_mem( void *address, unsigned short value );
 
 
 
 
/*=============================================================================
/*=============================================================================
 *                      MODULE GLOBAL FUNCTIONS PROTOTYPES
 *                      MODULE GLOBAL FUNCTIONS PROTOTYPES
 *===========================================================================*/
 *===========================================================================*/
 
 
ULONG gdb_c_test( ULONG *parm );
ULONG gdb_c_test( ULONG *parm );
 
 
 
 
void  lan_init( void );
void  lan_init( void );
 
 
void  lan_isr( void );
void  lan_isr( void );
 
 
long  lan_get_char( void );
long  lan_get_char( void );
 
 
long  lan_put_char( UCHAR c );
long  lan_put_char( UCHAR c );
 
 
ULONG lan_util( ULONG *parm );
ULONG lan_util( ULONG *parm );
 
 
 
 
/*=============================================================================
/*=============================================================================
 *                      MODULE LOCAL FUNCTION PROTOTYPES
 *                      MODULE LOCAL FUNCTION PROTOTYPES
 *===========================================================================*/
 *===========================================================================*/
 
 
static  void  lan_reset( void );
static  void  lan_reset( void );
 
 
static  void  lan_configure( void );
static  void  lan_configure( void );
 
 
static  void  lan_init_queue( T_RS232_QUEUE *p_queue );
static  void  lan_init_queue( T_RS232_QUEUE *p_queue );
 
 
static  void  lan_add_to_queue( long c, T_RS232_QUEUE *p_queue );
static  void  lan_add_to_queue( long c, T_RS232_QUEUE *p_queue );
 
 
static  UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue );
static  UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue );
 
 
static  void  lan_util_menu( void );
static  void  lan_util_menu( void );
 
 
static  long  get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
static  long  get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
 
 
 
 
/*=============================================================================
/*=============================================================================
 *                      GDB STUB FUNCTION PROTOTYPES
 *                      GDB STUB FUNCTION PROTOTYPES
 *===========================================================================*/
 *===========================================================================*/
 
 
void  gdb_trap_1_handler( void );
void  gdb_trap_1_handler( void );
void  gdb_trace_handler ( void );
void  gdb_trace_handler ( void );
 
 
void  gdb_get_eth_input( unsigned char *buf, long length );
void  gdb_get_eth_input( unsigned char *buf, long length );
 
 
static void getpacket ( void );
static void getpacket ( void );
static void putpacket ( char * );
static void putpacket ( char * );
static void discard_packet ( void );
static void discard_packet ( void );
 
 
#ifdef    STANDALONE    /* Compile this module stand-alone for debugging */
#ifdef    STANDALONE    /* Compile this module stand-alone for debugging */
#include <stdio.h>
#include <stdio.h>
#define printp printf   /* easier than declaring a local varargs stub func.  */
#define printp printf   /* easier than declaring a local varargs stub func.  */
#endif /* STANDALONE */
#endif /* STANDALONE */
 
 
 
 
/*=============================================================================
/*=============================================================================
 *                              MODULE BODY
 *                              MODULE BODY
 *===========================================================================*/
 *===========================================================================*/
 
 
/* ------------------- Things that belong in a header file --------------- */
/* ------------------- Things that belong in a header file --------------- */
extern char *memset (char *, int, int);
extern char *memset (char *, int, int);
 
 
                  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
                  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
                  *                                     *
                  *                                     *
                  *       Global Module Functions       *
                  *       Global Module Functions       *
                  *                                     *
                  *                                     *
                  *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
                  *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
 
 
static char   gdb_char_test;
static char   gdb_char_test;
static short  gdb_short_test;
static short  gdb_short_test;
static long   gdb_long_test;
static long   gdb_long_test;
static char   gdb_arr_test[25];
static char   gdb_arr_test[25];
static struct GDB_STRUCT_TEST
static struct GDB_STRUCT_TEST
{
{
  char   c;
  char   c;
  short  s;
  short  s;
  long   l;
  long   l;
  int    bfield : 11;   /* collect bitfield */
  int    bfield : 11;   /* collect bitfield */
  char   arr[25];
  char   arr[25];
  struct GDB_STRUCT_TEST *next;
  struct GDB_STRUCT_TEST *next;
} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
 
 
static union GDB_UNION_TEST
static union GDB_UNION_TEST
{
{
  char   c;
  char   c;
  short  s;
  short  s;
  long   l;
  long   l;
  int    bfield : 11;   /* collect bitfield */
  int    bfield : 11;   /* collect bitfield */
  char   arr[4];
  char   arr[4];
  union GDB_UNION_TEST *next;
  union GDB_UNION_TEST *next;
} gdb_union1_test;
} gdb_union1_test;
 
 
void gdb_recursion_test (int, int, int, int,  int,  int,  int);
void gdb_recursion_test (int, int, int, int,  int,  int,  int);
 
 
void gdb_recursion_test (int depth,
void gdb_recursion_test (int depth,
                         int q1,
                         int q1,
                         int q2,
                         int q2,
                         int q3,
                         int q3,
                         int q4,
                         int q4,
                         int q5,
                         int q5,
                         int q6)
                         int q6)
{       /* gdb_recursion_test line 0 */
{       /* gdb_recursion_test line 0 */
  int q = q1;                                           /* gdbtestline 1 */
  int q = q1;                                           /* gdbtestline 1 */
 
 
  q1 = q2;                                              /* gdbtestline 2 */
  q1 = q2;                                              /* gdbtestline 2 */
  q2 = q3;                                              /* gdbtestline 3 */
  q2 = q3;                                              /* gdbtestline 3 */
  q3 = q4;                                              /* gdbtestline 4 */
  q3 = q4;                                              /* gdbtestline 4 */
  q4 = q5;                                              /* gdbtestline 5 */
  q4 = q5;                                              /* gdbtestline 5 */
  q5 = q6;                                              /* gdbtestline 6 */
  q5 = q6;                                              /* gdbtestline 6 */
  q6 = q;                                               /* gdbtestline 7 */
  q6 = q;                                               /* gdbtestline 7 */
  if (depth--)                                          /* gdbtestline 8 */
  if (depth--)                                          /* gdbtestline 8 */
    gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */
    gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */
}
}
 
 
 
 
ULONG   gdb_c_test( ULONG *parm )
ULONG   gdb_c_test( ULONG *parm )
 
 
{
{
   char *p = "gdb_c_test";
   char *p = "gdb_c_test";
   char *rediculously_long_variable_name_with_equally_long_string_assignment;
   char *rediculously_long_variable_name_with_equally_long_string_assignment;
   register long local_reg = 7;
   register long local_reg = 7;
   static unsigned long local_static, local_static_sizeof;
   static unsigned long local_static, local_static_sizeof;
   long local_long;
   long local_long;
   unsigned long *stack_ptr;
   unsigned long *stack_ptr;
   unsigned long end_of_stack;
   unsigned long end_of_stack;
 
 
   rediculously_long_variable_name_with_equally_long_string_assignment =
   rediculously_long_variable_name_with_equally_long_string_assignment =
     "rediculously long variable name with equally long string assignment";
     "rediculously long variable name with equally long string assignment";
   local_static = 9;
   local_static = 9;
   local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
   local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
   local_long = local_reg + 1;
   local_long = local_reg + 1;
   stack_ptr  = (unsigned long *) &local_long;
   stack_ptr  = (unsigned long *) &local_long;
   end_of_stack =
   end_of_stack =
     (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
     (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
 
 
   printp ("\n$Id: gdb_c_test.c,v 1.1.1.1 2001-05-18 11:18:40 markom Exp $\n");
   printp ("\n$Id: gdb_c_test.c,v 1.1.1.1 2001-05-18 11:18:40 markom Exp $\n");
 
 
   printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n",
   printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n",
           p, parm[ 1 ], parm[ 2 ], parm[ 3 ], parm[ 4 ], parm[ 5 ], parm[ 6 ] );
           p, parm[ 1 ], parm[ 2 ], parm[ 3 ], parm[ 4 ], parm[ 5 ], parm[ 6 ] );
 
 
   gdb_char_test   = gdb_struct1_test.c = (char)   ((long) parm[1] & 0xff);
   gdb_char_test   = gdb_struct1_test.c = (char)   ((long) parm[1] & 0xff);
   gdb_short_test  = gdb_struct1_test.s = (short)  ((long) parm[2] & 0xffff);
   gdb_short_test  = gdb_struct1_test.s = (short)  ((long) parm[2] & 0xffff);
   gdb_long_test   = gdb_struct1_test.l = (long)   ((long) parm[3] & 0xffffffff);
   gdb_long_test   = gdb_struct1_test.l = (long)   ((long) parm[3] & 0xffffffff);
   gdb_union1_test.l = (long) parm[4];
   gdb_union1_test.l = (long) parm[4];
   gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff);
   gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff);
   gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff);
   gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff);
   gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff);
   gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff);
   gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff);
   gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff);
   gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff);
   gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff);
   gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff);
   gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff);
   gdb_struct1_test.bfield = 144;
   gdb_struct1_test.bfield = 144;
   gdb_struct1_test.next = &gdb_struct2_test;
   gdb_struct1_test.next = &gdb_struct2_test;
   gdb_structp_test      = &gdb_struct1_test;
   gdb_structp_test      = &gdb_struct1_test;
   gdb_structpp_test     = &gdb_structp_test;
   gdb_structpp_test     = &gdb_structp_test;
 
 
   gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
   gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
                       (long) parm[4], (long) parm[5], (long) parm[6]);
                       (long) parm[4], (long) parm[5], (long) parm[6]);
 
 
   gdb_char_test = gdb_short_test = gdb_long_test = 0;
   gdb_char_test = gdb_short_test = gdb_long_test = 0;
   gdb_structp_test  = (void *) 0;
   gdb_structp_test  = (void *) 0;
   gdb_structpp_test = (void *) 0;
   gdb_structpp_test = (void *) 0;
   memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
   memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
   memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
   memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
   local_static_sizeof = 0;
   local_static_sizeof = 0;
   local_static = 0;
   local_static = 0;
   return ( (ULONG) 0 );
   return ( (ULONG) 0 );
}
}
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_init
 * FUNCTION NAME:   lan_init
 *
 *
 *
 *
 * DESCRIPTION:
 * DESCRIPTION:
 *
 *
 *
 *
 * RETURN VALUE:
 * RETURN VALUE:
 *
 *
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *
 *
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
void    lan_init( void )
void    lan_init( void )
 
 
{
{
 
 
  if ( IS_SIDE_A( ) )
  if ( IS_SIDE_A( ) )
  {
  {
 
 
    lan_reset( );
    lan_reset( );
 
 
    lan_init_queue( &lan_input_queue );
    lan_init_queue( &lan_input_queue );
 
 
    lan_init_queue( &lan_output_queue );
    lan_init_queue( &lan_output_queue );
 
 
    lan_configure( );
    lan_configure( );
  }
  }
 
 
  return;
  return;
}
}
/* end of 'lan_init'
/* end of 'lan_init'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_isr
 * FUNCTION NAME:   lan_isr
 *
 *
 *
 *
 * DESCRIPTION:
 * DESCRIPTION:
 *
 *
 *
 *
 * RETURN VALUE:    None.
 * RETURN VALUE:    None.
 *
 *
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
void      lan_isr( void )
void      lan_isr( void )
 
 
{
{
  UCHAR   c;
  UCHAR   c;
 
 
 
 
  lan_shadow_imr = 0;           /*  Disable all UART interrupts.  */
  lan_shadow_imr = 0;           /*  Disable all UART interrupts.  */
  *P_LAN_IMR = lan_shadow_imr;
  *P_LAN_IMR = lan_shadow_imr;
 
 
 
 
  if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
  if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
  {
  {
 
 
    gdb_host_comm = VIA_RS232;
    gdb_host_comm = VIA_RS232;
 
 
    c = *P_LAN_RCV;
    c = *P_LAN_RCV;
 
 
    if ( test_echo )
    if ( test_echo )
    {
    {
      /* ????? */
      /* ????? */
    }
    }
 
 
    if ( c == CONTROL_C )
    if ( c == CONTROL_C )
    {
    {
        /* can't stop the target, but we can tell gdb to stop waiting... */
        /* can't stop the target, but we can tell gdb to stop waiting... */
      discard_packet( );
      discard_packet( );
      putpacket( "S03" );       /* send back SIGINT to the debugger */
      putpacket( "S03" );       /* send back SIGINT to the debugger */
    }
    }
 
 
    else
    else
    {
    {
      lan_add_to_queue( (long) c, &lan_input_queue );
      lan_add_to_queue( (long) c, &lan_input_queue );
      get_gdb_input( (long) c, &lan_input_queue );
      get_gdb_input( (long) c, &lan_input_queue );
    }
    }
 
 
  }
  }
 
 
  if ( XMT_VIA_BP_ENABLED( ) )
  if ( XMT_VIA_BP_ENABLED( ) )
  {
  {
 
 
    c = 0;
    c = 0;
 
 
    while ( (*P_LAN_ISR & M_UART_ISR_TxRDY)  &&  (c = lan_next_queue_char( &lan_output_queue )) )
    while ( (*P_LAN_ISR & M_UART_ISR_TxRDY)  &&  (c = lan_next_queue_char( &lan_output_queue )) )
    {
    {
      *P_LAN_XMT = c;
      *P_LAN_XMT = c;
      ++tx_by_intr;
      ++tx_by_intr;
    }
    }
 
 
    if ( c )
    if ( c )
    {
    {
      lan_shadow_imr |= UART_IMR_TxRDY;   /*  (Re-)Enable 'TxRDY' interrupt from UART.  */
      lan_shadow_imr |= UART_IMR_TxRDY;   /*  (Re-)Enable 'TxRDY' interrupt from UART.  */
    }
    }
 
 
  }
  }
 
 
 
 
  lan_shadow_imr |= UART_IMR_RxRDY;       /*  Re-Enable 'RxRDY' interrupt from UART.  */
  lan_shadow_imr |= UART_IMR_RxRDY;       /*  Re-Enable 'RxRDY' interrupt from UART.  */
  *P_LAN_IMR = lan_shadow_imr;
  *P_LAN_IMR = lan_shadow_imr;
 
 
 
 
 
 
  return;
  return;
}
}
/* end of 'lan_isr'
/* end of 'lan_isr'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_get_char
 * FUNCTION NAME:   lan_get_char
 *
 *
 *
 *
 * DESCRIPTION:     Fetches a character from the UART.
 * DESCRIPTION:     Fetches a character from the UART.
 *
 *
 *
 *
 * RETURN VALUE:    0 on success, -1 on failure.
 * RETURN VALUE:    0 on success, -1 on failure.
 *
 *
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
long    lan_get_char( void )
long    lan_get_char( void )
 
 
{
{
  long status = -2; /* AGD: nothing found in rcv buffer */
  long status = -2; /* AGD: nothing found in rcv buffer */
 
 
  if ( *P_LAN_SR & M_UART_SR_RxRDY )
  if ( *P_LAN_SR & M_UART_SR_RxRDY )
  {
  {
    char c = (char) *P_LAN_RCV;
    char c = (char) *P_LAN_RCV;
 
 
    if ( test_echo )
    if ( test_echo )
    {
    {
      LAN_PUT_CHAR ( c );
      LAN_PUT_CHAR ( c );
    }
    }
 
 
    if ( c == CONTROL_C )
    if ( c == CONTROL_C )
    {
    {
        /* can't stop the target, but we can tell gdb to stop waiting... */
        /* can't stop the target, but we can tell gdb to stop waiting... */
      discard_packet( );
      discard_packet( );
      putpacket( "S03" );       /* send back SIGINT to the debugger */
      putpacket( "S03" );       /* send back SIGINT to the debugger */
      status = 0;               /* success */
      status = 0;               /* success */
    }
    }
 
 
    else
    else
    {
    {
      lan_add_to_queue( (long) c, &lan_input_queue );
      lan_add_to_queue( (long) c, &lan_input_queue );
      status = get_gdb_input( (long) c, &lan_input_queue );
      status = get_gdb_input( (long) c, &lan_input_queue );
    }
    }
 
 
  }
  }
 
 
  return( status );
  return( status );
}
}
/* end of 'lan_get_char'
/* end of 'lan_get_char'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_put_char
 * FUNCTION NAME:   lan_put_char
 *
 *
 * DESCRIPTION:     Puts a character out via the UART.
 * DESCRIPTION:     Puts a character out via the UART.
 *
 *
 * RETURN VALUE:    0 on success, -1 on failure.
 * RETURN VALUE:    0 on success, -1 on failure.
 *
 *
 * USED GLOBAL VARIABLES: none.
 * USED GLOBAL VARIABLES: none.
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 * NOTES: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * NOTES: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *        !!                                                                  !!
 *        !!                                                                  !!
 *        !!  If 'XMT_VIA_BP_ENABLED()' is FALSE then output is THROWN AWAY.  !!
 *        !!  If 'XMT_VIA_BP_ENABLED()' is FALSE then output is THROWN AWAY.  !!
 *        !!  This prevents anyone infinite-looping on this function.         !!
 *        !!  This prevents anyone infinite-looping on this function.         !!
 *        !!                                                                  !!
 *        !!                                                                  !!
 *        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
long    lan_put_char( UCHAR c )
long    lan_put_char( UCHAR c )
 
 
{
{
  long    status = -1;
  long    status = -1;
 
 
  if ( XMT_VIA_BP_ENABLED( ) )
  if ( XMT_VIA_BP_ENABLED( ) )
  {
  {
 
 
    if ( *P_LAN_SR & M_UART_SR_TxRDY )
    if ( *P_LAN_SR & M_UART_SR_TxRDY )
    {
    {
      lan_add_to_queue( (long) c, &lan_output_queue );
      lan_add_to_queue( (long) c, &lan_output_queue );
 
 
      c = lan_next_queue_char( &lan_output_queue );
      c = lan_next_queue_char( &lan_output_queue );
 
 
      *P_LAN_XMT = c;
      *P_LAN_XMT = c;
      ++tx_by_poll;
      ++tx_by_poll;
      status = 0;
      status = 0;
    }
    }
#if 0
#if 0
    else
    else
    {
    {
      status = 0;
      status = 0;
      lan_shadow_imr |= UART_IMR_TxRDY;   /*  Enable 'TxRDY' interrupt from UART. */
      lan_shadow_imr |= UART_IMR_TxRDY;   /*  Enable 'TxRDY' interrupt from UART. */
      *P_LAN_IMR = lan_shadow_imr;
      *P_LAN_IMR = lan_shadow_imr;
    }
    }
#endif
#endif
  }
  }
 
 
  else
  else
  {
  {
    status = 0;   /* You lose: input character goes to the bit bucket. */
    status = 0;   /* You lose: input character goes to the bit bucket. */
  }
  }
 
 
  return( status );
  return( status );
}
}
/* end of 'lan_put_char'
/* end of 'lan_put_char'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_util
 * FUNCTION NAME:   lan_util
 *
 *
 * DESCRIPTION:
 * DESCRIPTION:
 *
 *
 * RETURN VALUE:
 * RETURN VALUE:
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
ULONG   lan_util( ULONG *parm )
ULONG   lan_util( ULONG *parm )
 
 
{
{
 
 
 
 
  static const struct {
  static const struct {
 
 
    ULONG rate_code;
    ULONG rate_code;
    UCHAR acr_setting;
    UCHAR acr_setting;
    UCHAR csr_setting;
    UCHAR csr_setting;
 
 
  } baud_rate_setting [] = {
  } baud_rate_setting [] = {
 
 
    { 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 },
    { 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 },
    { 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 },
    { 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 },
    { 0x9600,  LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600  },
    { 0x9600,  LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600  },
    { 0x4800,  LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800  }
    { 0x4800,  LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800  }
  };
  };
 
 
 
 
#define BOGUS_P1        0xE1
#define BOGUS_P1        0xE1
#define BOGUS_P2        0xE2
#define BOGUS_P2        0xE2
 
 
  ULONG   not_done_code;
  ULONG   not_done_code;
 
 
 
 
  ULONG   opcode;
  ULONG   opcode;
  ULONG   parm_1;
  ULONG   parm_1;
  ULONG   parm_2;
  ULONG   parm_2;
 
 
  int     i;
  int     i;
  UCHAR   c;
  UCHAR   c;
 
 
 
 
  not_done_code = 0;
  not_done_code = 0;
 
 
  opcode = parm[ 1 ];
  opcode = parm[ 1 ];
  parm_1 = parm[ 2 ];
  parm_1 = parm[ 2 ];
  parm_2 = parm[ 3 ];
  parm_2 = parm[ 3 ];
 
 
 
 
  switch ( opcode )
  switch ( opcode )
  {
  {
 
 
    case LAN_INIT:
    case LAN_INIT:
      {
      {
 
 
        lan_init( );
        lan_init( );
        printp( "\n\n  Interface (Re)Initialized ...\n\n" );
        printp( "\n\n  Interface (Re)Initialized ...\n\n" );
 
 
        break;
        break;
      }
      }
 
 
 
 
    case LAN_BAUD:
    case LAN_BAUD:
      {
      {
 
 
        for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
        for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
        {
        {
          if ( baud_rate_setting[i].rate_code == parm_1 )
          if ( baud_rate_setting[i].rate_code == parm_1 )
          {
          {
            baud_rate_idx = i;
            baud_rate_idx = i;
            *P_LAN_ACR = baud_rate_setting[i].acr_setting;
            *P_LAN_ACR = baud_rate_setting[i].acr_setting;
            *P_LAN_CSR = baud_rate_setting[i].csr_setting;
            *P_LAN_CSR = baud_rate_setting[i].csr_setting;
            printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code );
            printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code );
            return( not_done_code );
            return( not_done_code );
          }
          }
        }
        }
 
 
        printp( "\n\n  *** SYNTAX Error  -  Invalid baudrate (P2)\n\n" );
        printp( "\n\n  *** SYNTAX Error  -  Invalid baudrate (P2)\n\n" );
        not_done_code = BOGUS_P2;
        not_done_code = BOGUS_P2;
 
 
        break;
        break;
      }
      }
 
 
 
 
    case LAN_INTR:
    case LAN_INTR:
      {
      {
 
 
        switch ( parm_1 )
        switch ( parm_1 )
        {
        {
 
 
          case 0x0D: /* Disable 'RxRDY' Interrupts */
          case 0x0D: /* Disable 'RxRDY' Interrupts */
            {
            {
              lan_shadow_imr &= ~UART_IMR_RxRDY;
              lan_shadow_imr &= ~UART_IMR_RxRDY;
              *P_LAN_IMR = lan_shadow_imr;
              *P_LAN_IMR = lan_shadow_imr;
              printp( "\n\n  Receive Ready Interrupts DISABLED ...\n\n" );
              printp( "\n\n  Receive Ready Interrupts DISABLED ...\n\n" );
              break;
              break;
            }
            }
 
 
          case 0x0E: /* Enable 'RxRDY' Interrupts */
          case 0x0E: /* Enable 'RxRDY' Interrupts */
            {
            {
              lan_shadow_imr |= UART_IMR_RxRDY;
              lan_shadow_imr |= UART_IMR_RxRDY;
              *P_LAN_IMR = lan_shadow_imr;
              *P_LAN_IMR = lan_shadow_imr;
              printp( "\n\n  Receive Ready Interrupts ENABLED ...\n\n" );
              printp( "\n\n  Receive Ready Interrupts ENABLED ...\n\n" );
              break;
              break;
            }
            }
 
 
          default:
          default:
            {
            {
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
              not_done_code = BOGUS_P2;
              not_done_code = BOGUS_P2;
            }
            }
        }
        }
 
 
        break;
        break;
      }
      }
 
 
 
 
    case LAN_XMT:
    case LAN_XMT:
      {
      {
 
 
        switch ( parm_1 )
        switch ( parm_1 )
        {
        {
 
 
          case 0x0E: /* Enable Transmission-via-Backplane */
          case 0x0E: /* Enable Transmission-via-Backplane */
            {
            {
              if ( !(*P_LAN0TR_REG & M_LAN0TR) )
              if ( !(*P_LAN0TR_REG & M_LAN0TR) )
              {
              {
                *P_LAN0TR_REG |= M_LAN0TR;  /* 0 -> 1 */
                *P_LAN0TR_REG |= M_LAN0TR;  /* 0 -> 1 */
              }
              }
 
 
              printp( "\n\n  Transmit-via-Backplane ENABLED ...\n\n" );
              printp( "\n\n  Transmit-via-Backplane ENABLED ...\n\n" );
              break;
              break;
            }
            }
 
 
          case 0x0D: /* Disable Transmission-via-Backplane */
          case 0x0D: /* Disable Transmission-via-Backplane */
            {
            {
              if ( *P_LAN0TR_REG & M_LAN0TR )
              if ( *P_LAN0TR_REG & M_LAN0TR )
              {
              {
                *P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */
                *P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */
              }
              }
 
 
              printp( "\n\n  Transmit-via-Backplane DISABLED ...\n\n" );
              printp( "\n\n  Transmit-via-Backplane DISABLED ...\n\n" );
              break;
              break;
            }
            }
 
 
          default:
          default:
            {
            {
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 (use D or E)\n\n" );
              not_done_code = BOGUS_P2;
              not_done_code = BOGUS_P2;
              lan_util_menu( );
              lan_util_menu( );
            }
            }
        }
        }
 
 
        break;
        break;
      }
      }
 
 
 
 
    case LAN_STAT:
    case LAN_STAT:
      {
      {
 
 
      printp( "\n              -- Status --\n\n" );
      printp( "\n              -- Status --\n\n" );
 
 
        printp( "          Baud Rate: %X *\n",   baud_rate_setting[ baud_rate_idx ].rate_code );
        printp( "          Baud Rate: %X *\n",   baud_rate_setting[ baud_rate_idx ].rate_code );
        printp( "         Xmt-via-BP: %s *\n",   STATUS( XMT_VIA_BP_ENABLED( ) ) );
        printp( "         Xmt-via-BP: %s *\n",   STATUS( XMT_VIA_BP_ENABLED( ) ) );
        printp( "         RxRdy Intr: %s *\n",   STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) );
        printp( "         RxRdy Intr: %s *\n",   STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) );
   /*** printp( "         TxRdy Intr: %s\n",     STATUS( (lan_shadow_imr & M_UART_ISR_TxRDY) ) ); ***/
   /*** printp( "         TxRdy Intr: %s\n",     STATUS( (lan_shadow_imr & M_UART_ISR_TxRDY) ) ); ***/
        printp( "               Echo: %s *\n\n", STATUS( test_echo ) );
        printp( "               Echo: %s *\n\n", STATUS( test_echo ) );
 
 
        printp( "                IMR: %02X\n", (ULONG) lan_shadow_imr );
        printp( "                IMR: %02X\n", (ULONG) lan_shadow_imr );
        printp( "                ISR: %02X\n", (ULONG) *P_LAN_ISR );
        printp( "                ISR: %02X\n", (ULONG) *P_LAN_ISR );
        printp( "                 SR: %02X\n\n", (ULONG) *P_LAN_SR );
        printp( "                 SR: %02X\n\n", (ULONG) *P_LAN_SR );
 
 
        printp( "    Input Overflows: %d\n\n", lan_input_queue.overflows );
        printp( "    Input Overflows: %d\n\n", lan_input_queue.overflows );
 
 
        printp( "         Tx by Intr: %d\n", tx_by_intr  );
        printp( "         Tx by Intr: %d\n", tx_by_intr  );
        printp( "         Tx by Poll: %d\n\n", tx_by_poll );
        printp( "         Tx by Poll: %d\n\n", tx_by_poll );
 
 
        printp( "         *  Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE );
        printp( "         *  Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE );
 
 
        break;
        break;
      }
      }
 
 
 
 
    case LAN_IN:
    case LAN_IN:
      {
      {
 
 
        switch ( parm_1 )
        switch ( parm_1 )
        {
        {
 
 
          case 0x0C: /* Clear and Reset Queue */
          case 0x0C: /* Clear and Reset Queue */
            {
            {
              lan_init_queue( &lan_input_queue );
              lan_init_queue( &lan_input_queue );
              printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
              printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
              break;
              break;
            }
            }
 
 
          case 0x0D: /* Display Queue */
          case 0x0D: /* Display Queue */
            {
            {
              printp( "\n                        -- Input Queue --\n" );
              printp( "\n                        -- Input Queue --\n" );
              printp( "\n        Head Index: %8X     Tail Index: %8X\n\n    ",
              printp( "\n        Head Index: %8X     Tail Index: %8X\n\n    ",
                     (ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index );
                     (ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index );
 
 
              for ( i = 0; i < MAX_RS232_CHARS; ++i )
              for ( i = 0; i < MAX_RS232_CHARS; ++i )
              {
              {
                printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
                printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
 
 
                if ( 15 == (i % 16) )
                if ( 15 == (i % 16) )
                {
                {
                  int j;
                  int j;
 
 
                  printp ( "    " );
                  printp ( "    " );
                  for ( j = i - 15; j <= i; j++ )
                  for ( j = i - 15; j <= i; j++ )
                    {
                    {
                      if ( lan_input_queue.buf[ j ] >= ' ' &&
                      if ( lan_input_queue.buf[ j ] >= ' ' &&
                          lan_input_queue.buf[ j ] < 127 )
                          lan_input_queue.buf[ j ] < 127 )
                        printp ( "%c", lan_input_queue.buf[ j ] );
                        printp ( "%c", lan_input_queue.buf[ j ] );
                      else
                      else
                        printp ( "." );
                        printp ( "." );
                    }
                    }
                  printp( "\n    " );
                  printp( "\n    " );
                }
                }
 
 
                else if ( 7 == (i % 8) )
                else if ( 7 == (i % 8) )
                {
                {
                  printp( " " );
                  printp( " " );
                }
                }
 
 
              }
              }
 
 
              printp( "\n" );
              printp( "\n" );
 
 
              break;
              break;
            }
            }
 
 
          case 0x0F: /* Fetch next character in Queue */
          case 0x0F: /* Fetch next character in Queue */
            {
            {
              c = lan_next_queue_char( &lan_input_queue );
              c = lan_next_queue_char( &lan_input_queue );
 
 
              if ( c )
              if ( c )
              {
              {
                printp( "\n\n  Next Character: " );
                printp( "\n\n  Next Character: " );
                if (  0x21 <= c  &&  c <= 0x7F )
                if (  0x21 <= c  &&  c <= 0x7F )
                {
                {
                  printp( "%c\n\n", (ULONG) c );
                  printp( "%c\n\n", (ULONG) c );
                }
                }
 
 
                else if ( 0x20 == ((UCHAR) c) )
                else if ( 0x20 == ((UCHAR) c) )
                {
                {
                  printp( "<space>\n\n" );
                  printp( "<space>\n\n" );
                }
                }
 
 
                else
                else
                {
                {
                  printp( "%02X\n\n", (ULONG) c );
                  printp( "%02X\n\n", (ULONG) c );
                }
                }
              }
              }
 
 
              else
              else
              {
              {
                printp( "\n\n  Input Queue EMPTY ...\n\n" );
                printp( "\n\n  Input Queue EMPTY ...\n\n" );
              }
              }
 
 
            break;
            break;
            }
            }
 
 
          default:
          default:
            {
            {
            printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
            printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
            not_done_code = BOGUS_P2;
            not_done_code = BOGUS_P2;
            break;
            break;
            }
            }
        }
        }
 
 
      break;
      break;
      }
      }
 
 
 
 
    case LAN_OUT:
    case LAN_OUT:
      {
      {
 
 
        switch ( parm_1 )
        switch ( parm_1 )
        {
        {
 
 
          case 0x0C: /* Clear and Reset Queue */
          case 0x0C: /* Clear and Reset Queue */
            {
            {
              lan_init_queue( &lan_output_queue );
              lan_init_queue( &lan_output_queue );
              printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
              printp( "\n\n  Queue CLEARED/RESET ...\n\n" );
              break;
              break;
            }
            }
 
 
          case 0x0D: /* Display Queue */
          case 0x0D: /* Display Queue */
            {
            {
              printp( "\n                       -- Output Queue --\n" );
              printp( "\n                       -- Output Queue --\n" );
              printp( "\n        Head Index: %8X     Tail Index: %8X\n\n    ",
              printp( "\n        Head Index: %8X     Tail Index: %8X\n\n    ",
                     (ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index );
                     (ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index );
 
 
              for ( i = 0; i < MAX_RS232_CHARS; ++i )
              for ( i = 0; i < MAX_RS232_CHARS; ++i )
              {
              {
                printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
                printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
 
 
                if ( 15 == (i % 16) )
                if ( 15 == (i % 16) )
                {
                {
                  int j;
                  int j;
 
 
                  printp ( "    " );
                  printp ( "    " );
                  for ( j = i - 15; j <= i; j++ )
                  for ( j = i - 15; j <= i; j++ )
                    {
                    {
                      if ( lan_output_queue.buf[ j ] >= ' ' &&
                      if ( lan_output_queue.buf[ j ] >= ' ' &&
                          lan_output_queue.buf[ j ] < 127 )
                          lan_output_queue.buf[ j ] < 127 )
                        printp ( "%c", lan_output_queue.buf[ j ] );
                        printp ( "%c", lan_output_queue.buf[ j ] );
                      else
                      else
                        printp ( "." );
                        printp ( "." );
                    }
                    }
                  printp( "\n    " );
                  printp( "\n    " );
                }
                }
 
 
                else if ( 7 == (i % 8) )
                else if ( 7 == (i % 8) )
                {
                {
                  printp( " " );
                  printp( " " );
                }
                }
 
 
              }
              }
 
 
              printp( "\n" );
              printp( "\n" );
 
 
              break;
              break;
            }
            }
 
 
          case 0x0F: /* Fetch next character in Queue */
          case 0x0F: /* Fetch next character in Queue */
            {
            {
              c = lan_next_queue_char( &lan_output_queue );
              c = lan_next_queue_char( &lan_output_queue );
 
 
              if ( c )
              if ( c )
              {
              {
                printp( "\n\n  Next Character: " );
                printp( "\n\n  Next Character: " );
                if (  0x21 <= c  &&  c <= 0x7F )
                if (  0x21 <= c  &&  c <= 0x7F )
                {
                {
                  printp( "%c\n\n", (ULONG) c );
                  printp( "%c\n\n", (ULONG) c );
                }
                }
 
 
                else if ( 0x20 == c )
                else if ( 0x20 == c )
                {
                {
                  printp( "<space>\n\n" );
                  printp( "<space>\n\n" );
                }
                }
 
 
                else
                else
                {
                {
                  printp( "%02X\n\n", (ULONG) c );
                  printp( "%02X\n\n", (ULONG) c );
                }
                }
              }
              }
 
 
              else
              else
              {
              {
                printp( "\n\n  Input Queue EMPTY ...\n\n" );
                printp( "\n\n  Input Queue EMPTY ...\n\n" );
              }
              }
 
 
              break;
              break;
            }
            }
 
 
          default:
          default:
            {
            {
            printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
            printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
            not_done_code = BOGUS_P2;
            not_done_code = BOGUS_P2;
            break;
            break;
            }
            }
        }
        }
 
 
        break;
        break;
      }
      }
 
 
 
 
    case LAN_ECHO:
    case LAN_ECHO:
      {
      {
 
 
        switch ( parm_1 )
        switch ( parm_1 )
        {
        {
 
 
          case 0x0E:
          case 0x0E:
            {
            {
              test_echo = ENABLED;
              test_echo = ENABLED;
              printp( "\n\n  Test echo ENABLED ...\n\n" );
              printp( "\n\n  Test echo ENABLED ...\n\n" );
              break;
              break;
            }
            }
 
 
          case 0x0D:
          case 0x0D:
            {
            {
              test_echo = DISABLED;
              test_echo = DISABLED;
              printp( "\n\n  Test echo DISABLED ...\n\n" );
              printp( "\n\n  Test echo DISABLED ...\n\n" );
              break;
              break;
            }
            }
 
 
          default:
          default:
            {
            {
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
              printp( "\n\n  *** SYNTAX Error  -  Invalid P2 ...\n\n" );
              not_done_code = BOGUS_P2;
              not_done_code = BOGUS_P2;
              break;
              break;
            }
            }
        }
        }
 
 
        break;
        break;
      }
      }
 
 
 
 
    case LAN_PUTC:
    case LAN_PUTC:
      {
      {
 
 
        if ( 0x20 < parm_1  &&  parm_1 < 0x7F )
        if ( 0x20 < parm_1  &&  parm_1 < 0x7F )
        {
        {
          if ( lan_put_char( (UCHAR) parm_1 ) )
          if ( lan_put_char( (UCHAR) parm_1 ) )
          {
          {
            printp( "\n\n  *** 'lan_put_char' Error ...\n" );
            printp( "\n\n  *** 'lan_put_char' Error ...\n" );
          }
          }
 
 
          else
          else
          {
          {
            printp( "\n\n  O.K. ...\n" );
            printp( "\n\n  O.K. ...\n" );
          }
          }
 
 
        }
        }
 
 
        else
        else
        {
        {
          printp( "\n\n  *** Error  -  character must be in the 0x21-0x7E range ...\n" );
          printp( "\n\n  *** Error  -  character must be in the 0x21-0x7E range ...\n" );
          not_done_code = BOGUS_P2;
          not_done_code = BOGUS_P2;
        }
        }
 
 
        break;
        break;
      }
      }
 
 
/***
/***
    case LAN_WPM:
    case LAN_WPM:
      {
      {
 
 
        if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) )
        if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) )
        {
        {
          printp( "\n  Write to protected memory FAILED ...\n" );
          printp( "\n  Write to protected memory FAILED ...\n" );
        }
        }
 
 
        break;
        break;
      }
      }
***/
***/
 
 
    case 0: /* no argument -- print menu */
    case 0: /* no argument -- print menu */
      {
      {
        lan_util_menu( );
        lan_util_menu( );
        break;
        break;
      }
      }
 
 
 
 
    default:
    default:
      {
      {
        parm_2 = 0;  /* to supress compiler warning with 'LAN_WPM' case disabled */
        parm_2 = 0;  /* to supress compiler warning with 'LAN_WPM' case disabled */
 
 
        printp( "\n\n  *** SYNTAX Error  -  Invalid P1 ...\n\n" );
        printp( "\n\n  *** SYNTAX Error  -  Invalid P1 ...\n\n" );
        not_done_code = BOGUS_P1;
        not_done_code = BOGUS_P1;
        break;
        break;
      }
      }
 
 
 
 
  } /*  End of 'switch ( opcode )'. */
  } /*  End of 'switch ( opcode )'. */
 
 
 
 
return( not_done_code );
return( not_done_code );
}
}
/* end of 'lan_util'
/* end of 'lan_util'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
                  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
                  /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
                  *                                     *
                  *                                     *
                  *         Local Module Functions      *
                  *         Local Module Functions      *
                  *                                     *
                  *                                     *
                  *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
                  *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_reset
 * FUNCTION NAME:   lan_reset
 *
 *
 * DESCRIPTION:     Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the
 * DESCRIPTION:     Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the
 *                  Shared Control 1 area.
 *                  Shared Control 1 area.
 *
 *
 *                             1 _|       ______
 *                             1 _|       ______
 *                                |      |      |
 *                                |      |      |
 *                          Bit   |      |      |
 *                          Bit   |      |      |
 *                                |      |      |
 *                                |      |      |
 *                             0 _|______|      |______
 *                             0 _|______|      |______
 *                                |---------------------> t
 *                                |---------------------> t
 *
 *
 * RETURN VALUE:    None.
 * RETURN VALUE:    None.
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 * NOTES:           H/W configuration requires that a byte in the shared
 * NOTES:           H/W configuration requires that a byte in the shared
 *                  control 1 area must be read before being written.
 *                  control 1 area must be read before being written.
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
static  void    lan_reset( void )
static  void    lan_reset( void )
 
 
{
{
 
 
  while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
  while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
  {
  {
    *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
    *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
  }
  }
 
 
  while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) )
  while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) )
  {
  {
    *P_RST_LAN_UART_REG |= M_RST_LAN_UART;      /* 1 */
    *P_RST_LAN_UART_REG |= M_RST_LAN_UART;      /* 1 */
  }
  }
 
 
  while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
  while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
  {
  {
    *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
    *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;     /* 0 */
  }
  }
 
 
}
}
/* end of 'lan_reset'
/* end of 'lan_reset'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_configure
 * FUNCTION NAME:   lan_configure
 *
 *
 *
 *
 * DESCRIPTION:
 * DESCRIPTION:
 *
 *
 *
 *
 * RETURN VALUE:
 * RETURN VALUE:
 *
 *
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *
 *
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
static  void    lan_configure( void )
static  void    lan_configure( void )
 
 
{
{
 
 
  *P_LAN_CR = UART_CR_RESET_MR_PTR;       /*  Points to MR1.        */
  *P_LAN_CR = UART_CR_RESET_MR_PTR;       /*  Points to MR1.        */
  *P_LAN_CR = UART_CR_RESET_RVCR;         /*  Receiver disabled.    */
  *P_LAN_CR = UART_CR_RESET_RVCR;         /*  Receiver disabled.    */
  *P_LAN_CR = UART_CR_RESET_XMTR;         /*  Transmitter disabled. */
  *P_LAN_CR = UART_CR_RESET_XMTR;         /*  Transmitter disabled. */
  *P_LAN_CR = UART_CR_RESET_ERROR_STATUS;
  *P_LAN_CR = UART_CR_RESET_ERROR_STATUS;
  *P_LAN_CR = UART_CR_RESET_BRK_CHG_INT;
  *P_LAN_CR = UART_CR_RESET_BRK_CHG_INT;
 
 
  *P_LAN_MR1 = DEFAULT_LAN_MR1;
  *P_LAN_MR1 = DEFAULT_LAN_MR1;
  *P_LAN_MR2 = DEFAULT_LAN_MR2;
  *P_LAN_MR2 = DEFAULT_LAN_MR2;
 
 
  *P_LAN_ACR = DEFAULT_LAN_ACR;
  *P_LAN_ACR = DEFAULT_LAN_ACR;
 
 
  *P_LAN_CSR = UART_CSR_BR_9600;
  *P_LAN_CSR = UART_CSR_BR_9600;
  baud_rate_idx = 2;
  baud_rate_idx = 2;
 
 
  *P_LAN_CTUR = DEFAULT_LAN_CTUR;
  *P_LAN_CTUR = DEFAULT_LAN_CTUR;
  *P_LAN_CTLR = DEFAULT_LAN_CTLR;
  *P_LAN_CTLR = DEFAULT_LAN_CTLR;
 
 
  *P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
  *P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
 
 
  lan_shadow_imr = UART_IMR_RxRDY;        /*  Enable only 'RxRDY' interrupt from UART. */
  lan_shadow_imr = UART_IMR_RxRDY;        /*  Enable only 'RxRDY' interrupt from UART. */
  *P_LAN_IMR = lan_shadow_imr;
  *P_LAN_IMR = lan_shadow_imr;
 
 
  tx_by_intr = 0;
  tx_by_intr = 0;
  tx_by_poll = 0;
  tx_by_poll = 0;
 
 
  return;
  return;
}
}
/* end of 'lan_configure'
/* end of 'lan_configure'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_init_queue
 * FUNCTION NAME:   lan_init_queue
 *
 *
 * DESCRIPTION:
 * DESCRIPTION:
 *
 *
 * RETURN VALUE:    None.
 * RETURN VALUE:    None.
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
static  void    lan_init_queue( T_RS232_QUEUE *p_queue )
static  void    lan_init_queue( T_RS232_QUEUE *p_queue )
 
 
{
{
  long i;
  long i;
 
 
    /*
    /*
    *   We set "head" equal to "tail" implying the queue is empty,
    *   We set "head" equal to "tail" implying the queue is empty,
    *   BUT the "head" and "tail" should each point to valid queue
    *   BUT the "head" and "tail" should each point to valid queue
    *   positions.
    *   positions.
    */
    */
 
 
  p_queue->head_index = 0;
  p_queue->head_index = 0;
  p_queue->tail_index = 0;
  p_queue->tail_index = 0;
 
 
  p_queue->overflows = 0;
  p_queue->overflows = 0;
 
 
  p_queue->gdb_packet_start = -1;
  p_queue->gdb_packet_start = -1;
  p_queue->gdb_packet_end   = -1;
  p_queue->gdb_packet_end   = -1;
 
 
  p_queue->gdb_packet_csum1 = -1;
  p_queue->gdb_packet_csum1 = -1;
  p_queue->gdb_packet_csum2 = -1;
  p_queue->gdb_packet_csum2 = -1;
 
 
  for ( i = 0; i < MAX_RS232_CHARS; ++i )
  for ( i = 0; i < MAX_RS232_CHARS; ++i )
  {
  {
    p_queue->buf[ i ] = 0;
    p_queue->buf[ i ] = 0;
  }
  }
 
 
  return;
  return;
}
}
/* end of 'lan_init_queue'
/* end of 'lan_init_queue'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_add_to_queue
 * FUNCTION NAME:   lan_add_to_queue
 *
 *
 *
 *
 * DESCRIPTION:     Adds the specified character to the tail of the
 * DESCRIPTION:     Adds the specified character to the tail of the
 *                  specified queue.  Observes "oldest thrown on floor"
 *                  specified queue.  Observes "oldest thrown on floor"
 *                  rule (i.e. the queue is allowed to "wrap" and the
 *                  rule (i.e. the queue is allowed to "wrap" and the
 *                  input character is unconditionally placed at the
 *                  input character is unconditionally placed at the
 *                  tail of the queue.
 *                  tail of the queue.
 *
 *
 *
 *
 * RETURN VALUE:    None.
 * RETURN VALUE:    None.
 *
 *
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
static  void    lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
static  void    lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
 
 
{
{
 
 
  if ( p_queue )    /*  Sanity check. */
  if ( p_queue )    /*  Sanity check. */
  {
  {
 
 
    if ( c & 0x000000FF )   /*  We don't allow NULL characters to be added to a queue.  */
    if ( c & 0x000000FF )   /*  We don't allow NULL characters to be added to a queue.  */
    {
    {
        /*  Insert the new character at the tail of the queue.  */
        /*  Insert the new character at the tail of the queue.  */
 
 
      p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
      p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
 
 
        /*  Increment the tail index. */
        /*  Increment the tail index. */
 
 
      if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
      if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
      {
      {
        p_queue->tail_index = 0;
        p_queue->tail_index = 0;
      }
      }
 
 
        /*  Check for wrapping (i.e. overflow). */
        /*  Check for wrapping (i.e. overflow). */
 
 
      if ( p_queue->head_index == p_queue->tail_index )
      if ( p_queue->head_index == p_queue->tail_index )
      {
      {
          /*  If the tail has caught up to the head record the overflow . . . */
          /*  If the tail has caught up to the head record the overflow . . . */
 
 
        ++(p_queue->overflows);
        ++(p_queue->overflows);
 
 
          /*  . . . then increment the head index.  */
          /*  . . . then increment the head index.  */
 
 
        if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
        if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
        {
        {
          p_queue->head_index = 0;
          p_queue->head_index = 0;
        }
        }
 
 
      }
      }
 
 
    } /*  End of 'if ( c & 0x000000FF )'. */
    } /*  End of 'if ( c & 0x000000FF )'. */
 
 
  } /*  End of 'if ( p_queue )'.  */
  } /*  End of 'if ( p_queue )'.  */
 
 
 
 
  return;
  return;
}
}
/* end of 'lan_add_to_queue'
/* end of 'lan_add_to_queue'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_next_queue_char
 * FUNCTION NAME:   lan_next_queue_char
 *
 *
 * DESCRIPTION:
 * DESCRIPTION:
 *
 *
 * RETURN VALUE:
 * RETURN VALUE:
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
static  UCHAR   lan_next_queue_char( T_RS232_QUEUE *p_queue )
static  UCHAR   lan_next_queue_char( T_RS232_QUEUE *p_queue )
 
 
{
{
  UCHAR   c;
  UCHAR   c;
 
 
 
 
  c = 0;
  c = 0;
 
 
  if ( p_queue )
  if ( p_queue )
  {
  {
 
 
    if ( p_queue->head_index != p_queue->tail_index )
    if ( p_queue->head_index != p_queue->tail_index )
    {
    {
        /*  Return the 'oldest' character in the queue. */
        /*  Return the 'oldest' character in the queue. */
 
 
      c = p_queue->buf[ p_queue->head_index ];
      c = p_queue->buf[ p_queue->head_index ];
 
 
        /*  Increment the head index. */
        /*  Increment the head index. */
 
 
      if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
      if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
      {
      {
        p_queue->head_index = 0;
        p_queue->head_index = 0;
      }
      }
 
 
    }
    }
 
 
  } /*  End of 'if ( p_queue )'.  */
  } /*  End of 'if ( p_queue )'.  */
 
 
 
 
  return( c );
  return( c );
}
}
 
 
/* end of 'lan_next_queue_char'
/* end of 'lan_next_queue_char'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   lan_util_menu
 * FUNCTION NAME:   lan_util_menu
 *
 *
 * DESCRIPTION:     Prints out a brief help on the LAN UART control utility.
 * DESCRIPTION:     Prints out a brief help on the LAN UART control utility.
 *
 *
 * RETURN VALUE:    None.
 * RETURN VALUE:    None.
 *
 *
 * USED GLOBAL VARIABLES: None.
 * USED GLOBAL VARIABLES: None.
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None.
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None.
 *
 *
 * NOTES: None.
 * NOTES: None.
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
static  void    lan_util_menu( void )
static  void    lan_util_menu( void )
 
 
{
{
 
 
  /*
  /*
   * Multiply calling printp() below is made due to the limitations
   * Multiply calling printp() below is made due to the limitations
   * of printp(), incapable of handling long formatting constants:
   * of printp(), incapable of handling long formatting constants:
   */
   */
 
 
 printp( "\n               -- Options --\n\n" );
 printp( "\n               -- Options --\n\n" );
 
 
  printp( "    %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE );
 
 
  printp( "    %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );
 
 
/***
/***
  printp( "    %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );
  printp( "    %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );
***/
***/
 
 
  printp( "    <rate>:  4800  <mode>:  E - enable   <action>:  C - clear/reset\n" );
  printp( "    <rate>:  4800  <mode>:  E - enable   <action>:  C - clear/reset\n" );
  printp( "             9600           D - disable             D - display\n" );
  printp( "             9600           D - disable             D - display\n" );
  printp( "            19200                                   F - fetch next char\n" );
  printp( "            19200                                   F - fetch next char\n" );
  printp( "            38400\n" );
  printp( "            38400\n" );
}
}
/* end of 'lan_util_menu'
/* end of 'lan_util_menu'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
/* Thu Feb  5 17:14:41 EST 1998  CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */
/* Thu Feb  5 17:14:41 EST 1998  CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */
 
 
 
 
static  long    get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
static  long    get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
 
 
{
{
 
 
  /* Now to detect when we've got a gdb packet... */
  /* Now to detect when we've got a gdb packet... */
 
 
  if ( '$' == c ) { /* char marks beginning of a packet */
  if ( '$' == c ) { /* char marks beginning of a packet */
 
 
      if ( -1 != p_input_q->gdb_packet_start ||
      if ( -1 != p_input_q->gdb_packet_start ||
           -1 != p_input_q->gdb_packet_end   ||
           -1 != p_input_q->gdb_packet_end   ||
           -1 != p_input_q->gdb_packet_csum1 ||
           -1 != p_input_q->gdb_packet_csum1 ||
           -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
           -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
 
 
        /* NEW: Actually, this probably means that we muffed a packet,
        /* NEW: Actually, this probably means that we muffed a packet,
           and GDB has already resent it.  The thing to do now is to
           and GDB has already resent it.  The thing to do now is to
           throw away the one we WERE working on, but immediately start
           throw away the one we WERE working on, but immediately start
           accepting the new one.  Don't NAK, or GDB will have to try
           accepting the new one.  Don't NAK, or GDB will have to try
           and send it yet a third time!  */
           and send it yet a third time!  */
 
 
          /*NACK_PKT( );*/    /*<ETHERNET>*/
          /*NACK_PKT( );*/    /*<ETHERNET>*/
          discard_packet( );                    /* throw away old packet */
          discard_packet( );                    /* throw away old packet */
          lan_add_to_queue ('$', p_input_q);    /* put the new "$" back in */
          lan_add_to_queue ('$', p_input_q);    /* put the new "$" back in */
          return 0;
          return 0;
      } else {          /* match new "$" */
      } else {          /* match new "$" */
        p_input_q->gdb_packet_start = p_input_q->tail_index;
        p_input_q->gdb_packet_start = p_input_q->tail_index;
        p_input_q->gdb_packet_end =
        p_input_q->gdb_packet_end =
          p_input_q->gdb_packet_csum1 =
          p_input_q->gdb_packet_csum1 =
            p_input_q->gdb_packet_csum2 = -1;
            p_input_q->gdb_packet_csum2 = -1;
      }
      }
    } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */
    } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */
 
 
      if ( -1 == p_input_q->gdb_packet_start ||
      if ( -1 == p_input_q->gdb_packet_start ||
           -1 != p_input_q->gdb_packet_end   ||
           -1 != p_input_q->gdb_packet_end   ||
           -1 != p_input_q->gdb_packet_csum1 ||
           -1 != p_input_q->gdb_packet_csum1 ||
           -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
           -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
 
 
          /* Garbled packet.  Discard, but do not NAK.  */
          /* Garbled packet.  Discard, but do not NAK.  */
 
 
          /*NACK_PKT( );*/    /*<ETHERNET>*/
          /*NACK_PKT( );*/    /*<ETHERNET>*/
          discard_packet( );
          discard_packet( );
          return -1;
          return -1;
      }
      }
      p_input_q->gdb_packet_end = p_input_q->tail_index;
      p_input_q->gdb_packet_end = p_input_q->tail_index;
      p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1;
      p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1;
 
 
  } else if ( -1 != p_input_q->gdb_packet_start &&
  } else if ( -1 != p_input_q->gdb_packet_start &&
              -1 != p_input_q->gdb_packet_end) {
              -1 != p_input_q->gdb_packet_end) {
 
 
    if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */
    if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */
 
 
      if ( -1 == p_input_q->gdb_packet_csum1 &&
      if ( -1 == p_input_q->gdb_packet_csum1 &&
           LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) ==
           LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) ==
           p_input_q->tail_index ) {
           p_input_q->tail_index ) {
 
 
        /* first checksum digit */
        /* first checksum digit */
 
 
        p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
        p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
        p_input_q->gdb_packet_csum2 = -1;
        p_input_q->gdb_packet_csum2 = -1;
 
 
      } else if ( -1 == p_input_q->gdb_packet_csum2 &&
      } else if ( -1 == p_input_q->gdb_packet_csum2 &&
                  LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) ==
                  LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) ==
                  p_input_q->tail_index ) {
                  p_input_q->tail_index ) {
 
 
        /* second checksum digit: packet is complete! */
        /* second checksum digit: packet is complete! */
 
 
        p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
        p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
        getpacket();    /* got a packet -- extract it */
        getpacket();    /* got a packet -- extract it */
 
 
      } else { /* probably can't happen (um... three hex digits?) */
      } else { /* probably can't happen (um... three hex digits?) */
 
 
        /* PROTOCOL ERROR */
        /* PROTOCOL ERROR */
        /* Not sure how this can happen, but ...
        /* Not sure how this can happen, but ...
           discard it, but do not NAK it.  */
           discard it, but do not NAK it.  */
        /*NACK_PKT( );*/    /*<ETHERNET>*/
        /*NACK_PKT( );*/    /*<ETHERNET>*/
        discard_packet( );
        discard_packet( );
        return -1;
        return -1;
      }
      }
 
 
    } else { /* '#' followed by non-hex char */
    } else { /* '#' followed by non-hex char */
 
 
      /* PROTOCOL ERROR */
      /* PROTOCOL ERROR */
      /* Bad packet -- discard but do not NAK */
      /* Bad packet -- discard but do not NAK */
      /*NACK_PKT( );*/    /*<ETHERNET>*/
      /*NACK_PKT( );*/    /*<ETHERNET>*/
      discard_packet( );
      discard_packet( );
      return -1;
      return -1;
    }
    }
  }
  }
 
 
  return 0;
  return 0;
}
}
 
 
 
 
 
 
 
 
#ifdef    STANDALONE
#ifdef    STANDALONE
 
 
/* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone
/* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone
   stand-alone                                                 stand-alone
   stand-alone                                                 stand-alone
   stand-alone Enable stand-alone build, for ease of debugging stand-alone
   stand-alone Enable stand-alone build, for ease of debugging stand-alone
   stand-alone                                                 stand-alone
   stand-alone                                                 stand-alone
   stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */
   stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */
 
 
long write_to_protected_mem (addr, word)
long write_to_protected_mem (addr, word)
     void *addr;
     void *addr;
     unsigned short word;
     unsigned short word;
{
{
  return 0;
  return 0;
}
}
 
 
 
 
char dummy_memory[0x4000];
char dummy_memory[0x4000];
 
 
int main ( void )
int main ( void )
{
{
  long c;
  long c;
 
 
  lan_init_queue( &lan_input_queue );
  lan_init_queue( &lan_input_queue );
  printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) );
  printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) );
  printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory);
  printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory);
  while ( (c = getc( stdin ) ) != EOF )
  while ( (c = getc( stdin ) ) != EOF )
    {
    {
      if ( c == '\\' )  /* escape char */
      if ( c == '\\' )  /* escape char */
        break;
        break;
 
 
      lan_add_to_queue( c, &lan_input_queue );
      lan_add_to_queue( c, &lan_input_queue );
      get_gdb_input (c, &lan_input_queue);
      get_gdb_input (c, &lan_input_queue);
      fflush( stdout );
      fflush( stdout );
    }
    }
 
 
  printf( "Goodbye!\n" );
  printf( "Goodbye!\n" );
  exit( 0 );
  exit( 0 );
}
}
 
 
#define SRAM_START      ((void *) (&dummy_memory[0] + 0x00000000))
#define SRAM_START      ((void *) (&dummy_memory[0] + 0x00000000))
#define SRAM_END        ((void *) (&dummy_memory[0] + 0x00000400))
#define SRAM_END        ((void *) (&dummy_memory[0] + 0x00000400))
 
 
#define RO_AREA_START   ((void *) (&dummy_memory[0] + 0x00000100))
#define RO_AREA_START   ((void *) (&dummy_memory[0] + 0x00000100))
#define RO_AREA_END     ((void *) (&dummy_memory[0] + 0x00000300))
#define RO_AREA_END     ((void *) (&dummy_memory[0] + 0x00000300))
 
 
#define NVD_START       ((void *) (&dummy_memory[0] + 0x00003000))
#define NVD_START       ((void *) (&dummy_memory[0] + 0x00003000))
#define NVD_END         ((void *) (&dummy_memory[0] + 0x00003100))
#define NVD_END         ((void *) (&dummy_memory[0] + 0x00003100))
 
 
#else   /* normal stub (not stand-alone) */
#else   /* normal stub (not stand-alone) */
 
 
#define SRAM_START              ((void *) 0x00000000)
#define SRAM_START              ((void *) 0x00000000)
#define SRAM_END                ((void *) 0x00400000)
#define SRAM_END                ((void *) 0x00400000)
 
 
#define RO_AREA_START           ((void *) 0x00100000)
#define RO_AREA_START           ((void *) 0x00100000)
#define RO_AREA_END             ((void *) 0x00300000)
#define RO_AREA_END             ((void *) 0x00300000)
 
 
#define NVD_START               ((void *) 0x03000000)
#define NVD_START               ((void *) 0x03000000)
#define NVD_END                 ((void *) 0x03100000)
#define NVD_END                 ((void *) 0x03100000)
 
 
#endif /* STANDALONE */
#endif /* STANDALONE */
 
 
 
 
 
 
 
 
/* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb
/* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb
   gdb                                                                 gdb
   gdb                                                                 gdb
   gdb                Here begins the gdb stub section.                gdb
   gdb                Here begins the gdb stub section.                gdb
   gdb          The following functions were added by Cygnus,          gdb
   gdb          The following functions were added by Cygnus,          gdb
   gdb             to make this thing act like a gdb stub.             gdb
   gdb             to make this thing act like a gdb stub.             gdb
   gdb                                                                 gdb
   gdb                                                                 gdb
   gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb */
   gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb */
 
 
 
 
/* ------------------- global defines and data decl's -------------------- */
/* ------------------- global defines and data decl's -------------------- */
 
 
#define hexchars        "0123456789abcdef"
#define hexchars        "0123456789abcdef"
 
 
/* there are 180 bytes of registers on a 68020 w/68881      */
/* there are 180 bytes of registers on a 68020 w/68881      */
/* many of the fpa registers are 12 byte (96 bit) registers */
/* many of the fpa registers are 12 byte (96 bit) registers */
#define NUMREGBYTES          180
#define NUMREGBYTES          180
#define NUMREGS              29
#define NUMREGS              29
#define REGISTER_BYTE(regno) regno
#define REGISTER_BYTE(regno) regno
 
 
enum regnames { D0, D1, D2, D3, D4, D5, D6, D7,
enum regnames { D0, D1, D2, D3, D4, D5, D6, D7,
                A0, A1, A2, A3, A4, A5, A6, A7,
                A0, A1, A2, A3, A4, A5, A6, A7,
                PS, PC,
                PS, PC,
                FP0, FP1,
                FP0, FP1,
                FP2, FP3,
                FP2, FP3,
                FP4, FP5,
                FP4, FP5,
                FP6, FP7,
                FP6, FP7,
                FPCONTROL, FPSTATUS, FPIADDR
                FPCONTROL, FPSTATUS, FPIADDR
              };
              };
 
 
unsigned long registers[NUMREGBYTES/4];
unsigned long registers[NUMREGBYTES/4];
 
 
static long remote_debug;
static long remote_debug;
 
 
#define BUFMAX                MAX_IO_BUF_SIZE
#define BUFMAX                MAX_IO_BUF_SIZE
static char inbuffer[BUFMAX], outbuffer[BUFMAX];
static char inbuffer[BUFMAX], outbuffer[BUFMAX];
static char spare_buffer[BUFMAX];
static char spare_buffer[BUFMAX];
 
 
 
 
struct stub_trace_frame
struct stub_trace_frame
{
{
  int                    valid;
  int                    valid;
  unsigned long          frame_id;
  unsigned long          frame_id;
  unsigned long          tdp_id;
  unsigned long          tdp_id;
  FRAME_DEF             *frame_data;
  FRAME_DEF             *frame_data;
  COLLECTION_FORMAT_DEF *format;
  COLLECTION_FORMAT_DEF *format;
  unsigned long          traceregs[NUMREGBYTES/4];
  unsigned long          traceregs[NUMREGBYTES/4];
  unsigned char         *stack_data;
  unsigned char         *stack_data;
  unsigned char         *memrange_data;
  unsigned char         *memrange_data;
} curframe;
} curframe;
 
 
/* -------------------      function prototypes       -------------------- */
/* -------------------      function prototypes       -------------------- */
 
 
void handle_request ( char * );
void handle_request ( char * );
 
 
/* -------------------         Implementation         -------------------- */
/* -------------------         Implementation         -------------------- */
 
 
static void
static void
discard_packet( void )
discard_packet( void )
{
{
  lan_input_queue.head_index = lan_input_queue.tail_index;
  lan_input_queue.head_index = lan_input_queue.tail_index;
 
 
  lan_input_queue.gdb_packet_start =
  lan_input_queue.gdb_packet_start =
    lan_input_queue.gdb_packet_end   =
    lan_input_queue.gdb_packet_end   =
      lan_input_queue.gdb_packet_csum1 =
      lan_input_queue.gdb_packet_csum1 =
        lan_input_queue.gdb_packet_csum2 = -1;
        lan_input_queue.gdb_packet_csum2 = -1;
}
}
 
 
/* Utility function: convert an ASCII isxdigit to a hex nybble */
/* Utility function: convert an ASCII isxdigit to a hex nybble */
 
 
static long
static long
hex( char ch )
hex( char ch )
{
{
  if ( (ch >= 'A') && (ch <= 'F') )
  if ( (ch >= 'A') && (ch <= 'F') )
    return ch - 'A' + 10;
    return ch - 'A' + 10;
  if ( (ch >= 'a') && (ch <= 'f') )
  if ( (ch >= 'a') && (ch <= 'f') )
    return ch - 'a' + 10;
    return ch - 'a' + 10;
  if ( (ch >= '0') && (ch <= '9') )
  if ( (ch >= '0') && (ch <= '9') )
    return ch - '0';
    return ch - '0';
  return -1;
  return -1;
}
}
 
 
static void
static void
getpacket( void )
getpacket( void )
{
{
  unsigned char our_checksum, their_checksum;
  unsigned char our_checksum, their_checksum;
  char *copy = inbuffer;
  char *copy = inbuffer;
  unsigned char c;
  unsigned char c;
 
 
  our_checksum = 0;
  our_checksum = 0;
 
 
  /* first find the '$' */
  /* first find the '$' */
  while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
  while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
    if (c == 0)                 /* ??? Protocol error? (paranoia) */
    if (c == 0)                 /* ??? Protocol error? (paranoia) */
      {
      {
          /* PROTOCOL ERROR (missing '$') */
          /* PROTOCOL ERROR (missing '$') */
        /*NACK_PKT( );*/    /*<ETHERNET>*/
        /*NACK_PKT( );*/    /*<ETHERNET>*/
        return;
        return;
      }
      }
 
 
  /* Now copy the message (up to the '#') */
  /* Now copy the message (up to the '#') */
  for (c = lan_next_queue_char ( &lan_input_queue );    /* skip  the   '$' */
  for (c = lan_next_queue_char ( &lan_input_queue );    /* skip  the   '$' */
       c != 0 && c != '#';              /* stop at the '#' */
       c != 0 && c != '#';              /* stop at the '#' */
       c = lan_next_queue_char ( &lan_input_queue ))
       c = lan_next_queue_char ( &lan_input_queue ))
    {
    {
      *copy++ = c;
      *copy++ = c;
      our_checksum += c;
      our_checksum += c;
    }
    }
  *copy++ = '\0';               /* terminate the copy */
  *copy++ = '\0';               /* terminate the copy */
 
 
  if (c == 0)                   /* ??? Protocol error? (paranoia) */
  if (c == 0)                   /* ??? Protocol error? (paranoia) */
    {
    {
        /* PROTOCOL ERROR (missing '#') */
        /* PROTOCOL ERROR (missing '#') */
      /*NACK_PKT( );*/    /*<ETHERNET>*/
      /*NACK_PKT( );*/    /*<ETHERNET>*/
      return;
      return;
    }
    }
  their_checksum  = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
  their_checksum  = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
  their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
  their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
 
 
  /* Now reset the queue packet-recognition bits */
  /* Now reset the queue packet-recognition bits */
  discard_packet( );
  discard_packet( );
 
 
  if ( remote_debug ||
  if ( remote_debug ||
      our_checksum == their_checksum )
      our_checksum == their_checksum )
    {
    {
      ACK_PKT( );      /* good packet */
      ACK_PKT( );      /* good packet */
      /* Parse and process the packet */
      /* Parse and process the packet */
      handle_request( inbuffer );
      handle_request( inbuffer );
    }
    }
  else
  else
      /* PROTOCOL ERROR (bad check sum) */
      /* PROTOCOL ERROR (bad check sum) */
    NACK_PKT( );
    NACK_PKT( );
}
}
 
 
/* EMC will provide a better implementation
/* EMC will provide a better implementation
   (perhaps just of LAN_PUT_CHAR) that does not block.
   (perhaps just of LAN_PUT_CHAR) that does not block.
   For now, this works.  */
   For now, this works.  */
 
 
 
 
static void
static void
putpacket( char *str )
putpacket( char *str )
{
{
  unsigned char checksum;
  unsigned char checksum;
 
 
  /* '$'<packet>'#'<checksum> */
  /* '$'<packet>'#'<checksum> */
 
 
  if ( VIA_ETHERNET == gdb_host_comm )
  if ( VIA_ETHERNET == gdb_host_comm )
  {
  {
    char  *p_out;
    char  *p_out;
    long  length;
    long  length;
 
 
    p_out  = eth_outbuffer;
    p_out  = eth_outbuffer;
    length = 0;
    length = 0;
 
 
 
 
    if ( YES == gdb_cat_ack )
    if ( YES == gdb_cat_ack )
    {
    {
      *p_out++ = '+';
      *p_out++ = '+';
      ++length;
      ++length;
    }
    }
 
 
    gdb_cat_ack = NO;
    gdb_cat_ack = NO;
 
 
 
 
    *p_out++ = '$';
    *p_out++ = '$';
    ++length;
    ++length;
 
 
    checksum = 0;
    checksum = 0;
 
 
    while ( *str )
    while ( *str )
    {
    {
      *p_out++ = *str;
      *p_out++ = *str;
      ++length;
      ++length;
      checksum += *str++;
      checksum += *str++;
    }
    }
 
 
    *p_out++ = '#';
    *p_out++ = '#';
    *p_out++ = hexchars[checksum >> 4];
    *p_out++ = hexchars[checksum >> 4];
    *p_out = hexchars[checksum % 16];
    *p_out = hexchars[checksum % 16];
    length += 3;
    length += 3;
 
 
    eth_to_gdb( (UCHAR *) eth_outbuffer, length );
    eth_to_gdb( (UCHAR *) eth_outbuffer, length );
  }
  }
 
 
  else
  else
  {
  {
 
 
      /* via RS-232 */
      /* via RS-232 */
    do {
    do {
      LAN_PUT_CHAR( '$' );
      LAN_PUT_CHAR( '$' );
      checksum = 0;
      checksum = 0;
 
 
      while ( *str )
      while ( *str )
        {
        {
          LAN_PUT_CHAR( *str );
          LAN_PUT_CHAR( *str );
          checksum += *str++;
          checksum += *str++;
        }
        }
 
 
      LAN_PUT_CHAR( '#' );
      LAN_PUT_CHAR( '#' );
      LAN_PUT_CHAR( hexchars[checksum >> 4] );
      LAN_PUT_CHAR( hexchars[checksum >> 4] );
      LAN_PUT_CHAR( hexchars[checksum % 16] );
      LAN_PUT_CHAR( hexchars[checksum % 16] );
    } while ( 0 /* get_debug_char( ) != '+' */ );
    } while ( 0 /* get_debug_char( ) != '+' */ );
    /* XXX FIXME: not waiting for the ack. */
    /* XXX FIXME: not waiting for the ack. */
 
 
  }
  }
 
 
}
}
 
 
 
 
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
 *
 *
 * FUNCTION NAME:   gdb_get_eth_input
 * FUNCTION NAME:   gdb_get_eth_input
 *
 *
 *
 *
 * DESCRIPTION:
 * DESCRIPTION:
 *
 *
 *
 *
 * RETURN VALUE:    None.
 * RETURN VALUE:    None.
 *
 *
 *
 *
 * USED GLOBAL VARIABLES:
 * USED GLOBAL VARIABLES:
 *
 *
 *
 *
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
 *
 *
 *
 *
 * NOTES:
 * NOTES:
 *
 *
 *
 *
 *---------------------------------------------------------------------------*/
 *---------------------------------------------------------------------------*/
 
 
void    gdb_get_eth_input( unsigned char *buf, long length )
void    gdb_get_eth_input( unsigned char *buf, long length )
 
 
{
{
 
 
  gdb_host_comm = VIA_ETHERNET;
  gdb_host_comm = VIA_ETHERNET;
 
 
  for ( ; 0 < length; ++buf, --length)
  for ( ; 0 < length; ++buf, --length)
  {
  {
 
 
    if ( *buf == CONTROL_C )
    if ( *buf == CONTROL_C )
    {
    {
        /* can't stop the target, but we can tell gdb to stop waiting... */
        /* can't stop the target, but we can tell gdb to stop waiting... */
      discard_packet( );
      discard_packet( );
      putpacket( "S03" );       /* send back SIGINT to the debugger */
      putpacket( "S03" );       /* send back SIGINT to the debugger */
    }
    }
 
 
    else
    else
    {
    {
      lan_add_to_queue( (long) *buf, &lan_input_queue );
      lan_add_to_queue( (long) *buf, &lan_input_queue );
      get_gdb_input( (long) *buf, &lan_input_queue );
      get_gdb_input( (long) *buf, &lan_input_queue );
    }
    }
 
 
  }
  }
 
 
 
 
  return;
  return;
}
}
/* end of 'gdb_get_eth_input'
/* end of 'gdb_get_eth_input'
 *===========================================================================*/
 *===========================================================================*/
 
 
 
 
 
 
 
 
/* STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT
/* STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT
   Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
   Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
 
 
   Dear reader:
   Dear reader:
       This code is based on the premise that if GDB receives a packet
       This code is based on the premise that if GDB receives a packet
   from the stub that begins with the character CAPITAL-OH, GDB will
   from the stub that begins with the character CAPITAL-OH, GDB will
   echo the rest of the packet to GDB's console / stdout.  This gives
   echo the rest of the packet to GDB's console / stdout.  This gives
   the stub a way to send a message directly to the user.  In practice,
   the stub a way to send a message directly to the user.  In practice,
   (as currently implemented), GDB will only accept such a packet when
   (as currently implemented), GDB will only accept such a packet when
   it believes the target to be running (ie. when you say STEP or
   it believes the target to be running (ie. when you say STEP or
   CONTINUE); at other times it does not expect it.  This will probably
   CONTINUE); at other times it does not expect it.  This will probably
   change as a side effect of the "asynchronous" behavior.
   change as a side effect of the "asynchronous" behavior.
 
 
   Functions: gdb_putchar(char ch)
   Functions: gdb_putchar(char ch)
              gdb_write(char *str, int len)
              gdb_write(char *str, int len)
              gdb_puts(char *str)
              gdb_puts(char *str)
              gdb_error(char *format, char *parm)
              gdb_error(char *format, char *parm)
 */
 */
 
 
#if 0 /* avoid compiler warning while this is not used */
#if 0 /* avoid compiler warning while this is not used */
 
 
/* Function: gdb_putchar(int)
/* Function: gdb_putchar(int)
   Make gdb write a char to stdout.
   Make gdb write a char to stdout.
   Returns: the char */
   Returns: the char */
 
 
static int
static int
gdb_putchar( long ch )
gdb_putchar( long ch )
{
{
  char buf[4];
  char buf[4];
 
 
  buf[0] = 'O';
  buf[0] = 'O';
  buf[1] = hexchars[ch >> 4];
  buf[1] = hexchars[ch >> 4];
  buf[2] = hexchars[ch & 0x0F];
  buf[2] = hexchars[ch & 0x0F];
  buf[3] = 0;
  buf[3] = 0;
  putpacket( buf );
  putpacket( buf );
  return ch;
  return ch;
}
}
#endif
#endif
 
 
/* Function: gdb_write(char *, int)
/* Function: gdb_write(char *, int)
   Make gdb write n bytes to stdout (not assumed to be null-terminated).
   Make gdb write n bytes to stdout (not assumed to be null-terminated).
   Returns: number of bytes written */
   Returns: number of bytes written */
 
 
static int
static int
gdb_write( char *data, long len )
gdb_write( char *data, long len )
{
{
  char *buf, *cpy;
  char *buf, *cpy;
  long i;
  long i;
 
 
  buf = outbuffer;
  buf = outbuffer;
  buf[0] = 'O';
  buf[0] = 'O';
  i = 0;
  i = 0;
  while ( i < len )
  while ( i < len )
    {
    {
      for ( cpy = buf+1;
      for ( cpy = buf+1;
           i < len && cpy < buf + BUFMAX - 3;
           i < len && cpy < buf + BUFMAX - 3;
           i++ )
           i++ )
        {
        {
          *cpy++ = hexchars[data[i] >> 4];
          *cpy++ = hexchars[data[i] >> 4];
          *cpy++ = hexchars[data[i] & 0x0F];
          *cpy++ = hexchars[data[i] & 0x0F];
        }
        }
      *cpy = 0;
      *cpy = 0;
      putpacket( buf );
      putpacket( buf );
    }
    }
  return len;
  return len;
}
}
 
 
/* Function: gdb_puts(char *)
/* Function: gdb_puts(char *)
   Make gdb write a null-terminated string to stdout.
   Make gdb write a null-terminated string to stdout.
   Returns: the length of the string */
   Returns: the length of the string */
 
 
static int
static int
gdb_puts( char *str )
gdb_puts( char *str )
{
{
  return gdb_write( str, strlen( str ) );
  return gdb_write( str, strlen( str ) );
}
}
 
 
/* Function: gdb_error(char *, char *)
/* Function: gdb_error(char *, char *)
   Send an error message to gdb's stdout.
   Send an error message to gdb's stdout.
   First string may have 1 (one) optional "%s" in it, which
   First string may have 1 (one) optional "%s" in it, which
   will cause the optional second string to be inserted.  */
   will cause the optional second string to be inserted.  */
 
 
#if 0
#if 0
static void
static void
gdb_error( char *format, char *parm )
gdb_error( char *format, char *parm )
{
{
  static char buf[400];
  static char buf[400];
  char *cpy;
  char *cpy;
  long len;
  long len;
 
 
  if ( remote_debug )
  if ( remote_debug )
    {
    {
      if ( format && *format )
      if ( format && *format )
        len = strlen( format );
        len = strlen( format );
      else
      else
        return;             /* empty input */
        return;             /* empty input */
 
 
      if ( parm && *parm )
      if ( parm && *parm )
        len += strlen( parm );
        len += strlen( parm );
 
 
      for ( cpy = buf; *format; )
      for ( cpy = buf; *format; )
        {
        {
          if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */
          if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */
            {
            {
              format += 2;          /* advance two chars instead of just one */
              format += 2;          /* advance two chars instead of just one */
              while ( parm && *parm )
              while ( parm && *parm )
                *cpy++ = *parm++;
                *cpy++ = *parm++;
            }
            }
          else
          else
            *cpy++ = *format++;
            *cpy++ = *format++;
        }
        }
      *cpy = '\0';
      *cpy = '\0';
      gdb_puts( buf );
      gdb_puts( buf );
    }
    }
}
}
#endif
#endif
 
 
static void gdb_note (char *, int);
static void gdb_note (char *, int);
static int  error_ret (int, char *, int);
static int  error_ret (int, char *, int);
 
 
static unsigned long
static unsigned long
elinum_to_index (unsigned long elinum)
elinum_to_index (unsigned long elinum)
{
{
  if ((elinum & 0xf0) == 0xd0)
  if ((elinum & 0xf0) == 0xd0)
    return (elinum & 0x0f);
    return (elinum & 0x0f);
  else if ((elinum & 0xf0) == 0xa0)
  else if ((elinum & 0xf0) == 0xa0)
    return (elinum & 0x0f) + 8;
    return (elinum & 0x0f) + 8;
  else
  else
    return -1;
    return -1;
}
}
 
 
static long
static long
index_to_elinum (unsigned long index)
index_to_elinum (unsigned long index)
{
{
  if (index <= 7)
  if (index <= 7)
    return index + 0xd0;
    return index + 0xd0;
  else if (index <= 15)
  else if (index <= 15)
    return (index - 8) + 0xa0;
    return (index - 8) + 0xa0;
  else
  else
    return -1;
    return -1;
}
}
 
 
 
 
/*
/*
  READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
  READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
 
 
  The following code pertains to reading memory from the target.
  The following code pertains to reading memory from the target.
  Some sort of exception handling should be added to make it safe.
  Some sort of exception handling should be added to make it safe.
 
 
  READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
  READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
 
 
  Safe Memory Access:
  Safe Memory Access:
 
 
  All reads and writes into the application's memory will pass thru
  All reads and writes into the application's memory will pass thru
  get_uchar() or set_uchar(), which check whether accessing their
  get_uchar() or set_uchar(), which check whether accessing their
  argument is legal before actual access (thus avoiding a bus error).
  argument is legal before actual access (thus avoiding a bus error).
 
 
  */
  */
 
 
enum { SUCCESS = 0, FAIL = -1 };
enum { SUCCESS = 0, FAIL = -1 };
 
 
#if 0
#if 0
static long get_uchar ( const unsigned char * );
static long get_uchar ( const unsigned char * );
#endif
#endif
static long set_uchar ( unsigned char *, unsigned char );
static long set_uchar ( unsigned char *, unsigned char );
static long read_access_violation ( const void * );
static long read_access_violation ( const void * );
static long write_access_violation ( const void * );
static long write_access_violation ( const void * );
static long read_access_range(const void *, long);
static long read_access_range(const void *, long);
static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *);
static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *);
 
 
static int
static int
dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
{
{
  if (src)
  if (src)
    sprintp (spare_buffer,
    sprintp (spare_buffer,
             "'%s' returned DTC error '%s'.\n", src, get_err_text (code));
             "'%s' returned DTC error '%s'.\n", src, get_err_text (code));
  else
  else
    sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code));
    sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code));
 
 
  gdb_puts (spare_buffer);
  gdb_puts (spare_buffer);
  return ret;
  return ret;
}
}
 
 
 
 
#if 0
#if 0
/* I think this function is unnecessary since the introduction of
/* I think this function is unnecessary since the introduction of
   adbg_find_memory_addr_in_frame.  */
   adbg_find_memory_addr_in_frame.  */
 
 
/* Return the number of expressions in the format associated with a
/* Return the number of expressions in the format associated with a
   given trace frame.  */
   given trace frame.  */
static int
static int
count_frame_exprs (FRAME_DEF *frame)
count_frame_exprs (FRAME_DEF *frame)
{
{
  CFD *format;
  CFD *format;
  T_EXPR *expr;
  T_EXPR *expr;
  int num_exprs;
  int num_exprs;
 
 
  /* Get the format from the frame.  */
  /* Get the format from the frame.  */
  get_frame_format_pointer (frame, &format);
  get_frame_format_pointer (frame, &format);
 
 
  /* Walk the linked list of expressions, and count the number of
  /* Walk the linked list of expressions, and count the number of
     expressions we find there.  */
     expressions we find there.  */
  num_exprs = 0;
  num_exprs = 0;
  for (expr = format->p_cfd_expr; expr; expr = expr->next)
  for (expr = format->p_cfd_expr; expr; expr = expr->next)
    num_exprs++;
    num_exprs++;
 
 
  return num_exprs;
  return num_exprs;
}
}
#endif
#endif
 
 
#if 0
#if 0
/* Function: get_frame_addr
/* Function: get_frame_addr
 *
 *
 * Description: If the input memory address was collected in the
 * Description: If the input memory address was collected in the
 *     current trace frame, then lookup and return the address
 *     current trace frame, then lookup and return the address
 *     from within the trace buffer from which the collected byte
 *     from within the trace buffer from which the collected byte
 * may be retrieved.  Else return -1.  */
 * may be retrieved.  Else return -1.  */
 
 
unsigned char *
unsigned char *
get_frame_addr ( const unsigned char *addr )
get_frame_addr ( const unsigned char *addr )
{
{
  unsigned char *base, *regs, *stack, *mem;
  unsigned char *base, *regs, *stack, *mem;
  CFD *dummy;
  CFD *dummy;
  DTC_RESPONSE ret;
  DTC_RESPONSE ret;
 
 
  /* first, see if addr is on the saved piece of stack for curframe */
  /* first, see if addr is on the saved piece of stack for curframe */
  if (curframe.format->stack_size > 0 &&
  if (curframe.format->stack_size > 0 &&
      (base = (unsigned char *) curframe.traceregs[A7]) <= addr  &&
      (base = (unsigned char *) curframe.traceregs[A7]) <= addr  &&
      addr < base + curframe.format->stack_size)
      addr < base + curframe.format->stack_size)
    {
    {
      gdb_puts("STUB: get_frame_addr: call get_addr_to_frame_regs_stack_mem\n");
      gdb_puts("STUB: get_frame_addr: call get_addr_to_frame_regs_stack_mem\n");
      if ((ret = get_addr_to_frame_regs_stack_mem (curframe.frame_data,
      if ((ret = get_addr_to_frame_regs_stack_mem (curframe.frame_data,
                                                   &dummy,
                                                   &dummy,
                                                   (void *) &regs,
                                                   (void *) &regs,
                                                   (void *) &stack,
                                                   (void *) &stack,
                                                   (void *) &mem))
                                                   (void *) &mem))
          != OK_TARGET_RESPONSE)
          != OK_TARGET_RESPONSE)
        return (void *) dtc_error_ret (-1,
        return (void *) dtc_error_ret (-1,
                                       "get_addr_to_frame_regs_stack_mem",
                                       "get_addr_to_frame_regs_stack_mem",
                                       ret);
                                       ret);
      else
      else
        return stack + (addr - base);
        return stack + (addr - base);
    }
    }
 
 
  /* Next, try to find addr in the current frame's expression-
  /* Next, try to find addr in the current frame's expression-
     collected memory blocks.  I'm sure this is at least quadradic in
     collected memory blocks.  I'm sure this is at least quadradic in
     time.  */
     time.  */
  {
  {
    int num_exprs = count_frame_exprs (curframe.frame_data);
    int num_exprs = count_frame_exprs (curframe.frame_data);
    int expr, block;
    int expr, block;
 
 
    /* Try each expression in turn.  */
    /* Try each expression in turn.  */
    for (expr = 0; expr < num_exprs; expr++)
    for (expr = 0; expr < num_exprs; expr++)
      {
      {
        for (block = 0; ; block++)
        for (block = 0; ; block++)
          {
          {
            T_EXPR_DATA *data;
            T_EXPR_DATA *data;
            if (adbg_get_expr_data (curframe.frame_data,
            if (adbg_get_expr_data (curframe.frame_data,
                                    'x', expr, block,
                                    'x', expr, block,
                                    &data)
                                    &data)
                != OK_TARGET_RESPONSE)
                != OK_TARGET_RESPONSE)
              break;
              break;
            else if ((unsigned char *) data->address <= addr
            else if ((unsigned char *) data->address <= addr
                     && addr < ((unsigned char *) data->address + data->size))
                     && addr < ((unsigned char *) data->address + data->size))
              {
              {
                /* We have found the right block; is it valid data?
                /* We have found the right block; is it valid data?
                   Upper-case stamps mean bad data.  */
                   Upper-case stamps mean bad data.  */
                if ('A' <= data->stamp && data->stamp <= 'Z')
                if ('A' <= data->stamp && data->stamp <= 'Z')
                  {
                  {
                    gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
                    gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
                    return (unsigned char *) -1;
                    return (unsigned char *) -1;
                  }
                  }
                else
                else
                  {
                  {
                    if (remote_debug > 1)
                    if (remote_debug > 1)
                      {
                      {
                        sprintp(spare_buffer,
                        sprintp(spare_buffer,
                                "STUB: get_frame_addr: got it [%x,%x)\n",
                                "STUB: get_frame_addr: got it [%x,%x)\n",
                                data->address, data->address + data->size);
                                data->address, data->address + data->size);
                        gdb_puts(spare_buffer);
                        gdb_puts(spare_buffer);
                      }
                      }
 
 
                    return (((unsigned char *) &data->data)
                    return (((unsigned char *) &data->data)
                            + (addr - (unsigned char *) data->address));
                            + (addr - (unsigned char *) data->address));
                  }
                  }
              }
              }
          }
          }
      }
      }
  }
  }
 
 
  /* not found, return error */
  /* not found, return error */
  return (unsigned char *) -1;
  return (unsigned char *) -1;
}
}
 
 
/*============================================================*/
/*============================================================*/
 
 
static long get_uchar ( const unsigned char * addr )
static long get_uchar ( const unsigned char * addr )
{
{
  unsigned char *frame_addr;
  unsigned char *frame_addr;
 
 
  if ( read_access_violation ( addr ) )
  if ( read_access_violation ( addr ) )
    return ( -1 ); /* Access error */
    return ( -1 ); /* Access error */
 
 
  if (curframe.valid)   /* if debugging a trace frame? */
  if (curframe.valid)   /* if debugging a trace frame? */
    {
    {
      /* If the requested address was collected in the current frame,
      /* If the requested address was collected in the current frame,
       * then fetch and return the data from the trace buffer.
       * then fetch and return the data from the trace buffer.
       */
       */
      if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1)
      if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1)
        return ( *frame_addr );
        return ( *frame_addr );
      /* If the requested address is in the Code Section,
      /* If the requested address is in the Code Section,
       * let's be magnanimous and read it anyway (else we shall
       * let's be magnanimous and read it anyway (else we shall
       * not be able to disassemble, find function prologues, etc.)
       * not be able to disassemble, find function prologues, etc.)
       */
       */
      else if (CS_CODE_START <= (unsigned long) addr &&
      else if (CS_CODE_START <= (unsigned long) addr &&
               (unsigned long) addr < CS_CODE_START + CS_CODE_SIZE)
               (unsigned long) addr < CS_CODE_START + CS_CODE_SIZE)
        return (*addr);
        return (*addr);
      else
      else
        return ( -1 );  /* "Access error" (the data was not collected) */
        return ( -1 );  /* "Access error" (the data was not collected) */
    }
    }
  else
  else
    /* Not debugging a trace frame, read the data from live memory. */
    /* Not debugging a trace frame, read the data from live memory. */
    return ( *addr ); /* Meaningful result >= 0 */
    return ( *addr ); /* Meaningful result >= 0 */
}
}
#endif
#endif
 
 
/*============================================================*/
/*============================================================*/
 
 
static long set_uchar ( unsigned char * addr, unsigned char val )
static long set_uchar ( unsigned char * addr, unsigned char val )
{
{
  long check_result = write_access_violation ( addr );
  long check_result = write_access_violation ( addr );
 
 
  if ( check_result != 0L )
  if ( check_result != 0L )
    return ( check_result ); /* Access error */
    return ( check_result ); /* Access error */
 
 
  return ( *addr = val );    /* Successful writing */
  return ( *addr = val );    /* Successful writing */
}
}
 
 
/*============================================================*/
/*============================================================*/
 
 
/*
/*
 * Function read_access_violation() below returns TRUE if dereferencing
 * Function read_access_violation() below returns TRUE if dereferencing
 * its argument for reading would cause a bus error - and FALSE otherwise:
 * its argument for reading would cause a bus error - and FALSE otherwise:
 */
 */
 
 
static long read_access_violation ( const void * addr )
static long read_access_violation ( const void * addr )
{
{
  return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
  return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
           ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) );
           ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) );
}
}
 
 
/*============================================================*/
/*============================================================*/
 
 
/*
/*
 * Function write_access_violation() below returns zero if dereferencing
 * Function write_access_violation() below returns zero if dereferencing
 * its argument for writing is safe, -1 on a soft error (the argument
 * its argument for writing is safe, -1 on a soft error (the argument
 * falls into the write-protected area), -2 on a hard error (the argument
 * falls into the write-protected area), -2 on a hard error (the argument
 * points to a non-existent memory location). In other words, it returns
 * points to a non-existent memory location). In other words, it returns
 * FALSE when no bus error is expected - and an error code otherwise:
 * FALSE when no bus error is expected - and an error code otherwise:
 */
 */
 
 
static long write_access_violation ( const void * addr )
static long write_access_violation ( const void * addr )
{
{
  /*
  /*
   * The boundaries of the write-protected area have to be received via
   * The boundaries of the write-protected area have to be received via
   * an API provided in the Symmetrix core code. For now, these limits
   * an API provided in the Symmetrix core code. For now, these limits
   * are hard-coded:
   * are hard-coded:
   */
   */
 
 
  if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
  if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
    return ( -1 ); /* soft error */
    return ( -1 ); /* soft error */
 
 
  if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
  if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
       ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) )
       ( ( addr < NVD_START )  || ( addr >= NVD_END ) ) )
    return ( -2 ); /* hard error */
    return ( -2 ); /* hard error */
 
 
  return ( 0 );
  return ( 0 );
}
}
 
 
 
 
/* read_access_range is like read_access_violation,
/* read_access_range is like read_access_violation,
   but returns the number of bytes we can read w/o faulting.
   but returns the number of bytes we can read w/o faulting.
   that is, it checks an address range and tells us what portion
   that is, it checks an address range and tells us what portion
   (if any) of the prefix is safe to read without a bus error */
   (if any) of the prefix is safe to read without a bus error */
static long
static long
read_access_range(const void *addr, long count)
read_access_range(const void *addr, long count)
{
{
  if ((addr >= SRAM_START) && (addr < SRAM_END))
  if ((addr >= SRAM_START) && (addr < SRAM_END))
    {
    {
      if ((char *)addr + count < (char *)SRAM_END)
      if ((char *)addr + count < (char *)SRAM_END)
        return (count);
        return (count);
      else
      else
        return ((char *)SRAM_END - (char *)addr);
        return ((char *)SRAM_END - (char *)addr);
    }
    }
  else if (((char *)addr >= (char *)NVD_START) &&
  else if (((char *)addr >= (char *)NVD_START) &&
           ((char *)addr < (char *)NVD_END))
           ((char *)addr < (char *)NVD_END))
    {
    {
      if ((char *)addr + count < (char *)NVD_END)
      if ((char *)addr + count < (char *)NVD_END)
        return (count);
        return (count);
      else
      else
        return ((char *)NVD_END - (char *)addr);
        return ((char *)NVD_END - (char *)addr);
    }
    }
  else
  else
    return (0);
    return (0);
}
}
 
 
/* Convert the memory pointed to by mem into hex, placing result in buf.
/* Convert the memory pointed to by mem into hex, placing result in buf.
   Return SUCCESS or FAIL.
   Return SUCCESS or FAIL.
   If MAY_FAULT is non-zero, then we should return FAIL in response to
   If MAY_FAULT is non-zero, then we should return FAIL in response to
   a fault; if zero treat a fault like any other fault in the stub.  */
   a fault; if zero treat a fault like any other fault in the stub.  */
 
 
static long
static long
mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
{
{
  long ndx;
  long ndx;
  long ndx2;
  long ndx2;
  long ch;
  long ch;
  long incr;
  long incr;
  unsigned char *location;
  unsigned char *location;
  DTC_RESPONSE status;
  DTC_RESPONSE status;
 
 
  if (may_fault)
  if (may_fault)
    {
    {
      for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
      for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
        {
        {
          status = find_memory(mem, count - ndx, &location, &incr);
          status = find_memory(mem, count - ndx, &location, &incr);
 
 
          if (status == OK_TARGET_RESPONSE)
          if (status == OK_TARGET_RESPONSE)
            {
            {
              if (incr > 0)
              if (incr > 0)
                {
                {
                  for (ndx2 = 0; ndx2 < incr; ndx2++)
                  for (ndx2 = 0; ndx2 < incr; ndx2++)
                    {
                    {
                      ch = *location++;
                      ch = *location++;
                      *buf++ = hexchars[ch >> 4];
                      *buf++ = hexchars[ch >> 4];
                      *buf++ = hexchars[ch & 0xf];
                      *buf++ = hexchars[ch & 0xf];
                    }
                    }
                  mem += incr;
                  mem += incr;
                }
                }
              else if (incr <= 0) /* should never happen */
              else if (incr <= 0) /* should never happen */
                {
                {
                  *buf = 0;
                  *buf = 0;
                  return (0);
                  return (0);
                }
                }
            }
            }
          else if (status == NOT_FOUND_TARGET_RESPONSE)
          else if (status == NOT_FOUND_TARGET_RESPONSE)
            {
            {
              *buf = 0;
              *buf = 0;
              return (ndx);     /* return amount copied */
              return (ndx);     /* return amount copied */
            }
            }
          else
          else
            {
            {
              *buf = 0;
              *buf = 0;
              return (0);        /* XXX: how do we tell the user the status? */
              return (0);        /* XXX: how do we tell the user the status? */
            }
            }
        }
        }
      *buf = 0;
      *buf = 0;
      return (count);
      return (count);
    }
    }
  else
  else
    {
    {
      for (ndx = 0; ndx < count; ndx++)
      for (ndx = 0; ndx < count; ndx++)
        {
        {
          ch = *mem++;
          ch = *mem++;
          *buf++ = hexchars[ch >> 4];
          *buf++ = hexchars[ch >> 4];
          *buf++ = hexchars[ch & 0xf];
          *buf++ = hexchars[ch & 0xf];
        }
        }
      *buf = 0;
      *buf = 0;
      return (count);           /* we copied everything */
      return (count);           /* we copied everything */
    }
    }
}
}
 
 
static DTC_RESPONSE
static DTC_RESPONSE
find_memory(unsigned char *mem, long count,
find_memory(unsigned char *mem, long count,
            unsigned char **location, long *incr)
            unsigned char **location, long *incr)
{
{
  DTC_RESPONSE retval;
  DTC_RESPONSE retval;
  long length;
  long length;
 
 
  /* figure out how much of the memory range we can read w/o faulting */
  /* figure out how much of the memory range we can read w/o faulting */
  count = read_access_range(mem, count);
  count = read_access_range(mem, count);
  if (count == 0)
  if (count == 0)
    return (NOT_FOUND_TARGET_RESPONSE);
    return (NOT_FOUND_TARGET_RESPONSE);
 
 
  if (curframe.valid)
  if (curframe.valid)
    {
    {
      unsigned char *mem_block;
      unsigned char *mem_block;
      unsigned char *mem_addr;
      unsigned char *mem_addr;
      unsigned long mem_size;
      unsigned long mem_size;
      unsigned long mem_stamp;
      unsigned long mem_stamp;
 
 
      retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem,
      retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem,
                                              (unsigned long **)&mem_block,
                                              (unsigned long **)&mem_block,
                                              (unsigned long **)&mem_addr,
                                              (unsigned long **)&mem_addr,
                                              &mem_size, &mem_stamp);
                                              &mem_size, &mem_stamp);
 
 
      switch (retval)
      switch (retval)
        {
        {
        case OK_TARGET_RESPONSE:
        case OK_TARGET_RESPONSE:
#if 0
#if 0
          printp("FOUND: mem %x block %x addr %x size %d stamp %x\n",
          printp("FOUND: mem %x block %x addr %x size %d stamp %x\n",
                 mem, mem_block, mem_addr, mem_size, mem_stamp);
                 mem, mem_block, mem_addr, mem_size, mem_stamp);
#endif
#endif
          *location = mem_block + (mem - mem_addr);
          *location = mem_block + (mem - mem_addr);
          length = mem_size - (mem - mem_addr);;
          length = mem_size - (mem - mem_addr);;
 
 
          if (length < count)
          if (length < count)
            *incr = length;
            *incr = length;
          else
          else
            *incr = count;
            *incr = count;
 
 
          break;
          break;
 
 
        case NOT_FOUND_TARGET_RESPONSE:
        case NOT_FOUND_TARGET_RESPONSE:
        case NEAR_FOUND_TARGET_RESPONSE:
        case NEAR_FOUND_TARGET_RESPONSE:
#if 0
#if 0
          printp("NOT FOUND: mem %x, checking code region\n", mem);
          printp("NOT FOUND: mem %x, checking code region\n", mem);
#endif
#endif
          /* check to see if it's in the code region */
          /* check to see if it's in the code region */
          if ((CS_CODE_START <= (long)mem) &&
          if ((CS_CODE_START <= (long)mem) &&
              ((long)mem < CS_CODE_START + CS_CODE_SIZE))
              ((long)mem < CS_CODE_START + CS_CODE_SIZE))
            {
            {
              /* some or all of the address range is in the code */
              /* some or all of the address range is in the code */
              *location = mem;
              *location = mem;
              if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE)
              if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE)
                *incr = count; /* it's totally in the code */
                *incr = count; /* it's totally in the code */
              else
              else
                /* how much is in the code? */
                /* how much is in the code? */
                *incr = CS_CODE_START + CS_CODE_SIZE - (long)mem;
                *incr = CS_CODE_START + CS_CODE_SIZE - (long)mem;
#if 0
#if 0
              printp("FOUND in code region: %x\n", mem);
              printp("FOUND in code region: %x\n", mem);
#endif
#endif
              retval = OK_TARGET_RESPONSE;
              retval = OK_TARGET_RESPONSE;
            }
            }
          else
          else
            retval = NOT_FOUND_TARGET_RESPONSE;
            retval = NOT_FOUND_TARGET_RESPONSE;
 
 
          break;
          break;
 
 
        default:
        default:
#if 0
#if 0
          printp("BAD RETURN: %d\n", retval);
          printp("BAD RETURN: %d\n", retval);
#endif
#endif
          retval = NOT_FOUND_TARGET_RESPONSE;
          retval = NOT_FOUND_TARGET_RESPONSE;
          break;
          break;
        }
        }
    }
    }
  else
  else
    {
    {
      *location = mem;
      *location = mem;
      *incr = count;
      *incr = count;
      retval = OK_TARGET_RESPONSE;
      retval = OK_TARGET_RESPONSE;
    }
    }
 
 
  return (retval);
  return (retval);
}
}
 
 
/* Convert the hex array pointed to by buf into binary to be placed in mem.
/* Convert the hex array pointed to by buf into binary to be placed in mem.
   Return SUCCESS or FAIL.  */
   Return SUCCESS or FAIL.  */
 
 
static long
static long
hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
{
{
  long i, ch;
  long i, ch;
 
 
  for ( i=0; i<count; i++ )
  for ( i=0; i<count; i++ )
    {
    {
      ch = hex( *buf++ ) << 4;
      ch = hex( *buf++ ) << 4;
      ch = ch + hex( *buf++ );
      ch = ch + hex( *buf++ );
      if ( may_fault )
      if ( may_fault )
        {
        {
          ch = set_uchar( mem++, ch );
          ch = set_uchar( mem++, ch );
          if ( ch < 0 )    /* negative return indicates error */
          if ( ch < 0 )    /* negative return indicates error */
            return FAIL;
            return FAIL;
        }
        }
      else
      else
        *mem++ = ch;
        *mem++ = ch;
    }
    }
  return SUCCESS;
  return SUCCESS;
}
}
 
 
/**********************************************/
/**********************************************/
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
/* RETURN NUMBER OF CHARS PROCESSED           */
/* RETURN NUMBER OF CHARS PROCESSED           */
/**********************************************/
/**********************************************/
 
 
static int
static int
hexToInt( char **ptr, unsigned long *intValue )
hexToInt( char **ptr, unsigned long *intValue )
{
{
  long numChars = 0;
  long numChars = 0;
  long hexValue;
  long hexValue;
 
 
  *intValue = 0;
  *intValue = 0;
  while ( **ptr )
  while ( **ptr )
    {
    {
      hexValue = hex( **ptr );
      hexValue = hex( **ptr );
      if ( hexValue >=0 )
      if ( hexValue >=0 )
        {
        {
          *intValue = (*intValue << 4) | hexValue;
          *intValue = (*intValue << 4) | hexValue;
          numChars ++;
          numChars ++;
        }
        }
      else
      else
        break;
        break;
      (*ptr)++;
      (*ptr)++;
    }
    }
  return numChars;
  return numChars;
}
}
 
 
static volatile long gdb_handling_trap1;
static volatile long gdb_handling_trap1;
static volatile long gdb_handling_sstrace;
static volatile long gdb_handling_sstrace;
static volatile long gdb_signo;
static volatile long gdb_signo;
 
 
/*
/*
   Here is the "callable" stub entry point.
   Here is the "callable" stub entry point.
   Call this function with a GDB request as an argument,
   Call this function with a GDB request as an argument,
   and it will service the request and return.
   and it will service the request and return.
 
 
   May be further broken up as we go along, with individual requests
   May be further broken up as we go along, with individual requests
   broken out as separate functions.
   broken out as separate functions.
 */
 */
 
 
static char * handle_trace_query (char *);
static char * handle_trace_query (char *);
static char * handle_trace_set (char *);
static char * handle_trace_set (char *);
static int    handle_format (char **request, CFD *format);
static int    handle_format (char **request, CFD *format);
static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc);
static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc);
static char * crc_query (char *);
static char * crc_query (char *);
static char * handle_test (char *);
static char * handle_test (char *);
 
 
void
void
handle_request( char *request )
handle_request( char *request )
{
{
#if 0
#if 0
  remote_debug = 2;
  remote_debug = 2;
#endif
#endif
  switch( *request++ )
  switch( *request++ )
    {
    {
    case 'k':           /* "kill" */
    case 'k':           /* "kill" */
      curframe.valid = FALSE;
      curframe.valid = FALSE;
      putpacket ("");
      putpacket ("");
      break;
      break;
    case 'D':           /* "detach" */
    case 'D':           /* "detach" */
      curframe.valid = FALSE;
      curframe.valid = FALSE;
      putpacket ("");
      putpacket ("");
      break;
      break;
    default:            /* Unknown code.  Return an empty reply message. */
    default:            /* Unknown code.  Return an empty reply message. */
      putpacket( "" );  /* return empty packet */
      putpacket( "" );  /* return empty packet */
      break;
      break;
 
 
    case 'H':           /* Set thread for subsequent operations.
    case 'H':           /* Set thread for subsequent operations.
    Hct...                 c = 'c' for thread used in step and continue;
    Hct...                 c = 'c' for thread used in step and continue;
                           t... can be -1 for all threads.
                           t... can be -1 for all threads.
                           c = 'g' for thread used in other operations.
                           c = 'g' for thread used in other operations.
                           If zero, pick a thread, any thread.  */
                           If zero, pick a thread, any thread.  */
 
 
      putpacket( "OK" );
      putpacket( "OK" );
      break;
      break;
 
 
    case 'g':           /* Read registers.
    case 'g':           /* Read registers.
                           Each byte of register data is described by
                           Each byte of register data is described by
                           two hex digits.  registers are in the
                           two hex digits.  registers are in the
                           internal order for GDB, and the bytes in a
                           internal order for GDB, and the bytes in a
                           register are in the same order the machine
                           register are in the same order the machine
                           uses.  */
                           uses.  */
      {
      {
        /* Return the values in (one of) the registers cache(s).
        /* Return the values in (one of) the registers cache(s).
           Several situations may pertain:
           Several situations may pertain:
           1) We're synchronous, in which case the "registers" array
           1) We're synchronous, in which case the "registers" array
              should actually be current.
              should actually be current.
           2) We're asynchronous, in which case the "registers" array
           2) We're asynchronous, in which case the "registers" array
              holds whatever was cached most recently.
              holds whatever was cached most recently.
           3) We're looking at a trace frame that was collected earlier:
           3) We're looking at a trace frame that was collected earlier:
              we will return those earlier registers.
              we will return those earlier registers.
         */
         */
 
 
        /* all registers default to zero */
        /* all registers default to zero */
        memset (outbuffer, '0', NUMREGBYTES);
        memset (outbuffer, '0', NUMREGBYTES);
        outbuffer[NUMREGBYTES] = '\0';
        outbuffer[NUMREGBYTES] = '\0';
 
 
        if (curframe.valid)     /* debugging a trace frame */
        if (curframe.valid)     /* debugging a trace frame */
          mem2hex( (unsigned char*) curframe.traceregs,
          mem2hex( (unsigned char*) curframe.traceregs,
                  outbuffer, NUMREGBYTES, 0 );
                  outbuffer, NUMREGBYTES, 0 );
        else
        else
          mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 );
          mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 );
 
 
        putpacket( outbuffer );
        putpacket( outbuffer );
      }
      }
      break;
      break;
    case 'G':           /* Write registers.
    case 'G':           /* Write registers.
    Gxxxxxxxx              Each byte of register data is described by
    Gxxxxxxxx              Each byte of register data is described by
                           two hex digits.  */
                           two hex digits.  */
      if (curframe.valid)       /* debugging a trace frame */
      if (curframe.valid)       /* debugging a trace frame */
        putpacket ("E03");      /* can't write regs into a trace frame! */
        putpacket ("E03");      /* can't write regs into a trace frame! */
      else
      else
        {
        {
          /* Write the values into the local registers cache...
          /* Write the values into the local registers cache...
             Note that no actual registers are being changed.  */
             Note that no actual registers are being changed.  */
 
 
          hex2mem( request,
          hex2mem( request,
                  (unsigned char *) registers, NUMREGBYTES, 0 );
                  (unsigned char *) registers, NUMREGBYTES, 0 );
          putpacket( "OK" );
          putpacket( "OK" );
        }
        }
      break;
      break;
    case 'P':           /* Write (single) register.
    case 'P':           /* Write (single) register.
    Pnn=xxxxxxxx           register nn gets value xxxxxxxx;
    Pnn=xxxxxxxx           register nn gets value xxxxxxxx;
                           two hex digits for each byte in the register
                           two hex digits for each byte in the register
                           (target byte order).  */
                           (target byte order).  */
 
 
      if (curframe.valid)
      if (curframe.valid)
        putpacket ("E03");      /* can't write regs into a trace frame! */
        putpacket ("E03");      /* can't write regs into a trace frame! */
      else
      else
        {
        {
          unsigned long regno;
          unsigned long regno;
 
 
          if ( hexToInt( &request, &regno ) && *(request++) == '=' )
          if ( hexToInt( &request, &regno ) && *(request++) == '=' )
            {
            {
              if ( regno < NUMREGS )
              if ( regno < NUMREGS )
                {
                {
                  hexToInt( &request,
                  hexToInt( &request,
                           (unsigned long *) &registers[REGISTER_BYTE(regno)]);
                           (unsigned long *) &registers[REGISTER_BYTE(regno)]);
 
 
                  putpacket( "OK" );
                  putpacket( "OK" );
                }
                }
              else
              else
                putpacket( "E01" );   /* bad packet or regno */
                putpacket( "E01" );   /* bad packet or regno */
            }
            }
        }
        }
      break;
      break;
    case 'm':           /* Read memory.
    case 'm':           /* Read memory.
    mAAAAAAAA,LLLL         AAAAAAAA is address, LLLL is length.
    mAAAAAAAA,LLLL         AAAAAAAA is address, LLLL is length.
                           Reply can be fewer bytes than requested
                           Reply can be fewer bytes than requested
                           if able to read only part of the data.  */
                           if able to read only part of the data.  */
      {
      {
        unsigned long addr, len;
        unsigned long addr, len;
 
 
        if ( hexToInt( &request, &addr )    &&
        if ( hexToInt( &request, &addr )    &&
             *(request++) == ','            &&
             *(request++) == ','            &&
             hexToInt( &request, &len ) )
             hexToInt( &request, &len ) )
          {
          {
            /* better not overwrite outbuffer! */
            /* better not overwrite outbuffer! */
            if ( len > (BUFMAX / 2) - 5 )
            if ( len > (BUFMAX / 2) - 5 )
              len = (BUFMAX / 2) - 5;
              len = (BUFMAX / 2) - 5;
            if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0) /* XXX: eventually use returned value */
            if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0) /* XXX: eventually use returned value */
              putpacket( "E03" );       /* read fault (access denied) */
              putpacket( "E03" );       /* read fault (access denied) */
            else
            else
              putpacket( outbuffer );   /* read succeeded */
              putpacket( outbuffer );   /* read succeeded */
          }
          }
        else
        else
          putpacket( "E01" );           /* badly formed read request */
          putpacket( "E01" );           /* badly formed read request */
 
 
      }
      }
      break;
      break;
    case 'M':           /* Write memory.
    case 'M':           /* Write memory.
    Maaaaaaaa,llll:xxxx    aaaaaaaa is address, llll is length;
    Maaaaaaaa,llll:xxxx    aaaaaaaa is address, llll is length;
                           xxxx is data to write.  */
                           xxxx is data to write.  */
 
 
      {
      {
        unsigned long addr, len;
        unsigned long addr, len;
 
 
        if (curframe.valid)     /* can't write memory into a trace frame! */
        if (curframe.valid)     /* can't write memory into a trace frame! */
          putpacket ("E03");    /* "access denied" */
          putpacket ("E03");    /* "access denied" */
        else /*** if ( write_access_enabled ) ***/
        else /*** if ( write_access_enabled ) ***/
          {
          {
            if ( hexToInt( &request, &addr )  &&
            if ( hexToInt( &request, &addr )  &&
                 *(request++) == ','          &&
                 *(request++) == ','          &&
                 hexToInt( &request, &len )   &&
                 hexToInt( &request, &len )   &&
                 *(request++) == ':' )
                 *(request++) == ':' )
              {
              {
                if (len == 2 &&
                if (len == 2 &&
                    addr >= CS_CODE_START &&
                    addr >= CS_CODE_START &&
                    addr <= LAST_CS_WORD)
                    addr <= LAST_CS_WORD)
                  {
                  {
                    unsigned long val;
                    unsigned long val;
 
 
                    if ( !hexToInt( &request, &val ) ||
                    if ( !hexToInt( &request, &val ) ||
                         write_to_protected_mem( (void *)addr, val ) )
                         write_to_protected_mem( (void *)addr, val ) )
                      putpacket( "E03" );   /* write fault (access denied) */
                      putpacket( "E03" );   /* write fault (access denied) */
                    else
                    else
                      putpacket( "OK" );    /* write succeeded */
                      putpacket( "OK" );    /* write succeeded */
                  }
                  }
                else
                else
                  {
                  {
                    if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
                    if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
                      putpacket( "E03" );   /* write fault (access denied) */
                      putpacket( "E03" );   /* write fault (access denied) */
                    else
                    else
                      putpacket( "OK" );    /* write succeeded */
                      putpacket( "OK" );    /* write succeeded */
                  }
                  }
              }
              }
            else
            else
                putpacket( "E02" );     /* badly formed write request */
                putpacket( "E02" );     /* badly formed write request */
          }
          }
      }
      }
      break;
      break;
    case 'c':           /* Continue.
    case 'c':           /* Continue.
    cAAAAAAAA              AAAAAAAA is address from which to resume.
    cAAAAAAAA              AAAAAAAA is address from which to resume.
                           If omitted, resume at current PC.  */
                           If omitted, resume at current PC.  */
 
 
      {
      {
        unsigned long addr;
        unsigned long addr;
 
 
        if (curframe.valid)
        if (curframe.valid)
          {
          {
            /* Don't continue if debugging a trace frame! */
            /* Don't continue if debugging a trace frame! */
            gdb_puts ("Error: can't continue!\n");
            gdb_puts ("Error: can't continue!\n");
            putpacket ("S03");
            putpacket ("S03");
          }
          }
        else
        else
          {
          {
            gdb_signo = 3;
            gdb_signo = 3;
            if (isxdigit(request[0]))
            if (isxdigit(request[0]))
              {
              {
                hexToInt(&request, &addr);
                hexToInt(&request, &addr);
                registers[REGISTER_BYTE(PC)] = addr;
                registers[REGISTER_BYTE(PC)] = addr;
              }
              }
 
 
            gdb_handling_trap1 = FALSE;
            gdb_handling_trap1 = FALSE;
            gdb_handling_sstrace = FALSE;
            gdb_handling_sstrace = FALSE;
            sss_trace_flag = '\0';
            sss_trace_flag = '\0';
          }
          }
      }
      }
      break;
      break;
    case 's':           /* Step.
    case 's':           /* Step.
    sAAAAAAAA              AAAAAAAA is address from which to begin stepping.
    sAAAAAAAA              AAAAAAAA is address from which to begin stepping.
                           If omitted, begin stepping at current PC.  */
                           If omitted, begin stepping at current PC.  */
      {
      {
        unsigned long addr;
        unsigned long addr;
 
 
        if (curframe.valid)
        if (curframe.valid)
          {
          {
            /* Don't step if debugging a trace frame! */
            /* Don't step if debugging a trace frame! */
            gdb_puts ("Error: can't step!\n");
            gdb_puts ("Error: can't step!\n");
            putpacket ("S03");
            putpacket ("S03");
          }
          }
        else
        else
          {
          {
            gdb_signo = 3;
            gdb_signo = 3;
            if (isxdigit(request[0]))
            if (isxdigit(request[0]))
              {
              {
                hexToInt(&request, &addr);
                hexToInt(&request, &addr);
                registers[REGISTER_BYTE(PC)] = addr;
                registers[REGISTER_BYTE(PC)] = addr;
              }
              }
 
 
            gdb_handling_trap1 = FALSE;
            gdb_handling_trap1 = FALSE;
            gdb_handling_sstrace = FALSE;
            gdb_handling_sstrace = FALSE;
            sss_trace_flag = 't';
            sss_trace_flag = 't';
          }
          }
      }
      }
      break;
      break;
    case 'C':           /* Continue with signal.
    case 'C':           /* Continue with signal.
    Cxx;AAAAAAAA           xx is signal number in hex;
    Cxx;AAAAAAAA           xx is signal number in hex;
                           AAAAAAAA is adddress from which to resume.
                           AAAAAAAA is adddress from which to resume.
                           If ;AAAAAAAA omitted, continue from PC.   */
                           If ;AAAAAAAA omitted, continue from PC.   */
 
 
      {
      {
        unsigned long addr = 0;
        unsigned long addr = 0;
 
 
        if (!gdb_handling_trap1 || curframe.valid)
        if (!gdb_handling_trap1 || curframe.valid)
          {
          {
            /* Don't continue if not currently in synchronous mode,
            /* Don't continue if not currently in synchronous mode,
               or if currently debugging a trace frame!  */
               or if currently debugging a trace frame!  */
            gdb_puts( "Error: can't continue!\n" );
            gdb_puts( "Error: can't continue!\n" );
            putpacket( "S03" );       /* "sigquit"  (better idea?) */
            putpacket( "S03" );       /* "sigquit"  (better idea?) */
          }
          }
        else
        else
          {
          {
            gdb_signo = 3;
            gdb_signo = 3;
            if ( isxdigit( *request ) )
            if ( isxdigit( *request ) )
              {
              {
                hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
                hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
                request += 2;
                request += 2;
                if ( *request == ';' && isxdigit( *++request ) )
                if ( *request == ';' && isxdigit( *++request ) )
                  {
                  {
                    hexToInt( &request, &addr );
                    hexToInt( &request, &addr );
                    registers[REGISTER_BYTE(PC)] = addr;
                    registers[REGISTER_BYTE(PC)] = addr;
                  }
                  }
              }
              }
            gdb_handling_trap1 = FALSE;
            gdb_handling_trap1 = FALSE;
            gdb_handling_sstrace = FALSE;
            gdb_handling_sstrace = FALSE;
            sss_trace_flag = '\0';
            sss_trace_flag = '\0';
          }
          }
      }
      }
      break;
      break;
    case 'S':           /* Step with signal.
    case 'S':           /* Step with signal.
    Sxx;AAAAAAAA           xx is signal number in hex;
    Sxx;AAAAAAAA           xx is signal number in hex;
                           AAAAAAAA is adddress from which to begin stepping.
                           AAAAAAAA is adddress from which to begin stepping.
                           If ;AAAAAAAA omitted, begin stepping from PC.   */
                           If ;AAAAAAAA omitted, begin stepping from PC.   */
      {
      {
        unsigned long addr = 0;
        unsigned long addr = 0;
 
 
        if (!gdb_handling_trap1 || curframe.valid)
        if (!gdb_handling_trap1 || curframe.valid)
          {
          {
            /* Don't step if not currently in synchronous mode,
            /* Don't step if not currently in synchronous mode,
               or if currently debugging a trace frame!  */
               or if currently debugging a trace frame!  */
            gdb_puts( "Error: can't step!\n" );
            gdb_puts( "Error: can't step!\n" );
            putpacket( "S03" );       /* "sigquit"  (better idea?) */
            putpacket( "S03" );       /* "sigquit"  (better idea?) */
          }
          }
        else
        else
          {
          {
            gdb_signo = 3;
            gdb_signo = 3;
            if ( isxdigit( *request ) )
            if ( isxdigit( *request ) )
              {
              {
                hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
                hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
                request += 2;
                request += 2;
                if ( *request == ';' && isxdigit( *++request ) )
                if ( *request == ';' && isxdigit( *++request ) )
                  {
                  {
                    hexToInt( &request, &addr );
                    hexToInt( &request, &addr );
                    registers[REGISTER_BYTE(PC)] = addr;
                    registers[REGISTER_BYTE(PC)] = addr;
                  }
                  }
              }
              }
            gdb_handling_trap1 = FALSE;
            gdb_handling_trap1 = FALSE;
            gdb_handling_sstrace = FALSE;
            gdb_handling_sstrace = FALSE;
            sss_trace_flag = 't';
            sss_trace_flag = 't';
          }
          }
      }
      }
      break;
      break;
    case '?':           /* Query the latest reason for stopping.
    case '?':           /* Query the latest reason for stopping.
                           Should be same reply as was last generated
                           Should be same reply as was last generated
                           for step or continue.  */
                           for step or continue.  */
 
 
      if ( gdb_signo == 0 )
      if ( gdb_signo == 0 )
        gdb_signo = 3;  /* default to SIGQUIT */
        gdb_signo = 3;  /* default to SIGQUIT */
      outbuffer[ 0 ] = 'S';
      outbuffer[ 0 ] = 'S';
      outbuffer[ 1 ] = hexchars[ gdb_signo >>  4 ];
      outbuffer[ 1 ] = hexchars[ gdb_signo >>  4 ];
      outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ];
      outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ];
      outbuffer[ 3 ] = 0;
      outbuffer[ 3 ] = 0;
      putpacket( outbuffer );
      putpacket( outbuffer );
      break;
      break;
 
 
    case 'd':           /* Toggle debug mode
    case 'd':           /* Toggle debug mode
                           I'm sure we can think of something interesting.  */
                           I'm sure we can think of something interesting.  */
 
 
      remote_debug = !remote_debug;
      remote_debug = !remote_debug;
      putpacket( "" );  /* return empty packet */
      putpacket( "" );  /* return empty packet */
      break;
      break;
 
 
    case 'q':           /* general query */
    case 'q':           /* general query */
      switch (*request++)
      switch (*request++)
        {
        {
        default:
        default:
          putpacket ("");       /* nak a request which we don't handle */
          putpacket ("");       /* nak a request which we don't handle */
          break;
          break;
        case 'T':               /* trace query */
        case 'T':               /* trace query */
          putpacket (handle_trace_query (request));
          putpacket (handle_trace_query (request));
          break;
          break;
        case 'C':               /* crc query (?) */
        case 'C':               /* crc query (?) */
          if (*request++ == 'R' &&
          if (*request++ == 'R' &&
              *request++ == 'C' &&
              *request++ == 'C' &&
              *request++ == ':')
              *request++ == ':')
            putpacket (crc_query (request));
            putpacket (crc_query (request));
          else
          else
            putpacket ("");     /* unknown query */
            putpacket ("");     /* unknown query */
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 'Q':                   /* general set */
    case 'Q':                   /* general set */
      switch (*request++)
      switch (*request++)
        {
        {
        default:
        default:
          putpacket ("");       /* nak a request which we don't handle */
          putpacket ("");       /* nak a request which we don't handle */
          break;
          break;
        case 'T':               /* trace */
        case 'T':               /* trace */
          putpacket (handle_trace_set (request));
          putpacket (handle_trace_set (request));
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 'T':
    case 'T':
      /* call test function: TAAA,BBB,CCC
      /* call test function: TAAA,BBB,CCC
         A, B, and C are arguments to pass to gdb_c_test.  Reply is
         A, B, and C are arguments to pass to gdb_c_test.  Reply is
         "E01" (bad arguments) or "OK" (test function called).  */
         "E01" (bad arguments) or "OK" (test function called).  */
      putpacket (handle_test (request));
      putpacket (handle_test (request));
      break;
      break;
    }
    }
}
}
 
 
static TDP_SETUP_INFO tdp_temp;
static TDP_SETUP_INFO tdp_temp;
static int trace_running;
static int trace_running;
 
 
/*
/*
 * Function msgcmp:
 * Function msgcmp:
 *
 *
 * If second argument (str) is matched in first argument,
 * If second argument (str) is matched in first argument,
 *    then advance first argument past end of str and return "SAME"
 *    then advance first argument past end of str and return "SAME"
 * else return "DIFFERENT" without changing first argument.
 * else return "DIFFERENT" without changing first argument.
 *
 *
 * Return: zero for DIFFERENT, non-zero for SUCCESS
 * Return: zero for DIFFERENT, non-zero for SUCCESS
 */
 */
 
 
static int
static int
msgcmp (char **msgp, char *str)
msgcmp (char **msgp, char *str)
{
{
  char *next;
  char *next;
 
 
  if (msgp != 0 && str != 0)    /* input validation */
  if (msgp != 0 && str != 0)    /* input validation */
    if ((next = *msgp) != 0)
    if ((next = *msgp) != 0)
      {
      {
        for (;
        for (;
             *next && *str && *next == *str;
             *next && *str && *next == *str;
             next++, str++)
             next++, str++)
          ;
          ;
 
 
        if (*str == 0)                  /* matched all of str in msg */
        if (*str == 0)                  /* matched all of str in msg */
          return (int) (*msgp = next);  /* advance msg ptr past str  */
          return (int) (*msgp = next);  /* advance msg ptr past str  */
      }
      }
  return 0;                             /* failure */
  return 0;                             /* failure */
}
}
 
 
static char *
static char *
handle_trace_query (char *request)
handle_trace_query (char *request)
{
{
  if (msgcmp (&request, "Status"))
  if (msgcmp (&request, "Status"))
    {
    {
      if (adbg_check_if_active ())
      if (adbg_check_if_active ())
        {
        {
          gdb_puts ("Target trace is running.\n");
          gdb_puts ("Target trace is running.\n");
          return "T1";
          return "T1";
        }
        }
      else
      else
        {
        {
          gdb_puts ("Target trace not running.\n");
          gdb_puts ("Target trace not running.\n");
          trace_running = 0;
          trace_running = 0;
          return "T0";
          return "T0";
        }
        }
    }
    }
  else                  /* unknown trace query */
  else                  /* unknown trace query */
    {
    {
      return "";
      return "";
    }
    }
}
}
 
 
static void
static void
gdb_note (char *fmt, int arg1)
gdb_note (char *fmt, int arg1)
{
{
  if (remote_debug > 1)
  if (remote_debug > 1)
    {
    {
      sprintp (spare_buffer, fmt, arg1);
      sprintp (spare_buffer, fmt, arg1);
      gdb_puts (spare_buffer);
      gdb_puts (spare_buffer);
    }
    }
}
}
 
 
static int
static int
error_ret (int ret, char *fmt, int arg1)
error_ret (int ret, char *fmt, int arg1)
{
{
  if (remote_debug > 0)
  if (remote_debug > 0)
    {
    {
      sprintp (spare_buffer, fmt, arg1);
      sprintp (spare_buffer, fmt, arg1);
      gdb_puts (spare_buffer);
      gdb_puts (spare_buffer);
    }
    }
  return ret;
  return ret;
}
}
 
 
static int
static int
handle_format (char **request, COLLECTION_FORMAT_DEF *format)
handle_format (char **request, COLLECTION_FORMAT_DEF *format)
{
{
  MEMRANGE_DEF m;
  MEMRANGE_DEF m;
  DTC_RESPONSE ret;
  DTC_RESPONSE ret;
  int elinum;
  int elinum;
  unsigned long regnum;
  unsigned long regnum;
  long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4];
  long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4];
  struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes;
  struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes;
 
 
  if (format->id == 0)
  if (format->id == 0)
    {
    {
      if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
      if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
        return dtc_error_ret (-1, "get_unused_format_id", ret);
        return dtc_error_ret (-1, "get_unused_format_id", ret);
 
 
      if (**request == 'R')
      if (**request == 'R')
        {
        {
          (*request)++;
          (*request)++;
          hexToInt (request, &format->regs_mask);
          hexToInt (request, &format->regs_mask);
        }
        }
      gdb_note ("STUB: call define_format (id = %d, ", format->id);
      gdb_note ("STUB: call define_format (id = %d, ", format->id);
      gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
      gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
 
 
      if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
      if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
        {
        {
          sprintp (spare_buffer,
          sprintp (spare_buffer,
                   "'define_format': DTC error '%s' for format id %d.\n",
                   "'define_format': DTC error '%s' for format id %d.\n",
                   get_err_text (ret),
                   get_err_text (ret),
                   format->id);
                   format->id);
          gdb_puts (spare_buffer);
          gdb_puts (spare_buffer);
          return -1;
          return -1;
        }
        }
    }
    }
 
 
  while ((**request == 'M') || (**request == 'X'))
  while ((**request == 'M') || (**request == 'X'))
    {
    {
      switch (**request)
      switch (**request)
        {
        {
        case 'M':               /* M<regnum>,<offset>,<size> */
        case 'M':               /* M<regnum>,<offset>,<size> */
          (*request)++;
          (*request)++;
          hexToInt(request, &regnum);
          hexToInt(request, &regnum);
 
 
          if (regnum == 0 || regnum == (unsigned long) -1)
          if (regnum == 0 || regnum == (unsigned long) -1)
            m.typecode = -1;
            m.typecode = -1;
          else if ((elinum = index_to_elinum (regnum)) > 0)
          else if ((elinum = index_to_elinum (regnum)) > 0)
            m.typecode = elinum;
            m.typecode = elinum;
          else
          else
            return error_ret (-1,
            return error_ret (-1,
                              "Memrange register %d is not between 0 and 15\n",
                              "Memrange register %d is not between 0 and 15\n",
                              regnum);
                              regnum);
 
 
          if (*(*request)++ != ',')
          if (*(*request)++ != ',')
            return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1);
            return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1);
          hexToInt(request, &m.offset);
          hexToInt(request, &m.offset);
          if (*(*request)++ != ',')
          if (*(*request)++ != ',')
            return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2);
            return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2);
          hexToInt(request, &m.size);
          hexToInt(request, &m.size);
 
 
          gdb_note ("STUB: call add_format_mem_range (typecode =  0x%x, ",
          gdb_note ("STUB: call add_format_mem_range (typecode =  0x%x, ",
                    m.typecode);
                    m.typecode);
          gdb_note ("offset = 0x%X, ", m.offset);
          gdb_note ("offset = 0x%X, ", m.offset);
          gdb_note ("size = %d);\n", m.size);
          gdb_note ("size = %d);\n", m.size);
          if ((ret = add_format_mem_ranges (format->id, &m)) !=
          if ((ret = add_format_mem_ranges (format->id, &m)) !=
              OK_TARGET_RESPONSE)
              OK_TARGET_RESPONSE)
            {
            {
              dtc_error_ret (-1, "add_format_mem_ranges", ret);
              dtc_error_ret (-1, "add_format_mem_ranges", ret);
              sprintp (spare_buffer,
              sprintp (spare_buffer,
                       "format id %d: memrange (0x%x, 0x%x, 0x%x).\n",
                       "format id %d: memrange (0x%x, 0x%x, 0x%x).\n",
                       format->id, m.typecode, m.offset, m.size);
                       format->id, m.typecode, m.offset, m.size);
              gdb_puts (spare_buffer);
              gdb_puts (spare_buffer);
              return -1;
              return -1;
            }
            }
          break;
          break;
 
 
        case 'X':               /* X<length>,<bytecodes> */
        case 'X':               /* X<length>,<bytecodes> */
          {
          {
            unsigned long length;
            unsigned long length;
 
 
            (*request)++;
            (*request)++;
            hexToInt(request, &length);
            hexToInt(request, &length);
 
 
            if ((length <= 0) || (length > MAX_BYTE_CODES))
            if ((length <= 0) || (length > MAX_BYTE_CODES))
              return error_ret (-1,
              return error_ret (-1,
                                "Bytecode expression length (%d) too large\n",
                                "Bytecode expression length (%d) too large\n",
                                length);
                                length);
 
 
            if (*(*request)++ != ',')
            if (*(*request)++ != ',')
              return error_ret (-1,
              return error_ret (-1,
                                "Malformed bytecode expr (comma#%d missing)\n",
                                "Malformed bytecode expr (comma#%d missing)\n",
                                1);
                                1);
            t_expr->next = NULL;
            t_expr->next = NULL;
            /* subtract one to account for expr[0] in header */
            /* subtract one to account for expr[0] in header */
            t_expr->size = sizeof(struct t_expr_tag) + length - 1;
            t_expr->size = sizeof(struct t_expr_tag) + length - 1;
            t_expr->expr_size = length;
            t_expr->expr_size = length;
 
 
            hex2mem(*request, &t_expr->expr[0], length, 0);
            hex2mem(*request, &t_expr->expr[0], length, 0);
            *request += 2 * length;
            *request += 2 * length;
            build_and_add_expression(format->id, t_expr);
            build_and_add_expression(format->id, t_expr);
          }
          }
          break;
          break;
        }
        }
    }
    }
  return 0;
  return 0;
}
}
 
 
static char *
static char *
handle_trace_set (char *request)
handle_trace_set (char *request)
{
{
  long n_frame;
  long n_frame;
  unsigned long frameno, tdp, pc, start, stop;
  unsigned long frameno, tdp, pc, start, stop;
  DTC_RESPONSE ret = -1;
  DTC_RESPONSE ret = -1;
  static COLLECTION_FORMAT_DEF tempfmt1;
  static COLLECTION_FORMAT_DEF tempfmt1;
  static char enable;
  static char enable;
  static char retbuf[20];
  static char retbuf[20];
 
 
  if (msgcmp (&request, "init"))
  if (msgcmp (&request, "init"))
    {
    {
      gdb_note ("STUB: call clear_trace_state();\n", 0);
      gdb_note ("STUB: call clear_trace_state();\n", 0);
      curframe.valid = 0;       /* all old frames become invalid now */
      curframe.valid = 0;       /* all old frames become invalid now */
      if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE)
      if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE)
        return "OK";
        return "OK";
      else
      else
        {
        {
          sprintp (retbuf, "E2%x", ret);
          sprintp (retbuf, "E2%x", ret);
          return (char *) dtc_error_ret ((int) &retbuf,
          return (char *) dtc_error_ret ((int) &retbuf,
                                         "clear_trace_state",
                                         "clear_trace_state",
                                         ret);
                                         ret);
        }
        }
    }
    }
  else if (msgcmp (&request, "Start"))
  else if (msgcmp (&request, "Start"))
    {
    {
      trace_running = 1;
      trace_running = 1;
      curframe.valid = 0;       /* all old frames become invalid now */
      curframe.valid = 0;       /* all old frames become invalid now */
      gdb_note ("STUB: call start_trace_experiment();\n", 0);
      gdb_note ("STUB: call start_trace_experiment();\n", 0);
      adbg_save_trace_in_nvd ();
      adbg_save_trace_in_nvd ();
      if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE)
      if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE)
        return "OK";
        return "OK";
      else
      else
        {
        {
          sprintp (retbuf, "E2%x", ret);
          sprintp (retbuf, "E2%x", ret);
          return (char *) dtc_error_ret ((int) &retbuf,
          return (char *) dtc_error_ret ((int) &retbuf,
                                         "start_trace_experiment",
                                         "start_trace_experiment",
                                         ret);
                                         ret);
        }
        }
    }
    }
  else if (msgcmp (&request, "Stop"))
  else if (msgcmp (&request, "Stop"))
    {
    {
      trace_running = 0;
      trace_running = 0;
      if (adbg_check_if_active ())
      if (adbg_check_if_active ())
        {
        {
          gdb_note ("STUB: call end_trace_experiment();\n", 0);
          gdb_note ("STUB: call end_trace_experiment();\n", 0);
          if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
          if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
            return "OK";
            return "OK";
          else
          else
            {
            {
              sprintp (retbuf, "E2%x", ret);
              sprintp (retbuf, "E2%x", ret);
              return (char *) dtc_error_ret ((int) &retbuf,
              return (char *) dtc_error_ret ((int) &retbuf,
                                             "end_trace_experiment",
                                             "end_trace_experiment",
                                             ret);
                                             ret);
            }
            }
        }
        }
      else return "OK";
      else return "OK";
    }
    }
  /* "TDP:" (The 'T' was consumed in handle_request.)  */
  /* "TDP:" (The 'T' was consumed in handle_request.)  */
  else if (msgcmp (&request, "DP:"))
  else if (msgcmp (&request, "DP:"))
    {
    {
      /* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format>
      /* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format>
                                                     {S{R[M,X]+}}<tp-format>
                                                     {S{R[M,X]+}}<tp-format>
 
 
         D -- disable tracepoint (illegal from EMC's point of view)
         D -- disable tracepoint (illegal from EMC's point of view)
         E -- enable tracepoint?
         E -- enable tracepoint?
 
 
         R -- regs format: R<regs-mask>
         R -- regs format: R<regs-mask>
         M -- memory format: M<regnum>,<offset>,<size>
         M -- memory format: M<regnum>,<offset>,<size>
         X -- expr format: X<size>,<bytecodes>
         X -- expr format: X<size>,<bytecodes>
         S -- fencepost between trap formats and stepping formats.
         S -- fencepost between trap formats and stepping formats.
         */
         */
 
 
      /* state variable, required for splitting TDP packets. */
      /* state variable, required for splitting TDP packets. */
      static int doing_step_formats;
      static int doing_step_formats;
 
 
      /*
      /*
       * TDP: packets may now be split into multiple packets.
       * TDP: packets may now be split into multiple packets.
       * If a TDP packet is to be continued in another packet, it
       * If a TDP packet is to be continued in another packet, it
       * must end in a "-" character.  The subsequent continuation
       * must end in a "-" character.  The subsequent continuation
       * packet will then begin with a "-" character, between the
       * packet will then begin with a "-" character, between the
       * token "TDP:" and the tdp_id field.  The ID and address
       * token "TDP:" and the tdp_id field.  The ID and address
       * will be repeated in each sub-packet.  The step_count,
       * will be repeated in each sub-packet.  The step_count,
       * pass_count, and 'enabled' field must appear in the first
       * pass_count, and 'enabled' field must appear in the first
       * packet.  The boundary between sub-packets may not appear
       * packet.  The boundary between sub-packets may not appear
       * between the "S" that denotes the start of stepping "formats",
       * between the "S" that denotes the start of stepping "formats",
       * and the regs_mask that follows it.  The split may also not
       * and the regs_mask that follows it.  The split may also not
       * occur in the middle of either a memrange description or a
       * occur in the middle of either a memrange description or a
       * bytecode string.  -- MVS
       * bytecode string.  -- MVS
       */
       */
 
 
      if (*request == '-')      /* this is a continuation of a
      if (*request == '-')      /* this is a continuation of a
                                   trace definition in progress */
                                   trace definition in progress */
        {
        {
          unsigned long temp_id, temp_addr;
          unsigned long temp_id, temp_addr;
 
 
          request++;
          request++;
          if (!(hexToInt (&request, &temp_id) &&
          if (!(hexToInt (&request, &temp_id) &&
                *request++ == ':'))
                *request++ == ':'))
            return "E11";           /* badly formed packet, field 1 */
            return "E11";           /* badly formed packet, field 1 */
 
 
          if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
          if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
                *request++ == ':'))
                *request++ == ':'))
            return "E12";           /* badly formed packet, field 2 */
            return "E12";           /* badly formed packet, field 2 */
 
 
          if (temp_id   != tdp_temp.id)
          if (temp_id   != tdp_temp.id)
            return "E11";       /* something wrong: field 1 doesn't match */
            return "E11";       /* something wrong: field 1 doesn't match */
          if (temp_addr != (unsigned long) tdp_temp.addr)
          if (temp_addr != (unsigned long) tdp_temp.addr)
            return "E12";       /* something wrong: field 2 doesn't match */
            return "E12";       /* something wrong: field 2 doesn't match */
        }
        }
      else                      /* This is a new TDP definition */
      else                      /* This is a new TDP definition */
        {
        {
          memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
          memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
          memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
          memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
          doing_step_formats = FALSE;
          doing_step_formats = FALSE;
 
 
          if (!(hexToInt (&request, &tdp_temp.id) &&
          if (!(hexToInt (&request, &tdp_temp.id) &&
                *request++ == ':'))
                *request++ == ':'))
            return "E11";           /* badly formed packet, field 1 */
            return "E11";           /* badly formed packet, field 1 */
 
 
          if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
          if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
                *request++ == ':'))
                *request++ == ':'))
            return "E12";           /* badly formed packet, field 2 */
            return "E12";           /* badly formed packet, field 2 */
 
 
          if (!(((enable = *request++) == 'D' || enable == 'E') &&
          if (!(((enable = *request++) == 'D' || enable == 'E') &&
                *request++ == ':'))
                *request++ == ':'))
            return "E13";           /* badly formed packet, field 3 */
            return "E13";           /* badly formed packet, field 3 */
#if 0
#if 0
          if (enable == 'D')
          if (enable == 'D')
            {
            {
              gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
              gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
              return "E20";
              return "E20";
            }
            }
#endif
#endif
          if (!(hexToInt (&request, &tdp_temp.stepcount) &&
          if (!(hexToInt (&request, &tdp_temp.stepcount) &&
                *request++ == ':'))
                *request++ == ':'))
            return "E14";           /* badly formed packet, field 4 */
            return "E14";           /* badly formed packet, field 4 */
 
 
          if (!hexToInt (&request, &tdp_temp.pass_limit))
          if (!hexToInt (&request, &tdp_temp.pass_limit))
            return "E15";           /* badly formed packet, field 5 */
            return "E15";           /* badly formed packet, field 5 */
 
 
        }
        }
 
 
      /* Typically, the first group of collection descriptors
      /* Typically, the first group of collection descriptors
         refers to the trap collection.  There is an "S" token
         refers to the trap collection.  There is an "S" token
         to act as a fencepost between collection descriptors for
         to act as a fencepost between collection descriptors for
         the trap, and those for the single-stepping.
         the trap, and those for the single-stepping.
 
 
         However, when the packet is split up into several packets,
         However, when the packet is split up into several packets,
         this "S" token may already have been seen in a previous
         this "S" token may already have been seen in a previous
         sub-packet; so we have to remember it in a state variable.  */
         sub-packet; so we have to remember it in a state variable.  */
 
 
      if (*request == 'R' || *request == 'M' || *request == 'X')
      if (*request == 'R' || *request == 'M' || *request == 'X')
        {
        {
          if (handle_format (&request, &tempfmt1))
          if (handle_format (&request, &tempfmt1))
            return "E16";
            return "E16";
          if (doing_step_formats)
          if (doing_step_formats)
            tdp_temp.tp_format_p  = tempfmt1.id;
            tdp_temp.tp_format_p  = tempfmt1.id;
          else
          else
            tdp_temp.tdp_format_p = tempfmt1.id;
            tdp_temp.tdp_format_p = tempfmt1.id;
        }
        }
 
 
      /* When we see the "S" token, we remember it in a state variable
      /* When we see the "S" token, we remember it in a state variable
         (in case the packet is split up and continued in another message),
         (in case the packet is split up and continued in another message),
         and discard all current state from the collection "format".  */
         and discard all current state from the collection "format".  */
      if (*request == 'S')
      if (*request == 'S')
        {
        {
          doing_step_formats = TRUE;
          doing_step_formats = TRUE;
          /* discard prev format and start a new one */
          /* discard prev format and start a new one */
          memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
          memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
          request++;
          request++;
 
 
          /* Having seen the "S" fencepost, it is now possible that
          /* Having seen the "S" fencepost, it is now possible that
             we will see some more collection descriptors pertaining
             we will see some more collection descriptors pertaining
             to the stepping collection.  */
             to the stepping collection.  */
          if (*request   == 'R' || *request == 'M' || *request == 'X')
          if (*request   == 'R' || *request == 'M' || *request == 'X')
            {
            {
              if (handle_format (&request, &tempfmt1))
              if (handle_format (&request, &tempfmt1))
                return "E17";
                return "E17";
              /* new format ID is tp_format */
              /* new format ID is tp_format */
              tdp_temp.tp_format_p = tempfmt1.id;
              tdp_temp.tp_format_p = tempfmt1.id;
            }
            }
        }
        }
 
 
      if (*request == '-')      /* this TDP definition will be continued. */
      if (*request == '-')      /* this TDP definition will be continued. */
        sprintp (retbuf, "OK");
        sprintp (retbuf, "OK");
      else if (enable == 'E')   /* end of TDP definition: pass to ADBG (if enabled!) */
      else if (enable == 'E')   /* end of TDP definition: pass to ADBG (if enabled!) */
        {
        {
          gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id);
          gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id);
          gdb_note ("addr 0x%X, ", (int) tdp_temp.addr);
          gdb_note ("addr 0x%X, ", (int) tdp_temp.addr);
          gdb_note ("passc %d, ",        tdp_temp.pass_limit);
          gdb_note ("passc %d, ",        tdp_temp.pass_limit);
          gdb_note ("stepc %d, ",        tdp_temp.stepcount);
          gdb_note ("stepc %d, ",        tdp_temp.stepcount);
          gdb_note ("TDP fmt #%d, ",     tdp_temp.tdp_format_p);
          gdb_note ("TDP fmt #%d, ",     tdp_temp.tdp_format_p);
          gdb_note ("TP fmt #%d);\n",    tdp_temp.tp_format_p);
          gdb_note ("TP fmt #%d);\n",    tdp_temp.tp_format_p);
 
 
          ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
          ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
 
 
          if (ret == OK_TARGET_RESPONSE)
          if (ret == OK_TARGET_RESPONSE)
            {
            {
              sprintp (retbuf, "OK");
              sprintp (retbuf, "OK");
            }
            }
          else
          else
            {
            {
              sprintp (spare_buffer,
              sprintp (spare_buffer,
                       "'define_tdp' returned DTC error '%s' for tracepoint %d.\n",
                       "'define_tdp' returned DTC error '%s' for tracepoint %d.\n",
                       get_err_text (ret),
                       get_err_text (ret),
                       tdp_temp.id);
                       tdp_temp.id);
              gdb_puts (spare_buffer);
              gdb_puts (spare_buffer);
              sprintp (retbuf, "E2%x", ret);
              sprintp (retbuf, "E2%x", ret);
            }
            }
          /* Redundant, but let's try to make sure this state gets discarded. */
          /* Redundant, but let's try to make sure this state gets discarded. */
          {
          {
            memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
            memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
            memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
            memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
          }
          }
        }
        }
      else /* ADBG_DTC does not support disabled tracepoints -- ignore it.  */
      else /* ADBG_DTC does not support disabled tracepoints -- ignore it.  */
        gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
        gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
 
 
      return retbuf;
      return retbuf;
    }
    }
  else if (msgcmp (&request, "Frame:"))
  else if (msgcmp (&request, "Frame:"))
    {
    {
      ret = OK_TARGET_RESPONSE;
      ret = OK_TARGET_RESPONSE;
 
 
      if (msgcmp (&request, "pc:"))
      if (msgcmp (&request, "pc:"))
        {
        {
          if (!hexToInt (&request, &pc))
          if (!hexToInt (&request, &pc))
            return "E10";       /* badly formed packet */
            return "E10";       /* badly formed packet */
          n_frame = curframe.valid ? curframe.frame_id + 1 : 0;
          n_frame = curframe.valid ? curframe.frame_id + 1 : 0;
          gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame);
          gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame);
          gdb_note ("pc 0x%X);\n", pc);
          gdb_note ("pc 0x%X);\n", pc);
          ret = fetch_trace_frame_with_pc (&n_frame,
          ret = fetch_trace_frame_with_pc (&n_frame,
                                           (void *) pc,
                                           (void *) pc,
                                           &curframe.format,
                                           &curframe.format,
                                           &curframe.frame_data);
                                           &curframe.frame_data);
        }
        }
      else if (msgcmp (&request, "tdp:"))
      else if (msgcmp (&request, "tdp:"))
        {
        {
          if (!hexToInt (&request, &tdp))
          if (!hexToInt (&request, &tdp))
            return "E10";       /* badly formed packet */
            return "E10";       /* badly formed packet */
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
          gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame);
          gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame);
          gdb_note ("tdp 0x%X);\n", tdp);
          gdb_note ("tdp 0x%X);\n", tdp);
          ret = fetch_trace_frame_with_tdp (&n_frame,
          ret = fetch_trace_frame_with_tdp (&n_frame,
                                            tdp,
                                            tdp,
                                            &curframe.format,
                                            &curframe.format,
                                            &curframe.frame_data);
                                            &curframe.frame_data);
        }
        }
      else if (msgcmp (&request, "range:"))
      else if (msgcmp (&request, "range:"))
        {
        {
          if (!(hexToInt (&request, &start) &&
          if (!(hexToInt (&request, &start) &&
                *request++ == ':'))
                *request++ == ':'))
            return "E11";      /* badly formed packet, field 1 */
            return "E11";      /* badly formed packet, field 1 */
          else if (!hexToInt (&request, &stop))
          else if (!hexToInt (&request, &stop))
            return "E12";       /* badly formed packet, field 2 */
            return "E12";       /* badly formed packet, field 2 */
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
          gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame);
          gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame);
          gdb_note ("start 0x%X, ",   start);
          gdb_note ("start 0x%X, ",   start);
          gdb_note ("stop  0x%X);\n", stop);
          gdb_note ("stop  0x%X);\n", stop);
          ret = fetch_trace_frame_with_pc_in_range (&n_frame,
          ret = fetch_trace_frame_with_pc_in_range (&n_frame,
                                                    (void *) start,
                                                    (void *) start,
                                                    (void *) stop,
                                                    (void *) stop,
                                                    &curframe.format,
                                                    &curframe.format,
                                                    &curframe.frame_data);
                                                    &curframe.frame_data);
        }
        }
      else if (msgcmp (&request, "outside:"))
      else if (msgcmp (&request, "outside:"))
        {
        {
          if (!(hexToInt (&request, &start) &&
          if (!(hexToInt (&request, &start) &&
                *request++ == ':'))
                *request++ == ':'))
            return "E11";       /* badly formed packet, field 1 */
            return "E11";       /* badly formed packet, field 1 */
          else if (!hexToInt (&request, &stop))
          else if (!hexToInt (&request, &stop))
            return "E12";       /* badly formed packet, field 2 */
            return "E12";       /* badly formed packet, field 2 */
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
          n_frame = curframe.valid ? curframe.frame_id + 1: 0;
          gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame);
          gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame);
          gdb_note ("start 0x%X, ",   start);
          gdb_note ("start 0x%X, ",   start);
          gdb_note ("stop  0x%X);\n", stop);
          gdb_note ("stop  0x%X);\n", stop);
          ret = fetch_trace_frame_with_pc_outside (&n_frame,
          ret = fetch_trace_frame_with_pc_outside (&n_frame,
                                                   (void *) start,
                                                   (void *) start,
                                                   (void *) stop,
                                                   (void *) stop,
                                                   &curframe.format,
                                                   &curframe.format,
                                                   &curframe.frame_data);
                                                   &curframe.frame_data);
        }
        }
      else /* simple TFind by frame number: */
      else /* simple TFind by frame number: */
        {
        {
          if (!hexToInt (&request, &frameno))
          if (!hexToInt (&request, &frameno))
            return "E10";       /* badly formed packet */
            return "E10";       /* badly formed packet */
          if (frameno != (unsigned long) -1)
          if (frameno != (unsigned long) -1)
            {
            {
              gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno);
              gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno);
              ret = fetch_trace_frame (n_frame = frameno,
              ret = fetch_trace_frame (n_frame = frameno,
                                       &curframe.format,
                                       &curframe.format,
                                       &curframe.frame_data);
                                       &curframe.frame_data);
#if 0
#if 0
              printp("STUB: fetch_trace_frame: return %d\n", ret);
              printp("STUB: fetch_trace_frame: return %d\n", ret);
#endif
#endif
            }
            }
          else  /* discard any trace frame, debug "the real world" */
          else  /* discard any trace frame, debug "the real world" */
            {
            {
              if (curframe.valid)
              if (curframe.valid)
                gdb_note ("STUB: discard current trace frame #%d.\n",
                gdb_note ("STUB: discard current trace frame #%d.\n",
                          curframe.frame_id);
                          curframe.frame_id);
              curframe.valid = 0;
              curframe.valid = 0;
              return "OK";
              return "OK";
            }
            }
        }
        }
      if (ret == OK_TARGET_RESPONSE)    /* fetch_trace_frame succeeded */
      if (ret == OK_TARGET_RESPONSE)    /* fetch_trace_frame succeeded */
        { /* setup for debugging the trace frame */
        { /* setup for debugging the trace frame */
          curframe.valid    = 1;
          curframe.valid    = 1;
          curframe.frame_id = n_frame;
          curframe.frame_id = n_frame;
          curframe.tdp_id   = curframe.frame_data->id;
          curframe.tdp_id   = curframe.frame_data->id;
 
 
          memset ((char *) &curframe.traceregs, 0,
          memset ((char *) &curframe.traceregs, 0,
                  sizeof (curframe.traceregs));
                  sizeof (curframe.traceregs));
          curframe.traceregs[PC] = (unsigned long)
          curframe.traceregs[PC] = (unsigned long)
            curframe.frame_data->program_counter;
            curframe.frame_data->program_counter;
 
 
          if (curframe.format)
          if (curframe.format)
            {
            {
              unsigned long regs_mask = curframe.format->regs_mask;
              unsigned long regs_mask = curframe.format->regs_mask;
              unsigned long *regs, *stack, *mem;
              unsigned long *regs, *stack, *mem;
              unsigned long regno, index = 0;
              unsigned long regno, index = 0;
              CFD *dummy;
              CFD *dummy;
 
 
              if ((ret = get_addr_to_frame_regs_stack_mem
              if ((ret = get_addr_to_frame_regs_stack_mem
                   (curframe.frame_data, &dummy, &regs, &stack, &mem))
                   (curframe.frame_data, &dummy, &regs, &stack, &mem))
                  != OK_TARGET_RESPONSE)
                  != OK_TARGET_RESPONSE)
                {
                {
                  curframe.valid = 0;
                  curframe.valid = 0;
                  sprintp (retbuf, "E2%x", ret);
                  sprintp (retbuf, "E2%x", ret);
                  return (char *)
                  return (char *)
                    dtc_error_ret ((int) &retbuf,
                    dtc_error_ret ((int) &retbuf,
                                   "get_addr_to_frame_regs_stack_mem",
                                   "get_addr_to_frame_regs_stack_mem",
                                   ret);
                                   ret);
                }
                }
 
 
              if (remote_debug > 1)
              if (remote_debug > 1)
                { /* echo what we've found to gdb console */
                { /* echo what we've found to gdb console */
                  sprintp (spare_buffer,
                  sprintp (spare_buffer,
                           "STUB: Found frame %d, TDP %d, format %d (%s):\n",
                           "STUB: Found frame %d, TDP %d, format %d (%s):\n",
                           curframe.frame_id,
                           curframe.frame_id,
                           curframe.tdp_id & 0x7fffffff,
                           curframe.tdp_id & 0x7fffffff,
                           curframe.format->id,
                           curframe.format->id,
                           curframe.tdp_id & 0x80000000 ?
                           curframe.tdp_id & 0x80000000 ?
                           "trap frame" : "stepping frame");
                           "trap frame" : "stepping frame");
                  gdb_puts (spare_buffer);
                  gdb_puts (spare_buffer);
                }
                }
              /* copy trace frame regs into stub's data format */
              /* copy trace frame regs into stub's data format */
              for (regno = 0, index = 0;
              for (regno = 0, index = 0;
                   regno < 16;
                   regno < 16;
                   regno++, regs_mask >>= 1)
                   regno++, regs_mask >>= 1)
                if (regs_mask & 1)      /* got a collected register */
                if (regs_mask & 1)      /* got a collected register */
                  {
                  {
                    curframe.traceregs[regno] = regs[index++];
                    curframe.traceregs[regno] = regs[index++];
                    if (remote_debug > 1)
                    if (remote_debug > 1)
                      {
                      {
                        sprintp (spare_buffer,
                        sprintp (spare_buffer,
                                 "      Collected 0x%08x for register %d.\n",
                                 "      Collected 0x%08x for register %d.\n",
                                 curframe.traceregs[regno], regno);
                                 curframe.traceregs[regno], regno);
                        gdb_puts (spare_buffer);
                        gdb_puts (spare_buffer);
                      }
                      }
                  }
                  }
              if (remote_debug > 1)
              if (remote_debug > 1)
                {
                {
                  long           midx, ridx, len;
                  long           midx, ridx, len;
                  MEMRANGE_DEF  *mrange;
                  MEMRANGE_DEF  *mrange;
                  unsigned char *data, *base;
                  unsigned char *data, *base;
 
 
                  if (curframe.format->stack_size > 0)
                  if (curframe.format->stack_size > 0)
                    {
                    {
                      len = curframe.format->stack_size;
                      len = curframe.format->stack_size;
                      sprintp (spare_buffer,
                      sprintp (spare_buffer,
                               "      Collected %d bytes of stack at 0x%x:\n",
                               "      Collected %d bytes of stack at 0x%x:\n",
                               len, curframe.traceregs[A7]);
                               len, curframe.traceregs[A7]);
                      gdb_puts (spare_buffer);
                      gdb_puts (spare_buffer);
 
 
                      /* print stack data, but stay under msg len */
                      /* print stack data, but stay under msg len */
                      if (len >= (NUMREGBYTES/2 - 2))
                      if (len >= (NUMREGBYTES/2 - 2))
                        len =    (NUMREGBYTES/2 - 3);
                        len =    (NUMREGBYTES/2 - 3);
                      mem2hex ((unsigned char *) stack,
                      mem2hex ((unsigned char *) stack,
                               spare_buffer, len, 0);
                               spare_buffer, len, 0);
                      spare_buffer [len * 2] = '\n';
                      spare_buffer [len * 2] = '\n';
                      spare_buffer [len * 2 + 1] = '\0'; /* EOS */
                      spare_buffer [len * 2 + 1] = '\0'; /* EOS */
                      gdb_puts (spare_buffer);
                      gdb_puts (spare_buffer);
                    }
                    }
                  else
                  else
                    gdb_puts ("Stack not collected\n");
                    gdb_puts ("Stack not collected\n");
 
 
                  for (midx = 0;
                  for (midx = 0;
                       get_addr_to_a_mem_range (curframe.frame_data,
                       get_addr_to_a_mem_range (curframe.frame_data,
                                                midx,
                                                midx,
                                                &mrange,
                                                &mrange,
                                                (void **) &data)
                                                (void **) &data)
                       == OK_TARGET_RESPONSE;
                       == OK_TARGET_RESPONSE;
                       midx++)
                       midx++)
                    {
                    {
                      if ((mrange->typecode == 0) ||
                      if ((mrange->typecode == 0) ||
                          (mrange->typecode == (unsigned long) -1))
                          (mrange->typecode == (unsigned long) -1))
                        {
                        {
                          sprintp (spare_buffer,
                          sprintp (spare_buffer,
                                   "      Collected %d bytes at MEM: 0x%x:\n",
                                   "      Collected %d bytes at MEM: 0x%x:\n",
                                   mrange->size, mrange->offset);
                                   mrange->size, mrange->offset);
                          base = (unsigned char *) mrange->offset;
                          base = (unsigned char *) mrange->offset;
                        }
                        }
                      else
                      else
                        {
                        {
                          if ((ridx = elinum_to_index (mrange->typecode)) > 0)
                          if ((ridx = elinum_to_index (mrange->typecode)) > 0)
                            base = (unsigned char *) curframe.traceregs[ridx]
                            base = (unsigned char *) curframe.traceregs[ridx]
                              + (long) mrange->offset;
                              + (long) mrange->offset;
                          else
                          else
                            {
                            {
                              sprintp (spare_buffer,
                              sprintp (spare_buffer,
                   "STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n",
                   "STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n",
                                       midx,
                                       midx,
                                       mrange->typecode,
                                       mrange->typecode,
                                       mrange->offset,
                                       mrange->offset,
                                       mrange->size);
                                       mrange->size);
                              gdb_puts (spare_buffer);
                              gdb_puts (spare_buffer);
                              continue;
                              continue;
                            }
                            }
                          sprintp (spare_buffer,
                          sprintp (spare_buffer,
                   "      Collected %d bytes at 0x%x (REG %X + %d):\n",
                   "      Collected %d bytes at 0x%x (REG %X + %d):\n",
                                   mrange->size,
                                   mrange->size,
                                   base,
                                   base,
                                   mrange->typecode,
                                   mrange->typecode,
                                   mrange->offset);
                                   mrange->offset);
                        }
                        }
                      gdb_puts (spare_buffer);
                      gdb_puts (spare_buffer);
                      len = mrange->size;
                      len = mrange->size;
                      if (len >= (NUMREGBYTES/2 - 2))
                      if (len >= (NUMREGBYTES/2 - 2))
                        len =    (NUMREGBYTES/2 - 3);
                        len =    (NUMREGBYTES/2 - 3);
                      mem2hex (data, spare_buffer, len, 0);
                      mem2hex (data, spare_buffer, len, 0);
                      spare_buffer [len * 2] = '\n';
                      spare_buffer [len * 2] = '\n';
                      spare_buffer [len * 2 + 1] = '\0'; /* EOS */
                      spare_buffer [len * 2 + 1] = '\0'; /* EOS */
                      gdb_puts (spare_buffer);
                      gdb_puts (spare_buffer);
                    }
                    }
                }
                }
            }
            }
          sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
          sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
          return   retbuf;
          return   retbuf;
        }
        }
      else if (ret == NOT_FOUND_TARGET_RESPONSE)
      else if (ret == NOT_FOUND_TARGET_RESPONSE)
        {
        {
          /* Here's a question: if the fetch_trace_frame call failed
          /* Here's a question: if the fetch_trace_frame call failed
             (which probably means a bad "TFIND" command from GDB),
             (which probably means a bad "TFIND" command from GDB),
             should we remain focused on the previous frame (if any),
             should we remain focused on the previous frame (if any),
             or should we revert to "no current frame"?
             or should we revert to "no current frame"?
           */
           */
          return "F-1";
          return "F-1";
        }
        }
      else
      else
        {
        {
          sprintp (retbuf, "E2%x", ret);
          sprintp (retbuf, "E2%x", ret);
          return (char *) dtc_error_ret ((int) &retbuf,
          return (char *) dtc_error_ret ((int) &retbuf,
                                         "fetch_trace_frame[...]",
                                         "fetch_trace_frame[...]",
                                         ret);
                                         ret);
        }
        }
    }
    }
  else                  /* unknown trace command */
  else                  /* unknown trace command */
    {
    {
      return "";
      return "";
    }
    }
}
}
 
 
/* Table used by the crc32 function to calcuate the checksum. */
/* Table used by the crc32 function to calcuate the checksum. */
static unsigned long crc32_table[256];
static unsigned long crc32_table[256];
 
 
static int crc_mem_err;
static int crc_mem_err;
 
 
static unsigned long
static unsigned long
crc32 (buf, len, crc)
crc32 (buf, len, crc)
     unsigned char *buf;
     unsigned char *buf;
     int len;
     int len;
     unsigned long crc;
     unsigned long crc;
{
{
  crc_mem_err = FALSE;
  crc_mem_err = FALSE;
 
 
  if (! crc32_table[1])
  if (! crc32_table[1])
    {
    {
      /* Initialize the CRC table and the decoding table. */
      /* Initialize the CRC table and the decoding table. */
      int i, j;
      int i, j;
      unsigned int c;
      unsigned int c;
 
 
      for (i = 0; i < 256; i++)
      for (i = 0; i < 256; i++)
        {
        {
          for (c = i << 24, j = 8; j > 0; --j)
          for (c = i << 24, j = 8; j > 0; --j)
            c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
            c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
          crc32_table[i] = c;
          crc32_table[i] = c;
        }
        }
    }
    }
 
 
  while (len--)
  while (len--)
    {
    {
      if (read_access_violation (buf))
      if (read_access_violation (buf))
        {
        {
          crc_mem_err = TRUE;
          crc_mem_err = TRUE;
          return -1;
          return -1;
        }
        }
      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
    }
    }
  return crc;
  return crc;
}
}
 
 
static char *
static char *
crc_query (cmd)
crc_query (cmd)
     char *cmd;
     char *cmd;
{
{
  unsigned long startmem, len, crc;
  unsigned long startmem, len, crc;
  static char buf[32];
  static char buf[32];
 
 
  if (hexToInt (&cmd, &startmem) &&
  if (hexToInt (&cmd, &startmem) &&
      *cmd++ == ','              &&
      *cmd++ == ','              &&
      hexToInt (&cmd, &len))
      hexToInt (&cmd, &len))
    {
    {
      crc = crc32  ((unsigned char *) startmem, len, 0xffffffff);
      crc = crc32  ((unsigned char *) startmem, len, 0xffffffff);
      if (!crc_mem_err)
      if (!crc_mem_err)
        {
        {
          sprintp (buf, "C%08x", crc);
          sprintp (buf, "C%08x", crc);
          return buf;
          return buf;
        }
        }
      /* else error, fall thru */
      /* else error, fall thru */
    }
    }
  sprintp (buf, "E01");
  sprintp (buf, "E01");
  return buf;
  return buf;
}
}
 
 
 
 
static char *
static char *
handle_test (request)
handle_test (request)
     char *request;
     char *request;
{
{
  ULONG args[7];
  ULONG args[7];
  int i;
  int i;
 
 
  /* Parse the arguments, a comma-separated list of hex numbers, into
  /* Parse the arguments, a comma-separated list of hex numbers, into
     ARGS.  Parse at most six arguments.  */
     ARGS.  Parse at most six arguments.  */
  i = 1;
  i = 1;
  if (*request != '\0')
  if (*request != '\0')
    while (i < 7)
    while (i < 7)
      {
      {
        if (! hexToInt (&request, &args[i++]))
        if (! hexToInt (&request, &args[i++]))
          return "E01";
          return "E01";
        if (*request == '\0')
        if (*request == '\0')
          break;
          break;
        if (*request++ != ',')
        if (*request++ != ',')
          return "E01";
          return "E01";
      }
      }
 
 
  /* Fill the rest of the args array with zeros.  This is what the
  /* Fill the rest of the args array with zeros.  This is what the
     INLINES command processor does with omitted arguments.  */
     INLINES command processor does with omitted arguments.  */
  for (; i < 7; i++)
  for (; i < 7; i++)
    args[i] = 0;
    args[i] = 0;
 
 
  gdb_c_test (args);
  gdb_c_test (args);
 
 
  return "OK";
  return "OK";
}
}
 
 
 
 
/* GDB_TRAP_1_HANDLER
/* GDB_TRAP_1_HANDLER
 
 
   By the time this is called, the registers have been saved in "registers",
   By the time this is called, the registers have been saved in "registers",
   and the interrupt priority has been set to permit serial UART interrupts.
   and the interrupt priority has been set to permit serial UART interrupts.
 
 
   However, since no gdb request has yet been received, and there is no
   However, since no gdb request has yet been received, and there is no
   equivalent of getpacket for us to wait on, we can't sit here waiting
   equivalent of getpacket for us to wait on, we can't sit here waiting
   for packets and processing them.
   for packets and processing them.
 
 
   In fact, the ONLY thing for us to do here is sit and wait.
   In fact, the ONLY thing for us to do here is sit and wait.
   As gdb sends packet requests, they will handle themselves at the
   As gdb sends packet requests, they will handle themselves at the
   interrupt level.  When gdb decides we can continue, it will reset
   interrupt level.  When gdb decides we can continue, it will reset
   the global variable "gdb_handling_trap1", and we will return
   the global variable "gdb_handling_trap1", and we will return
   (whereupon registers will be restored etc.)   */
   (whereupon registers will be restored etc.)   */
 
 
void  gdb_trap_1_handler( void )
void  gdb_trap_1_handler( void )
{
{
  gdb_handling_trap1 = TRUE;
  gdb_handling_trap1 = TRUE;
  sss_trace_flag = '\0';        /* shut off "trace bit" (indirectly) */
  sss_trace_flag = '\0';        /* shut off "trace bit" (indirectly) */
  gdb_signo = 5;
  gdb_signo = 5;
  putpacket( "S05" );
  putpacket( "S05" );
  while ( gdb_handling_trap1 )
  while ( gdb_handling_trap1 )
    ;
    ;
  return;
  return;
}
}
 
 
void  gdb_trace_handler( void )
void  gdb_trace_handler( void )
{
{
  sss_trace_flag = '\0';        /* shut off "trace bit" (indirectly) */
  sss_trace_flag = '\0';        /* shut off "trace bit" (indirectly) */
  gdb_handling_trap1 = TRUE;
  gdb_handling_trap1 = TRUE;
  gdb_handling_sstrace = TRUE;
  gdb_handling_sstrace = TRUE;
  gdb_signo = 5;
  gdb_signo = 5;
  putpacket( "S05" );
  putpacket( "S05" );
  while ( gdb_handling_trap1 )
  while ( gdb_handling_trap1 )
    ;
    ;
  return;
  return;
}
}
 
 

powered by: WebSVN 2.1.0

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