Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hit bit interaction with action conflict when several triggers of the same priority match #1018

Open
en-sc opened this issue Apr 25, 2024 · 3 comments

Comments

@en-sc
Copy link
Contributor

en-sc commented Apr 25, 2024

From [5.3. Priority]:

When multiple triggers in the same priority fire at once, ... If one of these triggers has the "enter Debug Mode" action (1) and another trigger has the "raise a breakpoint exception" action (0), the preferred behavior is to have both actions take place. ... If this is not implemented, then the hart must enter Debug Mode and ignore the breakpoint exception. In the latter case, hit of the trigger whose action is 0 must still be set, giving a debugger an opportunity to handle this case.

  1. Question is about hit ... must still be set part. Is my understanding correct that either:
  • HW takes both actions ( "enter Debug Mode" & "raise a breakpoint exception")
  • HW only enters Debug Mode, but hit bit is required to be set, therefore the hit bit is expected to be supported by HW.
  1. Some trigger types are defined to set hit bit only when the trigger fires.
  • mcontrol6

The TM updates this field when the trigger fires.

  • icount:

If this bit is implemented, the hardware sets it when this trigger fires.

  • Trigger firing is defined as follows:

A trigger fires when a trigger that matches performs the action configured for that trigger.

  • Lets assume that the trigger with action "raise a breakpoint exception" in the case in question is one of mcontrol6 or icount.

  • Lets assume HW only enters Debug Mode without raising a breakpoint exception.

  • "breakpoint exception" has not been risen -> the trigger with action "raise a breakpoint exception" has not fired -> hit bit can not be set to 1.

  1. From points (1) and (2) it seems to follow that either:
  • HW takes both actions ( "enter Debug Mode" & "raise a breakpoint exception")
  • Triggers with action (0) and type mcontrol6 or icount can not be supported.

Can you please point to a mistake in my logic or clarify such case?

@pdonahue-ventana
Copy link
Collaborator

Question is about hit ... must still be set part. Is my understanding correct that either:

  • HW takes both actions ( "enter Debug Mode" & "raise a breakpoint exception")
  • HW only enters Debug Mode, but hit bit is required to be set, therefore the hit bit is expected to be supported by HW.

I don't think that the intention was for this obscure part of the spec to require hit to be implemented. Requirements like that should be more obvious. It should say "hit (if supported) ... must still be set" or something like that.

I don't think that I understand your point 3. Can you give a specific example where you give two triggers of certain types with certain actions and then what you think the problem is?

@en-sc
Copy link
Contributor Author

en-sc commented Apr 26, 2024

  • Assumption A: Trigger A: type mcontrol6 or icount, action: "raise a breakpoint exception"
  • Assumption B: Trigger B: any type, action: "enter Debug Mode"
  • Assumption C: Both triggers match on the same instruction.
  • Assumption D: HW does not support taking both actions ("enter Debug Mode" & "raise a breakpoint exception").
  • HW enters debug mode but does not raise a breakpoint exception
  • Trigger A had not fired, since the requested action ("raise a breakpoint exception") was not taken.
  • Trigger A can not have it's hit bit set, since it had not fired.
  • Contradiction: hit of the trigger whose action is 0 must still be set.

Therefore at least one of the assumptions should be false, in particular:

  • Trigger A: type mcontrol6 or icount, action: "raise a breakpoint exception" -- these triggers should not be supported.
  • Trigger B: any type, action: "enter Debug Mode" -- these triggers should not be supported.
  • Both triggers match on the same instruction -- HW should somehow ensure during setup that this is impossible (seems like an impossible task).
  • HW does not support taking both actions ("enter Debug Mode" & "raise a breakpoint exception") -- HW should support this case insted.

So, strictly speaking my conclusion was not correct. It should have been:
The following seems to be implied by the specification:
If triggers with action "enter Debug Mode" are supported and HW does not support taking both actions ("enter Debug Mode" & "raise a breakpoint exception")
then triggers with type mcontrol6 or icount and action: "raise a breakpoint exception" should not be supported.

I think this should be clarified.


I don't think that the intention was for this obscure part of the spec to require hit to be implemented. Requirements like that should be more obvious. It should say "hit (if supported) ... must still be set"

But in such case (HW does not take both actions and there are no hit bits) the debugger will not be able to emulate the breakpoint exception. So the fact that the debugger configured a trigger will change control flow of the program. I think this is
not the desired result.

@pdonahue-ventana
Copy link
Collaborator

The spec says:

If one of these triggers has the "enter Debug Mode" action (1) and another
trigger has the "raise a breakpoint exception" action (0), the preferred behavior is to have both actions
take place. It is implementation-dependent which of the two happens first.

This says that you could have both actions take place where entering Debug Mode happens first. That doesn't directly make sense because if you enter Debug Mode then you can't subsequently trap to M mode (or some other mode dictated by medeleg/hedeleg). My assumption has been that the two actions would happen at completely different times. You would enter Debug Mode and nothing else would happen right away. The external debugger does whatever it wants and when it wants to restart, it would:

  1. disable the trigger with action=1 that caused the halt (to prevent it from firing in step 2)
  2. single-step
  3. enable the trigger with action=1 that caused the halt (to allow it to fire in the future)
  4. resume

On step 2, the other trigger with action=0 would fire. In particular, the dpc after the single step would point to the breakpoint handler and step 4 would resume execution in the breakpoint handler. In the end, both actions were taken (separated by quite a bit of time).

If the external debugger is going to emulate the instruction rather than reexecuting it (skipping steps 1/2/3 and incrementing dpc before doing step 4) then it needs to emulate everything related to that instruction, including any other triggers. Whether an implementation has a hit bit doesn't matter. For each trigger, the emulator needs to do address/data comparison, looking at mode filters, looking at chaining, etc. It's not trivial but it's possible (just as it's possible for software to emulate all aspects of hardware).

I wouldn't be surprised if existing debuggers simply don't support having multiple simultaneous debuggers (native and external) running at the same time. But they could support that if they do the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants