This is an automated email from Gerrit.

"Evgeniy Naydanov <[email protected]>" just uploaded a new patch 
set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9176

-- gerrit

commit f86c1deceea8db1da47e5537aae5c1daaeda28d4
Author: Tim Newsome <[email protected]>
Date:   Mon Jan 31 09:23:38 2022 -0800

    Ask the RTOS which target to set swbp on.
    
    This is the result of squashing two commits from RISC-V OpenOCD, the
    first one is commit 52ca5d198e3b4a0565e810ff4b5545dfac39cec9 ("Ask the
    RTOS which target to set swbp on. (#673)") and the second one is commit
    8ae41e86e15df5df60cdf17a69ac2622570af6a7 ("Fix breackpoint_add for rtos
    swbp (#734)").
    
    The resulting change lets the RTOS pick the "current" target for setting
    the hardware breakpoint on, which matters if address translation differs
    between threads.
    
    Change-Id: I67ce24d6aa0ca9225436b380065d1e265424e70f
    Signed-off-by: Tim Newsome <[email protected]>
    Signed-off-by: Evgeniy Naydanov <[email protected]>

diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index b2a45ade9f..1d47b13223 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -28,6 +28,8 @@ static int hwthread_read_buffer(struct rtos *rtos, 
target_addr_t address,
                uint32_t size, uint8_t *buffer);
 static int hwthread_write_buffer(struct rtos *rtos, target_addr_t address,
                uint32_t size, const uint8_t *buffer);
+struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address,
+                                   uint32_t length, enum breakpoint_type type);
 
 #define HW_THREAD_NAME_STR_SIZE (32)
 
@@ -59,6 +61,7 @@ const struct rtos_type hwthread_rtos = {
        .set_reg = hwthread_set_reg,
        .read_buffer = hwthread_read_buffer,
        .write_buffer = hwthread_write_buffer,
+       .swbp_target = hwthread_swbp_target
 };
 
 struct hwthread_params {
@@ -446,3 +449,9 @@ static int hwthread_write_buffer(struct rtos *rtos, 
target_addr_t address,
 
        return target_write_buffer(curr, address, size, buffer);
 }
+
+struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address,
+                                   uint32_t length, enum breakpoint_type type)
+{
+       return hwthread_find_thread(rtos->target, rtos->current_thread);
+}
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index 2ccccf1b0d..961bc40b13 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -730,3 +730,11 @@ int rtos_write_buffer(struct target *target, target_addr_t 
address,
                return target->rtos->type->write_buffer(target->rtos, address, 
size, buffer);
        return ERROR_NOT_IMPLEMENTED;
 }
+
+struct target *rtos_swbp_target(struct target *target, target_addr_t address,
+                               uint32_t length, enum breakpoint_type type)
+{
+       if (target->rtos->type->swbp_target)
+               return target->rtos->type->swbp_target(target->rtos, address, 
length, type);
+       return target;
+}
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
index dbaa7e8ce8..0fc361eba1 100644
--- a/src/rtos/rtos.h
+++ b/src/rtos/rtos.h
@@ -9,6 +9,7 @@
 #define OPENOCD_RTOS_RTOS_H
 
 #include "server/server.h"
+#include "target/breakpoints.h"
 #include "target/target.h"
 
 typedef int64_t threadid_t;
@@ -77,6 +78,12 @@ struct rtos_type {
                        uint8_t *buffer);
        int (*write_buffer)(struct rtos *rtos, target_addr_t address, uint32_t 
size,
                        const uint8_t *buffer);
+       /* When a software breakpoint is set, it is set on only one target,
+        * because we assume memory is shared across them. By default this is 
the
+        * first target in the SMP group. Override this function to have
+        * breakpoint_add() use a different target. */
+       struct target * (*swbp_target)(struct rtos *rtos, target_addr_t address,
+                                    uint32_t length, enum breakpoint_type 
type);
 };
 
 struct stack_register_offset {
@@ -135,6 +142,8 @@ int rtos_read_buffer(struct target *target, target_addr_t 
address,
                uint32_t size, uint8_t *buffer);
 int rtos_write_buffer(struct target *target, target_addr_t address,
                uint32_t size, const uint8_t *buffer);
+struct target *rtos_swbp_target(struct target *target, target_addr_t address,
+                               uint32_t length, enum breakpoint_type type);
 
 // Keep in alphabetic order this list of rtos
 extern const struct rtos_type chibios_rtos;
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 080e3360ae..b565cb5a12 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1809,7 +1809,15 @@ static int gdb_breakpoint_watchpoint_packet(struct 
connection *connection,
                case 0:
                case 1:
                        if (packet[0] == 'Z') {
-                               retval = breakpoint_add(target, address, size, 
bp_type);
+                               struct target *bp_target = target;
+                               if (target->rtos && bp_type == BKPT_SOFT) {
+                                       bp_target = rtos_swbp_target(target, 
address, size, bp_type);
+                                       if (!bp_target) {
+                                               retval = ERROR_FAIL;
+                                               break;
+                                       }
+                               }
+                               retval = breakpoint_add(bp_target, address, 
size, bp_type);
                        } else {
                                assert(packet[0] == 'z');
                                retval = breakpoint_remove(target, address);
diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index 7254eac7dc..4781842846 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -210,16 +210,10 @@ int breakpoint_add(struct target *target,
        unsigned int length,
        enum breakpoint_type type)
 {
-       if (target->smp) {
-               struct target_list *head;
-
-               if (type == BKPT_SOFT) {
-                       head = list_first_entry(target->smp_targets, struct 
target_list, lh);
-                       return breakpoint_add_internal(head->target, address, 
length, type);
-               }
-
-               foreach_smp_target(head, target->smp_targets) {
-                       struct target *curr = head->target;
+       if (target->smp && type == BKPT_HARD) {
+               struct target_list *list_node;
+               foreach_smp_target(list_node, target->smp_targets) {
+                       struct target *curr = list_node->target;
                        int retval = breakpoint_add_internal(curr, address, 
length, type);
                        if (retval != ERROR_OK)
                                return retval;

-- 

Reply via email to