URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 123 to Rev 124
- ↔ Reverse comparison
Rev 123 → Rev 124
/trunk/gdb-5.0/gdb/jtag.c
4,6 → 4,8
Copyright 1993-1995, 2000 Free Software Foundation, Inc. |
Contributed by Cygnus Support. Written by Marko Mlinar |
<markom@opencores.org> |
Areas noted by (CZ) were modified by Chris Ziomkowski |
<chris@asics.ws> |
|
This file is part of GDB. |
|
34,6 → 36,15
#include "remote-utils.h" |
#include "gdb_string.h" |
#include "tm.h" |
/* Added by CZ 24/05/01 */ |
#include <sys/poll.h> |
#include <sys/socket.h> |
#include <netdb.h> |
#include <netinet/in.h> |
#include <netinet/tcp.h> |
#include <sys/select.h> |
#include <sys/time.h> |
#include <unistd.h> |
|
#include <signal.h> |
#include <sys/types.h> |
70,9 → 81,24
RUN TEST/IDLE */ |
static int select_dr = 0; |
|
/* Printer compatible device we have open. */ |
static int lp; |
/* CZ - 24/05/01 - Changed to structure for remote/local */ |
typedef enum { |
JTAG_NOT_CONNECTED = 0, |
JTAG_LOCAL = 1, |
JTAG_REMOTE = 2, |
} jtag_location; |
|
typedef struct { |
union { |
int lp; /* Printer compatible device we have open. */ |
int fd; /* Socket for remote or1k jtag interface */ |
} device; |
jtag_location location; |
} jtag_connection; |
|
/* Our current connect information */ |
static jtag_connection connection; |
|
/* Crc of current read or written data. */ |
static int crc_r, crc_w = 0; |
|
113,6 → 139,11
jp1_reset_JTAG () |
{ |
unsigned char data; |
int lp = connection.device.lp; /* CZ */ |
|
if(connection.location != JTAG_LOCAL) |
error("jp1_reset_JTAG called without a local connection!"); |
|
data = 0; |
write (lp, &data, sizeof (data)); |
JTAG_WAIT(); |
129,6 → 160,11
unsigned char packet; |
{ |
unsigned char data; |
int lp = connection.device.lp; /* CZ */ |
|
if(connection.location != JTAG_LOCAL) |
error("jp1_write_JTAG called without a local connection!"); |
|
data = ((packet & 3) << 2) | TRST; |
write (lp, &data, sizeof (data)); |
JTAG_WAIT(); |
146,6 → 182,10
jp1_read_JTAG () |
{ |
int data; |
|
if(connection.location != JTAG_LOCAL) /* CZ */ |
error("jp1_read_JTAG called without a local connection!"); |
|
ioctl (data, 0x60b, &data); |
data = ((data & 0x80) != 0); |
crc_r = crc_calc (crc_r, data); |
212,8 → 252,262
select_dr = 0; |
} |
|
/* Added by CZ 24/05/01 */ |
static int jtag_proxy_write(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: |
return JTAG_PROXY_SERVER_TERMINATED; |
default: |
return errno; |
} |
} |
else |
{ |
len -= n; |
w_buf += n; |
} |
} |
return 0; |
} |
|
/* Added by CZ 24/05/01 */ |
static int jtag_proxy_read(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 errno; |
} |
} |
else if(n == 0) |
return JTAG_PROXY_SERVER_TERMINATED; |
else |
{ |
len -= n; |
r_buf += n; |
} |
} |
return 0; |
} |
|
static int ReadResponse(int fd,void* buffer,int len) |
{ |
int32_t status = 0; |
int result = jtag_proxy_read(fd,&status,4); |
char* buf = (char*)buffer; |
|
status = ntohl(status); |
*((int32_t*)buffer) = status; |
|
if(result) return result; |
if(status) return status; |
|
result = jtag_proxy_read(fd,&buf[4],len-4); |
return result; |
} |
|
/* Added by CZ 24/05/01 */ |
#ifndef ANSI_PROTOTYPES |
static int jtag_send_proxy(va_alist) |
va_dcl |
#else |
static int jtag_send_proxy(int command,...) |
#endif |
{ |
va_list ap; |
int result = 0; |
int fd = connection.device.fd; |
JTAGProxyWriteMessage xmit_write; |
JTAGProxyReadMessage xmit_read; |
JTAGProxyChainMessage xmit_chain; |
JTAGProxyWriteResponse recv_write; |
JTAGProxyReadResponse recv_read; |
JTAGProxyChainResponse recv_chain; |
unsigned long long data,* ret_val; |
uint32_t word1; /* Use word1 and word2 to ease portability to platforms */ |
uint32_t word2; /* without long long and for alignment reasons */ |
|
#ifndef ANSI_PROTOTYPES |
int command; |
|
va_start(ap); |
command = va_arg(ap,int); |
#else |
va_start(ap, command); |
#endif |
|
|
|
if(connection.location == JTAG_REMOTE) |
{ |
switch(command) |
{ |
case JTAG_COMMAND_READ: |
xmit_read.command = htonl(command); |
xmit_read.length = htonl(sizeof(xmit_read)-8); |
xmit_read.address = htonl(va_arg(ap,int)); |
ret_val = va_arg(ap,unsigned long long *); |
/* intentional single equals */ |
if(result = jtag_proxy_write(fd,&xmit_read,sizeof(xmit_read))) |
break; |
if(result = ReadResponse(fd,&recv_read,sizeof(recv_read))) |
break; |
result = ntohl(recv_read.status); |
word1 = ntohl(recv_read.data_H); |
word2 = ntohl(recv_read.data_L); |
*ret_val = (((unsigned long long)word1) << 32) | word2; |
break; |
case JTAG_COMMAND_WRITE: |
xmit_write.command = htonl(command); |
xmit_write.length = htonl(sizeof(xmit_write)-8); |
xmit_write.address = htonl(va_arg(ap,int)); |
data = va_arg(ap,unsigned long long); |
word1 = htonl(data >> 32); |
word2 = htonl(data & 0xFFFFFFFF); |
xmit_write.data_H = word1; |
xmit_write.data_L = word2; |
if(result = jtag_proxy_write(fd,&xmit_write,sizeof(xmit_write))) |
break; |
if(result = ReadResponse(fd,&recv_write,sizeof(recv_write))) |
break; |
result = recv_write.status; |
break; |
case JTAG_COMMAND_CHAIN: |
xmit_chain.command = htonl(command); |
xmit_chain.length = htonl(sizeof(xmit_chain)-8); |
xmit_chain.chain = htonl(va_arg(ap,unsigned int)); |
if(result = jtag_proxy_write(fd,&xmit_chain,sizeof(xmit_chain))) |
break; |
if(result = ReadResponse(fd,&recv_chain,sizeof(recv_chain))) |
break; |
result = recv_chain.status; |
break; |
default: |
result = JTAG_PROXY_INVALID_COMMAND; |
break; |
} |
va_end(ap); |
} |
else |
{ |
va_end(ap); |
error("jtag_send_proxy called without a remote proxy connection!"); |
result = JTAG_PROXY_NO_CONNECTION; |
} |
|
if(result == JTAG_PROXY_SERVER_TERMINATED) |
{ |
close(connection.device.fd); |
connection.device.fd = 0; |
connection.location = JTAG_NOT_CONNECTED; |
} |
|
return result; |
} |
|
/* Added by CZ 24/05/01 */ |
#ifndef ANSI_PROTOTYPES |
static void jtag_proxy_error(va_alist) |
va_dcl |
#else |
static void jtag_proxy_error(int result,int command,...) |
#endif |
{ |
va_list ap; |
char sTemp[256]; |
|
#ifndef ANSI_PROTOTYPES |
int result; |
int command; |
|
va_start(ap); |
result = va_arg(ap,int); |
command = va_arg(ap,int); |
#else |
va_start(ap, command); |
#endif |
|
switch(command) |
{ |
case JTAG_COMMAND_READ: |
sprintf(sTemp,"An error was reported by the proxy server. The command was:\n" |
"\"JTAG_COMMAND_READ\",%u,0x%08x\nThe command returned %d.\n", |
va_arg(ap,unsigned int),va_arg(ap,unsigned long long*),result); |
error(sTemp); |
break; |
case JTAG_COMMAND_WRITE: |
sprintf(sTemp,"An error was reported by the proxy server. The command was:\n" |
"\"JTAG_COMMAND_WRITE\",%u,0x%016llx\nThe command returned %d.\n", |
va_arg(ap,unsigned int),va_arg(ap,unsigned long long),result); |
error(sTemp); |
break; |
case JTAG_COMMAND_CHAIN: |
sprintf(sTemp,"An error was reported by the proxy server. The command was:\n" |
"\"JTAG_COMMAND_CHAIN\",%u. The command returned %d.\n", |
va_arg(ap,unsigned int)); |
error(sTemp); |
break; |
default: |
sprintf(sTemp,"An error was reported by the proxy server. The command is " |
"currently unimplemented.\nThe command code was %d, and the result " |
"code was %d.\n",command,result); |
error(sTemp); |
break; |
} |
va_end(ap); |
} |
|
/* Sets register/memory regno to data. */ |
|
/* CZ 08/06/01: I am not sure how error checking is intended to |
be implemented here. It appears that no indication is returned |
to the caller as you have in standard unix system calls. Therefore, |
I guess the only way to use these functions when you want to know |
the exact position of the error is to manually clear err, call the |
function, and then manually check err. I have also made some changes |
where necessary because no value was returned at all int jtag_read_reg. |
*/ |
|
void |
jtag_write_reg (regno, data) |
int regno; |
220,52 → 514,68
ULONGEST data; |
{ |
int crc_read, crc_write, crc_ok, retry; |
int result; |
|
if (!select_dr) |
jp1_write_JTAG (1); /* SELECT_DR SCAN */ |
select_dr = 1; |
switch(connection.location) /* CZ */ |
{ |
case JTAG_LOCAL: |
if (!select_dr) |
jp1_write_JTAG (1); /* SELECT_DR SCAN */ |
select_dr = 1; |
|
/* If we don't have rw bit, we assume chain |
is read only. */ |
if (!chain_has_rw[current_chain]) |
error ("Internal: Chain not writable."); |
/* If we don't have rw bit, we assume chain |
is read only. */ |
if (!chain_has_rw[current_chain]) |
error ("Internal: Chain not writable."); |
|
for (retry = 0; retry < NUM_RETRIES; retry++) |
{ |
jp1_write_JTAG (0); /* CAPTURE_DR */ |
jp1_write_JTAG (0); /* SHIFT_DR */ |
crc_w = 0; |
for (retry = 0; retry < NUM_RETRIES; retry++) |
{ |
jp1_write_JTAG (0); /* CAPTURE_DR */ |
jp1_write_JTAG (0); /* SHIFT_DR */ |
crc_w = 0; |
|
/* write addr */ |
jp1_write_stream (regno, chain_addr_size[current_chain], 0); |
/* write addr */ |
jp1_write_stream (regno, chain_addr_size[current_chain], 0); |
|
/* write (R/W=1) - we tested that previously. */ |
jp1_write_JTAG (2); |
/* write (R/W=1) - we tested that previously. */ |
jp1_write_JTAG (2); |
|
/* write data */ |
jp1_write_stream (data, chain_data_size[current_chain], 0); |
if (chain_has_crc[current_chain]) |
{ |
crc_write = crc_w; |
/* write data */ |
jp1_write_stream (data, chain_data_size[current_chain], 0); |
if (chain_has_crc[current_chain]) |
{ |
crc_write = crc_w; |
|
/* write CRC, EXIT1_DR */ |
crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1); |
/* write CRC, EXIT1_DR */ |
crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1); |
} |
jp1_write_JTAG (1); /* UPDATE_DR */ |
|
/* Did JTAG receive packet correctly? */ |
if (chain_has_crc[current_chain]) |
crc_ok = jp1_read_JTAG (); |
jp1_write_JTAG (1); /* SELECT_DR */ |
if (chain_has_crc[current_chain]) |
{ |
if ((crc_read == crc_write) && (crc_ok)) |
return; |
JTAG_RETRY_WAIT(); |
} |
else return; |
} |
jp1_write_JTAG (1); /* UPDATE_DR */ |
|
/* Did JTAG receive packet correctly? */ |
if (chain_has_crc[current_chain]) |
crc_ok = jp1_read_JTAG (); |
jp1_write_JTAG (1); /* SELECT_DR */ |
if (chain_has_crc[current_chain]) |
err = ERR_CRC; |
break; |
case JTAG_REMOTE: |
if(result = jtag_send_proxy(JTAG_COMMAND_WRITE,regno,data)) |
{ |
if ((crc_read == crc_write) && (crc_ok)) |
return; |
JTAG_RETRY_WAIT(); |
jtag_proxy_error(result,JTAG_COMMAND_WRITE,regno,data); |
err = result; |
} |
else return; |
break; |
default: |
error("jtag_write_reg called with no connection!"); |
break; |
} |
err = ERR_CRC; |
} |
|
/* Reads register/memory from regno. */ |
276,51 → 586,69
{ |
ULONGEST data; |
int crc_read, crc_write, crc_actual_read, retry, crc_ok; |
int result; |
|
if (!select_dr) |
jp1_write_JTAG (1); /* SELECT_DR SCAN */ |
select_dr = 1; |
switch(connection.location) |
{ |
case JTAG_LOCAL: |
if (!select_dr) |
jp1_write_JTAG (1); /* SELECT_DR SCAN */ |
select_dr = 1; |
|
for (retry = 0; retry < NUM_RETRIES; retry++) |
{ |
jp1_write_JTAG (0); /* CAPTURE_DR */ |
jp1_write_JTAG (0); /* SHIFT_DR */ |
crc_w = 0; |
for (retry = 0; retry < NUM_RETRIES; retry++) |
{ |
jp1_write_JTAG (0); /* CAPTURE_DR */ |
jp1_write_JTAG (0); /* SHIFT_DR */ |
crc_w = 0; |
|
/* write addr */ |
jp1_write_stream (regno, chain_addr_size[current_chain], 0); |
/* write addr */ |
jp1_write_stream (regno, chain_addr_size[current_chain], 0); |
|
/* read (R/W=0) */ |
if (chain_has_rw[current_chain]) |
jp1_write_JTAG (0); |
if (chain_has_crc[current_chain]) |
{ |
crc_r = 0; |
/* read (R/W=0) */ |
if (chain_has_rw[current_chain]) |
jp1_write_JTAG (0); |
if (chain_has_crc[current_chain]) |
{ |
crc_r = 0; |
|
/* data = 0 */ |
data = jp1_read_stream (0, chain_data_size[current_chain], 0); |
crc_write = crc_w; |
crc_actual_read = crc_read; |
/* data = 0 */ |
data = jp1_read_stream (0, chain_data_size[current_chain], 0); |
crc_write = crc_w; |
crc_actual_read = crc_read; |
|
/* Send my crc, EXIT1_DR */ |
crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1); |
/* Send my crc, EXIT1_DR */ |
crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1); |
} |
jp1_write_JTAG (1); /* UPDATE_DR */ |
|
/* Did JTAG receive packet correctly? */ |
if (chain_has_crc[current_chain]) |
crc_ok = jp1_read_JTAG (); |
jp1_write_JTAG (1); /* SELECT_DR */ |
if (chain_has_crc[current_chain]) |
{ |
if ((crc_read == crc_actual_read) && (crc_ok)) |
return -1; /* CZ */ |
JTAG_RETRY_WAIT(); |
} |
else |
return -1; /* CZ */ |
} |
jp1_write_JTAG (1); /* UPDATE_DR */ |
|
/* Did JTAG receive packet correctly? */ |
if (chain_has_crc[current_chain]) |
crc_ok = jp1_read_JTAG (); |
jp1_write_JTAG (1); /* SELECT_DR */ |
if (chain_has_crc[current_chain]) |
err = ERR_CRC; |
break; |
case JTAG_REMOTE: |
if(result = jtag_send_proxy(JTAG_COMMAND_READ,regno,&data)) |
{ |
if ((crc_read == crc_actual_read) && (crc_ok)) |
return; |
JTAG_RETRY_WAIT(); |
jtag_proxy_error(result,JTAG_COMMAND_READ,regno,&data); |
err = result; |
} |
else |
return; |
break; |
default: |
error("jtag_write_reg called with no connection!"); |
break; |
} |
err = ERR_CRC; |
|
return data; /* CZ */ |
} |
|
/* Sets scan chain. */ |
329,46 → 657,179
jtag_set_chain (chain) |
int chain; |
{ |
if (current_chain != chain) |
int result; |
|
switch(connection.location) |
{ |
if (!chain_is_valid[chain]) |
error ("Chain not valid."); |
case JTAG_LOCAL: |
if (current_chain != chain) |
{ |
if (!chain_is_valid[chain]) |
error ("Chain not valid."); |
|
current_chain = chain; |
jp1_prepare_control (); |
current_chain = chain; |
jp1_prepare_control (); |
|
jp1_write_JTAG (0); /* CAPTURE_IR */ |
jp1_write_JTAG (0); /* SHIFT_IR */ |
jp1_write_JTAG (0); /* CAPTURE_IR */ |
jp1_write_JTAG (0); /* SHIFT_IR */ |
|
/* write data, EXIT1_IR */ |
jp1_write_stream (JI_CHAIN_SELECT, JI_SIZE, 4); |
/* write data, EXIT1_IR */ |
jp1_write_stream (JI_CHAIN_SELECT, JI_SIZE, 4); |
|
jp1_write_JTAG (1); /* UPDATE_IR */ |
jp1_write_JTAG (1); /* SELECT_DR */ |
jp1_write_JTAG (1); /* UPDATE_IR */ |
jp1_write_JTAG (1); /* SELECT_DR */ |
|
jp1_write_JTAG (0); /* CAPTURE_DR */ |
jp1_write_JTAG (0); /* SHIFT_DR */ |
jp1_write_JTAG (0); /* CAPTURE_DR */ |
jp1_write_JTAG (0); /* SHIFT_DR */ |
|
/* write data, EXIT1_DR */ |
jp1_write_stream (chain, SC_SIZE, 1); |
/* write data, EXIT1_DR */ |
jp1_write_stream (chain, SC_SIZE, 1); |
|
jp1_write_JTAG (1); /* UPDATE_DR */ |
jp1_write_JTAG (1); /* SELECT_DR */ |
jp1_write_JTAG (1); /* UPDATE_DR */ |
jp1_write_JTAG (1); /* SELECT_DR */ |
|
/* Now we have to go out of SELECT_CHAIN mode. */ |
jp1_write_JTAG (1); /* SELECT_IR */ |
jp1_write_JTAG (0); /* CAPTURE_IR */ |
jp1_write_JTAG (0); /* SHIFT_IR */ |
/* Now we have to go out of SELECT_CHAIN mode. */ |
jp1_write_JTAG (1); /* SELECT_IR */ |
jp1_write_JTAG (0); /* CAPTURE_IR */ |
jp1_write_JTAG (0); /* SHIFT_IR */ |
|
/* write data, EXIT1_IR */ |
jp1_write_stream (JI_DEBUG, JI_SIZE,1 ); |
/* write data, EXIT1_IR */ |
jp1_write_stream (JI_DEBUG, JI_SIZE,1 ); |
|
jp1_write_JTAG (1); /* UPDATE_IR */ |
jp1_write_JTAG (1); /* SELECT_DR */ |
select_dr = 1; |
jp1_write_JTAG (1); /* UPDATE_IR */ |
jp1_write_JTAG (1); /* SELECT_DR */ |
select_dr = 1; |
} |
break; |
case JTAG_REMOTE: |
if(current_chain != chain) |
{ |
if(result = jtag_send_proxy(JTAG_COMMAND_CHAIN,chain)) |
{ |
jtag_proxy_error(result,JTAG_COMMAND_CHAIN,chain); |
err = result; |
} |
} |
break; |
default: |
error("jtag_set_chain called with no connection!"); |
break; |
} |
} |
|
/* Added by CZ 24/05/01 */ |
static int jtag_connect_to_server(char* hostname,char* name) |
{ |
struct hostent *host; |
struct sockaddr_in sin; |
struct servent *service; |
struct protoent *protocol; |
int sock,flags; |
int fd; |
char sTemp[256],sTemp2[256]; |
char* proto_name = "tcp"; |
int port = 0; |
int on_off = 0; /* Turn off Nagel's algorithm on the socket */ |
char *s; |
|
if(!(protocol = getprotobyname(proto_name))) |
{ |
sprintf(sTemp,"jtag_connect_to_server: Protocol \"%s\" not available.\n", |
proto_name); |
error(sTemp); |
return 0; |
} |
|
/* Convert name to an integer only if it is well formatted. |
Otherwise, assume that it is a service name. */ |
|
port = strtol(name,&s,10); |
if(*s) |
port = 0; |
|
if(!port) |
{ |
if(!(service = getservbyname(name,protocol->p_name))) |
{ |
sprintf(sTemp,"jtag_connect_to_server: Unknown service \"%s\".\n",name); |
error(sTemp); |
return 0; |
} |
|
port = ntohs(service->s_port); |
} |
|
if(!(host = gethostbyname(hostname))) |
{ |
sprintf(sTemp,"jtag_connect_to_server: Unknown host \"%s\"\n",hostname); |
error(sTemp); |
return 0; |
} |
|
if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0) |
{ |
sprintf(sTemp,"jtag_connect_to_server: can't create socket errno = %d\n", |
errno); |
sprintf(sTemp2,"%s\n",strerror(errno)); |
strcat(sTemp,sTemp2); |
error(sTemp); |
return 0; |
} |
|
if(fcntl(sock,F_GETFL,&flags) < 0) |
{ |
sprintf(sTemp,"Unable to get flags for JTAG proxy socket %d",sock); |
error(sTemp); |
close(sock); |
return 0; |
} |
|
if(fcntl(sock,F_SETFL, flags & ~O_NONBLOCK) < 0) |
{ |
sprintf(sTemp,"Unable to set flags for JTAG proxy socket %d to value 0x%08x", |
sock,flags | O_NONBLOCK); |
error(sTemp); |
close(sock); |
return 0; |
} |
|
memset(&sin,0,sizeof(sin)); |
sin.sin_family = host->h_addrtype; |
memcpy(&sin.sin_addr,host->h_addr_list[0],host->h_length); |
sin.sin_port = htons(port); |
|
if((connect(sock,(struct sockaddr*)&sin, sizeof(sin)) < 0) |
&& errno != EINPROGRESS) |
{ |
|
sprintf(sTemp,"jtag_connect_to_server: connect failed errno = %d\n",errno); |
sprintf(sTemp2,"%s\n",strerror(errno)); |
close(sock); |
strcat(sTemp,sTemp2); |
error(sTemp); |
return 0; |
} |
|
if(fcntl(sock,F_SETFL, flags | O_NONBLOCK) < 0) |
{ |
sprintf(sTemp,"Unable to set flags for JTAG proxy socket %d to value 0x%08x", |
sock,flags | O_NONBLOCK); |
error(sTemp); |
close(sock); |
return 0; |
} |
|
if(setsockopt(sock,protocol->p_proto,TCP_NODELAY,&on_off,sizeof(int)) < 0) |
{ |
sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",sock); |
error(sTemp); |
close(sock); |
return 0; |
} |
|
return sock; |
} |
|
/* Initialize a new connection to the or1k board, and make sure we are |
really connected. */ |
|
380,10 → 841,32
char *port_name; |
char **argv; |
|
if (args == 0) |
error ("To open a or1k remote debugging connection, you need to specify what parallel\n" |
"port device is attached to the target board (e.g., /dev/lp0).\n"); |
if (args == 0) /* CZ */ |
error ( "To open a or1k remote debugging connection, you need to specify a " |
"parallel port\nconnected to the target board, or else a remote " |
"server which will proxy these\nservices for you.\nExample: " |
"/dev/lp0 or jtag://debughost.mydomain.com:8100.\n"); |
|
/* If we currently have an open connection, shut it |
down. This is due to a temporary bug in gdb. */ |
switch(connection.location) |
{ |
case JTAG_REMOTE: |
if(connection.device.fd > 0) |
{ |
close(connection.device.fd); |
} |
break; |
case JTAG_LOCAL: |
if(connection.device.lp > 0) |
{ |
close(connection.device.lp); |
} |
break; |
default: |
break; |
} |
|
/* Parse the port name. */ |
if ((argv = buildargv (args)) == NULL) |
nomem (0); |
390,21 → 873,103
port_name = strsave (argv[0]); |
make_cleanup_freeargv (argv); |
|
/* Open and initialize the parallel port. */ |
lp = open (port_name, O_WRONLY); |
if (lp < 0) |
error ("Cannot open device."); |
/* CZ 24/05/01 - Check to see if we have specified a remote |
jtag interface or a local one. It is remote if it follows |
the URL naming convention jtag://<hostname>:<port> */ |
if(!strncmp(port_name,"jtag://",7)) |
{ |
char *port = strchr(&port_name[7],':'); |
char hostname[256]; |
|
printf_unfiltered ("Remote or1k debugging using %s\n", port_name); |
if(port) |
{ |
int len = port - port_name - 7; |
strncpy(hostname,&port_name[7],len); |
hostname[len] = '\0'; |
port++; |
} |
else |
strcpy(hostname,&port_name[7]); |
|
/* Interface is remote */ |
if(!(connection.device.fd = jtag_connect_to_server(hostname,port))) |
{ |
char sTemp[256]; |
sprintf(sTemp,"Can not access JTAG Proxy Server at \"%s\"", |
&port_name[5]); |
error(sTemp); |
} |
connection.location = JTAG_REMOTE; |
printf_unfiltered ("Remote or1k debugging using %s\n",port_name); |
} |
else |
{ |
/* Interface is local */ |
/* Open and initialize the parallel port. */ |
connection.device.lp = open (port_name, O_WRONLY); |
if (connection.device.lp < 0) |
error ("Cannot open device."); |
connection.location = JTAG_LOCAL; /* CZ */ |
printf_unfiltered ("Local or1k debugging using %s\n", port_name); |
|
} |
|
current_chain = -1; |
jp1_reset_JTAG (); |
if(connection.location == JTAG_LOCAL) |
jp1_reset_JTAG (); |
jtag_set_chain (SC_RISC_DEBUG); |
|
free (port_name); |
} |
|
void |
jtag_done () |
jtag_done () /* CZ */ |
{ |
close (lp); |
switch(connection.location) |
{ |
case JTAG_LOCAL: |
sync_close (connection.device.lp); |
connection.device.lp = 0; |
break; |
case JTAG_REMOTE: |
sync_close(connection.device.fd); |
connection.device.fd = 0; |
break; |
default: |
error("No jtag connection specified!"); |
break; |
} |
connection.location = JTAG_NOT_CONNECTED; |
} |
|
int sync_close(int fd) |
{ |
int flags = 0; |
struct linger linger; |
char sTemp[256]; |
|
linger.l_onoff = 0; |
linger.l_linger = 0; |
|
/* First, make sure we're non blocking */ |
if(fcntl(fd,F_GETFL,&flags) < 0) |
{ |
sprintf(sTemp,"Unable to get flags for JTAG proxy socket %d",fd); |
error(sTemp); |
} |
if(fcntl(fd,F_SETFL, flags & ~O_NONBLOCK) < 0) |
{ |
sprintf(sTemp,"Unable to set flags for JTAG proxy socket %d to value 0x%08x", |
fd,flags | O_NONBLOCK); |
error(sTemp); |
} |
|
/* Now, make sure we don't linger around */ |
if(setsockopt(fd,SOL_SOCKET,SO_LINGER,&linger,sizeof(linger)) < 0) |
{ |
sprintf(sTemp,"Unable to disable SO_LINGER for JTAG proxy socket %d.",fd); |
error(sTemp); |
} |
|
return close(fd); |
} |