Hi Leo,
On Thu, 23 Oct 2025 at 16:00, Leo Yan leo.yan@arm.com wrote:
Hi Mike,
On Tue, Oct 07, 2025 at 02:56:46PM +0100, Mike Leach wrote:
[...]
System CTIs are attached to key HW trace infrastucture such as input triggers for ETR/ETB that have direct effect on trace. CoreCTIs, while they have some debug triggers, can also trigger ETM events.
Seems to me, it is no matter system CTIs or Core CTIs. Here, I am trying to distinguish three methods for enabling CTI:
(1) Enable CTI within a perf session. (2) Enable CTI within a sysfs session. (3) Enable CTI using the CTI driver's sysfs knob(s).
Currently, methods (2) and (3) are both using CS_MODE_SYSFS.
Method (2) enables a CTI device when we enable a source-to-sink path via the sysfs interface; CTI acts as a helper in this case.
Since the CTI driver also provides its own sysfs knobs to enable the CTI device by itself (defined in coresight-cti-sysfs.c), to distinguish this from method (2), this patch introduces CS_MODE_DEBUG.
The point here is that a user can (or at least could and should be able to) program and enable CTIs across the system to generate signal inputs to trace devices, then start trace either by sysfs or perf and expect those CTIs to have the desired effect.
I agree that we should allow users to configure CTI through the sysfs interface, and afterwards it can be enabled either via sysfs or a perf session.
However, the problem is that, unlike other components, the CTI module can be enabled directly through its own control knob (see enable_store() in coresight/coresight-cti-sysfs.c). As a result, the enabling is _not_ bound to any CoreSight path.
This is why a new mode (CS_MODE_DEBUG) is introduced. When users select this mode, power management should be handled by the CTI driver itself rather than by the CoreSight core layer, because in this case no CoreSight path is bound to the CTI devices.
The "mode" for CTIs was introduced to fix a ref count issue. I am not sure now that this is the best solution. A "mode" is good for components on the direct trace path responsible for transmitting trace from source to sink, but perhaps less useful on the CTI/CTM system which is both global and has multiple uses.
We effectively have three domains for CTIs all of which can be programmed to affect trace capture -
- CPU bound - on the trace path, possibly affected by core power down
depending on the implementation of the system and will be enabled as helpers as the path is enabled. 2) Trace path system CTIs - connected to other path devices - e.g. funnels, etr etc, that will also be enabled as helpers as trace path is enabled. 3) Other system CTIs - not directly connected to specific trace devices, but can channel signals via the CTM to other trace path CTIs
I would say we can simplify the case 1) and 2) as a single case, as both cases CTI is attached to a path, and can be managed by core layer for CPU PM. Only a difference between them is we cannot directly set register for CPU bound module as it might be not accessible when CPU power domain is off, but I will explain later appropriate way to handle the difference (and why we should not have "powered" flag).
The case 3) is special, as said, this is totally irrelevant to other coresight modules and CTI should manage every thing by self.
Could you confirm that the first two CTI cases can be enabled via CTI's "enable" knob? If answer is no (CTIs in the first two cases must be enabled by a source-to-sink session), then the last case should be no matter for CPU PM, and as a result, we can remove all CPU PM code in the CTI driver (as all PM things can be managed by core layer).
The CTI driver ref-counts CTI enables / disables, and alos has a flag to indicate when powered so that enables / disables are counted but will not be acted on unless powered.
I can accept the refcnt is used in CTI driver, a case is CTI module can be bound to links (e.g., a CTI binding to funnel/replicator, etc). So a CTI device can be enabled for multiple times.
But the "hw_enabled" and "hw_powered" flags should not exist at all. Currently, the CTI driver is a bit mess for me, mainly caused by these two flags used in the coresight-cti-sysfs.c.
We already have the mode and refcnt, this is sufficient to present if a CTI module has been enabled. And if we can clearly distinguish config parameters and runtime register values, and we must use SMP call to enable/disable CPU-bound CTI module, then we can remove "hw_powered" flag.
One of the key properties of the CTI drivers is that all the CTI registers can be programmed at any time - even while the CTI is enabled and trace is running. This differs from the ETM or other CS component cases where programmable registers ignore writes and may be unstable on reads while the trace is enabled. Indeed, it only makes sense for the CTI APPSET / APPCLR /APPPULSE registers to be written if the trace is running - which can be from the command line or some userspace software application.
Therefore the sysfs interface is designed to write to the internal register cache if the CTI is either disabled or unpowered, but will write both cache and physical register if the device is both powered and enabled. Hence the flags for powered and enabled. Effectively we maintain and count enable / disable requests even when unpowered - so that the state on repowering is respected. and note if enabled for the write through functionality.
Regards
Mike
There is probably a case for ensuring that the enables/disables via the sysfs files are balanced - i.e. a sysfs file disable should not disable a helper enable, so a specific count on that route may be needed.
IIUC, we don't need extra count for this case. We simply return back if users try to enable CTI duplicately - first time we set the mode, and afterwards just nop operations.
We might need to add an extra checking to prevent disable CTI via its own knob if the CTI has already been enabled by source-to-sink sessions.
I might extract out CTI patches in next spin, as we can discuss in small context.
Thanks, Leo