Title: Multi Target Trace (MTT)
Maintainers:
	Marc Titinger <marc.titinger@st.com>
	Chris Smith <chris.smith@st.com>

CONTENTS

1. Goals and Concepts
2. Architectures Supported
3. Requirements/Compiling/Running
4. Application Trace Logger/Viewer
5. API Reference and samples

1. Goals and Concepts

The Multi-Target Trace software provides a unified API and data format
for the cores found in STMicroelectronics SoCs, and more generally SoCs
running STLinux. This file is about the STLinux implementation of MTT,
but compatible implementations exist for ST40 (bare or OS21), ST200
and STXP70.

MTT was designed with the history of KPTrace history in mind, and after
considering generic trace frameworks and specifications like LTT-ng
and OST. The goals of this project are:

* Identify the common fundamentals of software traces between different
  cores found in STM/DCG SoCs
* Differentiate compile-time and runtime trace data and enable the use of
  dictionaries
* Establish the appropriate balance between trace compactness and
  CPU-cycle impact.
* Enable interleaving of trace streams from all cores on a SoC when
  using the System-Trace-Module (STM)
* Unify trace display and analysis tools for the different cores.
* Enable advanced use-cases like automation of trace acquisition
  and post-processing.

Common trace fundamentals
-------------------------

Here are the data fields required from all trace sources:

Trace ID:	indicates the location that issued the trace,
	this can consist of one of two kinds of value:
	a) Value of return address register
	   (return PC when exiting the trace routine)
	b) Key generated by a pre-processor, now under construction,
	   providing application specific metadata. This key will index
           a description of the trace described in an abstract format.
	   The set of those descriptors are a dictionary.
	   A typical description associated to a key can be:
	- A function name (symbol) and offset in the function
	- A LINE and FILE location of the trace point.
	- Structure types and field names of the payload
	- Post processing rules and application specific semantics
	  associated to the trace.

Timestamp:	can be inserted by the trace routines, or off-board by the
	STM-probe. Hence this is supported as an optional filed in the
	MTT binary data format.

Target ID:	The core issuing the trace: identifier of the SMP core or
		or the accelerator that issued the trace.

Payload:	The effectively useful data carried by the trace.
	This can be a structure or a scalar type, but also the trace
	can be just used as a marker with an empty payload.


Auxiliary data needed by the real world implementation
--------------------------------------------------

The fields above are not sufficient in the real world to achieve the goals
previously listed. In the real world, we need to:

- be able to compute the size of a frame with a payload of arbitrary size
- be able to cope with revisions of the trace format, and damaged frames.
- be able to identify, enable and disable trace sources within an SoC.

Moreover, because we prefer low CPU-cycle cost over low bandwidth, we try
avoiding non word-aligned accesses, and bit field constructions occurring
for each trace: we rather do two 32bits writes (2 cycles), rather than or'ing
shifting, adding etc., to pack bit fields into a word (N cycles).

Consequently:

- We introduce the concept of "component ID" which identifies the functional
block or the application responsible to the trace frame. Trace from this block
can be independently turned on or off.

- We introduce a first sync word that does not change for a core during the
trace session, can be initialized at no dynamic cost, and hence pack several
fields: Frame start marker (SYNC), target ID, format version.

- We introduce a packet type: this makes the format very versatile, as this
allows the definition of trace data packets, and also commands
(start/stop/setters getters...) and notifications.

- We introduce type information (type_info field) that allows computing the size
of the frame and can carry formatting data for most use cases.

The resulting frame is built as following:

Word0: MTT frame sync, target ID, version
Word1: Packet type, and protocol options flags
Word2: TraceID
Word3: componentID
Word4: type_info

Those 5 words are called "preamble", and can always be expected.

Optional fields for the MTT protocol
------------------------------------

Subsequent words can be:
- Context ID: like the PID in the case of Linux traces.
- Timestamp: as mentioned
- Level: if the user wishes to vary the verbosity level of the trace

Payload
-------

