If halt times out, stop GDB. Allows e.g. manual reset via monitor commands.
[fw/openocd] / src / target / target.c
index 253a7e464efa8970a2263384a8c8268e20e2aaa2..8bb9371f903bca836e16a17021668ac79dc8a21e 100644 (file)
@@ -269,8 +269,6 @@ static int new_target_number(void)
        return x + 1;
 }
 
-static int target_continuous_poll = 1;
-
 /* read a uint32_t from a buffer in target memory endianness */
 uint32_t target_buffer_get_u32(target_t *target, const uint8_t *buffer)
 {
@@ -380,24 +378,57 @@ target_t* get_current_target(command_context_t *cmd_ctx)
 
 int target_poll(struct target_s *target)
 {
+       int retval;
+
        /* We can't poll until after examine */
        if (!target_was_examined(target))
        {
                /* Fail silently lest we pollute the log */
                return ERROR_FAIL;
        }
-       return target->type->poll(target);
+
+       retval = target->type->poll(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (target->halt_issued)
+       {
+               if (target->state == TARGET_HALTED)
+               {
+                       target->halt_issued = false;
+               } else
+               {
+                       long long t = timeval_ms() - target->halt_issued_time;
+                       if (t>1000)
+                       {
+                               target->halt_issued = false;
+                               LOG_INFO("Halt timed out, wake up GDB.");
+                               target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
+                       }
+               }
+       }
+
+       return ERROR_OK;
 }
 
 int target_halt(struct target_s *target)
 {
+       int retval;
        /* We can't poll until after examine */
        if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
-       return target->type->halt(target);
+
+       retval = target->type->halt(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       target->halt_issued = true;
+       target->halt_issued_time = timeval_ms();
+
+       return ERROR_OK;
 }
 
 int target_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
@@ -436,13 +467,14 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
         * more predictable, i.e. dr/irscan & pathmove in events will
         * not have JTAG operations injected into the middle of a sequence.
         */
-       int save_poll = target_continuous_poll;
-       target_continuous_poll = 0;
+       bool save_poll = jtag_poll_get_enabled();
+
+       jtag_poll_set_enabled(false);
 
        sprintf(buf, "ocd_process_reset %s", n->name);
        retval = Jim_Eval(interp, buf);
 
-       target_continuous_poll = save_poll;
+       jtag_poll_set_enabled(save_poll);
 
        if (retval != JIM_OK) {
                Jim_PrintErrorMessage(interp);
@@ -1726,7 +1758,7 @@ int handle_target(void *priv)
         * Skip targets that are currently disabled.
         */
        for (target_t *target = all_targets;
-                       target_continuous_poll && target;
+                       is_jtag_poll_safe() && target;
                        target = target->next)
        {
                if (!target->tap->enabled)
@@ -1886,7 +1918,7 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha
        if (argc == 0)
        {
                command_print(cmd_ctx, "background polling: %s",
-                               target_continuous_poll ?  "on" : "off");
+                               jtag_poll_get_enabled() ? "on" : "off");
                command_print(cmd_ctx, "TAP: %s (%s)",
                                target->tap->dotted_name,
                                target->tap->enabled ? "enabled" : "disabled");
@@ -1902,11 +1934,11 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha
        {
                if (strcmp(args[0], "on") == 0)
                {
-                       target_continuous_poll = 1;
+                       jtag_poll_set_enabled(true);
                }
                else if (strcmp(args[0], "off") == 0)
                {
-                       target_continuous_poll = 0;
+                       jtag_poll_set_enabled(false);
                }
                else
                {
@@ -4237,6 +4269,8 @@ static int target_create(Jim_GetOptInfo *goi)
 
        target->display             = 1;
 
+       target->halt_issued                     = false;
+
        /* initialize trace information */
        target->trace_info = malloc(sizeof(trace_t));
        target->trace_info->num_trace_points         = 0;