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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [debug/] [rsp-server.c] - Diff between revs 1752 and 1756

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

Rev 1752 Rev 1756
Line 37... Line 37...
#include <sys/socket.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <poll.h>
#include <poll.h>
#include <netinet/tcp.h>
#include <netinet/tcp.h>
 
#include <signal.h>
 
 
/* Package includes */
/* Package includes */
#include "sim-config.h"
#include "sim-config.h"
#include "except.h"
#include "except.h"
#include "opcode/or32.h"
#include "opcode/or32.h"
#include "spr-defs.h"
#include "spr-defs.h"
#include "execute.h"
#include "execute.h"
#include "debug-unit.h"
#include "debug-unit.h"
#include "sprs.h"
#include "sprs.h"
 
#include "toplevel-support.h"
 
 
 
 
/* Define to log each packet */
/* Define to log each packet */
/* #define RSP_TRACE  1 */
/* #define RSP_TRACE  1 */
 
 
Line 57... Line 59...
#define OR1KSIM_RSP_SERVICE  "or1ksim-rsp"
#define OR1KSIM_RSP_SERVICE  "or1ksim-rsp"
 
 
/*! Protocol used by Or1ksim */
/*! Protocol used by Or1ksim */
#define OR1KSIM_RSP_PROTOCOL  "tcp"
#define OR1KSIM_RSP_PROTOCOL  "tcp"
 
 
 
/*! Thread ID used by Or1ksim */
 
#define OR1KSIM_TID  1
 
 
/* Indices of GDB registers that are not GPRs. Must match GDB settings! */
/* Indices of GDB registers that are not GPRs. Must match GDB settings! */
#define PPC_REGNUM  (MAX_GPRS + 0)      /*!< Previous PC */
#define PPC_REGNUM  (MAX_GPRS + 0)      /*!< Previous PC */
#define NPC_REGNUM  (MAX_GPRS + 1)      /*!< Next PC */
#define NPC_REGNUM  (MAX_GPRS + 1)      /*!< Next PC */
#define SR_REGNUM   (MAX_GPRS + 2)      /*!< Supervision Register */
#define SR_REGNUM   (MAX_GPRS + 2)      /*!< Supervision Register */
#define NUM_REGS    (MAX_GRPS + 3)      /*!< Total GDB registers */
#define NUM_REGS    (MAX_GRPS + 3)      /*!< Total GDB registers */
Line 128... Line 133...
/*! 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? */
  int                proto_num;         /*!< Number of the protocol used */
  int                proto_num;         /*!< Number of the protocol used */
  int                server_fd;         /*!< FD for new connections */
 
  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 */
  unsigned long int  start_addr;        /*!< Start of last run */
  unsigned long int  start_addr;        /*!< Start of last run */
  struct mp_entry   *mp_hash[MP_HASH_SIZE];     /*!< Matchpoint hash table */
  struct mp_entry   *mp_hash[MP_HASH_SIZE];     /*!< Matchpoint hash table */
} rsp;
} rsp;
 
 
/* Forward declarations of static functions */
/* Forward declarations of static functions */
static void               rsp_server_request ();
static void               rsp_get_client ();
static void               rsp_client_request ();
static void               rsp_client_request ();
static void               rsp_server_close ();
 
static void               rsp_client_close ();
static void               rsp_client_close ();
static void               put_packet (struct rsp_buf *buf);
static void               put_packet (struct rsp_buf *buf);
static void               put_str_packet (const char *str);
static void               put_str_packet (const char *str);
static struct rsp_buf    *get_packet ();
static struct rsp_buf    *get_packet ();
static void               put_rsp_char (char  c);
static void               put_rsp_char (char  c);
Line 192... Line 195...
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Initialize the Remote Serial Protocol connection
/*!Initialize the Remote Serial Protocol connection
 
 
   This involves setting up a socket to listen on a socket for attempted
   Set up the central data structures.                                       */
   connections from a single GDB instance (we couldn't be talking to multiple
 
   GDBs at once!).
 
 
 
   The service is specified either as a port number in the Or1ksim configuration
 
   (parameter rsp_port in section debug, default 51000) or as a service name
 
   in the constant OR1KSIM_RSP_SERVICE.
 
 
 
   The protocol used for communication is specified in OR1KSIM_RSP_PROTOCOL. */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void
