• No results found

Synchronization of DCC and ITR accesses

PART D: ARMV8 EXTERNAL DEBUG

10 THE DEBUG COMMUNICATIONS CHANNEL (DCC) AND INSTRUCTION TRANSFER REGISTER (ITR)

10.5 Synchronization of DCC and ITR accesses

ClearStickyErrors()

EDSCR.TXU = ‘0’; // Clear TX underrun flag EDSCR.RXO = ‘0’; // Clear RX overrun flag if Halted() then // in Debug state

EDSCR.ITO = ‘0’; // Clear ITR overrun flag EDSCR.ERR = ‘0’; // Clear cumulative error flag return;

10.5 Synchronization of DCC and ITR accesses

In addition to the standard synchronization requirements for register accesses, the following sections give additional requirements that apply for the DCC and ITR.

In these sections, accesses by the external debug interface are referred to as external reads and external writes. Accesses to system registers are referred to as direct reads, direct writes, indirect reads and indirect writes.

Note: In [v8Exception] external reads and external writes are described as forms of indirect access. This section uses more explicit language.

The DTR registers and DCC flags form a communications channel, with one end operating asynchronously to the other. Implementations must respect the ordering of accesses to these registers in order to maintain correct behavior of the channel.

External reads and external writes to DBGDTRRX_EL0 and DBGDTRTX_EL0 are asynchronous to direct reads and direct writes to DBGDTRRX_EL0, DBGDTRTX_EL0_EL0 and DBGDTR_EL0 made by software using system register access instructions. The direct reads and direct writes indirectly write to the DCC flags.

The external reads and external writes indirectly read the DCC flags to check for underrun and overrun.

In this section:

DCC flags means the RXfull and TXfull ready flags, the RXO and TXU overrun/underrun flags, and the ERR flag.

ITR flags means the ITE ready flag, the ITO overrun flag, and the ERR flag.

10.5.1 Summary of system register accesses to the DCC

System register accesses to the DTR registers are direct reads and direct writes of those registers, as shown in Table 56. Several of these instructions access the same registers using different encodings.

DBGDTRRX_EL0 and DBGDTRTX_EL0_EL0 (AArch64), and DBGDTRRXint and DBGDTRTXint (AArch32) are the same encoding (apart from the read/write bits), but different registers. As described in [v8Exception], this governs the ordering of these instructions. For more details see the register descriptions.

Operation OS lock AArch64 (MRS/MSR) AArch32 (MRC/MCR) Description

Read - DBGDTRRX_EL0 DBGDTRRXint Direct read of DTRRX

Write - DBGDTRTX_EL0 DBGDTRTXint Direct write of DTRTX

Read/write - DBGDTR_EL0 - Direct read/write of both DTRRX and DTRTX All of the above Indirect write to the DCC flags

Read - MDCCSR_EL0 DBGDSCRint Direct read of the DCC ready flags Read/write - OSDTRRX_EL1 DBGDTRRXext Direct read/write of DTRRX Read/write - OSDTRTX_EL1 DBGDTRTXext Direct read/write of DTRTX Read unlocked MDSCR_EL1 DBGDSCRext Direct read of DCC flags Read/write locked MDSCR_EL1 DBGDSCRext Direct read/write of DCC flags Table 56: Summary of system register accesses to the DCC

10.5.2 DCC accesses in Non-debug state

In Non-debug state, as described in Normal access mode on page 164:

 if a direct read of MDCCSR_EL0 returns RXfull == 1, then a following direct read of DBGDTRRX_EL0 or DBGDTR_EL0 returns valid data and indirectly writes 0 to MDCCSR_EL0.RXfull as a side-effect

 if a direct read of MDCCSR_EL0 returns TXfull == 0, then a following direct write to DBGDTRTX_EL0 or DBGDTR_EL0 writes the intended value, and indirectly writes 1 to MDCCSR_EL0.TXfull as a side-effect.

No context synchronization operation is required between these two instructions. Overrun and underrun detection prevents intervening external reads and external writes affecting the outcome of the second instruction.

The indirect write to the DCC flags as part of the DTR access instruction is made atomically with the DTR access.

As the direct read of DBGDTRRX_EL0 is an indirect write to MDCCSR_EL0.RXfull, it must not be executed speculatively ahead of the direct read of MDCCSR_EL0, meaning it is not permitted to return a speculative value for DTRRX that is younger than the RXfull flag returned by the direct read of MDCCSR_EL0. The direct write to DBGDTRTX_EL0 must not be executed speculatively.

