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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/or_debug_proxy
    from Rev 353 to Rev 376
    Reverse comparison

Rev 353 → Rev 376

/src/or_debug_proxy.c
70,18 → 70,14
#include "usb_functions.h"
#endif
 
#ifdef VPI_ENDPOINT_ENABLED
#include "vpi_functions.h"
#endif
 
#include "or_debug_proxy.h"
 
// Defines of endpoint numbers
#define ENDPOINT_TARGET_NONE 0
#define ENDPOINT_TARGET_USB 1
#define ENDPOINT_TARGET_VPI 2
#define ENDPOINT_TARGET_OTHER 2
 
static int endpoint_target; // Either VPI interface via sockets, or the USB device
static int endpoint_target; // Value to hold targeted endpoint
 
#define GDB_PROTOCOL_JTAG 1
#define GDB_PROTOCOL_RSP 2
104,11 → 100,9
 
// Check we were compiled with at least one endpoint enabled
#ifndef USB_ENDPOINT_ENABLED
#ifndef VPI_ENDPOINT_ENABLED
printf("No endpoints enabled.\nRecompile the proxy with at least one endpoint enabled\n");
exit(0);
#endif
#endif
 
// init our global error number
err = DBG_ERR_OK;
132,10 → 126,10
gdb_protocol = GDB_PROTOCOL_RSP;
endpoint_target = ENDPOINT_TARGET_USB;
}
else if(strcmp(argv[inp_arg], "-v") == 0)
else if(strcmp(argv[inp_arg], "-o") == 0)
{
gdb_protocol = GDB_PROTOCOL_RSP;
endpoint_target = ENDPOINT_TARGET_VPI;
endpoint_target = ENDPOINT_TARGET_OTHER;
}
else
{
175,17 → 169,6
dbg_test(); // Perform some tests
}
#endif
#ifdef VPI_ENDPOINT_ENABLED
/* RTL simulation endpoint */
if (endpoint_target == ENDPOINT_TARGET_VPI){
printf("\nConnecting to OR1k RTL simulation\n\n");
// Connect to the (hopefully) already running RTL simulation server running via VPI
vpi_fd = vpi_connect();
if ((err = vpi_dbg_reset())) goto JtagIfError;
vpi_dbg_test(); // Perform some tests
}
#endif
/* We have a connection to the target system. Now establish server connection. */
if(gdb_protocol == GDB_PROTOCOL_RSP)
212,9 → 195,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_reset();
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_reset();
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
222,9 → 202,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) usb_dbg_test();
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) vpi_dbg_test();
#endif
}
 
/* Set TAP instruction register */
240,9 → 217,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_set_chain(chain);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_set_chain(chain);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
260,9 → 234,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_ctrl(reset, stall);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_ctrl(reset, stall);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
271,9 → 242,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_ctrl_read(reset, stall);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_ctrl_read(reset, stall);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
291,9 → 259,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_read8(adr, data);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_read32(adr, data);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
303,9 → 268,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_read32(adr, data);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_read32(adr, data);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
322,9 → 284,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_write32( adr, data);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_write32( adr, data);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
333,9 → 292,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_read_block32( adr, data, len);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_read_block32( adr, data, len);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
344,9 → 300,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_write_block32( adr, data, len);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_write_block32( adr, data, len);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
355,9 → 308,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read( adr, data, length);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_read( adr, data);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
366,9 → 316,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write( adr, data, length);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_write( adr, data);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
377,9 → 324,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write_ctrl( adr, data);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_write_ctrl( adr, data);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
389,9 → 333,6
#ifdef USB_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read_ctrl( adr, data);
#endif
#ifdef VPI_ENDPOINT_ENABLED
if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_read_ctrl( adr, data);
#endif
return DBG_ERR_INVALID_ENDPOINT;
}
 
404,9 → 345,6
void catch_sigint(int sig_num)
{
// Close down any potentially open sockets and USB handles
#ifdef VPI_ENDPOINT_ENABLED
if (vpi_fd) close(vpi_fd);
#endif
if (server_fd) close(server_fd);
gdb_close();
#ifdef USB_ENDPOINT_ENABLED
427,9 → 365,6
printf("\t-r Start a server using RSP, connection to hadware target via\n\t USB\n");
printf("\t-j Start a server using legacy OR remote JTAG protocol, to\n\t hardware target via USB\n");
#endif
#ifdef VPI_ENDPOINT_ENABLED
printf("\t-v Start a server using RSP, connection to RTL sim. VPI server\n\t target via sockets\n");
#endif
printf("\n");
printf("port:\n");
printf("\tAny free port within the usable range of 0 - 65535\n");
440,10 → 375,5
printf("\tor_debug_proxy -r 5555\n");
printf("\n");
#endif
#ifdef VPI_ENDPOINT_ENABLED
printf("\tStart a GDB server on port 5555, using RSP, connecting to\n\trtl target via VPI\n");
printf("\tor_debug_proxy -v 5555\n");
printf("\n");
#endif
fflush (stdout);
}
/src/gdb.c
63,6 → 63,9
// in or1k jb
// 090828 Fixed byte/non-aligned accesses. Removed legacy
// "remote JTAG" protocol. jb
// 100924 Added RSP query handlers for things new to with
// gdb-7.2 jb
 
#ifdef CYGWIN_COMPILE
 
#else
122,12 → 125,12
#define OR1K_TRAP_INSTR 0x21000001
 
/*! The maximum number of characters in inbound/outbound buffers. The largest
packets are the 'G' packet, which must hold the 'G' and all the registers
with two hex digits per byte and the 'g' reply, which must hold all the
registers, and (in our implementation) an end-of-string (0)
character. Adding the EOS allows us to print out the packet as a
string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed
for register packets */
packets are the 'G' packet, which must hold the 'G' and all the registers
with two hex digits per byte and the 'g' reply, which must hold all the
registers, and (in our implementation) an end-of-string (0)
character. Adding the EOS allows us to print out the packet as a
string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed
for register packets */
//#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1)
#define GDB_BUF_MAX 4096
#define GDB_BUF_MAX_TIMES_TWO (GDB_BUF_MAX*2)
180,10 → 183,10
 
 
/*! Definition of GDB target signals. Data taken from the GDB 6.8
source. Only those we use defined here. The exact meaning of
signal number is defined by the header `include/gdb/signals.h'
in the GDB source code. For an explanation of what each signal
means, see target_signal_to_string.*/
source. Only those we use defined here. The exact meaning of
signal number is defined by the header `include/gdb/signals.h'
in the GDB source code. For an explanation of what each signal
means, see target_signal_to_string.*/
enum target_signal {
TARGET_SIGNAL_NONE = 0,
TARGET_SIGNAL_INT = 2,
246,7 → 249,7
static int tcp_level = 0;
 
/* global to store what chain the debug unit is currently connected to
(not the JTAG TAP, but the onchip debug module has selected) */
(not the JTAG TAP, but the onchip debug module has selected) */
int gdb_chain = -1;
 
/*! Data structure for RSP buffers. Can't be null terminated, since it may
258,7 → 261,7
};
 
/*! Enumeration of different types of matchpoint. These have explicit values
matching the second digit of 'z' and 'Z' packets. */
matching the second digit of 'z' and 'Z' packets. */
enum mp_type {
BP_MEMORY = 0, // software-breakpoint Z0 break
BP_HARDWARE = 1, // hardware-breakpoint Z1 hbreak
280,7 → 283,7
static struct
{
int client_waiting; /*!< Is client waiting a response? */
// Not used int proto_num; /*!< Number of the protocol used */
// Not used int proto_num; /*!< Number of the protocol used */
int client_fd; /*!< FD for talking to GDB */
int sigval; /*!< GDB signal for any exception */
uint32_t start_addr; /*!< Start of last run */
366,7 → 369,7
/*---------------------------------------------------------------------------*/
/*!Initialize the Remote Serial Protocol connection
 
Set up the central data structures. */
Set up the central data structures. */
/*---------------------------------------------------------------------------*/
void
rsp_init (void)
394,17 → 397,17
/*---------------------------------------------------------------------------*/
/*!Look for action on RSP
 
This function is called when the processor has stalled, which, except for
initialization, must be due to an interrupt.
This function is called when the processor has stalled, which, except for
initialization, must be due to an interrupt.
 
If we have no RSP client, we get one. We can make no progress until the
client is available.
If we have no RSP client, we get one. We can make no progress until the
client is available.
 
Then if the cause is an exception following a step or continue command, and
the exception not been notified to GDB, a packet reporting the cause of the
exception is sent.
Then if the cause is an exception following a step or continue command, and
the exception not been notified to GDB, a packet reporting the cause of the
exception is sent.
 
The next client request is then processed. */
The next client request is then processed. */
/*---------------------------------------------------------------------------*/
void
handle_rsp (void)
567,12 → 570,12
/*---------------------------------------------------------------------------*/
/*!Check if PPC is in an exception vector that halts program flow
 
Compare the provided PPC with known exception vectors that are fatal
to a program's execution. Call rsp_exception(ppc) to set the appropriate
sigval and return.
Compare the provided PPC with known exception vectors that are fatal
to a program's execution. Call rsp_exception(ppc) to set the appropriate
sigval and return.
 
@param[in] ppc Value of current PPC, as read from debug unit
@return: 1 if we set a sigval and should return control to GDB, else 0 */
@param[in] ppc Value of current PPC, as read from debug unit
@return: 1 if we set a sigval and should return control to GDB, else 0 */
/*---------------------------------------------------------------------------*/
static int
check_for_exception_vector(uint32_t ppc)
584,9 → 587,9
case EXCEPT_ALIGN:
case EXCEPT_ILLEGAL:
case EXCEPT_TRAP: if(DEBUG_GDB)
printf("PPC at exception address\n");
rsp_exception(ppc);
return 1;
printf("PPC at exception address\n");
rsp_exception(ppc);
return 1;
default:
return 0;
597,14 → 600,14
/*---------------------------------------------------------------------------*/
/*!Note an exception for future processing
 
The simulator has encountered an exception. Record it here, so that a
future call to handle_exception will report it back to the client. The
signal is supplied in Or1ksim form and recorded in GDB form.
The simulator has encountered an exception. Record it here, so that a
future call to handle_exception will report it back to the client. The
signal is supplied in Or1ksim form and recorded in GDB form.
 
We flag up a warning if an exception is already pending, and ignore the
earlier exception.
We flag up a warning if an exception is already pending, and ignore the
earlier exception.
 
@param[in] except The exception (Or1ksim form) */
@param[in] except The exception (Or1ksim form) */
/*---------------------------------------------------------------------------*/
void
rsp_exception (uint32_t except)
647,19 → 650,19
/*---------------------------------------------------------------------------*/
/*!Get a new client connection.
 
Blocks until the client connection is available.
Blocks until the client connection is available.
 
A lot of this code is copied from remote_open in gdbserver remote-utils.c.
A lot of this code is copied from remote_open in gdbserver remote-utils.c.
 
This involves setting up a socket to listen on a socket for attempted
connections from a single GDB instance (we couldn't be talking to multiple
GDBs at once!).
This involves setting up a socket to listen on a socket for attempted
connections from a single GDB instance (we couldn't be talking to multiple
GDBs at once!).
 
The service is specified either as a port number in the Or1ksim configuration
(parameter rsp_port in section debug, default 51000) or as a service name
in the constant OR1KSIM_RSP_SERVICE.
The service is specified either as a port number in the Or1ksim configuration
(parameter rsp_port in section debug, default 51000) or as a service name
in the constant OR1KSIM_RSP_SERVICE.
 
The protocol used for communication is specified in OR1KSIM_RSP_PROTOCOL. */
The protocol used for communication is specified in OR1KSIM_RSP_PROTOCOL. */
/*---------------------------------------------------------------------------*/
static void
rsp_get_client (void)
672,16 → 675,16
/* 0 is used as the RSP port number to indicate that we should use the
service name instead. */
if (0 == serverPort)
{
struct servent *service = getservbyname (OR1KSIM_RSP_SERVICE, "tcp");
if (NULL == service)
{
fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n",
OR1KSIM_RSP_SERVICE, strerror (errno));
return;
}
serverPort = ntohs (service->s_port);
}
{
struct servent *service = getservbyname (OR1KSIM_RSP_SERVICE, "tcp");
if (NULL == service)
{
fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n",
OR1KSIM_RSP_SERVICE, strerror (errno));
return;
}
serverPort = ntohs (service->s_port);
}
 
/* Open a socket on which we'll listen for clients */
tmp_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
724,10 → 727,10
rsp.client_fd = accept (tmp_fd, (struct sockaddr *)&sock_addr, &len);
 
if (-1 == rsp.client_fd)
{
fprintf (stderr, "Warning: Failed to accept RSP client\n");
return;
}
{
fprintf (stderr, "Warning: Failed to accept RSP client\n");
return;
}
 
/* Enable TCP keep alive process */
optval = 1;
794,8 → 797,8
/*---------------------------------------------------------------------------*/
/*!Deal with a request from the GDB client session
 
In general, apart from the simplest requests, this function replies on
other functions to implement the functionality. */
In general, apart from the simplest requests, this function replies on
other functions to implement the functionality. */
/*---------------------------------------------------------------------------*/
static void rsp_client_request (void)
{
888,7 → 891,7
case 'H':
/* Set the thread number of subsequent operations. For now ignore
silently and just reply "OK" */
silently and just reply "OK" */
put_str_packet ("OK");
return;
 
953,25 → 956,25
 
case 's':
/* Single step (one high level instruction). This could be hard without
DWARF2 info */
DWARF2 info */
rsp_step (p_buf);
return;
 
case 'S':
/* Single step (one high level instruction) with signal. This could be
hard without DWARF2 info */
hard without DWARF2 info */
rsp_step_with_signal (p_buf);
return;
 
case 't':
/* Search. This is not well defined in the manual and for now we don't
support it. No response is defined. */
support it. No response is defined. */
fprintf (stderr, "Warning: RSP 't' packet not supported: ignored\n");
return;
 
case 'T':
/* Is the thread alive. We are bare metal, so don't have a thread
context. The answer is always "OK". */
context. The answer is always "OK". */
put_str_packet ("OK");
return;
 
1020,12 → 1023,12
/*---------------------------------------------------------------------------*/
/*!Send a packet to the GDB client
 
Modeled on the stub version supplied with GDB. Put out the data preceded by
a '$', followed by a '#' and a one byte checksum. '$', '#', '*' and '}' are
escaped by preceding them with '}' and then XORing the character with
0x20.
Modeled on the stub version supplied with GDB. Put out the data preceded by
a '$', followed by a '#' and a one byte checksum. '$', '#', '*' and '}' are
escaped by preceding them with '}' and then XORing the character with
0x20.
 
@param[in] p_buf The data to send */
@param[in] p_buf The data to send */
/*---------------------------------------------------------------------------*/
static void
put_packet (struct rsp_buf *p_buf)
1037,50 → 1040,50
/* Construct $<packet info>#<checksum>. Repeat until the GDB client
acknowledges satisfactory receipt. */
do
{
unsigned char checksum = 0; /* Computed checksum */
int count = 0; /* Index into the buffer */
{
unsigned char checksum = 0; /* Computed checksum */
int count = 0; /* Index into the buffer */
 
if (DEBUG_GDB_DUMP_DATA){
printf ("Putting %s\n\n", p_buf->data);
fflush (stdout);
}
if (DEBUG_GDB_DUMP_DATA){
printf ("Putting %s\n\n", p_buf->data);
fflush (stdout);
}
 
len = 0;
data[len++] = '$'; /* Start char */
len = 0;
data[len++] = '$'; /* Start char */
 
/* Body of the packet */
for (count = 0; count < p_buf->len; count++)
{
unsigned char ch = p_buf->data[count];
/* Body of the packet */
for (count = 0; count < p_buf->len; count++)
{
unsigned char ch = p_buf->data[count];
 
/* Check for escaped chars */
if (('$' == ch) || ('#' == ch) || ('*' == ch) || ('}' == ch))
{
ch ^= 0x20;
checksum += (unsigned char)'}';
data[len++] = '}';
}
/* Check for escaped chars */
if (('$' == ch) || ('#' == ch) || ('*' == ch) || ('}' == ch))
{
ch ^= 0x20;
checksum += (unsigned char)'}';
data[len++] = '}';
}
 
checksum += ch;
data[len++] = ch;
}
checksum += ch;
data[len++] = ch;
}
 
data[len++] = '#'; /* End char */
data[len++] = '#'; /* End char */
 
/* Computed checksum */
data[len++] = (hexchars[checksum >> 4]);
data[len++] = (hexchars[checksum % 16]);
/* Computed checksum */
data[len++] = (hexchars[checksum >> 4]);
data[len++] = (hexchars[checksum % 16]);
 
send_rsp_str ((unsigned char *) &data, len);
send_rsp_str ((unsigned char *) &data, len);
 
/* Check for ack of connection failure */
ch = get_rsp_char ();
if (0 > ch)
{
return; /* Fail the put silently. */
}
}
/* Check for ack of connection failure */
ch = get_rsp_char ();
if (0 > ch)
{
return; /* Fail the put silently. */
}
}
while ('+' != ch);
} /* put_packet () */
1089,7 → 1092,7
/*---------------------------------------------------------------------------*/
/*!Convenience to put a constant string packet
 
param[in] str The text of the packet */
param[in] str The text of the packet */
/*---------------------------------------------------------------------------*/
static void
put_str_packet (const char *str)
1119,16 → 1122,16
/*---------------------------------------------------------------------------*/
/*!Get a packet from the GDB client
Modeled on the stub version supplied with GDB. The data is in a static
buffer. The data should be copied elsewhere if it is to be preserved across
a subsequent call to get_packet().
Modeled on the stub version supplied with GDB. The data is in a static
buffer. The data should be copied elsewhere if it is to be preserved across
a subsequent call to get_packet().
 
Unlike the reference implementation, we don't deal with sequence
numbers. GDB has never used them, and this implementation is only intended
for use with GDB 6.8 or later. Sequence numbers were removed from the RSP
standard at GDB 5.0.
Unlike the reference implementation, we don't deal with sequence
numbers. GDB has never used them, and this implementation is only intended
for use with GDB 6.8 or later. Sequence numbers were removed from the RSP
standard at GDB 5.0.
 
@return A pointer to the static buffer containing the data */
@return A pointer to the static buffer containing the data */
/*---------------------------------------------------------------------------*/
static struct rsp_buf *
get_packet (void)
1137,115 → 1140,115
 
/* Keep getting packets, until one is found with a valid checksum */
while (1)
{
unsigned char checksum; /* The checksum we have computed */
int count; /* Index into the buffer */
int ch; /* Current character */
{
unsigned char checksum; /* The checksum we have computed */
int count; /* Index into the buffer */
int ch; /* Current character */
 
/* Wait around for the start character ('$'). Ignore all other
characters */
ch = get_rsp_char ();
/* Wait around for the start character ('$'). Ignore all other
characters */
ch = get_rsp_char ();
 
while (ch != '$')
{
if (-1 == ch)
{
return NULL; /* Connection failed */
}
while (ch != '$')
{
if (-1 == ch)
{
return NULL; /* Connection failed */
}
 
ch = get_rsp_char ();
ch = get_rsp_char ();
 
// Potentially handle an interrupt character (0x03) here
}
// Potentially handle an interrupt character (0x03) here
}
 
/* Read until a '#' or end of buffer is found */
checksum = 0;
count = 0;
while (count < GDB_BUF_MAX - 1)
{
ch = get_rsp_char ();
/* Read until a '#' or end of buffer is found */
checksum = 0;
count = 0;
while (count < GDB_BUF_MAX - 1)
{
ch = get_rsp_char ();
if(rsp.client_waiting && DEBUG_GDB)
{
printf("%x\n",ch);
}
if(rsp.client_waiting && DEBUG_GDB)
{
printf("%x\n",ch);
}
 
 
/* Check for connection failure */
if (0 > ch)
{
return NULL;
}
/* Check for connection failure */
if (0 > ch)
{
return NULL;
}
 
/* If we hit a start of line char begin all over again */
if ('$' == ch)
{
checksum = 0;
count = 0;
/* If we hit a start of line char begin all over again */
if ('$' == ch)
{
checksum = 0;
count = 0;
 
continue;
}
continue;
}
 
/* Break out if we get the end of line char */
if ('#' == ch)
{
break;
}
/* Break out if we get the end of line char */
if ('#' == ch)
{
break;
}
 
/* Update the checksum and add the char to the buffer */
/* Update the checksum and add the char to the buffer */
 
checksum = checksum + (unsigned char)ch;
buf.data[count] = (char)ch;
count = count + 1;
}
checksum = checksum + (unsigned char)ch;
buf.data[count] = (char)ch;
count = count + 1;
}
 
/* Mark the end of the buffer with EOS - it's convenient for non-binary
data to be valid strings. */
buf.data[count] = 0;
buf.len = count;
/* Mark the end of the buffer with EOS - it's convenient for non-binary
data to be valid strings. */
buf.data[count] = 0;
buf.len = count;
 
/* If we have a valid end of packet char, validate the checksum */
if ('#' == ch)
{
unsigned char xmitcsum; /* The checksum in the packet */
/* If we have a valid end of packet char, validate the checksum */
if ('#' == ch)
{
unsigned char xmitcsum; /* The checksum in the packet */
 
ch = get_rsp_char ();
if (0 > ch)
{
return NULL; /* Connection failed */
}
xmitcsum = hex (ch) << 4;
ch = get_rsp_char ();
if (0 > ch)
{
return NULL; /* Connection failed */
}
xmitcsum = hex (ch) << 4;
 
ch = get_rsp_char ();
if (0 > ch)
{
return NULL; /* Connection failed */
}
ch = get_rsp_char ();
if (0 > ch)
{
return NULL; /* Connection failed */
}
 
xmitcsum += hex (ch);
xmitcsum += hex (ch);
 
/* If the checksums don't match print a warning, and put the
negative ack back to the client. Otherwise put a positive ack. */
if (checksum != xmitcsum)
{
fprintf (stderr, "Warning: Bad RSP checksum: Computed "
"0x%02x, received 0x%02x\n", checksum, xmitcsum);
/* If the checksums don't match print a warning, and put the
negative ack back to the client. Otherwise put a positive ack. */
if (checksum != xmitcsum)
{
fprintf (stderr, "Warning: Bad RSP checksum: Computed "
"0x%02x, received 0x%02x\n", checksum, xmitcsum);
 
ch = '-';
send_rsp_str ((unsigned char *) &ch, 1); /* Failed checksum */
}
else
{
ch = '+';
send_rsp_str ((unsigned char *) &ch, 1); /* successful transfer */
break;
}
}
else
{
fprintf (stderr, "Warning: RSP packet overran buffer\n");
}
}
ch = '-';
send_rsp_str ((unsigned char *) &ch, 1); /* Failed checksum */
}
else
{
ch = '+';
send_rsp_str ((unsigned char *) &ch, 1); /* successful transfer */
break;
}
}
else
{
fprintf (stderr, "Warning: RSP packet overran buffer\n");
}
}
return &buf; /* Success */
} /* get_packet () */
 
1253,9 → 1256,9
/*---------------------------------------------------------------------------*/
/*!Put a single character out onto the client socket
 
This should only be called if the client is open, but we check for safety.
This should only be called if the client is open, but we check for safety.
 
@param[in] c The character to put out */
@param[in] c The character to put out */
/*---------------------------------------------------------------------------*/
static void
send_rsp_str (unsigned char *data, int len)
1272,26 → 1275,26
while (1)
{
switch (write (rsp.client_fd, data, len))
{
case -1:
/* Error: only allow interrupts or would block */
if ((EAGAIN != errno) && (EINTR != errno))
{
fprintf (stderr, "Warning: Failed to write to RSP client: "
"Closing client connection: %s\n",
strerror (errno));
rsp_client_close ();
return;
}
{
case -1:
/* Error: only allow interrupts or would block */
if ((EAGAIN != errno) && (EINTR != errno))
{
fprintf (stderr, "Warning: Failed to write to RSP client: "
"Closing client connection: %s\n",
strerror (errno));
rsp_client_close ();
return;
}
break;
break;
 
case 0:
break; /* Nothing written! Try again */
case 0:
break; /* Nothing written! Try again */
 
default:
return; /* Success, we can return */
}
default:
return; /* Success, we can return */
}
}
} /* send_rsp_str () */
 
1299,9 → 1302,9
/*---------------------------------------------------------------------------*/
/*!Get a single character from the client socket
 
This should only be called if the client is open, but we check for safety.
This should only be called if the client is open, but we check for safety.
 
@return The character read, or -1 on failure */
@return The character read, or -1 on failure */
/*---------------------------------------------------------------------------*/
static int
get_rsp_char ()
1357,11 → 1360,11
rsp_peek()
{
/*
if (-1 == rsp.client_fd)
if (-1 == rsp.client_fd)
{
fprintf (stderr, "Warning: Attempt to read from unopened RSP "
"client: Ignored\n");
return -1;
fprintf (stderr, "Warning: Attempt to read from unopened RSP "
"client: Ignored\n");
return -1;
}
*/
char c;
1388,7 → 1391,7
/*---------------------------------------------------------------------------*/
/*!Handle an interrupt from GDB
 
Detect an interrupt from GDB and stall the processor */
Detect an interrupt from GDB and stall the processor */
/*---------------------------------------------------------------------------*/
static void
rsp_interrupt()
1430,14 → 1433,14
/*---------------------------------------------------------------------------*/
/*!"Unescape" RSP binary data
 
'#', '$' and '}' are escaped by preceding them by '}' and oring with 0x20.
'#', '$' and '}' are escaped by preceding them by '}' and oring with 0x20.
 
This function reverses that, modifying the data in place.
This function reverses that, modifying the data in place.
 
@param[in] data The array of bytes to convert
@para[in] len The number of bytes to be converted
@param[in] data The array of bytes to convert
@para[in] len The number of bytes to be converted
 
@return The number of bytes AFTER conversion */
@return The number of bytes AFTER conversion */
/*---------------------------------------------------------------------------*/
static int
rsp_unescape (char *data,
1450,14 → 1453,14
{
/* Is it escaped */
if ( '}' == data[from_off])
{
from_off++;
data[to_off] = data[from_off] ^ 0x20;
}
else
{
data[to_off] = data[from_off];
}
{
from_off++;
data[to_off] = data[from_off] ^ 0x20;
}
else
{
data[to_off] = data[from_off];
}
 
from_off++;
to_off++;
1471,8 → 1474,8
/*---------------------------------------------------------------------------*/
/*!Initialize the matchpoint hash table
 
This is an open hash table, so this function clears all the links to
NULL. */
This is an open hash table, so this function clears all the links to
NULL. */
/*---------------------------------------------------------------------------*/
static void
mp_hash_init (void)
1489,14 → 1492,14
/*---------------------------------------------------------------------------*/
/*!Add an entry to the matchpoint hash table
 
Add the entry if it wasn't already there. If it was there do nothing. The
match just be on type and addr. The instr need not match, since if this is
a duplicate insertion (perhaps due to a lost packet) they will be
different.
Add the entry if it wasn't already there. If it was there do nothing. The
match just be on type and addr. The instr need not match, since if this is
a duplicate insertion (perhaps due to a lost packet) they will be
different.
 
@param[in] type The type of matchpoint
@param[in] addr The address of the matchpoint
@para[in] instr The instruction to associate with the address */
@param[in] type The type of matchpoint
@param[in] addr The address of the matchpoint
@para[in] instr The instruction to associate with the address */
/*---------------------------------------------------------------------------*/
static void
mp_hash_add (enum mp_type type,
1508,12 → 1511,12
 
/* See if we already have the entry */
for(curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
{
if ((type == curr->type) && (addr == curr->addr))
{
return; /* We already have the entry */
}
}
{
if ((type == curr->type) && (addr == curr->addr))
{
return; /* We already have the entry */
}
}
 
/* Insert the new entry at the head of the chain */
curr = (struct mp_entry*) malloc (sizeof (*curr));
1531,12 → 1534,12
/*---------------------------------------------------------------------------*/
/*!Look up an entry in the matchpoint hash table
 
The match must be on type AND addr.
The match must be on type AND addr.
 
@param[in] type The type of matchpoint
@param[in] addr The address of the matchpoint
@param[in] type The type of matchpoint
@param[in] addr The address of the matchpoint
 
@return The entry deleted, or NULL if the entry was not found */
@return The entry deleted, or NULL if the entry was not found */
/*---------------------------------------------------------------------------*/
static struct mp_entry * mp_hash_lookup (enum mp_type type, uint32_t addr)
{
1545,12 → 1548,12
 
/* Search */
for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
{
if ((type == curr->type) && (addr == curr->addr))
{
return curr; /* The entry found */
}
}
{
if ((type == curr->type) && (addr == curr->addr))
{
return curr; /* The entry found */
}
}
 
/* Not found */
return NULL;
1561,20 → 1564,20
/*---------------------------------------------------------------------------*/
/*!Delete an entry from the matchpoint hash table
 
If it is there the entry is deleted from the hash table. If it is not
there, no action is taken. The match must be on type AND addr.
If it is there the entry is deleted from the hash table. If it is not
there, no action is taken. The match must be on type AND addr.
 
The usual fun and games tracking the previous entry, so we can delete
things.
The usual fun and games tracking the previous entry, so we can delete
things.
 
@note The deletion DOES NOT free the memory associated with the entry,
since that is returned. The caller should free the memory when they
have used the information.
@note The deletion DOES NOT free the memory associated with the entry,
since that is returned. The caller should free the memory when they
have used the information.
 
@param[in] type The type of matchpoint
@param[in] addr The address of the matchpoint
@param[in] type The type of matchpoint
@param[in] addr The address of the matchpoint
 
@return The entry deleted, or NULL if the entry was not found */
@return The entry deleted, or NULL if the entry was not found */
/*---------------------------------------------------------------------------*/
static struct mp_entry *
mp_hash_delete (enum mp_type type,
1615,18 → 1618,18
/*---------------------------------------------------------------------------*/
/*!Utility to give the value of a hex char
 
@param[in] ch A character representing a hexadecimal digit. Done as -1,
for consistency with other character routines, which can use
-1 as EOF.
@param[in] ch A character representing a hexadecimal digit. Done as -1,
for consistency with other character routines, which can use
-1 as EOF.
 
@return The value of the hex character, or -1 if the character is
invalid. */
@return The value of the hex character, or -1 if the character is
invalid. */
/*---------------------------------------------------------------------------*/
static int hex (int c)
{
return ((c >= 'a') && (c <= 'f')) ? c - 'a' + 10 :
((c >= '0') && (c <= '9')) ? c - '0' :
((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : -1;
((c >= '0') && (c <= '9')) ? c - '0' :
((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : -1;
 
} /* hex () */
 
1634,17 → 1637,17
/*---------------------------------------------------------------------------*/
/*!Convert a register to a hex digit string
 
The supplied 32-bit value is converted to an 8 digit hex string according
the target endianism. It is null terminated for convenient printing.
The supplied 32-bit value is converted to an 8 digit hex string according
the target endianism. It is null terminated for convenient printing.
 
@param[in] val The value to convert
@param[out] p_buf The buffer for the text string */
@param[in] val The value to convert
@param[out] p_buf The buffer for the text string */
/*---------------------------------------------------------------------------*/
static void
reg2hex (uint32_t val, char *p_buf)
{
int n; /* Counter for digits */
int nyb_shift;
int nyb_shift;
 
for (n = 0; n < 8; n++)
{
1651,10 → 1654,10
#ifdef WORDSBIGENDIAN
if(n%2==0){
nyb_shift = n * 4 + 4;
}
else{
nyb_shift = n * 4 - 4;
}
}
else{
nyb_shift = n * 4 - 4;
}
#else
nyb_shift = 28 - (n * 4);
#endif
1669,12 → 1672,12
/*---------------------------------------------------------------------------*/
/*!Convert a hex digit string to a register value
 
The supplied 8 digit hex string is converted to a 32-bit value according
the target endianism
The supplied 8 digit hex string is converted to a 32-bit value according
the target endianism
 
@param[in] p_buf The buffer with the hex string
@param[in] p_buf The buffer with the hex string
 
@return The value to convert */
@return The value to convert */
/*---------------------------------------------------------------------------*/
static uint32_t
hex2reg (char *p_buf)
1700,10 → 1703,10
/*---------------------------------------------------------------------------*/
/*!Convert an ASCII character string to pairs of hex digits
 
Both source and destination are null terminated.
Both source and destination are null terminated.
 
@param[out] dest Buffer to store the hex digit pairs (null terminated)
@param[in] src The ASCII string (null terminated) */
@param[out] dest Buffer to store the hex digit pairs (null terminated)
@param[in] src The ASCII string (null terminated) */
/*---------------------------------------------------------------------------*/
static void ascii2hex (char *dest,
char *src)
1727,10 → 1730,10
/*---------------------------------------------------------------------------*/
/*!Convert pairs of hex digits to an ASCII character string
 
Both source and destination are null terminated.
Both source and destination are null terminated.
 
@param[out] dest The ASCII string (null terminated)
@param[in] src Buffer holding the hex digit pairs (null terminated) */
@param[out] dest The ASCII string (null terminated)
@param[in] src Buffer holding the hex digit pairs (null terminated) */
/*---------------------------------------------------------------------------*/
static void hex2ascii (char *dest,
char *src)
1751,14 → 1754,14
/*---------------------------------------------------------------------------*/
/*!Set the program counter
 
This sets the value in the NPC SPR. Not completely trivial, since this is
actually cached in cpu_state.pc. Any reset of the NPC also involves
clearing the delay state and setting the pcnext global.
This sets the value in the NPC SPR. Not completely trivial, since this is
actually cached in cpu_state.pc. Any reset of the NPC also involves
clearing the delay state and setting the pcnext global.
 
Only actually do this if the requested address is different to the current
NPC (avoids clearing the delay pipe).
Only actually do this if the requested address is different to the current
NPC (avoids clearing the delay pipe).
 
@param[in] addr The address to use */
@param[in] addr The address to use */
/*---------------------------------------------------------------------------*/
static void
set_npc (uint32_t addr)
1769,24 → 1772,24
 
 
if (addr != get_npc())
{
{
 
gdb_write_reg(NPC_CPU_REG_ADD, addr);
gdb_write_reg(NPC_CPU_REG_ADD, addr);
if (STALLED == stallState)
{
if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written and locally cached \n", addr);
npcCachedValue = addr;
npcIsCached = 1;
}
else
{
if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written \n", addr);
npcIsCached = 0;
}
if (STALLED == stallState)
{
if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written and locally cached \n", addr);
npcCachedValue = addr;
npcIsCached = 1;
}
else
{
if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written \n", addr);
npcIsCached = 0;
}
 
}
}
else
return;
 
1850,7 → 1853,7
/*---------------------------------------------------------------------------*/
/*!Send a packet acknowledging an exception has occurred
 
This is only called if there is a client FD to talk to */
This is only called if there is a client FD to talk to */
/*---------------------------------------------------------------------------*/
static void
rsp_report_exception (void)
1872,10 → 1875,10
/*---------------------------------------------------------------------------*/
/*!Handle a RSP continue request
 
Parse the command to see if there is an address. Uses the underlying
generic continue function, with EXCEPT_NONE.
Parse the command to see if there is an address. Uses the underlying
generic continue function, with EXCEPT_NONE.
 
@param[in] p_buf The full continue packet */
@param[in] p_buf The full continue packet */
/*---------------------------------------------------------------------------*/
static void
rsp_continue (struct rsp_buf *p_buf)
1895,21 → 1898,21
}
 
if (0 == strcmp ("c", p_buf->data))
{
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- NPC ---------- */
addr = get_npc();
}
{
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- NPC ---------- */
addr = get_npc();
}
else if (1 != sscanf (p_buf->data, "c%x", &addr))
{
fprintf (stderr,
"Warning: RSP continue address %s not recognized: ignored\n",
p_buf->data);
{
fprintf (stderr,
"Warning: RSP continue address %s not recognized: ignored\n",
p_buf->data);
 
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- NPC ---------- */
addr = get_npc();
}
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- NPC ---------- */
addr = get_npc();
}
 
if (DEBUG_GDB) printf("rsp_continue() --> Read NPC = 0x%08x\n", addr);
 
1921,9 → 1924,9
/*---------------------------------------------------------------------------*/
/*!Handle a RSP continue with signal request
 
Currently null. Will use the underlying generic continue function.
Currently null. Will use the underlying generic continue function.
 
@param[in] p_buf The full continue with signal packet */
@param[in] p_buf The full continue with signal packet */
/*---------------------------------------------------------------------------*/
static void
rsp_continue_with_signal (struct rsp_buf *p_buf)
1937,14 → 1940,14
/*---------------------------------------------------------------------------*/
/*!Generic processing of a continue request
 
The signal may be EXCEPT_NONE if there is no exception to be
handled. Currently the exception is ignored.
The signal may be EXCEPT_NONE if there is no exception to be
handled. Currently the exception is ignored.
 
The single step flag is cleared in the debug registers and then the
processor is unstalled.
The single step flag is cleared in the debug registers and then the
processor is unstalled.
 
@param[in] addr Address from which to step
@param[in] except The exception to use (if any) */
@param[in] addr Address from which to step
@param[in] except The exception to use (if any) */
/*---------------------------------------------------------------------------*/
static void
rsp_continue_generic (uint32_t addr,
1989,11 → 1992,11
/*---------------------------------------------------------------------------*/
/*!Handle a RSP read all registers request
 
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
(i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is
returned as a sequence of bytes in target endian order.
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
(i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is
returned as a sequence of bytes in target endian order.
 
Each byte is packed as a pair of hex digits. */
Each byte is packed as a pair of hex digits. */
/*---------------------------------------------------------------------------*/
static void
rsp_read_all_regs (void)
2042,9 → 2045,9
/* ---------- PPC ---------- */
err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> PPC\n", err);
put_str_packet ("E01");
return;
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> PPC\n", err);
put_str_packet ("E01");
return;
}
reg2hex (temp_uint32, &(buffer.data[PPC_REGNUM * 8]));
if (DEBUG_GDB_DUMP_DATA) printf("PPC 0x%08x\n", temp_uint32);
2051,12 → 2054,12
/* ---------- NPC ---------- */
temp_uint32 = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> NPC\n", err);
put_str_packet ("E01");
return;
}
err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> NPC\n", err);
put_str_packet ("E01");
return;
}
*/
reg2hex (temp_uint32, &(buffer.data[NPC_REGNUM * 8]));
if (DEBUG_GDB_DUMP_DATA) printf("NPC 0x%08x\n", temp_uint32);
2063,12 → 2066,12
/* ---------- SR ---------- */
err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> SP\n", err);
put_str_packet ("E01");
return;
if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> SP\n", err);
put_str_packet ("E01");
return;
}
reg2hex (temp_uint32, &(buffer.data[SR_REGNUM * 8]));
if (DEBUG_GDB_DUMP_DATA) printf("SR 0x%08x\n", temp_uint32);
if (DEBUG_GDB_DUMP_DATA) printf("SR 0x%08x\n", temp_uint32);
 
/* Finalize the packet and send it */
buffer.data[NUM_REGS * 8] = 0;
2075,7 → 2078,7
buffer.len = NUM_REGS * 8;
 
put_packet (&buffer);
return;
return;
} /* rsp_read_all_regs () */
 
 
2082,17 → 2085,17
/*---------------------------------------------------------------------------*/
/*!Handle a RSP write all registers request
 
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
(i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is
supplied as a sequence of bytes in target endian order.
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
(i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is
supplied as a sequence of bytes in target endian order.
 
Each byte is packed as a pair of hex digits.
Each byte is packed as a pair of hex digits.
 
@todo There is no error checking at present. Non-hex chars will generate a
warning message, but there is no other check that the right amount
of data is present. The result is always "OK".
@todo There is no error checking at present. Non-hex chars will generate a
warning message, but there is no other check that the right amount
of data is present. The result is always "OK".
 
@param[in] p_buf The original packet request. */
@param[in] p_buf The original packet request. */
/*---------------------------------------------------------------------------*/
static void
rsp_write_all_regs (struct rsp_buf *p_buf)
2115,45 → 2118,45
// First set the chain
err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
put_str_packet ("E01");
return;
}
return;
}
 
/* ---------- GPRS ---------- */
for (regnum = 0; regnum < MAX_GPRS; regnum++)
{
err = gdb_write_reg(0x400 + regnum, hex2reg (&p_buf->data[regnum * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err);
put_str_packet ("E01");
return;
}
}
{
err = gdb_write_reg(0x400 + regnum, hex2reg (&p_buf->data[regnum * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err);
put_str_packet ("E01");
return;
}
}
/* ---------- PPC ---------- */
err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (&p_buf->data[PPC_REGNUM * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> PPC\n", err);
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> PPC\n", err);
put_str_packet ("E01");
return;
return;
}
/* ---------- SR ---------- */
err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (&p_buf->data[SR_REGNUM * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err);
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err);
put_str_packet ("E01");
return;
return;
}
/* ---------- NPC ---------- */
set_npc(hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
/*
err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
put_str_packet ("E01");
return;
}
return;
}
*/
/* Acknowledge. TODO: We always succeed at present, even if the data was
defective. */
2166,7 → 2169,7
 
Syntax is:
 
m<addr>,<length>:
m<addr>,<length>:
 
The response is the bytes, lowest address first, encoded as pairs of hex
digits.
2195,20 → 2198,20
 
 
if (2 != sscanf (p_buf->data, "m%x,%x:", &addr, &len))
{
fprintf (stderr, "Warning: Failed to recognize RSP read memory "
"command: %s\n", p_buf->data);
put_str_packet ("E01");
return;
}
{
fprintf (stderr, "Warning: Failed to recognize RSP read memory "
"command: %s\n", p_buf->data);
put_str_packet ("E01");
return;
}
 
/* Make sure we won't overflow the buffer (2 chars per byte) */
if ((len * 2) >= GDB_BUF_MAX_TIMES_TWO)
{
fprintf (stderr, "Warning: Memory read %s too large for RSP packet: "
"truncated\n", p_buf->data);
len = (GDB_BUF_MAX - 1) / 2;
}
{
fprintf (stderr, "Warning: Memory read %s too large for RSP packet: "
"truncated\n", p_buf->data);
len = (GDB_BUF_MAX - 1) / 2;
}
 
if(!(rec_buf = (char*)malloc(len))) {
put_str_packet ("E01");
2291,7 → 2294,7
}
 
if (DEBUG_GDB && (err > 0)) printf("\nError %x\n", err);fflush (stdout);
free(rec_buf);
free(rec_buf);
p_buf->data[off * 2] = 0; /* End of string */
p_buf->len = strlen (p_buf->data);
if (DEBUG_GDB_BLOCK_DATA){
2309,24 → 2312,24
/*---------------------------------------------------------------------------*/
/*!Handle a RSP write memory (symbolic) request ("M")
 
Syntax is:
Syntax is:
 
M<addr>,<length>:<data>
M<addr>,<length>:<data>
 
Example: M4015cc,2:c320#
(Write the value 0xc320 to address 0x4015cc.)
Example: M4015cc,2:c320#
(Write the value 0xc320 to address 0x4015cc.)
 
An example target response:
+ $OK#
An example target response:
+ $OK#
 
The data is the bytes, lowest address first, encoded as pairs of hex
digits.
The data is the bytes, lowest address first, encoded as pairs of hex
digits.
 
The length given is the number of bytes to be written.
The length given is the number of bytes to be written.
 
@note This function reuses p_buf, so trashes the original command.
@note This function reuses p_buf, so trashes the original command.
 
@param[in] p_buf The command received */
@param[in] p_buf The command received */
/*---------------------------------------------------------------------------*/
static void
rsp_write_mem (struct rsp_buf *p_buf)
2337,15 → 2340,15
int datlen; /* Number of digits in symbolic data */
int off; /* Offset into the memory */
int nibc; /* Nibbel counter */
uint32_t val;
uint32_t val;
if (2 != sscanf (p_buf->data, "M%x,%x:", &addr, &len))
{
fprintf (stderr, "Warning: Failed to recognize RSP write memory "
"command: %s\n", p_buf->data);
put_str_packet ("E01");
return;
}
{
fprintf (stderr, "Warning: Failed to recognize RSP write memory "
"command: %s\n", p_buf->data);
put_str_packet ("E01");
return;
}
 
/* Find the start of the data and check there is the amount we expect. */
symdat = (char*) memchr ((const void *)p_buf->data, ':', GDB_BUF_MAX) + 1;
2353,12 → 2356,12
 
/* Sanity check */
if (len * 2 != datlen)
{
fprintf (stderr, "Warning: Write of %d digits requested, but %d digits "
"supplied: packet ignored\n", len * 2, datlen );
put_str_packet ("E01");
return;
}
{
fprintf (stderr, "Warning: Write of %d digits requested, but %d digits "
"supplied: packet ignored\n", len * 2, datlen );
put_str_packet ("E01");
return;
}
 
// Make sure the processor is stalled
gdb_ensure_or1k_stalled();
2366,29 → 2369,29
 
// Set chain 5 --> Wishbone Memory chain
err = gdb_set_chain(SC_WISHBONE);
if(err){
if(err){
put_str_packet ("E01");
return;
}
}
val = 0;
off = 0;
val = 0;
off = 0;
/* Write the bytes to memory */
for (nibc = 0; nibc < datlen; nibc++)
{
val |= 0x0000000f & hex (symdat[nibc]);
if(nibc % 8 == 7){
err = gdb_write_block(addr + off, &val, 4);
if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout);
if(err){
put_str_packet ("E01");
return;
}
val = 0;
off += 4;
}
val <<= 4;
}
{
val |= 0x0000000f & hex (symdat[nibc]);
if(nibc % 8 == 7){
err = gdb_write_block(addr + off, &val, 4);
if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout);
if(err){
put_str_packet ("E01");
return;
}
val = 0;
off += 4;
}
val <<= 4;
}
put_str_packet ("OK");
} /* rsp_write_mem () */
 
2396,19 → 2399,19
/*---------------------------------------------------------------------------*/
/*!Read a single register
 
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
(i.e. SPR NPC) and SR (i.e. SPR SR). The register is returned as a
sequence of bytes in target endian order.
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
(i.e. SPR NPC) and SR (i.e. SPR SR). The register is returned as a
sequence of bytes in target endian order.
 
Each byte is packed as a pair of hex digits.
Each byte is packed as a pair of hex digits.
 
@param[in] p_buf The original packet request. Reused for the reply. */
@param[in] p_buf The original packet request. Reused for the reply. */
/*---------------------------------------------------------------------------*/
static void
rsp_read_reg (struct rsp_buf *p_buf)
{
unsigned int regnum;
uint32_t temp_uint32;
uint32_t temp_uint32;
 
/* Break out the fields from the data */
if (1 != sscanf (p_buf->data, "p%x", &regnum))
2425,10 → 2428,10
// First set the chain
err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
put_str_packet ("E01");
return;
}
return;
}
/* Get the relevant register */
if (regnum < MAX_GPRS)
2492,13 → 2495,13
/*---------------------------------------------------------------------------*/
/*!Write a single register
 
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
(i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a
sequence of bytes in target endian order.
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
(i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a
sequence of bytes in target endian order.
 
Each byte is packed as a pair of hex digits.
Each byte is packed as a pair of hex digits.
 
@param[in] p_buf The original packet request. */
@param[in] p_buf The original packet request. */
/*---------------------------------------------------------------------------*/
static void
rsp_write_reg (struct rsp_buf *p_buf)
2505,7 → 2508,7
{
unsigned int regnum;
char valstr[9]; /* Allow for EOS on the string */
// int err = 0;
// int err = 0;
 
/* Break out the fields from the data */
if (2 != sscanf (p_buf->data, "P%x=%8s", &regnum, valstr))
2522,10 → 2525,10
// First set the chain
err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
put_str_packet ("E01");
return;
}
return;
}
 
/* Set the relevant register */
if (regnum < MAX_GPRS) /* ---------- GPRS ---------- */
2550,12 → 2553,12
{
set_npc(hex2reg (valstr));
/*
err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (valstr));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
put_str_packet ("E01");
return;
}
err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (valstr));
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
put_str_packet ("E01");
return;
}
*/
}
else if (SR_REGNUM == regnum) /* ---------- SR ---------- */
2565,7 → 2568,7
if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err);
put_str_packet ("E01");
return;
}
}
}
else
{
2584,7 → 2587,7
/*---------------------------------------------------------------------------*/
/*!Handle a RSP query request
 
@param[in] p_buf The request */
@param[in] p_buf The request */
/*---------------------------------------------------------------------------*/
static void
rsp_query (struct rsp_buf *p_buf)
2596,6 → 2599,14
support a thread concept, this is the appropriate response. */
put_str_packet ("");
}
if (0 == strncmp ("qAttached", p_buf->data, strlen ("qAttached")))
{
/* Return an indication of whether the remote server attached to an
existing process or created a new process.
Reply: '1' - The remote server attached to an existing process.
'0' - The remote server created a new process. */
put_str_packet ("1");
}
else if (0 == strncmp ("qCRC", p_buf->data, strlen ("qCRC")))
{
/* Return CRC of memory area */
2643,10 → 2654,10
else if (0 == strncmp ("qSupported", p_buf->data, strlen ("qSupported")))
{
/* Report a list of the features we support. For now we just ignore any
supplied specific feature queries, but in the future these may be
supported as well. Note that the packet size allows for 'G' + all the
registers sent to us, or a reply to 'g' with all the registers and an
EOS so the buffer is a well formed string. */
supplied specific feature queries, but in the future these may be
supported as well. Note that the packet size allows for 'G' + all the
registers sent to us, or a reply to 'g' with all the registers and an
EOS so the buffer is a well formed string. */
setup_or32(); // setup cpu
char reply[GDB_BUF_MAX];
sprintf (reply, "PacketSize=%x", GDB_BUF_MAX);
2676,6 → 2687,39
fprintf (stderr, "Warning: RSP 'qXfer' not supported: ignored\n");
put_str_packet ("");
}
else if (0 == strncmp ("qTStatus", p_buf->data, strlen ("qTStatus")))
{
/* Ask the stub if there is a trace experiment running right now.
The reply has the form:
`Trunning[;field]...'
running is a single digit 1 if the trace is presently running, or 0
if not. It is followed by semicolon-separated optional fields that an
agent may use to report additional status.
*/
put_str_packet ("T0");
}
else if ((0 == strncmp ("qTfV", p_buf->data, strlen ("qTfV"))) ||
(0 == strncmp ("qTsV", p_buf->data, strlen ("qTsV"))))
{
/*
These packets request data about trace state variables that are on the
target. gdb sends qTfV to get the first vari of data, and multiple qTsV
to get additional variables. Replies to these packets follow the syntax
of the QTDV packets that define trace state variables.
*/
put_str_packet ("");
}
else if (0 == strncmp ("qTfP", p_buf->data, strlen ("qTfP")))
{
/*
These packets request data about tracepoints that are being used by the
target. gdb sends qTfP to get the first piece of data, and multiple
qTsP to get additional pieces. Replies to these packets generally take
the form of the QTDP packets that define tracepoints. (FIXME add
detailed syntax)
*/
put_str_packet ("");
}
else
{
fprintf (stderr, "Unrecognized RSP query: ignored\n");
2688,7 → 2732,7
 
The actual command follows the "qRcmd," in ASCII encoded to hex
 
@param[in] p_buf The request in full */
@param[in] p_buf The request in full */
/*---------------------------------------------------------------------------*/
static void
rsp_command (struct rsp_buf *p_buf)
2701,53 → 2745,53
 
/* Work out which command it is */
if (0 == strncmp ("readspr ", cmd, strlen ("readspr")))
{
/* Parse and return error if we fail */
if( 1 != sscanf (cmd, "readspr %4x", &regno))
{
fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", cmd);
put_str_packet ("E01");
return;
}
{
/* Parse and return error if we fail */
if( 1 != sscanf (cmd, "readspr %4x", &regno))
{
fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", cmd);
put_str_packet ("E01");
return;
}
/* SPR out of range */
if (regno > MAX_SPRS)
{
fprintf (stderr, "Warning: qRcmd readspr %x too large: ignored\n",
regno);
put_str_packet ("E01");
return;
}
/* SPR out of range */
if (regno > MAX_SPRS)
{
fprintf (stderr, "Warning: qRcmd readspr %x too large: ignored\n",
regno);
put_str_packet ("E01");
return;
}
/* Construct the reply */
/* Construct the reply */
// Make sure the processor is stalled
gdb_ensure_or1k_stalled();
// Make sure the processor is stalled
gdb_ensure_or1k_stalled();
 
// First set the chain
gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
// First set the chain
gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
// special case for NPC
if(regno == NPC_CPU_REG_ADD)
temp_uint32 = get_npc();
else
{
err = gdb_read_reg(regno, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_command at reg. %x \n", err, regno);
}
else{
reg2hex (temp_uint32, cmd);
if (DEBUG_GDB) printf("Error %d Command readspr Read reg. %x = 0x%08x\n", err, regno, temp_uint32);
// special case for NPC
if(regno == NPC_CPU_REG_ADD)
temp_uint32 = get_npc();
else
{
err = gdb_read_reg(regno, &temp_uint32);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_command at reg. %x \n", err, regno);
}
else{
reg2hex (temp_uint32, cmd);
if (DEBUG_GDB) printf("Error %d Command readspr Read reg. %x = 0x%08x\n", err, regno, temp_uint32);
}
}
}
// pack the result into the buffer to send back
sprintf (cmd, "%8x", (unsigned int)temp_uint32);
ascii2hex (p_buf->data, cmd);
p_buf->len = strlen (p_buf->data);
put_packet (p_buf);
}
// pack the result into the buffer to send back
sprintf (cmd, "%8x", (unsigned int)temp_uint32);
ascii2hex (p_buf->data, cmd);
p_buf->len = strlen (p_buf->data);
put_packet (p_buf);
}
else if (0 == strncmp ("writespr ", cmd, strlen ("writespr")))
{
unsigned int regno;
2802,7 → 2846,7
/*---------------------------------------------------------------------------*/
/*!Handle a RSP set request
 
@param[in] p_buf The request */
@param[in] p_buf The request */
/*---------------------------------------------------------------------------*/
static void
rsp_set (struct rsp_buf *p_buf)
2834,9 → 2878,9
/*---------------------------------------------------------------------------*/
/*!Handle a RSP restart request
 
For now we just put the program counter back to the one used with the last
vRun request. There is no point in unstalling the processor, since we'll
never get control back. */
For now we just put the program counter back to the one used with the last
vRun request. There is no point in unstalling the processor, since we'll
never get control back. */
/*---------------------------------------------------------------------------*/
static void
rsp_restart (void)
2847,24 → 2891,24
// First set the chain
err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
if(err > 0){
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
put_str_packet ("E01");
return;
}
// OR32 Arc sim equivalent --> set_npc (rsp.start_addr);
return;
}
// OR32 Arc sim equivalent --> set_npc (rsp.start_addr);
/* Set NPC to reset vector 0x100 */
set_npc(rsp.start_addr);
/*
err = gdb_write_reg(NPC_CPU_REG_ADD, rsp.start_addr);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_restart write Reg. %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
err = gdb_write_reg(NPC_CPU_REG_ADD, rsp.start_addr);
if(err > 0){
if (DEBUG_GDB) printf("Error %d in rsp_restart write Reg. %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
put_str_packet ("E01");
return;
}
return;
}
else{
if (DEBUG_GDB) printf("Error %d Command Reset. Set NPC to Start vector %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
}
else{
if (DEBUG_GDB) printf("Error %d Command Reset. Set NPC to Start vector %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
}
*/
} /* rsp_restart () */
 
