#ifdef DO_IT_BY_THE_BOOK
#include "symtypes_defs.h"
#include "printp.h"
#include "adbg_expression.h"
#include "common_hw_ds.h"
#include "common_hw_defs.h"
#include "evnttrac.h"
#include "sym_scratch_ds.h"
#include "symglob_ds.h"
#include "sym_protglob_ds.h"
#include "ether.h"
#include <ctype.h>
#else
#include "adbg_dtc.h"
#define YES 1
#define NO 0
#define TRUE 1
#define FALSE 0
#define ENABLED 1
#define DISABLED 0
#define CONTROL_C 3
#define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
((X) >= 'A' && (X) <= 'F') || \
((X) >= 'a' && (X) <= 'f'))
extern unsigned int strlen ( const char * );
typedef char BOOL;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned long ULONG;
#include "adbg_expression.h"
#define NULL 0
extern void printp ( const char * fptr, ... );
extern void sprintp ( const char * fptr, ... );
extern long eth_to_gdb ( UCHAR *buf, long length );
#define CS_CODE_START 0x100000
#define CS_CODE_SIZE 0x200000
#define LAST_CS_WORD (CS_CODE_START + CS_CODE_SIZE - 2)
#define sh_genstat1 (*((volatile ULONG *) 0xFFFFFE54))
#define rs232_mode1 0
#define rs232_mode2 rs232_mode1
#define rs232_stat 4
#define rs232_clk rs232_stat
#define rs232_cmd 8
#define rs232_transmit 12
#define rs232_receive rs232_transmit
#define rs232_aux 16
#define rs232_isr 20
#define rs232_imr rs232_isr
#define rs232_tc_high 24
#define rs232_tc_low 28
#endif
#define P_RST_LAN_UART_REG ((volatile UCHAR *) 0xFFFFFE45)
#define M_RST_LAN_UART 0x80
#define P_LAN0TR_REG P_RST_LAN_UART_REG
#define M_LAN0TR 0x20
#define M_SH_GENCON_LAN0TR 0x00200000
#define MAX_RS232_CHARS 512
#define LAN_Q_MOD(X) ((X) % MAX_RS232_CHARS)
#define LAN_UART_BASE ((ULONG) 0xfffffc22)
#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_ACR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux )))
#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_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_IMR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr )))
#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_XMT ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit)))
#define P_LAN_RCV ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive )))
#define DEFAULT_LAN_MR1 ((UCHAR) 0x13)
#define DEFAULT_LAN_MR2 ((UCHAR) 0x07)
#define DEFAULT_LAN_CSR ((UCHAR) 0xcc)
#define DEFAULT_LAN_ACR ((UCHAR) 0x38)
#define DEFAULT_LAN_CTUR ((UCHAR) 0xff)
#define DEFAULT_LAN_CTLR ((UCHAR) 0xff)
#define LAN_ACR_SELECT_BRG_0 DEFAULT_LAN_ACR
#define LAN_ACR_SELECT_BRG_1 (DEFAULT_LAN_ACR | 0x80)
#define UART_CR_RESET_MR_PTR ((UCHAR) 0x10)
#define UART_CR_RESET_RVCR ((UCHAR) 0x20)
#define UART_CR_RESET_XMTR ((UCHAR) 0x30)
#define UART_CR_RESET_ERROR_STATUS ((UCHAR) 0x40)
#define UART_CR_RESET_BRK_CHG_INT ((UCHAR) 0x50)
#define UART_CR_START_CNTR_TIMER ((UCHAR) 0x80)
#define UART_CR_STOP_CNTR ((UCHAR) 0x90)
#define UART_CR_DISABLE_XMTR ((UCHAR) 0x08)
#define UART_CR_ENABLE_XMTR ((UCHAR) 0x04)
#define UART_CR_DISABLE_RCVR ((UCHAR) 0x02)
#define UART_CR_ENABLE_RCVR ((UCHAR) 0x01)
#define UART_CSR_BR_4800 ((UCHAR) 0x99)
#define UART_CSR_BR_9600 ((UCHAR) 0xbb)
#define UART_CSR_BR_19200 ((UCHAR) 0xcc)
#define UART_CSR_BR_38400 ((UCHAR) 0xcc)
#define UART_IMR_RxRDY ((UCHAR) 0x04)
#define UART_IMR_TxEMT ((UCHAR) 0x02)
#define UART_IMR_TxRDY ((UCHAR) 0x01)
#define M_UART_SR_RCVD_BRK 0x80
#define M_UART_SR_FE 0x40
#define M_UART_SR_PE 0x20
#define M_UART_SR_OE 0x10
#define M_UART_SR_TxEMT 0x08
#define M_UART_SR_TxRDY 0x04
#define M_UART_SR_FFULL 0x02
#define M_UART_SR_RxRDY 0x01
#define M_UART_ISR_RxRDY 0x04
#define M_UART_ISR_TxEMT 0x02
#define M_UART_ISR_TxRDY 0x01
#define LAN_UTIL_CODE 0x83
#define LAN_INIT ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T'))
#define LAN_BAUD ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D'))
#define LAN_INTR ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R'))
#define LAN_XMT ((ULONG) (('X' << 16) | ('M' << 8) | 'T'))
#define LAN_ECHO ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O'))
#define LAN_STAT ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T'))
#define LAN_IN ((ULONG) (('I' << 8) | 'N'))
#define LAN_OUT ((ULONG) (('O' << 16) | ('U' << 8) | 'T'))
#define LAN_PUTC ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
#define LAN_WPM ((ULONG) (('W' << 16) | ('P' << 8) | 'M'))
#define STATUS(X) ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
#define XMT_VIA_BP_ENABLED() ( *P_LAN0TR_REG & M_LAN0TR ? 1 : 0 )
#define TRAP_1_INST 0x4E41
#define M_PROC_ID 0x00002000
#define IS_SIDE_A() ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
#define IS_SIDE_B() ( (sh_genstat1) & M_PROC_ID )
#ifdef STANDALONE
#define LAN_PUT_CHAR(X) printf("%c", X)
#else
#define LAN_PUT_CHAR(X) while ( lan_put_char( X ) )
#endif
#define VIA_RS232 0
#define VIA_ETHERNET 1
#define MAX_IO_BUF_SIZE 400
#define MAX_BYTE_CODES 200
static ULONG gdb_host_comm;
static ULONG gdb_cat_ack;
static char eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
#ifdef STANDALONE
#define ACK_PKT() LAN_PUT_CHAR( '+' )
#define NACK_PKT() LAN_PUT_CHAR( '-' )
#else
#define ACK_PKT() { \
if ( VIA_ETHERNET == gdb_host_comm ) \
{ \
gdb_cat_ack = YES; \
} \
else \
{ \
LAN_PUT_CHAR( '+' ); \
} \
}
#define NACK_PKT() { \
if ( VIA_ETHERNET == gdb_host_comm ) \
{ \
eth_outbuffer[ 0 ] = '-'; \
eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
} \
else \
{ \
LAN_PUT_CHAR( '-' ); \
} \
}
#endif
typedef struct rs232_queue {
long head_index;
long tail_index;
ULONG overflows;
long gdb_packet_start;
long gdb_packet_end;
long gdb_packet_csum1;
long gdb_packet_csum2;
UCHAR buf[ MAX_RS232_CHARS ];
} T_RS232_QUEUE;
extern volatile UCHAR sss_trace_flag;
static T_RS232_QUEUE lan_input_queue,
lan_output_queue;
static BOOL test_echo;
#if 0
static BOOL write_access_enabled;
#endif
static int baud_rate_idx;
static ULONG tx_by_intr,
tx_by_poll;
static UCHAR lan_shadow_imr;
extern long write_to_protected_mem( void *address, unsigned short value );
ULONG gdb_c_test( ULONG *parm );
void lan_init( void );
void lan_isr( void );
long lan_get_char( void );
long lan_put_char( UCHAR c );
ULONG lan_util( ULONG *parm );
static void lan_reset( void );
static void lan_configure( void );
static void lan_init_queue( 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 void lan_util_menu( void );
static long get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
void gdb_trap_1_handler( void );
void gdb_trace_handler ( void );
void gdb_get_eth_input( unsigned char *buf, long length );
static void getpacket ( void );
static void putpacket ( char * );
static void discard_packet ( void );
#ifdef STANDALONE
#include <stdio.h>
#define printp printf
#endif
extern char *memset (char *, int, int);
static char gdb_char_test;
static short gdb_short_test;
static long gdb_long_test;
static char gdb_arr_test[25];
static struct GDB_STRUCT_TEST
{
char c;
short s;
long l;
int bfield : 11;
char arr[25];
struct GDB_STRUCT_TEST *next;
} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
static union GDB_UNION_TEST
{
char c;
short s;
long l;
int bfield : 11;
char arr[4];
union GDB_UNION_TEST *next;
} gdb_union1_test;
void gdb_recursion_test (int, int, int, int, int, int, int);
void gdb_recursion_test (int depth,
int q1,
int q2,
int q3,
int q4,
int q5,
int q6)
{
int q = q1;
q1 = q2;
q2 = q3;
q3 = q4;
q4 = q5;
q5 = q6;
q6 = q;
if (depth--)
gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6);
}
ULONG gdb_c_test( ULONG *parm )
{
char *p = "gdb_c_test";
char *ridiculously_long_variable_name_with_equally_long_string_assignment;
register long local_reg = 7;
static unsigned long local_static, local_static_sizeof;
long local_long;
unsigned long *stack_ptr;
unsigned long end_of_stack;
ridiculously_long_variable_name_with_equally_long_string_assignment =
"ridiculously long variable name with equally long string assignment";
local_static = 9;
local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
local_long = local_reg + 1;
stack_ptr = (unsigned long *) &local_long;
end_of_stack =
(unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
printp ("\ngdb_c_test.c,v 1.3 2002/03/07 04:18:55 fnf Exp\n");
printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n",
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_short_test = gdb_struct1_test.s = (short) ((long) parm[2] & 0xffff);
gdb_long_test = gdb_struct1_test.l = (long) ((long) parm[3] & 0xffffffff);
gdb_union1_test.l = (long) parm[4];
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[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[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_struct1_test.bfield = 144;
gdb_struct1_test.next = &gdb_struct2_test;
gdb_structp_test = &gdb_struct1_test;
gdb_structpp_test = &gdb_structp_test;
gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
(long) parm[4], (long) parm[5], (long) parm[6]);
gdb_char_test = gdb_short_test = gdb_long_test = 0;
gdb_structp_test = (void *) 0;
gdb_structpp_test = (void *) 0;
memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
local_static_sizeof = 0;
local_static = 0;
return ( (ULONG) 0 );
}
void lan_init( void )
{
if ( IS_SIDE_A( ) )
{
lan_reset( );
lan_init_queue( &lan_input_queue );
lan_init_queue( &lan_output_queue );
lan_configure( );
}
return;
}
void lan_isr( void )
{
UCHAR c;
lan_shadow_imr = 0;
*P_LAN_IMR = lan_shadow_imr;
if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
{
gdb_host_comm = VIA_RS232;
c = *P_LAN_RCV;
if ( test_echo )
{
}
if ( c == CONTROL_C )
{
discard_packet( );
putpacket( "S03" );
}
else
{
lan_add_to_queue( (long) c, &lan_input_queue );
get_gdb_input( (long) c, &lan_input_queue );
}
}
if ( XMT_VIA_BP_ENABLED( ) )
{
c = 0;
while ( (*P_LAN_ISR & M_UART_ISR_TxRDY) && (c = lan_next_queue_char( &lan_output_queue )) )
{
*P_LAN_XMT = c;
++tx_by_intr;
}
if ( c )
{
lan_shadow_imr |= UART_IMR_TxRDY;
}
}
lan_shadow_imr |= UART_IMR_RxRDY;
*P_LAN_IMR = lan_shadow_imr;
return;
}
long lan_get_char( void )
{
long status = -2;
if ( *P_LAN_SR & M_UART_SR_RxRDY )
{
char c = (char) *P_LAN_RCV;
if ( test_echo )
{
LAN_PUT_CHAR ( c );
}
if ( c == CONTROL_C )
{
discard_packet( );
putpacket( "S03" );
status = 0;
}
else
{
lan_add_to_queue( (long) c, &lan_input_queue );
status = get_gdb_input( (long) c, &lan_input_queue );
}
}
return( status );
}
long lan_put_char( UCHAR c )
{
long status = -1;
if ( XMT_VIA_BP_ENABLED( ) )
{
if ( *P_LAN_SR & M_UART_SR_TxRDY )
{
lan_add_to_queue( (long) c, &lan_output_queue );
c = lan_next_queue_char( &lan_output_queue );
*P_LAN_XMT = c;
++tx_by_poll;
status = 0;
}
#if 0
else
{
status = 0;
lan_shadow_imr |= UART_IMR_TxRDY;
*P_LAN_IMR = lan_shadow_imr;
}
#endif
}
else
{
status = 0;
}
return( status );
}
ULONG lan_util( ULONG *parm )
{
static const struct {
ULONG rate_code;
UCHAR acr_setting;
UCHAR csr_setting;
} baud_rate_setting [] = {
{ 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 },
{ 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 },
{ 0x9600, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600 },
{ 0x4800, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800 }
};
#define BOGUS_P1 0xE1
#define BOGUS_P2 0xE2
ULONG not_done_code;
ULONG opcode;
ULONG parm_1;
ULONG parm_2;
int i;
UCHAR c;
not_done_code = 0;
opcode = parm[ 1 ];
parm_1 = parm[ 2 ];
parm_2 = parm[ 3 ];
switch ( opcode )
{
case LAN_INIT:
{
lan_init( );
printp( "\n\n Interface (Re)Initialized ...\n\n" );
break;
}
case LAN_BAUD:
{
for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
{
if ( baud_rate_setting[i].rate_code == parm_1 )
{
baud_rate_idx = i;
*P_LAN_ACR = baud_rate_setting[i].acr_setting;
*P_LAN_CSR = baud_rate_setting[i].csr_setting;
printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code );
return( not_done_code );
}
}
printp( "\n\n *** SYNTAX Error - Invalid baudrate (P2)\n\n" );
not_done_code = BOGUS_P2;
break;
}
case LAN_INTR:
{
switch ( parm_1 )
{
case 0x0D:
{
lan_shadow_imr &= ~UART_IMR_RxRDY;
*P_LAN_IMR = lan_shadow_imr;
printp( "\n\n Receive Ready Interrupts DISABLED ...\n\n" );
break;
}
case 0x0E:
{
lan_shadow_imr |= UART_IMR_RxRDY;
*P_LAN_IMR = lan_shadow_imr;
printp( "\n\n Receive Ready Interrupts ENABLED ...\n\n" );
break;
}
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
not_done_code = BOGUS_P2;
}
}
break;
}
case LAN_XMT:
{
switch ( parm_1 )
{
case 0x0E:
{
if ( !(*P_LAN0TR_REG & M_LAN0TR) )
{
*P_LAN0TR_REG |= M_LAN0TR;
}
printp( "\n\n Transmit-via-Backplane ENABLED ...\n\n" );
break;
}
case 0x0D:
{
if ( *P_LAN0TR_REG & M_LAN0TR )
{
*P_LAN0TR_REG &= ~M_LAN0TR;
}
printp( "\n\n Transmit-via-Backplane DISABLED ...\n\n" );
break;
}
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
not_done_code = BOGUS_P2;
lan_util_menu( );
}
}
break;
}
case LAN_STAT:
{
printp( "\n -- Status --\n\n" );
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( " RxRdy Intr: %s *\n", STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) );
printp( " Echo: %s *\n\n", STATUS( test_echo ) );
printp( " IMR: %02X\n", (ULONG) lan_shadow_imr );
printp( " ISR: %02X\n", (ULONG) *P_LAN_ISR );
printp( " SR: %02X\n\n", (ULONG) *P_LAN_SR );
printp( " Input Overflows: %d\n\n", lan_input_queue.overflows );
printp( " Tx by Intr: %d\n", tx_by_intr );
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 );
break;
}
case LAN_IN:
{
switch ( parm_1 )
{
case 0x0C:
{
lan_init_queue( &lan_input_queue );
printp( "\n\n Queue CLEARED/RESET ...\n\n" );
break;
}
case 0x0D:
{
printp( "\n -- Input Queue --\n" );
printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
(ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index );
for ( i = 0; i < MAX_RS232_CHARS; ++i )
{
printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
if ( 15 == (i % 16) )
{
int j;
printp ( " " );
for ( j = i - 15; j <= i; j++ )
{
if ( lan_input_queue.buf[ j ] >= ' ' &&
lan_input_queue.buf[ j ] < 127 )
printp ( "%c", lan_input_queue.buf[ j ] );
else
printp ( "." );
}
printp( "\n " );
}
else if ( 7 == (i % 8) )
{
printp( " " );
}
}
printp( "\n" );
break;
}
case 0x0F:
{
c = lan_next_queue_char( &lan_input_queue );
if ( c )
{
printp( "\n\n Next Character: " );
if ( 0x21 <= c && c <= 0x7F )
{
printp( "%c\n\n", (ULONG) c );
}
else if ( 0x20 == ((UCHAR) c) )
{
printp( "<space>\n\n" );
}
else
{
printp( "%02X\n\n", (ULONG) c );
}
}
else
{
printp( "\n\n Input Queue EMPTY ...\n\n" );
}
break;
}
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
not_done_code = BOGUS_P2;
break;
}
}
break;
}
case LAN_OUT:
{
switch ( parm_1 )
{
case 0x0C:
{
lan_init_queue( &lan_output_queue );
printp( "\n\n Queue CLEARED/RESET ...\n\n" );
break;
}
case 0x0D:
{
printp( "\n -- Output Queue --\n" );
printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
(ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index );
for ( i = 0; i < MAX_RS232_CHARS; ++i )
{
printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
if ( 15 == (i % 16) )
{
int j;
printp ( " " );
for ( j = i - 15; j <= i; j++ )
{
if ( lan_output_queue.buf[ j ] >= ' ' &&
lan_output_queue.buf[ j ] < 127 )
printp ( "%c", lan_output_queue.buf[ j ] );
else
printp ( "." );
}
printp( "\n " );
}
else if ( 7 == (i % 8) )
{
printp( " " );
}
}
printp( "\n" );
break;
}
case 0x0F:
{
c = lan_next_queue_char( &lan_output_queue );
if ( c )
{
printp( "\n\n Next Character: " );
if ( 0x21 <= c && c <= 0x7F )
{
printp( "%c\n\n", (ULONG) c );
}
else if ( 0x20 == c )
{
printp( "<space>\n\n" );
}
else
{
printp( "%02X\n\n", (ULONG) c );
}
}
else
{
printp( "\n\n Input Queue EMPTY ...\n\n" );
}
break;
}
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
not_done_code = BOGUS_P2;
break;
}
}
break;
}
case LAN_ECHO:
{
switch ( parm_1 )
{
case 0x0E:
{
test_echo = ENABLED;
printp( "\n\n Test echo ENABLED ...\n\n" );
break;
}
case 0x0D:
{
test_echo = DISABLED;
printp( "\n\n Test echo DISABLED ...\n\n" );
break;
}
default:
{
printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
not_done_code = BOGUS_P2;
break;
}
}
break;
}
case LAN_PUTC:
{
if ( 0x20 < parm_1 && parm_1 < 0x7F )
{
if ( lan_put_char( (UCHAR) parm_1 ) )
{
printp( "\n\n *** 'lan_put_char' Error ...\n" );
}
else
{
printp( "\n\n O.K. ...\n" );
}
}
else
{
printp( "\n\n *** Error - character must be in the 0x21-0x7E range ...\n" );
not_done_code = BOGUS_P2;
}
break;
}
case 0:
{
lan_util_menu( );
break;
}
default:
{
parm_2 = 0;
printp( "\n\n *** SYNTAX Error - Invalid P1 ...\n\n" );
not_done_code = BOGUS_P1;
break;
}
}
return( not_done_code );
}
static void lan_reset( void )
{
while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
{
*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;
}
while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
{
*P_RST_LAN_UART_REG &= ~M_RST_LAN_UART;
}
}
static void lan_configure( void )
{
*P_LAN_CR = UART_CR_RESET_MR_PTR;
*P_LAN_CR = UART_CR_RESET_RVCR;
*P_LAN_CR = UART_CR_RESET_XMTR;
*P_LAN_CR = UART_CR_RESET_ERROR_STATUS;
*P_LAN_CR = UART_CR_RESET_BRK_CHG_INT;
*P_LAN_MR1 = DEFAULT_LAN_MR1;
*P_LAN_MR2 = DEFAULT_LAN_MR2;
*P_LAN_ACR = DEFAULT_LAN_ACR;
*P_LAN_CSR = UART_CSR_BR_9600;
baud_rate_idx = 2;
*P_LAN_CTUR = DEFAULT_LAN_CTUR;
*P_LAN_CTLR = DEFAULT_LAN_CTLR;
*P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
lan_shadow_imr = UART_IMR_RxRDY;
*P_LAN_IMR = lan_shadow_imr;
tx_by_intr = 0;
tx_by_poll = 0;
return;
}
static void lan_init_queue( T_RS232_QUEUE *p_queue )
{
long i;
p_queue->head_index = 0;
p_queue->tail_index = 0;
p_queue->overflows = 0;
p_queue->gdb_packet_start = -1;
p_queue->gdb_packet_end = -1;
p_queue->gdb_packet_csum1 = -1;
p_queue->gdb_packet_csum2 = -1;
for ( i = 0; i < MAX_RS232_CHARS; ++i )
{
p_queue->buf[ i ] = 0;
}
return;
}
static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
{
if ( p_queue )
{
if ( c & 0x000000FF )
{
p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
{
p_queue->tail_index = 0;
}
if ( p_queue->head_index == p_queue->tail_index )
{
++(p_queue->overflows);
if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
{
p_queue->head_index = 0;
}
}
}
}
return;
}
static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue )
{
UCHAR c;
c = 0;
if ( p_queue )
{
if ( p_queue->head_index != p_queue->tail_index )
{
c = p_queue->buf[ p_queue->head_index ];
if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
{
p_queue->head_index = 0;
}
}
}
return( c );
}
static void lan_util_menu( void )
{
printp( "\n -- Options --\n\n" );
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,'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,'STAT' ............... Display STATUS.\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,'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( " <rate>: 4800 <mode>: E - enable <action>: C - clear/reset\n" );
printp( " 9600 D - disable D - display\n" );
printp( " 19200 F - fetch next char\n" );
printp( " 38400\n" );
}
static long get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
{
if ( '$' == c ) {
if ( -1 != p_input_q->gdb_packet_start ||
-1 != p_input_q->gdb_packet_end ||
-1 != p_input_q->gdb_packet_csum1 ||
-1 != p_input_q->gdb_packet_csum2 ) {
discard_packet( );
lan_add_to_queue ('$', p_input_q);
return 0;
} else {
p_input_q->gdb_packet_start = p_input_q->tail_index;
p_input_q->gdb_packet_end =
p_input_q->gdb_packet_csum1 =
p_input_q->gdb_packet_csum2 = -1;
}
} else if ( '#' == c ) {
if ( -1 == p_input_q->gdb_packet_start ||
-1 != p_input_q->gdb_packet_end ||
-1 != p_input_q->gdb_packet_csum1 ||
-1 != p_input_q->gdb_packet_csum2 ) {
discard_packet( );
return -1;
}
p_input_q->gdb_packet_end = p_input_q->tail_index;
p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1;
} else if ( -1 != p_input_q->gdb_packet_start &&
-1 != p_input_q->gdb_packet_end) {
if ( isxdigit( c ) ) {
if ( -1 == p_input_q->gdb_packet_csum1 &&
LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) ==
p_input_q->tail_index ) {
p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
p_input_q->gdb_packet_csum2 = -1;
} else if ( -1 == p_input_q->gdb_packet_csum2 &&
LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) ==
p_input_q->tail_index ) {
p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
getpacket();
} else {
discard_packet( );
return -1;
}
} else {
discard_packet( );
return -1;
}
}
return 0;
}
#ifdef STANDALONE
long write_to_protected_mem (addr, word)
void *addr;
unsigned short word;
{
return 0;
}
char dummy_memory[0x4000];
int main ( void )
{
long c;
lan_init_queue( &lan_input_queue );
printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) );
printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory);
while ( (c = getc( stdin ) ) != EOF )
{
if ( c == '\\' )
break;
lan_add_to_queue( c, &lan_input_queue );
get_gdb_input (c, &lan_input_queue);
fflush( stdout );
}
printf( "Goodbye!\n" );
exit( 0 );
}
#define SRAM_START ((void *) (&dummy_memory[0] + 0x00000000))
#define SRAM_END ((void *) (&dummy_memory[0] + 0x00000400))
#define RO_AREA_START ((void *) (&dummy_memory[0] + 0x00000100))
#define RO_AREA_END ((void *) (&dummy_memory[0] + 0x00000300))
#define NVD_START ((void *) (&dummy_memory[0] + 0x00003000))
#define NVD_END ((void *) (&dummy_memory[0] + 0x00003100))
#else
#define SRAM_START ((void *) 0x00000000)
#define SRAM_END ((void *) 0x00400000)
#define RO_AREA_START ((void *) 0x00100000)
#define RO_AREA_END ((void *) 0x00300000)
#define NVD_START ((void *) 0x03000000)
#define NVD_END ((void *) 0x03100000)
#endif
#define hexchars "0123456789abcdef"
#define NUMREGBYTES 180
#define NUMREGS 29
#define REGISTER_BYTE(regno) regno
enum regnames { D0, D1, D2, D3, D4, D5, D6, D7,
A0, A1, A2, A3, A4, A5, A6, A7,
PS, PC,
FP0, FP1,
FP2, FP3,
FP4, FP5,
FP6, FP7,
FPCONTROL, FPSTATUS, FPIADDR
};
unsigned long registers[NUMREGBYTES/4];
static long remote_debug;
#define BUFMAX MAX_IO_BUF_SIZE
static char inbuffer[BUFMAX], outbuffer[BUFMAX];
static char spare_buffer[BUFMAX];
struct stub_trace_frame
{
int valid;
unsigned long frame_id;
unsigned long tdp_id;
FRAME_DEF *frame_data;
COLLECTION_FORMAT_DEF *format;
unsigned long traceregs[NUMREGBYTES/4];
unsigned char *stack_data;
unsigned char *memrange_data;
} curframe;
void handle_request ( char * );
static void
discard_packet( void )
{
lan_input_queue.head_index = lan_input_queue.tail_index;
lan_input_queue.gdb_packet_start =
lan_input_queue.gdb_packet_end =
lan_input_queue.gdb_packet_csum1 =
lan_input_queue.gdb_packet_csum2 = -1;
}
static long
hex( char ch )
{
if ( (ch >= 'A') && (ch <= 'F') )
return ch - 'A' + 10;
if ( (ch >= 'a') && (ch <= 'f') )
return ch - 'a' + 10;
if ( (ch >= '0') && (ch <= '9') )
return ch - '0';
return -1;
}
static void
getpacket( void )
{
unsigned char our_checksum, their_checksum;
char *copy = inbuffer;
unsigned char c;
our_checksum = 0;
while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
if (c == 0)
{
return;
}
for (c = lan_next_queue_char ( &lan_input_queue );
c != 0 && c != '#';
c = lan_next_queue_char ( &lan_input_queue ))
{
*copy++ = c;
our_checksum += c;
}
*copy++ = '\0';
if (c == 0)
{
return;
}
their_checksum = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
discard_packet( );
if ( remote_debug ||
our_checksum == their_checksum )
{
ACK_PKT( );
handle_request( inbuffer );
}
else
NACK_PKT( );
}
static void
putpacket( char *str )
{
unsigned char checksum;
if ( VIA_ETHERNET == gdb_host_comm )
{
char *p_out;
long length;
p_out = eth_outbuffer;
length = 0;
if ( YES == gdb_cat_ack )
{
*p_out++ = '+';
++length;
}
gdb_cat_ack = NO;
*p_out++ = '$';
++length;
checksum = 0;
while ( *str )
{
*p_out++ = *str;
++length;
checksum += *str++;
}
*p_out++ = '#';
*p_out++ = hexchars[checksum >> 4];
*p_out = hexchars[checksum % 16];
length += 3;
eth_to_gdb( (UCHAR *) eth_outbuffer, length );
}
else
{
do {
LAN_PUT_CHAR( '$' );
checksum = 0;
while ( *str )
{
LAN_PUT_CHAR( *str );
checksum += *str++;
}
LAN_PUT_CHAR( '#' );
LAN_PUT_CHAR( hexchars[checksum >> 4] );
LAN_PUT_CHAR( hexchars[checksum % 16] );
} while ( 0 );
}
}
void gdb_get_eth_input( unsigned char *buf, long length )
{
gdb_host_comm = VIA_ETHERNET;
for ( ; 0 < length; ++buf, --length)
{
if ( *buf == CONTROL_C )
{
discard_packet( );
putpacket( "S03" );
}
else
{
lan_add_to_queue( (long) *buf, &lan_input_queue );
get_gdb_input( (long) *buf, &lan_input_queue );
}
}
return;
}
#if 0
static int
gdb_putchar( long ch )
{
char buf[4];
buf[0] = 'O';
buf[1] = hexchars[ch >> 4];
buf[2] = hexchars[ch & 0x0F];
buf[3] = 0;
putpacket( buf );
return ch;
}
#endif
static int
gdb_write( char *data, long len )
{
char *buf, *cpy;
long i;
buf = outbuffer;
buf[0] = 'O';
i = 0;
while ( i < len )
{
for ( cpy = buf+1;
i < len && cpy < buf + BUFMAX - 3;
i++ )
{
*cpy++ = hexchars[data[i] >> 4];
*cpy++ = hexchars[data[i] & 0x0F];
}
*cpy = 0;
putpacket( buf );
}
return len;
}
static int
gdb_puts( char *str )
{
return gdb_write( str, strlen( str ) );
}
#if 0
static void
gdb_error( char *format, char *parm )
{
static char buf[400];
char *cpy;
long len;
if ( remote_debug )
{
if ( format && *format )
len = strlen( format );
else
return;
if ( parm && *parm )
len += strlen( parm );
for ( cpy = buf; *format; )
{
if ( format[0] == '%' && format[1] == 's' )
{
format += 2;
while ( parm && *parm )
*cpy++ = *parm++;
}
else
*cpy++ = *format++;
}
*cpy = '\0';
gdb_puts( buf );
}
}
#endif
static void gdb_note (char *, int);
static int error_ret (int, char *, int);
static unsigned long
elinum_to_index (unsigned long elinum)
{
if ((elinum & 0xf0) == 0xd0)
return (elinum & 0x0f);
else if ((elinum & 0xf0) == 0xa0)
return (elinum & 0x0f) + 8;
else
return -1;
}
static long
index_to_elinum (unsigned long index)
{
if (index <= 7)
return index + 0xd0;
else if (index <= 15)
return (index - 8) + 0xa0;
else
return -1;
}
enum { SUCCESS = 0, FAIL = -1 };
#if 0
static long get_uchar ( const unsigned char * );
#endif
static long set_uchar ( unsigned char *, unsigned char );
static long read_access_violation ( const void * );
static long write_access_violation ( const void * );
static long read_access_range(const void *, long);
static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *);
static int
dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
{
if (src)
sprintp (spare_buffer,
"'%s' returned DTC error '%s'.\n", src, get_err_text (code));
else
sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code));
gdb_puts (spare_buffer);
return ret;
}
#if 0
static int
count_frame_exprs (FRAME_DEF *frame)
{
CFD *format;
T_EXPR *expr;
int num_exprs;
get_frame_format_pointer (frame, &format);
num_exprs = 0;
for (expr = format->p_cfd_expr; expr; expr = expr->next)
num_exprs++;
return num_exprs;
}
#endif
#if 0
unsigned char *
get_frame_addr ( const unsigned char *addr )
{
unsigned char *base, *regs, *stack, *mem;
CFD *dummy;
DTC_RESPONSE ret;
if (curframe.format->stack_size > 0 &&
(base = (unsigned char *) curframe.traceregs[A7]) <= addr &&
addr < base + curframe.format->stack_size)
{
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,
&dummy,
(void *) ®s,
(void *) &stack,
(void *) &mem))
!= OK_TARGET_RESPONSE)
return (void *) dtc_error_ret (-1,
"get_addr_to_frame_regs_stack_mem",
ret);
else
return stack + (addr - base);
}
{
int num_exprs = count_frame_exprs (curframe.frame_data);
int expr, block;
for (expr = 0; expr < num_exprs; expr++)
{
for (block = 0; ; block++)
{
T_EXPR_DATA *data;
if (adbg_get_expr_data (curframe.frame_data,
'x', expr, block,
&data)
!= OK_TARGET_RESPONSE)
break;
else if ((unsigned char *) data->address <= addr
&& addr < ((unsigned char *) data->address + data->size))
{
if ('A' <= data->stamp && data->stamp <= 'Z')
{
gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
return (unsigned char *) -1;
}
else
{
if (remote_debug > 1)
{
sprintp(spare_buffer,
"STUB: get_frame_addr: got it [%x,%x)\n",
data->address, data->address + data->size);
gdb_puts(spare_buffer);
}
return (((unsigned char *) &data->data)
+ (addr - (unsigned char *) data->address));
}
}
}
}
}
return (unsigned char *) -1;
}
static long get_uchar ( const unsigned char * addr )
{
unsigned char *frame_addr;
if ( read_access_violation ( addr ) )
return ( -1 );
if (curframe.valid)
{
if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1)
return ( *frame_addr );
else if (CS_CODE_START <= (unsigned long) addr &&
(unsigned long) addr < CS_CODE_START + CS_CODE_SIZE)
return (*addr);
else
return ( -1 );
}
else
return ( *addr );
}
#endif
static long set_uchar ( unsigned char * addr, unsigned char val )
{
long check_result = write_access_violation ( addr );
if ( check_result != 0L )
return ( check_result );
return ( *addr = val );
}
static long read_access_violation ( const void * addr )
{
return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
( ( addr < NVD_START ) || ( addr >= NVD_END ) ) );
}
static long write_access_violation ( const void * addr )
{
if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
return ( -1 );
if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
( ( addr < NVD_START ) || ( addr >= NVD_END ) ) )
return ( -2 );
return ( 0 );
}
static long
read_access_range(const void *addr, long count)
{
if ((addr >= SRAM_START) && (addr < SRAM_END))
{
if ((char *)addr + count < (char *)SRAM_END)
return (count);
else
return ((char *)SRAM_END - (char *)addr);
}
else if (((char *)addr >= (char *)NVD_START) &&
((char *)addr < (char *)NVD_END))
{
if ((char *)addr + count < (char *)NVD_END)
return (count);
else
return ((char *)NVD_END - (char *)addr);
}
else
return (0);
}
static long
mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
{
long ndx;
long ndx2;
long ch;
long incr;
unsigned char *location;
DTC_RESPONSE status;
if (may_fault)
{
for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
{
status = find_memory(mem, count - ndx, &location, &incr);
if (status == OK_TARGET_RESPONSE)
{
if (incr > 0)
{
for (ndx2 = 0; ndx2 < incr; ndx2++)
{
ch = *location++;
*buf++ = hexchars[ch >> 4];
*buf++ = hexchars[ch & 0xf];
}
mem += incr;
}
else if (incr <= 0)
{
*buf = 0;
return (0);
}
}
else if (status == NOT_FOUND_TARGET_RESPONSE)
{
*buf = 0;
return (ndx);
}
else
{
*buf = 0;
return (0);
}
}
*buf = 0;
return (count);
}
else
{
for (ndx = 0; ndx < count; ndx++)
{
ch = *mem++;
*buf++ = hexchars[ch >> 4];
*buf++ = hexchars[ch & 0xf];
}
*buf = 0;
return (count);
}
}
static DTC_RESPONSE
find_memory(unsigned char *mem, long count,
unsigned char **location, long *incr)
{
DTC_RESPONSE retval;
long length;
count = read_access_range(mem, count);
if (count == 0)
return (NOT_FOUND_TARGET_RESPONSE);
if (curframe.valid)
{
unsigned char *mem_block;
unsigned char *mem_addr;
unsigned long mem_size;
unsigned long mem_stamp;
retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem,
(unsigned long **)&mem_block,
(unsigned long **)&mem_addr,
&mem_size, &mem_stamp);
switch (retval)
{
case OK_TARGET_RESPONSE:
#if 0
printp("FOUND: mem %x block %x addr %x size %d stamp %x\n",
mem, mem_block, mem_addr, mem_size, mem_stamp);
#endif
*location = mem_block + (mem - mem_addr);
length = mem_size - (mem - mem_addr);
if (length < count)
*incr = length;
else
*incr = count;
break;
case NOT_FOUND_TARGET_RESPONSE:
case NEAR_FOUND_TARGET_RESPONSE:
#if 0
printp("NOT FOUND: mem %x, checking code region\n", mem);
#endif
if ((CS_CODE_START <= (long)mem) &&
((long)mem < CS_CODE_START + CS_CODE_SIZE))
{
*location = mem;
if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE)
*incr = count;
else
*incr = CS_CODE_START + CS_CODE_SIZE - (long)mem;
#if 0
printp("FOUND in code region: %x\n", mem);
#endif
retval = OK_TARGET_RESPONSE;
}
else
retval = NOT_FOUND_TARGET_RESPONSE;
break;
default:
#if 0
printp("BAD RETURN: %d\n", retval);
#endif
retval = NOT_FOUND_TARGET_RESPONSE;
break;
}
}
else
{
*location = mem;
*incr = count;
retval = OK_TARGET_RESPONSE;
}
return (retval);
}
static long
hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
{
long i, ch;
for ( i=0; i<count; i++ )
{
ch = hex( *buf++ ) << 4;
ch = ch + hex( *buf++ );
if ( may_fault )
{
ch = set_uchar( mem++, ch );
if ( ch < 0 )
return FAIL;
}
else
*mem++ = ch;
}
return SUCCESS;
}
static int
hexToInt( char **ptr, unsigned long *intValue )
{
long numChars = 0;
long hexValue;
*intValue = 0;
while ( **ptr )
{
hexValue = hex( **ptr );
if ( hexValue >=0 )
{
*intValue = (*intValue << 4) | hexValue;
numChars ++;
}
else
break;
(*ptr)++;
}
return numChars;
}
static volatile long gdb_handling_trap1;
static volatile long gdb_handling_sstrace;
static volatile long gdb_signo;
static char * handle_trace_query (char *);
static char * handle_trace_set (char *);
static int handle_format (char **request, CFD *format);
static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc);
static char * crc_query (char *);
static char * handle_test (char *);
void
handle_request( char *request )
{
#if 0
remote_debug = 2;
#endif
switch( *request++ )
{
case 'k':
curframe.valid = FALSE;
putpacket ("");
break;
case 'D':
curframe.valid = FALSE;
putpacket ("");
break;
default:
putpacket( "" );
break;
case 'H':
putpacket( "OK" );
break;
case 'g':
{
memset (outbuffer, '0', NUMREGBYTES);
outbuffer[NUMREGBYTES] = '\0';
if (curframe.valid)
mem2hex( (unsigned char*) curframe.traceregs,
outbuffer, NUMREGBYTES, 0 );
else
mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 );
putpacket( outbuffer );
}
break;
case 'G':
if (curframe.valid)
putpacket ("E03");
else
{
hex2mem( request,
(unsigned char *) registers, NUMREGBYTES, 0 );
putpacket( "OK" );
}
break;
case 'P':
if (curframe.valid)
putpacket ("E03");
else
{
unsigned long regno;
if ( hexToInt( &request, ®no ) && *(request++) == '=' )
{
if ( regno < NUMREGS )
{
hexToInt( &request,
(unsigned long *) ®isters[REGISTER_BYTE(regno)]);
putpacket( "OK" );
}
else
putpacket( "E01" );
}
}
break;
case 'm':
{
unsigned long addr, len;
if ( hexToInt( &request, &addr ) &&
*(request++) == ',' &&
hexToInt( &request, &len ) )
{
if ( len > (BUFMAX / 2) - 5 )
len = (BUFMAX / 2) - 5;
if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0)
putpacket( "E03" );
else
putpacket( outbuffer );
}
else
putpacket( "E01" );
}
break;
case 'M':
{
unsigned long addr, len;
if (curframe.valid)
putpacket ("E03");
else
{
if ( hexToInt( &request, &addr ) &&
*(request++) == ',' &&
hexToInt( &request, &len ) &&
*(request++) == ':' )
{
if (len == 2 &&
addr >= CS_CODE_START &&
addr <= LAST_CS_WORD)
{
unsigned long val;
if ( !hexToInt( &request, &val ) ||
write_to_protected_mem( (void *)addr, val ) )
putpacket( "E03" );
else
putpacket( "OK" );
}
else
{
if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
putpacket( "E03" );
else
putpacket( "OK" );
}
}
else
putpacket( "E02" );
}
}
break;
case 'c':
{
unsigned long addr;
if (curframe.valid)
{
gdb_puts ("Error: can't continue!\n");
putpacket ("S03");
}
else
{
gdb_signo = 3;
if (isxdigit(request[0]))
{
hexToInt(&request, &addr);
registers[REGISTER_BYTE(PC)] = addr;
}
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = '\0';
}
}
break;
case 's':
{
unsigned long addr;
if (curframe.valid)
{
gdb_puts ("Error: can't step!\n");
putpacket ("S03");
}
else
{
gdb_signo = 3;
if (isxdigit(request[0]))
{
hexToInt(&request, &addr);
registers[REGISTER_BYTE(PC)] = addr;
}
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = 't';
}
}
break;
case 'C':
{
unsigned long addr = 0;
if (!gdb_handling_trap1 || curframe.valid)
{
gdb_puts( "Error: can't continue!\n" );
putpacket( "S03" );
}
else
{
gdb_signo = 3;
if ( isxdigit( *request ) )
{
hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
request += 2;
if ( *request == ';' && isxdigit( *++request ) )
{
hexToInt( &request, &addr );
registers[REGISTER_BYTE(PC)] = addr;
}
}
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = '\0';
}
}
break;
case 'S':
{
unsigned long addr = 0;
if (!gdb_handling_trap1 || curframe.valid)
{
gdb_puts( "Error: can't step!\n" );
putpacket( "S03" );
}
else
{
gdb_signo = 3;
if ( isxdigit( *request ) )
{
hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
request += 2;
if ( *request == ';' && isxdigit( *++request ) )
{
hexToInt( &request, &addr );
registers[REGISTER_BYTE(PC)] = addr;
}
}
gdb_handling_trap1 = FALSE;
gdb_handling_sstrace = FALSE;
sss_trace_flag = 't';
}
}
break;
case '?':
if ( gdb_signo == 0 )
gdb_signo = 3;
outbuffer[ 0 ] = 'S';
outbuffer[ 1 ] = hexchars[ gdb_signo >> 4 ];
outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ];
outbuffer[ 3 ] = 0;
putpacket( outbuffer );
break;
case 'd':
remote_debug = !remote_debug;
putpacket( "" );
break;
case 'q':
switch (*request++)
{
default:
putpacket ("");
break;
case 'T':
putpacket (handle_trace_query (request));
break;
case 'C':
if (*request++ == 'R' &&
*request++ == 'C' &&
*request++ == ':')
putpacket (crc_query (request));
else
putpacket ("");
break;
}
break;
case 'Q':
switch (*request++)
{
default:
putpacket ("");
break;
case 'T':
putpacket (handle_trace_set (request));
break;
}
break;
case 'T':
putpacket (handle_test (request));
break;
}
}
static TDP_SETUP_INFO tdp_temp;
static int trace_running;
static int
msgcmp (char **msgp, char *str)
{
char *next;
if (msgp != 0 && str != 0)
if ((next = *msgp) != 0)
{
for (;
*next && *str && *next == *str;
next++, str++)
;
if (*str == 0)
return (int) (*msgp = next);
}
return 0;
}
static char *
handle_trace_query (char *request)
{
if (msgcmp (&request, "Status"))
{
if (adbg_check_if_active ())
{
gdb_puts ("Target trace is running.\n");
return "T1";
}
else
{
gdb_puts ("Target trace not running.\n");
trace_running = 0;
return "T0";
}
}
else
{
return "";
}
}
static void
gdb_note (char *fmt, int arg1)
{
if (remote_debug > 1)
{
sprintp (spare_buffer, fmt, arg1);
gdb_puts (spare_buffer);
}
}
static int
error_ret (int ret, char *fmt, int arg1)
{
if (remote_debug > 0)
{
sprintp (spare_buffer, fmt, arg1);
gdb_puts (spare_buffer);
}
return ret;
}
static int
handle_format (char **request, COLLECTION_FORMAT_DEF *format)
{
MEMRANGE_DEF m;
DTC_RESPONSE ret;
int elinum;
unsigned long regnum;
long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4];
struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes;
if (format->id == 0)
{
if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
return dtc_error_ret (-1, "get_unused_format_id", ret);
if (**request == 'R')
{
(*request)++;
hexToInt (request, &format->regs_mask);
}
gdb_note ("STUB: call define_format (id = %d, ", format->id);
gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
{
sprintp (spare_buffer,
"'define_format': DTC error '%s' for format id %d.\n",
get_err_text (ret),
format->id);
gdb_puts (spare_buffer);
return -1;
}
}
while ((**request == 'M') || (**request == 'X'))
{
switch (**request)
{
case 'M':
(*request)++;
hexToInt(request, ®num);
if (regnum == 0 || regnum == (unsigned long) -1)
m.typecode = -1;
else if ((elinum = index_to_elinum (regnum)) > 0)
m.typecode = elinum;
else
return error_ret (-1,
"Memrange register %d is not between 0 and 15\n",
regnum);
if (*(*request)++ != ',')
return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1);
hexToInt(request, &m.offset);
if (*(*request)++ != ',')
return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2);
hexToInt(request, &m.size);
gdb_note ("STUB: call add_format_mem_range (typecode = 0x%x, ",
m.typecode);
gdb_note ("offset = 0x%X, ", m.offset);
gdb_note ("size = %d);\n", m.size);
if ((ret = add_format_mem_ranges (format->id, &m)) !=
OK_TARGET_RESPONSE)
{
dtc_error_ret (-1, "add_format_mem_ranges", ret);
sprintp (spare_buffer,
"format id %d: memrange (0x%x, 0x%x, 0x%x).\n",
format->id, m.typecode, m.offset, m.size);
gdb_puts (spare_buffer);
return -1;
}
break;
case 'X':
{
unsigned long length;
(*request)++;
hexToInt(request, &length);
if ((length <= 0) || (length > MAX_BYTE_CODES))
return error_ret (-1,
"Bytecode expression length (%d) too large\n",
length);
if (*(*request)++ != ',')
return error_ret (-1,
"Malformed bytecode expr (comma#%d missing)\n",
1);
t_expr->next = NULL;
t_expr->size = sizeof(struct t_expr_tag) + length - 1;
t_expr->expr_size = length;
hex2mem(*request, &t_expr->expr[0], length, 0);
*request += 2 * length;
build_and_add_expression(format->id, t_expr);
}
break;
}
}
return 0;
}
static char *
handle_trace_set (char *request)
{
long n_frame;
unsigned long frameno, tdp, pc, start, stop;
DTC_RESPONSE ret = -1;
static COLLECTION_FORMAT_DEF tempfmt1;
static char enable;
static char retbuf[20];
if (msgcmp (&request, "init"))
{
gdb_note ("STUB: call clear_trace_state();\n", 0);
curframe.valid = 0;
if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE)
return "OK";
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"clear_trace_state",
ret);
}
}
else if (msgcmp (&request, "Start"))
{
trace_running = 1;
curframe.valid = 0;
gdb_note ("STUB: call start_trace_experiment();\n", 0);
adbg_save_trace_in_nvd ();
if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE)
return "OK";
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"start_trace_experiment",
ret);
}
}
else if (msgcmp (&request, "Stop"))
{
trace_running = 0;
if (adbg_check_if_active ())
{
gdb_note ("STUB: call end_trace_experiment();\n", 0);
if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
return "OK";
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"end_trace_experiment",
ret);
}
}
else return "OK";
}
else if (msgcmp (&request, "DP:"))
{
static int doing_step_formats;
if (*request == '-')
{
unsigned long temp_id, temp_addr;
request++;
if (!(hexToInt (&request, &temp_id) &&
*request++ == ':'))
return "E11";
if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
*request++ == ':'))
return "E12";
if (temp_id != tdp_temp.id)
return "E11";
if (temp_addr != (unsigned long) tdp_temp.addr)
return "E12";
}
else
{
memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
doing_step_formats = FALSE;
if (!(hexToInt (&request, &tdp_temp.id) &&
*request++ == ':'))
return "E11";
if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
*request++ == ':'))
return "E12";
if (!(((enable = *request++) == 'D' || enable == 'E') &&
*request++ == ':'))
return "E13";
#if 0
if (enable == 'D')
{
gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
return "E20";
}
#endif
if (!(hexToInt (&request, &tdp_temp.stepcount) &&
*request++ == ':'))
return "E14";
if (!hexToInt (&request, &tdp_temp.pass_limit))
return "E15";
}
if (*request == 'R' || *request == 'M' || *request == 'X')
{
if (handle_format (&request, &tempfmt1))
return "E16";
if (doing_step_formats)
tdp_temp.tp_format_p = tempfmt1.id;
else
tdp_temp.tdp_format_p = tempfmt1.id;
}
if (*request == 'S')
{
doing_step_formats = TRUE;
memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
request++;
if (*request == 'R' || *request == 'M' || *request == 'X')
{
if (handle_format (&request, &tempfmt1))
return "E17";
tdp_temp.tp_format_p = tempfmt1.id;
}
}
if (*request == '-')
sprintp (retbuf, "OK");
else if (enable == 'E')
{
gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id);
gdb_note ("addr 0x%X, ", (int) tdp_temp.addr);
gdb_note ("passc %d, ", tdp_temp.pass_limit);
gdb_note ("stepc %d, ", tdp_temp.stepcount);
gdb_note ("TDP fmt #%d, ", tdp_temp.tdp_format_p);
gdb_note ("TP fmt #%d);\n", tdp_temp.tp_format_p);
ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
if (ret == OK_TARGET_RESPONSE)
{
sprintp (retbuf, "OK");
}
else
{
sprintp (spare_buffer,
"'define_tdp' returned DTC error '%s' for tracepoint %d.\n",
get_err_text (ret),
tdp_temp.id);
gdb_puts (spare_buffer);
sprintp (retbuf, "E2%x", ret);
}
{
memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
}
}
else
gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
return retbuf;
}
else if (msgcmp (&request, "Frame:"))
{
ret = OK_TARGET_RESPONSE;
if (msgcmp (&request, "pc:"))
{
if (!hexToInt (&request, &pc))
return "E10";
n_frame = curframe.valid ? curframe.frame_id + 1 : 0;
gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame);
gdb_note ("pc 0x%X);\n", pc);
ret = fetch_trace_frame_with_pc (&n_frame,
(void *) pc,
&curframe.format,
&curframe.frame_data);
}
else if (msgcmp (&request, "tdp:"))
{
if (!hexToInt (&request, &tdp))
return "E10";
n_frame = curframe.valid ? curframe.frame_id + 1: 0;
gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame);
gdb_note ("tdp 0x%X);\n", tdp);
ret = fetch_trace_frame_with_tdp (&n_frame,
tdp,
&curframe.format,
&curframe.frame_data);
}
else if (msgcmp (&request, "range:"))
{
if (!(hexToInt (&request, &start) &&
*request++ == ':'))
return "E11";
else if (!hexToInt (&request, &stop))
return "E12";
n_frame = curframe.valid ? curframe.frame_id + 1: 0;
gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame);
gdb_note ("start 0x%X, ", start);
gdb_note ("stop 0x%X);\n", stop);
ret = fetch_trace_frame_with_pc_in_range (&n_frame,
(void *) start,
(void *) stop,
&curframe.format,
&curframe.frame_data);
}
else if (msgcmp (&request, "outside:"))
{
if (!(hexToInt (&request, &start) &&
*request++ == ':'))
return "E11";
else if (!hexToInt (&request, &stop))
return "E12";
n_frame = curframe.valid ? curframe.frame_id + 1: 0;
gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame);
gdb_note ("start 0x%X, ", start);
gdb_note ("stop 0x%X);\n", stop);
ret = fetch_trace_frame_with_pc_outside (&n_frame,
(void *) start,
(void *) stop,
&curframe.format,
&curframe.frame_data);
}
else
{
if (!hexToInt (&request, &frameno))
return "E10";
if (frameno != (unsigned long) -1)
{
gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno);
ret = fetch_trace_frame (n_frame = frameno,
&curframe.format,
&curframe.frame_data);
#if 0
printp("STUB: fetch_trace_frame: return %d\n", ret);
#endif
}
else
{
if (curframe.valid)
gdb_note ("STUB: discard current trace frame #%d.\n",
curframe.frame_id);
curframe.valid = 0;
return "OK";
}
}
if (ret == OK_TARGET_RESPONSE)
{
curframe.valid = 1;
curframe.frame_id = n_frame;
curframe.tdp_id = curframe.frame_data->id;
memset ((char *) &curframe.traceregs, 0,
sizeof (curframe.traceregs));
curframe.traceregs[PC] = (unsigned long)
curframe.frame_data->program_counter;
if (curframe.format)
{
unsigned long regs_mask = curframe.format->regs_mask;
unsigned long *regs, *stack, *mem;
unsigned long regno, index = 0;
CFD *dummy;
if ((ret = get_addr_to_frame_regs_stack_mem
(curframe.frame_data, &dummy, ®s, &stack, &mem))
!= OK_TARGET_RESPONSE)
{
curframe.valid = 0;
sprintp (retbuf, "E2%x", ret);
return (char *)
dtc_error_ret ((int) &retbuf,
"get_addr_to_frame_regs_stack_mem",
ret);
}
if (remote_debug > 1)
{
sprintp (spare_buffer,
"STUB: Found frame %d, TDP %d, format %d (%s):\n",
curframe.frame_id,
curframe.tdp_id & 0x7fffffff,
curframe.format->id,
curframe.tdp_id & 0x80000000 ?
"trap frame" : "stepping frame");
gdb_puts (spare_buffer);
}
for (regno = 0, index = 0;
regno < 16;
regno++, regs_mask >>= 1)
if (regs_mask & 1)
{
curframe.traceregs[regno] = regs[index++];
if (remote_debug > 1)
{
sprintp (spare_buffer,
" Collected 0x%08x for register %d.\n",
curframe.traceregs[regno], regno);
gdb_puts (spare_buffer);
}
}
if (remote_debug > 1)
{
long midx, ridx, len;
MEMRANGE_DEF *mrange;
unsigned char *data, *base;
if (curframe.format->stack_size > 0)
{
len = curframe.format->stack_size;
sprintp (spare_buffer,
" Collected %d bytes of stack at 0x%x:\n",
len, curframe.traceregs[A7]);
gdb_puts (spare_buffer);
if (len >= (NUMREGBYTES/2 - 2))
len = (NUMREGBYTES/2 - 3);
mem2hex ((unsigned char *) stack,
spare_buffer, len, 0);
spare_buffer [len * 2] = '\n';
spare_buffer [len * 2 + 1] = '\0';
gdb_puts (spare_buffer);
}
else
gdb_puts ("Stack not collected\n");
for (midx = 0;
get_addr_to_a_mem_range (curframe.frame_data,
midx,
&mrange,
(void **) &data)
== OK_TARGET_RESPONSE;
midx++)
{
if ((mrange->typecode == 0) ||
(mrange->typecode == (unsigned long) -1))
{
sprintp (spare_buffer,
" Collected %d bytes at MEM: 0x%x:\n",
mrange->size, mrange->offset);
base = (unsigned char *) mrange->offset;
}
else
{
if ((ridx = elinum_to_index (mrange->typecode)) > 0)
base = (unsigned char *) curframe.traceregs[ridx]
+ (long) mrange->offset;
else
{
sprintp (spare_buffer,
"STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n",
midx,
mrange->typecode,
mrange->offset,
mrange->size);
gdb_puts (spare_buffer);
continue;
}
sprintp (spare_buffer,
" Collected %d bytes at 0x%x (REG %X + %d):\n",
mrange->size,
base,
mrange->typecode,
mrange->offset);
}
gdb_puts (spare_buffer);
len = mrange->size;
if (len >= (NUMREGBYTES/2 - 2))
len = (NUMREGBYTES/2 - 3);
mem2hex (data, spare_buffer, len, 0);
spare_buffer [len * 2] = '\n';
spare_buffer [len * 2 + 1] = '\0';
gdb_puts (spare_buffer);
}
}
}
sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
return retbuf;
}
else if (ret == NOT_FOUND_TARGET_RESPONSE)
{
return "F-1";
}
else
{
sprintp (retbuf, "E2%x", ret);
return (char *) dtc_error_ret ((int) &retbuf,
"fetch_trace_frame[...]",
ret);
}
}
else
{
return "";
}
}
static unsigned long crc32_table[256];
static int crc_mem_err;
static unsigned long
crc32 (buf, len, crc)
unsigned char *buf;
int len;
unsigned long crc;
{
crc_mem_err = FALSE;
if (! crc32_table[1])
{
int i, j;
unsigned int c;
for (i = 0; i < 256; i++)
{
for (c = i << 24, j = 8; j > 0; --j)
c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
crc32_table[i] = c;
}
}
while (len--)
{
if (read_access_violation (buf))
{
crc_mem_err = TRUE;
return -1;
}
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
}
return crc;
}
static char *
crc_query (cmd)
char *cmd;
{
unsigned long startmem, len, crc;
static char buf[32];
if (hexToInt (&cmd, &startmem) &&
*cmd++ == ',' &&
hexToInt (&cmd, &len))
{
crc = crc32 ((unsigned char *) startmem, len, 0xffffffff);
if (!crc_mem_err)
{
sprintp (buf, "C%08x", crc);
return buf;
}
}
sprintp (buf, "E01");
return buf;
}
static char *
handle_test (request)
char *request;
{
ULONG args[7];
int i;
i = 1;
if (*request != '\0')
while (i < 7)
{
if (! hexToInt (&request, &args[i++]))
return "E01";
if (*request == '\0')
break;
if (*request++ != ',')
return "E01";
}
for (; i < 7; i++)
args[i] = 0;
gdb_c_test (args);
return "OK";
}
void gdb_trap_1_handler( void )
{
gdb_handling_trap1 = TRUE;
sss_trace_flag = '\0';
gdb_signo = 5;
putpacket( "S05" );
while ( gdb_handling_trap1 )
;
return;
}
void gdb_trace_handler( void )
{
sss_trace_flag = '\0';
gdb_handling_trap1 = TRUE;
gdb_handling_sstrace = TRUE;
gdb_signo = 5;
putpacket( "S05" );
while ( gdb_handling_trap1 )
;
return;
}