From a92d27afb0733f6280088bd79b048cbd87a2a0c4 Mon Sep 17 00:00:00 2001
From: ntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Mon, 18 Feb 2008 14:32:43 +0000
Subject: [PATCH] =?UTF-8?q?-=20Added=20a=20"User:"=20debug=20level.=20Thes?=
 =?UTF-8?q?e=20are=20messages=20that=20are=20intended=20for=20the=20user?=
 =?UTF-8?q?=20and=20are=20part=20of=20normal=20operation.=20-=20Faster=20D?=
 =?UTF-8?q?EBUG/INFO()=20when=20they=20are=20disabled=20-=20target=5Fread/?=
 =?UTF-8?q?write=5Fbuffer()=20now=20uses=2016=20and=2032=20bit=20access=20?=
 =?UTF-8?q?for=20single=20word=20aligned=20requests.=20Other=20requests=20?=
 =?UTF-8?q?are=20serviced=20as=20quickly=20as=20possible.=20-=20*much*=20f?=
 =?UTF-8?q?aster=20read/write=20GDB=20packets,=20removing=20timeout=20prob?=
 =?UTF-8?q?lems.=20-=20GDB=20read/write=20packets=20w/single=20word=20alig?=
 =?UTF-8?q?ned=2032/16=20bit=20access=20now=20use=2032/16=20bit=20word=20a?=
 =?UTF-8?q?ccess.=20-=20working=20area=20can=20now=20be=20changed=20on=20t?=
 =?UTF-8?q?he=20fly.=20Provides=20a=20way=20to=20move=20working=20area=20a?=
 =?UTF-8?q?bout=20as=20MMU=20is=20enabled/disabled.=20-=20cleaned=20up=20e?=
 =?UTF-8?q?rror=20messages=20for=20verify=5Fimage.=20Thanks=20=C3=98yvind?=
 =?UTF-8?q?=20Harboe?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

git-svn-id: svn://svn.berlios.de/openocd/trunk@302 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/helper/log.c        |  7 ++--
 src/helper/log.h        | 17 +++++++-
 src/server/gdb_server.c | 87 +++++------------------------------------
 src/target/target.c     | 50 +++++++++++++++--------
 4 files changed, 62 insertions(+), 99 deletions(-)

diff --git a/src/helper/log.c b/src/helper/log.c
index 4cdcfc872..fe475130e 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -43,12 +43,13 @@ void log_setCallback(logCallback c, void *p)
 	privData = p;
 }
 
-static char *log_strings[4] = 
+static char *log_strings[5] = 
 {
+	"User:  ",
 	"Error:  ",
 	"Warning:",
 	"Info:   ",
-	"Debug:  ",
+	"Debug:  "
 };
 
 void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
@@ -68,7 +69,7 @@ void log_printf(enum log_levels level, const char *file, int line, const char *f
 	if (f != NULL)
 		file = f + 1;
 
-	fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level], count, time(NULL), file, line, function, buffer);
+	fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, time(NULL), file, line, function, buffer);
 	fflush(log_output);
 	
 	va_end(args);
diff --git a/src/helper/log.h b/src/helper/log.h
index 09bc3a17b..ab32760a9 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -26,6 +26,9 @@
 #include <stdarg.h>
 
 /* logging priorities 
+ * LOG_USER - user messages. Could be anything from information 
+ *            to progress messags. These messages do not represent
+ *            incorrect or unexpected behaviour, just normal execution. 
  * LOG_ERROR - fatal errors, that are likely to cause program abort
  * LOG_WARNING - non-fatal errors, that may be resolved later
  * LOG_INFO - state information, etc.
@@ -33,6 +36,7 @@
  */
 enum log_levels
 {
+	LOG_USER = -1,
 	LOG_ERROR = 0,
 	LOG_WARNING = 1,
 	LOG_INFO = 2,
@@ -53,13 +57,16 @@ extern void log_setCallback(logCallback callback, void *priv);
 
 extern int debug_level;
 
+/* Avoid fn call and building parameter list if we're not outputting the information.
+ * Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */
+
 #define DEBUG(expr ...) \
-	do { \
+	do { if (debug_level >= LOG_DEBUG) \
 		log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
 	} while(0)
 
 #define INFO(expr ...) \
-	do { \
+	do { if (debug_level >= LOG_INFO) \
 		log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \
 	} while(0)
 
@@ -73,6 +80,12 @@ extern int debug_level;
 		log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \
 	} while(0)
 
+#define USER(expr ...) \
+	do { \
+		log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \
+	} while(0)
+
+
 /* general failures
  * error codes < 100
  */
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 99c9376d9..d940bc1a5 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -524,7 +524,7 @@ int gdb_output_con(connection_t *connection, char* line)
 int gdb_output(struct command_context_s *context, char* line)
 {
 	/* this will be dumped to the log and also sent as an O packet if possible */
-	ERROR(line);
+	USER(line); 
 	return ERROR_OK;
 }
 
@@ -1056,35 +1056,18 @@ int gdb_read_memory_packet(connection_t *connection, target_t *target, char *pac
 
 	DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
 
-	switch (len)
-	{
-		case 4:
-			if ((addr % 4) == 0)
-				retval = target->type->read_memory(target, addr, 4, 1, buffer);
-			else
-				retval = target->type->read_memory(target, addr, 1, len, buffer);
-			break;
-		case 2:
-			if ((addr % 2) == 0)
-				retval = target->type->read_memory(target, addr, 2, 1, buffer);
-			else
-				retval = target->type->read_memory(target, addr, 1, len, buffer);
-			break;
-		case 3:
-		case 1:
-			retval = target->type->read_memory(target, addr, 1, len, buffer);
-			break;
-			/* handle bulk reads */
-		default:
-			retval = target_read_buffer(target, addr, len, buffer);
-			break;
-	}
+	retval = target_read_buffer(target, addr, len, buffer);
 
 #if 0
 	if (retval == ERROR_TARGET_DATA_ABORT)
 	{
 		/* TODO : Here we have to lie and send back all zero's lest stack traces won't work.
 		 * At some point this might be fixed in GDB, in which case this code can be removed.
+		 * 
+		 * OpenOCD developers are acutely aware of this problem, but there is nothing
+		 * gained by involving the user in this problem that hopefully will get resolved
+		 * eventually
+		 * 
 		 * http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395
 		 */
 		memset(buffer, 0, len);
@@ -1159,31 +1142,7 @@ int gdb_write_memory_packet(connection_t *connection, target_t *target, char *pa
 		buffer[i] = tmp;
 	}
 
-	retval = ERROR_OK;
-	switch (len)
-	{
-		/* handle sized writes */
-		case 4:
-			if ((addr % 4) == 0)
-				retval = target->type->write_memory(target, addr, 4, 1, buffer);
-			else
-				retval = target->type->write_memory(target, addr, 1, len, buffer);
-			break;
-		case 2:
-			if ((addr % 2) == 0)
-				retval = target->type->write_memory(target, addr, 2, 1, buffer);
-			else
-				retval = target->type->write_memory(target, addr, 1, len, buffer);
-			break;
-		case 3:
-		case 1:
-			retval = target->type->write_memory(target, addr, 1, len, buffer);
-			break;
-			/* handle bulk writes */
-		default:
-			retval = target_write_buffer(target, addr, len, buffer);
-			break;
-	}
+	retval = target_write_buffer(target, addr, len, buffer);
 
 	if (retval == ERROR_OK)
 	{
@@ -1206,7 +1165,6 @@ int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, c
 	u32 addr = 0;
 	u32 len = 0;
 
-	u8 *buffer;
 	int retval;
 
 	/* skip command character */
@@ -1231,36 +1189,9 @@ int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, c
 	retval = ERROR_OK;
 	if( len ) {
 
-		buffer = malloc(len);
-
 		DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
 
-		memcpy( buffer, separator, len );
-
-		switch (len)
-		{
-			case 4:
-				if ((addr % 4) == 0)
-					retval = target->type->write_memory(target, addr, 4, 1, buffer);
-				else
-					retval = target->type->write_memory(target, addr, 1, len, buffer);
-				break;
-			case 2:
-				if ((addr % 2) == 0)
-					retval = target->type->write_memory(target, addr, 2, 1, buffer);
-				else
-					retval = target->type->write_memory(target, addr, 1, len, buffer);
-				break;
-			case 3:
-			case 1:
-				retval = target->type->write_memory(target, addr, 1, len, buffer);
-				break;
-			default:
-				retval = target_write_buffer(target, addr, len, buffer);
-				break;
-		}
-
-		free(buffer);
+		retval = target_write_buffer(target, addr, len, separator);
 	}
 
 	if (retval == ERROR_OK)
diff --git a/src/target/target.c b/src/target/target.c
index bafbfb0f6..a60637644 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -700,23 +700,24 @@ int target_register_commands(struct command_context_s *cmd_ctx)
 	register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG, NULL);
 	register_command(cmd_ctx, NULL, "target_script", handle_target_script_command, COMMAND_CONFIG, NULL);
 	register_command(cmd_ctx, NULL, "run_and_halt_time", handle_run_and_halt_time_command, COMMAND_CONFIG, NULL);
-	register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_CONFIG, NULL);
+	register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, NULL);
 
 	return ERROR_OK;
 }
 
+/* Single aligned words are guaranteed to use 16 or 32 bit access 
+ * mode respectively, otherwise data is handled as quickly as 
+ * possible
+ */
 int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
 {
 	int retval;
 	
 	DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
 	
-	/* handle writes of less than 4 byte */
-	if (size < 4)
+	if (((address % 2) == 0) && (size == 2))
 	{
-		if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)
-			return retval;
-		return ERROR_OK;
+		return target->type->write_memory(target, address, 2, 1, buffer);
 	}
 	
 	/* handle unaligned head bytes */
@@ -764,18 +765,20 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff
 	return ERROR_OK;
 }
 
