Add JTAG tap events for enable/disable
git-svn-id: svn://svn.berlios.de/openocd/trunk@1237 b42882b7-edfa-0310-969c-e2dbd0fdcd60__archive__
parent
bcde5b3830
commit
846a2589a4
185
src/jtag/jtag.c
185
src/jtag/jtag.c
|
@ -110,6 +110,13 @@ char* jtag_event_strings[] =
|
||||||
"JTAG controller reset (RESET or TRST)"
|
"JTAG controller reset (RESET or TRST)"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Jim_Nvp nvp_jtag_tap_event[] = {
|
||||||
|
{ .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" },
|
||||||
|
{ .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" },
|
||||||
|
|
||||||
|
{ .name = NULL, .value = -1 }
|
||||||
|
};
|
||||||
|
|
||||||
/* kludge!!!! these are just global variables that the
|
/* kludge!!!! these are just global variables that the
|
||||||
* interface use internally. They really belong
|
* interface use internally. They really belong
|
||||||
* inside the drivers, but we don't want to break
|
* inside the drivers, but we don't want to break
|
||||||
|
@ -1699,6 +1706,104 @@ int jtag_validate_chain(void)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum jtag_tap_cfg_param {
|
||||||
|
JCFG_EVENT
|
||||||
|
};
|
||||||
|
|
||||||
|
static Jim_Nvp nvp_config_opts[] = {
|
||||||
|
{ .name = "-event", .value = JCFG_EVENT },
|
||||||
|
|
||||||
|
{ .name = NULL, .value = -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
jtag_tap_configure_cmd( Jim_GetOptInfo *goi,
|
||||||
|
jtag_tap_t * tap)
|
||||||
|
{
|
||||||
|
Jim_Nvp *n;
|
||||||
|
Jim_Obj *o;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
/* parse config or cget options */
|
||||||
|
while (goi->argc > 0) {
|
||||||
|
Jim_SetEmptyResult (goi->interp);
|
||||||
|
|
||||||
|
e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
|
||||||
|
if (e != JIM_OK) {
|
||||||
|
Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (n->value) {
|
||||||
|
case JCFG_EVENT:
|
||||||
|
if (goi->argc == 0) {
|
||||||
|
Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ..." );
|
||||||
|
return JIM_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = Jim_GetOpt_Nvp( goi, nvp_jtag_tap_event, &n );
|
||||||
|
if (e != JIM_OK) {
|
||||||
|
Jim_GetOpt_NvpUnknown(goi, nvp_jtag_tap_event, 1);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (goi->isconfigure) {
|
||||||
|
if (goi->argc != 1) {
|
||||||
|
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
|
||||||
|
return JIM_ERR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (goi->argc != 0) {
|
||||||
|
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
|
||||||
|
return JIM_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
jtag_tap_event_action_t *jteap;
|
||||||
|
|
||||||
|
jteap = tap->event_action;
|
||||||
|
/* replace existing? */
|
||||||
|
while (jteap) {
|
||||||
|
if (jteap->event == n->value) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
jteap = jteap->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (goi->isconfigure) {
|
||||||
|
if (jteap == NULL) {
|
||||||
|
/* create new */
|
||||||
|
jteap = calloc(1, sizeof (*jteap));
|
||||||
|
}
|
||||||
|
jteap->event = n->value;
|
||||||
|
Jim_GetOpt_Obj( goi, &o);
|
||||||
|
if (jteap->body) {
|
||||||
|
Jim_DecrRefCount(interp, jteap->body);
|
||||||
|
}
|
||||||
|
jteap->body = Jim_DuplicateObj(goi->interp, o);
|
||||||
|
Jim_IncrRefCount(jteap->body);
|
||||||
|
|
||||||
|
/* add to head of event list */
|
||||||
|
jteap->next = tap->event_action;
|
||||||
|
tap->event_action = jteap;
|
||||||
|
Jim_SetEmptyResult(goi->interp);
|
||||||
|
} else {
|
||||||
|
/* get */
|
||||||
|
if (jteap == NULL) {
|
||||||
|
Jim_SetEmptyResult(goi->interp);
|
||||||
|
} else {
|
||||||
|
Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, jteap->body));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* loop for more */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* while (goi->argc) */
|
||||||
|
|
||||||
|
return JIM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
jim_newtap_cmd( Jim_GetOptInfo *goi )
|
jim_newtap_cmd( Jim_GetOptInfo *goi )
|
||||||
|
@ -1901,6 +2006,7 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
|
||||||
Jim_GetOptInfo goi;
|
Jim_GetOptInfo goi;
|
||||||
int e;
|
int e;
|
||||||
Jim_Nvp *n;
|
Jim_Nvp *n;
|
||||||
|
Jim_Obj *o;
|
||||||
struct command_context_s *context;
|
struct command_context_s *context;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -1909,7 +2015,9 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
|
||||||
JTAG_CMD_NEWTAP,
|
JTAG_CMD_NEWTAP,
|
||||||
JTAG_CMD_TAPENABLE,
|
JTAG_CMD_TAPENABLE,
|
||||||
JTAG_CMD_TAPDISABLE,
|
JTAG_CMD_TAPDISABLE,
|
||||||
JTAG_CMD_TAPISENABLED
|
JTAG_CMD_TAPISENABLED,
|
||||||
|
JTAG_CMD_CONFIGURE,
|
||||||
|
JTAG_CMD_CGET
|
||||||
};
|
};
|
||||||
|
|
||||||
const Jim_Nvp jtag_cmds[] = {
|
const Jim_Nvp jtag_cmds[] = {
|
||||||
|
@ -1919,6 +2027,8 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
|
||||||
{ .name = "tapisenabled" , .value = JTAG_CMD_TAPISENABLED },
|
{ .name = "tapisenabled" , .value = JTAG_CMD_TAPISENABLED },
|
||||||
{ .name = "tapenable" , .value = JTAG_CMD_TAPENABLE },
|
{ .name = "tapenable" , .value = JTAG_CMD_TAPENABLE },
|
||||||
{ .name = "tapdisable" , .value = JTAG_CMD_TAPDISABLE },
|
{ .name = "tapdisable" , .value = JTAG_CMD_TAPDISABLE },
|
||||||
|
{ .name = "configure" , .value = JTAG_CMD_CONFIGURE },
|
||||||
|
{ .name = "cget" , .value = JTAG_CMD_CGET },
|
||||||
|
|
||||||
{ .name = NULL, .value = -1 },
|
{ .name = NULL, .value = -1 },
|
||||||
};
|
};
|
||||||
|
@ -1977,10 +2087,12 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
|
||||||
// below
|
// below
|
||||||
break;
|
break;
|
||||||
case JTAG_CMD_TAPENABLE:
|
case JTAG_CMD_TAPENABLE:
|
||||||
|
jtag_tap_handle_event( t, JTAG_TAP_EVENT_ENABLE);
|
||||||
e = 1;
|
e = 1;
|
||||||
t->enabled = e;
|
t->enabled = e;
|
||||||
break;
|
break;
|
||||||
case JTAG_CMD_TAPDISABLE:
|
case JTAG_CMD_TAPDISABLE:
|
||||||
|
jtag_tap_handle_event( t, JTAG_TAP_EVENT_DISABLE);
|
||||||
e = 0;
|
e = 0;
|
||||||
t->enabled = e;
|
t->enabled = e;
|
||||||
break;
|
break;
|
||||||
|
@ -1988,6 +2100,46 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
|
||||||
Jim_SetResult( goi.interp, Jim_NewIntObj( goi.interp, e ) );
|
Jim_SetResult( goi.interp, Jim_NewIntObj( goi.interp, e ) );
|
||||||
return JIM_OK;
|
return JIM_OK;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JTAG_CMD_CGET:
|
||||||
|
if( goi.argc < 2 ){
|
||||||
|
Jim_WrongNumArgs( goi.interp, 0, NULL, "?tap-name? -option ...");
|
||||||
|
return JIM_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
jtag_tap_t *t;
|
||||||
|
|
||||||
|
Jim_GetOpt_Obj(&goi, &o);
|
||||||
|
t = jtag_TapByJimObj( goi.interp, o );
|
||||||
|
if( t == NULL ){
|
||||||
|
return JIM_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
goi.isconfigure = 0;
|
||||||
|
return jtag_tap_configure_cmd( &goi, t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JTAG_CMD_CONFIGURE:
|
||||||
|
if( goi.argc < 3 ){
|
||||||
|
Jim_WrongNumArgs( goi.interp, 0, NULL, "?tap-name? -option ?VALUE? ...");
|
||||||
|
return JIM_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
jtag_tap_t *t;
|
||||||
|
|
||||||
|
Jim_GetOpt_Obj(&goi, &o);
|
||||||
|
t = jtag_TapByJimObj( goi.interp, o );
|
||||||
|
if( t == NULL ){
|
||||||
|
return JIM_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
goi.isconfigure = 1;
|
||||||
|
return jtag_tap_configure_cmd( &goi, t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2763,3 +2915,34 @@ int jtag_srst_asserted(int *srst_asserted)
|
||||||
return jtag->srst_asserted(srst_asserted);
|
return jtag->srst_asserted(srst_asserted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_event e)
|
||||||
|
{
|
||||||
|
jtag_tap_event_action_t * jteap;
|
||||||
|
int done;
|
||||||
|
|
||||||
|
jteap = tap->event_action;
|
||||||
|
|
||||||
|
done = 0;
|
||||||
|
while (jteap) {
|
||||||
|
if (jteap->event == e) {
|
||||||
|
done = 1;
|
||||||
|
LOG_DEBUG( "JTAG tap: %s event: %d (%s) action: %s\n",
|
||||||
|
tap->dotted_name,
|
||||||
|
e,
|
||||||
|
Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e)->name,
|
||||||
|
Jim_GetString(jteap->body, NULL) );
|
||||||
|
if (Jim_EvalObj(interp, jteap->body) != JIM_OK) {
|
||||||
|
Jim_PrintErrorMessage(interp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jteap = jteap->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
LOG_DEBUG( "event %d %s - no action",
|
||||||
|
e,
|
||||||
|
Jim_Nvp_value2name_simple( nvp_jtag_tap_event, e)->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,9 @@ typedef struct jtag_command_s
|
||||||
|
|
||||||
extern jtag_command_t *jtag_command_queue;
|
extern jtag_command_t *jtag_command_queue;
|
||||||
|
|
||||||
|
// forward declaration
|
||||||
|
typedef struct jtag_tap_event_action_s jtag_tap_event_action_t;
|
||||||
|
|
||||||
// this is really: typedef jtag_tap_t
|
// this is really: typedef jtag_tap_t
|
||||||
// But - the typedef is done in "types.h"
|
// But - the typedef is done in "types.h"
|
||||||
// due to "forward decloration reasons"
|
// due to "forward decloration reasons"
|
||||||
|
@ -178,6 +181,9 @@ struct jtag_tap_s
|
||||||
u8 expected_ids_cnt;/* Number of expected identification codes */
|
u8 expected_ids_cnt;/* Number of expected identification codes */
|
||||||
u8 *cur_instr; /* current instruction */
|
u8 *cur_instr; /* current instruction */
|
||||||
int bypass; /* bypass register selected */
|
int bypass; /* bypass register selected */
|
||||||
|
|
||||||
|
jtag_tap_event_action_t *event_action;
|
||||||
|
|
||||||
jtag_tap_t *next_tap;
|
jtag_tap_t *next_tap;
|
||||||
};
|
};
|
||||||
extern jtag_tap_t *jtag_AllTaps(void);
|
extern jtag_tap_t *jtag_AllTaps(void);
|
||||||
|
@ -273,6 +279,20 @@ enum jtag_event
|
||||||
|
|
||||||
extern char * jtag_event_strings[];
|
extern char * jtag_event_strings[];
|
||||||
|
|
||||||
|
enum jtag_tap_event
|
||||||
|
{
|
||||||
|
JTAG_TAP_EVENT_ENABLE,
|
||||||
|
JTAG_TAP_EVENT_DISABLE
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const Jim_Nvp nvp_jtag_tap_event[];
|
||||||
|
|
||||||
|
struct jtag_tap_event_action_s {
|
||||||
|
enum jtag_tap_event event;
|
||||||
|
Jim_Obj *body;
|
||||||
|
jtag_tap_event_action_t *next;
|
||||||
|
};
|
||||||
|
|
||||||
extern int jtag_trst;
|
extern int jtag_trst;
|
||||||
extern int jtag_srst;
|
extern int jtag_srst;
|
||||||
|
|
||||||
|
@ -462,6 +482,8 @@ extern int jtag_register_event_callback(int (*callback)(enum jtag_event event, v
|
||||||
|
|
||||||
extern int jtag_verify_capture_ir;
|
extern int jtag_verify_capture_ir;
|
||||||
|
|
||||||
|
void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_event e);
|
||||||
|
|
||||||
/* error codes
|
/* error codes
|
||||||
* JTAG subsystem uses codes between -100 and -199 */
|
* JTAG subsystem uses codes between -100 and -199 */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue