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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_61/] [or1ksim/] [toplevel.c] - Diff between revs 294 and 304

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

Rev 294 Rev 304
Line 27... Line 27...
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#include <signal.h>
#include <signal.h>
#include <stdarg.h>
#include <stdarg.h>
/* Added by CZ 24/05/01 */
 
#include <sys/stat.h>
 
#include <sys/types.h>
 
#include <sys/socket.h>
 
#include <netinet/in.h>
 
#include <sys/select.h>
 
#include <sys/poll.h>
 
#include <fcntl.h>
#include <fcntl.h>
#include <netdb.h>
 
#include <netinet/tcp.h>
 
#include <inttypes.h>
 
 
 
#ifdef HAVE_LIBREADLINE
#ifdef HAVE_LIBREADLINE
#include <readline/readline.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <readline/history.h>
#endif /* HAVE_LIBREADLINE */
#endif /* HAVE_LIBREADLINE */
Line 53... Line 43...
#include "trace.h"
#include "trace.h"
#include "execute.h"
#include "execute.h"
#include "sim-config.h"
#include "sim-config.h"
#include "spr_defs.h"
#include "spr_defs.h"
#include "dma.h"
#include "dma.h"
 
#include "vapi.h"
 
 
#include "coff.h"
#include "coff.h"
 
 
/* Added by CZ 24/05/01 */
#include "gdbcomm.h"
#include "gdb.h"
 
#include <signal.h>
 
#include <errno.h>
 
typedef enum {
 
  false = 0,
 
  true = 1,
 
} Boolean;
 
unsigned int serverIP = 0;
 
unsigned int serverPort = 0;
 
unsigned int server_fd = 0;
 
unsigned int gdb_fd = 0;
 
void HandleServerSocket(Boolean);
 
void JTAGRequest(void);
 
void GDBRequest(void);
 
void ProtocolClean(int,int32_t);
 
static int gdb_read(void*,int);
 
static int gdb_write(void*,int);
 
void BlockJTAG(void);
 
 
 
/* CVS revision number. */
/* CVS revision number. */
const char rcsrev[] = "$Revision: 1.37 $";
const char rcsrev[] = "$Revision: 1.38 $";
 
 
/* Continuos run versus single step tracing switch. */
/* Continuos run versus single step tracing switch. */
int cont_run;
int cont_run;
 
 
/* History of execution */
/* History of execution */
Line 134... Line 107...
  free(p);
  free(p);
#endif
#endif
  }
  }
}
}
 
 
/* Strip whitespace from the start and end of STRING.  Return a pointer
void ctrl_c(signum)
   into STRING. */
 
#ifndef whitespace
 
#define whitespace(a)   ((a) == '\t' ? 1 : ((a) == ' '? 1 : 0))
 
#endif
 
 
 
char *
 
stripwhite (string)
 
     char *string;
 
{
 
  register char *s, *t;
 
 
 
  for (s = string; whitespace (*s); s++)
 
    ;
 
 
 
  if (*s == 0)
 
    return (s);
 
 
 
  t = s + strlen (s) - 1;
 
  while (t > s && whitespace (*t))
 
    t--;
 
  *++t = '\0';
 
 
 
  return s;
 
}
 
 
 
void
 
ctrl_c(signum)
 
     int signum;
     int signum;
{
{
  extern int cpu_stalled;  /* CZ from debug_interface */
  extern int cpu_stalled;  /* CZ from debug_interface */
  cont_run = cpu_stalled ? 0 : 1;
  cont_run = cpu_stalled ? 0 : 1;
  config.sim.iprompt = 1;
  config.sim.iprompt = 1;
  cpu_stalled = 0;
  cpu_stalled = 0;
  signal(SIGINT, ctrl_c);
  signal(SIGINT, ctrl_c);
}
}
 
 
void
void version()
version()
 
