return ERROR_OK;
}
-/**
- * Generate a DR SCAN using the array of output values passed to the function
- *
- * This function assumes that the parameter target_tap specifies the one TAP
- * that is not bypassed. All other TAPs must be bypassed and the function will
- * generate a dummy 1bit field for them.
- *
- * For the target_tap a sequence of output-only fields will be generated where
- * each field has the size num_bits and the field's values are taken from
- * the array value.
- *
- * The bypass status of TAPs is set by jtag_add_ir_scan().
- *
- */
-void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
- int in_num_fields,
- const int *num_bits,
- const uint32_t *value,
- tap_state_t end_state)
-{
- /* count devices in bypass */
-
- size_t bypass_devices = 0;
-
- for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) {
- if (tap->bypass)
- bypass_devices++;
- }
-
-
- struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
- struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));
- struct scan_field *out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field));
-
- jtag_queue_command(cmd);
-
- cmd->type = JTAG_SCAN;
- cmd->cmd.scan = scan;
-
- scan->ir_scan = false;
- scan->num_fields = in_num_fields + bypass_devices;
- scan->fields = out_fields;
- scan->end_state = end_state;
-
-
- bool target_tap_match = false;
-
- struct scan_field *field = out_fields; /* keep track where we insert data */
-
- /* loop over all enabled TAPs */
-
- for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) {
- /* if TAP is not bypassed insert matching input fields */
-
- if (!tap->bypass) {
- assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */
-
- target_tap_match = true;
-
- for (int j = 0; j < in_num_fields; j++) {
- uint8_t out_value[4];
- size_t scan_size = num_bits[j];
- buf_set_u32(out_value, 0, scan_size, value[j]);
-
- field->num_bits = scan_size;
- field->out_value = buf_cpy(out_value, cmd_queue_alloc(DIV_ROUND_UP(scan_size, 8)), scan_size);
- field->in_value = NULL;
-
- field++;
- }
- }
-
- /* if a TAP is bypassed, generated a dummy bit*/
- else {
-
- field->num_bits = 1;
- field->out_value = NULL;
- field->in_value = NULL;
-
- field++;
- }
- }
-
- assert(target_tap_match); /* target_tap should be enabled and not bypassed */
-}
-
static int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits,
uint8_t *in_bits, tap_state_t state, bool ir_scan)
{
jtag_add_callback4(jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);
}
-/* A minidriver can use use an inline versions of this API level fn */
-void jtag_add_dr_out(struct jtag_tap *tap,
- int num_fields, const int *num_bits, const uint32_t *value,
- tap_state_t end_state)
-{
- assert(end_state != TAP_RESET);
- assert(end_state != TAP_INVALID);
-
- cmd_queue_cur_state = end_state;
-
- interface_jtag_add_dr_out(tap,
- num_fields, num_bits, value,
- end_state);
-}
-
void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
{
interface_jtag_add_callback(f, data0);
field->in_value = cmd_queue_alloc(num_bytes);
}
-void interface_jtag_add_dr_out(struct jtag_tap *tap,
- int num_fields, const int *num_bits, const uint32_t *value,
- tap_state_t end_state);
-
void interface_jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0);
void interface_jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
jtag_callback_data_t data1, jtag_callback_data_t data2,
jtag_callback_data_t data3);
-void jtag_add_dr_out(struct jtag_tap *tap,
- int num_fields, const int *num_bits, const uint32_t *value,
- tap_state_t end_state);
-
-
void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
jtag_callback_data_t data1, jtag_callback_data_t data2,
jtag_callback_data_t data3);
#define ERROR_JTAG_TRANSITION_INVALID (-109)
#define ERROR_JTAG_INIT_SOFT_FAIL (-110)
-/**
- * jtag_add_dr_out() is a version of jtag_add_dr_scan() which
- * only scans data out. It operates on 32 bit integers instead
- * of 8 bit, which makes it a better impedance match with
- * the calling code which often operate on 32 bit integers.
- *
- * Current or end_state can not be TAP_RESET. end_state can be TAP_INVALID
- *
- * num_bits[i] is the number of bits to clock out from value[i] LSB first.
- *
- * If the device is in bypass, then that is an error condition in
- * the caller code that is not detected by this fn, whereas
- * jtag_add_dr_scan() does detect it. Similarly if the device is not in
- * bypass, data must be passed to it.
- *
- * If anything fails, then jtag_error will be set and jtag_execute() will
- * return an error. There is no way to determine if there was a failure
- * during this function call.
- *
- * This is an inline fn to speed up embedded hosts. Also note that
- * interface_jtag_add_dr_out() can be a *small* inline function for
- * embedded hosts.
- *
- * There is no jtag_add_dr_outin() version of this fn that also allows
- * clocking data back in. Patches gladly accepted!
- */
-
/**
* Set the current JTAG core execution error, unless one was set
* by a previous call previously. Driver or application code must
* define static inline versions of them):
* - jtag_add_callback
* - jtag_add_callback4
- * - interface_jtag_add_dr_out
*
* The following core functions are declared in this file for use by
* the minidriver and do @b not need to be defined by an implementation:
#include <jtag/jtag_minidriver.h>
-static inline void jtag_add_dr_out(struct jtag_tap *tap,
- int num_fields, const int *num_bits, const uint32_t *value,
- tap_state_t end_state)
-{
- cmd_queue_cur_state = end_state;
-
- interface_jtag_add_dr_out(tap,
- num_fields, num_bits, value,
- end_state);
-}
-
#define jtag_add_callback(callback, in) interface_jtag_add_callback(callback, in)
#define jtag_add_callback4(callback, in, data1, data2, data3) \
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
-static inline void interface_jtag_add_dr_out_core(struct jtag_tap *targettap,
- int num_fields,
- const int *num_bits,
- const uint32_t *value,
- enum tap_state end_state)
-{
- /* synchronously do the operation here */
-}
-
-static inline void interface_jtag_add_dr_out(struct jtag_tap *targettap,
- int num_fields,
- const int *num_bits,
- const uint32_t *value,
- enum tap_state end_state)
-{
- /* synchronously do the operation here */
-}
-
#define interface_jtag_add_callback(callback, in) callback(in)
#define interface_jtag_add_callback4(callback, in, data1, data2, data3) \
#endif
}
-static inline void interface_jtag_add_dr_out_core(struct jtag_tap *target_tap,
- int num_fields,
- const int *num_bits,
- const uint32_t *value,
- enum tap_state end_state)
-{
- enum tap_state pause_state = TAP_DRSHIFT;
-
- struct jtag_tap *tap, *nextTap;
- for (tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = nextTap) {
- nextTap = jtag_tap_next_enabled(tap);
- if (nextTap == NULL)
- pause_state = end_state;
- if (tap == target_tap) {
- int j;
- for (j = 0; j < (num_fields-1); j++)
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[j], value[j]);
- shiftValueInner(TAP_DRSHIFT, pause_state, num_bits[j], value[j]);
- } else {
- /* program the scan field to 1 bit length, and ignore it's value */
- shiftValueInner(TAP_DRSHIFT, pause_state, 1, 0);
- }
- }
-}
-
-static inline void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
- int num_fields,
- const int *num_bits,
- const uint32_t *value,
- enum tap_state end_state)
-{
-
- int singletap = (jtag_tap_next_enabled(jtag_tap_next_enabled(NULL)) == NULL);
- if ((singletap) && (num_fields == 3)) {
- /* used by embeddedice_write_reg_inner() */
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[0], value[0]);
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[1], value[1]);
- shiftValueInner(TAP_DRSHIFT, end_state, num_bits[2], value[2]);
- } else if ((singletap) && (num_fields == 2)) {
- /* used by arm7 code */
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[0], value[0]);
- shiftValueInner(TAP_DRSHIFT, end_state, num_bits[1], value[1]);
- } else
- interface_jtag_add_dr_out_core(target_tap, num_fields, num_bits, value, end_state);
-}
-
#if BUILD_ZY1000_MASTER
#define interface_jtag_add_callback(callback, in) callback(in)
#define interface_jtag_add_callback4(callback, in, data1, data2, \
*post = post_bits;
}
-#if 0
-static const int embeddedice_num_bits[] = {32, 6};
- uint32_t values[2];
-
- values[0] = value;
- values[1] = (1 << 5) | reg_addr;
-
- jtag_add_dr_out(tap, 2, embeddedice_num_bits, values, TAP_IDLE);
-#endif
-
void embeddedice_write_dcc(struct jtag_tap *tap,
int reg_addr,
const uint8_t *buffer,
uint32_t, const uint32_t *, size_t);
return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count);
} else {
- static const int bits[] = {32, 2};
- uint32_t values[] = {0, 0};
+ static const uint8_t zero;
/* FIX!!!!!! the target_write_memory() API started this nasty problem
* with unaligned uint32_t * pointers... */
while (--count > 0) {
#if 1
/* Danger! This code doesn't update cmd_queue_cur_state, so
- * invoking jtag_add_pathmove() before jtag_add_dr_out() after
+ * invoking jtag_add_pathmove() before jtag_add_dr_scan() after
* this loop would fail!
*/
shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0);
TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT
};
- values[0] = *t++;
- values[0] |= (*t++<<8);
- values[0] |= (*t++<<16);
- values[0] |= (*t++<<24);
+ struct scan_field fields[2] = {
+ { .num_bits = 32, .out_value = t },
+ { .num_bits = 2, .out_value = &zero },
+ };
+ t += 4;
- jtag_add_dr_out(tap,
+ jtag_add_dr_scan(tap,
2,
- bits,
- values,
+ fields,
TAP_IDLE);
jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay),
#endif
}
- values[0] = *t++;
- values[0] |= (*t++<<8);
- values[0] |= (*t++<<16);
- values[0] |= (*t++<<24);
+ struct scan_field fields[2] = {
+ { .num_bits = 32, .out_value = t },
+ { .num_bits = 2, .out_value = &zero },
+ };
/* This will happen on the last iteration updating cmd_queue_cur_state
* so we don't have to track it during the common code path
*/
- jtag_add_dr_out(tap,
+ jtag_add_dr_scan(tap,
2,
- bits,
- values,
+ fields,
TAP_IDLE);
return jtag_execute_queue();
static inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint)
{
- uint32_t values[2] = {breakpoint, flip_u32(out, 32)};
+ uint8_t bp = breakpoint ? 1 : 0;
+ uint8_t out_value[4];
+ buf_set_u32(out_value, 0, 32, flip_u32(out, 32));
- jtag_add_dr_out(jtag_info->tap,
+ struct scan_field fields[2] = {
+ { .num_bits = arm7tdmi_num_bits[0], .out_value = &bp },
+ { .num_bits = arm7tdmi_num_bits[1], .out_value = out_value },
+ };
+
+ jtag_add_dr_scan(jtag_info->tap,
2,
- arm7tdmi_num_bits,
- values,
+ fields,
TAP_DRPAUSE);
jtag_add_runtest(0, TAP_DRPAUSE);
int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state)
{
int retval = ERROR_OK;
- uint32_t values[1];
- int num_bits[1];
- values[0] = new_scan_chain;
- num_bits[0] = jtag_info->scann_size;
+ uint8_t out_value[4];
+ buf_set_u32(out_value, 0, jtag_info->scann_size, new_scan_chain);
+ struct scan_field field = { .num_bits = jtag_info->scann_size, .out_value = out_value, };
retval = arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL, end_state);
if (retval != ERROR_OK)
return retval;
- jtag_add_dr_out(jtag_info->tap,
+ jtag_add_dr_scan(jtag_info->tap,
1,
- num_bits,
- values,
+ &field,
end_state);
jtag_info->cur_scan_chain = new_scan_chain;
*/
static inline void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_addr, uint32_t value)
{
- static const int embeddedice_num_bits[] = {32, 6};
- uint32_t values[2];
+ uint8_t out_reg_addr = (1 << 5) | reg_addr;
+ uint8_t out_value[4];
+ buf_set_u32(out_value, 0, 32, value);
- values[0] = value;
- values[1] = (1 << 5) | reg_addr;
+ struct scan_field fields[2] = {
+ { .num_bits = 32, .out_value = out_value },
+ { .num_bits = 6, .out_value = &out_reg_addr },
+ };
- jtag_add_dr_out(tap, 2, embeddedice_num_bits, values, TAP_IDLE);
+ jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
}
void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer,
static int xscale_send(struct target *target, const uint8_t *buffer, int count, int size)
{
struct xscale_common *xscale = target_to_xscale(target);
- uint32_t t[3];
- int bits[3];
int retval;
int done_count = 0;
XSCALE_DBGRX << xscale->xscale_variant,
TAP_IDLE);
- bits[0] = 3;
- t[0] = 0;
- bits[1] = 32;
- t[2] = 1;
- bits[2] = 1;
+ static const uint8_t t0;
+ uint8_t t1[4];
+ static const uint8_t t2 = 1;
+ struct scan_field fields[3] = {
+ { .num_bits = 3, .out_value = &t0 },
+ { .num_bits = 32, .out_value = t1 },
+ { .num_bits = 1, .out_value = &t2 },
+ };
+
int endianness = target->endianness;
while (done_count++ < count) {
+ uint32_t t;
+
switch (size) {
case 4:
if (endianness == TARGET_LITTLE_ENDIAN)
- t[1] = le_to_h_u32(buffer);
+ t = le_to_h_u32(buffer);
else
- t[1] = be_to_h_u32(buffer);
+ t = be_to_h_u32(buffer);
break;
case 2:
if (endianness == TARGET_LITTLE_ENDIAN)
- t[1] = le_to_h_u16(buffer);
+ t = le_to_h_u16(buffer);
else
- t[1] = be_to_h_u16(buffer);
+ t = be_to_h_u16(buffer);
break;
case 1:
- t[1] = buffer[0];
+ t = buffer[0];
break;
default:
LOG_ERROR("BUG: size neither 4, 2 nor 1");
return ERROR_COMMAND_SYNTAX_ERROR;
}
- jtag_add_dr_out(target->tap,
+
+ buf_set_u32(t1, 0, 32, t);
+
+ jtag_add_dr_scan(target->tap,
3,
- bits,
- t,
+ fields,
TAP_IDLE);
buffer += size;
}