void
rsp_init ()
rsp_init ()
{
{
  struct protoent    *protocol;         /* Protocol number */
 
  struct hostent     *host_entry;       /* Our host entry */
 
  struct sockaddr_in  sock_addr;        /* Socket address */
 
 
 
  int                 optval;           /* Socket options */
 
  int                 flags;            /* Socket flags */
 
  char                name[256];        /* Our name */
 
 
 
  /* 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.proto_num      = -1;              /* i.e. invalid */
 
  rsp.server_fd      = -1;              /* i.e. invalid */
 
  rsp.client_fd      = -1;              /* i.e. invalid */
  rsp.client_fd      = -1;              /* i.e. invalid */
  rsp.sigval         =  0;               /* No exception */
  rsp.sigval         =  0;               /* No exception */
  rsp.start_addr     = EXCEPT_RESET;    /* Default restart point */
  rsp.start_addr     = EXCEPT_RESET;    /* Default restart point */
 
 
  /* Set up the matchpoint hash table */
  /* Set up the matchpoint hash table */
  mp_hash_init ();
  mp_hash_init ();
 
 
  /* Get the protocol number of TCP and save it for future use */
 
  protocol = getprotobyname (OR1KSIM_RSP_PROTOCOL);
 
  if (NULL == protocol)
 
    {
 
      fprintf (stderr, "Warning: RSP unable to load protocol \"%s\": %s\n",
 
               OR1KSIM_RSP_PROTOCOL, strerror (errno));
 
      return;
 
    }
 
 
 
  rsp.proto_num = protocol->p_proto;    /* Saved for future client use */
 
 
 
  /* 0 is used as the RSP port number to indicate that we should use the
 
     service name instead. */
 
  if (0 == config.debug.rsp_port)
 
    {
 
      struct servent *service =
 
        getservbyname (OR1KSIM_RSP_SERVICE, protocol->p_name);
 
 
 
      if (NULL == service)
 
        {
 
          fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n",
 
                   OR1KSIM_RSP_SERVICE, strerror (errno));
 
          return;
 
        }
 
 
 
      config.debug.rsp_port = ntohs (service->s_port);
 
    }
 
 
 
  /* Create the socket using the TCP protocol */
 
  rsp.server_fd = socket (PF_INET, SOCK_STREAM, protocol->p_proto);
 
  if (rsp.server_fd < 0)
 
    {
 
      fprintf (stderr, "Warning: RSP could not create server socket: %s\n",
 
               strerror (errno));
 
      return;
 
    }
 
 
 
  /* Set this socket to reuse its address. This allows the server to keep
 
     trying before a GDB session has got going. */
 
  optval = 1;
 
  if (setsockopt(rsp.server_fd, SOL_SOCKET,
 
                 SO_REUSEADDR, &optval, sizeof (optval)) < 0)
 
    {
 
      fprintf (stderr, "Cannot set SO_REUSEADDR option on server socket %d: "
 
               "%s\n", rsp.server_fd, strerror (errno));
 
      rsp_server_close();
 
      return;
 
    }
 
 
 
  /* The server should be non-blocking. Get the current flags and then set the
 
     non-blocking flags */
 
  flags = fcntl (rsp.server_fd, F_GETFL);
 
  if (flags < 0)
 
    {
 
      fprintf (stderr, "Warning: Unable to get flags for RSP server socket "
 
               "%d: %s\n", rsp.server_fd, strerror (errno));
 
      rsp_server_close();
 
      return;
 
    }
 
 
 
  flags |= O_NONBLOCK;
 
  if (fcntl (rsp.server_fd, F_SETFL, flags) < 0)
 
    {
 
      fprintf (stderr, "Warning: Unable to set flags for RSP server socket "
 
               "%d to 0x%08x: %s\n", rsp.server_fd, flags, strerror (errno));
 
      rsp_server_close();
 
      return;
 
    }
 
 
 
  /* Find out what our name is */
 
  if (gethostname (name, sizeof (name)) < 0)
 
    {
 
      fprintf (stderr, "Warning: Unable to get hostname for RSP server: %s\n",
 
               strerror (errno));
 
      rsp_server_close();
 
      return;
 
    }
 
 
 
  /* Find out what our address is */
 
  host_entry = gethostbyname (name);
 
  if (NULL == host_entry)
 
    {
 
      fprintf (stderr, "Warning: Unable to get host entry for RSP server: "
 
               "%s\n", strerror (errno));
 
      rsp_server_close();
 
      return;
 
    }
 
 
 
  /* Bind our socket to the appropriate address */
 
  memset (&sock_addr, 0, sizeof (sock_addr));
 
  sock_addr.sin_family = host_entry->h_addrtype;
 
  sock_addr.sin_port   = htons (config.debug.rsp_port);
 
 
 
  if (bind (rsp.server_fd,
 
            (struct sockaddr *)&sock_addr, sizeof (sock_addr)) < 0)
 
    {
 
      fprintf (stderr, "Warning: Unable to bind RSP server socket %d to port "
 
               "%d: %s\n", rsp.server_fd, config.debug.rsp_port,
 
               strerror (errno));
 
      rsp_server_close();
 
      return;
 
    }
 
 
 
  /* Mark us as a passive port, with a maximum backlog of 1 connection (we
 
     never connect simultaneously to more than one RSP client!) */
 
  if (listen (rsp.server_fd, 1) < 0)
 
    {
 
      fprintf (stderr, "Warning: Unable to set RSP backlog on server socket "
 
               "%d to %d: %s\n", rsp.server_fd, 1, strerror (errno));
 
      rsp_server_close();
 
      return;
 
    }
 
}       /* rsp_init () */
}       /* rsp_init () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Look for action on RSP
/*!Look for action on RSP
 
 
   This function is called when the processor has stalled, which, except for
   This function is called when the processor has stalled, which, except for
   initialization, must be due to an interrupt.
   initialization, must be due to an interrupt.
 
 
   If we have no RSP client, we poll the RSP server for a client requesting to
   If we have no RSP client, we get one. We can make no progress until the
   join. We can make no progress until the client is available.
   client is available.
 
 
   Then if the cause is an interrupt, and the interrupt not been notified to
 
   GDB, a packet reporting the cause of the interrupt is sent.
 
 
 
   The function then polls the RSP client port (if open)
 
   for available input. It then processes the GDB RSP request and return.
 
 
 
   If an error occurs when polling the RSP server, other than an interrupt, a
 
   warning message is printed out and the RSP server and client (if open)
 
   connections are closed.
 
 
 
   If an error occurs when polling the RSP client, other than an interrupt, a
   Then if the cause is an exception following a step or continue command, and
   warning message is printed out and the RSP client connection is closed.
   the exception not been notified to GDB, a packet reporting the cause of the
 
   exception is sent.
 
 
   Polling is always blocking (i.e. timeout -1).                             */
   The next client request is then processed.                                */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void
