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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [trunk/] [Software/] [adv_jtag_bridge/] [adv_jtag_bridge.c] - Diff between revs 8 and 14

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

Rev 8 Rev 14
/* adv_jtag_bridge.c -- JTAG protocol bridge between GDB and Advanced debug module.
/* adv_jtag_bridge.c -- JTAG protocol bridge between GDB and Advanced debug module.
   Copyright(C) 2001 Marko Mlinar, markom@opencores.org
   Copyright(C) 2001 Marko Mlinar, markom@opencores.org
   Code for TCP/IP copied from gdb, by Chris Ziomkowski
   Code for TCP/IP copied from gdb, by Chris Ziomkowski
   Refactoring by Nathan Yawn, nyawn@opencores.org
   Refactoring by Nathan Yawn, nyawn@opencores.org
 
 
   This file was part of the OpenRISC 1000 Architectural Simulator.
   This file was part of the OpenRISC 1000 Architectural Simulator.
   It is now also used to connect GDB to a running hardware OpenCores / OR1200
   It is now also used to connect GDB to a running hardware OpenCores / OR1200
   advanced debug unit.
   advanced debug unit.
 
 
   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., 675 Mass Ave, Cambridge, MA 02139, USA. */
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
/* Establishes jtag proxy server and communicates with parallel
/* Establishes jtag proxy server and communicates with parallel
   port directly.  Requires root access. */
   port directly.  Requires root access. */
 
 
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>  // for exit(), atoi(), strtoul()
#include <stdlib.h>  // for exit(), atoi(), strtoul()
#include <unistd.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdarg.h>
#include <string.h>  // for strstr()
#include <string.h>  // for strstr()
#include <sys/types.h>
#include <sys/types.h>
 
 
 
 
#include "adv_jtag_bridge.h"
#include "adv_jtag_bridge.h"
#include "rsp-server.h"
#include "rsp-server.h"
#include "chain_commands.h"
#include "chain_commands.h"
#include "cable_common.h"
#include "cable_common.h"
#include "or32_selftest.h"
#include "or32_selftest.h"
#include "bsdl.h"
#include "bsdl.h"
#include "errcodes.h"
#include "errcodes.h"
 
 
#define debug(...) //fprintf(stderr, __VA_ARGS__ )
#define debug(...) //fprintf(stderr, __VA_ARGS__ )
 
 
// How many command-line IR length settings to create by default
// How many command-line IR length settings to create by default
#define IR_START_SETS 16
#define IR_START_SETS 16
 
 
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// Command line option flags / values
// Command line option flags / values
 
 
/* Which device in the scan chain we want to target.
/* Which device in the scan chain we want to target.
 * 0 is the first device we find, which is nearest the data input of the cable.
 * 0 is the first device we find, which is nearest the data input of the cable.
 */
 */
