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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or_debug_proxy/] [src/] [gdb.c] - Diff between revs 431 and 497

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 431 Rev 497
Line 41... Line 41...
/******************************************************************************/
/******************************************************************************/
//
//
// Implements GDB stub for OpenRISC debug proxy.
// Implements GDB stub for OpenRISC debug proxy.
//
//
 
 
 
 
/*$$CHANGE HISTORY*/
/*$$CHANGE HISTORY*/
/******************************************************************************/
/******************************************************************************/
/*                                                                            */
/*                                                                            */
/*                         C H A N G E  H I S T O R Y                         */
/*                         C H A N G E  H I S T O R Y                         */
/*                                                                            */
/*                                                                            */
Line 95... Line 94...
#include <signal.h>
#include <signal.h>
#include <inttypes.h>
#include <inttypes.h>
#include <errno.h>
#include <errno.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
 
 
 
 
/*! Name of the Or1ksim RSP service */
/*! Name of the Or1ksim RSP service */
#define OR1KSIM_RSP_SERVICE  "or1ksim-rsp"
#define OR1KSIM_RSP_SERVICE  "or1ksim-rsp"
 
 
#include "gdb.h" /* partially copied from gdb/config/or1k */
#include "gdb.h" /* partially copied from gdb/config/or1k */
#include "or_debug_proxy.h"
#include "or_debug_proxy.h"
Line 179... Line 177...
#define SPR_DRR_RE    0x00000400  //!< Range fault
#define SPR_DRR_RE    0x00000400  //!< Range fault
#define SPR_DRR_SCE   0x00000800  //!< System call
#define SPR_DRR_SCE   0x00000800  //!< System call
#define SPR_DRR_FPE   0x00001000  //!< Floating point
#define SPR_DRR_FPE   0x00001000  //!< Floating point
#define SPR_DRR_TE    0x00002000  //!< Trap
#define SPR_DRR_TE    0x00002000  //!< Trap
 
 
 
 
/*! Definition of GDB target signals. Data taken from the GDB 6.8
/*! Definition of GDB target signals. Data taken from the GDB 6.8
  source. Only those we use defined here. The exact meaning of
  source. Only those we use defined here. The exact meaning of
  signal number is defined by the header `include/gdb/signals.h'
  signal number is defined by the header `include/gdb/signals.h'
  in the GDB source code. For an explanation of what each signal
  in the GDB source code. For an explanation of what each signal
  means, see target_signal_to_string.*/
  means, see target_signal_to_string.*/
Line 201... Line 198...
};
};
 
 
/*! String to map hex digits to chars */
/*! String to map hex digits to chars */
static const char hexchars[]="0123456789abcdef";
static const char hexchars[]="0123456789abcdef";
 
 
 
 
//! Is the NPC cached?
//! Is the NPC cached?
 
 
//! Setting the NPC flushes the pipeline, so subsequent reads will return
//! Setting the NPC flushes the pipeline, so subsequent reads will return
//! zero until the processor has refilled the pipeline. This will not be
//! zero until the processor has refilled the pipeline. This will not be
//! happening if the processor is stalled (as it is when GDB had control),
//! happening if the processor is stalled (as it is when GDB had control),
Line 220... Line 216...
 
 
int      npcIsCached;           //!< Is the NPC cached - should be bool
int      npcIsCached;           //!< Is the NPC cached - should be bool
uint32_t  npcCachedValue;               //!< Cached value of the NPC
uint32_t  npcCachedValue;               //!< Cached value of the NPC
 
 
/* OR32 Linux kernel debugging hacks */
/* OR32 Linux kernel debugging hacks */
 
