This is an automated email from Gerrit.

Hsiangkai Wang ([email protected]) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/1092

-- gerrit

commit dc7c0300198eb6bb509ca531d6adc7f9bbdeefc1
Author: Hsiangkai Wang <[email protected]>
Date:   Wed Dec 26 19:11:03 2012 +0800

    topic: new feature, add stop reason in stop reply packet for gdb
    
    In GDB remote serial protocol, the stop reply packet could contain more
    detail stop reason. The currently defined stop reasons are listed below.
    
    * watch
    * rwatch
    * awatch
    * library
    * replaylog
    
    This commit adds stop reason, watch/rwatch/awatch, in stop reply packet for
    just hit watchpoint. As manual indicates, at most one stop reason should be 
present.
    
    Refer to GDB Manual, D.3 Stop Reply Packets
    
    Change-Id: I1f70a1a9cc772e88e641b6171f1a009629a43bd1
    Signed-off-by: Hsiangkai Wang <[email protected]>

diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index ee7683a..5885c04 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -702,7 +702,8 @@ static void gdb_frontend_halted(struct target *target, 
struct connection *connec
         * that are to be ignored.
         */
        if (gdb_connection->frontend_state == TARGET_RUNNING) {
-               char sig_reply[4];
+               char sig_reply[20];
+               int sig_reply_len;
                int signal_var;
 
                /* stop forwarding log packets! */
@@ -715,7 +716,44 @@ static void gdb_frontend_halted(struct target *target, 
struct connection *connec
                        signal_var = gdb_last_signal(target);
 
                snprintf(sig_reply, 4, "T%2.2x", signal_var);
-               gdb_put_packet(connection, sig_reply, 3);
+               sig_reply_len = 3;
+
+               if (target->debug_reason == DBG_REASON_WATCHPOINT) {
+                       enum watchpoint_rw hit_wp_type;
+                       uint32_t hit_wp_address;
+
+                       if (watchpoint_hit(target, &hit_wp_type, 
&hit_wp_address) == ERROR_OK) {
+                               uint32_t i;
+                               uint8_t *buffer;
+
+                               switch (hit_wp_type) {
+                                       case WPT_WRITE:
+                                               snprintf(sig_reply + 3, 7, 
"watch:");
+                                               sig_reply_len = 9;
+                                               break;
+                                       case WPT_READ:
+                                               snprintf(sig_reply + 3, 8, 
"rwatch:");
+                                               sig_reply_len = 10;
+                                               break;
+                                       case WPT_ACCESS:
+                                               snprintf(sig_reply + 3, 8, 
"awatch:");
+                                               sig_reply_len = 10;
+                                               break;
+                               }
+
+                               buffer = (uint8_t *)&hit_wp_address;
+                               for (i = 0; i < 4; i++) {
+                                       /* Reported address is big-endian */
+                                       uint8_t t = buffer[4 - i - 1];
+                                       sig_reply[sig_reply_len] = DIGITS[(t >> 
4) & 0xf];
+                                       sig_reply[sig_reply_len + 1] = DIGITS[t 
& 0xf];
+                                       sig_reply_len += 2;
+                               }
+                               sig_reply[sig_reply_len++] = ';';
+                               sig_reply[sig_reply_len] = 0;
+                       }
+               }
+               gdb_put_packet(connection, sig_reply, sig_reply_len);
                gdb_connection->frontend_state = TARGET_HALTED;
                rtos_update_threads(target);
        }
diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index 3b516d0..70c69ac 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -500,3 +500,22 @@ void watchpoint_clear_target(struct target *target)
        while (target->watchpoints != NULL)
                watchpoint_free(target, target->watchpoints);
 }
+
+int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, uint32_t 
*address)
+{
+       int retval;
+       struct watchpoint *hit_watchpoint;
+
+       retval = target_hit_watchpoint(target, &hit_watchpoint);
+       if (retval != ERROR_OK)
+               return ERROR_FAIL;
+
+       *rw = hit_watchpoint->rw;
+       *address = hit_watchpoint->address;
+
+       LOG_DEBUG("Found hit watchpoint at 0x%8.8" PRIx32 " (WPID: %d)",
+               hit_watchpoint->address,
+               hit_watchpoint->unique_id);
+
+       return ERROR_OK;
+}
diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h
index a019e96..aafc141 100644
--- a/src/target/breakpoints.h
+++ b/src/target/breakpoints.h
@@ -72,4 +72,7 @@ int watchpoint_add(struct target *target,
                enum watchpoint_rw rw, uint32_t value, uint32_t mask);
 void watchpoint_remove(struct target *target, uint32_t address);
 
+/* report type and address of just hit watchpoint */
+int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, uint32_t 
*address);
+
 #endif /* BREAKPOINTS_H */
diff --git a/src/target/target.c b/src/target/target.c
index 41fab1e..2cda298 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1028,6 +1028,23 @@ int target_remove_watchpoint(struct target *target,
 {
        return target->type->remove_watchpoint(target, watchpoint);
 }
+int target_hit_watchpoint(struct target *target,
+               struct watchpoint **hit_watchpoint)
+{
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target %s is not halted", target->cmd_name);
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if (target->type->hit_watchpoint == NULL) {
+               /* For backward compatible, if hit_watchpoint is not 
implemented,
+                * return ERROR_FAIL such that gdb_server will not take the 
nonsense
+                * information. */
+               return ERROR_FAIL;
+       }
+
+       return target->type->hit_watchpoint(target, hit_watchpoint);
+}
 
 int target_get_gdb_reg_list(struct target *target,
                struct reg **reg_list[], int *reg_list_size)
diff --git a/src/target/target.h b/src/target/target.h
index 9707bcc..ad9b362 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -388,6 +388,14 @@ int target_remove_watchpoint(struct target *target,
                struct watchpoint *watchpoint);
 
 /**
+ * Find out the just hit @a watchpoint for @a target.
+ *
+ * This routine is a wrapper for target->type->hit_watchpoint.
+ */
+int target_hit_watchpoint(struct target *target,
+               struct watchpoint **watchpoint);
+
+/**
  * Obtain the registers for GDB.
  *
  * This routine is a wrapper for target->type->get_gdb_reg_list.
diff --git a/src/target/target_type.h b/src/target/target_type.h
index 277607e..82fd25c 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -177,6 +177,11 @@ struct target_type {
         */
        int (*remove_watchpoint)(struct target *target, struct watchpoint 
*watchpoint);
 
+       /* Find out just hit watchpoint. After the target hits a watchpoint, the
+        * information could assist gdb to locate where the modified/accessed 
memory is.
+        */
+       int (*hit_watchpoint)(struct target *target, struct watchpoint 
**hit_watchpoint);
+
        /**
         * Target algorithm support.  Do @b not call this method directly,
         * use target_run_algorithm() instead.

-- 

------------------------------------------------------------------------------
LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
Remotely access PCs and mobile devices and provide instant support
Improve your efficiency, and focus on delivering more value-add services
Discover what IT Professionals Know. Rescue delivers
http://p.sf.net/sfu/logmein_12329d2d
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to