unsigned int target_dev_pos = 0;
unsigned int target_dev_pos = 0;
 
 
// Do test before setting up server?
// Do test before setting up server?
unsigned char do_selftest = 0;
unsigned char do_selftest = 0;
 
 
// IR register length in TAP of 
// IR register length in TAP of 
// Can override autoprobe, or set if IDCODE not supported
// Can override autoprobe, or set if IDCODE not supported
typedef struct {
typedef struct {
  int dev_index;
  int dev_index;
  int ir_length;
  int ir_length;
} irset;
} irset;
 
 
#define START_IR_SETS 16
#define START_IR_SETS 16
int reallocs = 0;
int reallocs = 0;
int num_ir_sets = 0;
int num_ir_sets = 0;
irset * cmd_line_ir_sizes = NULL;
irset * cmd_line_ir_sizes = NULL;
 
 
// DEBUG command for target device TAP
// DEBUG command for target device TAP
// May actually be USER1, for Xilinx devices using internal BSCAN modules
// May actually be USER1, for Xilinx devices using internal BSCAN modules
// Can override autoprobe, or set if unable to find in BSDL files
// Can override autoprobe, or set if unable to find in BSDL files
int cmd_line_cmd_debug = -1;  // 0 is a valid debug command, so use -1
int cmd_line_cmd_debug = -1;  // 0 is a valid debug command, so use -1
 
 
// TCP port to set up the server for GDB on
// TCP port to set up the server for GDB on
char *port;
char *port;
char default_port[] = "9999";
char default_port[] = "9999";
 
 
// Force altera virtual jtag mode on(1) or off(-1)
// Force altera virtual jtag mode on(1) or off(-1)
int force_alt_vjtag = 0;
int force_alt_vjtag = 0;
 
 
 
 
// Pointer to the command line arg used as the cable name
// Pointer to the command line arg used as the cable name
char * cable_name = NULL;
char * cable_name = NULL;
 
 
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
// List of IDCODES of devices on the JTAG scan chain
// List of IDCODES of devices on the JTAG scan chain
// The array is dynamically allocated in chain_commands/jtag_enumerate_chain()
// The array is dynamically allocated in chain_commands/jtag_enumerate_chain()
 
 
uint32_t *idcodes = NULL;
uint32_t *idcodes = NULL;
int num_devices = 0;
int num_devices = 0;
 
 
 
 
const char *name_not_found = "(unknown)";
const char *name_not_found = "(unknown)";
 
 
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// JTAG constants
// JTAG constants
 
 
// Defines for Altera JTAG constants
// Defines for Altera JTAG constants
#define ALTERA_MANUFACTURER_ID   0x6E
#define ALTERA_MANUFACTURER_ID   0x6E
 
 
// Defines for Xilinx JTAG constants
// Defines for Xilinx JTAG constants
#define XILINX_MANUFACTURER_ID   0x49
#define XILINX_MANUFACTURER_ID   0x49
 
 
 
 
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Prototypes for local / helper functions
// Prototypes for local / helper functions
int get_IR_size(int devidx);
int get_IR_size(int devidx);
uint32_t get_debug_cmd(int devidx);
uint32_t get_debug_cmd(int devidx);
void configure_chain(void);
void configure_chain(void);
void print_usage(char *func);
void print_usage(char *func);
void parse_args(int argc, char **argv);
void parse_args(int argc, char **argv);
void get_ir_opts(char *optstr, int *idx, int *val);
void get_ir_opts(char *optstr, int *idx, int *val);
 
 
 
 
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------*/
// Functions
// Functions
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
 
 
// Resets JTAG, and sets up DEBUG scan chain
// Resets JTAG, and sets up DEBUG scan chain
void configure_chain(void)
void configure_chain(void)
{
{
  int i;
  int i;
  unsigned int manuf_id;
  unsigned int manuf_id;
  uint32_t cmd;
  uint32_t cmd;
  const char *name;
  const char *name;
  int irlen;
  int irlen;
  int err = APP_ERR_NONE;
  int err = APP_ERR_NONE;
 
 
  err |= tap_reset();
  err |= tap_reset();
  err |= jtag_enumerate_chain(&idcodes, &num_devices);
  err |= jtag_enumerate_chain(&idcodes, &num_devices);
 
 
  if(err != APP_ERR_NONE) {
  if(err != APP_ERR_NONE) {
    printf("Error %s enumerating JTAG chain, aborting.\n", get_err_string(err));
    printf("Error %s enumerating JTAG chain, aborting.\n", get_err_string(err));
    exit(1);
    exit(1);
  }
  }
 
 
  printf("\nDevices on JTAG chain:\n");
  printf("\nDevices on JTAG chain:\n");
  printf("Index\tName\t\tID Code\t\tIR Length\n");
  printf("Index\tName\t\tID Code\t\tIR Length\n");
  printf("----------------------------------------------------------------\n");
  printf("----------------------------------------------------------------\n");
  for(i = 0; i < num_devices; i++)
  for(i = 0; i < num_devices; i++)
    {
    {
      if(idcodes[i] != IDCODE_INVALID) {
      if(idcodes[i] != IDCODE_INVALID) {
        name = bsdl_get_name(idcodes[i]);
        name = bsdl_get_name(idcodes[i]);
        irlen = bsdl_get_IR_size(idcodes[i]);
        irlen = bsdl_get_IR_size(idcodes[i]);
        if(name == NULL)
        if(name == NULL)
          name = name_not_found;
          name = name_not_found;
      } else {
      } else {
        name = name_not_found;
        name = name_not_found;
        irlen = -1;
        irlen = -1;
      }
      }
      printf("%d: \t%s \t0x%08lX \t%d\n", i, name, idcodes[i], irlen);
      printf("%d: \t%s \t0x%08X \t%d\n", i, name, idcodes[i], irlen);
    }
    }
  printf("\n");
  printf("\n");
 
 
 
#ifdef __LEGACY__
 
// The legacy debug interface cannot support multi-device chains.  If there is more than
 
// one device on this chain, pull the cord.
 
if(num_devices > 1) {
 
        fprintf(stderr, "\n*** ERROR: The legacy debug hardware cannot support JTAG chains with\n");
 
        fprintf(stderr, "*** more than one device.  Reconnect the JTAG cable to ONLY the legacy\n");
 
        fprintf(stderr, "*** debug unit, or change your SoC to use the Advanced Debug Unit.\n");
 
        exit(0);
 
}
 
#endif
 
 
 
 
  if(target_dev_pos >= num_devices) {
  if(target_dev_pos >= num_devices) {
    printf("ERROR:  Requested target device (%i) beyond highest device index (%i).\n", target_dev_pos, num_devices-1);
    printf("ERROR:  Requested target device (%i) beyond highest device index (%i).\n", target_dev_pos, num_devices-1);
    exit(1);
    exit(1);
  } else {
  } else {
    printf("Target device %i, JTAG ID = 0x%08lx\n", target_dev_pos, idcodes[target_dev_pos]);
    printf("Target device %i, JTAG ID = 0x%08x\n", target_dev_pos, idcodes[target_dev_pos]);
  }
  }
 
 
  manuf_id = (idcodes[target_dev_pos] >> 1) & 0x7FF;
  manuf_id = (idcodes[target_dev_pos] >> 1) & 0x7FF;
 
 
  // Use BSDL files to determine prefix bits, postfix bits, debug command, IR length
  // Use BSDL files to determine prefix bits, postfix bits, debug command, IR length
  config_set_IR_size(get_IR_size(target_dev_pos));
  config_set_IR_size(get_IR_size(target_dev_pos));
 
 
  // Set the IR prefix / postfix bits
  // Set the IR prefix / postfix bits
  int total = 0;
  int total = 0;
  for(i = 0; i < num_devices; i++) {
  for(i = 0; i < num_devices; i++) {
    if(i == target_dev_pos) {
    if(i == target_dev_pos) {
      config_set_IR_postfix_bits(total);
      config_set_IR_postfix_bits(total);
      //debug("Postfix bits: %d\n", total);
      //debug("Postfix bits: %d\n", total);
      total = 0;
      total = 0;
      continue;
      continue;
    }
    }
 
 
    total += get_IR_size(i);
    total += get_IR_size(i);
    debug("Adding %i to total for devidx %i\n", get_IR_size(i), i);
    debug("Adding %i to total for devidx %i\n", get_IR_size(i), i);
  }
  }
  config_set_IR_prefix_bits(total);
  config_set_IR_prefix_bits(total);
  debug("Prefix bits: %d\n", total);
  debug("Prefix bits: %d\n", total);
 
 
 
 
  // Note that there's a little translation here, since device index 0 is actually closest to the cable data input
  // Note that there's a little translation here, since device index 0 is actually closest to the cable data input
  config_set_DR_prefix_bits(num_devices - target_dev_pos - 1);  // number of devices between cable data out and target device
  config_set_DR_prefix_bits(num_devices - target_dev_pos - 1);  // number of devices between cable data out and target device
  config_set_DR_postfix_bits(target_dev_pos);  // number of devices between target device and cable data in
  config_set_DR_postfix_bits(target_dev_pos);  // number of devices between target device and cable data in
 
 
  // Set the DEBUG command for the IR of the target device.
  // Set the DEBUG command for the IR of the target device.
  // If this is a Xilinx device, use USER1 instead of DEBUG
  // If this is a Xilinx device, use USER1 instead of DEBUG
  // If we Altera Virtual JTAG mode, we don't care.
  // If we Altera Virtual JTAG mode, we don't care.
  if((force_alt_vjtag == -1) || ((force_alt_vjtag == 0) &&  (manuf_id != ALTERA_MANUFACTURER_ID))) {
  if((force_alt_vjtag == -1) || ((force_alt_vjtag == 0) &&  (manuf_id != ALTERA_MANUFACTURER_ID))) {
    cmd = get_debug_cmd(target_dev_pos);
    cmd = get_debug_cmd(target_dev_pos);
    if(cmd == TAP_CMD_INVALID) {
    if(cmd == TAP_CMD_INVALID) {
      printf("Unable to find DEBUG command, aborting.\n");
      printf("Unable to find DEBUG command, aborting.\n");
      exit(1);
      exit(1);
    }
    }
    config_set_debug_cmd(cmd);  // This may have to be USER1 if this is a Xilinx device   
    config_set_debug_cmd(cmd);  // This may have to be USER1 if this is a Xilinx device   
  }
  }
 
 
  // Enable the kludge for Xilinx BSCAN, if necessary.
  // Enable the kludge for Xilinx BSCAN, if necessary.
  // Safe, but slower, for non-BSCAN TAPs.
  // Safe, but slower, for non-BSCAN TAPs.
  if(manuf_id == XILINX_MANUFACTURER_ID) {
  if(manuf_id == XILINX_MANUFACTURER_ID) {
    config_set_xilinx_bscan(1);
    config_set_xilinx_bscan(1);
  }
  }
 
 
  // Set Altera Virtual JTAG mode on or off.  If not forced, then enable
  // Set Altera Virtual JTAG mode on or off.  If not forced, then enable
  // if the target device has an Altera manufacturer IDCODE
  // if the target device has an Altera manufacturer IDCODE
  if(force_alt_vjtag == 1) {
  if(force_alt_vjtag == 1) {
    config_set_alt_vjtag(1);
    config_set_alt_vjtag(1);
  } else if(force_alt_vjtag == -1) {
  } else if(force_alt_vjtag == -1) {
    config_set_alt_vjtag(0);
    config_set_alt_vjtag(0);
  } else {
  } else {
    if(manuf_id == ALTERA_MANUFACTURER_ID) {
    if(manuf_id == ALTERA_MANUFACTURER_ID) {
      config_set_alt_vjtag(1);
      config_set_alt_vjtag(1);
    } else {
    } else {
      config_set_alt_vjtag(0);
      config_set_alt_vjtag(0);
    }
    }
  }
  }
 
 
  // Do a sanity test
  // Do a sanity test
  cmd = bsdl_get_idcode_cmd(idcodes[target_dev_pos]);
  cmd = bsdl_get_idcode_cmd(idcodes[target_dev_pos]);
  if(cmd != TAP_CMD_INVALID) {
  if(cmd != TAP_CMD_INVALID) {
       uint32_t id_read;
       uint32_t id_read;
       err |= jtag_get_idcode(cmd, &id_read);
       err |= jtag_get_idcode(cmd, &id_read);
 
 
       if(err != APP_ERR_NONE) {
       if(err != APP_ERR_NONE) {
         printf("Error %s checking IDCODE, aborting.\n", get_err_string(err));
         printf("Error %s checking IDCODE, aborting.\n", get_err_string(err));
         exit(1);
         exit(1);
       }
       }
 
 
       if(id_read == idcodes[target_dev_pos]) {
       if(id_read == idcodes[target_dev_pos]) {
         printf("IDCODE sanity test passed, chain OK!\n");
         printf("IDCODE sanity test passed, chain OK!\n");
       } else {
       } else {
         printf("Warning: IDCODE sanity test failed.  Read IDCODE 0x%08lX, expected 0x%08lX\n", id_read, idcodes[target_dev_pos]);
         printf("Warning: IDCODE sanity test failed.  Read IDCODE 0x%08X, expected 0x%08X\n", id_read, idcodes[target_dev_pos]);
       }
       }
     }
     }
 
 
  if(err |= tap_enable_debug_module()) {  // Select the debug unit in the TAP.
  if(err |= tap_enable_debug_module()) {  // Select the debug unit in the TAP.
    printf("Error %s enabling debug module, aborting.\n", get_err_string(err));
    printf("Error %s enabling debug module, aborting.\n", get_err_string(err));
    exit(1);
    exit(1);
  }
  }
}
}
 
 
 
 
void print_usage(char *func)
void print_usage(char *func)
{
{
  printf("JTAG connection between GDB and the Advanced Debug Interface.\n");
  printf("JTAG connection between GDB and the SoC debug interface.\n");
 
#ifdef __LEGACY__
 
  printf("Compiled with support for the Legacy debug unit (debug_if).\n");
 
#else
 
  printf("Compiled with support for the Advanced Debug Interface (adv_dbg_if).\n");
 
#endif
  printf("Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org\n\n");
  printf("Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org\n\n");
  printf("Usage: %s (options) [cable] (cable options)\n", func);
  printf("Usage: %s (options) [cable] (cable options)\n", func);
  printf("Options:\n");
  printf("Options:\n");
  printf("\t-g [port]     : port number for GDB (default: 9999)\n");
  printf("\t-g [port]     : port number for GDB (default: 9999)\n");
  printf("\t-x [index]    : Position of the target device in the scan chain\n");
  printf("\t-x [index]    : Position of the target device in the scan chain\n");
  printf("\t-a [0 / 1]    : force Altera virtual JTAG mode off (0) or on (1)\n");
  printf("\t-a [0 / 1]    : force Altera virtual JTAG mode off (0) or on (1)\n");
  printf("\t-l [<index>:<bits>]     : Specify length of IR register for device\n");
  printf("\t-l [<index>:<bits>]     : Specify length of IR register for device\n");
  printf("\t                <index>, override autodetect (if any)\n");
  printf("\t                <index>, override autodetect (if any)\n");
  printf("\t-c [hex cmd]  : Debug command for target TAP, override autodetect\n");
  printf("\t-c [hex cmd]  : Debug command for target TAP, override autodetect\n");
  printf("\t                (ignored for Altera targets)\n");
  printf("\t                (ignored for Altera targets)\n");
  printf("\t-v [hex cmd]  : VIR command for target TAP, override autodetect\n");
  printf("\t-v [hex cmd]  : VIR command for target TAP, override autodetect\n");
  printf("\t                (Altera virtual JTAG targets only)\n");
  printf("\t                (Altera virtual JTAG targets only)\n");
  printf("\t-r [hex cmd]  : VDR for target TAP, override autodetect\n");
  printf("\t-r [hex cmd]  : VDR for target TAP, override autodetect\n");
  printf("\t                (Altera virtual JTAG targets only)\n");
  printf("\t                (Altera virtual JTAG targets only)\n");
  printf("\t-b [dirname]  : Add a directory to search for BSDL files\n");
  printf("\t-b [dirname]  : Add a directory to search for BSDL files\n");
  printf("\t-t            : perform CPU / memory self-test before starting server\n");
  printf("\t-t            : perform CPU / memory self-test before starting server\n");
  printf("\t-h            : show help\n\n");
  printf("\t-h            : show help\n\n");
  cable_print_help();
  cable_print_help();
}
}
 
 
 
 
void parse_args(int argc, char **argv)
void parse_args(int argc, char **argv)
{
{
  int c;
  int c;
  int i;
  int i;
  int idx, val;
  int idx, val;
  const char *valid_cable_args = NULL;
  const char *valid_cable_args = NULL;
  port = NULL;
  port = NULL;
  force_alt_vjtag = 0;
  force_alt_vjtag = 0;
  cmd_line_cmd_debug = -1;
  cmd_line_cmd_debug = -1;
 
 
  /* Parse the global arguments (if-any) */
  /* Parse the global arguments (if-any) */
  while((c = getopt(argc, argv, "+g:x:a:l:c:v:r:b:th")) != -1) {
  while((c = getopt(argc, argv, "+g:x:a:l:c:v:r:b:th")) != -1) {
    switch(c) {
    switch(c) {
    case 'h':
    case 'h':
      print_usage(argv[0]);
      print_usage(argv[0]);
      exit(0);
      exit(0);
      break;
      break;
    case 'g':
    case 'g':
      port = optarg;
      port = optarg;
      break;
      break;
    case 'x':
    case 'x':
      target_dev_pos = atoi(optarg);
      target_dev_pos = atoi(optarg);
      break;
      break;
    case 'l':
    case 'l':
      get_ir_opts(optarg, &idx, &val);        // parse the option
      get_ir_opts(optarg, &idx, &val);        // parse the option
      if(num_ir_sets >= (IR_START_SETS<<reallocs)) {
      if(num_ir_sets >= (IR_START_SETS<<reallocs)) {
        cmd_line_ir_sizes = (irset *) realloc(cmd_line_ir_sizes, (IR_START_SETS<<reallocs)*sizeof(irset));
        cmd_line_ir_sizes = (irset *) realloc(cmd_line_ir_sizes, (IR_START_SETS<<reallocs)*sizeof(irset));
        if(cmd_line_ir_sizes == NULL) {
        if(cmd_line_ir_sizes == NULL) {
          printf("Error: out of memory while parsing command line.  Aborting.\n");
          printf("Error: out of memory while parsing command line.  Aborting.\n");
          exit(1);
          exit(1);
        }
        }
      }
      }
      cmd_line_ir_sizes[num_ir_sets].dev_index = idx;
      cmd_line_ir_sizes[num_ir_sets].dev_index = idx;
      cmd_line_ir_sizes[num_ir_sets].ir_length = val;
      cmd_line_ir_sizes[num_ir_sets].ir_length = val;
      num_ir_sets++;
      num_ir_sets++;
      break;
      break;
    case 'c':
    case 'c':
      cmd_line_cmd_debug = strtoul(optarg, NULL, 16);
      cmd_line_cmd_debug = strtoul(optarg, NULL, 16);
      break;
      break;
    case 'v':
    case 'v':
      config_set_vjtag_cmd_vir(strtoul(optarg, NULL, 16));
      config_set_vjtag_cmd_vir(strtoul(optarg, NULL, 16));
      break;
      break;
    case 'r':
    case 'r':
      config_set_vjtag_cmd_vdr(strtoul(optarg, NULL, 16));
      config_set_vjtag_cmd_vdr(strtoul(optarg, NULL, 16));
      break;
      break;
    case 't':
    case 't':
      do_selftest = 1;
      do_selftest = 1;
      break;
      break;
     case 'a':
     case 'a':
       if(atoi(optarg) == 1)
       if(atoi(optarg) == 1)
        force_alt_vjtag = 1;
        force_alt_vjtag = 1;
       else
       else
        force_alt_vjtag = -1;
        force_alt_vjtag = -1;
       break;
       break;
    case 'b':
    case 'b':
       bsdl_add_directory(optarg);
       bsdl_add_directory(optarg);
      break;
      break;
    default:
    default:
      print_usage(argv[0]);
      print_usage(argv[0]);
      exit(1);
      exit(1);
    }
    }
  }
  }
 
 
  if(port == NULL)
  if(port == NULL)
    port = default_port;
    port = default_port;
 
 
  int found_cable = 0;
  int found_cable = 0;
  char* start_str = argv[optind];
  char* start_str = argv[optind];
  int start_idx = optind;
  int start_idx = optind;
  for(i = optind; i < argc; i++) {
  for(i = optind; i < argc; i++) {
    if(cable_select(argv[i]) == APP_ERR_NONE) {
    if(cable_select(argv[i]) == APP_ERR_NONE) {
      found_cable = 1;
      found_cable = 1;
      cable_name = argv[i];
      cable_name = argv[i];
      argv[optind] = argv[start_idx];  // swap the cable name with the other arg,
      argv[optind] = argv[start_idx];  // swap the cable name with the other arg,
      argv[start_idx] = start_str;     // keep all cable opts at the end
      argv[start_idx] = start_str;     // keep all cable opts at the end
      break;
      break;
    }
    }
  }
  }
 
 
 
 
  if(!found_cable) {
  if(!found_cable) {
    fprintf(stderr, "No valid cable specified.\n");
    fprintf(stderr, "No valid cable specified.\n");
    exit(1);
    exit(1);
  }
  }
 
 
  optind = start_idx+1;  // reset the parse index
  optind = start_idx+1;  // reset the parse index
 
 
    /* Get the cable-arguments */
    /* Get the cable-arguments */
  valid_cable_args = cable_get_args();
  valid_cable_args = cable_get_args();
 
 
  /* Parse the remaining options for the cable.
  /* Parse the remaining options for the cable.
   * Note that this will include unrecognized option from before the cable name.
   * Note that this will include unrecognized option from before the cable name.
   */
   */
  while((c = getopt(argc, argv, valid_cable_args)) != -1) {
  while((c = getopt(argc, argv, valid_cable_args)) != -1) {
    //printf("Got cable opt %c (0x%X)\n", (char)c, c);
    //printf("Got cable opt %c (0x%X)\n", (char)c, c);
    if(c == '?') {
    if(c == '?') {
      printf("\nERROR:  Unknown cable option \'-%c\'\n\n", optopt);
      printf("\nERROR:  Unknown cable option \'-%c\'\n\n", optopt);
      print_usage(argv[0]);
      print_usage(argv[0]);
      exit(1);
      exit(1);
    }
    }
    else if(cable_parse_opt(c, optarg) != APP_ERR_NONE) {
    else if(cable_parse_opt(c, optarg) != APP_ERR_NONE) {
      printf("\nERROR:  Failed to parse cable option \'-%c\' %s\n\n", (char)c, optarg);
      printf("\nERROR:  Failed to parse cable option \'-%c\' %s\n\n", (char)c, optarg);
      print_usage(argv[0]);
      print_usage(argv[0]);
      exit(1);
      exit(1);
    }
    }
  }
  }
}
}
 
 
 
 
 
 
int main(int argc,  char *argv[]) {
int main(int argc,  char *argv[]) {
  char *s;
  char *s;
  long int serverPort;
  long int serverPort;
 
 
  srand(getpid());
  srand(getpid());
  bsdl_init();
  bsdl_init();
  cmd_line_ir_sizes = (irset *) malloc(IR_START_SETS * sizeof(irset));
  cmd_line_ir_sizes = (irset *) malloc(IR_START_SETS * sizeof(irset));
  if(cmd_line_ir_sizes == NULL) {
  if(cmd_line_ir_sizes == NULL) {
    printf("ERROR: out of memory allocating array for IR sizes.\n");
    printf("ERROR: out of memory allocating array for IR sizes.\n");
    return 1;
    return 1;
  }
  }
 
 
  parse_args(argc, argv);
  parse_args(argc, argv);
 
 
  if(cable_init() != APP_ERR_NONE) {
  if(cable_init() != APP_ERR_NONE) {
    printf("Failed to initialize cable \'%s\', aborting.\n", cable_name);
    printf("Failed to initialize cable \'%s\', aborting.\n", cable_name);
    exit(1);
    exit(1);
  }
  }
 
 
 
 
  /* 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.  */
  configure_chain();
  configure_chain();
 
 
  if(do_selftest) {
  if(do_selftest) {
    // Test the connection.
    // Test the connection.
    printf("*** Doing self-test ***\n");
    printf("*** Doing self-test ***\n");
    if(dbg_test() != APP_ERR_NONE) {
    if(dbg_test() != APP_ERR_NONE) {
      printf("Self-test FAILED *** Bailing out!\n");
      printf("Self-test FAILED *** Bailing out!\n");
      exit(1);
      exit(1);
    }
    }
    printf("*** Self-test PASSED ***\n");
    printf("*** Self-test PASSED ***\n");
  }
  }
 
 
  /* We have a connection.  Establish server.  */
  /* We have a connection.  Establish server.  */
  serverPort = strtol(port,&s,10);
  serverPort = strtol(port,&s,10);
  if(*s) return -1;
  if(*s) return -1;
 
 
  rsp_init(serverPort);
  rsp_init(serverPort);
 
 
  printf("JTAG bridge ready!\n");
  printf("JTAG bridge ready!\n");
 
 
  // This handles requests from GDB.  I'd prefer the while() loop to be in the function
  // This handles requests from GDB.  I'd prefer the while() loop to be in the function
  // with the select()/poll(), but the or1ksim rsp code (ported for use here) doesn't work 
  // with the select()/poll(), but the or1ksim rsp code (ported for use here) doesn't work 
  // that way, and I don't want to rework that code (to make it easier to import fixes
  // that way, and I don't want to rework that code (to make it easier to import fixes
  // written for the or1ksim rsp server).  --NAY
  // written for the or1ksim rsp server).  --NAY
  while(handle_rsp());
  while(handle_rsp());
 
 
  return 0;
  return 0;
}
}
 
 
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// Helper functions
// Helper functions
 
 
int get_IR_size(int devidx)
int get_IR_size(int devidx)
{
{
  int retval = -1;
  int retval = -1;
  int i;
  int i;
 
 
  if(idcodes[devidx] != IDCODE_INVALID) {
  if(idcodes[devidx] != IDCODE_INVALID) {
    retval = bsdl_get_IR_size(idcodes[devidx]);
    retval = bsdl_get_IR_size(idcodes[devidx]);
  }
  }
 
 
  // Search for this devices in the array of command line IR sizes
  // Search for this devices in the array of command line IR sizes
  for(i = 0; i < num_ir_sets; i++) {
  for(i = 0; i < num_ir_sets; i++) {
    if(cmd_line_ir_sizes[i].dev_index == devidx) {
    if(cmd_line_ir_sizes[i].dev_index == devidx) {
      if((retval > 0) && (retval != cmd_line_ir_sizes[i].ir_length))
      if((retval > 0) && (retval != cmd_line_ir_sizes[i].ir_length))
        printf("Warning: overriding autoprobed IR length (%i) with command line value (%i) for device %i\n", retval,
        printf("Warning: overriding autoprobed IR length (%i) with command line value (%i) for device %i\n", retval,
                            cmd_line_ir_sizes[i].ir_length, devidx);
                            cmd_line_ir_sizes[i].ir_length, devidx);
      retval = cmd_line_ir_sizes[i].ir_length;
      retval = cmd_line_ir_sizes[i].ir_length;
    }
    }
  }
  }
 
 
  if(retval < 0) {  // Make sure we have a value
  if(retval < 0) {  // Make sure we have a value
    printf("ERROR! Unable to autoprobe IR length for device index %i;  Must set IR size on command line. Aborting.\n", devidx);
    printf("ERROR! Unable to autoprobe IR length for device index %i;  Must set IR size on command line. Aborting.\n", devidx);
    exit(1);
    exit(1);
  }
  }
 
 
  return retval;
  return retval;
}
}
 
 
 
 
uint32_t get_debug_cmd(int devidx)
uint32_t get_debug_cmd(int devidx)
{
{
  int retval = TAP_CMD_INVALID;
  int retval = TAP_CMD_INVALID;
  uint32_t manuf_id = (idcodes[devidx] >> 1) & 0x7FF;
  uint32_t manuf_id = (idcodes[devidx] >> 1) & 0x7FF;
 
 
  if(idcodes[devidx] != IDCODE_INVALID) {
  if(idcodes[devidx] != IDCODE_INVALID) {
    if(manuf_id == XILINX_MANUFACTURER_ID) {
    if(manuf_id == XILINX_MANUFACTURER_ID) {
      retval = bsdl_get_user1_cmd(idcodes[devidx]);
      retval = bsdl_get_user1_cmd(idcodes[devidx]);
      if(cmd_line_cmd_debug < 0) printf("Xilinx IDCODE, assuming internal BSCAN mode\n\t(using USER1 instead of DEBUG TAP command)\n");
      if(cmd_line_cmd_debug < 0) printf("Xilinx IDCODE, assuming internal BSCAN mode\n\t(using USER1 instead of DEBUG TAP command)\n");
    } else {
    } else {
      retval = bsdl_get_debug_cmd(idcodes[devidx]);
      retval = bsdl_get_debug_cmd(idcodes[devidx]);
    }
    }
  }
  }
 
 
  if(cmd_line_cmd_debug >= 0) {
  if(cmd_line_cmd_debug >= 0) {
    if(retval != TAP_CMD_INVALID) {
    if(retval != TAP_CMD_INVALID) {
      printf("Warning: overriding autoprobe debug command (0x%X) with command line value (0x%X)\n", retval, cmd_line_cmd_debug);
      printf("Warning: overriding autoprobe debug command (0x%X) with command line value (0x%X)\n", retval, cmd_line_cmd_debug);
    } else {
    } else {
      printf("Using command-line debug command 0x%X\n", cmd_line_cmd_debug);
      printf("Using command-line debug command 0x%X\n", cmd_line_cmd_debug);
    }
    }
    retval = cmd_line_cmd_debug;
    retval = cmd_line_cmd_debug;
  }
  }
 
 
  if(retval == TAP_CMD_INVALID) {
  if(retval == TAP_CMD_INVALID) {
    printf("ERROR!  Unable to find DEBUG command for device index %i, device ID 0x%0lX\n", devidx, idcodes[devidx]);
    printf("ERROR!  Unable to find DEBUG command for device index %i, device ID 0x%0X\n", devidx, idcodes[devidx]);
  }
  }
 
 
  return retval;
  return retval;
}
}
 
 
 
 
// Extracts two values from an option string
// Extracts two values from an option string
// of the form "<index>:<value>", where both args
// of the form "<index>:<value>", where both args
// are in base 10
// are in base 10
void get_ir_opts(char *optstr, int *idx, int *val)
void get_ir_opts(char *optstr, int *idx, int *val)
{
{
  char *ptr;
  char *ptr;
 
 
  ptr = strstr(optstr, ":");
  ptr = strstr(optstr, ":");
  if(ptr == NULL) {
  if(ptr == NULL) {
    printf("Error: badly formatted IR length option.  Use format \'<index>:<value>\', without spaces, where both args are in base 10\n");
    printf("Error: badly formatted IR length option.  Use format \'<index>:<value>\', without spaces, where both args are in base 10\n");
    exit(1);
    exit(1);
  }
  }
 
 
  *ptr = '\0';
  *ptr = '\0';
  ptr++;  // This now points to the second (value) arg string
  ptr++;  // This now points to the second (value) arg string
 
 
  *idx = strtoul(optstr, NULL, 10);
  *idx = strtoul(optstr, NULL, 10);
  *val = strtoul(ptr, NULL, 10);
  *val = strtoul(ptr, NULL, 10);
  // ***CHECK FOR SUCCESS
  // ***CHECK FOR SUCCESS
}
}
 
 
 
 

powered by: WebSVN 2.1.0

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