]> git.sur5r.net Git - openocd/commitdiff
target: uplevel add_{break,watch}point() error checks
authorDavid Brownell <dbrownell@users.sourceforge.net>
Sat, 28 Nov 2009 18:40:26 +0000 (10:40 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Sat, 28 Nov 2009 18:40:26 +0000 (10:40 -0800)
In target_type.h it's documented that the target must be
halted for add_breakpoint() ... and with slight ambiguity,
also for its add_watchpoint() sibling.  So rather than
verifying that constraint in the CPU drivers, do it in the
target_add_{break,watch}point() routines.

Add minor paranoia on the remove_*point() paths too:  save
the return value, and print it out in in the LOG_DEBUG message
in case it's nonzero.

Note that with some current cores, like all ARMv7 ones I've
looked at, there's no technical issue preventing watchpoint or
breakpoint add/remove operations on active cores.  This model
seems deeply wired into OpenOCD though.

ALSO:  the ARM targets were fairly "good" about enforcing that
constraint themselves.  The MIPS ones were relied on other code
to catch such stuff, but it's not clear such code existed ...
keep an eye out for new issues on MIPS.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/target/arm7_9_common.c
src/target/breakpoints.c
src/target/cortex_m3.c
src/target/target.c
src/target/target_type.h
src/target/xscale.c

index f7b86693d2a5bc888f09cea0c28bf64ee821fc3e..b5553cd801c2fa168ae7d69bb98b7012feacf104 100644 (file)
@@ -426,12 +426,6 @@ int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if (arm7_9->breakpoint_count == 0)
        {
                /* make sure we don't have any dangling breakpoints. This is vital upon
@@ -631,12 +625,6 @@ int arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
 {
        struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if (arm7_9->wp_available < 1)
        {
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
index 16ab7e0caa672c03d5c9dbd4ebb6625d80904ccc..2542c41a6fec9b9670256abcccb9c54e6a90b7eb 100644 (file)
@@ -109,6 +109,7 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint
 {
        struct breakpoint *breakpoint = target->breakpoints;
        struct breakpoint **breakpoint_p = &target->breakpoints;
+       int retval;
 
        while (breakpoint)
        {
@@ -121,9 +122,9 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint
        if (breakpoint == NULL)
                return;
 
-       target_remove_breakpoint(target, breakpoint);
+       retval = target_remove_breakpoint(target, breakpoint);
 
-       LOG_DEBUG("BPID: %d", breakpoint->unique_id );
+       LOG_DEBUG("free BPID: %d --> %d", breakpoint->unique_id, retval);
        (*breakpoint_p) = breakpoint->next;
        free(breakpoint->orig_instr);
        free(breakpoint);
@@ -249,6 +250,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint
 {
        struct watchpoint *watchpoint = target->watchpoints;
        struct watchpoint **watchpoint_p = &target->watchpoints;
+       int retval;
 
        while (watchpoint)
        {
@@ -260,8 +262,8 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint
 
        if (watchpoint == NULL)
                return;
-       target_remove_watchpoint(target, watchpoint);
-       LOG_DEBUG("WPID: %d", watchpoint->unique_id );
+       retval = target_remove_watchpoint(target, watchpoint);
+       LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
        (*watchpoint_p) = watchpoint->next;
        free(watchpoint);
 }
index 7cfe540a389a6aa700b31ad4628b0f4f9c151270..ad59c785ce9132a6f0f456aca759fe3faa24f1ad 100644 (file)
@@ -1141,13 +1141,6 @@ cortex_m3_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
 
-       /* REVISIT why check? DWT can be updated with core running ... */
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if (cortex_m3->dwt_comp_available < 1)
        {
                LOG_DEBUG("no comparators?");
index a2bd88689cd3b2d71ad38531f7f615b9b2f076a1..28387f447e3bdb4a7493cff5634ba4738299c42d 100644 (file)
@@ -606,6 +606,10 @@ int target_bulk_write_memory(struct target *target,
 int target_add_breakpoint(struct target *target,
                struct breakpoint *breakpoint)
 {
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target %s is not halted", target->cmd_name);
+               return ERROR_TARGET_NOT_HALTED;
+       }
        return target->type->add_breakpoint(target, breakpoint);
 }
 int target_remove_breakpoint(struct target *target,
@@ -617,6 +621,10 @@ int target_remove_breakpoint(struct target *target,
 int target_add_watchpoint(struct target *target,
                struct watchpoint *watchpoint)
 {
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target %s is not halted", target->cmd_name);
+               return ERROR_TARGET_NOT_HALTED;
+       }
        return target->type->add_watchpoint(target, watchpoint);
 }
 int target_remove_watchpoint(struct target *target,
index 333b58b41f49201d6b2204728c05e405f4be5b2c..d141608b41409f6e8b847658961ac85a09a71f21 100644 (file)
@@ -124,18 +124,24 @@ struct target_type
         * Target must be halted while this is invoked as this
         * will actually set up breakpoints on target.
         *
-        * The breakpoint hardware will be set up upon adding the first breakpoint.
+        * The breakpoint hardware will be set up upon adding the
+        * first breakpoint.
         *
         * Upon GDB connection all breakpoints/watchpoints are cleared.
         */
        int (*add_breakpoint)(struct target *target, struct breakpoint *breakpoint);
 
-       /* remove breakpoint. hw will only be updated if the target is currently halted.
+       /* remove breakpoint. hw will only be updated if the target
+        * is currently halted.
         * However, this method can be invoked on unresponsive targets.
         */
        int (*remove_breakpoint)(struct target *target, struct breakpoint *breakpoint);
+
+       /* add watchpoint ... see add_breakpoint() comment above. */
        int (*add_watchpoint)(struct target *target, struct watchpoint *watchpoint);
-       /* remove watchpoint. hw will only be updated if the target is currently halted.
+
+       /* remove watchpoint. hw will only be updated if the target
+        * is currently halted.
         * However, this method can be invoked on unresponsive targets.
         */
        int (*remove_watchpoint)(struct target *target, struct watchpoint *watchpoint);
index 1a18ab85aac8de544d348f28dbb779417b7e6cbe..49653a96ee755a32130ae31307d3a871507b3171 100644 (file)
@@ -2137,12 +2137,6 @@ static int xscale_add_breakpoint(struct target *target,
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
        {
                LOG_INFO("no breakpoint unit available for hardware breakpoint");
@@ -2300,12 +2294,6 @@ static int xscale_add_watchpoint(struct target *target,
 {
        struct xscale_common *xscale = target_to_xscale(target);
 
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_WARNING("target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
        if (xscale->dbr_available < 1)
        {
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;