Line 205... |
Line 205... |
|
|
jreg[zero_bytes] >>= zero_off;
|
jreg[zero_bytes] >>= zero_off;
|
jreg[zero_bytes] <<= zero_off;
|
jreg[zero_bytes] <<= zero_off;
|
|
|
/* Determine how much to skip in total */
|
/* Determine how much to skip in total */
|
unsigned int skip_bytes = ign_bits + zero_bits / 8;
|
unsigned int skip_bytes = (ign_bits + zero_bits) / 8;
|
unsigned int bit_off = ign_bits + zero_bits % 8;
|
unsigned int bit_off = (ign_bits + zero_bits) % 8;
|
|
|
/* Simplify by dealing separately with two cases:
|
/* Simplify by dealing separately with two cases:
|
- the bit offset is less than or equal to 4, so the status goes in the
|
- the bit offset is less than or equal to 4, so the status goes in the
|
first free byte, with some CRC.
|
first free byte, with some CRC.
|
- the bit offset is greater than 4 but less than 8, so the status goes in
|
- the bit offset is greater than 4 but less than 8, so the status goes in
|
Line 288... |
Line 288... |
static int
|
static int
|
module_select (unsigned char *jreg)
|
module_select (unsigned char *jreg)
|
{
|
{
|
/* Break out the fields */
|
/* Break out the fields */
|
uint8_t mod_id = reverse_bits ((jreg[0] >> 1) & 0xf, 4);
|
uint8_t mod_id = reverse_bits ((jreg[0] >> 1) & 0xf, 4);
|
uint32_t crc_in = reverse_bits (((uint32_t ) jreg[0] & 0xe0 >> 5) |
|
uint32_t crc_in = reverse_bits (((uint32_t ) (jreg[0] & 0xe0) >> 5) |
|
((uint32_t ) jreg[1] << 3) |
|
((uint32_t ) jreg[1] << 3) |
|
((uint32_t ) jreg[2] << 11) |
|
((uint32_t ) jreg[2] << 11) |
|
((uint32_t ) jreg[3] << 19) |
|
((uint32_t ) jreg[3] << 19) |
|
((uint32_t ) (jreg[4] & 0x1f) << 27), 32);
|
((uint32_t ) (jreg[4] & 0x1f) << 27), 32);
|
|
|
Line 384... |
Line 384... |
case JAT_READ32:
|
case JAT_READ32:
|
access_bits = 32;
|
access_bits = 32;
|
break;
|
break;
|
|
|
default:
|
default:
|
fprintf (stderr, "*** ABORT ***: validate_wb_fields: unknown access "
|
fprintf (stderr, "Warning: validate_wb_fields: unknown access "
|
"type %u\n", runtime.debug.acc_type);
|
"type %u\n", runtime.debug.acc_type);
|
abort ();
|
return 0;
|
}
|
}
|
|
|
/* Check for validity. This works for 8-bit, although the tests will always
|
/* Check for validity. This works for 8-bit, although the tests will always
|
pass. */
|
pass. */
|
uint32_t access_bytes = access_bits / 8;
|
uint32_t access_bytes = access_bits / 8;
|
Line 474... |
Line 474... |
|
|
/* Get the data with no cache or VM translation and update the CRC */
|
/* Get the data with no cache or VM translation and update the CRC */
|
unsigned char byte = eval_direct8 (runtime.debug.addr + i, 0, 0);
|
unsigned char byte = eval_direct8 (runtime.debug.addr + i, 0, 0);
|
crc_out = crc32 (byte, 8, crc_out);
|
crc_out = crc32 (byte, 8, crc_out);
|
|
|
/* Store the byte in the register, without trampling adjacent
|
/* Reverse, then store the byte in the register, without trampling
|
bits. Simplified version when the bit offset is zero. */
|
adjacent bits. Simplified version when the bit offset is zero. */
|
|
byte = reverse_byte (byte);
|
|
|
if (0 == bit_off)
|
if (0 == bit_off)
|
{
|
{
|
jreg[byte_off + i] = byte;
|
jreg[byte_off + i] = byte;
|
}
|
}
|
else
|
else
|
Line 528... |
Line 530... |
Warning messages are printed to explain any validation problems.
|
Warning messages are printed to explain any validation problems.
|
|
|
@todo Should multiple SPR accesses be allowed in a single access?
|
@todo Should multiple SPR accesses be allowed in a single access?
|
|
|
@note The size of the data is one greater than the length specified in the
|
@note The size of the data is one greater than the length specified in the
|
original WRITE_COMMAND. */
|
original WRITE_COMMAND.
|
|
|
|
@return 1 (TRUE) if we could validate, even if we had to modify a field
|
|
with a warning. 0 (FALSE) otherwise. */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
static void
|
static int
|
validate_spr_fields ()
|
validate_spr_fields ()
|
{
|
{
|
int access_bits;
|
int access_bits;
|
int is_read_p;
|
int is_read_p;
|
|
|
switch (runtime.debug.acc_type)
|
switch (runtime.debug.acc_type)
|
{
|
{
|
case JAT_WRITE8: access_bits = 8; is_read_p = 0;
|
case JAT_WRITE8: access_bits = 8; is_read_p = 0; break;
|
case JAT_READ8: access_bits = 8; is_read_p = 1;
|
case JAT_READ8: access_bits = 8; is_read_p = 1; break;
|
case JAT_WRITE16: access_bits = 16; is_read_p = 0;
|
case JAT_WRITE16: access_bits = 16; is_read_p = 0; break;
|
case JAT_READ16: access_bits = 16; is_read_p = 1;
|
case JAT_READ16: access_bits = 16; is_read_p = 1; break;
|
case JAT_WRITE32: access_bits = 32; is_read_p = 0;
|
case JAT_WRITE32: access_bits = 32; is_read_p = 0; break;
|
case JAT_READ32: access_bits = 32; is_read_p = 1;
|
case JAT_READ32: access_bits = 32; is_read_p = 1; break;
|
|
|
default:
|
default:
|
fprintf (stderr, "*** ABORT ***: validate_spr_fields: unknown access "
|
fprintf (stderr, "Warning: validate_spr_fields: unknown access "
|
"type %u\n", runtime.debug.acc_type);
|
"type %u\n", runtime.debug.acc_type);
|
abort ();
|
return 0;
|
}
|
}
|
|
|
/* Validate and correct if necessary access width */
|
/* Validate and correct if necessary access width */
|
if (32 != access_bits)
|
if (32 != access_bits)
|
{
|
{
|
Line 562... |
Line 567... |
}
|
}
|
|
|
/* Validate and correct if necessary access size */
|
/* Validate and correct if necessary access size */
|
if (1 != runtime.debug.size)
|
if (1 != runtime.debug.size)
|
{
|
{
|
fprintf (stderr, "warning: JTAG SPR access must be 1 word in length: "
|
fprintf (stderr, "Warning: JTAG SPR access must be 1 word in length: "
|
"corrected\n");
|
"corrected\n");
|
runtime.debug.size = 1;
|
runtime.debug.size = 1;
|
}
|
}
|
|
|
/* Validate and correct if necessary access size */
|
/* Validate and correct if necessary access size */
|
if (runtime.debug.addr >= MAX_SPRS)
|
if (runtime.debug.addr >= MAX_SPRS)
|
{
|
{
|
fprintf (stderr, "warning: JTAG SPR address exceeds MAX_SPRS: "
|
fprintf (stderr, "Warning: JTAG SPR address exceeds MAX_SPRS: "
|
"truncated\n");
|
"truncated\n");
|
runtime.debug.addr %= MAX_SPRS;
|
runtime.debug.addr %= MAX_SPRS;
|
}
|
}
|
|
|
|
return 0; /* Success */
|
|
|
} /* validate_spr_fields () */
|
} /* validate_spr_fields () */
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
/*!Read SPR data
|
/*!Read SPR data
|
Line 610... |
Line 619... |
unsigned int skip_bits)
|
unsigned int skip_bits)
|
{
|
{
|
/* Compute the CRC as we go */
|
/* Compute the CRC as we go */
|
uint32_t crc_out = 0xffffffff;
|
uint32_t crc_out = 0xffffffff;
|
|
|
/* Validate the fields for the SPR read. This doesn't stop us - just prints
|
/* Validate the fields for the SPR read. This mostly just prints
|
out warnings and corrects the problems. */
|
out warnings and corrects the problems. However if the access type
|
validate_spr_fields();
|
cannot be worked out, we must use empty data. */
|
|
uint32_t spr;
|
|
|
|
if (validate_spr_fields())
|
|
{
|
/* Transfer the SPR */
|
/* Transfer the SPR */
|
uint32_t spr = mfspr (runtime.debug.addr);
|
spr = mfspr (runtime.debug.addr);
|
|
}
|
|
else
|
|
{
|
|
spr = 0;
|
|
}
|
|
|
runtime.debug.addr++;
|
runtime.debug.addr++;
|
|
|
/* Store the SPR in the register, without trampling adjacent
|
/* Store the SPR in the register, without trampling adjacent
|
bits. Simplified version when the bit offset is zero. Compute the CRC as
|
bits. Simplified version when the bit offset is zero. Compute the CRC as
|
Line 752... |
Line 769... |
fprintf (stderr, "Warning: JTAG attempt to read from CPU1: Not "
|
fprintf (stderr, "Warning: JTAG attempt to read from CPU1: Not "
|
"supported.\n");
|
"supported.\n");
|
break;
|
break;
|
|
|
default:
|
default:
|
fprintf (stderr, "*** ABORT ***: go_command_read: invalid "
|
fprintf (stderr, "Warning: go_command_read: invalid module 0x%lx\n",
|
"module\n");
|
runtime.debug.mod_id);
|
abort ();
|
break;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
/* Mismatch: record the error */
|
/* Mismatch: record the error */
|
Line 822... |
Line 839... |
return;
|
return;
|
}
|
}
|
|
|
/* Extract the byte from the register. Simplified version when the bit
|
/* Extract the byte from the register. Simplified version when the bit
|
offset is zero. */
|
offset is zero. */
|
unsigned char byte_r;
|
unsigned char byte;
|
|
|
if (0 == bit_off)
|
if (0 == bit_off)
|
{
|
{
|
byte_r = jreg[byte_off + i];
|
byte = jreg[byte_off + i];
|
}
|
}
|
else
|
else
|
{
|
{
|
byte_r = jreg[byte_off + i] >> bit_off |
|
byte = jreg[byte_off + i] >> bit_off |
|
jreg[byte_off + i + 1] >> (8 - bit_off);
|
jreg[byte_off + i + 1] << (8 - bit_off);
|
}
|
}
|
|
|
/* Circumvent the read-only check usually done for mem accesses. */
|
/* Circumvent the read-only check usually done for mem accesses. */
|
set_program8 (runtime.debug.addr + i, reverse_byte (byte_r));
|
set_program8 (runtime.debug.addr + i, reverse_byte (byte));
|
}
|
}
|
|
|
runtime.debug.addr += runtime.debug.size;
|
runtime.debug.addr += runtime.debug.size;
|
|
|
} /* wishbone_write () */
|
} /* wishbone_write () */
|
Line 870... |
Line 887... |
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
static void
|
static void
|
spr_write (unsigned char *jreg,
|
spr_write (unsigned char *jreg,
|
unsigned int skip_bits)
|
unsigned int skip_bits)
|
{
|
{
|
/* Validate the fields for the SPR write. This doesn't stop us - just prints
|
/* Validate the fields for the SPR write. This doesn't stop us most of the
|
out warnings and corrects the problems. */
|
time, just prints out warnings and corrects the problems. However if we
|
validate_spr_fields ();
|
don't know the access type, then it will fail and we do nothing. */
|
|
if (!validate_spr_fields ())
|
|
{
|
|
return;
|
|
}
|
|
|
/* Construct the SPR value one byte at a time. */
|
/* Construct the SPR value one byte at a time. */
|
uint32_t spr = 0;
|
uint32_t spr = 0;
|
|
|
unsigned byte_off = skip_bits / 8;
|
unsigned byte_off = skip_bits / 8;
|
Line 974... |
Line 995... |
|
|
int i;
|
int i;
|
|
|
for (i = 0; i < runtime.debug.size; i++)
|
for (i = 0; i < runtime.debug.size; i++)
|
{
|
{
|
uint8_t byte = ((jreg[i] & 0xe0) >> 5) | ((jreg[i + 1] & 0x1f) << 3);
|
uint8_t byte = reverse_bits (((jreg[i] & 0xe0) >> 5) |
|
|
((jreg[i + 1] & 0x1f) << 3), 8);
|
crc_computed = crc32 (byte, 8, crc_computed);
|
crc_computed = crc32 (byte, 8, crc_computed);
|
}
|
}
|
|
|
/* Status flags */
|
/* Status flags */
|
enum jtag_status status = JS_OK;
|
enum jtag_status status = JS_OK;
|
Line 1001... |
Line 1023... |
fprintf (stderr, "Warning: JTAG attempt to write to CPU1: Not "
|
fprintf (stderr, "Warning: JTAG attempt to write to CPU1: Not "
|
"supported.\n");
|
"supported.\n");
|
break;
|
break;
|
|
|
default:
|
default:
|
fprintf (stderr, "*** ABORT ***: go_command_write: invalid "
|
fprintf (stderr, "Warning: go_command_write: invalid module 0x%lx\n",
|
"module\n");
|
runtime.debug.mod_id);
|
abort ();
|
break;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
/* Mismatch: record the error */
|
/* Mismatch: record the error */
|
Line 1129... |
Line 1151... |
if (crc_computed != crc_in)
|
if (crc_computed != crc_in)
|
{
|
{
|
/* Mismatch: record the error */
|
/* Mismatch: record the error */
|
status |= JS_CRC_IN_ERROR;
|
status |= JS_CRC_IN_ERROR;
|
}
|
}
|
else if (runtime.debug.write_defined_p)
|
|
|
/* If we haven't had a previous WRITE_COMMAND, then we return empty
|
|
data. There is no valid status flag we can use, but we print a rude
|
|
message. */
|
|
uint8_t acc_type_r;
|
|
uint32_t addr_r;
|
|
uint16_t len_r;
|
|
|
|
if (runtime.debug.write_defined_p)
|
{
|
{
|
/* Compute the CRC */
|
/* Compute the CRC */
|
crc_out = crc32 (runtime.debug.acc_type, 4, crc_out);
|
crc_out = crc32 (runtime.debug.acc_type, 4, crc_out);
|
crc_out = crc32 (runtime.debug.addr, 32, crc_out);
|
crc_out = crc32 (runtime.debug.addr, 32, crc_out);
|
crc_out = crc32 (runtime.debug.size - 1, 16, crc_out);
|
crc_out = crc32 (runtime.debug.size - 1, 16, crc_out);
|
|
|
|
/* Reverse the bit fields */
|
|
acc_type_r = reverse_bits (runtime.debug.acc_type, 4);
|
|
addr_r = reverse_bits (runtime.debug.addr, 32);
|
|
len_r = reverse_bits (runtime.debug.size - 1, 16);
|
|
}
|
|
else
|
|
{
|
|
fprintf (stderr, "Warning: JTAG READ_COMMAND finds no data\n");
|
|
|
|
/* Compute the CRC */
|
|
crc_out = crc32 (0, 4, crc_out);
|
|
crc_out = crc32 (0, 32, crc_out);
|
|
crc_out = crc32 (0, 16, crc_out);
|
|
|
|
/* Empty data */
|
|
acc_type_r = 0;
|
|
addr_r = 0;
|
|
len_r = 0;
|
|
}
|
|
|
/* Construct the outgoing register. Fields can only be written if they
|
/* Construct the outgoing register. Fields can only be written if they
|
are available */
|
are available */
|
uint8_t acc_type_r = reverse_bits (runtime.debug.acc_type, 4);
|
|
uint32_t addr_r = reverse_bits (runtime.debug.addr, 32);
|
|
uint16_t len_r = reverse_bits (runtime.debug.size - 1, 16);
|
|
|
|
jreg[ 4] |= (acc_type_r << 5) & 0xf8;
|
jreg[ 4] |= (acc_type_r << 5) & 0xf8;
|
jreg[ 5] |= (acc_type_r >> 3) & 0x07;
|
jreg[ 5] |= (acc_type_r >> 3) & 0x07;
|
jreg[ 5] |= (addr_r << 1) & 0xfe;
|
jreg[ 5] |= (addr_r << 1) & 0xfe;
|
jreg[ 6] |= (addr_r >> 7) & 0xff;
|
jreg[ 6] |= (addr_r >> 7) & 0xff;
|
jreg[ 7] |= (addr_r >> 15) & 0xff;
|
jreg[ 7] |= (addr_r >> 15) & 0xff;
|
jreg[ 8] |= (addr_r >> 23) & 0xff;
|
jreg[ 8] |= (addr_r >> 23) & 0xff;
|
jreg[ 9] |= (addr_r >> 31) & 0x01;
|
jreg[ 9] |= (addr_r >> 31) & 0x01;
|
jreg[ 9] |= (len_r << 1) & 0xfe;
|
jreg[ 9] |= (len_r << 1) & 0xfe;
|
jreg[10] |= (len_r >> 7) & 0xff;
|
jreg[10] |= (len_r >> 7) & 0xff;
|
jreg[11] |= (len_r >> 15) & 0x01;
|
jreg[11] |= (len_r >> 15) & 0x01;
|
}
|
|
else
|
|
{
|
|
fprintf (stderr, "Warning: JTAG attempt to READ_COMMAND without prior "
|
|
"WRITE_COMMAND: no data returned\n");
|
|
}
|
|
|
|
/* Construct the final response with the status, skipping the fields we've
|
/* Construct the final response with the status, skipping the fields we've
|
just (possibly) written. */
|
just (possibly) written. */
|
return construct_response (jreg, status, crc_out, 52, 37);
|
return construct_response (jreg, status, crc_out, 52, 37);
|
|
|
Line 1203... |
Line 1243... |
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
static int
|
static int
|
write_command (unsigned char *jreg)
|
write_command (unsigned char *jreg)
|
{
|
{
|
/* Break out the fields */
|
/* Break out the fields */
|
uint8_t acc_type = reverse_bits (((jreg[0] & 0x0e) >> 5) |
|
uint8_t acc_type = reverse_bits (((jreg[0] & 0xe0) >> 5) |
|
(jreg[1] & 0x01), 4);
|
((jreg[1] & 0x01) << 3) , 4);
|
uint32_t addr = reverse_bits (((uint32_t) (jreg[ 1] & 0xfe) >> 1) |
|
uint32_t addr = reverse_bits (((uint32_t) (jreg[ 1] & 0xfe) >> 1) |
|
((uint32_t) jreg[ 2] << 7) |
|
((uint32_t) jreg[ 2] << 7) |
|
((uint32_t) jreg[ 3] << 15) |
|
((uint32_t) jreg[ 3] << 15) |
|
((uint32_t) jreg[ 4] << 23) |
|
((uint32_t) jreg[ 4] << 23) |
|
((uint32_t) (jreg[ 5] & 0x01) << 31), 32);
|
((uint32_t) (jreg[ 5] & 0x01) << 31), 32);
|
Line 1540... |
Line 1580... |
case JI_BYPASS:
|
case JI_BYPASS:
|
fprintf (stderr, "Warning: JTAG BYPASS shifted\n");
|
fprintf (stderr, "Warning: JTAG BYPASS shifted\n");
|
break;
|
break;
|
|
|
default:
|
default:
|
fprintf (stderr, "Warning: Unknown JTAG instruction %04x shifted\n",
|
fprintf (stderr, "Warning: Unknown JTAG instruction 0x%1x shifted\n",
|
runtime.debug.instr);
|
runtime.debug.instr);
|
break;
|
break;
|
}
|
}
|
|
|
return 4; /* Register length */
|
return 4; /* Register length */
|