void
handle_rsp ()
handle_rsp ()
{
{
  struct pollfd  fds[1];        /* The FD to poll for */
  /* If we have no RSP client, wait until we get one. */
 
 
  /* Give up if no RSP server port (this should not occur) */
 
  if (-1 == rsp.server_fd)
 
    {
 
      fprintf (stderr, "Warning: No RSP server port open\n");
 
      return;
 
    }
 
 
 
  /* If we have no RSP client, poll the server until we get one. */
 
  while (-1 == rsp.client_fd)
  while (-1 == rsp.client_fd)
    {
    {
      /* Poll for a client on the RSP server socket */
      rsp_get_client ();
      fds[0].fd     = rsp.server_fd;     /* FD for the server socket */
 
      fds[0].events = POLLIN;            /* Poll for input activity */
 
 
 
      /* Poll is always blocking. We can't do anything more until something
 
         happens here. */
 
      switch (poll (fds, 1, -1))
 
        {
 
        case -1:
 
          /* Error. Only one we ignore is an interrupt */
 
          if (EINTR != errno)
 
            {
 
              fprintf (stderr, "Warning: poll for RSP failed: closing "
 
                       "server connection: %s\n", strerror (errno));
 
              rsp_client_close();
 
              rsp_server_close();
 
              return;
 
            }
 
          break;
 
 
 
        case 0:
 
          /* Timeout. This can't occur! */
 
          fprintf (stderr, "Warning: Unexpected RSP server poll timeout\n");
 
          break;
 
 
 
        default:
 
          /* Is the poll due to input available? If we succeed ignore any
 
             outstanding reports of exceptions. */
 
          if (POLLIN == (fds[0].revents & POLLIN))
 
            {
 
              rsp_server_request ();
 
              rsp.client_waiting = 0;            /* No longer waiting */
              rsp.client_waiting = 0;            /* No longer waiting */
            }
            }
          else
 
            {
 
              /* Error leads to closing the client and server */
 
              fprintf (stderr, "Warning: RSP server received flags "
 
                       "0x%08x: closing server connection\n", fds[0].revents);
 
              rsp_client_close();
 
              rsp_server_close();
 
            }
 
        }
 
    }
 
 
 
  /* If we have an unacknowledged exception and a client is available, tell
  /* If we have an unacknowledged exception tell the GDB client. If this
     GDB. If this exception was a trap due to a memory breakpoint, then
     exception was a trap due to a memory breakpoint, then adjust the NPC. */
     adjust the NPC. */
 
  if (rsp.client_waiting)
  if (rsp.client_waiting)
    {
    {
      if ((TARGET_SIGNAL_TRAP == rsp.sigval) &&
      if ((TARGET_SIGNAL_TRAP == rsp.sigval) &&
          (NULL != mp_hash_lookup (BP_MEMORY, cpu_state.sprs[SPR_PPC])))
          (NULL != mp_hash_lookup (BP_MEMORY, cpu_state.sprs[SPR_PPC])))
        {
        {
Line 437... Line 251...
 
 
      rsp_report_exception();
      rsp_report_exception();
      rsp.client_waiting = 0;            /* No longer waiting */
      rsp.client_waiting = 0;            /* No longer waiting */
    }
    }
 
 
  /* Poll the RSP client socket for a message from GDB */
  /* Get a RSP client request */
  fds[0].fd     = rsp.client_fd; /* FD for the client socket */
 
  fds[0].events = POLLIN;                /* Poll for input activity */
 
 
 
  /* Poll is always blocking. We can't do anything more until something
 
     happens here. */
 
  switch (poll (fds, 1, -1))
 
    {
 
    case -1:
 
      /* Error. Only one we ignore is an interrupt */
 
      if (EINTR != errno)
 
        {
 
          fprintf (stderr, "Warning: poll for RSP failed: closing "
 
                   "server connection: %s\n", strerror (errno));
 
          rsp_client_close();
 
          rsp_server_close();
 
        }
 
 
 
      return;
 
 
 
    case 0:
 
      /* Timeout. This can't occur! */
 
      fprintf (stderr, "Warning: Unexpected RSP client poll timeout\n");
 
      return;
 
 
 
    default:
 
      /* Is the client activity due to input available? */
 
      if (POLLIN == (fds[0].revents & POLLIN))
 
        {
 
          rsp_client_request ();
          rsp_client_request ();
        }
 
      else
 
        {
 
          /* Error leads to closing the client, but not the server. */
 
          fprintf (stderr, "Warning: RSP client received flags "
 
                   "0x%08x: closing client connection\n", fds[0].revents);
 
          rsp_client_close();
 
        }
 
    }
 
}       /* handle_rsp () */
}       /* handle_rsp () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Note an exception for future processing
/*!Note an exception for future processing
Line 530... Line 308...
 
 
}       /* rsp_exception () */
}       /* rsp_exception () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a request to the server for a new client
/*!Get a new client connection.
 
 
 
   Blocks until the client connection is available.
 
 
 
   A lot of this code is copied from remote_open in gdbserver remote-utils.c.
 
 
 
   This involves setting up a socket to listen on a socket for attempted
 
   connections from a single GDB instance (we couldn't be talking to multiple
 
   GDBs at once!).
 
 
   We may already have a client. If we do, we will accept an immediately close
   The service is specified either as a port number in the Or1ksim configuration
   the new client.                                                           */
   (parameter rsp_port in section debug, default 51000) or as a service name
 
   in the constant OR1KSIM_RSP_SERVICE.
 
 
 
   The protocol used for communication is specified in OR1KSIM_RSP_PROTOCOL. */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
rsp_server_request ()
rsp_get_client ()
{
{
  struct sockaddr_in  sock_addr;        /* The socket address */
  int                 tmp_fd;           /* Temporary descriptor for socket */
 
  int                 optval;           /* Socket options */
 
  struct sockaddr_in  sock_addr;        /* Socket address */
  socklen_t           len;              /* Size of the socket address */
  socklen_t           len;              /* Size of the socket address */
  int                 fd;               /* The client FD */
 
  int                 flags;            /* fcntl () flags */
 
  int                 optval;           /* Option value for setsockopt () */
 
 
 
  /* Get the client FD */
 
  len = sizeof (sock_addr);
 
  fd  = accept (rsp.server_fd, (struct sockaddr *)&sock_addr, &len);
 
  if (fd < 0)
 
    {
 
      /* This is can happen, because a connection could have started, and then
 
         terminated due to a protocol error or user initiation before the
 
         accept could take place.
 
 
 
         Two of the errors we can ignore (a retry is permissible). All other
  /* 0 is used as the RSP port number to indicate that we should use the
         errors, we assume the server port has gone tits up and close. */
     service name instead. */
 
  if (0 == config.debug.rsp_port)
 
    {
 
      struct servent *service =
 
        getservbyname (OR1KSIM_RSP_SERVICE, "tcp");
 
 
      if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
      if (NULL == service)
        {
        {
          fprintf (stderr, "Warning: RSP server error creating client: "
          fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n",
                   "closing connection %s\n", strerror (errno));
                   OR1KSIM_RSP_SERVICE, strerror (errno));
          rsp_client_close ();
          return;
          rsp_server_close ();
 
        }
        }
 
 
      return;
      config.debug.rsp_port = ntohs (service->s_port);
    }
    }
 
 
  /* If we already have a client, then immediately close the new one */
  /* Open a socket on which we'll listen for clients */
  if (-1 != rsp.client_fd)
  tmp_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
 
  if (tmp_fd < 0)
    {
    {
      fprintf (stderr, "Warning: Additional RSP client request refused\n");
      fprintf (stderr, "ERROR: Cannot open RSP socket\n");
      close (fd);
      sim_done ();
      return;
 
    }
    }
 
 
  /* We have a new client, which should be non-blocking. Get the current flags
  /* Allow rapid reuse of the port on this socket */
     and then set the non-blocking flags */
  optval = 1;
  flags = fcntl (fd, F_GETFL);
  setsockopt (tmp_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval,
  if (flags < 0)
              sizeof (optval));
 
 
 
  /* Bind the port to the socket */
 
  sock_addr.sin_family      = PF_INET;
 
  sock_addr.sin_port        = htons (config.debug.rsp_port);
 
  sock_addr.sin_addr.s_addr = INADDR_ANY;
 
  if (bind (tmp_fd, (struct sockaddr *) &sock_addr, sizeof (sock_addr)))
    {
    {
      fprintf (stderr, "Warning: Unable to get flags for RSP client socket "
      fprintf (stderr, "ERROR: Cannot bind to RSP socket\n");
               "%d: %s\n", fd, strerror (errno));
      sim_done ();
      close (fd);
 
      return;
 
    }
    }
 
 
  flags |= O_NONBLOCK;
  /* Listen for (at most one) client */
  if (fcntl (fd, F_SETFL, flags) < 0)
  if (listen (tmp_fd, 1))
    {
    {
      fprintf (stderr, "Warning: Unable to set flags for RSP client socket "
      fprintf (stderr, "ERROR: Cannot listen on RSP socket\n");
               "%d to 0x%08x: %s\n", fd, flags, strerror (errno));
      sim_done ();
      close (fd);
 
      return;
 
    }
    }
 
 
  /* Turn of Nagel's algorithm for the client socket. This means the client
  printf ("Listening for RSP on port %d\n", config.debug.rsp_port);
     sends stuff immediately, it doesn't wait to fill up a packet. */
  fflush (stdout);
  optval = 0;
 
  len    = sizeof (optval);
  /* Accept a client which connects */
  if (setsockopt (fd, rsp.proto_num, TCP_NODELAY, &optval, len) < 0)
  rsp.client_fd = accept (tmp_fd, (struct sockaddr *)&sock_addr, &len);
 
 
 
  if (-1 == rsp.client_fd)
    {
    {
      fprintf (stderr, "Warning: Unable to disable Nagel's algorithm for "
      fprintf (stderr, "Warning: Failed to accept RSP client\n");
               "RSP client socket %d: %s\n", fd, strerror (errno));
 
      close (fd);
 
      return;
      return;
    }
    }
 
 
  /* We have a new client socket */
  /* Enable TCP keep alive process */
  rsp.client_fd = fd;
  optval = 1;
 
  setsockopt (rsp.client_fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval,
 
              sizeof (optval));
 
 
 
  /* Don't delay small packets, for better interactive response (disable
 
     Nagel's algorithm) */
 
  optval = 1;
 
  setsockopt (rsp.client_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval,
 
              sizeof (optval));
 
 
 
  /* Socket is no longer needed */
 
  close (tmp_fd);                       /* No longer need this */
 
  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));
 
 
 
  /* If fcntl () is available, use it to enable async I/O
 
#if defined(F_SETFL) && defined (FASYNC)
 
  save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
 
  fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
 
#if defined (F_SETOWN)
 
  fcntl (remote_desc, F_SETOWN, getpid ());
 
#endif
 
#endif */
 
 
}       /* rsp_server_request () */
}       /* rsp_get_client () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Deal with a request from the GDB client session
/*!Deal with a request from the GDB client session
 
 
Line 691... Line 498...
         meaning? Or does it just mean that only vAttach will be recognized
         meaning? Or does it just mean that only vAttach will be recognized
         after this? */
         after this? */
      put_str_packet ("OK");
      put_str_packet ("OK");
      rsp_client_close ();
      rsp_client_close ();
      set_stall_state (0);
      set_stall_state (0);
 
      rsp.sigval = TARGET_SIGNAL_NONE;  /* No signal now */
      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' "
