Browse Source

build: cleanup src/jtag directory

Change-Id: I7caf57ca3d9dfbe152504472a6bb26c2a28b92e8
Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk>
Reviewed-on: http://openocd.zylin.com/423
Tested-by: jenkins
tags/v0.6.0-rc1
Spencer Oliver 10 years ago
parent
commit
38f8e5eefa
14 changed files with 911 additions and 979 deletions
  1. +34
    -43
      src/jtag/adapter.c
  2. +21
    -35
      src/jtag/commands.c
  3. +41
    -40
      src/jtag/commands.h
  4. +206
    -254
      src/jtag/core.c
  5. +24
    -0
      src/jtag/driver.h
  6. +217
    -226
      src/jtag/interface.c
  7. +14
    -15
      src/jtag/interface.h
  8. +6
    -5
      src/jtag/interfaces.c
  9. +3
    -2
      src/jtag/interfaces.h
  10. +72
    -80
      src/jtag/jtag.h
  11. +9
    -8
      src/jtag/minidriver.h
  12. +23
    -6
      src/jtag/swd.h
  13. +209
    -263
      src/jtag/tcl.c
  14. +32
    -2
      src/jtag/tcl.h

+ 34
- 43
src/jtag/adapter.c View File

@@ -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);



+ 21
- 35
src/jtag/commands.c View File

@@ -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;
}



+ 41
- 40
src/jtag/commands.h View File

@@ -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 */

+ 206
- 254
src/jtag/core.c
File diff suppressed because it is too large
View File


+ 24
- 0
src/jtag/driver.h View File

@@ -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 */

+ 217
- 226
src/jtag/interface.c View File

@@ -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;
}


+ 14
- 15
src/jtag/interface.h View File

@@ -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 */

+ 6
- 5
src/jtag/interfaces.c View File

@@ -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 */
}

+ 3
- 2
src/jtag/interfaces.h View File

@@ -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 */

+ 72
- 80
src/jtag/jtag.h View File

@@ -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


+ 9
- 8
src/jtag/minidriver.h View File

@@ -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 */

+ 23
- 6
src/jtag/swd.h View File

@@ -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);



+ 209
- 263
src/jtag/tcl.c View File

@@ -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);