2872,10 → 2916,10
/*---------------------------------------------------------------------------*/
/*!Handle a RSP step request
 
Parse the command to see if there is an address. Uses the underlying
generic step function, with EXCEPT_NONE.
Parse the command to see if there is an address. Uses the underlying
generic step function, with EXCEPT_NONE.
 
@param[in] p_buf The full step packet */
@param[in] p_buf The full step packet */
/*---------------------------------------------------------------------------*/
static void
rsp_step (struct rsp_buf *p_buf)
2888,43 → 2932,43
// First set the chain
err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
if(err > 0){
printf("Error %d to set RISC Debug Interface chain in the STEP command 's'\n", err);
printf("Error %d to set RISC Debug Interface chain in the STEP command 's'\n", err);
rsp_client_close ();
return;
}
}
 
if (0 == strcmp ("s", p_buf->data))
{
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- Npc ---------- */
addr = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
if(err > 0){
printf("Error %d to read NPC in the STEP command 's'\n", err);
rsp_client_close ();
return;
{
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- Npc ---------- */
addr = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
if(err > 0){
printf("Error %d to read NPC in the STEP command 's'\n", err);
rsp_client_close ();
return;
}
*/
}
*/
}
else if (1 != sscanf (p_buf->data, "s%x", &addr))
{
fprintf (stderr,
"Warning: RSP step address %s not recognized: ignored\n",
p_buf->data);
{
fprintf (stderr,
"Warning: RSP step address %s not recognized: ignored\n",
p_buf->data);
 
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- NPC ---------- */
addr = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
if(err > 0){
printf("Error %d to read NPC in the STEP command 's'\n", err);
rsp_client_close ();
return;
// Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
/* ---------- NPC ---------- */
addr = get_npc();
/*
err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
if(err > 0){
printf("Error %d to read NPC in the STEP command 's'\n", err);
rsp_client_close ();
return;
}
*/
}
*/
}
 
//if (DEBUG_GDB) printf("rsp_step() --> Read NPC = 0x%08x\n", addr);
rsp_step_generic (addr, EXCEPT_NONE);
2935,9 → 2979,9
/*---------------------------------------------------------------------------*/
/*!Handle a RSP step with signal request
 
Currently null. Will use the underlying generic step function.
Currently null. Will use the underlying generic step function.
 
@param[in] p_buf The full step with signal packet */
@param[in] p_buf The full step with signal packet */
/*---------------------------------------------------------------------------*/
static void
rsp_step_with_signal (struct rsp_buf *p_buf)
2950,14 → 2994,14
/*---------------------------------------------------------------------------*/
/*!Generic processing of a step request
 
The signal may be EXCEPT_NONE if there is no exception to be
handled. Currently the exception is ignored.
The signal may be EXCEPT_NONE if there is no exception to be
handled. Currently the exception is ignored.
 
The single step flag is set in the debug registers and then the processor
is unstalled.
The single step flag is set in the debug registers and then the processor
is unstalled.
 
@param[in] addr Address from which to step
@param[in] except The exception to use (if any) */
@param[in] addr Address from which to step
@param[in] except The exception to use (if any) */
/*---------------------------------------------------------------------------*/
static void
rsp_step_generic (uint32_t addr,
3003,9 → 3047,9
/*---------------------------------------------------------------------------*/
/*!Handle a RSP 'v' packet
 
These are commands associated with executing the code on the target
These are commands associated with executing the code on the target
 
@param[in] p_buf The request */
@param[in] p_buf The request */
/*---------------------------------------------------------------------------*/
static void
rsp_vpkt (struct rsp_buf *p_buf)
3086,18 → 3130,18
/*---------------------------------------------------------------------------*/
/*!Handle a RSP write memory (binary) request
 
Syntax is:
Syntax is:
 
X<addr>,<length>:
X<addr>,<length>:
 
Followed by the specified number of bytes as raw binary. Response should be
"OK" if all copied OK, E<nn> if error <nn> has occurred.
Followed by the specified number of bytes as raw binary. Response should be
"OK" if all copied OK, E<nn> if error <nn> has occurred.
 
The length given is the number of bytes to be written. However the number
of data bytes may be greater, since '#', '$' and '}' are escaped by
preceding them by '}' and oring with 0x20.
The length given is the number of bytes to be written. However the number
of data bytes may be greater, since '#', '$' and '}' are escaped by
preceding them by '}' and oring with 0x20.
 
@param[in] p_buf The command received */
@param[in] p_buf The command received */
/*---------------------------------------------------------------------------*/
static void
rsp_write_mem_bin (struct rsp_buf *p_buf)
3121,29 → 3165,29
/* Find the start of the data and "unescape" it */
bindat = p_buf->data;
while(off < GDB_BUF_MAX){
if(bindat[off] == ':'){
bindat = bindat + off + 1;
off++;
break;
}
off++;
if(bindat[off] == ':'){
bindat = bindat + off + 1;
off++;
break;
}
off++;
}
if(off >= GDB_BUF_MAX){
put_str_packet ("E01");
return;
}
if(off >= GDB_BUF_MAX){
put_str_packet ("E01");
return;
}
newlen = rsp_unescape (bindat, p_buf->len - off);
 
/* Sanity check */
if (newlen != len)
{
int minlen = len < newlen ? len : newlen;
{
int minlen = len < newlen ? len : newlen;
 
fprintf (stderr, "Warning: Write of %d bytes requested, but %d bytes "
"supplied. %d will be written\n", len, newlen, minlen);
len = minlen;
}
fprintf (stderr, "Warning: Write of %d bytes requested, but %d bytes "
"supplied. %d will be written\n", len, newlen, minlen);
len = minlen;
}
 
// Make sure the processor is stalled
gdb_ensure_or1k_stalled();
3249,13 → 3293,13
/*---------------------------------------------------------------------------*/
/*!Handle a RSP remove breakpoint or matchpoint request
 
For now only memory breakpoints are implemented, which are implemented by
substituting a breakpoint at the specified address. The implementation must
cope with the possibility of duplicate packets.
For now only memory breakpoints are implemented, which are implemented by
substituting a breakpoint at the specified address. The implementation must
cope with the possibility of duplicate packets.
 
@todo This doesn't work with icache/immu yet
@todo This doesn't work with icache/immu yet
 
@param[in] p_buf The command received */
@param[in] p_buf The command received */
/*---------------------------------------------------------------------------*/
static void
rsp_remove_matchpoint (struct rsp_buf *p_buf)
3290,26 → 3334,26
mpe = mp_hash_delete (type, addr);
 
/* If the BP hasn't yet been deleted, put the original instruction
back. Don't forget to free the hash table entry afterwards. */
if (NULL != mpe)
{
// Arc Sim Code --> set_program32 (addr, mpe->instr);
// Make sure the processor is stalled
gdb_ensure_or1k_stalled();
back. Don't forget to free the hash table entry afterwards. */
if (NULL != mpe)
{
// Arc Sim Code --> set_program32 (addr, mpe->instr);
// Make sure the processor is stalled
gdb_ensure_or1k_stalled();
 
// Set chain 5 --> Wishbone Memory chain
err = gdb_set_chain(SC_WISHBONE);
if(err){
put_str_packet ("E01");
return;
}
err = gdb_write_block(addr, &mpe->instr, 4);
if(err){
put_str_packet ("E01");
return;
}
free (mpe);
}
// Set chain 5 --> Wishbone Memory chain
err = gdb_set_chain(SC_WISHBONE);
if(err){
put_str_packet ("E01");
return;
}
err = gdb_write_block(addr, &mpe->instr, 4);
if(err){
put_str_packet ("E01");
return;
}
free (mpe);
}
 
put_str_packet ("OK");
return;
3343,13 → 3387,13
/*---------------------------------------------------------------------------*/
/*!Handle a RSP insert breakpoint or matchpoint request
 
For now only memory breakpoints are implemented, which are implemented by
substituting a breakpoint at the specified address. The implementation must
cope with the possibility of duplicate packets.
For now only memory breakpoints are implemented, which are implemented by
substituting a breakpoint at the specified address. The implementation must
cope with the possibility of duplicate packets.
 
@todo This doesn't work with icache/immu yet
@todo This doesn't work with icache/immu yet
 
@param[in] p_buf The command received */
@param[in] p_buf The command received */
/*---------------------------------------------------------------------------*/
static void
rsp_insert_matchpoint (struct rsp_buf *p_buf)
3357,7 → 3401,7
enum mp_type type; /* What sort of matchpoint */
uint32_t addr; /* Address specified */
int len; /* Matchpoint length (not used) */
uint32_t instr;
uint32_t instr;
 
/* Break out the instruction */
if (3 != sscanf (p_buf->data, "Z%1d,%x,%1d", (int *)&type, &addr, &len))
3429,9 → 3473,9
 
 
/*---------------------------------------------------------------------------
Setup the or32 to init state
Setup the or32 to init state
 
---------------------------------------------------------------------------*/
---------------------------------------------------------------------------*/
void setup_or32(void)
{
uint32_t temp_uint32;
3584,8 → 3628,8
}
 
/*****************************************************************************
* Close the connection to the client if it is open
******************************************************************************/
* Close the connection to the client if it is open
******************************************************************************/
static void client_close (char err)
{
if(gdb_fd) {
3604,24 → 3648,24
/*---------------------------------------------------------------------------*/
static void swap_buf(char* p_buf, int len)
{
int temp;
int n = 0;
int temp;
int n = 0;
 
if (len > 2)
{
while(n < len){
{
while(n < len){
// swap 0 and 3
temp = p_buf[n];
p_buf[n] = p_buf[n + 3];
p_buf[n + 3] = temp;
p_buf[n] = p_buf[n + 3];
p_buf[n + 3] = temp;
// swap 1 and 2
temp = p_buf[n + 1];
p_buf[n + 1] = p_buf[n + 2];
p_buf[n + 2] = temp;
p_buf[n + 1] = p_buf[n + 2];
p_buf[n + 2] = temp;
n += 4;
n += 4;
}
}
}
}
 
 
3628,7 → 3672,7
/*---------------------------------------------------------------------------*/
/*!Set the stall state of the processor
 
@param[in] state If non-zero stall the processor. */
@param[in] state If non-zero stall the processor. */
/*---------------------------------------------------------------------------*/
static void
set_stall_state (int state)
/ChangeLog
0,0 → 1,7
2010-09-24 Julius Baxter <julius@opencores.org>
 
* ChangeLog: Created.
* src/or_debug_proxy.c: Removed all VPI endpoint options.
* src/gdb.c: Added rsp_query handlers for various new packets seen
with gdb-7.2.
 

powered by: WebSVN 2.1.0

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