Line 825... Line 633...
    }
    }
}       /* rsp_client_request () */
}       /* rsp_client_request () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Close the server if it is open                                            */
/*!Close the connection to the client if it is open                          */
/*---------------------------------------------------------------------------*/
 
static void
 
rsp_server_close ()
 
{
 
  if (-1 != rsp.server_fd)
 
    {
 
      close (rsp.server_fd);
 
      rsp.server_fd = -1;
 
    }
 
}       /* rsp_server_close () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Close the client if it is open                                            */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
rsp_client_close ()
rsp_client_close ()
{
{
  if (-1 != rsp.client_fd)
  if (-1 != rsp.client_fd)
Line 1127... Line 921...
   @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 ()
{
{
  unsigned char  c;             /* The character read */
 
 
 
  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;
    }
    }
 
 
  /* Read until successful (we retry after interrupts) or catastrophic
  /* Non-blocking read until successful (we retry after interrupts) or
     failure. */
     catastrophic failure. */
  while (1)
  while (1)
    {
    {
 
      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 or would block */
          /* Error: only allow interrupts */
          if ((EAGAIN != errno) && (EINTR != errno))
          if ((EAGAIN != errno) && (EINTR != errno))
            {
            {
              fprintf (stderr, "Warning: Failed to read from RSP client: "
              fprintf (stderr, "Warning: Failed to read from RSP client: "
                       "Closing client connection: %s\n",
                       "Closing client connection: %s\n",
                       strerror (errno));
                       strerror (errno));
Line 1609... Line 1403...
  cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
  cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
 
 
  /* Unstall the processor */
  /* Unstall the processor */
  set_stall_state (0);
  set_stall_state (0);
 
 
 
  /* Any signal is cleared. */
 
  rsp.sigval = TARGET_SIGNAL_NONE;
 
 
  /* 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 () */
 
 
Line 1844... Line 1641...
rsp_read_reg (struct rsp_buf *buf)
rsp_read_reg (struct rsp_buf *buf)
{
{
  unsigned int  regnum;
  unsigned int  regnum;
 
 
  /* Break out the fields from the data */
  /* Break out the fields from the data */
  if (2 != sscanf (buf->data, "p%x", &regnum))
  if (1 != sscanf (buf->data, "p%x", &regnum))
    {
    {
      fprintf (stderr, "Warning: Failed to recognize RSP read register "
      fprintf (stderr, "Warning: Failed to recognize RSP read register "
               "command: %s\n", buf->data);
               "command: %s\n", buf->data);
      put_str_packet ("E01");
      put_str_packet ("E01");
      return;
      return;
Line 1944... Line 1741...
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Handle a RSP query request
/*!Handle a RSP query request
 
 
   @param[in] buf  The request                                               */
   @param[in] buf  The request. Reused for any packets that need to be sent
 
                   back.                                                     */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
rsp_query (struct rsp_buf *buf)
rsp_query (struct rsp_buf *buf)
{
{
  if (0 == strcmp ("qC", buf->data))
  if (0 == strcmp ("qC", 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. We use the constant
         support a thread concept, this is the appropriate response. */
         OR1KSIM_TID to represent our single thread of control. */
      put_str_packet ("");
      sprintf (buf->data, "QC%x", OR1KSIM_TID);
 
      buf->len = strlen (buf->data);
 
      put_packet (buf);
    }
    }
  else if (0 == strncmp ("qCRC", buf->data, strlen ("qCRC")))
  else if (0 == strncmp ("qCRC", 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", buf->data))
  else if (0 == strcmp ("qfThreadInfo", buf->data))
    {
    {
      /* Return info about active threads. We return just '-1' */
      /* Return info about active threads. We return just the constant
      put_str_packet ("m-1");
         OR1KSIM_TID to represent our single thread of control. */
 
      sprintf (buf->data, "m%x", OR1KSIM_TID);
 
      buf->len = strlen (buf->data);
 
      put_packet (buf);
    }
    }
  else if (0 == strcmp ("qsThreadInfo", buf->data))
  else if (0 == strcmp ("qsThreadInfo", 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' */
Line 2082... Line 1885...
          put_str_packet ("E01");
          put_str_packet ("E01");
          return;
          return;
        }
        }
 
 
      /* Construct the reply */
      /* Construct the reply */
      sprintf (cmd, "%8x", mfspr (regno));
      sprintf (cmd, "%8lx", (unsigned long int)mfspr (regno));
      ascii2hex (buf->data, cmd);
      ascii2hex (buf->data, cmd);
      buf->len = strlen (buf->data);
      buf->len = strlen (buf->data);
      put_packet (buf);
      put_packet (buf);
    }
    }
  else if (0 == strncmp ("writespr ", cmd, strlen ("writespr")))
  else if (0 == strncmp ("writespr ", cmd, strlen ("writespr")))
Line 2242... Line 2045...
  cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
  cpu_state.sprs[SPR_DSR]  |= SPR_DSR_TE;
 
 
  /* Unstall the processor */
  /* Unstall the processor */
  set_stall_state (0);
  set_stall_state (0);
 
 
 
  /* Any signal is cleared. */
 
  rsp.sigval = TARGET_SIGNAL_NONE;
 
 
  /* 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 () */
 
 
Line 2391... Line 2197...
          put_str_packet ("E01");
          put_str_packet ("E01");
          return;
          return;
        }
        }
      else
      else
        {
        {
          // circumvent the read-only check usually done for mem accesses
          // Circumvent the read-only check usually done for mem accesses
          // data is in host order, because that's what set_direct32 needs
 
          set_program8 (addr + off, bindat[off]);
          set_program8 (addr + off, bindat[off]);
        }
        }
    }
    }
 
 
  put_str_packet ("OK");
  put_str_packet ("OK");

powered by: WebSVN 2.1.0

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