From: <ge...@op...> - 2025-10-21 18:02:13
|
This is an automated email from Gerrit. "Evgeniy Naydanov <evg...@sy...>" 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 <ti...@si...> 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 <ti...@si...> Signed-off-by: Evgeniy Naydanov <evg...@sy...> 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; -- |