#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;
}
/** 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.
/* NOTE: we've lost diagnostic context here -- 'which tap' */
- captured_str = buf_to_str(captured, bits, 16);
- in_check_value_str = buf_to_str(in_check_value, bits, 16);
+ captured_str = buf_to_hex_str(captured, bits);
+ in_check_value_str = buf_to_hex_str(in_check_value, bits);
LOG_WARNING("Bad value '%s' captured during DR or IR scan:",
captured_str);
if (in_check_mask) {
char *in_check_mask_str;
- in_check_mask_str = buf_to_str(in_check_mask, bits, 16);
+ in_check_mask_str = buf_to_hex_str(in_check_mask, bits);
LOG_WARNING(" check_mask: 0x%s", in_check_mask_str);
free(in_check_mask_str);
}
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 (!jtag) {
LOG_ERROR("No JTAG interface configured yet. "
"Issue 'init' command in startup scripts "
"before communicating with targets.");
int result = jtag->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 && cmd) {
+ while (debug_level >= LOG_LVL_DEBUG_IO && cmd) {
switch (cmd->type) {
case JTAG_SCAN:
LOG_DEBUG_IO("JTAG %s SCAN to %s",
for (int i = 0; i < cmd->cmd.scan->num_fields; i++) {
struct scan_field *field = cmd->cmd.scan->fields + i;
if (field->out_value) {
- char *str = buf_to_str(field->out_value, field->num_bits, 16);
+ char *str = buf_to_hex_str(field->out_value, field->num_bits);
LOG_DEBUG_IO(" %db out: %s", field->num_bits, str);
free(str);
}
if (field->in_value) {
- char *str = buf_to_str(field->in_value, field->num_bits, 16);
+ char *str = buf_to_hex_str(field->in_value, field->num_bits);
LOG_DEBUG_IO(" %db in: %s", field->num_bits, str);
free(str);
}
}
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
&& tap->ir_length < JTAG_IRLEN_MAX) {
tap->ir_length++;
}
- LOG_WARNING("AUTO %s - use \"jtag newtap " "%s %s -irlen %d "
+ LOG_WARNING("AUTO %s - use \"jtag newtap %s %s -irlen %d "
"-expected-id 0x%08" PRIx32 "\"",
tap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode);
}
/* verify the '11' sentinel we wrote is returned at the end */
val = buf_get_u64(ir_test, chain_pos, 2);
if (val != 0x3) {
- char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
+ char *cbuf = buf_to_hex_str(ir_test, total_ir_length);
LOG_ERROR("IR capture error at bit %d, saw 0x%s not 0x...3",
chain_pos, cbuf);
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);
return retval;
jtag = adapter_driver;
- if (jtag->speed == NULL) {
+ if (!jtag->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;
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.
*
if (jtag && jtag->quit) {
/* close the JTAG interface */
int result = jtag->quit();
- if (ERROR_OK != result)
+ if (result != ERROR_OK)
LOG_ERROR("failed: %d", result);
}
}
int speed_div1;
int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
- if (ERROR_OK != retval)
+ 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);
}
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 jtag_power_dropout(int *dropout)
{
- if (jtag == NULL) {
+ if (!jtag) {
/* 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.");
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;
}
jtag_execute_queue();
return ERROR_OK;
} else if (transport_is_swd() || transport_is_hla() ||
- transport_is_dapdirect_swd() || transport_is_dapdirect_jtag()) {
+ transport_is_dapdirect_swd() || transport_is_dapdirect_jtag() ||
+ transport_is_swim()) {
if (trst == TRST_ASSERT) {
LOG_ERROR("transport %s has no trst signal",
get_current_transport()->name);
jtag_add_reset(0, 1);
return ERROR_OK;
} else if (transport_is_swd() || transport_is_hla() ||
- transport_is_dapdirect_jtag() || transport_is_dapdirect_swd())
+ 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
jtag_add_reset(0, 0);
return ERROR_OK;
} else if (transport_is_swd() || transport_is_hla() ||
- transport_is_dapdirect_jtag() || transport_is_dapdirect_swd())
+ 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