From 39d80bad9bb405dab262ab2c4bedaef18d8c1df8 Mon Sep 17 00:00:00 2001
From: oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Mon, 23 Feb 2009 21:26:11 +0000
Subject: [PATCH] tinkered a bit with performance for Cortex flash programming.
 Mainly make it easier to profile as a start.

git-svn-id: svn://svn.berlios.de/openocd/trunk@1380 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/target/cortex_swjdp.c | 41 ++++++++++++++++++++++++---------------
 src/target/target.c       | 21 ++++++++++++++------
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/src/target/cortex_swjdp.c b/src/target/cortex_swjdp.c
index 974ced022..3e094d84d 100644
--- a/src/target/cortex_swjdp.c
+++ b/src/target/cortex_swjdp.c
@@ -5,6 +5,9 @@
  *   Copyright (C) 2008 by Spencer Oliver                                  *
  *   spen@spen-soft.co.uk                                                  *
  *                                                                         *
+ *   Copyright (C) 2009 by Oyvind Harboe                                   *
+ *   oyvind.harboe@zylin.com                                               *
+ *																		   *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
@@ -178,7 +181,7 @@ int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
 	int retval;
 	u32 ctrlstat;
 
-	keep_alive();
+	/* too expensive to call keep_alive() here */
 
 	/* Danger!!!! BROKEN!!!! */
 	scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
@@ -199,27 +202,33 @@ int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
 
 	swjdp->ack = swjdp->ack & 0x7;
 
-	long long then=timeval_ms();
-	while (swjdp->ack != 2)
+	if (swjdp->ack != 2)
 	{
-		if (swjdp->ack == 1)
+		long long then=timeval_ms();
+		while (swjdp->ack != 2)
 		{
-			if ((timeval_ms()-then) > 1000)
+			if (swjdp->ack == 1)
 			{
-				LOG_WARNING("Timeout (1000ms) waiting for ACK = OK/FAULT in SWJDP transaction");
+				if ((timeval_ms()-then) > 1000)
+				{
+					LOG_WARNING("Timeout (1000ms) waiting for ACK = OK/FAULT in SWJDP transaction");
+					return ERROR_JTAG_DEVICE_ERROR;
+				}
+			}
+			else
+			{
+				LOG_WARNING("Invalid ACK in SWJDP transaction");
 				return ERROR_JTAG_DEVICE_ERROR;
 			}
-		}
-		else
-		{
-			LOG_WARNING("Invalid ACK in SWJDP transaction");
-			return ERROR_JTAG_DEVICE_ERROR;
-		}
 
-		scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
-		if ((retval=jtag_execute_queue())!=ERROR_OK)
-			return retval;
-		swjdp->ack = swjdp->ack & 0x7;
+			scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+			if ((retval=jtag_execute_queue())!=ERROR_OK)
+				return retval;
+			swjdp->ack = swjdp->ack & 0x7;
+		}
+	} else
+	{
+		/* common code path avoids fn to timeval_ms() */
 	}
 
 	/* Check for STICKYERR and STICKYORUN */
diff --git a/src/target/target.c b/src/target/target.c
index cc1d48a88..70660e3b4 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1700,32 +1700,41 @@ int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char
 	return target_wait_state(target, TARGET_HALTED, ms);
 }
 
+/* wait for target state to change. The trick here is to have a low
+ * latency for short waits and not to suck up all the CPU time
+ * on longer waits.
+ *
+ * After 500ms, keep_alive() is invoked
+ */
 int target_wait_state(target_t *target, enum target_state state, int ms)
 {
 	int retval;
-	struct timeval timeout, now;
+	long long then=0, cur;
 	int once=1;
-	gettimeofday(&timeout, NULL);
-	timeval_add_time(&timeout, 0, ms * 1000);
 
 	for (;;)
 	{
 		if ((retval=target_poll(target))!=ERROR_OK)
 			return retval;
-		keep_alive();
 		if (target->state == state)
 		{
 			break;
 		}
+		cur = timeval_ms();
 		if (once)
 		{
 			once=0;
+			then = timeval_ms();
 			LOG_DEBUG("waiting for target %s...",
 				Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
 		}
 
-		gettimeofday(&now, NULL);
-		if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
+		if (cur-then>500)
+		{
+			keep_alive();
+		}
+
+		if ((cur-then)>ms)
 		{
 			LOG_ERROR("timed out while waiting for target %s",
 				Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
-- 
GitLab