int kernel_debug = 0; // Disabled by default. Enabled via command line.
/* If we're operating in virtual memory space, currently the standard VM base
/* If we're operating in virtual memory space, currently the standard VM base
   is 0xc0000000, since the GDB we're currently using is bare-metal we will
   is 0xc0000000, since the GDB we're currently using is bare-metal we will
   do a translation of these VM addresses to their physical address - although
   do a translation of these VM addresses to their physical address - although
   not with any sophistication, we simply map all 0xc0000000 based addresses
   not with any sophistication, we simply map all 0xc0000000 based addresses
   to 0x0. This allows GDB to read/wite the addresses the PC and NPC point to,
   to 0x0. This allows GDB to read/wite the addresses the PC and NPC point to,
Line 234... Line 231...
#define OR32_LINUX_VM_MASK 0xf0000000
#define OR32_LINUX_VM_MASK 0xf0000000
 
 
#define IS_VM_ADDR(adr) ((adr & OR32_LINUX_VM_MASK) == OR32_LINUX_VM_OFFSET)
#define IS_VM_ADDR(adr) ((adr & OR32_LINUX_VM_MASK) == OR32_LINUX_VM_OFFSET)
 
 
 
 
 
 
 
 
/************************
/************************
   JTAG Server Routines
   JTAG Server Routines
************************/
************************/
int serverIP = 0;
int serverIP = 0;
int serverPort = 0;
int serverPort = 0;
Line 252... Line 247...
   (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;
int gdb_chain = -1;
 
 
/*! Data structure for RSP buffers. Can't be null terminated, since it may
/*! Data structure for RSP buffers. Can't be null terminated, since it may
  include zero bytes */
  include zero bytes */
struct rsp_buf
struct rsp_buf {
{
 
  char  data[GDB_BUF_MAX_TIMES_TWO];
  char  data[GDB_BUF_MAX_TIMES_TWO];
  int   len;
  int   len;
};
};
 
 
/*! Enumeration of different types of matchpoint. These have explicit values
/*! Enumeration of different types of matchpoint. These have explicit values
Line 269... Line 263...
  WP_READ     = 3,              // read-watchpoint     Z3  rwatch  
  WP_READ     = 3,              // read-watchpoint     Z3  rwatch  
  WP_ACCESS   = 4                       // access-watchpoint   Z4  awatch
  WP_ACCESS   = 4                       // access-watchpoint   Z4  awatch
};
};
 
 
/*! Data structure for a matchpoint hash table entry */
/*! Data structure for a matchpoint hash table entry */
struct mp_entry
struct mp_entry {
{
 
  enum mp_type       type;              /*!< Type of matchpoint */
  enum mp_type       type;              /*!< Type of matchpoint */
  uint32_t  addr;               /*!< Address with the matchpoint */
  uint32_t  addr;               /*!< Address with the matchpoint */
  uint32_t  instr;              /*!< Substituted instruction */
  uint32_t  instr;              /*!< Substituted instruction */
  struct mp_entry   *next;              /*!< Next entry with this hash */
  struct mp_entry   *next;              /*!< Next entry with this hash */
};
};
 
 
/*! Central data for the RSP connection */
/*! Central data for the RSP connection */
static struct
static struct {
{
 
  int                           client_waiting; /*!< Is client waiting a response? */
  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                client_fd;         /*!< FD for talking to GDB */
  int               sigval;                     /*!< GDB signal for any exception */
  int               sigval;                     /*!< GDB signal for any exception */
  uint32_t start_addr;  /*!< Start of last run */
  uint32_t start_addr;  /*!< Start of last run */
Line 360... Line 352...
  struct tm *strtm;
  struct tm *strtm;
  static char timeBuf[20];
  static char timeBuf[20];
 
 
  time(&tid);
  time(&tid);
  strtm = localtime(&tid);
  strtm = localtime(&tid);
  sprintf(timeBuf,"[%.02d:%.02d:%.02d] ",strtm->tm_hour,strtm->tm_min,strtm->tm_sec);
        sprintf(timeBuf, "[%.02d:%.02d:%.02d] ", strtm->tm_hour, strtm->tm_min,
 
                strtm->tm_sec);
  return timeBuf;
  return timeBuf;
}
}
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Initialize the Remote Serial Protocol connection
/*!Initialize the Remote Serial Protocol connection
 
 
  Set up the central data structures.                                       */
  Set up the central data structures.                                       */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void
void rsp_init(void)
rsp_init (void)
 
{
{
  /* Clear out the central data structure */
  /* Clear out the central data structure */
  rsp.client_waiting =  0;               /* GDB client is not waiting for us */
  rsp.client_waiting =  0;               /* GDB client is not waiting for us */
  rsp.client_fd      = -1;              /* i.e. invalid */
  rsp.client_fd      = -1;              /* i.e. invalid */
  rsp.sigval         = 0;                /* No exception */
  rsp.sigval         = 0;                /* No exception */
Line 407... Line 399...
  the exception not been notified to GDB, a packet reporting the cause of the
  the exception not been notified to GDB, a packet reporting the cause of the
  exception is sent.
  exception is sent.
 
 
  The next client request is then processed.                                */
  The next client request is then processed.                                */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void
void handle_rsp(void)
handle_rsp (void)
 
{
{
  uint32_t              temp_uint32;
  uint32_t              temp_uint32;
 
 
  rsp_init();
  rsp_init();
 
 
  while (1){
  while (1){
    /* If we have no RSP client, wait until we get one. */
    /* If we have no RSP client, wait until we get one. */
    while (-1 == rsp.client_fd)
                while (-1 == rsp.client_fd) {
      {
 
        rsp_get_client ();
        rsp_get_client ();
        rsp.client_waiting = 0;          /* No longer waiting */
        rsp.client_waiting = 0;          /* No longer waiting */
      }
      }
 
 
    /* If we have an unacknowledged exception tell the GDB client. If this
    /* If we have an unacknowledged exception tell the GDB client. If this
       exception was a trap due to a memory breakpoint, then adjust the NPC. */
       exception was a trap due to a memory breakpoint, then adjust the NPC. */
    if (rsp.client_waiting)
                if (rsp.client_waiting) {
      {
 
 
 
        // Check for exception
        // Check for exception
        rsp_check_for_exception();
        rsp_check_for_exception();
 
 
        if(stallState == STALLED)
        if(stallState == STALLED)
          // Get the PPC if we're stalled
          // Get the PPC if we're stalled
          gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
          gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
 
 
 
                        if ((TARGET_SIGNAL_TRAP == rsp.sigval)
        if ((TARGET_SIGNAL_TRAP == rsp.sigval) && (NULL != mp_hash_lookup (BP_MEMORY, temp_uint32)))
                            && (NULL !=
          {
                                mp_hash_lookup(BP_MEMORY, temp_uint32))) {
            if (stallState != STALLED)
            if (stallState != STALLED)
              // This is a quick fix for a strange situation seen in some of 
              // This is a quick fix for a strange situation seen in some of 
              // the simulators where the sw bp would be detected, but the 
              // the simulators where the sw bp would be detected, but the 
              // stalled state variable wasn't updated correctly indicating 
              // stalled state variable wasn't updated correctly indicating 
              // that last time it checked, it wasn't set but the processor 
              // that last time it checked, it wasn't set but the processor 
              // had hit the breakpoint. So run rsp_check_for_exception() to 
              // had hit the breakpoint. So run rsp_check_for_exception() to 
              // bring everything up to date.
              // bring everything up to date.
              rsp_check_for_exception();
              rsp_check_for_exception();
 
 
            if(DEBUG_GDB) printf("Software breakpoint hit at 0x%08x. Rolling back NPC to this instruction\n", temp_uint32);
                                if (DEBUG_GDB)
 
                                        printf
 
                                            ("Software breakpoint hit at 0x%08x. Rolling back NPC to this instruction\n",
 
                                             temp_uint32);
 
 
            set_npc (temp_uint32);
            set_npc (temp_uint32);
 
 
            rsp_report_exception();
            rsp_report_exception();
            rsp.client_waiting = 0;              /* No longer waiting */
            rsp.client_waiting = 0;              /* No longer waiting */
          }
                        } else if (stallState == STALLED) {
        else if(stallState == STALLED) {
 
          // If we're here, the thing has stalled, but not because of a breakpoint we set
          // If we're here, the thing has stalled, but not because of a breakpoint we set
          // report back the exception
          // report back the exception
 
 
          rsp_report_exception();
          rsp_report_exception();
          rsp.client_waiting = 0;                /* No longer waiting */
          rsp.client_waiting = 0;                /* No longer waiting */
 
 
        }
        }
 
 
 
 
#ifdef CYGWIN_COMPILE
#ifdef CYGWIN_COMPILE
        //if (rsp.client_waiting)
        //if (rsp.client_waiting)
        //sleep(1);
        //sleep(1);
#else
#else
        if (rsp.client_waiting)
        if (rsp.client_waiting)
          usleep(10000);
          usleep(10000);
        sched_yield();
        sched_yield();
#endif
#endif
 
 
 
 
      }
      }
 
 
    // See if there's any incoming data from the client by peeking at the socket
    // See if there's any incoming data from the client by peeking at the socket
    if (rsp_peek() > 0)
                if (rsp_peek() > 0) {
      {
 
        if (rsp_peek() == 0x03 && (stallState != STALLED)) // ETX, end of text control char
        if (rsp_peek() == 0x03 && (stallState != STALLED)) // ETX, end of text control char
          {
          {
            // Got an interrupt command from GDB, this function should
            // Got an interrupt command from GDB, this function should
            // pull the packet off the socket and stall the processor.
            // pull the packet off the socket and stall the processor.
            // and then send a stop reply packet with signal TARGET_SIGNAL_NONE
            // and then send a stop reply packet with signal TARGET_SIGNAL_NONE
            rsp_interrupt();
            rsp_interrupt();
            rsp.client_waiting = 0;
            rsp.client_waiting = 0;
          }
                        } else if (rsp.client_waiting == 0) {
        else if (rsp.client_waiting == 0)
 
          {
 
            // Default handling of data from the client:
            // Default handling of data from the client:
            /* Get a RSP client request */
            /* Get a RSP client request */
            rsp_client_request ();
            rsp_client_request ();
          }
          }
      } /* end if (rsp_peek() > 0) */
      } /* end if (rsp_peek() > 0) */
Line 507... Line 492...
 
 
  }
  }
 
 
}       /* handle_rsp () */
}       /* handle_rsp () */
 
 
 
 
/*
/*
  Check if processor is stalled - if it is, read the DRR
  Check if processor is stalled - if it is, read the DRR
  and return the target signal code
  and return the target signal code
*/
*/
static void rsp_check_for_exception()
static void rsp_check_for_exception()
Line 519... Line 503...
 
 
  unsigned char stalled;
  unsigned char stalled;
  uint32_t drr;
  uint32_t drr;
  err = dbg_cpu0_read_ctrl(0, &stalled); /* check if we're stalled */
  err = dbg_cpu0_read_ctrl(0, &stalled); /* check if we're stalled */
 
 
  if (!(stalled & 0x01))
        if (!(stalled & 0x01)) {
    {
 
      // Processor not stalled. Just return;
      // Processor not stalled. Just return;
      return;
      return;
    }
    }
 
 
  if (DEBUG_GDB) printf("rsp_check_for_exception() detected processor was stalled\nChecking DRR\n");
        if (DEBUG_GDB)
 
                printf
 
                    ("rsp_check_for_exception() detected processor was stalled\nChecking DRR\n");
 
 
  // We're stalled
  // We're stalled
  stallState = STALLED;
  stallState = STALLED;
  npcIsCached = 0;
  npcIsCached = 0;
 
 
  gdb_set_chain(SC_RISC_DEBUG);
  gdb_set_chain(SC_RISC_DEBUG);
 
 
  // Now read the DRR (Debug Reason Register)
  // Now read the DRR (Debug Reason Register)
  gdb_read_reg(DRR_CPU_REG_ADD, &drr);
  gdb_read_reg(DRR_CPU_REG_ADD, &drr);
 
 
  if (DEBUG_GDB) printf("DRR: 0x%08x\n", drr);
        if (DEBUG_GDB)
 
                printf("DRR: 0x%08x\n", drr);
 
 
  switch ((int)(drr&0xffffffff))
        switch ((int)(drr & 0xffffffff)) {
    {
        case SPR_DRR_RSTE:
    case SPR_DRR_RSTE:  rsp.sigval = TARGET_SIGNAL_PWR;  break;
                rsp.sigval = TARGET_SIGNAL_PWR;
    case SPR_DRR_BUSEE: rsp.sigval = TARGET_SIGNAL_BUS;  break;
                break;
    case SPR_DRR_DPFE:  rsp.sigval = TARGET_SIGNAL_SEGV; break;
        case SPR_DRR_BUSEE:
    case SPR_DRR_IPFE:  rsp.sigval = TARGET_SIGNAL_SEGV; break;
                rsp.sigval = TARGET_SIGNAL_BUS;
    case SPR_DRR_TTE:   rsp.sigval = TARGET_SIGNAL_ALRM; break;
                break;
    case SPR_DRR_AE:    rsp.sigval = TARGET_SIGNAL_BUS;  break;
        case SPR_DRR_DPFE:
    case SPR_DRR_IIE:   rsp.sigval = TARGET_SIGNAL_ILL;  break;
                rsp.sigval = TARGET_SIGNAL_SEGV;
    case SPR_DRR_IE:    rsp.sigval = TARGET_SIGNAL_INT;  break;
                break;
    case SPR_DRR_DME:   rsp.sigval = TARGET_SIGNAL_SEGV; break;
        case SPR_DRR_IPFE:
    case SPR_DRR_IME:   rsp.sigval = TARGET_SIGNAL_SEGV; break;
                rsp.sigval = TARGET_SIGNAL_SEGV;
    case SPR_DRR_RE:    rsp.sigval = TARGET_SIGNAL_FPE;  break;
                break;
    case SPR_DRR_SCE:   rsp.sigval = TARGET_SIGNAL_USR2; break;
        case SPR_DRR_TTE:
    case SPR_DRR_FPE:   rsp.sigval = TARGET_SIGNAL_FPE;  break;
                rsp.sigval = TARGET_SIGNAL_ALRM;
    case SPR_DRR_TE:    rsp.sigval = TARGET_SIGNAL_TRAP; break;
                break;
 
        case SPR_DRR_AE:
 
                rsp.sigval = TARGET_SIGNAL_BUS;
 
                break;
 
        case SPR_DRR_IIE:
 
                rsp.sigval = TARGET_SIGNAL_ILL;
 
                break;
 
        case SPR_DRR_IE:
 
                rsp.sigval = TARGET_SIGNAL_INT;
 
                break;
 
        case SPR_DRR_DME:
 
                rsp.sigval = TARGET_SIGNAL_SEGV;
 
                break;
 
        case SPR_DRR_IME:
 
                rsp.sigval = TARGET_SIGNAL_SEGV;
 
                break;
 
        case SPR_DRR_RE:
 
                rsp.sigval = TARGET_SIGNAL_FPE;
 
                break;
 
        case SPR_DRR_SCE:
 
                rsp.sigval = TARGET_SIGNAL_USR2;
 
                break;
 
        case SPR_DRR_FPE:
 
                rsp.sigval = TARGET_SIGNAL_FPE;
 
                break;
 
        case SPR_DRR_TE:
 
                rsp.sigval = TARGET_SIGNAL_TRAP;
 
                break;
 
 
    default:
    default:
      // This must be the case of single step (which does not set DRR)
      // This must be the case of single step (which does not set DRR)
      rsp.sigval = TARGET_SIGNAL_TRAP; break;
                rsp.sigval = TARGET_SIGNAL_TRAP;
 
                break;
    }
    }
 
 
  if (DEBUG_GDB) printf("rsp.sigval: 0x%x\n", rsp.sigval);
        if (DEBUG_GDB)
 
                printf("rsp.sigval: 0x%x\n", rsp.sigval);
 
 
  return;
  return;
}
}
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Line 575... Line 590...
  sigval and return.
  sigval and return.
 
 
  @param[in] ppc  Value of current PPC, as read from debug unit
  @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       */
  @return: 1 if we set a sigval and should return control to GDB, else 0       */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static int check_for_exception_vector(uint32_t ppc)
check_for_exception_vector(uint32_t ppc)
 
{
 
  switch(ppc)
 
    {
    {
 
        switch (ppc) {
      // The following should return sigvals to GDB for processing
      // The following should return sigvals to GDB for processing
    case EXCEPT_BUSERR:
    case EXCEPT_BUSERR:
    case EXCEPT_ALIGN:
    case EXCEPT_ALIGN:
    case EXCEPT_ILLEGAL:
    case EXCEPT_ILLEGAL:
    case EXCEPT_TRAP:     if(DEBUG_GDB)
        case EXCEPT_TRAP:
 
                if (DEBUG_GDB)
        printf("PPC at exception address\n");
        printf("PPC at exception address\n");
      rsp_exception(ppc);
      rsp_exception(ppc);
      return 1;
      return 1;
 
 
    default:
    default:
Line 607... Line 621...
  We flag up a warning if an exception is already pending, and ignore the
  We flag up a warning if an exception is already pending, and ignore the
  earlier exception.
  earlier exception.
 
 
  @param[in] except  The exception (Or1ksim form)                           */
  @param[in] except  The exception (Or1ksim form)                           */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void
void rsp_exception(uint32_t except)
rsp_exception (uint32_t  except)
 
{
{
  int  sigval;                  /* GDB signal equivalent to exception */
  int  sigval;                  /* GDB signal equivalent to exception */
 
 
  switch (except)
        switch (except) {
    {
        case EXCEPT_RESET:
    case EXCEPT_RESET:    sigval = TARGET_SIGNAL_PWR;  break;
                sigval = TARGET_SIGNAL_PWR;
    case EXCEPT_BUSERR:   sigval = TARGET_SIGNAL_BUS;  break;
                break;
    case EXCEPT_DPF:      sigval = TARGET_SIGNAL_SEGV; break;
        case EXCEPT_BUSERR:
    case EXCEPT_IPF:      sigval = TARGET_SIGNAL_SEGV; break;
                sigval = TARGET_SIGNAL_BUS;
    case EXCEPT_TICK:     sigval = TARGET_SIGNAL_ALRM; break;
                break;
    case EXCEPT_ALIGN:    sigval = TARGET_SIGNAL_BUS;  break;
        case EXCEPT_DPF:
    case EXCEPT_ILLEGAL:  sigval = TARGET_SIGNAL_ILL;  break;
                sigval = TARGET_SIGNAL_SEGV;
    case EXCEPT_INT:      sigval = TARGET_SIGNAL_INT;  break;
                break;
    case EXCEPT_DTLBMISS: sigval = TARGET_SIGNAL_SEGV; break;
        case EXCEPT_IPF:
    case EXCEPT_ITLBMISS: sigval = TARGET_SIGNAL_SEGV; break;
                sigval = TARGET_SIGNAL_SEGV;
    case EXCEPT_RANGE:    sigval = TARGET_SIGNAL_FPE;  break;
                break;
    case EXCEPT_SYSCALL:  sigval = TARGET_SIGNAL_USR2; break;
        case EXCEPT_TICK:
    case EXCEPT_FPE:      sigval = TARGET_SIGNAL_FPE;  break;
                sigval = TARGET_SIGNAL_ALRM;
    case EXCEPT_TRAP:     sigval = TARGET_SIGNAL_TRAP; break;
                break;
 
        case EXCEPT_ALIGN:
 
                sigval = TARGET_SIGNAL_BUS;
 
                break;
 
        case EXCEPT_ILLEGAL:
 
                sigval = TARGET_SIGNAL_ILL;
 
                break;
 
        case EXCEPT_INT:
 
                sigval = TARGET_SIGNAL_INT;
 
                break;
 
        case EXCEPT_DTLBMISS:
 
                sigval = TARGET_SIGNAL_SEGV;
 
                break;
 
        case EXCEPT_ITLBMISS:
 
                sigval = TARGET_SIGNAL_SEGV;
 
                break;
 
        case EXCEPT_RANGE:
 
                sigval = TARGET_SIGNAL_FPE;
 
                break;
 
        case EXCEPT_SYSCALL:
 
                sigval = TARGET_SIGNAL_USR2;
 
                break;
 
        case EXCEPT_FPE:
 
                sigval = TARGET_SIGNAL_FPE;
 
                break;
 
        case EXCEPT_TRAP:
 
                sigval = TARGET_SIGNAL_TRAP;
 
                break;
 
 
    default:
    default:
      fprintf (stderr, "Warning: Unknown RSP exception %u: Ignored\n", except);
                fprintf(stderr, "Warning: Unknown RSP exception %u: Ignored\n",
 
                        except);
      return;
      return;
    }
    }
 
 
  if ((0 != rsp.sigval) && (sigval != rsp.sigval))
        if ((0 != rsp.sigval) && (sigval != rsp.sigval)) {
    {
 
      fprintf (stderr, "Warning: RSP signal %d received while signal "
      fprintf (stderr, "Warning: RSP signal %d received while signal "
               "%d pending: Pending exception replaced\n", sigval, rsp.sigval);
                        "%d pending: Pending exception replaced\n", sigval,
 
                        rsp.sigval);
    }
    }
 
 
  rsp.sigval         = sigval;          /* Save the signal value */
  rsp.sigval         = sigval;          /* Save the signal value */
 
 
}       /* rsp_exception () */
}       /* rsp_exception () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Get a new client connection.
/*!Get a new client connection.
 
 
  Blocks until the client connection is available.
  Blocks until the client connection is available.
 
 
Line 662... Line 702...
  (parameter rsp_port in section debug, default 51000) or as a service name
  (parameter rsp_port in section debug, default 51000) or as a service name
  in the constant OR1KSIM_RSP_SERVICE.
  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
static void rsp_get_client(void)
rsp_get_client (void)
 
{
{
  int                 tmp_fd;           /* Temporary descriptor for socket */
  int                 tmp_fd;           /* Temporary descriptor for socket */
  int                 optval;           /* Socket options */
  int                 optval;           /* Socket options */
  struct sockaddr_in  sock_addr;        /* Socket address */
  struct sockaddr_in  sock_addr;        /* Socket address */
  socklen_t           len;              /* Size of the socket address */
  socklen_t           len;              /* Size of the socket address */
 
 
  /* 0 is used as the RSP port number to indicate that we should use the
  /* 0 is used as the RSP port number to indicate that we should use the
     service name instead. */
     service name instead. */
  if (0 == serverPort)
        if (0 == serverPort) {
    {
                struct servent *service =
      struct servent *service = getservbyname (OR1KSIM_RSP_SERVICE, "tcp");
                    getservbyname(OR1KSIM_RSP_SERVICE, "tcp");
      if (NULL == service)
                if (NULL == service) {
        {
                        fprintf(stderr,
          fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n",
                                "Warning: RSP unable to find service \"%s\": %s\n",
                   OR1KSIM_RSP_SERVICE, strerror (errno));
                   OR1KSIM_RSP_SERVICE, strerror (errno));
          return;
          return;
        }
        }
      serverPort = ntohs (service->s_port);
      serverPort = ntohs (service->s_port);
    }
    }
 
 
  /* Open a socket on which we'll listen for clients */
  /* Open a socket on which we'll listen for clients */
  tmp_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
  tmp_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (tmp_fd < 0)
        if (tmp_fd < 0) {
    {
 
      fprintf (stderr, "ERROR: Cannot open RSP socket\n");
      fprintf (stderr, "ERROR: Cannot open RSP socket\n");
      exit (0);
      exit (0);
    }
    }
 
 
  /* Allow rapid reuse of the port on this socket */
  /* Allow rapid reuse of the port on this socket */
Line 701... Line 739...
 
 
  /* Bind the port to the socket */
  /* Bind the port to the socket */
  sock_addr.sin_family      = PF_INET;
  sock_addr.sin_family      = PF_INET;
  sock_addr.sin_port        = htons (serverPort);
  sock_addr.sin_port        = htons (serverPort);
  sock_addr.sin_addr.s_addr = INADDR_ANY;
  sock_addr.sin_addr.s_addr = INADDR_ANY;
  if (bind (tmp_fd, (struct sockaddr *) &sock_addr, sizeof (sock_addr)))
        if (bind(tmp_fd, (struct sockaddr *)&sock_addr, sizeof(sock_addr))) {
    {
 
      fprintf (stderr, "ERROR: Cannot bind to RSP socket\n");
      fprintf (stderr, "ERROR: Cannot bind to RSP socket\n");
      exit (0);
      exit (0);
    }
    }
 
 
  /* Listen for (at most one) client */
  /* Listen for (at most one) client */
  if (0 != listen (tmp_fd, 1))
        if (0 != listen(tmp_fd, 1)) {
    {
 
      fprintf (stderr, "ERROR: Cannot listen on RSP socket\n");
      fprintf (stderr, "ERROR: Cannot listen on RSP socket\n");
      exit (0);
      exit (0);
    }
    }
 
 
  printf("Waiting for gdb connection on localhost:%d\n", serverPort);
  printf("Waiting for gdb connection on localhost:%d\n", serverPort);
Line 724... Line 760...
 
 
  /* Accept a client which connects */
  /* Accept a client which connects */
  len = sizeof (sock_addr);
  len = sizeof (sock_addr);
  rsp.client_fd = accept (tmp_fd, (struct sockaddr *)&sock_addr, &len);
  rsp.client_fd = accept (tmp_fd, (struct sockaddr *)&sock_addr, &len);
 
 
  if (-1 == rsp.client_fd)
        if (-1 == rsp.client_fd) {
    {
 
      fprintf (stderr, "Warning: Failed to accept RSP client\n");
      fprintf (stderr, "Warning: Failed to accept RSP client\n");
      return;
      return;
    }
    }
 
 
  /* Enable TCP keep alive process */
  /* Enable TCP keep alive process */
Line 769... Line 804...
     non-blocking socket was required (in the event that a read/write throws
     non-blocking socket was required (in the event that a read/write throws
     back a EWOULDBLOCK error, as was looked to be the case in the previous
     back a EWOULDBLOCK error, as was looked to be the case in the previous
     GDB handling code) -- Julius
     GDB handling code) -- Julius
  */
  */
 
 
  if (ioctl(rsp.client_fd, FIONBIO, (char *)&optval) > 0 )
        if (ioctl(rsp.client_fd, FIONBIO, (char *)&optval) > 0) {
    {
 
      perror("ioctl() failed");
      perror("ioctl() failed");
      close(rsp.client_fd);
      close(rsp.client_fd);
      close(tmp_fd);
      close(tmp_fd);
      exit(0);
      exit(0);
    }
    }
 
 
 
 
  /* Don't delay small packets, for better interactive response (disable
  /* Don't delay small packets, for better interactive response (disable
     Nagel's algorithm) */
     Nagel's algorithm) */
  optval = 1;
  optval = 1;
  setsockopt (rsp.client_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval,
  setsockopt (rsp.client_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval,
              sizeof (optval));
              sizeof (optval));
 
 
  /* Socket is no longer needed */
  /* Socket is no longer needed */
  close (tmp_fd);                       /* No longer need this */
  close (tmp_fd);                       /* No longer need this */
  signal (SIGPIPE, SIG_IGN);            /* So we don't exit if client dies */
  signal (SIGPIPE, SIG_IGN);            /* So we don't exit if client dies */
 
 
  printf ("Remote debugging from host %s\n", inet_ntoa (sock_addr.sin_addr));
        printf("Remote debugging from host %s\n",
 
               inet_ntoa(sock_addr.sin_addr));
}       /* rsp_get_client () */
}       /* rsp_get_client () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Deal with a request from the GDB client session
/*!Deal with a request from the GDB client session
 
 
  In general, apart from the simplest requests, this function replies on
  In general, apart from the simplest requests, this function replies on
  other functions to implement the functionality.                           */
  other functions to implement the functionality.                           */
Line 804... Line 837...
{
{
  struct rsp_buf *p_buf = get_packet ();        /* Message sent to us */
  struct rsp_buf *p_buf = get_packet ();        /* Message sent to us */
 
 
  // Null packet means we hit EOF or the link was closed for some other
  // Null packet means we hit EOF or the link was closed for some other
  // reason. Close the client and return
  // reason. Close the client and return
  if (NULL == p_buf)
        if (NULL == p_buf) {
    {
 
      rsp_client_close ();
      rsp_client_close ();
      return;
      return;
    }
    }
 
 
  if (DEBUG_GDB){
  if (DEBUG_GDB){
    printf("%s-----------------------------------------------------\n", printTime());
                printf
    printf ("Packet received %s: %d chars\n", p_buf->data, p_buf->len );
                    ("%s-----------------------------------------------------\n",
 
                     printTime());
 
                printf("Packet received %s: %d chars\n", p_buf->data,
 
                       p_buf->len);
    fflush (stdout);
    fflush (stdout);
  }
  }
 
 
  switch (p_buf->data[0])
        switch (p_buf->data[0]) {
    {
 
    case '!':
    case '!':
      /* Request for extended remote mode */
      /* Request for extended remote mode */
      put_str_packet ("OK"); // OK = supports and has enabled extended mode.
      put_str_packet ("OK"); // OK = supports and has enabled extended mode.
      return;
      return;
 
 
Line 830... Line 864...
      rsp_report_exception();
      rsp_report_exception();
      return;
      return;
 
 
    case 'A':
    case 'A':
      /* Initialization of argv not supported */
      /* Initialization of argv not supported */
      fprintf (stderr, "Warning: RSP 'A' packet not supported: ignored\n");
                fprintf(stderr,
 
                        "Warning: RSP 'A' packet not supported: ignored\n");
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
 
 
    case 'b':
    case 'b':
      /* Setting baud rate is deprecated */
      /* Setting baud rate is deprecated */
Line 842... Line 877...
               "supported: ignored\n");
               "supported: ignored\n");
      return;
      return;
 
 
    case 'B':
    case 'B':
      /* Breakpoints should be set using Z packets */
      /* Breakpoints should be set using Z packets */
      fprintf (stderr, "Warning: RSP 'B' packet is deprecated (use 'Z'/'z' "
                fprintf(stderr,
 
                        "Warning: RSP 'B' packet is deprecated (use 'Z'/'z' "
               "packets instead): ignored\n");
               "packets instead): ignored\n");
      return;
      return;
 
 
    case 'c':
    case 'c':
      /* Continue */
      /* Continue */
Line 858... Line 894...
      rsp_continue_with_signal (p_buf);
      rsp_continue_with_signal (p_buf);
      return;
      return;
 
 
    case 'd':
    case 'd':
      /* Disable debug using a general query */
      /* Disable debug using a general query */
      fprintf (stderr, "Warning: RSP 'd' packet is deprecated (define a 'Q' "
                fprintf(stderr,
 
                        "Warning: RSP 'd' packet is deprecated (define a 'Q' "
               "packet instead: ignored\n");
               "packet instead: ignored\n");
      return;
      return;
 
 
    case 'D':
    case 'D':
      /* Detach GDB. Do this by closing the client. The rules say that
      /* Detach GDB. Do this by closing the client. The rules say that
Line 875... Line 912...
      set_stall_state (0);
      set_stall_state (0);
      return;
      return;
 
 
    case 'F':
    case 'F':
      /* File I/O is not currently supported */
      /* File I/O is not currently supported */
      fprintf (stderr, "Warning: RSP file I/O not currently supported: 'F' "
                fprintf(stderr,
 
                        "Warning: RSP file I/O not currently supported: 'F' "
               "packet ignored\n");
               "packet ignored\n");
      return;
      return;
 
 
    case 'g':
    case 'g':
      rsp_read_all_regs ();
      rsp_read_all_regs ();
Line 895... Line 933...
      put_str_packet ("OK");
      put_str_packet ("OK");
      return;
      return;
 
 
    case 'i':
    case 'i':
      /* Single instruction step */
      /* Single instruction step */
      fprintf (stderr, "Warning: RSP cycle stepping not supported: target "
                fprintf(stderr,
 
                        "Warning: RSP cycle stepping not supported: target "
               "stopped immediately\n");
               "stopped immediately\n");
      rsp.client_waiting = 1;                   /* Stop reply will be sent */
      rsp.client_waiting = 1;                   /* Stop reply will be sent */
      return;
      return;
 
 
    case 'I':
    case 'I':
      /* Single instruction step with signal */
      /* Single instruction step with signal */
      fprintf (stderr, "Warning: RSP cycle stepping not supported: target "
                fprintf(stderr,
 
                        "Warning: RSP cycle stepping not supported: target "
               "stopped immediately\n");
               "stopped immediately\n");
      rsp.client_waiting = 1;                   /* Stop reply will be sent */
      rsp.client_waiting = 1;                   /* Stop reply will be sent */
      return;
      return;
 
 
    case 'k':
    case 'k':
Line 943... Line 983...
      rsp_set (p_buf);
      rsp_set (p_buf);
      return;
      return;
 
 
    case 'r':
    case 'r':
      /* Reset the system. Deprecated (use 'R' instead) */
      /* Reset the system. Deprecated (use 'R' instead) */
      fprintf (stderr, "Warning: RSP 'r' packet is deprecated (use 'R' "
                fprintf(stderr,
 
                        "Warning: RSP 'r' packet is deprecated (use 'R' "
               "packet instead): ignored\n");
               "packet instead): ignored\n");
      return;
      return;
 
 
    case 'R':
    case 'R':
      /* Restart the program being debugged. */
      /* Restart the program being debugged. */
Line 967... Line 1008...
      return;
      return;
 
 
    case 't':
    case 't':
      /* Search. This is not well defined in the manual and for now we don'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");
                fprintf(stderr,
 
                        "Warning: RSP 't' packet not supported: ignored\n");
      return;
      return;
 
 
    case 'T':
    case 'T':
      /* Is the thread alive. We are bare metal, so don't have a thread
      /* 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". */
Line 998... Line 1040...
      rsp_insert_matchpoint (p_buf);
      rsp_insert_matchpoint (p_buf);
      return;
      return;
 
 
    default:
    default:
      /* Unknown commands are ignored */
      /* Unknown commands are ignored */
      fprintf (stderr, "Warning: Unknown RSP request %s\n", p_buf->data);
                fprintf(stderr, "Warning: Unknown RSP request %s\n",
 
                        p_buf->data);
      return;
      return;
    }
    }
}       /* rsp_client_request () */
}       /* rsp_client_request () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Close the connection to the client if it is open                          */
/*!Close the connection to the client if it is open                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_client_close(void)
rsp_client_close (void)
 
{
 
  if (-1 != rsp.client_fd)
 
    {
    {
 
        if (-1 != rsp.client_fd) {
      close (rsp.client_fd);
      close (rsp.client_fd);
      rsp.client_fd = -1;
      rsp.client_fd = -1;
    }
    }
}       /* rsp_client_close () */
}       /* rsp_client_close () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Send a packet to the GDB client
/*!Send a packet to the GDB client
 
 
  Modeled on the stub version supplied with GDB. Put out the data preceded by
  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
  a '$', followed by a '#' and a one byte checksum. '$', '#', '*' and '}' are
  escaped by preceding them with '}' and then XORing the character with
  escaped by preceding them with '}' and then XORing the character with
  0x20.
  0x20.
 
 
  @param[in] p_buf  The data to send                                          */
  @param[in] p_buf  The data to send                                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void put_packet(struct rsp_buf *p_buf)
put_packet (struct rsp_buf *p_buf)
 