+
+/* Single aligned words are guaranteed to use 16 or 32 bit access 
+ * mode respectively, otherwise data is handled as quickly as 
+ * possible
+ */
 int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
 {
 	int retval;
 	
 	DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
 	
-	/* handle reads of less than 4 byte */
-	if (size < 4)
+	if (((address % 2) == 0) && (size == 2))
 	{
-		if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)
-			return retval;
-		return ERROR_OK;
+		return target->type->read_memory(target, address, 2, 1, buffer);
 	}
 	
 	/* handle unaligned head bytes */
@@ -828,9 +831,14 @@ int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32*
 		if (buffer == NULL)
 		{
 			ERROR("error allocating buffer for section (%d bytes)", size);
-			return ERROR_OK;
+			return ERROR_INVALID_ARGUMENTS;
+		}
+		retval = target_read_buffer(target, address, size, buffer);
+		if (retval != ERROR_OK)
+		{
+			free(buffer);
+			return retval;
 		}
-		target_read_buffer(target, address, size, buffer);
 
 		/* convert to target endianess */
 		for (i = 0; i < (size/sizeof(u32)); i++)
@@ -1226,6 +1234,7 @@ int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, ch
 		ERROR("target number '%s' not defined", args[0]);
 		exit(-1);
 	}
+	target_free_all_working_areas(target);
 	
 	target->working_area = strtoul(args[1], NULL, 0);
 	target->working_area_size = strtoul(args[2], NULL, 0);
@@ -1450,6 +1459,13 @@ int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char
 	return wait_state(cmd_ctx, cmd, TARGET_HALTED, ms); 
 }
 
+static void target_process_events(struct command_context_s *cmd_ctx)
+{
+	target_t *target = get_current_target(cmd_ctx);
+	target->type->poll(target);
+	target_call_timer_callbacks();
+}
+
 static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms)
 {
 	struct timeval timeout, now;
@@ -1634,7 +1650,9 @@ int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **a
 		}
 	}
 
-	return wait_state(cmd_ctx, cmd, TARGET_RUNNING, 5000);
+	target_process_events(cmd_ctx);
+	
+	return ERROR_OK;
 }
 
 int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
@@ -2017,7 +2035,7 @@ int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, ch
 		
 		if( retval != ERROR_OK )
 		{
-			command_print(cmd_ctx, "image verify failed, verify aborted");
+			command_print(cmd_ctx, "could not calculate checksum, verify aborted");
 			free(buffer);
 			image_close(&image);
 			return ERROR_OK;
@@ -2028,7 +2046,7 @@ int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, ch
 			/* failed crc checksum, fall back to a binary compare */
 			u8 *data;
 			
-			command_print(cmd_ctx, "image verify checksum failed - attempting binary compare");
+			command_print(cmd_ctx, "checksum mismatch - attempting binary compare");
 			
 			data = (u8*)malloc(buf_cnt);
 			
-- 
GitLab