- added synchronous reset patch, Thanks Øyvind Harboe
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 7 Feb 2008 20:20:11 +0000 (20:20 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 7 Feb 2008 20:20:11 +0000 (20:20 +0000)
- added target_init_reset which calls target_process_reset after all drivers have been initialised

git-svn-id: svn://svn.berlios.de/openocd/trunk@284 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/openocd.c
src/target/target.c
src/target/target.h

index 92305fb73cd46eef8c851801dafb4e8853235be7..a8f12a8b93777c337853d584be414626ce36995e 100644 (file)
@@ -135,7 +135,12 @@ int main(int argc, char *argv[])
        /* initialize telnet subsystem */
        telnet_init("Open On-Chip Debugger");
        gdb_init();
-
+       
+       /* call any target resets */
+       if (target_init_reset(cmd_ctx) != ERROR_OK)
+               return EXIT_FAILURE;
+       DEBUG("target init reset complete");
+       
        /* handle network connections */
        server_loop(cmd_ctx);
        
index 25df2a2b85e4048e8f209b90f9c95f881149ca51..114832783b4427960d450df0089ae6507f53b320 100644 (file)
@@ -253,11 +253,28 @@ int target_process_reset(struct command_context_s *cmd_ctx)
 {
        int retval = ERROR_OK;
        target_t *target;
+       struct timeval timeout, now;
        
        /* prepare reset_halt where necessary */
        target = targets;
        while (target)
        {
+               if (jtag_reset_config & RESET_SRST_PULLS_TRST)
+               {
+                       switch (target->reset_mode)
+                       {
+                               case RESET_HALT:
+                                       command_print(cmd_ctx, "nSRST pulls nTRST, falling back to RESET_RUN_AND_HALT");
+                                       target->reset_mode = RESET_RUN_AND_HALT;
+                                       break;
+                               case RESET_INIT:
+                                       command_print(cmd_ctx, "nSRST pulls nTRST, falling back to RESET_RUN_AND_INIT");
+                                       target->reset_mode = RESET_RUN_AND_INIT;
+                                       break;
+                               default:
+                                       break;
+                       } 
+               }
                switch (target->reset_mode)
                {
                        case RESET_HALT:
@@ -316,6 +333,42 @@ int target_process_reset(struct command_context_s *cmd_ctx)
                target = target->next;
        }
        jtag_execute_queue();
+
+       /* Wait for reset to complete, maximum 5 seconds. */    
+       gettimeofday(&timeout, NULL);
+       timeval_add_time(&timeout, 5, 0);
+       for(;;)
+       {
+               gettimeofday(&now, NULL);
+               
+               target_call_timer_callbacks();
+       
+               target = targets;
+               while (target)
+               {
+                       target->type->poll(target);
+                       if ((target->reset_mode == RESET_RUN_AND_INIT) || (target->reset_mode == RESET_RUN_AND_HALT))
+                       {
+                               if (target->state != TARGET_HALTED)
+                               {
+                                       if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
+                                       {
+                                               command_print(cmd_ctx, "Timed out waiting for reset");
+                                               goto done;
+                                       }
+                                       usleep(100*1000); /* Do not eat all cpu */
+                                       goto again;
+                               }
+                       }
+                       target = target->next;
+               }
+               /* All targets we're waiting for are halted */
+               break;
+               
+               again:;
+       }
+       done:
+       
        
        return retval;
 }      
@@ -340,6 +393,11 @@ int target_init(struct command_context_s *cmd_ctx)
                target_register_timer_callback(handle_target, 100, 1, NULL);
        }
                
+       return ERROR_OK;
+}
+
+int target_init_reset(struct command_context_s *cmd_ctx)
+{
        if (startup_mode == DAEMON_RESET)
                target_process_reset(cmd_ctx);
        
@@ -1358,6 +1416,10 @@ int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
                {
                        target_continous_poll = 0;
                }
+               else
+               {
+                       command_print(cmd_ctx, "arg is \"on\" or \"off\"");
+               }
        }
        
        
@@ -1482,7 +1544,8 @@ int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd,
 int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        target_t *target = get_current_target(cmd_ctx);
-       enum target_reset_mode reset_mode = RESET_RUN;
+       enum target_reset_mode reset_mode = target->reset_mode;
+       enum target_reset_mode save = target->reset_mode;
        
        DEBUG("-");
        
@@ -1515,11 +1578,17 @@ int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **ar
                        command_print(cmd_ctx, "usage: reset ['run', 'halt', 'init', 'run_and_halt', 'run_and_init]");
                        return ERROR_OK;
                }
-               target->reset_mode = reset_mode;
        }
        
+       /* temporarily modify mode of current reset target */
+       target->reset_mode = reset_mode;
+
+       /* reset *all* targets */
        target_process_reset(cmd_ctx);
        
+       /* Restore default reset mode for this target */
+    target->reset_mode = save;
+       
        return ERROR_OK;
 }
 
@@ -1803,6 +1872,7 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
        u32 address;
        u32 size;
        u8 buffer[560];
+       int retval;
        
        duration_t duration;
        char *duration_text;
@@ -1837,7 +1907,13 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
                u32 size_written;
                u32 this_run_size = (size > 560) ? 560 : size;
                
-               target->type->read_memory(target, address, 4, this_run_size / 4, buffer);
+               retval = target->type->read_memory(target, address, 4, this_run_size / 4, buffer);
+               if (retval != ERROR_OK)
+               {
+                       command_print(cmd_ctx, "Reading memory failed %d", retval);
+                       break;
+               }
+               
                fileio_write(&fileio, this_run_size, buffer, &size_written);
                
                size -= this_run_size;
@@ -1851,7 +1927,6 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
        free(duration_text);
        
        return ERROR_OK;
-
 }
 
 int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
@@ -2141,6 +2216,3 @@ int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args
        
        return ERROR_OK;
 }
-
-
-
index 46aaa7aea5efaf93b8564017c3530f951f5e5306..46ae505d3110c8f5906d06463e0e79431aaff8f1 100644 (file)
@@ -205,6 +205,7 @@ typedef struct target_timer_callback_s
 extern int target_register_commands(struct command_context_s *cmd_ctx);
 extern int target_register_user_commands(struct command_context_s *cmd_ctx);
 extern int target_init(struct command_context_s *cmd_ctx);
+extern int target_init_reset(struct command_context_s *cmd_ctx);
 extern int handle_target(void *priv);
 extern int target_process_reset(struct command_context_s *cmd_ctx);