How to configure TF-A FW CONFIG

Applicable for STM32MP13x lines, STM32MP15x lines

1 Article purpose[edit]

This section details the Trusted Firmware-A 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 firmware configuration framework[1] (FCONF), the BL2 stage can be dynamically configured using configuration files. The 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 Firmware configuration file management[edit]

Each FIP binary must embed the FW_CONFIG file. 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 BL2 has been adapted to use the FW_CONFIG from the FIP binary.
The FW_CONFIG file replaces the properties previously hardcoded.

Thanks to this external configuration, the Trusted Firmware-A BL2 binary becomes independent from the next stages.
The FW_CONFIG file is the first binary read from the FIP binary and loaded in internal RAM.

The configuration description defines base address, maximum size, and image id of the binaries to be loaded in the internal RAM or DDR. For the STM32 MPU, all the boards using the same DDR size inherit from the same FW_CONFIG.

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[2], this section describes the firmware to be loaded and their properties. Each node must contain:

Below an example of a configuration file:

  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 
          };
          ...
          tos_fw {                                                BL32 image section
                  load-address = <0x0 0x2FFC0000>;                // Load address in SYSRAM
                  max-size = <0x0001F000>;                        // Maximum firmware size
                  id = <BL32_IMAGE_ID>;                           // Unique ID
          };

STM32 MPU firmware configuration files can be found in fdts folder.
Most of the defined ID use the generic values from TF-A source code. However, to reduce the size of the tables describing images, some are replaced by hardcoded values in plat/st/stm32mp1/include/plat_tbbr_img_def.h .

In the OP-TEE usage, the tos_fw is related to the tee_header. 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.
On STM32MP15x lines More info.png, if 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/stm32mp13-tzc400.h (STM32MP13x lines More info.png) or include/dt-bindings/soc/stm32mp15-tzc400.h (STM32MP15x lines More info.png).

  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 DDR Encryption area[edit]

On STM32MP13x lines More info.png, a region of the DDR can be encrypted, thanks to DDRMCE.
The STM32 MPU extends the FW_CONFIG file to manage this configuration.

The associated definitions and macros are defined in stm32mp13-mce.h

  st-mem-encrypt {
       compatible = "st,mem-encrypt";
       memory-ranges = <DDR_SEC_BASE DDR_SEC_SIZE MCE_ENCRYPT>;
  };
  • memory-ranges: 3 values are requested in this order:
    • start address of the DDRMCE region,
    • its size in bytes,
    • its type: MCE_ENCRYPT if encryption is enabled, MCE_PLAINTEXT else.

The DDRMCE related information is located in the stm32mp13-fw-config.dtsi .

4.4 Build command[edit]

FW_CONFIG files are located in the fdts folder. It must be built using the TF-A Makefile.

It can be rebuilt explicitly using the dtbs rules. The default build commands for STM32MP1 is:

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

4.5 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.