Line 37... |
Line 37... |
#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)
|
|
|
/* Scan chain for risc debug interface. */
|
/* Selects crc trailer size in bits. Currently supported: 8 */
|
#define SC_RISC_DEBUG 0x1
|
#define CRC_SIZE (8)
|
#define SC_SIZE 4
|
|
|
/* Scan chain size in bits. */
|
|
#define SC_SIZE (4)
|
|
|
|
/* Scan chain info. */
|
|
/* *INDENT-OFF* */
|
|
static int chain_addr_size[] = { 0, 32, 0, 0, 5 };
|
|
static int chain_data_size[] = { 0, 32, 0, 32, 32 };
|
|
static int chain_is_valid[] = { 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 };
|
|
/* *INDENT-OFF* */
|
|
|
|
/* Currently selected scan chain - just to prevent unnecessary
|
|
transfers. */
|
|
|
|
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;
|
|
|
Line 65... |
Line 81... |
{
|
{
|
int c;
|
int c;
|
int new_crc;
|
int new_crc;
|
int d;
|
int d;
|
|
|
|
#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;
|
Line 78... |
Line 95... |
/* 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
|
|
return 0;
|
|
#endif
|
}
|
}
|
|
|
/* Resets JTAG.
|
/* Resets JTAG.
|
Writes TRST=0
|
Writes TRST=0
|
and TRST=1 */
|
and TRST=1 */
|
Line 131... |
Line 151... |
|
|
/* 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 stream;
|
unsigned long long int 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;
|
Line 148... |
Line 168... |
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
|
static unsigned long long int
|
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 data;
|
unsigned long long int 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++)
|
{
|
{
|
Line 192... |
Line 212... |
/* 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 int data;
|
unsigned long long int 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
|
|
is read only. */
|
|
if (!chain_has_rw[current_chain])
|
|
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;
|
jp1_write_stream (regno, 32, 0); /* addr32 */
|
/* write addr */
|
jp1_write_JTAG (2); /* write (R/W=1) */
|
jp1_write_stream (regno, chain_addr_size[current_chain], 0);
|
jp1_write_stream (data, 32, 0); /* data32 */
|
/* write (R/W=1) - we tested that previously. */
|
|
jp1_write_JTAG (2);
|
|
/* write data */
|
|
jp1_write_stream (data, chain_data_size[current_chain], 0);
|
|
if (chain_has_crc[current_chain])
|
|
{
|
crc_write = crc_w;
|
crc_write = crc_w;
|
crc_read = jp1_read_stream (crc_write, 8, 1); /* write CRC, EXIT1_DR */
|
/* write CRC, EXIT1_DR */
|
|
crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1);
|
|
}
|
jp1_write_JTAG (1); /* UPDATE_DR */
|
jp1_write_JTAG (1); /* UPDATE_DR */
|
crc_ok = jp1_read_JTAG (); /* Did JTAG receive packet correctly? */
|
/* Did JTAG receive packet correctly? */
|
|
if (chain_has_crc[current_chain])
|
|
crc_ok = jp1_read_JTAG ();
|
jp1_write_JTAG (1); /* SELECT_DR */
|
jp1_write_JTAG (1); /* SELECT_DR */
|
|
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;
|
|
}
|
err = ERR_CRC;
|
err = ERR_CRC;
|
}
|
}
|
|
|
/* Reads register/memory from regno. */
|
/* Reads register/memory from regno. */
|
|
|
unsigned int
|
unsigned long long int
|
jtag_read_reg (regno)
|
jtag_read_reg (regno)
|
unsigned int regno;
|
unsigned int regno;
|
{
|
{
|
unsigned int data;
|
unsigned long long int 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;
|
Line 238... |
Line 276... |
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;
|
jp1_write_stream (regno, 32, 0); /* addr32 */
|
/* write addr */
|
jp1_write_JTAG (0); /* read (R/W=0) */
|
jp1_write_stream (regno, chain_addr_size[current_chain], 0);
|
|
/* read (R/W=0) */
|
|
if (chain_has_rw[current_chain])
|
|
jp1_write_JTAG (0);
|
|
if (chain_has_crc[current_chain])
|
|
{
|
crc_r = 0;
|
crc_r = 0;
|
data = jp1_read_stream (0, 32, 0); /* data32=0 */
|
/* data = 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;
|
crc_read = jp1_read_stream (crc_write, 8, 1); /* Send my crc, EXIT1_DR */
|
/* Send my crc, EXIT1_DR */
|
|
crc_read = jp1_read_stream (crc_write, CRC_SIZE, 1);
|
|
}
|
jp1_write_JTAG (1); /* UPDATE_DR */
|
jp1_write_JTAG (1); /* UPDATE_DR */
|
crc_ok = jp1_read_JTAG (); /* Did JTAG receive packet correctly? */
|
/* Did JTAG receive packet correctly? */
|
|
if (chain_has_crc[current_chain])
|
|
crc_ok = jp1_read_JTAG ();
|
jp1_write_JTAG (1); /* SELECT_DR */
|
jp1_write_JTAG (1); /* SELECT_DR */
|
|
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
|
|
return;
|
|
}
|
err = ERR_CRC;
|
err = ERR_CRC;
|
}
|
}
|
|
|
|
/* Sets scan chain. */
|
|
|
|
void
|
|
jtag_set_chain (chain)
|
|
int chain;
|
|
{
|
|
if (current_chain != chain)
|
|
{
|
|
if (!chain_is_valid[chain])
|
|
error ("Chain not valid.");
|
|
|
|
current_chain = chain;
|
|
jp1_prepare_control ();
|
|
jp1_write_stream (chain, SC_SIZE, 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)
|
Line 284... |
Line 353... |
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;
|
jp1_reset_JTAG ();
|
jp1_reset_JTAG ();
|
jp1_prepare_control ();
|
jtag_set_chain (SC_RISC_DEBUG);
|
jp1_write_stream (SC_RISC_DEBUG, SC_SIZE, 1);
|
|
free (port_name);
|
free (port_name);
|
}
|
}
|
|
|
void
|
void
|
jtag_done ()
|
jtag_done ()
|