struct target *all_targets;
static struct target_event_callback *target_event_callbacks;
static struct target_timer_callback *target_timer_callbacks;
+LIST_HEAD(target_reset_callback_list);
static const int polling_interval = 100;
static const Jim_Nvp nvp_assert[] = {
return cp;
}
+const char *target_event_name(enum target_event event)
+{
+ const char *cp;
+ cp = Jim_Nvp_value2name_simple(nvp_target_event, event)->name;
+ if (!cp) {
+ LOG_ERROR("Invalid target event: %d", (int)(event));
+ cp = "(*BUG*unknown*BUG*)";
+ }
+ return cp;
+}
+
+const char *target_reset_mode_name(enum target_reset_mode reset_mode)
+{
+ const char *cp;
+ cp = Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name;
+ if (!cp) {
+ LOG_ERROR("Invalid target reset mode: %d", (int)(reset_mode));
+ cp = "(*BUG*unknown*BUG*)";
+ }
+ return cp;
+}
+
/* determine the number of the new target */
static int new_target_number(void)
{
return ERROR_FAIL;
}
+ struct target *target;
+ for (target = all_targets; target; target = target->next)
+ target_call_reset_callbacks(target, reset_mode);
+
/* disable polling during reset to make reset event scripts
* more predictable, i.e. dr/irscan & pathmove in events will
* not have JTAG operations injected into the middle of a sequence.
/* We want any events to be processed before the prompt */
retval = target_call_timer_callbacks_now();
- struct target *target;
for (target = all_targets; target; target = target->next) {
target->type->check_reset(target);
target->running_alg = false;
return ERROR_OK;
}
+int target_register_reset_callback(int (*callback)(struct target *target,
+ enum target_reset_mode reset_mode, void *priv), void *priv)
+{
+ struct target_reset_callback *entry;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ entry = malloc(sizeof(struct target_reset_callback));
+ if (entry == NULL) {
+ LOG_ERROR("error allocating buffer for reset callback entry");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ entry->callback = callback;
+ entry->priv = priv;
+ list_add(&entry->list, &target_reset_callback_list);
+
+
+ return ERROR_OK;
+}
+
int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
{
struct target_timer_callback **callbacks_p = &target_timer_callbacks;
return ERROR_OK;
}
+int target_unregister_reset_callback(int (*callback)(struct target *target,
+ enum target_reset_mode reset_mode, void *priv), void *priv)
+{
+ struct target_reset_callback *entry;
+
+ if (callback == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ list_for_each_entry(entry, &target_reset_callback_list, list) {
+ if (entry->callback == callback && entry->priv == priv) {
+ list_del(&entry->list);
+ free(entry);
+ break;
+ }
+ }
+
+ return ERROR_OK;
+}
+
int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
{
struct target_timer_callback **p = &target_timer_callbacks;
return ERROR_OK;
}
+int target_call_reset_callbacks(struct target *target, enum target_reset_mode reset_mode)
+{
+ struct target_reset_callback *callback;
+
+ LOG_DEBUG("target reset %i (%s)", reset_mode,
+ Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name);
+
+ list_for_each_entry(callback, &target_reset_callback_list, list)
+ callback->callback(target, reset_mode, callback->priv);
+
+ return ERROR_OK;
+}
+
static int target_timer_callback_periodic_restart(
struct target_timer_callback *cb, struct timeval *now)
{
return target_create(&goi);
}
-static int jim_target_number(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-
- /* It's OK to remove this mechanism sometime after August 2010 or so */
- LOG_WARNING("don't use numbers as target identifiers; use names");
- if (goi.argc != 1) {
- Jim_SetResultFormatted(goi.interp, "usage: target number <number>");
- return JIM_ERR;
- }
- jim_wide w;
- int e = Jim_GetOpt_Wide(&goi, &w);
- if (e != JIM_OK)
- return JIM_ERR;
-
- struct target *target;
- for (target = all_targets; NULL != target; target = target->next) {
- if (target->target_number != w)
- continue;
-
- Jim_SetResultString(goi.interp, target_name(target), -1);
- return JIM_OK;
- }
- {
- Jim_Obj *wObj = Jim_NewIntObj(goi.interp, w);
- Jim_SetResultFormatted(goi.interp,
- "Target: number %#s does not exist", wObj);
- Jim_FreeNewObj(interp, wObj);
- }
- return JIM_ERR;
-}
-
-static int jim_target_count(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "<no parameters>");
- return JIM_ERR;
- }
- unsigned count = 0;
- struct target *target = all_targets;
- while (NULL != target) {
- target = target->next;
- count++;
- }
- Jim_SetResult(interp, Jim_NewIntObj(interp, count));
- return JIM_OK;
-}
-
static const struct command_registration target_subcommand_handlers[] = {
{
.name = "init",
.jim_handler = jim_target_names,
.help = "Returns the names of all targets as a list of strings",
},
- {
- .name = "number",
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_number,
- .usage = "number",
- .help = "Returns the name of the numbered target "
- "(DEPRECATED)",
- },
- {
- .name = "count",
- .mode = COMMAND_ANY,
- .jim_handler = jim_target_count,
- .help = "Returns the number of targets as an integer "
- "(DEPRECATED)",
- },
{
.name = "smp",
.mode = COMMAND_ANY,