This is an automated email from Gerrit. "Viraaj Somayajula <viraajsomayaj...@intensivate.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8342
-- gerrit commit 11acc318c19a3e06197348b24feef62a96561033 Author: Viraaj Somayajula <viraajsomayaj...@intensivate.com> Date: Sat Jun 15 22:28:27 2024 -0400 target/riscv: Check before executing abstract command From the riscv debug spec - 0.13.2: "Before starting an abstract command, a debugger must ensure that haltreq, resumereq, and ackhavereset are all 0" Also, when executing ndmreset, there is a chance that the hardware does not accept ndmreset if ndmactive is 0. When writing ndmactive and ndmreset together, the hardware may not accept the ndmreset. To be safe, first set ndmactive to 1 and then assert ndmreset. Change-Id: I7dc0fbc318c35e554a29095aac69a0e81192e54b Signed-off-by: Viraaj Somayajula <viraajsomayaj...@intensivate.com> diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 2f4a8fe2e6..27fec7e570 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -789,6 +789,23 @@ static int execute_abstract_command(struct target *target, uint32_t command) break; } } + /* + * Before starting an abstract command, a debugger must ensure that haltreq, resumereq, and + * ackhavereset are all 0 + */ + + uint32_t dmcontrol = 0; + + if (dmi_read(target, &dmcontrol, DM_DMCONTROL) != ERROR_OK) + return ERROR_FAIL; + + if (dmcontrol & (DM_DMCONTROL_HALTREQ | DM_DMCONTROL_RESUMEREQ | DM_DMCONTROL_ACKHAVERESET) + != 0x0) { + dmcontrol = set_field(dmcontrol, DM_DMCONTROL_HALTREQ | DM_DMCONTROL_RESUMEREQ + | DM_DMCONTROL_ACKHAVERESET, 0); + dmi_write(target, DM_DMCONTROL, dmcontrol); + } + if (dmi_write_exec(target, DM_COMMAND, command, false) != ERROR_OK) return ERROR_FAIL; @@ -2368,6 +2385,9 @@ static int assert_reset(struct target *target) uint32_t control = set_hartsel(control_base, r->current_hartid); control = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0); + dmi_write(target, DM_DMCONTROL, control); + + /* Assert ndmreset */ control = set_field(control, DM_DMCONTROL_NDMRESET, 1); dmi_write(target, DM_DMCONTROL, control); } --