X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=a498a8cf48f25e0334824e526e569ad9cd8e6264;hb=2dc88e1479f29ef0141b05bfcd907ad9a3e2d54c;hp=cb3e9265cc4e123fc1a27ad9b279da0275ffbf0a;hpb=6819468a78ce9f0835a9063d93bc839f3d55eb84;p=fw%2Fopenocd diff --git a/src/jtag/core.c b/src/jtag/core.c index cb3e9265c..a498a8cf4 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -23,9 +23,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -36,6 +34,7 @@ #include "swd.h" #include "interface.h" #include +#include #ifdef HAVE_STRINGS_H #include @@ -649,6 +648,12 @@ void swd_add_reset(int req_srst) if (adapter_nsrst_delay) jtag_add_sleep(adapter_nsrst_delay * 1000); } + + retval = jtag_execute_queue(); + if (retval != ERROR_OK) { + LOG_ERROR("SRST timings error"); + return; + } } } @@ -831,7 +836,75 @@ int default_interface_jtag_execute_queue(void) return ERROR_FAIL; } - return jtag->execute_queue(); + int result = jtag->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) { + switch (cmd->type) { + case JTAG_SCAN: + LOG_DEBUG_IO("JTAG %s SCAN to %s", + cmd->cmd.scan->ir_scan ? "IR" : "DR", + tap_state_name(cmd->cmd.scan->end_state)); + 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); + 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); + LOG_DEBUG_IO(" %db in: %s", field->num_bits, str); + free(str); + } + } + break; + case JTAG_TLR_RESET: + LOG_DEBUG_IO("JTAG TLR RESET to %s", + tap_state_name(cmd->cmd.statemove->end_state)); + break; + case JTAG_RUNTEST: + LOG_DEBUG_IO("JTAG RUNTEST %d cycles to %s", + cmd->cmd.runtest->num_cycles, + tap_state_name(cmd->cmd.runtest->end_state)); + break; + case JTAG_RESET: + { + const char *reset_str[3] = { + "leave", "deassert", "assert" + }; + LOG_DEBUG_IO("JTAG RESET %s TRST, %s SRST", + reset_str[cmd->cmd.reset->trst + 1], + reset_str[cmd->cmd.reset->srst + 1]); + } + break; + case JTAG_PATHMOVE: + LOG_DEBUG_IO("JTAG PATHMOVE (TODO)"); + break; + case JTAG_SLEEP: + LOG_DEBUG_IO("JTAG SLEEP (TODO)"); + break; + case JTAG_STABLECLOCKS: + LOG_DEBUG_IO("JTAG STABLECLOCKS (TODO)"); + break; + case JTAG_TMS: + LOG_DEBUG_IO("JTAG TMS (TODO)"); + break; + default: + LOG_ERROR("Unknown JTAG command: %d", cmd->type); + break; + } + cmd = cmd->next; + } +#endif + + return result; } void jtag_execute_queue_noclear(void) @@ -888,6 +961,8 @@ void jtag_sleep(uint32_t us) #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) @@ -951,10 +1026,11 @@ static void jtag_examine_chain_display(enum log_levels level, const char *msg, { log_printf_lf(level, __FILE__, __LINE__, __func__, "JTAG tap: %s %16.16s: 0x%08x " - "(mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)", + "(mfg: 0x%3.3x (%s), part: 0x%4.4x, ver: 0x%1.1x)", name, msg, (unsigned int)idcode, (unsigned int)EXTRACT_MFG(idcode), + jep106_manufacturer(EXTRACT_JEP106_BANK(idcode), EXTRACT_JEP106_ID(idcode)), (unsigned int)EXTRACT_PART(idcode), (unsigned int)EXTRACT_VER(idcode)); } @@ -999,7 +1075,7 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap) return true; /* optionally ignore the JTAG version field - bits 28-31 of IDCODE */ - uint32_t mask = tap->ignore_version ? ~(0xf << 28) : ~0; + uint32_t mask = tap->ignore_version ? ~(0xfU << 28) : ~0U; uint32_t idcode = tap->idcode & mask; /* Loop over the expected identification codes and test for a match */ @@ -1099,7 +1175,8 @@ static int jtag_examine_chain(void) if ((idcode & 1) == 0) { /* Zero for LSB indicates a device in bypass */ - LOG_INFO("TAP %s does not have IDCODE", tap->dotted_name); + LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%x)", + tap->dotted_name, idcode); tap->hasidcode = false; tap->idcode = 0; @@ -1300,6 +1377,14 @@ void jtag_tap_free(struct jtag_tap *tap) { jtag_unregister_event_callback(&jtag_reset_callback, tap); + struct jtag_tap_event_action *jteap = tap->event_action; + while (jteap) { + struct jtag_tap_event_action *next = jteap->next; + Jim_DecrRefCount(jteap->interp, jteap->body); + free(jteap); + jteap = next; + } + free(tap->expected); free(tap->expected_mask); free(tap->expected_ids); @@ -1332,19 +1417,6 @@ int adapter_init(struct command_context *cmd_ctx) return retval; jtag = jtag_interface; - /* LEGACY SUPPORT ... adapter drivers must declare what - * transports they allow. Until they all do so, assume - * the legacy drivers are JTAG-only - */ - if (!transports_are_declared()) { - LOG_ERROR("Adapter driver '%s' did not declare " - "which transports it allows; assuming " - "JTAG-only", jtag->name); - retval = allow_transports(cmd_ctx, jtag_only); - if (retval != ERROR_OK) - return retval; - } - if (jtag->speed == NULL) { LOG_INFO("This adapter doesn't support configurable speed"); return ERROR_OK; @@ -1464,13 +1536,19 @@ int jtag_init_inner(struct command_context *cmd_ctx) int adapter_quit(void) { - if (!jtag || !jtag->quit) - return ERROR_OK; + if (jtag && jtag->quit) { + /* close the JTAG interface */ + int result = jtag->quit(); + if (ERROR_OK != result) + LOG_ERROR("failed: %d", result); + } - /* close the JTAG interface */ - int result = jtag->quit(); - if (ERROR_OK != result) - LOG_ERROR("failed: %d", result); + struct jtag_tap *t = jtag_all_taps(); + while (t) { + struct jtag_tap *n = t->next_tap; + jtag_tap_free(t); + t = n; + } return ERROR_OK; } @@ -1589,14 +1667,18 @@ static int adapter_khz_to_speed(unsigned khz, int *speed) { LOG_DEBUG("convert khz to interface specific speed value"); speed_khz = khz; - if (jtag != NULL) { - LOG_DEBUG("have interface set up"); - int speed_div1; - int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1); - if (ERROR_OK != retval) - return retval; - *speed = speed_div1; + if (!jtag) + return ERROR_OK; + LOG_DEBUG("have interface set up"); + if (!jtag->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) + return retval; + *speed = speed_div1; return ERROR_OK; } @@ -1659,7 +1741,13 @@ int jtag_get_speed_readable(int *khz) int retval = jtag_get_speed(&jtag_speed_var); if (retval != ERROR_OK) return retval; - return jtag ? jtag->speed_div(jtag_speed_var, khz) : ERROR_OK; + if (!jtag) + return ERROR_OK; + if (!jtag->speed_div) { + LOG_ERROR("Translation from jtag_speed to khz not implemented"); + return ERROR_FAIL; + } + return jtag->speed_div(jtag_speed_var, khz); } void jtag_set_verify(bool enable) @@ -1690,12 +1778,20 @@ int jtag_power_dropout(int *dropout) LOG_ERROR("No Valid JTAG Interface Configured."); exit(-1); } - return jtag->power_dropout(dropout); + if (jtag->power_dropout) + return jtag->power_dropout(dropout); + + *dropout = 0; /* by default we can't detect power dropout */ + return ERROR_OK; } int jtag_srst_asserted(int *srst_asserted) { - return jtag->srst_asserted(srst_asserted); + if (jtag->srst_asserted) + return jtag->srst_asserted(srst_asserted); + + *srst_asserted = 0; /* by default we can't detect srst asserted */ + return ERROR_OK; } enum reset_types jtag_get_reset_config(void) @@ -1709,11 +1805,11 @@ void jtag_set_reset_config(enum reset_types type) int jtag_get_trst(void) { - return jtag_trst; + return jtag_trst == 1; } int jtag_get_srst(void) { - return jtag_srst; + return jtag_srst == 1; } void jtag_set_nsrst_delay(unsigned delay) @@ -1801,8 +1897,6 @@ void adapter_assert_reset(void) jtag_add_reset(0, 1); } else if (transport_is_swd()) swd_add_reset(1); - else if (transport_is_cmsis_dap()) - swd_add_reset(1); /* FIXME */ else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); @@ -1816,8 +1910,6 @@ void adapter_deassert_reset(void) jtag_add_reset(0, 0); else if (transport_is_swd()) swd_add_reset(0); - else if (transport_is_cmsis_dap()) - swd_add_reset(0); /* FIXME */ else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); @@ -1825,13 +1917,14 @@ void adapter_deassert_reset(void) LOG_ERROR("transport is not selected"); } -int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) +int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, + 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); - else if (enabled) { + if (jtag->config_trace) { + return jtag->config_trace(enabled, pin_protocol, port_size, trace_freq, + traceclkin_freq, prescaler); + } else if (enabled) { LOG_ERROR("The selected interface does not support tracing"); return ERROR_FAIL; }