1. Article purpose[edit source]
The purpose of this article is to describe the different requirements on system configuration (RIF, RCC) to guarantee a correct execution of the ROM code in all the supported execution contexts.
2. Introduction[edit source]
The STM32MP2 ROM code is executed in different boot and lower power exit sequences:
- Cold boot to load the FSBL-A or the FSBL-M depending on main processor selection. In this context, Cortex-M33 and other master peripherals are under reset.
- Standby exit to reload FSBL-A and restart Cortex-A35. In this context, Cortex-M33 and other master peripherals are maintained under reset. But part of the system is initialized (Mainly RIF)
- D1Standby exit to (re)load FSBL-A and restart Cortex-A35. In the context, Cortex-M33 and other master peripherals could be running. Moreover system is fully initialized (RIF, RCC...)
Depending on main processor selection (Cortex-A35 TDCID or Cortex-M33 TDCID), ROM code has or has not the right to modify system configuration under TDCID responsibility. Moreover ROM code execution shall not impact rest of system during D1Stanby exit sequence.
Some rules on system configuration (RIF, RCC...) must be applied to guarantee STM32MP2 ROM code execution and isolation in the different contexts:
3. ROM code peripheral assignment[edit source]
3.1. Principles[edit source]
ROM code shall be able to access all resources required for its execution whatever ROM execution context (Cold boot, Standby exit and D1 Standby exit).
Depending on ROM code execution context, part of the system could be already configured and running. System configuration should be compliant with ROM code resource needs.
- RIF configuration including RIFSC and RIF-aware peripherals
- RCC clock tree configuration
At each execution ROM code checks resource access rights based on RIF registers ( RIFSC and RIF-aware).
Four actions are possible:
Resource control type | What is controlled | How |
---|---|---|
Ensuring non-exclusive access | The ROM code first checks that either resource access rights are not set, or are statically assigned to A35 | The ROM code checks that either CID filtering is not configured, or is configured static and assigned to the A35. |
Ensuring exclusive access | The ROM code checks that either resource is statically assigned to A35, or that resource is shared via its semaphore, and semaphore can be taken within 10 ms. | The ROM code checks that either CID filtering is configured static and assigned to the A35, or CID filtering is configured dynamic (meaning resource is shared via a semaphore) and semaphore can be taken within 10 ms. |
Checking security level | The ROM code checks that resource security level correspond to its needs | The ROM code checks that resource security level |
Setting security level | The ROM code sets resource security level according to its needs. Indeed in that case security level used by SW ecosystem could be different from ROM code one. | The ROM code sets resource security level according to its needs. |
3.2. Secure peripherals[edit source]
The ROM code always ensure exclusive access and security level on these peripherals:
Peripheral | RIF resource number | RIF block | Comment | Secure level checked | Cold boot | Standby exit | D1Standby exit |
---|---|---|---|---|---|---|---|
BSEC clock | R103 | RCC | 1 | ![]() |
![]() |
![]() | |
CPU1 boot, reset, IWDG management | R70 | RCC | 1 | ![]() |
![]() |
![]() | |
CPU PWR1 | R2 | PWR | power control | 1 | ![]() |
![]() |
![]() |
STGEN | R33 | RCC | flexgen | 1 | ![]() |
![]() |
![]() |
In case of secure boot when the chip is in CLOSED-LOCKED state, the ROM code always ensure exclusive access and security level on these peripherals to perform boot authentication and decryption:
Peripheral | RIF resource number | RIF block | Secure level checked | Cold boot | Standby exit | D1Standby exit |
---|---|---|---|---|---|---|
RNG | R92 | RIFSC | 1 | ![]() |
![]() |
![]() |
PKA | R93 | RIFSC | 1 | ![]() |
![]() |
![]() |
SAES | R94 | RIFSC | 1 | ![]() |
![]() |
![]() |
HASH | R95 | RIFSC | 1 | ![]() |
![]() |
![]() |
CRYP1 | R96 | RIFSC | 1 | ![]() |
![]() |
![]() |
SYSRAM/RISAB1 & RISAB2 | R74 | RCC | 1 | ![]() |
![]() |
![]() |
CA35SS | R106 | RCC | 1 | ![]() |
![]() |
![]() |
3.3. Non-secure peripherals[edit source]
ROM code ensures non-secure access to non-secure peripherals used during its execution, then it sets security level according to its needs.
ROM code adapts list of non-secure peripherals according to selected boot source.
3.3.1. SDMMC1 access ensure[edit source]
Checked in the following boot selection:
- Cortex-A35 main processor
- Boot from eMMC SDMMC1
- Boot from SD-Card SDMMC1
- Cortex-M33 main processor single boot device
- Boot from eMMC SDMMC1
- Boot from SD-Card SDMMC1
- Cortex-M33 main processor dual boot device
- Boot Cortex-M33 from sNOR and Cortex-A35 from eMMC SDMMC1
- Boot Cortex-M33 from sNOR and Cortex-A35 from SD-Card SDMMC1
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from eMMC SDMMC1
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from SD-Card SDMMC1
The following table list resources associated to SDMMC1.
Function | RIF resource number | RIF block | Resource description | Secure level set | Check at cold boot | Check at Standby exit | Check at D1Standby exit |
---|---|---|---|---|---|---|---|
Root Clock SDMMC1 | R51 | RCC | Flexgen 51 | 0 | ![]() |
![]() |
![]() |
Clock GPIOE | R94 | RCC | GPIO E clock config | 0 | ![]() |
![]() |
![]() |
IO voltage protection | R6 | PWR | VDDIO1 (PWR_C8) | 1 | ![]() |
![]() |
![]() |
GPIO PE3 | R3 | GPIOE | SDMMC1_CK | 0 | ![]() |
![]() |
![]() |
GPIO PE2 | R2 | GPIOE | SDMMC1_CMD | 0 | ![]() |
![]() |
![]() |
GPIO PE4 | R4 | GPIOE | SDMMC1_D0 | 0 | ![]() |
![]() |
![]() |
SDMMC1 | R76 | RIFSC | SDMMC1 controller | 0 | ![]() |
![]() |
![]() |
3.3.2. SDMMC2 access ensure[edit source]
Checked in the following boot selection:
- Cortex-A35 main processor
- Boot from eMMC SDMMC2
- Boot from SD-Card SDMMC2
- Cortex-M33 main processor single boot device
- Boot from eMMC SDMMC2
- Boot from SD-Card SDMMC2
- Cortex-M33 main processor dual boot device
- Boot Cortex-M33 from sNOR and Cortex-A35 from eMMC SDMMC2
- Boot Cortex-M33 from sNOR and Cortex-A35 from SD-Card SDMMC2
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from eMMC SDMMC2
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from SD-Card SDMMC2
The following table list resources associated to SDMMC2.
Function | RIF resource number | RIF block | Resource description | Secure level set | Check at cold boot | Check at Standby exit | Check at D1Standby exit |
---|---|---|---|---|---|---|---|
Root Clock SDMMC2 | R52 | RCC | Flexgen 52 | 0 | ![]() |
![]() |
![]() |
Clock GPIOE | R94 | RCC | GPIO E clock config | 0 | ![]() |
![]() |
![]() |
IO voltage protection | R5 | PWR | VDDIO2 (PWR_C7) | 1 | ![]() |
![]() |
![]() |
GPIO PE14 | R14 | GPIOE | SDMMC2_CK | 0 | ![]() |
![]() |
![]() |
GPIO PE15 | R15 | GPIOE | SDMMC2_CMD | 0 | ![]() |
![]() |
![]() |
GPIO PE13 | R13 | GPIOE | SDMMC2_D0 | 0 | ![]() |
![]() |
![]() |
SDMMC2 | R77 | RIFSC | SDMMC1 controller | 0 | ![]() |
![]() |
![]() |
3.3.3. OCTOSPI1 access ensure[edit source]
Checked in the following boot selection:
- Cortex-A35 main processor
- Boot from sNAND
- Boot from sNOR
- Boot from Hyperflash
- Cortex-M33 main processor single boot device
- Boot from sNAND
- Boot from sNOR
- Boot from Hyperflash
- Cortex-M33 main processor dual boot device
- Boot Cortex-M33 from sNOR and Cortex-A35 from eMMC SDMMC1
- Boot Cortex-M33 from sNOR and Cortex-A35 from SD-Card SDMMC1
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from eMMC SDMMC1
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from SD-Card SDMMC1
- Boot Cortex-M33 from sNOR and Cortex-A35 from eMMC SDMMC2
- Boot Cortex-M33 from sNOR and Cortex-A35 from SD-Card SDMMC2
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from eMMC SDMMC2
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from SD-Card SDMMC2
The following table list resources associated to OctoSPI1.
Function | RIF resource number | RIF block | Resource description | Secure level set | Check at cold boot | Check at Standby exit | Check at D1Standby exit |
---|---|---|---|---|---|---|---|
Root Clock Octospi1 | R48 | RCC | Flexgen 48 | 0 | ![]() |
![]() |
![]() |
Octospi1 Clock gating | R110 | RCC | Octospi1 clock and reset | 0 | ![]() |
![]() |
![]() |
IOM | R111 | RIFSC | IOManager | 0 | ![]() |
![]() |
![]() |
IO voltage protection | R0 | PWR | VDDIO3 & VDDIO4 (PWR_CR1) | 1 | ![]() |
![]() |
![]() |
Clock GPIOB | R91 | RCC | GPIO B clock config | 0 | ![]() |
![]() |
![]() |
Clock GPIOD | R93 | RCC | GPIO B clock config | 0 | ![]() |
![]() |
![]() |
GPIO PD 0, 3-5 | R0, 3-5 | GPIOD | Port 1 config single wire | 0 | ![]() |
![]() |
![]() |
GPIO PD 1, 2, 6-11 | R1, 2, 6-11 | GPIOD | Port 1 hyperflash | 0 | ![]() |
![]() |
![]() |
GPIO PE 0, 1, 8, 10 | R0, 1, 8, 10 | GPIOE | Port 2 config single wire | 0 | ![]() |
![]() |
![]() |
GPIO PE 2-7, 9, 11 | R2-7, 9, 11 | GPIOE | Port 2 hyperflash | 0 | ![]() |
![]() |
![]() |
![]() |
OctoSPI1 and OctoSPI2 controllers connected to the physical port thanks to the IO Manager (IOM) which support different modes (direct, swap or muxed). Mode is set by ecosystem SW according to board definition. When executed D1Standby exit procedure, ROM code can't modify IOM configuration set by ecosystem to not disturb rest of the system. It is ecosystem responsibility to set an IOM configuration that guarantee ROM code execution. |
3.3.4. FMC raw NAND[edit source]
Checked in the following boot selection:
- Cortex-A35 main processor
- Boot from FMC raw NAND
- Cortex-M33 main processor single boot device
- Boot from FMC raw NAND
- Cortex-M33 main processor dual boot device
- Boot Cortex-M33 from sNOR and Cortex-A35 from FMC raw NAND
- Boot Cortex-M33 from Hyperflash and Cortex-A35 from FMC raw NAND
The following table list resources associated to FMC.
Function | RIF resource number | RIF block | Resource description | Secure level set | Check at cold boot | Check at Standby exit | Check at D1Standby exit |
---|---|---|---|---|---|---|---|
Root Clock FMC | R50 | [[RCC internal peripheral|RCC] | Flexgen 50 | 0 | ![]() |
![]() |
![]() |
FMC clock gating | R112 | RCC | FMC clock and reset | 0 | ![]() |
![]() |
![]() |
Clock GPIOB | R91 | RCC | GPIO B clock config | 0 | ![]() |
![]() |
![]() |
Clock GPIOD | R93 | RCC | GPIO D clock config | 0 | ![]() |
![]() |
![]() |
Clock GPIOE | R94 | RCC | GPIO E clock config | 0 | ![]() |
![]() |
![]() |
IO voltage protection | R5 | PWR | VDDIO2 (PWR_C7) | 1 | ![]() |
![]() |
![]() |
GPIO PB 13-14 | R13-14 | GPIOB | 8bit config (12 IOs) | 0 | ![]() |
![]() |
![]() |
GPIO PD 12,14-15 | R12, 14-15 | GPIOD | 8bit config (12 IOs) | 0 | ![]() |
![]() |
![]() |
GPIO PE 6-9, 11-15 | R6-9, 11-15 | GPIOE | 8bit config (12 IOs) | 0 | ![]() |
![]() |
![]() |
GPIO PB 5-11 | R5-11 | GPIOB | 16bit config added | 0 | ![]() |
![]() |
![]() |
GPIO PD13 | R13 | GPIOD | 16bit config added | 0 | ![]() |
![]() |
![]() |
FMC R0 | R0 | FMC | FMC common resource | 0 | ![]() |
![]() |
![]() |
FMC R5 | R5 | FMC | FMC NAND controler | 0 | ![]() |
![]() |
![]() |
![]() |
FMC is a RIF-aware peripheral. Each FMC internal controller could be allocated to a different execution context. That means FMC could be used by Cortex-M33 when ROM code is executing D1Standby exit sequence. As ROM code doesn't know about product definition, ROM code considers that common FMC resources (FMC_R0, clock, associated IOs) are configured by ecosystem SW and is not reconfiguring these items in case of D1Standby exit. |
4. ROM code secure context isolation[edit source]
4.1. Principles[edit source]
The STM32MP2 ROM code is SESIP level 3 certified. This implies some guarantees regarding the isolation of the ROM code secure execution. ROM code defines some RIF configuration rules on ecosystem SW to:
- guarantee that all secure IPs used by ROM code are exclusively assigned to the Cortex-A35 secure context during ROM code execution and can't preempted by another secure processor running in parallel of the ROM code.
- guarantee that no processor and no bus master peripheral can access secure resources (peripheral and memories) owned by ROM code. That means no master with secure level and CID1 RIF configuration shall be active during ROM code execution
4.2. Rules on Secure SYSRAM[edit source]
SYSRAM is protected by RISAB1 and RISAB2 which are under the control of Cortex-A35 secure context. This is an exception in the RIF as normally all the control of all the RIF units is under the main processor secure context (TDCID) responsibility. This allows to guarantee the SYSRAM isolation during ROM code execution whatever main processor selection.
4.3. Rules on Secure peripherals RIF protection[edit source]
When Cortex-A35 is the main processor, Cortex-A35 secure context controls RIF configuration. When ROM code is running, no other master can modify RIF configuration. Checking access to secure peripheral is enough to guarantee ROM code exclusive access.
When Cortex-M33 is the main processor, the Cortex-M33 secure context controls RIF configuration. When ROM code is running, Cortex-M33 secure context can modify RIF configuration which can compromise ROM code exclusive access. To guarantee ROM code exclusive access to secure peripherals, associated RIF configuration must be locked. In addition to access checking, ROM code also verifies RIF lock status. If not set, ROM code goes in failure mode.
The following table list all RIF locks checked by ROM code in Cortex-M33 main processor, closed-locked boot.
Peripheral | RIF resource number | RIF block | Secure level checked | D1Standby exit lock check |
---|---|---|---|---|
BSEC clock | R103 | RCC | 1 | ![]() |
CPU1 boot, reset, IWDG management | R70 | RCC | 1 | ![]() |
CPU PWR1 | R2 | PWR | 1 | ![]() |
STGEN | R33 | RCC | 1 | ![]() |
RNG | R92 | RIFSC | 1 | ![]() |
PKA | R93 | RIFSC | 1 | ![]() |
SAES | R94 | RIFSC | 1 | ![]() |
HASH | R95 | RIFSC | 1 | ![]() |
CRYP1 | R96 | RIFSC | 1 | ![]() |
SYSRAM/RISAB2 | R74 | RCC | 1 | ![]() |
CA35SS | R106 | RCC | 1 | ![]() |
4.4. Rules on master peripherals RIF protection[edit source]
During ROM code execution, it shall not be possible for another master to access peripherals and memories assigned to ROM code secure context (CID1 secure).
For that, ROM code checks RIFSC RIMU configuration to detect any master with CID1 secure configuration:
- RIFSC RIMU sets to secure and RIFSC RISUP also set to secure (if RIFSC RISUP is set to non-secure, this tie RIMU secure level to non-secure)
- RISFC RIMU sets to CID1 or RIFSC RIMU set in CID inheritance mode and RIFSC RISUP set to CID1
If the RIF configuration of a master matches CID1 secure one, ROM code verifies if this peripheral is running or not in associated RCC registers (clock enabled). In such case, ROM code goes in failure mode. Note that in case of serial NOR or serial NAND boot, only SDMMC interfaces that are not used for that boot are checked here.
In the case of Cortex-M33 main processor, Cortex-M33 can modify RIFSC RISUP and RIMU during ROM code execution. In addition to access right verification, ROM code also verifies that RIMU and associated RISUP are locked.
The following table sums up the master peripheral RIFSC resources checked by ROM code.
Bus master peripheral | RIFSC RIMU index | RIFSC RISUP index | D1Standby exit RISUP lock check |
---|---|---|---|
SDMMC1 | 1 | 76 | ![]() |
SDMMC2 | 2 | 77 | ![]() |
SDMMC3 | 3 | 78 | ![]() |
USB3DR | 4 | 66 | ![]() |
USBH | 5 | 63 | ![]() |
ETH1 | 6 | 60 | ![]() |
ETH2 | 7 | 61 | ![]() |
PCIE | 8 | 68 | ![]() |
GPU | 9 | 79 | ![]() |
DCMIPP | 10 | 87 | ![]() |
LTDC | 11, 12, 13 | NA | ![]() |
VDEC | 14 | 89 | ![]() |
VENC | 15 | 90 | ![]() |
In addition, ROM code checks that no HPDMA channel owned by CID1 secure context is armed.