#include "interface.h"
#include <transport/transport.h>
#include <helper/jep106.h>
+#include "helper/system.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
#include "svf/svf.h"
#include "xsvf/xsvf.h"
+/* ipdbg are utilities to debug IP-cores. It uses JTAG for transport. */
+#include "server/ipdbg.h"
+
/** The number of JTAG queue flushes (for profiling and debugging purposes). */
static int jtag_flush_queue_count;
/* speed to fallback to when RCLK is requested but not supported */
static int rclk_fallback_speed_khz;
static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode;
-static int jtag_speed;
-
-/* FIXME: change name to this variable, it is not anymore JTAG only */
-static struct adapter_driver *jtag;
extern struct adapter_driver *adapter_driver;
+static bool adapter_initialized;
+
+static bool is_adapter_initialized(void)
+{
+ return adapter_initialized;
+}
+
void jtag_set_flush_queue_sleep(int ms)
{
jtag_flush_queue_sleep = ms;
}
/** Append a new TAP to the chain of all taps. */
-void jtag_tap_add(struct jtag_tap *t)
+static void jtag_tap_add(struct jtag_tap *t)
{
unsigned jtag_num_taps = 0;
struct jtag_tap **tap = &__jtag_all_taps;
- while (*tap != NULL) {
+ while (*tap) {
jtag_num_taps++;
tap = &(*tap)->next_tap;
}
struct jtag_tap *t = jtag_all_taps();
while (t) {
- if (0 == strcmp(t->dotted_name, s))
+ if (strcmp(t->dotted_name, s) == 0)
return t;
t = t->next_tap;
}
const char *jtag_tap_name(const struct jtag_tap *tap)
{
- return (tap == NULL) ? "(unknown)" : tap->dotted_name;
+ return (!tap) ? "(unknown)" : tap->dotted_name;
}
{
struct jtag_event_callback **callbacks_p = &jtag_event_callbacks;
- if (callback == NULL)
+ if (!callback)
return ERROR_COMMAND_SYNTAX_ERROR;
if (*callbacks_p) {
{
struct jtag_event_callback **p = &jtag_event_callbacks, *temp;
- if (callback == NULL)
+ if (!callback)
return ERROR_COMMAND_SYNTAX_ERROR;
while (*p) {
void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits,
tap_state_t state)
{
- assert(out_bits != NULL);
+ assert(out_bits);
assert(state != TAP_RESET);
jtag_prelude(state);
jtag_add_scan(active, in_num_fields, in_fields, state);
for (int i = 0; i < in_num_fields; i++) {
- if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value != NULL)) {
- /* this is synchronous for a minidriver */
+ if ((in_fields[i].check_value) && (in_fields[i].in_value)) {
jtag_add_callback4(jtag_check_value_mask_callback,
(jtag_callback_data_t)in_fields[i].in_value,
(jtag_callback_data_t)in_fields[i].check_value,
void jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits,
tap_state_t state)
{
- assert(out_bits != NULL);
+ assert(out_bits);
assert(state != TAP_RESET);
jtag_prelude(state);
/**
* If supported by the underlying adapter, this clocks a raw bit sequence
- * onto TMS for switching betwen JTAG and SWD modes.
+ * onto TMS for switching between JTAG and SWD modes.
*
* DO NOT use this to bypass the integrity checks and logging provided
* by the jtag_add_pathmove() and jtag_add_statemove() calls.
{
int retval;
- if (!(jtag->jtag_ops->supported & DEBUG_CAP_TMS_SEQ))
+ if (!(adapter_driver->jtag_ops->supported & DEBUG_CAP_TMS_SEQ))
return ERROR_JTAG_NOT_IMPLEMENTED;
jtag_checks();
/* Maybe change SRST signal state */
if (jtag_srst != req_srst) {
- retval = jtag->reset(0, req_srst);
+ retval = adapter_driver->reset(0, req_srst);
if (retval != ERROR_OK) {
LOG_ERROR("SRST error");
return ERROR_FAIL;
int new_srst = 0;
int new_trst = 0;
- if (!jtag->reset) {
+ if (!adapter_driver->reset) {
legacy_jtag_add_reset(req_tlr_or_trst, req_srst);
return;
}
/* guarantee jtag queue empty before changing reset status */
jtag_execute_queue();
- retval = jtag->reset(new_trst, new_srst);
+ retval = adapter_driver->reset(new_trst, new_srst);
if (retval != ERROR_OK) {
jtag_set_error(retval);
LOG_ERROR("TRST/SRST error");
void jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *mask)
{
- assert(field->in_value != NULL);
+ assert(field->in_value);
- if (value == NULL) {
+ if (!value) {
/* no checking to do */
return;
}
int default_interface_jtag_execute_queue(void)
{
- if (NULL == jtag) {
+ if (!is_adapter_initialized()) {
LOG_ERROR("No JTAG interface configured yet. "
"Issue 'init' command in startup scripts "
"before communicating with targets.");
* The fix can be applied immediately after next release (v0.11.0 ?)
*/
LOG_ERROR("JTAG API jtag_execute_queue() called on non JTAG interface");
- if (!jtag->jtag_ops || !jtag->jtag_ops->execute_queue)
+ if (!adapter_driver->jtag_ops || !adapter_driver->jtag_ops->execute_queue)
return ERROR_OK;
}
- int result = jtag->jtag_ops->execute_queue();
+ int result = adapter_driver->jtag_ops->execute_queue();
-#if !BUILD_ZY1000
- /* Only build this if we use a regular driver with a command queue.
- * Otherwise jtag_command_queue won't be found at compile/link time. Its
- * definition is in jtag/commands.c, which is only built/linked by
- * jtag/Makefile.am if MINIDRIVER_DUMMY || !MINIDRIVER, but those variables
- * aren't accessible here. */
struct jtag_command *cmd = jtag_command_queue;
while (debug_level >= LOG_LVL_DEBUG_IO && cmd) {
switch (cmd->type) {
}
cmd = cmd->next;
}
-#endif
return result;
}
#define JTAG_MAX_AUTO_TAPS 20
-#define EXTRACT_JEP106_BANK(X) (((X) & 0xf00) >> 8)
-#define EXTRACT_JEP106_ID(X) (((X) & 0xfe) >> 1)
#define EXTRACT_MFG(X) (((X) & 0xffe) >> 1)
#define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)
#define EXTRACT_VER(X) (((X) & 0xf0000000) >> 28)
name, msg,
(unsigned int)idcode,
(unsigned int)EXTRACT_MFG(idcode),
- jep106_manufacturer(EXTRACT_JEP106_BANK(idcode), EXTRACT_JEP106_ID(idcode)),
+ jep106_manufacturer(EXTRACT_MFG(idcode)),
(unsigned int)EXTRACT_PART(idcode),
(unsigned int)EXTRACT_VER(idcode));
}
return true;
/* treat "-expected-id 0" as a "don't-warn" wildcard */
- if (0 == tap->expected_ids[ii])
+ if (tap->expected_ids[ii] == 0)
return true;
}
max_taps++;
uint8_t *idcode_buffer = calloc(4, max_taps);
- if (idcode_buffer == NULL)
+ if (!idcode_buffer)
return ERROR_JTAG_INIT_FAILED;
/* DR scan to collect BYPASS or IDCODE register contents.
uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);
/* No predefined TAP? Auto-probe. */
- if (tap == NULL) {
+ if (!tap) {
/* Is there another TAP? */
if (jtag_idcode_is_final(idcode))
break;
if ((idcode & 1) == 0) {
/* Zero for LSB indicates a device in bypass */
- LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%x)",
+ LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%" PRIx32 ")",
tap->dotted_name, idcode);
tap->hasidcode = false;
tap->idcode = 0;
static int jtag_validate_ircapture(void)
{
struct jtag_tap *tap;
- int total_ir_length = 0;
uint8_t *ir_test = NULL;
struct scan_field field;
- uint64_t val;
int chain_pos = 0;
int retval;
- /* when autoprobing, accomodate huge IR lengths */
- for (tap = NULL, total_ir_length = 0;
- (tap = jtag_tap_next_enabled(tap)) != NULL;
- total_ir_length += tap->ir_length) {
+ /* when autoprobing, accommodate huge IR lengths */
+ int total_ir_length = 0;
+ for (tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {
if (tap->ir_length == 0)
total_ir_length += JTAG_IRLEN_MAX;
+ else
+ total_ir_length += tap->ir_length;
}
/* increase length to add 2 bit sentinel after scan */
total_ir_length += 2;
ir_test = malloc(DIV_ROUND_UP(total_ir_length, 8));
- if (ir_test == NULL)
+ if (!ir_test)
return ERROR_FAIL;
/* after this scan, all TAPs will capture BYPASS instructions */
for (;; ) {
tap = jtag_tap_next_enabled(tap);
- if (tap == NULL)
+ if (!tap)
break;
/* If we're autoprobing, guess IR lengths. They must be at
*/
if (tap->ir_length == 0) {
tap->ir_length = 2;
- while ((val = buf_get_u64(ir_test, chain_pos, tap->ir_length + 1)) == 1
+ while (buf_get_u64(ir_test, chain_pos, tap->ir_length + 1) == 1
&& tap->ir_length < JTAG_IRLEN_MAX) {
tap->ir_length++;
}
* this part of the JTAG spec, so their capture mask/value
* attributes might disable this test.
*/
- val = buf_get_u64(ir_test, chain_pos, tap->ir_length);
+ uint64_t val = buf_get_u64(ir_test, chain_pos, tap->ir_length);
if ((val & tap->ir_capture_mask) != tap->ir_capture_value) {
LOG_ERROR("%s: IR capture error; saw 0x%0*" PRIx64 " not 0x%0*" PRIx32,
jtag_tap_name(tap),
}
/* verify the '11' sentinel we wrote is returned at the end */
- val = buf_get_u64(ir_test, chain_pos, 2);
+ uint64_t val = buf_get_u64(ir_test, chain_pos, 2);
if (val != 0x3) {
char *cbuf = buf_to_hex_str(ir_test, total_ir_length);
unsigned ir_len_bytes;
/* if we're autoprobing, cope with potentially huge ir_length */
- ir_len_bits = tap->ir_length ? : JTAG_IRLEN_MAX;
+ ir_len_bits = tap->ir_length ? tap->ir_length : JTAG_IRLEN_MAX;
ir_len_bytes = DIV_ROUND_UP(ir_len_bits, 8);
tap->expected = calloc(1, ir_len_bytes);
*/
int adapter_init(struct command_context *cmd_ctx)
{
- if (jtag)
+ if (is_adapter_initialized())
return ERROR_OK;
if (!adapter_driver) {
retval = adapter_driver->init();
if (retval != ERROR_OK)
return retval;
- jtag = adapter_driver;
+ adapter_initialized = true;
- if (jtag->speed == NULL) {
+ if (!adapter_driver->speed) {
LOG_INFO("This adapter doesn't support configurable speed");
return ERROR_OK;
}
- if (CLOCK_MODE_UNSELECTED == clock_mode) {
+ if (clock_mode == CLOCK_MODE_UNSELECTED) {
LOG_ERROR("An adapter speed is not selected in the init script."
" Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed.");
return ERROR_JTAG_INIT_FAILED;
retval = jtag_get_speed(&jtag_speed_var);
if (retval != ERROR_OK)
return retval;
- retval = jtag->speed(jtag_speed_var);
+ retval = adapter_driver->speed(jtag_speed_var);
if (retval != ERROR_OK)
return retval;
retval = jtag_get_speed_readable(&actual_khz);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var);
else if (actual_khz) {
/* Adaptive clocking -- JTAG-specific */
- if ((CLOCK_MODE_RCLK == clock_mode)
- || ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz)) {
+ if ((clock_mode == CLOCK_MODE_RCLK)
+ || ((clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) {
LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
, actual_khz);
} else
LOG_DEBUG("Init JTAG chain");
tap = jtag_tap_next_enabled(NULL);
- if (tap == NULL) {
+ if (!tap) {
/* Once JTAG itself is properly set up, and the scan chain
* isn't absurdly large, IDCODE autoprobe should work fine.
*
int adapter_quit(void)
{
- if (jtag && jtag->quit) {
+ if (is_adapter_initialized() && adapter_driver->quit) {
/* close the JTAG interface */
- int result = jtag->quit();
- if (ERROR_OK != result)
+ int result = adapter_driver->quit();
+ if (result != ERROR_OK)
LOG_ERROR("failed: %d", result);
}
{
LOG_DEBUG("convert khz to interface specific speed value");
speed_khz = khz;
- if (!jtag)
+ if (!is_adapter_initialized())
return ERROR_OK;
LOG_DEBUG("have interface set up");
- if (!jtag->khz) {
+ if (!adapter_driver->khz) {
LOG_ERROR("Translation from khz to jtag_speed not implemented");
return ERROR_FAIL;
}
int speed_div1;
- int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
- if (ERROR_OK != retval)
+ int retval = adapter_driver->khz(jtag_get_speed_khz(), &speed_div1);
+ if (retval != ERROR_OK)
return retval;
*speed = speed_div1;
return ERROR_OK;
static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int *speed)
{
int retval = adapter_khz_to_speed(0, speed);
- if ((ERROR_OK != retval) && fallback_speed_khz) {
+ if ((retval != ERROR_OK) && fallback_speed_khz) {
LOG_DEBUG("trying fallback speed...");
retval = adapter_khz_to_speed(fallback_speed_khz, speed);
}
static int jtag_set_speed(int speed)
{
- jtag_speed = speed;
/* this command can be called during CONFIG,
* in which case jtag isn't initialized */
- return jtag ? jtag->speed(speed) : ERROR_OK;
+ return is_adapter_initialized() ? adapter_driver->speed(speed) : ERROR_OK;
}
int jtag_config_khz(unsigned khz)
clock_mode = CLOCK_MODE_KHZ;
int speed = 0;
int retval = adapter_khz_to_speed(khz, &speed);
- return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
+ return (retval != ERROR_OK) ? retval : jtag_set_speed(speed);
}
int jtag_config_rclk(unsigned fallback_speed_khz)
rclk_fallback_speed_khz = fallback_speed_khz;
int speed = 0;
int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed);
- return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
+ return (retval != ERROR_OK) ? retval : jtag_set_speed(speed);
}
int jtag_get_speed(int *speed)
int retval = jtag_get_speed(&jtag_speed_var);
if (retval != ERROR_OK)
return retval;
- if (!jtag)
+ if (!is_adapter_initialized())
return ERROR_OK;
- if (!jtag->speed_div) {
+ if (!adapter_driver->speed_div) {
LOG_ERROR("Translation from jtag_speed to khz not implemented");
return ERROR_FAIL;
}
- return jtag->speed_div(jtag_speed_var, khz);
+ return adapter_driver->speed_div(jtag_speed_var, khz);
}
void jtag_set_verify(bool enable)
int jtag_power_dropout(int *dropout)
{
- if (jtag == NULL) {
+ if (!is_adapter_initialized()) {
/* TODO: as the jtag interface is not valid all
* we can do at the moment is exit OpenOCD */
LOG_ERROR("No Valid JTAG Interface Configured.");
exit(-1);
}
- if (jtag->power_dropout)
- return jtag->power_dropout(dropout);
+ if (adapter_driver->power_dropout)
+ return adapter_driver->power_dropout(dropout);
*dropout = 0; /* by default we can't detect power dropout */
return ERROR_OK;
int jtag_srst_asserted(int *srst_asserted)
{
- if (jtag->srst_asserted)
- return jtag->srst_asserted(srst_asserted);
+ if (adapter_driver->srst_asserted)
+ return adapter_driver->srst_asserted(srst_asserted);
*srst_asserted = 0; /* by default we can't detect srst asserted */
return ERROR_OK;
if (retval != ERROR_OK)
return retval;
- return xsvf_register_commands(ctx);
+ retval = xsvf_register_commands(ctx);
+
+ if (retval != ERROR_OK)
+ return retval;
+
+ return ipdbg_register_commands(ctx);
}
static struct transport jtag_transport = {
int adapter_resets(int trst, int srst)
{
- if (get_current_transport() == NULL) {
+ if (!get_current_transport()) {
LOG_ERROR("transport is not selected");
return ERROR_FAIL;
}
transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() ||
transport_is_swim())
return adapter_system_reset(1);
- else if (get_current_transport() != NULL)
+ else if (get_current_transport())
LOG_ERROR("reset is not supported on %s",
get_current_transport()->name);
else
transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() ||
transport_is_swim())
return adapter_system_reset(0);
- else if (get_current_transport() != NULL)
+ else if (get_current_transport())
LOG_ERROR("reset is not supported on %s",
get_current_transport()->name);
else
uint32_t port_size, unsigned int *trace_freq,
unsigned int traceclkin_freq, uint16_t *prescaler)
{
- if (jtag->config_trace) {
- return jtag->config_trace(enabled, pin_protocol, port_size, trace_freq,
+ if (adapter_driver->config_trace) {
+ return adapter_driver->config_trace(enabled, pin_protocol, port_size, trace_freq,
traceclkin_freq, prescaler);
} else if (enabled) {
LOG_ERROR("The selected interface does not support tracing");
int adapter_poll_trace(uint8_t *buf, size_t *size)
{
- if (jtag->poll_trace)
- return jtag->poll_trace(buf, size);
+ if (adapter_driver->poll_trace)
+ return adapter_driver->poll_trace(buf, size);
return ERROR_FAIL;
}