Last edited one month ago

How to configure TF-A FW CONFIG

Applicable for STM32MP13x lines, STM32MP15x lines, STM32MP21x lines, STM32MP23x lines, STM32MP25x lines

1. Article purpose[edit | edit source]

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 | edit source]

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 | edit source]

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 | edit source]

4.1. Image properties[edit | edit source]

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 for STM32MP1 series and in plat/st/stm32mp2/include/plat_tbbr_img_def.h for STM32MP2 series.

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 | edit source]

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.

4.2.1. STM32MP1 series[edit | edit source]

On STM32MP1 series, the DDR firewall is managed by the TZC peripheral.

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 0x02000000 TZC_REGION_S_RDWR 0>;

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: 32-Mbyte region where only secure accesses are allowed

4.2.2. STM32MP2 series[edit | edit source]

On STM32MP2 series, the DDR firewall is managed by the DDR RISAF peripheral (RISAF4).

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

		compatible = "st,stm32mp2-mem-firewall";
		op_tee: op-tee@82000000 {
			reg = <0x0 0x82000000 0x0 0x2000000>;
			st,protreg = <RISAFPROT(RISAF_REG_ID(8), RIF_CID0_BF|RIF_CID1_BF, RIF_CID0_BF|RIF_CID1_BF, 0, RIF_SEC, RIF_ENC_EN, RIF_BREN_EN)>;
		};

Each area to configure must have its own node. The previous example configures a region that will be used by OP-TEE, starting at 0x82000000 and with a size of 0x2000000 (32MB), using 64 bit values (two 32bit words for address and size). More information about the st,protreg configuration can be found in the RISAF device tree configuration page.

4.3. DDR Encryption area[edit | edit source]

4.3.1. STM32MP1 series[edit | edit source]

Warning white.png Warning
DDR encryption is not supported on STM32MP15x lines More info.png

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.3.2. STM32MP2 series[edit | edit source]

On STM32MP2 series, the encryption is also managed by the DDR RISAF peripheral (RISAF4). It is done by the RIF_ENC_EN macro in st,protreg device tree property (see previous example). More information can be found in the RISAF device tree configuration page.

4.4. Build command[edit | edit source]

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 | edit source]

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