{
{
  unsigned char  data[GDB_BUF_MAX * 2];
  unsigned char  data[GDB_BUF_MAX * 2];
  int   len;
  int   len;
  int   ch;                             /* Ack char */
  int   ch;                             /* Ack char */
 
 
  /* Construct $<packet info>#<checksum>. Repeat until the GDB client
  /* Construct $<packet info>#<checksum>. Repeat until the GDB client
     acknowledges satisfactory receipt. */
     acknowledges satisfactory receipt. */
  do
        do {
    {
 
      unsigned char checksum = 0;        /* Computed checksum */
      unsigned char checksum = 0;        /* Computed checksum */
      int           count    = 0;        /* Index into the buffer */
      int           count    = 0;        /* Index into the buffer */
 
 
      if (DEBUG_GDB_DUMP_DATA){
      if (DEBUG_GDB_DUMP_DATA){
        printf ("Putting %s\n\n", p_buf->data);
        printf ("Putting %s\n\n", p_buf->data);
Line 1051... Line 1088...
 
 
      len = 0;
      len = 0;
      data[len++] =  '$';                       /* Start char */
      data[len++] =  '$';                       /* Start char */
 
 
      /* Body of the packet */
      /* Body of the packet */
      for (count = 0; count < p_buf->len; count++)
                for (count = 0; count < p_buf->len; count++) {
        {
 
          unsigned char  ch = p_buf->data[count];
          unsigned char  ch = p_buf->data[count];
 
 
          /* Check for escaped chars */
          /* Check for escaped chars */
          if (('$' == ch) || ('#' == ch) || ('*' == ch) || ('}' == ch))
                        if (('$' == ch) || ('#' == ch) || ('*' == ch)
            {
                            || ('}' == ch)) {
              ch       ^= 0x20;
              ch       ^= 0x20;
              checksum += (unsigned char)'}';
              checksum += (unsigned char)'}';
              data[len++] =  '}';
              data[len++] =  '}';
            }
            }
 
 
Line 1077... Line 1113...
 
 
      send_rsp_str ((unsigned char *) &data, len);
      send_rsp_str ((unsigned char *) &data, len);
 
 
      /* Check for ack of connection failure */
      /* Check for ack of connection failure */
      ch = get_rsp_char ();
      ch = get_rsp_char ();
      if (0 > ch)
                if (0 > ch) {
        {
 
          return;                       /* Fail the put silently. */
          return;                       /* Fail the put silently. */
        }
        }
    }
    }
  while ('+' != ch);
  while ('+' != ch);
 
 
}       /* put_packet () */
}       /* put_packet () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Convenience to put a constant string packet
/*!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
static void put_str_packet(const char *str)
put_str_packet (const char *str)
 
{
{
  struct rsp_buf  buffer;
  struct rsp_buf  buffer;
  int    len = strlen (str);
  int    len = strlen (str);
 
 
  /* Construct the packet to send, so long as string is not too big,
  /* Construct the packet to send, so long as string is not too big,
     otherwise truncate. Add EOS at the end for convenient debug printout */
     otherwise truncate. Add EOS at the end for convenient debug printout */
 
 
  if (len >= GDB_BUF_MAX)
        if (len >= GDB_BUF_MAX) {
    {
 
      fprintf (stderr, "Warning: String %s too large for RSP packet: "
      fprintf (stderr, "Warning: String %s too large for RSP packet: "
               "truncated\n", str);
               "truncated\n", str);
      len = GDB_BUF_MAX - 1;
      len = GDB_BUF_MAX - 1;
    }
    }
 
 
Line 1116... Line 1148...
 
 
  put_packet (&buffer);
  put_packet (&buffer);
 
 
}       /* put_str_packet () */
}       /* put_str_packet () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Get a packet from the GDB client
/*!Get a packet from the GDB client
 
 
  Modeled on the stub version supplied with GDB. The data is in a static
  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
  buffer. The data should be copied elsewhere if it is to be preserved across
Line 1131... Line 1162...
  for use with GDB 6.8 or later. Sequence numbers were removed from the RSP
  for use with GDB 6.8 or later. Sequence numbers were removed from the RSP
  standard at GDB 5.0.
  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 *
static struct rsp_buf *get_packet(void)
get_packet (void)
 
{
{
  static struct rsp_buf  buf;           /* Survives the return */
  static struct rsp_buf  buf;           /* Survives the return */
 
 
  /* Keep getting packets, until one is found with a valid checksum */
  /* Keep getting packets, until one is found with a valid checksum */
  while (1)
        while (1) {
    {
 
      unsigned char checksum;           /* The checksum we have computed */
      unsigned char checksum;           /* The checksum we have computed */
      int           count;                      /* Index into the buffer */
      int           count;                      /* Index into the buffer */
      int                       ch;                                     /* Current character */
      int                       ch;                                     /* Current character */
 
 
      /* Wait around for the start character ('$'). Ignore all other
      /* Wait around for the start character ('$'). Ignore all other
         characters */
         characters */
      ch = get_rsp_char ();
      ch = get_rsp_char ();
 
 
      while (ch != '$')
                while (ch != '$') {
        {
                        if (-1 == ch) {
          if (-1 == ch)
 
            {
 
              return  NULL;             /* Connection failed */
              return  NULL;             /* Connection failed */
            }
            }
 
 
          ch = get_rsp_char ();
          ch = get_rsp_char ();
 
 
Line 1162... Line 1189...
        }
        }
 
 
      /* Read until a '#' or end of buffer is found */
      /* Read until a '#' or end of buffer is found */
      checksum =  0;
      checksum =  0;
      count    =  0;
      count    =  0;
      while (count < GDB_BUF_MAX - 1)
                while (count < GDB_BUF_MAX - 1) {
        {
 
          ch = get_rsp_char ();
          ch = get_rsp_char ();
 
 
          if(rsp.client_waiting && DEBUG_GDB)
                        if (rsp.client_waiting && DEBUG_GDB) {
            {
 
              printf("%x\n",ch);
              printf("%x\n",ch);
            }
            }
 
 
 
 
          /* Check for connection failure */
          /* Check for connection failure */
          if (0 > ch)
                        if (0 > ch) {
            {
 
              return  NULL;
              return  NULL;
            }
            }
 
 
          /* If we hit a start of line char begin all over again */
          /* If we hit a start of line char begin all over again */
          if ('$' == ch)
                        if ('$' == ch) {
            {
 
              checksum =  0;
              checksum =  0;
              count    =  0;
              count    =  0;
 
 
              continue;
              continue;
            }
            }
 
 
          /* Break out if we get the end of line char */
          /* Break out if we get the end of line char */
          if ('#' == ch)
                        if ('#' == ch) {
            {
 
              break;
              break;
            }
            }
 
 
          /* Update the checksum and add the char to the buffer */
          /* Update the checksum and add the char to the buffer */
 
 
Line 1206... Line 1227...
         data to be valid strings. */
         data to be valid strings. */
      buf.data[count] = 0;
      buf.data[count] = 0;
      buf.len         = count;
      buf.len         = count;
 
 
      /* If we have a valid end of packet char, validate the checksum */
      /* If we have a valid end of packet char, validate the checksum */
      if ('#' == ch)
                if ('#' == ch) {
        {
 
          unsigned char  xmitcsum;      /* The checksum in the packet */
          unsigned char  xmitcsum;      /* The checksum in the packet */
 
 
          ch = get_rsp_char ();
          ch = get_rsp_char ();
          if (0 > ch)
                        if (0 > ch) {
            {
 
              return  NULL;             /* Connection failed */
              return  NULL;             /* Connection failed */
            }
            }
          xmitcsum = hex (ch) << 4;
          xmitcsum = hex (ch) << 4;
 
 
          ch = get_rsp_char ();
          ch = get_rsp_char ();
          if (0 > ch)
                        if (0 > ch) {
            {
 
              return  NULL;             /* Connection failed */
              return  NULL;             /* Connection failed */
            }
            }
 
 
          xmitcsum += hex (ch);
          xmitcsum += hex (ch);
 
 
          /* If the checksums don't match print a warning, and put the
          /* If the checksums don't match print a warning, and put the
             negative ack back to the client. Otherwise put a positive ack. */
             negative ack back to the client. Otherwise put a positive ack. */
          if (checksum != xmitcsum)
                        if (checksum != xmitcsum) {
            {
                                fprintf(stderr,
              fprintf (stderr, "Warning: Bad RSP checksum: Computed "
                                        "Warning: Bad RSP checksum: Computed "
                       "0x%02x, received 0x%02x\n", checksum, xmitcsum);
                                        "0x%02x, received 0x%02x\n", checksum,
 
                                        xmitcsum);
 
 
              ch = '-';
              ch = '-';
              send_rsp_str ((unsigned char *) &ch, 1);  /* Failed checksum */
              send_rsp_str ((unsigned char *) &ch, 1);  /* Failed checksum */
            }
                        } else {
          else
 
            {
 
              ch = '+';
              ch = '+';
              send_rsp_str ((unsigned char *) &ch, 1);  /* successful transfer */
              send_rsp_str ((unsigned char *) &ch, 1);  /* successful transfer */
              break;
              break;
            }
            }
        }
                } else {
      else
 
        {
 
          fprintf (stderr, "Warning: RSP packet overran buffer\n");
          fprintf (stderr, "Warning: RSP packet overran buffer\n");
        }
        }
    }
    }
  return &buf;                          /* Success */
  return &buf;                          /* Success */
}       /* get_packet () */
}       /* get_packet () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Put a single character out onto the client socket
/*!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
static void send_rsp_str(unsigned char *data, int len)
send_rsp_str (unsigned char *data, int len)
 
{
{
  if (-1 == rsp.client_fd)
        if (-1 == rsp.client_fd) {
    {
                fprintf(stderr,
      fprintf (stderr, "Warning: Attempt to write '%s' to unopened RSP "
                        "Warning: Attempt to write '%s' to unopened RSP "
               "client: Ignored\n", data);
               "client: Ignored\n", data);
      return;
      return;
    }
    }
 
 
  /* Write until successful (we retry after interrupts) or catastrophic
  /* Write until successful (we retry after interrupts) or catastrophic
     failure. */
     failure. */
  while (1)
        while (1) {
    {
                switch (write(rsp.client_fd, data, len)) {
      switch (write (rsp.client_fd, data, len))
 
        {
 
        case -1:
        case -1:
          /* Error: only allow interrupts or would block */
          /* Error: only allow interrupts or would block */
          if ((EAGAIN != errno) && (EINTR != errno))
                        if ((EAGAIN != errno) && (EINTR != errno)) {
            {
                                fprintf(stderr,
              fprintf (stderr, "Warning: Failed to write to RSP client: "
                                        "Warning: Failed to write to RSP client: "
                       "Closing client connection: %s\n",
                       "Closing client connection: %s\n",
                       strerror (errno));
                       strerror (errno));
              rsp_client_close ();
              rsp_client_close ();
              return;
              return;
            }
            }
Line 1296... Line 1307...
          return;               /* Success, we can return */
          return;               /* Success, we can return */
        }
        }
    }
    }
}       /* send_rsp_str () */
}       /* send_rsp_str () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Get a single character from the client socket
/*!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
static int get_rsp_char()
get_rsp_char ()
 
{
 
  if (-1 == rsp.client_fd)
 
    {
    {
 
        if (-1 == rsp.client_fd) {
      fprintf (stderr, "Warning: Attempt to read from unopened RSP "
      fprintf (stderr, "Warning: Attempt to read from unopened RSP "
               "client: Ignored\n");
               "client: Ignored\n");
      return  -1;
      return  -1;
    }
    }
 
 
  /* Non-blocking read until successful (we retry after interrupts) or
  /* Non-blocking read until successful (we retry after interrupts) or
     catastrophic failure. */
     catastrophic failure. */
  while (1)
        while (1) {
    {
 
      unsigned char  c;
      unsigned char  c;
 
 
      switch (read (rsp.client_fd, &c, sizeof (c)))
                switch (read(rsp.client_fd, &c, sizeof(c))) {
        {
 
        case -1:
        case -1:
          /* Error: only allow interrupts */
          /* Error: only allow interrupts */
          if ((EAGAIN != errno) && (EINTR != errno))
                        if ((EAGAIN != errno) && (EINTR != errno)) {
            {
                                fprintf(stderr,
              fprintf (stderr, "Warning: Failed to read from RSP client: "
                                        "Warning: Failed to read from RSP client: "
                       "Closing client connection: %s\n",
                       "Closing client connection: %s\n",
                       strerror (errno));
                       strerror (errno));
              rsp_client_close ();
              rsp_client_close ();
              return  -1;
              return  -1;
            }
            }
Line 1354... Line 1360...
   Useful for polling for ETX (0x3) chars being sent when GDB wants to
   Useful for polling for ETX (0x3) chars being sent when GDB wants to
   interrupt
   interrupt
 
 
   @return the char we peeked, 0 otherwise                                   */
   @return the char we peeked, 0 otherwise                                   */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static char
static char rsp_peek()
rsp_peek()
 
{
{
  /*
  /*
    if (-1 == rsp.client_fd)
    if (-1 == rsp.client_fd)
    {
    {
    fprintf (stderr, "Warning: Attempt to read from unopened RSP "
    fprintf (stderr, "Warning: Attempt to read from unopened RSP "
Line 1391... Line 1396...
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle an interrupt from GDB
/*!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
static void rsp_interrupt()
rsp_interrupt()
 
{
{
  unsigned char  c;
  unsigned char  c;
 
 
  if (read (rsp.client_fd, &c, sizeof (c)) <= 0)
        if (read(rsp.client_fd, &c, sizeof(c)) <= 0) {
    {
 
      // Had issues, just return
      // Had issues, just return
      return;
      return;
    }
    }
 
 
  // Ensure this is a ETX control char (0x3), currently, we only call this
  // Ensure this is a ETX control char (0x3), currently, we only call this
  // function when we've peeked and seen it, otherwise, ignore, return and pray
  // function when we've peeked and seen it, otherwise, ignore, return and pray
  // things go back to normal...
  // things go back to normal...
  if (c != 0x03)
        if (c != 0x03) {
    {
                printf
      printf("Warning: Interrupt character expected but not found on socket.\n");
                    ("Warning: Interrupt character expected but not found on socket.\n");
      return;
      return;
    }
    }
 
 
  // Otherwise, it's an interrupt packet, stall the processor, and upon return
  // Otherwise, it's an interrupt packet, stall the processor, and upon return
  // to the main handle_rsp() loop, it will inform GDB.
  // to the main handle_rsp() loop, it will inform GDB.
 
 
  if (DEBUG_GDB) printf("Interrupt received from GDB. Stalling processor.\n");
        if (DEBUG_GDB)
 
                printf("Interrupt received from GDB. Stalling processor.\n");
 
 
  set_stall_state (1);
  set_stall_state (1);
 
 
  // Send a stop reply response, manually set rsp.sigval to TARGET_SIGNAL_NONE
  // Send a stop reply response, manually set rsp.sigval to TARGET_SIGNAL_NONE
  rsp.sigval = TARGET_SIGNAL_NONE;
  rsp.sigval = TARGET_SIGNAL_NONE;
Line 1427... Line 1429...
 
 
  return;
  return;
 
 
}
}
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!"Unescape" RSP binary data
/*!"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.
 
 
Line 1440... Line 1441...
  @param[in] data  The array of bytes to convert
  @param[in] data  The array of bytes to convert
  @para[in]  len   The number of bytes to be converted
  @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
static int rsp_unescape(char *data, int len)
rsp_unescape (char *data,
 
              int   len)
 
{
{
  int  from_off = 0;             /* Offset to source char */
  int  from_off = 0;             /* Offset to source char */
  int  to_off   = 0;             /* Offset to dest char */
  int  to_off   = 0;             /* Offset to dest char */
 
 
  while (from_off < len)
        while (from_off < len) {
    {
 
      /* Is it escaped */
      /* Is it escaped */
      if ( '}' == data[from_off])
                if ('}' == data[from_off]) {
        {
 
          from_off++;
          from_off++;
          data[to_off] = data[from_off] ^ 0x20;
          data[to_off] = data[from_off] ^ 0x20;
        }
                } else {
      else
 
        {
 
          data[to_off] = data[from_off];
          data[to_off] = data[from_off];
        }
        }
 
 
      from_off++;
      from_off++;
      to_off++;
      to_off++;
Line 1468... Line 1463...
 
 
  return  to_off;
  return  to_off;
 
 
}       /* rsp_unescape () */
}       /* rsp_unescape () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Initialize the matchpoint hash table
/*!Initialize the matchpoint hash table
 
 
  This is an open hash table, so this function clears all the links to
  This is an open hash table, so this function clears all the links to
  NULL.                                                                     */
  NULL.                                                                     */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void mp_hash_init(void)
mp_hash_init (void)
 
{
{
  int  i;
  int  i;
 
 
  for (i = 0; i < MP_HASH_SIZE; i++)
        for (i = 0; i < MP_HASH_SIZE; i++) {
    {
 
      rsp.mp_hash[i] = NULL;
      rsp.mp_hash[i] = NULL;
    }
    }
}       /* mp_hash_init () */
}       /* mp_hash_init () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Add an entry to the matchpoint hash table
/*!Add an entry to the matchpoint hash table
 
 
  Add the entry if it wasn't already there. If it was there do nothing. The
  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
  match just be on type and addr. The instr need not match, since if this is
Line 1499... Line 1490...
 
 
  @param[in] type   The type of matchpoint
  @param[in] type   The type of matchpoint
  @param[in] addr   The address of the matchpoint
  @param[in] addr   The address of the matchpoint
  @para[in]  instr  The instruction to associate with the address           */
  @para[in]  instr  The instruction to associate with the address           */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void mp_hash_add(enum mp_type type, uint32_t addr, uint32_t instr)
mp_hash_add (enum mp_type type,
 
             uint32_t  addr,
 
             uint32_t  instr)
 
{
{
  int              hv    = addr % MP_HASH_SIZE;
  int              hv    = addr % MP_HASH_SIZE;
  struct mp_entry *curr;
  struct mp_entry *curr;
 
 
  /* See if we already have the entry */
  /* See if we already have the entry */
  for(curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
        for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) {
    {
                if ((type == curr->type) && (addr == curr->addr)) {
      if ((type == curr->type) && (addr == curr->addr))
 
        {
 
          return;               /* We already have the entry */
          return;               /* We already have the entry */
        }
        }
    }
    }
 
 
  /* Insert the new entry at the head of the chain */
  /* Insert the new entry at the head of the chain */
Line 1528... Line 1514...
 
 
  rsp.mp_hash[hv] = curr;
  rsp.mp_hash[hv] = curr;
 
 
}       /* mp_hash_add () */
}       /* mp_hash_add () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Look up an entry in the matchpoint hash table
/*!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.
 
 
Line 1545... Line 1530...
{
{
  int    hv = addr % MP_HASH_SIZE;
  int    hv = addr % MP_HASH_SIZE;
  struct mp_entry *curr;
  struct mp_entry *curr;
 
 
  /* Search */
  /* Search */
  for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
        for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) {
    {
                if ((type == curr->type) && (addr == curr->addr)) {
      if ((type == curr->type) && (addr == curr->addr))
 
        {
 
          return  curr;         /* The entry found */
          return  curr;         /* The entry found */
        }
        }
    }
    }
 
 
  /* Not found */
  /* Not found */
  return  NULL;
  return  NULL;
 
 
}       /* mp_hash_lookup () */
}       /* mp_hash_lookup () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Delete an entry from the matchpoint hash table
/*!Delete an entry from the matchpoint hash table
 
 
  If it is there the entry is deleted from the hash table. If it is not
  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.
  there, no action is taken. The match must be on type AND addr.
Line 1577... Line 1559...
  @param[in] type   The type of matchpoint
  @param[in] type   The type of matchpoint
  @param[in] addr   The address of the 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 *
static struct mp_entry *mp_hash_delete(enum mp_type type, uint32_t addr)
mp_hash_delete (enum mp_type       type,
 
                uint32_t  addr)
 
{
{
  int              hv   = addr % MP_HASH_SIZE;
  int              hv   = addr % MP_HASH_SIZE;
  struct mp_entry *prev = NULL;
  struct mp_entry *prev = NULL;
  struct mp_entry *curr;
  struct mp_entry *curr;
 
 
  /* Search */
  /* Search */
  for (curr  = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
        for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next) {
    {
                if ((type == curr->type) && (addr == curr->addr)) {
      if ((type == curr->type) && (addr == curr->addr))
 
        {
 
          /* Found - delete. Method depends on whether we are the head of
          /* Found - delete. Method depends on whether we are the head of
             chain. */
             chain. */
          if (NULL == prev)
                        if (NULL == prev) {
            {
 
              rsp.mp_hash[hv] = curr->next;
              rsp.mp_hash[hv] = curr->next;
            }
                        } else {
          else
 
            {
 
              prev->next = curr->next;
              prev->next = curr->next;
            }
            }
 
 
          return  curr;         /* The entry deleted */
          return  curr;         /* The entry deleted */
        }
        }
Line 1612... Line 1587...
  /* Not found */
  /* Not found */
  return  NULL;
  return  NULL;
 
 
}       /* mp_hash_delete () */
}       /* mp_hash_delete () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Utility to give the value of a hex char
/*!Utility to give the value of a hex char
 
 
  @param[in] ch  A character representing a hexadecimal digit. Done as -1,
  @param[in] ch  A character representing a hexadecimal digit. Done as -1,
  for consistency with other character routines, which can use
  for consistency with other character routines, which can use
Line 1631... Line 1605...
    ((c >= '0') && (c <= '9')) ? c - '0' :
    ((c >= '0') && (c <= '9')) ? c - '0' :
    ((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : -1;
    ((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : -1;
 
 
}       /* hex () */
}       /* hex () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Convert a register to a hex digit string
/*!Convert a register to a hex digit string
 
 
  The supplied 32-bit value is converted to an 8 digit hex string according
  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 target endianism. It is null terminated for convenient printing.
 
 
  @param[in]  val  The value to convert
  @param[in]  val  The value to convert
  @param[out] p_buf  The buffer for the text string                           */
  @param[out] p_buf  The buffer for the text string                           */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void reg2hex(uint32_t val, char *p_buf)
reg2hex (uint32_t  val, char *p_buf)
 
{
{
  int  n;                       /* Counter for digits */
  int  n;                       /* Counter for digits */
  int  nyb_shift;
  int  nyb_shift;
 
 
  for (n = 0; n < 8; n++)
        for (n = 0; n < 8; n++) {
    {
 
#ifdef WORDSBIGENDIAN
#ifdef WORDSBIGENDIAN
      if(n%2==0){
                if (n % 2 == 0) {
        nyb_shift = n * 4 + 4;
        nyb_shift = n * 4 + 4;
      }
                } else {
      else{
 
        nyb_shift = n * 4 - 4;
        nyb_shift = n * 4 - 4;
      }
      }
#else
#else
      nyb_shift = 28 - (n * 4);
      nyb_shift = 28 - (n * 4);
#endif
#endif
Line 1666... Line 1636...
 
 
  p_buf[8] = 0;                  /* Useful to terminate as string */
  p_buf[8] = 0;                  /* Useful to terminate as string */
 
 
}       /* reg2hex () */
}       /* reg2hex () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Convert a hex digit string to a register value
/*!Convert a hex digit string to a register value
 
 
  The supplied 8 digit hex string is converted to a 32-bit value according
  The supplied 8 digit hex string is converted to a 32-bit value according
  the target endianism
  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
static uint32_t hex2reg(char *p_buf)
hex2reg (char *p_buf)
 
{
{
  int                n;         /* Counter for digits */
  int                n;         /* Counter for digits */
  uint32_t  val = 0;     /* The result */
  uint32_t  val = 0;     /* The result */
 
 
  for (n = 0; n < 8; n++)
        for (n = 0; n < 8; n++) {
    {
 
#ifdef WORDSBIGENDIAN
#ifdef WORDSBIGENDIAN
      int  nyb_shift = n * 4;
      int  nyb_shift = n * 4;
#else
#else
      int  nyb_shift = 28 - (n * 4);
      int  nyb_shift = 28 - (n * 4);
#endif
#endif
Line 1697... Line 1664...
 
 
  return val;
  return val;
 
 
}       /* hex2reg () */
}       /* hex2reg () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Convert an ASCII character string to pairs of hex digits
/*!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[out] dest  Buffer to store the hex digit pairs (null terminated)
  @param[in]  src   The ASCII string (null terminated)                      */
  @param[in]  src   The ASCII string (null terminated)                      */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void  ascii2hex (char *dest,
static void ascii2hex(char *dest, char *src)
                        char *src)
 
{
{
  int  i;
  int  i;
 
 
  /* Step through converting the source string */
  /* Step through converting the source string */
  for (i = 0; src[i] != '\0'; i++)
        for (i = 0; src[i] != '\0'; i++) {
    {
 
      char  ch = src[i];
      char  ch = src[i];
 
 
      dest[i * 2]     = hexchars[ch >> 4 & 0xf];
      dest[i * 2]     = hexchars[ch >> 4 & 0xf];
      dest[i * 2 + 1] = hexchars[ch      & 0xf];
      dest[i * 2 + 1] = hexchars[ch      & 0xf];
    }
    }
 
 
  dest[i * 2] = '\0';
  dest[i * 2] = '\0';
 
 
}       /* ascii2hex () */
}       /* ascii2hex () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Convert pairs of hex digits to an ASCII character string
/*!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[out] dest  The ASCII string (null terminated)
  @param[in]  src   Buffer holding the hex digit pairs (null terminated)    */
  @param[in]  src   Buffer holding the hex digit pairs (null terminated)    */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void  hex2ascii (char *dest,
static void hex2ascii(char *dest, char *src)
                        char *src)
 
{
{
  int  i;
  int  i;
 
 
  /* Step through convering the source hex digit pairs */
  /* Step through convering the source hex digit pairs */
  for (i = 0; src[i * 2] != '\0' && src[i * 2 + 1] != '\0'; i++)
        for (i = 0; src[i * 2] != '\0' && src[i * 2 + 1] != '\0'; i++) {
    {
                dest[i] =
      dest[i] = ((hex (src[i * 2]) & 0xf) << 4) | (hex (src[i * 2 + 1]) & 0xf);
                    ((hex(src[i * 2]) & 0xf) << 4) | (hex(src[i * 2 + 1]) &
 
                                                      0xf);
    }
    }
 
 
  dest[i] = '\0';
  dest[i] = '\0';
 
 
}       /* hex2ascii () */
}       /* hex2ascii () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Set the program counter
/*!Set the program counter
 
 
  This sets the value in the NPC SPR. Not completely trivial, since this is
  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
  actually cached in cpu_state.pc. Any reset of the NPC also involves
Line 1761... Line 1723...
  Only actually do this if the requested address is different to the current
  Only actually do this if the requested address is different to the current
  NPC (avoids clearing the delay pipe).
  NPC (avoids clearing the delay pipe).
 
 
  @param[in] addr  The address to use                                       */
  @param[in] addr  The address to use                                       */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void set_npc(uint32_t addr)
set_npc (uint32_t  addr)
 
{
{
 
 
  // First set the chain 
  // First set the chain 
  gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
  gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
 
 
 
        if (addr != get_npc()) {
  if (addr != get_npc())
 
    {
 
 
 
      gdb_write_reg(NPC_CPU_REG_ADD, addr);
      gdb_write_reg(NPC_CPU_REG_ADD, addr);
 
 
      if (STALLED == stallState)
                if (STALLED == stallState) {
        {
                        if (DEBUG_GDB)
          if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written and locally cached \n", addr);
                                printf
 
                                    ("set_npc(): New NPC value (0x%08x) written and locally cached \n",
 
                                     addr);
          npcCachedValue = addr;
          npcCachedValue = addr;
          npcIsCached = 1;
          npcIsCached = 1;
        }
                } else {
      else
                        if (DEBUG_GDB)
        {
                                printf
          if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written \n", addr);
                                    ("set_npc(): New NPC value (0x%08x) written \n",
 
                                     addr);
          npcIsCached = 0;
          npcIsCached = 0;
        }
        }
 
 
 
        } else
    }
 
  else
 
    return;
    return;
 
 
 
 
}       /* set_npc () */
}       /* set_npc () */
 
 
 
 
//! Read the value of the Next Program Counter (a SPR)
//! Read the value of the Next Program Counter (a SPR)
 
 
//! Setting the NPC flushes the pipeline, so subsequent reads will return
//! Setting the NPC flushes the pipeline, so subsequent reads will return
//! zero until the processor has refilled the pipeline. This will not be
//! zero until the processor has refilled the pipeline. This will not be
//! happening if the processor is stalled (as it is when GDB had control),
//! happening if the processor is stalled (as it is when GDB had control),
Line 1812... Line 1770...
//! @return  The value of the NPC
//! @return  The value of the NPC
static uint32_t get_npc ()
static uint32_t get_npc ()
{
{
  uint32_t current_npc;
  uint32_t current_npc;
 
 
  if (STALLED == stallState)
        if (STALLED == stallState) {
    {
                if (npcIsCached == 0) {
      if (npcIsCached == 0)
 
        {
 
          err = gdb_set_chain(SC_RISC_DEBUG);
          err = gdb_set_chain(SC_RISC_DEBUG);
          err = gdb_read_reg(NPC_CPU_REG_ADD, &npcCachedValue);
          err = gdb_read_reg(NPC_CPU_REG_ADD, &npcCachedValue);
          if(err > 0){
          if(err > 0){
            printf("Error %d reading NPC\n", err);
            printf("Error %d reading NPC\n", err);
            rsp_client_close ();
            rsp_client_close ();
            return 0;
            return 0;
          }
          }
          if (DEBUG_GDB) printf("get_npc(): caching newly read NPC value (0x%08x)\n",npcCachedValue);
                        if (DEBUG_GDB)
 
                                printf
 
                                    ("get_npc(): caching newly read NPC value (0x%08x)\n",
 
                                     npcCachedValue);
 
 
          npcIsCached    = 1;
          npcIsCached    = 1;
        }
                } else if (DEBUG_GDB)
      else
                        printf("get_npc(): reading cached NPC value (0x%08x)\n",
        if (DEBUG_GDB) printf("get_npc(): reading cached NPC value (0x%08x)\n",npcCachedValue);
                               npcCachedValue);
 
 
      return  npcCachedValue;
      return  npcCachedValue;
    }
        } else {
  else
 
    {
 
      err = gdb_read_reg(NPC_CPU_REG_ADD, &current_npc);
      err = gdb_read_reg(NPC_CPU_REG_ADD, &current_npc);
      if(err > 0){
      if(err > 0){
        printf("Error %d reading NPC\n", err);
        printf("Error %d reading NPC\n", err);
        rsp_client_close ();
        rsp_client_close ();
        return 0;
        return 0;
Line 1846... Line 1802...
      return current_npc;
      return current_npc;
 
 
    }
    }
}       // get_npc ()
}       // get_npc ()
 
 
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Send a packet acknowledging an exception has occurred
/*!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
static void rsp_report_exception(void)
rsp_report_exception (void)
 
{
{
  struct rsp_buf  buffer;
  struct rsp_buf  buffer;
 
 
  /* Construct a signal received packet */
  /* Construct a signal received packet */
  buffer.data[0] = 'S';
  buffer.data[0] = 'S';
Line 1869... Line 1822...
 
 
  put_packet (&buffer);
  put_packet (&buffer);
 
 
}       /* rsp_report_exception () */
}       /* rsp_report_exception () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP continue request
/*!Handle a RSP continue request
 
 
  Parse the command to see if there is an address. Uses the underlying
  Parse the command to see if there is an address. Uses the underlying
  generic continue function, with EXCEPT_NONE.
  generic continue function, with EXCEPT_NONE.
 
 
  @param[in] p_buf  The full continue packet                                  */
  @param[in] p_buf  The full continue packet                                  */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_continue(struct rsp_buf *p_buf)
rsp_continue (struct rsp_buf *p_buf)
 
{
{
  uint32_t  addr;               /* Address to continue from, if any */
  uint32_t  addr;               /* Address to continue from, if any */
 
 
  // First set the chain 
  // First set the chain 
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
 
 
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  if(err > 0){
  if(err > 0){
    printf("Error %d to set RISC Debug Interface chain in the CONTINUE command 'c'\n", err);
                printf
 
                    ("Error %d to set RISC Debug Interface chain in the CONTINUE command 'c'\n",
 
                     err);
    rsp_client_close ();
    rsp_client_close ();
    return;
    return;
  }
  }
 
 
  if (0 == strcmp ("c", p_buf->data))
        if (0 == strcmp("c", p_buf->data)) {
    {
 
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
      /* ---------- NPC ---------- */
      /* ---------- NPC ---------- */
      addr = get_npc();
      addr = get_npc();
    }
        } else if (1 != sscanf(p_buf->data, "c%x", &addr)) {
  else if (1 != sscanf (p_buf->data, "c%x", &addr))
 
    {
 
      fprintf (stderr,
      fprintf (stderr,
               "Warning: RSP continue address %s not recognized: ignored\n",
               "Warning: RSP continue address %s not recognized: ignored\n",
               p_buf->data);
               p_buf->data);
 
 
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
      /* ---------- NPC ---------- */
      /* ---------- NPC ---------- */
      addr = get_npc();
      addr = get_npc();
    }
    }
 
 
  if (DEBUG_GDB) printf("rsp_continue() --> Read NPC = 0x%08x\n", addr);
        if (DEBUG_GDB)
 
                printf("rsp_continue() --> Read NPC = 0x%08x\n", addr);
 
 
  rsp_continue_generic (addr, EXCEPT_NONE);
  rsp_continue_generic (addr, EXCEPT_NONE);
 
 
}       /* rsp_continue () */
}       /* rsp_continue () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP continue with signal request
/*!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
static void rsp_continue_with_signal(struct rsp_buf *p_buf)
rsp_continue_with_signal (struct rsp_buf *p_buf)
 
{
{
  printf ("RSP continue with signal '%s' received, signal ignored\n", p_buf->data);
        printf("RSP continue with signal '%s' received, signal ignored\n",
 
               p_buf->data);
  rsp_continue (p_buf);
  rsp_continue (p_buf);
 
 
}       /* rsp_continue_with_signal () */
}       /* rsp_continue_with_signal () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Generic processing of a continue request
/*!Generic processing of a continue request
 
 
  The signal may be EXCEPT_NONE if there is no exception to be
  The signal may be EXCEPT_NONE if there is no exception to be
  handled. Currently the exception is ignored.
  handled. Currently the exception is ignored.
Line 1947... Line 1896...
  processor is unstalled.
  processor is unstalled.
 
 
  @param[in] addr    Address from which to step
  @param[in] addr    Address from which to step
  @param[in] except  The exception to use (if any)                          */
  @param[in] except  The exception to use (if any)                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_continue_generic(uint32_t addr, uint32_t except)
rsp_continue_generic (uint32_t  addr,
 
                      uint32_t  except)
 
{
{
  uint32_t              temp_uint32;
  uint32_t              temp_uint32;
 
 
  /* Set the address as the value of the next program counter */
  /* Set the address as the value of the next program counter */
  set_npc (addr);
  set_npc (addr);
 
 
  /* Clear Debug Reason Register (DRR) 0x3015 */
  /* Clear Debug Reason Register (DRR) 0x3015 */
  // Arc sim --> cpu_state.sprs[SPR_DRR]   = 0;
  // Arc sim --> cpu_state.sprs[SPR_DRR]   = 0;
  if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n");
        if (gdb_write_reg(DRR_CPU_REG_ADD, 0))
 
                printf("Error write to DRR register\n");
 
 
  /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
  /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
  // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
  // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
  if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n");
        if (gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32))
 
                printf("Error read from DMR2 register\n");
  temp_uint32 &= ~SPR_DMR2_WGB;
  temp_uint32 &= ~SPR_DMR2_WGB;
  if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n");
        if (gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32))
 
                printf("Error write to DMR2 register\n");
 
 
  /* Clear the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
  /* Clear the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
  // Arc sim --> cpu_state.sprs[SPR_DMR1] &= ~SPR_DMR1_ST;
  // Arc sim --> cpu_state.sprs[SPR_DMR1] &= ~SPR_DMR1_ST;
  if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n");
        if (gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32))
 
                printf("Error read from DMR1 register\n");
  temp_uint32 &= ~SPR_DMR1_ST;
  temp_uint32 &= ~SPR_DMR1_ST;
  if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n");
        if (gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32))
 
                printf("Error write to DMR1 register\n");
 
 
  /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
  /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
  // Arc sim --> cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
  // Arc sim --> cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
  if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n");
        if (gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32))
 
                printf("Error read from DSR register\n");
  temp_uint32 |= SPR_DSR_TE;
  temp_uint32 |= SPR_DSR_TE;
  if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n");
        if (gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32))
 
                printf("Error write to DSR register\n");
 
 
  /* Unstall the processor */
  /* Unstall the processor */
  set_stall_state (0);
  set_stall_state (0);
 
 
  /* Note the GDB client is now waiting for a reply. */
  /* Note the GDB client is now waiting for a reply. */
  rsp.client_waiting = 1;
  rsp.client_waiting = 1;
 
 
}       /* rsp_continue_generic () */
}       /* rsp_continue_generic () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP read all registers request
/*!Handle a RSP read all registers request
 
 
  The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
  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
  (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.
  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
static void rsp_read_all_regs(void)
rsp_read_all_regs (void)
 
{
{
  struct rsp_buf  buffer;                       /* Buffer for the reply */
  struct rsp_buf  buffer;                       /* Buffer for the reply */
  int             r;                            /* Register index */
  int             r;                            /* Register index */
  uint32_t   temp_uint32;
  uint32_t   temp_uint32;
 
 
Line 2009... Line 1961...
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // First set the chain 
  // First set the chain 
  gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
  gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
 
 
 
 
  // Read all GPRs
  // Read all GPRs
  for (r = 0; r < MAX_GPRS; r++){
  for (r = 0; r < MAX_GPRS; r++){
 
 
    err = gdb_read_reg(0x400 + r, &temp_uint32);
    err = gdb_read_reg(0x400 + r, &temp_uint32);
    if(err > 0){
    if(err > 0){
      if (DEBUG_GDB) printf("Error %d in gdb_read_reg at reg. %d\n", err, r);
                        if (DEBUG_GDB)
 
                                printf("Error %d in gdb_read_reg at reg. %d\n",
 
                                       err, r);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
    reg2hex (temp_uint32, &(buffer.data[r * 8]));
    reg2hex (temp_uint32, &(buffer.data[r * 8]));
 
 
    if (DEBUG_GDB_DUMP_DATA){
    if (DEBUG_GDB_DUMP_DATA){
      switch(r % 4)
                        switch (r % 4) {
        {
 
        case 0:
        case 0:
          printf("gpr%02d   0x%08x  ", r, temp_uint32);
          printf("gpr%02d   0x%08x  ", r, temp_uint32);
          break;
          break;
        case 1:
        case 1:
        case 2:
        case 2:
Line 2043... Line 1995...
 
 
  }
  }
  /* ---------- PPC ---------- */
  /* ---------- PPC ---------- */
  err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
  err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
  if(err > 0){
  if(err > 0){
    if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> PPC\n", err);
                if (DEBUG_GDB)
 
                        printf("Error %d in gdb_read_reg read --> PPC\n", err);
    put_str_packet ("E01");
    put_str_packet ("E01");
    return;
    return;
  }
  }
  reg2hex (temp_uint32, &(buffer.data[PPC_REGNUM * 8]));
  reg2hex (temp_uint32, &(buffer.data[PPC_REGNUM * 8]));
  if (DEBUG_GDB_DUMP_DATA)      printf("PPC     0x%08x\n", temp_uint32);
        if (DEBUG_GDB_DUMP_DATA)
 
                printf("PPC     0x%08x\n", temp_uint32);
  /* ---------- NPC ---------- */
  /* ---------- NPC ---------- */
  temp_uint32 = get_npc();
  temp_uint32 = get_npc();
  /*
  /*
    err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
    err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
    if(err > 0){
    if(err > 0){
Line 2060... Line 2014...
    put_str_packet ("E01");
    put_str_packet ("E01");
    return;
    return;
    }
    }
  */
  */
  reg2hex (temp_uint32, &(buffer.data[NPC_REGNUM * 8]));
  reg2hex (temp_uint32, &(buffer.data[NPC_REGNUM * 8]));
  if (DEBUG_GDB_DUMP_DATA)      printf("NPC     0x%08x\n", temp_uint32);
        if (DEBUG_GDB_DUMP_DATA)
 
                printf("NPC     0x%08x\n", temp_uint32);
  /* ---------- SR ---------- */
  /* ---------- SR ---------- */
  err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
  err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
  if(err > 0){
  if(err > 0){
    if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> SP\n", err);
                if (DEBUG_GDB)
 
                        printf("Error %d in gdb_read_reg read --> SP\n", err);
    put_str_packet ("E01");
    put_str_packet ("E01");
    return;
    return;
  }
  }
  reg2hex (temp_uint32, &(buffer.data[SR_REGNUM * 8]));
  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 */
  /* Finalize the packet and send it */
  buffer.data[NUM_REGS * 8] = 0;
  buffer.data[NUM_REGS * 8] = 0;
  buffer.len                = NUM_REGS * 8;
  buffer.len                = NUM_REGS * 8;
 
 
  put_packet (&buffer);
  put_packet (&buffer);
  return;
  return;
}       /* rsp_read_all_regs () */
}       /* rsp_read_all_regs () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP write all registers request
/*!Handle a RSP write all registers request
 
 
  The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
  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
  (i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is
Line 2095... Line 2051...
  warning message, but there is no other check that the right amount
  warning message, but there is no other check that the right amount
  of data is present. The result is always "OK".
  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
static void rsp_write_all_regs(struct rsp_buf *p_buf)
rsp_write_all_regs (struct rsp_buf *p_buf)
 
{
{
  uint32_t  regnum;                             /* Register index */
  uint32_t  regnum;                             /* Register index */
  // char          valstr[9];           /* Allow for EOS on the string */
  // char          valstr[9];           /* Allow for EOS on the string */
 
 
  // /* Check for valid data */
  // /* Check for valid data */
Line 2116... Line 2071...
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // First set the chain 
  // First set the chain 
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  if(err > 0){
  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");
    put_str_packet ("E01");
    return;
    return;
  }
  }
 
 
  /* ---------- GPRS ---------- */
  /* ---------- GPRS ---------- */
  for (regnum = 0; regnum < MAX_GPRS; regnum++)
        for (regnum = 0; regnum < MAX_GPRS; regnum++) {
    {
                err =
      err = gdb_write_reg(0x400 + regnum, hex2reg (&p_buf->data[regnum * 8 + 1]));
                    gdb_write_reg(0x400 + regnum,
 
                                  hex2reg(&p_buf->data[regnum * 8 + 1]));
      if(err > 0){
      if(err > 0){
        if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err);
                        if (DEBUG_GDB)
 
                                printf
 
                                    ("Error %d in rsp_write_reg write --> GPRS\n",
 
                                     err);
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
      }
      }
    }
    }
 
 
  /* ---------- PPC ---------- */
  /* ---------- PPC ---------- */
  err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (&p_buf->data[PPC_REGNUM * 8 + 1]));
        err =
 
            gdb_write_reg(PPC_CPU_REG_ADD,
 
                          hex2reg(&p_buf->data[PPC_REGNUM * 8 + 1]));
  if(err > 0){
  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");
    put_str_packet ("E01");
    return;
    return;
  }
  }
  /* ---------- SR ---------- */
  /* ---------- SR ---------- */
  err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (&p_buf->data[SR_REGNUM * 8 + 1]));
        err =
 
            gdb_write_reg(SR_CPU_REG_ADD,
 
                          hex2reg(&p_buf->data[SR_REGNUM * 8 + 1]));
  if(err > 0){
  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");
    put_str_packet ("E01");
    return;
    return;
  }
  }
  /* ---------- NPC ---------- */
  /* ---------- NPC ---------- */
  set_npc(hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
  set_npc(hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
Line 2161... Line 2128...
  /* Acknowledge. TODO: We always succeed at present, even if the data was
  /* Acknowledge. TODO: We always succeed at present, even if the data was
     defective. */
     defective. */
  put_str_packet ("OK");
  put_str_packet ("OK");
}       /* rsp_write_all_regs () */
}       /* rsp_write_all_regs () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Handle a RSP read memory (symbolic) request
/* Handle a RSP read memory (symbolic) request
 
 
   Syntax is:
   Syntax is:
 
 
Line 2193... Line 2159...
  /* Couple of temps we might need when doing aligning/leftover accesses */
  /* Couple of temps we might need when doing aligning/leftover accesses */
  uint32_t tmp_word;
  uint32_t tmp_word;
  uint8_t tmp_byte;
  uint8_t tmp_byte;
  char *tmp_word_ptr = (char*) &tmp_word;
  char *tmp_word_ptr = (char*) &tmp_word;
 
 
 
        if (2 != sscanf(p_buf->data, "m%x,%x:", &addr, &len)) {
 
 
  if (2 != sscanf (p_buf->data, "m%x,%x:", &addr, &len))
 
    {
 
      fprintf (stderr, "Warning: Failed to recognize RSP read memory "
      fprintf (stderr, "Warning: Failed to recognize RSP read memory "
               "command: %s\n", p_buf->data);
               "command: %s\n", p_buf->data);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  /* Make sure we won't overflow the buffer (2 chars per byte) */
  /* Make sure we won't overflow the buffer (2 chars per byte) */
  if ((len * 2) >= GDB_BUF_MAX_TIMES_TWO)
        if ((len * 2) >= GDB_BUF_MAX_TIMES_TWO) {
    {
                fprintf(stderr,
      fprintf (stderr, "Warning: Memory read %s too large for RSP packet: "
                        "Warning: Memory read %s too large for RSP packet: "
               "truncated\n", p_buf->data);
               "truncated\n", p_buf->data);
      len = (GDB_BUF_MAX - 1) / 2;
      len = (GDB_BUF_MAX - 1) / 2;
    }
    }
 
 
  if(!(rec_buf = (char*)malloc(len))) {
  if(!(rec_buf = (char*)malloc(len))) {
    put_str_packet ("E01");
    put_str_packet ("E01");
    return;
    return;
  }
  }
 
 
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // Set chain 5 --> Wishbone Memory chain
  // Set chain 5 --> Wishbone Memory chain
  err = gdb_set_chain(SC_WISHBONE);
  err = gdb_set_chain(SC_WISHBONE);
  if(err){
  if(err){
    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");
    put_str_packet ("E01");
    return;
    return;
  }
  }
 
 
  len_cpy = len;
  len_cpy = len;
Line 2238... Line 2201...
      int num_bytes_to_align = bytes_per_word - (addr & 0x3);
      int num_bytes_to_align = bytes_per_word - (addr & 0x3);
 
 
      int bytes_to_read = (num_bytes_to_align >= len_cpy) ?
      int bytes_to_read = (num_bytes_to_align >= len_cpy) ?
        len_cpy : num_bytes_to_align;
        len_cpy : num_bytes_to_align;
 
 
      for (i=0;i<bytes_to_read;i++)
                for (i = 0; i < bytes_to_read; i++) {
        {
 
          err = gdb_read_byte(addr++, (uint8_t*) &rec_buf[i]);
          err = gdb_read_byte(addr++, (uint8_t*) &rec_buf[i]);
          if(err){
          if(err){
            put_str_packet ("E01");
            put_str_packet ("E01");
            return;
            return;
          }
          }
Line 2255... Line 2217...
    }
    }
 
 
  if (len_cpy/bytes_per_word) // Now perform all full word accesses
  if (len_cpy/bytes_per_word) // Now perform all full word accesses
    {
    {
      int words_to_read = len_cpy/bytes_per_word; // Full words to read
      int words_to_read = len_cpy/bytes_per_word; // Full words to read
      if (DEBUG_GDB) printf("rsp_read_mem: reading %d words from 0x%.8x\n",
                if (DEBUG_GDB)
 
                        printf("rsp_read_mem: reading %d words from 0x%.8x\n",
                            words_to_read, addr);
                            words_to_read, addr);
      // Read full data words from Wishbone Memory chain
      // Read full data words from Wishbone Memory chain
      err = gdb_read_block(addr, (uint32_t*)rec_buf_ptr,
      err = gdb_read_block(addr, (uint32_t*)rec_buf_ptr,
                           words_to_read*bytes_per_word);
                           words_to_read*bytes_per_word);
 
 
      if(err){
      if(err){
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
      }
      }
 
 
      // Adjust our status
      // Adjust our status
      len_cpy -= (words_to_read*bytes_per_word);
      len_cpy -= (words_to_read*bytes_per_word);
      addr += (words_to_read*bytes_per_word);
      addr += (words_to_read*bytes_per_word);
      rec_buf_ptr += (words_to_read*bytes_per_word);
      rec_buf_ptr += (words_to_read*bytes_per_word);
    }
    }
  if (len_cpy) // Leftover bytes
  if (len_cpy) // Leftover bytes
    {
    {
      for (i=0;i<len_cpy;i++)
                for (i = 0; i < len_cpy; i++) {
        {
                        err =
          err = gdb_read_byte(addr++, (uint8_t*) &rec_buf_ptr[i]);
                            gdb_read_byte(addr++, (uint8_t *) & rec_buf_ptr[i]);
          if(err){
          if(err){
            put_str_packet ("E01");
            put_str_packet ("E01");
            return;
            return;
          }
          }
        }
        }
Line 2291... Line 2253...
    ;
    ;
    p_buf->data[(2*off)] = hexchars[((rec_buf[off]&0xf0)>>4)];
    p_buf->data[(2*off)] = hexchars[((rec_buf[off]&0xf0)>>4)];
    p_buf->data[(2*off)+1] = hexchars[(rec_buf[off]&0x0f)];
    p_buf->data[(2*off)+1] = hexchars[(rec_buf[off]&0x0f)];
  }
  }
 
 
  if (DEBUG_GDB && (err > 0)) printf("\nError %x\n", err);fflush (stdout);
        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->data[off * 2] = 0;                      /* End of string */
  p_buf->len           = strlen (p_buf->data);
  p_buf->len           = strlen (p_buf->data);
  if (DEBUG_GDB_BLOCK_DATA){
  if (DEBUG_GDB_BLOCK_DATA){
    printf("rsp_read_mem: adr 0x%.8x data: ", addr);
    printf("rsp_read_mem: adr 0x%.8x data: ", addr);
Line 2306... Line 2270...
 
 
  put_packet (p_buf);
  put_packet (p_buf);
 
 
}       /* rsp_read_mem () */
}       /* rsp_read_mem () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP write memory (symbolic) request  ("M")
/*!Handle a RSP write memory (symbolic) request  ("M")
 
 
  Syntax is:
  Syntax is:
 
 
Line 2329... Line 2292...
 
 
  @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
static void rsp_write_mem(struct rsp_buf *p_buf)
rsp_write_mem (struct rsp_buf *p_buf)
 
{
{
  unsigned int    addr;                 /* Where to write the memory */
  unsigned int    addr;                 /* Where to write the memory */
  int             len;                  /* Number of bytes to write */
  int             len;                  /* Number of bytes to write */
  char           *symdat;               /* Pointer to the symboli data */
  char           *symdat;               /* Pointer to the symboli data */
  int             datlen;               /* Number of digits in symbolic data */
  int             datlen;               /* Number of digits in symbolic data */
  int             off;                  /* Offset into the memory */
  int             off;                  /* Offset into the memory */
  int             nibc;                 /* Nibbel counter */
  int             nibc;                 /* Nibbel counter */
  uint32_t   val;
  uint32_t   val;
 
 
  if (2 != sscanf (p_buf->data, "M%x,%x:", &addr, &len))
        if (2 != sscanf(p_buf->data, "M%x,%x:", &addr, &len)) {
    {
 
      fprintf (stderr, "Warning: Failed to recognize RSP write memory "
      fprintf (stderr, "Warning: Failed to recognize RSP write memory "
               "command: %s\n", p_buf->data);
               "command: %s\n", p_buf->data);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  /* Find the start of the data and check there is the amount we expect. */
  /* 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;
        symdat =
 
            (char *)memchr((const void *)p_buf->data, ':', GDB_BUF_MAX) + 1;
  datlen = p_buf->len - (symdat - p_buf->data);
  datlen = p_buf->len - (symdat - p_buf->data);
 
 
  /* Sanity check */
  /* Sanity check */
  if (len * 2 != datlen)
        if (len * 2 != datlen) {
    {
                fprintf(stderr,
      fprintf (stderr, "Warning: Write of %d digits requested, but %d digits "
                        "Warning: Write of %d digits requested, but %d digits "
               "supplied: packet ignored\n", len * 2, datlen );
               "supplied: packet ignored\n", len * 2, datlen );
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
 
 
  // Set chain 5 --> Wishbone Memory chain
  // Set chain 5 --> Wishbone Memory chain
  err = gdb_set_chain(SC_WISHBONE);
  err = gdb_set_chain(SC_WISHBONE);
  if(err){
  if(err){
    put_str_packet ("E01");
    put_str_packet ("E01");
    return;
    return;
  }
  }
 
 
  val = 0;
  val = 0;
  off = 0;
  off = 0;
  /* Write the bytes to memory */
  /* Write the bytes to memory */
  for (nibc = 0; nibc < datlen; nibc++)
        for (nibc = 0; nibc < datlen; nibc++) {
    {
 
      val |= 0x0000000f & hex (symdat[nibc]);
      val |= 0x0000000f & hex (symdat[nibc]);
      if(nibc % 8 == 7){
      if(nibc % 8 == 7){
        err = gdb_write_block(addr + off, &val, 4);
        err = gdb_write_block(addr + off, &val, 4);
        if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout);
                        if (DEBUG_GDB)
 
                                printf("Error %x\n", err);
 
                        fflush(stdout);
        if(err){
        if(err){
          put_str_packet ("E01");
          put_str_packet ("E01");
          return;
          return;
        }
        }
        val = 0;
        val = 0;
Line 2393... Line 2354...
      val <<= 4;
      val <<= 4;
    }
    }
  put_str_packet ("OK");
  put_str_packet ("OK");
}       /* rsp_write_mem () */
}       /* rsp_write_mem () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Read a single register
/*!Read a single register
 
 
  The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
  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
  (i.e. SPR NPC) and SR (i.e. SPR SR). The register is returned as a
Line 2405... Line 2365...
 
 
  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
static void rsp_read_reg(struct rsp_buf *p_buf)
rsp_read_reg (struct rsp_buf *p_buf)
 
{
{
  unsigned int          regnum;
  unsigned int          regnum;
  uint32_t      temp_uint32;
  uint32_t      temp_uint32;
 
 
  /* Break out the fields from the data */
  /* Break out the fields from the data */
  if (1 != sscanf (p_buf->data, "p%x", &regnum))
        if (1 != sscanf(p_buf->data, "p%x", &regnum)) {
    {
                fprintf(stderr,
      fprintf (stderr, "Warning: Failed to recognize RSP read register "
                        "Warning: Failed to recognize RSP read register "
               "command: %s\n", p_buf->data);
               "command: %s\n", p_buf->data);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // First set the chain 
  // First set the chain 
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  if(err > 0){
  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");
    put_str_packet ("E01");
    return;
    return;
  }
  }
 
 
  /* Get the relevant register */
  /* Get the relevant register */
  if (regnum < MAX_GPRS)
        if (regnum < MAX_GPRS) {
    {
 
      err = gdb_read_reg(0x400 + regnum, &temp_uint32);
      err = gdb_read_reg(0x400 + regnum, &temp_uint32);
      if(err > 0){
      if(err > 0){
        if (DEBUG_GDB) printf("Error %d in rsp_read_reg at reg. %d \n", err, regnum);
                        if (DEBUG_GDB)
 
                                printf("Error %d in rsp_read_reg at reg. %d \n",
 
                                       err, regnum);
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
      }
      }
      reg2hex (temp_uint32, p_buf->data);
      reg2hex (temp_uint32, p_buf->data);
    }
        } else if (PPC_REGNUM == regnum) {      /* ---------- PPC ---------- */
  else if (PPC_REGNUM == regnum)        /* ---------- PPC ---------- */
 
    {
 
      err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
      err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
      if(err > 0){
      if(err > 0){
        if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err);
                        if (DEBUG_GDB)
 
                                printf
 
                                    ("Error %d in rsp_read_reg read --> PPC\n",
 
                                     err);
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
      }
      }
      reg2hex (temp_uint32, p_buf->data);
      reg2hex (temp_uint32, p_buf->data);
    }
        } else if (NPC_REGNUM == regnum) {      /* ---------- NPC ---------- */
  else if (NPC_REGNUM == regnum)        /* ---------- NPC ---------- */
 
    {
 
      temp_uint32 = get_npc();
      temp_uint32 = get_npc();
      /*
      /*
        err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
        err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
        if(err > 0){
        if(err > 0){
        if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err);
        if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err);
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
        }
        }
      */
      */
      reg2hex (temp_uint32, p_buf->data);
      reg2hex (temp_uint32, p_buf->data);
    }
        } else if (SR_REGNUM == regnum) {       /* ---------- SR ---------- */
  else if (SR_REGNUM == regnum)         /* ---------- SR ---------- */
 
    {
 
      err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
      err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
      if(err > 0){
      if(err > 0){
        if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err);
                        if (DEBUG_GDB)
 
                                printf
 
                                    ("Error %d in rsp_read_reg read --> PPC\n",
 
                                     err);
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
      }
      }
      reg2hex (temp_uint32, p_buf->data);
      reg2hex (temp_uint32, p_buf->data);
    }
        } else {
  else
 
    {
 
      /* Error response if we don't know the register */
      /* Error response if we don't know the register */
      fprintf (stderr, "Warning: Attempt to read unknown register 0x%x: "
                fprintf(stderr,
 
                        "Warning: Attempt to read unknown register 0x%x: "
               "ignored\n", regnum);
               "ignored\n", regnum);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  p_buf->len = strlen (p_buf->data);
  p_buf->len = strlen (p_buf->data);
  put_packet (p_buf);
  put_packet (p_buf);
 
 
}       /* rsp_read_reg () */
}       /* rsp_read_reg () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Write a single register
/*!Write a single register
 
 
  The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
  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
  (i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a
Line 2501... Line 2459...
 
 
  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
static void rsp_write_reg(struct rsp_buf *p_buf)
rsp_write_reg (struct rsp_buf *p_buf)
 
{
{
  unsigned int  regnum;
  unsigned int  regnum;
  char          valstr[9];              /* Allow for EOS on the string */
  char          valstr[9];              /* Allow for EOS on the string */
  // int           err = 0;
  // int           err = 0;
 
 
  /* Break out the fields from the data */
  /* Break out the fields from the data */
  if (2 != sscanf (p_buf->data, "P%x=%8s", &regnum, valstr))
        if (2 != sscanf(p_buf->data, "P%x=%8s", &regnum, valstr)) {
    {
                fprintf(stderr,
      fprintf (stderr, "Warning: Failed to recognize RSP write register "
                        "Warning: Failed to recognize RSP write register "
               "command: %s\n", p_buf->data);
               "command: %s\n", p_buf->data);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // First set the chain 
  // First set the chain 
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  if(err > 0){
  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");
    put_str_packet ("E01");
    return;
    return;
  }
  }
 
 
  /* Set the relevant register */
  /* Set the relevant register */
  if (regnum < MAX_GPRS)                                 /* ---------- GPRS ---------- */
        if (regnum < MAX_GPRS) {        /* ---------- GPRS ---------- */
    {
 
      err = gdb_write_reg(0x400 + regnum, hex2reg (valstr));
      err = gdb_write_reg(0x400 + regnum, hex2reg (valstr));
      if(err > 0){
      if(err > 0){
        if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err);
                        if (DEBUG_GDB)
 
                                printf
 
                                    ("Error %d in rsp_write_reg write --> GPRS\n",
 
                                     err);
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
      }
      }
    }
        } else if (PPC_REGNUM == regnum) {      /* ---------- PPC ---------- */
  else if (PPC_REGNUM == regnum) /* ---------- PPC ---------- */
 
    {
 
      err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (valstr));
      err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (valstr));
      if(err > 0){
      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");
        put_str_packet ("E01");
        return;
        return;
      }
      }
    }
        } else if (NPC_REGNUM == regnum) {      /* ---------- NPC ---------- */
  else if (NPC_REGNUM == regnum) /* ---------- NPC ---------- */
 
    {
 
      set_npc(hex2reg (valstr));
      set_npc(hex2reg (valstr));
      /*
      /*
        err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (valstr));
        err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (valstr));
        if(err > 0){
        if(err > 0){
        if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
        if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
        }
        }
      */
      */
    }
        } else if (SR_REGNUM == regnum) {       /* ---------- SR ---------- */
  else if (SR_REGNUM == regnum)  /* ---------- SR ---------- */
 
    {
 
      err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (valstr));
      err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (valstr));
      if(err > 0){
      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");
        put_str_packet ("E01");
        return;
        return;
      }
      }
    }
        } else {
  else
 
    {
 
      /* Error response if we don't know the register */
      /* Error response if we don't know the register */
      fprintf (stderr, "Warning: Attempt to write unknown register 0x%x: "
                fprintf(stderr,
 
                        "Warning: Attempt to write unknown register 0x%x: "
               "ignored\n", regnum);
               "ignored\n", regnum);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  put_str_packet ("OK");
  put_str_packet ("OK");
 
 
}       /* rsp_write_reg () */
}       /* rsp_write_reg () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP query request
/*!Handle a RSP query request
 
 
  @param[in] p_buf  The request                                               */
  @param[in] p_buf  The request                                               */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_query(struct rsp_buf *p_buf)
