Skip to content

Commit af81a9b

Browse files
committed
[cherry-pick] 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" See: riscv-collab/riscv-openocd#1296 Signed-off-by: Parshintsev Anatoly <[email protected]>
1 parent bf678d7 commit af81a9b

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 %u 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 %u 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 @@ 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)