From 4411c2643e41d023a1909b1040361912422be6c0 Mon Sep 17 00:00:00 2001 From: oharboe Date: Wed, 26 Mar 2008 13:29:48 +0000 Subject: TAP_SD/SI are now forbidden end states. jtag_add_reset() now returns void streamlining the API git-svn-id: svn://svn.berlios.de/openocd/trunk@525 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/jtag/bitbang.c | 86 +++++++++++++++++----------------------------- src/jtag/jtag.c | 31 ++++++++--------- src/jtag/jtag.h | 21 ++++++----- src/target/arm7_9_common.c | 54 ++++++++--------------------- src/target/cortex_m3.c | 51 +++++++-------------------- 5 files changed, 85 insertions(+), 158 deletions(-) (limited to 'src') diff --git a/src/jtag/bitbang.c b/src/jtag/bitbang.c index 054faf5..a4e415c 100644 --- a/src/jtag/bitbang.c +++ b/src/jtag/bitbang.c @@ -75,7 +75,7 @@ void bitbang_path_move(pathmove_command_t *cmd) { int num_states = cmd->num_states; int state_count; - int tms; + int tms = 0; state_count = 0; while (num_states) @@ -138,7 +138,6 @@ void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) { enum tap_state saved_end_state = end_state; int bit_cnt; - int last_bit, last_bit_in; if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI)))) { @@ -151,7 +150,7 @@ void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) bitbang_end_state(saved_end_state); } - for (bit_cnt = 0; bit_cnt < scan_size - 1; bit_cnt++) + for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) { /* if we're just reading the scan, but don't care about the output * default to outputting 'low', this also makes valgrind traces more readable, @@ -159,69 +158,48 @@ void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) */ if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1)) { - bitbang_interface->write(0, 0, 1); - bitbang_interface->write(1, 0, 1); + bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1); + bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1); } else { - bitbang_interface->write(0, 0, 0); - bitbang_interface->write(1, 0, 0); + bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 0); + bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 0); } if (type != SCAN_OUT) { + /* + TDO should be sampled on the rising edge, and will change + on the falling edge. + + Because there is no way to read the signal exactly at the rising edge, + read after the rising edge. + + This is plain IEEE 1149 JTAG - nothing specific to the OpenOCD or its JTAG + API. + */ if (bitbang_interface->read()) buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8); else buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8)); } } - - if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1)) - last_bit = 1; - else - last_bit = 0; - - if ((ir_scan && (end_state == TAP_SI)) || - (!ir_scan && (end_state == TAP_SD))) - { - bitbang_interface->write(0, 0, last_bit); - bitbang_interface->write(1, 0, last_bit); - - if (type != SCAN_OUT) - last_bit_in = bitbang_interface->read(); - - bitbang_interface->write(0, 0, last_bit); - } + + /* TAP_SD & TAP_SI are illegal end states, so we always transition to the pause + * state which is a legal stable state from which statemove will work. + * + * Exit1 -> Pause + */ + bitbang_interface->write(0, 0, 0); + bitbang_interface->write(1, 0, 0); + bitbang_interface->write(0, 0, 0); + + if (ir_scan) + cur_state = TAP_PI; else - { - /* Shift-[ID]R -> Exit1-[ID]R */ - bitbang_interface->write(0, 1, last_bit); - bitbang_interface->write(1, 1, last_bit); - - if (type != SCAN_OUT) - last_bit_in = bitbang_interface->read(); - - /* Exit1-[ID]R -> Pause-[ID]R */ - bitbang_interface->write(0, 0, 0); - bitbang_interface->write(1, 0, 0); - - if (cur_state == TAP_SI) - cur_state = TAP_PI; - else - cur_state = TAP_PD; - - if (cur_state != end_state) - bitbang_state_move(); - else - bitbang_interface->write(0, 0, 0); - } - - if (type != SCAN_OUT) - { - if (last_bit_in) - buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8); - else - buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8)); - } + cur_state = TAP_PD; + + if (cur_state != end_state) + bitbang_state_move(); } int bitbang_execute_queue(void) diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 463a172..8f55ea0 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -225,7 +225,7 @@ int jtag_speed_post_reset = 0; void jtag_add_statemove(enum tap_state endstate); void jtag_add_pathmove(int num_states, enum tap_state *path); void jtag_add_runtest(int num_cycles, enum tap_state endstate); -int jtag_add_reset(int trst, int srst); +void jtag_add_reset(int trst, int srst); void jtag_add_end_state(enum tap_state endstate); void jtag_add_sleep(u32 us); int jtag_execute_queue(void); @@ -411,7 +411,7 @@ static void jtag_prelude(enum tap_state state) jtag_prelude1(); if (state != -1) - cmd_queue_end_state = state; + jtag_add_end_state(state); cmd_queue_cur_state = cmd_queue_end_state; } @@ -884,23 +884,18 @@ void jtag_add_runtest(int num_cycles, enum tap_state state) jtag_error=retval; } -int jtag_add_reset(int req_trst, int req_srst) +void jtag_add_reset(int req_trst, int req_srst) { int trst_with_tms = 0; int retval; - if (req_trst == -1) - req_trst = jtag_trst; - - if (req_srst == -1) - req_srst = jtag_srst; - /* Make sure that jtag_reset_config allows the requested reset */ /* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */ if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (req_trst == 0)) { - LOG_WARNING("requested reset would assert trst"); - return ERROR_JTAG_RESET_WOULD_ASSERT_TRST; + LOG_ERROR("BUG: requested reset would assert trst"); + jtag_error=ERROR_FAIL; + return; } /* if TRST pulls SRST, we reset with TAP T-L-R */ @@ -912,8 +907,9 @@ int jtag_add_reset(int req_trst, int req_srst) if (req_srst && !(jtag_reset_config & RESET_HAS_SRST)) { - LOG_WARNING("requested nSRST assertion, but the current configuration doesn't support this"); - return ERROR_JTAG_RESET_CANT_SRST; + LOG_ERROR("BUG: requested nSRST assertion, but the current configuration doesn't support this"); + jtag_error=ERROR_FAIL; + return; } if (req_trst && !(jtag_reset_config & RESET_HAS_TRST)) @@ -929,7 +925,7 @@ int jtag_add_reset(int req_trst, int req_srst) if (retval!=ERROR_OK) { jtag_error=retval; - return retval; + return; } if (jtag_srst) @@ -949,7 +945,7 @@ int jtag_add_reset(int req_trst, int req_srst) jtag_add_end_state(TAP_TLR); jtag_add_statemove(TAP_TLR); jtag_call_event_callbacks(JTAG_TRST_ASSERTED); - return ERROR_OK; + return; } if (jtag_trst) @@ -970,7 +966,6 @@ int jtag_add_reset(int req_trst, int req_srst) if (jtag_ntrst_delay) jtag_add_sleep(jtag_ntrst_delay * 1000); } - return ERROR_OK; } int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst) @@ -994,6 +989,10 @@ int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst) void jtag_add_end_state(enum tap_state state) { cmd_queue_end_state = state; + if ((cmd_queue_end_state == TAP_SD)||(cmd_queue_end_state == TAP_SD)) + { + LOG_ERROR("BUG: TAP_SD/SI can't be end state. Calling code should use a larger scan field"); + } } int MINIDRIVER(interface_jtag_add_sleep)(u32 us) diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index fca7c35..4d482f0 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -245,7 +245,11 @@ extern enum reset_types jtag_reset_config; extern int jtag_init(struct command_context_s *cmd_ctx); extern int jtag_register_commands(struct command_context_s *cmd_ctx); -/* JTAG interface, can be implemented with a software or hardware fifo */ +/* JTAG interface, can be implemented with a software or hardware fifo + * + * TAP_SD and TAP_SI are illegal end states. TAP_SD/SI as end states + * can be emulated by using a larger scan. + */ extern void jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); extern int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); extern void jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); @@ -294,16 +298,13 @@ extern int interface_jtag_add_pathmove(int num_states, enum tap_state *path); */ extern void jtag_add_runtest(int num_cycles, enum tap_state endstate); extern int interface_jtag_add_runtest(int num_cycles, enum tap_state endstate); -/* If it fails and one of the error messages below are returned, nothing is - * added to the queue and jtag_execute() won't return an error code. - * - * ERROR_JTAG_RESET_WOULD_ASSERT_TRST - * ERROR_JTAG_RESET_CANT_SRST +/* Invoking jtag_add_reset() with unsupported combinations is + * not allowed and constitutes a bug in the calling code. * - * All other error codes will result in jtag_execute_queue() returning - * an error. + * trst & srst must be 0 or 1. There is no way to + * read the current reset state. */ -extern int jtag_add_reset(int trst, int srst); +extern void jtag_add_reset(int trst, int srst); extern int interface_jtag_add_reset(int trst, int srst); extern void jtag_add_end_state(enum tap_state endstate); extern int interface_jtag_add_end_state(enum tap_state endstate); @@ -357,8 +358,6 @@ extern int jtag_verify_capture_ir; #define ERROR_JTAG_NOT_IMPLEMENTED (-102) #define ERROR_JTAG_TRST_ASSERTED (-103) #define ERROR_JTAG_QUEUE_FAILED (-104) -#define ERROR_JTAG_RESET_WOULD_ASSERT_TRST (-105) -#define ERROR_JTAG_RESET_CANT_SRST (-106) #define ERROR_JTAG_DEVICE_ERROR (-107) diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 4b393cc..4208f38 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -735,10 +735,14 @@ int arm7_9_poll(target_t *target) int arm7_9_assert_reset(target_t *target) { - int retval; - LOG_DEBUG("target->state: %s", target_state_strings[target->state]); + if (!(jtag_reset_config & RESET_HAS_SRST)) + { + LOG_ERROR("Can't assert SRST"); + return ERROR_FAIL; + } + if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN) { /* if the target wasn't running, there might be working areas allocated */ @@ -746,46 +750,18 @@ int arm7_9_assert_reset(target_t *target) /* assert SRST and TRST */ /* system would get ouf sync if we didn't reset test-logic, too */ - if ((retval = jtag_add_reset(1, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_CANT_SRST) - { - return retval; - } - else - { - LOG_ERROR("unknown error"); - exit(-1); - } - } + jtag_add_reset(1, 1); + jtag_add_sleep(5000); - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - retval = jtag_add_reset(1, 1); - } - } + } - else + + if (jtag_reset_config & RESET_SRST_PULLS_TRST) { - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - retval = jtag_add_reset(1, 1); - } - - if (retval == ERROR_JTAG_RESET_CANT_SRST) - { - return retval; - } - else if (retval != ERROR_OK) - { - LOG_ERROR("unknown error"); - exit(-1); - } - } + jtag_add_reset(1, 1); + } else + { + jtag_add_reset(0, 1); } target->state = TARGET_RESET; diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index aba15e7..aa67474 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -701,13 +701,18 @@ int cortex_m3_step(struct target_s *target, int current, u32 address, int handle int cortex_m3_assert_reset(target_t *target) { - int retval; armv7m_common_t *armv7m = target->arch_info; cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_info; LOG_DEBUG("target->state: %s", target_state_strings[target->state]); + if (!(jtag_reset_config & RESET_HAS_SRST)) + { + LOG_ERROR("Can't assert SRST"); + return ERROR_FAIL; + } + ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 ); if (target->reset_mode == RESET_RUN) @@ -727,46 +732,16 @@ int cortex_m3_assert_reset(target_t *target) { /* assert SRST and TRST */ /* system would get ouf sync if we didn't reset test-logic, too */ - if ((retval = jtag_add_reset(1, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_CANT_SRST) - { - return retval; - } - else - { - LOG_ERROR("unknown error"); - exit(-1); - } - } + jtag_add_reset(1, 1); jtag_add_sleep(5000); - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - retval = jtag_add_reset(1, 1); - } - } } - else + + if (jtag_reset_config & RESET_SRST_PULLS_TRST) { - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - retval = jtag_add_reset(1, 1); - } - - if (retval == ERROR_JTAG_RESET_CANT_SRST) - { - return retval; - } - else if (retval != ERROR_OK) - { - LOG_ERROR("unknown error"); - exit(-1); - } - } + jtag_add_reset(1, 1); + } else + { + jtag_add_reset(0, 1); } target->state = TARGET_RESET; -- cgit v1.1