Direct reads of DBGDTRRX_EL0, DBGDTR_EL0, and MDCCSR_EL0 must occur in program order with respect to other direct reads of the same register using the same encoding.

The following accesses have an implied order within the atomic access:

 In the simple sequential execution of the program the indirect write to the DCC flags occurs immediately after the direct DTR access.

Note: For an access to DBGDTR_EL0, this means the indirect write happens after both DBGDTRRX_EL0 and DBGDTRTX_EL0 have been accessed.

 In the simple sequential execution model, for an external read of DBGDTRTX_EL0 or external write of DBGDTRRX_EL0:

— The check of the DCC flags for overrun or underrun occurs immediately before the access.

— If there is no underrun or overrun, the update of the DCC ready flags occurs immediately after the access.

— If there is underrun or overrun, the update of the DCC underrun/overrun flags occurs immediately after the access.

All observers must observe the same order for accesses.

Note: This does not create order where order does not otherwise exist. It applies only for ordered accesses.

Without explicit synchronization following external writes and external reads:

 The value written by an external write to DBGDTRRX_EL0 that does not overrun must be observable to direct reads of DBGDTRRX_EL0 and DBGDTR_EL0 in finite time.

The DCC flags updated as a side-effect of the external write or external read must be observable to:

— direct reads of MDCCSR_EL0 in finite time

— following external reads of EDSCR

— following external reads of DBGDTRRX_EL0 and external writes of DBGDTRTX_EL0 when checking for underrun and overrun.

Explicit synchronization is required to guarantee that a direct read of MDCCSR_EL0 returns up-to-date DCC ready flags. This means that if a signal is received from another agent that indicates that MDCCSR_EL0 must be read, an ISB is used to ensure that the direct read of MDCCSR_EL0 occurs after the signal has been received. This will also synchronize the value in DBGDTRRX_EL0, if applicable.

However, if that signal is an interrupt triggered by COMMIRQ, COMMTX or COMMRX, the exception entry is sufficient synchronization. See Synchronization of DCC interrupt request signals below.

Explicit synchronization is required following a direct read or direct write:

 for a value directly written to DBGDTRTX_EL0 to be observable to external reads of DBGDTRTX_EL0

 for a value directly written to DBGDTR_EL0 to be observable to external reads of DBGDTRTX_EL0 and DBGDTRRX_EL0

 to guarantee that the indirect writes to the DCC flags caused as a side-effect of the direct read or direct write have occurred, and hence the updated values will be:

— observable to external reads of EDSCR

— observable and to external reads of DBGDTRRX_EL0 and external writes of DBGDTRTX_EL0 when checking for underrun and overrun

— returned by a following direct read of MDCCSR_EL0.

See also Memory-mapped accesses to the DCC and ITR on page 166 and Synchronization of changes to external debug registers on page 190.

Derived requirements These rules mean that:

 Following a direct read of DBGDTRRX_EL0 made when RXfull == 1:

— If an external write to DBGDTRRX_EL0 checks the RXfull flag for overrun and observes RXfull == 0, the value returned by the previous direct read must not affected by the external write.

— If an external read of EDSCR returns RXfull == 0, then the value returned by the previous direct read must not be affected by a following external write to DBGDTRRX_EL0, and the following external write will not overrun.

 Following a direct read of DBGDTR_EL0 made when RXfull == 1:

— If an external write to DBGDTRRX_EL0 checks the RXfull flag for overrun and observes RXfull == 0, the value returned by the previous direct read must not affected by the external write nor by a following direct write to DBGDTRTX_EL0.

— If an external read of EDSCR returns RXfull == 0, then the value returned by the previous direct read must not be affected by following external writes to DBGDTRRX_EL0 and DBGDTRTX_EL0 (in either order) , and the following external write of DBGDTRRX_EL0 will not underrun.

 Following a direct write of DBGDTRTX_EL0 made when TXfull == 0:

— If an external read of DBGDTRTX_EL0 checks the TXfull flag for underrun and observes TXfull == 1, the value returned by the external read must be the value written by the previous direct write.

— If an external read of EDSCR returns TXfull == 1, then the value returned by a following external read of DBGDTRRX_EL0 must be the value written by the previous direct read, and the following external read will not underrun.

 Following a direct write of DBGDTR_EL0 made when TXfull == 0:

