pulp-platform / riscv-dbg

RISC-V Debug Support for our PULP RISC-V Cores
Other
197 stars 70 forks source link

`sberror` not clearing properly causes OpenOCD interoperability issues #154

Closed timothytrippel closed 1 year ago

timothytrippel commented 1 year ago

The OpenTitan project uses GDB/OpenOCD to develop top-level debug and manufacturing test cases. We have noticed some test failures when performing unaligned system bus accesses (see here).

In short, when an unaligned read operation is performed, sberror is set to 3 (which is correct according to the spec), but after, OpenOCD tries to clear the error with a W1C, by sending 0x7, however, the sberror field fails to clear. We believe there is an RTL bug described here.

Could someone confirm / fix?

andreaskurth commented 1 year ago

I agree that writing 0x7 should clear the entire sberror field:

The RISC-V External Debug Support spec defines sberror as follows (excerpt from version 0.13.2, but version 1.0-STABLE does not differ in aspects relevant for this): 2023-03-31T07:03:16+00:00 and R/W1C as 2023-03-31T07:05:52+00:00

Thus, according to "For each bit in the field, writing 1 clears that bit", 0x7 should indeed clear the entire sberror field.


What should happen when the sberror field (or a W1C field in general) is only partially written, though? The v0.13.2 spec does not define this. v1.0 clearly states that partial writes are not what R/W1C fields are intended for: 2023-03-31T07:16:01+00:00 and 2023-03-31T07:47:06+00:00


In conclusion, I suggest changing https://github.com/pulp-platform/riscv-dbg/blob/09c8d7a4e67f6bde756c4de6319d87e929faf188/src/dm_csrs.sv?plain=1#L466 to

sbcs_d.sberror     = (|sbcs.sberror) ? 3'b0 : sbcs_q.sberror;

so that

If compatibility with current behavior is not a concern, an alternative would be to clear sberror only if all bits are written.

Not clearing all bits on a partial write would not be meaningful IMO, because it modifies the error condition and still does not allow debug accesses.

bluewww commented 1 year ago

I agree with @andreaskurth interpretation of the spec. I would opt for the backwards compatible solution because we might already rely on this behavior in some testbench (assuming the meaning of undefined is the same as in e.g. the C programming language standard)

andreaskurth commented 1 year ago

Thanks for your feedback, @bluewww. :+1:

I did not find a definition of undefined in the RISC-V Debug Spec, and other RISC-V specs I know use implementation-defined instead. But I think interpreting undefined as implementation-defined for the Debug Spec, too, makes sense.

I'll create a PR to implement the backwards-compatible solution