As mentioned, the size of the payload is known at compile time, and built into
the type_info word. When the trace is used as a marker, the payload may be
empty. In the current implementation, type encoding (for display) is available
for scalar types of vectors, or blobs (only size info).


About Components (see components.c)
---------------

MTT embeds the notion of component, which is needed in order to enable/disable
tracing for given parts of the software. The kernel implementation creates a
kobject for each component to store the name/id/filter-level etc...

A component has a "private" field which is the "pre-fetched" value that the
output driver will use to select the right channel for a given component.
With the System Trace Module, it is typically the channel assigned to the
component on allocation of the component, or assigned statically for predefined
or critical components such as hardirq tracing.

About packets (see packets.c)
---------------

Packets are pre-allocated buffers used to prepare a trace record. A circular
per-cpu set of buffers is allocated at startup and handed out in turn each
time a packet is requested, avoiding the overhead of entering the memory
allocator each time a trace record is emitted. The set is large enough to
provide ample contingency for nested trace events.


About trace collection
-----------------------

Trace data output is designed to use low-CPU paths. When using the
System Trace Module, usermode trace packets are written to the STM
through an mmaped address range. When VFS is used, the kernel traces
are first written to a Relay channel for each CPU, and collected and
written to the user's chosen filesystem (NFS, SATA, USB...) by unprivileged
code. The goal is to give priority to the application and to minimize system
intrusion. MTT's binary data format allows packet frame resynchronization,
so that corrupted or lost frames do not break the complete trace session.

The trace infrastructure uses a target service, the MTT Daemon, that provides
discovery, connectivity, and is responsible for low-intrusion trace collection
in buffered cases.


2. Architectures Supported

MTT is implemented on the following architectures

Linux:
- sh4
- armv7

Non-Linux targets:
- ST40  OS21
- ST200 OS21
- XP70 bare
- XP70 FreeRTOS


3. Requirements/Compiling/Running

You may go to "Kernel Hacking" to enable "Multi-Target Trace (MTT)
Infrastructure Support" (CONFIG_MTT).

See the help text for the mttcontrol and kptrace binaries, which are frontend
command line clients provided to interface with the trace infrastructure.

% mttcontrol --status		provides the status of the trace system
% mttcontrol --setup		sets the MTT options for the system
% mttcontrol --start / --stop	provides session start/stop control
% mttcontrol --help		more detailed help

4. Application Trace Logger/Viewer

The Application Trace Logger is the host side control and display software that
we recommend using, providing an easy-to-use interface to setup and control the
trace session, and to visualize traces in a convenient form. Quick command line
dump tools are also available.

5. API Reference and samples

For those interested in static instrumentation of the system, or for cases where
critical/frequent data needs to be output for later charting or statistical
analysis, the MTT API provides short path and compact API call to output this
kind of data.

The function mtt_trace is the preferred API call for this:

- No string formatting target side
- Compact, word aligned and optimized packet handling
- Possibility to use a dictionary key, or a hint to describe/name the value
- In the GUI tools, the value can be filtered, charted, or exported to compute
  statistics and display waveforms.

Please refer to the API documentation.

The API prototypes are defined in <linux/mtt.h>, typical initialization code
would be like:

 #include <linux/mtt.h>

 static mtt_comp_handle_t mtt_handle;

 mtt_open(MTT_COMPONENTID_ANY, MTTDEV_NAME, &mtt_handle);

 mtt_close(mtt_handle);


Tracing a simple 32 bits integer:

 mtt_trace(mtt_handle, MTT_LEVEL_INFO, MTT_TRACEITEM_UINT32, &my_var, "NULL");

Tracing a simple 32 bits value as a named signal (for later analysis):

 mtt_trace(mtt_handle, MTT_LEVEL_INFO, MTT_TRACEITEM_UINT32, &val, "signal0");

Basic printf-like logging is also available:

 mtt_print(mtt_handle, MTT_LEVEL_API_RETURN, "fake_alsa_init");

Sample Code is located in samples/mtt.