— If an external read of DBGDTRTX_EL0 checks the TXfull flag for underrun and observes TXfull == 1, the values returned by the external read and by a following external read of DBGDTRRX_EL0 must must be the value written by the previous direct write.

— If an external read of EDSCR returns TXfull == 1, then the value returned by following external reads of DBGDTRRX_EL0 and DBGDTRTX_EL0 (in either order) must be the value written by the previous direct read, and the following external read of DBGDTRTX_EL0 will not underrun.

 Following an external read of DBGDTRTX_EL0 that does not underrun, if a direct read of

MDCCSR_EL0 returns TXfull == 0, then the value returned by the external read must not be affected by a following direct write to DBGDTRTX_EL0.

 Following a first external read DBGDTRRX_EL0 and a following second external read of

DBGDTRTX_EL0 that does not underrun, if a direct read of MDCCSR_EL0 returns TXfull == 0, then the values returned by the external reads must not be affected by a following direct write to

DBGDTR_EL0.

 Following an external write of DBGDTRRX_EL0 that does not overrun, if a direct read of MDCCSR_EL0 returns RXfull == 1, then the value returned by a following direct read of

DBGDTRRX_EL0 or DBGDTR_EL0 must return the value written by the previous external write.

 Following a first external write to DBGDTRTX_EL0 and a following second external write of

DBGDTRRX_EL0 that does not overrun, if a direct read of MDCCSR_EL0 returns RXfull == 1, then the value returned by a following direct read of DBGDTR_EL0 must return the values written by the previous external writes.

10.5.3 Synchronization of DCC interrupt request signals

Following an external read or external write access to the DTR registers, the interrupt request signals, COMMIRQ, COMMTX and COMMRX, must be updated in finite time without explicit synchronization.

Furthermore, the updated values must be observable to a direct read of MDCCSR_EL0 or DBGDTRRX_EL0 or a direct write of DBGDTRTX_EL0 executed after taking of an interrupt exception generated by the interrupt request.

Following a direct read of DBGDTRRX_EL0 or direct write of DBGDTRTX_EL0, software must execute a context synchronization operation to ensure the interrupt request signals are updated. (This can be an exception return.)

10.5.4 DCC and ITR accesses in Debug state

In Debug state the observability rules are tightened for instructions issued through the ITR, to maintain communication between a debugger and the processor debug logic without requiring excessive explicit synchronization.

In Normal mode, without explicit synchronization:

 A direct read or direct write of the DTR registers by an instruction written to EDITR must be observable to an external write or external read in finite time:

— a direct read of DBGDTRRX_EL0 to an external write of DBGDTRRX_EL0

— a direct read of DBGDTR_EL0 to external writes of DBGDTRRX_EL0 and DBGDTRTX_EL0

— a direct write of DBGDTRTX_EL0 to an external read of DBGDTRTX_EL0

— a direct write of DBGDTR_EL0 to external reads of DBGDTRTX_EL0 and DBGDTRRX_EL0.

This includes the indirect write to the DCC flags, which occurs atomically with the access as described in DCC accesses in Non-debug state above.

The subsequent external write or external read must observe either the old or new values of both the DTR contents and DCC flags. If the old values are observed, this will typically result in overrun or underrun (assuming the old DCC flag values indicate an overrun or underrun condition, as would normally be the case).

This means the debugger can observe the direct read or direct write without explicit synchronization and without explicitly testing the DCC flags in EDSCR, but can rely on overrun and underrun tests.

 External reads of DBGDTRTX_EL0 that do not underrun and external writes of DBGDTRRX_EL0 that do not overrun must be observable to an instruction subsequently written to EDITR on completion of the external access. This includes the indirect write to the DCC flags.

This means that, without explicit synchronization and without the need to first check the DCC flags in MDCCSR_EL0:

— if the instruction is a direct read of DBGDTRRX_EL0 or DBGDTR_EL0 it will observe the external write.

— if the instruction is a direct write of DBGDTRTX_EL0 or DBGDTR_EL0, it will observe the external read.

 Following an external write to EDITR:

— A write that does not overrun commits an instruction for execution. The instruction must complete execution in finite time without requiring any further operation by the debugger.

— The ITR flags updated as a side-effect of the external write must be observable to:

 following external reads of EDSCR

 following external writes of EDITR when checking for overrun.

In memory access mode, these requirements shift to the instructions implicitly executed by external reads and external writes of the DTR registers.