Skip to content

Commit 785bda1

Browse files
committed
fix error detection during trigger removal
The error manifests on designs that allow CSR reads when hart is not halted. This results in `rwp` command to erroneously report "success" Signed-off-by: Parshintsev Anatoly <[email protected]>
1 parent 608ba43 commit 785bda1

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

src/target/riscv/riscv.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,22 +1669,38 @@ static int remove_trigger(struct target *target, int unique_id)
16691669

16701670
bool done = false;
16711671
for (unsigned int i = 0; i < r->trigger_count; i++) {
1672-
if (r->trigger_unique_id[i] == unique_id) {
1673-
riscv_reg_set(target, GDB_REGNO_TSELECT, i);
1674-
riscv_reg_set(target, GDB_REGNO_TDATA1, 0);
1675-
r->trigger_unique_id[i] = -1;
1676-
LOG_TARGET_DEBUG(target, "Stop using resource %d for bp %d",
1677-
i, unique_id);
1678-
done = true;
1672+
if (r->trigger_unique_id[i] != unique_id)
1673+
continue;
1674+
done = false;
1675+
result = riscv_reg_set(target, GDB_REGNO_TSELECT, i);
1676+
if (result == ERROR_OK)
1677+
result = riscv_reg_set(target, GDB_REGNO_TDATA1, 0);
1678+
if (result != ERROR_OK) {
1679+
LOG_TARGET_ERROR(target,
1680+
"Could not free resource %d for bp %d. "
1681+
"Target is in a potentially unrecoverable state!",
1682+
i, unique_id);
1683+
return ERROR_FAIL;
16791684
}
1685+
r->trigger_unique_id[i] = -1;
1686+
LOG_TARGET_DEBUG(target, "Stop using resource %d for bp %d",
1687+
i, unique_id);
1688+
done = true;
16801689
}
16811690
if (!done) {
16821691
LOG_TARGET_ERROR(target,
16831692
"Couldn't find the hardware resources used by hardware trigger.");
16841693
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
16851694
}
16861695

1687-
riscv_reg_set(target, GDB_REGNO_TSELECT, tselect);
1696+
result = riscv_reg_set(target, GDB_REGNO_TSELECT, tselect);
1697+
if (result != ERROR_OK) {
1698+
LOG_TARGET_ERROR(target,
1699+
"Could not restore tselect after bp %d removal. "
1700+
"Target is in a potentially unrecoverable state!",
1701+
unique_id);
1702+
return ERROR_FAIL;
1703+
}
16881704

16891705
return ERROR_OK;
16901706
}
@@ -1713,6 +1729,8 @@ static int riscv_remove_breakpoint(struct target *target,
17131729
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
17141730
}
17151731

1732+
/* FIXME: we should clear this flag even if remove_trigger fails for cases
1733+
* when all HW resources from Trigger Module were de-allocated */
17161734
breakpoint->is_set = false;
17171735

17181736
return ERROR_OK;
@@ -1763,6 +1781,8 @@ int riscv_remove_watchpoint(struct target *target,
17631781
int result = remove_trigger(target, trigger.unique_id);
17641782
if (result != ERROR_OK)
17651783
return result;
1784+
/* FIXME: we should clear this flag even if remove_trigger fails for cases
1785+
* when all HW resources from Trigger Module were de-allocated */
17661786
watchpoint->is_set = false;
17671787

17681788
return ERROR_OK;

0 commit comments

Comments
 (0)