{
{
        printf ("\n");
        printf ("\n");
        printf ("OpenRISC 1000 (OR16+OR32) Architectural Simulator, %s\n", rcsrev);
        printf ("OpenRISC 1000 (OR16+OR32) Architectural Simulator, %s\n", rcsrev);
        printf ("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
        printf ("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
        printf ("Copyright (C) 2000 Damjan Lampret, lampret@opencores.org\n");
        printf ("Copyright (C) 2000 Damjan Lampret, lampret@opencores.org\n");
Line 218... Line 163...
        printf("help                     - available commands (this list)\n");
        printf("help                     - available commands (this list)\n");
}
}
 
 
void debugmem( unsigned long from, unsigned long to );
void debugmem( unsigned long from, unsigned long to );
 
 
main(argc, argv)
/* Initalizes all devices and sim */
     int argc;
void sim_init ()
     char *argv[];
 
{
{
        char *linestr;
 
        char item1[500], b2[500], prev_str[500] = "";
 
        char *redirstr;
 
        int hush = 0;
 
        unsigned long endaddr = 0xFFFFFFFF;
 
        int first_prompt = 1;
 
        int trace_fd = 0;
 
 
 
        srand(getpid());
 
        init_defconfig();
 
        if (parse_args(argc, argv)) {
 
                printf("Usage: %s [options] <filename>\n", argv[0]);
 
                printf("Options:\n");
 
                printf(" -v                 version and copyright note\n");
 
                printf(" -i                 enable interactive command prompt\n");
 
                printf(" -f or --file       change script file [sim.cfg]\n");
 
                printf(" --nosrv            do not launch JTAG proxy server\n"); /* (CZ) */
 
                printf(" --srv <n>          launch JTAG proxy server on port <n>; [random]\n"); /* (CZ) */
 
                printf(" --profile          enable profiling\n");
 
                exit(-1);
 
        }
 
 
 
#ifdef HAVE_LIBREADLINE
 
  initialize_readline ();       /* Bind our completer. */
 
#endif
 
 
 
  /* Read configuration file.  */
 
  read_script_file(config.script_file);
 
  print_config();
 
  init_labels();
  init_labels();
  init_breakpoints();
  init_breakpoints();
        signal(SIGINT, ctrl_c);
 
        initstats();
        initstats();
        build_automata();
        build_automata();
 
 
  if(GDB_ENABLED) {
  if(GDB_ENABLED) {
    serverPort = config.debug.server_port;
    serverPort = config.debug.server_port;
Line 310... Line 224...
            exit(1);
            exit(1);
    }
    }
  }
  }
 
 
        if(config.filename) {
        if(config.filename) {
 
          unsigned long endaddr = 0xFFFFFFFF;
          endaddr = loadcode(config.filename, 0, 0); /* MM170901 always load at address zero.  */
          endaddr = loadcode(config.filename, 0, 0); /* MM170901 always load at address zero.  */
          if (endaddr == -1) {
          if (endaddr == -1) {
            fprintf(stderr, "Problems loading boot code.\n");
            fprintf(stderr, "Problems loading boot code.\n");
            exit(1);
            exit(1);
          }
          }
Line 329... Line 244...
        tick_reset();
        tick_reset();
        pm_reset();
        pm_reset();
        pic_reset();
        pic_reset();
        mc_reset();
        mc_reset();
        reset();
        reset();
 
}
 
 
 
/* Display info about various modules */
 
void sim_info () {
 
  itlb_status(-1);
 
        dtlb_status(-1);
 
        ic_info();
 
        dc_info();
 
        sprs_status();
 
 
 
        if (config.cpu.bpb) bpb_info();
 
        if (config.cpu.btic) btic_info();
 
        if (config.uarts_enabled) uart_status();
 
        if (config.dmas_enabled) dma_status();
 
        if (config.ethernets_enabled) eth_status();
 
}
 
 
 
/* Cleanup */
 
void sim_done ()
 
{
 
  if (config.sim.profile) {
 
    extern int cycles;
 
    fprintf(config.sim.fprof,"-%08X FFFFFFFF\n", cycles);
 
    fclose(config.sim.fprof);
 
  }
 
  if (config.sim.exe_log)   fclose(config.sim.fexe_log);
 
  if (config.vapi.enabled)  vapi_done ();
 
  exit(0);
 
}
 
 
 
int main(argc, argv)
 
     int argc;
 
     char *argv[];
 
{
 
        char *linestr;
 
        char item1[500], b2[500], prev_str[500] = "";
 
        char *redirstr;
 
        int hush = 0;
 
        int first_prompt = 1;
 
        int trace_fd = 0;
 
 
 
        srand(getpid());
 
        init_defconfig();
 
        if (parse_args(argc, argv)) {
 
                printf("Usage: %s [options] <filename>\n", argv[0]);
 
                printf("Options:\n");
 
                printf(" -v                 version and copyright note\n");
 
                printf(" -i                 enable interactive command prompt\n");
 
                printf(" -f or --file       change script file [sim.cfg]\n");
 
                printf(" --nosrv            do not launch JTAG proxy server\n"); /* (CZ) */
 
                printf(" --srv <n>          launch JTAG proxy server on port <n>; [random]\n"); /* (CZ) */
 
                printf(" --profile          enable profiling\n");
 
                exit(-1);
 
        }
 
 
 
#ifdef HAVE_LIBREADLINE
 
  initialize_readline ();       /* Bind our completer. */
 
#endif
 
 
 
  /* Read configuration file.  */
 
  read_script_file(config.script_file);
 
  print_config();
 
  signal(SIGINT, ctrl_c);
 
  sim_init ();
 
 
        while(1) {
        while(1) {
                if (config.sim.iprompt) {
                if (config.sim.iprompt) {
                  if(server_fd)
                  if (GDB_ENABLED && server_fd)
                    {
                    {
                      printf ("(sim) ");
                      printf ("(sim) ");
                      fflush(stdout);
                      fflush(stdout);
                      HandleServerSocket(true);  /* block & check_stdin = true */
                      HandleServerSocket(true);  /* block & check_stdin = true */
                    }
                    }
Line 390... Line 369...
                  strcpy (&prev_str[0], linestr);
                  strcpy (&prev_str[0], linestr);
 
 
                strtoken(linestr, item1, 1);
                strtoken(linestr, item1, 1);
                if (strcmp(item1, "q") == 0) {   /* quit */
                if (strcmp(item1, "q") == 0) {   /* quit */
                  printf ("\n");
                  printf ("\n");
                  if (config.sim.profile) {
                  sim_done ();
                    extern int cycles;
 
                    fprintf(config.sim.fprof,"-%08X FFFFFFFF\n", cycles);
 
                    fclose(config.sim.fprof);
 
                  }
 
                  if (config.sim.exe_log)
 
                    fclose(config.sim.fexe_log);
 
                  exit(0);
 
                } else
                } else
                if (strcmp(item1, "help") == 0)  /* help */
                if (strcmp(item1, "help") == 0)  /* help */
                        help();
                        help();
                else
                else
                if (strcmp(item1, "t") == 0) {   /* trace */
                if (strcmp(item1, "t") == 0) {   /* trace */
Line 600... Line 572...
                        } else {
                        } else {
                                i = strtoul(item2, NULL, 0);
                                i = strtoul(item2, NULL, 0);
                                printstats(i);
                                printstats(i);
                        }
                        }
                } else
                } else
                if (strcmp(item1, "info") == 0) { /* configuration info */
                if (strcmp(item1, "info") == 0) /* configuration info */
                        itlb_status(-1);
                        sim_info ();
                        dtlb_status(-1);
                else
                        bpb_info();
 
                        btic_info();
 
                        ic_info();
 
                        dc_info();
 
                        uart_status();
 
                        sprs_status();
 
                        dma_status();
 
                        eth_status();
 
                } else {
 
                        printf("%s: Unknown command.\n", linestr);
                        printf("%s: Unknown command.\n", linestr);
                }
 
 
 
                /* MM: 'run -1' means endless execution.  */
                /* MM: 'run -1' means endless execution.  */
                while(cont_run != 0) {
                while(cont_run != 0) {
                  int debug_slowdown = DEBUG_SLOWDOWN;
                  int debug_slowdown = DEBUG_SLOWDOWN;
                  extern int cycle_delay;  /* Added by CZ 27/05/01. Set during exception. */
                  extern int cycle_delay;  /* Added by CZ 27/05/01. Set during exception. */
Line 630... Line 593...
                continue;
                continue;
              } else
              } else
                fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled.");
                fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled.");
 
 
      if (!testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
      if (!testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
        if(cycle_delay <= 0)
        if(cycle_delay <= 0) {
          {
 
            unsigned int addr;
            unsigned int addr;
            if (cont_run > 0) cont_run--;
            if (cont_run > 0) cont_run--;
            if(fetch()) {
            if(fetch()) {
              cont_run = 0; /* memory breakpoint encountered */
              cont_run = 0; /* memory breakpoint encountered */
              break;
              break;
Line 644... Line 606...
 
 
            /* If trace_fd is non zero, we want
            /* If trace_fd is non zero, we want
               to make sure that disassemble is called */
               to make sure that disassemble is called */
 
 
            decode_execute(&iqueue[0],trace_fd);
            decode_execute(&iqueue[0],trace_fd);
            if(trace_fd)
          if(trace_fd) {
              {
 
                char sTemp[256];
                char sTemp[256];
                char sTemp2[256];
                char sTemp2[256];
                unsigned long value;
                unsigned long value;
                extern char *disassembled;
                extern char *disassembled;
                extern unsigned long reg[];
                extern unsigned long reg[];
Line 676... Line 637...
              }
              }
            update_pc();
            update_pc();
            analysis();
            analysis();
            if (!hush)
            if (!hush)
              dumpreg();
              dumpreg();
          }
        } else
        else
 
          cycle_delay--;
          cycle_delay--;
 
 
        pic_clock();
        pic_clock();
        dc_clock();
        dc_clock();
        ic_clock();
        ic_clock();
 
        if (!testsprbits(SPR_PMR, SPR_PMR_SME)) tick_clock();
      }
      }
      if (!testsprbits(SPR_PMR, SPR_PMR_SME))
 
        tick_clock();
 
      pm_clock();
 
      uart_clock();
 
      dma_clock();
 
      eth_clock();
 
      if (config.sim.exe_log)
 
        dump_exe_log();
 
 
 
      /*if (config.vapi.enabled)
      pm_clock();
        vapi_check();*/
      if (config.uarts_enabled) uart_clock();
 
      if (config.dmas_enabled) dma_clock();
 
      if (config.ethernets_enabled) eth_clock();
 
      if (config.sim.exe_log) dump_exe_log();
 
      if (config.vapi.enabled) vapi_check();
      if (GDB_ENABLED && debug_slowdown-- == 0) {
      if (GDB_ENABLED && debug_slowdown-- == 0) {
        debug_slowdown = DEBUG_SLOWDOWN;
        debug_slowdown = DEBUG_SLOWDOWN;
                          HandleServerSocket(false); /* block & check_stdin = false */
                          HandleServerSocket(false); /* block & check_stdin = false */
                        }
                        }
                }
                }
                hush = 0;
                hush = 0;
                fflush(stdout);
                fflush(stdout);
                freopen("/dev/fd/0", "w+", stdout);
                freopen("/dev/fd/0", "w+", stdout);
 
 
                if (!config.sim.iprompt) {      /* non-interactive quit */
                if (!config.sim.iprompt)        /* non-interactive quit */
                  if (config.sim.profile) {
                  sim_done();
                    extern int cycles;
 
                    fprintf(config.sim.fprof,"-%08X FFFFFFFF\n", cycles);
 
                    fclose(config.sim.fprof);
 
                  }
 
                  if (config.sim.exe_log)
 
                    fclose(config.sim.fexe_log);
 
                  exit(0);
 
                }
 
#ifdef HAVE_LIBREADLINE
#ifdef HAVE_LIBREADLINE
                if (linestr)
                if (linestr)
                        free (linestr);
                        free (linestr);
#endif
#endif
 
 
        }
        }
        exit(0);
        sim_done();
}
}
 
 
#ifdef HAVE_LIBREADLINE
#ifdef HAVE_LIBREADLINE
char *command_generator ();
char *command_generator ();
char **sim_completion ();
char **sim_completion ();
Line 795... Line 745...
 
 
  /* If no names matched, then return NULL. */
  /* If no names matched, then return NULL. */
  return ((char *)NULL);
  return ((char *)NULL);
}
}
 
 
char *
 