rsp_query (struct rsp_buf *p_buf)
 
{
 
  if (0 == strcmp ("qC", p_buf->data))
 
    {
    {
 
        if (0 == strcmp("qC", p_buf->data)) {
      /* Return the current thread ID (unsigned hex). A null response
      /* Return the current thread ID (unsigned hex). A null response
         indicates to use the previously selected thread. Since we do not
         indicates to use the previously selected thread. Since we do not
         support a thread concept, this is the appropriate response. */
         support a thread concept, this is the appropriate response. */
      put_str_packet ("");
      put_str_packet ("");
    }
    }
  if (0 == strncmp ("qAttached", p_buf->data, strlen ("qAttached")))
        if (0 == strncmp("qAttached", p_buf->data, strlen("qAttached"))) {
    {
 
      /* Return an indication of whether the remote server attached to an
      /* Return an indication of whether the remote server attached to an
         existing process or created a new process.
         existing process or created a new process.
         Reply: '1' - The remote server attached to an existing process.
         Reply: '1' - The remote server attached to an existing process.
                '0' - The remote server created a new process. */
                '0' - The remote server created a new process. */
      put_str_packet ("1");
      put_str_packet ("1");
    }
        } else if (0 == strncmp("qCRC", p_buf->data, strlen("qCRC"))) {
  else if (0 == strncmp ("qCRC", p_buf->data, strlen ("qCRC")))
 
    {
 
      /* Return CRC of memory area */
      /* Return CRC of memory area */
      fprintf (stderr, "Warning: RSP CRC query not supported\n");
      fprintf (stderr, "Warning: RSP CRC query not supported\n");
      put_str_packet ("E01");
      put_str_packet ("E01");
    }
        } else if (0 == strcmp("qfThreadInfo", p_buf->data)) {
  else if (0 == strcmp ("qfThreadInfo", p_buf->data))
 
    {
 
      /* Return info about active threads. We return just '-1' */
      /* Return info about active threads. We return just '-1' */
      put_str_packet ("m-1");
      put_str_packet ("m-1");
    }
        } else if (0 == strcmp("qsThreadInfo", p_buf->data)) {
  else if (0 == strcmp ("qsThreadInfo", p_buf->data))
 
    {
 
      /* Return info about more active threads. We have no more, so return the
      /* Return info about more active threads. We have no more, so return the
         end of list marker, 'l' */
         end of list marker, 'l' */
      put_str_packet ("l");
      put_str_packet ("l");
    }
        } else if (0 ==
  else if (0 == strncmp ("qGetTLSAddr:", p_buf->data, strlen ("qGetTLSAddr:")))
                   strncmp("qGetTLSAddr:", p_buf->data,
    {
                           strlen("qGetTLSAddr:"))) {
      /* We don't support this feature */
      /* We don't support this feature */
      put_str_packet ("");
      put_str_packet ("");
    }
        } else if (0 == strncmp("qL", p_buf->data, strlen("qL"))) {
  else if (0 == strncmp ("qL", p_buf->data, strlen ("qL")))
 
    {
 
      /* Deprecated and replaced by 'qfThreadInfo' */
      /* Deprecated and replaced by 'qfThreadInfo' */
      fprintf (stderr, "Warning: RSP qL deprecated: no info returned\n");
                fprintf(stderr,
 
                        "Warning: RSP qL deprecated: no info returned\n");
      put_str_packet ("qM001");
      put_str_packet ("qM001");
    }
        } else if (0 == strcmp("qOffsets", p_buf->data)) {
  else if (0 == strcmp ("qOffsets", p_buf->data))
 
    {
 
      /* Report any relocation */
      /* Report any relocation */
      put_str_packet ("Text=0;Data=0;Bss=0");
      put_str_packet ("Text=0;Data=0;Bss=0");
    }
        } else if (0 == strncmp("qP", p_buf->data, strlen("qP"))) {
  else if (0 == strncmp ("qP", p_buf->data, strlen ("qP")))
 
    {
 
      /* Deprecated and replaced by 'qThreadExtraInfo' */
      /* Deprecated and replaced by 'qThreadExtraInfo' */
      fprintf (stderr, "Warning: RSP qP deprecated: no info returned\n");
                fprintf(stderr,
 
                        "Warning: RSP qP deprecated: no info returned\n");
      put_str_packet ("");
      put_str_packet ("");
    }
        } else if (0 == strncmp("qRcmd,", p_buf->data, strlen("qRcmd,"))) {
  else if (0 == strncmp ("qRcmd,", p_buf->data, strlen ("qRcmd,")))
 
    {
 
      /* This is used to interface to commands to do "stuff" */
      /* This is used to interface to commands to do "stuff" */
      rsp_command (p_buf);
      rsp_command (p_buf);
    }
        } else if (0 ==
  else if (0 == strncmp ("qSupported", p_buf->data, strlen ("qSupported")))
                   strncmp("qSupported", p_buf->data, strlen("qSupported"))) {
    {
 
      /* Report a list of the features we support. For now we just ignore any
      /* 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
         supplied specific feature queries, but in the future these may be
         supported as well. Note that the packet size allows for 'G' + all the
         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
         registers sent to us, or a reply to 'g' with all the registers and an
         EOS so the buffer is a well formed string. */
         EOS so the buffer is a well formed string. */
      setup_or32();     // setup cpu
      setup_or32();     // setup cpu
      char  reply[GDB_BUF_MAX];
      char  reply[GDB_BUF_MAX];
      sprintf (reply, "PacketSize=%x", GDB_BUF_MAX);
      sprintf (reply, "PacketSize=%x", GDB_BUF_MAX);
      put_str_packet (reply);
      put_str_packet (reply);
    }
        } else if (0 == strncmp("qSymbol:", p_buf->data, strlen("qSymbol:"))) {
  else if (0 == strncmp ("qSymbol:", p_buf->data, strlen ("qSymbol:")))
 
    {
 
      /* Offer to look up symbols. Nothing we want (for now). TODO. This just
      /* Offer to look up symbols. Nothing we want (for now). TODO. This just
         ignores any replies to symbols we looked up, but we didn't want to
         ignores any replies to symbols we looked up, but we didn't want to
         do that anyway! */
         do that anyway! */
      put_str_packet ("OK");
      put_str_packet ("OK");
    }
        } else if (0 == strncmp("qThreadExtraInfo,", p_buf->data,
  else if (0 == strncmp ("qThreadExtraInfo,", p_buf->data,
                                strlen("qThreadExtraInfo,"))) {
                         strlen ("qThreadExtraInfo,")))
 
    {
 
      /* Report that we are runnable, but the text must be hex ASCI
      /* Report that we are runnable, but the text must be hex ASCI
         digits. For now do this by steam, reusing the original packet */
         digits. For now do this by steam, reusing the original packet */
      sprintf (p_buf->data, "%02x%02x%02x%02x%02x%02x%02x%02x%02x",
      sprintf (p_buf->data, "%02x%02x%02x%02x%02x%02x%02x%02x%02x",
               'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
               'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
      p_buf->len = strlen (p_buf->data);
      p_buf->len = strlen (p_buf->data);
      put_packet (p_buf);
      put_packet (p_buf);
    }
        } else if (0 == strncmp("qXfer:", p_buf->data, strlen("qXfer:"))) {
  else if (0 == strncmp ("qXfer:", p_buf->data, strlen ("qXfer:")))
 
    {
 
      /* For now we support no 'qXfer' requests, but these should not be
      /* For now we support no 'qXfer' requests, but these should not be
         expected, since they were not reported by 'qSupported' */
         expected, since they were not reported by 'qSupported' */
      fprintf (stderr, "Warning: RSP 'qXfer' not supported: ignored\n");
                fprintf(stderr,
 
                        "Warning: RSP 'qXfer' not supported: ignored\n");
      put_str_packet ("");
      put_str_packet ("");
    }
        } else if (0 == strncmp("qTStatus", p_buf->data, strlen("qTStatus"))) {
  else if (0 == strncmp ("qTStatus", p_buf->data, strlen ("qTStatus")))
 
    {
 
      /* Ask the stub if there is a trace experiment running right now.
      /* Ask the stub if there is a trace experiment running right now.
         The reply has the form:
         The reply has the form:
         `Trunning[;field]...'
         `Trunning[;field]...'
          running is a single digit 1 if the trace is presently running, or 0
          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
          if not. It is followed by semicolon-separated optional fields that an
          agent may use to report additional status.
          agent may use to report additional status.
      */
      */
      /* Not supported. Return empty packet */
      /* Not supported. Return empty packet */
      put_str_packet ("");
      put_str_packet ("");
    }
        } else if ((0 == strncmp("qTfV", p_buf->data, strlen("qTfV"))) ||
  else if ((0 == strncmp ("qTfV", p_buf->data, strlen ("qTfV"))) ||
                   (0 == strncmp("qTsV", p_buf->data, strlen("qTsV")))) {
           (0 == strncmp ("qTsV", p_buf->data, strlen ("qTsV"))))
 
    {
 
      /*
      /*
        These packets request data about trace state variables that are on the
        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
        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
        to get additional variables. Replies to these packets follow the syntax
        of the QTDV packets that define trace state variables.
        of the QTDV packets that define trace state variables.
      */
      */
      put_str_packet ("");
      put_str_packet ("");
    }
        } else if (0 == strncmp("qTfP", p_buf->data, strlen("qTfP"))) {
  else if (0 == strncmp ("qTfP", p_buf->data, strlen ("qTfP")))
 
    {
 
      /*
      /*
        These packets request data about tracepoints that are being used by the
        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
        target. gdb sends qTfP to get the first piece of data, and multiple
        qTsP to get additional pieces. Replies to these packets generally take
        qTsP to get additional pieces. Replies to these packets generally take
        the form of the QTDP packets that define tracepoints. (FIXME add
        the form of the QTDP packets that define tracepoints. (FIXME add
        detailed syntax)
        detailed syntax)
      */
      */
      put_str_packet ("");
      put_str_packet ("");
    }
        } else {
  else
 
    {
 
      fprintf (stderr, "Unrecognized RSP query: ignored\n");
      fprintf (stderr, "Unrecognized RSP query: ignored\n");
    }
    }
}       /* rsp_query () */
}       /* rsp_query () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP qRcmd request
/*!Handle a RSP qRcmd request
 
 
  The actual command follows the "qRcmd," in ASCII encoded to hex
  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
static void rsp_command(struct rsp_buf *p_buf)
rsp_command (struct rsp_buf *p_buf)
 
{
{
  char  cmd[GDB_BUF_MAX];
  char  cmd[GDB_BUF_MAX];
  unsigned int      regno;
  unsigned int      regno;
  uint32_t              temp_uint32;
  uint32_t              temp_uint32;
 
 
  hex2ascii (cmd, &(p_buf->data[strlen ("qRcmd,")]));
  hex2ascii (cmd, &(p_buf->data[strlen ("qRcmd,")]));
 
 
  /* Work out which command it is */
  /* Work out which command it is */
  if (0 == strncmp ("readspr ", cmd, strlen ("readspr")))
        if (0 == strncmp("readspr ", cmd, strlen("readspr"))) {
    {
 
      /* Parse and return error if we fail */
      /* Parse and return error if we fail */
      if( 1 != sscanf (cmd, "readspr %4x", &regno))
                if (1 != sscanf(cmd, "readspr %4x", &regno)) {
        {
                        fprintf(stderr,
          fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", cmd);
                                "Warning: qRcmd %s not recognized: ignored\n",
 
                                cmd);
          put_str_packet ("E01");
          put_str_packet ("E01");
          return;
          return;
        }
        }
 
 
      /* SPR out of range */
      /* SPR out of range */
      if (regno > MAX_SPRS)
                if (regno > MAX_SPRS) {
        {
                        fprintf(stderr,
          fprintf (stderr, "Warning: qRcmd readspr %x too large: ignored\n",
                                "Warning: qRcmd readspr %x too large: ignored\n",
                   regno);
                   regno);
          put_str_packet ("E01");
          put_str_packet ("E01");
          return;
          return;
        }
        }
 
 
Line 2773... Line 2699...
      gdb_set_chain(SC_RISC_DEBUG);     /* 1 RISC Debug Interface chain */
      gdb_set_chain(SC_RISC_DEBUG);     /* 1 RISC Debug Interface chain */
 
 
      // special case for NPC
      // special case for NPC
      if(regno == NPC_CPU_REG_ADD)
      if(regno == NPC_CPU_REG_ADD)
        temp_uint32 = get_npc();
        temp_uint32 = get_npc();
      else
                else {
        {
 
          err = gdb_read_reg(regno, &temp_uint32);
          err = gdb_read_reg(regno, &temp_uint32);
          if(err > 0){
          if(err > 0){
            if (DEBUG_GDB) printf("Error %d in rsp_command at reg. %x \n", err, regno);
                                if (DEBUG_GDB)
          }
                                        printf
          else{
                                            ("Error %d in rsp_command at reg. %x \n",
 
                                             err, regno);
 
                        } else {
            reg2hex (temp_uint32, cmd);
            reg2hex (temp_uint32, cmd);
            if (DEBUG_GDB) printf("Error %d Command readspr Read reg. %x = 0x%08x\n", err, regno, temp_uint32);
                                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
      // pack the result into the buffer to send back
      sprintf (cmd, "%8x", (unsigned int)temp_uint32);
      sprintf (cmd, "%8x", (unsigned int)temp_uint32);
      ascii2hex (p_buf->data, cmd);
      ascii2hex (p_buf->data, cmd);
      p_buf->len = strlen (p_buf->data);
      p_buf->len = strlen (p_buf->data);
      put_packet (p_buf);
      put_packet (p_buf);
    }
        } else if (0 == strncmp("writespr ", cmd, strlen("writespr"))) {
  else if (0 == strncmp ("writespr ", cmd, strlen ("writespr")))
 
    {
 
      unsigned int       regno;
      unsigned int       regno;
      uint32_t  val;
      uint32_t  val;
 
 
      /* Parse and return error if we fail */
      /* Parse and return error if we fail */
      if( 2 != sscanf (cmd, "writespr %4x %8x", &regno, &val))
                if (2 != sscanf(cmd, "writespr %4x %8x", &regno, &val)) {
        {
                        fprintf(stderr,
          fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n",
                                "Warning: qRcmd %s not recognized: ignored\n",
                   cmd);
                   cmd);
          put_str_packet ("E01");
          put_str_packet ("E01");
          return;
          return;
        }
        }
 
 
      /* SPR out of range */
      /* SPR out of range */
      if (regno > MAX_SPRS)
                if (regno > MAX_SPRS) {
        {
                        fprintf(stderr,
          fprintf (stderr, "Warning: qRcmd writespr %x too large: ignored\n",
                                "Warning: qRcmd writespr %x too large: ignored\n",
                   regno);
                   regno);
          put_str_packet ("E01");
          put_str_packet ("E01");
          return;
          return;
        }
        }
 
 
      // Make sure the processor is stalled
      // Make sure the processor is stalled
      gdb_ensure_or1k_stalled();
      gdb_ensure_or1k_stalled();
 
 
      // First set the chain 
      // First set the chain 
      gdb_set_chain(SC_RISC_DEBUG);     /* 1 RISC Debug Interface chain */
      gdb_set_chain(SC_RISC_DEBUG);     /* 1 RISC Debug Interface chain */
 
 
      /* set the relevant register */
      /* set the relevant register */
      // special case for NPC
      // special case for NPC
      if(regno == NPC_CPU_REG_ADD)
      if(regno == NPC_CPU_REG_ADD)
        set_npc(val);
        set_npc(val);
      else
                else {
        {
 
 
 
          err = gdb_write_reg(regno, val);
          err = gdb_write_reg(regno, val);
          if(err > 0){
          if(err > 0){
            if (DEBUG_GDB) printf("Error %d in rsp_command write Reg. %x = 0x%08x\n", err, regno, val);
                                if (DEBUG_GDB)
 
                                        printf
 
                                            ("Error %d in rsp_command write Reg. %x = 0x%08x\n",
 
                                             err, regno, val);
            put_str_packet ("E01");
            put_str_packet ("E01");
            return;
            return;
          }
                        } else {
          else{
                                if (DEBUG_GDB)
            if (DEBUG_GDB) printf("Error %d Command writespr Write reg. %x = 0x%08x\n", err, regno, val);
                                        printf
 
                                            ("Error %d Command writespr Write reg. %x = 0x%08x\n",
 
                                             err, regno, val);
          }
          }
        }
        }
      put_str_packet ("OK");
      put_str_packet ("OK");
    }
    }
}       /* rsp_command () */
}       /* rsp_command () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP set request
/*!Handle a RSP set request
 
 
  @param[in] p_buf  The request                                               */
  @param[in] p_buf  The request                                               */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_set(struct rsp_buf *p_buf)
rsp_set (struct rsp_buf *p_buf)
 
{
 
  if (0 == strncmp ("QPassSignals:", p_buf->data, strlen ("QPassSignals:")))
 
    {
    {
 
        if (0 == strncmp("QPassSignals:", p_buf->data, strlen("QPassSignals:"))) {
      /* Passing signals not supported */
      /* Passing signals not supported */
      put_str_packet ("");
      put_str_packet ("");
    }
        } else if ((0 == strncmp("QTDP", p_buf->data, strlen("QTDP"))) ||
  else if ((0 == strncmp ("QTDP",    p_buf->data, strlen ("QTDP")))   ||
 
           (0 == strncmp ("QFrame",  p_buf->data, strlen ("QFrame"))) ||
           (0 == strncmp ("QFrame",  p_buf->data, strlen ("QFrame"))) ||
           (0 == strcmp  ("QTStart", p_buf->data))                    ||
           (0 == strcmp  ("QTStart", p_buf->data))                    ||
           (0 == strcmp  ("QTStop",  p_buf->data))                    ||
           (0 == strcmp  ("QTStop",  p_buf->data))                    ||
           (0 == strcmp  ("QTinit",  p_buf->data))                    ||
           (0 == strcmp  ("QTinit",  p_buf->data))                    ||
           (0 == strncmp ("QTro",    p_buf->data, strlen ("QTro"))))
                   (0 == strncmp("QTro", p_buf->data, strlen("QTro")))) {
    {
 
      /* All tracepoint features are not supported. This reply is really only
      /* All tracepoint features are not supported. This reply is really only
         needed to 'QTDP', since with that the others should not be
         needed to 'QTDP', since with that the others should not be
         generated. */
         generated. */
      put_str_packet ("");
      put_str_packet ("");
    }
        } else {
  else
 
    {
 
      fprintf (stderr, "Unrecognized RSP set request: ignored\n");
      fprintf (stderr, "Unrecognized RSP set request: ignored\n");
    }
    }
}       /* rsp_set () */
}       /* rsp_set () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP restart request
/*!Handle a RSP restart request
 
 
  For now we just put the program counter back to the one used with the last
  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
  vRun request. There is no point in unstalling the processor, since we'll
  never get control back.                                                   */
  never get control back.                                                   */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_restart(void)
rsp_restart (void)
 
{
{
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // First set the chain 
  // First set the chain 
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  if(err > 0){
  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");
    put_str_packet ("E01");
    return;
    return;
  }
  }
  // OR32 Arc sim equivalent --> set_npc (rsp.start_addr);
  // OR32 Arc sim equivalent --> set_npc (rsp.start_addr);
  /* Set NPC to reset vector 0x100 */
  /* Set NPC to reset vector 0x100 */
Line 2911... Line 2834...
    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);
    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 () */
}       /* rsp_restart () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP step request
/*!Handle a RSP step request
 
 
  Parse the command to see if there is an address. Uses the underlying
  Parse the command to see if there is an address. Uses the underlying
  generic step function, with EXCEPT_NONE.
  generic step function, with EXCEPT_NONE.
 
 
  @param[in] p_buf  The full step packet                          */
  @param[in] p_buf  The full step packet                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_step(struct rsp_buf *p_buf)
rsp_step (struct rsp_buf *p_buf)
 
{
{
  uint32_t  addr;               /* The address to step from, if any */
  uint32_t  addr;               /* The address to step from, if any */
 
 
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // First set the chain 
  // First set the chain 
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  err = gdb_set_chain(SC_RISC_DEBUG);   /* 1 RISC Debug Interface chain */
  if(err > 0){
  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 ();
    rsp_client_close ();
    return;
    return;
  }
  }
 
 
  if (0 == strcmp ("s", p_buf->data))
        if (0 == strcmp("s", p_buf->data)) {
    {
 
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
      /* ---------- Npc ---------- */
      /* ---------- Npc ---------- */
      addr = get_npc();
      addr = get_npc();
      /*
      /*
        err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
        err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
Line 2949... Line 2871...
        printf("Error %d to read NPC in the STEP command 's'\n", err);
        printf("Error %d to read NPC in the STEP command 's'\n", err);
        rsp_client_close ();
        rsp_client_close ();
        return;
        return;
        }
        }
      */
      */
    }
        } else if (1 != sscanf(p_buf->data, "s%x", &addr)) {
  else if (1 != sscanf (p_buf->data, "s%x", &addr))
 
    {
 
      fprintf (stderr,
      fprintf (stderr,
               "Warning: RSP step address %s not recognized: ignored\n",
               "Warning: RSP step address %s not recognized: ignored\n",
               p_buf->data);
               p_buf->data);
 
 
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
      // Arc Sim Code -->   addr = cpu_state.pc;        /* Default uses current NPC */
Line 2968... Line 2888...
        rsp_client_close ();
        rsp_client_close ();
        return;
        return;
        }
        }
      */
      */
    }
    }
 
 
  //if (DEBUG_GDB) printf("rsp_step() --> Read NPC = 0x%08x\n", addr);
  //if (DEBUG_GDB) printf("rsp_step() --> Read NPC = 0x%08x\n", addr);
  rsp_step_generic (addr, EXCEPT_NONE);
  rsp_step_generic (addr, EXCEPT_NONE);
 
 
}       /* rsp_step () */
}       /* rsp_step () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP step with signal request
/*!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
static void rsp_step_with_signal(struct rsp_buf *p_buf)
rsp_step_with_signal (struct rsp_buf *p_buf)
 
{
{
  printf ("RSP step with signal '%s' received\n", p_buf->data);
  printf ("RSP step with signal '%s' received\n", p_buf->data);
 
 
}       /* rsp_step_with_signal () */
}       /* rsp_step_with_signal () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Generic processing of a step request
/*!Generic processing of a step request
 
 
  The signal may be EXCEPT_NONE if there is no exception to be
  The signal may be EXCEPT_NONE if there is no exception to be
  handled. Currently the exception is ignored.
  handled. Currently the exception is ignored.
Line 3002... Line 2918...
  is unstalled.
  is unstalled.
 
 
  @param[in] addr    Address from which to step
  @param[in] addr    Address from which to step
  @param[in] except  The exception to use (if any)                          */
  @param[in] except  The exception to use (if any)                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_step_generic(uint32_t addr, uint32_t except)
