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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [jtag.c] - Diff between revs 1330 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1330 Rev 1765
/* Remote debugging interface for JTAG debugging protocol.
/* Remote debugging interface for JTAG debugging protocol.
   JTAG connects to or1k target ops. See or1k-tdep.c
   JTAG connects to or1k target ops. See or1k-tdep.c
 
 
   Copyright 1993-1995, 2000 Free Software Foundation, Inc.
   Copyright 1993-1995, 2000 Free Software Foundation, Inc.
   Contributed by Cygnus Support.  Written by Marko Mlinar
   Contributed by Cygnus Support.  Written by Marko Mlinar
   <markom@opencores.org>
   <markom@opencores.org>
   Areas noted by (CZ) were modified by Chris Ziomkowski
   Areas noted by (CZ) were modified by Chris Ziomkowski
   <chris@asics.ws>
   <chris@asics.ws>
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
   Boston, MA 02111-1307, USA.  */
 
 
#include "defs.h"
#include "defs.h"
#include "inferior.h"
#include "inferior.h"
#include "bfd.h"
#include "bfd.h"
#include "symfile.h"
#include "symfile.h"
#include "gdb_wait.h"
#include "gdb_wait.h"
#include "gdbcmd.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "gdbcore.h"
#include "serial.h"
#include "serial.h"
#include "target.h"
#include "target.h"
#include "remote-utils.h"
#include "remote-utils.h"
#include "gdb_string.h"
#include "gdb_string.h"
#include "tm.h"
#include "tm.h"
/* Added by CZ 24/05/01 */
/* Added by CZ 24/05/01 */
#include <sys/poll.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/tcp.h>
#include <sys/select.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/time.h>
#include <unistd.h>
#include <unistd.h>
 
 
#include <signal.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <fcntl.h>
 
 
#define TCLK (0x01)
#define TCLK (0x01)
#define TRST (0x02)
#define TRST (0x02)
#define JTAG_WAIT()
#define JTAG_WAIT()
#define NUM_RETRIES (16)
#define NUM_RETRIES (16)
#define JTAG_RETRY_WAIT() usleep (100)
#define JTAG_RETRY_WAIT() usleep (100)
 
 
/* Selects crc trailer size in bits. Currently supported: 8 */
/* Selects crc trailer size in bits. Currently supported: 8 */
#define CRC_SIZE (8)
#define CRC_SIZE (8)
 
 
/* Scan chain size in bits.  */
/* Scan chain size in bits.  */
#define SC_SIZE (4)
#define SC_SIZE (4)
 
 
/* Scan chain info. */
/* Scan chain info. */
/* *INDENT-OFF* */
/* *INDENT-OFF* */
static int chain_addr_size[] = { 0,  32, 0,  0,  5  };
static int chain_addr_size[] = { 0,  32, 0,  0,  5  };
static int chain_data_size[] = { 0,  32, 0,  32, 32 };
static int chain_data_size[] = { 0,  32, 0,  32, 32 };
static int chain_is_valid[]  = { 0,  1,  0,  1,  1  };
static int chain_is_valid[]  = { 0,  1,  0,  1,  1  };
static int chain_has_crc[]   = { 0,  1,  0,  1,  1  };
static int chain_has_crc[]   = { 0,  1,  0,  1,  1  };
static int chain_has_rw[]    = { 0,  1,  0,  0,  1  };
static int chain_has_rw[]    = { 0,  1,  0,  0,  1  };
/* *INDENT-OFF* */
/* *INDENT-OFF* */
 
 
/* Currently selected scan chain - just to prevent unnecessary
/* Currently selected scan chain - just to prevent unnecessary
   transfers. */
   transfers. */
static int current_chain;
static int current_chain;
 
 
/* Designates whether we are in SELECT_DR state, otherwise in
/* Designates whether we are in SELECT_DR state, otherwise in
   RUN TEST/IDLE */
   RUN TEST/IDLE */
static int select_dr = 0;
static int select_dr = 0;
 
 
/* CZ - 24/05/01 - Changed to structure for remote/local */
/* CZ - 24/05/01 - Changed to structure for remote/local */
typedef enum {
typedef enum {
  JTAG_NOT_CONNECTED = 0,
  JTAG_NOT_CONNECTED = 0,
  JTAG_LOCAL = 1,
  JTAG_LOCAL = 1,
  JTAG_REMOTE = 2,
  JTAG_REMOTE = 2,
} jtag_location;
} jtag_location;
 
 
typedef struct {
typedef struct {
  union {
  union {
    int lp; /* Printer compatible device we have open.  */
    int lp; /* Printer compatible device we have open.  */
    int fd; /* Socket for remote or1k jtag interface */
    int fd; /* Socket for remote or1k jtag interface */
  } device;
  } device;
  jtag_location location;
  jtag_location location;
} jtag_connection;
} jtag_connection;
 
 
/* Our current connect information */
/* Our current connect information */
static jtag_connection connection;
static jtag_connection connection;
 
 
/* Crc of current read or written data.  */
/* Crc of current read or written data.  */
static int crc_r, crc_w = 0;
static int crc_r, crc_w = 0;
 
 
/* Generates new crc, sending in new bit input_bit */
/* Generates new crc, sending in new bit input_bit */
 
 
static int
static int
crc_calc (int crc, int input_bit)
crc_calc (int crc, int input_bit)
{
{
  int c;
  int c;
  int new_crc;
  int new_crc;
  int d;
  int d;
 
 
#if (CRC_SIZE == 8)
#if (CRC_SIZE == 8)
  d = input_bit&1;
  d = input_bit&1;
  c = crc;
  c = crc;
 
 
  /* Move queue left.  */
  /* Move queue left.  */
  new_crc = crc << 1;
  new_crc = crc << 1;
 
 
  /* Mask upper five bits.  */
  /* Mask upper five bits.  */
  new_crc &= 0xF8;
  new_crc &= 0xF8;
 
 
  /* Set lower three bits */
  /* Set lower three bits */
  new_crc |= (d ^ ((c >> 7)&1));
  new_crc |= (d ^ ((c >> 7)&1));
  new_crc |= (d ^ ((c >> 0)&1) ^ ((c >> 7)&1)) << 1;
  new_crc |= (d ^ ((c >> 0)&1) ^ ((c >> 7)&1)) << 1;
  new_crc |= (d ^ ((c >> 1)&1) ^ ((c >> 7)&1)) << 2;
  new_crc |= (d ^ ((c >> 1)&1) ^ ((c >> 7)&1)) << 2;
  return new_crc;
  return new_crc;
#else
#else
  return 0;
  return 0;
#endif
#endif
}
}
 
 
/* Resets JTAG.
/* Resets JTAG.
   Writes TRST=0
   Writes TRST=0
   and    TRST=1 */
   and    TRST=1 */
 
 
static void
static void
jp1_reset_JTAG ()
jp1_reset_JTAG ()
{
{
  unsigned char data;
  unsigned char data;
  int lp = connection.device.lp;         /* CZ */
  int lp = connection.device.lp;         /* CZ */
 
 
  if(connection.location != JTAG_LOCAL)
  if(connection.location != JTAG_LOCAL)
    error("jp1_reset_JTAG called without a local connection!");
    error("jp1_reset_JTAG called without a local connection!");
 
 
  data = 0;
  data = 0;
  write (lp, &data, sizeof (data));
  write (lp, &data, sizeof (data));
  JTAG_WAIT();
  JTAG_WAIT();
  data = TRST;
  data = TRST;
  write (lp, &data, sizeof (data));
  write (lp, &data, sizeof (data));
  JTAG_WAIT();
  JTAG_WAIT();
}
}
 
 
/* Writes TCLK=0, TRST=1, TMS=bit0, TDI=bit1
/* Writes TCLK=0, TRST=1, TMS=bit0, TDI=bit1
   and    TCLK=1, TRST=1, TMS=bit0, TDI=bit1 */
   and    TCLK=1, TRST=1, TMS=bit0, TDI=bit1 */
 
 
