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

- Add S-mode debug CSR for debug #60

Merged
merged 6 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 138 additions & 61 deletions chapter2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ When debug is allowed in supervisor domain, <<dbops, debug operations>> are allo
[[dbgaccpriv]]
==== Debug Access Privilege

The *debug access privilege* is defined as the privilege level granted to the external debugger to access hardware resources with abstract commands or program buffers. Memory and register accesses from Debug Mode also carry *debug access privilege* instead of always with M-mode. The *debug access privilege* is represented by the `prv` and `v` fields in dcsr. The legal privilege levels programmable to `dcsr` in Debug Mode are elaborated in <<prvvacc>>. Debugger accesses to registers and memory will be checked by permission check mechanisms against *debug access privilege*, and trigger traps if they violate corresponding rules.
The *debug access privilege* is defined as the privilege level granted to the external debugger to access hardware resources with abstract commands or program buffers. Memory and register accesses from Debug Mode also carry *debug access privilege* instead of always with M-mode. The *debug access privilege* is represented by the `prv` and `v` fields in `dcsr` or <<ssdextcsr, sdcsr>>. The legal privilege levels programmable to the fields in Debug Mode are elaborated in <<prvvacc>>. Debugger accesses to registers and memory will be checked by permission check mechanisms against *debug access privilege*, and trap if they violate corresponding rules.
AoteJin marked this conversation as resolved.
Show resolved Hide resolved

[[prvvacc]]
===== Configuring dcsr for External Debugger Access Privileges
===== Configuring External Debugger Access Privileges

The dcsr (at 0x7b0) is always accessible in Debug Mode and the `prv` and `v` fields in the dcsr have been modified to authorize privilege for external debug accesses. Upon transitioning into Debug Mode, the `prv` and `v` fields are updated to the privilege level the hart was previously operating in. The maximum debug privilege level that can be configured in `prv` and `v` is determined in <<maxdbgpriv>>. The fields retain legal values when the `prv` and `v` are configured with an illegal privilege level. Illegal privilege levels include unsupported levels and any level higher than the maximum allowed debug privilege. When the hart resumes from Debug Mode, the current privilege mode and virtualization mode are changed to that specified by `prv` and `v`.
The `prv` and `v` fields have been modified to authorize privilege for external debug accesses. Upon transitioning into Debug Mode, the `prv` and `v` fields are updated to the privilege level the hart was previously operating in. The maximum debug privilege level that can be configured in `prv` and `v` is determined in <<maxdbgpriv>>. The fields retain legal values when the `prv` and `v` are configured with an illegal privilege level. Illegal privilege levels include unsupported levels and any level higher than the maximum allowed debug privilege. When the hart resumes from Debug Mode, the current privilege mode and virtualization mode are changed to that specified by `prv` and `v`.

[[maxdbgpriv]]
[options="header"]
Expand All @@ -78,38 +78,36 @@ The dcsr (at 0x7b0) is always accessible in Debug Mode and the `prv` and `v` fie
|=========================================

[NOTE]
As the `prv` and `v` fields in dcsr are Write Any Read Legal (WARL) fields, the external debugger is able to read back the written value to determine the maximum debug privilege level.
As the `prv` and `v` fields are Write Any Read Legal (WARL) fields, the external debugger is able to read back the written value to determine the maximum debug privilege level.

==== Privilege Level Changing Instructions

The RISC-V Debug Specification cite:[dbgspec] defines that the instructions that change the privilege mode have UNSPECIFIED behavior when executed within the Program Buffer, with exception of the ebreak instruction. In Sdsec, those instructions including mret, sret, uret, ecall, must either act as NOP or trigger an exception (stopping execution and setting `cmderr` to 3) in Program Buffer. Notably, these instructions retain their normal functionality during single stepping.

==== Interrupt during Single Stepping

The interrupt can be disabled by `stepie` in the dcsr during single stepping. When `mdbgen` is 1, `stepie` disables interrupts in all privilege modes for the hart. When `mdbgen` is 0 and `sdedbgalw` is 1, only interrupts delegated to the supervisor domain are disabled, while interrupts that trap to M-mode are not affected.
The interrupt can be disabled by `stepie` during single stepping. When `mdbgen` is 1, `stepie` disables interrupts in all privilege modes for the hart. When `mdbgen` is 0 and `sdedbgalw` is 1, only interrupts delegated to the supervisor domain are disabled, while interrupts that trap to M-mode are not affected.
AoteJin marked this conversation as resolved.
Show resolved Hide resolved

