From 83440065c00cce9d36f23182b439d7bf2306cfb2 Mon Sep 17 00:00:00 2001
From: drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Sun, 5 Nov 2006 17:38:35 +0000
Subject: [PATCH] - correctly enter debug state on a "soft_reset_halt" command
 - several small fixes - retry reading from a FT2232 device on incomplete
 reads

git-svn-id: svn://svn.berlios.de/openocd/trunk@110 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/flash/lpc2000.c        |  7 +++
 src/helper/command.c       |  2 +-
 src/jtag/ft2232.c          | 27 ++++++++----
 src/target/arm7_9_common.c | 88 ++++++++++++++++++++++++--------------
 src/target/breakpoints.c   |  4 ++
 src/target/target.c        |  1 -
 6 files changed, 87 insertions(+), 42 deletions(-)

diff --git a/src/flash/lpc2000.c b/src/flash/lpc2000.c
index 9ec4165bd..16e20e2a6 100644
--- a/src/flash/lpc2000.c
+++ b/src/flash/lpc2000.c
@@ -46,6 +46,7 @@
  * variant 2 (lpc2000_v2):
  * - 213x
  * - 214x
+ * - 2101|2|3
  */
 
 int lpc2000_register_commands(struct command_context_s *cmd_ctx);
@@ -152,6 +153,12 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank)
 		/* variant 2 has a uniform layout, only number of sectors differs */
 		switch (bank->size)
 		{
+			case 8 * 1024:
+				num_sectors = 2;
+				break;
+			case 16 * 1024:
+				num_sectors = 4;
+				break;
 			case 32 * 1024:
 				num_sectors = 8;
 				break;
diff --git a/src/helper/command.c b/src/helper/command.c
index 9a38723c8..ca08535a4 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -400,7 +400,7 @@ int command_run_file(command_context_t *context, FILE *file, enum command_mode m
 			break;
 
 		/* run line */
-		if (command_run_line(context, cmd) == ERROR_COMMAND_CLOSE_CONNECTION)
+		if ((retval = command_run_line(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION)
 			break;
 	}
 	
diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c
index e681b3e5a..9af57dd1b 100644
--- a/src/jtag/ft2232.c
+++ b/src/jtag/ft2232.c
@@ -189,15 +189,19 @@ int ft2232_read(u8* buf, int size, u32* bytes_read)
 #if BUILD_FT2232_FTD2XX == 1
 	DWORD dw_bytes_read;
 	FT_STATUS status;
-	if ((status = FT_Read(ftdih, buf, size, &dw_bytes_read)) != FT_OK)
+	int timeout = 5;
+	*bytes_read = 0;
+
+	while ((*bytes_read < size) && timeout--)
 	{
-		*bytes_read = dw_bytes_read; 
-		ERROR("FT_Read returned: %i", status);
-		return ERROR_JTAG_DEVICE_ERROR;
+		if ((status = FT_Read(ftdih, buf, size, &dw_bytes_read)) != FT_OK)
+		{
+			*bytes_read = 0; 
+			ERROR("FT_Read returned: %i", status);
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
+		*bytes_read += dw_bytes_read; 
 	}
-	*bytes_read = dw_bytes_read; 
-	return ERROR_OK;	
-
 #elif BUILD_FT2232_LIBFTDI == 1
 	int retval;
 	int timeout = 100;
@@ -213,8 +217,15 @@ int ft2232_read(u8* buf, int size, u32* bytes_read)
 		}
 		*bytes_read += retval;
 	}
-	return ERROR_OK;	
 #endif
+
+	if (*bytes_read < size)
+	{
+		ERROR("couldn't read the requested number of bytes from FT2232 device (%i < %i)", *bytes_read, size);
+		return ERROR_JTAG_DEVICE_ERROR;
+	}
+	
+	return ERROR_OK;
 }
 
 int ft2232_speed(int speed)
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index c298c904e..7bf042a91 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -656,6 +656,9 @@ int arm7_9_assert_reset(target_t *target)
 	
 	if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
 	{
+		/* if the target wasn't running, there might be working areas allocated */
+		target_free_all_working_areas(target);
+		
 		/* assert SRST and TRST */
 		/* system would get ouf sync if we didn't reset test-logic, too */
 		if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
@@ -724,11 +727,44 @@ int arm7_9_deassert_reset(target_t *target)
 
 }
 
+int arm7_9_clear_halt(target_t *target)
+{
+	armv4_5_common_t *armv4_5 = target->arch_info;
+	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+	reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
+	
+	if (arm7_9->use_dbgrq)
+	{
+		/* program EmbeddedICE Debug Control Register to deassert DBGRQ
+		 */
+		buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);	
+		embeddedice_store_reg(dbg_ctrl);
+	}
+	else
+	{
+		/* restore registers if watchpoint unit 0 was in use
+		 */
+		if (arm7_9->wp0_used)
+		{
+			embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
+			embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
+			embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
+		}
+		/* control value always has to be restored, as it was either disabled, 
+		 * or enabled with possibly different bits
+		 */
+		embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
+	}
+	
+	return ERROR_OK;
+}
+
 int arm7_9_soft_reset_halt(struct target_s *target)
 {
 	armv4_5_common_t *armv4_5 = target->arch_info;
 	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
 	reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
+	reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
 	int i;
 	
 	if (target->state == TARGET_RUNNING)
@@ -743,6 +779,26 @@ int arm7_9_soft_reset_halt(struct target_s *target)
 	}
 	target->state = TARGET_HALTED;
 	