static void
static void
jp1_write_JTAG (packet)
jp1_write_JTAG (packet)
     unsigned char packet;
     unsigned char packet;
{
{
  unsigned char data;
  unsigned char data;
  int lp = connection.device.lp;    /* CZ */
  int lp = connection.device.lp;    /* CZ */
 
 
  if(connection.location != JTAG_LOCAL)
  if(connection.location != JTAG_LOCAL)
    error("jp1_write_JTAG called without a local connection!");
    error("jp1_write_JTAG called without a local connection!");
 
 
  data = ((packet & 3) << 2) | TRST;
  data = ((packet & 3) << 2) | TRST;
  write (lp, &data, sizeof (data));
  write (lp, &data, sizeof (data));
  JTAG_WAIT();
  JTAG_WAIT();
  crc_w = crc_calc (crc_w, (packet >> 1)&1);
  crc_w = crc_calc (crc_w, (packet >> 1)&1);
 
 
  /* rise clock */
  /* rise clock */
  data |= TCLK;
  data |= TCLK;
  write (lp, &data, sizeof (data));
  write (lp, &data, sizeof (data));
  JTAG_WAIT();
  JTAG_WAIT();
}
}
 
 
/* Reads TDO, using IOCTL.  */
/* Reads TDO, using IOCTL.  */
 
 
static int
static int
jp1_read_JTAG ()
jp1_read_JTAG ()
{
{
  int data;
  int data;
 
 
  if(connection.location != JTAG_LOCAL)    /* CZ */
  if(connection.location != JTAG_LOCAL)    /* CZ */
    error("jp1_read_JTAG called without a local connection!");
    error("jp1_read_JTAG called without a local connection!");
 
 
  ioctl (data, 0x60b, &data);
  ioctl (data, 0x60b, &data);
  data = ((data & 0x80) != 0);
  data = ((data & 0x80) != 0);
  crc_r = crc_calc (crc_r, data);
  crc_r = crc_calc (crc_r, data);
  return data;
  return data;
}
}
 
 
/* Writes bitstream.  MS bit first.  */
/* Writes bitstream.  MS bit first.  */
 
 
static void
static void
jp1_write_stream (stream, len, set_last_bit)
jp1_write_stream (stream, len, set_last_bit)
     ULONGEST stream;
     ULONGEST stream;
     int len;
     int len;
     int set_last_bit;
     int set_last_bit;
{
{
  int i;
  int i;
  if (len <= 0) return;
  if (len <= 0) return;
  for (i = len - 1; i > 0; i--)
  for (i = len - 1; i > 0; i--)
    jp1_write_JTAG (((stream >> i) & 1) << 1);
    jp1_write_JTAG (((stream >> i) & 1) << 1);
 
 
  if (set_last_bit)
  if (set_last_bit)
    jp1_write_JTAG (((stream & 1) << 1) | 1);
    jp1_write_JTAG (((stream & 1) << 1) | 1);
  else
  else
    jp1_write_JTAG ((stream & 1) << 1);
    jp1_write_JTAG ((stream & 1) << 1);
}
}
 
 
/* Gets bitstream.  MS bit first.  */
/* Gets bitstream.  MS bit first.  */
 
 
static ULONGEST
static ULONGEST
jp1_read_stream (len, stream, set_last_bit)
jp1_read_stream (len, stream, set_last_bit)
     int len;
     int len;
     unsigned long stream;
     unsigned long stream;
     int set_last_bit;
     int set_last_bit;
{
{
  int i;
  int i;
  ULONGEST data;
  ULONGEST data;
 
 
  if (len <= 0) return;
  if (len <= 0) return;
  data = 0;
  data = 0;
  for (i = 0; i < len-1; i++)
  for (i = 0; i < len-1; i++)
    {
    {
      jp1_write_JTAG (0 + ((stream & 1) << 1));
      jp1_write_JTAG (0 + ((stream & 1) << 1));
      stream >>= 1;
      stream >>= 1;
      data <<= 1;
      data <<= 1;
      data |= jp1_read_JTAG ();
      data |= jp1_read_JTAG ();
    }
    }
 
 
  if (set_last_bit)
  if (set_last_bit)
    jp1_write_JTAG (1 + (stream & 1) << 1);
    jp1_write_JTAG (1 + (stream & 1) << 1);
  else
  else
    jp1_write_JTAG (0 + (stream & 1) << 1);
    jp1_write_JTAG (0 + (stream & 1) << 1);
  data <<= 1;
  data <<= 1;
  data |= jp1_read_JTAG ();
  data |= jp1_read_JTAG ();
  return data;
  return data;
}
}
 
 
/* Goes into SELECT_IR state. Should be called before every control write.  */
/* Goes into SELECT_IR state. Should be called before every control write.  */
 
 
static void
static void
jp1_prepare_control ()
jp1_prepare_control ()
{
{
  if (!select_dr)
  if (!select_dr)
    jp1_write_JTAG (1); /* SELECT_DR SCAN */
    jp1_write_JTAG (1); /* SELECT_DR SCAN */
  jp1_write_JTAG (1);   /* SELECT_IR SCAN */
  jp1_write_JTAG (1);   /* SELECT_IR SCAN */
  select_dr = 0;
  select_dr = 0;
}
}
 
 
/* Added by CZ 24/05/01 */
/* Added by CZ 24/05/01 */
static int jtag_proxy_write(int fd,void* buf,int len)
static int jtag_proxy_write(int fd,void* buf,int len)
{
{
  int n;
  int n;
  char* w_buf = (char*)buf;
  char* w_buf = (char*)buf;
  struct pollfd block;
  struct pollfd block;
 
 
  while(len)
  while(len)
    {
    {
      if((n = write(fd,w_buf,len)) < 0)
      if((n = write(fd,w_buf,len)) < 0)
        {
        {
          switch(errno)
          switch(errno)
            {
            {
            case EWOULDBLOCK: /* or EAGAIN */
            case EWOULDBLOCK: /* or EAGAIN */
              /* We've been called on a descriptor marked
              /* We've been called on a descriptor marked
                 for nonblocking I/O. We better simulate
                 for nonblocking I/O. We better simulate
                 blocking behavior. */
                 blocking behavior. */
              block.fd = fd;
              block.fd = fd;
              block.events = POLLOUT;
              block.events = POLLOUT;
              block.revents = 0;
              block.revents = 0;
              poll(&block,1,-1);
              poll(&block,1,-1);
              continue;
              continue;
            case EINTR:
            case EINTR:
              continue;
              continue;
            case EPIPE:
            case EPIPE:
              return JTAG_PROXY_SERVER_TERMINATED;
              return JTAG_PROXY_SERVER_TERMINATED;
            default:
            default:
              return errno;
              return errno;
            }
            }
        }
        }
      else
      else
        {
        {
          len -= n;
          len -= n;
          w_buf += n;
          w_buf += n;
        }
        }
    }
    }
  return 0;
  return 0;
}
}
 
 
/* Added by CZ 24/05/01 */
/* Added by CZ 24/05/01 */
static int jtag_proxy_read(int fd,void* buf,int len)
static int jtag_proxy_read(int fd,void* buf,int len)
{
{
  int n;
  int n;
  char* r_buf = (char*)buf;
  char* r_buf = (char*)buf;
  struct pollfd block;
  struct pollfd block;
 
 
  while(len)
  while(len)
    {
    {
      if((n = read(fd,r_buf,len)) < 0)
      if((n = read(fd,r_buf,len)) < 0)
        {
        {
          switch(errno)
          switch(errno)
            {
            {
            case EWOULDBLOCK: /* or EAGAIN */
            case EWOULDBLOCK: /* or EAGAIN */
              /* We've been called on a descriptor marked
              /* We've been called on a descriptor marked
                 for nonblocking I/O. We better simulate
                 for nonblocking I/O. We better simulate
                 blocking behavior. */
                 blocking behavior. */
              block.fd = fd;
              block.fd = fd;
              block.events = POLLIN;
              block.events = POLLIN;
              block.revents = 0;
              block.revents = 0;
              poll(&block,1,-1);
              poll(&block,1,-1);
              continue;
              continue;
            case EINTR:
            case EINTR:
              continue;
              continue;
            default:
            default:
              return errno;
              return errno;
            }
            }
        }
        }
      else if(n == 0)
      else if(n == 0)
        return JTAG_PROXY_SERVER_TERMINATED;
        return JTAG_PROXY_SERVER_TERMINATED;
      else
      else
        {
        {
          len -= n;
          len -= n;
          r_buf += n;
          r_buf += n;
        }
        }
    }
    }
  return 0;
  return 0;
}
}
 
 
static int ReadResponse(int fd,void* buffer,int len)
static int ReadResponse(int fd,void* buffer,int len)
{
{
  int32_t status = 0;
  int32_t status = 0;
  int result;
  int result;
  char* buf = (char*)buffer;
  char* buf = (char*)buffer;
 
 
        result = jtag_proxy_read(fd,&status,4);
        result = jtag_proxy_read(fd,&status,4);
 
 
  status = ntohl(status);
  status = ntohl(status);
  *((int32_t*)buffer) = status;
  *((int32_t*)buffer) = status;
 
 
  if(result)    {printf("result %i %x\n", result, result); return result;}
  if(result)    {printf("result %i %x\n", result, result); return result;}
  if(status)    {printf("status %i %x\n", status, status); return status;}
  if(status)    {printf("status %i %x\n", status, status); return status;}
 
 
  result = jtag_proxy_read(fd,&buf[4],len-4);
  result = jtag_proxy_read(fd,&buf[4],len-4);
  return result;
  return result;
}
}
 
 
/* Added by CZ 24/05/01 */
/* Added by CZ 24/05/01 */
#ifndef ANSI_PROTOTYPES
#ifndef ANSI_PROTOTYPES
static int jtag_send_proxy(va_alist)
static int jtag_send_proxy(va_alist)
va_dcl
va_dcl
#else
#else
static int jtag_send_proxy(int command,...)
static int jtag_send_proxy(int command,...)
#endif
#endif
{
{
  va_list ap;
  va_list ap;
  int result = 0;
  int result = 0;
  int fd = connection.device.fd;
  int fd = connection.device.fd;
  JTAGProxyWriteMessage xmit_write;
  JTAGProxyWriteMessage xmit_write;
  JTAGProxyReadMessage xmit_read;
  JTAGProxyReadMessage xmit_read;
  JTAGProxyChainMessage xmit_chain;
  JTAGProxyChainMessage xmit_chain;
  JTAGProxyBlockWriteMessage *xmit_bwrite;
  JTAGProxyBlockWriteMessage *xmit_bwrite;
  JTAGProxyBlockReadMessage xmit_bread;
  JTAGProxyBlockReadMessage xmit_bread;
  JTAGProxyWriteResponse recv_write;
  JTAGProxyWriteResponse recv_write;
  JTAGProxyReadResponse recv_read;
  JTAGProxyReadResponse recv_read;
  JTAGProxyChainResponse recv_chain;
  JTAGProxyChainResponse recv_chain;
  JTAGProxyBlockWriteResponse recv_bwrite;
  JTAGProxyBlockWriteResponse recv_bwrite;
  JTAGProxyBlockReadResponse recv_bread;
  JTAGProxyBlockReadResponse recv_bread;
  unsigned long long data,* ret_val;
  unsigned long long data,* ret_val;
  uint32_t word1; /* Use word1 and word2 to ease portability to platforms */
  uint32_t word1; /* Use word1 and word2 to ease portability to platforms */
  uint32_t word2; /* without long long and for alignment reasons */
  uint32_t word2; /* without long long and for alignment reasons */
  unsigned long  address;
  unsigned long  address;
  unsigned long* b_data;
  unsigned long* b_data;
  int nRegisters;
  int nRegisters;
  int len,i;
  int len,i;
 
 
#ifndef ANSI_PROTOTYPES
#ifndef ANSI_PROTOTYPES
  int command;
  int command;
 
 
  va_start(ap);
  va_start(ap);
  command = va_arg(ap,int);
  command = va_arg(ap,int);
#else
#else
  va_start(ap, command);
  va_start(ap, command);
#endif
#endif
 
 
 
 
 
 
  if(connection.location == JTAG_REMOTE)
  if(connection.location == JTAG_REMOTE)
    {
    {
      switch(command)
      switch(command)
        {
        {
        case JTAG_COMMAND_READ:
        case JTAG_COMMAND_READ:
          xmit_read.command = htonl(command);
          xmit_read.command = htonl(command);
          xmit_read.length = htonl(sizeof(xmit_read)-8);
          xmit_read.length = htonl(sizeof(xmit_read)-8);
          xmit_read.address = htonl(va_arg(ap,int));
          xmit_read.address = htonl(va_arg(ap,int));
          ret_val = va_arg(ap,unsigned long long *);
          ret_val = va_arg(ap,unsigned long long *);
          /* intentional single equals */
          /* intentional single equals */
          if(result = jtag_proxy_write(fd,&xmit_read,sizeof(xmit_read)))
          if(result = jtag_proxy_write(fd,&xmit_read,sizeof(xmit_read)))
            break;
            break;
          if(result = ReadResponse(fd,&recv_read,sizeof(recv_read)))
          if(result = ReadResponse(fd,&recv_read,sizeof(recv_read)))
            break;
            break;
          result = ntohl(recv_read.status);
          result = ntohl(recv_read.status);
          word1 = ntohl(recv_read.data_H);
          word1 = ntohl(recv_read.data_H);
          word2 = ntohl(recv_read.data_L);
          word2 = ntohl(recv_read.data_L);
          *ret_val = (((unsigned long long)word1) << 32) | word2;
          *ret_val = (((unsigned long long)word1) << 32) | word2;
          break;
          break;
        case JTAG_COMMAND_WRITE:
        case JTAG_COMMAND_WRITE:
          xmit_write.command = htonl(command);
          xmit_write.command = htonl(command);
          xmit_write.length = htonl(sizeof(xmit_write)-8);
          xmit_write.length = htonl(sizeof(xmit_write)-8);
          xmit_write.address = htonl(va_arg(ap,int));
          xmit_write.address = htonl(va_arg(ap,int));
          data = va_arg(ap,unsigned long long);
          data = va_arg(ap,unsigned long long);
          word1 = htonl(data >> 32);
          word1 = htonl(data >> 32);
          word2 = htonl(data & 0xFFFFFFFF);
          word2 = htonl(data & 0xFFFFFFFF);
          xmit_write.data_H = word1;
          xmit_write.data_H = word1;
          xmit_write.data_L = word2;
          xmit_write.data_L = word2;
          if(result = jtag_proxy_write(fd,&xmit_write,sizeof(xmit_write)))
          if(result = jtag_proxy_write(fd,&xmit_write,sizeof(xmit_write)))
            break;
            break;
          if(result = ReadResponse(fd,&recv_write,sizeof(recv_write)))
          if(result = ReadResponse(fd,&recv_write,sizeof(recv_write)))
            break;
            break;
          result = recv_write.status;
          result = recv_write.status;
          break;
          break;
        case JTAG_COMMAND_BLOCK_WRITE:
        case JTAG_COMMAND_BLOCK_WRITE:
          address = va_arg(ap,unsigned long);
          address = va_arg(ap,unsigned long);
          b_data = va_arg(ap,unsigned long*);
          b_data = va_arg(ap,unsigned long*);
          nRegisters = va_arg(ap,int);
          nRegisters = va_arg(ap,int);
          len = sizeof(JTAGProxyBlockWriteMessage) + (nRegisters-1)*4;
          len = sizeof(JTAGProxyBlockWriteMessage) + (nRegisters-1)*4;
          xmit_bwrite = (JTAGProxyBlockWriteMessage*)malloc(len);
          xmit_bwrite = (JTAGProxyBlockWriteMessage*)malloc(len);
          xmit_bwrite->command = htonl(command);
          xmit_bwrite->command = htonl(command);
          xmit_bwrite->length = htonl(len-8);
          xmit_bwrite->length = htonl(len-8);
          xmit_bwrite->address = htonl(address);
          xmit_bwrite->address = htonl(address);
          xmit_bwrite->nRegisters = htonl(nRegisters);
          xmit_bwrite->nRegisters = htonl(nRegisters);
          for(i=0;i<nRegisters;i++)
          for(i=0;i<nRegisters;i++)
            xmit_bwrite->data[i] = htonl(b_data[i]);
            xmit_bwrite->data[i] = htonl(b_data[i]);
          if(!(result = jtag_proxy_write(fd,xmit_bwrite,len)) &&
          if(!(result = jtag_proxy_write(fd,xmit_bwrite,len)) &&
             !(result = ReadResponse(fd,&recv_bwrite,sizeof(recv_bwrite))))
             !(result = ReadResponse(fd,&recv_bwrite,sizeof(recv_bwrite))))
            result = recv_bwrite.status;
            result = recv_bwrite.status;
          free(xmit_bwrite);
          free(xmit_bwrite);
          xmit_bwrite = NULL;
          xmit_bwrite = NULL;
          break;
          break;
        case JTAG_COMMAND_BLOCK_READ:
        case JTAG_COMMAND_BLOCK_READ:
          address = va_arg(ap,unsigned long);
          address = va_arg(ap,unsigned long);
          b_data = va_arg(ap,unsigned long*);
          b_data = va_arg(ap,unsigned long*);
          nRegisters = va_arg(ap,int);
          nRegisters = va_arg(ap,int);
          xmit_bread.command = htonl(command);
          xmit_bread.command = htonl(command);
          xmit_bread.length = htonl(sizeof(xmit_bread)-8);
          xmit_bread.length = htonl(sizeof(xmit_bread)-8);
          xmit_bread.address = htonl(address);
          xmit_bread.address = htonl(address);
          xmit_bread.nRegisters = htonl(nRegisters);
          xmit_bread.nRegisters = htonl(nRegisters);
          if(result = jtag_proxy_write(fd,&xmit_bread,sizeof(xmit_bread)))
          if(result = jtag_proxy_write(fd,&xmit_bread,sizeof(xmit_bread)))
            break;
            break;
          if(result = ReadResponse(fd,&recv_bread,sizeof(recv_bread)))
          if(result = ReadResponse(fd,&recv_bread,sizeof(recv_bread)))
            break;
            break;
          b_data[0] = ntohl(recv_bread.data[0]);
          b_data[0] = ntohl(recv_bread.data[0]);
          recv_bread.nRegisters = ntohl(recv_bread.nRegisters);
          recv_bread.nRegisters = ntohl(recv_bread.nRegisters);
          if(result = jtag_proxy_read(fd,&b_data[1],4*(recv_bread.nRegisters-1)))
          if(result = jtag_proxy_read(fd,&b_data[1],4*(recv_bread.nRegisters-1)))
            break;
            break;
          if(recv_bread.nRegisters != nRegisters)
          if(recv_bread.nRegisters != nRegisters)
            result = JTAG_PROXY_PROTOCOL_ERROR;
            result = JTAG_PROXY_PROTOCOL_ERROR;
          else
          else
            {
            {
              for(i=1;i<nRegisters;i++)
              for(i=1;i<nRegisters;i++)
                b_data[i] = ntohl(b_data[i]);
                b_data[i] = ntohl(b_data[i]);
            }
            }
          break;
          break;
        case JTAG_COMMAND_CHAIN:
        case JTAG_COMMAND_CHAIN:
          xmit_chain.command = htonl(command);
          xmit_chain.command = htonl(command);
          xmit_chain.length = htonl(sizeof(xmit_chain)-8);
          xmit_chain.length = htonl(sizeof(xmit_chain)-8);
          xmit_chain.chain = htonl(va_arg(ap,unsigned int));
          xmit_chain.chain = htonl(va_arg(ap,unsigned int));
          if(result = jtag_proxy_write(fd,&xmit_chain,sizeof(xmit_chain)))
          if(result = jtag_proxy_write(fd,&xmit_chain,sizeof(xmit_chain)))
            break;
            break;
          if(result = ReadResponse(fd,&recv_chain,sizeof(recv_chain)))
          if(result = ReadResponse(fd,&recv_chain,sizeof(recv_chain)))
            break;
            break;
          result = recv_chain.status;
          result = recv_chain.status;
          break;
          break;
        default:
        default:
          result = JTAG_PROXY_INVALID_COMMAND;
          result = JTAG_PROXY_INVALID_COMMAND;
          break;
          break;
        }
        }
      va_end(ap);
      va_end(ap);
    }
    }
  else
  else
    {
    {
      va_end(ap);
      va_end(ap);
      error("jtag_send_proxy called without a remote proxy connection!");
      error("jtag_send_proxy called without a remote proxy connection!");
      result = JTAG_PROXY_NO_CONNECTION;
      result = JTAG_PROXY_NO_CONNECTION;
    }
    }
 
 
  if(result == JTAG_PROXY_SERVER_TERMINATED)
  if(result == JTAG_PROXY_SERVER_TERMINATED)
    {
    {
      close(connection.device.fd);
      close(connection.device.fd);
      connection.device.fd = 0;
      connection.device.fd = 0;
      connection.location = JTAG_NOT_CONNECTED;
      connection.location = JTAG_NOT_CONNECTED;
    }
    }
 
 
  return result;
  return result;
}
}
 
 
/* Added by CZ 24/05/01 */
/* Added by CZ 24/05/01 */
#ifndef ANSI_PROTOTYPES
#ifndef ANSI_PROTOTYPES
static void jtag_proxy_error(va_alist)
static void jtag_proxy_error(va_alist)
va_dcl
va_dcl
#else
#else
static void jtag_proxy_error(int result,int command,...)
static void jtag_proxy_error(int result,int command,...)
#endif
#endif
{
{
  va_list ap;
  va_list ap;
  char sTemp[256];
  char sTemp[256];
 
 
#ifndef ANSI_PROTOTYPES
#ifndef ANSI_PROTOTYPES
  int result;
  int result;
  int command;
  int command;
 
 
  va_start(ap);
  va_start(ap);
  result = va_arg(ap,int);
  result = va_arg(ap,int);
  command = va_arg(ap,int);
  command = va_arg(ap,int);
#else
#else
  va_start(ap, command);
  va_start(ap, command);
#endif
#endif
 
 
  switch(command)
  switch(command)
    {
    {
    case JTAG_COMMAND_READ:
    case JTAG_COMMAND_READ:
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
      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",
              "\"JTAG_COMMAND_READ\",%u,0x%08x\nThe command returned %d.\n",
              va_arg(ap,unsigned int),va_arg(ap,unsigned long long*),result);
              va_arg(ap,unsigned int),va_arg(ap,unsigned long long*),result);
      error(sTemp);
      error(sTemp);
      break;
      break;
    case JTAG_COMMAND_WRITE:
    case JTAG_COMMAND_WRITE:
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
      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",
              "\"JTAG_COMMAND_WRITE\",%u,0x%016llx\nThe command returned %d.\n",
              va_arg(ap,unsigned int),va_arg(ap,unsigned long long),result);
              va_arg(ap,unsigned int),va_arg(ap,unsigned long long),result);
      error(sTemp);
      error(sTemp);
      break;
      break;
    case JTAG_COMMAND_CHAIN:
    case JTAG_COMMAND_CHAIN:
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
              "\"JTAG_COMMAND_CHAIN\",%u. The command returned %d.\n",
              "\"JTAG_COMMAND_CHAIN\",%u. The command returned %d.\n",
              va_arg(ap,unsigned int));
              va_arg(ap,unsigned int));
      error(sTemp);
      error(sTemp);
      break;
      break;
    case JTAG_COMMAND_BLOCK_READ:
    case JTAG_COMMAND_BLOCK_READ:
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
              "\"JTAG_COMMAND_BLOCK_READ\",0x%08x,0x%08x,%d\nThe command returned %d.\n",
              "\"JTAG_COMMAND_BLOCK_READ\",0x%08x,0x%08x,%d\nThe command returned %d.\n",
              va_arg(ap,unsigned long),va_arg(ap,unsigned long),va_arg(ap,int),result);
              va_arg(ap,unsigned long),va_arg(ap,unsigned long),va_arg(ap,int),result);
      error(sTemp);
      error(sTemp);
      break;
      break;
    case JTAG_COMMAND_BLOCK_WRITE:
    case JTAG_COMMAND_BLOCK_WRITE:
    default:
    default:
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
      sprintf(sTemp,"An error was reported by the proxy server. The command was:\n"
              "\"JTAG_COMMAND_BLOCK_WRITE\",0x%08x,0x%08x,%d\nThe command returned %d.\n",
              "\"JTAG_COMMAND_BLOCK_WRITE\",0x%08x,0x%08x,%d\nThe command returned %d.\n",
              va_arg(ap,unsigned long),va_arg(ap,unsigned long),va_arg(ap,int),result);
              va_arg(ap,unsigned long),va_arg(ap,unsigned long),va_arg(ap,int),result);
      error(sTemp);
      error(sTemp);
      break;
      break;
    }
    }
  va_end(ap);
  va_end(ap);
}
}
 
 
/* Sets register/memory regno to data.  */
/* Sets register/memory regno to data.  */
 
 
/* CZ 08/06/01: I am not sure how error checking is intended to
/* CZ 08/06/01: I am not sure how error checking is intended to
   be implemented here. It appears that no indication is returned
   be implemented here. It appears that no indication is returned
   to the caller as you have in standard unix system calls. Therefore,
   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
   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
   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
   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.
   where necessary because no value was returned at all int jtag_read_reg.
*/
*/
 
 
void
void
jtag_write_reg (regno, data)
jtag_write_reg (regno, data)
     int regno;
     int regno;
     ULONGEST data;
     ULONGEST data;
{
{
  int crc_read, crc_write, crc_ok, retry;
  int crc_read, crc_write, crc_ok, retry;
  int result;
  int result;
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("write reg %x <- %x\n", regno, data);
  printf_unfiltered ("write reg %x <- %x\n", regno, data);
  fflush (stdout);
  fflush (stdout);
#endif
#endif
  switch(connection.location) /* CZ */
  switch(connection.location) /* CZ */
    {
    {
    case JTAG_LOCAL:
    case JTAG_LOCAL:
      if (!select_dr)
      if (!select_dr)
        jp1_write_JTAG (1); /* SELECT_DR SCAN */
        jp1_write_JTAG (1); /* SELECT_DR SCAN */
      select_dr = 1;
      select_dr = 1;
 
 
      /* If we don't have rw bit, we assume chain
      /* If we don't have rw bit, we assume chain
         is read only. */
         is read only. */
      if (!chain_has_rw[current_chain])
      if (!chain_has_rw[current_chain])
        error ("Internal: Chain not writable.");
        error ("Internal: Chain not writable.");
 
 
      for (retry = 0; retry < NUM_RETRIES; retry++)
      for (retry = 0; retry < NUM_RETRIES; retry++)
        {
        {
          jp1_write_JTAG (0); /* CAPTURE_DR */
          jp1_write_JTAG (0); /* CAPTURE_DR */
          jp1_write_JTAG (0); /* SHIFT_DR */
          jp1_write_JTAG (0); /* SHIFT_DR */
          crc_w = 0;
          crc_w = 0;
 
 
          /* write addr */
          /* write addr */
          jp1_write_stream (regno, chain_addr_size[current_chain], 0);
          jp1_write_stream (regno, chain_addr_size[current_chain], 0);
 
 
          /* write (R/W=1) - we tested that previously. */
          /* write (R/W=1) - we tested that previously. */
          jp1_write_JTAG (2);
          jp1_write_JTAG (2);
 
 
          /* write data */
          /* write data */
          jp1_write_stream (data, chain_data_size[current_chain], 0);
          jp1_write_stream (data, chain_data_size[current_chain], 0);
          if (chain_has_crc[current_chain])
          if (chain_has_crc[current_chain])
            {
            {
              crc_write = crc_w;
              crc_write = crc_w;
 
 
              /* write CRC, EXIT1_DR */
              /* write CRC, EXIT1_DR */
              crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1);
              crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1);
            }
            }
          jp1_write_JTAG (1); /* UPDATE_DR */
          jp1_write_JTAG (1); /* UPDATE_DR */
 
 
          /* Did JTAG receive packet correctly? */
          /* Did JTAG receive packet correctly? */
          if (chain_has_crc[current_chain])
          if (chain_has_crc[current_chain])
            crc_ok = jp1_read_JTAG ();
            crc_ok = jp1_read_JTAG ();
          jp1_write_JTAG (1); /* SELECT_DR */
          jp1_write_JTAG (1); /* SELECT_DR */
          if (chain_has_crc[current_chain])
          if (chain_has_crc[current_chain])
            {
            {
              if ((crc_read == crc_write) && (crc_ok))
              if ((crc_read == crc_write) && (crc_ok))
                return;
                return;
              JTAG_RETRY_WAIT();
              JTAG_RETRY_WAIT();
            }
            }
          else return;
          else return;
        }
        }
      err = ERR_CRC;
      err = ERR_CRC;
      break;
      break;
    case JTAG_REMOTE:
    case JTAG_REMOTE:
      if(result = jtag_send_proxy(JTAG_COMMAND_WRITE,regno,data))
      if(result = jtag_send_proxy(JTAG_COMMAND_WRITE,regno,data))
        {
        {
          jtag_proxy_error(result,JTAG_COMMAND_WRITE,regno,data);
          jtag_proxy_error(result,JTAG_COMMAND_WRITE,regno,data);
          err = result;
          err = result;
        }
        }
      break;
      break;
    default:
    default:
      error("jtag_write_reg called with no connection!");
      error("jtag_write_reg called with no connection!");
      break;
      break;
    }
    }
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("!write reg\n");
  printf_unfiltered ("!write reg\n");
  fflush (stdout);
  fflush (stdout);
