blob: 1135de04c2a2d866bd4925a7560aa6089f0e51dd [file] [log] [blame]
#############
TF-M profiler
#############
TF-M profiler is a tool for profiling and benchmarking TF-M. The developer can
leverage it to get the interested data of runtime.
Initially, TF-M profiler supports only count logging. You can add "checkpoint"
in the program. The timer count or CPU cycle count of this checkpoint can be
saved at runtime and be analysed in the future.
************************
How to use TF-M profiler
************************
1. Integrate profiler tool with TF-M
The profiler should be compiled together with TF-M, thus running in SPE.
The source file need to be compiled with TF-M is mainly `profiler.c`. The header
files are in `export` folder.
`export/prof_hal.h` defines the HAL that should be implemented by the platform.
* `prof_hal_init()`: Initialize the counter hardware.
* `prof_hal_get_count()`: Get current counter value.
The size of the database is determined by `PROF_DB_MAX` defined in
`export/prof_common.h`.
The developer can override the size by redefining `PROF_DB_MAX`.
2. Add checkpoints for secure side
The developer should identify the places in source code for adding the
checkpoints. The count value of the timer or CPU cycle will be saved into the
database for the checkpoints.
The interface APIs are defined in `export/prof_if_s.h` for secure side.
3. Add checkpoints for non-secure side
It's supported to add checkpionts in non-secure side. Add
`export/ns/prof_if_ns.c` to the source file list of non-secure side.
The interface APIs for non-secure side are defined in `export/ns/prof_if_ns.h`.
4. Run the program and collect data
After successfully run the program, the data should be saved into the database.
The developer can dump the data throught the interface defined in the header
files mentioned above.
A customized software or tool can be used to generate the analysis report based
on the data.
********************
Interface user guide
********************
Initialization
==============
`prof_data_init()` should be called in secure side before calling any API of
profiler.
Count logging
=============
The counter logging related APIs are defined in macros to keep the interface
consistent between secure and non-secure side.
`PROF_TIMING_LOG`: This API is used to log the counter value when calling this
macro. `topic_id` and `cp_id` are the parameters.
`topic_id`: Topic is used to gather a group of checkpoints. It's useful when
you have many checkpoints for different purposes. Topic can help to organize
them and filter the related information out. It's a 8-bit unsigned value.
`cp_id`: Checkpoint ID. Different topics can have same `cp_id`. It's a 16-bit
unsigned value.
Data fetching
=============
For the same consistent reason as counter logging, same macros are defined as
the interface for both secure and non-secure side.
The data fetching interface works as stream way. `PROF_FETCH_DATA_START` and
`PROF_FETCH_DATA_BY_XXX_START` search the data that matches the given pattern
from the beginning of the database. `PROF_FETCH_DATA_CONTINUE` and
`PROF_FETCH_DATA_BY_XXX_CONTINUE` search from the next data set of the
previous result.
The match condition of a search is controlled by the tag mask. It's `tag value`
& `tag_mask` == `tag_pattern`. To enumerate the whole database, set
`tag_mask` and `tag_pattern` both to `0`.
`PROF_FETCH_DATA_XXX`: The generic interface for getting data.
`PROF_FETCH_DATA_BY_TOPIC_XXX`: Get data for a specific `topic`.
`PROF_FETCH_DATA_BY_CP_XXX`: Get data for a specific checkpoint by specifying
both `topic` and `cp`.
The APIs return `false` if no matching data found until the end of the database.
Calibration
===========
The profiler itself has the tick or cycle cost. To get a more accurate data, a
calibration system is introduced. It's optional.
The counter logging APIs can be called from secure or non-secure side. And the
cost of calling functions from these two worlds are different. So, secure and
non-secure have different calibration data.
The system performance might float during the initialization, for example change
CPU frequency, enable cache, etc. So, it's recommendated that the calibration is
done just before the first checkpoint.
`PROF_DO_CALIBRATE`: Call this macro to get calibration value. The more `rounds`
the more accurate.
`PROF_GET_CALI_VALUE_FROM_TAG`: Get the calibration value from the tag. The
calibrated counter is "current_counter" - "previous_counter" -
"current_cali_value".
"current_cali_value" = PROF_GET_CALI_VALUE_FROM_TAG(current_tag).
--------------
*Copyright (c) 2022, Arm Limited. All rights reserved.*