URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 303 to Rev 304
- ↔ Reverse comparison
Rev 303 → Rev 304
/trunk/or1ksim/sim-config.h
57,6 → 57,8
unsigned irq; |
} dmas[NR_DMAS]; |
|
int nethernets; |
int ethernets_enabled; |
struct { |
unsigned long baseaddr; |
unsigned dma; /* Which controller is this ethernet "connected" to */ |
92,7 → 94,7
int dependstats; /* dependency statistics */ |
int dependency; /* not sure: same as dependency statistics? */ |
int slp; /* not sure: stack analisys? */ |
int btic_sim; /* branch prediction target insn cache analysis */ |
int btic; /* branch prediction target insn cache analysis */ |
int bpb; /* branch prediction buffer analysis */ |
} cpu; |
|
/trunk/or1ksim/sim.cfg
35,7 → 35,7
dependstats = 0 |
dependency = 0 |
slp = 0 |
btic_sim = 0 |
btic = 0 |
bpb = 0 |
end |
|
51,18 → 51,18
prof_fn = "sim.profile" |
|
/* iprompt = 0 */ |
exe_log = 1 |
exe_log = 0 |
exe_log_fn = "executed.log" |
end |
|
section mc |
enabled = 1 |
enabled = 0 |
baseaddr = 0xa0000000 |
POC = 0x00000008 /* Power on configuration register */ |
end |
|
section uart |
enabled = 1 |
enabled = 0 |
nuarts = 1 |
|
device 0 |
74,7 → 74,7
end |
|
section dma |
enabled = 1 |
enabled = 0 |
ndmas = 1 |
|
device 0 |
85,4 → 85,9
|
section VAPI |
enabled = 0 |
server_port = 9998 |
end |
|
section ethernet |
enabled = 0 |
end |
/trunk/or1ksim/debug/Makefile.am
19,4 → 19,4
# |
|
noinst_LIBRARIES = libdebug.a |
libdebug_a_SOURCES = debug_unit.c debug_unit.h |
libdebug_a_SOURCES = debug_unit.c debug_unit.h gdbcomm.c gdbcomm.h |
/trunk/or1ksim/cpu/common/parse.h
25,4 → 25,12
#define LABELEND_CHAR ":" |
/*#define OPERAND_DELIM ","*/ |
|
/* Strip whitespace from the start and end of STRING. Return a pointer |
into STRING. */ |
#ifndef whitespace |
#define whitespace(a) ((a) == '\t' ? 1 : ((a) == ' '? 1 : 0)) |
#endif |
|
char *stripwhite (char *string); |
char *dupstr (char *s); |
char *strtoken(char *in, char *out, int which); |
/trunk/or1ksim/cpu/common/parse.c
69,6 → 69,37
return(out); |
} |
|
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; |
} |
|
char * |
dupstr (s) |
char *s; |
{ |
char *r; |
|
r = xmalloc (strlen (s) + 1); |
strcpy (r, s); |
return (r); |
} |
|
/* Used only by the simulator loader to translate logical addresses into physical. |
If loadcode() is called with valid virtphy_transl pointer to a table of |
translations then translate() performs translation otherwise phy address is |
/trunk/or1ksim/vapi/vapi.c
42,26 → 42,163
|
//#include "sim-config.h" |
|
unsigned int serverIP = 0; |
static unsigned int serverIP = 0; |
|
struct { |
struct { |
int enabled; |
unsigned int server_port; |
} vapi; |
struct { |
int verbose; |
} sim; |
} config; |
#define debug printf |
|
unsigned int server_fd = 0; |
unsigned int vapi_fd = 0; |
static unsigned int server_fd = 0; |
static unsigned int nhandlers = 0; |
|
void server_request(void); |
|
static int tcp_level = 0; |
|
struct vapi_handler { |
static struct vapi_handler { |
int fd; |
unsigned long id; |
void (*read_func)(int); |
void (*read_func)(unsigned long); |
struct vapi_handler *next; |
int temp; |
} *vapi_handler; |
|
|
/* Structure for polling, it is cached, that it doesn't have to be rebuilt each time */ |
static struct pollfd *fds = NULL; |
static int nfds = 0; |
|
/* Rebuilds the fds structures; see fds. */ |
void rebuild_fds () { |
struct vapi_handler *t; |
if (fds) |
free (fds); |
fds = (struct pollfd *) malloc (sizeof (struct pollfd) * (nhandlers + 1)); |
if (!fds) { |
fprintf (stderr, "FATAL: Out of memory.\n"); |
exit (1); |
} |
|
nfds = 0; |
fds[nfds].fd = server_fd; |
fds[nfds].events = POLLIN; |
fds[nfds++].revents = 0; |
|
for (t = vapi_handler; t; t = t->next) { |
if (t->fd) { |
t->temp = nfds; |
fds[nfds].fd = t->fd; |
fds[nfds].events = POLLIN; |
fds[nfds++].revents = 0; |
} else |
t->temp = -1; |
} |
} |
|
/* Finds a handler with given ID, return it, NULL if not found. */ |
static struct vapi_handler *find_handler (unsigned long id) { |
struct vapi_handler *t = vapi_handler; |
while (t && t->id != id) |
t = t->next; |
return t; |
} |
|
/* Adds a handler with given id and returns it. */ |
static struct vapi_handler *add_handler (unsigned long id) { |
struct vapi_handler **t = &vapi_handler; |
struct vapi_handler *tt; |
while ((*t)) |
t = &(*t)->next; |
tt = (struct vapi_handler *)malloc (sizeof (struct vapi_handler)); |
tt->next = NULL; |
tt->id = id; |
tt->read_func = NULL; |
tt->fd = 0; |
(*t) = tt; |
free (fds); |
fds = NULL; |
nhandlers++; |
rebuild_fds (); |
return tt; |
} |
|
static int vapi_write_stream(int fd, void* buf, int len) |
{ |
int n; |
char* w_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = write(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 = fd; |
block.events = POLLOUT; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
case EPIPE: |
close(fd); |
fd = 0; |
return -1; |
default: |
return -1; |
} |
} else { |
len -= n; |
w_buf += n; |
} |
} |
return 0; |
} |
|
static int vapi_read_stream(int fd, void* buf, int len) |
{ |
int n; |
char* r_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = read(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 = fd; |
block.events = POLLIN; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
default: |
return -1; |
} |
} else if(n == 0) { |
close(fd); |
fd = 0; |
return -1; |
} else { |
len -= n; |
r_buf += n; |
} |
} |
return 0; |
} |
|
/* Added by CZ 24/05/01 */ |
int get_server_socket(const char* name,const char* proto,int port) |
{ |
177,17 → 314,12
perror("accept"); |
close(server_fd); |
server_fd = 0; |
config.vapi.server_port = 0; |
config.vapi.enabled = 0; |
serverIP = 0; |
} |
return; |
} |
|
if(vapi_fd) { |
close(fd); |
return; |
} |
|
if(fcntl(fd,F_GETFL,&flags) < 0) { |
sprintf(sTemp,"Unable to get flags for vapi socket %d",fd); |
perror(sTemp); |
209,176 → 341,121
close(fd); |
return; |
} |
|
vapi_fd = fd; |
} |
|
static int vapi_write_stream(void* buf, int len) |
{ |
int n; |
char* w_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = write(vapi_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 = vapi_fd; |
block.events = POLLOUT; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
case EPIPE: |
close(vapi_fd); |
vapi_fd = 0; |
return -1; |
default: |
return -1; |
} |
} else { |
len -= n; |
w_buf += n; |
|
/* Install new handler */ |
{ |
unsigned long id; |
struct vapi_handler *t; |
if (vapi_read_stream (fd, &id, sizeof (id))) { |
perror ("Cannot get id"); |
close (fd); |
return; |
} |
} |
return 0; |
} |
|
static int vapi_read_stream(void* buf, int len) |
{ |
int n; |
char* r_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = read(vapi_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 = vapi_fd; |
block.events = POLLIN; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
default: |
return -1; |
} |
} else if(n == 0) { |
close(vapi_fd); |
vapi_fd = 0; |
return -1; |
} else { |
len -= n; |
r_buf += n; |
t = find_handler (id); |
if (t) |
if (t->fd) { |
fprintf (stderr, "WARNING: Test with id %x already connected. Ignoring.\n", id); |
close (fd); |
return; |
} else t->fd = fd; |
else { |
t = add_handler (id); |
t->fd = fd; |
rebuild_fds (); |
} |
if(config.sim.verbose) |
printf ("Connection with test (id %x) established.\n", id); |
} |
return 0; |
} |
|
static int write_packet (unsigned long id, unsigned long data) { |
struct vapi_handler *t = find_handler (id); |
if (!t || !t->fd) |
return 1; |
id = htonl (id); |
if (vapi_write_stream(&id, sizeof (id)) < 0) |
if (vapi_write_stream(t->fd, &id, sizeof (id)) < 0) |
return 1; |
data = htonl (data); |
if (vapi_write_stream(&data, sizeof (data)) < 0) |
if (vapi_write_stream(t->fd, &data, sizeof (data)) < 0) |
return 1; |
return 0; |
} |
|
static int read_packet (unsigned long *id, unsigned long *data) { |
if (vapi_read_stream(id, sizeof (unsigned long)) < 0) |
static int read_packet (unsigned long id, unsigned long *data) { |
unsigned long t_id; |
struct vapi_handler *t = find_handler (id); |
if (!t || !t->fd) |
return 1; |
*id = htonl (*id); |
if (vapi_read_stream(data, sizeof (unsigned long)) < 0) |
if (vapi_read_stream(t->fd, &t_id, sizeof (unsigned long)) < 0) |
return 1; |
t_id = htonl (t_id); |
if (t_id != id) { |
fprintf (stderr, "IDs not the same (got %x, expected %x)\n", t_id, id); |
return 1; |
} |
if (vapi_read_stream(t->fd, data, sizeof (unsigned long)) < 0) |
return 1; |
*data = htonl (*data); |
return 0; |
} |
} |
|
static void vapi_request() |
{ |
unsigned long id, data; |
struct vapi_handler *t; |
if(read_packet (&id, &data)) { |
if(vapi_fd) { |
static void vapi_request (struct vapi_handler *t) { |
unsigned long data; |
if(read_packet (t->id, &data)) { |
if(t->fd) { |
perror("vapi read"); |
close(vapi_fd); |
vapi_fd = 0; |
close(t->fd); |
t->fd = 0; |
} |
return; |
} |
|
printf ("[%08x, %08x]\n", id, data); |
t = vapi_handler; |
while (t && t->id != id) |
t = t->next; |
if (!t && t->read_func) |
fprintf (stderr, "WARNING: packet sent to undefined id %x, %x\n", id, data); |
debug ("[%08x, %08x]\n", t->id, data); |
if (!t->read_func) |
fprintf (stderr, "WARNING: packet sent to undefined id %x, %x\n", t->id, data); |
else |
t->read_func(data); |
write_packet (id, data + 1); |
write_packet (t->id, data + 1); //REMOVE!!!!!!!!!! |
} |
|
void vapi_check () |
{ |
struct pollfd fds[2]; |
int nfds = 0; |
int o_serv_fd = server_fd; |
|
if(!o_serv_fd && !vapi_fd) |
return; |
struct vapi_handler *t; |
|
if(o_serv_fd) { |
fds[nfds].fd = o_serv_fd; |
fds[nfds].events = POLLIN; |
fds[nfds++].revents = 0; |
if (!server_fd || !fds) { |
fprintf (stderr, "FATAL: Unable to maintain VAPI server.\n"); |
exit (1); |
} |
if(vapi_fd) { |
fds[nfds].fd = vapi_fd; |
fds[nfds].events = POLLIN; |
fds[nfds++].revents = 0; |
} |
|
/* Handle everything in queue. */ |
while(1) { |
switch(poll(fds,nfds,0)) { |
switch(poll(fds, nfds, 0)) { |
case -1: |
if(errno == EINTR) |
continue; |
perror("poll"); |
server_fd = 0; |
break; |
if (server_fd) |
close(server_fd); |
config.vapi.enabled = 0; |
serverIP = 0; |
return; |
case 0: /* Nothing interesting going on */ |
return; |
default: |
/* Make sure to handle the vapi port first! */ |
if((fds[0].revents && (vapi_fd && !o_serv_fd) || |
fds[1].revents && (server_fd && vapi_fd))) { |
int revents = o_serv_fd ? fds[1].revents : fds[0].revents; |
/* Handle the vapi ports first. */ |
for (t = vapi_handler; t; t = t->next) |
if (t->temp >= 0 && fds[t->temp].revents) |
vapi_request (t); |
|
if(revents & POLLIN) |
vapi_request(); |
else { /* Error Occurred */ |
fprintf(stderr,"Received flags 0x%08x on vapi socket. Shutting down.\n",revents); |
close(vapi_fd); |
vapi_fd = 0; |
} |
} |
if(fds[0].revents && o_serv_fd) { |
if(fds[0].revents) { |
if(fds[0].revents & POLLIN) |
server_request(); |
else { /* Error Occurred */ |
fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n",fds[0].revents); |
close(o_serv_fd); |
fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n", fds[0].revents); |
if (server_fd) |
close(server_fd); |
server_fd = 0; |
config.vapi.server_port = 0; |
config.vapi.enabled = 0; |
serverIP = 0; |
} |
} |
387,23 → 464,57
} /* End of while statement */ |
} |
|
int vapi_init () { |
/* Inits the VAPI, according to sim-config */ |
int vapi_init () |
{ |
if(server_fd = get_server_socket("or1ksim","tcp",config.vapi.server_port)) |
nhandlers = 0; |
vapi_handler = NULL; |
if (!config.vapi.enabled) |
return 0; /* Nothing to do */ |
|
if (!config.vapi.server_port) { |
fprintf (stderr, "WARNING: server_port = 0, shutting down VAPI\n"); |
config.vapi.enabled = 0; |
return 1; |
} |
if (server_fd = get_server_socket("or1ksim","tcp",config.vapi.server_port)) |
printf("VAPI Server started on port %d\n",config.vapi.server_port); |
else |
else { |
perror ("Connection"); |
return 1; |
} |
|
rebuild_fds (); |
return 0; |
} |
|
/* Closes the VAPI */ |
void vapi_done () |
{ |
int i; |
struct vapi_handler *t = vapi_handler; |
|
freopen("/dev/fd/0", "w+", stdout); |
for (i = 0; i < nfds; i++) |
if (fds[i].fd) |
fclose (fds[i].fd); |
server_fd = 0; |
config.vapi.enabled = 0; |
serverIP = 0; |
free (fds); |
fds = 0; |
while (vapi_handler) { |
t = vapi_handler; |
vapi_handler = vapi_handler->next; |
free (t); |
} |
} |
|
void vapi_done () {} |
|
/* Installs a vapi handler to VAPI id */ |
void vapi_install_handler (unsigned long id, void (*read_func) (unsigned long)) { |
struct vapi_handler **t = &vapi_handler; |
void vapi_install_handler (unsigned long id, void (*read_func) (unsigned long)) |
{ |
struct vapi_handler *tt; |
if (readfunc == NULL) { |
if (read_func == NULL) { |
struct vapi_handler **t = &vapi_handler; |
while ((*t) && (*t)->id != id) |
t = &(*t)->next; |
if (!t) { |
413,21 → 524,31
tt = *t; |
(*t) = (*t)->next; |
free (tt); |
nhandlers--; |
} else { |
while ((*t)) |
t = &(*t)->next; |
tt = (struct vapi_handler *)malloc (sizeof (struct vapi_handler)); |
tt->next = NULL; |
tt->id = id; |
tt = add_handler (id); |
tt->read_func = read_func; |
(*t) = tt; |
} |
} |
|
int main () { |
/* Returns number of unconnected handles. */ |
int vapi_num_unconnected () |
{ |
struct vapi_handler *t = vapi_handler; |
int numu = 0; |
for (; t; t = t->next) |
if (!t->fd) numu++; |
return numu; |
} |
|
int main () |
{ |
config.vapi.enabled = 1; |
config.vapi.server_port = 9999; |
vapi_init (); |
while (1) { |
vapi_check(); |
usleep(1); |
} |
vapi_done (); |
} |
/trunk/or1ksim/vapi/vapit.c
38,6 → 38,96
int vapi_fd; |
unsigned long vapi_id; |
|
static int vapi_write_stream(int fd, void* buf, int len) |
{ |
int n; |
char* w_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = write(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 = fd; |
block.events = POLLOUT; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
case EPIPE: |
close(fd); |
vapi_fd = 0; |
return -1; |
default: |
return -1; |
} |
} else { |
len -= n; |
w_buf += n; |
} |
} |
return 0; |
} |
|
static int vapi_read_stream(int fd, void* buf, int len) |
{ |
int n; |
char* r_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = read(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 = fd; |
block.events = POLLIN; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
default: |
return -1; |
} |
} else if(n == 0) { |
close(fd); |
fd = 0; |
return -1; |
} else { |
len -= n; |
r_buf += n; |
} |
} |
return 0; |
} |
|
static int write_packet (unsigned long id, unsigned long data) { |
id = htonl (id); |
if (vapi_write_stream(vapi_fd, &id, sizeof (id)) < 0) |
return 1; |
data = htonl (data); |
if (vapi_write_stream(vapi_fd, &data, sizeof (data)) < 0) |
return 1; |
return 0; |
} |
|
static int read_packet (unsigned long *id, unsigned long *data) { |
if (vapi_read_stream(vapi_fd, id, sizeof (unsigned long)) < 0) |
return 1; |
*id = htonl (*id); |
if (vapi_read_stream(vapi_fd, data, sizeof (unsigned long)) < 0) |
return 1; |
*data = htonl (*data); |
return 0; |
} |
|
/* Added by CZ 24/05/01 */ |
static int connect_to_server(char* hostname,char* name) |
{ |
166,7 → 256,9
&port_name[5]); |
error(sTemp); |
} |
printf("Remote or1k debugging using %s\n",port_name); |
printf("Remote or1k testing using %s, id %x\n", port_name, id); |
if (vapi_write_stream (vapi_fd, &id, sizeof (id))) |
return 1; |
} else |
return 1; |
return 0; |
201,97 → 293,6
close(vapi_fd); |
} |
|
|
static int vapi_write_stream(void* buf, int len) |
{ |
int n; |
char* w_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = write(vapi_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 = vapi_fd; |
block.events = POLLOUT; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
case EPIPE: |
close(vapi_fd); |
vapi_fd = 0; |
return -1; |
default: |
return -1; |
} |
} else { |
len -= n; |
w_buf += n; |
} |
} |
return 0; |
} |
|
static int vapi_read_stream(void* buf, int len) |
{ |
int n; |
char* r_buf = (char*)buf; |
struct pollfd block; |
|
while(len) { |
if((n = read(vapi_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 = vapi_fd; |
block.events = POLLIN; |
block.revents = 0; |
poll(&block,1,-1); |
continue; |
case EINTR: |
continue; |
default: |
return -1; |
} |
} else if(n == 0) { |
close(vapi_fd); |
vapi_fd = 0; |
return -1; |
} else { |
len -= n; |
r_buf += n; |
} |
} |
return 0; |
} |
|
static int write_packet (unsigned long id, unsigned long data) { |
id = htonl (id); |
if (vapi_write_stream(&id, sizeof (id)) < 0) |
return 1; |
data = htonl (data); |
if (vapi_write_stream(&data, sizeof (data)) < 0) |
return 1; |
return 0; |
} |
|
static int read_packet (unsigned long *id, unsigned long *data) { |
if (vapi_read_stream(id, sizeof (unsigned long)) < 0) |
return 1; |
*id = htonl (*id); |
if (vapi_read_stream(data, sizeof (unsigned long)) < 0) |
return 1; |
*data = htonl (*data); |
return 0; |
} |
|
void vapi_write(unsigned long data) { |
if (write_packet (vapi_id, data)) |
perror ("write packet"); |
344,8 → 345,9
|
int main () { |
unsigned long id, data; |
printf ("%x", getpid()); |
vapi_init("vapi://localhost:9999", getpid()); |
if (vapi_init("vapi://localhost:9999", getpid())) |
return 1; |
|
while (1) { |
vapi_write (0xdeaddead); |
|
352,7 → 354,7
if (vapi_waiting ()) |
vapi_read(); |
|
sleep (1); |
usleep (10); |
} |
vapi_done(); |
return 0; |
/trunk/or1ksim/vapi/vapi.h
17,7 → 17,10
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
/* Inits the VAPI, according to sim-config */ |
int vapi_init (); |
|
/* Closes the VAPI */ |
void vapi_done (); |
|
/* Installs a vapi handler to VAPI id */ |
25,3 → 28,6
|
/* Checks for incoming packets */ |
void vapi_check (); |
|
/* Returns number of unconnected handles. */ |
int vapi_num_unconnected (); |
/trunk/or1ksim/toplevel.c
29,17 → 29,7
#include <unistd.h> |
#include <signal.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 <netdb.h> |
#include <netinet/tcp.h> |
#include <inttypes.h> |
|
#ifdef HAVE_LIBREADLINE |
#include <readline/readline.h> |
55,31 → 45,14
#include "sim-config.h" |
#include "spr_defs.h" |
#include "dma.h" |
#include "vapi.h" |
|
#include "coff.h" |
|
/* Added by CZ 24/05/01 */ |
#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); |
#include "gdbcomm.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.37 $"; |
const char rcsrev[] = "$Revision: 1.38 $"; |
|
/* Continuos run versus single step tracing switch. */ |
int cont_run; |
136,34 → 109,7
} |
} |
|
/* Strip whitespace from the start and end of STRING. Return a pointer |
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) |
void ctrl_c(signum) |
int signum; |
{ |
extern int cpu_stalled; /* CZ from debug_interface */ |
173,8 → 119,7
signal(SIGINT, ctrl_c); |
} |
|
void |
version() |
void version() |
{ |
printf ("\n"); |
printf ("OpenRISC 1000 (OR16+OR32) Architectural Simulator, %s\n", rcsrev); |
220,42 → 165,11
|
void debugmem( unsigned long from, unsigned long to ); |
|
main(argc, argv) |
int argc; |
char *argv[]; |
/* Initalizes all devices and sim */ |
void sim_init () |
{ |
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_breakpoints(); |
signal(SIGINT, ctrl_c); |
initstats(); |
build_automata(); |
|
312,6 → 226,7
} |
|
if(config.filename) { |
unsigned long endaddr = 0xFFFFFFFF; |
endaddr = loadcode(config.filename, 0, 0); /* MM170901 always load at address zero. */ |
if (endaddr == -1) { |
fprintf(stderr, "Problems loading boot code.\n"); |
331,10 → 246,74
pic_reset(); |
mc_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) { |
if (config.sim.iprompt) { |
if(server_fd) |
if (GDB_ENABLED && server_fd) |
{ |
printf ("(sim) "); |
fflush(stdout); |
392,14 → 371,7
strtoken(linestr, item1, 1); |
if (strcmp(item1, "q") == 0) { /* quit */ |
printf ("\n"); |
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); |
exit(0); |
sim_done (); |
} else |
if (strcmp(item1, "help") == 0) /* help */ |
help(); |
602,21 → 574,12
printstats(i); |
} |
} else |
if (strcmp(item1, "info") == 0) { /* configuration info */ |
itlb_status(-1); |
dtlb_status(-1); |
bpb_info(); |
btic_info(); |
ic_info(); |
dc_info(); |
uart_status(); |
sprs_status(); |
dma_status(); |
eth_status(); |
} else { |
if (strcmp(item1, "info") == 0) /* configuration info */ |
sim_info (); |
else |
printf("%s: Unknown command.\n", linestr); |
} |
|
|
/* MM: 'run -1' means endless execution. */ |
while(cont_run != 0) { |
int debug_slowdown = DEBUG_SLOWDOWN; |
632,71 → 595,65
fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled."); |
|
if (!testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) { |
if(cycle_delay <= 0) |
{ |
unsigned int addr; |
if (cont_run > 0) cont_run--; |
if(fetch()) { |
cont_run = 0; /* memory breakpoint encountered */ |
break; |
} |
addr = iqueue[0].insn_addr; |
|
/* If trace_fd is non zero, we want |
to make sure that disassemble is called */ |
if(cycle_delay <= 0) { |
unsigned int addr; |
if (cont_run > 0) cont_run--; |
if(fetch()) { |
cont_run = 0; /* memory breakpoint encountered */ |
break; |
} |
addr = iqueue[0].insn_addr; |
|
/* If trace_fd is non zero, we want |
to make sure that disassemble is called */ |
|
decode_execute(&iqueue[0],trace_fd); |
if(trace_fd) |
{ |
char sTemp[256]; |
char sTemp2[256]; |
unsigned long value; |
extern char *disassembled; |
extern unsigned long reg[]; |
decode_execute(&iqueue[0],trace_fd); |
if(trace_fd) { |
char sTemp[256]; |
char sTemp2[256]; |
unsigned long value; |
extern char *disassembled; |
extern unsigned long reg[]; |
|
/* The objects passed to the |
trace command should not be |
hardcoded like this...instead |
what to dump should be passed |
on the command line. |
/* The objects passed to the |
trace command should not be |
hardcoded like this...instead |
what to dump should be passed |
on the command line. |
|
FIX THIS LATER... |
*/ |
value = (evalsim_mem8(0x306bc) << 24) + |
(evalsim_mem8(0x306bd) << 16) + |
(evalsim_mem8(0x306be) << 8) |
+ evalsim_mem8(0x306bf); |
FIX THIS LATER... |
*/ |
value = (evalsim_mem8(0x306bc) << 24) + |
(evalsim_mem8(0x306bd) << 16) + |
(evalsim_mem8(0x306be) << 8) |
+ evalsim_mem8(0x306bf); |
|
sprintf(sTemp,"0x%06x: %s",addr,disassembled); |
memset(sTemp2,' ',sizeof(sTemp2)); |
strncpy(sTemp2,sTemp,strlen(sTemp)); |
sprintf(&sTemp2[40],"<0x%08x,0x%08x> [0x%08x]\n", |
reg[3],reg[4],value); |
write(trace_fd,sTemp2,strlen(sTemp2)); |
} |
update_pc(); |
analysis(); |
if (!hush) |
dumpreg(); |
sprintf(sTemp,"0x%06x: %s",addr,disassembled); |
memset(sTemp2,' ',sizeof(sTemp2)); |
strncpy(sTemp2,sTemp,strlen(sTemp)); |
sprintf(&sTemp2[40],"<0x%08x,0x%08x> [0x%08x]\n", |
reg[3],reg[4],value); |
write(trace_fd,sTemp2,strlen(sTemp2)); |
} |
else |
update_pc(); |
analysis(); |
if (!hush) |
dumpreg(); |
} else |
cycle_delay--; |
|
pic_clock(); |
dc_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) |
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) { |
debug_slowdown = DEBUG_SLOWDOWN; |
HandleServerSocket(false); /* block & check_stdin = false */ |
706,16 → 663,9
fflush(stdout); |
freopen("/dev/fd/0", "w+", stdout); |
|
if (!config.sim.iprompt) { /* non-interactive quit */ |
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); |
exit(0); |
} |
if (!config.sim.iprompt) /* non-interactive quit */ |
sim_done(); |
|
#ifdef HAVE_LIBREADLINE |
if (linestr) |
free (linestr); |
722,7 → 672,7
#endif |
|
} |
exit(0); |
sim_done(); |
} |
|
#ifdef HAVE_LIBREADLINE |
797,17 → 747,6
return ((char *)NULL); |
} |
|
char * |
dupstr (s) |
char *s; |
{ |
char *r; |
|
r = xmalloc (strlen (s) + 1); |
strcpy (r, s); |
return (r); |
} |
|
/* Repeats the last command. */ |
char * |
repeat_last_command () |
844,612 → 783,3
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; |
} |
/trunk/or1ksim/sim-config.c
82,6 → 82,9
|
/* VAPI */ |
config.vapi.enabled = 0; |
|
/* Ethernet */ |
config.ethernets_enabled = 0; |
|
/* Old */ |
config.dc.tagtype = NONE/*VIRTUAL*/; |
250,7 → 253,8
{"cpu", 0}, |
{"sim", 0}, |
{"debug", 0}, |
{"VAPI", 0} |
{"VAPI", 0}, |
{"ethernet",0} |
}; |
|
unsigned long tempL; |
303,7 → 307,7
{5, "dependency", "=%i", NULL, (void *)(&config.cpu.dependency)}, |
{5, "slp", "=%i", NULL, (void *)(&config.cpu.slp)}, |
{5, "bpb", "=%i", NULL, (void *)(&config.cpu.bpb)}, |
{5, "btic_sim", "=%i", NULL, (void *)(&config.cpu.btic_sim)}, |
{5, "btic", "=%i", NULL, (void *)(&config.cpu.btic)}, |
|
{6, "debug", "=%i", NULL, (void *)(&config.sim.debug)}, |
{6, "iprompt", "=%i", NULL, (void *)(&config.sim.iprompt)}, |
319,6 → 323,15
{7, "server_port", "=%i", NULL, (void *)(&config.debug.server_port)}, |
|
{8, "enabled", "=%i", NULL, (void *)(&config.vapi.enabled)} |
{8, "server_port", "=%i", NULL, (void *)(&config.vapi.server_port)}, |
|
{9, "enabled", "=%i", NULL, (void *)(&config.ethernetss_enabled)}, |
{9, "neths", "=%i", NULL, (void *)(&config.nethernetss)}, |
{9, "device", "%i", change_device, (void *)(&tempL)}, |
{9, "enddevice", "", end_device, NULL}, |
{9, "baseaddr", "=0x%x", eth_baseaddr, (void *)(&tempUL)}, |
{9, "dma", "=%i", eth_dma, (void *)(&tempL)}, |
|
}; |
|
int current_device = -1; |
400,6 → 413,24
} |
} |
|
void eth_baseaddr () { |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].baseaddr = tempUL; |
else { |
fprintf (stderr, "ERROR: invalid device number."); |
exit (-1); |
} |
} |
|
void eth_dma () { |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethertnets[current_device].dma = tempL; |
else { |
fprintf (stderr, "ERROR: invalid device number."); |
exit (-1); |
} |
} |
|
/* Read environment from a script file. Does not fail - assumes defaukt configuration instead. |
The syntax of script file is: |
param = value |