[NOTE]
When debugging is only allowed for the supervisor domain, M-mode interrupts must not be disabled. Otherwise, debugging might impact the behavior of other parts of the system. For example, if a context switch for the supervisor domain triggered by a timer interrupt is suppressed, some real-time workloads might not be completed on time, resulting in unexpected errors.

=== Trace
When Sdsec is supported, trace, as a non-intrusive debug method, will be constrained based on RISC-V privilege level. The availability of trace output is indicated through the interface defined in <<<_reference to the trace interface doc_>>> to trace module.

[mtrcctl]
==== M-Mode Trace Control
Each hart must add a new state element, `mtrcen`, which controls the availability of M-mode tracing. Setting `mtrcen` to 1 enables trace for both M-mode and the supervisor domain; setting `mtrcen` to 0 disables trace output when the hart is running in M-mode.

[NOTE]
Similar to M-mode debug control, `mtrcen` may be controlled through various methods, such as a new input port to the hart, a handshake with the system Root of Trust (RoT), or other methods. The implementation may group several harts together and use one signal to drive their `mtrcen` state or assign each hart its own dedicated state.

[sdtrcctl]
==== Supervisor Domain Trace Control
The Smsdetrc extension introduces `sdetrcalw` field (bit 8) in CSR <<Sdseccsr,msdcfg>> within a hart. The trace availability for a hart in supervisor domain is determined by the `sdetrcalw` field and `mtrcen`. If either `sdetrcalw` or `mtrcen` is set to 1, the trace output is allowed when the hart runs in the supervisor domain.

When both `sdetrcalw` and `mtrcen` are set to 0, trace output is inhibited at all privilege levels.

=== Trigger (Sdtrig)

Triggers configured to enter Debug Mode can only fire or match when external debug is allowed, as outlined in <<dbgpriv>>. A trigger enabled for a privilege level higher than debug allowed privilege is not accessible by an external debugger. When this trigger is selected using `tselect`, it always reads as 0, and any writes to it are ignored.
Triggers configured to enter Debug Mode can only fire or match when external debug is allowed, as outlined in <<dbgpriv>>.

[NOTE]
Implementations must ensure that pending triggers intending to enter Debug Mode match or fire only when the hart is in a state where debug is allowed. For example, if an interrupt traps the hart to a debug-disallowed privilege mode, the trigger can only take effect either before the privilege is updated and control flow is transferred to the trap handler, or after the interrupt is completely handled and returns from the trap handler. The implementation must prevent Debug Mode from being entered in an intermediate state where privilege is changed or the PC is updated. This also applies to scenarios where a trigger is configured to enter Debug Mode before instruction execution and an interrupt occurs simultaneously.
Expand All @@ -134,68 +132,147 @@ The privilege level of the trigger chain is determined by the trigger enabled fo
[NOTE]
This represents a balance between usability and hardware complexity. There may be instances where the triggers are linked across different privilege levels (e.g., from S-mode to M-mode), while the external debugger may only have access with S-mode privilege. The external debugger should not modify the chain, because it could be suppressed or incorrectly match or fire in M-mode.

==== Sdtrig CSR
=== CSRs

The CSRs tcontrol, scontext, hcontext, mcontext, and mscontext must follow access rules defined in <<dbgaccpriv, debug access privilege>>. Meanwhile, tselect, tdata1, tdata2, and tdata3 are read/write accessible when debug is allowed. If debug is disallowed, writes to these registers are ignored, and reads return zero. The table below illustrates the access conditions for tselect, tdata1, tdata2, and tdata3.
[[ssdextcsr]]
==== Extension of Sdext CSR

[options="header"]
[cols="30%,70%"]
.Tselect, tdata1, tdata2, tdata3 CSR access condition in Debug Mode
|================================================================
| Register | Access condition
| tselect(0x7a0) | mdbgen == 1 \|\| sdedbgalw == 1
| tdata1(0x7a1) | mdbgen == 1 \|\| sdedbgalw == 1
| tdata2(0x7a2) | mdbgen == 1 \|\| sdedbgalw == 1
| tdata3(0x7a3) | mdbgen == 1 \|\| sdedbgalw == 1
| tinfo(0x7a4) | mdbgen == 1 \|\| sdedbgalw == 1
|================================================================

The fields in mcontrol, mcontrol6, icount, itrigger, etrigger, and tmexttrigger are read/write accessible only when the access conditions are met. When access is disallowed, writes to these fields are ignored, and reads return zero.
The following CSRs are provided for debugging supervisor domain. They are only read/write in Debug Mode and not accessible by hart.

.Allocated addresses for supervisor shadow of Debug Mode CSR
[options="header"]
[cols="20%,80%"]
.Tdata1 fields access condtion against privilege granted to external debugger
|====================================
| Field | Access condition
| m | mdbgen == 1
| s | mdbgen == 1 \|\| sdedbgalw == 1
| u | mdbgen == 1 \|\| sdedbgalw == 1
| vs | mdbgen == 1 \|\| sdedbgalw == 1
| vu | mdbgen == 1 \|\| sdedbgalw == 1
|====================================

=== Other CSR updates
[cols="25%,25%,50%"]
|============================================================================================
| Number | Name | Descirption
| 0xaaa | sdcsr | Supervisor debug control and status register.
| 0xaaa | sdpc | Supervisor debug program counter.
| 0xaaa | sdcratch0 | Supervisor debug scratch register 0.
| 0xaaa | sdcratch1 | Supervisor debug scratch register 1.
|============================================================================================

==== Debug Control and Status (dcsr)
The `sdcsr` register tracks the current debug state of the hart, formatted as shown in <<sdcsr32>> and <<sdcsr64>>. When `mdbgen` is 0 and `sdedbgalw` is set to 1, the `prv` and `v` fields indicate the the privilege level at which the hart was executing before entering Debug Mode. Meanwhile, the `sdpc` is updated with the address of the next instruction to executed upon entry into Debug Mode. When resuming from Debug Mode, the privilege level of the hart is restored to the values in `prv` and `v`, while the hart's PC is updated wth the address in `sdpc`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say this differently.

The sdcsr, sdpc, sdscratch0, and sdscratch1 registers are accessible only from Debug Mode, and provide supervisor access to dcsr, dpc, dscratch0, and dscratch1, respectively. The dscratch0 and dscratch1 registers are optional, and sdscratch0 and sdscratch1 are only required if dscratch0 and dscratch1 are implemented.

The sdcsr register provides masked access to dcsr, to prevent supervisor access to machine state. When dcsr is accessed through sdcsr, the following state modifications apply:

  • mprven and ebreakm are read-only 0
  • prv[1] is read-only 0, which prevents prv from being set to M-mode
  • <...>

This way you aren't duplicating fields defined in the Debug spec, which risks the two specs getting out of sync. In fact, that already happened, you didn't include the new dcsr.cetrig bit. But it also makes clear that sdcsr is simply a masked alias of dcsr, not a new physical register. Much the way stselect is an alias (albeit unmasked) of tselect. So you only have to define how accesses to sdcsr differ from accesses to dcsr, you don't need to name all the fields that are accessed normally (e.g., v, cause, ebreak{s,u,vs,vu}, etc).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think sdpc, sdscratch* should have separate physical registers unlike sdcsr. Assuming there is lifecycle control, the contents in dpc, dscratch* might be leaked to S-mode debugger. cetrig is masked in sdcsr on purpose, since it shouldn't be configured by S-mode. I would say any new field in dcsr need requires revisit of sdcsr, and it is equivalent to have a diagram to show unmasked field or describe the masked fields in narrative words.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I have to think about that leakage case. So your worry is that an M-mode external debugger may populate dpc and dscratch*, then later an S-mode external debugger may be able to read those values if sdpc and sdscratch* are just aliases? So there is no reset between the use of the two debuggers? I would think a reset would be required for a change to the lifecycle value, but maybe not for an M-mode change to sdedbgalw. And I guess M-mode can't then clear dpc/dscratch*, since that can only be done in debug mode. Though won't entering debug mode always overwrite dpc? So I don't think that one could leak anything. But I suppose in theory dscratch* could.

Maybe separate sdscratch* regs is reasonable, though it seems inefficient. We could also say that changes to sdedbgalw reset dscratch*, not sure if that's better though.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the sdcsr field specification, I guess you can do it either way, but if you plan to list all the unmasked fields then you probably want a non-normative comment describing why the remaining fields were masked. That way it's clear which fields you have considered, in case future dscr fields are added.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe separate sdscratch* regs is reasonable, though it seems inefficient. We could also say that changes to sdedbgalw reset dscratch*, not sure if that's better though.

I think it makes sense to clear the scratch register whenever mdbgen or sdedbalw is cleared. Beside the scenario where the M-mode debugger is deprivileged to S-mode, there could also be cases where multiple supervisor domains are debuggable while others are not. Therefore, it would be more secure to clear the scratch registers during context switch and requires no separate physical registers anymore.
@pdonahue-ventana do you think this will break any debug use cases?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes me wonder why we ever standardized dscratch* in the first place.

Similarly, the dret instruction was standardized in the normative part of Debug 0.13. I argued in 2020 that this was a microarchitecture thing so we moved dret to the appendix in 1.0.

The dscratch* CSRs might also be details from the initial implementation that were incorrectly elevated to architecture status, though nscratch does kind of make them available architecturally.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with what you say. I just think that we should think about how you might do a ROM-based implementation. We shouldn't define the architecture in a way that somehow prevents ROM-based implementations. Here's one way to do it:

  • define a custom CSR romcontrol that is only accessible in Debug mode (similar to dcsr/dpc/dscratch)
  • software can clear romcontrol[0] but cannot set it. Hardware can set it.
  • romcontrol[0]=1 means that debug mode can access any CSRs that the ROM needs to access (e.g. mhartid, dscratch0) and it ignores MPRV.
  • romcontrol[0]=0 means that debug mode cannot access those CSRs and MPRV behaves as defined by mprven.
  • upon entry to debug mode, hardware sets romcontrol[0] (so the ROM can access what it needs)
  • ROM does a csrrci x0, romcontrol, 1 right before jumping to the program buffer
  • then the program buffer cannot access these things and it also cannot elevate its own permission due to the rule above about writing romcontrol

Of course, this is just a thought exercise and it's not mandatory to implement it like this. The only important thing is that it's possible to have a ROM-based implementation.

If you agree with the above then I don't think that we need smhartid and we probably don't need sdscratch*. What do you think?

One note on this proposal: this would mean that the hart would need to recognise when it leaves the program buffer code to go back to the ROM park loop, and at that point set romcontrol[0] back to 1. Perhaps that could be added to the ebreak behaviour in ROM-based implementations with program buffers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I was implicitly considering the ebreak to be a re-entry to debug mode in the fifth bullet. It's kind of like when you're in M-mode and you execute an ebreak and you trap to the M-mode handler. Of course, different implementations may do things differently and the only important thing is that the bit gets set whenever you go to the park loop.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, the romcontrol and its behavior shall not be normative part, it is very implementation-specific. I assume it can be included in appendix as an implementation suggestion.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we all agree that this CSR based approach is just thought exercise to understand ROM-based execution is possible. There are also other ways and they are implementation specific. They will not be in the normative part of the spec.


The dcsr is always accessible in Debug Mode. The access rules for field `prv` and `v` are addressed in subsection <<prvvacc>>. Beside `prv` and `v`, the access condition of remaining fields are listed in the following table.
When the access conditions are met, they are read/write accessible. When access is disallowed, writes to these fields are ignored, and reads return zero.
The `sdscratch0` and `sdscratch1` are optional scratch registers.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above


.Dcsr fields access condition against privilege granted to external debugger
[options="header"]
[cols="40%,60%"]
|============================================
| Field | Access condition
| debugver | mdbgen == 1 \|\| sdedbgalw == 1
| extcause | mdbgen == 1 \|\| sdedbgalw == 1
| cetrig | mdbgen == 1
| ebreakvs | mdbgen == 1 \|\| sdedbgalw == 1
| ebreakvu | mdbgen == 1 \|\| sdedbgalw == 1
| ebreakm | mdbgen == 1
| ebreaks | mdbgen == 1 \|\| sdedbgalw == 1
| ebreaku | mdbgen == 1 \|\| sdedbgalw == 1
| stepie | mdbgen == 1 \|\| sdedbgalw == 1
| stoptime | mdbgen == 1
| mprven | mdbgen == 1
| nmip | mdbgen == 1
|============================================

==== Debug PC (dpc) and Debug Scratch Register (dscratch0 and dscratch1)
[NOTE]
In a straightforward implementation, reading or writing any field in `sdcsr` is equivalent to reading or writing the corresponding field in `dcsr`, much like how it works for `sstatus`.
AoteJin marked this conversation as resolved.
Show resolved Hide resolved

[caption="Register {counter:rimage}: ", reftext="Register {rimage}"]
[title="Supervisor debug control and status register (sdcsr) for RV32"]
[id=sdcsr32]
[wavedrom, ,svg]
....
{reg: [
{bits: 1, name: 'prv'},
{bits: 1, name: '0'},
{bits: 1, name: 'step'},
{bits: 1, name: '0'},
{bits: 1, name: '0'},
{bits: 1, name: 'v'},
{bits: 3, name: 'cause'},
{bits: 1, name: '0'},
{bits: 1, name: '0'},
{bits: 1, name: 'stepie'},
{bits: 1, name: 'ebreaku'},
{bits: 1, name: 'ebreaks'},
{bits: 1, name: '0'},
{bits: 1, name: '0'},
{bits: 1, name: 'ebreakvu'},
{bits: 1, name: 'ebreakvs'},
{bits: 6, name: '0'},
{bits: 3, name: 'extcause'},
{bits: 1, name: '0'},
{bits: 4, name: 'debugver'}
], config:{lanes: 3, hspace:1024}}
....

[caption="Register {counter:rimage}: ", reftext="Register {rimage}"]
[title="Supervisor debug control and status register (sdcsr) for RV64"]
[id=sdcsr64]
AoteJin marked this conversation as resolved.
Show resolved Hide resolved
[wavedrom, ,svg]
....
{reg: [
{bits: 1, name: 'prv'},
{bits: 1, name: '0'},
{bits: 1, name: 'step'},
{bits: 1, name: '0'},
{bits: 1, name: '0'},
{bits: 1, name: 'v'},
{bits: 3, name: 'cause'},
{bits: 1, name: '0'},
{bits: 1, name: '0'},
{bits: 1, name: 'stepie'},
{bits: 1, name: 'ebreaku'},
{bits: 1, name: 'ebreaks'},
{bits: 1, name: '0'},
{bits: 1, name: '0'},
{bits: 1, name: 'ebreakvu'},
{bits: 1, name: 'ebreakvs'},
{bits: 6, name: '0'},
{bits: 3, name: 'extcause'},
{bits: 1, name: '0'},
{bits: 4, name: 'debugver'},
{bits: 32, name: '0'},
], config:{lanes: 4, hspace:1024}}
....

[caption="Register {counter:rimage}: ", reftext="Register {rimage}"]
[title="Supervisor debug program counter (sdpc)"]
[id=sdpc]
[bytefield]
----
(defattrs :plain [:plain { :font-size 24}])
(def row-height 40 )
(def row-header-fn nil)
(def left-margin 30)
(def right-margin 30)
(def boxes-per-row 32)
(draw-column-headers {:height 24 :font-size 24 :labels (reverse ["0" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "DXLEN-1" ""])})
(draw-box "sdpc" {:span 32:text-anchor "middle" :borders {:left :border-unrelated :top :border-unrelated :bottom :border-unrelated :right :border-unrelated}})
(draw-box "DXLEN" {:font-size 24 :span 32 :borders {}})
----

[caption="Register {counter:rimage}: ", reftext="Register {rimage}"]
[title="Supervisor debug scratch register 0 (sdscratch0)"]
[id=sdscratch0]
[bytefield]
----
(defattrs :plain [:plain { :font-size 24}])
(def row-height 40 )
(def row-header-fn nil)
(def left-margin 30)
(def right-margin 30)
(def boxes-per-row 32)
(draw-column-headers {:height 24 :font-size 24 :labels (reverse ["0" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "DXLEN-1" ""])})
(draw-box "sdscratch0" {:span 32:text-anchor "middle" :borders {:left :border-unrelated :top :border-unrelated :bottom :border-unrelated :right :border-unrelated}})
(draw-box "DXLEN" {:font-size 24 :span 32 :borders {}})
----

[caption="Register {counter:rimage}: ", reftext="Register {rimage}"]
[title="Supervisor debug scratch register 1 (sdscratch1)"]
[id=sdscratch1]
[bytefield]
----
(defattrs :plain [:plain { :font-size 24}])
(def row-height 40 )
(def row-header-fn nil)
(def left-margin 30)
(def right-margin 30)
(def boxes-per-row 32)
(draw-column-headers {:height 24 :font-size 24 :labels (reverse ["0" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "DXLEN-1" ""])})
(draw-box "sdscratch0" {:span 32:text-anchor "middle" :borders {:left :border-unrelated :top :border-unrelated :bottom :border-unrelated :right :border-unrelated}})
(draw-box "DXLEN" {:font-size 24 :span 32 :borders {}})
----
bcstrongx marked this conversation as resolved.
Show resolved Hide resolved

==== Extension of Sdtrig CSR

The Smtdeleg and Sstcfg extensions define the process for delegating triggers to modes with lower privilege than M-mode. The Sdsec requires both extensions to securely delegate Sdtrig triggers to supervisor domain.

Debug PC (at 0x7b1) and Debug Scratch Register (at 0x7b2 and 0x7b3) are not restricted by <<dbgaccpriv, debug access privilege>>, they are always accessible in Debug Mode.
[NOTE]
When M-mode enables debugging for supervisor domain, it can optionally delegate the triggers to the supervisor domain, allowing an external debugger with S-mode privilege to configure these triggers.

[[Sdseccsr]]
==== Sdsec CSR
==== Debug Control CSR

The Sdsec extension does not introduce any new CSR. The CSR control knobs in `msdcfg` for supervisor domain debug and trace are specified in Smsdedbg and Smsdetrc extension respectively in _RISC-V Supervisor Domains Access Protection_ cite:[smmtt]. The Smsdedbg and/or Smsdetrc extension must be implemented to support security control for debugging and/or tracing in supervisor domain.
The CSR holding the debug and trace contol knobs for supervisor domain are specified in Smsdedbg and Smsdetrc extension respectively in _RISC-V Supervisor Domains Access Protection_ cite:[smmtt]. The Smsdedbg and/or Smsdetrc extension must be implemented to support security control for debugging and/or tracing in supervisor domain.
bcstrongx marked this conversation as resolved.
Show resolved Hide resolved

2 changes: 1 addition & 1 deletion chapter3.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Trusted entities like RoT should configure IOPMP or equivalent protection before

=== Security Fault Error Reporting

A dedicated error code, security fault error (cmderr 6), is included in `cmderr` of abstractcs (at 0x16 in Debug Module). Misconfigurations of the dcsr and issuance of abstract commands under disallowed circumstance can signify such an error. Additionally, the bus security fault error (sberror 6) is introduced in `sberror` of sbcs (at 0x38 in Debug Module) to denote errors related to system bus access.
A dedicated error code, security fault error (cmderr 6), is included in `cmderr` of abstractcs (at 0x16 in Debug Module). Issuance of abstract commands under disallowed circumstance can signify such an error. Additionally, the bus security fault error (sberror 6) is introduced in `sberror` of sbcs (at 0x38 in Debug Module) to denote errors related to system bus access.
AoteJin marked this conversation as resolved.
Show resolved Hide resolved

The error raised by resethaltreq, reset can be identified through the fields `allsecfault` and `anysecfault` in dmstatus. Error status bits are internally maintained for each hart, with the `allsecfault` and `anysecfault` fields indicating the error status of the currently selected harts. These error statuses are sticky and can only be cleared by writing 1 to `acksecfault` in dmcs2.

Expand Down
Binary file modified external-debug-security.pdf
Binary file not shown.
Loading