/* 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>
|
|
|
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"
|
|
|
#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;
|
|
|
/* Printer compatible device we have open. */
|
/* Printer compatible device we have open. */
|
static int lp;
|
static int lp;
|
|
|
/* 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;
|
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;
|
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;
|
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)
|
unsigned long long int 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 unsigned long long int
|
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;
|
unsigned long long int 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;
|
}
|
}
|
|
|
/* Sets register/memory regno to data. */
|
/* Sets register/memory regno to data. */
|
|
|
void
|
void
|
jtag_write_reg (regno, data)
|
jtag_write_reg (regno, data)
|
int regno;
|
int regno;
|
unsigned long long int data;
|
ULONGEST data;
|
{
|
{
|
int crc_read, crc_write, crc_ok, retry;
|
int crc_read, crc_write, crc_ok, retry;
|
|
|
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;
|
}
|
}
|
|
|
/* Reads register/memory from regno. */
|
/* Reads register/memory from regno. */
|
|
|
unsigned long long int
|
ULONGEST
|
jtag_read_reg (regno)
|
jtag_read_reg (regno)
|
unsigned int regno;
|
unsigned int regno;
|
{
|
{
|
unsigned long long int 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;
|
|
|
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;
|
return;
|
JTAG_RETRY_WAIT();
|
JTAG_RETRY_WAIT();
|
}
|
}
|
else
|
else
|
return;
|
return;
|
}
|
}
|
err = ERR_CRC;
|
err = ERR_CRC;
|
}
|
}
|
|
|
/* Sets scan chain. */
|
/* Sets scan chain. */
|
|
|
void
|
void
|
jtag_set_chain (chain)
|
jtag_set_chain (chain)
|
int chain;
|
int chain;
|
{
|
{
|
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;
|
}
|
}
|
}
|
}
|
|
|
/* 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;
|
|
|
if (args == 0)
|
if (args == 0)
|
error ("To open a or1k remote debugging connection, you need to specify what parallel\n"
|
error ("To open a or1k remote debugging connection, you need to specify what parallel\n"
|
"port device is attached to the target board (e.g., /dev/lp0).\n");
|
"port device is attached to the target board (e.g., /dev/lp0).\n");
|
|
|
/* Parse the port name. */
|
/* Parse the port name. */
|
if ((argv = buildargv (args)) == NULL)
|
if ((argv = buildargv (args)) == NULL)
|
nomem (0);
|
nomem (0);
|
port_name = strsave (argv[0]);
|
port_name = strsave (argv[0]);
|
make_cleanup_freeargv (argv);
|
make_cleanup_freeargv (argv);
|
|
|
/* Open and initialize the parallel port. */
|
/* Open and initialize the parallel port. */
|
lp = open (port_name, O_WRONLY);
|
lp = open (port_name, O_WRONLY);
|
if (lp < 0)
|
if (lp < 0)
|
error ("Cannot open device.");
|
error ("Cannot open device.");
|
|
|
printf_unfiltered ("Remote or1k debugging using %s\n", port_name);
|
printf_unfiltered ("Remote or1k debugging using %s\n", port_name);
|
|
|
current_chain = -1;
|
current_chain = -1;
|
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 ()
|
jtag_done ()
|
{
|
{
|
close (lp);
|
close (lp);
|
}
|
}
|
|
|