How to pause system level timers while CPU execution is halted
Article ID: 146787168
Published date: 15 Aug 2018
Last updated: -
Applies to: Cortex-A, Cortex-R
How can I pause system level timers while CPU execution is halted?
This knowledge article is relevant to RTL system designers who must provide a means to temporarily suspend system-level counter or timer modules while CPU execution is halted for software debug purposes (for example, at a breakpoint). The primary reason for doing this is to prevent system timer timeouts, for any timers which require regular service as part of normal software operation. When CPU execution is halted for debug, software execution is typically suspended for millions of clock cycles while the external debugger communicates with the system. During this time, system-level timers are likely to timeout, resulting in unwanted interrupts or watchdog reset events. This can be avoided by temporarily stopping the timers while CPU execution is halted. This article describes some ways to implement this.
Typically, there are two possible approaches to stopping timers while CPU execution is halted for debug:
Use processor DBGACK output to halt timers.
Use CoreSight Cross Trigger Interface (CTI) triggers to halt timers.
Many (but not all) Arm processors provide a per-core DBGACK output, which indicates that the corresponding core is halted for debug for any reason (halt request, breakpoint, or other reason). This signal is asserted when the Arm CPU is halted, and is deasserted when the Arm CPU resumes execution. In simple systems with one or more CPUs, or systems without a CoreSight debug infrastructure, the processor DBGACK outputs may be used to stop timers. That is, to stop timers when DBGACK is asserted, and allow timers to count when DBGACK is deasserted.
The main disadvantage to the DBGACK approach described in the previous paragraph is that it is inflexible (non-programmable), and typically relies on hard-wire connections to processor signals, which must be customized for each system. It is also not possible to use it with any processor that does not provide a DBGACK output.
A more flexible approach is to use CoreSight Cross Trigger Interface (CTI) triggers to halt system-level timers. The main benefit to this approach is that the cross-trigger logic is software programmable, from on-chip software or external debug tools. This gives the end-user more control over when and under what circumstances a timer should be halted. For example, the user may choose whether or not to stop the timer depending on whether all CPUs are being halted or only some or certain CPUs are being halted (in which case other CPUs may still be relying on the timer operating normally). In multi-core systems with CoreSight, CTIs are typically used to manage the halting and restarting of CPUs in the system, so with the cross-trigger approach, timer halting can be managed by debug tools in the exact same way that CPU halting is managed.
See the CoreSight system design documentation for details on integrating CTI trigger signals with timer modules.
Additional notes on common types of counter and timer-type modules found in Arm-based systems:
Modern Cortex-A class processors require a System Counter, which must be implemented at the system level. The System Counter might need be stopped when CPUs are halted. When all CPUs are halted for debug, the system counter should be halted as well. This makes it seem to software that time did not stop, preventing timer timeouts. But if any part of the system still requires access to the system counter (for example, if some CPUs are not halted), then the System Counter should not be halted. Arm recommends the CTI approach described above, which enables configurable System Counter halt behavior
Many modern CoreSight trace sources (ETM, STM, and so on) support trace timestamping, where the timestamp values are sourced from a system-level ‘timestamp generator', which is separate from the System Counter or other system-level timers. Arm recommends the timestamp generator is not halted for debug events – this counter should continue to operate normally through CPU halt events.
For watchdog or other system-level timers, the system designer should decide if and how these timers should be stopped.
CoreSight SoC System Design Guide (CTI based timer halting)
ARMv7-A / ARMv8-A Architecture Reference Manuals (System Counter)