riscv-non-isa / riscv-sbi-doc

Documentation for the RISC-V Supervisor Binary Interface
https://jira.riscv.org/browse/RVG-49
Creative Commons Attribution 4.0 International
350 stars 90 forks source link

DBTR How to discovery chained triggers capabilities #163

Open mmamayka opened 2 months ago

mmamayka commented 2 months ago

Current version of DBTR extension documentation proposes to use sbi_debug_num_triggers in boot time of S-mode application due to discovery of hardware debug triggers capabilities. It easily allows to count number of triggers that support configuration specified with tdata1 CSR value, discover supported trigger types & optional bit fields.

But It is unclear how chaining capabilities could be discovered using this method. What method should be used to figure out

As an example we can meet hardware implementation supporting 4 mcontrol6 triggers where the 1st and 3rd triggers are breakpoints only, 2nd and 4th triggers are watchpoints only. In this case probe with sbi_debug_num_triggers says us, that there are 2 breakpoints supported, but there is no way to get out information, that breakpoints can't be chained.

atishp04 commented 4 days ago

@avpatel @hschauhan

avpatel commented 4 days ago

The SBI DBTR extension exposes logical debug triggers to the supervisor software because the SBI implementation could be a hypervisor running in HS-mode where the debug triggers are shared between host (hypervisor) and guest. Even for M-mode SBI implementation, the debug triggers might be shared between external debugger and HS-mode.

The sbi_debug_num_triggers() returns the number of debug triggers on the calling hart which can support the trigger configuration specified by the trig_tdata1 parameter. Over here as well, it is logical debug triggers and not physical or hardware triggers. Please note that, the SBI implementation may intentionally not support certain trigger configuration (i.e. trig_tdata1) in which case the sbi_debug_num_triggers() will return 0 for such trigger configuration.

To detect chaining, just pass a valid trig_tdata1 parameter with chain bit set so that sbi_debug_num_triggers() will return how many logical debug triggers support it. The sbi_debug_install_triggers() has a requirement which ensures that SBI implementation MUST use contiguous physical / hardware triggers for chained trigger configuration.

mmamayka commented 4 hours ago

Hi, @avpatel, thank you for your reply!

As you said, chaining capabilities of hardware debug triggers can be discovered with the sbi_debug_num_triggers() call along with other trigger features. It works fine without chaining because each debug trigger is a separate entity which features may be easily discovered with the sbi_debug_num_triggers() call. Thus we can just ask SBI about each trigger we want to install, get the number of places where it is possible to install it and make the sbi_debug_install_triggers() call, being sure that it will likely be successful. However, it works well only because unchained triggers do not require information about the order, i. e. SBI is free to install required debug trigger at any physical id (satisfying all limitations of hypervisor, external debugger and hardware).

Process of discovering chained triggers capabilities requires information about the order of the hardware debug triggers, because Sdtrig extension specification allows hardware to have non-uniform triggers, where some set of triggers supports only a subset of features. As an example, I can propose a valid hardware configuration (in terms of Sdtrig SPEC) that has the following hardware debug triggers structure:

trig0 mcontrol6: `load`, `store`, `chain` bits supported, `execute` did not (watchpoint trigger)
trig1 mcontrol6: `load`, `store`, `chain` bits supported, 'chain' and `execute` did not (watchpoint trigger)
trig2 mcontrol6: `execute` bit supported, `load`, `store` and 'chain' did not (breakpoint trigger)
trig3 mcontrol6: `load`, `store`, `chain` bits supported, `execute` did not (watchpoint trigger)
trig4 mcontrol6: `load`, `store`, `chain` bits supported, 'chain' and `execute` did not (watchpoint trigger)

In this case the sbi_debug_num_triggers() call will detect two triggers with chaining and load, store bits support, but there is no way to determine from current SBI SPEC that it is impossible to setup three-trigger-length chain. Thus, there is no way to find out possible chained triggers configurations in S-mode software and particularly to find out max length of each or at least any chain. So the main point of my longread is that lack of knowledge about triggers order makes it impossible to discover the capabilities of chained non-uniform triggers .

When faced with this problem it is tempting to use sbi_debug_install_triggers for discovery of chaining hardware capabilities, but it still does not enough for the discovery, because this call does not provide any transactional semantics guarantees. I mean that being called with N triggers to be installed sbi_debug_install_triggers may fail on Mth (where M < N) trigger installation and left 1st .. (M-1)th triggers installed raising a error (as I see the SBI SPEC). Of course, you mentioned that sbi_debug_install_triggers() should not be used for triggers capabilities discovery, but it is the only way to gain any knowledge about triggers order.

Could you please comment this on whether this idea is correct? In turn, I may be wrong, misunderstanding something in SBI SPEC. If that is the case, I would propose to make the sbi_debug_num_triggers() call take an array of tdata1 trigger values and return non-zero value in case the triggers configuration can be installed on the current hardware (or to make separate call for this purpose). What do you think about this?

P. S. I suppose, there is also another problem with sbi_debug_num_triggers() and sbi_debug_install_triggers() calls pair. Two different calls do not provide an atomic interface of hardware debug triggers discovery and installation. The triggers can be 'stolen' between sbi_debug_num_triggers() and sbi_debug_install_triggers() calls by a hypervisor or external debugger, so discovered triggers configuration may be changed multiple times between these calls... However, in absence of hypervisor and external debugger, the previous problem is much more significant in my opinion...