rsp_step_generic (uint32_t  addr,
 
                  uint32_t  except)
 
{
{
  uint32_t              temp_uint32;
  uint32_t              temp_uint32;
 
 
  /* Set the address as the value of the next program counter */
  /* Set the address as the value of the next program counter */
 
 
  set_npc (addr);
  set_npc (addr);
 
 
  /* Clear Debug Reason Register (DRR) 0x3015 */
  /* Clear Debug Reason Register (DRR) 0x3015 */
  // Arc sim --> cpu_state.sprs[SPR_DRR]   = 0;
  // Arc sim --> cpu_state.sprs[SPR_DRR]   = 0;
  if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n");
        if (gdb_write_reg(DRR_CPU_REG_ADD, 0))
 
                printf("Error write to DRR register\n");
 
 
  /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
  /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
  // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
  // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
  if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n");
        if (gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32))
 
                printf("Error read from DMR2 register\n");
  temp_uint32 &= ~SPR_DMR2_WGB;
  temp_uint32 &= ~SPR_DMR2_WGB;
  if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n");
        if (gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32))
 
                printf("Error write to DMR2 register\n");
 
 
  /* Set the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
  /* Set the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
  // Arc sim --> cpu_state.sprs[SPR_DMR1] |= SPR_DMR1_ST;
  // Arc sim --> cpu_state.sprs[SPR_DMR1] |= SPR_DMR1_ST;
  if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n");
        if (gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32))
 
                printf("Error read from DMR1 register\n");
  temp_uint32 |= SPR_DMR1_ST;
  temp_uint32 |= SPR_DMR1_ST;
  if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n");
        if (gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32))
 
                printf("Error write to DMR1 register\n");
 
 
  /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
  /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
  // Arc sim --> cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
  // Arc sim --> cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
  if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n");
        if (gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32))
 
                printf("Error read from DSR register\n");
  temp_uint32 |= SPR_DSR_TE;
  temp_uint32 |= SPR_DSR_TE;
  if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n");
        if (gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32))
 
                printf("Error write to DSR register\n");
 
 
  /* Unstall the processor */
  /* Unstall the processor */
  set_stall_state (0);
  set_stall_state (0);
 
 
  /* Note the GDB client is now waiting for a reply. */
  /* Note the GDB client is now waiting for a reply. */
  rsp.client_waiting = 1;
  rsp.client_waiting = 1;
 
 
}       /* rsp_step_generic () */
}       /* rsp_step_generic () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP 'v' packet
/*!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
static void rsp_vpkt(struct rsp_buf *p_buf)
rsp_vpkt (struct rsp_buf *p_buf)
 
{
 
  if (0 == strncmp ("vAttach;", p_buf->data, strlen ("vAttach;")))
 
    {
    {
 
        if (0 == strncmp("vAttach;", p_buf->data, strlen("vAttach;"))) {
      /* Attaching is a null action, since we have no other process. We just
      /* Attaching is a null action, since we have no other process. We just
         return a stop packet (using TRAP) to indicate we are stopped. */
         return a stop packet (using TRAP) to indicate we are stopped. */
      put_str_packet ("S05");
      put_str_packet ("S05");
      return;
      return;
    }
        } else if (0 == strcmp("vCont?", p_buf->data)) {
  else if (0 == strcmp ("vCont?", p_buf->data))
 
    {
 
      /* For now we don't support this. */
      /* For now we don't support this. */
      put_str_packet ("");
      put_str_packet ("");
      return;
      return;
    }
        } else if (0 == strncmp("vCont", p_buf->data, strlen("vCont"))) {
  else if (0 == strncmp ("vCont", p_buf->data, strlen ("vCont")))
 
    {
 
      /* This shouldn't happen, because we've reported non-support via vCont?
      /* This shouldn't happen, because we've reported non-support via vCont?
         above */
         above */
      fprintf (stderr, "Warning: RSP vCont not supported: ignored\n" );
      fprintf (stderr, "Warning: RSP vCont not supported: ignored\n" );
      return;
      return;
    }
        } else if (0 == strncmp("vFile:", p_buf->data, strlen("vFile:"))) {
  else if (0 == strncmp ("vFile:", p_buf->data, strlen ("vFile:")))
 
    {
 
      /* For now we don't support this. */
      /* For now we don't support this. */
      fprintf (stderr, "Warning: RSP vFile not supported: ignored\n" );
      fprintf (stderr, "Warning: RSP vFile not supported: ignored\n" );
      put_str_packet ("");
      put_str_packet ("");
      return;
      return;
    }
        } else if (0 ==
  else if (0 == strncmp ("vFlashErase:", p_buf->data, strlen ("vFlashErase:")))
                   strncmp("vFlashErase:", p_buf->data,
    {
                           strlen("vFlashErase:"))) {
      /* For now we don't support this. */
      /* For now we don't support this. */
      fprintf (stderr, "Warning: RSP vFlashErase not supported: ignored\n" );
                fprintf(stderr,
 
                        "Warning: RSP vFlashErase not supported: ignored\n");
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
        } else if (0 ==
  else if (0 == strncmp ("vFlashWrite:", p_buf->data, strlen ("vFlashWrite:")))
                   strncmp("vFlashWrite:", p_buf->data,
    {
                           strlen("vFlashWrite:"))) {
      /* For now we don't support this. */
      /* For now we don't support this. */
      fprintf (stderr, "Warning: RSP vFlashWrite not supported: ignored\n" );
                fprintf(stderr,
 
                        "Warning: RSP vFlashWrite not supported: ignored\n");
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
        } else if (0 == strcmp("vFlashDone", p_buf->data)) {
  else if (0 == strcmp ("vFlashDone", p_buf->data))
 
    {
 
      /* For now we don't support this. */
      /* For now we don't support this. */
      fprintf (stderr, "Warning: RSP vFlashDone not supported: ignored\n" );
                fprintf(stderr,
 
                        "Warning: RSP vFlashDone not supported: ignored\n");
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
        } else if (0 == strncmp("vRun;", p_buf->data, strlen("vRun;"))) {
  else if (0 == strncmp ("vRun;", p_buf->data, strlen ("vRun;")))
 
    {
 
      /* We shouldn't be given any args, but check for this */
      /* We shouldn't be given any args, but check for this */
      if (p_buf->len > (int) strlen ("vRun;"))
                if (p_buf->len > (int)strlen("vRun;")) {
        {
                        fprintf(stderr,
          fprintf (stderr, "Warning: Unexpected arguments to RSP vRun "
                                "Warning: Unexpected arguments to RSP vRun "
                   "command: ignored\n");
                   "command: ignored\n");
        }
        }
 
 
      /* Restart the current program. However unlike a "R" packet, "vRun"
      /* Restart the current program. However unlike a "R" packet, "vRun"
         should behave as though it has just stopped. We use signal
         should behave as though it has just stopped. We use signal
         5 (TRAP). */
         5 (TRAP). */
      rsp_restart ();
      rsp_restart ();
      put_str_packet ("S05");
      put_str_packet ("S05");
    }
        } else {
  else
                fprintf(stderr,
    {
                        "Warning: Unknown RSP 'v' packet type %s: ignored\n",
      fprintf (stderr, "Warning: Unknown RSP 'v' packet type %s: ignored\n",
 
               p_buf->data);
               p_buf->data);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
}       /* rsp_vpkt () */
}       /* rsp_vpkt () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP write memory (binary) request
/*!Handle a RSP write memory (binary) request
 
 
  Syntax is:
  Syntax is:
 
 
Line 3142... Line 3051...
  of data bytes may be greater, since '#', '$' and '}' are escaped by
  of data bytes may be greater, since '#', '$' and '}' are escaped by
  preceding them by '}' and oring with 0x20.
  preceding them by '}' and oring with 0x20.
 
 
  @param[in] p_buf  The command received                                      */
  @param[in] p_buf  The command received                                      */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void rsp_write_mem_bin(struct rsp_buf *p_buf)
rsp_write_mem_bin (struct rsp_buf *p_buf)
 
{
{
  unsigned int  addr;                   /* Where to write the memory */
  unsigned int  addr;                   /* Where to write the memory */
  int           len;                    /* Number of bytes to write */
  int           len;                    /* Number of bytes to write */
  char          *bindat, *bindat_ptr;   /* Pointer to the binary data */
  char          *bindat, *bindat_ptr;   /* Pointer to the binary data */
  int           off = 0; /* Offset to start of binary data */
  int           off = 0; /* Offset to start of binary data */
  int           newlen;         /* Number of bytes in bin data */
  int           newlen;         /* Number of bytes in bin data */
  int i;
  int i;
  int bytes_per_word = 4; /* Current OR implementation is 4-byte words */
  int bytes_per_word = 4; /* Current OR implementation is 4-byte words */
 
 
  if (2 != sscanf (p_buf->data, "X%x,%x:", &addr, &len))
        if (2 != sscanf(p_buf->data, "X%x,%x:", &addr, &len)) {
    {
 
      fprintf (stderr, "Warning: Failed to recognize RSP write memory "
      fprintf (stderr, "Warning: Failed to recognize RSP write memory "
               "command: %s\n", p_buf->data);
               "command: %s\n", p_buf->data);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
Line 3179... Line 3086...
  }
  }
 
 
  newlen = rsp_unescape (bindat, p_buf->len - off);
  newlen = rsp_unescape (bindat, p_buf->len - off);
 
 
  /* Sanity check */
  /* Sanity check */
  if (newlen != len)
        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 "
                fprintf(stderr,
 
                        "Warning: Write of %d bytes requested, but %d bytes "
               "supplied. %d will be written\n", len, newlen, minlen);
               "supplied. %d will be written\n", len, newlen, minlen);
      len = minlen;
      len = minlen;
    }
    }
 
 
  // Make sure the processor is stalled
  // Make sure the processor is stalled
  gdb_ensure_or1k_stalled();
  gdb_ensure_or1k_stalled();
 
 
  // Set chain 5 --> Wishbone Memory chain
  // Set chain 5 --> Wishbone Memory chain
  err = gdb_set_chain(SC_WISHBONE);
  err = gdb_set_chain(SC_WISHBONE);
Line 3199... Line 3105...
    put_str_packet ("E01");
    put_str_packet ("E01");
    return;
    return;
  }
  }
 
 
  /* Write the bytes to memory */
  /* Write the bytes to memory */
  if (len)
        if (len) {
    {
 
      //swap_buf(bindat, len);
      //swap_buf(bindat, len);
      if (DEBUG_GDB_BLOCK_DATA){
      if (DEBUG_GDB_BLOCK_DATA){
        uint32_t  temp_uint32;
        uint32_t  temp_uint32;
        for (off = 0; off < len; off++){
        for (off = 0; off < len; off++){
          temp_uint32 = (temp_uint32 << 8) | (0x000000ff & bindat[off]);
                                temp_uint32 =
          if((off %4 ) == 3){
                                    (temp_uint32 << 8) | (0x000000ff &
 
                                                          bindat[off]);
 
                                if ((off % 4) == 3) {
            //temp_uint32 = htonl(temp_uint32);
            //temp_uint32 = htonl(temp_uint32);
          }
          }
          switch(off % 16)
                                switch (off % 16) {
            {
 
            case 3:
            case 3:
              printf("Add 0x%08x   Data 0x%08x  ", addr + off - 3, temp_uint32);
                                        printf("Add 0x%08x   Data 0x%08x  ",
 
                                               addr + off - 3, temp_uint32);
              break;
              break;
            case 7:
            case 7:
            case 11:
            case 11:
              printf("0x%08x  ", temp_uint32);
              printf("0x%08x  ", temp_uint32);
              break;
              break;
Line 3224... Line 3131...
              printf("0x%08x\n", temp_uint32);
              printf("0x%08x\n", temp_uint32);
              break;
              break;
            default:
            default:
              break;
              break;
            }
            }
          if ((len - off == 1) && (off % 16) < 15) printf("\n");
                                if ((len - off == 1) && (off % 16) < 15)
 
                                        printf("\n");
        }
        }
      }
      }
 
 
      bindat_ptr = bindat; // Copy pointer so we don't trash the original.
      bindat_ptr = bindat; // Copy pointer so we don't trash the original.
      if (addr & 0x3) // not perfectly aligned at beginning - fix
      if (addr & 0x3) // not perfectly aligned at beginning - fix
        {
        {
          if (DEBUG_GDB) {
          if (DEBUG_GDB) {
            printf("rsp_write_mem_bin: address not word aligned: 0x%.8x\n",
                                printf
                   addr);fflush (stdout);
                                    ("rsp_write_mem_bin: address not word aligned: 0x%.8x\n",
 
                                     addr);
 
                                fflush(stdout);
          }
          }
          // Write enough to align us
          // Write enough to align us
          int bytes_to_write = bytes_per_word - (addr&0x3);
          int bytes_to_write = bytes_per_word - (addr&0x3);
          if (bytes_to_write > len) bytes_to_write = len; // case of writing 1 byte to adr 0x1
                        if (bytes_to_write > len)
 
                                bytes_to_write = len;   // case of writing 1 byte to adr 0x1
          if (DEBUG_GDB) {
          if (DEBUG_GDB) {
            printf("rsp_write_mem_bin: writing %d bytes of len (%d)\n",
                                printf
                   bytes_to_write, len);fflush (stdout);
                                    ("rsp_write_mem_bin: writing %d bytes of len (%d)\n",
 
                                     bytes_to_write, len);
 
                                fflush(stdout);
          }
          }
 
 
          for (i=0;i<bytes_to_write;i++)
          for (i=0;i<bytes_to_write;i++)
            err = gdb_write_byte(addr+i, (uint8_t) bindat_ptr[i]);
                                err =
 
                                    gdb_write_byte(addr + i,
 
                                                   (uint8_t) bindat_ptr[i]);
 
 
          addr += bytes_to_write; bindat_ptr += bytes_to_write;
                        addr += bytes_to_write;
 
                        bindat_ptr += bytes_to_write;
          len -= bytes_to_write;
          len -= bytes_to_write;
          if (DEBUG_GDB){
          if (DEBUG_GDB){
            printf("rsp_write_mem_bin: address should now be word aligned: 0x%.8x\n", addr);
                                printf
 
                                    ("rsp_write_mem_bin: address should now be word aligned: 0x%.8x\n",
 
                                     addr);
            fflush (stdout);
            fflush (stdout);
          }
          }
        }
        }
      if ((len > 3) && !err) // now write full words, if we can
      if ((len > 3) && !err) // now write full words, if we can
        {
        {
          int words_to_write = len/bytes_per_word;
          int words_to_write = len/bytes_per_word;
          if (DEBUG_GDB)
          if (DEBUG_GDB)
            printf("rsp_write_mem_bin: writing %d words from 0x%x, len %d bytes\n",
                                printf
                   words_to_write, addr, len);fflush (stdout);
                                    ("rsp_write_mem_bin: writing %d words from 0x%x, len %d bytes\n",
 
                                     words_to_write, addr, len);
 
                        fflush(stdout);
 
 
          err = gdb_write_block(addr, (uint32_t*)bindat_ptr,
          err = gdb_write_block(addr, (uint32_t*)bindat_ptr,
                                (words_to_write*bytes_per_word));
                                              (words_to_write *
 
                                               bytes_per_word));
 
 
          addr+=(words_to_write*bytes_per_word);
          addr+=(words_to_write*bytes_per_word);
          bindat_ptr+=(words_to_write*bytes_per_word);
          bindat_ptr+=(words_to_write*bytes_per_word);
          len-=(words_to_write*bytes_per_word);
          len-=(words_to_write*bytes_per_word);
        }
        }
      if (len && !err)  // leftover words. Write them out
      if (len && !err)  // leftover words. Write them out
        {
        {
          if (DEBUG_GDB)
          if (DEBUG_GDB)
            printf("rsp_write_mem_bin: writing remainder %d bytes to 0x%.8x\n",
                                printf
                   len, addr);fflush (stdout);
                                    ("rsp_write_mem_bin: writing remainder %d bytes to 0x%.8x\n",
 
                                     len, addr);
 
                        fflush(stdout);
 
 
          for (i=0;i<len;i++)
          for (i=0;i<len;i++)
            err = gdb_write_byte(addr+i, (uint8_t) bindat_ptr[i]);
                                err =
 
                                    gdb_write_byte(addr + i,
 
                                                   (uint8_t) bindat_ptr[i]);
        }
        }
 
 
      if(err){
      if(err){
        put_str_packet ("E01");
        put_str_packet ("E01");
        return;
        return;
      }
      }
 
 
      if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout);
                if (DEBUG_GDB)
 
                        printf("Error %x\n", err);
 
                fflush(stdout);
    }
    }
  put_str_packet ("OK");
  put_str_packet ("OK");
 
 
}       /* rsp_write_mem_bin () */
}       /* rsp_write_mem_bin () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP remove breakpoint or matchpoint request
/*!Handle a RSP remove breakpoint or matchpoint request
 
 
  For now only memory breakpoints are implemented, which are implemented by
  For now only memory breakpoints are implemented, which are implemented by
  substituting a breakpoint at the specified address. The implementation must
  substituting a breakpoint at the specified address. The implementation must
Line 3300... Line 3226...
 
 
  @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
static void rsp_remove_matchpoint(struct rsp_buf *p_buf)
rsp_remove_matchpoint (struct rsp_buf *p_buf)
 
{
{
  enum mp_type       type;              /* What sort of matchpoint */
  enum mp_type       type;              /* What sort of matchpoint */
  uint32_t  addr;               /* Address specified */
  uint32_t  addr;               /* Address specified */
  int                len;                       /* Matchpoint length (not used) */
  int                len;                       /* Matchpoint length (not used) */
  struct mp_entry   *mpe;                       /* Info about the replaced instr */
  struct mp_entry   *mpe;                       /* Info about the replaced instr */
 
 
  /* Break out the instruction */
  /* Break out the instruction */
  if (3 != sscanf (p_buf->data, "z%1d,%x,%1d", (int *)&type, &addr, &len))
        if (3 != sscanf(p_buf->data, "z%1d,%x,%1d", (int *)&type, &addr, &len)) {
    {
 
      fprintf (stderr, "Warning: RSP matchpoint deletion request not "
      fprintf (stderr, "Warning: RSP matchpoint deletion request not "
               "recognized: ignored\n");
               "recognized: ignored\n");
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  /* Sanity check that the length is 4 */
  /* Sanity check that the length is 4 */
  if (4 != len)
        if (4 != len) {
    {
                fprintf(stderr,
      fprintf (stderr, "Warning: RSP matchpoint deletion length %d not "
                        "Warning: RSP matchpoint deletion length %d not "
               "valid: 4 assumed\n", len);
               "valid: 4 assumed\n", len);
      len = 4;
      len = 4;
    }
    }
 
 
  /* Sort out the type of matchpoint */
  /* Sort out the type of matchpoint */
  switch (type)
        switch (type) {
    {
 
    case BP_MEMORY:
    case BP_MEMORY:
      /* Memory breakpoint - replace the original instruction. */
      /* Memory breakpoint - replace the original instruction. */
      mpe = mp_hash_delete (type, addr);
      mpe = mp_hash_delete (type, addr);
 
 
      /* If the BP hasn't yet been deleted, put the original instruction
      /* If the BP hasn't yet been deleted, put the original instruction
         back. Don't forget to free the hash table entry afterwards. */
         back. Don't forget to free the hash table entry afterwards. */
      if (NULL != mpe)
                if (NULL != mpe) {
        {
 
          // Arc Sim Code -->   set_program32 (addr, mpe->instr);
          // Arc Sim Code -->   set_program32 (addr, mpe->instr);
          // Make sure the processor is stalled
          // Make sure the processor is stalled
          gdb_ensure_or1k_stalled();
          gdb_ensure_or1k_stalled();
 
 
          // Set chain 5 --> Wishbone Memory chain
          // Set chain 5 --> Wishbone Memory chain
Line 3382... Line 3304...
      return;
      return;
 
 
    }
    }
}       /* rsp_remove_matchpoint () */
}       /* rsp_remove_matchpoint () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP insert breakpoint or matchpoint request
/*!Handle a RSP insert breakpoint or matchpoint request
 
 
  For now only memory breakpoints are implemented, which are implemented by
  For now only memory breakpoints are implemented, which are implemented by
  substituting a breakpoint at the specified address. The implementation must
  substituting a breakpoint at the specified address. The implementation must
Line 3394... Line 3315...
 
 
  @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
static void rsp_insert_matchpoint(struct rsp_buf *p_buf)
rsp_insert_matchpoint (struct rsp_buf *p_buf)
 
{
{
  enum mp_type       type;              /* What sort of matchpoint */
  enum mp_type       type;              /* What sort of matchpoint */
  uint32_t  addr;               /* Address specified */
  uint32_t  addr;               /* Address specified */
  int                len;               /* Matchpoint length (not used) */
  int                len;               /* Matchpoint length (not used) */
  uint32_t      instr;
  uint32_t      instr;
 
 
  /* Break out the instruction */
  /* Break out the instruction */
  if (3 != sscanf (p_buf->data, "Z%1d,%x,%1d", (int *)&type, &addr, &len))
        if (3 != sscanf(p_buf->data, "Z%1d,%x,%1d", (int *)&type, &addr, &len)) {
    {
 
      fprintf (stderr, "Warning: RSP matchpoint insertion request not "
      fprintf (stderr, "Warning: RSP matchpoint insertion request not "
               "recognized: ignored\n");
               "recognized: ignored\n");
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
 
 
  /* Sanity check that the length is 4 */
  /* Sanity check that the length is 4 */
  if (4 != len)
        if (4 != len) {
    {
                fprintf(stderr,
      fprintf (stderr, "Warning: RSP matchpoint insertion length %d not "
                        "Warning: RSP matchpoint insertion length %d not "
               "valid: 4 assumed\n", len);
               "valid: 4 assumed\n", len);
      len = 4;
      len = 4;
    }
    }
 
 
  /* Sort out the type of matchpoint */
  /* Sort out the type of matchpoint */
  switch (type)
        switch (type) {
    {
 
    case BP_MEMORY:             // software-breakpoint Z0  break
    case BP_MEMORY:             // software-breakpoint Z0  break
      /* Memory breakpoint - substitute a TRAP instruction */
      /* Memory breakpoint - substitute a TRAP instruction */
      // Make sure the processor is stalled
      // Make sure the processor is stalled
      gdb_ensure_or1k_stalled();
      gdb_ensure_or1k_stalled();
 
 
Line 3470... Line 3388...
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
    }
    }
}       /* rsp_insert_matchpoint () */
}       /* rsp_insert_matchpoint () */
 
 
 
 
/*---------------------------------------------------------------------------
/*---------------------------------------------------------------------------
  Setup the or32 to init state
  Setup the or32 to init state
 
 
  ---------------------------------------------------------------------------*/
  ---------------------------------------------------------------------------*/
void setup_or32(void)
void setup_or32(void)
{
{
  uint32_t              temp_uint32;
  uint32_t              temp_uint32;
  // First set the chain 
  // First set the chain 
  err = gdb_set_chain(SC_REGISTER);     /* 4 Register Chain */
  err = gdb_set_chain(SC_REGISTER);     /* 4 Register Chain */
  if(err > 0){
  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);
  }
  }
  if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
        if (gdb_read_reg(0x04, &temp_uint32))
  if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );
                printf("Error read from register\n");
 
        if (DEBUG_GDB)
 
                printf
 
                    ("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n",
 
                     temp_uint32);
 
 
  if(gdb_write_reg(0x04, 0x00000001)) printf("Error write to register\n");
        if (gdb_write_reg(0x04, 0x00000001))
  if (DEBUG_GDB) printf("Write to chain 4 SC_REGISTER at add 0x00000004 = 0x00000001\n");
                printf("Error write to register\n");
 
        if (DEBUG_GDB)
 
                printf
 
                    ("Write to chain 4 SC_REGISTER at add 0x00000004 = 0x00000001\n");
 
 
  //    if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
  //    if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
  //    if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );                      
  //    if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );                      
 
 
  //    if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
  //    if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
  //    if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );                      
  //    if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );                      
 
 
  if(gdb_write_reg(0x00, 0x01000001)) printf("Error write to register\n");
        if (gdb_write_reg(0x00, 0x01000001))
  if (DEBUG_GDB) printf("Write to chain 4 SC_REGISTER at add 0x00000000 = 0x01000001\n");
                printf("Error write to register\n");
 
        if (DEBUG_GDB)
 
                printf
 
                    ("Write to chain 4 SC_REGISTER at add 0x00000000 = 0x01000001\n");
}
}
 
 
// Function to check if the processor is stalled - if not then stall it.
// Function to check if the processor is stalled - if not then stall it.
// this is useful in the event that GDB thinks the processor is stalled, but has, in fact
// this is useful in the event that GDB thinks the processor is stalled, but has, in fact
// been hard reset on the board and is running.
// been hard reset on the board and is running.
static void gdb_ensure_or1k_stalled()
static void gdb_ensure_or1k_stalled()
{
{
  unsigned char stalled;
  unsigned char stalled;
  dbg_cpu0_read_ctrl(0, &stalled);
  dbg_cpu0_read_ctrl(0, &stalled);
  if ((stalled & 0x1) != 0x1)
        if ((stalled & 0x1) != 0x1) {
    {
 
      if (DEBUG_GDB)
      if (DEBUG_GDB)
        printf("Processor not stalled, like we thought\n");
        printf("Processor not stalled, like we thought\n");
 
 
      // Set the TAP controller to its OR1k chain
      // Set the TAP controller to its OR1k chain
      dbg_set_tap_ir(JI_DEBUG);
      dbg_set_tap_ir(JI_DEBUG);
Line 3521... Line 3448...
      printf("Stalling or1k\n");
      printf("Stalling or1k\n");
      dbg_cpu0_write_ctrl(0, 0x01);      // stall or1k
      dbg_cpu0_write_ctrl(0, 0x01);      // stall or1k
    }
    }
}
}
 
 
int gdb_write_byte(uint32_t adr, uint8_t data) {
int gdb_write_byte(uint32_t adr, uint8_t data)
 
{
 
 
#ifdef OR32_KERNEL_DBG_COMPAT
#ifdef OR32_KERNEL_DBG_COMPAT
  if (IS_VM_ADDR(adr))
        if (kernel_debug && IS_VM_ADDR(adr))
    adr = adr & ~OR32_LINUX_VM_MASK;
    adr = adr & ~OR32_LINUX_VM_MASK;
#endif
#endif
 
 
  if (DEBUG_CMDS) printf("wbyte %d\n", gdb_chain);
        if (DEBUG_CMDS)
 
                printf("wbyte %d\n", gdb_chain);
  switch (gdb_chain) {
  switch (gdb_chain) {
  case SC_WISHBONE:   return dbg_wb_write8(adr, data) ?
        case SC_WISHBONE:
      ERR_CRC : ERR_NONE;
                return dbg_wb_write8(adr, data) ? ERR_CRC : ERR_NONE;
  default:            return JTAG_PROXY_INVALID_CHAIN;
        default:
 
                return JTAG_PROXY_INVALID_CHAIN;
  }
  }
}
}
int gdb_read_byte(uint32_t adr, uint8_t *data) {
 
 
int gdb_read_byte(uint32_t adr, uint8_t * data)
 
{
 
 
#ifdef OR32_KERNEL_DBG_COMPAT
#ifdef OR32_KERNEL_DBG_COMPAT
  if (IS_VM_ADDR(adr))
        if (kernel_debug && IS_VM_ADDR(adr))
    adr = adr & ~OR32_LINUX_VM_MASK;
    adr = adr & ~OR32_LINUX_VM_MASK;
#endif
#endif
 
 
  switch (gdb_chain) {
  switch (gdb_chain) {
  case SC_WISHBONE:   return dbg_wb_read8(adr, data) ? ERR_CRC : ERR_NONE;
        case SC_WISHBONE:
  case SC_TRACE:      *data = 0; return 0;
                return dbg_wb_read8(adr, data) ? ERR_CRC : ERR_NONE;
  default:            return JTAG_PROXY_INVALID_CHAIN;
        case SC_TRACE:
 
                *data = 0;
 
                return 0;
 
        default:
 
                return JTAG_PROXY_INVALID_CHAIN;
  }
  }
}
}
 
 
 
