Skip to content

Latest commit

 

History

History
303 lines (223 loc) · 11.7 KB

File metadata and controls

303 lines (223 loc) · 11.7 KB

Integrating {cheri_base_ext_name} with Debug

Integrating {cheri_base_ext_name} with Sdext

This section describes changes to integrate the Sdext ISA and {cheri_base_ext_name}. It must be implemented to make external debug compatible with {cheri_base_ext_name}. Modifications to Sdext are kept to a minimum.

The following features, which are optional in Sdext, must be implemented for use with {cheri_base_ext_name}:

  • The hartinfo register must be implemented.

  • All harts which support {cheri_base_ext_name} must provide hartinfo.nscratch of at least 1 and implement the dscratch0 ({cheri_base_ext_name}) register.

  • All harts which support {cheri_base_ext_name} must provide hartinfo.datasize of at least 1 and hartinfo.dataaccess of 0.

  • The program buffer must be implemented, with abstractcs.progbufsize of at least 4 if dmstatus.impebreak is 1, or at least 5 if dmstatus.impebreak is 0.

Note

These requirements allow a debugger to read and write capabilities in integer registers without disturbing other registers. These requirements may be relaxed if some other means of accessing capabilities in integer registers, such as an extension of the Access Register abstract command, is added.

The following sequences demonstrate how a debugger can read and write a capability in {creg}1 using the program buffer if MXLEN is 64, hartinfo.dataaccess is 0, hartinfo.dataaddr is 0xBF0, hartinfo.datasize is 1, hartinfo.nscratch is at least 1, dmstatus.impebreak is 0, and abstractcs.progbufsize is 5:

# Read the high MXLEN bits into data0-data1
csrrw  {creg}2, dscratch0, {creg}2
{gchi_lc}   x2, {creg}1
csrw   0xBF0, x2
csrrw  {creg}2, dscratch0, {creg}2
ebreak

# Read the {ctag} into data0
csrrw  {creg}2, dscratch0, {creg}2
{gctag_lc}  x2, {creg}1
csrw   0xBF0, x2
csrrw  {creg}2, dscratch0, {creg}2
ebreak

# Write the high MXLEN bits from data0-data1
csrrw  {creg}2, dscratch0, {creg}2
csrr   x2, 0xBF0
{schi_lc}   {creg}1, {creg}1, x2
csrrw  {creg}2, dscratch0, {creg}2
ebreak

# Write the {ctag} (if nonzero)
csrrw   {creg}2, dscratch0, {creg}2
csrr    {creg}2, drootc
{cbld_lc}    {creg}1, {creg}2, {creg}1
csrrw   {creg}2, dscratch0, {creg}2
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 ({cheri_base_ext_name}) is guaranteed to retain its value within a single abstract command.

    If dscratch0 ({cheri_base_ext_name}) 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).

Abstract Commands

This section describes the behavior of Abstract Commands, specified by the RISC-V Debug Specification in section 3.7, on harts that implement {cheri_base_ext_name}.

Access Register Abstract Command

TODO

Access Memory Abstract Command

If the debug module implements Access Memory Abstract Command, then any write to memory through this abstract command shall clear the capability tag (or tags) associated with that memory location.

Note

Misaligned write may clear at most two capability tags.

Debug Mode

When executing code due to an abstract command, the hart stays in debug mode and the rules outlined in Section 4.1 of the RISC-V Debug Specification apply.

Core Debug Registers

{cheri_base_ext_name} extends debug CSRs that are designated to hold addresses to be able to hold capabilities. The extended debug CSRs are listed in [dcsrnames-renamed].

The [pcc] must grant [asr_perm] to access debug CSRs. This permission is automatically provided when the hart enters debug mode as described in the dpc ({cheri_base_ext_name}) section. The [pcc] metadata can only be changed if the implementation supports executing control transfer instructions from the program buffer — this is an optional feature according to the RISC-V Debug Specification.

This specification extends the following registers from the RISC-V Debug Specification.

Debug Program Counter (dpc)

dpc is a DXLEN-bit register used as the PC saved when entering debug mode.

Debug program counter

img/dpcreg.edn

Debug Scratch Register 0 (dscratch0)

dscratch0 is an optional DXLEN-bit scratch register that can be used by implementations which need it.

Debug scratch 0 register

img/dscratch0reg.edn

Debug Scratch Register 1 (dscratch1)

dscratch1 is an optional DXLEN-bit scratch register that can be used by implementations which need it.

