diff --git a/docs/firmware-design.md b/docs/firmware-design.md index 417ef62c5..abe7dc5a0 100644 --- a/docs/firmware-design.md +++ b/docs/firmware-design.md @@ -15,8 +15,9 @@ Contents : 10. [Firmware Image Package (FIP)](#10--firmware-image-package-fip) 11. [Use of coherent memory in Trusted Firmware](#11--use-of-coherent-memory-in-trusted-firmware) 12. [Isolating code and read-only data on separate memory pages](#12--isolating-code-and-read-only-data-on-separate-memory-pages) -13. [Code Structure](#13--code-structure) -14. [References](#14--references) +13. [Performance Measurement Framework](#13--performance-measurement-framework) +14. [Code Structure](#14--code-structure) +15. [References](#15--references) 1. Introduction @@ -2016,7 +2017,128 @@ This build flag is disabled by default, minimising memory footprint. On ARM platforms, it is enabled. -13. Code Structure +13. Performance Measurement Framework +-------------------------------------- + +The Performance Measurement Framework (PMF) facilitates collection of +timestamps by registered services and provides interfaces to retrieve +them from within the ARM Trusted Firmware. A platform can choose to +expose appropriate SMCs to retrieve these collected timestamps. + +By default, the global physical counter is used for the timestamp +value and is read via `CNTPCT_EL0`. The framework allows to retrieve +timestamps captured by other CPUs. + +### Timestamp identifier format + +A PMF timestamp is uniquely identified across the system via the +timestamp ID or `tid`. The `tid` is composed as follows: + + Bits 0-7: The local timestamp identifier. + Bits 8-9: Reserved. + Bits 10-15: The service identifier. + Bits 16-31: Reserved. + +1. The service identifier. Each PMF service is identified by a + service name and a service identifier. Both the service name and + identifier are unique within the system as a whole. + +2. The local timestamp identifier. This identifier is unique within a given + service. + +### Registering a PMF service + +To register a PMF service, the `PMF_REGISTER_SERVICE()` macro from `pmf.h` +is used. The arguments required are the service name, the service ID, +the total number of local timestamps to be captured and a set of flags. + +The `flags` field can be specified as a bitwise-OR of the following values: + + PMF_STORE_ENABLE: The timestamp is stored in memory for later retrieval. + PMF_DUMP_ENABLE: The timestamp is dumped on the serial console. + +The `PMF_REGISTER_SERVICE()` reserves memory to store captured +timestamps in a PMF specific linker section at build time. +Additionally, it defines necessary functions to capture and +retrieve a particular timestamp for the given service at runtime. + +The macro `PMF_REGISTER_SERVICE()` only enables capturing PMF +timestamps from within ARM Trusted Firmware. In order to retrieve +timestamps from outside of ARM Trusted Firmware, the +`PMF_REGISTER_SERVICE_SMC()` macro must be used instead. This macro +accepts the same set of arguments as the `PMF_REGISTER_SERVICE()` +macro but additionally supports retrieving timestamps using SMCs. + +### Capturing a timestamp + +PMF timestamps are stored in a per-service timestamp region. On a +system with multiple CPUs, each timestamp is captured and stored +in a per-CPU cache line aligned memory region. + +Having registered the service, the `PMF_CAPTURE_TIMESTAMP()` macro can be +used to capture a timestamp at the location where it is used. The macro +takes the service name, a local timestamp identifier and a flag as arguments. + +The `flags` field argument can be zero, or `PMF_CACHE_MAINT` which +instructs PMF to do cache maintenance following the capture. Cache +maintenance is required if any of the service's timestamps are captured +with data cache disabled. + +To capture a timestamp in assembly code, the caller should use +`pmf_calc_timestamp_addr` macro (defined in `pmf_asm_macros.S`) to +calculate the address of where the timestamp would be stored. The +caller should then read `CNTPCT_EL0` register to obtain the timestamp +and store it at the determined address for later retrieval. + +### Retrieving a timestamp + +From within ARM Trusted Firmware, timestamps for individual CPUs can +be retrieved using either `PMF_GET_TIMESTAMP_BY_MPIDR()` or +`PMF_GET_TIMESTAMP_BY_INDEX()` macros. These macros accept the CPU's MPIDR +value, or its ordinal position, respectively. + +From outside ARM Trusted Firmware, timestamps for individual CPUs can be +retrieved by calling into `pmf_smc_handler()`. + + Interface : pmf_smc_handler() + Argument : unsigned int smc_fid, u_register_t x1, + u_register_t x2, u_register_t x3, + u_register_t x4, void *cookie, + void *handle, u_register_t flags + Return : uintptr_t + + smc_fid: Holds the SMC identifier which is either `PMF_SMC_GET_TIMESTAMP_32` + when the caller of the SMC is running in AArch32 mode + or `PMF_SMC_GET_TIMESTAMP_64` when the caller is running in AArch64 mode. + x1: Timestamp identifier. + x2: The `mpidr` of the CPU for which the timestamp has to be retrieved. + This can be the `mpidr` of a different core to the one initiating + the SMC. In that case, service specific cache maintenance may be + required to ensure the updated copy of the timestamp is returned. + x3: A flags value that is either 0 or `PMF_CACHE_MAINT`. If + `PMF_CACHE_MAINT` is passed, then the PMF code will perform a + cache invalidate before reading the timestamp. This ensures + an updated copy is returned. + +The remaining arguments, `x4`, `cookie`, `handle` and `flags` are unused +in this implementation. + +### PMF code structure + +1. `pmf_main.c` consists of core functions that implement service registration, + initialization, storing, dumping and retrieving timestamps. + +2. `pmf_smc.c` contains the SMC handling for registered PMF services. + +3. `pmf.h` contains the public interface to Performance Measurement Framework. + +4. `pmf_asm_macros.S` consists of macros to facilitate capturing timestamps in + assembly code. + +5. `pmf_helpers.h` is an internal header used by `pmf.h`. + + +14. Code Structure ------------------- Trusted Firmware code is logically divided between the three boot loader @@ -2060,7 +2182,7 @@ FDTs provide a description of the hardware platform and are used by the Linux kernel at boot time. These can be found in the `fdts` directory. -14. References +15. References --------------- 1. Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available