riscv-openocd icon indicating copy to clipboard operation
riscv-openocd copied to clipboard

Enabling ebreaks after reset

Open erhankur opened this issue 3 years ago • 6 comments

I wonder which part of the code will be responsible to set dcsr.ebreak bits immediately after reset?

There are 3 flags inside riscv.c

bool riscv_ebreakm = true;
bool riscv_ebreaks = true;
bool riscv_ebreaku = true;

They are in use only in riscv013_on_step_or_resume() But what about the reset conditions which occurred while OpenOCD is running? dcsr.ebreakX bits will return to default state (zero) and needs to be set again.

Is it expected to handle in TARGET_EVENT_RESET_ASSERT ?

erhankur avatar Mar 02 '22 13:03 erhankur

I confirm your point is valid - dcsr.ebreakX bits are currently not handled after reset.

One consequence of this issue is that syscalls (semihosting) won't work if the program execution is started by reset run TCL command.

For resets triggered by OpenOCD itself - I'd recommend to set the ebreak bits in the deassert_reset() callback (riscv-013.c#L2382).

As for resets triggered outside of OpenOCD - I do not know how to best handle them, or if there is a reliable enough solution.

JanMatCodasip avatar Mar 02 '22 13:03 JanMatCodasip

As for resets triggered outside of OpenOCD - I do not know how to best handle them, or if there is a reliable enough solution.

In this case, we are enabling ebreaks in on_reset()callback which I mentioned at this PR

This question came into my mind while I was thinking to replace it with more reliable solution.

We need to understand the core was reset, then halt the core, set dcsr.ebreakX bits and then resume the core again.

erhankur avatar Mar 02 '22 14:03 erhankur

It seems reasonable to have OpenOCD always set resethaltreq, so that if the hart resets for any reason, it will halt. Then OpenOCD can set the ebreak bits and resume the hart if the user expects it to be running. resethaltreq must be cleared before exiting.

timsifive avatar Mar 02 '22 18:03 timsifive

Hi Tim, I would like to implement this feature.

As a summary; we need to handle 2 reset scenarios;

1- OpenOCD resets; as @JanMatCodasip suggested, it can be handled in the deassert_reset() callback 2- External resets; you said resethaltreq is a good option for this. Can you elaborate the flow in your mind?

erhankur avatar Jun 06 '22 15:06 erhankur

I didn't think about any of the details, but essentially the debugger should make sure resethaltreq is always set. When an unexpected reset occurs, the target will halt. OpenOCD will notice while polling and then can set the ebreak* bits to their expected values. Then if the target is supposed to be running, OpenOCD can let it run.

timsifive avatar Jun 06 '22 16:06 timsifive