OP-TEE SPMC supports two methods for finding and loading the SP executable images. Currently only ELF executables are supported. In our buildsystem the method can be selected with the SP_PACKAGING_METHOD option .
- Embedded SP
In this case the early TA mechanism of optee_os is reused: the SP ELF files are embedded into the main OP-TEE binary. Each ELF should start with a specific section (.sp_head) containing a struct which describes the SP (UUID, stack size, etc.). The images can be added to optee_os using the EARLY_TA_PATHS config option, but our buildsystem will set this up automatically when SP_PACKAGING_METHOD=embedded is selected. The images passed in EARLY_TA_PATHS are processed by ta_bin_to_c.py in optee_os and linked into the main binary. At runtime the for_each_early_ta() macro  can iterate through these images (both TAs and SPs), so a particular SP can be found by UUID and then loaded by ldelf.
The SP manifest file  used by the SPMC to setup SPs is not included with the individual SP images. The manifest DTs should be concatenated into one DT and passed to optee_os in the CFG_EMBED_DTB_SOURCE_FILE option. Again, when selecting the embedded SP option in  this will be done automatically by our buildsystem.
- FIP SP
In this case the SP ELF files and the corresponding SP manifest DTs are encapsulated into SP packages and packed into the FIP. The goal of providing this alternative flow is to make updating SPs easier (independent of the main OP-TEE binary) and to get aligned with Hafnium (S-EL2 SPMC). For more information about the FIP, please refer to the TF-A documentation . The SP packaging process and the package format is provided by TF-A (Hafnium), detailed description is available at . In our buildsystem this method can be selected by SP_PACKAGING_METHOD=fip, it covers all the necessary setup automatically. In case of using another buildsystem, the following steps should be implemented:
- TF-A config SP_LAYOUT_FILE: provide a JSON file which describes the SPs (path to SP executable and corresponding DT, example ). The TF-A buildsystem will create the SP packages (using sptool) based on this and pack them into the FIP.
- TF-A config ARM_BL2_SP_LIST_DTS: provide a DT snippet which describes the SPs' UUIDs and load addresses (example: ). This will be injected into the SP list in TB_FW_CONFIG DT of TF-A, and BL2 will load the SPs based on this. Note that BL2 doesn't automatically load all images from the FIP: it's necessary to explicitly define them in TB_FW_CONFIG (using this injected snippet or manually editing the DT).
- TF-A config ARM_SPMC_MANIFEST_DTS: provide the SPMC manifest (example: ). This DT is passed to the SPMC as a boot argument (in the TF-A naming convention this is the TOS_FW_CONFIG). It should contain the list of SP packages and the load addresses in the compatible = "arm,optee-spmc" node.
- optee_os config: set CFG_FIP_SP=y.
At boot optee_os will parse the SP load addresses from the SPMC manifest and find the SP packages already loaded by BL2 . Iterating through the SP packages, based on the SP package header in each package it will map the SP manifest DTs and load the executables using ldelf.
Note that in the process described above there are some redundancies:
- the SP UUID has to be provided twice: in the SP manifest DT and in the ARM_BL2_SP_LIST_DTS DT snippet,
- the SP load address has to be provided twice: in the SPMC manifest DT and in the ARM_BL2_SP_LIST_DTS DT snippet.
This could be improved in the future to have a more streamlined solution.
Note: necessary security improvements described in this task: https://developer.trustedfirmware.org/T914