From da2bbc90fc8b1a44fe466e6f168882b65381df3e Mon Sep 17 00:00:00 2001
From: ntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Thu, 7 Feb 2008 20:20:11 +0000
Subject: - added synchronous reset patch, Thanks Øyvind Harboe - added
 target_init_reset which calls target_process_reset after all drivers have
 been initialised
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

git-svn-id: svn://svn.berlios.de/openocd/trunk@284 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/openocd.c       |  7 ++++-
 src/target/target.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 src/target/target.h |  1 +
 3 files changed, 86 insertions(+), 8 deletions(-)

(limited to 'src')

diff --git a/src/openocd.c b/src/openocd.c
index 92305fb7..a8f12a8b 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -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);
 	
diff --git a/src/target/target.c b/src/target/target.c
index 25df2a2b..11483278 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -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;
 }
-
-
-
diff --git a/src/target/target.h b/src/target/target.h
index 46aaa7ae..46ae505d 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -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);
 
-- 
cgit v1.2.3