dupstr (s)
 
     char *s;
 
{
 
  char *r;
 
 
 
  r = xmalloc (strlen (s) + 1);
 
  strcpy (r, s);
 
  return (r);
 
}
 
 
 
/* Repeats the last command.  */
/* Repeats the last command.  */
char *
char *
repeat_last_command ()
repeat_last_command ()
{
{
  int offset = where_history ();
  int offset = where_history ();
Line 843... Line 782...
    printf("%08x %s\n", _insn, disassembled);
    printf("%08x %s\n", _insn, disassembled);
                i += insn_len( iqueue[0].insn_index );
                i += insn_len( iqueue[0].insn_index );
  }
  }
}
}
 
 
static int tcp_level = 0;
 
 
 
/* Added by CZ 24/05/01 */
 
int GetServerSocket(const char* name,const char* proto,int port)
 
{
 
  struct servent *service;
 
  struct protoent *protocol;
 
  struct sockaddr_in sa;
 
  struct hostent *hp;
 
  int sockfd;
 
  char myname[256];
 
  int flags;
 
  char sTemp[256];
 
 
 
  /* First, get the protocol number of TCP */
 
  if(!(protocol = getprotobyname(proto)))
 
    {
 
      sprintf(sTemp,"Unable to load protocol \"%s\"",proto);
 
      perror(sTemp);
 
      return 0;
 
    }
 
  tcp_level = protocol->p_proto; /* Save for later */
 
 
 
  /* If we weren't passed a non standard port, get the port
 
     from the services directory. */
 
  if(!port)
 
    {
 
      if(service = getservbyname(name,protocol->p_name))
 
        port = ntohs(service->s_port);
 
    }
 
 
 
  /* Create the socket using the TCP protocol */
 
  if((sockfd = socket(PF_INET,SOCK_STREAM,protocol->p_proto)) < 0)
 
    {
 
      perror("Unable to create socket");
 
      return 0;
 
    }
 
 
 
  flags = 1;
 
  if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&flags,sizeof(int)) < 0)
 
    {
 
      sprintf(sTemp,"Can not set SO_REUSEADDR option on socket %d",sockfd);
 
      perror(sTemp);
 
      close(sockfd);
 
      return 0;
 
    }
 
 
 
  /* The server should also be non blocking. Get the current flags. */
 
  if(fcntl(sockfd,F_GETFL,&flags) < 0)
 
    {
 
      sprintf(sTemp,"Unable to get flags for socket %d",sockfd);
 
      perror(sTemp);
 
      close(sockfd);
 
      return 0;
 
    }
 
 
 
  /* Set the nonblocking flag */
 
  if(fcntl(sockfd,F_SETFL, flags | O_NONBLOCK) < 0)
 
    {
 
      sprintf(sTemp,"Unable to set flags for socket %d to value 0x%08x",
 
              sockfd,flags | O_NONBLOCK);
 
      perror(sTemp);
 
      close(sockfd);
 
      return 0;
 
    }
 
 
 
  /* Find out what our address is */
 
  memset(&sa,0,sizeof(struct sockaddr_in));
 
  gethostname(myname,sizeof(myname));
 
  if(!(hp = gethostbyname(myname)))
 
    {
 
      perror("Unable to read hostname");
 
      close(sockfd);
 
      return 0;
 
    }
 
 
 
  /* Bind our socket to the appropriate address */
 
  sa.sin_family = hp->h_addrtype;
 
  sa.sin_port = htons(port);
 
  if(bind(sockfd,(struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0)
 
    {
 
      sprintf(sTemp,"Unable to bind socket %d to port %d",sockfd,port);
 
      perror(sTemp);
 
      close(sockfd);
 
      return 0;
 
    }
 
  serverIP = sa.sin_addr.s_addr;
 
  flags = sizeof(struct sockaddr_in);
 
  if(getsockname(sockfd,(struct sockaddr*)&sa,&flags) < 0)
 
    {
 
      sprintf(sTemp,"Unable to get socket information for socket %d",sockfd);
 
      perror(sTemp);
 
      close(sockfd);
 
      return 0;
 
    }
 
  serverPort = ntohs(sa.sin_port);
 
 
 
  /* Set the backlog to 1 connections */
 
  if(listen(sockfd,1) < 0)
 
    {
 
      sprintf(sTemp,"Unable to set backlog on socket %d to %d",sockfd,1);
 
      perror(sTemp);
 
      close(sockfd);
 
      return 0;
 
    }
 
 
 
  return sockfd;
 
}
 
 
 
void BlockJTAG()
 
{
 
  struct pollfd fds[2];
 
  int n = 0;
 
 
 
  fds[n].fd = server_fd;
 
  fds[n].events = POLLIN;
 
  fds[n++].revents = 0;
 
  if(gdb_fd)
 
    {
 
      fds[n].fd = gdb_fd;
 
      fds[n].events = POLLIN;
 
      fds[n++].revents = 0;
 
    }
 
  poll(fds,n,-1);
 
}
 
 
 
void HandleServerSocket(Boolean block)
 
{
 
  struct pollfd fds[3];
 
  int n = 0;
 
  int timeout = block ? -1 : 0;
 
  int server_index = -1;
 
  int gdb_index = -1;
 
  Boolean data_on_stdin = false;
 
  int o_serv_fd = server_fd;
 
 
 
  if(!o_serv_fd && !gdb_fd)
 
    return;
 
 
 
  if(o_serv_fd)
 
    {
 
      fds[n].fd = o_serv_fd;
 
      fds[n].events = POLLIN;
 
      fds[n++].revents = 0;
 
    }
 
  if(gdb_fd)
 
    {
 
      fds[n].fd = gdb_fd;
 
      fds[n].events = POLLIN;
 
      fds[n++].revents = 0;
 
    }
 
  if(block)
 
    {
 
      fds[n].fd = 0;
 
      fds[n].events = POLLIN;
 
      fds[n++].revents = 0;
 
    }
 
 
 
  while(!data_on_stdin)
 
    {
 
      switch(poll(fds,n,timeout))
 
        {
 
        case -1:
 
          if(errno == EINTR)
 
            continue;
 
          perror("poll");
 
          server_fd = 0;
 
          break;
 
        case 0: /* Nothing interesting going on */
 
          data_on_stdin = true; /* Can only get here if nonblocking */
 
          break;
 
        default:
 
          /* Make sure to handle the gdb port first! */
 
          if((fds[0].revents && (gdb_fd && !o_serv_fd) ||
 
              fds[1].revents && (server_fd && gdb_fd)))
 
            {
 
              int revents = o_serv_fd ? fds[1].revents : fds[0].revents;
 
 
 
              if(revents & POLLIN)
 
                GDBRequest();
 
              else /* Error Occurred */
 
                {
 
                  fprintf(stderr,"Received flags 0x%08x on gdb socket. Shutting down.\n",revents);
 
                  close(gdb_fd);
 
                  gdb_fd = 0;
 
                }
 
            }
 
          if(fds[0].revents && o_serv_fd)
 
            {
 
              if(fds[0].revents & POLLIN)
 
                JTAGRequest();
 
              else /* Error Occurred */
 
                {
 
                  fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n",fds[0].revents);
 
                  close(o_serv_fd);
 
                  server_fd = 0;
 
                  serverPort = 0;
 
                  serverIP = 0;
 
                }
 
            }
 
          if(fds[2].revents || (fds[1].revents && !gdb_fd))
 
            data_on_stdin = true;
 
          break;
 
        } /* End of switch statement */
 
    } /* End of while statement */
 
}
 
 
 
void JTAGRequest()
 
{
 
  struct sockaddr_in sa;
 
  struct sockaddr* addr = (struct sockaddr*)&sa;
 
  int n = sizeof(struct sockaddr_in);
 
  int fd = accept(server_fd,addr,&n);
 
  int on_off = 0; /* Turn off Nagel's algorithm on the socket */
 
  int flags;
 
  char sTemp[256];
 
 
 
  if(fd < 0)
 
    {
 
      /* This is valid, because a connection could have started,
 
         and then terminated due to a protocol error or user
 
         initiation before the accept could take place. */
 
      if(errno != EWOULDBLOCK && errno != EAGAIN)
 
        {
 
          perror("accept");
 
          close(server_fd);
 
          server_fd = 0;
 
          serverPort = 0;
 
          serverIP = 0;
 
        }
 
      return;
 
    }
 
 
 
  if(gdb_fd)
 
    {
 
      close(fd);
 
      return;
 
    }
 
 
 
  if(fcntl(fd,F_GETFL,&flags) < 0)
 
    {
 
      sprintf(sTemp,"Unable to get flags for gdb socket %d",fd);
 
      perror(sTemp);
 
      close(fd);
 
      return;
 
    }
 
 
 
  if(fcntl(fd,F_SETFL, flags | O_NONBLOCK) < 0)
 
    {
 
      sprintf(sTemp,"Unable to set flags for gdb socket %d to value 0x%08x",
 
              fd,flags | O_NONBLOCK);
 
      perror(sTemp);
 
      close(fd);
 
      return;
 
    }
 
 
 
  if(setsockopt(fd,tcp_level,TCP_NODELAY,&on_off,sizeof(int)) < 0)
 
    {
 
      sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",fd);
 
      perror(sTemp);
 
      close(fd);
 
      return;
 
    }
 
 
 
  gdb_fd = fd;
 
}
 
 
 
void GDBRequest()
 
{
 
  JTAGProxyWriteMessage msg_write;
 
  JTAGProxyReadMessage msg_read;
 
  JTAGProxyChainMessage msg_chain;
 
  JTAGProxyWriteResponse resp_write;
 
  JTAGProxyReadResponse resp_read;
 
  JTAGProxyChainResponse resp_chain;
 
  JTAGProxyBlockWriteMessage *msg_bwrite;
 
  JTAGProxyBlockReadMessage msg_bread;
 
  JTAGProxyBlockWriteResponse resp_bwrite;
 
  JTAGProxyBlockReadResponse *resp_bread;
 
  char *buf;
 
  unsigned long long data;
 
  int err = 0;
 
  uint32_t command,length;
 
  int len,i;
 
 
 
  /* First, we must read the incomming command */
 
  if(gdb_read(&command,sizeof(uint32_t)) < 0)
 
    {
 
      if(gdb_fd)
 
        {
 
          perror("gdb socket - 1");
 
          close(gdb_fd);
 
          gdb_fd = 0;
 
        }
 
      return;
 
    }
 
  if(gdb_read(&length,sizeof(uint32_t)) < 0)
 
    {
 
      if(gdb_fd)
 
        {
 
          perror("gdb socket - 2");
 
          close(gdb_fd);
 
          gdb_fd = 0;
 
        }
 
      return;
 
    }
 
  length = ntohl(length);
 
 
 
  /* Now, verify the protocol and implement the command */
 
  switch(ntohl(command))
 
    {
 
    case JTAG_COMMAND_WRITE:
 
      if(length != sizeof(msg_write) - 8)
 
        {
 
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
 
          return;
 
        }
 
      buf = (char*)&msg_write;
 
      if(gdb_read(&buf[8],length) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 3");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      msg_write.address = ntohl(msg_write.address);
 
      msg_write.data_H = ntohl(msg_write.data_H);
 
      msg_write.data_L = ntohl(msg_write.data_L);
 
      err = DebugSetRegister(msg_write.address,msg_write.data_L);
 
      resp_write.status = htonl(err);
 
      if(gdb_write(&resp_write,sizeof(resp_write)) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 4");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      break;
 
    case JTAG_COMMAND_READ:
 
      if(length != sizeof(msg_read) - 8)
 
        {
 
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
 
          return;
 
        }
 
      buf = (char*)&msg_read;
 
      if(gdb_read(&buf[8],length) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 5");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      msg_read.address = ntohl(msg_read.address);
 
      err = DebugGetRegister(msg_read.address,&resp_read.data_L);
 
      resp_read.status = htonl(err);
 
      resp_read.data_H = 0;
 
      resp_read.data_L = htonl(resp_read.data_L);
 
      if(gdb_write(&resp_read,sizeof(resp_read)) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 6");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      break;
 
    case JTAG_COMMAND_BLOCK_WRITE:
 
      if(length < sizeof(JTAGProxyBlockWriteMessage)-8)
 
        {
 
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
 
          return;
 
        }
 
      if(!(buf = (char*)malloc(8+length)))
 
        {
 
          ProtocolClean(length,JTAG_PROXY_OUT_OF_MEMORY);
 
          return;
 
        }
 
      msg_bwrite = (JTAGProxyBlockWriteMessage*)buf;
 
      if(gdb_read(&buf[8],length) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 5");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          free(buf);
 
          return;
 
        }
 
      msg_bwrite->address = ntohl(msg_bwrite->address);
 
      msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
 
      for(i=0;i<msg_bwrite->nRegisters;i++)
 
        {
 
          int t_err = 0;
 
 
 
          msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
 
          t_err = DebugSetRegister(msg_bwrite->address+i,msg_bwrite->data[i]);
 
          err = err ? err : t_err;
 
        }
 
      resp_bwrite.status = htonl(err);
 
      free(buf);
 
      buf = NULL;
 
      msg_bwrite = NULL;
 
      if(gdb_write(&resp_bwrite,sizeof(resp_bwrite)) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 4");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      break;
 
    case JTAG_COMMAND_BLOCK_READ:
 
      if(length != sizeof(msg_bread) - 8)
 
        {
 
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
 
          return;
 
        }
 
      buf = (char*)&msg_bread;
 
      if(gdb_read(&buf[8],length) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 5");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      msg_bread.address = ntohl(msg_bread.address);
 
      msg_bread.nRegisters = ntohl(msg_bread.nRegisters);
 
      len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1);
 
      if(!(buf = (char*)malloc(len)))
 
        {
 
          ProtocolClean(0,JTAG_PROXY_OUT_OF_MEMORY);
 
          return;
 
        }
 
      resp_bread = (JTAGProxyBlockReadResponse*)buf;
 
      for(i=0;i<msg_bread.nRegisters;i++)
 
        {
 
          int t_err;
 
 
 
          t_err = DebugGetRegister(msg_bread.address+i,&resp_bread->data[i]);
 
          resp_bread->data[i] = htonl(resp_bread->data[i]);
 
          err = err ? err : t_err;
 
        }
 
      resp_bread->status = htonl(err);
 
      resp_bread->nRegisters = htonl(msg_bread.nRegisters);
 
      if(gdb_write(resp_bread,len) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 6");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          free(buf);
 
          return;
 
        }
 
      free(buf);
 
      buf = NULL;
 
      resp_bread = NULL;
 
      break;
 
    case JTAG_COMMAND_CHAIN:
 
      if(length != sizeof(msg_chain) - 8)
 
        {
 
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
 
          return;
 
        }
 
      buf = (char*)&msg_chain;
 
      if(gdb_read(&buf[8],sizeof(msg_chain)-8) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 7");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      msg_chain.chain = htonl(msg_chain.chain);
 
      err = DebugSetChain(msg_chain.chain);
 
      resp_chain.status = htonl(err);
 
      if(gdb_write(&resp_chain,sizeof(resp_chain)) < 0)
 
        {
 
          if(gdb_fd)
 
            {
 
              perror("gdb socket - 8");
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
            }
 
          return;
 
        }
 
      break;
 
    default:
 
      ProtocolClean(length,JTAG_PROXY_COMMAND_NOT_IMPLEMENTED);
 
      break;
 
    }
 
}
 
 
 
void ProtocolClean(int length,int32_t err)
 
{
 
  char buf[4096];
 
 
 
  err = htonl(err);
 
  if((gdb_read(buf,length) < 0) ||
 
      (gdb_write(&err,sizeof(err)) < 0) && gdb_fd)
 
    {
 
      perror("gdb socket - 9");
 
      close(gdb_fd);
 
      gdb_fd = 0;
 
    }
 
}
 
 
 
static int gdb_write(void* buf,int len)
 
{
 
  int n;
 
  char* w_buf = (char*)buf;
 
  struct pollfd block;
 
 
 
  while(len)
 
    {
 
      if((n = write(gdb_fd,w_buf,len)) < 0)
 
        {
 
          switch(errno)
 
            {
 
            case EWOULDBLOCK: /* or EAGAIN */
 
              /* We've been called on a descriptor marked
 
                 for nonblocking I/O. We better simulate
 
                 blocking behavior. */
 
              block.fd = gdb_fd;
 
              block.events = POLLOUT;
 
              block.revents = 0;
 
              poll(&block,1,-1);
 
              continue;
 
            case EINTR:
 
              continue;
 
            case EPIPE:
 
              close(gdb_fd);
 
              gdb_fd = 0;
 
              return -1;
 
            default:
 
              return -1;
 
            }
 
        }
 
      else
 
        {
 
          len -= n;
 
          w_buf += n;
 
        }
 
    }
 
  return 0;
 
}
 
 
 
static int gdb_read(void* buf,int len)
 
{
 
  int n;
 
  char* r_buf = (char*)buf;
 
  struct pollfd block;
 
 
 
  while(len)
 
    {
 
      if((n = read(gdb_fd,r_buf,len)) < 0)
 
        {
 
          switch(errno)
 
            {
 
            case EWOULDBLOCK: /* or EAGAIN */
 
              /* We've been called on a descriptor marked
 
                 for nonblocking I/O. We better simulate
 
                 blocking behavior. */
 
              block.fd = gdb_fd;
 
              block.events = POLLIN;
 
              block.revents = 0;
 
              poll(&block,1,-1);
 
              continue;
 
            case EINTR:
 
              continue;
 
            default:
 
              return -1;
 
            }
 
        }
 
      else if(n == 0)
 
        {
 
          close(gdb_fd);
 
          gdb_fd = 0;
 
          return -1;
 
        }
 
      else
 
        {
 
          len -= n;
 
          r_buf += n;
 
        }
 
    }
 
  return 0;
 
}
 
 
 
 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.