+	/* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS
+	 * ensure that DBGRQ is cleared
+	 */
+	buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
+	buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);
+	buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);
+	embeddedice_store_reg(dbg_ctrl);
+	
+	arm7_9_clear_halt(target);
+	
+	/* if the target is in Thumb state, change to ARM state */
+	if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1))
+	{
+		u32 r0_thumb, pc_thumb;
+		DEBUG("target entered debug from Thumb state, changing to ARM");
+		/* Entered debug from Thumb mode */
+		armv4_5->core_state = ARMV4_5_STATE_THUMB;
+		arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);
+	}
+	
 	/* all register content is now invalid */
 	armv4_5_invalidate_core_regs(target);
 	
@@ -819,38 +875,6 @@ int arm7_9_halt(target_t *target)
 	return ERROR_OK;
 }
 
-int arm7_9_clear_halt(target_t *target)
-{
-	armv4_5_common_t *armv4_5 = target->arch_info;
-	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
-	reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
-	
-	if (arm7_9->use_dbgrq)
-	{
-		/* program EmbeddedICE Debug Control Register to deassert DBGRQ
-		 */
-		buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);	
-		embeddedice_store_reg(dbg_ctrl);
-	}
-	else
-	{
-		/* restore registers if watchpoint unit 0 was in use
-		 */
-		if (arm7_9->wp0_used)
-		{
-			embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
-			embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
-			embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
-		}
-		/* control value always has to be restored, as it was either disabled, 
-		 * or enabled with possibly different bits
-		 */
-		embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
-	}
-	
-	return ERROR_OK;
-}
-
 int arm7_9_debug_entry(target_t *target)
 {
 	int i;
diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index 3da927386..a30d67a4c 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -167,6 +167,10 @@ int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw
 				INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[rw]);
 				return retval;
 				break;
+			case ERROR_TARGET_NOT_HALTED:
+				INFO("can't add watchpoint while target is running");
+				return retval;
+				break;
 			default:
 				ERROR("unknown error");
 				exit(-1);
diff --git a/src/target/target.c b/src/target/target.c
index 531d632e6..732288880 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -904,7 +904,6 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
 				(*last_target_p)->working_areas = NULL;
 				(*last_target_p)->backup_working_area = 0;
 				
-				(*last_target_p)->endianness = TARGET_LITTLE_ENDIAN;
 				(*last_target_p)->state = TARGET_UNKNOWN;
 				(*last_target_p)->reg_cache = NULL;
 				(*last_target_p)->breakpoints = NULL;
-- 
GitLab