int gdb_write_reg(uint32_t adr, uint32_t data)
int gdb_write_reg(uint32_t adr, uint32_t data) {
{
 
 
#ifdef OR32_KERNEL_DBG_COMPAT
#ifdef OR32_KERNEL_DBG_COMPAT
  if (IS_VM_ADDR(adr))
        if (kernel_debug && IS_VM_ADDR(adr))
    adr = adr & ~OR32_LINUX_VM_MASK;
    adr = adr & ~OR32_LINUX_VM_MASK;
#endif
#endif
 
 
  switch (gdb_chain) { /* remap registers, to be compatible with jp1 */
  switch (gdb_chain) { /* remap registers, to be compatible with jp1 */
  case SC_RISC_DEBUG: return dbg_cpu0_write(adr, &data, 4) ? ERR_CRC : ERR_NONE;
        case SC_RISC_DEBUG:
  case SC_REGISTER:   return dbg_cpu0_write_ctrl(adr, data) ? ERR_CRC : ERR_NONE;
                return dbg_cpu0_write(adr, &data, 4) ? ERR_CRC : ERR_NONE;
  case SC_WISHBONE:   return dbg_wb_write32(adr, data) ? ERR_CRC : ERR_NONE;
        case SC_REGISTER:
  case SC_TRACE:      return 0;
                return dbg_cpu0_write_ctrl(adr, data) ? ERR_CRC : ERR_NONE;
  default:            return JTAG_PROXY_INVALID_CHAIN;
        case SC_WISHBONE:
 
                return dbg_wb_write32(adr, data) ? ERR_CRC : ERR_NONE;
 
        case SC_TRACE:
 
                return 0;
 
        default:
 
                return JTAG_PROXY_INVALID_CHAIN;
  }
  }
}
}
int gdb_read_reg(uint32_t adr, uint32_t *data) {
 
 
int gdb_read_reg(uint32_t adr, uint32_t * data)
 
{
 
 
#ifdef OR32_KERNEL_DBG_COMPAT
#ifdef OR32_KERNEL_DBG_COMPAT
  if (IS_VM_ADDR(adr))
        if (kernel_debug && IS_VM_ADDR(adr))
    adr = adr & ~OR32_LINUX_VM_MASK;
    adr = adr & ~OR32_LINUX_VM_MASK;
#endif
#endif
 
 
  switch (gdb_chain) {
  switch (gdb_chain) {
  case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data, 4) ? ERR_CRC : ERR_NONE;
        case SC_RISC_DEBUG:
  case SC_REGISTER:   return dbg_cpu0_read_ctrl(adr, (unsigned char*)data) ?
                return dbg_cpu0_read(adr, data, 4) ? ERR_CRC : ERR_NONE;
 
        case SC_REGISTER:
 
                return dbg_cpu0_read_ctrl(adr, (unsigned char *)data) ?
      ERR_CRC : ERR_NONE;
      ERR_CRC : ERR_NONE;
  case SC_WISHBONE:   return dbg_wb_read32(adr, data) ? ERR_CRC : ERR_NONE;
        case SC_WISHBONE:
  case SC_TRACE:      *data = 0; return 0;
                return dbg_wb_read32(adr, data) ? ERR_CRC : ERR_NONE;
  default:            return JTAG_PROXY_INVALID_CHAIN;
        case SC_TRACE:
 
                *data = 0;
 
                return 0;
 
        default:
 
                return JTAG_PROXY_INVALID_CHAIN;
  }
  }
}
}
 
 
 
