Five EmbedDev logo Five EmbedDev

An Embedded RISC-V Blog
RISC-V External Debug Support

The trigger registers are only accessible in machine and Debug Mode to prevent untrusted user code from causing entry into Debug Mode without the OS’s permission.

In this section XLEN means MXLEN when in M-mode, and DXLEN when in Debug Mode. Note that this makes several of the fields in move around based on the current execution mode and value of MXLEN.

Address Name Page
0x7a0 Trigger Select (tselect)
0x7a1 Trigger Data 1 (tdata1)
0x7a1 Match Control (mcontrol)
0x7a1 Instruction Count (icount)
0x7a1 Interrupt Trigger (itrigger)
0x7a1 Exception Trigger (etrigger)
0x7a2 Trigger Data 2 (tdata2)
0x7a3 Trigger Data 3 (tdata3)
0x7a3 Trigger Extra (RV32) (textra32)
0x7a3 Trigger Extra (RV64) (textra64)
0x7a4 Trigger Info (tinfo)
0x7a5 Trigger Control (tcontrol)
0x7a8 Machine Context (mcontext)
0x7aa Supervisor Context (scontext)

Trigger Select (tselect, at 0x7a0)

[csrTselect] This register determines which trigger is accessible through the other trigger registers. It is optional if no triggers are implemented. The set of accessible triggers must start at 0, and be contiguous.

Writes of values greater than or equal to the number of supported triggers may result in a different value in this register than what was written. To verify that what they wrote is a valid index, debuggers can read back the value and check that holds what they wrote.

Since triggers can be used both by Debug Mode and M-mode, the external debugger must restore this register if it modifies it.

image

Trigger Data 1 (tdata1, at 0x7a1)

[csrTdataOne] This register is optional if no triggers are implemented.

image

Field Description Access Reset
[csrTdataOneType] |type|

0: There is no trigger at this .

1: The trigger is a legacy SiFive address match trigger. These should not be implemented and aren’t further documented here.

2: The trigger is an address/data match trigger. The remaining bits in this register act as described in .

3: The trigger is an instruction count trigger. The remaining bits in this register act as described in .

4: The trigger is an interrupt trigger. The remaining bits in this register act as described in .

5: The trigger is an exception trigger. The remaining bits in this register act as described in .

12–14: These trigger types are available for non-standard use.

15: This trigger exists (so enumeration shouldn’t terminate), but is not currently available.

Other values are reserved for future use.

WARL Preset
[csrTdataOneDmode] |dmode|

If is 0, then this bit is hard-wired to 0.

0: Both Debug and M-mode can write the tdata registers at the selected .

1: Only Debug Mode can write the tdata registers at the selected . Writes from other modes are ignored.

This bit is only writable from Debug Mode. When clearing this bit, the debugger should also clear the action field (whose location depends on ).

WARL 0
[csrTdataOneData] |data|

If is 0, then this field is hard-wired to 0.

Trigger-specific data.

WARL Preset

Trigger Data 2 (tdata2, at 0x7a2)

[csrTdataTwo] Trigger-specific data. It is optional if no implemented triggers use it.

If XLEN is less than DXLEN, writes to this register are sign-extended.

image

Trigger Data 3 (tdata3, at 0x7a3)

[csrTdataThree] Trigger-specific data. It is optional if no implemented triggers use it.

If XLEN is less than DXLEN, writes to this register are sign-extended.

image

Trigger Info (tinfo, at 0x7a4)

[csrTinfo] This register is optional if no triggers are implemented, or if is not writable. In this case the debugger can read the only supported type from .

This entire register is read-only.

image

Field Description Access Reset
[csrTinfoInfo] |info|

One bit for each possible enumerated in . Bit N corresponds to type N. If the bit is set, then that type is supported by the currently selected trigger.

If the currently selected trigger doesn’t exist, this field contains 1.

R Preset

Trigger Control (tcontrol, at 0x7a5)

[csrTcontrol] This optional register is one solution to a problem regarding triggers with action=0 firing in M-mode trap handlers. See Section [sec:mmtrigger] for more details.

image

Field Description Access Reset
[csrTcontrolMpte] |mpte|

M-mode previous trigger enable field.

When a trap into M-mode is taken, is set to the value of .

WARL 0
[csrTcontrolMte] |mte|

M-mode trigger enable field.

0: Triggers with action=0 do not match/fire while the hart is in M-mode.

1: Triggers do match/fire while the hart is in M-mode.

When a trap into M-mode is taken, is set to 0. When mret is executed, is set to the value of .

WARL 0

Machine Context (mcontext, at 0x7a8)

[csrMcontext] This optional register is only writable in M mode and Debug Mode.

image

Field Description Access Reset
[csrMcontextMcontext] |mcontext|

Machine mode software can write a context number to this register, which can be used to set triggers that only fire in that specific context.

An implementation may tie any number of upper bits in this field to 0. It’s recommended to implement no more than 6 bits on RV32, and 13 on RV64.

WARL 0

Supervisor Context (scontext, at 0x7aa)

[csrScontext] This optional register is only writable in S mode, M mode and Debug Mode.

Note that the register number does not follow the read and write accessibility of the CSRs according to privilege level as defined in the Privileged Spec.

image

Field Description Access Reset
[csrScontextData] |data|

Supervisor mode software can write a context number to this register, which can be used to set triggers that only fire in that specific context.

An implementation may tie any number of high bits in this field to 0. It’s recommended to implement no more than 16 bits on RV32, and 34 on RV64.

WARL 0

Match Control (mcontrol, at 0x7a1)

[csrMcontrol] This register is accessible as when is 2.

Address and data trigger implementation are heavily dependent on how the processor core is implemented. To accommodate various implementations, execute, load, and store address/data triggers may fire at whatever point in time is most convenient for the implementation. The debugger may request specific timings as described in . Table [tab:hwbp_timing] suggests timings for the best user experience.

Match Type Suggested Trigger Timing
Execute Address Before
Execute Instruction Before
Execute Address+Instruction Before
Load Address Before
Load Data After
Load Address+Data After
Store Address Before
Store Data Before
Store Address+Data Before

[tab:hwbp_timing]

A chain of triggers that don’t all have the same value will never fire. That means to implement the suggestions in Table [tab:hwbp_timing], both timings should be supported on load address triggers.

This trigger type may be limited to address comparisons (is always 0) only. If that is the case, then must be able to hold all valid virtual addresses but it need not be capable of holding other values.

image

image

image

Field Description Access Reset
[csrMcontrolMaskmax] |maskmax| Specifies the largest naturally aligned powers-of-two (NAPOT) range supported by the hardware when is 1. The value is the logarithm base 2 of the number of bytes in that range. A value of 0 indicates that only exact value matches are supported (one byte range). A value of 63 corresponds to the maximum NAPOT range, which is 263 bytes in size. R Preset
[csrMcontrolSizehi] |sizehi| This field only exists when XLEN is at least 64. It contains the 2 high bits of the access size. The low bits come from . See for how this is used. WARL 0
[csrMcontrolHit] |hit| If this bit is implemented, the hardware sets it when this trigger matches. The trigger’s user can set or clear it at any time. It is used to determine which trigger(s) matched. If the bit is not implemented, it is always 0 and writing it has no effect. WARL 0
[csrMcontrolSelect] |select|

0: Perform a match on the lowest virtual address of the access. In addition, it is recommended that the trigger also fires if any of the other accessed virtual addresses match. (E.g. on a 32-bit read from 0x4000, the lowest address is 0x4000 and the other addresses are 0x4001, 0x4002, and 0x4003.)

1: Perform a match on the data value loaded or stored, or the instruction executed.

WARL 0
[csrMcontrolTiming] |timing|

0: The action for this trigger will be taken just before the instruction that triggered it is executed, but after all preceding instructions are committed. or (depending on ) must be set to the virtual address of the instruction that matched.

If this is combined with then a memory access will be performed (including any side effects of performing such an access) even though the load will not update its destination register. Debuggers should consider this when setting such breakpoints on, for example, memory-mapped I/O addresses.

1: The action for this trigger will be taken after the instruction that triggered it is executed. It should be taken before the next instruction is executed, but it is better to implement triggers imprecisely than to not implement them at all. or (depending on ) must be set to the virtual address of the next instruction that must be executed to preserve the program flow.

Most hardware will only implement one timing or the other, possibly dependent on , , , and . This bit primarily exists for the hardware to communicate to the debugger what will happen. Hardware may implement the bit fully writable, in which case the debugger has a little more control.

Data load triggers with of 0 will result in the same load happening again when the debugger lets the hart run. For data load triggers, debuggers must first attempt to set the breakpoint with of 1.

If a trigger with of 0 matches, it is implementation-dependent whether that prevents a trigger with of 1 matching as well.

WARL 0
[csrMcontrolSizelo] |sizelo|

This field contains the 2 low bits of the access size. The high bits come from . The combined value is interpreted as follows:

0: The trigger will attempt to match against an access of any size. The behavior is only well-defined if |select| = 0, or if the access size is XLEN.

1: The trigger will only match against 8-bit memory accesses.

2: The trigger will only match against 16-bit memory accesses or execution of 16-bit instructions.

3: The trigger will only match against 32-bit memory accesses or execution of 32-bit instructions.

4: The trigger will only match against execution of 48-bit instructions.

5: The trigger will only match against 64-bit memory accesses or execution of 64-bit instructions.

6: The trigger will only match against execution of 80-bit instructions.

7: The trigger will only match against execution of 96-bit instructions.

8: The trigger will only match against execution of 112-bit instructions.

9: The trigger will only match against 128-bit memory accesses or execution of 128-bit instructions.

An implementation must support the value of 0, but all other values are optional. It is recommended to support triggers for every access size the hart supports, as well as for every instruction size the hart supports.

WARL 0
[csrMcontrolAction] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. WARL 0
[csrMcontrolChain] |chain|

0: When this trigger matches, the configured action is taken.

1: While this trigger does not match, it prevents the trigger with the next index from matching.

A trigger chain starts on the first trigger with |chain| = 1 after a trigger with |chain| = 0, or simply on the first trigger if that has |chain| = 1. It ends on the first trigger after that which has |chain| = 0. This final trigger is part of the chain. The action on all but the final trigger is ignored. The action on that final trigger will be taken if and only if all the triggers in the chain match at the same time.

Because affects the next trigger, hardware must zero it in writes to that set to 0 if the next trigger has of 1. In addition hardware should ignore writes to that set to 1 if the previous trigger has both of 0 and of 1. Debuggers must avoid the latter case by checking on the previous trigger if they’re writing .

Implementations that wish to limit the maximum length of a trigger chain (eg. to meet timing requirements) may do so by zeroing in writes to that would make the chain too long.

WARL 0
[csrMcontrolMatch] |match|

0: Matches when the value equals .

1: Matches when the top M bits of the value match the top M bits of . M is XLEN-1 minus the index of the least-significant bit containing 0 in . Debuggers should only write values to such that M + XLEN, otherwise it’s undefined on what conditions the trigger will fire.

2: Matches when the value is greater than (unsigned) or equal to .

3: Matches when the value is less than (unsigned) .

4: Matches when the lower half of the value equals the lower half of after the lower half of the value is ANDed with the upper half of .

5: Matches when the upper half of the value equals the lower half of after the upper half of the value is ANDed with the upper half of .

8: Matches when  = 0 would not match.

9: Matches when  = 1 would not match.

12: Matches when  = 4 would not match.

13: Matches when  = 5 would not match.

Other values are reserved for future use.

WARL 0
[csrMcontrolM] |m| When set, enable this trigger in M-mode. WARL 0
[csrMcontrolS] |s| When set, enable this trigger in S-mode. WARL 0
[csrMcontrolU] |u| When set, enable this trigger in U-mode. WARL 0
[csrMcontrolExecute] |execute| When set, the trigger fires on the virtual address or opcode of an instruction that is executed. WARL 0
[csrMcontrolStore] |store| When set, the trigger fires on the virtual address or data of any store. WARL 0
[csrMcontrolLoad] |load| When set, the trigger fires on the virtual address or data of any load. WARL 0

Instruction Count (icount, at 0x7a1)

[csrIcount] This register is accessible as when is 3.

CUSTOMTAGBEGINCOMMENTARY This trigger type is intended to be used as a single step that’s useful both for external debuggers and for software monitor programs. For that case it is not necessary to support greater than 1. The only two combinations of the mode bits that are useful in those scenarios are by itself, or , , and all set.

If the hardware limits to 1, and changes mode bits instead of decrementing , this register can be implemented with just 2 bits. One for , and one for and tied together. If only the external debugger or only a software monitor needs to be supported, a single bit is enough.

image

image

