This document is a specification snapshot built from github.com/riscv/riscv-cheri/commit/ce97d508c546047176b7e81a37de8839f21247cd and is not a versioned release. The latest versioned PDF release can be downloaded from github.com/riscv/riscv-cheri/releases.
This document is in the Stable state

Assume anything could still change, but limited change should be expected.

1. Integrating RVY with Debug

1.1. Integrating RVY with Sdtrig

The Sdtrig extension is orthogonal to RVY. However, the priority of synchronous exceptions and where triggers fit is adjusted as shown in Table 1.

Debug triggers are higher priority than CHERI exceptions to allow debug.

Table 1. Synchronous exception priority in decreasing priority order.
Priority Exception Code Description Trigger

Highest

3
3
3
3

etrigger
icount
itrigger
mcontrol/mcontrol6 after (on previous instruction)

3

Instruction address breakpoint

mcontrol/mcontrol6 execute address before

32

Prior to instruction address translation:
CHERI Instruction Access Fault due to pc checks (capability tag, sealed, execute permission, bounds1)

12, 20, 1

During instruction address translation: First encountered page fault, guest-page fault, or access fault

1

With physical address for instruction: Instruction access fault

3

mcontrol/mcontrol6 execute data before

2
22
0
8, 9, 10, 11
3
3

Illegal instruction
Virtual instruction
Instruction address misaligned
Environment call
Environment break
Load/Store/AMO address breakpoint

mcontrol/mcontrol6 load/store address before, store data before

33,34

Prior to address translation for an explicit memory access:
CHERI Load Access Fault, CHERI Store/AMO Access Fault due to capability checks (capability tag, sealed, permissions, bounds)

4,6

Load/store/AMO capability address misaligned

4, 6

Optionally: Load/Store/AMO address misaligned

36, 13, 15, 21, 23, 5, 7

During address translation for an explicit memory access: First encountered CHERI Store/AMO Page Fault, page fault, guest-page fault, or access fault

5, 7

With physical address for an explicit memory access: Load/store/AMO access fault

4, 6

If not higher priority: Load/store/AMO address misaligned

35

CHERI Load Capability Fault

Lowest

3

mcontrol/mcontrol6 load data before

1.2. Integrating RVY with Sdext

RVY harts must provide a means for accessing capabilities in registers and in memory via the external debugger.

This is achieved by supporting at least one of:

  1. Implementing a program buffer configured as specified below.

  2. Supporting full capability access for both Access Register and Access Memory abstract commands (aarsize=7 and aamsize=7).

1.2.1. Program Buffer

If a Program Buffer is implemented, this section shows how it can be configured and used to access capabilities.

  • hartinfo must be implemented.

  • hartinfo.nscratch is at least 1 and the dscratch0 (RVY) register is implemented.

  • hartinfo.datasize is at least 1 and hartinfo.dataaccess is 0.

  • abstractcs.progbufsize is at least 4 if dmstatus.impebreak is 1, or at least 5 if dmstatus.impebreak is 0.

These requirements allow a debugger to read and write capabilities in integer registers without disturbing other registers. These requirements may be relaxed if abstract commands support full capability access.

The sequences below demonstrate how a debugger can read and write a capability in x1 using the program buffer if:

  • MXLEN is 64, and

  • hartinfo.dataaccess is 0, and

  • hartinfo.dataaddr is 0xBF0, and

  • hartinfo.datasize is 1, and

  • hartinfo.nscratch is at least 1, and

  • dmstatus.impebreak is 0, and

  • abstractcs.progbufsize is 5.

# Read the high MXLEN bits into data0-data1
csrrw  x2, dscratch0, x2
yhir   x2, x1
csrw   0xBF0, x2
csrrw  x2, dscratch0, x2
ebreak

# Read the capability tag into data0
csrrw  x2, dscratch0, x2
ytagr  x2, x1
csrw   0xBF0, x2
csrrw  x2, dscratch0, x2
ebreak

# Write the high MXLEN bits from data0-data1
csrrw  x2, dscratch0, x2
csrr   x2, 0xBF0
yhiw   x1, x1, x2
csrrw  x2, dscratch0, x2
ebreak

