Five EmbedDev logo Five EmbedDev

An Embedded RISC-V Blog
RISC-V External Debug Support , task_group_vote-4-g4e0bb0f 2019/03/25

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 tdata1move around based on the current execution mode and value of MXLEN.

|r|L| Value & Description
& Raise a breakpoint exception. (Used when software wants to use the trigger module without an external debugger attached.)
& Enter Debug Mode. (Only supported when the trigger’s dmodeis 1.)
– 5 & Reserved for use by the trace specification.
other & Reserved for future use.

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)

[tselect] This register determines which trigger is accessible through the other trigger registers. 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 tselectholds what they wrote.

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

image

Trigger Data 1 (tdata1, at 0x7a1)

[tdata1]

image

Field Description Access Reset
[type] |type|

0: There is no trigger at this tselect.

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 mcontrol.

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

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

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

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

Other values are reserved for future use.

R/W Preset
[dmode] |dmode|

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

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

This bit is only writable from Debug Mode.

R/W 0
[data] |data| Trigger-specific data. R/W Preset

Trigger Data 2 (tdata2, at 0x7a2)

[tdata2] Trigger-specific data.

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

image

Trigger Data 3 (tdata3, at 0x7a3)

[tdata3] Trigger-specific data.

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

image

Trigger Info (tinfo, at 0x7a4)

[tinfo]

This entire register is read-only.

image

Field Description Access Reset
[info] |info|

One bit for each possible typeenumerated in tdata1. 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.

If typeis not writable, this register may be unimplemented, in which case reading it causes an illegal instruction exception. In this case the debugger can read the only supported type from tdata1.

R Preset

Trigger Control (tcontrol, at 0x7a5)

[tcontrol] 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
[mpte] |mpte|

M-mode previous trigger enable field.

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

R/W 0
[mte] |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, mteis set to 0. When mret is executed, mteis set to the value of mpte.

R/W 0

Machine Context (mcontext, at 0x7a8)

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

image

Field Description Access Reset
[mcontext] |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.

R/W 0

Supervisor Context (scontext, at 0x7aa)

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

image

Field Description Access Reset
[data] |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.

R/W 0

Match Control (mcontrol, at 0x7a1)

[mcontrol] This register is accessible as tdata1when typeis 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 timing. 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

This trigger type may be limited to address comparisons (selectis always 0) only. If that is the case, then tdata2must 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
[maskmax] |maskmax| Specifies the largest naturally aligned powers-of-two (NAPOT) range supported by the hardware when matchis 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
[sizehi] |sizehi| This field only exists if XLEN is greater than 32. In that case it extends size. If it does not exist then hardware operates as if the field contains 0. R/W 0
[hit] |hit| If this optional 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. R/W 0
[select] |select|

0: Perform a match on the virtual address.

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

R/W 0
[timing] |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.

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 and not implement that suggestion than to not implement them at all.

Most hardware will only implement one timing or the other, possibly dependent on select, execute, load, and store. 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 timingof 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 timingof 1.

A chain of triggers that don’t all have the same timingvalue will never fire (unless consecutive instructions match the appropriate triggers).

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

R/W 0
[sizelo] |sizelo|

This field contains the 2 low bits of size. The high bits come from sizehi. 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.

R/W 0
[action] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. R/W 0
[chain] |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 chainaffects the next trigger, hardware must zero it in writes to mcontrolthat set dmodeto 0 if the next trigger has dmodeof 1. In addition hardware should ignore writes to mcontrolthat set dmodeto 1 if the previous trigger has both dmodeof 0 and chainof 1. Debuggers must avoid the latter case by checking chainon the previous trigger if they’re writing mcontrol.

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

R/W 0
[match] |match|

0: Matches when the value equals tdata2.

1: Matches when the top M bits of the value match the top M bits of tdata2. M is XLEN-1 minus the index of the least-significant bit containing 0 in tdata2.

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

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

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

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

Other values are reserved for future use.

R/W 0
[m] |m| When set, enable this trigger in M-mode. R/W 0
[s] |s| When set, enable this trigger in S-mode. R/W 0
[u] |u| When set, enable this trigger in U-mode. R/W 0
[execute] |execute| When set, the trigger fires on the virtual address or opcode of an instruction that is executed. R/W 0
[store] |store| When set, the trigger fires on the virtual address or data of a store. R/W 0
[load] |load| When set, the trigger fires on the virtual address or data of a load. R/W 0

Instruction Count (icount, at 0x7a1)

[icount] This register is accessible as tdata1when typeis 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 countgreater than 1. The only two combinations of the mode bits that are useful in those scenarios are uby itself, or m, s, and uall set.

If the hardware limits countto 1, and changes mode bits instead of decrementing count, this register can be implemented with just 2 bits. One for u, and one for mand stied 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
[hit] |hit| If this optional 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. R/W 0
[count] |count| When count is decremented to 0, the trigger fires. Instead of changing countfrom 1 to 0, it is also acceptable for hardware to clear m, s, and u. This allows countto be hard-wired to 1 if this register just exists for single step. R/W 1
[m] |m| When set, every instruction completed or exception taken in M-mode decrements count by 1. R/W 0
[s] |s| When set, every instruction completed or exception taken in S-mode decrements count by 1. R/W 0
[u] |u| When set, every instruction completed or exception taken in U-mode decrements count by 1. R/W 0
[action] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. R/W 0

Interrupt Trigger (itrigger, at 0x7a1)

[itrigger] This register is accessible as tdata1when typeis 4.

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

Hardware may only support a subset of interrupts for this trigger. A debugger must read back tdata2after 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 mie.)

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 interrupt/exception handler is executed.

image

image

Field Description Access Reset
[hit] |hit| If this optional 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. R/W 0
[m] |m| When set, enable this trigger for interrupts that are taken from M mode. R/W 0
[s] |s| When set, enable this trigger for interrupts that are taken from S mode. R/W 0
[u] |u| When set, enable this trigger for interrupts that are taken from U mode. R/W 0
[action] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. R/W 0

Exception Trigger (etrigger, at 0x7a1)

[etrigger] This register is accessible as tdata1when typeis 5.

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

Hardware may support only a subset of exceptions. A debugger must read back tdata2after 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 interrupt/exception handler is executed.

image

image

Field Description Access Reset
[hit] |hit| If this optional 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. R/W 0
[m] |m| When set, enable this trigger for exceptions that are taken from M mode. R/W 0
[s] |s| When set, enable this trigger for exceptions that are taken from S mode. R/W 0
[u] |u| When set, enable this trigger for exceptions that are taken from U mode. R/W 0
[action] |action| The action to take when the trigger fires. The values are explained in Table [tab:action]. R/W 0

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

[textra32] This register is accessible as tdata3when typeis 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
[mvalue] |mvalue| Data used together with mselect. R/W 0
[mselect] |mselect|

0: Ignore mvalue.

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

WARL 0
[svalue] |svalue| Data used together with sselect. R/W 0
[sselect] |sselect|

0: Ignore svalue.

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

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

WARL 0

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

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

image

image