int gdb_read_block(uint32_t adr, uint32_t * data, int len)
int gdb_read_block(uint32_t adr, uint32_t *data, int len) {
{
 
 
#ifdef OR32_KERNEL_DBG_COMPAT
#ifdef OR32_KERNEL_DBG_COMPAT
  if (IS_VM_ADDR(adr))
        if (kernel_debug && IS_VM_ADDR(adr))
    adr = adr & ~OR32_LINUX_VM_MASK;
    adr = adr & ~OR32_LINUX_VM_MASK;
#endif
#endif
 
 
  if (DEBUG_CMDS) printf("rb %d\n", gdb_chain);
        if (DEBUG_CMDS)
 
                printf("rb %d\n", gdb_chain);
 
 
  switch (gdb_chain) {
  switch (gdb_chain) {
  case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data, len) ? ERR_CRC : ERR_NONE;
        case SC_RISC_DEBUG:
  case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ? ERR_CRC : ERR_NONE;
                return dbg_cpu0_read(adr, data, len) ? ERR_CRC : ERR_NONE;
 
        case SC_WISHBONE:
 
                return dbg_wb_read_block32(adr, data, len) ? ERR_CRC : ERR_NONE;
 
 
  default:            return JTAG_PROXY_INVALID_CHAIN;
        default:
 
                return JTAG_PROXY_INVALID_CHAIN;
  }
  }
}
}
 
 
int gdb_write_block(uint32_t adr, uint32_t *data, int len) {
int gdb_write_block(uint32_t adr, uint32_t * data, int len)
 
{
 
 
#ifdef OR32_KERNEL_DBG_COMPAT
#ifdef OR32_KERNEL_DBG_COMPAT
  if (IS_VM_ADDR(adr))
        if (kernel_debug && IS_VM_ADDR(adr))
    adr = adr & ~OR32_LINUX_VM_MASK;
    adr = adr & ~OR32_LINUX_VM_MASK;
#endif
#endif
 
 
  if (DEBUG_CMDS) printf("wb %d\n", gdb_chain);
        if (DEBUG_CMDS)
 
                printf("wb %d\n", gdb_chain);
  switch (gdb_chain) {
  switch (gdb_chain) {
  case SC_RISC_DEBUG: return dbg_cpu0_write(adr, data, (uint32_t) len) ? ERR_CRC : ERR_NONE;
        case SC_RISC_DEBUG:
  case SC_WISHBONE:   return dbg_wb_write_block32(adr, data, len) ? ERR_CRC : ERR_NONE;
                return dbg_cpu0_write(adr, data,
  default:            return JTAG_PROXY_INVALID_CHAIN;
                                      (uint32_t) len) ? ERR_CRC : ERR_NONE;
 
        case SC_WISHBONE:
 
                return dbg_wb_write_block32(adr, data,
 
                                            len) ? ERR_CRC : ERR_NONE;
 
        default:
 
                return JTAG_PROXY_INVALID_CHAIN;
  }
  }
}
}
 
 
int gdb_set_chain(int chain) {
int gdb_set_chain(int chain)
 
{
  switch (chain) {
  switch (chain) {
  case SC_RISC_DEBUG:
  case SC_RISC_DEBUG:
  case SC_REGISTER:
  case SC_REGISTER:
  case SC_TRACE:
  case SC_TRACE:
  case SC_WISHBONE:   gdb_chain = chain;
        case SC_WISHBONE:
 
                gdb_chain = chain;
    return ERR_NONE;
    return ERR_NONE;
  default:            return JTAG_PROXY_INVALID_CHAIN;
        default:
 
                return JTAG_PROXY_INVALID_CHAIN;
  }
  }
}
}
 
 
/*****************************************************************************
/*****************************************************************************
 * Close the connection to the client if it is open
 * Close the connection to the client if it is open
Line 3638... Line 3601...
    close(gdb_fd);
    close(gdb_fd);
    gdb_fd = 0;
    gdb_fd = 0;
  }
  }
}       /* client_close () */
}       /* client_close () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Swap a buffer of 4-byte from 1234 to 4321
/* Swap a buffer of 4-byte from 1234 to 4321
 
 
   parameter[in]  p_buf and len
   parameter[in]  p_buf and len
   parameter[out] none                                                                                                                                                                                                                   */
   parameter[out] none                                                                                                                                                                                                                   */
