X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=2166374cc74c732de6c22965ebcf5e6279c0f47d;hb=8e337052b6b808d3b6b3833ef74f9089ab1b9fd1;hp=97caeb18aaaf4e3c6896b431f774c2153bfe23fa;hpb=8850eb8f2c5142346e5a450b13d56130691cd894;p=fw%2Fopenocd diff --git a/src/jtag/core.c b/src/jtag/core.c index 97caeb18a..2166374cc 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -35,8 +35,7 @@ #include "interface.h" #include #include -#include -#include +#include "helper/system.h" #ifdef HAVE_STRINGS_H #include @@ -46,6 +45,9 @@ #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; @@ -128,10 +130,10 @@ static int rclk_fallback_speed_khz; static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; static int jtag_speed; -static struct jtag_interface *jtag; +/* FIXME: change name to this variable, it is not anymore JTAG only */ +static struct adapter_driver *jtag; -/* configuration */ -struct jtag_interface *jtag_interface; +extern struct adapter_driver *adapter_driver; void jtag_set_flush_queue_sleep(int ms) { @@ -211,7 +213,7 @@ unsigned jtag_tap_count_enabled(void) } /** 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; @@ -428,7 +430,6 @@ static void jtag_add_scan_check(struct jtag_tap *active, void (*jtag_add_scan)( 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 */ 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, @@ -489,7 +490,7 @@ void jtag_add_tlr(void) /** * 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. @@ -505,7 +506,7 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state) { int retval; - if (!(jtag->supported & DEBUG_CAP_TMS_SEQ)) + if (!(jtag->jtag_ops->supported & DEBUG_CAP_TMS_SEQ)) return ERROR_JTAG_NOT_IMPLEMENTED; jtag_checks(); @@ -844,6 +845,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) if (trst_with_tlr) { LOG_DEBUG("JTAG reset with TLR instead of TRST"); jtag_add_tlr(); + jtag_execute_queue(); } else if (jtag_trst != new_trst) { jtag_trst = new_trst; @@ -892,8 +894,8 @@ static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, /* 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); @@ -905,7 +907,7 @@ static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, 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); } @@ -939,16 +941,23 @@ int default_interface_jtag_execute_queue(void) return ERROR_FAIL; } - int result = jtag->execute_queue(); + if (!transport_is_jtag()) { + /* + * FIXME: This should not happen! + * There could be old code that queues jtag commands with non jtag interfaces so, for + * the moment simply highlight it by log an error and return on empty execute_queue. + * We should fix it quitting with assert(0) because it is an internal error. + * 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) + return ERROR_OK; + } + + 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", @@ -957,12 +966,12 @@ int default_interface_jtag_execute_queue(void) 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); } @@ -1005,7 +1014,6 @@ int default_interface_jtag_execute_queue(void) } cmd = cmd->next; } -#endif return result; } @@ -1221,7 +1229,7 @@ static int jtag_examine_chain(void) /* Add room for end-of-chain marker. */ max_taps++; - uint8_t *idcode_buffer = malloc(max_taps * 4); + uint8_t *idcode_buffer = calloc(4, max_taps); if (idcode_buffer == NULL) return ERROR_JTAG_INIT_FAILED; @@ -1257,7 +1265,7 @@ static int jtag_examine_chain(void) * REVISIT create a jtag_alloc(chip, tap) routine, and * share it with jim_newtap_cmd(). */ - tap = calloc(1, sizeof *tap); + tap = calloc(1, sizeof(*tap)); if (!tap) { retval = ERROR_FAIL; goto out; @@ -1278,7 +1286,7 @@ 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 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; @@ -1335,7 +1343,7 @@ static int jtag_validate_ircapture(void) int chain_pos = 0; int retval; - /* when autoprobing, accomodate huge IR lengths */ + /* when autoprobing, accommodate huge IR lengths */ for (tap = NULL, total_ir_length = 0; (tap = jtag_tap_next_enabled(tap)) != NULL; total_ir_length += tap->ir_length) { @@ -1394,7 +1402,7 @@ static int jtag_validate_ircapture(void) && 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); } @@ -1424,7 +1432,7 @@ static int jtag_validate_ircapture(void) /* 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); @@ -1507,18 +1515,18 @@ int adapter_init(struct command_context *cmd_ctx) if (jtag) return ERROR_OK; - if (!jtag_interface) { - /* nothing was previously specified by "interface" command */ + if (!adapter_driver) { + /* nothing was previously specified by "adapter driver" command */ LOG_ERROR("Debug Adapter has to be specified, " - "see \"interface\" command"); + "see \"adapter driver\" command"); return ERROR_JTAG_INVALID_INTERFACE; } int retval; - retval = jtag_interface->init(); + retval = adapter_driver->init(); if (retval != ERROR_OK) return retval; - jtag = jtag_interface; + jtag = adapter_driver; if (jtag->speed == NULL) { LOG_INFO("This adapter doesn't support configurable speed"); @@ -1527,7 +1535,7 @@ int adapter_init(struct command_context *cmd_ctx) if (CLOCK_MODE_UNSELECTED == clock_mode) { LOG_ERROR("An adapter speed is not selected in the init script." - " Insert a call to adapter_khz or jtag_rclk to proceed."); + " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed."); return ERROR_JTAG_INIT_FAILED; } @@ -1860,7 +1868,7 @@ void jtag_set_verify(bool enable) jtag_verify = enable; } -bool jtag_will_verify() +bool jtag_will_verify(void) { return jtag_verify; } @@ -1870,7 +1878,7 @@ void jtag_set_verify_capture_ir(bool enable) jtag_verify_capture_ir = enable; } -bool jtag_will_verify_capture_ir() +bool jtag_will_verify_capture_ir(void) { return jtag_verify_capture_ir; } @@ -1970,7 +1978,12 @@ static int jtag_select(struct command_context *ctx) 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 = { @@ -2008,20 +2021,15 @@ int adapter_resets(int trst, int srst) /* adapters without trst signal will eventually use tlr sequence */ jtag_add_reset(trst, srst); + /* + * The jtag queue is still used for reset by some adapter. Flush it! + * FIXME: To be removed when all adapter drivers will be updated! + */ + jtag_execute_queue(); return ERROR_OK; - } else if (transport_is_swd()) { - if (trst == TRST_ASSERT) { - LOG_ERROR("transport swd has no trst signal"); - return ERROR_FAIL; - } - - if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) { - LOG_ERROR("adapter has no srst signal"); - return ERROR_FAIL; - } - adapter_system_reset(srst); - return ERROR_OK; - } else if (transport_is_hla()) { + } else if (transport_is_swd() || transport_is_hla() || + 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); @@ -2032,7 +2040,8 @@ int adapter_resets(int trst, int srst) LOG_ERROR("adapter has no srst signal"); return ERROR_FAIL; } - return hl_interface_reset(srst); + adapter_system_reset(srst); + return ERROR_OK; } if (trst == TRST_DEASSERT && srst == SRST_DEASSERT) @@ -2044,33 +2053,41 @@ int adapter_resets(int trst, int srst) return ERROR_FAIL; } -void adapter_assert_reset(void) +int adapter_assert_reset(void) { if (transport_is_jtag()) { if (jtag_reset_config & RESET_SRST_PULLS_TRST) jtag_add_reset(1, 1); else jtag_add_reset(0, 1); - } else if (transport_is_swd()) - adapter_system_reset(1); + return ERROR_OK; + } else if (transport_is_swd() || transport_is_hla() || + transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() || + transport_is_swim()) + return adapter_system_reset(1); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); else LOG_ERROR("transport is not selected"); + return ERROR_FAIL; } -void adapter_deassert_reset(void) +int adapter_deassert_reset(void) { - if (transport_is_jtag()) + if (transport_is_jtag()) { jtag_add_reset(0, 0); - else if (transport_is_swd()) - adapter_system_reset(0); + return ERROR_OK; + } else if (transport_is_swd() || transport_is_hla() || + transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() || + transport_is_swim()) + return adapter_system_reset(0); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); else LOG_ERROR("transport is not selected"); + return ERROR_FAIL; } int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,