How to configure TF-A FW CONFIG

1 Article purpose[edit]

This section details the TF-A firmware configuration file (FW_CONFIG). It explains how to configure it to update the STM32 MPU boot chain, how to use it in STM32 MPU context and the build/update process that is required to deploy on your target.

2 Overview[edit]

Thanks to TF-A Firmware configuration framework (FCONF), the BL2 stage can be dynamically configured using a configuration file. FW_CONFIG file is designed based on device tree model and parsed by the BL2 to manage the next loaded stages.
It is a key file that dynamically sets the proper information to load, checks their size and identifies the different firmware embedded in the FIP binary.

3 Configuration[edit]

Each board must embed the FW_CONFIG file in the FIP binary. Originally, this file is loaded from BL1 and passed to the BL2 through arguments.
The STM32 MPU does not use the BL1. It uses the ROM code instead. The boot flow has been adapted to use the FW_CONFIG. In order to keep the BL2 independent from the next stages, the FW_CONFIG file is located into the FIP binary and loaded as the first binary in internal RAM.

The configuration description defines the internal RAM and DDR mapping used by the next stages. For the STM32 MPU, all the boards using the same DDR size inherit from the same FW_CONFIG.

When TRUSTED_BOARD_BOOT is enabled, the FW_CONFIG file is authenticated by a certificate described in the CoT.

Warning.png The properties described in this file replace the hardcoded values previously defined in the bl2_mem_param_desc structure in include/common/desc_image_load.h . The FW_CONFIG file must reflect the defined structure.

4 Structure[edit]

4.1 Image properties[edit]

This is the generic part of the FW_CONFIG.

As defined in the FCONF device tree bindings docs/components/fconf/fconf_properties.rst , this section describes the firmware to be loaded and their properties. Each node must contain:

Below an example using the STM32MP15 evaluation board with 1Gbyte DDR:
fdts/stm32mp15-ddr-512m-fw-config.dts

  dtb-registry {
          compatible = "fconf,dyn_cfg-dtb_registry";
          hw-config {                                            HW_CONFIG file section
                  load-address = <0x0 STM32MP_HW_CONFIG_BASE>;   // STM32MP_HW_CONFIG_BASE and SIZE 
                  max-size = <STM32MP_HW_CONFIG_MAX_SIZE>;       // are defined in platform definition file
                  id = <HW_CONFIG_ID>;                           // Unique ID defined in
                                                                 // include/export/common/tbbr/tbbr_img_def_exp.h 
           };
           ...
  #ifdef AARCH32_SP_OPTEE                                          OP-TEE specific 
           tos_fw {
                   load-address = <0x0 0x2FFC0000>;                // Load address in SYSRAM
                   max-size = <0x0001F000>;                        // Maximum firmware size
                   id = <BL32_IMAGE_ID>;                           // Unique ID
           };
  #else			

In this example, the file used allows the generation of a file for OP-TEE OS support or SP_MIN management. Most of the defined values use the generic enum from TF-A source code. However they can be replaced by hardcoded values.

In the OP-TEE usage, the tos_fw is related to the tee_header AND tee_pager part. As explain in the OP-TEE article, the header_v2 also indicates the pager_v2.bin startup address and the pageable part (when enabled) is platform-specific. The header_v2 only indicates the binary size. In STM32MP15, as the pager mode is used, the pageable start address is hardcoded using DDR_MAX_ADDRESS - STM32MP_DDR_S_SIZE.

4.2 Firewall management[edit]

Depending on the DDR usage of the product, the DDR firewall must be configured to restrict access to specific areas. This must be done prior to loading the binary. The STM32 MPU extends the FW_CONFIG file to manage the firewall access.

The associated definitions and macros are defined in include/dt-bindings/soc/stm32mp1-tzc400.h

   compatible = "st,mem-firewall";
        memory-ranges = <
               0xc0000000 0x1e000000 TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
               0xde000000 0x01e00000 TZC_REGION_S_RDWR 0
               0xdfe00000 0x00200000 TZC_REGION_S_NONE
               TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)>;

The previous example defines three regions:

  • Start address = 0xC000 0000: 480-Mbyte region where secure accesses are forbidden and to which all non-secure peripherals can access
  • Start address = 0xDE00 0000: 30-Mbyte region where only secure accesses are allowed
  • Start address = 0xDFE0 0000: 2-Mbyte region where secure accesses are forbidden and non-secure accesses are possible only from an A7 CPU

4.3 Install sources[edit]

The Developer Package contains OpenSTLinux and TF-A sources: TF-A Installation

4.4 Official source tree[edit]

Download source code from the official Trusted Firmware-A git repository.

 PC $> git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
Warning.png The STM32MP1 platform is not yet fully upstreamed. Depending on the version used, some features may not be available.


For a full-featured software, go to STMicroelectronics github:

 PC $> git clone https://github.com/STMicroelectronics/arm-trusted-firmware.git


4.5 Initializing the cross compile environment[edit]

Refer to Setup Cross compile environment.

4.6 Build command[edit]

FW_CONFIG file uses device tree files located in the ftds folder.
FW_CONFIG file must be built using the TF-A Makefile.

First add your own environment flags:

 PC $> unset LDFLAGS;
 PC $> unset CFLAGS;

Then compile the TF-A dtbs rule.

4.6.1 TF-A Build flags[edit]

Here is the list of the mandatory flags that need to be specified to complete the FW_CONFIG build:

  • ARM_ARCH_MAJOR=7: the major version of Arm® architecture to target (STM32MP1 is based on an Arm v7 architecture)
  • ARCH=aarch32: specifies aarch32 architecture to be built
  • PLAT=stm32mp1: builds an STM32MP1 platform
  • DTB_FILE_NAME=<fdt file name>.dtb: this flag must be defined to build the proper target and include the correct DTB file into the final file
  • AARCH32_SP=<sp_min/optee>: the FW_CONFIG may be associated to some BL32 specific flags (such as OP-TEE), so a AARCH32_SP must be properly selected

Optional flags:

  • BUILD_PLAT=<folder>: custom output folder name (default is build/<debug/release>/)
  • V=1: prints verbose compilation traces

4.6.2 STM32MP15[edit]

The default build commands for STM32MP15 are:

 PC $> make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 AARCH32_SP=sp_min \
         DTB_FILE_NAME=<board>.dtb dtbs

or

 PC $> make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 AARCH32_SP=optee \
         DTB_FILE_NAME=<board>.dtb dtbs

4.7 Final image[edit]

Final images are available for updating the FIP binary (including the associated firmware configuration file):

<BUILD_PLAT>/fdts/<board>-fw-config.dtb

4.8 Distribution Package[edit]

For an OpenSTLinux distribution, the TF-A FW_CONFIG file is built in release mode by default. The yocto recipe can be found in:

meta-st/meta-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_<version>.bb

To modify the TF-A FW_CONFIG code source, use the following steps starting from an already downloaded and built OpenSTLinux distribution.

4.8.1 Accessing the sources[edit]

You can use devtool to access the source.

 PC $> cd <baseline root directory>
 PC $> devtool modify tf-a-stm32mp sources/boot/tf-a

By going to the sources/boot/tf-a folder, you can manage and modify the TF-A sources. To rebuild it, go back to the build-<distribution> folder and launch the TF-A recipe:

 PC $> bitbake tf-a-stm32mp

The final image is deployed in the image default output folder.

4.9 Updating the software[edit]

FW_CONFIG file is part of the FIP binary. The next step to deploy the FW_CONFIG firmware is to update the FIP binary following the FIP update process.