#endif
#endif
}
}
 
 
/* Reads register/memory from regno.  */
/* Reads register/memory from regno.  */
 
 
ULONGEST
ULONGEST
jtag_read_reg (regno)
jtag_read_reg (regno)
     unsigned int regno;
     unsigned int regno;
{
{
  ULONGEST data;
  ULONGEST data;
  int crc_read, crc_write, crc_actual_read,  retry, crc_ok;
  int crc_read, crc_write, crc_actual_read,  retry, crc_ok;
  int result;
  int result;
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("read reg %x\n", regno);
  printf_unfiltered ("read reg %x\n", regno);
  fflush (stdout);
  fflush (stdout);
#endif
#endif
  switch(connection.location)
  switch(connection.location)
    {
    {
    case JTAG_LOCAL:
    case JTAG_LOCAL:
      if (!select_dr)
      if (!select_dr)
        jp1_write_JTAG (1); /* SELECT_DR SCAN */
        jp1_write_JTAG (1); /* SELECT_DR SCAN */
      select_dr = 1;
      select_dr = 1;
 
 
      for (retry = 0; retry < NUM_RETRIES; retry++)
      for (retry = 0; retry < NUM_RETRIES; retry++)
        {
        {
          jp1_write_JTAG (0); /* CAPTURE_DR */
          jp1_write_JTAG (0); /* CAPTURE_DR */
          jp1_write_JTAG (0); /* SHIFT_DR */
          jp1_write_JTAG (0); /* SHIFT_DR */
          crc_w = 0;
          crc_w = 0;
 
 
          /* write addr */
          /* write addr */
          jp1_write_stream (regno, chain_addr_size[current_chain], 0);
          jp1_write_stream (regno, chain_addr_size[current_chain], 0);
 
 
          /* read (R/W=0) */
          /* read (R/W=0) */
          if (chain_has_rw[current_chain])
          if (chain_has_rw[current_chain])
            jp1_write_JTAG (0);
            jp1_write_JTAG (0);
          if (chain_has_crc[current_chain])
          if (chain_has_crc[current_chain])
            {
            {
              crc_r = 0;
              crc_r = 0;
 
 
              /* data = 0 */
              /* data = 0 */
              data = jp1_read_stream (0, chain_data_size[current_chain], 0);
              data = jp1_read_stream (0, chain_data_size[current_chain], 0);
              crc_write = crc_w;
              crc_write = crc_w;
              crc_actual_read = crc_read;
              crc_actual_read = crc_read;
 
 
              /* Send my crc, EXIT1_DR */
              /* Send my crc, EXIT1_DR */
              crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1);
              crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1);
            }
            }
          jp1_write_JTAG (1); /* UPDATE_DR */
          jp1_write_JTAG (1); /* UPDATE_DR */
 
 
          /* Did JTAG receive packet correctly? */
          /* Did JTAG receive packet correctly? */
          if (chain_has_crc[current_chain])
          if (chain_has_crc[current_chain])
            crc_ok = jp1_read_JTAG ();
            crc_ok = jp1_read_JTAG ();
          jp1_write_JTAG (1); /* SELECT_DR */
          jp1_write_JTAG (1); /* SELECT_DR */
          if (chain_has_crc[current_chain])
          if (chain_has_crc[current_chain])
            {
            {
              if ((crc_read == crc_actual_read) && (crc_ok))
              if ((crc_read == crc_actual_read) && (crc_ok))
                return -1;  /* CZ */
                return -1;  /* CZ */
              JTAG_RETRY_WAIT();
              JTAG_RETRY_WAIT();
            }
            }
          else
          else
            return -1;  /* CZ */
            return -1;  /* CZ */
        }
        }
      err = ERR_CRC;
      err = ERR_CRC;
      break;
      break;
    case JTAG_REMOTE:
    case JTAG_REMOTE:
      if(result = jtag_send_proxy(JTAG_COMMAND_READ,regno,&data))
      if(result = jtag_send_proxy(JTAG_COMMAND_READ,regno,&data))
        {
        {
          jtag_proxy_error(result,JTAG_COMMAND_READ,regno,&data);
          jtag_proxy_error(result,JTAG_COMMAND_READ,regno,&data);
          err = result;
          err = result;
        }
        }
      break;
      break;
    default:
    default:
      error("jtag_write_reg called with no connection!");
      error("jtag_write_reg called with no connection!");
      break;
      break;
    }
    }
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("read reg %x\n", data);
  printf_unfiltered ("read reg %x\n", data);
  fflush (stdout);
  fflush (stdout);