# Write the capability tag (if nonzero)
csrrw   x2, dscratch0, x2
csrr    x2, drootc
ybld    x1, x2, x1
csrrw   x2, dscratch0, x2
ebreak

The low MXLEN bits of a capability are read and written using normal Access Register abstract commands.

The above instruction sequences utilize these guarantees provided by the RISC-V Debug Specification:

  • When hartinfo.nscratch is greater than 0, the dscratch0 (RVY) register is guaranteed to retain its value within a single abstract command.

    If dscratch0 (RVY) were known to be preserved between abstract commands, it would be possible to remove the requirements on hartinfo.datasize, hartinfo.dataaccess, and abstractcs.progbufsize, however, there is no way to discover the former property.

  • Execution of Access Register abstract commands does not alter the values of data debug module registers (unless read of a register is explicitly requested by setting transfer to 1 and write to 0).

1.2.2. Abstract Commands

Abstract commands are optionally extended to access full capabilities.

aarsize/aamsize=7 represent full capability access.

When a capability is written via an abstract command it must be derivable from the set of root capabilities available in drootc. If not then the destination capability tag is set to zero.

The data<n> register mapping for full capability accesses is as shown in Table 2.

Table 2. Data register mapping when aarsize/aamsize=7
ISA arg0/return value arg11 arg22 capability tag

RV32Y

data0,data1

data2

data3,data4

data5

RV64Y

data0-data3

data4,data5

data6-data9

data10

1 arg1 represents an address so never needs to exceed DXLEN. Each data<n> register is 32-bit so a maximum of 2 are required.

2 arg2 is not used for abstract commands, and is included for consistency with the equivalent table in the RISC-V Debug Specification

Bit 0 of data5 or data10 contain the capability tag which is either written to, or read from, the target register. All other bits in that data register are UNSPECIFIED.

1.2.3. Access Register Command

When a YLEN-wide register is accessible via an Access Register abstract command, then:

  • Reads of YLEN bits or any smaller amounts of bits must be supported.

  • Writes of YLEN bits must be supported.

  • Writes of smaller amounts of bits than YLEN may optionally be supported but it is UNSPECIFIED what happens to the higher bits.

The debugger can change the low XLEN bits of a YLEN wide register by performing a read-modify-write sequence.

The requirement to support YLEN-wide access mandates that enough data<n> registers are implemented to cover the entire YLEN bit-width (at least 2 for RV32Y or at least 4 for RV64Y).

Implementations can choose to also support accessing capability tags as part of the access register command by supporting aarsize=7.

If there is only a single root capability, then the derivable check is a capability subset of the written capability against the capability in drootc. If there are multiple root capabilities then checks against multiple root capabilities may be required, as defined by the capability encoding format.

If aarsize≠7 then capability tags are always read and written as zero.

For the capability subset: cap2 is the capability being written and cap1 is the value of drootc.
It is valid for root capabilities not to cover the entire possible address space. In this case the debugger cannot claim access to more memory than is permitted by the current value of drootc.

1.2.4. Access Memory Command

Implementations can choose to support accessing full capabilities, including the capability tags, via the Access Memory abstract command. Full capability access is denoted by aamsize=7 and uses the data<n> register assignments specified in Table 2.

If aamsize≠7 then capability tags are always read and written as zero.

1.2.5. Core Debug Registers

RVY widens debug CSRs that are designated to hold addresses so that they can hold capabilities.

1.2.5.1. Debug Program Counter Capability (dpc)

The dpc register is widened to a capability.

The reset value of the capability tag of this CSR is zero, the reset values of the metadata and address fields are UNSPECIFIED.

Diagram
Figure 1. Debug program counter capability

When the hart is in debug mode, the RISC-V Debug Specification does not specify how the pc is updated, and says that PC-relative instructions may be illegal. This concept is extended to include any instruction which reads or updates PC, which refers to all jumps, conditional branches and AUIPC. The exceptions are YMODESWY and YMODESWI, which are supported if Zyhybrid is implemented, see drootc for details.

As a result, the value of the pc is UNSPECIFIED in debug mode according to this specification. The pc metadata has no architectural effect in debug mode. Therefore, ASR-permission is implicitly granted for access to all CSRs for instruction execution.

On debug mode entry, dpc (RVY) is updated with the capability in the pc, whose address field equals to the address of the next instruction to be executed upon debug mode exit as described in the RISC-V Debug Specification.

When leaving debug mode, the value in dpc (RVY) is unsealed if it is a Sealed entry point capability and is written to PC.

A debugger may write dpc (RVY) to change where the hart resumes and its mode, permissions, sealing or bounds. The value saved from the pc on debug mode entry cannot be sealed.

The legalization of dpc (RVY) follows the same rules described for mepc.

One possible implementation choice for debug mode exit is DRET.

1.2.5.2. Debug Scratch Register 0 (dscratch0)

The dscratch0 register is widened to a capability.

The reset value of the capability tag of this CSR is zero, the reset values of the metadata and address fields are UNSPECIFIED.

Diagram
Figure 2. Debug scratch 0 capability register
1.2.5.3. Debug Scratch Register 1 (dscratch1)

The dscratch1 register is widened to a capability.

The reset value of the capability tag of this CSR is zero, the reset values of the metadata and address fields are UNSPECIFIED.

Diagram
Figure 3. Debug scratch 1 capability register
1.2.5.4. Debug Root Capability Selector (drootcsel)

drootcsel is a DXLEN-bit debug mode accessible integer CSR. The address and access details are shown in Table 5.

It selects which Root capability is exposed through drootc. The reset value is 0, which must cause drootc to expose a Root Executable capability.

Other capability values may be defined for exposure through drootc by the capability encoding, and may be selected by having the debugger write to this register. Writes are WARL, so the debugger may confirm that its selection has been applied.

Diagram
Figure 4. Debug root capability selector register
1.2.5.5. Debug Root Capability Register (drootc)

drootc is a debug mode accessible capability CSR. The address and access details are shown in Table 5. It exposes the capability selected by drootcsel.

drootc is DRW; writes are ignored (WARL with no writable fields).

If Zyhybrid is implemented, the Root Executable exposed when drootcsel is 0 is further specified as follows:

  • The P-bit is reset to Integral Pointer Mode (1).

  • The debugger can set the P-bit to Capability Pointer Mode (0) by executing YMODESWY from the program buffer.

    • Executing YMODESWY causes execution of subsequent instructions from the program buffer, starting from the next instruction, to be executed in Capability Pointer Mode. It also sets the CHERI Pointer Mode to Capability Pointer Mode on future entry into debug mode.

    • Therefore, to enable use of a CHERI debugger, only a single YMODESWY needs to be executed once from the program buffer after resetting the core.

    • The debugger can also execute YMODESWI to change the CHERI Pointer Mode back to Integral Pointer Mode. This affects the execution of the next instruction in the program buffer, updates the P-bit of drootc, and thereby controls which CHERI Pointer Mode to use on the next entry into debug mode.

The P-bit of this capability is only updated by executing YMODESWY or YMODESWI from the program buffer.

Diagram
Figure 5. Debug root capability register
1.2.5.6. DRET (RVY)
Synopsis

Debug Return (DRET)

Mnemonic

dret

Encoding
Diagram
Description

DRET returns from debug mode. It unseals dpc (RVY) if it is sealed as a Sealed entry point capability and writes the result into the pc. It also restores ddc from dddc.

The DRET instruction is a documented method of exiting debug mode. However, it is a pseudoinstruction to return that technically does not execute from the program buffer or memory. It does not require the pc to grant ASR-permission so it never raises an exception.
The definition of DRET is not part of Sdext, and is suggested as an implementation choice in the RISC-V Debug Specification. This specification assumes the recommended specification including the recommended encoding.
Prerequisites

RVY

Operation
SAIL TO BE UPDATED

1.3. Integrating Zyhybrid with Sdext

A new debug default data capability (dddc) CSR is added.

Zyhybrid allows YMODESWY and YMODESWI to execute in debug mode.

When entering debug mode, whether the core enters Integral Pointer Mode or Capability Pointer Mode is controlled by the P-bit in the drootc capability selected by drootcsel value 0.

The current mode can be read by setting drootcsel to 0 and then reading drootc.

The following sequence executed from the program buffer will write 0 for Capability Pointer Mode and 1 for Integral Pointer Mode to x1:

csrr   x1, drootc
ymoder x1, x1
There is no CHERI enable/disable bit for debug mode, so CHERI register and instruction access is always permitted.

1.3.1. Debug Default Data Capability CSR (dddc)

dddc is a debug mode accessible capability CSR.

The reset value of the capability tag of this CSR is zero, the reset values of the metadata and address fields are UNSPECIFIED.

This CSR is only implemented if Zyhybrid is implemented.

Diagram
Figure 6. Debug default data capability

Upon entry to debug mode, ddc is saved in dddc. ddc is set to a Root Data capability with an unchanged address.

If the Root Data capability does not cover all of memory then ddc must be updated using the semantics of YADDRW.

When debug mode is exited by executing DRET (RVY), the hart’s ddc is updated to the capability stored in dddc. When debug mode is exited the hart’s ddc is updated to the capability stored in dddc, which may have been updated by the debugger. A debugger may write dddc to change the hart’s context.

As shown in Table 4, dddc is a data pointer, so it does not need to be able to hold all possible invalid addresses.

1.4. Debug Mode YLEN CSR Summary

The tables below show all debug mode CSRs added or modified by RVY.

Table 3. Action taken on writing to YLEN-bit and extended debug mode CSRs
RVY CSR Extension Width Action on XLEN write Action on YLEN write

dpc (RVY)

Sdext

YLEN

Apply invalid address conversion. Always update the CSR with YADDRW even if the address didn’t change.

Apply invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change

dscratch0 (RVY)

Sdext

YLEN

Update the CSR using YADDRW.

Direct write

dscratch1 (RVY)

Sdext

YLEN

Update the CSR using YADDRW.

Direct write

dddc

Sdext, Zyhybrid

YLEN

Apply invalid address conversion. Always update the CSR with YADDRW even if the address didn’t change.

Apply invalid address conversion and update the CSR with the result if the address changed, direct write if address didn’t change

drootc

Sdext

YLEN

Ignore

Ignore

Code pointers and data pointers in Table 4 are WARL CSRs that do not need to store full 64-bit addresses on RV64, and so may be subject to invalid address conversion on writing.

Table 4. YLEN-wide Debug-Mode CSRs storing code pointers or data pointers
RVY CSR Extension Code Pointer Data Pointer Unseal On Execution

dpc (RVY)

Sdext

dddc

Sdext, Zyhybrid

Table 5 shows all debug-mode CSRs added or modified by RVY.

Table 5. All RVY debug mode CSRs.
RVY CSR Extension Width Address Permissions Reset Value Description

dpc (RVY)

Sdext

YLEN

0x7b1

DRW

tag=0, otherwise specified by the platform

Debug Program Counter Capability

dscratch0 (RVY)

Sdext

YLEN

0x7b2

DRW

tag=0, otherwise specified by the platform

Debug Scratch Capability 0

dscratch1 (RVY)

Sdext

YLEN

0x7b3

DRW

tag=0, otherwise specified by the platform

Debug Scratch Capability 1

dddc

Sdext, Zyhybrid

YLEN

0x7bc

DRW

tag=0, otherwise specified by the platform

Debug Default Data Capability (saved/restored on debug mode entry/exit)

drootcsel

Sdext

DXLEN

0x7ba

DRW

0

Multiplexing selector for drootc

drootc

Sdext

YLEN

0x7bd

DRW

nominally Root Executable

Source of authority in debug mode, writes are ignored

Where reset values are specified as a Root Executable or Root Data Capability they are the maximum possible value. The platform may reset those CSRs to a smaller memory range, or to have fewer permissions.