From efef05870d726fe4cb6786d785fae4628fe7ec1e Mon Sep 17 00:00:00 2001
From: oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Fri, 28 Aug 2009 09:47:19 +0000
Subject: restore ICE watchpoint registers when the *last* software breakpoint
 is removed

git-svn-id: svn://svn.berlios.de/openocd/trunk@2646 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/target/arm7_9_common.c | 25 ++++++++++++++++++++++---
 src/target/arm7_9_common.h |  1 +
 2 files changed, 23 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 7400f181..459b7d44 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -61,6 +61,7 @@ static int arm7_9_clear_watchpoints(arm7_9_common_t *arm7_9)
 	LOG_DEBUG("-");
 	embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
 	embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
+	arm7_9->sw_breakpoint_count = 0;
 	arm7_9->sw_breakpoints_added = 0;
 	arm7_9->wp0_used = 0;
 	arm7_9->wp1_used = arm7_9->wp1_used_default;
@@ -274,9 +275,6 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
 	}
 	else if (breakpoint->type == BKPT_SOFT)
 	{
-		if ((retval = arm7_9_set_software_breakpoints(arm7_9)) != ERROR_OK)
-			return retval;
-
 		/* did we already set this breakpoint? */
 		if (breakpoint->set)
 			return ERROR_OK;
@@ -329,6 +327,12 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
 				return ERROR_OK;
 			}
 		}
+
+		if ((retval = arm7_9_set_software_breakpoints(arm7_9)) != ERROR_OK)
+			return retval;
+
+		arm7_9->sw_breakpoint_count++;
+
 		breakpoint->set = 1;
 	}
 
@@ -415,6 +419,20 @@ int arm7_9_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
 					return retval;
 				}
 		}
+
+		if (--arm7_9->sw_breakpoint_count==0)
+		{
+			/* We have removed the last sw breakpoint, clear the hw breakpoint we used to implement it */
+			if (arm7_9->sw_breakpoints_added == 1)
+			{
+				embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0);
+			}
+			else if (arm7_9->sw_breakpoints_added == 2)
+			{
+				embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0);
+			}
+		}
+
 		breakpoint->set = 0;
 	}
 
@@ -3109,6 +3127,7 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
 	arm7_9->wp_available = 0; /* this is set up in arm7_9_clear_watchpoints() */
 	arm7_9->wp_available_max = 2;
 	arm7_9->sw_breakpoints_added = 0;
+	arm7_9->sw_breakpoint_count = 0;
 	arm7_9->breakpoint_count = 0;
 	arm7_9->wp0_used = 0;
 	arm7_9->wp1_used = 0;
diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h
index fc2c3201..68197b46 100644
--- a/src/target/arm7_9_common.h
+++ b/src/target/arm7_9_common.h
@@ -47,6 +47,7 @@ typedef struct arm7_9_common_s
 	uint32_t arm_bkpt; /**< ARM breakpoint instruction */
 	uint16_t thumb_bkpt; /**< Thumb breakpoint instruction */
 	int sw_breakpoints_added; /**< Specifies which watchpoint software breakpoints are setup on */
+	int sw_breakpoint_count; /**< keep track of number of software breakpoints we have set */
 	int breakpoint_count; /**< Current number of set breakpoints */
 	int wp_available; /**< Current number of available watchpoint units */
 	int wp_available_max; /**< Maximum number of available watchpoint units */
-- 
cgit v1.2.3