Line 37... |
Line 37... |
#include <sys/select.h>
|
#include <sys/select.h>
|
#include <sys/poll.h>
|
#include <sys/poll.h>
|
#include <fcntl.h>
|
#include <fcntl.h>
|
#include <netdb.h>
|
#include <netdb.h>
|
#include <netinet/tcp.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 54... |
Line 55... |
#include "spr_defs.h"
|
#include "spr_defs.h"
|
|
|
#include "coff.h"
|
#include "coff.h"
|
|
|
/* Added by CZ 24/05/01 */
|
/* Added by CZ 24/05/01 */
|
|
#include "gdb.h"
|
#include <signal.h>
|
#include <signal.h>
|
#include <errno.h>
|
#include <errno.h>
|
typedef enum {
|
typedef enum {
|
false = 0,
|
false = 0,
|
true = 1,
|
true = 1,
|
Line 67... |
Line 69... |
unsigned int server_fd = 0;
|
unsigned int server_fd = 0;
|
unsigned int gdb_fd = 0;
|
unsigned int gdb_fd = 0;
|
void HandleServerSocket(Boolean);
|
void HandleServerSocket(Boolean);
|
void JTAGRequest(void);
|
void JTAGRequest(void);
|
void GDBRequest(void);
|
void GDBRequest(void);
|
|
void ProtocolClean(int,int32_t);
|
|
static int gdb_read(void*,int);
|
|
static int gdb_write(void*,int);
|
|
void BlockJTAG(void);
|
|
|
int GlobalMode = 0; /* Start off in the orginal mode */
|
int GlobalMode = 0; /* Start off in the orginal mode */
|
|
|
/* CVS revision number. */
|
/* CVS revision number. */
|
const char rcsrev[] = "$Revision: 1.16 $";
|
const char rcsrev[] = "$Revision: 1.17 $";
|
|
|
/* 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 599... |
Line 606... |
sprs_status();
|
sprs_status();
|
} else {
|
} else {
|
printf("%s: Unknown command.\n", linestr);
|
printf("%s: Unknown command.\n", linestr);
|
}
|
}
|
|
|
while(cont_run) {
|
while(cont_run > 0) {
|
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. */
|
|
extern int cpu_stalled; /* CZ from debug_interface */
|
|
|
|
if(cpu_stalled)
|
|
{
|
|
BlockJTAG();
|
|
HandleServerSocket(false);
|
|
continue;
|
|
}
|
|
|
if (!getsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
|
if (!getsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
|
if(cycle_delay <= 0)
|
if(cycle_delay <= 0)
|
{
|
{
|
cont_run--;
|
cont_run--;
|
Line 761... |
Line 776... |
if(strlen(mem[i].insn->op4) != 0) printf("%s ", mem[i].insn->op4);
|
if(strlen(mem[i].insn->op4) != 0) printf("%s ", mem[i].insn->op4);
|
printf("\n");
|
printf("\n");
|
}
|
}
|
}
|
}
|
|
|
|
static int tcp_level = 0;
|
|
|
/* Added by CZ 24/05/01 */
|
/* Added by CZ 24/05/01 */
|
int GetServerSocket(const char* name,const char* proto,int port)
|
int GetServerSocket(const char* name,const char* proto,int port)
|
{
|
{
|
struct servent *service;
|
struct servent *service;
|
struct protoent *protocol;
|
struct protoent *protocol;
|
Line 780... |
Line 797... |
{
|
{
|
sprintf(sTemp,"Unable to load protocol \"%s\"",proto);
|
sprintf(sTemp,"Unable to load protocol \"%s\"",proto);
|
perror(sTemp);
|
perror(sTemp);
|
return 0;
|
return 0;
|
}
|
}
|
|
tcp_level = protocol->p_proto; /* Save for later */
|
|
|
/* If we weren't passed a non standard port, get the port
|
/* If we weren't passed a non standard port, get the port
|
from the services directory. */
|
from the services directory. */
|
if(!port)
|
if(!port)
|
{
|
{
|
Line 868... |
Line 886... |
}
|
}
|
|
|
return sockfd;
|
return sockfd;
|
}
|
}
|
|
|
void HandleServerSocket(Boolean block)
|
void BlockJTAG()
|
{
|
{
|
struct pollfd fds[2];
|
struct pollfd fds[2];
|
int n = 0;
|
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 timeout = block ? -1 : 0;
|
int server_index = -1;
|
int server_index = -1;
|
int gdb_index = -1;
|
int gdb_index = -1;
|
Boolean data_on_stdin = false;
|
Boolean data_on_stdin = false;
|
int o_serv_fd = server_fd;
|
int o_serv_fd = server_fd;
|
Line 914... |
Line 949... |
break;
|
break;
|
case 0: /* Nothing interesting going on */
|
case 0: /* Nothing interesting going on */
|
data_on_stdin = true; /* Can only get here if nonblocking */
|
data_on_stdin = true; /* Can only get here if nonblocking */
|
break;
|
break;
|
default:
|
default:
|
if(fds[0].revents && o_serv_fd)
|
/* Make sure to handle the gdb port first! */
|
{
|
|
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[0].revents && (gdb_fd && !o_serv_fd) ||
|
if((fds[0].revents && (gdb_fd && !o_serv_fd) ||
|
fds[1].revents && (server_fd && gdb_fd)))
|
fds[1].revents && (server_fd && gdb_fd)))
|
{
|
{
|
int revents = o_serv_fd ? fds[1].revents : fds[0].revents;
|
int revents = o_serv_fd ? fds[1].revents : fds[0].revents;
|
|
|
Line 941... |
Line 964... |
fprintf(stderr,"Received flags 0x%08x on gdb socket. Shutting down.\n",revents);
|
fprintf(stderr,"Received flags 0x%08x on gdb socket. Shutting down.\n",revents);
|
close(gdb_fd);
|
close(gdb_fd);
|
gdb_fd = 0;
|
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))
|
if(fds[2].revents || (fds[1].revents && !gdb_fd))
|
data_on_stdin = true;
|
data_on_stdin = true;
|
break;
|
break;
|
} /* End of switch statement */
|
} /* End of switch statement */
|
} /* End of while statement */
|
} /* End of while statement */
|
Line 997... |
Line 1033... |
perror(sTemp);
|
perror(sTemp);
|
close(fd);
|
close(fd);
|
return;
|
return;
|
}
|
}
|
|
|
if(setsockopt(fd,SOL_TCP,TCP_NODELAY,&on_off,sizeof(int)) < 0)
|
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);
|
sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",fd);
|
perror(sTemp);
|
perror(sTemp);
|
close(fd);
|
close(fd);
|
return;
|
return;
|
Line 1010... |
Line 1046... |
gdb_fd = fd;
|
gdb_fd = fd;
|
}
|
}
|
|
|
void GDBRequest()
|
void GDBRequest()
|
{
|
{
|
/* Debug interface simulation should go here. */
|
JTAGProxyWriteMessage msg_write;
|
|
JTAGProxyReadMessage msg_read;
|
|
JTAGProxyChainMessage msg_chain;
|
|
JTAGProxyWriteResponse resp_write;
|
|
JTAGProxyReadResponse resp_read;
|
|
JTAGProxyChainResponse resp_chain;
|
|
char *buf;
|
|
unsigned long long data;
|
|
int err;
|
|
uint32_t command,length;
|
|
|
|
/* 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_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
|