This is an automated email from Gerrit. "Anatoly Parshintsev <kupokupokup...@gmail.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7840
-- gerrit commit c65d5d0d2436eecae6ac2b44a66dce51463c417b Author: Parshintsev Anatoly <anatoly.parshint...@syntacore.com> Date: Fri Jul 28 20:41:32 2023 +0300 data watchpoints should have 64-bit type for value and mask This patch changes data types of watchpoint value and mask to allow for 64-bit values match that some architectures (like RISCV) allow. In addition this patch fixes the behavior of watchpoint command to zero-out mask if only data value is provided. Change-Id: I3c7ec1630f03ea9534ec34c0ebe99e08ea56e7f0 Signed-off-by: Parshintsev Anatoly <anatoly.parshint...@syntacore.com> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 702dbef499..4a4ea53dc3 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1779,7 +1779,7 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection, case 4: { if (packet[0] == 'Z') { - retval = watchpoint_add(target, address, size, wp_type, 0, 0xffffffffu); + retval = watchpoint_add(target, address, size, wp_type, 0, WATCHPOINT_IGNORE_DATA_VALUE_MASK); if (retval == ERROR_NOT_IMPLEMENTED) { /* Send empty reply to report that watchpoints of this type are not supported */ gdb_put_packet(connection, "", 0); diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index bbdbc4981c..ad814e0541 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -451,6 +451,7 @@ static int arm7_9_set_watchpoint(struct target *target, struct watchpoint *watch struct arm7_9_common *arm7_9 = target_to_arm7_9(target); int rw_mask = 1; uint32_t mask; + const uint32_t wp_data_mask = watchpoint->mask; mask = watchpoint->length - 1; @@ -469,8 +470,8 @@ static int arm7_9_set_watchpoint(struct target *target, struct watchpoint *watch watchpoint->address); embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask); embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], - watchpoint->mask); - if (watchpoint->mask != 0xffffffffu) + wp_data_mask); + if (wp_data_mask != (uint32_t)WATCHPOINT_IGNORE_DATA_VALUE_MASK) embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], watchpoint->value); embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], @@ -488,8 +489,8 @@ static int arm7_9_set_watchpoint(struct target *target, struct watchpoint *watch watchpoint->address); embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask); embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], - watchpoint->mask); - if (watchpoint->mask != 0xffffffffu) + wp_data_mask); + if (wp_data_mask != (uint32_t)WATCHPOINT_IGNORE_DATA_VALUE_MASK) embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], watchpoint->value); embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index fd6fb263fc..ab9b50e230 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -918,7 +918,7 @@ static int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t, uint32_t control; /* this hardware doesn't support data value matching or masking */ - if (wp->value || wp->mask != ~(uint32_t)0) { + if (wp->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK) { LOG_DEBUG("watchpoint values and masking not supported"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index d1eefe5b32..9ba6b5453b 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -1210,7 +1210,7 @@ static int dpmv8_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t, uint32_t control; /* this hardware doesn't support data value matching or masking */ - if (wp->value || wp->mask != ~(uint32_t)0) { + if (wp->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK) { LOG_DEBUG("watchpoint values and masking not supported"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index bbaff4e756..4d268cebb3 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -393,7 +393,7 @@ struct breakpoint *breakpoint_find(struct target *target, target_addr_t address) } static int watchpoint_add_internal(struct target *target, target_addr_t address, - uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask) + uint32_t length, enum watchpoint_rw rw, uint64_t value, uint64_t mask) { struct watchpoint *watchpoint = target->watchpoints; struct watchpoint **watchpoint_p = &target->watchpoints; @@ -460,7 +460,7 @@ bye: } int watchpoint_add(struct target *target, target_addr_t address, - uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask) + uint32_t length, enum watchpoint_rw rw, uint64_t value, uint64_t mask) { if (target->smp) { struct target_list *head; diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h index a9ae484357..8fad741da6 100644 --- a/src/target/breakpoints.h +++ b/src/target/breakpoints.h @@ -36,11 +36,12 @@ struct breakpoint { int linked_brp; }; +#define WATCHPOINT_IGNORE_DATA_VALUE_MASK (~(uint64_t)0) struct watchpoint { target_addr_t address; uint32_t length; - uint32_t mask; - uint32_t value; + uint64_t mask; + uint64_t value; enum watchpoint_rw rw; bool is_set; unsigned int number; @@ -69,7 +70,7 @@ static inline void breakpoint_hw_set(struct breakpoint *breakpoint, unsigned int void watchpoint_clear_target(struct target *target); int watchpoint_add(struct target *target, target_addr_t address, uint32_t length, - enum watchpoint_rw rw, uint32_t value, uint32_t mask); + enum watchpoint_rw rw, uint64_t value, uint64_t mask); void watchpoint_remove(struct target *target, target_addr_t address); /* report type and address of just hit watchpoint */ diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 9541caa792..81a859025c 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2047,7 +2047,7 @@ int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint } /* hardware doesn't support data value masking */ - if (watchpoint->mask != ~(uint32_t)0) { + if (watchpoint->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK) { LOG_TARGET_DEBUG(target, "watchpoint value masks not supported"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } diff --git a/src/target/target.c b/src/target/target.c index 89eaa23d84..96f4ae7d3e 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -4061,8 +4061,8 @@ COMMAND_HANDLER(handle_wp_command) while (watchpoint) { command_print(CMD, "address: " TARGET_ADDR_FMT ", len: 0x%8.8" PRIx32 - ", r/w/a: %i, value: 0x%8.8" PRIx32 - ", mask: 0x%8.8" PRIx32, + ", r/w/a: %i, value: 0x%8.8" PRIx64 + ", mask: 0x%8.8" PRIx64, watchpoint->address, watchpoint->length, (int)watchpoint->rw, @@ -4076,15 +4076,20 @@ COMMAND_HANDLER(handle_wp_command) enum watchpoint_rw type = WPT_ACCESS; target_addr_t addr = 0; uint32_t length = 0; - uint32_t data_value = 0x0; - uint32_t data_mask = 0xffffffff; + uint64_t data_value = 0x0; + uint64_t data_mask = WATCHPOINT_IGNORE_DATA_VALUE_MASK; + bool mask_specified = false; switch (CMD_ARGC) { case 5: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], data_mask); + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[4], data_mask); + mask_specified = true; /* fall through */ case 4: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], data_value); + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[3], data_value); + // if user specified only data value without mask - the mask should be 0 + if (!mask_specified) + data_mask = 0; /* fall through */ case 3: switch (CMD_ARGV[2][0]) { diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index 431be894b9..c575b534e0 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -2570,7 +2570,7 @@ int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint) return ERROR_TARGET_NOT_HALTED; } - if (watchpoint->mask != ~(uint32_t)0) { + if (watchpoint->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK) { LOG_TARGET_ERROR(target, "watchpoint value masks not supported"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } --