]> git.sur5r.net Git - openocd/commitdiff
restore ICE watchpoint registers when the *last* software breakpoint is removed
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Fri, 28 Aug 2009 09:47:19 +0000 (09:47 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Fri, 28 Aug 2009 09:47:19 +0000 (09:47 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@2646 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/target/arm7_9_common.c
src/target/arm7_9_common.h

index 7400f18122c081fa7178968b2766494f57ab2c17..459b7d449b779f9a23ce4c1f60ffbb340efce4be 100644 (file)
@@ -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;
index fc2c3201a46b9b887fe1693ef4a3f85e5dca07ae..68197b46d65c5c43b73e01f2f87cebb1c9d517ff 100644 (file)
@@ -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 */