Line 199... |
Line 199... |
|
|
jreg[0] = ival;
|
jreg[0] = ival;
|
|
|
dump_jreg (" shifting in", jreg, 1);
|
dump_jreg (" shifting in", jreg, 1);
|
|
|
double t = or1ksim_jtag_shift_ir (jreg);
|
double t = or1ksim_jtag_shift_ir (jreg, 4);
|
|
|
dump_jreg (" shifted out", jreg, 1);
|
dump_jreg (" shifted out", jreg, 1);
|
printf (" time taken: %.12fs\n", t);
|
printf (" time taken: %.12fs\n", t);
|
|
|
free (jreg);
|
free (jreg);
|
Line 293... |
Line 293... |
jreg[3] = crc_in >> 19;
|
jreg[3] = crc_in >> 19;
|
jreg[4] = crc_in >> 27;
|
jreg[4] = crc_in >> 27;
|
|
|
/* Note what we are shifting in and shift it. */
|
/* Note what we are shifting in and shift it. */
|
dump_jreg (" shifting in", jreg, num_bytes);
|
dump_jreg (" shifting in", jreg, num_bytes);
|
double t = or1ksim_jtag_shift_dr (jreg);
|
double t = or1ksim_jtag_shift_dr (jreg, 32 + 4 + 32 + 4 + 1);
|
|
|
/* Diagnose what we are shifting out. */
|
/* Diagnose what we are shifting out. */
|
dump_jreg (" shifted out", jreg, num_bytes);
|
dump_jreg (" shifted out", jreg, num_bytes);
|
|
|
/* Break out fields */
|
/* Break out fields */
|
Line 395... |
Line 395... |
{
|
{
|
printf ("ERROR: WRITE_COMMAND address 0x%lx too large\n", addr);
|
printf ("ERROR: WRITE_COMMAND address 0x%lx too large\n", addr);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
if (len > 0xffff)
|
if ((len + 1) < 0x1)
|
{
|
{
|
printf ("ERROR: WRITE_COMMAND length 0x%lx too large\n", len);
|
printf ("ERROR: WRITE_COMMAND length 0x%lx too small\n", len + 1);
|
|
return 0;
|
|
}
|
|
else if ((len + 1) > 0x10000)
|
|
{
|
|
printf ("ERROR: WRITE_COMMAND length 0x%lx too large\n", len + 1);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Compute the CRC */
|
/* Compute the CRC */
|
unsigned long int crc_in;
|
unsigned long int crc_in;
|
Line 464... |
Line 469... |
jreg[10] = crc_in >> 23;
|
jreg[10] = crc_in >> 23;
|
jreg[11] = crc_in >> 31;
|
jreg[11] = crc_in >> 31;
|
|
|
/* Note what we are shifting in and shift it. */
|
/* Note what we are shifting in and shift it. */
|
dump_jreg (" shifting in", jreg, num_bytes);
|
dump_jreg (" shifting in", jreg, num_bytes);
|
double t = or1ksim_jtag_shift_dr (jreg);
|
double t = or1ksim_jtag_shift_dr (jreg, 32 + 4 + 32 + 16 + 32 + 4 + 4 + 1);
|
|
|
/* Diagnose what we are shifting out. */
|
/* Diagnose what we are shifting out. */
|
dump_jreg (" shifted out", jreg, num_bytes);
|
dump_jreg (" shifted out", jreg, num_bytes);
|
|
|
/* Break out fields */
|
/* Break out fields */
|
Line 579... |
Line 584... |
jreg[3] = crc_in >> 19;
|
jreg[3] = crc_in >> 19;
|
jreg[4] = crc_in >> 27;
|
jreg[4] = crc_in >> 27;
|
|
|
/* Note what we are shifting in and shift it. */
|
/* Note what we are shifting in and shift it. */
|
dump_jreg (" shifting in", jreg, num_bytes);
|
dump_jreg (" shifting in", jreg, num_bytes);
|
double t = or1ksim_jtag_shift_dr (jreg);
|
double t = or1ksim_jtag_shift_dr (jreg, 32 + 4 + 16 + 32 + 4 + 32 + 4 + 1);
|
|
|
/* Diagnose what we are shifting out. */
|
/* Diagnose what we are shifting out. */
|
dump_jreg (" shifted out", jreg, num_bytes);
|
dump_jreg (" shifted out", jreg, num_bytes);
|
|
|
/* Break out fields */
|
/* Break out fields */
|
Line 592... |
Line 597... |
unsigned long int len;
|
unsigned long int len;
|
unsigned char status;
|
unsigned char status;
|
unsigned long int crc_out;
|
unsigned long int crc_out;
|
|
|
access_type = ((jreg[4] >> 5) | (jreg[5] << 3)) & 0xf ;
|
access_type = ((jreg[4] >> 5) | (jreg[5] << 3)) & 0xf ;
|
|
|
addr = ((unsigned long int) jreg[ 5] >> 1) |
|
addr = ((unsigned long int) jreg[ 5] >> 1) |
|
((unsigned long int) jreg[ 6] << 7) |
|
((unsigned long int) jreg[ 6] << 7) |
|
((unsigned long int) jreg[ 7] << 15) |
|
((unsigned long int) jreg[ 7] << 15) |
|
((unsigned long int) jreg[ 8] << 23) |
|
((unsigned long int) jreg[ 8] << 23) |
|
((unsigned long int) jreg[ 9] << 31);
|
((unsigned long int) jreg[ 9] << 31);
|
Line 629... |
Line 633... |
crc_computed = crc32 (len, 16, crc_computed);
|
crc_computed = crc32 (len, 16, crc_computed);
|
crc_computed = crc32 (status, 4, crc_computed);
|
crc_computed = crc32 (status, 4, crc_computed);
|
|
|
/* Log the results. Remember the length is 1 greater than the value
|
/* Log the results. Remember the length is 1 greater than the value
|
returned. */
|
returned. */
|
printf (" access_type: 0x%x\n", status);
|
printf (" access_type: 0x%x\n", access_type);
|
printf (" address: 0x%lx\n", addr);
|
printf (" address: 0x%lx\n", addr);
|
printf (" length: 0x%lx\n", len + 1);
|
printf (" length: 0x%lx\n", len + 1);
|
printf (" status: 0x%x\n", status);
|
printf (" status: 0x%x\n", status);
|
|
|
if (crc_out != crc_computed)
|
if (crc_out != crc_computed)
|
Line 656... |
Line 660... |
|
|
Usage:
|
Usage:
|
|
|
GO_COMMAND_WRITE <data>
|
GO_COMMAND_WRITE <data>
|
|
|
The one argument is a string of bytes to be written, MS byte first.
|
The one argument is a string of bytes to be written, LS byte first.
|
|
|
Like all the JTAG fields, each data byte must be reversed, so it is shifted
|
Like all the JTAG fields, each data byte must be reversed, so it is shifted
|
MS bit first. It also requires a 32-bit CRC.
|
MS bit first. It also requires a 32-bit CRC.
|
|
|
On return we get a status register and CRC.
|
On return we get a status register and CRC.
|
Line 689... |
Line 693... |
/* Break out the fields, including the data string into a vector of bytes. */
|
/* Break out the fields, including the data string into a vector of bytes. */
|
unsigned long int cmd = 0; /* GO_COMMAND */
|
unsigned long int cmd = 0; /* GO_COMMAND */
|
|
|
char *data_str = argv[next_jreg];
|
char *data_str = argv[next_jreg];
|
int data_len = strlen (data_str);
|
int data_len = strlen (data_str);
|
int data_bytes = (data_len + 1) / 2;
|
int data_bytes = data_len / 2;
|
unsigned char *data = malloc (data_bytes);
|
unsigned char *data = malloc (data_bytes);
|
|
|
if (NULL == data)
|
if (NULL == data)
|
{
|
{
|
printf ("ERROR: data malloc for GO_COMMAND_WRITE register failed.\n");
|
printf ("ERROR: data malloc for GO_COMMAND_WRITE register failed.\n");
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
if (1 == (data_len % 2))
|
|
{
|
|
printf ("Warning: GO_COMMAND_WRITE odd char ignored\n");
|
|
}
|
|
|
int i;
|
int i;
|
|
|
for (i = 0; i < data_bytes; i++)
|
for (i = 0; i < data_bytes; i++)
|
{
|
{
|
int ch_off_ls = data_len - (i * 2) - 1;
|
int ch_off_ms = i * 2;
|
int ch_off_ms = (0 == ch_off_ls) ? 0 : ch_off_ls - 1;
|
int ch_off_ls = i * 2 + 1;
|
int j;
|
|
|
|
/* Get each nybble in turn, remembering that we may not have a MS nybble
|
/* Get each nybble in turn, remembering that we may not have a MS nybble
|
if the data string has an odd number of chars. */
|
if the data string has an odd number of chars. */
|
data[i] = 0;
|
data[i] = 0;
|
|
|
|
int j;
|
|
|
for (j = ch_off_ms; j <= ch_off_ls; j++)
|
for (j = ch_off_ms; j <= ch_off_ls; j++)
|
{
|
{
|
char c = data_str[j];
|
char c = data_str[j];
|
int dig_val = (('0' <= c) && (c <= '9')) ? c - '0' :
|
int dig_val = (('0' <= c) && (c <= '9')) ? c - '0' :
|
(('a' <= c) && (c <= 'f')) ? c - 'a' + 10 :
|
(('a' <= c) && (c <= 'f')) ? c - 'a' + 10 :
|
Line 790... |
Line 800... |
jreg[data_bytes + 3] = crc_in >> 19;
|
jreg[data_bytes + 3] = crc_in >> 19;
|
jreg[data_bytes + 4] = crc_in >> 27;
|
jreg[data_bytes + 4] = crc_in >> 27;
|
|
|
/* Note what we are shifting in and shift it. */
|
/* Note what we are shifting in and shift it. */
|
dump_jreg (" shifting in", jreg, num_bytes);
|
dump_jreg (" shifting in", jreg, num_bytes);
|
double t = or1ksim_jtag_shift_dr (jreg);
|
double t = or1ksim_jtag_shift_dr (jreg,
|
|
32 + 4 + 32 + data_bytes * 8 + 4 + 1);
|
|
|
/* Diagnose what we are shifting out. */
|
/* Diagnose what we are shifting out. */
|
dump_jreg (" shifted out", jreg, num_bytes);
|
dump_jreg (" shifted out", jreg, num_bytes);
|
|
|
/* Break out fields */
|
/* Break out fields */
|
Line 875... |
Line 886... |
/* Is the argument in range? Remember the length we actually put in has 1
|
/* Is the argument in range? Remember the length we actually put in has 1
|
subtracted, so although it is a 16-bit field, it can be up to 2^16. */
|
subtracted, so although it is a 16-bit field, it can be up to 2^16. */
|
unsigned long int cmd = 0; /* GO_COMMAND */
|
unsigned long int cmd = 0; /* GO_COMMAND */
|
unsigned long int data_bytes = strtoul (argv[next_jreg], NULL, 16);
|
unsigned long int data_bytes = strtoul (argv[next_jreg], NULL, 16);
|
|
|
if (data_bytes > 0x10000)
|
if (data_bytes < 0)
|
|
{
|
|
printf ("ERROR: GO_COMMAND_READ length 0x%lx too small\n", data_bytes);
|
|
return 0;
|
|
}
|
|
else if (data_bytes > 0x10000)
|
{
|
{
|
printf ("ERROR: GO_COMMAND_READ length 0x%lx too large\n", data_bytes);
|
printf ("ERROR: GO_COMMAND_READ length 0x%lx too large\n", data_bytes);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
Line 922... |
Line 938... |
jreg[3] = crc_in >> 19;
|
jreg[3] = crc_in >> 19;
|
jreg[4] = crc_in >> 27;
|
jreg[4] = crc_in >> 27;
|
|
|
/* Note what we are shifting in and shift it. */
|
/* Note what we are shifting in and shift it. */
|
dump_jreg (" shifting in", jreg, num_bytes);
|
dump_jreg (" shifting in", jreg, num_bytes);
|
double t = or1ksim_jtag_shift_dr (jreg);
|
double t = or1ksim_jtag_shift_dr (jreg,
|
|
32 + 4 + data_bytes * 8 + 32 + 4 + 1);
|
|
|
/* Diagnose what we are shifting out. */
|
/* Diagnose what we are shifting out. */
|
dump_jreg (" shifted out", jreg, num_bytes);
|
dump_jreg (" shifted out", jreg, num_bytes);
|
|
|
/* Break out fields */
|
/* Break out fields */
|
Line 934... |
Line 951... |
unsigned char status;
|
unsigned char status;
|
unsigned long int crc_out;
|
unsigned long int crc_out;
|
|
|
if (NULL == data)
|
if (NULL == data)
|
{
|
{
|
printf ("ERROR: data malloc for GO_COMMAND_WRITE register failed.\n");
|
printf ("ERROR: data malloc for GO_COMMAND_READ register failed.\n");
|
free (jreg);
|
free (jreg);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
int i;
|
int i;
|
Line 973... |
Line 990... |
crc_computed = crc32 (data[i], 8, crc_computed);
|
crc_computed = crc32 (data[i], 8, crc_computed);
|
}
|
}
|
|
|
crc_computed = crc32 (status, 4, crc_computed);
|
crc_computed = crc32 (status, 4, crc_computed);
|
|
|
/* Log the results, ignoring a leading zero on the MS byte */
|
/* Log the results, remembering these are bytes, so endianness is not a
|
printf (" data: 0x%x", data[data_bytes - 1]);
|
factor here. Since the OR1K is big endian, the lowest numbered byte will
|
|
be the least significant, and the first printed */
|
|
printf (" data: ");
|
|
|
for (i = data_bytes - 2; i >= 0; i--)
|
for (i = 0; i < data_bytes; i++)
|
{
|
{
|
printf ("%02x", data[i]);
|
printf ("%02x", data[i]);
|
}
|
}
|
|
|
printf ("\n");
|
printf ("\n");
|
Line 1111... |
Line 1130... |
jreg[10] = crc_in >> 23;
|
jreg[10] = crc_in >> 23;
|
jreg[11] = crc_in >> 31;
|
jreg[11] = crc_in >> 31;
|
|
|
/* Note what we are shifting in and shift it. */
|
/* Note what we are shifting in and shift it. */
|
dump_jreg (" shifting in", jreg, num_bytes);
|
dump_jreg (" shifting in", jreg, num_bytes);
|
double t = or1ksim_jtag_shift_dr (jreg);
|
double t = or1ksim_jtag_shift_dr (jreg, 32 + 4 + 32 + 52 + 4 + 1);
|
|
|
/* Diagnose what we are shifting out. */
|
/* Diagnose what we are shifting out. */
|
dump_jreg (" shifted out", jreg, num_bytes);
|
dump_jreg (" shifted out", jreg, num_bytes);
|
|
|
/* Break out fields */
|
/* Break out fields */
|
Line 1226... |
Line 1245... |
jreg[3] = crc_in >> 19;
|
jreg[3] = crc_in >> 19;
|
jreg[4] = crc_in >> 27;
|
jreg[4] = crc_in >> 27;
|
|
|
/* Note what we are shifting in and shift it. */
|
/* Note what we are shifting in and shift it. */
|
dump_jreg (" shifting in", jreg, num_bytes);
|
dump_jreg (" shifting in", jreg, num_bytes);
|
double t = or1ksim_jtag_shift_dr (jreg);
|
double t = or1ksim_jtag_shift_dr (jreg, 32 + 4 + 52 + 32 + 4 + 1);
|
|
|
/* Diagnose what we are shifting out. */
|
/* Diagnose what we are shifting out. */
|
dump_jreg (" shifted out", jreg, num_bytes);
|
dump_jreg (" shifted out", jreg, num_bytes);
|
|
|
/* Break out fields */
|
/* Break out fields */
|
Line 1318... |
Line 1337... |
/* --------------------------------------------------------------------------*/
|
/* --------------------------------------------------------------------------*/
|
int
|
int
|
main (int argc,
|
main (int argc,
|
char *argv[])
|
char *argv[])
|
{
|
{
|
|
const double QUANTUM = 5.0e-3; /* Time in sec for each step. */
|
|
|
/* Check we have minimum number of args. */
|
/* Check we have minimum number of args. */
|
if (argc < 4)
|
if (argc < 4)
|
{
|
{
|
printf ("usage: lib-jtag <config-file> <image> <jregtype> [<args>] "
|
printf ("usage: lib-jtag <config-file> <image> <jregtype> [<args>] "
|
"[<jregtype> [<args>]] ...\n");
|
"[<jregtype> [<args>]] ...\n");
|
Line 1338... |
Line 1359... |
{
|
{
|
printf ("Initalization failed.\n");
|
printf ("Initalization failed.\n");
|
return 1;
|
return 1;
|
}
|
}
|
|
|
/* Run repeatedly for 1 millisecond until we have processed all JTAG
|
/* Run repeatedly for 10 milliseconds until we have processed all JTAG
|
registers */
|
registers */
|
int next_jreg = 3; /* Offset to next JTAG register */
|
int next_jreg = 3; /* Offset to next JTAG register */
|
|
|
do
|
do
|
{
|
{
|
switch (or1ksim_run (1.0e-3))
|
switch (or1ksim_run (QUANTUM))
|
{
|
{
|
case OR1KSIM_RC_OK:
|
case OR1KSIM_RC_OK:
|
printf ("Execution step completed OK.\n");
|
printf ("Execution step completed OK.\n");
|
break;
|
break;
|
|
|
Line 1465... |
Line 1486... |
}
|
}
|
}
|
}
|
while (next_jreg < argc);
|
while (next_jreg < argc);
|
|
|
/* A little longer to allow response to last upcall to be handled. */
|
/* A little longer to allow response to last upcall to be handled. */
|
switch (or1ksim_run (1.0e-3))
|
switch (or1ksim_run (QUANTUM))
|
{
|
{
|
case OR1KSIM_RC_OK:
|
case OR1KSIM_RC_OK:
|
printf ("Execution step completed OK.\n");
|
printf ("Execution step completed OK.\n");
|
break;
|
break;
|
|
|