#endif
#endif
  return data;  /* CZ */
  return data;  /* CZ */
}
}
 
 
int jtag_write_block(unsigned int regno,void* data,int nRegisters)
int jtag_write_block(unsigned int regno,void* data,int nRegisters)
{
{
  unsigned long* buffer = (unsigned long*)data;
  unsigned long* buffer = (unsigned long*)data;
  int i,result;
  int i,result;
 
 
  if(nRegisters == 1) {
  if(nRegisters == 1) {
    jtag_write_reg(regno, *buffer);
    jtag_write_reg(regno, *buffer);
    return err;
    return err;
  }
  }
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("write block %x,%i\n", regno, nRegisters);
  printf_unfiltered ("write block %x,%i\n", regno, nRegisters);
  fflush (stdout);
  fflush (stdout);
#endif
#endif
 
 
  err = 0;
  err = 0;
  switch(connection.location)
  switch(connection.location)
    {
    {
    case JTAG_LOCAL:         /* We can't do any better than this locally */
    case JTAG_LOCAL:         /* We can't do any better than this locally */
      for(i=0;i<nRegisters;i++)
      for(i=0;i<nRegisters;i++)
        jtag_write_reg(regno+i,(ULONGEST)buffer[i]);
        jtag_write_reg(regno+i,(ULONGEST)buffer[i]);
      break;
      break;
    case JTAG_REMOTE:
    case JTAG_REMOTE:
      if(result = jtag_send_proxy(JTAG_COMMAND_BLOCK_WRITE,regno,data,nRegisters))
      if(result = jtag_send_proxy(JTAG_COMMAND_BLOCK_WRITE,regno,data,nRegisters))
        {
        {
          jtag_proxy_error(result,JTAG_COMMAND_BLOCK_WRITE,regno,data,nRegisters);
          jtag_proxy_error(result,JTAG_COMMAND_BLOCK_WRITE,regno,data,nRegisters);
          err = result;
          err = result;
        }
        }
      break;
      break;
    default:
    default:
      error("jtag_write_reg called with no connection!");
      error("jtag_write_reg called with no connection!");
      break;
      break;
    }
    }
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("!write block\n");
  printf_unfiltered ("!write block\n");
  fflush (stdout);
  fflush (stdout);
#endif
#endif
  return err;
  return err;
}
}
 
 
int jtag_read_block(unsigned int regno,void* data,int nRegisters)
int jtag_read_block(unsigned int regno,void* data,int nRegisters)
{
{
  unsigned long* buffer = (unsigned long*)data;
  unsigned long* buffer = (unsigned long*)data;
  int i,result;
  int i,result;
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("read block %x,%i\n", regno, nRegisters);
  printf_unfiltered ("read block %x,%i\n", regno, nRegisters);
  fflush (stdout);
  fflush (stdout);
#endif
#endif
 
 
  /*  if(nRegisters == 1) {
  /*  if(nRegisters == 1) {
    *buffer = jtag_read_reg(regno);
    *buffer = jtag_read_reg(regno);
    return err;
    return err;
    }*/
    }*/
  err = 0;
  err = 0;
  switch(connection.location)
  switch(connection.location)
    {
    {
    case JTAG_LOCAL:         /* We can't do any better than this locally */
    case JTAG_LOCAL:         /* We can't do any better than this locally */
      for(i=0;i<nRegisters;i++)
      for(i=0;i<nRegisters;i++)
        buffer[i] = (unsigned long)jtag_read_reg(regno+i);
        buffer[i] = (unsigned long)jtag_read_reg(regno+i);
      break;
      break;
    case JTAG_REMOTE:
    case JTAG_REMOTE:
      if(result = jtag_send_proxy(JTAG_COMMAND_BLOCK_READ,regno,data,nRegisters))
      if(result = jtag_send_proxy(JTAG_COMMAND_BLOCK_READ,regno,data,nRegisters))
        {
        {
          jtag_proxy_error(result,JTAG_COMMAND_BLOCK_READ,regno,data,nRegisters);
          jtag_proxy_error(result,JTAG_COMMAND_BLOCK_READ,regno,data,nRegisters);
          err = result;
          err = result;
        }
        }
      break;
      break;
    default:
    default:
      error("jtag_write_reg called with no connection!");
      error("jtag_write_reg called with no connection!");
      break;
      break;
    }
    }
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("read block\n");
  printf_unfiltered ("read block\n");
  fflush (stdout);
  fflush (stdout);
#endif  
#endif  
  return err;
  return err;
}
}
 
 
/* Sets scan chain.  */
/* Sets scan chain.  */
 
 
void
void
jtag_set_chain (chain)
jtag_set_chain (chain)
     int chain;
     int chain;
{
{
  int result;
  int result;
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("set chain %x\n", chain);
  printf_unfiltered ("set chain %x\n", chain);
  fflush (stdout);
  fflush (stdout);
#endif
#endif
  switch(connection.location)
  switch(connection.location)
    {
    {
    case JTAG_LOCAL:
    case JTAG_LOCAL:
      if (current_chain != chain)
      if (current_chain != chain)
        {
        {
          if (!chain_is_valid[chain])
          if (!chain_is_valid[chain])
            error ("Chain not valid.");
            error ("Chain not valid.");
 
 
          current_chain = chain;
          current_chain = chain;
          jp1_prepare_control ();
          jp1_prepare_control ();
 
 
          jp1_write_JTAG (0); /* CAPTURE_IR */
          jp1_write_JTAG (0); /* CAPTURE_IR */
          jp1_write_JTAG (0); /* SHIFT_IR */
          jp1_write_JTAG (0); /* SHIFT_IR */
 
 
          /* write data, EXIT1_IR */
          /* write data, EXIT1_IR */
          jp1_write_stream (JI_CHAIN_SELECT, JI_SIZE, 4);
          jp1_write_stream (JI_CHAIN_SELECT, JI_SIZE, 4);
 
 
          jp1_write_JTAG (1); /* UPDATE_IR */
          jp1_write_JTAG (1); /* UPDATE_IR */
          jp1_write_JTAG (1); /* SELECT_DR */
          jp1_write_JTAG (1); /* SELECT_DR */
 
 
          jp1_write_JTAG (0); /* CAPTURE_DR */
          jp1_write_JTAG (0); /* CAPTURE_DR */
          jp1_write_JTAG (0); /* SHIFT_DR */
          jp1_write_JTAG (0); /* SHIFT_DR */
 
 
          /* write data, EXIT1_DR */
          /* write data, EXIT1_DR */
          jp1_write_stream (chain, SC_SIZE, 1);
          jp1_write_stream (chain, SC_SIZE, 1);
 
 
          jp1_write_JTAG (1); /* UPDATE_DR */
          jp1_write_JTAG (1); /* UPDATE_DR */
          jp1_write_JTAG (1); /* SELECT_DR */
          jp1_write_JTAG (1); /* SELECT_DR */
 
 
          /* Now we have to go out of SELECT_CHAIN mode.  */
          /* Now we have to go out of SELECT_CHAIN mode.  */
          jp1_write_JTAG (1); /* SELECT_IR */
          jp1_write_JTAG (1); /* SELECT_IR */
          jp1_write_JTAG (0); /* CAPTURE_IR */
          jp1_write_JTAG (0); /* CAPTURE_IR */
          jp1_write_JTAG (0); /* SHIFT_IR */
          jp1_write_JTAG (0); /* SHIFT_IR */
 
 
          /* write data, EXIT1_IR */
          /* write data, EXIT1_IR */
          jp1_write_stream (JI_DEBUG, JI_SIZE,1 );
          jp1_write_stream (JI_DEBUG, JI_SIZE,1 );
 
 
          jp1_write_JTAG (1); /* UPDATE_IR */
          jp1_write_JTAG (1); /* UPDATE_IR */
          jp1_write_JTAG (1); /* SELECT_DR */
          jp1_write_JTAG (1); /* SELECT_DR */
          select_dr = 1;
          select_dr = 1;
        }
        }
      break;
      break;
    case JTAG_REMOTE:
    case JTAG_REMOTE:
      if(current_chain != chain)
      if(current_chain != chain)
        {
        {
          if(result = jtag_send_proxy(JTAG_COMMAND_CHAIN,chain))
          if(result = jtag_send_proxy(JTAG_COMMAND_CHAIN,chain))
            {
            {
              jtag_proxy_error(result,JTAG_COMMAND_CHAIN,chain);
              jtag_proxy_error(result,JTAG_COMMAND_CHAIN,chain);
              err = result;
              err = result;
            }
            }
        }
        }
      break;
      break;
    default:
    default:
      error("jtag_set_chain called with no connection!");
      error("jtag_set_chain called with no connection!");
      break;
      break;
    }
    }
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("!set chain\n");
  printf_unfiltered ("!set chain\n");
  fflush (stdout);
  fflush (stdout);
#endif
#endif
}
}
 
 
/* Added by CZ 24/05/01 */
/* Added by CZ 24/05/01 */
static int jtag_connect_to_server(char* hostname,char* name)
static int jtag_connect_to_server(char* hostname,char* name)
{
{
  struct hostent *host;
  struct hostent *host;
  struct sockaddr_in sin;
  struct sockaddr_in sin;
  struct servent *service;
  struct servent *service;
  struct protoent *protocol;
  struct protoent *protocol;
  int sock,flags;
  int sock,flags;
  int fd;
  int fd;
  char sTemp[256],sTemp2[256];
  char sTemp[256],sTemp2[256];
  char* proto_name = "tcp";
  char* proto_name = "tcp";
  int port = 0;
  int port = 0;
  int on_off = 0; /* Turn off Nagel's algorithm on the socket */
  int on_off = 0; /* Turn off Nagel's algorithm on the socket */
  char *s;
  char *s;
 
 
  if(!(protocol = getprotobyname(proto_name)))
  if(!(protocol = getprotobyname(proto_name)))
    {
    {
      sprintf(sTemp,"jtag_connect_to_server: Protocol \"%s\" not available.\n",
      sprintf(sTemp,"jtag_connect_to_server: Protocol \"%s\" not available.\n",
              proto_name);
              proto_name);
      error(sTemp);
      error(sTemp);
      return 0;
      return 0;
    }
    }
 
 
  /* Convert name to an integer only if it is well formatted.
  /* Convert name to an integer only if it is well formatted.
     Otherwise, assume that it is a service name. */
     Otherwise, assume that it is a service name. */
 
 
  port = strtol(name,&s,10);
  port = strtol(name,&s,10);
  if(*s)
  if(*s)
    port = 0;
    port = 0;
 
 
  if(!port)
  if(!port)
    {
    {
      if(!(service = getservbyname(name,protocol->p_name)))
      if(!(service = getservbyname(name,protocol->p_name)))
        {
        {
          sprintf(sTemp,"jtag_connect_to_server: Unknown service \"%s\".\n",name);
          sprintf(sTemp,"jtag_connect_to_server: Unknown service \"%s\".\n",name);
          error(sTemp);
          error(sTemp);
          return 0;
          return 0;
        }
        }
 
 
      port = ntohs(service->s_port);
      port = ntohs(service->s_port);
    }
    }
 
 
  if(!(host = gethostbyname(hostname)))
  if(!(host = gethostbyname(hostname)))
    {
    {
      sprintf(sTemp,"jtag_connect_to_server: Unknown host \"%s\"\n",hostname);
      sprintf(sTemp,"jtag_connect_to_server: Unknown host \"%s\"\n",hostname);
      error(sTemp);
      error(sTemp);
      return 0;
      return 0;
    }
    }
 
 
  if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0)
  if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0)
    {
    {
      sprintf(sTemp,"jtag_connect_to_server: can't create socket errno = %d\n",
      sprintf(sTemp,"jtag_connect_to_server: can't create socket errno = %d\n",
              errno);
              errno);
      sprintf(sTemp2,"%s\n",strerror(errno));
      sprintf(sTemp2,"%s\n",strerror(errno));
      strcat(sTemp,sTemp2);
      strcat(sTemp,sTemp2);
      error(sTemp);
      error(sTemp);
      return 0;
      return 0;
    }
    }
 
 
  if(flags = fcntl(sock,F_GETFL,0) < 0)
  if(flags = fcntl(sock,F_GETFL,0) < 0)
    {
    {
      sprintf(sTemp,"Unable to get flags for JTAG proxy socket %d",sock);
      sprintf(sTemp,"Unable to get flags for JTAG proxy socket %d",sock);
      error(sTemp);
      error(sTemp);
      close(sock);
      close(sock);
      return 0;
      return 0;
    }
    }
 
 
  if(fcntl(sock,F_SETFL, flags & ~O_NONBLOCK) < 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",
      sprintf(sTemp,"Unable to set flags for JTAG proxy socket %d to value 0x%08x",
              sock,flags & ~O_NONBLOCK);
              sock,flags & ~O_NONBLOCK);
      perror("fcntl ~O_NONBLOCK");
      perror("fcntl ~O_NONBLOCK");
      error(sTemp);
      error(sTemp);
      close(sock);
      close(sock);
      return 0;
      return 0;
    }
    }
 
 
  memset(&sin,0,sizeof(sin));
  memset(&sin,0,sizeof(sin));
  sin.sin_family = host->h_addrtype;
  sin.sin_family = host->h_addrtype;
  memcpy(&sin.sin_addr,host->h_addr_list[0],host->h_length);
  memcpy(&sin.sin_addr,host->h_addr_list[0],host->h_length);
  sin.sin_port = htons(port);
  sin.sin_port = htons(port);
 
 
  if((connect(sock,(struct sockaddr*)&sin, sizeof(sin)) < 0)
  if((connect(sock,(struct sockaddr*)&sin, sizeof(sin)) < 0)
     && errno != EINPROGRESS)
     && errno != EINPROGRESS)
    {
    {
 
 
      sprintf(sTemp,"jtag_connect_to_server: connect failed  errno = %d\n",errno);
      sprintf(sTemp,"jtag_connect_to_server: connect failed  errno = %d\n",errno);
      sprintf(sTemp2,"%s\n",strerror(errno));
      sprintf(sTemp2,"%s\n",strerror(errno));
      close(sock);
      close(sock);
      strcat(sTemp,sTemp2);
      strcat(sTemp,sTemp2);
      error(sTemp);
      error(sTemp);
      return 0;
      return 0;
    }
    }
 
 
  if(fcntl(sock,F_SETFL, flags | O_NONBLOCK) < 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",
      sprintf(sTemp,"Unable to set flags for JTAG proxy socket %d to value 0x%08x",
              sock,flags | O_NONBLOCK);
              sock,flags | O_NONBLOCK);
      perror("fcntl | O_NONBLOCK");
      perror("fcntl | O_NONBLOCK");
      error(sTemp);
      error(sTemp);
      close(sock);
      close(sock);
      return 0;
      return 0;
    }
    }
 
 
  if(setsockopt(sock,protocol->p_proto,TCP_NODELAY,&on_off,sizeof(int)) < 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);
      sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",sock);
      error(sTemp);
      error(sTemp);
      close(sock);
      close(sock);
      return 0;
      return 0;
    }
    }
 
 
  return sock;
  return sock;
}
}
 
 
/* Initialize a new connection to the or1k board, and make sure we are
/* Initialize a new connection to the or1k board, and make sure we are
   really connected.  */
   really connected.  */
 
 
