Change-Id: I7caf57ca3d9dfbe152504472a6bb26c2a28b92e8 Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk> Reviewed-on: http://openocd.zylin.com/423 Tested-by: jenkinstags/v0.6.0-rc1
@@ -27,6 +27,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -49,8 +50,7 @@ | |||
extern struct jtag_interface *jtag_interface; | |||
const char *jtag_only[] = { "jtag", NULL }; | |||
static int | |||
jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) | |||
{ | |||
Jim_GetOptInfo goi; | |||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); | |||
@@ -67,7 +67,6 @@ jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
return JIM_OK; | |||
} | |||
static int default_khz(int khz, int *jtag_speed) | |||
{ | |||
LOG_ERROR("Translation from khz to jtag_speed not implemented"); | |||
@@ -98,9 +97,8 @@ COMMAND_HANDLER(interface_transport_command) | |||
int retval; | |||
retval = CALL_COMMAND_HANDLER(transport_list_parse, &transports); | |||
if (retval != ERROR_OK) { | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
retval = allow_transports(CMD_CTX, (const char **)transports); | |||
@@ -118,8 +116,7 @@ COMMAND_HANDLER(handle_interface_list_command) | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
command_print(CMD_CTX, "The following debug interfaces are available:"); | |||
for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) | |||
{ | |||
for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) { | |||
const char *name = jtag_interfaces[i]->name; | |||
command_print(CMD_CTX, "%u: %s", i + 1, name); | |||
} | |||
@@ -132,8 +129,7 @@ COMMAND_HANDLER(handle_interface_command) | |||
int retval; | |||
/* check whether the interface is already configured */ | |||
if (jtag_interface) | |||
{ | |||
if (jtag_interface) { | |||
LOG_WARNING("Interface already configured, ignoring"); | |||
return ERROR_OK; | |||
} | |||
@@ -142,13 +138,11 @@ COMMAND_HANDLER(handle_interface_command) | |||
if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0') | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) | |||
{ | |||
for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) { | |||
if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0) | |||
continue; | |||
if (NULL != jtag_interfaces[i]->commands) | |||
{ | |||
if (NULL != jtag_interfaces[i]->commands) { | |||
retval = register_commands(CMD_CTX, NULL, | |||
jtag_interfaces[i]->commands); | |||
if (ERROR_OK != retval) | |||
@@ -325,34 +319,34 @@ next: | |||
/* minimal JTAG has neither SRST nor TRST (so that's the default) */ | |||
switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) { | |||
case RESET_HAS_SRST: | |||
modes[0] = "srst_only"; | |||
break; | |||
case RESET_HAS_TRST: | |||
modes[0] = "trst_only"; | |||
break; | |||
case RESET_TRST_AND_SRST: | |||
modes[0] = "trst_and_srst"; | |||
break; | |||
default: | |||
modes[0] = "none"; | |||
break; | |||
case RESET_HAS_SRST: | |||
modes[0] = "srst_only"; | |||
break; | |||
case RESET_HAS_TRST: | |||
modes[0] = "trst_only"; | |||
break; | |||
case RESET_TRST_AND_SRST: | |||
modes[0] = "trst_and_srst"; | |||
break; | |||
default: | |||
modes[0] = "none"; | |||
break; | |||
} | |||
/* normally SRST and TRST are decoupled; but bugs happen ... */ | |||
switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) { | |||
case RESET_SRST_PULLS_TRST: | |||
modes[1] = "srst_pulls_trst"; | |||
break; | |||
case RESET_TRST_PULLS_SRST: | |||
modes[1] = "trst_pulls_srst"; | |||
break; | |||
case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST: | |||
modes[1] = "combined"; | |||
break; | |||
default: | |||
modes[1] = "separate"; | |||
break; | |||
case RESET_SRST_PULLS_TRST: | |||
modes[1] = "srst_pulls_trst"; | |||
break; | |||
case RESET_TRST_PULLS_SRST: | |||
modes[1] = "trst_pulls_srst"; | |||
break; | |||
case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST: | |||
modes[1] = "combined"; | |||
break; | |||
default: | |||
modes[1] = "separate"; | |||
break; | |||
} | |||
/* TRST-less connectors include Altera, Xilinx, and minimal JTAG */ | |||
@@ -391,8 +385,7 @@ COMMAND_HANDLER(handle_adapter_nsrst_delay_command) | |||
{ | |||
if (CMD_ARGC > 1) | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
if (CMD_ARGC == 1) | |||
{ | |||
if (CMD_ARGC == 1) { | |||
unsigned delay; | |||
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay); | |||
@@ -406,8 +399,7 @@ COMMAND_HANDLER(handle_adapter_nsrst_assert_width_command) | |||
{ | |||
if (CMD_ARGC > 1) | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
if (CMD_ARGC == 1) | |||
{ | |||
if (CMD_ARGC == 1) { | |||
unsigned width; | |||
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], width); | |||
@@ -425,8 +417,7 @@ COMMAND_HANDLER(handle_adapter_khz_command) | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
int retval = ERROR_OK; | |||
if (CMD_ARGC == 1) | |||
{ | |||
if (CMD_ARGC == 1) { | |||
unsigned khz = 0; | |||
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz); | |||
@@ -27,6 +27,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -41,14 +42,14 @@ struct cmd_queue_page { | |||
}; | |||
#define CMD_QUEUE_PAGE_SIZE (1024 * 1024) | |||
static struct cmd_queue_page *cmd_queue_pages = NULL; | |||
static struct cmd_queue_page *cmd_queue_pages; | |||
struct jtag_command *jtag_command_queue = NULL; | |||
struct jtag_command *jtag_command_queue; | |||
static struct jtag_command **next_command_pointer = &jtag_command_queue; | |||
void jtag_queue_command(struct jtag_command * cmd) | |||
void jtag_queue_command(struct jtag_command *cmd) | |||
{ | |||
// this command goes on the end, so ensure the queue terminates | |||
/* this command goes on the end, so ensure the queue terminates */ | |||
cmd->next = NULL; | |||
struct jtag_command **last_cmd = next_command_pointer; | |||
@@ -56,11 +57,11 @@ void jtag_queue_command(struct jtag_command * cmd) | |||
assert(NULL == *last_cmd); | |||
*last_cmd = cmd; | |||
// store location where the next command pointer will be stored | |||
/* store location where the next command pointer will be stored */ | |||
next_command_pointer = &cmd->next; | |||
} | |||
void* cmd_queue_alloc(size_t size) | |||
void *cmd_queue_alloc(size_t size) | |||
{ | |||
struct cmd_queue_page **p_page = &cmd_queue_pages; | |||
int offset; | |||
@@ -95,19 +96,17 @@ void* cmd_queue_alloc(size_t size) | |||
#define ALIGN_SIZE (sizeof(union worse_case_align)) | |||
/* The alignment process. */ | |||
size = (size + ALIGN_SIZE -1) & (~(ALIGN_SIZE-1)); | |||
size = (size + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1)); | |||
/* Done... */ | |||
if (*p_page) | |||
{ | |||
if (*p_page) { | |||
while ((*p_page)->next) | |||
p_page = &((*p_page)->next); | |||
if (CMD_QUEUE_PAGE_SIZE - (*p_page)->used < size) | |||
p_page = &((*p_page)->next); | |||
} | |||
if (!*p_page) | |||
{ | |||
if (!*p_page) { | |||
*p_page = malloc(sizeof(struct cmd_queue_page)); | |||
(*p_page)->used = 0; | |||
(*p_page)->address = malloc(CMD_QUEUE_PAGE_SIZE); | |||
@@ -125,8 +124,7 @@ static void cmd_queue_free(void) | |||
{ | |||
struct cmd_queue_page *page = cmd_queue_pages; | |||
while (page) | |||
{ | |||
while (page) { | |||
struct cmd_queue_page *last = page; | |||
free(page->address); | |||
page = page->next; | |||
@@ -149,8 +147,7 @@ enum scan_type jtag_scan_type(const struct scan_command *cmd) | |||
int i; | |||
int type = 0; | |||
for (i = 0; i < cmd->num_fields; i++) | |||
{ | |||
for (i = 0; i < cmd->num_fields; i++) { | |||
if (cmd->fields[i].in_value) | |||
type |= SCAN_IN; | |||
if (cmd->fields[i].out_value) | |||
@@ -167,9 +164,7 @@ int jtag_scan_size(const struct scan_command *cmd) | |||
/* count bits in scan command */ | |||
for (i = 0; i < cmd->num_fields; i++) | |||
{ | |||
bit_count += cmd->fields[i].num_bits; | |||
} | |||
return bit_count; | |||
} | |||
@@ -180,7 +175,7 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer) | |||
int i; | |||
bit_count = jtag_scan_size(cmd); | |||
*buffer = calloc(1,DIV_ROUND_UP(bit_count, 8)); | |||
*buffer = calloc(1, DIV_ROUND_UP(bit_count, 8)); | |||
bit_count = 0; | |||
@@ -188,10 +183,8 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer) | |||
cmd->ir_scan ? "IRSCAN" : "DRSCAN", | |||
cmd->num_fields); | |||
for (i = 0; i < cmd->num_fields; i++) | |||
{ | |||
if (cmd->fields[i].out_value) | |||
{ | |||
for (i = 0; i < cmd->num_fields; i++) { | |||
if (cmd->fields[i].out_value) { | |||
#ifdef _DEBUG_JTAG_IO_ | |||
char *char_buf = buf_to_str(cmd->fields[i].out_value, | |||
(cmd->fields[i].num_bits > DEBUG_JTAG_IOZ) | |||
@@ -204,9 +197,7 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer) | |||
#endif | |||
buf_set_buf(cmd->fields[i].out_value, 0, *buffer, | |||
bit_count, cmd->fields[i].num_bits); | |||
} | |||
else | |||
{ | |||
} else { | |||
DEBUG_JTAG_IO("fields[%i].out_value[%i]: NULL", | |||
i, cmd->fields[i].num_bits); | |||
} | |||
@@ -214,7 +205,7 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer) | |||
bit_count += cmd->fields[i].num_bits; | |||
} | |||
//DEBUG_JTAG_IO("bit_count totalling: %i", bit_count); | |||
/*DEBUG_JTAG_IO("bit_count totalling: %i", bit_count); */ | |||
return bit_count; | |||
} | |||
@@ -228,15 +219,14 @@ int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd) | |||
/* we return ERROR_OK, unless a check fails, or a handler reports a problem */ | |||
retval = ERROR_OK; | |||
for (i = 0; i < cmd->num_fields; i++) | |||
{ | |||
for (i = 0; i < cmd->num_fields; i++) { | |||
/* if neither in_value nor in_handler | |||
* are specified we don't have to examine this field | |||
*/ | |||
if (cmd->fields[i].in_value) | |||
{ | |||
if (cmd->fields[i].in_value) { | |||
int num_bits = cmd->fields[i].num_bits; | |||
uint8_t *captured = buf_set_buf(buffer, bit_count, malloc(DIV_ROUND_UP(num_bits, 8)), 0, num_bits); | |||
uint8_t *captured = buf_set_buf(buffer, bit_count, | |||
malloc(DIV_ROUND_UP(num_bits, 8)), 0, num_bits); | |||
#ifdef _DEBUG_JTAG_IO_ | |||
char *char_buf = buf_to_str(captured, | |||
@@ -250,9 +240,7 @@ int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd) | |||
#endif | |||
if (cmd->fields[i].in_value) | |||
{ | |||
buf_cpy(captured, cmd->fields[i].in_value, num_bits); | |||
} | |||
free(captured); | |||
} | |||
@@ -261,5 +249,3 @@ int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd) | |||
return retval; | |||
} | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef JTAG_COMMANDS_H | |||
#define JTAG_COMMANDS_H | |||
@@ -32,11 +33,11 @@ | |||
* to the device, or both. | |||
*/ | |||
enum scan_type { | |||
/// From device to host, | |||
/** From device to host, */ | |||
SCAN_IN = 1, | |||
/// From host to device, | |||
/** From host to device, */ | |||
SCAN_OUT = 2, | |||
/// Full-duplex scan. | |||
/** Full-duplex scan. */ | |||
SCAN_IO = 3 | |||
}; | |||
@@ -45,56 +46,56 @@ enum scan_type { | |||
* structures that should be scanned in/out to the device. | |||
*/ | |||
struct scan_command { | |||
/// instruction/not data scan | |||
/** instruction/not data scan */ | |||
bool ir_scan; | |||
/// number of fields in *fields array | |||
/** number of fields in *fields array */ | |||
int num_fields; | |||
/// pointer to an array of data scan fields | |||
struct scan_field* fields; | |||
/// state in which JTAG commands should finish | |||
/** pointer to an array of data scan fields */ | |||
struct scan_field *fields; | |||
/** state in which JTAG commands should finish */ | |||
tap_state_t end_state; | |||
}; | |||
struct statemove_command { | |||
/// state in which JTAG commands should finish | |||
/** state in which JTAG commands should finish */ | |||
tap_state_t end_state; | |||
}; | |||
struct pathmove_command { | |||
/// number of states in *path | |||
/** number of states in *path */ | |||
int num_states; | |||
/// states that have to be passed | |||
tap_state_t* path; | |||
/** states that have to be passed */ | |||
tap_state_t *path; | |||
}; | |||
struct runtest_command { | |||
/// number of cycles to spend in Run-Test/Idle state | |||
/** number of cycles to spend in Run-Test/Idle state */ | |||
int num_cycles; | |||
/// state in which JTAG commands should finish | |||
/** state in which JTAG commands should finish */ | |||
tap_state_t end_state; | |||
}; | |||
struct stableclocks_command { | |||
/// number of clock cycles that should be sent | |||
/** number of clock cycles that should be sent */ | |||
int num_cycles; | |||
}; | |||
struct reset_command { | |||
/// Set TRST output: 0 = deassert, 1 = assert, -1 = no change | |||
/** Set TRST output: 0 = deassert, 1 = assert, -1 = no change */ | |||
int trst; | |||
/// Set SRST output: 0 = deassert, 1 = assert, -1 = no change | |||
/** Set SRST output: 0 = deassert, 1 = assert, -1 = no change */ | |||
int srst; | |||
}; | |||
struct end_state_command { | |||
/// state in which JTAG commands should finish | |||
/** state in which JTAG commands should finish */ | |||
tap_state_t end_state; | |||
}; | |||
struct sleep_command { | |||
/// number of microseconds to sleep | |||
/** number of microseconds to sleep */ | |||
uint32_t us; | |||
}; | |||
@@ -112,9 +113,9 @@ struct sleep_command { | |||
*/ | |||
struct tms_command { | |||
/** How many bits should be clocked out. */ | |||
unsigned num_bits; | |||
/** The bits to clock out; the LSB is bit 0 of bits[0]. */ | |||
const uint8_t *bits; | |||
unsigned num_bits; | |||
/** The bits to clock out; the LSB is bit 0 of bits[0]. */ | |||
const uint8_t *bits; | |||
}; | |||
/** | |||
@@ -122,15 +123,15 @@ struct tms_command { | |||
* structure of any defined type. | |||
*/ | |||
union jtag_command_container { | |||
struct scan_command *scan; | |||
struct statemove_command *statemove; | |||
struct pathmove_command *pathmove; | |||
struct runtest_command *runtest; | |||
struct stableclocks_command *stableclocks; | |||
struct reset_command *reset; | |||
struct end_state_command *end_state; | |||
struct sleep_command *sleep; | |||
struct tms_command *tms; | |||
struct scan_command *scan; | |||
struct statemove_command *statemove; | |||
struct pathmove_command *pathmove; | |||
struct runtest_command *runtest; | |||
struct stableclocks_command *stableclocks; | |||
struct reset_command *reset; | |||
struct end_state_command *end_state; | |||
struct sleep_command *sleep; | |||
struct tms_command *tms; | |||
}; | |||
/** | |||
@@ -157,21 +158,21 @@ enum jtag_command_type { | |||
struct jtag_command { | |||
union jtag_command_container cmd; | |||
enum jtag_command_type type; | |||
enum jtag_command_type type; | |||
struct jtag_command *next; | |||
}; | |||
/// The current queue of jtag_command_s structures. | |||
extern struct jtag_command* jtag_command_queue; | |||
/** The current queue of jtag_command_s structures. */ | |||
extern struct jtag_command *jtag_command_queue; | |||
void* cmd_queue_alloc(size_t size); | |||
void *cmd_queue_alloc(size_t size); | |||
void jtag_queue_command(struct jtag_command *cmd); | |||
void jtag_command_queue_reset(void); | |||
enum scan_type jtag_scan_type(const struct scan_command* cmd); | |||
int jtag_scan_size(const struct scan_command* cmd); | |||
int jtag_read_buffer(uint8_t* buffer, const struct scan_command* cmd); | |||
int jtag_build_buffer(const struct scan_command* cmd, uint8_t** buffer); | |||
enum scan_type jtag_scan_type(const struct scan_command *cmd); | |||
int jtag_scan_size(const struct scan_command *cmd); | |||
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd); | |||
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer); | |||
#endif // JTAG_COMMANDS_H | |||
#endif /* JTAG_COMMANDS_H */ |
@@ -1,4 +1,28 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2005 by Dominic Rath * | |||
* Dominic.Rath@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* 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., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef JTAG_DRIVER_H | |||
#define JTAG_DRIVER_H | |||
struct command_context; | |||
int interface_register_commands(struct command_context *ctx); | |||
#endif /* JTAG_DRIVER_H */ |
@@ -27,6 +27,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -60,7 +61,7 @@ static tap_state_t end_state_follower = TAP_RESET; | |||
void tap_set_end_state(tap_state_t new_end_state) | |||
{ | |||
/* this is the state we think the TAPs will be in at completion of the | |||
current TAP operation, was end_state | |||
* current TAP operation, was end_state | |||
*/ | |||
end_state_follower = new_end_state; | |||
} | |||
@@ -70,7 +71,6 @@ tap_state_t tap_get_end_state() | |||
return end_state_follower; | |||
} | |||
int tap_move_ndx(tap_state_t astate) | |||
{ | |||
/* given a stable state, return the index into the tms_seqs[] | |||
@@ -79,33 +79,42 @@ int tap_move_ndx(tap_state_t astate) | |||
int ndx; | |||
switch (astate) | |||
{ | |||
case TAP_RESET: ndx = 0; break; | |||
case TAP_IDLE: ndx = 1; break; | |||
case TAP_DRSHIFT: ndx = 2; break; | |||
case TAP_DRPAUSE: ndx = 3; break; | |||
case TAP_IRSHIFT: ndx = 4; break; | |||
case TAP_IRPAUSE: ndx = 5; break; | |||
default: | |||
LOG_ERROR("FATAL: unstable state \"%s\" in tap_move_ndx()", | |||
tap_state_name(astate)); | |||
exit(1); | |||
switch (astate) { | |||
case TAP_RESET: | |||
ndx = 0; | |||
break; | |||
case TAP_IDLE: | |||
ndx = 1; | |||
break; | |||
case TAP_DRSHIFT: | |||
ndx = 2; | |||
break; | |||
case TAP_DRPAUSE: | |||
ndx = 3; | |||
break; | |||
case TAP_IRSHIFT: | |||
ndx = 4; | |||
break; | |||
case TAP_IRPAUSE: | |||
ndx = 5; | |||
break; | |||
default: | |||
LOG_ERROR("FATAL: unstable state \"%s\" in tap_move_ndx()", | |||
tap_state_name(astate)); | |||
exit(1); | |||
} | |||
return ndx; | |||
} | |||
/* tap_move[i][j]: tap movement command to go from state i to state j | |||
* encodings of i and j are what tap_move_ndx() reports. | |||
* | |||
* DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code | |||
*/ | |||
struct tms_sequences | |||
{ | |||
uint8_t bits; | |||
uint8_t bit_count; | |||
struct tms_sequences { | |||
uint8_t bits; | |||
uint8_t bit_count; | |||
}; | |||
/* | |||
@@ -114,119 +123,111 @@ struct tms_sequences | |||
*/ | |||
#define HEX__(n) 0x##n##LU | |||
#define B8__(x) \ | |||
(((x) & 0x0000000FLU)?(1 << 0):0) \ | |||
+(((x) & 0x000000F0LU)?(1 << 1):0) \ | |||
+(((x) & 0x00000F00LU)?(1 << 2):0) \ | |||
+(((x) & 0x0000F000LU)?(1 << 3):0) \ | |||
+(((x) & 0x000F0000LU)?(1 << 4):0) \ | |||
+(((x) & 0x00F00000LU)?(1 << 5):0) \ | |||
+(((x) & 0x0F000000LU)?(1 << 6):0) \ | |||
+(((x) & 0xF0000000LU)?(1 << 7):0) | |||
#define B8__(x) \ | |||
((((x) & 0x0000000FLU) ? (1 << 0) : 0) \ | |||
+(((x) & 0x000000F0LU) ? (1 << 1) : 0) \ | |||
+(((x) & 0x00000F00LU) ? (1 << 2) : 0) \ | |||
+(((x) & 0x0000F000LU) ? (1 << 3) : 0) \ | |||
+(((x) & 0x000F0000LU) ? (1 << 4) : 0) \ | |||
+(((x) & 0x00F00000LU) ? (1 << 5) : 0) \ | |||
+(((x) & 0x0F000000LU) ? (1 << 6) : 0) \ | |||
+(((x) & 0xF0000000LU) ? (1 << 7) : 0)) | |||
#define B8(bits,count) { ((uint8_t)B8__(HEX__(bits))), (count) } | |||
#define B8(bits, count) {((uint8_t)B8__(HEX__(bits))), (count)} | |||
static const struct tms_sequences old_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ | |||
{ | |||
static const struct tms_sequences old_tms_seqs[6][6] = { /* [from_state_ndx][to_state_ndx] */ | |||
/* value clocked to TMS to move from one of six stable states to another. | |||
* N.B. OOCD clocks TMS from LSB first, so read these right-to-left. | |||
* N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable. | |||
* These extra ones cause no TAP state problem, because we go into reset and stay in reset. | |||
*/ | |||
/* to state: */ | |||
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ | |||
{ B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ | |||
{ B8(1111111,7), B8(0000000,7), B8(0100101,7), B8(0000101,7), B8(0101011,7), B8(0001011,7) }, /* IDLE */ | |||
{ B8(1111111,7), B8(0110001,7), B8(0000000,7), B8(0000001,7), B8(0001111,7), B8(0101111,7) }, /* DRSHIFT */ | |||
{ B8(1111111,7), B8(0110000,7), B8(0100000,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* DRPAUSE */ | |||
{ B8(1111111,7), B8(0110001,7), B8(0000111,7), B8(0010111,7), B8(0000000,7), B8(0000001,7) }, /* IRSHIFT */ | |||
{ B8(1111111,7), B8(0110000,7), B8(0011100,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* IRPAUSE */ | |||
/* to state: */ | |||
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ | |||
{B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)},/* RESET */ | |||
{B8(1111111, 7), B8(0000000, 7), B8(0100101, 7), B8(0000101, 7), B8(0101011, 7), B8(0001011, 7)},/* IDLE */ | |||
{B8(1111111, 7), B8(0110001, 7), B8(0000000, 7), B8(0000001, 7), B8(0001111, 7), B8(0101111, 7)},/* DRSHIFT */ | |||
{B8(1111111, 7), B8(0110000, 7), B8(0100000, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* DRPAUSE */ | |||
{B8(1111111, 7), B8(0110001, 7), B8(0000111, 7), B8(0010111, 7), B8(0000000, 7), B8(0000001, 7)},/* IRSHIFT */ | |||
{B8(1111111, 7), B8(0110000, 7), B8(0011100, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* IRPAUSE */ | |||
}; | |||
static const struct tms_sequences short_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ | |||
{ | |||
static const struct tms_sequences short_tms_seqs[6][6] = { /* [from_state_ndx][to_state_ndx] */ | |||
/* this is the table submitted by Jeff Williams on 3/30/2009 with this comment: | |||
OK, I added Peter's version of the state table, and it works OK for | |||
me on MC1322x. I've recreated the jlink portion of patch with this | |||
new state table. His changes to my state table are pretty minor in | |||
terms of total transitions, but Peter feels that his version fixes | |||
some long-standing problems. | |||
Jeff | |||
I added the bit count into the table, reduced RESET column to 7 bits from 8. | |||
Dick | |||
state specific comments: | |||
------------------------ | |||
*->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to | |||
work better on ARM9 with ft2232 driver. (Dick) | |||
RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing. | |||
needed on ARM9 with ft2232 driver. (Dick) | |||
(For a total of *THREE* extra clocks in RESET; NOP.) | |||
RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing. | |||
needed on ARM9 with ft2232 driver. (Dick) | |||
(For a total of *TWO* extra clocks in RESET; NOP.) | |||
RESET->* always adds one or more clocks in the target state, | |||
which should be NOPS; except shift states which (as | |||
noted above) add those clocks in RESET. | |||
The X-to-X transitions always add clocks; from *SHIFT, they go | |||
via IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update). | |||
*/ | |||
/* to state: */ | |||
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ | |||
{ B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ | |||
{ B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */ | |||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */ | |||
{ B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */ | |||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */ | |||
{ B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1)} /* IRPAUSE */ | |||
OK, I added Peter's version of the state table, and it works OK for | |||
me on MC1322x. I've recreated the jlink portion of patch with this | |||
new state table. His changes to my state table are pretty minor in | |||
terms of total transitions, but Peter feels that his version fixes | |||
some long-standing problems. | |||
Jeff | |||
I added the bit count into the table, reduced RESET column to 7 bits from 8. | |||
Dick | |||
state specific comments: | |||
------------------------ | |||
*->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to | |||
work better on ARM9 with ft2232 driver. (Dick) | |||
RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing. | |||
needed on ARM9 with ft2232 driver. (Dick) | |||
(For a total of *THREE* extra clocks in RESET; NOP.) | |||
RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing. | |||
needed on ARM9 with ft2232 driver. (Dick) | |||
(For a total of *TWO* extra clocks in RESET; NOP.) | |||
RESET->* always adds one or more clocks in the target state, | |||
which should be NOPS; except shift states which (as | |||
noted above) add those clocks in RESET. | |||
The X-to-X transitions always add clocks; from *SHIFT, they go | |||
via IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update). | |||
*/ | |||
/* to state: */ | |||
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ | |||
{B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)}, /* RESET */ | |||
{B8(1111111, 7), B8(0000000, 7), B8(001, 3), B8(0101, 4), B8(0011, 4), B8(01011, 5)}, /* IDLE */ | |||
{B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(01, 2), B8(001111, 6), B8(0101111, 7)}, /* DRSHIFT */ | |||
{B8(1111111, 7), B8(011, 3), B8(01, 2), B8(0, 1), B8(001111, 6), B8(0101111, 7)}, /* DRPAUSE */ | |||
{B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(010111, 6), B8(001111, 6), B8(01, 2)}, /* IRSHIFT */ | |||
{B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(010111, 6), B8(01, 2), B8(0, 1)} /* IRPAUSE */ | |||
}; | |||
typedef const struct tms_sequences tms_table[6][6]; | |||
static tms_table *tms_seqs=&short_tms_seqs; | |||
static tms_table *tms_seqs = &short_tms_seqs; | |||
int tap_get_tms_path(tap_state_t from, tap_state_t to) | |||
{ | |||
return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits; | |||
} | |||
int tap_get_tms_path_len(tap_state_t from, tap_state_t to) | |||
{ | |||
return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count; | |||
} | |||
bool tap_is_state_stable(tap_state_t astate) | |||
{ | |||
bool is_stable; | |||
/* A switch () is used because it is symbol dependent | |||
(not value dependent like an array), and can also check bounds. | |||
* (not value dependent like an array), and can also check bounds. | |||
*/ | |||
switch (astate) | |||
{ | |||
case TAP_RESET: | |||
case TAP_IDLE: | |||
case TAP_DRSHIFT: | |||
case TAP_DRPAUSE: | |||
case TAP_IRSHIFT: | |||
case TAP_IRPAUSE: | |||
is_stable = true; | |||
break; | |||
default: | |||
is_stable = false; | |||
switch (astate) { | |||
case TAP_RESET: | |||
case TAP_IDLE: | |||
case TAP_DRSHIFT: | |||
case TAP_DRPAUSE: | |||
case TAP_IRSHIFT: | |||
case TAP_IRPAUSE: | |||
is_stable = true; | |||
break; | |||
default: | |||
is_stable = false; | |||
} | |||
return is_stable; | |||
@@ -237,126 +238,120 @@ tap_state_t tap_state_transition(tap_state_t cur_state, bool tms) | |||
tap_state_t new_state; | |||
/* A switch is used because it is symbol dependent and not value dependent | |||
like an array. Also it can check for out of range conditions. | |||
* like an array. Also it can check for out of range conditions. | |||
*/ | |||
if (tms) | |||
{ | |||
switch (cur_state) | |||
{ | |||
case TAP_RESET: | |||
new_state = cur_state; | |||
break; | |||
case TAP_IDLE: | |||
case TAP_DRUPDATE: | |||
case TAP_IRUPDATE: | |||
new_state = TAP_DRSELECT; | |||
break; | |||
case TAP_DRSELECT: | |||
new_state = TAP_IRSELECT; | |||
break; | |||
case TAP_DRCAPTURE: | |||
case TAP_DRSHIFT: | |||
new_state = TAP_DREXIT1; | |||
break; | |||
case TAP_DREXIT1: | |||
case TAP_DREXIT2: | |||
new_state = TAP_DRUPDATE; | |||
break; | |||
case TAP_DRPAUSE: | |||
new_state = TAP_DREXIT2; | |||
break; | |||
case TAP_IRSELECT: | |||
new_state = TAP_RESET; | |||
break; | |||
case TAP_IRCAPTURE: | |||
case TAP_IRSHIFT: | |||
new_state = TAP_IREXIT1; | |||
break; | |||
case TAP_IREXIT1: | |||
case TAP_IREXIT2: | |||
new_state = TAP_IRUPDATE; | |||
break; | |||
case TAP_IRPAUSE: | |||
new_state = TAP_IREXIT2; | |||
break; | |||
default: | |||
LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state); | |||
exit(1); | |||
break; | |||
if (tms) { | |||
switch (cur_state) { | |||
case TAP_RESET: | |||
new_state = cur_state; | |||
break; | |||
case TAP_IDLE: | |||
case TAP_DRUPDATE: | |||
case TAP_IRUPDATE: | |||
new_state = TAP_DRSELECT; | |||
break; | |||
case TAP_DRSELECT: | |||
new_state = TAP_IRSELECT; | |||
break; | |||
case TAP_DRCAPTURE: | |||
case TAP_DRSHIFT: | |||
new_state = TAP_DREXIT1; | |||
break; | |||
case TAP_DREXIT1: | |||
case TAP_DREXIT2: | |||
new_state = TAP_DRUPDATE; | |||
break; | |||
case TAP_DRPAUSE: | |||
new_state = TAP_DREXIT2; | |||
break; | |||
case TAP_IRSELECT: | |||
new_state = TAP_RESET; | |||
break; | |||
case TAP_IRCAPTURE: | |||
case TAP_IRSHIFT: | |||
new_state = TAP_IREXIT1; | |||
break; | |||
case TAP_IREXIT1: | |||
case TAP_IREXIT2: | |||
new_state = TAP_IRUPDATE; | |||
break; | |||
case TAP_IRPAUSE: | |||
new_state = TAP_IREXIT2; | |||
break; | |||
default: | |||
LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state); | |||
exit(1); | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
switch (cur_state) | |||
{ | |||
case TAP_RESET: | |||
case TAP_IDLE: | |||
case TAP_DRUPDATE: | |||
case TAP_IRUPDATE: | |||
new_state = TAP_IDLE; | |||
break; | |||
case TAP_DRSELECT: | |||
new_state = TAP_DRCAPTURE; | |||
break; | |||
case TAP_DRCAPTURE: | |||
case TAP_DRSHIFT: | |||
case TAP_DREXIT2: | |||
new_state = TAP_DRSHIFT; | |||
break; | |||
case TAP_DREXIT1: | |||
case TAP_DRPAUSE: | |||
new_state = TAP_DRPAUSE; | |||
break; | |||
case TAP_IRSELECT: | |||
new_state = TAP_IRCAPTURE; | |||
break; | |||
case TAP_IRCAPTURE: | |||
case TAP_IRSHIFT: | |||
case TAP_IREXIT2: | |||
new_state = TAP_IRSHIFT; | |||
break; | |||
case TAP_IREXIT1: | |||
case TAP_IRPAUSE: | |||
new_state = TAP_IRPAUSE; | |||
break; | |||
default: | |||
LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state); | |||
exit(1); | |||
break; | |||
} else { | |||
switch (cur_state) { | |||
case TAP_RESET: | |||
case TAP_IDLE: | |||
case TAP_DRUPDATE: | |||
case TAP_IRUPDATE: | |||
new_state = TAP_IDLE; | |||
break; | |||
case TAP_DRSELECT: | |||
new_state = TAP_DRCAPTURE; | |||
break; | |||
case TAP_DRCAPTURE: | |||
case TAP_DRSHIFT: | |||
case TAP_DREXIT2: | |||
new_state = TAP_DRSHIFT; | |||
break; | |||
case TAP_DREXIT1: | |||
case TAP_DRPAUSE: | |||
new_state = TAP_DRPAUSE; | |||
break; | |||
case TAP_IRSELECT: | |||
new_state = TAP_IRCAPTURE; | |||
break; | |||
case TAP_IRCAPTURE: | |||
case TAP_IRSHIFT: | |||
case TAP_IREXIT2: | |||
new_state = TAP_IRSHIFT; | |||
break; | |||
case TAP_IREXIT1: | |||
case TAP_IRPAUSE: | |||
new_state = TAP_IRPAUSE; | |||
break; | |||
default: | |||
LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state); | |||
exit(1); | |||
break; | |||
} | |||
} | |||
return new_state; | |||
} | |||
/* NOTE: do not change these state names. They're documented, | |||
* and we rely on them to match SVF input (except for "RUN/IDLE"). | |||
*/ | |||
static const struct name_mapping { | |||
enum tap_state symbol; | |||
const char *name; | |||
enum tap_state symbol; | |||
const char *name; | |||
} tap_name_mapping[] = { | |||
{ TAP_RESET, "RESET", }, | |||
{ TAP_IDLE, "RUN/IDLE", }, | |||
{ TAP_DRSELECT, "DRSELECT", }, | |||
{ TAP_DRCAPTURE,"DRCAPTURE", }, | |||
{ TAP_DRSHIFT, "DRSHIFT", }, | |||
{ TAP_DREXIT1, "DREXIT1", }, | |||
{ TAP_DRPAUSE, "DRPAUSE", }, | |||
{ TAP_DREXIT2, "DREXIT2", }, | |||
{ TAP_DRUPDATE, "DRUPDATE", }, | |||
{ TAP_IRSELECT, "IRSELECT", }, | |||
{ TAP_IRCAPTURE,"IRCAPTURE", }, | |||
{ TAP_IRSHIFT, "IRSHIFT", }, | |||
{ TAP_IREXIT1, "IREXIT1", }, | |||
{ TAP_IRPAUSE, "IRPAUSE", }, | |||
{ TAP_IREXIT2, "IREXIT2", }, | |||
{ TAP_IRUPDATE, "IRUPDATE", }, | |||
{ TAP_RESET, "RESET", }, | |||
{ TAP_IDLE, "RUN/IDLE", }, | |||
{ TAP_DRSELECT, "DRSELECT", }, | |||
{ TAP_DRCAPTURE, "DRCAPTURE", }, | |||
{ TAP_DRSHIFT, "DRSHIFT", }, | |||
{ TAP_DREXIT1, "DREXIT1", }, | |||
{ TAP_DRPAUSE, "DRPAUSE", }, | |||
{ TAP_DREXIT2, "DREXIT2", }, | |||
{ TAP_DRUPDATE, "DRUPDATE", }, | |||
{ TAP_IRSELECT, "IRSELECT", }, | |||
{ TAP_IRCAPTURE, "IRCAPTURE", }, | |||
{ TAP_IRSHIFT, "IRSHIFT", }, | |||
{ TAP_IREXIT1, "IREXIT1", }, | |||
{ TAP_IRPAUSE, "IRPAUSE", }, | |||
{ TAP_IREXIT2, "IREXIT2", }, | |||
{ TAP_IRUPDATE, "IRUPDATE", }, | |||
/* only for input: accept standard SVF name */ | |||
{ TAP_IDLE, "IDLE", }, | |||
{ TAP_IDLE, "IDLE", }, | |||
}; | |||
const char *tap_state_name(tap_state_t state) | |||
@@ -386,13 +381,13 @@ tap_state_t tap_state_by_name(const char *name) | |||
#ifdef _DEBUG_JTAG_IO_ | |||
#define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \ | |||
do { buf[len] = bit ? '1' : '0'; } while (0) | |||
do { buf[len] = bit ? '1' : '0'; } while (0) | |||
#define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \ | |||
DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \ | |||
tap_state_name(a), tap_state_name(b), astr, bstr) | |||
DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \ | |||
tap_state_name(a), tap_state_name(b), astr, bstr) | |||
tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, | |||
unsigned tap_bits, tap_state_t next_state) | |||
unsigned tap_bits, tap_state_t next_state) | |||
{ | |||
const uint8_t *tms_buffer; | |||
const uint8_t *tdi_buffer; | |||
@@ -406,7 +401,7 @@ tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, | |||
tap_state_t last_state; | |||
// set startstate (and possibly last, if tap_bits == 0) | |||
/* set startstate (and possibly last, if tap_bits == 0) */ | |||
last_state = next_state; | |||
DEBUG_JTAG_IO("TAP/SM: START state: %s", tap_state_name(next_state)); | |||
@@ -417,47 +412,44 @@ tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, | |||
DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes); | |||
tap_out_bits = 0; | |||
for (cur_byte = 0; cur_byte < tap_bytes; cur_byte++) | |||
{ | |||
for (cur_bit = 0; cur_bit < 8; cur_bit++) | |||
{ | |||
// make sure we do not run off the end of the buffers | |||
for (cur_byte = 0; cur_byte < tap_bytes; cur_byte++) { | |||
for (cur_bit = 0; cur_bit < 8; cur_bit++) { | |||
/* make sure we do not run off the end of the buffers */ | |||
unsigned tap_bit = cur_byte * 8 + cur_bit; | |||
if (tap_bit == tap_bits) | |||
break; | |||
// check and save TMS bit | |||
/* check and save TMS bit */ | |||
tap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit)); | |||
JTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit); | |||
// use TMS bit to find the next TAP state | |||
/* use TMS bit to find the next TAP state */ | |||
next_state = tap_state_transition(last_state, tap_bit); | |||
// check and store TDI bit | |||
/* check and store TDI bit */ | |||
tap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit)); | |||
JTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit); | |||
// increment TAP bits | |||
/* increment TAP bits */ | |||
tap_out_bits++; | |||
// Only show TDO bits on state transitions, or | |||
// after some number of bits in the same state. | |||
/* Only show TDO bits on state transitions, or */ | |||
/* after some number of bits in the same state. */ | |||
if ((next_state == last_state) && (tap_out_bits < 32)) | |||
continue; | |||
// terminate strings and display state transition | |||
/* terminate strings and display state transition */ | |||
tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; | |||
JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); | |||
// reset state | |||
/* reset state */ | |||
last_state = next_state; | |||
tap_out_bits = 0; | |||
} | |||
} | |||
if (tap_out_bits) | |||
{ | |||
// terminate strings and display state transition | |||
if (tap_out_bits) { | |||
/* terminate strings and display state transition */ | |||
tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; | |||
JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); | |||
} | |||
@@ -466,7 +458,7 @@ tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, | |||
return next_state; | |||
} | |||
#endif // _DEBUG_JTAG_IO_ | |||
#endif /* _DEBUG_JTAG_IO_ */ | |||
void tap_use_new_tms_table(bool use_new) | |||
{ | |||
@@ -476,4 +468,3 @@ bool tap_uses_new_tms_table(void) | |||
{ | |||
return tms_seqs == &short_tms_seqs; | |||
} | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef OPENOCD_JTAG_INTERFACE_H | |||
#define OPENOCD_JTAG_INTERFACE_H | |||
@@ -54,7 +55,7 @@ void tap_set_state_impl(tap_state_t new_state); | |||
* expected to traverse, not just end points of a multi-step state path. | |||
* | |||
* @param new_state The state we think the TAPs are currently in (or | |||
* are about to enter). | |||
* are about to enter). | |||
*/ | |||
#if defined(_DEBUG_JTAG_IO_) | |||
#define tap_set_state(new_state) \ | |||
@@ -85,7 +86,7 @@ tap_state_t tap_get_state(void); | |||
* state follower via tap_set_state(). | |||
* | |||
* @param new_end_state The state the TAPs should enter at completion of | |||
* a pending TAP operation. | |||
* a pending TAP operation. | |||
*/ | |||
void tap_set_end_state(tap_state_t new_end_state); | |||
@@ -106,11 +107,10 @@ tap_state_t tap_get_end_state(void); | |||
* @param from The starting state. | |||
* @param to The desired final state. | |||
* @return int The required TMS bit sequence, with the first bit in the | |||
* sequence at bit 0. | |||
* sequence at bit 0. | |||
*/ | |||
int tap_get_tms_path(tap_state_t from, tap_state_t to); | |||
/** | |||
* Function int tap_get_tms_path_len | |||
* returns the total number of bits that represents a TMS path | |||
@@ -160,9 +160,9 @@ bool tap_is_state_stable(tap_state_t astate); | |||
*/ | |||
tap_state_t tap_state_transition(tap_state_t current_state, bool tms); | |||
/// Allow switching between old and new TMS tables. @see tap_get_tms_path | |||
/** Allow switching between old and new TMS tables. @see tap_get_tms_path */ | |||
void tap_use_new_tms_table(bool use_new); | |||
/// @returns True if new TMS table is active; false otherwise. | |||
/** @returns True if new TMS table is active; false otherwise. */ | |||
bool tap_uses_new_tms_table(void); | |||
#ifdef _DEBUG_JTAG_IO_ | |||
@@ -182,7 +182,7 @@ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, | |||
{ | |||
return start_tap_state; | |||
} | |||
#endif // _DEBUG_JTAG_IO_ | |||
#endif /* _DEBUG_JTAG_IO_ */ | |||
/** | |||
* Represents a driver for a debugging interface. | |||
@@ -197,8 +197,8 @@ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, | |||
* debugging interface. | |||
*/ | |||
struct jtag_interface { | |||
/// The name of the JTAG interface driver. | |||
char* name; | |||
/** The name of the JTAG interface driver. */ | |||
char *name; | |||
/** | |||
* Bit vector listing capabilities exposed by this driver. | |||
@@ -261,7 +261,7 @@ struct jtag_interface { | |||
* and use a fallback kHz TCK. | |||
* @returns ERROR_OK on success, or an error code on failure. | |||
*/ | |||
int (*khz)(int khz, int* jtag_speed); | |||
int (*khz)(int khz, int *jtag_speed); | |||
/** | |||
* Calculate the clock frequency (in KHz) for the given @a speed. | |||
@@ -270,7 +270,7 @@ struct jtag_interface { | |||
* @returns ERROR_OK on success, or an error code if the | |||
* interface cannot support the specified speed (KHz or RTCK). | |||
*/ | |||
int (*speed_div)(int speed, int* khz); | |||
int (*speed_div)(int speed, int *khz); | |||
/** | |||
* Read and clear the power dropout flag. Note that a power dropout | |||
@@ -283,7 +283,7 @@ struct jtag_interface { | |||
* | |||
* @returns ERROR_OK on success, or an error code on failure. | |||
*/ | |||
int (*power_dropout)(int* power_dropout); | |||
int (*power_dropout)(int *power_dropout); | |||
/** | |||
* Read and clear the srst asserted detection flag. | |||
@@ -297,12 +297,11 @@ struct jtag_interface { | |||
* been asserted. | |||
* @returns ERROR_OK on success, or an error code on failure. | |||
*/ | |||
int (*srst_asserted)(int* srst_asserted); | |||
int (*srst_asserted)(int *srst_asserted); | |||
}; | |||
extern const char *jtag_only[]; | |||
extern const struct swd_driver *swd; | |||
#endif // OPENOCD_JTAG_INTERFACE_H | |||
#endif /* OPENOCD_JTAG_INTERFACE_H */ |
@@ -27,6 +27,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -45,7 +46,7 @@ | |||
extern struct jtag_interface zy1000_interface; | |||
#elif defined(BUILD_MINIDRIVER_DUMMY) | |||
extern struct jtag_interface minidummy_interface; | |||
#else // standard drivers | |||
#else /* standard drivers */ | |||
#if BUILD_PARPORT == 1 | |||
extern struct jtag_interface parport_interface; | |||
#endif | |||
@@ -103,7 +104,7 @@ extern struct jtag_interface remote_bitbang_interface; | |||
#if BUILD_STLINK == 1 | |||
extern struct jtag_interface stlink_interface; | |||
#endif | |||
#endif // standard drivers | |||
#endif /* standard drivers */ | |||
/** | |||
* The list of built-in JTAG interfaces, containing entries for those | |||
@@ -117,7 +118,7 @@ struct jtag_interface *jtag_interfaces[] = { | |||
&zy1000_interface, | |||
#elif defined(BUILD_MINIDRIVER_DUMMY) | |||
&minidummy_interface, | |||
#else // standard drivers | |||
#else /* standard drivers */ | |||
#if BUILD_PARPORT == 1 | |||
&parport_interface, | |||
#endif | |||
@@ -175,11 +176,11 @@ struct jtag_interface *jtag_interfaces[] = { | |||
#if BUILD_STLINK == 1 | |||
&stlink_interface, | |||
#endif | |||
#endif // standard drivers | |||
#endif /* standard drivers */ | |||
NULL, | |||
}; | |||
void jtag_interface_modules_load(const char *path) | |||
{ | |||
// @todo: implement dynamic module loading for JTAG interface drivers | |||
/* @todo: implement dynamic module loading for JTAG interface drivers */ | |||
} |
@@ -27,6 +27,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef OPENOCD_JTAG_INTERFACES_H | |||
#define OPENOCD_JTAG_INTERFACES_H | |||
@@ -37,9 +38,9 @@ | |||
#include <jtag/interface.h> | |||
/// Dynamically load all JTAG interface modules from specified directory. | |||
/** Dynamically load all JTAG interface modules from specified directory. */ | |||
void jtag_interface_modules_load(const char *path); | |||
extern struct jtag_interface *jtag_interfaces[]; | |||
#endif // OPENOCD_JTAG_INTERFACES_H | |||
#endif /* OPENOCD_JTAG_INTERFACES_H */ |
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef JTAG_H | |||
#define JTAG_H | |||
@@ -52,8 +53,7 @@ | |||
* Fix those drivers to map as appropriate ... then pick some | |||
* sane set of numbers here (where 0/uninitialized == INVALID). | |||
*/ | |||
typedef enum tap_state | |||
{ | |||
typedef enum tap_state { | |||
TAP_INVALID = -1, | |||
#if BUILD_ZY1000 | |||
@@ -92,10 +92,10 @@ typedef enum tap_state | |||
*/ | |||
const char *tap_state_name(tap_state_t state); | |||
/// Provides user-friendly name lookup of TAP states. | |||
/** Provides user-friendly name lookup of TAP states. */ | |||
tap_state_t tap_state_by_name(const char *name); | |||
/// The current TAP state of the pending JTAG command queue. | |||
/** The current TAP state of the pending JTAG command queue. */ | |||
extern tap_state_t cmd_queue_cur_state; | |||
/** | |||
@@ -107,54 +107,54 @@ extern tap_state_t cmd_queue_cur_state; | |||
* jtag_add_dr_scan_check() to validate the value that was scanned out. | |||
*/ | |||
struct scan_field { | |||
/// The number of bits this field specifies (up to 32) | |||
/** The number of bits this field specifies (up to 32) */ | |||
int num_bits; | |||
/// A pointer to value to be scanned into the device | |||
const uint8_t* out_value; | |||
/// A pointer to a 32-bit memory location for data scanned out | |||
uint8_t* in_value; | |||
/// The value used to check the data scanned out. | |||
uint8_t* check_value; | |||
/// The mask to go with check_value | |||
uint8_t* check_mask; | |||
/** A pointer to value to be scanned into the device */ | |||
const uint8_t *out_value; | |||
/** A pointer to a 32-bit memory location for data scanned out */ | |||
uint8_t *in_value; | |||
/** The value used to check the data scanned out. */ | |||
uint8_t *check_value; | |||
/** The mask to go with check_value */ | |||
uint8_t *check_mask; | |||
}; | |||
struct jtag_tap { | |||
const char* chip; | |||
const char* tapname; | |||
const char* dotted_name; | |||
const char *chip; | |||
const char *tapname; | |||
const char *dotted_name; | |||
int abs_chain_position; | |||
/// Is this TAP disabled after JTAG reset? | |||
/** Is this TAP disabled after JTAG reset? */ | |||
bool disabled_after_reset; | |||
/// Is this TAP currently enabled? | |||
/** Is this TAP currently enabled? */ | |||
bool enabled; | |||
int ir_length; /**< size of instruction register */ | |||
uint32_t ir_capture_value; | |||
uint8_t* expected; /**< Capture-IR expected value */ | |||
uint8_t *expected; /**< Capture-IR expected value */ | |||
uint32_t ir_capture_mask; | |||
uint8_t* expected_mask; /**< Capture-IR expected mask */ | |||
uint8_t *expected_mask; /**< Capture-IR expected mask */ | |||
uint32_t idcode; /**< device identification code */ | |||
/** not all devices have idcode, | |||
* we'll discover this during chain examination */ | |||
bool hasidcode; | |||
/// Array of expected identification codes */ | |||
uint32_t* expected_ids; | |||
/// Number of expected identification codes | |||
/** Array of expected identification codes */ | |||
uint32_t *expected_ids; | |||
/** Number of expected identification codes */ | |||
uint8_t expected_ids_cnt; | |||
/// Flag saying whether to ignore version field in expected_ids[] | |||
/** Flag saying whether to ignore version field in expected_ids[] */ | |||
bool ignore_version; | |||
/// current instruction | |||
uint8_t* cur_instr; | |||
/// Bypass register selected | |||
/** current instruction */ | |||
uint8_t *cur_instr; | |||
/** Bypass register selected */ | |||
int bypass; | |||
struct jtag_tap_event_action *event_action; | |||
struct jtag_tap* next_tap; | |||
struct jtag_tap *next_tap; | |||
/* dap instance if some null if no instance , initialized to 0 by calloc*/ | |||
struct adiv5_dap *dap; | |||
/* private pointer to support none-jtag specific functions */ | |||
@@ -164,16 +164,15 @@ struct jtag_tap { | |||
void jtag_tap_init(struct jtag_tap *tap); | |||
void jtag_tap_free(struct jtag_tap *tap); | |||
struct jtag_tap* jtag_all_taps(void); | |||
struct jtag_tap *jtag_all_taps(void); | |||
const char *jtag_tap_name(const struct jtag_tap *tap); | |||
struct jtag_tap* jtag_tap_by_string(const char* dotted_name); | |||
struct jtag_tap* jtag_tap_by_jim_obj(Jim_Interp* interp, Jim_Obj* obj); | |||
struct jtag_tap* jtag_tap_by_position(unsigned abs_position); | |||
struct jtag_tap* jtag_tap_next_enabled(struct jtag_tap* p); | |||
struct jtag_tap *jtag_tap_by_string(const char* dotted_name); | |||
struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp* interp, Jim_Obj *obj); | |||
struct jtag_tap *jtag_tap_by_position(unsigned abs_position); | |||
struct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p); | |||
unsigned jtag_tap_count_enabled(void); | |||
unsigned jtag_tap_count(void); | |||
/* | |||
* - TRST_ASSERTED triggers two sets of callbacks, after operations to | |||
* reset the scan chain -- via TMS+TCK signaling, or deasserting the | |||
@@ -203,15 +202,14 @@ enum jtag_event { | |||
JTAG_TAP_EVENT_DISABLE, | |||
}; | |||
struct jtag_tap_event_action | |||
{ | |||
/// The event for which this action will be triggered. | |||
struct jtag_tap_event_action { | |||
/** The event for which this action will be triggered. */ | |||
enum jtag_event event; | |||
/// The interpreter to use for evaluating the @c body. | |||
/** The interpreter to use for evaluating the @c body. */ | |||
Jim_Interp *interp; | |||
/// Contains a script to 'eval' when the @c event is triggered. | |||
/** Contains a script to 'eval' when the @c event is triggered. */ | |||
Jim_Obj *body; | |||
// next action in linked list | |||
/* next action in linked list */ | |||
struct jtag_tap_event_action *next; | |||
}; | |||
@@ -226,7 +224,7 @@ struct jtag_tap_event_action | |||
* | |||
* @todo Change to return void or define a use for its return code. | |||
*/ | |||
typedef int (*jtag_event_handler_t)(enum jtag_event event, void* priv); | |||
typedef int (*jtag_event_handler_t)(enum jtag_event event, void *priv); | |||
int jtag_register_event_callback(jtag_event_handler_t f, void *x); | |||
int jtag_unregister_event_callback(jtag_event_handler_t f, void *x); | |||
@@ -234,7 +232,7 @@ int jtag_unregister_event_callback(jtag_event_handler_t f, void *x); | |||
int jtag_call_event_callbacks(enum jtag_event event); | |||
/// @returns The current JTAG speed setting. | |||
/** @returns The current JTAG speed setting. */ | |||
int jtag_get_speed(int *speed); | |||
/** | |||
@@ -246,7 +244,7 @@ int jtag_get_speed(int *speed); | |||
*/ | |||
int jtag_get_speed_readable(int *speed); | |||
/// Attempt to configure the interface for the specified KHz. | |||
/** Attempt to configure the interface for the specified KHz. */ | |||
int jtag_config_khz(unsigned khz); | |||
/** | |||
@@ -255,10 +253,9 @@ int jtag_config_khz(unsigned khz); | |||
*/ | |||
int jtag_config_rclk(unsigned fallback_speed_khz); | |||
/// Retreives the clock speed of the JTAG interface in KHz. | |||
/** Retreives the clock speed of the JTAG interface in KHz. */ | |||
unsigned jtag_get_speed_khz(void); | |||
enum reset_types { | |||
RESET_NONE = 0x0, | |||
RESET_HAS_TRST = 0x1, | |||
@@ -286,40 +283,39 @@ unsigned jtag_get_nsrst_assert_width(void); | |||
void jtag_set_ntrst_assert_width(unsigned delay); | |||
unsigned jtag_get_ntrst_assert_width(void); | |||
/// @returns The current state of TRST. | |||
/** @returns The current state of TRST. */ | |||
int jtag_get_trst(void); | |||
/// @returns The current state of SRST. | |||
/** @returns The current state of SRST. */ | |||
int jtag_get_srst(void); | |||
/// Enable or disable data scan verification checking. | |||
/** Enable or disable data scan verification checking. */ | |||
void jtag_set_verify(bool enable); | |||
/// @returns True if data scan verification will be performed. | |||
/** @returns True if data scan verification will be performed. */ | |||
bool jtag_will_verify(void); | |||
/// Enable or disable verification of IR scan checking. | |||
/** Enable or disable verification of IR scan checking. */ | |||
void jtag_set_verify_capture_ir(bool enable); | |||
/// @returns True if IR scan verification will be performed. | |||
/** @returns True if IR scan verification will be performed. */ | |||
bool jtag_will_verify_capture_ir(void); | |||
/** Initialize debug adapter upon startup. */ | |||
int adapter_init(struct command_context* cmd_ctx); | |||
int adapter_init(struct command_context *cmd_ctx); | |||
/// Shutdown the debug adapter upon program exit. | |||
int adapter_quit(void); | |||
/** Shutdown the debug adapter upon program exit. */ | |||
int adapter_quit(void); | |||
/// Set ms to sleep after jtag_execute_queue() flushes queue. Debug | |||
/// purposes. | |||
/** Set ms to sleep after jtag_execute_queue() flushes queue. Debug purposes. */ | |||
void jtag_set_flush_queue_sleep(int ms); | |||
/** | |||
* Initialize JTAG chain using only a RESET reset. If init fails, | |||
* try reset + init. | |||
*/ | |||
int jtag_init(struct command_context* cmd_ctx); | |||
int jtag_init(struct command_context *cmd_ctx); | |||
/// reset, then initialize JTAG chain | |||
int jtag_init_reset(struct command_context* cmd_ctx); | |||
int jtag_register_commands(struct command_context* cmd_ctx); | |||
/** reset, then initialize JTAG chain */ | |||
int jtag_init_reset(struct command_context *cmd_ctx); | |||
int jtag_register_commands(struct command_context *cmd_ctx); | |||
int jtag_init_inner(struct command_context *cmd_ctx); | |||
/** | |||
@@ -347,13 +343,13 @@ int jtag_init_inner(struct command_context *cmd_ctx); | |||
* subsequent DR SCANs. | |||
* | |||
*/ | |||
void jtag_add_ir_scan(struct jtag_tap* tap, | |||
struct scan_field* fields, tap_state_t endstate); | |||
void jtag_add_ir_scan(struct jtag_tap *tap, | |||
struct scan_field *fields, tap_state_t endstate); | |||
/** | |||
* The same as jtag_add_ir_scan except no verification is performed out | |||
* the output values. | |||
*/ | |||
void jtag_add_ir_scan_noverify(struct jtag_tap* tap, | |||
void jtag_add_ir_scan_noverify(struct jtag_tap *tap, | |||
const struct scan_field *fields, tap_state_t state); | |||
/** | |||
* Scan out the bits in ir scan mode. | |||
@@ -363,18 +359,17 @@ void jtag_add_ir_scan_noverify(struct jtag_tap* tap, | |||
void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, | |||
tap_state_t endstate); | |||
/** | |||
* Generate a DR SCAN using the fields passed to the function. | |||
* For connected TAPs, the function checks in_fields and uses fields | |||
* specified there. For bypassed TAPs, the function generates a dummy | |||
* 1-bit field. The bypass status of TAPs is set by jtag_add_ir_scan(). | |||
*/ | |||
void jtag_add_dr_scan(struct jtag_tap* tap, int num_fields, | |||
const struct scan_field* fields, tap_state_t endstate); | |||
/// A version of jtag_add_dr_scan() that uses the check_value/mask fields | |||
void jtag_add_dr_scan_check(struct jtag_tap* tap, int num_fields, | |||
struct scan_field* fields, tap_state_t endstate); | |||
void jtag_add_dr_scan(struct jtag_tap *tap, int num_fields, | |||
const struct scan_field *fields, tap_state_t endstate); | |||
/** A version of jtag_add_dr_scan() that uses the check_value/mask fields */ | |||
void jtag_add_dr_scan_check(struct jtag_tap *tap, int num_fields, | |||
struct scan_field *fields, tap_state_t endstate); | |||
/** | |||
* Scan out the bits in ir scan mode. | |||
* | |||
@@ -399,7 +394,7 @@ typedef intptr_t jtag_callback_data_t; | |||
*/ | |||
typedef void (*jtag_callback1_t)(jtag_callback_data_t data0); | |||
/// A simpler version of jtag_add_callback4(). | |||
/** A simpler version of jtag_add_callback4(). */ | |||
void jtag_add_callback(jtag_callback1_t, jtag_callback_data_t data0); | |||
@@ -489,7 +484,7 @@ void jtag_add_tlr(void); | |||
* - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid | |||
* state transitions. | |||
*/ | |||
void jtag_add_pathmove(int num_states, const tap_state_t* path); | |||
void jtag_add_pathmove(int num_states, const tap_state_t *path); | |||
/** | |||
* jtag_add_statemove() moves from the current state to @a goal_state. | |||
@@ -550,7 +545,6 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state t); | |||
*/ | |||
void jtag_add_clocks(int num_cycles); | |||
/** | |||
* For software FIFO implementations, the queued commands can be executed | |||
* during this call or earlier. A sw queue might decide to push out | |||
@@ -573,19 +567,18 @@ void jtag_add_clocks(int num_cycles); | |||
*/ | |||
int jtag_execute_queue(void); | |||
/// same as jtag_execute_queue() but does not clear the error flag | |||
/** same as jtag_execute_queue() but does not clear the error flag */ | |||
void jtag_execute_queue_noclear(void); | |||
/// @returns the number of times the scan queue has been flushed | |||
/** @returns the number of times the scan queue has been flushed */ | |||
int jtag_get_flush_queue_count(void); | |||
/// Report Tcl event to all TAPs | |||
/** Report Tcl event to all TAPs */ | |||
void jtag_notify_event(enum jtag_event); | |||
/* can be implemented by hw + sw */ | |||
int jtag_power_dropout(int* dropout); | |||
int jtag_srst_asserted(int* srst_asserted); | |||
int jtag_power_dropout(int *dropout); | |||
int jtag_srst_asserted(int *srst_asserted); | |||
/* JTAG support functions */ | |||
@@ -642,7 +635,6 @@ void jtag_sleep(uint32_t us); | |||
* clocking data back in. Patches gladly accepted! | |||
*/ | |||
/** | |||
* Set the current JTAG core execution error, unless one was set | |||
* by a previous call previously. Driver or application code must | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef MINIDRIVER_H | |||
#define MINIDRIVER_H | |||
@@ -45,26 +46,26 @@ | |||
* - default_interface_jtag_execute_queue() | |||
*/ | |||
// this header will be provided by the minidriver implementation, | |||
// and it may provide additional declarations that must be defined. | |||
/* this header will be provided by the minidriver implementation, */ | |||
/* and it may provide additional declarations that must be defined. */ | |||
#include <jtag/minidriver_imp.h> | |||
int interface_jtag_add_ir_scan(struct jtag_tap* active, | |||
const struct scan_field* fields, | |||
int interface_jtag_add_ir_scan(struct jtag_tap *active, | |||
const struct scan_field *fields, | |||
tap_state_t endstate); | |||
int interface_jtag_add_plain_ir_scan( | |||
int num_bits, const uint8_t *out_bits, uint8_t *in_bits, | |||
tap_state_t endstate); | |||
int interface_jtag_add_dr_scan(struct jtag_tap* active, | |||
int num_fields, const struct scan_field* fields, | |||
int interface_jtag_add_dr_scan(struct jtag_tap *active, | |||
int num_fields, const struct scan_field *fields, | |||
tap_state_t endstate); | |||
int interface_jtag_add_plain_dr_scan( | |||
int num_bits, const uint8_t *out_bits, uint8_t *in_bits, | |||
tap_state_t endstate); | |||
int interface_jtag_add_tlr(void); | |||
int interface_jtag_add_pathmove(int num_states, const tap_state_t* path); | |||
int interface_jtag_add_pathmove(int num_states, const tap_state_t *path); | |||
int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate); | |||
int interface_add_tms_seq(unsigned num_bits, | |||
@@ -89,4 +90,4 @@ int interface_jtag_execute_queue(void); | |||
*/ | |||
int default_interface_jtag_execute_queue(void); | |||
#endif // MINIDRIVER_H | |||
#endif /* MINIDRIVER_H */ |
@@ -1,12 +1,29 @@ | |||
// | |||
/*************************************************************************** | |||
* Copyright (C) 2009-2010 by David Brownell * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* 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., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
/* Bits in SWD command packets, written from host to target | |||
* first bit on the wire is START | |||
*/ | |||
#define SWD_CMD_START (1 << 0) /* always set */ | |||
#define SWD_CMD_APnDP (1 << 1) /* set only for AP access */ | |||
#define SWD_CMD_RnW (1 << 2) /* set only for read access */ | |||
#define SWD_CMD_A32 (3 << 3) /* bits A[3:2] of register addr */ | |||
#define SWD_CMD_RnW (1 << 2) /* set only for read access */ | |||
#define SWD_CMD_A32 (3 << 3) /* bits A[3:2] of register addr */ | |||
#define SWD_CMD_PARITY (1 << 5) /* parity of APnDP|RnW|A32 */ | |||
#define SWD_CMD_STOP (0 << 6) /* always clear for synch SWD */ | |||
#define SWD_CMD_PARK (0 << 7) /* not driven by host (pull high) */ | |||
@@ -33,7 +50,7 @@ static inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum) | |||
| (is_read ? SWD_CMD_RnW : 0) | |||
| ((regnum & 0xc) << 1); | |||
//8 cmd bits 4:1 may be set | |||
/* 8 cmd bits 4:1 may be set */ | |||
if (nibble_parity(cmd >> 1)) | |||
cmd |= SWD_CMD_PARITY; | |||
@@ -75,7 +92,7 @@ struct swd_driver { | |||
* @param where to store value to read from register | |||
* | |||
* @return SWD_ACK_* code for the transaction | |||
* or (negative) fault code | |||
* or (negative) fault code | |||
*/ | |||
int (*read_reg)(uint8_t cmd, uint32_t *value); | |||
@@ -86,7 +103,7 @@ struct swd_driver { | |||
* @param value to be written to the register | |||
* | |||
* @return SWD_ACK_* code for the transaction | |||
* or (negative) fault code | |||
* or (negative) fault code | |||
*/ | |||
int (*write_reg)(uint8_t cmd, uint32_t value); | |||
@@ -27,6 +27,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -49,8 +50,8 @@ | |||
*/ | |||
static const Jim_Nvp nvp_jtag_tap_event[] = { | |||
{ .value = JTAG_TRST_ASSERTED, .name = "post-reset" }, | |||
{ .value = JTAG_TAP_EVENT_SETUP, .name = "setup" }, | |||
{ .value = JTAG_TRST_ASSERTED, .name = "post-reset" }, | |||
{ .value = JTAG_TAP_EVENT_SETUP, .name = "setup" }, | |||
{ .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" }, | |||
{ .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" }, | |||
@@ -72,15 +73,14 @@ struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) | |||
static bool scan_is_safe(tap_state_t state) | |||
{ | |||
switch (state) | |||
{ | |||
case TAP_RESET: | |||
case TAP_IDLE: | |||
case TAP_DRPAUSE: | |||
case TAP_IRPAUSE: | |||
return true; | |||
default: | |||
return false; | |||
switch (state) { | |||
case TAP_RESET: | |||
case TAP_IDLE: | |||
case TAP_DRPAUSE: | |||
case TAP_IRPAUSE: | |||
return true; | |||
default: | |||
return false; | |||
} | |||
} | |||
@@ -103,8 +103,7 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args | |||
* args[N-2] = "-endstate" | |||
* args[N-1] = statename | |||
*/ | |||
if ((argc < 4) || ((argc % 2) != 0)) | |||
{ | |||
if ((argc < 4) || ((argc % 2) != 0)) { | |||
Jim_WrongNumArgs(interp, 1, args, "wrong arguments"); | |||
return JIM_ERR; | |||
} | |||
@@ -115,16 +114,14 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args | |||
/* validate arguments as numbers */ | |||
e = JIM_OK; | |||
for (i = 2; i < argc; i += 2) | |||
{ | |||
for (i = 2; i < argc; i += 2) { | |||
long bits; | |||
const char *cp; | |||
e = Jim_GetLong(interp, args[i], &bits); | |||
/* If valid - try next arg */ | |||
if (e == JIM_OK) { | |||
if (e == JIM_OK) | |||
continue; | |||
} | |||
/* Not valid.. are we at the end? */ | |||
if (((i + 2) != argc)) { | |||
@@ -148,11 +145,11 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args | |||
endstate = tap_state_by_name(cp); | |||
if (endstate < 0) { | |||
/* update the error message */ | |||
Jim_SetResultFormatted(interp,"endstate: %s invalid", cp); | |||
Jim_SetResultFormatted(interp, "endstate: %s invalid", cp); | |||
} else { | |||
if (!scan_is_safe(endstate)) | |||
LOG_WARNING("drscan with unsafe " | |||
"endstate \"%s\"", cp); | |||
"endstate \"%s\"", cp); | |||
/* valid - so clear the error */ | |||
e = JIM_OK; | |||
@@ -162,23 +159,20 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args | |||
} | |||
/* Still an error? */ | |||
if (e != JIM_OK) { | |||
return e; /* too bad */ | |||
} | |||
} /* validate args */ | |||
if (e != JIM_OK) | |||
return e; /* too bad */ | |||
} /* validate args */ | |||
assert(e == JIM_OK); | |||
tap = jtag_tap_by_jim_obj(interp, args[1]); | |||
if (tap == NULL) { | |||
if (tap == NULL) | |||
return JIM_ERR; | |||
} | |||
num_fields = (argc-2)/2; | |||
assert(num_fields > 0); | |||
fields = malloc(sizeof(struct scan_field) * num_fields); | |||
for (i = 2; i < argc; i += 2) | |||
{ | |||
for (i = 2; i < argc; i += 2) { | |||
long bits; | |||
int len; | |||
const char *str; | |||
@@ -187,7 +181,7 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args | |||
str = Jim_GetString(args[i + 1], &len); | |||
fields[field_count].num_bits = bits; | |||
void * t = malloc(DIV_ROUND_UP(bits, 8)); | |||
void *t = malloc(DIV_ROUND_UP(bits, 8)); | |||
fields[field_count].out_value = t; | |||
str_to_buf(str, len, t, bits, 0); | |||
fields[field_count].in_value = t; | |||
@@ -197,16 +191,14 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args | |||
jtag_add_dr_scan(tap, num_fields, fields, endstate); | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
{ | |||
Jim_SetResultString(interp, "drscan: jtag execute failed",-1); | |||
if (retval != ERROR_OK) { | |||
Jim_SetResultString(interp, "drscan: jtag execute failed", -1); | |||
return JIM_ERR; | |||
} | |||
field_count = 0; | |||
Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); | |||
for (i = 2; i < argc; i += 2) | |||
{ | |||
for (i = 2; i < argc; i += 2) { | |||
long bits; | |||
char *str; | |||
@@ -231,8 +223,7 @@ static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *ar | |||
{ | |||
tap_state_t states[8]; | |||
if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1))) | |||
{ | |||
if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1))) { | |||
Jim_WrongNumArgs(interp, 1, args, "wrong arguments"); | |||
return JIM_ERR; | |||
} | |||
@@ -240,30 +231,26 @@ static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *ar | |||
script_debug(interp, "pathmove", argc, args); | |||
int i; | |||
for (i = 0; i < argc-1; i++) | |||
{ | |||
for (i = 0; i < argc-1; i++) { | |||
const char *cp; | |||
cp = Jim_GetString(args[i + 1], NULL); | |||
states[i] = tap_state_by_name(cp); | |||
if (states[i] < 0) | |||
{ | |||
if (states[i] < 0) { | |||
/* update the error message */ | |||
Jim_SetResultFormatted(interp,"endstate: %s invalid", cp); | |||
Jim_SetResultFormatted(interp, "endstate: %s invalid", cp); | |||
return JIM_ERR; | |||
} | |||
} | |||
if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue()!= ERROR_OK)) | |||
{ | |||
Jim_SetResultString(interp, "pathmove: jtag execute failed",-1); | |||
if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue() != ERROR_OK)) { | |||
Jim_SetResultString(interp, "pathmove: jtag execute failed", -1); | |||