Field Description Access Reset
[csrIcountHit] |hit| If this bit is implemented, the hardware sets it when this trigger matches. The trigger’s user can set or clear it at any time. It is used to determine which trigger(s) matched. If the bit is not implemented, it is always 0 and writing it has no effect. WARL 0
[csrIcountCount] |count| When count is decremented to 0, the trigger fires. Instead of changing from 1 to 0, it is also acceptable for hardware to clear , , and . This allows to be hard-wired to 1 if this register just exists for single step. WARL 1
[csrIcountM] |m| When set, every instruction completed in or trap taken from M-mode decrements by 1. WARL 0
[csrIcountS] |s| When set, every instruction completed in or trap taken from S-mode decrements by 1. WARL 0
[csrIcountU] |u| When set, every instruction completed in or trap taken from U-mode decrements by 1. WARL 0
[csrIcountAction] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. WARL 0

Interrupt Trigger (itrigger, at 0x7a1)

[csrItrigger] This register is accessible as when is 4.

This trigger may fire on any of the interrupts configurable in (described in the Privileged Spec). The interrupts to fire on are configured by setting the same bit in as would be set in to enable the interrupt.

Hardware may only support a subset of interrupts for this trigger. A debugger must read back after writing it to confirm the requested functionality is actually supported.

The trigger only fires if the hart takes a trap because of the interrupt. (E.g. it does not fire when a timer interrupt occurs but that interrupt is not enabled in .)

When the trigger fires, all CSRs are updated as defined by the Privileged Spec, and the requested action is taken just before the first instruction of the trap handler is executed.

image

image

Field Description Access Reset
[csrItriggerHit] |hit| If this bit is implemented, the hardware sets it when this trigger matches. The trigger’s user can set or clear it at any time. It is used to determine which trigger(s) matched. If the bit is not implemented, it is always 0 and writing it has no effect. WARL 0
[csrItriggerM] |m| When set, enable this trigger for interrupts that are taken from M mode. WARL 0
[csrItriggerS] |s| When set, enable this trigger for interrupts that are taken from S mode. WARL 0
[csrItriggerU] |u| When set, enable this trigger for interrupts that are taken from U mode. WARL 0
[csrItriggerAction] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. WARL 0

Exception Trigger (etrigger, at 0x7a1)

[csrEtrigger] This register is accessible as when is 5.

This trigger may fire on up to XLEN of the Exception Codes defined in (described in the Privileged Spec, with Interrupt=0). Those causes are configured by writing the corresponding bit in . (E.g. to trap on an illegal instruction, the debugger sets bit 2 in .)

Hardware may support only a subset of exceptions. A debugger must read back after writing it to confirm the requested functionality is actually supported.

When the trigger fires, all CSRs are updated as defined by the Privileged Spec, and the requested action is taken just before the first instruction of the trap handler is executed.

image

image

Field Description Access Reset
[csrEtriggerHit] |hit| If this bit is implemented, the hardware sets it when this trigger matches. The trigger’s user can set or clear it at any time. It is used to determine which trigger(s) matched. If the bit is not implemented, it is always 0 and writing it has no effect. WARL 0
[csrEtriggerNmi] |nmi| When set, non-maskable interrupts cause this trigger to fire, regardless of the values of , , and . WARL 0
[csrEtriggerM] |m| When set, enable this trigger for exceptions that are taken from M mode. WARL 0
[csrEtriggerS] |s| When set, enable this trigger for exceptions that are taken from S mode. WARL 0
[csrEtriggerU] |u| When set, enable this trigger for exceptions that are taken from U mode. WARL 0
[csrEtriggerAction] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. WARL 0

Trigger Extra (RV32) (textra32, at 0x7a3)

[csrTextraThirtytwo] This register is accessible as when is 2, 3, 4, or 5.

All functionality in this register is optional. The |value| bits may tie any number of upper bits to 0. The |select| bits may only support 0 (ignore).

image

Field Description Access Reset
[csrTextraThirtytwoMvalue] |mvalue| Data used together with . WARL 0
[csrTextraThirtytwoMselect] |mselect|

0: Ignore .

1: This trigger will only match if the low bits of equal .

WARL 0
[csrTextraThirtytwoSvalue] |svalue|

Data used together with .

This field should be tied to 0 when S-mode is not supported.

WARL 0
[csrTextraThirtytwoSselect] |sselect|

0: Ignore .

1: This trigger will only match if the low bits of equal .

2: This trigger will only match if in equals the lower ASIDMAX (defined in the Privileged Spec) bits of .

This field should be tied to 0 when S-mode is not supported.

WARL 0

Trigger Extra (RV64) (textra64, at 0x7a3)

[csrTextraSixtyfour] This is the layout of textra if XLEN is 64. The fields are defined above, in .

image

image