target: Use proper data types for timer callback
[openocd.git] / src / target / target.c
index 8715883..a3230d2 100644 (file)
@@ -517,9 +517,7 @@ struct target *get_target_by_num(int num)
 
 struct target *get_current_target(struct command_context *cmd_ctx)
 {
-       struct target *target = cmd_ctx->current_target_override
-               ? cmd_ctx->current_target_override
-               : cmd_ctx->current_target;
+       struct target *target = get_current_target_or_null(cmd_ctx);
 
        if (target == NULL) {
                LOG_ERROR("BUG: current_target out of bounds");
@@ -529,6 +527,13 @@ struct target *get_current_target(struct command_context *cmd_ctx)
        return target;
 }
 
+struct target *get_current_target_or_null(struct command_context *cmd_ctx)
+{
+       return cmd_ctx->current_target_override
+               ? cmd_ctx->current_target_override
+               : cmd_ctx->current_target;
+}
+
 int target_poll(struct target *target)
 {
        int retval;
@@ -1455,7 +1460,8 @@ int target_register_trace_callback(int (*callback)(struct target *target,
        return ERROR_OK;
 }
 
-int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
+int target_register_timer_callback(int (*callback)(void *priv),
+               unsigned int time_ms, enum target_timer_type type, void *priv)
 {
        struct target_timer_callback **callbacks_p = &target_timer_callbacks;
 
@@ -1470,7 +1476,7 @@ int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int
 
        (*callbacks_p) = malloc(sizeof(struct target_timer_callback));
        (*callbacks_p)->callback = callback;
-       (*callbacks_p)->periodic = periodic;
+       (*callbacks_p)->type = type;
        (*callbacks_p)->time_ms = time_ms;
        (*callbacks_p)->removed = false;
 
@@ -1620,7 +1626,7 @@ static int target_call_timer_callback(struct target_timer_callback *cb,
 {
        cb->callback(cb->priv);
 
-       if (cb->periodic)
+       if (cb->type == TARGET_TIMER_TYPE_PERIODIC)
                return target_timer_callback_periodic_restart(cb, now);
 
        return target_unregister_timer_callback(cb->callback, cb->priv);
@@ -1654,7 +1660,7 @@ static int target_call_timer_callbacks_check_time(int checktime)
                }
 
                bool call_it = (*callback)->callback &&
-                       ((!checktime && (*callback)->periodic) ||
+                       ((!checktime && (*callback)->type == TARGET_TIMER_TYPE_PERIODIC) ||
                         timeval_compare(&now, &(*callback)->when) >= 0);
 
                if (call_it)
@@ -1914,6 +1920,65 @@ int target_free_working_area(struct target *target, struct working_area *area)
        return target_free_working_area_restore(target, area, 1);
 }
 
+/* free resources and restore memory, if restoring memory fails,
+ * free up resources anyway
+ */
+static void target_free_all_working_areas_restore(struct target *target, int restore)
+{
+       struct working_area *c = target->working_areas;
+
+       LOG_DEBUG("freeing all working areas");
+
+       /* Loop through all areas, restoring the allocated ones and marking them as free */
+       while (c) {
+               if (!c->free) {
+                       if (restore)
+                               target_restore_working_area(target, c);
+                       c->free = true;
+                       *c->user = NULL; /* Same as above */
+                       c->user = NULL;
+               }
+               c = c->next;
+       }
+
+       /* Run a merge pass to combine all areas into one */
+       target_merge_working_areas(target);
+
+       print_wa_layout(target);
+}
+
+void target_free_all_working_areas(struct target *target)
+{
+       target_free_all_working_areas_restore(target, 1);
+
+       /* Now we have none or only one working area marked as free */
+       if (target->working_areas) {
+               /* Free the last one to allow on-the-fly moving and resizing */
+               free(target->working_areas->backup);
+               free(target->working_areas);
+               target->working_areas = NULL;
+       }
+}
+
+/* Find the largest number of bytes that can be allocated */
+uint32_t target_get_working_area_avail(struct target *target)
+{
+       struct working_area *c = target->working_areas;
+       uint32_t max_size = 0;
+
+       if (c == NULL)
+               return target->working_area_size;
+
+       while (c) {
+               if (c->free && max_size < c->size)
+                       max_size = c->size;
+
+               c = c->next;
+       }
+
+       return max_size;
+}
+
 static void target_destroy(struct target *target)
 {
        if (target->type->deinit_target)
@@ -1933,11 +1998,6 @@ static void target_destroy(struct target *target)
        }
 
        target_free_all_working_areas(target);
-       /* Now we have none or only one working area marked as free */
-       if (target->working_areas) {
-               free(target->working_areas->backup);
-               free(target->working_areas);
-       }
 
        /* release the targets SMP list */
        if (target->smp) {
@@ -1988,57 +2048,6 @@ void target_quit(void)
        all_targets = NULL;
 }
 
-/* free resources and restore memory, if restoring memory fails,
- * free up resources anyway
- */
-static void target_free_all_working_areas_restore(struct target *target, int restore)
-{
-       struct working_area *c = target->working_areas;
-
-       LOG_DEBUG("freeing all working areas");
-
-       /* Loop through all areas, restoring the allocated ones and marking them as free */
-       while (c) {
-               if (!c->free) {
-                       if (restore)
-                               target_restore_working_area(target, c);
-                       c->free = true;
-                       *c->user = NULL; /* Same as above */
-                       c->user = NULL;
-               }
-               c = c->next;
-       }
-
-       /* Run a merge pass to combine all areas into one */
-       target_merge_working_areas(target);
-
-       print_wa_layout(target);
-}
-
-void target_free_all_working_areas(struct target *target)
-{
-       target_free_all_working_areas_restore(target, 1);
-}
-
-/* Find the largest number of bytes that can be allocated */
-uint32_t target_get_working_area_avail(struct target *target)
-{
-       struct working_area *c = target->working_areas;
-       uint32_t max_size = 0;
-
-       if (c == NULL)
-               return target->working_area_size;
-
-       while (c) {
-               if (c->free && max_size < c->size)
-                       max_size = c->size;
-
-               c = c->next;
-       }
-
-       return max_size;
-}
-
 int target_arch_state(struct target *target)
 {
        int retval;
@@ -3711,38 +3720,31 @@ static int handle_bp_command_set(struct command_context *cmd_ctx,
 
        if (asid == 0) {
                retval = breakpoint_add(target, addr, length, hw);
+               /* error is always logged in breakpoint_add(), do not print it again */
                if (ERROR_OK == retval)
                        command_print(cmd_ctx, "breakpoint set at " TARGET_ADDR_FMT "", addr);
-               else {
-                       LOG_ERROR("Failure setting breakpoint, the same address(IVA) is already used");
-                       return retval;
-               }
+
        } else if (addr == 0) {
                if (target->type->add_context_breakpoint == NULL) {
-                       LOG_WARNING("Context breakpoint not available");
-                       return ERROR_OK;
+                       LOG_ERROR("Context breakpoint not available");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
                retval = context_breakpoint_add(target, asid, length, hw);
+               /* error is always logged in context_breakpoint_add(), do not print it again */
                if (ERROR_OK == retval)
                        command_print(cmd_ctx, "Context breakpoint set at 0x%8.8" PRIx32 "", asid);
-               else {
-                       LOG_ERROR("Failure setting breakpoint, the same address(CONTEXTID) is already used");
-                       return retval;
-               }
+
        } else {
                if (target->type->add_hybrid_breakpoint == NULL) {
-                       LOG_WARNING("Hybrid breakpoint not available");
-                       return ERROR_OK;
+                       LOG_ERROR("Hybrid breakpoint not available");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
                retval = hybrid_breakpoint_add(target, addr, asid, length, hw);
+               /* error is always logged in hybrid_breakpoint_add(), do not print it again */
                if (ERROR_OK == retval)
                        command_print(cmd_ctx, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid);
-               else {
-                       LOG_ERROR("Failure setting breakpoint, the same address is already used");
-                       return retval;
-               }
        }
-       return ERROR_OK;
+       return retval;
 }
 
 COMMAND_HANDLER(handle_bp_command)
@@ -5874,8 +5876,7 @@ static const struct command_registration target_subcommand_handlers[] = {
        },
        {
                .name = "create",
-               /* REVISIT this should be COMMAND_CONFIG ... */
-               .mode = COMMAND_ANY,
+               .mode = COMMAND_CONFIG,
                .jim_handler = jim_target_create,
                .usage = "name type '-chain-position' name [options ...]",
                .help = "Creates and selects a new target",