diff options
-rw-r--r-- | src/jtag/jtag.c | 185 | ||||
-rw-r--r-- | src/jtag/jtag.h | 24 |
2 files changed, 207 insertions, 2 deletions
diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 0b70c0f1..3c05592f 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -110,6 +110,13 @@ char* jtag_event_strings[] = "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 * interface use internally. They really belong * inside the drivers, but we don't want to break @@ -1699,6 +1706,104 @@ int jtag_validate_chain(void) 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 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; int e; Jim_Nvp *n; + Jim_Obj *o; struct command_context_s *context; enum { @@ -1909,7 +2015,9 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) JTAG_CMD_NEWTAP, JTAG_CMD_TAPENABLE, JTAG_CMD_TAPDISABLE, - JTAG_CMD_TAPISENABLED + JTAG_CMD_TAPISENABLED, + JTAG_CMD_CONFIGURE, + JTAG_CMD_CGET }; 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 = "tapenable" , .value = JTAG_CMD_TAPENABLE }, { .name = "tapdisable" , .value = JTAG_CMD_TAPDISABLE }, + { .name = "configure" , .value = JTAG_CMD_CONFIGURE }, + { .name = "cget" , .value = JTAG_CMD_CGET }, { .name = NULL, .value = -1 }, }; @@ -1977,10 +2087,12 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) // below break; case JTAG_CMD_TAPENABLE: + jtag_tap_handle_event( t, JTAG_TAP_EVENT_ENABLE); e = 1; t->enabled = e; break; case JTAG_CMD_TAPDISABLE: + jtag_tap_handle_event( t, JTAG_TAP_EVENT_DISABLE); e = 0; t->enabled = e; 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 ) ); 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); } +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); + } +} + diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 3ca084ac..bd306aba 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -158,6 +158,9 @@ typedef struct jtag_command_s 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 // But - the typedef is done in "types.h" // due to "forward decloration reasons" @@ -178,6 +181,9 @@ struct jtag_tap_s u8 expected_ids_cnt;/* Number of expected identification codes */ u8 *cur_instr; /* current instruction */ int bypass; /* bypass register selected */ + + jtag_tap_event_action_t *event_action; + jtag_tap_t *next_tap; }; extern jtag_tap_t *jtag_AllTaps(void); @@ -271,7 +277,21 @@ enum jtag_event JTAG_TRST_ASSERTED }; -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_srst; @@ -462,6 +482,8 @@ extern int jtag_register_event_callback(int (*callback)(enum jtag_event event, v extern int jtag_verify_capture_ir; +void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_event e); + /* error codes * JTAG subsystem uses codes between -100 and -199 */ |