/** * usbp5_scan - launches a DR-scan or IR-scan * @cmd: the command to launch * * Launch a JTAG IR-scan or DR-scan * * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured. */ static int usbp5_scan(struct scan_command *cmd) { int scan_bits; uint8_t *buf = NULL; int retval = ERROR_OK; scan_bits = jtag_build_buffer(cmd, &buf); if (cmd->ir_scan) { retval = usbp5_state_move(TAP_IRSHIFT); if (retval != ERROR_OK) return retval; } else { retval = usbp5_state_move(TAP_DRSHIFT); if (retval != ERROR_OK) return retval; } if (cmd->end_state == TAP_DRSHIFT) { retval = usbp5_tdi_seq(buf, buf, scan_bits, NO_TAP_SHIFT); if (retval != ERROR_OK) return retval; } else { retval = usbp5_tdi_seq(buf, buf, scan_bits, TAP_SHIFT); if (retval != ERROR_OK) return retval; } if (cmd->end_state != TAP_DRSHIFT) { /* * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it * forward to a stable IRPAUSE or DRPAUSE. */ retval = usbp5_clock_tms(0); if (retval != ERROR_OK) return retval; if (cmd->ir_scan) tap_set_state(TAP_IRPAUSE); else tap_set_state(TAP_DRPAUSE); } retval = jtag_read_buffer(buf, cmd); if (retval != ERROR_OK) return retval; if (buf) free(buf); if (cmd->end_state != TAP_DRSHIFT) { retval = usbp5_state_move(cmd->end_state); if (retval != ERROR_OK) return retval; } return ERROR_OK; }
static int vsllink_jtag_execute(void) { int i; int result; if (tap_length <= 0) return ERROR_OK; versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer, tdo_buffer, tap_length); result = versaloon_interface.adaptors.peripheral_commit(); if (result == ERROR_OK) { for (i = 0; i < pending_scan_results_length; i++) { struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[i]; uint8_t *buffer = pending_scan_result->buffer; int length = pending_scan_result->length; int src_first = pending_scan_result->src_offset; int dest_first = pending_scan_result->dest_offset; bool last = pending_scan_result->last; struct scan_command *command; command = pending_scan_result->command; buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length); #ifdef _DEBUG_JTAG_IO_ DEBUG_JTAG_IO( "JTAG scan read(%d bits, from src %d bits to dest %d bits):", length, src_first, dest_first); vsllink_debug_buffer(buffer + dest_first / 8, DIV_ROUND_UP(length, 7)); #endif if (last) { if (jtag_read_buffer(buffer, command) != ERROR_OK) { vsllink_tap_init(); return ERROR_JTAG_QUEUE_FAILED; } if (pending_scan_result->buffer != NULL) free(pending_scan_result->buffer); } } } else { LOG_ERROR("vsllink_jtag_execute failure"); return ERROR_JTAG_QUEUE_FAILED; } vsllink_tap_init(); return ERROR_OK; }
/** * jtag_vpi_scan - launches a DR-scan or IR-scan * @cmd: the command to launch * * Launch a JTAG IR-scan or DR-scan * * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured. */ static int jtag_vpi_scan(struct scan_command *cmd) { int scan_bits; uint8_t *buf = NULL; int ret = ERROR_OK; scan_bits = jtag_build_buffer(cmd, &buf); if (cmd->ir_scan) jtag_vpi_state_move(TAP_IRSHIFT); else jtag_vpi_state_move(TAP_DRSHIFT); if(cmd->end_state == TAP_DRSHIFT) jtag_vpi_queue_tdi(buf, scan_bits, NO_TAP_SHIFT); else jtag_vpi_queue_tdi(buf, scan_bits, TAP_SHIFT); if(cmd->end_state != TAP_DRSHIFT) { /* * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it * forward to a stable IRPAUSE or DRPAUSE. */ jtag_vpi_clock_tms(0); if (cmd->ir_scan) tap_set_state(TAP_IRPAUSE); else tap_set_state(TAP_DRPAUSE); } ret = jtag_read_buffer(buf, cmd); if (buf) free(buf); if(cmd->end_state != TAP_DRSHIFT) jtag_vpi_state_move(cmd->end_state); return ret; }
static int dtc_queue_run(void) { struct dtc_reply_queue_entry *rq_p, *rq_next; int retval; int usb_err; int bit_cnt; int x; uint8_t *dtc_p, *tdo_p; uint8_t dtc_mask, tdo_mask; uint8_t reply_buffer[USB_EP2IN_SIZE]; retval = ERROR_OK; if (dtc_queue.cmd_index < 1) return(retval); dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = DTC_CMD_STOP; /* run the cmd */ if (dtc_queue.rq_head == NULL) { usb_err = dtc_run_download(pHDev, dtc_queue.cmd_buffer, dtc_queue.cmd_index, NULL, 0 ); if (usb_err < 0) { LOG_ERROR("dtc_run_download: %s", usb_strerror()); exit(1); } } else { usb_err = dtc_run_download(pHDev, dtc_queue.cmd_buffer, dtc_queue.cmd_index, reply_buffer, dtc_queue.reply_index ); if (usb_err < 0) { LOG_ERROR("dtc_run_download: %s", usb_strerror()); exit(1); } else { /* process the reply, which empties the reply queue and frees its entries */ dtc_p = reply_buffer; /* The rigamarole with the masks and doing it bit-by-bit is due to the fact that the scan buffer is LSb-first and the DTC code is MSb-first for hardware reasons. It was that or craft a function to do the reversal, and that wouldn't work with bit-stuffing (supplying extra bits to use mostly byte operations), or any other scheme which would throw the byte alignment off. */ for ( rq_p = dtc_queue.rq_head; rq_p != NULL; rq_p = rq_next ) { tdo_p = rq_p->scan.buffer + (rq_p->scan.offset / 8); tdo_mask = 1 << (rq_p->scan.offset % 8); bit_cnt = rq_p->scan.length; if (bit_cnt >= 8) { /* bytes */ dtc_mask = 1 << (8 - 1); for ( ; bit_cnt; bit_cnt-- ) { if (*dtc_p & dtc_mask) { *tdo_p |= tdo_mask; } else { *tdo_p &=~ tdo_mask; } dtc_mask >>= 1; if (dtc_mask == 0) { dtc_p++; dtc_mask = 1 << (8 - 1); } tdo_mask <<= 1; if (tdo_mask == 0) { tdo_p++; tdo_mask = 1; } } } else { /* extra bits or last bit */ x = *dtc_p++; if (( rq_p->scan.type == SCAN_IN ) && ( rq_p->scan.offset != rq_p->scan.size - 1 )) { /* extra bits were sent as a full byte with padding on the end */ dtc_mask = 1 << (8 - 1); } else { dtc_mask = 1 << (bit_cnt - 1); } for ( ; bit_cnt; bit_cnt-- ) { if (x & dtc_mask) { *tdo_p |= tdo_mask; } else { *tdo_p &=~ tdo_mask; } dtc_mask >>= 1; tdo_mask <<= 1; if (tdo_mask == 0) { tdo_p++; tdo_mask = 1; } } } if ((rq_p->scan.offset + rq_p->scan.length) >= rq_p->scan.size) { /* feed scan buffer back into openocd and free it */ if (jtag_read_buffer(rq_p->scan.buffer, rq_p->cmd->cmd.scan) != ERROR_OK) { retval = ERROR_JTAG_QUEUE_FAILED; } free(rq_p->scan.buffer); } rq_next = rq_p->next; free(rq_p); } dtc_queue.rq_head = NULL; dtc_queue.rq_tail = NULL; }