Line 3650... Line 3612...
static void swap_buf(char* p_buf, int len)
static void swap_buf(char* p_buf, int len)
{
{
  int temp;
  int temp;
  int n = 0;
  int n = 0;
 
 
  if (len > 2)
        if (len > 2) {
    {
 
      while(n < len){
      while(n < len){
        // swap 0 and 3
        // swap 0 and 3
        temp = p_buf[n];
        temp = p_buf[n];
        p_buf[n] = p_buf[n + 3];
        p_buf[n] = p_buf[n + 3];
        p_buf[n + 3] = temp;
        p_buf[n + 3] = temp;
Line 3667... Line 3628...
        n += 4;
        n += 4;
      }
      }
    }
    }
}
}
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Set the stall state of the processor
/*!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
static void set_stall_state(int state)
set_stall_state (int state)
 
{
{
 
 
  if(state == 0)
        if (state == 0) {
    {
 
      err = dbg_cpu0_write_ctrl(0, 0);     /* unstall or1k */
      err = dbg_cpu0_write_ctrl(0, 0);     /* unstall or1k */
      stallState = UNSTALLED;
      stallState = UNSTALLED;
      npcIsCached = 0;
      npcIsCached = 0;
      rsp.sigval = TARGET_SIGNAL_NONE;
      rsp.sigval = TARGET_SIGNAL_NONE;
    }
        } else {
  else
 
    {
 
      err = dbg_cpu0_write_ctrl(0, 0x01);                                 /* stall or1k */
      err = dbg_cpu0_write_ctrl(0, 0x01);                                 /* stall or1k */
      stallState = STALLED;
      stallState = STALLED;
    }
    }
 
 
  if(err > 0 && DEBUG_GDB)printf("Error %d in set_stall_state Stall state = %d\n", err, state);
        if (err > 0 && DEBUG_GDB)
 
                printf("Error %d in set_stall_state Stall state = %d\n", err,
 
                       state);
 
 
}       /* set_stall_state () */
}       /* set_stall_state () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Set the reset bit of the processor's control reg in debug interface
/*!Set the reset bit of the processor's control reg in debug interface
 */
 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void reset_or1k(void)
reset_or1k (void)
 
{
{
 
 
  //err = dbg_cpu0_write_ctrl(0, 0x02);  /* reset or1k */
  //err = dbg_cpu0_write_ctrl(0, 0x02);  /* reset or1k */
 
 
  //if(err > 0 && DEBUG_GDB)printf("Error %d in reset_or1k()\n", err);
  //if(err > 0 && DEBUG_GDB)printf("Error %d in reset_or1k()\n", err);
 
 
}       /* reset_or1k () */
}       /* reset_or1k () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Close down the connection with GDB in the event of a kill signal
/*!Close down the connection with GDB in the event of a kill signal
 
 
 */
 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void gdb_close()
void gdb_close()
{
{
  if (gdb_fd) close(gdb_fd);
        if (gdb_fd)
 
                close(gdb_fd);
  // Maybe do other things here!
  // Maybe do other things here!
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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