riscv / riscv-debug-spec

Working Draft of the RISC-V Debug Specification Standard
https://jira.riscv.org/browse/RVG-94
Other
454 stars 92 forks source link

Software control of mcontrol6.hit0 and mcontrol6.hit1 and clearing of mcontrol6.hit0 and mcontrol6.hit1 #840

Open Silabs-ArjanB opened 1 year ago

Silabs-ArjanB commented 1 year ago

Before introduction of the hit0 and hit1 bits in mcontrol6 the 'old style' mcontrol.hit had a description allowing user control of the hit bit. Similarly other 'hit' bits (e.g. legacy mcontrol.hit and icount.hit) have descriptions as the following, highlighting that the trigger's user (I assume that means software or debugger) can set/clear hit as well:

If this bit is implemented then it must become set when this trigger fires and may become set when this trigger matches. The trigger’s user can set or clear it at any time.

This 'the trigger’s user can set or clear it at any time' phrase is no longer part of the mcontrol6 hit0/hit1 descriptions. Instead there is now the encoding '0 (false) the trigger did not fire'. That seems quite ambiguous as I would expect that once a trigger fires that its hit0/hit1 info would remain available until either software clears it or that same trigger fires with a different timing reason.

In particular the 'trigger did not fire' condition will typically hold let's say 99.9% of the time (as normally triggers won't fire) and therefore the hit0/hit1 field would end up as 0 before the debugger can inspect it.

Example: We have 4 mcontrol6 triggers set up for load address matching. Initially for some reasons has hit bitfields of these 4 triggers are set to 3. Now suppose there is a load that does not match any of the triggers. I would expect that all hit bitfields remain set to 3 (as opposed to all of them getting set to 0 as the Debug specification seems to imply).

Now, assuming that again the 4 mcontrol6 bitfields are initially 3 and suppose that only instance 0 has a match with before timing and fires for some load instruction and the other 3 triggers do neither match nor fire.

Now I would think that there are two sensible outcomes:

1) Set hit of instance 0 to 1 and leave the hit bitfields of the other 3 instances unchanged (so value 3). 2) Set hit of instance 0 to 1 and set the hit bitfields of the other 3 instances to value 0 (indicating that some trigger fired, but not these ones).

I also would assume that normally the debugger software would clear all hit* bitfields to 0 after having handled an initial firing, right (assuming 'firing into debug mode)?

Could you please clarify the hit operation a bit further and especially whether hardware and/or software is reponsible and/or able to clear the hit bitfield?

Best regards, Arjan

pdonahue-ventana commented 1 year ago

These bits are WARL which means that a debugger can do a write regardless of whether that's explicitly stated in each field description:

Write any, read legal. A debugger may write any value. If a value is unsupported, the implementation converts the value to one that is supported.

The description should probably say that hardware sets the 2-bit field to 1 when firing before, to 2 when firing after, and to 3 when firing immediately after. Otherwise, hardware doesn't write at all. Hardware can support any subset of those three values (including none of them) but it also must support the value 0 (which can only occur on reset or when software does a write).

The debugger can do whatever it wants with this field but presumably it will write 0 so it can detect when hardware writes one of the other 3 values.

Silabs-ArjanB commented 1 year ago

Hi @pdonahue-ventana Thank you for your quick answer. That makes complete sense. Just having the sentence somewhere that hardware writes are limited to writing 1, 2, or 3 would suffice to make this clear.

If you want you can close this issue (or you can keep it open if you want to change the documentation later).

Best regards, arjan