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);
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;
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],
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],
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;
}
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;
}
}
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;
}
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;
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;
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 */
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- /* hardware doesn't support data value masking */
- if (watchpoint->mask != ~(uint32_t)0) {
+ /* REVISIT This DWT may well be able to watch for specific data
+ * values. Requires comparator #1 to set DATAVMATCH and match
+ * the data, and another comparator (DATAVADDR0) matching addr.
+ *
+ * NOTE: hardware doesn't support data value masking, so we'll need
+ * to check that mask is zero
+ */
+ if (watchpoint->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK) {
LOG_TARGET_DEBUG(target, "watchpoint value masks not supported");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- /* Caller doesn't seem to be able to describe watching for data
- * values of zero; that flags "no value".
- *
- * REVISIT This DWT may well be able to watch for specific data
- * values. Requires comparator #1 to set DATAVMATCH and match
- * the data, and another comparator (DATAVADDR0) matching addr.
- */
- if (watchpoint->value) {
- LOG_TARGET_DEBUG(target, "data value watchpoint not YET supported");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
cortex_m->dwt_comp_available--;
LOG_TARGET_DEBUG(target, "dwt_comp_available: %d", cortex_m->dwt_comp_available);
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,
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]) {
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- if (watchpoint->value)
+ if (watchpoint->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK)
LOG_WARNING("xscale does not support value, mask arguments; ignoring");
/* check that length is a power of two */
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;
}