Skip to content

Commit

Permalink
Switch to use Smstateen, and add stselect CSR
Browse files Browse the repository at this point in the history
  • Loading branch information
bcstrongx committed Aug 9, 2024
1 parent 9885059 commit 4ec296c
Showing 1 changed file with 51 additions and 66 deletions.
117 changes: 51 additions & 66 deletions riscv-smtdeleg-sstcfg.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,107 +7,92 @@ Supervisor-level environment, extension *Sstcfg* (‘Ss’ for Privileged archit
[[body]]
== CSRs

=== Machine Trigger Delegation Register (`tdeleg`)
=== Supervisor Trigger Select (`stselect`)

`tdeleg` is a 64-bit register, accessible only in M-mode, that allows M-mode to delegate select triggers to S-mode. For each bit _i_ in `tdeleg`, when `tdeleg`[_i_] = 1, the trigger with index _i_ (accessible via tdata* when tselect=_i_) is delegated to S-mode.
`stselect` provides access to `tselect` from S-mode and VS-mode.

For RV32, bits 63:32 of `tdeleg` can be accessed via the `tdelegh` CSR.
== Supervisor and Virtual Supervisor Trigger Access

[NOTE]
====
_Sdtrig allows up to 2^32^ triggers to be implemented. Only the lower 64 triggers can be delegated._
====
While `siselect` holds XXX, the `sireg*` registers provide access to the `tdata*` and `tinfo` registers associated with the trigger selected in `tselect`. The register mapping is shown below.

.Indirect Trigger Register Mappings
[width="50%",options="header"]
|===
| Indirect CSR | Sdtrig CSR
| `sireg` | `tdata1`
| `sireg2` | `tdata2`
| `sireg3` | `tdata3`
| `sireg4` | `tinfo`
|===

[WARN]
====
_It is an open question whether selective trigger delegation is needed, or whether a single bit to delegate all triggers will suffice. The latter has the benefit of saving CSRs, and does not impose a limit on the number of triggers that can be delegated. Selective delegation is only needed if we believe that M-mode may either want to preserve some triggers for its own use, or want to block exposure of some triggers to S-mode._
_There has been much discussion of the best way to access counters in S-mode. This method requires 1 new CSR (`stselect`), and creates a scenario where there are 2 levels of indirection (siselect routes sireg* to t*, and tselect routes t* to the state associated with the selected trigger)._
_If selective triggering is preferred, the next question is how many to support. We could add additional `tdeleg` CSRs if more than 64 are desired._
====
_Also proposed was to simply allocate a range of `siselect` values that serve to select the trigger, bypassing `tselect` when accessing trigger state through `sireg*`. This avoids the 2nd level of indirection, but artificially limits the number of triggers accessible in S-mode. `tselect` supports up to 2^32^ triggers, while `siselect` would likely allocate only enough values to cover practical implementations (256?)._
=== Hypervisor Trigger Delegation Register (`htdeleg`)
_A third approach was considered, akin to what is spec'd here but accessing `tselect` via `sireg5` instead of through a new `stselect` CSR. While saving a CSR, this approach would require `sireg5` to continue to access `tselect` while the other `sireg*` registers shift the state they acccess based on the `tselect` value. This approach seems more awkward for implementation._
`htdeleg` is a 64-bit register that allows HS-mode to further delegate triggers delegated to S-mode to VS-mode. For each bit _i_ in `htdeleg`, when `tdeleg`[_i_] = 1 and `htdeleg`[_i_] = 1, the trigger with index _i_ (accessible via tdata* when tselect=_i_) is delegated to VS-mode.
_Feedback on these options, or others, is welcome._
====

For RV32, bits 63:32 of `htdeleg` can be accessed via the `htdelegh` CSR.
Similarly, when `vsiselect` holds XXX, the `vsireg*` registers provide access to `tdata*` and `tinfo` in the same manner as described above for `sireg*`.

== Trigger Delegation
=== Trigger State Access Modifications

The `siselect` (and `vsiselect`) index range 0x300-0x33F (_actual range TBD_) is reserved for delegated trigger access. When a trigger _i_ is delegated (`tdeleg`[_i_]=1), the Sdtrig registers associated with trigger _i_ can be read or written via `sireg*`, while `siselect` holds 0x300+__i__. If the H extension is also implemented, the registers associated with trigger _i_ can also be read or written via `vsireg*` while `vsiselect` holds 0x300+__i__. The mapping of sireg* and vsireg* registers to Sdtrig trigger registers is shown below.
`sireg*` and `vsireg*` provide access to a subset of the fields in the native trigger CSRs, and in some cases fields are relocated. The field modifications that apply when trigger registers are accessed via `sireg*` or `vsireg*` are documented below.

.Indirect Trigger Register Mappings
[width="50%",options="header"]
|===
| Sdtrig CSR | Indirect CSR
| tdata1 | sireg/vsireg
| tdata2 | sireg2/vsireg2
| tdata3 | sireg3/vsireg3
| tinfo | sireg4/vsireg4
.Delegated Trigger CSR Field Modifications
[options="header", cols="20%,30%,50%"]
|===
| Sdtrig Register | `sireg*` Field Modifications | `vsireg*` Field Modifications
| `tdata1` | M is read-only 0

[WARN]
====
_The use of Sscsrind for trigger access again limits the number of triggers that can be delegated, since siselect is only required to hold values up to 0xfff, and that value space is shared with other extensions that depend on Sscsrind. That said, it is expected that a sufficient range of siselect values can be applied to cover the number of triggers implemented in any practical implementation (256?)._
VS and VU are read-only 0

_Alternatives have been discussed that would provide S-mode access to tselect, bypassing any limitations imposed by siselect. However, that would require either having sireg* depend on tselect, or defining additional S-mode CSRs to access tdata*/tinfo. In the interest of simplicity and consistency, this proposal uses Sscsrind in a natural manner._
====
| M is read-only 0

If extension Smstateen is implemented, refer to extension Sscsrind (upon which this extension depends) for how setting bit 60 of CSR mstateen0 to zero prevents access to registers `siselect`, `sireg*`, `vsiselect`, and `vsireg*` from privileged modes less privileged than M-mode, and likewise how setting bit 60 of hstateen0 to zero prevents access to `siselect` and `sireg*` (really `vsiselect` and `vsireg*`) from VS-mode.
S accesses `tdata1`.VS

The remaining rules of this section apply only when access to a CSR is not blocked by mstateen0[60] = 0 or hstateen0[60] = 0.
U accesses `tdata1`.VU

While the privilege mode is M or S and `siselect` holds a value in the range 0x300-0x33F, illegal instruction exceptions are raised for the following cases:
VS and VU are read-only 0
| `tdata2` | none | none
| `tdata3` | none | MHVALUE and MHSELECT are read-only 0
| `tinfo` | none | none
|===

* attempts to access `sireg5`, `sireg6`, `vsireg5`, or `vsireg6`;
* attempts to access `sireg*` when the trigger selected by `siselect` is not delegated to S-mode (the corresponding bit in `tdeleg` = 0);
* attempts to access `vsireg*` when the trigger selected by `vsiselect` is not delegated to S-mode.
When `tdata1.dmode` = 1 for the trigger with index _i_, the trigger is reserved for Debug Mode use. In that case, when `tselect` holds _i_ and the hart is not in Debug Mode, writes to `sireg` and `sireg[234]` are ignored while `siselect` holds XXX, and writes to `vsireg` and `vsireg[234]` are ignored while `vsiselect` holds XXX.

While the privilege mode is VS and `vsiselect` holds a value in the range 0x300-0x33F, virtual instruction exceptions are raised for the following cases:
== Supervisor and Virtual Supervisor Trigger State Access Control

* attempts to access `sireg5` (really `vsireg5`) or `sireg6` (really `vsireg6`);
* attempts to access `sireg*` (really `vsireg*`) when the trigger selected by `vsiselect` is not delegated to VS-mode (the corresponding bit in `tdeleg` or `htdeleg` = 0).
While the privilege mode is M or S and `siselect` holds XXX, illegal instruction exceptions are raised for attempts to access `sireg5` or `sireg6`. Similarly, while the privilege mode is M or S and `vsiselect` holds XXX, illegal instruction exceptions are raised for attempts to access `vsireg5`, or `vsireg6`.

=== Trigger State Access
While the privilege mode is VS and `vsiselect` holds XXX, virtual instruction exceptions are raised for attempts to access `sireg5` (really `vsireg5`) or `sireg6` (really `vsireg6`).

For delegated triggers, `sireg*` and `vsireg*` provide access to a subset of the fields in the native trigger CSRs, and in some cases field behavior is modified. The modifications and restrictions are documented below.
=== State Enable Access Control

.Delegated Trigger CSR Field Modifications
[options="header", cols="20%,30%,50%"]
|===
| Sdtrig Register | `sireg*` Modifications | `vsireg*` Modifications
| `tdata1` | `m` is read-only 0 | `m` is read-only 0
When Smstateen is implemented, the `mstateen0`.TR bit controls access to Sdtrig register state from privilege modes less privileged than M-mode. When `mstateen0`.TR=1, accesses to Sdtrig register state behave as described in <<Supervisor and Virtual Supervisor Trigger Access>> above. When `mstateen0`.TR=0 and the privilege mode is less privileged than M-mode, attempts to access `sireg` or `sireg[234]` while `siselect` holds XXX, or to access `vsireg` or `vsireg[234]` while `vsiselect` holds XXX, raise an illegal-instruction exception.

`s` enables trigger match in VS-mode
If the H extension is implemented and `mstateen0`.TR=1, the `hstateen0`.TR bit controls access to Sdtrig state when V=1. `hstateen0`.TR is read-only 0 when `mstateen0`.TR=0.

`u` enables trigger match in VU-mode
When `mstateen0`.TR=1 and `hstateen0`.TR=1, VS-mode accesses to supervisor TR state behave as described in <<Supervisor and Virtual Supervisor Trigger Access>> above. When `mstateen0`.TR=1 and `hstateen0`.TR=0, attempts from VS-mode to access `sireg` (really `vsireg`) or `sireg[234]` (really `vsireg[234]`) while `vsiselect` holds XXX raise a virtual-instruction exception.

`vs` and `vu` are read-only 0
| `tdata2` | none | none
| `tdata3` | none | `mhvalue` and `mhselect` are read-only 0
| `tinfo` | none | none
|===
The TR bit is bit YYY in `mstateen0` and `hstateen0`.

[NOTE]
[%unbreakable]
====
_It is assumed that a hypervisor will not delegate triggers to a nested hypervisor running in VS-mode. In such cases an SBI interface will be preferred, allowing the L0 hypervisor, running in HS-mode, to emulate the behavior of fields like `vs`, `vu`, and `mhvalue`/`mhselect`._
_See the Sscsrind spec for how bit 60 in mstateen0 and hstateen0 can also restrict access to `sireg*`/`siselect` and `vsireg*`/`vsiselect` from privilege modes less privileged than M-mode._
====

When `tdata1.dmode` = 1 for the trigger with index _i_, the trigger is reserved for Debug Mode use. In that case, when not in Debug Mode, writes to `sireg` and `sireg[234]` are dropped when `siselect` holds 0x300+_i_, while writes to `vsireg` and `vsireg[234]` are dropped when `vsiselect` holds 0x300+_i_.

== Enumeration
[WARN]
====
_Utilizing Smstateen to control access to trigger state in S-mode and VS-mode results in an "all or none" delegation mechanism. It is believed that this is sufficient, that software is not accustomed to exposing only select triggers to less privileged modes on other architectures._
S-mode software can discover the capabilities of triggers delegated to S-mode as follows:
_If there is a reason to support selective delegation, new `tdelegX` and `htdelegX` registers could be defined, such that each bit enables delegation of the associated trigger. However, this would artificially limit the number of triggers that could be delegated._
====

1. Write 0x300 to `siselect`
2. Read `tinfo` (`sireg4`)
* If the read returns 0, tinfo is either not implemented or the trigger is not delegated, go to #3
* If `tinfo.info`=1, the trigger is not implemented, exit the loop
* Otherwise record the supported types found in `tinfo.info`, then go to #4
3. Read `tdata1` (`sireg`)
* If the read returns 0, the trigger is either not implemented or not delegated, go to #4
* Otherwise record the type in `tdata1.type`, then go to #4
4. If `siselect` < 0x33F, increment `siselect` and go to #2, else exit the loop

VS-mode software can use the same algorithm to discover the capabilities of triggers delegated to VS-mode.


0 comments on commit 4ec296c

Please sign in to comment.