Debug scratch 1 register

img/dscratch1reg.edn

Debug Program Counter Capability (dpc)

The dpc register is extended to hold a capability.

{TAG_RESET_DCSR}

Debug program counter capability

img/dpccreg.edn

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 [pcc], which refers to all jumps, conditional branches and [AUIPC_CHERI]. The exceptions are [MODESW_CAP] and [MODESW_INT], which are supported if {cheri_default_ext_name} is implemented, see drootc for details.

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

On debug mode entry, dpc ({cheri_base_ext_name}) is updated with the capability in [pcc], 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 ({cheri_base_ext_name}) is unsealed if it is a [sentry_cap] and is written to [pcc].

Note
A debugger may write dpc ({cheri_base_ext_name}) to change where the hart resumes and its mode, permissions, sealing or bounds. The value saved from the [pcc] on debug mode entry cannot be sealed.

The legalization of dpc ({cheri_base_ext_name}) follows the same rules described for [mepc_y].

One possible implementation choice for debug mode exit is DRET.

Debug Scratch Register 0 (dscratch0)

The dscratch0 register is extended to hold a capability.

{TAG_RESET_DCSR}

Debug scratch 0 capability register

img/dscratch0creg.edn

Debug Scratch Register 1 (dscratch1)

The dscratch1 register is extended to hold a capability.

{TAG_RESET_DCSR}

Debug scratch 1 capability register

img/dscratch1creg.edn

Debug Root Capability Selector (drootcsel)

drootcsel is a debug mode accessible integer CSR. The address and access details are shown in [all_capability_CSRs].

It selects which [root-cap] capability is exposed through drootc. The reset value is 0, which must cause drootc to expose a [root-rx-cap] 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.

Debug root capability register

img/drootcselreg.edn

Debug Root Capability Register (drootc)

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

If {cheri_default_ext_name} is implemented, the [root-rx-cap] exposed when drootcsel is 0 is further specified as follows:

  • The [p_bit] is reset to {cheri_int_mode_name} ({INT_MODE_VALUE}).

  • The debugger can set the [p_bit] to {cheri_cap_mode_name} ({CAP_MODE_VALUE}) by executing [MODESW_CAP] from the program buffer.

    • Executing [MODESW_CAP] causes execution of subsequent instructions from the program buffer, starting from the next instruction, to be executed in {cheri_cap_mode_name}. It also sets the {cheri_mode_name} to {cheri_cap_mode_name} on future entry into debug mode.

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

    • The debugger can also execute [MODESW_INT] to change the {cheri_mode_name} back to {cheri_int_mode_name}. This affects the execution of the next instruction in the program buffer, updates the [p_bit] of drootc, and thereby controls which {cheri_mode_name} to use on the next entry into debug mode.

The [p_bit] of this capability is only updated by executing [MODESW_CAP] or [MODESW_INT] from the program buffer.

Debug root capability register

img/drootcreg.edn

Integrating {cheri_default_ext_name} with Sdext

A new debug default data capability (dddc) CSR is added at the CSR number shown in [default-csrnames-added].

{cheri_default_ext_name} allows [MODESW_CAP] and [MODESW_INT] to execute in debug mode.

When entering debug mode, whether the core enters {cheri_int_mode_name} or {cheri_cap_mode_name} 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 {CAP_MODE_VALUE} for {cheri_cap_mode_name} and {INT_MODE_VALUE} for {cheri_int_mode_name} to x1:

csrr   {creg}1, drootc
{gcmode_lc} x1, {creg}1
Note
There is no CHERI enable/disable bit for debug mode, so CHERI register and instruction access is always permitted in debug mode.

Debug Default Data Capability CSR (dddc)

dddc is a debug mode accessible capability CSR. The address is shown in [default-csrnames-added].

{TAG_RESET_DCSR}

{REQUIRE_HYBRID_CSR}

Debug default data capability

img/dddcreg.edn

Upon entry to debug mode, [ddc] is saved in dddc. [ddc] is set to a [root-rw-cap] capability such that [ddc]'s address remains unchanged.

When debug mode is exited by executing [DRET_CHERI], the hart’s [ddc] is updated to the capability stored in dddc. A debugger may write dddc to change the When debug mode is exited, the hart’s [ddc] is updated to the capability stored in dddc. A debugger may write dddc to change the hart’s context.

As shown in [CSR_exevectors], dddc is a data pointer, so it does not need to be able to hold all possible invalid addresses (see [section_invalid_addr_conv]).