diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:13:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:13:47 +0000 |
commit | 102b0d2daa97dae68d3eed54d8fe37a9cc38a892 (patch) | |
tree | bcf648efac40ca6139842707f0eba5a4496a6dd2 /docs/getting_started | |
parent | Initial commit. (diff) | |
download | arm-trusted-firmware-102b0d2daa97dae68d3eed54d8fe37a9cc38a892.tar.xz arm-trusted-firmware-102b0d2daa97dae68d3eed54d8fe37a9cc38a892.zip |
Adding upstream version 2.8.0+dfsg.upstream/2.8.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'docs/getting_started')
-rw-r--r-- | docs/getting_started/build-options.rst | 1164 | ||||
-rw-r--r-- | docs/getting_started/docs-build.rst | 112 | ||||
-rw-r--r-- | docs/getting_started/image-terminology.rst | 192 | ||||
-rw-r--r-- | docs/getting_started/index.rst | 20 | ||||
-rw-r--r-- | docs/getting_started/initial-build.rst | 118 | ||||
-rw-r--r-- | docs/getting_started/porting-guide.rst | 3515 | ||||
-rw-r--r-- | docs/getting_started/prerequisites.rst | 181 | ||||
-rw-r--r-- | docs/getting_started/psci-lib-integration-guide.rst | 536 | ||||
-rw-r--r-- | docs/getting_started/rt-svc-writers-guide.rst | 320 | ||||
-rw-r--r-- | docs/getting_started/tools-build.rst | 179 |
10 files changed, 6337 insertions, 0 deletions
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst new file mode 100644 index 0000000..402de13 --- /dev/null +++ b/docs/getting_started/build-options.rst @@ -0,0 +1,1164 @@ +Build Options +============= + +The TF-A build system supports the following build options. Unless mentioned +otherwise, these options are expected to be specified at the build command +line and are not to be modified in any component makefiles. Note that the +build system doesn't track dependency for build options. Therefore, if any of +the build options are changed from a previous build, a clean build must be +performed. + +.. _build_options_common: + +Common build options +-------------------- + +- ``AARCH32_INSTRUCTION_SET``: Choose the AArch32 instruction set that the + compiler should use. Valid values are T32 and A32. It defaults to T32 due to + code having a smaller resulting size. + +- ``AARCH32_SP`` : Choose the AArch32 Secure Payload component to be built as + as the BL32 image when ``ARCH=aarch32``. The value should be the path to the + directory containing the SP source, relative to the ``bl32/``; the directory + is expected to contain a makefile called ``<aarch32_sp-value>.mk``. + +- ``AMU_RESTRICT_COUNTERS``: Register reads to the group 1 counters will return + zero at all but the highest implemented exception level. Reads from the + memory mapped view are unaffected by this control. + +- ``ARCH`` : Choose the target build architecture for TF-A. It can take either + ``aarch64`` or ``aarch32`` as values. By default, it is defined to + ``aarch64``. + +- ``ARM_ARCH_FEATURE``: Optional Arm Architecture build option which specifies + one or more feature modifiers. This option has the form ``[no]feature+...`` + and defaults to ``none``. It translates into compiler option + ``-march=armvX[.Y]-a+[no]feature+...``. See compiler's documentation for the + list of supported feature modifiers. + +- ``ARM_ARCH_MAJOR``: The major version of Arm Architecture to target when + compiling TF-A. Its value must be numeric, and defaults to 8 . See also, + *Armv8 Architecture Extensions* and *Armv7 Architecture Extensions* in + :ref:`Firmware Design`. + +- ``ARM_ARCH_MINOR``: The minor version of Arm Architecture to target when + compiling TF-A. Its value must be a numeric, and defaults to 0. See also, + *Armv8 Architecture Extensions* in :ref:`Firmware Design`. + +- ``BL2``: This is an optional build option which specifies the path to BL2 + image for the ``fip`` target. In this case, the BL2 in the TF-A will not be + built. + +- ``BL2U``: This is an optional build option which specifies the path to + BL2U image. In this case, the BL2U in TF-A will not be built. + +- ``BL2_AT_EL3``: This is an optional build option that enables the use of + BL2 at EL3 execution level. + +- ``BL2_ENABLE_SP_LOAD``: Boolean option to enable loading SP packages from the + FIP. Automatically enabled if ``SP_LAYOUT_FILE`` is provided. + +- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place + (XIP) memory, like BL1. In these use-cases, it is necessary to initialize + the RW sections in RAM, while leaving the RO sections in place. This option + enable this use-case. For now, this option is only supported when BL2_AT_EL3 + is set to '1'. + +- ``BL31``: This is an optional build option which specifies the path to + BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not + be built. + +- ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the + file that contains the BL31 private key in PEM format. If ``SAVE_KEYS=1``, + this file name will be used to save the key. + +- ``BL32``: This is an optional build option which specifies the path to + BL32 image for the ``fip`` target. In this case, the BL32 in TF-A will not + be built. + +- ``BL32_EXTRA1``: This is an optional build option which specifies the path to + Trusted OS Extra1 image for the ``fip`` target. + +- ``BL32_EXTRA2``: This is an optional build option which specifies the path to + Trusted OS Extra2 image for the ``fip`` target. + +- ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the + file that contains the BL32 private key in PEM format. If ``SAVE_KEYS=1``, + this file name will be used to save the key. + +- ``BL33``: Path to BL33 image in the host file system. This is mandatory for + ``fip`` target in case TF-A BL2 is used. + +- ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the + file that contains the BL33 private key in PEM format. If ``SAVE_KEYS=1``, + this file name will be used to save the key. + +- ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication + and ARMv8.5 Branch Target Identification support for TF-A BL images themselves. + If enabled, it is needed to use a compiler that supports the option + ``-mbranch-protection``. Selects the branch protection features to use: +- 0: Default value turns off all types of branch protection +- 1: Enables all types of branch protection features +- 2: Return address signing to its standard level +- 3: Extend the signing to include leaf functions +- 4: Turn on branch target identification mechanism + + The table below summarizes ``BRANCH_PROTECTION`` values, GCC compilation options + and resulting PAuth/BTI features. + + +-------+--------------+-------+-----+ + | Value | GCC option | PAuth | BTI | + +=======+==============+=======+=====+ + | 0 | none | N | N | + +-------+--------------+-------+-----+ + | 1 | standard | Y | Y | + +-------+--------------+-------+-----+ + | 2 | pac-ret | Y | N | + +-------+--------------+-------+-----+ + | 3 | pac-ret+leaf | Y | N | + +-------+--------------+-------+-----+ + | 4 | bti | N | Y | + +-------+--------------+-------+-----+ + + This option defaults to 0. + Note that Pointer Authentication is enabled for Non-secure world + irrespective of the value of this option if the CPU supports it. + +- ``BUILD_MESSAGE_TIMESTAMP``: String used to identify the time and date of the + compilation of each build. It must be set to a C string (including quotes + where applicable). Defaults to a string that contains the time and date of + the compilation. + +- ``BUILD_STRING``: Input string for VERSION_STRING, which allows the TF-A + build to be uniquely identified. Defaults to the current git commit id. + +- ``BUILD_BASE``: Output directory for the build. Defaults to ``./build`` + +- ``CFLAGS``: Extra user options appended on the compiler's command line in + addition to the options set by the build system. + +- ``COLD_BOOT_SINGLE_CPU``: This option indicates whether the platform may + release several CPUs out of reset. It can take either 0 (several CPUs may be + brought up) or 1 (only one CPU will ever be brought up during cold reset). + Default is 0. If the platform always brings up a single CPU, there is no + need to distinguish between primary and secondary CPUs and the boot path can + be optimised. The ``plat_is_my_cpu_primary()`` and + ``plat_secondary_cold_boot_setup()`` platform porting interfaces do not need + to be implemented in this case. + +- ``COT``: When Trusted Boot is enabled, selects the desired chain of trust. + Defaults to ``tbbr``. + +- ``CRASH_REPORTING``: A non-zero value enables a console dump of processor + register state when an unexpected exception occurs during execution of + BL31. This option defaults to the value of ``DEBUG`` - i.e. by default + this is only enabled for a debug build of the firmware. + +- ``CREATE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the + certificate generation tool to create new keys in case no valid keys are + present or specified. Allowed options are '0' or '1'. Default is '1'. + +- ``CTX_INCLUDE_AARCH32_REGS`` : Boolean option that, when set to 1, will cause + the AArch32 system registers to be included when saving and restoring the + CPU context. The option must be set to 0 for AArch64-only platforms (that + is on hardware that does not implement AArch32, or at least not at EL1 and + higher ELs). Default value is 1. + +- ``CTX_INCLUDE_EL2_REGS`` : This boolean option provides context save/restore + operations when entering/exiting an EL2 execution context. This is of primary + interest when Armv8.4-SecEL2 extension is implemented. Default is 0 (disabled). + This option must be equal to 1 (enabled) when ``SPD=spmd`` and + ``SPMD_SPM_AT_SEL2`` is set. + +- ``CTX_INCLUDE_FPREGS``: Boolean option that, when set to 1, will cause the FP + registers to be included when saving and restoring the CPU context. Default + is 0. + +- ``CTX_INCLUDE_MTE_REGS``: Numeric value to include Memory Tagging Extension + registers in cpu context. This must be enabled, if the platform wants to use + this feature in the Secure world and MTE is enabled at ELX. This flag can + take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. + Default value is 0. + +- ``CTX_INCLUDE_NEVE_REGS``: Numeric value, when set will cause the Armv8.4-NV + registers to be saved/restored when entering/exiting an EL2 execution + context. This flag can take values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. Default value is 0. + +- ``CTX_INCLUDE_PAUTH_REGS``: Numeric value to enable the Pointer + Authentication for Secure world. This will cause the ARMv8.3-PAuth registers + to be included when saving and restoring the CPU context as part of world + switch. This flag can take values 0 to 2, to align with ``FEATURE_DETECTION`` + mechanism. Default value is 0. + + Note that Pointer Authentication is enabled for Non-secure world irrespective + of the value of this flag if the CPU supports it. + +- ``DEBUG``: Chooses between a debug and release build. It can take either 0 + (release) or 1 (debug) as values. 0 is the default. + +- ``DECRYPTION_SUPPORT``: This build flag enables the user to select the + authenticated decryption algorithm to be used to decrypt firmware/s during + boot. It accepts 2 values: ``aes_gcm`` and ``none``. The default value of + this flag is ``none`` to disable firmware decryption which is an optional + feature as per TBBR. + +- ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation + of the binary image. If set to 1, then only the ELF image is built. + 0 is the default. + +- ``DISABLE_MTPMU``: Boolean option to disable FEAT_MTPMU if implemented + (Armv8.6 onwards). Its default value is 0 to keep consistency with platforms + that do not implement FEAT_MTPMU. For more information on FEAT_MTPMU, + check the latest Arm ARM. + +- ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted + Board Boot authentication at runtime. This option is meant to be enabled only + for development platforms. ``TRUSTED_BOARD_BOOT`` flag must be set if this + flag has to be enabled. 0 is the default. + +- ``E``: Boolean option to make warnings into errors. Default is 1. + +- ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of + the normal boot flow. It must specify the entry point address of the EL3 + payload. Please refer to the "Booting an EL3 payload" section for more + details. + +- ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions. + This is an optional architectural feature available on v8.4 onwards. Some + v8.2 implementations also implement an AMU and this option can be used to + enable this feature on those systems as well. Default is 0. + +- ``ENABLE_AMU_AUXILIARY_COUNTERS``: Enables support for AMU auxiliary counters + (also known as group 1 counters). These are implementation-defined counters, + and as such require additional platform configuration. Default is 0. + +- ``ENABLE_AMU_FCONF``: Enables configuration of the AMU through FCONF, which + allows platforms with auxiliary counters to describe them via the + ``HW_CONFIG`` device tree blob. Default is 0. + +- ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()`` + are compiled out. For debug builds, this option defaults to 1, and calls to + ``assert()`` are left in place. For release builds, this option defaults to 0 + and calls to ``assert()`` function are compiled out. This option can be set + independently of ``DEBUG``. It can also be used to hide any auxiliary code + that is only required for the assertion and does not fit in the assertion + itself. + +- ``ENABLE_BACKTRACE``: This option controls whether to enable backtrace + dumps or not. It is supported in both AArch64 and AArch32. However, in + AArch32 the format of the frame records are not defined in the AAPCS and they + are defined by the implementation. This implementation of backtrace only + supports the format used by GCC when T32 interworking is disabled. For this + reason enabling this option in AArch32 will force the compiler to only + generate A32 code. This option is enabled by default only in AArch64 debug + builds, but this behaviour can be overridden in each platform's Makefile or + in the build command line. + +- ``ENABLE_FEAT_AMUv1``: Numeric value to enable access to the HAFGRTR_EL2 + (Hypervisor Activity Monitors Fine-Grained Read Trap Register) during EL2 + to EL3 context save/restore operations. This flag can take the values 0 to 2, + to align with the ``FEATURE_DETECTION`` mechanism. It is an optional feature + available on v8.4 and onwards and must be set to either 1 or 2 alongside + ``ENABLE_FEAT_FGT``, to access the HAFGRTR_EL2 register. + Default value is ``0``. + +- ``ENABLE_FEAT_AMUv1p1``: Numeric value to enable the ``FEAT_AMUv1p1`` + extension. ``FEAT_AMUv1p1`` is an optional feature available on Arm v8.6 + onwards. This flag can take the values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_CSV2_2``: Numeric value to enable the ``FEAT_CSV2_2`` + extension. It allows access to the SCXTNUM_EL2 (Software Context Number) + register during EL2 context save/restore operations. ``FEAT_CSV2_2`` is an + optional feature available on Arm v8.0 onwards. This flag can take values + 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. + Default value is ``0``. + +- ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent + Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3. + ``FEAT_DIT`` is a mandatory architectural feature and is enabled from v8.4 + and upwards. This flag can take the values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_ECV``: Numeric value to enable support for the Enhanced Counter + Virtualization feature, allowing for access to the CNTPOFF_EL2 (Counter-timer + Physical Offset register) during EL2 to EL3 context save/restore operations. + Its a mandatory architectural feature and is enabled from v8.6 and upwards. + This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps) + feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained + Read Trap Register) during EL2 to EL3 context save/restore operations. + Its a mandatory architectural feature and is enabled from v8.6 and upwards. + This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_HCX``: Numeric value to set the bit SCR_EL3.HXEn in EL3 to + allow access to HCRX_EL2 (extended hypervisor control register) from EL2 as + well as adding HCRX_EL2 to the EL2 context save/restore operations. Its a + mandatory architectural feature and is enabled from v8.7 and upwards. This + flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged + Access Never) extension. ``FEAT_PAN`` adds a bit to PSTATE, generating a + permission fault for any privileged data access from EL1/EL2 to virtual + memory address, accessible at EL0, provided (HCR_EL2.E2H=1). It is a + mandatory architectural feature and is enabled from v8.1 and upwards. This + flag can take values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_RNG``: Numeric value to enable the ``FEAT_RNG`` extension. + ``FEAT_RNG`` is an optional feature available on Arm v8.5 onwards. This + flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_RNG_TRAP``: Numeric value to enable the ``FEAT_RNG_TRAP`` + extension. This feature is only supported in AArch64 state. This flag can + take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. + Default value is ``0``. ``FEAT_RNG_TRAP`` is an optional feature from + Armv8.5 onwards. + +- ``ENABLE_FEAT_SB``: Numeric value to enable the ``FEAT_SB`` (Speculation + Barrier) extension allowing access to ``sb`` instruction. ``FEAT_SB`` is an + optional feature and defaults to ``0`` for pre-Armv8.5 CPUs but are mandatory + for Armv8.5 or later CPUs. This flag can take values 0 to 2, to align with + ``FEATURE_DETECTION`` mechanism. It is enabled from v8.5 and upwards and if + needed could be overidden from platforms explicitly. Default value is ``0``. + +- ``ENABLE_FEAT_SEL2``: Numeric value to enable the ``FEAT_SEL2`` (Secure EL2) + extension. ``FEAT_SEL2`` is a mandatory feature available on Arm v8.4. + This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default is ``0``. + +- ``ENABLE_FEAT_TWED``: Numeric value to enable the ``FEAT_TWED`` (Delayed + trapping of WFE Instruction) extension. ``FEAT_TWED`` is a optional feature + available on Arm v8.6. This flag can take values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. Default is ``0``. + + When ``ENABLE_FEAT_TWED`` is set to ``1``, WFE instruction trapping gets + delayed by the amount of value in ``TWED_DELAY``. + +- ``ENABLE_FEAT_VHE``: Numeric value to enable the ``FEAT_VHE`` (Virtualization + Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register + during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory + architectural feature and is enabled from v8.1 and upwards. It can take + values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. + Default value is ``0``. + +- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO) + support in GCC for TF-A. This option is currently only supported for + AArch64. Default is 0. + +- ``ENABLE_MPAM_FOR_LOWER_ELS``: Numeric value to enable lower ELs to use MPAM + feature. MPAM is an optional Armv8.4 extension that enables various memory + system components and resources to define partitions; software running at + various ELs can assign themselves to desired partition to control their + performance aspects. + + This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. When this option is set to ``1`` or ``2``, EL3 allows lower ELs to + access their own MPAM registers without trapping into EL3. This option + doesn't make use of partitioning in EL3, however. Platform initialisation + code should configure and use partitions in EL3 as required. This option + defaults to ``0``. + +- ``ENABLE_MPMM``: Boolean option to enable support for the Maximum Power + Mitigation Mechanism supported by certain Arm cores, which allows the SoC + firmware to detect and limit high activity events to assist in SoC processor + power domain dynamic power budgeting and limit the triggering of whole-rail + (i.e. clock chopping) responses to overcurrent conditions. Defaults to ``0``. + +- ``ENABLE_MPMM_FCONF``: Enables configuration of MPMM through FCONF, which + allows platforms with cores supporting MPMM to describe them via the + ``HW_CONFIG`` device tree blob. Default is 0. + +- ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE) + support within generic code in TF-A. This option is currently only supported + in BL2_AT_EL3, BL31, and BL32 (TSP) for AARCH64 binaries, and in BL32 + (SP_min) for AARCH32. Default is 0. + +- ``ENABLE_PMF``: Boolean option to enable support for optional Performance + Measurement Framework(PMF). Default is 0. + +- ``ENABLE_PSCI_STAT``: Boolean option to enable support for optional PSCI + functions ``PSCI_STAT_RESIDENCY`` and ``PSCI_STAT_COUNT``. Default is 0. + In the absence of an alternate stat collection backend, ``ENABLE_PMF`` must + be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in + software. + +- ``ENABLE_RME``: Numeric value to enable support for the ARMv9 Realm + Management Extension. This flag can take the values 0 to 2, to align with + the ``FEATURE_DETECTION`` mechanism. Default value is 0. This is currently + an experimental feature. + +- ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime + instrumentation which injects timestamp collection points into TF-A to + allow runtime performance to be measured. Currently, only PSCI is + instrumented. Enabling this option enables the ``ENABLE_PMF`` build option + as well. Default is 0. + +- ``ENABLE_SME_FOR_NS``: Boolean option to enable Scalable Matrix Extension + (SME), SVE, and FPU/SIMD for the non-secure world only. These features share + registers so are enabled together. Using this option without + ENABLE_SME_FOR_SWD=1 will cause SME, SVE, and FPU/SIMD instructions in secure + world to trap to EL3. SME is an optional architectural feature for AArch64 + and TF-A support is experimental. At this time, this build option cannot be + used on systems that have SPD=spmd/SPM_MM or ENABLE_RME, and attempting to + build with these options will fail. Default is 0. + +- ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix + Extension for secure world use along with SVE and FPU/SIMD, ENABLE_SME_FOR_NS + must also be set to use this. If enabling this, the secure world MUST + handle context switching for SME, SVE, and FPU/SIMD registers to ensure that + no data is leaked to non-secure world. This is experimental. Default is 0. + +- ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling + extensions. This is an optional architectural feature for AArch64. + The default is 1 but is automatically disabled when the target architecture + is AArch32. + +- ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension + (SVE) for the Non-secure world only. SVE is an optional architectural feature + for AArch64. Note that when SVE is enabled for the Non-secure world, access + to SIMD and floating-point functionality from the Secure world is disabled by + default and controlled with ENABLE_SVE_FOR_SWD. + This is to avoid corruption of the Non-secure world data in the Z-registers + which are aliased by the SIMD and FP registers. The build option is not + compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an + assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to + 1. The default is 1 but is automatically disabled when ENABLE_SME_FOR_NS=1 + since SME encompasses SVE. At this time, this build option cannot be used on + systems that have SPM_MM enabled. + +- ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world. + SVE is an optional architectural feature for AArch64. Note that this option + requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it + is automatically disabled when the target architecture is AArch32. + +- ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection + checks in GCC. Allowed values are "all", "strong", "default" and "none". The + default value is set to "none". "strong" is the recommended stack protection + level if this feature is desired. "none" disables the stack protection. For + all values other than "none", the ``plat_get_stack_protector_canary()`` + platform hook needs to be implemented. The value is passed as the last + component of the option ``-fstack-protector-$ENABLE_STACK_PROTECTOR``. + +- ``ENCRYPT_BL31``: Binary flag to enable encryption of BL31 firmware. This + flag depends on ``DECRYPTION_SUPPORT`` build flag. + +- ``ENCRYPT_BL32``: Binary flag to enable encryption of Secure BL32 payload. + This flag depends on ``DECRYPTION_SUPPORT`` build flag. + +- ``ENC_KEY``: A 32-byte (256-bit) symmetric key in hex string format. It could + either be SSK or BSSK depending on ``FW_ENC_STATUS`` flag. This value depends + on ``DECRYPTION_SUPPORT`` build flag. + +- ``ENC_NONCE``: A 12-byte (96-bit) encryption nonce or Initialization Vector + (IV) in hex string format. This value depends on ``DECRYPTION_SUPPORT`` + build flag. + +- ``ERROR_DEPRECATED``: This option decides whether to treat the usage of + deprecated platform APIs, helper functions or drivers within Trusted + Firmware as error. It can take the value 1 (flag the use of deprecated + APIs as error) or 0. The default is 0. + +- ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions + targeted at EL3. When set ``0`` (default), no exceptions are expected or + handled at EL3, and a panic will result. The exception to this rule is when + ``SPMD_SPM_AT_SEL2`` is set to ``1``, in which case, only exceptions + occuring during normal world execution, are trapped to EL3. Any exception + trapped during secure world execution are trapped to the SPMC. This is + supported only for AArch64 builds. + +- ``EVENT_LOG_LEVEL``: Chooses the log level to use for Measured Boot when + ``MEASURED_BOOT`` is enabled. For a list of valid values, see ``LOG_LEVEL``. + Default value is 40 (LOG_LEVEL_INFO). + +- ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault + injection from lower ELs, and this build option enables lower ELs to use + Error Records accessed via System Registers to inject faults. This is + applicable only to AArch64 builds. + + This feature is intended for testing purposes only, and is advisable to keep + disabled for production images. + +- ``FEATURE_DETECTION``: Boolean option to enable the architectural features + detection mechanism. It detects whether the Architectural features enabled + through feature specific build flags are supported by the PE or not by + validating them either at boot phase or at runtime based on the value + possessed by the feature flag (0 to 2) and report error messages at an early + stage. + + This prevents and benefits us from EL3 runtime exceptions during context save + and restore routines guarded by these build flags. Henceforth validating them + before their usage provides more control on the actions taken under them. + + The mechanism permits the build flags to take values 0, 1 or 2 and + evaluates them accordingly. + + Lets consider ``ENABLE_FEAT_HCX``, build flag for ``FEAT_HCX`` as an example: + + :: + + ENABLE_FEAT_HCX = 0: Feature disabled statically at compile time. + ENABLE_FEAT_HCX = 1: Feature Enabled and the flag is validated at boottime. + ENABLE_FEAT_HCX = 2: Feature Enabled and the flag is validated at runtime. + + In the above example, if the feature build flag, ``ENABLE_FEAT_HCX`` set to + 0, feature is disabled statically during compilation. If it is defined as 1, + feature is validated, wherein FEAT_HCX is detected at boot time. In case not + implemented by the PE, a hard panic is generated. Finally, if the flag is set + to 2, feature is validated at runtime. + + Note that the entire implementation is divided into two phases, wherein as + as part of phase-1 we are supporting the values 0,1. Value 2 is currently not + supported and is planned to be handled explicilty in phase-2 implementation. + + FEATURE_DETECTION macro is disabled by default, and is currently an + experimental procedure. Platforms can explicitly make use of this by + mechanism, by enabling it to validate whether they have set their build flags + properly at an early phase. + +- ``FIP_NAME``: This is an optional build option which specifies the FIP + filename for the ``fip`` target. Default is ``fip.bin``. + +- ``FWU_FIP_NAME``: This is an optional build option which specifies the FWU + FIP filename for the ``fwu_fip`` target. Default is ``fwu_fip.bin``. + +- ``FW_ENC_STATUS``: Top level firmware's encryption numeric flag, values: + + :: + + 0: Encryption is done with Secret Symmetric Key (SSK) which is common + for a class of devices. + 1: Encryption is done with Binding Secret Symmetric Key (BSSK) which is + unique per device. + + This flag depends on ``DECRYPTION_SUPPORT`` build flag. + +- ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create`` + tool to create certificates as per the Chain of Trust described in + :ref:`Trusted Board Boot`. The build system then calls ``fiptool`` to + include the certificates in the FIP and FWU_FIP. Default value is '0'. + + Specify both ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=1`` to include support + for the Trusted Board Boot feature in the BL1 and BL2 images, to generate + the corresponding certificates, and to include those certificates in the + FIP and FWU_FIP. + + Note that if ``TRUSTED_BOARD_BOOT=0`` and ``GENERATE_COT=1``, the BL1 and BL2 + images will not include support for Trusted Board Boot. The FIP will still + include the corresponding certificates. This FIP can be used to verify the + Chain of Trust on the host machine through other mechanisms. + + Note that if ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=0``, the BL1 and BL2 + images will include support for Trusted Board Boot, but the FIP and FWU_FIP + will not include the corresponding certificates, causing a boot failure. + +- ``GICV2_G0_FOR_EL3``: Unlike GICv3, the GICv2 architecture doesn't have + inherent support for specific EL3 type interrupts. Setting this build option + to ``1`` assumes GICv2 *Group 0* interrupts are expected to target EL3, both + by :ref:`platform abstraction layer<platform Interrupt Controller API>` and + :ref:`Interrupt Management Framework<Interrupt Management Framework>`. + This allows GICv2 platforms to enable features requiring EL3 interrupt type. + This also means that all GICv2 Group 0 interrupts are delivered to EL3, and + the Secure Payload interrupts needs to be synchronously handed over to Secure + EL1 for handling. The default value of this option is ``0``, which means the + Group 0 interrupts are assumed to be handled by Secure EL1. + +- ``HANDLE_EA_EL3_FIRST_NS``: When set to ``1``, External Aborts and SError + Interrupts, resulting from errors in NS world, will be always trapped in + EL3 i.e. in BL31 at runtime. When set to ``0`` (default), these exceptions + will be trapped in the current exception level (or in EL1 if the current + exception level is EL0). + +- ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific + software operations are required for CPUs to enter and exit coherency. + However, newer systems exist where CPUs' entry to and exit from coherency + is managed in hardware. Such systems require software to only initiate these + operations, and the rest is managed in hardware, minimizing active software + management. In such systems, this boolean option enables TF-A to carry out + build and run-time optimizations during boot and power management operations. + This option defaults to 0 and if it is enabled, then it implies + ``WARMBOOT_ENABLE_DCACHE_EARLY`` is also enabled. + + If this flag is disabled while the platform which TF-A is compiled for + includes cores that manage coherency in hardware, then a compilation error is + generated. This is based on the fact that a system cannot have, at the same + time, cores that manage coherency in hardware and cores that don't. In other + words, a platform cannot have, at the same time, cores that require + ``HW_ASSISTED_COHERENCY=1`` and cores that require + ``HW_ASSISTED_COHERENCY=0``. + + Note that, when ``HW_ASSISTED_COHERENCY`` is enabled, version 2 of + translation library (xlat tables v2) must be used; version 1 of translation + library is not supported. + +- ``INVERTED_MEMMAP``: memmap tool print by default lower addresses at the + bottom, higher addresses at the top. This build flag can be set to '1' to + invert this behavior. Lower addresses will be printed at the top and higher + addresses at the bottom. + +- ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3 + runtime software in AArch32 mode, which is required to run AArch32 on Juno. + By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in + AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable + images. + +- ``KEY_ALG``: This build flag enables the user to select the algorithm to be + used for generating the PKCS keys and subsequent signing of the certificate. + It accepts 5 values: ``rsa``, ``rsa_1_5``, ``ecdsa``, ``ecdsa-brainpool-regular`` + and ``ecdsa-brainpool-twisted``. The option ``rsa_1_5`` is the legacy PKCS#1 + RSA 1.5 algorithm which is not TBBR compliant and is retained only for + compatibility. The default value of this flag is ``rsa`` which is the TBBR + compliant PKCS#1 RSA 2.1 scheme. + +- ``KEY_SIZE``: This build flag enables the user to select the key size for + the algorithm specified by ``KEY_ALG``. The valid values for ``KEY_SIZE`` + depend on the chosen algorithm and the cryptographic module. + + +---------------------------+------------------------------------+ + | KEY_ALG | Possible key sizes | + +===========================+====================================+ + | rsa | 1024 , 2048 (default), 3072, 4096* | + +---------------------------+------------------------------------+ + | ecdsa | unavailable | + +---------------------------+------------------------------------+ + | ecdsa-brainpool-regular | unavailable | + +---------------------------+------------------------------------+ + | ecdsa-brainpool-twisted | unavailable | + +---------------------------+------------------------------------+ + + + * Only 2048 bits size is available with CryptoCell 712 SBROM release 1. + Only 3072 bits size is available with CryptoCell 712 SBROM release 2. + +- ``HASH_ALG``: This build flag enables the user to select the secure hash + algorithm. It accepts 3 values: ``sha256``, ``sha384`` and ``sha512``. + The default value of this flag is ``sha256``. + +- ``LDFLAGS``: Extra user options appended to the linkers' command line in + addition to the one set by the build system. + +- ``LOG_LEVEL``: Chooses the log level, which controls the amount of console log + output compiled into the build. This should be one of the following: + + :: + + 0 (LOG_LEVEL_NONE) + 10 (LOG_LEVEL_ERROR) + 20 (LOG_LEVEL_NOTICE) + 30 (LOG_LEVEL_WARNING) + 40 (LOG_LEVEL_INFO) + 50 (LOG_LEVEL_VERBOSE) + + All log output up to and including the selected log level is compiled into + the build. The default value is 40 in debug builds and 20 in release builds. + +- ``MEASURED_BOOT``: Boolean flag to include support for the Measured Boot + feature. This flag can be enabled with ``TRUSTED_BOARD_BOOT`` in order to + provide trust that the code taking the measurements and recording them has + not been tampered with. + + This option defaults to 0. + +- ``DRTM_SUPPORT``: Boolean flag to enable support for Dynamic Root of Trust + for Measurement (DRTM). This feature has trust dependency on BL31 for taking + the measurements and recording them as per `PSA DRTM specification`_. For + platforms which use BL2 to load/authenticate BL31 ``TRUSTED_BOARD_BOOT`` can + be used and for the platforms which use ``RESET_TO_BL31`` platform owners + should have mechanism to authenticate BL31. + + This option defaults to 0. + +- ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It + specifies the file that contains the Non-Trusted World private key in PEM + format. If ``SAVE_KEYS=1``, this file name will be used to save the key. + +- ``NS_BL2U``: Path to NS_BL2U image in the host file system. This image is + optional. It is only needed if the platform makefile specifies that it + is required in order to build the ``fwu_fip`` target. + +- ``NS_TIMER_SWITCH``: Enable save and restore for non-secure timer register + contents upon world switch. It can take either 0 (don't save and restore) or + 1 (do save and restore). 0 is the default. An SPD may set this to 1 if it + wants the timer registers to be saved and restored. + +- ``OVERRIDE_LIBC``: This option allows platforms to override the default libc + for the BL image. It can be either 0 (include) or 1 (remove). The default + value is 0. + +- ``PL011_GENERIC_UART``: Boolean option to indicate the PL011 driver that + the underlying hardware is not a full PL011 UART but a minimally compliant + generic UART, which is a subset of the PL011. The driver will not access + any register that is not part of the SBSA generic UART specification. + Default value is 0 (a full PL011 compliant UART is present). + +- ``PLAT``: Choose a platform to build TF-A for. The chosen platform name + must be subdirectory of any depth under ``plat/``, and must contain a + platform makefile named ``platform.mk``. For example, to build TF-A for the + Arm Juno board, select PLAT=juno. + +- ``PRELOADED_BL33_BASE``: This option enables booting a preloaded BL33 image + instead of the normal boot flow. When defined, it must specify the entry + point address for the preloaded BL33 image. This option is incompatible with + ``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority + over ``PRELOADED_BL33_BASE``. + +- ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset + vector address can be programmed or is fixed on the platform. It can take + either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a + programmable reset address, it is expected that a CPU will start executing + code directly at the right address, both on a cold and warm reset. In this + case, there is no need to identify the entrypoint on boot and the boot path + can be optimised. The ``plat_get_my_entrypoint()`` platform porting interface + does not need to be implemented in this case. + +- ``PSCI_EXTENDED_STATE_ID``: As per PSCI1.0 Specification, there are 2 formats + possible for the PSCI power-state parameter: original and extended State-ID + formats. This flag if set to 1, configures the generic PSCI layer to use the + extended format. The default value of this flag is 0, which means by default + the original power-state format is used by the PSCI implementation. This flag + should be specified by the platform makefile and it governs the return value + of PSCI_FEATURES API for CPU_SUSPEND smc function id. When this option is + enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be + set to 1 as well. + +- ``RAS_EXTENSION``: Numeric value to enable Armv8.2 RAS features. RAS features + are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2 + or later CPUs. This flag can take the values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. + + When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST_NS`` must also be + set to ``1``. + + This option is disabled by default. + +- ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead + of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1 + entrypoint) or 1 (CPU reset to BL31 entrypoint). + The default value is 0. + +- ``RESET_TO_BL31_WITH_PARAMS``: If ``RESET_TO_BL31`` has been enabled, setting + this additional option guarantees that the input registers are not cleared + therefore allowing parameters to be passed to the BL31 entrypoint. + The default value is 0. + +- ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided + in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector + instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1 + entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0. + +- ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the + file that contains the ROT private key in PEM format and enforces public key + hash generation. If ``SAVE_KEYS=1``, this + file name will be used to save the key. + +- ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the + certificate generation tool to save the keys used to establish the Chain of + Trust. Allowed options are '0' or '1'. Default is '0' (do not save). + +- ``SCP_BL2``: Path to SCP_BL2 image in the host file system. This image is optional. + If a SCP_BL2 image is present then this option must be passed for the ``fip`` + target. + +- ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the + file that contains the SCP_BL2 private key in PEM format. If ``SAVE_KEYS=1``, + this file name will be used to save the key. + +- ``SCP_BL2U``: Path to SCP_BL2U image in the host file system. This image is + optional. It is only needed if the platform makefile specifies that it + is required in order to build the ``fwu_fip`` target. + +- ``SDEI_SUPPORT``: Setting this to ``1`` enables support for Software + Delegated Exception Interface to BL31 image. This defaults to ``0``. + + When set to ``1``, the build option ``EL3_EXCEPTION_HANDLING`` must also be + set to ``1``. + +- ``SEPARATE_CODE_AND_RODATA``: Whether code and read-only data should be + isolated on separate memory pages. This is a trade-off between security and + memory usage. See "Isolating code and read-only data on separate memory + pages" section in :ref:`Firmware Design`. This flag is disabled by default + and affects all BL images. + +- ``SEPARATE_NOBITS_REGION``: Setting this option to ``1`` allows the NOBITS + sections of BL31 (.bss, stacks, page tables, and coherent memory) to be + allocated in RAM discontiguous from the loaded firmware image. When set, the + platform is expected to provide definitions for ``BL31_NOBITS_BASE`` and + ``BL31_NOBITS_LIMIT``. When the option is ``0`` (the default), NOBITS + sections are placed in RAM immediately following the loaded firmware image. + +- ``SEPARATE_BL2_NOLOAD_REGION``: Setting this option to ``1`` allows the + NOLOAD sections of BL2 (.bss, stacks, page tables) to be allocated in RAM + discontiguous from loaded firmware images. When set, the platform need to + provide definitions of ``BL2_NOLOAD_START`` and ``BL2_NOLOAD_LIMIT``. This + flag is disabled by default and NOLOAD sections are placed in RAM immediately + following the loaded firmware image. + +- ``SMC_PCI_SUPPORT``: This option allows platforms to handle PCI configuration + access requests via a standard SMCCC defined in `DEN0115`_. When combined with + UEFI+ACPI this can provide a certain amount of OS forward compatibility + with newer platforms that aren't ECAM compliant. + +- ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A. + This build option is only valid if ``ARCH=aarch64``. The value should be + the path to the directory containing the SPD source, relative to + ``services/spd/``; the directory is expected to contain a makefile called + ``<spd-value>.mk``. The SPM Dispatcher standard service is located in + services/std_svc/spmd and enabled by ``SPD=spmd``. The SPM Dispatcher + cannot be enabled when the ``SPM_MM`` option is enabled. + +- ``SPIN_ON_BL1_EXIT``: This option introduces an infinite loop in BL1. It can + take either 0 (no loop) or 1 (add a loop). 0 is the default. This loop stops + execution in BL1 just before handing over to BL31. At this point, all + firmware images have been loaded in memory, and the MMU and caches are + turned off. Refer to the "Debugging options" section for more details. + +- ``SPMC_AT_EL3`` : This boolean option is used jointly with the SPM + Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC + component runs at the EL3 exception level. The default value is ``0`` ( + disabled). This configuration supports pre-Armv8.4 platforms (aka not + implementing the ``FEAT_SEL2`` extension). This is an experimental feature. + +- ``SPMD_SPM_AT_SEL2`` : This boolean option is used jointly with the SPM + Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC + component runs at the S-EL2 exception level provided by the ``FEAT_SEL2`` + extension. This is the default when enabling the SPM Dispatcher. When + disabled (0) it indicates the SPMC component runs at the S-EL1 execution + state or at EL3 if ``SPMC_AT_EL3`` is enabled. The latter configurations + support pre-Armv8.4 platforms (aka not implementing the ``FEAT_SEL2`` + extension). + +- ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure + Partition Manager (SPM) implementation. The default value is ``0`` + (disabled). This option cannot be enabled (``1``) when SPM Dispatcher is + enabled (``SPD=spmd``). + +- ``SP_LAYOUT_FILE``: Platform provided path to JSON file containing the + description of secure partitions. The build system will parse this file and + package all secure partition blobs into the FIP. This file is not + necessarily part of TF-A tree. Only available when ``SPD=spmd``. + +- ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles + secure interrupts (caught through the FIQ line). Platforms can enable + this directive if they need to handle such interruption. When enabled, + the FIQ are handled in monitor mode and non secure world is not allowed + to mask these events. Platforms that enable FIQ handling in SP_MIN shall + implement the api ``sp_min_plat_fiq_handler()``. The default value is 0. + +- ``SVE_VECTOR_LEN``: SVE vector length to configure in ZCR_EL3. + Platforms can configure this if they need to lower the hardware + limit, for example due to asymmetric configuration or limitations of + software run at lower ELs. The default is the architectural maximum + of 2048 which should be suitable for most configurations, the + hardware will limit the effective VL to the maximum physically supported + VL. + +- ``TRNG_SUPPORT``: Setting this to ``1`` enables support for True + Random Number Generator Interface to BL31 image. This defaults to ``0``. + +- ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board + Boot feature. When set to '1', BL1 and BL2 images include support to load + and verify the certificates and images in a FIP, and BL1 includes support + for the Firmware Update. The default value is '0'. Generation and inclusion + of certificates in the FIP and FWU_FIP depends upon the value of the + ``GENERATE_COT`` option. + + .. warning:: + This option depends on ``CREATE_KEYS`` to be enabled. If the keys + already exist in disk, they will be overwritten without further notice. + +- ``TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It + specifies the file that contains the Trusted World private key in PEM + format. If ``SAVE_KEYS=1``, this file name will be used to save the key. + +- ``TSP_INIT_ASYNC``: Choose BL32 initialization method as asynchronous or + synchronous, (see "Initializing a BL32 Image" section in + :ref:`Firmware Design`). It can take the value 0 (BL32 is initialized using + synchronous method) or 1 (BL32 is initialized using asynchronous method). + Default is 0. + +- ``TSP_NS_INTR_ASYNC_PREEMPT``: A non zero value enables the interrupt + routing model which routes non-secure interrupts asynchronously from TSP + to EL3 causing immediate preemption of TSP. The EL3 is responsible + for saving and restoring the TSP context in this routing model. The + default routing model (when the value is 0) is to route non-secure + interrupts to TSP allowing it to save its context and hand over + synchronously to EL3 via an SMC. + + .. note:: + When ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT`` + must also be set to ``1``. + +- ``TWED_DELAY``: Numeric value to be set in order to delay the trapping of + WFE instruction. ``ENABLE_FEAT_TWED`` build option must be enabled to set + this delay. It can take values in the range (0-15). Default value is ``0`` + and based on this value, 2^(TWED_DELAY + 8) cycles will be delayed. + Platforms need to explicitly update this value based on their requirements. + +- ``USE_ARM_LINK``: This flag determines whether to enable support for ARM + linker. When the ``LINKER`` build variable points to the armlink linker, + this flag is enabled automatically. To enable support for armlink, platforms + will have to provide a scatter file for the BL image. Currently, Tegra + platforms use the armlink support to compile BL3-1 images. + +- ``USE_COHERENT_MEM``: This flag determines whether to include the coherent + memory region in the BL memory map or not (see "Use of Coherent memory in + TF-A" section in :ref:`Firmware Design`). It can take the value 1 + (Coherent memory region is included) or 0 (Coherent memory region is + excluded). Default is 1. + +- ``USE_DEBUGFS``: When set to 1 this option activates an EXPERIMENTAL feature + exposing a virtual filesystem interface through BL31 as a SiP SMC function. + Default is 0. + +- ``ARM_IO_IN_DTB``: This flag determines whether to use IO based on the + firmware configuration framework. This will move the io_policies into a + configuration device tree, instead of static structure in the code base. + +- ``COT_DESC_IN_DTB``: This flag determines whether to create COT descriptors + at runtime using fconf. If this flag is enabled, COT descriptors are + statically captured in tb_fw_config file in the form of device tree nodes + and properties. Currently, COT descriptors used by BL2 are moved to the + device tree and COT descriptors used by BL1 are retained in the code + base statically. + +- ``SDEI_IN_FCONF``: This flag determines whether to configure SDEI setup in + runtime using firmware configuration framework. The platform specific SDEI + shared and private events configuration is retrieved from device tree rather + than static C structures at compile time. This is only supported if + SDEI_SUPPORT build flag is enabled. + +- ``SEC_INT_DESC_IN_FCONF``: This flag determines whether to configure Group 0 + and Group1 secure interrupts using the firmware configuration framework. The + platform specific secure interrupt property descriptor is retrieved from + device tree in runtime rather than depending on static C structure at compile + time. + +- ``USE_ROMLIB``: This flag determines whether library at ROM will be used. + This feature creates a library of functions to be placed in ROM and thus + reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default + is 0. + +- ``V``: Verbose build. If assigned anything other than 0, the build commands + are printed. Default is 0. + +- ``VERSION_STRING``: String used in the log output for each TF-A image. + Defaults to a string formed by concatenating the version number, build type + and build string. + +- ``W``: Warning level. Some compiler warning options of interest have been + regrouped and put in the root Makefile. This flag can take the values 0 to 3, + each level enabling more warning options. Default is 0. + +- ``WARMBOOT_ENABLE_DCACHE_EARLY`` : Boolean option to enable D-cache early on + the CPU after warm boot. This is applicable for platforms which do not + require interconnect programming to enable cache coherency (eg: single + cluster platforms). If this option is enabled, then warm boot path + enables D-caches immediately after enabling MMU. This option defaults to 0. + +- ``SUPPORT_STACK_MEMTAG``: This flag determines whether to enable memory + tagging for stack or not. It accepts 2 values: ``yes`` and ``no``. The + default value of this flag is ``no``. Note this option must be enabled only + for ARM architecture greater than Armv8.5-A. + +- ``ERRATA_SPECULATIVE_AT``: This flag determines whether to enable ``AT`` + speculative errata workaround or not. It accepts 2 values: ``1`` and ``0``. + The default value of this flag is ``0``. + + ``AT`` speculative errata workaround disables stage1 page table walk for + lower ELs (EL1 and EL0) in EL3 so that ``AT`` speculative fetch at any point + produces either the correct result or failure without TLB allocation. + + This boolean option enables errata for all below CPUs. + + +---------+--------------+-------------------------+ + | Errata | CPU | Workaround Define | + +=========+==============+=========================+ + | 1165522 | Cortex-A76 | ``ERRATA_A76_1165522`` | + +---------+--------------+-------------------------+ + | 1319367 | Cortex-A72 | ``ERRATA_A72_1319367`` | + +---------+--------------+-------------------------+ + | 1319537 | Cortex-A57 | ``ERRATA_A57_1319537`` | + +---------+--------------+-------------------------+ + | 1530923 | Cortex-A55 | ``ERRATA_A55_1530923`` | + +---------+--------------+-------------------------+ + | 1530924 | Cortex-A53 | ``ERRATA_A53_1530924`` | + +---------+--------------+-------------------------+ + + .. note:: + This option is enabled by build only if platform sets any of above defines + mentioned in ’Workaround Define' column in the table. + If this option is enabled for the EL3 software then EL2 software also must + implement this workaround due to the behaviour of the errata mentioned + in new SDEN document which will get published soon. + +- ``RAS_TRAP_NS_ERR_REC_ACCESS``: This flag enables/disables the SCR_EL3.TERR + bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs. + This flag is disabled by default. + +- ``OPENSSL_DIR``: This option is used to provide the path to a directory on the + host machine where a custom installation of OpenSSL is located, which is used + to build the certificate generation, firmware encryption and FIP tools. If + this option is not set, the default OS installation will be used. + +- ``USE_SP804_TIMER``: Use the SP804 timer instead of the Generic Timer for + functions that wait for an arbitrary time length (udelay and mdelay). The + default value is 0. + +- ``ENABLE_BRBE_FOR_NS``: Numeric value to enable access to the branch record + buffer registers from NS ELs when FEAT_BRBE is implemented. BRBE is an + optional architectural feature for AArch64. This flag can take the values + 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. The default is 0 + and it is automatically disabled when the target architecture is AArch32. + +- ``ENABLE_TRBE_FOR_NS``: Numeric value to enable access of trace buffer + control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented + but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural + feature for AArch64. This flag can take the values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. The default is 0 and it is automatically + disabled when the target architecture is AArch32. + +- ``ENABLE_SYS_REG_TRACE_FOR_NS``: Boolean option to enable trace system + registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented + but unused). This feature is available if trace unit such as ETMv4.x, and + ETE(extending ETM feature) is implemented. This flag is disabled by default. + +- ``ENABLE_TRF_FOR_NS``: Numeric value to enable trace filter control registers + access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused), + if FEAT_TRF is implemented. This flag can take the values 0 to 2, to align + with the ``FEATURE_DETECTION`` mechanism. This flag is disabled by default. + +- ``PLAT_RSS_NOT_SUPPORTED``: Boolean option to enable the usage of the PSA + APIs on platforms that doesn't support RSS (providing Arm CCA HES + functionalities). When enabled (``1``), a mocked version of the APIs are used. + The default value is 0. + +- ``CONDITIONAL_CMO``: Boolean option to enable call to platform-defined routine + ``plat_can_cmo`` which will return zero if cache management operations should + be skipped and non-zero otherwise. By default, this option is disabled which + means platform hook won't be checked and CMOs will always be performed when + related functions are called. + +GICv3 driver options +-------------------- + +GICv3 driver files are included using directive: + +``include drivers/arm/gic/v3/gicv3.mk`` + +The driver can be configured with the following options set in the platform +makefile: + +- ``GICV3_SUPPORT_GIC600``: Add support for the GIC-600 variants of GICv3. + Enabling this option will add runtime detection support for the + GIC-600, so is safe to select even for a GIC500 implementation. + This option defaults to 0. + +- ``GICV3_SUPPORT_GIC600AE_FMU``: Add support for the Fault Management Unit + for GIC-600 AE. Enabling this option will introduce support to initialize + the FMU. Platforms should call the init function during boot to enable the + FMU and its safety mechanisms. This option defaults to 0. + +- ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip + functionality. This option defaults to 0 + +- ``GICV3_OVERRIDE_DISTIF_PWR_OPS``: Allows override of default implementation + of ``arm_gicv3_distif_pre_save`` and ``arm_gicv3_distif_post_restore`` + functions. This is required for FVP platform which need to simulate GIC save + and restore during SYSTEM_SUSPEND without powering down GIC. Default is 0. + +- ``GIC_ENABLE_V4_EXTN`` : Enables GICv4 related changes in GICv3 driver. + This option defaults to 0. + +- ``GIC_EXT_INTID``: When set to ``1``, GICv3 driver will support extended + PPI (1056-1119) and SPI (4096-5119) range. This option defaults to 0. + +Debugging options +----------------- + +To compile a debug version and make the build more verbose use + +.. code:: shell + + make PLAT=<platform> DEBUG=1 V=1 all + +AArch64 GCC 11 uses DWARF version 5 debugging symbols by default. Some tools +(for example Arm-DS) might not support this and may need an older version of +DWARF symbols to be emitted by GCC. This can be achieved by using the +``-gdwarf-<version>`` flag, with the version being set to 2, 3, 4 or 5. Setting +the version to 4 is recommended for Arm-DS. + +When debugging logic problems it might also be useful to disable all compiler +optimizations by using ``-O0``. + +.. warning:: + Using ``-O0`` could cause output images to be larger and base addresses + might need to be recalculated (see the **Memory layout on Arm development + platforms** section in the :ref:`Firmware Design`). + +Extra debug options can be passed to the build system by setting ``CFLAGS`` or +``LDFLAGS``: + +.. code:: shell + + CFLAGS='-O0 -gdwarf-2' \ + make PLAT=<platform> DEBUG=1 V=1 all + +Note that using ``-Wl,`` style compilation driver options in ``CFLAGS`` will be +ignored as the linker is called directly. + +It is also possible to introduce an infinite loop to help in debugging the +post-BL2 phase of TF-A. This can be done by rebuilding BL1 with the +``SPIN_ON_BL1_EXIT=1`` build flag. Refer to the :ref:`build_options_common` +section. In this case, the developer may take control of the target using a +debugger when indicated by the console output. When using Arm-DS, the following +commands can be used: + +:: + + # Stop target execution + interrupt + + # + # Prepare your debugging environment, e.g. set breakpoints + # + + # Jump over the debug loop + set var $AARCH64::$Core::$PC = $AARCH64::$Core::$PC + 4 + + # Resume execution + continue + +Firmware update options +----------------------- + +- ``NR_OF_FW_BANKS``: Define the number of firmware banks. This flag is used + in defining the firmware update metadata structure. This flag is by default + set to '2'. + +- ``NR_OF_IMAGES_IN_FW_BANK``: Define the number of firmware images in each + firmware bank. Each firmware bank must have the same number of images as per + the `PSA FW update specification`_. + This flag is used in defining the firmware update metadata structure. This + flag is by default set to '1'. + +- ``PSA_FWU_SUPPORT``: Enable the firmware update mechanism as per the + `PSA FW update specification`_. The default value is 0, and this is an + experimental feature. + PSA firmware update implementation has some limitations, such as BL2 is + not part of the protocol-updatable images, if BL2 needs to be updated, then + it should be done through another platform-defined mechanism, and it assumes + that the platform's hardware supports CRC32 instructions. + +-------------- + +*Copyright (c) 2019-2022, Arm Limited. All rights reserved.* + +.. _DEN0115: https://developer.arm.com/docs/den0115/latest +.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/ +.. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst new file mode 100644 index 0000000..4a48059 --- /dev/null +++ b/docs/getting_started/docs-build.rst @@ -0,0 +1,112 @@ +Building Documentation +====================== + +To create a rendered copy of this documentation locally you can use the +`Sphinx`_ tool to build and package the plain-text documents into HTML-formatted +pages. + +If you are building the documentation for the first time then you will need to +check that you have the required software packages, as described in the +*Prerequisites* section that follows. + +.. note:: + An online copy of the documentation is available at + https://www.trustedfirmware.org/docs/tf-a, if you want to view a rendered + copy without doing a local build. + +Prerequisites +------------- + +For building a local copy of the |TF-A| documentation you will need: + +- Python 3 (3.5 or later) +- PlantUML (1.2017.15 or later) +- Python modules specified in ``docs/requirements.txt`` + + You can install these with ``pip3`` (the Python Package Installer) by + passing it the requirements file above (with ``-r``). An optional ``--user`` + argument will install them locally, but you have to add their location to + $PATH (pip will emit a warning). Alternatively, they can be installed + globally (but will probably require root privileges). + + .. note:: + Although not necessary, it is recommended you use a virtual environment. + More advanced usage instructions for *pip* are beyond the scope of this + document but you can refer to the `pip homepage`_ for detailed guides. + +- Optionally, the `Dia`_ application can be installed if you need to edit + existing ``.dia`` diagram files, or create new ones. + +An example set of installation commands for Ubuntu follows, assuming that the +working directory is ``docs``: + +.. code:: shell + + sudo apt install python3 python3-pip plantuml [dia] + pip3 install [--user] -r requirements.txt + +.. note:: + Several other modules will be installed as dependencies. Please review + the list to ensure that there will be no conflicts with other modules already + installed in your environment. + +Building rendered documentation +------------------------------- + +Documents can be built into HTML-formatted pages from project root directory by +running the following command. + +.. code:: shell + + make doc + +Output from the build process will be placed in: + +:: + + docs/build/html + +We also support building documentation in other formats. From the ``docs`` +directory of the project, run the following command to see the supported +formats. It is important to note that you will not get the correct result if +the command is run from the project root directory, as that would invoke the +top-level Makefile for |TF-A| itself. + +.. code:: shell + + make help + +Building rendered documentation from a container +------------------------------------------------ + +There may be cases where you can not either install or upgrade required +dependencies to generate the documents, so in this case, one way to +create the documentation is through a docker container. The first step is +to check if `docker`_ is installed in your host, otherwise check main docker +page for installation instructions. Once installed, run the following script +from project root directory + +.. code:: shell + + docker run --rm -v $PWD:/TF sphinxdoc/sphinx \ + bash -c 'cd /TF && \ + pip3 install plantuml -r ./docs/requirements.txt && make doc' + +The above command fetches the ``sphinxdoc/sphinx`` container from `docker +hub`_, launches the container, installs documentation requirements and finally +creates the documentation. Once done, exit the container and output from the +build process will be placed in: + +:: + + docs/build/html + +-------------- + +*Copyright (c) 2019, Arm Limited. All rights reserved.* + +.. _Sphinx: http://www.sphinx-doc.org/en/master/ +.. _pip homepage: https://pip.pypa.io/en/stable/ +.. _Dia: https://wiki.gnome.org/Apps/Dia +.. _docker: https://www.docker.com/ +.. _docker hub: https://hub.docker.com/repository/docker/sphinxdoc/sphinx diff --git a/docs/getting_started/image-terminology.rst b/docs/getting_started/image-terminology.rst new file mode 100644 index 0000000..66f47e8 --- /dev/null +++ b/docs/getting_started/image-terminology.rst @@ -0,0 +1,192 @@ +Image Terminology +================= + +This page contains the current name, abbreviated name and purpose of the various +images referred to in the Trusted Firmware project. + +Common Image Features +--------------------- + +- Some of the names and abbreviated names have changed to accommodate new + requirements. The changed names are as backward compatible as possible to + minimize confusion. Where applicable, the previous names are indicated. Some + code, documentation and build artefacts may still refer to the previous names; + these will inevitably take time to catch up. + +- The main name change is to prefix each image with the processor it corresponds + to (for example ``AP_``, ``SCP_``, ...). In situations where there is no + ambiguity (for example, within AP specific code/documentation), it is + permitted to omit the processor prefix (for example, just BL1 instead of + ``AP_BL1``). + +- Previously, the format for 3rd level images had 2 forms; ``BL3`` was either + suffixed with a dash ("-") followed by a number (for example, ``BL3-1``) or a + subscript number, depending on whether rich text formatting was available. + This was confusing and often the dash gets omitted in practice. Therefore the + new form is to just omit the dash and not use subscript formatting. + +- The names no longer contain dash ("-") characters at all. In some places (for + example, function names) it's not possible to use this character. All dashes + are either removed or replaced by underscores ("_"). + +- The abbreviation BL stands for BootLoader. This is a historical anomaly. + Clearly, many of these images are not BootLoaders, they are simply firmware + images. However, the BL abbreviation is now widely used and is retained for + backwards compatibility. + +- The image names are not case sensitive. For example, ``bl1`` is + interchangeable with ``BL1``, although mixed case should be avoided. + +Trusted Firmware Images +----------------------- + +Firmware Image Package: ``FIP`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is a packaging format used by TF-A to package firmware images in a single +binary. The number and type of images that should be packed in a FIP is +platform-specific and may include TF-A images and other firmware images +required by the platform. For example, most platforms require a BL33 image +which corresponds to the normal world bootloader (e.g. UEFI or U-Boot). + +AP Boot ROM: ``AP_BL1`` +~~~~~~~~~~~~~~~~~~~~~~~ + +Typically, this is the first code to execute on the AP and cannot be modified. +Its primary purpose is to perform the minimum initialization necessary to load +and authenticate an updateable AP firmware image into an executable RAM +location, then hand-off control to that image. + +AP RAM Firmware: ``AP_BL2`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the 2nd stage AP firmware. It is currently also known as the "Trusted +Boot Firmware". Its primary purpose is to perform any additional initialization +required to load and authenticate all 3rd level firmware images into their +executable RAM locations, then hand-off control to the EL3 Runtime Firmware. + +EL3 Runtime Firmware: ``AP_BL31`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Also known as "SoC AP firmware" or "EL3 monitor firmware". Its primary purpose +is to handle transitions between the normal and secure world. + +Secure-EL1 Payload (SP): ``AP_BL32`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Typically this is a TEE or Trusted OS, providing runtime secure services to the +normal world. However, it may refer to a more abstract Secure-EL1 Payload (SP). +Note that this abbreviation should only be used in systems where there is a +single or primary image executing at Secure-EL1. In systems where there are +potentially multiple SPs and there is no concept of a primary SP, this +abbreviation should be avoided; use the recommended **Other AP 3rd level +images** abbreviation instead. + +AP Normal World Firmware: ``AP_BL33`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For example, UEFI or uboot. Its primary purpose is to boot a normal world OS. + +Other AP 3rd level images: ``AP_BL3_XXX`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The abbreviated names of the existing 3rd level images imply a load/execution +ordering (for example, ``AP_BL31 -> AP_BL32 -> AP_BL33``). Some systems may +have additional images and/or a different load/execution ordering. The +abbreviated names of the existing images are retained for backward compatibility +but new 3rd level images should be suffixed with an underscore followed by text +identifier, not a number. + +In systems where 3rd level images are provided by different vendors, the +abbreviated name should identify the vendor as well as the image +function. For example, ``AP_BL3_ARM_RAS``. + +Realm Monitor Management Firmware: ``RMM`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the Realm-EL2 firmware. It is required if +:ref:`Realm Management Extension (RME)` feature is enabled. If a path to RMM +image is not provided, TF-A builds Test Realm Payload (TRP) image by default +and uses it as the RMM image. + +SCP Boot ROM: ``SCP_BL1`` (previously ``BL0``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Typically, this is the first code to execute on the SCP and cannot be modified. +Its primary purpose is to perform the minimum initialization necessary to load +and authenticate an updateable SCP firmware image into an executable RAM +location, then hand-off control to that image. This may be performed in +conjunction with other processor firmware (for example, ``AP_BL1`` and +``AP_BL2``). + +This image was previously abbreviated as ``BL0`` but in some systems, the SCP +may directly load/authenticate its own firmware. In these systems, it doesn't +make sense to interleave the image terminology for AP and SCP; both AP and SCP +Boot ROMs are ``BL1`` from their own point of view. + +SCP RAM Firmware: ``SCP_BL2`` (previously ``BL3-0``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the 2nd stage SCP firmware. It is currently also known as the "SCP +runtime firmware" but it could potentially be an intermediate firmware if the +SCP needs to load/authenticate multiple 3rd level images in future. + +This image was previously abbreviated as BL3-0 but from the SCP's point of view, +this has always been the 2nd stage firmware. The previous name is too +AP-centric. + +Firmware Update (FWU) Images +---------------------------- + +The terminology for these images has not been widely adopted yet but they have +to be considered in a production Trusted Board Boot solution. + +AP Firmware Update Boot ROM: ``AP_NS_BL1U`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Typically, this is the first normal world code to execute on the AP during a +firmware update operation, and cannot be modified. Its primary purpose is to +load subsequent firmware update images from an external interface and communicate +with ``AP_BL1`` to authenticate those images. + +During firmware update, there are (potentially) multiple transitions between the +secure and normal world. The "level" of the BL image is relative to the world +it's in so it makes sense to encode "NS" in the normal world images. The absence +of "NS" implies a secure world image. + +AP Firmware Update Config: ``AP_BL2U`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This image does the minimum necessary AP secure world configuration required to +complete the firmware update operation. It is potentially a subset of ``AP_BL2`` +functionality. + +SCP Firmware Update Config: ``SCP_BL2U`` (previously ``BL2-U0``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This image does the minimum necessary SCP secure world configuration required to +complete the firmware update operation. It is potentially a subset of +``SCP_BL2`` functionality. + +AP Firmware Updater: ``AP_NS_BL2U`` (previously ``BL3-U``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the 2nd stage AP normal world firmware updater. Its primary purpose is +to load a new set of firmware images from an external interface and write them +into non-volatile storage. + +Other Processor Firmware Images +------------------------------- + +Some systems may have additional processors to the AP and SCP. For example, a +Management Control Processor (MCP). Images for these processors should follow +the same terminology, with the processor abbreviation prefix, followed by +underscore and the level of the firmware image. + +For example, + +MCP Boot ROM: ``MCP_BL1`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +MCP RAM Firmware: ``MCP_BL2`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst new file mode 100644 index 0000000..3fbf48d --- /dev/null +++ b/docs/getting_started/index.rst @@ -0,0 +1,20 @@ +Getting Started +=============== + +.. toctree:: + :maxdepth: 1 + :caption: Contents + + prerequisites + docs-build + initial-build + tools-build + build-options + image-terminology + porting-guide + psci-lib-integration-guide + rt-svc-writers-guide + +-------------- + +*Copyright (c) 2019, Arm Limited. All rights reserved.* diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst new file mode 100644 index 0000000..4f41be4 --- /dev/null +++ b/docs/getting_started/initial-build.rst @@ -0,0 +1,118 @@ +Performing an Initial Build +=========================== + +- Before building TF-A, the environment variable ``CROSS_COMPILE`` must point + to your cross compiler. + + For AArch64: + + .. code:: shell + + export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- + + For AArch32: + + .. code:: shell + + export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-none-eabi- + + It is possible to build TF-A using Clang or Arm Compiler 6. To do so + ``CC`` needs to point to the clang or armclang binary, which will + also select the clang or armclang assembler. Arm Compiler 6 will be selected + when the base name of the path assigned to ``CC`` matches the string + 'armclang'. GNU binutils are required since the TF-A build system doesn't + currently support Arm Scatter files. Meaning the GNU linker is used by + default for Arm Compiler 6. Because of this dependency, ``CROSS_COMPILE`` + should be set as described above. + + For AArch64 using Arm Compiler 6: + + .. code:: shell + + export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- + make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all + + On the other hand, Clang uses LLVM linker (LLD) and other LLVM binutils by + default instead of GNU utilities (LLVM linker (LLD) 14.0.0 is known to + work with TF-A). ``CROSS_COMPILE`` need not be set for Clang. Please note, + that the default linker may be manually overridden using the ``LD`` variable. + + Clang will be selected when the base name of the path assigned to ``CC`` + contains the string 'clang'. This is to allow both clang and clang-X.Y + to work. + + For AArch64 using clang: + + .. code:: shell + + make CC=<path-to-clang>/bin/clang PLAT=<platform> all + +- Change to the root directory of the TF-A source tree and build. + + For AArch64: + + .. code:: shell + + make PLAT=<platform> all + + For AArch32: + + .. code:: shell + + make PLAT=<platform> ARCH=aarch32 AARCH32_SP=sp_min all + + Notes: + + - If ``PLAT`` is not specified, ``fvp`` is assumed by default. See the + :ref:`Build Options` document for more information on available build + options. + + - (AArch32 only) Currently only ``PLAT=fvp`` is supported. + + - (AArch32 only) ``AARCH32_SP`` is the AArch32 EL3 Runtime Software and it + corresponds to the BL32 image. A minimal ``AARCH32_SP``, sp_min, is + provided by TF-A to demonstrate how PSCI Library can be integrated with + an AArch32 EL3 Runtime Software. Some AArch32 EL3 Runtime Software may + include other runtime services, for example Trusted OS services. A guide + to integrate PSCI library with AArch32 EL3 Runtime Software can be found + at :ref:`PSCI Library Integration guide for Armv8-A AArch32 systems`. + + - (AArch64 only) The TSP (Test Secure Payload), corresponding to the BL32 + image, is not compiled in by default. Refer to the + :ref:`Test Secure Payload (TSP) and Dispatcher (TSPD)` document for + details on building the TSP. + + - By default this produces a release version of the build. To produce a + debug version instead, refer to the "Debugging options" section below. + + - The build process creates products in a ``build`` directory tree, building + the objects and binaries for each boot loader stage in separate + sub-directories. The following boot loader binary files are created + from the corresponding ELF files: + + - ``build/<platform>/<build-type>/bl1.bin`` + - ``build/<platform>/<build-type>/bl2.bin`` + - ``build/<platform>/<build-type>/bl31.bin`` (AArch64 only) + - ``build/<platform>/<build-type>/bl32.bin`` (mandatory for AArch32) + + where ``<platform>`` is the name of the chosen platform and ``<build-type>`` + is either ``debug`` or ``release``. The actual number of images might differ + depending on the platform. + +- Build products for a specific build variant can be removed using: + + .. code:: shell + + make DEBUG=<D> PLAT=<platform> clean + + ... where ``<D>`` is ``0`` or ``1``, as specified when building. + + The build tree can be removed completely using: + + .. code:: shell + + make realclean + +-------------- + +*Copyright (c) 2020-2022, Arm Limited. All rights reserved.* diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst new file mode 100644 index 0000000..aa57e1d --- /dev/null +++ b/docs/getting_started/porting-guide.rst @@ -0,0 +1,3515 @@ +Porting Guide +============= + +Introduction +------------ + +Porting Trusted Firmware-A (TF-A) to a new platform involves making some +mandatory and optional modifications for both the cold and warm boot paths. +Modifications consist of: + +- Implementing a platform-specific function or variable, +- Setting up the execution context in a certain way, or +- Defining certain constants (for example #defines). + +The platform-specific functions and variables are declared in +``include/plat/common/platform.h``. The firmware provides a default +implementation of variables and functions to fulfill the optional requirements. +These implementations are all weakly defined; they are provided to ease the +porting effort. Each platform port can override them with its own implementation +if the default implementation is inadequate. + +Some modifications are common to all Boot Loader (BL) stages. Section 2 +discusses these in detail. The subsequent sections discuss the remaining +modifications for each BL stage in detail. + +Please refer to the :ref:`Platform Ports Policy` for the policy regarding +compatibility and deprecation of these porting interfaces. + +Only Arm development platforms (such as FVP and Juno) may use the +functions/definitions in ``include/plat/arm/common/`` and the corresponding +source files in ``plat/arm/common/``. This is done so that there are no +dependencies between platforms maintained by different people/companies. If you +want to use any of the functionality present in ``plat/arm`` files, please +create a pull request that moves the code to ``plat/common`` so that it can be +discussed. + +Common modifications +-------------------- + +This section covers the modifications that should be made by the platform for +each BL stage to correctly port the firmware stack. They are categorized as +either mandatory or optional. + +Common mandatory modifications +------------------------------ + +A platform port must enable the Memory Management Unit (MMU) as well as the +instruction and data caches for each BL stage. Setting up the translation +tables is the responsibility of the platform port because memory maps differ +across platforms. A memory translation library (see ``lib/xlat_tables/``) is +provided to help in this setup. + +Note that although this library supports non-identity mappings, this is intended +only for re-mapping peripheral physical addresses and allows platforms with high +I/O addresses to reduce their virtual address space. All other addresses +corresponding to code and data must currently use an identity mapping. + +Also, the only translation granule size supported in TF-A is 4KB, as various +parts of the code assume that is the case. It is not possible to switch to +16 KB or 64 KB granule sizes at the moment. + +In Arm standard platforms, each BL stage configures the MMU in the +platform-specific architecture setup function, ``blX_plat_arch_setup()``, and uses +an identity mapping for all addresses. + +If the build option ``USE_COHERENT_MEM`` is enabled, each platform can allocate a +block of identity mapped secure memory with Device-nGnRE attributes aligned to +page boundary (4K) for each BL stage. All sections which allocate coherent +memory are grouped under ``coherent_ram``. For ex: Bakery locks are placed in a +section identified by name ``bakery_lock`` inside ``coherent_ram`` so that its +possible for the firmware to place variables in it using the following C code +directive: + +:: + + __section("bakery_lock") + +Or alternatively the following assembler code directive: + +:: + + .section bakery_lock + +The ``coherent_ram`` section is a sum of all sections like ``bakery_lock`` which are +used to allocate any data structures that are accessed both when a CPU is +executing with its MMU and caches enabled, and when it's running with its MMU +and caches disabled. Examples are given below. + +The following variables, functions and constants must be defined by the platform +for the firmware to work correctly. + +.. _platform_def_mandatory: + +File : platform_def.h [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each platform must ensure that a header file of this name is in the system +include path with the following constants defined. This will require updating +the list of ``PLAT_INCLUDES`` in the ``platform.mk`` file. + +Platform ports may optionally use the file ``include/plat/common/common_def.h``, +which provides typical values for some of the constants below. These values are +likely to be suitable for all platform ports. + +- **#define : PLATFORM_LINKER_FORMAT** + + Defines the linker format used by the platform, for example + ``elf64-littleaarch64``. + +- **#define : PLATFORM_LINKER_ARCH** + + Defines the processor architecture for the linker by the platform, for + example ``aarch64``. + +- **#define : PLATFORM_STACK_SIZE** + + Defines the normal stack memory available to each CPU. This constant is used + by ``plat/common/aarch64/platform_mp_stack.S`` and + ``plat/common/aarch64/platform_up_stack.S``. + +- **#define : CACHE_WRITEBACK_GRANULE** + + Defines the size in bytes of the largest cache line across all the cache + levels in the platform. + +- **#define : FIRMWARE_WELCOME_STR** + + Defines the character string printed by BL1 upon entry into the ``bl1_main()`` + function. + +- **#define : PLATFORM_CORE_COUNT** + + Defines the total number of CPUs implemented by the platform across all + clusters in the system. + +- **#define : PLAT_NUM_PWR_DOMAINS** + + Defines the total number of nodes in the power domain topology + tree at all the power domain levels used by the platform. + This macro is used by the PSCI implementation to allocate + data structures to represent power domain topology. + +- **#define : PLAT_MAX_PWR_LVL** + + Defines the maximum power domain level that the power management operations + should apply to. More often, but not always, the power domain level + corresponds to affinity level. This macro allows the PSCI implementation + to know the highest power domain level that it should consider for power + management operations in the system that the platform implements. For + example, the Base AEM FVP implements two clusters with a configurable + number of CPUs and it reports the maximum power domain level as 1. + +- **#define : PLAT_MAX_OFF_STATE** + + Defines the local power state corresponding to the deepest power down + possible at every power domain level in the platform. The local power + states for each level may be sparsely allocated between 0 and this value + with 0 being reserved for the RUN state. The PSCI implementation uses this + value to initialize the local power states of the power domain nodes and + to specify the requested power state for a PSCI_CPU_OFF call. + +- **#define : PLAT_MAX_RET_STATE** + + Defines the local power state corresponding to the deepest retention state + possible at every power domain level in the platform. This macro should be + a value less than PLAT_MAX_OFF_STATE and greater than 0. It is used by the + PSCI implementation to distinguish between retention and power down local + power states within PSCI_CPU_SUSPEND call. + +- **#define : PLAT_MAX_PWR_LVL_STATES** + + Defines the maximum number of local power states per power domain level + that the platform supports. The default value of this macro is 2 since + most platforms just support a maximum of two local power states at each + power domain level (power-down and retention). If the platform needs to + account for more local power states, then it must redefine this macro. + + Currently, this macro is used by the Generic PSCI implementation to size + the array used for PSCI_STAT_COUNT/RESIDENCY accounting. + +- **#define : BL1_RO_BASE** + + Defines the base address in secure ROM where BL1 originally lives. Must be + aligned on a page-size boundary. + +- **#define : BL1_RO_LIMIT** + + Defines the maximum address in secure ROM that BL1's actual content (i.e. + excluding any data section allocated at runtime) can occupy. + +- **#define : BL1_RW_BASE** + + Defines the base address in secure RAM where BL1's read-write data will live + at runtime. Must be aligned on a page-size boundary. + +- **#define : BL1_RW_LIMIT** + + Defines the maximum address in secure RAM that BL1's read-write data can + occupy at runtime. + +- **#define : BL2_BASE** + + Defines the base address in secure RAM where BL1 loads the BL2 binary image. + Must be aligned on a page-size boundary. This constant is not applicable + when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2_LIMIT** + + Defines the maximum address in secure RAM that the BL2 image can occupy. + This constant is not applicable when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2_RO_BASE** + + Defines the base address in secure XIP memory where BL2 RO section originally + lives. Must be aligned on a page-size boundary. This constant is only needed + when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2_RO_LIMIT** + + Defines the maximum address in secure XIP memory that BL2's actual content + (i.e. excluding any data section allocated at runtime) can occupy. This + constant is only needed when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2_RW_BASE** + + Defines the base address in secure RAM where BL2's read-write data will live + at runtime. Must be aligned on a page-size boundary. This constant is only + needed when BL2_IN_XIP_MEM is set to '1'. + +- **#define : BL2_RW_LIMIT** + + Defines the maximum address in secure RAM that BL2's read-write data can + occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set + to '1'. + +- **#define : BL31_BASE** + + Defines the base address in secure RAM where BL2 loads the BL31 binary + image. Must be aligned on a page-size boundary. + +- **#define : BL31_LIMIT** + + Defines the maximum address in secure RAM that the BL31 image can occupy. + +- **#define : PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE** + + Defines the maximum message size between AP and RSS. Need to define if + platform supports RSS. + +For every image, the platform must define individual identifiers that will be +used by BL1 or BL2 to load the corresponding image into memory from non-volatile +storage. For the sake of performance, integer numbers will be used as +identifiers. The platform will use those identifiers to return the relevant +information about the image to be loaded (file handler, load address, +authentication information, etc.). The following image identifiers are +mandatory: + +- **#define : BL2_IMAGE_ID** + + BL2 image identifier, used by BL1 to load BL2. + +- **#define : BL31_IMAGE_ID** + + BL31 image identifier, used by BL2 to load BL31. + +- **#define : BL33_IMAGE_ID** + + BL33 image identifier, used by BL2 to load BL33. + +If Trusted Board Boot is enabled, the following certificate identifiers must +also be defined: + +- **#define : TRUSTED_BOOT_FW_CERT_ID** + + BL2 content certificate identifier, used by BL1 to load the BL2 content + certificate. + +- **#define : TRUSTED_KEY_CERT_ID** + + Trusted key certificate identifier, used by BL2 to load the trusted key + certificate. + +- **#define : SOC_FW_KEY_CERT_ID** + + BL31 key certificate identifier, used by BL2 to load the BL31 key + certificate. + +- **#define : SOC_FW_CONTENT_CERT_ID** + + BL31 content certificate identifier, used by BL2 to load the BL31 content + certificate. + +- **#define : NON_TRUSTED_FW_KEY_CERT_ID** + + BL33 key certificate identifier, used by BL2 to load the BL33 key + certificate. + +- **#define : NON_TRUSTED_FW_CONTENT_CERT_ID** + + BL33 content certificate identifier, used by BL2 to load the BL33 content + certificate. + +- **#define : FWU_CERT_ID** + + Firmware Update (FWU) certificate identifier, used by NS_BL1U to load the + FWU content certificate. + +- **#define : PLAT_CRYPTOCELL_BASE** + + This defines the base address of Arm® TrustZone® CryptoCell and must be + defined if CryptoCell crypto driver is used for Trusted Board Boot. For + capable Arm platforms, this driver is used if ``ARM_CRYPTOCELL_INTEG`` is + set. + +If the AP Firmware Updater Configuration image, BL2U is used, the following +must also be defined: + +- **#define : BL2U_BASE** + + Defines the base address in secure memory where BL1 copies the BL2U binary + image. Must be aligned on a page-size boundary. + +- **#define : BL2U_LIMIT** + + Defines the maximum address in secure memory that the BL2U image can occupy. + +- **#define : BL2U_IMAGE_ID** + + BL2U image identifier, used by BL1 to fetch an image descriptor + corresponding to BL2U. + +If the SCP Firmware Update Configuration Image, SCP_BL2U is used, the following +must also be defined: + +- **#define : SCP_BL2U_IMAGE_ID** + + SCP_BL2U image identifier, used by BL1 to fetch an image descriptor + corresponding to SCP_BL2U. + + .. note:: + TF-A does not provide source code for this image. + +If the Non-Secure Firmware Updater ROM, NS_BL1U is used, the following must +also be defined: + +- **#define : NS_BL1U_BASE** + + Defines the base address in non-secure ROM where NS_BL1U executes. + Must be aligned on a page-size boundary. + + .. note:: + TF-A does not provide source code for this image. + +- **#define : NS_BL1U_IMAGE_ID** + + NS_BL1U image identifier, used by BL1 to fetch an image descriptor + corresponding to NS_BL1U. + +If the Non-Secure Firmware Updater, NS_BL2U is used, the following must also +be defined: + +- **#define : NS_BL2U_BASE** + + Defines the base address in non-secure memory where NS_BL2U executes. + Must be aligned on a page-size boundary. + + .. note:: + TF-A does not provide source code for this image. + +- **#define : NS_BL2U_IMAGE_ID** + + NS_BL2U image identifier, used by BL1 to fetch an image descriptor + corresponding to NS_BL2U. + +For the the Firmware update capability of TRUSTED BOARD BOOT, the following +macros may also be defined: + +- **#define : PLAT_FWU_MAX_SIMULTANEOUS_IMAGES** + + Total number of images that can be loaded simultaneously. If the platform + doesn't specify any value, it defaults to 10. + +If a SCP_BL2 image is supported by the platform, the following constants must +also be defined: + +- **#define : SCP_BL2_IMAGE_ID** + + SCP_BL2 image identifier, used by BL2 to load SCP_BL2 into secure memory + from platform storage before being transferred to the SCP. + +- **#define : SCP_FW_KEY_CERT_ID** + + SCP_BL2 key certificate identifier, used by BL2 to load the SCP_BL2 key + certificate (mandatory when Trusted Board Boot is enabled). + +- **#define : SCP_FW_CONTENT_CERT_ID** + + SCP_BL2 content certificate identifier, used by BL2 to load the SCP_BL2 + content certificate (mandatory when Trusted Board Boot is enabled). + +If a BL32 image is supported by the platform, the following constants must +also be defined: + +- **#define : BL32_IMAGE_ID** + + BL32 image identifier, used by BL2 to load BL32. + +- **#define : TRUSTED_OS_FW_KEY_CERT_ID** + + BL32 key certificate identifier, used by BL2 to load the BL32 key + certificate (mandatory when Trusted Board Boot is enabled). + +- **#define : TRUSTED_OS_FW_CONTENT_CERT_ID** + + BL32 content certificate identifier, used by BL2 to load the BL32 content + certificate (mandatory when Trusted Board Boot is enabled). + +- **#define : BL32_BASE** + + Defines the base address in secure memory where BL2 loads the BL32 binary + image. Must be aligned on a page-size boundary. + +- **#define : BL32_LIMIT** + + Defines the maximum address that the BL32 image can occupy. + +If the Test Secure-EL1 Payload (TSP) instantiation of BL32 is supported by the +platform, the following constants must also be defined: + +- **#define : TSP_SEC_MEM_BASE** + + Defines the base address of the secure memory used by the TSP image on the + platform. This must be at the same address or below ``BL32_BASE``. + +- **#define : TSP_SEC_MEM_SIZE** + + Defines the size of the secure memory used by the BL32 image on the + platform. ``TSP_SEC_MEM_BASE`` and ``TSP_SEC_MEM_SIZE`` must fully + accommodate the memory required by the BL32 image, defined by ``BL32_BASE`` + and ``BL32_LIMIT``. + +- **#define : TSP_IRQ_SEC_PHY_TIMER** + + Defines the ID of the secure physical generic timer interrupt used by the + TSP's interrupt handling code. + +If the platform port uses the translation table library code, the following +constants must also be defined: + +- **#define : PLAT_XLAT_TABLES_DYNAMIC** + + Optional flag that can be set per-image to enable the dynamic allocation of + regions even when the MMU is enabled. If not defined, only static + functionality will be available, if defined and set to 1 it will also + include the dynamic functionality. + +- **#define : MAX_XLAT_TABLES** + + Defines the maximum number of translation tables that are allocated by the + translation table library code. To minimize the amount of runtime memory + used, choose the smallest value needed to map the required virtual addresses + for each BL stage. If ``PLAT_XLAT_TABLES_DYNAMIC`` flag is enabled for a BL + image, ``MAX_XLAT_TABLES`` must be defined to accommodate the dynamic regions + as well. + +- **#define : MAX_MMAP_REGIONS** + + Defines the maximum number of regions that are allocated by the translation + table library code. A region consists of physical base address, virtual base + address, size and attributes (Device/Memory, RO/RW, Secure/Non-Secure), as + defined in the ``mmap_region_t`` structure. The platform defines the regions + that should be mapped. Then, the translation table library will create the + corresponding tables and descriptors at runtime. To minimize the amount of + runtime memory used, choose the smallest value needed to register the + required regions for each BL stage. If ``PLAT_XLAT_TABLES_DYNAMIC`` flag is + enabled for a BL image, ``MAX_MMAP_REGIONS`` must be defined to accommodate + the dynamic regions as well. + +- **#define : PLAT_VIRT_ADDR_SPACE_SIZE** + + Defines the total size of the virtual address space in bytes. For example, + for a 32 bit virtual address space, this value should be ``(1ULL << 32)``. + +- **#define : PLAT_PHY_ADDR_SPACE_SIZE** + + Defines the total size of the physical address space in bytes. For example, + for a 32 bit physical address space, this value should be ``(1ULL << 32)``. + +If the platform port uses the IO storage framework, the following constants +must also be defined: + +- **#define : MAX_IO_DEVICES** + + Defines the maximum number of registered IO devices. Attempting to register + more devices than this value using ``io_register_device()`` will fail with + -ENOMEM. + +- **#define : MAX_IO_HANDLES** + + Defines the maximum number of open IO handles. Attempting to open more IO + entities than this value using ``io_open()`` will fail with -ENOMEM. + +- **#define : MAX_IO_BLOCK_DEVICES** + + Defines the maximum number of registered IO block devices. Attempting to + register more devices this value using ``io_dev_open()`` will fail + with -ENOMEM. MAX_IO_BLOCK_DEVICES should be less than MAX_IO_DEVICES. + With this macro, multiple block devices could be supported at the same + time. + +If the platform needs to allocate data within the per-cpu data framework in +BL31, it should define the following macro. Currently this is only required if +the platform decides not to use the coherent memory section by undefining the +``USE_COHERENT_MEM`` build flag. In this case, the framework allocates the +required memory within the the per-cpu data to minimize wastage. + +- **#define : PLAT_PCPU_DATA_SIZE** + + Defines the memory (in bytes) to be reserved within the per-cpu data + structure for use by the platform layer. + +The following constants are optional. They should be defined when the platform +memory layout implies some image overlaying like in Arm standard platforms. + +- **#define : BL31_PROGBITS_LIMIT** + + Defines the maximum address in secure RAM that the BL31's progbits sections + can occupy. + +- **#define : TSP_PROGBITS_LIMIT** + + Defines the maximum address that the TSP's progbits sections can occupy. + +If the platform port uses the PL061 GPIO driver, the following constant may +optionally be defined: + +- **PLAT_PL061_MAX_GPIOS** + Maximum number of GPIOs required by the platform. This allows control how + much memory is allocated for PL061 GPIO controllers. The default value is + + #. $(eval $(call add_define,PLAT_PL061_MAX_GPIOS)) + +If the platform port uses the partition driver, the following constant may +optionally be defined: + +- **PLAT_PARTITION_MAX_ENTRIES** + Maximum number of partition entries required by the platform. This allows + control how much memory is allocated for partition entries. The default + value is 128. + For example, define the build flag in ``platform.mk``: + PLAT_PARTITION_MAX_ENTRIES := 12 + $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES)) + +- **PLAT_PARTITION_BLOCK_SIZE** + The size of partition block. It could be either 512 bytes or 4096 bytes. + The default value is 512. + For example, define the build flag in ``platform.mk``: + PLAT_PARTITION_BLOCK_SIZE := 4096 + $(eval $(call add_define,PLAT_PARTITION_BLOCK_SIZE)) + +The following constant is optional. It should be defined to override the default +behaviour of the ``assert()`` function (for example, to save memory). + +- **PLAT_LOG_LEVEL_ASSERT** + If ``PLAT_LOG_LEVEL_ASSERT`` is higher or equal than ``LOG_LEVEL_VERBOSE``, + ``assert()`` prints the name of the file, the line number and the asserted + expression. Else if it is higher than ``LOG_LEVEL_INFO``, it prints the file + name and the line number. Else if it is lower than ``LOG_LEVEL_INFO``, it + doesn't print anything to the console. If ``PLAT_LOG_LEVEL_ASSERT`` isn't + defined, it defaults to ``LOG_LEVEL``. + +If the platform port uses the DRTM feature, the following constants must be +defined: + +- **#define : PLAT_DRTM_EVENT_LOG_MAX_SIZE** + + Maximum Event Log size used by the platform. Platform can decide the maximum + size of the Event Log buffer, depending upon the highest hash algorithm + chosen and the number of components selected to measure during the DRTM + execution flow. + +- **#define : PLAT_DRTM_MMAP_ENTRIES** + + Number of the MMAP entries used by the DRTM implementation to calculate the + size of address map region of the platform. + +File : plat_macros.S [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each platform must ensure a file of this name is in the system include path with +the following macro defined. In the Arm development platforms, this file is +found in ``plat/arm/board/<plat_name>/include/plat_macros.S``. + +- **Macro : plat_crash_print_regs** + + This macro allows the crash reporting routine to print relevant platform + registers in case of an unhandled exception in BL31. This aids in debugging + and this macro can be defined to be empty in case register reporting is not + desired. + + For instance, GIC or interconnect registers may be helpful for + troubleshooting. + +Handling Reset +-------------- + +BL1 by default implements the reset vector where execution starts from a cold +or warm boot. BL31 can be optionally set as a reset vector using the +``RESET_TO_BL31`` make variable. + +For each CPU, the reset vector code is responsible for the following tasks: + +#. Distinguishing between a cold boot and a warm boot. + +#. In the case of a cold boot and the CPU being a secondary CPU, ensuring that + the CPU is placed in a platform-specific state until the primary CPU + performs the necessary steps to remove it from this state. + +#. In the case of a warm boot, ensuring that the CPU jumps to a platform- + specific address in the BL31 image in the same processor mode as it was + when released from reset. + +The following functions need to be implemented by the platform port to enable +reset vector code to perform the above tasks. + +Function : plat_get_my_entrypoint() [mandatory when PROGRAMMABLE_RESET_ADDRESS == 0] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uintptr_t + +This function is called with the MMU and caches disabled +(``SCTLR_EL3.M`` = 0 and ``SCTLR_EL3.C`` = 0). The function is responsible for +distinguishing between a warm and cold reset for the current CPU using +platform-specific means. If it's a warm reset, then it returns the warm +reset entrypoint point provided to ``plat_setup_psci_ops()`` during +BL31 initialization. If it's a cold reset then this function must return zero. + +This function does not follow the Procedure Call Standard used by the +Application Binary Interface for the Arm 64-bit architecture. The caller should +not assume that callee saved registers are preserved across a call to this +function. + +This function fulfills requirement 1 and 3 listed above. + +Note that for platforms that support programming the reset address, it is +expected that a CPU will start executing code directly at the right address, +both on a cold and warm reset. In this case, there is no need to identify the +type of reset nor to query the warm reset entrypoint. Therefore, implementing +this function is not required on such platforms. + +Function : plat_secondary_cold_boot_setup() [mandatory when COLD_BOOT_SINGLE_CPU == 0] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + +This function is called with the MMU and data caches disabled. It is responsible +for placing the executing secondary CPU in a platform-specific state until the +primary CPU performs the necessary actions to bring it out of that state and +allow entry into the OS. This function must not return. + +In the Arm FVP port, when using the normal boot flow, each secondary CPU powers +itself off. The primary CPU is responsible for powering up the secondary CPUs +when normal world software requires them. When booting an EL3 payload instead, +they stay powered on and are put in a holding pen until their mailbox gets +populated. + +This function fulfills requirement 2 above. + +Note that for platforms that can't release secondary CPUs out of reset, only the +primary CPU will execute the cold boot code. Therefore, implementing this +function is not required on such platforms. + +Function : plat_is_my_cpu_primary() [mandatory when COLD_BOOT_SINGLE_CPU == 0] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : unsigned int + +This function identifies whether the current CPU is the primary CPU or a +secondary CPU. A return value of zero indicates that the CPU is not the +primary CPU, while a non-zero return value indicates that the CPU is the +primary CPU. + +Note that for platforms that can't release secondary CPUs out of reset, only the +primary CPU will execute the cold boot code. Therefore, there is no need to +distinguish between primary and secondary CPUs and implementing this function is +not required. + +Function : platform_mem_init() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function is called before any access to data is made by the firmware, in +order to carry out any essential memory initialization. + +Function: plat_get_rotpk_info() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void *, void **, unsigned int *, unsigned int * + Return : int + +This function is mandatory when Trusted Board Boot is enabled. It returns a +pointer to the ROTPK stored in the platform (or a hash of it) and its length. +The ROTPK must be encoded in DER format according to the following ASN.1 +structure: + +:: + + AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY DEFINED BY algorithm OPTIONAL + } + + SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING + } + +In case the function returns a hash of the key: + +:: + + DigestInfo ::= SEQUENCE { + digestAlgorithm AlgorithmIdentifier, + digest OCTET STRING + } + +The function returns 0 on success. Any other value is treated as error by the +Trusted Board Boot. The function also reports extra information related +to the ROTPK in the flags parameter: + +:: + + ROTPK_IS_HASH : Indicates that the ROTPK returned by the platform is a + hash. + ROTPK_NOT_DEPLOYED : This allows the platform to skip certificate ROTPK + verification while the platform ROTPK is not deployed. + When this flag is set, the function does not need to + return a platform ROTPK, and the authentication + framework uses the ROTPK in the certificate without + verifying it against the platform value. This flag + must not be used in a deployed production environment. + +Function: plat_get_nv_ctr() +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void *, unsigned int * + Return : int + +This function is mandatory when Trusted Board Boot is enabled. It returns the +non-volatile counter value stored in the platform in the second argument. The +cookie in the first argument may be used to select the counter in case the +platform provides more than one (for example, on platforms that use the default +TBBR CoT, the cookie will correspond to the OID values defined in +TRUSTED_FW_NVCOUNTER_OID or NON_TRUSTED_FW_NVCOUNTER_OID). + +The function returns 0 on success. Any other value means the counter value could +not be retrieved from the platform. + +Function: plat_set_nv_ctr() +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void *, unsigned int + Return : int + +This function is mandatory when Trusted Board Boot is enabled. It sets a new +counter value in the platform. The cookie in the first argument may be used to +select the counter (as explained in plat_get_nv_ctr()). The second argument is +the updated counter value to be written to the NV counter. + +The function returns 0 on success. Any other value means the counter value could +not be updated. + +Function: plat_set_nv_ctr2() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void *, const auth_img_desc_t *, unsigned int + Return : int + +This function is optional when Trusted Board Boot is enabled. If this +interface is defined, then ``plat_set_nv_ctr()`` need not be defined. The +first argument passed is a cookie and is typically used to +differentiate between a Non Trusted NV Counter and a Trusted NV +Counter. The second argument is a pointer to an authentication image +descriptor and may be used to decide if the counter is allowed to be +updated or not. The third argument is the updated counter value to +be written to the NV counter. + +The function returns 0 on success. Any other value means the counter value +either could not be updated or the authentication image descriptor indicates +that it is not allowed to be updated. + +Function: plat_convert_pk() +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void *, unsigned int, void **, unsigned int * + Return : int + +This function is optional when Trusted Board Boot is enabled, and only +used if the platform saves a hash of the ROTPK. +First argument is the Distinguished Encoding Rules (DER) ROTPK. +Second argument is its size. +Third argument is used to return a pointer to a buffer, which hash should +be the one saved in OTP. +Fourth argument is a pointer to return its size. + +Most platforms save the hash of the ROTPK, but some may save slightly different +information - e.g the hash of the ROTPK plus some related information. +Defining this function allows to transform the ROTPK used to verify +the signature to the buffer (a platform specific public key) which +hash is saved in OTP. + +The default implementation copies the input key and length to the output without +modification. + +The function returns 0 on success. Any other value means the expected +public key buffer cannot be extracted. + +Dynamic Root of Trust for Measurement support (in BL31) +------------------------------------------------------- + +The functions mentioned in this section are mandatory, when platform enables +DRTM_SUPPORT build flag. + +Function : plat_get_addr_mmap() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : const mmap_region_t * + +This function is used to return the address of the platform *address-map* table, +which describes the regions of normal memory, memory mapped I/O +and non-volatile memory. + +Function : plat_has_non_host_platforms() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : bool + +This function returns *true* if the platform has any trusted devices capable of +DMA, otherwise returns *false*. + +Function : plat_has_unmanaged_dma_peripherals() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : bool + +This function returns *true* if platform uses peripherals whose DMA is not +managed by an SMMU, otherwise returns *false*. + +Note - +If the platform has peripherals that are not managed by the SMMU, then the +platform should investigate such peripherals to determine whether they can +be trusted, and such peripherals should be moved under "Non-host platforms" +if they can be trusted. + +Function : plat_get_total_num_smmus() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : unsigned int + +This function returns the total number of SMMUs in the platform. + +Function : plat_enumerate_smmus() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:: + + + Argument : void + Return : const uintptr_t *, size_t + +This function returns an array of SMMU addresses and the actual number of SMMUs +reported by the platform. + +Function : plat_drtm_get_dma_prot_features() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : const plat_drtm_dma_prot_features_t* + +This function returns the address of plat_drtm_dma_prot_features_t structure +containing the maximum number of protected regions and bitmap with the types +of DMA protection supported by the platform. +For more details see section 3.3 Table 6 of `DRTM`_ specification. + +Function : plat_drtm_dma_prot_get_max_table_bytes() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint64_t + +This function returns the maximum size of DMA protected regions table in +bytes. + +Function : plat_drtm_get_tpm_features() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : const plat_drtm_tpm_features_t* + +This function returns the address of *plat_drtm_tpm_features_t* structure +containing PCR usage schema, TPM-based hash, and firmware hash algorithm +supported by the platform. + +Function : plat_drtm_get_min_size_normal_world_dce() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint64_t + +This function returns the size normal-world DCE of the platform. + +Function : plat_drtm_get_imp_def_dlme_region_size() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint64_t + +This function returns the size of implementation defined DLME region +of the platform. + +Function : plat_drtm_get_tcb_hash_table_size() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint64_t + +This function returns the size of TCB hash table of the platform. + +Function : plat_drtm_get_tcb_hash_features() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint64_t + +This function returns the Maximum number of TCB hashes recorded by the +platform. +For more details see section 3.3 Table 6 of `DRTM`_ specification. + +Function : plat_drtm_validate_ns_region() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uintptr_t, uintptr_t + Return : int + +This function validates that given region is within the Non-Secure region +of DRAM. This function takes a region start address and size an input +arguments, and returns 0 on success and -1 on failure. + +Function : plat_set_drtm_error() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint64_t + Return : int + +This function writes a 64 bit error code received as input into +non-volatile storage and returns 0 on success and -1 on failure. + +Function : plat_get_drtm_error() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint64_t* + Return : int + +This function reads a 64 bit error code from the non-volatile storage +into the received address, and returns 0 on success and -1 on failure. + +Common mandatory function modifications +--------------------------------------- + +The following functions are mandatory functions which need to be implemented +by the platform port. + +Function : plat_my_core_pos() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : unsigned int + +This function returns the index of the calling CPU which is used as a +CPU-specific linear index into blocks of memory (for example while allocating +per-CPU stacks). This function will be invoked very early in the +initialization sequence which mandates that this function should be +implemented in assembly and should not rely on the availability of a C +runtime environment. This function can clobber x0 - x8 and must preserve +x9 - x29. + +This function plays a crucial role in the power domain topology framework in +PSCI and details of this can be found in +:ref:`PSCI Power Domain Tree Structure`. + +Function : plat_core_pos_by_mpidr() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : u_register_t + Return : int + +This function validates the ``MPIDR`` of a CPU and converts it to an index, +which can be used as a CPU-specific linear index into blocks of memory. In +case the ``MPIDR`` is invalid, this function returns -1. This function will only +be invoked by BL31 after the power domain topology is initialized and can +utilize the C runtime environment. For further details about how TF-A +represents the power domain topology and how this relates to the linear CPU +index, please refer :ref:`PSCI Power Domain Tree Structure`. + +Function : plat_get_mbedtls_heap() [when TRUSTED_BOARD_BOOT == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Arguments : void **heap_addr, size_t *heap_size + Return : int + +This function is invoked during Mbed TLS library initialisation to get a heap, +by means of a starting address and a size. This heap will then be used +internally by the Mbed TLS library. Hence, each BL stage that utilises Mbed TLS +must be able to provide a heap to it. + +A helper function can be found in `drivers/auth/mbedtls/mbedtls_common.c` in +which a heap is statically reserved during compile time inside every image +(i.e. every BL stage) that utilises Mbed TLS. In this default implementation, +the function simply returns the address and size of this "pre-allocated" heap. +For a platform to use this default implementation, only a call to the helper +from inside plat_get_mbedtls_heap() body is enough and nothing else is needed. + +However, by writting their own implementation, platforms have the potential to +optimise memory usage. For example, on some Arm platforms, the Mbed TLS heap is +shared between BL1 and BL2 stages and, thus, the necessary space is not reserved +twice. + +On success the function should return 0 and a negative error code otherwise. + +Function : plat_get_enc_key_info() [when FW_ENC_STATUS == 0 or 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Arguments : enum fw_enc_status_t fw_enc_status, uint8_t *key, + size_t *key_len, unsigned int *flags, const uint8_t *img_id, + size_t img_id_len + Return : int + +This function provides a symmetric key (either SSK or BSSK depending on +fw_enc_status) which is invoked during runtime decryption of encrypted +firmware images. `plat/common/plat_bl_common.c` provides a dummy weak +implementation for testing purposes which must be overridden by the platform +trying to implement a real world firmware encryption use-case. + +It also allows the platform to pass symmetric key identifier rather than +actual symmetric key which is useful in cases where the crypto backend provides +secure storage for the symmetric key. So in this case ``ENC_KEY_IS_IDENTIFIER`` +flag must be set in ``flags``. + +In addition to above a platform may also choose to provide an image specific +symmetric key/identifier using img_id. + +On success the function should return 0 and a negative error code otherwise. + +Note that this API depends on ``DECRYPTION_SUPPORT`` build flag. + +Function : plat_fwu_set_images_source() [when PSA_FWU_SUPPORT == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : const struct fwu_metadata *metadata + Return : void + +This function is mandatory when PSA_FWU_SUPPORT is enabled. +It provides a means to retrieve image specification (offset in +non-volatile storage and length) of active/updated images using the passed +FWU metadata, and update I/O policies of active/updated images using retrieved +image specification information. +Further I/O layer operations such as I/O open, I/O read, etc. on these +images rely on this function call. + +In Arm platforms, this function is used to set an I/O policy of the FIP image, +container of all active/updated secure and non-secure images. + +Function : plat_fwu_set_metadata_image_source() [when PSA_FWU_SUPPORT == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec + Return : int + +This function is mandatory when PSA_FWU_SUPPORT is enabled. It is +responsible for setting up the platform I/O policy of the requested metadata +image (either FWU_METADATA_IMAGE_ID or BKUP_FWU_METADATA_IMAGE_ID) that will +be used to load this image from the platform's non-volatile storage. + +FWU metadata can not be always stored as a raw image in non-volatile storage +to define its image specification (offset in non-volatile storage and length) +statically in I/O policy. +For example, the FWU metadata image is stored as a partition inside the GUID +partition table image. Its specification is defined in the partition table +that needs to be parsed dynamically. +This function provides a means to retrieve such dynamic information to set +the I/O policy of the FWU metadata image. +Further I/O layer operations such as I/O open, I/O read, etc. on FWU metadata +image relies on this function call. + +It returns '0' on success, otherwise a negative error value on error. +Alongside, returns device handle and image specification from the I/O policy +of the requested FWU metadata image. + +Function : plat_fwu_get_boot_idx() [when PSA_FWU_SUPPORT == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint32_t + +This function is mandatory when PSA_FWU_SUPPORT is enabled. It provides the +means to retrieve the boot index value from the platform. The boot index is the +bank from which the platform has booted the firmware images. + +By default, the platform will read the metadata structure and try to boot from +the active bank. If the platform fails to boot from the active bank due to +reasons like an Authentication failure, or on crossing a set number of watchdog +resets while booting from the active bank, the platform can then switch to boot +from a different bank. This function then returns the bank that the platform +should boot its images from. + +Common optional modifications +----------------------------- + +The following are helper functions implemented by the firmware that perform +common platform-specific tasks. A platform may choose to override these +definitions. + +Function : plat_set_my_stack() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function sets the current stack pointer to the normal memory stack that +has been allocated for the current CPU. For BL images that only require a +stack for the primary CPU, the UP version of the function is used. The size +of the stack allocated to each CPU is specified by the platform defined +constant ``PLATFORM_STACK_SIZE``. + +Common implementations of this function for the UP and MP BL images are +provided in ``plat/common/aarch64/platform_up_stack.S`` and +``plat/common/aarch64/platform_mp_stack.S`` + +Function : plat_get_my_stack() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uintptr_t + +This function returns the base address of the normal memory stack that +has been allocated for the current CPU. For BL images that only require a +stack for the primary CPU, the UP version of the function is used. The size +of the stack allocated to each CPU is specified by the platform defined +constant ``PLATFORM_STACK_SIZE``. + +Common implementations of this function for the UP and MP BL images are +provided in ``plat/common/aarch64/platform_up_stack.S`` and +``plat/common/aarch64/platform_mp_stack.S`` + +Function : plat_report_exception() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int + Return : void + +A platform may need to report various information about its status when an +exception is taken, for example the current exception level, the CPU security +state (secure/non-secure), the exception type, and so on. This function is +called in the following circumstances: + +- In BL1, whenever an exception is taken. +- In BL2, whenever an exception is taken. + +The default implementation doesn't do anything, to avoid making assumptions +about the way the platform displays its status information. + +For AArch64, this function receives the exception type as its argument. +Possible values for exceptions types are listed in the +``include/common/bl_common.h`` header file. Note that these constants are not +related to any architectural exception code; they are just a TF-A convention. + +For AArch32, this function receives the exception mode as its argument. +Possible values for exception modes are listed in the +``include/lib/aarch32/arch.h`` header file. + +Function : plat_reset_handler() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +A platform may need to do additional initialization after reset. This function +allows the platform to do the platform specific initializations. Platform +specific errata workarounds could also be implemented here. The API should +preserve the values of callee saved registers x19 to x29. + +The default implementation doesn't do anything. If a platform needs to override +the default implementation, refer to the :ref:`Firmware Design` for general +guidelines. + +Function : plat_disable_acp() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This API allows a platform to disable the Accelerator Coherency Port (if +present) during a cluster power down sequence. The default weak implementation +doesn't do anything. Since this API is called during the power down sequence, +it has restrictions for stack usage and it can use the registers x0 - x17 as +scratch registers. It should preserve the value in x18 register as it is used +by the caller to store the return address. + +Function : plat_error_handler() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : int + Return : void + +This API is called when the generic code encounters an error situation from +which it cannot continue. It allows the platform to perform error reporting or +recovery actions (for example, reset the system). This function must not return. + +The parameter indicates the type of error using standard codes from ``errno.h``. +Possible errors reported by the generic code are: + +- ``-EAUTH``: a certificate or image could not be authenticated (when Trusted + Board Boot is enabled) +- ``-ENOENT``: the requested image or certificate could not be found or an IO + error was detected +- ``-ENOMEM``: resources exhausted. TF-A does not use dynamic memory, so this + error is usually an indication of an incorrect array size + +The default implementation simply spins. + +Function : plat_panic_handler() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This API is called when the generic code encounters an unexpected error +situation from which it cannot recover. This function must not return, +and must be implemented in assembly because it may be called before the C +environment is initialized. + +.. note:: + The address from where it was called is stored in x30 (Link Register). + The default implementation simply spins. + +Function : plat_system_reset() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function is used by the platform to resets the system. It can be used +in any specific use-case where system needs to be resetted. For example, +in case of DRTM implementation this function reset the system after +writing the DRTM error code in the non-volatile storage. This function +never returns. Failure in reset results in panic. + +Function : plat_get_bl_image_load_info() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : bl_load_info_t * + +This function returns pointer to the list of images that the platform has +populated to load. This function is invoked in BL2 to load the +BL3xx images. + +Function : plat_get_next_bl_params() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : bl_params_t * + +This function returns a pointer to the shared memory that the platform has +kept aside to pass TF-A related information that next BL image needs. This +function is invoked in BL2 to pass this information to the next BL +image. + +Function : plat_get_stack_protector_canary() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : u_register_t + +This function returns a random value that is used to initialize the canary used +when the stack protector is enabled with ENABLE_STACK_PROTECTOR. A predictable +value will weaken the protection as the attacker could easily write the right +value as part of the attack most of the time. Therefore, it should return a +true random number. + +.. warning:: + For the protection to be effective, the global data need to be placed at + a lower address than the stack bases. Failure to do so would allow an + attacker to overwrite the canary as part of the stack buffer overflow attack. + +Function : plat_flush_next_bl_params() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function flushes to main memory all the image params that are passed to +next image. This function is invoked in BL2 to flush this information +to the next BL image. + +Function : plat_log_get_prefix() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int + Return : const char * + +This function defines the prefix string corresponding to the `log_level` to be +prepended to all the log output from TF-A. The `log_level` (argument) will +correspond to one of the standard log levels defined in debug.h. The platform +can override the common implementation to define a different prefix string for +the log output. The implementation should be robust to future changes that +increase the number of log levels. + +Function : plat_get_soc_version() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int32_t + +This function returns soc version which mainly consist of below fields + +:: + + soc_version[30:24] = JEP-106 continuation code for the SiP + soc_version[23:16] = JEP-106 identification code with parity bit for the SiP + soc_version[15:0] = Implementation defined SoC ID + +Function : plat_get_soc_revision() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int32_t + +This function returns soc revision in below format + +:: + + soc_revision[0:30] = SOC revision of specific SOC + +Function : plat_is_smccc_feature_available() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : u_register_t + Return : int32_t + +This function returns SMC_ARCH_CALL_SUCCESS if the platform supports +the SMCCC function specified in the argument; otherwise returns +SMC_ARCH_CALL_NOT_SUPPORTED. + +Function : plat_mboot_measure_image() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int, image_info_t * + Return : int + +When the MEASURED_BOOT flag is enabled: + +- This function measures the given image and records its measurement using + the measured boot backend driver. +- On the Arm FVP port, this function measures the given image using its + passed id and information and then records that measurement in the + Event Log buffer. +- This function must return 0 on success, a signed integer error code + otherwise. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Function : plat_mboot_measure_critical_data() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int, const void *, size_t + Return : int + +When the MEASURED_BOOT flag is enabled: + +- This function measures the given critical data structure and records its + measurement using the measured boot backend driver. +- This function must return 0 on success, a signed integer error code + otherwise. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Function : plat_can_cmo() +~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint64_t + +When CONDITIONAL_CMO flag is enabled: + +- This function indicates whether cache management operations should be + performed. It returns 0 if CMOs should be skipped and non-zero + otherwise. +- The function must not clobber x1, x2 and x3. It's also not safe to rely on + stack. Otherwise obey AAPCS. + +Modifications specific to a Boot Loader stage +--------------------------------------------- + +Boot Loader Stage 1 (BL1) +------------------------- + +BL1 implements the reset vector where execution starts from after a cold or +warm boot. For each CPU, BL1 is responsible for the following tasks: + +#. Handling the reset as described in section 2.2 + +#. In the case of a cold boot and the CPU being the primary CPU, ensuring that + only this CPU executes the remaining BL1 code, including loading and passing + control to the BL2 stage. + +#. Identifying and starting the Firmware Update process (if required). + +#. Loading the BL2 image from non-volatile storage into secure memory at the + address specified by the platform defined constant ``BL2_BASE``. + +#. Populating a ``meminfo`` structure with the following information in memory, + accessible by BL2 immediately upon entry. + + :: + + meminfo.total_base = Base address of secure RAM visible to BL2 + meminfo.total_size = Size of secure RAM visible to BL2 + + By default, BL1 places this ``meminfo`` structure at the end of secure + memory visible to BL2. + + It is possible for the platform to decide where it wants to place the + ``meminfo`` structure for BL2 or restrict the amount of memory visible to + BL2 by overriding the weak default implementation of + ``bl1_plat_handle_post_image_load`` API. + +The following functions need to be implemented by the platform port to enable +BL1 to perform the above tasks. + +Function : bl1_early_platform_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. + +On Arm standard platforms, this function: + +- Enables a secure instance of SP805 to act as the Trusted Watchdog. + +- Initializes a UART (PL011 console), which enables access to the ``printf`` + family of functions in BL1. + +- Enables issuing of snoop and DVM (Distributed Virtual Memory) requests to + the CCI slave interface corresponding to the cluster that includes the + primary CPU. + +Function : bl1_plat_arch_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function performs any platform-specific and architectural setup that the +platform requires. Platform-specific setup might include configuration of +memory controllers and the interconnect. + +In Arm standard platforms, this function enables the MMU. + +This function helps fulfill requirement 2 above. + +Function : bl1_platform_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function executes with the MMU and data caches enabled. It is responsible +for performing any remaining platform-specific setup that can occur after the +MMU and data cache have been enabled. + +if support for multiple boot sources is required, it initializes the boot +sequence used by plat_try_next_boot_source(). + +In Arm standard platforms, this function initializes the storage abstraction +layer used to load the next bootloader image. + +This function helps fulfill requirement 4 above. + +Function : bl1_plat_sec_mem_layout() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : meminfo * + +This function should only be called on the cold boot path. It executes with the +MMU and data caches enabled. The pointer returned by this function must point to +a ``meminfo`` structure containing the extents and availability of secure RAM for +the BL1 stage. + +:: + + meminfo.total_base = Base address of secure RAM visible to BL1 + meminfo.total_size = Size of secure RAM visible to BL1 + +This information is used by BL1 to load the BL2 image in secure RAM. BL1 also +populates a similar structure to tell BL2 the extents of memory available for +its own use. + +This function helps fulfill requirements 4 and 5 above. + +Function : bl1_plat_prepare_exit() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : entry_point_info_t * + Return : void + +This function is called prior to exiting BL1 in response to the +``BL1_SMC_RUN_IMAGE`` SMC request raised by BL2. It should be used to perform +platform specific clean up or bookkeeping operations before transferring +control to the next image. It receives the address of the ``entry_point_info_t`` +structure passed from BL2. This function runs with MMU disabled. + +Function : bl1_plat_set_ep_info() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int image_id, entry_point_info_t *ep_info + Return : void + +This function allows platforms to override ``ep_info`` for the given ``image_id``. + +The default implementation just returns. + +Function : bl1_plat_get_next_image_id() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : unsigned int + +This and the following function must be overridden to enable the FWU feature. + +BL1 calls this function after platform setup to identify the next image to be +loaded and executed. If the platform returns ``BL2_IMAGE_ID`` then BL1 proceeds +with the normal boot sequence, which loads and executes BL2. If the platform +returns a different image id, BL1 assumes that Firmware Update is required. + +The default implementation always returns ``BL2_IMAGE_ID``. The Arm development +platforms override this function to detect if firmware update is required, and +if so, return the first image in the firmware update process. + +Function : bl1_plat_get_image_desc() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int image_id + Return : image_desc_t * + +BL1 calls this function to get the image descriptor information ``image_desc_t`` +for the provided ``image_id`` from the platform. + +The default implementation always returns a common BL2 image descriptor. Arm +standard platforms return an image descriptor corresponding to BL2 or one of +the firmware update images defined in the Trusted Board Boot Requirements +specification. + +Function : bl1_plat_handle_pre_image_load() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int image_id + Return : int + +This function can be used by the platforms to update/use image information +corresponding to ``image_id``. This function is invoked in BL1, both in cold +boot and FWU code path, before loading the image. + +Function : bl1_plat_handle_post_image_load() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int image_id + Return : int + +This function can be used by the platforms to update/use image information +corresponding to ``image_id``. This function is invoked in BL1, both in cold +boot and FWU code path, after loading and authenticating the image. + +The default weak implementation of this function calculates the amount of +Trusted SRAM that can be used by BL2 and allocates a ``meminfo_t`` +structure at the beginning of this free memory and populates it. The address +of ``meminfo_t`` structure is updated in ``arg1`` of the entrypoint +information to BL2. + +Function : bl1_plat_fwu_done() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int image_id, uintptr_t image_src, + unsigned int image_size + Return : void + +BL1 calls this function when the FWU process is complete. It must not return. +The platform may override this function to take platform specific action, for +example to initiate the normal boot flow. + +The default implementation spins forever. + +Function : bl1_plat_mem_check() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uintptr_t mem_base, unsigned int mem_size, + unsigned int flags + Return : int + +BL1 calls this function while handling FWU related SMCs, more specifically when +copying or authenticating an image. Its responsibility is to ensure that the +region of memory identified by ``mem_base`` and ``mem_size`` is mapped in BL1, and +that this memory corresponds to either a secure or non-secure memory region as +indicated by the security state of the ``flags`` argument. + +This function can safely assume that the value resulting from the addition of +``mem_base`` and ``mem_size`` fits into a ``uintptr_t`` type variable and does not +overflow. + +This function must return 0 on success, a non-null error code otherwise. + +The default implementation of this function asserts therefore platforms must +override it when using the FWU feature. + +Function : bl1_plat_mboot_init() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to initialize the backend driver(s) of measured boot. +- On the Arm FVP port, this function is used to initialize the Event Log + backend driver, and also to write header information in the Event Log buffer. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Function : bl1_plat_mboot_finish() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to finalize the measured boot backend driver(s), + and also, set the information for the next bootloader component to + extend the measurement if needed. +- On the Arm FVP port, this function is used to pass the base address of + the Event Log buffer and its size to BL2 via tb_fw_config to extend the + Event Log buffer with the measurement of various images loaded by BL2. + It results in panic on error. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Boot Loader Stage 2 (BL2) +------------------------- + +The BL2 stage is executed only by the primary CPU, which is determined in BL1 +using the ``platform_is_primary_cpu()`` function. BL1 passed control to BL2 at +``BL2_BASE``. BL2 executes in Secure EL1 and and invokes +``plat_get_bl_image_load_info()`` to retrieve the list of images to load from +non-volatile storage to secure/non-secure RAM. After all the images are loaded +then BL2 invokes ``plat_get_next_bl_params()`` to get the list of executable +images to be passed to the next BL image. + +The following functions must be implemented by the platform port to enable BL2 +to perform the above tasks. + +Function : bl2_early_platform_setup2() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : u_register_t, u_register_t, u_register_t, u_register_t + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. The 4 arguments are passed by BL1 to BL2 and these arguments +are platform specific. + +On Arm standard platforms, the arguments received are : + + arg0 - Points to load address of FW_CONFIG + + arg1 - ``meminfo`` structure populated by BL1. The platform copies + the contents of ``meminfo`` as it may be subsequently overwritten by BL2. + +On Arm standard platforms, this function also: + +- Initializes a UART (PL011 console), which enables access to the ``printf`` + family of functions in BL2. + +- Initializes the storage abstraction layer used to load further bootloader + images. It is necessary to do this early on platforms with a SCP_BL2 image, + since the later ``bl2_platform_setup`` must be done after SCP_BL2 is loaded. + +Function : bl2_plat_arch_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. + +The purpose of this function is to perform any architectural initialization +that varies across platforms. + +On Arm standard platforms, this function enables the MMU. + +Function : bl2_platform_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initialization in ``bl2_plat_arch_setup()``. It is only +called by the primary CPU. + +The purpose of this function is to perform any platform initialization +specific to BL2. + +In Arm standard platforms, this function performs security setup, including +configuration of the TrustZone controller to allow non-secure masters access +to most of DRAM. Part of DRAM is reserved for secure world use. + +Function : bl2_plat_handle_pre_image_load() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int + Return : int + +This function can be used by the platforms to update/use image information +for given ``image_id``. This function is currently invoked in BL2 before +loading each image. + +Function : bl2_plat_handle_post_image_load() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int + Return : int + +This function can be used by the platforms to update/use image information +for given ``image_id``. This function is currently invoked in BL2 after +loading each image. + +Function : bl2_plat_preload_setup [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This optional function performs any BL2 platform initialization +required before image loading, that is not done later in +bl2_platform_setup(). Specifically, if support for multiple +boot sources is required, it initializes the boot sequence used by +plat_try_next_boot_source(). + +Function : plat_try_next_boot_source() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int + +This optional function passes to the next boot source in the redundancy +sequence. + +This function moves the current boot redundancy source to the next +element in the boot sequence. If there are no more boot sources then it +must return 0, otherwise it must return 1. The default implementation +of this always returns 0. + +Function : bl2_plat_mboot_init() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to initialize the backend driver(s) of measured boot. +- On the Arm FVP port, this function is used to initialize the Event Log + backend driver with the Event Log buffer information (base address and + size) received from BL1. It results in panic on error. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Function : bl2_plat_mboot_finish() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to finalize the measured boot backend driver(s), + and also, set the information for the next bootloader component to extend + the measurement if needed. +- On the Arm FVP port, this function is used to pass the Event Log buffer + information (base address and size) to non-secure(BL33) and trusted OS(BL32) + via nt_fw and tos_fw config respectively. It results in panic on error. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Boot Loader Stage 2 (BL2) at EL3 +-------------------------------- + +When the platform has a non-TF-A Boot ROM it is desirable to jump +directly to BL2 instead of TF-A BL1. In this case BL2 is expected to +execute at EL3 instead of executing at EL1. Refer to the :ref:`Firmware Design` +document for more information. + +All mandatory functions of BL2 must be implemented, except the functions +bl2_early_platform_setup and bl2_el3_plat_arch_setup, because +their work is done now by bl2_el3_early_platform_setup and +bl2_el3_plat_arch_setup. These functions should generally implement +the bl1_plat_xxx() and bl2_plat_xxx() functionality combined. + + +Function : bl2_el3_early_platform_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : u_register_t, u_register_t, u_register_t, u_register_t + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. This function receives four parameters which can be used +by the platform to pass any needed information from the Boot ROM to BL2. + +On Arm standard platforms, this function does the following: + +- Initializes a UART (PL011 console), which enables access to the ``printf`` + family of functions in BL2. + +- Initializes the storage abstraction layer used to load further bootloader + images. It is necessary to do this early on platforms with a SCP_BL2 image, + since the later ``bl2_platform_setup`` must be done after SCP_BL2 is loaded. + +- Initializes the private variables that define the memory layout used. + +Function : bl2_el3_plat_arch_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. + +The purpose of this function is to perform any architectural initialization +that varies across platforms. + +On Arm standard platforms, this function enables the MMU. + +Function : bl2_el3_plat_prepare_exit() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function is called prior to exiting BL2 and run the next image. +It should be used to perform platform specific clean up or bookkeeping +operations before transferring control to the next image. This function +runs with MMU disabled. + +FWU Boot Loader Stage 2 (BL2U) +------------------------------ + +The AP Firmware Updater Configuration, BL2U, is an optional part of the FWU +process and is executed only by the primary CPU. BL1 passes control to BL2U at +``BL2U_BASE``. BL2U executes in Secure-EL1 and is responsible for: + +#. (Optional) Transferring the optional SCP_BL2U binary image from AP secure + memory to SCP RAM. BL2U uses the SCP_BL2U ``image_info`` passed by BL1. + ``SCP_BL2U_BASE`` defines the address in AP secure memory where SCP_BL2U + should be copied from. Subsequent handling of the SCP_BL2U image is + implemented by the platform specific ``bl2u_plat_handle_scp_bl2u()`` function. + If ``SCP_BL2U_BASE`` is not defined then this step is not performed. + +#. Any platform specific setup required to perform the FWU process. For + example, Arm standard platforms initialize the TZC controller so that the + normal world can access DDR memory. + +The following functions must be implemented by the platform port to enable +BL2U to perform the tasks mentioned above. + +Function : bl2u_early_platform_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : meminfo *mem_info, void *plat_info + Return : void + +This function executes with the MMU and data caches disabled. It is only +called by the primary CPU. The arguments to this function is the address +of the ``meminfo`` structure and platform specific info provided by BL1. + +The platform may copy the contents of the ``mem_info`` and ``plat_info`` into +private storage as the original memory may be subsequently overwritten by BL2U. + +On Arm CSS platforms ``plat_info`` is interpreted as an ``image_info_t`` structure, +to extract SCP_BL2U image information, which is then copied into a private +variable. + +Function : bl2u_plat_arch_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function executes with the MMU and data caches disabled. It is only +called by the primary CPU. + +The purpose of this function is to perform any architectural initialization +that varies across platforms, for example enabling the MMU (since the memory +map differs across platforms). + +Function : bl2u_platform_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initialization in ``bl2u_plat_arch_setup()``. It is only +called by the primary CPU. + +The purpose of this function is to perform any platform initialization +specific to BL2U. + +In Arm standard platforms, this function performs security setup, including +configuration of the TrustZone controller to allow non-secure masters access +to most of DRAM. Part of DRAM is reserved for secure world use. + +Function : bl2u_plat_handle_scp_bl2u() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int + +This function is used to perform any platform-specific actions required to +handle the SCP firmware. Typically it transfers the image into SCP memory using +a platform-specific protocol and waits until SCP executes it and signals to the +Application Processor (AP) for BL2U execution to continue. + +This function returns 0 on success, a negative error code otherwise. +This function is included if SCP_BL2U_BASE is defined. + +Boot Loader Stage 3-1 (BL31) +---------------------------- + +During cold boot, the BL31 stage is executed only by the primary CPU. This is +determined in BL1 using the ``platform_is_primary_cpu()`` function. BL1 passes +control to BL31 at ``BL31_BASE``. During warm boot, BL31 is executed by all +CPUs. BL31 executes at EL3 and is responsible for: + +#. Re-initializing all architectural and platform state. Although BL1 performs + some of this initialization, BL31 remains resident in EL3 and must ensure + that EL3 architectural and platform state is completely initialized. It + should make no assumptions about the system state when it receives control. + +#. Passing control to a normal world BL image, pre-loaded at a platform- + specific address by BL2. On ARM platforms, BL31 uses the ``bl_params`` list + populated by BL2 in memory to do this. + +#. Providing runtime firmware services. Currently, BL31 only implements a + subset of the Power State Coordination Interface (PSCI) API as a runtime + service. See Section 3.3 below for details of porting the PSCI + implementation. + +#. Optionally passing control to the BL32 image, pre-loaded at a platform- + specific address by BL2. BL31 exports a set of APIs that allow runtime + services to specify the security state in which the next image should be + executed and run the corresponding image. On ARM platforms, BL31 uses the + ``bl_params`` list populated by BL2 in memory to do this. + +If BL31 is a reset vector, It also needs to handle the reset as specified in +section 2.2 before the tasks described above. + +The following functions must be implemented by the platform port to enable BL31 +to perform the above tasks. + +Function : bl31_early_platform_setup2() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : u_register_t, u_register_t, u_register_t, u_register_t + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. BL2 can pass 4 arguments to BL31 and these arguments are +platform specific. + +In Arm standard platforms, the arguments received are : + + arg0 - The pointer to the head of `bl_params_t` list + which is list of executable images following BL31, + + arg1 - Points to load address of SOC_FW_CONFIG if present + except in case of Arm FVP and Juno platform. + + In case of Arm FVP and Juno platform, points to load address + of FW_CONFIG. + + arg2 - Points to load address of HW_CONFIG if present + + arg3 - A special value to verify platform parameters from BL2 to BL31. Not + used in release builds. + +The function runs through the `bl_param_t` list and extracts the entry point +information for BL32 and BL33. It also performs the following: + +- Initialize a UART (PL011 console), which enables access to the ``printf`` + family of functions in BL31. + +- Enable issuing of snoop and DVM (Distributed Virtual Memory) requests to the + CCI slave interface corresponding to the cluster that includes the primary + CPU. + +Function : bl31_plat_arch_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function executes with the MMU and data caches disabled. It is only called +by the primary CPU. + +The purpose of this function is to perform any architectural initialization +that varies across platforms. + +On Arm standard platforms, this function enables the MMU. + +Function : bl31_platform_setup() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initialization in ``bl31_plat_arch_setup()``. It is only +called by the primary CPU. + +The purpose of this function is to complete platform initialization so that both +BL31 runtime services and normal world software can function correctly. + +On Arm standard platforms, this function does the following: + +- Initialize the generic interrupt controller. + + Depending on the GIC driver selected by the platform, the appropriate GICv2 + or GICv3 initialization will be done, which mainly consists of: + + - Enable secure interrupts in the GIC CPU interface. + - Disable the legacy interrupt bypass mechanism. + - Configure the priority mask register to allow interrupts of all priorities + to be signaled to the CPU interface. + - Mark SGIs 8-15 and the other secure interrupts on the platform as secure. + - Target all secure SPIs to CPU0. + - Enable these secure interrupts in the GIC distributor. + - Configure all other interrupts as non-secure. + - Enable signaling of secure interrupts in the GIC distributor. + +- Enable system-level implementation of the generic timer counter through the + memory mapped interface. + +- Grant access to the system counter timer module + +- Initialize the power controller device. + + In particular, initialise the locks that prevent concurrent accesses to the + power controller device. + +Function : bl31_plat_runtime_setup() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +The purpose of this function is allow the platform to perform any BL31 runtime +setup just prior to BL31 exit during cold boot. The default weak +implementation of this function will invoke ``console_switch_state()`` to switch +console output to consoles marked for use in the ``runtime`` state. + +Function : bl31_plat_get_next_image_ep_info() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint32_t + Return : entry_point_info * + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initializations in ``bl31_plat_arch_setup()``. + +This function is called by ``bl31_main()`` to retrieve information provided by +BL2 for the next image in the security state specified by the argument. BL31 +uses this information to pass control to that image in the specified security +state. This function must return a pointer to the ``entry_point_info`` structure +(that was copied during ``bl31_early_platform_setup()``) if the image exists. It +should return NULL otherwise. + +Function : plat_rmmd_get_cca_attest_token() [mandatory when ENABLE_RME == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uintptr_t, size_t *, uintptr_t, size_t + Return : int + +This function returns the Platform attestation token. + +The parameters of the function are: + + arg0 - A pointer to the buffer where the Platform token should be copied by + this function. The buffer must be big enough to hold the Platform + token. + + arg1 - Contains the size (in bytes) of the buffer passed in arg0. The + function returns the platform token length in this parameter. + + arg2 - A pointer to the buffer where the challenge object is stored. + + arg3 - The length of the challenge object in bytes. Possible values are 32, + 48 and 64. + +The function returns 0 on success, -EINVAL on failure. + +Function : plat_rmmd_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uintptr_t, size_t *, unsigned int + Return : int + +This function returns the delegated realm attestation key which will be used to +sign Realm attestation token. The API currently only supports P-384 ECC curve +key. + +The parameters of the function are: + + arg0 - A pointer to the buffer where the attestation key should be copied + by this function. The buffer must be big enough to hold the + attestation key. + + arg1 - Contains the size (in bytes) of the buffer passed in arg0. The + function returns the attestation key length in this parameter. + + arg2 - The type of the elliptic curve to which the requested attestation key + belongs. + +The function returns 0 on success, -EINVAL on failure. + +Function : plat_rmmd_get_el3_rmm_shared_mem() [when ENABLE_RME == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uintptr_t * + Return : size_t + +This function returns the size of the shared area between EL3 and RMM (or 0 on +failure). A pointer to the shared area (or a NULL pointer on failure) is stored +in the pointer passed as argument. + +Function : plat_rmmd_load_manifest() [when ENABLE_RME == 1] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Arguments : rmm_manifest_t *manifest + Return : int + +When ENABLE_RME is enabled, this function populates a boot manifest for the +RMM image and stores it in the area specified by manifest. + +When ENABLE_RME is disabled, this function is not used. + +Function : bl31_plat_enable_mmu [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint32_t + Return : void + +This function enables the MMU. The boot code calls this function with MMU and +caches disabled. This function should program necessary registers to enable +translation, and upon return, the MMU on the calling PE must be enabled. + +The function must honor flags passed in the first argument. These flags are +defined by the translation library, and can be found in the file +``include/lib/xlat_tables/xlat_mmu_helpers.h``. + +On DynamIQ systems, this function must not use stack while enabling MMU, which +is how the function in xlat table library version 2 is implemented. + +Function : plat_init_apkey [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint128_t + +This function returns the 128-bit value which can be used to program ARMv8.3 +pointer authentication keys. + +The value should be obtained from a reliable source of randomness. + +This function is only needed if ARMv8.3 pointer authentication is used in the +Trusted Firmware by building with ``BRANCH_PROTECTION`` option set to non-zero. + +Function : plat_get_syscnt_freq2() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : unsigned int + +This function is used by the architecture setup code to retrieve the counter +frequency for the CPU's generic timer. This value will be programmed into the +``CNTFRQ_EL0`` register. In Arm standard platforms, it returns the base frequency +of the system counter, which is retrieved from the first entry in the frequency +modes table. + +#define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When ``USE_COHERENT_MEM = 0``, this constant defines the total memory (in +bytes) aligned to the cache line boundary that should be allocated per-cpu to +accommodate all the bakery locks. + +If this constant is not defined when ``USE_COHERENT_MEM = 0``, the linker +calculates the size of the ``bakery_lock`` input section, aligns it to the +nearest ``CACHE_WRITEBACK_GRANULE``, multiplies it with ``PLATFORM_CORE_COUNT`` +and stores the result in a linker symbol. This constant prevents a platform +from relying on the linker and provide a more efficient mechanism for +accessing per-cpu bakery lock information. + +If this constant is defined and its value is not equal to the value +calculated by the linker then a link time assertion is raised. A compile time +assertion is raised if the value of the constant is not aligned to the cache +line boundary. + +.. _porting_guide_sdei_requirements: + +SDEI porting requirements +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The |SDEI| dispatcher requires the platform to provide the following macros +and functions, of which some are optional, and some others mandatory. + +Macros +...... + +Macro: PLAT_SDEI_NORMAL_PRI [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This macro must be defined to the EL3 exception priority level associated with +Normal |SDEI| events on the platform. This must have a higher value +(therefore of lower priority) than ``PLAT_SDEI_CRITICAL_PRI``. + +Macro: PLAT_SDEI_CRITICAL_PRI [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This macro must be defined to the EL3 exception priority level associated with +Critical |SDEI| events on the platform. This must have a lower value +(therefore of higher priority) than ``PLAT_SDEI_NORMAL_PRI``. + +**Note**: |SDEI| exception priorities must be the lowest among Secure +priorities. Among the |SDEI| exceptions, Critical |SDEI| priority must +be higher than Normal |SDEI| priority. + +Functions +......... + +Function: int plat_sdei_validate_entry_point() [optional] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + Argument: uintptr_t ep, unsigned int client_mode + Return: int + +This function validates the entry point address of the event handler provided by +the client for both event registration and *Complete and Resume* |SDEI| calls. +The function ensures that the address is valid in the client translation regime. + +The second argument is the exception level that the client is executing in. It +can be Non-Secure EL1 or Non-Secure EL2. + +The function must return ``0`` for successful validation, or ``-1`` upon failure. + +The default implementation always returns ``0``. On Arm platforms, this function +translates the entry point address within the client translation regime and +further ensures that the resulting physical address is located in Non-secure +DRAM. + +Function: void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr) [optional] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + Argument: uint64_t + Argument: unsigned int + Return: void + +|SDEI| specification requires that a PE comes out of reset with the events +masked. The client therefore is expected to call ``PE_UNMASK`` to unmask +|SDEI| events on the PE. No |SDEI| events can be dispatched until such +time. + +Should a PE receive an interrupt that was bound to an |SDEI| event while the +events are masked on the PE, the dispatcher implementation invokes the function +``plat_sdei_handle_masked_trigger``. The MPIDR of the PE that received the +interrupt and the interrupt ID are passed as parameters. + +The default implementation only prints out a warning message. + +.. _porting_guide_trng_requirements: + +TRNG porting requirements +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The |TRNG| backend requires the platform to provide the following values +and mandatory functions. + +Values +...... + +value: uuid_t plat_trng_uuid [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This value must be defined to the UUID of the TRNG backend that is specific to +the hardware after ``plat_entropy_setup`` function is called. This value must +conform to the SMCCC calling convention; The most significant 32 bits of the +UUID must not equal ``0xffffffff`` or the signed integer ``-1`` as this value in +w0 indicates failure to get a TRNG source. + +Functions +......... + +Function: void plat_entropy_setup(void) [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + Argument: none + Return: none + +This function is expected to do platform-specific initialization of any TRNG +hardware. This may include generating a UUID from a hardware-specific seed. + +Function: bool plat_get_entropy(uint64_t \*out) [mandatory] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + Argument: uint64_t * + Return: bool + Out : when the return value is true, the entropy has been written into the + storage pointed to + +This function writes entropy into storage provided by the caller. If no entropy +is available, it must return false and the storage must not be written. + +Power State Coordination Interface (in BL31) +-------------------------------------------- + +The TF-A implementation of the PSCI API is based around the concept of a +*power domain*. A *power domain* is a CPU or a logical group of CPUs which +share some state on which power management operations can be performed as +specified by `PSCI`_. Each CPU in the system is assigned a cpu index which is +a unique number between ``0`` and ``PLATFORM_CORE_COUNT - 1``. The +*power domains* are arranged in a hierarchical tree structure and each +*power domain* can be identified in a system by the cpu index of any CPU that +is part of that domain and a *power domain level*. A processing element (for +example, a CPU) is at level 0. If the *power domain* node above a CPU is a +logical grouping of CPUs that share some state, then level 1 is that group of +CPUs (for example, a cluster), and level 2 is a group of clusters (for +example, the system). More details on the power domain topology and its +organization can be found in :ref:`PSCI Power Domain Tree Structure`. + +BL31's platform initialization code exports a pointer to the platform-specific +power management operations required for the PSCI implementation to function +correctly. This information is populated in the ``plat_psci_ops`` structure. The +PSCI implementation calls members of the ``plat_psci_ops`` structure for performing +power management operations on the power domains. For example, the target +CPU is specified by its ``MPIDR`` in a PSCI ``CPU_ON`` call. The ``pwr_domain_on()`` +handler (if present) is called for the CPU power domain. + +The ``power-state`` parameter of a PSCI ``CPU_SUSPEND`` call can be used to +describe composite power states specific to a platform. The PSCI implementation +defines a generic representation of the power-state parameter, which is an +array of local power states where each index corresponds to a power domain +level. Each entry contains the local power state the power domain at that power +level could enter. It depends on the ``validate_power_state()`` handler to +convert the power-state parameter (possibly encoding a composite power state) +passed in a PSCI ``CPU_SUSPEND`` call to this representation. + +The following functions form part of platform port of PSCI functionality. + +Function : plat_psci_stat_accounting_start() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : const psci_power_state_t * + Return : void + +This is an optional hook that platforms can implement for residency statistics +accounting before entering a low power state. The ``pwr_domain_state`` field of +``state_info`` (first argument) can be inspected if stat accounting is done +differently at CPU level versus higher levels. As an example, if the element at +index 0 (CPU power level) in the ``pwr_domain_state`` array indicates a power down +state, special hardware logic may be programmed in order to keep track of the +residency statistics. For higher levels (array indices > 0), the residency +statistics could be tracked in software using PMF. If ``ENABLE_PMF`` is set, the +default implementation will use PMF to capture timestamps. + +Function : plat_psci_stat_accounting_stop() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : const psci_power_state_t * + Return : void + +This is an optional hook that platforms can implement for residency statistics +accounting after exiting from a low power state. The ``pwr_domain_state`` field +of ``state_info`` (first argument) can be inspected if stat accounting is done +differently at CPU level versus higher levels. As an example, if the element at +index 0 (CPU power level) in the ``pwr_domain_state`` array indicates a power down +state, special hardware logic may be programmed in order to keep track of the +residency statistics. For higher levels (array indices > 0), the residency +statistics could be tracked in software using PMF. If ``ENABLE_PMF`` is set, the +default implementation will use PMF to capture timestamps. + +Function : plat_psci_stat_get_residency() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int, const psci_power_state_t *, unsigned int + Return : u_register_t + +This is an optional interface that is is invoked after resuming from a low power +state and provides the time spent resident in that low power state by the power +domain at a particular power domain level. When a CPU wakes up from suspend, +all its parent power domain levels are also woken up. The generic PSCI code +invokes this function for each parent power domain that is resumed and it +identified by the ``lvl`` (first argument) parameter. The ``state_info`` (second +argument) describes the low power state that the power domain has resumed from. +The current CPU is the first CPU in the power domain to resume from the low +power state and the ``last_cpu_idx`` (third parameter) is the index of the last +CPU in the power domain to suspend and may be needed to calculate the residency +for that power domain. + +Function : plat_get_target_pwr_state() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int, const plat_local_state_t *, unsigned int + Return : plat_local_state_t + +The PSCI generic code uses this function to let the platform participate in +state coordination during a power management operation. The function is passed +a pointer to an array of platform specific local power state ``states`` (second +argument) which contains the requested power state for each CPU at a particular +power domain level ``lvl`` (first argument) within the power domain. The function +is expected to traverse this array of upto ``ncpus`` (third argument) and return +a coordinated target power state by the comparing all the requested power +states. The target power state should not be deeper than any of the requested +power states. + +A weak definition of this API is provided by default wherein it assumes +that the platform assigns a local state value in order of increasing depth +of the power state i.e. for two power states X & Y, if X < Y +then X represents a shallower power state than Y. As a result, the +coordinated target local power state for a power domain will be the minimum +of the requested local power state values. + +Function : plat_get_power_domain_tree_desc() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : const unsigned char * + +This function returns a pointer to the byte array containing the power domain +topology tree description. The format and method to construct this array are +described in :ref:`PSCI Power Domain Tree Structure`. The BL31 PSCI +initialization code requires this array to be described by the platform, either +statically or dynamically, to initialize the power domain topology tree. In case +the array is populated dynamically, then plat_core_pos_by_mpidr() and +plat_my_core_pos() should also be implemented suitably so that the topology tree +description matches the CPU indices returned by these APIs. These APIs together +form the platform interface for the PSCI topology framework. + +Function : plat_setup_psci_ops() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uintptr_t, const plat_psci_ops ** + Return : int + +This function may execute with the MMU and data caches enabled if the platform +port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only +called by the primary CPU. + +This function is called by PSCI initialization code. Its purpose is to let +the platform layer know about the warm boot entrypoint through the +``sec_entrypoint`` (first argument) and to export handler routines for +platform-specific psci power management actions by populating the passed +pointer with a pointer to BL31's private ``plat_psci_ops`` structure. + +A description of each member of this structure is given below. Please refer to +the Arm FVP specific implementation of these handlers in +``plat/arm/board/fvp/fvp_pm.c`` as an example. For each PSCI function that the +platform wants to support, the associated operation or operations in this +structure must be provided and implemented (Refer section 4 of +:ref:`Firmware Design` for the PSCI API supported in TF-A). To disable a PSCI +function in a platform port, the operation should be removed from this +structure instead of providing an empty implementation. + +plat_psci_ops.cpu_standby() +........................... + +Perform the platform-specific actions to enter the standby state for a cpu +indicated by the passed argument. This provides a fast path for CPU standby +wherein overheads of PSCI state management and lock acquisition is avoided. +For this handler to be invoked by the PSCI ``CPU_SUSPEND`` API implementation, +the suspend state type specified in the ``power-state`` parameter should be +STANDBY and the target power domain level specified should be the CPU. The +handler should put the CPU into a low power retention state (usually by +issuing a wfi instruction) and ensure that it can be woken up from that +state by a normal interrupt. The generic code expects the handler to succeed. + +plat_psci_ops.pwr_domain_on() +............................. + +Perform the platform specific actions to power on a CPU, specified +by the ``MPIDR`` (first argument). The generic code expects the platform to +return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure. + +plat_psci_ops.pwr_domain_off() +.............................. + +Perform the platform specific actions to prepare to power off the calling CPU +and its higher parent power domain levels as indicated by the ``target_state`` +(first argument). It is called by the PSCI ``CPU_OFF`` API implementation. + +The ``target_state`` encodes the platform coordinated target local power states +for the CPU power domain and its parent power domain levels. The handler +needs to perform power management operation corresponding to the local state +at each power level. + +For this handler, the local power state for the CPU power domain will be a +power down state where as it could be either power down, retention or run state +for the higher power domain levels depending on the result of state +coordination. The generic code expects the handler to succeed. + +plat_psci_ops.pwr_domain_suspend_pwrdown_early() [optional] +........................................................... + +This optional function may be used as a performance optimization to replace +or complement pwr_domain_suspend() on some platforms. Its calling semantics +are identical to pwr_domain_suspend(), except the PSCI implementation only +calls this function when suspending to a power down state, and it guarantees +that data caches are enabled. + +When HW_ASSISTED_COHERENCY = 0, the PSCI implementation disables data caches +before calling pwr_domain_suspend(). If the target_state corresponds to a +power down state and it is safe to perform some or all of the platform +specific actions in that function with data caches enabled, it may be more +efficient to move those actions to this function. When HW_ASSISTED_COHERENCY += 1, data caches remain enabled throughout, and so there is no advantage to +moving platform specific actions to this function. + +plat_psci_ops.pwr_domain_suspend() +.................................. + +Perform the platform specific actions to prepare to suspend the calling +CPU and its higher parent power domain levels as indicated by the +``target_state`` (first argument). It is called by the PSCI ``CPU_SUSPEND`` +API implementation. + +The ``target_state`` has a similar meaning as described in +the ``pwr_domain_off()`` operation. It encodes the platform coordinated +target local power states for the CPU power domain and its parent +power domain levels. The handler needs to perform power management operation +corresponding to the local state at each power level. The generic code +expects the handler to succeed. + +The difference between turning a power domain off versus suspending it is that +in the former case, the power domain is expected to re-initialize its state +when it is next powered on (see ``pwr_domain_on_finish()``). In the latter +case, the power domain is expected to save enough state so that it can resume +execution by restoring this state when its powered on (see +``pwr_domain_suspend_finish()``). + +When suspending a core, the platform can also choose to power off the GICv3 +Redistributor and ITS through an implementation-defined sequence. To achieve +this safely, the ITS context must be saved first. The architectural part is +implemented by the ``gicv3_its_save_disable()`` helper, but most of the needed +sequence is implementation defined and it is therefore the responsibility of +the platform code to implement the necessary sequence. Then the GIC +Redistributor context can be saved using the ``gicv3_rdistif_save()`` helper. +Powering off the Redistributor requires the implementation to support it and it +is the responsibility of the platform code to execute the right implementation +defined sequence. + +When a system suspend is requested, the platform can also make use of the +``gicv3_distif_save()`` helper to save the context of the GIC Distributor after +it has saved the context of the Redistributors and ITS of all the cores in the +system. The context of the Distributor can be large and may require it to be +allocated in a special area if it cannot fit in the platform's global static +data, for example in DRAM. The Distributor can then be powered down using an +implementation-defined sequence. + +plat_psci_ops.pwr_domain_pwr_down_wfi() +....................................... + +This is an optional function and, if implemented, is expected to perform +platform specific actions including the ``wfi`` invocation which allows the +CPU to powerdown. Since this function is invoked outside the PSCI locks, +the actions performed in this hook must be local to the CPU or the platform +must ensure that races between multiple CPUs cannot occur. + +The ``target_state`` has a similar meaning as described in the ``pwr_domain_off()`` +operation and it encodes the platform coordinated target local power states for +the CPU power domain and its parent power domain levels. This function must +not return back to the caller (by calling wfi in an infinite loop to ensure +some CPUs power down mitigations work properly). + +If this function is not implemented by the platform, PSCI generic +implementation invokes ``psci_power_down_wfi()`` for power down. + +plat_psci_ops.pwr_domain_on_finish() +.................................... + +This function is called by the PSCI implementation after the calling CPU is +powered on and released from reset in response to an earlier PSCI ``CPU_ON`` call. +It performs the platform-specific setup required to initialize enough state for +this CPU to enter the normal world and also provide secure runtime firmware +services. + +The ``target_state`` (first argument) is the prior state of the power domains +immediately before the CPU was turned on. It indicates which power domains +above the CPU might require initialization due to having previously been in +low power states. The generic code expects the handler to succeed. + +plat_psci_ops.pwr_domain_on_finish_late() [optional] +........................................................... + +This optional function is called by the PSCI implementation after the calling +CPU is fully powered on with respective data caches enabled. The calling CPU and +the associated cluster are guaranteed to be participating in coherency. This +function gives the flexibility to perform any platform-specific actions safely, +such as initialization or modification of shared data structures, without the +overhead of explicit cache maintainace operations. + +The ``target_state`` has a similar meaning as described in the ``pwr_domain_on_finish()`` +operation. The generic code expects the handler to succeed. + +plat_psci_ops.pwr_domain_suspend_finish() +......................................... + +This function is called by the PSCI implementation after the calling CPU is +powered on and released from reset in response to an asynchronous wakeup +event, for example a timer interrupt that was programmed by the CPU during the +``CPU_SUSPEND`` call or ``SYSTEM_SUSPEND`` call. It performs the platform-specific +setup required to restore the saved state for this CPU to resume execution +in the normal world and also provide secure runtime firmware services. + +The ``target_state`` (first argument) has a similar meaning as described in +the ``pwr_domain_on_finish()`` operation. The generic code expects the platform +to succeed. + +If the Distributor, Redistributors or ITS have been powered off as part of a +suspend, their context must be restored in this function in the reverse order +to how they were saved during suspend sequence. + +plat_psci_ops.system_off() +.......................... + +This function is called by PSCI implementation in response to a ``SYSTEM_OFF`` +call. It performs the platform-specific system poweroff sequence after +notifying the Secure Payload Dispatcher. + +plat_psci_ops.system_reset() +............................ + +This function is called by PSCI implementation in response to a ``SYSTEM_RESET`` +call. It performs the platform-specific system reset sequence after +notifying the Secure Payload Dispatcher. + +plat_psci_ops.validate_power_state() +.................................... + +This function is called by the PSCI implementation during the ``CPU_SUSPEND`` +call to validate the ``power_state`` parameter of the PSCI API and if valid, +populate it in ``req_state`` (second argument) array as power domain level +specific local states. If the ``power_state`` is invalid, the platform must +return PSCI_E_INVALID_PARAMS as error, which is propagated back to the +normal world PSCI client. + +plat_psci_ops.validate_ns_entrypoint() +...................................... + +This function is called by the PSCI implementation during the ``CPU_SUSPEND``, +``SYSTEM_SUSPEND`` and ``CPU_ON`` calls to validate the non-secure ``entry_point`` +parameter passed by the normal world. If the ``entry_point`` is invalid, +the platform must return PSCI_E_INVALID_ADDRESS as error, which is +propagated back to the normal world PSCI client. + +plat_psci_ops.get_sys_suspend_power_state() +........................................... + +This function is called by the PSCI implementation during the ``SYSTEM_SUSPEND`` +call to get the ``req_state`` parameter from platform which encodes the power +domain level specific local states to suspend to system affinity level. The +``req_state`` will be utilized to do the PSCI state coordination and +``pwr_domain_suspend()`` will be invoked with the coordinated target state to +enter system suspend. + +plat_psci_ops.get_pwr_lvl_state_idx() +..................................... + +This is an optional function and, if implemented, is invoked by the PSCI +implementation to convert the ``local_state`` (first argument) at a specified +``pwr_lvl`` (second argument) to an index between 0 and +``PLAT_MAX_PWR_LVL_STATES`` - 1. This function is only needed if the platform +supports more than two local power states at each power domain level, that is +``PLAT_MAX_PWR_LVL_STATES`` is greater than 2, and needs to account for these +local power states. + +plat_psci_ops.translate_power_state_by_mpidr() +.............................................. + +This is an optional function and, if implemented, verifies the ``power_state`` +(second argument) parameter of the PSCI API corresponding to a target power +domain. The target power domain is identified by using both ``MPIDR`` (first +argument) and the power domain level encoded in ``power_state``. The power domain +level specific local states are to be extracted from ``power_state`` and be +populated in the ``output_state`` (third argument) array. The functionality +is similar to the ``validate_power_state`` function described above and is +envisaged to be used in case the validity of ``power_state`` depend on the +targeted power domain. If the ``power_state`` is invalid for the targeted power +domain, the platform must return PSCI_E_INVALID_PARAMS as error. If this +function is not implemented, then the generic implementation relies on +``validate_power_state`` function to translate the ``power_state``. + +This function can also be used in case the platform wants to support local +power state encoding for ``power_state`` parameter of PSCI_STAT_COUNT/RESIDENCY +APIs as described in Section 5.18 of `PSCI`_. + +plat_psci_ops.get_node_hw_state() +................................. + +This is an optional function. If implemented this function is intended to return +the power state of a node (identified by the first parameter, the ``MPIDR``) in +the power domain topology (identified by the second parameter, ``power_level``), +as retrieved from a power controller or equivalent component on the platform. +Upon successful completion, the implementation must map and return the final +status among ``HW_ON``, ``HW_OFF`` or ``HW_STANDBY``. Upon encountering failures, it +must return either ``PSCI_E_INVALID_PARAMS`` or ``PSCI_E_NOT_SUPPORTED`` as +appropriate. + +Implementations are not expected to handle ``power_levels`` greater than +``PLAT_MAX_PWR_LVL``. + +plat_psci_ops.system_reset2() +............................. + +This is an optional function. If implemented this function is +called during the ``SYSTEM_RESET2`` call to perform a reset +based on the first parameter ``reset_type`` as specified in +`PSCI`_. The parameter ``cookie`` can be used to pass additional +reset information. If the ``reset_type`` is not supported, the +function must return ``PSCI_E_NOT_SUPPORTED``. For architectural +resets, all failures must return ``PSCI_E_INVALID_PARAMETERS`` +and vendor reset can return other PSCI error codes as defined +in `PSCI`_. On success this function will not return. + +plat_psci_ops.write_mem_protect() +................................. + +This is an optional function. If implemented it enables or disables the +``MEM_PROTECT`` functionality based on the value of ``val``. +A non-zero value enables ``MEM_PROTECT`` and a value of zero +disables it. Upon encountering failures it must return a negative value +and on success it must return 0. + +plat_psci_ops.read_mem_protect() +................................ + +This is an optional function. If implemented it returns the current +state of ``MEM_PROTECT`` via the ``val`` parameter. Upon encountering +failures it must return a negative value and on success it must +return 0. + +plat_psci_ops.mem_protect_chk() +............................... + +This is an optional function. If implemented it checks if a memory +region defined by a base address ``base`` and with a size of ``length`` +bytes is protected by ``MEM_PROTECT``. If the region is protected +then it must return 0, otherwise it must return a negative number. + +.. _porting_guide_imf_in_bl31: + +Interrupt Management framework (in BL31) +---------------------------------------- + +BL31 implements an Interrupt Management Framework (IMF) to manage interrupts +generated in either security state and targeted to EL1 or EL2 in the non-secure +state or EL3/S-EL1 in the secure state. The design of this framework is +described in the :ref:`Interrupt Management Framework` + +A platform should export the following APIs to support the IMF. The following +text briefly describes each API and its implementation in Arm standard +platforms. The API implementation depends upon the type of interrupt controller +present in the platform. Arm standard platform layer supports both +`Arm Generic Interrupt Controller version 2.0 (GICv2)`_ +and `3.0 (GICv3)`_. Juno builds the Arm platform layer to use GICv2 and the +FVP can be configured to use either GICv2 or GICv3 depending on the build flag +``FVP_USE_GIC_DRIVER`` (See :ref:`build_options_arm_fvp_platform` for more +details). + +See also: :ref:`Interrupt Controller Abstraction APIs<Platform Interrupt Controller API>`. + +Function : plat_interrupt_type_to_line() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint32_t, uint32_t + Return : uint32_t + +The Arm processor signals an interrupt exception either through the IRQ or FIQ +interrupt line. The specific line that is signaled depends on how the interrupt +controller (IC) reports different interrupt types from an execution context in +either security state. The IMF uses this API to determine which interrupt line +the platform IC uses to signal each type of interrupt supported by the framework +from a given security state. This API must be invoked at EL3. + +The first parameter will be one of the ``INTR_TYPE_*`` values (see +:ref:`Interrupt Management Framework`) indicating the target type of the +interrupt, the second parameter is the security state of the originating +execution context. The return result is the bit position in the ``SCR_EL3`` +register of the respective interrupt trap: IRQ=1, FIQ=2. + +In the case of Arm standard platforms using GICv2, S-EL1 interrupts are +configured as FIQs and Non-secure interrupts as IRQs from either security +state. + +In the case of Arm standard platforms using GICv3, the interrupt line to be +configured depends on the security state of the execution context when the +interrupt is signalled and are as follows: + +- The S-EL1 interrupts are signaled as IRQ in S-EL0/1 context and as FIQ in + NS-EL0/1/2 context. +- The Non secure interrupts are signaled as FIQ in S-EL0/1 context and as IRQ + in the NS-EL0/1/2 context. +- The EL3 interrupts are signaled as FIQ in both S-EL0/1 and NS-EL0/1/2 + context. + +Function : plat_ic_get_pending_interrupt_type() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint32_t + +This API returns the type of the highest priority pending interrupt at the +platform IC. The IMF uses the interrupt type to retrieve the corresponding +handler function. ``INTR_TYPE_INVAL`` is returned when there is no interrupt +pending. The valid interrupt types that can be returned are ``INTR_TYPE_EL3``, +``INTR_TYPE_S_EL1`` and ``INTR_TYPE_NS``. This API must be invoked at EL3. + +In the case of Arm standard platforms using GICv2, the *Highest Priority +Pending Interrupt Register* (``GICC_HPPIR``) is read to determine the id of +the pending interrupt. The type of interrupt depends upon the id value as +follows. + +#. id < 1022 is reported as a S-EL1 interrupt +#. id = 1022 is reported as a Non-secure interrupt. +#. id = 1023 is reported as an invalid interrupt type. + +In the case of Arm standard platforms using GICv3, the system register +``ICC_HPPIR0_EL1``, *Highest Priority Pending group 0 Interrupt Register*, +is read to determine the id of the pending interrupt. The type of interrupt +depends upon the id value as follows. + +#. id = ``PENDING_G1S_INTID`` (1020) is reported as a S-EL1 interrupt +#. id = ``PENDING_G1NS_INTID`` (1021) is reported as a Non-secure interrupt. +#. id = ``GIC_SPURIOUS_INTERRUPT`` (1023) is reported as an invalid interrupt type. +#. All other interrupt id's are reported as EL3 interrupt. + +Function : plat_ic_get_pending_interrupt_id() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint32_t + +This API returns the id of the highest priority pending interrupt at the +platform IC. ``INTR_ID_UNAVAILABLE`` is returned when there is no interrupt +pending. + +In the case of Arm standard platforms using GICv2, the *Highest Priority +Pending Interrupt Register* (``GICC_HPPIR``) is read to determine the id of the +pending interrupt. The id that is returned by API depends upon the value of +the id read from the interrupt controller as follows. + +#. id < 1022. id is returned as is. +#. id = 1022. The *Aliased Highest Priority Pending Interrupt Register* + (``GICC_AHPPIR``) is read to determine the id of the non-secure interrupt. + This id is returned by the API. +#. id = 1023. ``INTR_ID_UNAVAILABLE`` is returned. + +In the case of Arm standard platforms using GICv3, if the API is invoked from +EL3, the system register ``ICC_HPPIR0_EL1``, *Highest Priority Pending Interrupt +group 0 Register*, is read to determine the id of the pending interrupt. The id +that is returned by API depends upon the value of the id read from the +interrupt controller as follows. + +#. id < ``PENDING_G1S_INTID`` (1020). id is returned as is. +#. id = ``PENDING_G1S_INTID`` (1020) or ``PENDING_G1NS_INTID`` (1021). The system + register ``ICC_HPPIR1_EL1``, *Highest Priority Pending Interrupt group 1 + Register* is read to determine the id of the group 1 interrupt. This id + is returned by the API as long as it is a valid interrupt id +#. If the id is any of the special interrupt identifiers, + ``INTR_ID_UNAVAILABLE`` is returned. + +When the API invoked from S-EL1 for GICv3 systems, the id read from system +register ``ICC_HPPIR1_EL1``, *Highest Priority Pending group 1 Interrupt +Register*, is returned if is not equal to GIC_SPURIOUS_INTERRUPT (1023) else +``INTR_ID_UNAVAILABLE`` is returned. + +Function : plat_ic_acknowledge_interrupt() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : uint32_t + +This API is used by the CPU to indicate to the platform IC that processing of +the highest pending interrupt has begun. It should return the raw, unmodified +value obtained from the interrupt controller when acknowledging an interrupt. +The actual interrupt number shall be extracted from this raw value using the API +`plat_ic_get_interrupt_id()<plat_ic_get_interrupt_id>`. + +This function in Arm standard platforms using GICv2, reads the *Interrupt +Acknowledge Register* (``GICC_IAR``). This changes the state of the highest +priority pending interrupt from pending to active in the interrupt controller. +It returns the value read from the ``GICC_IAR``, unmodified. + +In the case of Arm standard platforms using GICv3, if the API is invoked +from EL3, the function reads the system register ``ICC_IAR0_EL1``, *Interrupt +Acknowledge Register group 0*. If the API is invoked from S-EL1, the function +reads the system register ``ICC_IAR1_EL1``, *Interrupt Acknowledge Register +group 1*. The read changes the state of the highest pending interrupt from +pending to active in the interrupt controller. The value read is returned +unmodified. + +The TSP uses this API to start processing of the secure physical timer +interrupt. + +Function : plat_ic_end_of_interrupt() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint32_t + Return : void + +This API is used by the CPU to indicate to the platform IC that processing of +the interrupt corresponding to the id (passed as the parameter) has +finished. The id should be the same as the id returned by the +``plat_ic_acknowledge_interrupt()`` API. + +Arm standard platforms write the id to the *End of Interrupt Register* +(``GICC_EOIR``) in case of GICv2, and to ``ICC_EOIR0_EL1`` or ``ICC_EOIR1_EL1`` +system register in case of GICv3 depending on where the API is invoked from, +EL3 or S-EL1. This deactivates the corresponding interrupt in the interrupt +controller. + +The TSP uses this API to finish processing of the secure physical timer +interrupt. + +Function : plat_ic_get_interrupt_type() [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint32_t + Return : uint32_t + +This API returns the type of the interrupt id passed as the parameter. +``INTR_TYPE_INVAL`` is returned if the id is invalid. If the id is valid, a valid +interrupt type (one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1`` and ``INTR_TYPE_NS``) is +returned depending upon how the interrupt has been configured by the platform +IC. This API must be invoked at EL3. + +Arm standard platforms using GICv2 configures S-EL1 interrupts as Group0 interrupts +and Non-secure interrupts as Group1 interrupts. It reads the group value +corresponding to the interrupt id from the relevant *Interrupt Group Register* +(``GICD_IGROUPRn``). It uses the group value to determine the type of interrupt. + +In the case of Arm standard platforms using GICv3, both the *Interrupt Group +Register* (``GICD_IGROUPRn``) and *Interrupt Group Modifier Register* +(``GICD_IGRPMODRn``) is read to figure out whether the interrupt is configured +as Group 0 secure interrupt, Group 1 secure interrupt or Group 1 NS interrupt. + +Common helper functions +----------------------- + +Function : do_panic() +~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This API is called from assembly files when encountering a critical failure that +cannot be recovered from. It also invokes elx_panic() which allows to report a +crash from lower exception level. This function assumes that it is invoked from +a C runtime environment i.e. valid stack exists. This call **must not** return. + +Function : panic() +~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This API called from C files when encountering a critical failure that cannot +be recovered from. This function in turn prints backtrace (if enabled) and calls +do_panic(). This call **must not** return. + +Crash Reporting mechanism (in BL31) +----------------------------------- + +BL31 implements a crash reporting mechanism which prints the various registers +of the CPU to enable quick crash analysis and debugging. This mechanism relies +on the platform implementing ``plat_crash_console_init``, +``plat_crash_console_putc`` and ``plat_crash_console_flush``. + +The file ``plat/common/aarch64/crash_console_helpers.S`` contains sample +implementation of all of them. Platforms may include this file to their +makefiles in order to benefit from them. By default, they will cause the crash +output to be routed over the normal console infrastructure and get printed on +consoles configured to output in crash state. ``console_set_scope()`` can be +used to control whether a console is used for crash output. + +.. note:: + Platforms are responsible for making sure that they only mark consoles for + use in the crash scope that are able to support this, i.e. that are written + in assembly and conform with the register clobber rules for putc() + (x0-x2, x16-x17) and flush() (x0-x3, x16-x17) crash callbacks. + +In some cases (such as debugging very early crashes that happen before the +normal boot console can be set up), platforms may want to control crash output +more explicitly. These platforms may instead provide custom implementations for +these. They are executed outside of a C environment and without a stack. Many +console drivers provide functions named ``console_xxx_core_init/putc/flush`` +that are designed to be used by these functions. See Arm platforms (like juno) +for an example of this. + +Function : plat_crash_console_init [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int + +This API is used by the crash reporting mechanism to initialize the crash +console. It must only use the general purpose registers x0 through x7 to do the +initialization and returns 1 on success. + +Function : plat_crash_console_putc [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : int + Return : int + +This API is used by the crash reporting mechanism to print a character on the +designated crash console. It must only use general purpose registers x1 and +x2 to do its work. The parameter and the return value are in general purpose +register x0. + +Function : plat_crash_console_flush [mandatory] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This API is used by the crash reporting mechanism to force write of all buffered +data on the designated crash console. It should only use general purpose +registers x0 through x5 to do its work. + +.. _External Abort handling and RAS Support: + +External Abort handling and RAS Support +--------------------------------------- + +Function : plat_ea_handler +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : int + Argument : uint64_t + Argument : void * + Argument : void * + Argument : uint64_t + Return : void + +This function is invoked by the RAS framework for the platform to handle an +External Abort received at EL3. The intention of the function is to attempt to +resolve the cause of External Abort and return; if that's not possible, to +initiate orderly shutdown of the system. + +The first parameter (``int ea_reason``) indicates the reason for External Abort. +Its value is one of ``ERROR_EA_*`` constants defined in ``ea_handle.h``. + +The second parameter (``uint64_t syndrome``) is the respective syndrome +presented to EL3 after having received the External Abort. Depending on the +nature of the abort (as can be inferred from the ``ea_reason`` parameter), this +can be the content of either ``ESR_EL3`` or ``DISR_EL1``. + +The third parameter (``void *cookie``) is unused for now. The fourth parameter +(``void *handle``) is a pointer to the preempted context. The fifth parameter +(``uint64_t flags``) indicates the preempted security state. These parameters +are received from the top-level exception handler. + +If ``RAS_EXTENSION`` is set to ``1``, the default implementation of this +function iterates through RAS handlers registered by the platform. If any of the +RAS handlers resolve the External Abort, no further action is taken. + +If ``RAS_EXTENSION`` is set to ``0``, or if none of the platform RAS handlers +could resolve the External Abort, the default implementation prints an error +message, and panics. + +Function : plat_handle_uncontainable_ea +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : int + Argument : uint64_t + Return : void + +This function is invoked by the RAS framework when an External Abort of +Uncontainable type is received at EL3. Due to the critical nature of +Uncontainable errors, the intention of this function is to initiate orderly +shutdown of the system, and is not expected to return. + +This function must be implemented in assembly. + +The first and second parameters are the same as that of ``plat_ea_handler``. + +The default implementation of this function calls +``report_unhandled_exception``. + +Function : plat_handle_double_fault +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : int + Argument : uint64_t + Return : void + +This function is invoked by the RAS framework when another External Abort is +received at EL3 while one is already being handled. I.e., a call to +``plat_ea_handler`` is outstanding. Due to its critical nature, the intention of +this function is to initiate orderly shutdown of the system, and is not expected +recover or return. + +This function must be implemented in assembly. + +The first and second parameters are the same as that of ``plat_ea_handler``. + +The default implementation of this function calls +``report_unhandled_exception``. + +Function : plat_handle_el3_ea +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Return : void + +This function is invoked when an External Abort is received while executing in +EL3. Due to its critical nature, the intention of this function is to initiate +orderly shutdown of the system, and is not expected recover or return. + +This function must be implemented in assembly. + +The default implementation of this function calls +``report_unhandled_exception``. + +Build flags +----------- + +There are some build flags which can be defined by the platform to control +inclusion or exclusion of certain BL stages from the FIP image. These flags +need to be defined in the platform makefile which will get included by the +build system. + +- **NEED_BL33** + By default, this flag is defined ``yes`` by the build system and ``BL33`` + build option should be supplied as a build option. The platform has the + option of excluding the BL33 image in the ``fip`` image by defining this flag + to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE`` + are used, this flag will be set to ``no`` automatically. + +Platform include paths +---------------------- + +Platforms are allowed to add more include paths to be passed to the compiler. +The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in +particular for the file ``platform_def.h``. + +Example: + +.. code:: c + + PLAT_INCLUDES += -Iinclude/plat/myplat/include + +C Library +--------- + +To avoid subtle toolchain behavioral dependencies, the header files provided +by the compiler are not used. The software is built with the ``-nostdinc`` flag +to ensure no headers are included from the toolchain inadvertently. Instead the +required headers are included in the TF-A source tree. The library only +contains those C library definitions required by the local implementation. If +more functionality is required, the needed library functions will need to be +added to the local implementation. + +Some C headers have been obtained from `FreeBSD`_ and `SCC`_, while others have +been written specifically for TF-A. Some implementation files have been obtained +from `FreeBSD`_, others have been written specifically for TF-A as well. The +files can be found in ``include/lib/libc`` and ``lib/libc``. + +SCC can be found in http://www.simple-cc.org/. A copy of the `FreeBSD`_ sources +can be obtained from http://github.com/freebsd/freebsd. + +Storage abstraction layer +------------------------- + +In order to improve platform independence and portability a storage abstraction +layer is used to load data from non-volatile platform storage. Currently +storage access is only required by BL1 and BL2 phases and performed inside the +``load_image()`` function in ``bl_common.c``. + +.. uml:: ../resources/diagrams/plantuml/io_framework_usage_overview.puml + +It is mandatory to implement at least one storage driver. For the Arm +development platforms the Firmware Image Package (FIP) driver is provided as +the default means to load data from storage (see :ref:`firmware_design_fip`). +The storage layer is described in the header file +``include/drivers/io/io_storage.h``. The implementation of the common library is +in ``drivers/io/io_storage.c`` and the driver files are located in +``drivers/io/``. + +.. uml:: ../resources/diagrams/plantuml/io_arm_class_diagram.puml + +Each IO driver must provide ``io_dev_*`` structures, as described in +``drivers/io/io_driver.h``. These are returned via a mandatory registration +function that is called on platform initialization. The semi-hosting driver +implementation in ``io_semihosting.c`` can be used as an example. + +Each platform should register devices and their drivers via the storage +abstraction layer. These drivers then need to be initialized by bootloader +phases as required in their respective ``blx_platform_setup()`` functions. + +.. uml:: ../resources/diagrams/plantuml/io_dev_registration.puml + +The storage abstraction layer provides mechanisms (``io_dev_init()``) to +initialize storage devices before IO operations are called. + +.. uml:: ../resources/diagrams/plantuml/io_dev_init_and_check.puml + +The basic operations supported by the layer +include ``open()``, ``close()``, ``read()``, ``write()``, ``size()`` and ``seek()``. +Drivers do not have to implement all operations, but each platform must +provide at least one driver for a device capable of supporting generic +operations such as loading a bootloader image. + +The current implementation only allows for known images to be loaded by the +firmware. These images are specified by using their identifiers, as defined in +``include/plat/common/common_def.h`` (or a separate header file included from +there). The platform layer (``plat_get_image_source()``) then returns a reference +to a device and a driver-specific ``spec`` which will be understood by the driver +to allow access to the image data. + +The layer is designed in such a way that is it possible to chain drivers with +other drivers. For example, file-system drivers may be implemented on top of +physical block devices, both represented by IO devices with corresponding +drivers. In such a case, the file-system "binding" with the block device may +be deferred until the file-system device is initialised. + +The abstraction currently depends on structures being statically allocated +by the drivers and callers, as the system does not yet provide a means of +dynamically allocating memory. This may also have the affect of limiting the +amount of open resources per driver. + +-------------- + +*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.* + +.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf +.. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html +.. _3.0 (GICv3): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html +.. _FreeBSD: https://www.freebsd.org +.. _SCC: http://www.simple-cc.org/ +.. _DRTM: https://developer.arm.com/documentation/den0113/a diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst new file mode 100644 index 0000000..3723294 --- /dev/null +++ b/docs/getting_started/prerequisites.rst @@ -0,0 +1,181 @@ +Prerequisites +============= + +This document describes the software requirements for building |TF-A| for +AArch32 and AArch64 target platforms. + +It may possible to build |TF-A| with combinations of software packages that are +different from those listed below, however only the software described in this +document can be officially supported. + +Build Host +---------- + +|TF-A| can be built using either a Linux or a Windows machine as the build host. + +A relatively recent Linux distribution is recommended for building |TF-A|. We +have performed tests using Ubuntu 20.04 LTS (64-bit) but other distributions +should also work fine as a base, provided that the necessary tools and libraries +can be installed. + +.. _prerequisites_toolchain: + +Toolchain +--------- + +|TF-A| can be built with any of the following *cross-compiler* toolchains that +target the Armv7-A or Armv8-A architectures: + +- GCC >= 11.3.Rel1 (from the `Arm Developer website`_) + + You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for + AArch32 and AArch64 builds respectively. + +- Clang >= 14.0.0 +- Arm Compiler >= 6.18 + +In addition, a native compiler is required to build the supporting tools. + +.. note:: + The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE, + Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain. + +.. note:: + For instructions on how to select the cross compiler refer to + :ref:`Performing an Initial Build`. + +.. _prerequisites_software_and_libraries: + +Software and Libraries +---------------------- + +The following tools are required to obtain and build |TF-A|: + +- An appropriate toolchain (see :ref:`prerequisites_toolchain`) +- GNU Make +- Git + +The following libraries must be available to build one or more components or +supporting tools: + +- OpenSSL >= 1.1.1 (v3.0.0 to v3.0.6 highly discouraged due to security issues) + + Required to build the cert_create, encrypt_fw, and fiptool tools. + + .. note:: + + If using OpenSSL 3, older Linux versions may require it to be built from + source code, as it may not be available in the default package repositories. + Please refer to the OpenSSL project documentation for more information. + +The following libraries are required for Trusted Board Boot and Measured Boot +support: + +- mbed TLS == 2.28.1 (tag: ``mbedtls-2.28.1``) + +These tools are optional: + +- Device Tree Compiler (DTC) >= 1.4.6 + + Needed if you want to rebuild the provided Flattened Device Tree (FDT) + source files (``.dts`` files). DTC is available for Linux through the package + repositories of most distributions. + +- Arm `Development Studio (Arm-DS)`_ + + The standard software package used for debugging software on Arm development + platforms and |FVP| models. + +- Node.js >= 16 + + Highly recommended, and necessary in order to install and use the packaged + Git hooks and helper tools. Without these tools you will need to rely on the + CI for feedback on commit message conformance. + +Package Installation (Linux) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you are using the recommended Ubuntu distribution then you can install the +required packages with the following command: + +.. code:: shell + + sudo apt install build-essential git + +The optional packages can be installed using: + +.. code:: shell + + sudo apt install device-tree-compiler + +Additionally, to install a version of Node.js compatible with TF-A's repository +scripts, you can use the `Node Version Manager`_. To install both NVM and an +appropriate version of Node.js, run the following **from the root directory of +the repository**: + +.. code:: shell + + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash + exec "$SHELL" -ic "nvm install; exec $SHELL" + +.. _Node Version Manager: https://github.com/nvm-sh/nvm#install--update-script + +Supporting Files +---------------- + +TF-A has been tested with pre-built binaries and file systems from `Linaro +Release 20.01`_. Alternatively, you can build the binaries from source using +instructions in :ref:`Performing an Initial Build`. + +.. _prerequisites_get_source: + +Getting the TF-A Source +----------------------- + +Source code for |TF-A| is maintained in a Git repository hosted on +TrustedFirmware.org. To clone this repository from the server, run the following +in your shell: + +.. code:: shell + + git clone "https://review.trustedfirmware.org/TF-A/trusted-firmware-a" + +Additional Steps for Contributors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you are planning on contributing back to TF-A, there are some things you'll +want to know. + +TF-A is hosted by a `Gerrit Code Review`_ server. Gerrit requires that all +commits include a ``Change-Id`` footer, and this footer is typically +automatically generated by a Git hook installed by you, the developer. + +If you have Node.js installed already, you can automatically install this hook, +along with any additional hooks and Javascript-based tooling that we use, by +running from within your newly-cloned repository: + +.. code:: shell + + npm install --no-save + +If you have opted **not** to install Node.js, you can install the Gerrit hook +manually by running: + +.. code:: shell + + curl -Lo $(git rev-parse --git-dir)/hooks/commit-msg https://review.trustedfirmware.org/tools/hooks/commit-msg + chmod +x $(git rev-parse --git-dir)/hooks/commit-msg + +You can read more about Git hooks in the *githooks* page of the Git +documentation, available `here <https://git-scm.com/docs/githooks>`_. + +-------------- + +*Copyright (c) 2021-2022, Arm Limited. All rights reserved.* + +.. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads +.. _Gerrit Code Review: https://www.gerritcodereview.com/ +.. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes +.. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables +.. _Development Studio (Arm-DS): https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio +.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01 diff --git a/docs/getting_started/psci-lib-integration-guide.rst b/docs/getting_started/psci-lib-integration-guide.rst new file mode 100644 index 0000000..4d690a9 --- /dev/null +++ b/docs/getting_started/psci-lib-integration-guide.rst @@ -0,0 +1,536 @@ +PSCI Library Integration guide for Armv8-A AArch32 systems +========================================================== + +This document describes the PSCI library interface with a focus on how to +integrate with a suitable Trusted OS for an Armv8-A AArch32 system. The PSCI +Library implements the PSCI Standard as described in `PSCI spec`_ and is meant +to be integrated with EL3 Runtime Software which invokes the PSCI Library +interface appropriately. **EL3 Runtime Software** refers to software executing +at the highest secure privileged mode, which is EL3 in AArch64 or Secure SVC/ +Monitor mode in AArch32, and provides runtime services to the non-secure world. +The runtime service request is made via SMC (Secure Monitor Call) and the call +must adhere to `SMCCC`_. In AArch32, EL3 Runtime Software may additionally +include Trusted OS functionality. A minimal AArch32 Secure Payload, SP-MIN, is +provided in Trusted Firmware-A (TF-A) to illustrate the usage and integration +of the PSCI library. The description of PSCI library interface and its +integration with EL3 Runtime Software in this document is targeted towards +AArch32 systems. + +Generic call sequence for PSCI Library interface (AArch32) +---------------------------------------------------------- + +The generic call sequence of PSCI Library interfaces (see +`PSCI Library Interface`_) during cold boot in AArch32 +system is described below: + +#. After cold reset, the EL3 Runtime Software performs its cold boot + initialization including the PSCI library pre-requisites mentioned in + `PSCI Library Interface`_, and also the necessary platform + setup. + +#. Call ``psci_setup()`` in Monitor mode. + +#. Optionally call ``psci_register_spd_pm_hook()`` to register callbacks to + do bookkeeping for the EL3 Runtime Software during power management. + +#. Call ``psci_prepare_next_non_secure_ctx()`` to initialize the non-secure CPU + context. + +#. Get the non-secure ``cpu_context_t`` for the current CPU by calling + ``cm_get_context()`` , then programming the registers in the non-secure + context and exiting to non-secure world. If the EL3 Runtime Software needs + additional configuration to be set for non-secure context, like routing + FIQs to the secure world, the values of the registers can be modified prior + to programming. See `PSCI CPU context management`_ for more + details on CPU context management. + +The generic call sequence of PSCI library interfaces during warm boot in +AArch32 systems is described below: + +#. After warm reset, the EL3 Runtime Software performs the necessary warm + boot initialization including the PSCI library pre-requisites mentioned in + `PSCI Library Interface`_ (Note that the Data cache + **must not** be enabled). + +#. Call ``psci_warmboot_entrypoint()`` in Monitor mode. This interface + initializes/restores the non-secure CPU context as well. + +#. Do step 5 of the cold boot call sequence described above. + +The generic call sequence of PSCI library interfaces on receipt of a PSCI SMC +on an AArch32 system is described below: + +#. On receipt of an SMC, save the register context as per `SMCCC`_. + +#. If the SMC function identifier corresponds to a SMC32 PSCI API, construct + the appropriate arguments and call the ``psci_smc_handler()`` interface. + The invocation may or may not return back to the caller depending on + whether the PSCI API resulted in power down of the CPU. + +#. If ``psci_smc_handler()`` returns, populate the return value in R0 (AArch32)/ + X0 (AArch64) and restore other registers as per `SMCCC`_. + +PSCI CPU context management +--------------------------- + +PSCI library is in charge of initializing/restoring the non-secure CPU system +registers according to `PSCI specification`_ during cold/warm boot. +This is referred to as ``PSCI CPU Context Management``. Registers that need to +be preserved across CPU power down/power up cycles are maintained in +``cpu_context_t`` data structure. The initialization of other non-secure CPU +system registers which do not require coordination with the EL3 Runtime +Software is done directly by the PSCI library (see ``cm_prepare_el3_exit()``). + +The EL3 Runtime Software is responsible for managing register context +during switch between Normal and Secure worlds. The register context to be +saved and restored depends on the mechanism used to trigger the world switch. +For example, if the world switch was triggered by an SMC call, then the +registers need to be saved and restored according to `SMCCC`_. In AArch64, +due to the tight integration with BL31, both BL31 and PSCI library +use the same ``cpu_context_t`` data structure for PSCI CPU context management +and register context management during world switch. This cannot be assumed +for AArch32 EL3 Runtime Software since most AArch32 Trusted OSes already implement +a mechanism for register context management during world switch. Hence, when +the PSCI library is integrated with a AArch32 EL3 Runtime Software, the +``cpu_context_t`` is stripped down for just PSCI CPU context management. + +During cold/warm boot, after invoking appropriate PSCI library interfaces, it +is expected that the EL3 Runtime Software will query the ``cpu_context_t`` and +write appropriate values to the corresponding system registers. This mechanism +resolves 2 additional problems for AArch32 EL3 Runtime Software: + +#. Values for certain system registers like SCR and SCTLR cannot be + unilaterally determined by PSCI library and need inputs from the EL3 + Runtime Software. Using ``cpu_context_t`` as an intermediary data store + allows EL3 Runtime Software to modify the register values appropriately + before programming them. + +#. The PSCI library provides appropriate LR and SPSR values (entrypoint + information) for exit into non-secure world. Using ``cpu_context_t`` as an + intermediary data store allows the EL3 Runtime Software to store these + values safely until it is ready for exit to non-secure world. + +Currently the ``cpu_context_t`` data structure for AArch32 stores the following +registers: R0 - R3, LR (R14), SCR, SPSR, SCTLR. + +The EL3 Runtime Software must implement accessors to get/set pointers +to CPU context ``cpu_context_t`` data and these are described in +`CPU Context management API`_. + +PSCI Library Interface +---------------------- + +The PSCI library implements the `PSCI Specification`_. The interfaces +to this library are declared in ``psci_lib.h`` and are as listed below: + +.. code:: c + + u_register_t psci_smc_handler(uint32_t 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); + int psci_setup(const psci_lib_args_t *lib_args); + void psci_warmboot_entrypoint(void); + void psci_register_spd_pm_hook(const spd_pm_ops_t *pm); + void psci_prepare_next_non_secure_ctx(entry_point_info_t *next_image_info); + +The CPU context data 'cpu_context_t' is programmed to the registers differently +when PSCI is integrated with an AArch32 EL3 Runtime Software compared to +when the PSCI is integrated with an AArch64 EL3 Runtime Software (BL31). For +example, in the case of AArch64, there is no need to retrieve ``cpu_context_t`` +data and program the registers as it will done implicitly as part of +``el3_exit``. The description below of the PSCI interfaces is targeted at +integration with an AArch32 EL3 Runtime Software. + +The PSCI library is responsible for initializing/restoring the non-secure world +to an appropriate state after boot and may choose to directly program the +non-secure system registers. The PSCI generic code takes care not to directly +modify any of the system registers affecting the secure world and instead +returns the values to be programmed to these registers via ``cpu_context_t``. +The EL3 Runtime Software is responsible for programming those registers and +can use the proposed values provided in the ``cpu_context_t``, modifying the +values if required. + +PSCI library needs the flexibility to access both secure and non-secure +copies of banked registers. Hence it needs to be invoked in Monitor mode +for AArch32 and in EL3 for AArch64. The NS bit in SCR (in AArch32) or SCR_EL3 +(in AArch64) must be set to 0. Additional requirements for the PSCI library +interfaces are: + +- Instruction cache must be enabled +- Both IRQ and FIQ must be masked for the current CPU +- The page tables must be setup and the MMU enabled +- The C runtime environment must be setup and stack initialized +- The Data cache must be enabled prior to invoking any of the PSCI library + interfaces except for ``psci_warmboot_entrypoint()``. For + ``psci_warmboot_entrypoint()``, if the build option ``HW_ASSISTED_COHERENCY`` + is enabled however, data caches are expected to be enabled. + +Further requirements for each interface can be found in the interface +description. + +Interface : psci_setup() +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : const psci_lib_args_t *lib_args + Return : void + +This function is to be called by the primary CPU during cold boot before +any other interface to the PSCI library. It takes ``lib_args``, a const pointer +to ``psci_lib_args_t``, as the argument. The ``psci_lib_args_t`` is a versioned +structure and is declared in ``psci_lib.h`` header as follows: + +.. code:: c + + typedef struct psci_lib_args { + /* The version information of PSCI Library Interface */ + param_header_t h; + /* The warm boot entrypoint function */ + mailbox_entrypoint_t mailbox_ep; + } psci_lib_args_t; + +The first field ``h``, of ``param_header_t`` type, provides the version +information. The second field ``mailbox_ep`` is the warm boot entrypoint address +and is used to configure the platform mailbox. Helper macros are provided in +``psci_lib.h`` to construct the ``lib_args`` argument statically or during +runtime. Prior to calling the ``psci_setup()`` interface, the platform setup for +cold boot must have completed. Major actions performed by this interface are: + +- Initializes architecture. +- Initializes PSCI power domain and state coordination data structures. +- Calls ``plat_setup_psci_ops()`` with warm boot entrypoint ``mailbox_ep`` as + argument. +- Calls ``cm_set_context_by_index()`` (see + `CPU Context management API`_) for all the CPUs in the + platform + +Interface : psci_prepare_next_non_secure_ctx() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : entry_point_info_t *next_image_info + Return : void + +After ``psci_setup()`` and prior to exit to the non-secure world, this function +must be called by the EL3 Runtime Software to initialize the non-secure world +context. The non-secure world entrypoint information ``next_image_info`` (first +argument) will be used to determine the non-secure context. After this function +returns, the EL3 Runtime Software must retrieve the ``cpu_context_t`` (using +cm_get_context()) for the current CPU and program the registers prior to exit +to the non-secure world. + +Interface : psci_register_spd_pm_hook() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : const spd_pm_ops_t * + Return : void + +As explained in `Secure payload power management callback`_, +the EL3 Runtime Software may want to perform some bookkeeping during power +management operations. This function is used to register the ``spd_pm_ops_t`` +(first argument) callbacks with the PSCI library which will be called +appropriately during power management. Calling this function is optional and +need to be called by the primary CPU during the cold boot sequence after +``psci_setup()`` has completed. + +Interface : psci_smc_handler() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : uint32_t 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 : u_register_t + +This function is the top level handler for SMCs which fall within the +PSCI service range specified in `SMCCC`_. The function ID ``smc_fid`` (first +argument) determines the PSCI API to be called. The ``x1`` to ``x4`` (2nd to 5th +arguments), are the values of the registers r1 - r4 (in AArch32) or x1 - x4 +(in AArch64) when the SMC is received. These are the arguments to PSCI API as +described in `PSCI spec`_. The 'flags' (8th argument) is a bit field parameter +and is detailed in 'smccc.h' header. It includes whether the call is from the +secure or non-secure world. The ``cookie`` (6th argument) and the ``handle`` +(7th argument) are not used and are reserved for future use. + +The return value from this interface is the return value from the underlying +PSCI API corresponding to ``smc_fid``. This function may not return back to the +caller if PSCI API causes power down of the CPU. In this case, when the CPU +wakes up, it will start execution from the warm reset address. + +Interface : psci_warmboot_entrypoint() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +This function performs the warm boot initialization/restoration as mandated by +`PSCI spec`_. For AArch32, on wakeup from power down the CPU resets to secure SVC +mode and the EL3 Runtime Software must perform the prerequisite initializations +mentioned at top of this section. This function must be called with Data cache +disabled (unless build option ``HW_ASSISTED_COHERENCY`` is enabled) but with MMU +initialized and enabled. The major actions performed by this function are: + +- Invalidates the stack and enables the data cache. +- Initializes architecture and PSCI state coordination. +- Restores/Initializes the peripheral drivers to the required state via + appropriate ``plat_psci_ops_t`` hooks +- Restores the EL3 Runtime Software context via appropriate ``spd_pm_ops_t`` + callbacks. +- Restores/Initializes the non-secure context and populates the + ``cpu_context_t`` for the current CPU. + +Upon the return of this function, the EL3 Runtime Software must retrieve the +non-secure ``cpu_context_t`` using ``cm_get_context()`` and program the registers +prior to exit to the non-secure world. + +EL3 Runtime Software dependencies +--------------------------------- + +The PSCI Library includes supporting frameworks like context management, +cpu operations (cpu_ops) and per-cpu data framework. Other helper library +functions like bakery locks and spin locks are also included in the library. +The dependencies which must be fulfilled by the EL3 Runtime Software +for integration with PSCI library are described below. + +General dependencies +~~~~~~~~~~~~~~~~~~~~ + +The PSCI library being a Multiprocessor (MP) implementation, EL3 Runtime +Software must provide an SMC handling framework capable of MP adhering to +`SMCCC`_ specification. + +The EL3 Runtime Software must also export cache maintenance primitives +and some helper utilities for assert, print and memory operations as listed +below. The TF-A source tree provides implementations for all +these functions but the EL3 Runtime Software may use its own implementation. + +**Functions : assert(), memcpy(), memset(), printf()** + +These must be implemented as described in ISO C Standard. + +**Function : flush_dcache_range()** + +:: + + Argument : uintptr_t addr, size_t size + Return : void + +This function cleans and invalidates (flushes) the data cache for memory +at address ``addr`` (first argument) address and of size ``size`` (second argument). + +**Function : inv_dcache_range()** + +:: + + Argument : uintptr_t addr, size_t size + Return : void + +This function invalidates (flushes) the data cache for memory at address +``addr`` (first argument) address and of size ``size`` (second argument). + +CPU Context management API +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The CPU context management data memory is statically allocated by PSCI library +in BSS section. The PSCI library requires the EL3 Runtime Software to implement +APIs to store and retrieve pointers to this CPU context data. SP-MIN +demonstrates how these APIs can be implemented but the EL3 Runtime Software can +choose a more optimal implementation (like dedicating the secure TPIDRPRW +system register (in AArch32) for storing these pointers). + +**Function : cm_set_context_by_index()** + +:: + + Argument : unsigned int cpu_idx, void *context, unsigned int security_state + Return : void + +This function is called during cold boot when the ``psci_setup()`` PSCI library +interface is called. + +This function must store the pointer to the CPU context data, ``context`` (2nd +argument), for the specified ``security_state`` (3rd argument) and CPU identified +by ``cpu_idx`` (first argument). The ``security_state`` will always be non-secure +when called by PSCI library and this argument is retained for compatibility +with BL31. The ``cpu_idx`` will correspond to the index returned by the +``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU. + +The actual method of storing the ``context`` pointers is implementation specific. +For example, SP-MIN stores the pointers in the array ``sp_min_cpu_ctx_ptr`` +declared in ``sp_min_main.c``. + +**Function : cm_get_context()** + +:: + + Argument : uint32_t security_state + Return : void * + +This function must return the pointer to the ``cpu_context_t`` structure for +the specified ``security_state`` (first argument) for the current CPU. The caller +must ensure that ``cm_set_context_by_index`` is called first and the appropriate +context pointers are stored prior to invoking this API. The ``security_state`` +will always be non-secure when called by PSCI library and this argument +is retained for compatibility with BL31. + +**Function : cm_get_context_by_index()** + +:: + + Argument : unsigned int cpu_idx, unsigned int security_state + Return : void * + +This function must return the pointer to the ``cpu_context_t`` structure for +the specified ``security_state`` (second argument) for the CPU identified by +``cpu_idx`` (first argument). The caller must ensure that +``cm_set_context_by_index`` is called first and the appropriate context +pointers are stored prior to invoking this API. The ``security_state`` will +always be non-secure when called by PSCI library and this argument is +retained for compatibility with BL31. The ``cpu_idx`` will correspond to the +index returned by the ``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU. + +Platform API +~~~~~~~~~~~~ + +The platform layer abstracts the platform-specific details from the generic +PSCI library. The following platform APIs/macros must be defined by the EL3 +Runtime Software for integration with the PSCI library. + +The mandatory platform APIs are: + +- plat_my_core_pos +- plat_core_pos_by_mpidr +- plat_get_syscnt_freq2 +- plat_get_power_domain_tree_desc +- plat_setup_psci_ops +- plat_reset_handler +- plat_panic_handler +- plat_get_my_stack + +The mandatory platform macros are: + +- PLATFORM_CORE_COUNT +- PLAT_MAX_PWR_LVL +- PLAT_NUM_PWR_DOMAINS +- CACHE_WRITEBACK_GRANULE +- PLAT_MAX_OFF_STATE +- PLAT_MAX_RET_STATE +- PLAT_MAX_PWR_LVL_STATES (optional) +- PLAT_PCPU_DATA_SIZE (optional) + +The details of these APIs/macros can be found in the :ref:`Porting Guide`. + +All platform specific operations for power management are done via +``plat_psci_ops_t`` callbacks registered by the platform when +``plat_setup_psci_ops()`` API is called. The description of each of +the callbacks in ``plat_psci_ops_t`` can be found in PSCI section of the +:ref:`Porting Guide`. If any these callbacks are not registered, then the +PSCI API associated with that callback will not be supported by PSCI +library. + +Secure payload power management callback +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +During PSCI power management operations, the EL3 Runtime Software may +need to perform some bookkeeping, and PSCI library provides +``spd_pm_ops_t`` callbacks for this purpose. These hooks must be +populated and registered by using ``psci_register_spd_pm_hook()`` PSCI +library interface. + +Typical bookkeeping during PSCI power management calls include save/restore +of the EL3 Runtime Software context. Also if the EL3 Runtime Software makes +use of secure interrupts, then these interrupts must also be managed +appropriately during CPU power down/power up. Any secure interrupt targeted +to the current CPU must be disabled or re-targeted to other running CPU prior +to power down of the current CPU. During power up, these interrupt can be +enabled/re-targeted back to the current CPU. + +.. code:: c + + typedef struct spd_pm_ops { + void (*svc_on)(u_register_t target_cpu); + int32_t (*svc_off)(u_register_t __unused); + void (*svc_suspend)(u_register_t max_off_pwrlvl); + void (*svc_on_finish)(u_register_t __unused); + void (*svc_suspend_finish)(u_register_t max_off_pwrlvl); + int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu); + int32_t (*svc_migrate_info)(u_register_t *resident_cpu); + void (*svc_system_off)(void); + void (*svc_system_reset)(void); + } spd_pm_ops_t; + +A brief description of each callback is given below: + +- svc_on, svc_off, svc_on_finish + + The ``svc_on``, ``svc_off`` callbacks are called during PSCI_CPU_ON, + PSCI_CPU_OFF APIs respectively. The ``svc_on_finish`` is called when the + target CPU of PSCI_CPU_ON API powers up and executes the + ``psci_warmboot_entrypoint()`` PSCI library interface. + +- svc_suspend, svc_suspend_finish + + The ``svc_suspend`` callback is called during power down bu either + PSCI_SUSPEND or PSCI_SYSTEM_SUSPEND APIs. The ``svc_suspend_finish`` is + called when the CPU wakes up from suspend and executes the + ``psci_warmboot_entrypoint()`` PSCI library interface. The ``max_off_pwrlvl`` + (first parameter) denotes the highest power domain level being powered down + to or woken up from suspend. + +- svc_system_off, svc_system_reset + + These callbacks are called during PSCI_SYSTEM_OFF and PSCI_SYSTEM_RESET + PSCI APIs respectively. + +- svc_migrate_info + + This callback is called in response to PSCI_MIGRATE_INFO_TYPE or + PSCI_MIGRATE_INFO_UP_CPU APIs. The return value of this callback must + correspond to the return value of PSCI_MIGRATE_INFO_TYPE API as described + in `PSCI spec`_. If the secure payload is a Uniprocessor (UP) + implementation, then it must update the mpidr of the CPU it is resident in + via ``resident_cpu`` (first argument). The updates to ``resident_cpu`` is + ignored if the secure payload is a multiprocessor (MP) implementation. + +- svc_migrate + + This callback is only relevant if the secure payload in EL3 Runtime + Software is a Uniprocessor (UP) implementation and supports migration from + the current CPU ``from_cpu`` (first argument) to another CPU ``to_cpu`` + (second argument). This callback is called in response to PSCI_MIGRATE + API. This callback is never called if the secure payload is a + Multiprocessor (MP) implementation. + +CPU operations +~~~~~~~~~~~~~~ + +The CPU operations (cpu_ops) framework implement power down sequence specific +to the CPU and the details of which can be found at +:ref:`firmware_design_cpu_ops_fwk`. The TF-A tree implements the ``cpu_ops`` +for various supported CPUs and the EL3 Runtime Software needs to include the +required ``cpu_ops`` in its build. The start and end of the ``cpu_ops`` +descriptors must be exported by the EL3 Runtime Software via the +``__CPU_OPS_START__`` and ``__CPU_OPS_END__`` linker symbols. + +The ``cpu_ops`` descriptors also include reset sequences and may include errata +workarounds for the CPU. The EL3 Runtime Software can choose to call this +during cold/warm reset if it does not implement its own reset sequence/errata +workarounds. + +-------------- + +*Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.* + +.. _PSCI spec: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf +.. _SMCCC: https://developer.arm.com/docs/den0028/latest +.. _PSCI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf +.. _PSCI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst new file mode 100644 index 0000000..5a4be4d --- /dev/null +++ b/docs/getting_started/rt-svc-writers-guide.rst @@ -0,0 +1,320 @@ +EL3 Runtime Service Writer's Guide +===================================================== + +Introduction +------------ + +This document describes how to add a runtime service to the EL3 Runtime +Firmware component of Trusted Firmware-A (TF-A), BL31. + +Software executing in the normal world and in the trusted world at exception +levels lower than EL3 will request runtime services using the Secure Monitor +Call (SMC) instruction. These requests will follow the convention described in +the SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function +identifiers to each SMC request and describes how arguments are passed and +results are returned. + +SMC Functions are grouped together based on the implementor of the service, for +example a subset of the Function IDs are designated as "OEM Calls" (see `SMCCC`_ +for full details). The EL3 runtime services framework in BL31 enables the +independent implementation of services for each group, which are then compiled +into the BL31 image. This simplifies the integration of common software from +Arm to support `PSCI`_, Secure Monitor for a Trusted OS and SoC specific +software. The common runtime services framework ensures that SMC Functions are +dispatched to their respective service implementation - the +:ref:`Firmware Design` document provides details of how this is achieved. + +The interface and operation of the runtime services depends heavily on the +concepts and definitions described in the `SMCCC`_, in particular SMC Function +IDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and +SMC64 calling conventions. Please refer to that document for a full explanation +of these terms. + +Owning Entities, Call Types and Function IDs +-------------------------------------------- + +The SMC Function Identifier includes a OEN field. These values and their +meaning are described in `SMCCC`_ and summarized in table 1 below. Some entities +are allocated a range of of OENs. The OEN must be interpreted in conjunction +with the SMC call type, which is either *Fast* or *Yielding*. Fast calls are +uninterruptible whereas Yielding calls can be pre-empted. The majority of +Owning Entities only have allocated ranges for Fast calls: Yielding calls are +reserved exclusively for Trusted OS providers or for interoperability with +legacy 32-bit software that predates the `SMCCC`_. + +:: + + Type OEN Service + Fast 0 Arm Architecture calls + Fast 1 CPU Service calls + Fast 2 SiP Service calls + Fast 3 OEM Service calls + Fast 4 Standard Service calls + Fast 5-47 Reserved for future use + Fast 48-49 Trusted Application calls + Fast 50-63 Trusted OS calls + + Yielding 0- 1 Reserved for existing Armv7-A calls + Yielding 2-63 Trusted OS Standard Calls + +*Table 1: Service types and their corresponding Owning Entity Numbers* + +Each individual entity can allocate the valid identifiers within the entity +range as they need - it is not necessary to coordinate with other entities of +the same type. For example, two SoC providers can use the same Function ID +within the SiP Service calls OEN range to mean different things - as these +calls should be specific to the SoC. The Standard Runtime Calls OEN is used for +services defined by Arm standards, such as `PSCI`_. + +The SMC Function ID also indicates whether the call has followed the SMC32 +calling convention, where all parameters are 32-bit, or the SMC64 calling +convention, where the parameters are 64-bit. The framework identifies and +rejects invalid calls that use the SMC64 calling convention but that originate +from an AArch32 caller. + +The EL3 runtime services framework uses the call type and OEN to identify a +specific handler for each SMC call, but it is expected that an individual +handler will be responsible for all SMC Functions within a given service type. + +Getting started +--------------- + +TF-A has a ``services`` directory in the source tree under which +each owning entity can place the implementation of its runtime service. The +`PSCI`_ implementation is located here in the ``lib/psci`` directory. + +Runtime service sources will need to include the ``runtime_svc.h`` header file. + +Registering a runtime service +----------------------------- + +A runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying +the name of the service, the range of OENs covered, the type of service and +initialization and call handler functions. + +.. code:: c + + #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) + +- ``_name`` is used to identify the data structure declared by this macro, and + is also used for diagnostic purposes + +- ``_start`` and ``_end`` values must be based on the ``OEN_*`` values defined in + ``smccc.h`` + +- ``_type`` must be one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD`` + +- ``_setup`` is the initialization function with the ``rt_svc_init`` signature: + + .. code:: c + + typedef int32_t (*rt_svc_init)(void); + +- ``_smch`` is the SMC handler function with the ``rt_svc_handle`` signature: + + .. code:: c + + typedef uintptr_t (*rt_svc_handle_t)(uint32_t 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); + +Details of the requirements and behavior of the two callbacks is provided in +the following sections. + +During initialization the services framework validates each declared service +to ensure that the following conditions are met: + +#. The ``_start`` OEN is not greater than the ``_end`` OEN +#. The ``_end`` OEN does not exceed the maximum OEN value (63) +#. The ``_type`` is one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD`` +#. ``_setup`` and ``_smch`` routines have been specified + +``std_svc_setup.c`` provides an example of registering a runtime service: + +.. code:: c + + /* Register Standard Service Calls as runtime service */ + DECLARE_RT_SVC( + std_svc, + OEN_STD_START, + OEN_STD_END, + SMC_TYPE_FAST, + std_svc_setup, + std_svc_smc_handler + ); + +Initializing a runtime service +------------------------------ + +Runtime services are initialized once, during cold boot, by the primary CPU +after platform and architectural initialization is complete. The framework +performs basic validation of the declared service before calling +the service initialization function (``_setup`` in the declaration). This +function must carry out any essential EL3 initialization prior to receiving a +SMC Function call via the handler function. + +On success, the initialization function must return ``0``. Any other return value +will cause the framework to issue a diagnostic: + +:: + + Error initializing runtime service <name of the service> + +and then ignore the service - the system will continue to boot but SMC calls +will not be passed to the service handler and instead return the *Unknown SMC +Function ID* result ``0xFFFFFFFF``. + +If the system must not be allowed to proceed without the service, the +initialization function must itself cause the firmware boot to be halted. + +If the service uses per-CPU data this must either be initialized for all CPUs +during this call, or be done lazily when a CPU first issues an SMC call to that +service. + +Handling runtime service requests +--------------------------------- + +SMC calls for a service are forwarded by the framework to the service's SMC +handler function (``_smch`` in the service declaration). This function must have +the following signature: + +.. code:: c + + typedef uintptr_t (*rt_svc_handle_t)(uint32_t 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); + +The handler is responsible for: + +#. Determining that ``smc_fid`` is a valid and supported SMC Function ID, + otherwise completing the request with the *Unknown SMC Function ID*: + + .. code:: c + + SMC_RET1(handle, SMC_UNK); + +#. Determining if the requested function is valid for the calling security + state. SMC Calls can be made from Non-secure, Secure or Realm worlds and + the framework will forward all calls to the service handler. + + The ``flags`` parameter to this function indicates the caller security state + in bits 0 and 5. The ``is_caller_secure(flags)``, ``is_caller_non_secure(flags)`` + and ``is_caller_realm(flags)`` helper functions can be used to determine whether + the caller's security state is Secure, Non-secure or Realm respectively. + + If invalid, the request should be completed with: + + .. code:: c + + SMC_RET1(handle, SMC_UNK); + +#. Truncating parameters for calls made using the SMC32 calling convention. + Such calls can be determined by checking the CC field in bit[30] of the + ``smc_fid`` parameter, for example by using: + + :: + + if (GET_SMC_CC(smc_fid) == SMC_32) ... + + For such calls, the upper bits of the parameters x1-x4 and the saved + parameters X5-X7 are UNDEFINED and must be explicitly ignored by the + handler. This can be done by truncating the values to a suitable 32-bit + integer type before use, for example by ensuring that functions defined + to handle individual SMC Functions use appropriate 32-bit parameters. + +#. Providing the service requested by the SMC Function, utilizing the + immediate parameters x1-x4 and/or the additional saved parameters X5-X7. + The latter can be retrieved using the ``SMC_GET_GP(handle, ref)`` function, + supplying the appropriate ``CTX_GPREG_Xn`` reference, e.g. + + .. code:: c + + uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6); + +#. Implementing the standard SMC32 Functions that provide information about + the implementation of the service. These are the Call Count, Implementor + UID and Revision Details for each service documented in section 6 of the + `SMCCC`_. + + TF-A expects owning entities to follow this recommendation. + +#. Returning the result to the caller. Based on `SMCCC`_ spec, results are + returned in W0-W7(X0-X7) registers for SMC32(SMC64) calls from AArch64 + state. Results are returned in R0-R7 registers for SMC32 calls from AArch32 + state. The framework provides a family of macros to set the multi-register + return value and complete the handler: + + .. code:: c + + AArch64 state: + + SMC_RET1(handle, x0); + SMC_RET2(handle, x0, x1); + SMC_RET3(handle, x0, x1, x2); + SMC_RET4(handle, x0, x1, x2, x3); + SMC_RET5(handle, x0, x1, x2, x3, x4); + SMC_RET6(handle, x0, x1, x2, x3, x4, x5); + SMC_RET7(handle, x0, x1, x2, x3, x4, x5, x6); + SMC_RET8(handle, x0, x1, x2, x3, x4, x5, x6, x7); + + AArch32 state: + + SMC_RET1(handle, r0); + SMC_RET2(handle, r0, r1); + SMC_RET3(handle, r0, r1, r2); + SMC_RET4(handle, r0, r1, r2, r3); + SMC_RET5(handle, r0, r1, r2, r3, r4); + SMC_RET6(handle, r0, r1, r2, r3, r4, r5); + SMC_RET7(handle, r0, r1, r2, r3, r4, r5, r6); + SMC_RET8(handle, r0, r1, r2, r3, r4, r5, r6, r7); + +The ``cookie`` parameter to the handler is reserved for future use and can be +ignored. The ``handle`` is returned by the SMC handler - completion of the +handler function must always be via one of the ``SMC_RETn()`` macros. + +.. note:: + The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow + all of the above requirements yet. + +Services that contain multiple sub-services +------------------------------------------- + +It is possible that a single owning entity implements multiple sub-services. For +example, the Standard calls service handles ``0x84000000``-``0x8400FFFF`` and +``0xC4000000``-``0xC400FFFF`` functions. Within that range, the `PSCI`_ service +handles the ``0x84000000``-``0x8400001F`` and ``0xC4000000``-``0xC400001F`` functions. +In that respect, `PSCI`_ is a 'sub-service' of the Standard calls service. In +future, there could be additional such sub-services in the Standard calls +service which perform independent functions. + +In this situation it may be valuable to introduce a second level framework to +enable independent implementation of sub-services. Such a framework might look +very similar to the current runtime services framework, but using a different +part of the SMC Function ID to identify the sub-service. TF-A does not provide +such a framework at present. + +Secure-EL1 Payload Dispatcher service (SPD) +------------------------------------------- + +Services that handle SMC Functions targeting a Trusted OS, Trusted Application, +or other Secure-EL1 Payload are special. These services need to manage the +Secure-EL1 context, provide the *Secure Monitor* functionality of switching +between the normal and secure worlds, deliver SMC Calls through to Secure-EL1 +and generally manage the Secure-EL1 Payload through CPU power-state transitions. + +TODO: Provide details of the additional work required to implement a SPD and +the BL31 support for these services. Or a reference to the document that will +provide this information.... + +-------------- + +*Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.* + +.. _SMCCC: https://developer.arm.com/docs/den0028/latest +.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf diff --git a/docs/getting_started/tools-build.rst b/docs/getting_started/tools-build.rst new file mode 100644 index 0000000..166b527 --- /dev/null +++ b/docs/getting_started/tools-build.rst @@ -0,0 +1,179 @@ +Building Supporting Tools +========================= + +.. note:: + + OpenSSL 3.0 is needed in order to build the tools. A custom installation + can be used if not updating the OpenSSL version on the OS. In order to do + this, use the ``OPENSSL_DIR`` variable after the ``make`` command to + indicate the location of the custom OpenSSL build. Then, to run the tools, + use the ``LD_LIBRARY_PATH`` to indicate the location of the built + libraries. More info about ``OPENSSL_DIR`` can be found at + :ref:`Build Options`. + +Building and using the FIP tool +------------------------------- + +The following snippets build a :ref:`FIP<Image Terminology>` for the FVP +platform. While it is not an intrinsic part of the FIP format, a BL33 image is +required for these examples. For the purposes of experimentation, `Trusted +Firmware-A Tests`_ (`tftf.bin``) may be used. Refer to to the `TFTF +documentation`_ for instructions on building a TFTF binary. + +The TF-A build system provides the make target ``fip`` to create a FIP file +for the specified platform using the FIP creation tool included in the TF-A +project. Examples below show how to build a FIP file for FVP, packaging TF-A +and BL33 images. + +For AArch64: + +.. code:: shell + + make PLAT=fvp BL33=<path-to>/bl33.bin fip + +For AArch32: + +.. code:: shell + + make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=<path-to>/bl33.bin fip + +The resulting FIP may be found in: + +:: + + build/fvp/<build-type>/fip.bin + +For advanced operations on FIP files, it is also possible to independently build +the tool and create or modify FIPs using this tool. To do this, follow these +steps: + +It is recommended to remove old artifacts before building the tool: + +.. code:: shell + + make -C tools/fiptool clean + +Build the tool: + +.. code:: shell + + make [DEBUG=1] [V=1] fiptool + +The tool binary can be located in: + +:: + + ./tools/fiptool/fiptool + +Invoking the tool with ``help`` will print a help message with all available +options. + +Example 1: create a new Firmware package ``fip.bin`` that contains BL2 and BL31: + +.. code:: shell + + ./tools/fiptool/fiptool create \ + --tb-fw build/<platform>/<build-type>/bl2.bin \ + --soc-fw build/<platform>/<build-type>/bl31.bin \ + fip.bin + +Example 2: view the contents of an existing Firmware package: + +.. code:: shell + + ./tools/fiptool/fiptool info <path-to>/fip.bin + +Example 3: update the entries of an existing Firmware package: + +.. code:: shell + + # Change the BL2 from Debug to Release version + ./tools/fiptool/fiptool update \ + --tb-fw build/<platform>/release/bl2.bin \ + build/<platform>/debug/fip.bin + +Example 4: unpack all entries from an existing Firmware package: + +.. code:: shell + + # Images will be unpacked to the working directory + ./tools/fiptool/fiptool unpack <path-to>/fip.bin + +Example 5: remove an entry from an existing Firmware package: + +.. code:: shell + + ./tools/fiptool/fiptool remove \ + --tb-fw build/<platform>/debug/fip.bin + +Note that if the destination FIP file exists, the create, update and +remove operations will automatically overwrite it. + +The unpack operation will fail if the images already exist at the +destination. In that case, use -f or --force to continue. + +More information about FIP can be found in the :ref:`Firmware Design` document. + +.. _tools_build_cert_create: + +Building the Certificate Generation Tool +---------------------------------------- + +The ``cert_create`` tool is built as part of the TF-A build process when the +``fip`` make target is specified and TBB is enabled (as described in the +previous section), but it can also be built separately with the following +command: + +.. code:: shell + + make PLAT=<platform> [DEBUG=1] [V=1] certtool + +For platforms that require their own IDs in certificate files, the generic +'cert_create' tool can be built with the following command. Note that the target +platform must define its IDs within a ``platform_oid.h`` header file for the +build to succeed. + +.. code:: shell + + make PLAT=<platform> USE_TBBR_DEFS=0 [DEBUG=1] [V=1] certtool + +``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more +verbose. The following command should be used to obtain help about the tool: + +.. code:: shell + + ./tools/cert_create/cert_create -h + +.. _tools_build_enctool: + +Building the Firmware Encryption Tool +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``encrypt_fw`` tool is built as part of the TF-A build process when the +``fip`` make target is specified, DECRYPTION_SUPPORT and TBB are enabled, but +it can also be built separately with the following command: + +.. code:: shell + + make PLAT=<platform> [DEBUG=1] [V=1] enctool + +``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more +verbose. The following command should be used to obtain help about the tool: + +.. code:: shell + + ./tools/encrypt_fw/encrypt_fw -h + +Note that the enctool in its current implementation only supports encryption +key to be provided in plain format. A typical implementation can very well +extend this tool to support custom techniques to protect encryption key. + +Also, a user may choose to provide encryption key or nonce as an input file +via using ``cat <filename>`` instead of a hex string. + +-------------- + +*Copyright (c) 2019-2022, Arm Limited. All rights reserved.* + +.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/ +.. _TFTF documentation: https://trustedfirmware-a-tests.readthedocs.io/en/latest/ |