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.
|0x7a0||Trigger Select (
|0x7a1||Trigger Data 1 (
|0x7a1||Match Control (
|0x7a1||Instruction Count (
|0x7a1||Interrupt Trigger (
|0x7a1||Exception Trigger (
|0x7a2||Trigger Data 2 (
|0x7a3||Trigger Data 3 (
|0x7a3||Trigger Extra (RV32) (
|0x7a3||Trigger Extra (RV64) (
|0x7a4||Trigger Info (
|0x7a5||Trigger Control (
|0x7a8||Machine Context (
|0x7aa||Supervisor Context (
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.
Trigger Data 1 (
tdata1, at 0x7a1)
[csrTdataOne] This register is optional if no triggers are implemented.
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.
If is 0, then this bit is hard-wired to 0.
0: Both Debug and M-mode can write the
1: Only Debug Mode can write the
This bit is only writable from Debug Mode. When clearing this bit, the debugger should also clear the action field (whose location depends on ).
If is 0, then this field is hard-wired to 0.
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.
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.
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.
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.
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.
M-mode previous trigger enable field.
When a trap into M-mode is taken, is set to the value of .
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
Machine Context (
mcontext, at 0x7a8)
[csrMcontext] This optional register is only writable in M mode and Debug Mode.
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.
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.
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.
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|
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.
|[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|
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.
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.
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.
|[csrMcontrolAction] |action|||The action to take when the trigger fires. The values are explained in Table [tab:action].||WARL||0|
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.
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.
|[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.