void
void
jtag_init (args)
jtag_init (args)
     char * args;
     char * args;
{
{
  char *ptype;
  char *ptype;
  char *port_name;
  char *port_name;
  char **argv;
  char **argv;
 
 
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf_unfiltered ("INIT\n");
  printf_unfiltered ("INIT\n");
  fflush(stdout);
  fflush(stdout);
#endif
#endif
  if (args == 0) /* CZ */
  if (args == 0) /* CZ */
    error ( "To open a or1k remote debugging connection, you need to specify a "
    error ( "To open a or1k remote debugging connection, you need to specify a "
            "parallel port\nconnected to the target board, or else a remote "
            "parallel port\nconnected to the target board, or else a remote "
            "server which will proxy these\nservices for you.\nExample: "
            "server which will proxy these\nservices for you.\nExample: "
            "/dev/lp0 or jtag://debughost.mydomain.com:8100.\n");
            "/dev/lp0 or jtag://debughost.mydomain.com:8100.\n");
 
 
  /* If we currently have an open connection, shut it
  /* If we currently have an open connection, shut it
     down.  This is due to a temporary bug in gdb. */
     down.  This is due to a temporary bug in gdb. */
  switch(connection.location)
  switch(connection.location)
    {
    {
    case JTAG_REMOTE:
    case JTAG_REMOTE:
      if(connection.device.fd > 0)
      if(connection.device.fd > 0)
        {
        {
          close(connection.device.fd);
          close(connection.device.fd);
        }
        }
      break;
      break;
    case JTAG_LOCAL:
    case JTAG_LOCAL:
      if(connection.device.lp > 0)
      if(connection.device.lp > 0)
        {
        {
          close(connection.device.lp);
          close(connection.device.lp);
        }
        }
      break;
      break;
    default:
    default:
      break;
      break;
    }
    }
 
 
  /* Parse the port name.  */
  /* Parse the port name.  */
  if ((argv = buildargv (args)) == NULL)
  if ((argv = buildargv (args)) == NULL)
    nomem (0);
    nomem (0);
  port_name = xstrdup (argv[0]);
  port_name = xstrdup (argv[0]);
  make_cleanup_freeargv (argv);
  make_cleanup_freeargv (argv);
 
 
  /* CZ 24/05/01 - Check to see if we have specified a remote
  /* 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
     jtag interface or a local one. It is remote if it follows
     the URL naming convention jtag://<hostname>:<port> */
     the URL naming convention jtag://<hostname>:<port> */
  if(!strncmp(port_name,"jtag://",7))
  if(!strncmp(port_name,"jtag://",7))
    {
    {
      char *port = strchr(&port_name[7],':');
      char *port = strchr(&port_name[7],':');
      char hostname[256];
      char hostname[256];
 
 
      if(port)
      if(port)
        {
        {
          int len = port - port_name - 7;
          int len = port - port_name - 7;
          strncpy(hostname,&port_name[7],len);
          strncpy(hostname,&port_name[7],len);
          hostname[len] = '\0';
          hostname[len] = '\0';
          port++;
          port++;
        }
        }
      else
      else
        strcpy(hostname,&port_name[7]);
        strcpy(hostname,&port_name[7]);
 
 
      /* Interface is remote */
      /* Interface is remote */
      if(!(connection.device.fd = jtag_connect_to_server(hostname,port)))
      if(!(connection.device.fd = jtag_connect_to_server(hostname,port)))
        {
        {
          char sTemp[256];
          char sTemp[256];
          sprintf(sTemp,"Can not access JTAG Proxy Server at \"%s\"",
          sprintf(sTemp,"Can not access JTAG Proxy Server at \"%s\"",
                  &port_name[5]);
                  &port_name[5]);
          error(sTemp);
          error(sTemp);
        }
        }
      connection.location = JTAG_REMOTE;
      connection.location = JTAG_REMOTE;
      printf_unfiltered ("Remote or1k debugging using %s\n",port_name);
      printf_unfiltered ("Remote or1k debugging using %s\n",port_name);
    }
    }
  else
  else
    {
    {
      /* Interface is local */
      /* Interface is local */
      /* Open and initialize the parallel port.  */
      /* Open and initialize the parallel port.  */
      connection.device.lp = open (port_name, O_WRONLY);
      connection.device.lp = open (port_name, O_WRONLY);
      if (connection.device.lp < 0)
      if (connection.device.lp < 0)
        error ("Cannot open device.");
        error ("Cannot open device.");
      connection.location = JTAG_LOCAL; /* CZ */
      connection.location = JTAG_LOCAL; /* CZ */
      printf_unfiltered ("Local or1k debugging using %s\n", port_name);
      printf_unfiltered ("Local or1k debugging using %s\n", port_name);
 
 
    }
    }
 
 
  current_chain = -1;
  current_chain = -1;
  if(connection.location == JTAG_LOCAL)
  if(connection.location == JTAG_LOCAL)
    jp1_reset_JTAG ();
    jp1_reset_JTAG ();
  jtag_set_chain (SC_RISC_DEBUG);
  jtag_set_chain (SC_RISC_DEBUG);
 
 
  free (port_name);
  free (port_name);
}
}
 
 
void
void
jtag_done ()  /* CZ */
jtag_done ()  /* CZ */
{
{
  switch(connection.location)
  switch(connection.location)
    {
    {
    case JTAG_LOCAL:
    case JTAG_LOCAL:
      sync_close (connection.device.lp);
      sync_close (connection.device.lp);
      connection.device.lp = 0;
      connection.device.lp = 0;
      break;
      break;
    case JTAG_REMOTE:
    case JTAG_REMOTE:
      sync_close(connection.device.fd);
      sync_close(connection.device.fd);
      connection.device.fd = 0;
      connection.device.fd = 0;
      break;
      break;
    default:
    default:
      break;
      break;
    }
    }
  connection.location = JTAG_NOT_CONNECTED;
  connection.location = JTAG_NOT_CONNECTED;
}
}
 
 
int sync_close(int fd)
int sync_close(int fd)
{
{
  int flags = 0;
  int flags = 0;
  struct linger linger;
  struct linger linger;
  char sTemp[256];
  char sTemp[256];
 
 
  linger.l_onoff = 0;
  linger.l_onoff = 0;
  linger.l_linger = 0;
  linger.l_linger = 0;
 
 
  /* First, make sure we're non blocking */
  /* First, make sure we're non blocking */
  if(flags = fcntl(fd,F_GETFL,0) < 0)
  if(flags = fcntl(fd,F_GETFL,0) < 0)
    {
    {
      sprintf(sTemp,"Unable to get flags for JTAG proxy socket %d",fd);
      sprintf(sTemp,"Unable to get flags for JTAG proxy socket %d",fd);
      error(sTemp);
      error(sTemp);
    }
    }
  if(fcntl(fd,F_SETFL, flags & ~O_NONBLOCK) < 0)
  if(fcntl(fd,F_SETFL, flags & ~O_NONBLOCK) < 0)
    {
    {
      sprintf(sTemp,"Unable to set flags for JTAG proxy socket %d to value 0x%08x",
      sprintf(sTemp,"Unable to set flags for JTAG proxy socket %d to value 0x%08x",
              fd,flags | O_NONBLOCK);
              fd,flags | O_NONBLOCK);
      error(sTemp);
      error(sTemp);
    }
    }
 
 
  /* Now, make sure we don't linger around */
  /* Now, make sure we don't linger around */
  if(setsockopt(fd,SOL_SOCKET,SO_LINGER,&linger,sizeof(linger)) < 0)
  if(setsockopt(fd,SOL_SOCKET,SO_LINGER,&linger,sizeof(linger)) < 0)
    {
    {
      sprintf(sTemp,"Unable to disable SO_LINGER for JTAG proxy socket %d.",fd);
      sprintf(sTemp,"Unable to disable SO_LINGER for JTAG proxy socket %d.",fd);
      error(sTemp);
      error(sTemp);
    }
    }
 
 
  return close(fd);
  return close(fd);
}
}
 
 

powered by: WebSVN 2.1.0

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