Commit 4411c264 authored by oharboe's avatar oharboe
Browse files

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
parent 2df3ca97
......@@ -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)
......
......@@ -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)
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment