X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=b61280cc0ce2bb349a1d23f3bb041b4aba62516c;hp=f87a66a559af4177a12219af6b4cbd21fc9481da;hb=3e90b63b1f54330de7ea3b6454ff5810ac861961;hpb=38f8e5eefac748a30a4bf5e9d7a7313c8ae0e4e9 diff --git a/src/jtag/core.c b/src/jtag/core.c index f87a66a559..b61280cc0c 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -25,7 +25,7 @@ * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -33,6 +33,7 @@ #endif #include "jtag.h" +#include "swd.h" #include "interface.h" #include @@ -113,11 +114,11 @@ static int jtag_ntrst_assert_width; /* width of assertion */ * when an event occurs. */ struct jtag_event_callback { - /* / a event callback */ + /** a event callback */ jtag_event_handler_t callback; - /* / the private data to pass to the callback */ + /** the private data to pass to the callback */ void *priv; - /* / the next callback */ + /** the next callback */ struct jtag_event_callback *next; }; @@ -206,7 +207,7 @@ unsigned jtag_tap_count_enabled(void) return n; } -/* / Append a new TAP to the chain of all taps. */ +/** Append a new TAP to the chain of all taps. */ void jtag_tap_add(struct jtag_tap *t) { t->abs_chain_position = jtag_num_taps++; @@ -606,6 +607,46 @@ void jtag_add_clocks(int num_cycles) } } +void swd_add_reset(int req_srst) +{ + if (req_srst) { + if (!(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("BUG: can't assert SRST"); + jtag_set_error(ERROR_FAIL); + return; + } + req_srst = 1; + } + + /* Maybe change SRST signal state */ + if (jtag_srst != req_srst) { + int retval; + + retval = interface_jtag_add_reset(0, req_srst); + if (retval != ERROR_OK) + jtag_set_error(retval); + else + retval = jtag_execute_queue(); + + if (retval != ERROR_OK) { + LOG_ERROR("TRST/SRST error"); + return; + } + + /* SRST resets everything hooked up to that signal */ + jtag_srst = req_srst; + if (jtag_srst) { + LOG_DEBUG("SRST line asserted"); + if (adapter_nsrst_assert_width) + jtag_add_sleep(adapter_nsrst_assert_width * 1000); + } else { + LOG_DEBUG("SRST line released"); + if (adapter_nsrst_delay) + jtag_add_sleep(adapter_nsrst_delay * 1000); + } + } +} + void jtag_add_reset(int req_tlr_or_trst, int req_srst) { int trst_with_tlr = 0; @@ -716,7 +757,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) void jtag_add_sleep(uint32_t us) { - /* / @todo Here, keep_alive() appears to be a layering violation!!! */ + /** @todo Here, keep_alive() appears to be a layering violation!!! */ keep_alive(); jtag_set_error(interface_jtag_add_sleep(us)); } @@ -853,7 +894,7 @@ void jtag_sleep(uint32_t us) /* A reserved manufacturer ID is used in END_OF_CHAIN_FLAG, so we * know that no valid TAP will have it as an IDCODE value. */ -#define END_OF_CHAIN_FLAG 0x000000ff +#define END_OF_CHAIN_FLAG 0xffffffff /* a larger IR length than we ever expect to autoprobe */ #define JTAG_IRLEN_MAX 60 @@ -921,10 +962,10 @@ static bool jtag_idcode_is_final(uint32_t idcode) { /* * Some devices, such as AVR8, will output all 1's instead - * of TDI input value at end of chain. Allow those values + * of TDI input value at end of chain. Allow those values * instead of failing. */ - return idcode == END_OF_CHAIN_FLAG || idcode == 0xFFFFFFFF; + return idcode == END_OF_CHAIN_FLAG; } /** @@ -958,8 +999,8 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap) if (0 == tap->expected_ids_cnt && !idcode) return true; - /* optionally ignore the JTAG version field */ - uint32_t mask = tap->ignore_version ? ~(0xff << 24) : ~0; + /* optionally ignore the JTAG version field - bits 28-31 of IDCODE */ + uint32_t mask = tap->ignore_version ? ~(0xf << 28) : ~0; idcode &= mask; @@ -1136,7 +1177,7 @@ static int jtag_validate_ircapture(void) int total_ir_length = 0; uint8_t *ir_test = NULL; struct scan_field field; - int val; + uint64_t val; int chain_pos = 0; int retval; @@ -1195,8 +1236,8 @@ static int jtag_validate_ircapture(void) */ if (tap->ir_length == 0) { tap->ir_length = 2; - while ((val = buf_get_u32(ir_test, chain_pos, tap->ir_length + 1)) == 1 - && tap->ir_length <= 32) { + while ((val = buf_get_u64(ir_test, chain_pos, tap->ir_length + 1)) == 1 + && tap->ir_length <= 64) { tap->ir_length++; } LOG_WARNING("AUTO %s - use \"... -irlen %d\"", @@ -1210,25 +1251,23 @@ static int jtag_validate_ircapture(void) * this part of the JTAG spec, so their capture mask/value * attributes might disable this test. */ - val = buf_get_u32(ir_test, chain_pos, tap->ir_length); + 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*x not 0x%0*x", + LOG_ERROR("%s: IR capture error; saw 0x%0*" PRIx64 " not 0x%0*" PRIx32, jtag_tap_name(tap), - (tap->ir_length + 7) / tap->ir_length, - val, - (tap->ir_length + 7) / tap->ir_length, - (unsigned) tap->ir_capture_value); + (tap->ir_length + 7) / tap->ir_length, val, + (tap->ir_length + 7) / tap->ir_length, tap->ir_capture_value); retval = ERROR_JTAG_INIT_FAILED; goto done; } - LOG_DEBUG("%s: IR capture 0x%0*x", jtag_tap_name(tap), + LOG_DEBUG("%s: IR capture 0x%0*" PRIx64, jtag_tap_name(tap), (tap->ir_length + 7) / tap->ir_length, val); chain_pos += tap->ir_length; } /* verify the '11' sentinel we wrote is returned at the end */ - val = buf_get_u32(ir_test, chain_pos, 2); + val = buf_get_u64(ir_test, chain_pos, 2); if (val != 0x3) { char *cbuf = buf_to_str(ir_test, total_ir_length, 16); @@ -1260,7 +1299,7 @@ void jtag_tap_init(struct jtag_tap *tap) tap->expected_mask = calloc(1, ir_len_bytes); tap->cur_instr = malloc(ir_len_bytes); - /* / @todo cope better with ir_length bigger than 32 bits */ + /** @todo cope better with ir_length bigger than 32 bits */ if (ir_len_bits > 32) ir_len_bits = 32; @@ -1273,20 +1312,20 @@ void jtag_tap_init(struct jtag_tap *tap) /* register the reset callback for the TAP */ jtag_register_event_callback(&jtag_reset_callback, tap); + jtag_tap_add(tap); LOG_DEBUG("Created Tap: %s @ abs position %d, " - "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name, - tap->abs_chain_position, tap->ir_length, - (unsigned) tap->ir_capture_value, - (unsigned) tap->ir_capture_mask); - jtag_tap_add(tap); + "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name, + tap->abs_chain_position, tap->ir_length, + (unsigned) tap->ir_capture_value, + (unsigned) tap->ir_capture_mask); } void jtag_tap_free(struct jtag_tap *tap) { jtag_unregister_event_callback(&jtag_reset_callback, tap); - /* / @todo is anything missing? no memory leaks please */ + /** @todo is anything missing? no memory leaks please */ free((void *)tap->expected); free((void *)tap->expected_ids); free((void *)tap->chip); @@ -1330,6 +1369,11 @@ int adapter_init(struct command_context *cmd_ctx) return retval; } + if (jtag->speed == NULL) { + LOG_INFO("This adapter doesn't support configurable speed"); + return ERROR_OK; + } + 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."); @@ -1455,6 +1499,20 @@ int adapter_quit(void) return ERROR_OK; } +int swd_init_reset(struct command_context *cmd_ctx) +{ + int retval = adapter_init(cmd_ctx); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("Initializing with hard SRST reset"); + + if (jtag_reset_config & RESET_HAS_SRST) + swd_add_reset(1); + swd_add_reset(0); + retval = jtag_execute_queue(); + return retval; +} int jtag_init_reset(struct command_context *cmd_ctx) { @@ -1494,7 +1552,17 @@ int jtag_init_reset(struct command_context *cmd_ctx) if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) jtag_add_reset(0, 1); } - jtag_add_reset(0, 0); + + /* some targets enable us to connect with srst asserted */ + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) + jtag_add_reset(0, 1); + else { + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + jtag_add_reset(0, 0); + } + } else + jtag_add_reset(0, 0); retval = jtag_execute_queue(); if (retval != ERROR_OK) return retval; @@ -1517,6 +1585,14 @@ int jtag_init(struct command_context *cmd_ctx) /* guard against oddball hardware: force resets to be inactive */ jtag_add_reset(0, 0); + + /* some targets enable us to connect with srst asserted */ + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) + jtag_add_reset(0, 1); + else + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + } retval = jtag_execute_queue(); if (retval != ERROR_OK) return retval; @@ -1738,3 +1814,32 @@ bool transport_is_jtag(void) { return get_current_transport() == &jtag_transport; } + +void 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()) + swd_add_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"); +} + +void adapter_deassert_reset(void) +{ + if (transport_is_jtag()) + jtag_add_reset(0, 0); + else if (transport_is_swd()) + swd_add_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"); +}