Last edited 3 months ago

STM32MP15 backup registers: Difference between revisions

Registered User
Registered User
Tag: 2017 source edit
(34 intermediate revisions by 7 users not shown)
Line 1: Line 1:
<noinclude>{{ApplicableFor
|MPUs list= STM32MP15x
|MPUs checklist=STM32MP13x, STM32MP15x
}}</noinclude>
This article explains which backup registers are used for system aspects in STM32 MPU Embedded Software distribution and so, which ones remain free for the application needs.
__FORCETOC__
__FORCETOC__


== Article purpose ==
== Article purpose ==
The purpose of this article is to explain how the [[TAMP internal peripheral|TAMP]] backup registers are used by [[STM32MPU Embedded Software architecture overview|STM32MPU Embedded Software]].
This article explains how the [[TAMP internal peripheral|TAMP]] backup registers are used by [[STM32MPU Embedded Software architecture overview|STM32MPU Embedded Software]] on STM32MP15.


== Overview ==
== Overview ==
The STM32MP15 embeds 32 backup registers of 32 bits. A programmable border allows to split those backup registers into a secure and a non-secure group.<br />
The STM32MP15 embeds 32 backup registers of 32 bits. A programmable border allows these backup registers to be split into a secure and a non-secure group<sup>[[#Security|a]]</sup>.<br />
By default, the [[STM32MP15 ROM code overview|ROM]] code defines the 10 first backup registers as secure, but this secure/non-secure border can be changed later on from the secure context.
 
== Backup register usage ==
This paragraph explains the default usage of of backup registers by the [[STM32 MPU ROM code overview|ROM]] code and [[:Category:STM32MPU_Embedded_Software_distribution|STM32MPU Embedded Software distribution]]. The subsequent chapter then shows the backup register mapping used to fulfill those needs.
{{Warning|It is important to notice that the backup registers can be erased when a tamper detection occurs in [[TAMP internal peripheral]]}}
{{Info | Backup register(s) might be used for another purpose by the application when the feature(s) listed below is/are not used by the said application}}
 
=== Boot counter feature ===
The [[#BOOT_COUNTER|BOOT_COUNTER]] is used by [[U-Boot overview|U-Boot]] to detect boot failures between its execution and before the complete Linux application initialization:
* It is incremented by U-Boot
* It is reset by the application
Hence if U-Boot reads a non-null value after a reset, this means that something went wrong at boot time. This information can be used to initiate  entry into a fail safe mode.
{{Warning|This feature is disabled by default, since TF-A BL2 firmware update feature takes care of a boot counter management}}
 
=== Boot mode selection feature ===
The [[#BOOT_MODE|BOOT_MODE]] register is used to propagate boot mode information from one component to the next boot stage, on cold boot or after a reset:
* The [[STM32 MPU ROM code overview|ROM code]] executes a serial boot if [[#BOOT_MODE|BOOT_MODE]][7:0] is equal to 0xFF, as stated in the [[STM32 MPU ROM code overview#Boot_device_selection|ROM code boot device selection strategy]]. In this case, the backup register is reset by the ROM code before proceeding with the serial boot mode. Other values are ignored by the ROM code.
* [[TF-A overview | TF-A]] gets the selected boot device from the ROM code context in SYSRAM and writes it into [[#BOOT_MODE|BOOT_MODE]][15:8] for U-Boot<ref name="u-boot">{{CodeSource | U-Boot |arch/arm/mach-stm32mp/include/mach/stm32.h}}</ref>. The boot interface type is written into [[#BOOT_MODE|BOOT_MODE]][15:12], and the instance used is written into [[#BOOT_MODE|BOOT_MODE]][11:8]. TF-A also writes other information in this register. The partition that was used to boot is written into [[#BOOT_MODE|BOOT_MODE]][19:16], and the BL2 authentification status from ROM code into [[#BOOT_MODE|BOOT_MODE]][23:20].
* [[U-Boot overview|U-Boot]] uses the [[#BOOT_MODE|BOOT_MODE]] register to get TF-A and Linux kernel (as explained in the next bullet) information<ref name="kernel"/> in order to select the desired boot mode (among "NORMAL", "STM32PROG", ...<ref name="u-boot" />) and build the appropriate "chosen" node in the device tree. This device tree is given to the Linux kernel for its start up, as explained in the "Runtime configuration" paragraph in {{CodeSource | Linux kernel | Documentation/devicetree/usage-model.rst | Documentation/devicetree/usage-model.rst}}.
* The [[STM32MP15 Linux kernel overview | Linux kernel]] can force a reboot mode by writing to the [[#BOOT_MODE|BOOT_MODE]] register. This writing is done via the "reboot" Linux command, which is configured via the compatible "syscon-reboot-mode" in the device tree <ref name="kernel">{{CodeSource | Linux kernel | arch/arm/boot/dts/stm32mp151.dtsi}}</ref>.


== Backup registers usage ==
=== Firmware update info feature ===
This paragraph explains the default backup registers usage by the [[STM32MP15 ROM code overview|ROM]] code and [[STM32MPU Embedded Software distribution]].<br />
The [[#FWU_INFO|FWU_INFO]] is used by [[TF-A overview|TF-A BL2]] to detect boot failures between its execution and before the complete Linux application initialization during a [[Secure Firmware Update]].
Then, the next chapter shows the backup register mapping used to fulfill those needs.
<br />
<br />
{{Warning|It is important to notice that the backup registers are erased when a tamper detection occurs in [[TAMP internal peripheral]]}}
=== At boot time ===
{{InternalInfo| '''Non-secure backup registers''' not yet developed usage:
* by [[U-Boot overview|U-Boot]] or [[Linux remoteproc framework overview|Linux remoteproc]] to store the Cortex<sup>&reg;</sup>-M4 firmware '''integrity check value'''. This firmware can be loaded in U-Boot or in Linux<sup>&reg;</sup>, depending on the [[Boot chains overview|boot chain configuration]].
}}
* '''Non-secure backup registers''' are used:
** during a cold boot:
*** by [[U-Boot overview|U-Boot]] to initialize the '''boot counter''', that should be reset later on by the application.
** after a reset:
*** by the [[STM32MP15 ROM code overview|ROM]] code to get an eventual '''forced boot mode''' that was set before reset. Notice that the ROM code is only interprating the value 0xFF to trigger a serial boot, as shown in the [[STM32MP15_ROM_code_overview#Boot_device_selection_via_the_boot_pins_and_OTP|ROM code boot device selection strategy]]. Other values are ignored by the ROM code but may be interprated by U-Boot, as described just below.
*** by [[U-Boot overview|U-Boot]] to get an eventual '''forced boot mode''' that was set before reset. This can be useful to set U-Boot in programmer mode after a reboot, for instance.
*** by [[U-Boot overview|U-Boot]] to increment the '''boot counter''' and perform given actions if a predefined number of successive boots is reached, due to cyclic resets before the application is alive (and clears the counter).
* '''Secure backup registers''' are used:
** to tell to the FSBL ([[TF-A overview|TF-A]] or [[U-Boot overview|U-Boot SPL]]) how to behave:
*** on cold boot, the [[STM32MP15 ROM code overview|ROM]] code sets the '''magic number''' to 0x0: this value tells to the FSBL that a complete [[DDRCTRL and DDRPHYC internal peripherals|DDR]] initialization is needed before jumping to the SSBL ([[U-Boot overview|U-Boot]]).
*** on wakeup from Standby with DDR in self-refresh [[Power overview|low power mode]], if the '''magic number''' == 0xCA7FACE0 then the FSBL performs a partial [[DDRCTRL and DDRPHYC internal peripherals|DDR]] initialization to exit Self-Refresh then it branches the Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 0 non-secure execution to the given '''branch address''' (in Linux<sup>&reg;</sup> kernel, that was set during secure context saving before the Standby [[Power overview|low power mode]] entering).
** by Linux<sup>&reg;</sup> kernel on Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 0 (via a [[Security_overview#PSCI|PSCI]] secure service) to tell to the [[STM32MP15 ROM code overview|ROM]] code how to start Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 1 (and enable the SMP mode): when Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 1 non-secure sees the '''magic number''' == 0xCA7FACE1 then it jumps to the given '''branch address'''.
** by the [[STM32MP15 ROM code overview|ROM]] code during wakeup from Standby [[Power overview|low power mode]] to recover the Cortex<sup>&reg;</sup>-M4 firmware '''integrity check value''' and compare it to the one computed on [[RETRAM internal memory|RETRAM]] before starting the Cortex<sup>&reg;</sup>-M4 again.


Notice: the [[STM32MP15 ROM code overview|ROM]] code knows if Cortex<sup>&reg;</sup>-A7 and/or Cortex<sup>&reg;</sup>-M4 have to be restarted after Standby thanks to [[RCC internal peripheral|RCC_MP_BOOTCR]] register, so the backup registers are not used here.
=== DDR and CPU wake up management feature ===
The [[#MAGIC_NUMBER|MAGIC_NUMBER]] and [[#BRANCH_ADDRESS|BRANCH_ADDRESS]] registers allow control of the [[DDRCTRL and DDRPHYC internal peripherals|DDR]] initialization and the Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 CPU core's behavior on system transitions:
* On cold boot, the [[STM32 MPU ROM code overview|ROM code]] sets the [[#MAGIC_NUMBER|MAGIC_NUMBER]] register to 0x0. When the FSBL [[TF-A overview|TF-A BL2]] reads a value different from 0xCA7FACE0 (for example 0x0) in [[#MAGIC_NUMBER|MAGIC_NUMBER]], it performs a complete DDR initialization before jumping to the SSBL ([[U-Boot overview|U-Boot]]).
* Before entering Standby with DDR in self-refresh [[Power overview|low power mode]], the PSCI framework writes the return address to which the Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 0 should branch to on wake up into the  [[#BRANCH_ADDRESS|BRANCH_ADDRESS]] register, and sets the [[#MAGIC_NUMBER|MAGIC_NUMBER]] register to 0xCA7FACE0.
* On wakeup from Standby, when the FSBL reads the value 0xCA7FACE0 from the [[#MAGIC_NUMBER|MAGIC_NUMBER]] register, it has to perform a partial DDR initialization to exit Self-Refresh, before branching the Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 0 non-secure execution back to the address given by the [[#BRANCH_ADDRESS|BRANCH_ADDRESS]] register.
* On startup, the Linux<sup>&reg;</sup> kernel starts to run on the Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 0, and uses the PSCI framework to write the address where the core 1 has to jump in [[#BRANCH_ADDRESS|BRANCH_ADDRESS]] register and to set [[#MAGIC_NUMBER|MAGIC_NUMBER]] register to 0xCA7FACE1. These values are then interpreted by the ROM code, as explained in [[STM32_MPU_ROM_code_overview#Secondary_core_boot|secondary core boot]] paragraph.


=== At runtime ===
=== Cortex-M4 wake up feature ===
* Non secure backup registers
The [[STM32 MPU ROM code overview|ROM code]] can autonomously start the Arm Cortex<sup>&reg;</sup>-M4 with a firmware kept in [[RETRAM internal memory|RETRAM]] after a Standby low power mode period:
** own the '''boot counter''' and should be reset by the application after a successful startup.
* On wake up from Standby low power mode, the [[#M4_WAKEUP_AREA_HASH|M4_WAKEUP_AREA_HASH]], [[#M4_WAKEUP_AREA_LENGTH|M4_WAKEUP_AREA_LENGTH]] and [[#M4_WAKEUP_AREA_START|M4_WAKEUP_AREA_START]] registers are used by the ROM code to perform an integrity check on the Arm Cortex<sup>&reg;</sup>-M4 firmware stored in RETRAM. If successful, the ROM code starts the Cortex-M4 execution.
** are used to store Cortex<sup>&reg;</sup>-M4 retention firmware '''integrity check value''' before going to Standby mode, if the Cortex<sup>&reg;</sup>-M4 needs to be started on wakeup from Standby mode by the [[STM32MP15 ROM code overview|ROM]] code.
* Before entering Standby mode, it is the application's responsibility to set the above registers; the application has to compute and store the SHA-256 hash to be used by the ROM code on wake up. The hash is computed starting from the address stored in [[#M4_WAKEUP_AREA_START|M4_WAKEUP_AREA_START]], for the length defined in [[#M4_WAKEUP_AREA_LENGTH|M4_WAKEUP_AREA_LENGTH]] and is stored in [[#M4_WAKEUP_AREA_HASH|M4_WAKEUP_AREA_HASH]].
* Secure backup registers
* In addition to this branching mechanism, the Cortex-M4 coprocessor may need to access to some system resources that are secured (and so not accessible) by default. To achieve this, the RCC registers [[RCC internal peripheral |RCC]]_TZCR, [[EXTI internal peripheral |EXTI]]_TZENR1, [[EXTI internal peripheral |EXTI]]_TZENR2 and [[EXTI internal peripheral |EXTI]]_TZENR3 respectively are saved into the [[#WAKEUP_SEC|WAKEUP_SEC]], [[#M4_SECURITY_PERIMETER_EXTI1|M4_SECURITY_PERIMETER_EXTI1]], [[#M4_SECURITY_PERIMETER_EXTI2|M4_SECURITY_PERIMETER_EXTI2]], and [[#M4_SECURITY_PERIMETER_EXTI3|M4_SECURITY_PERIMETER_EXTI3]] registers by the application before entering Standby mode, and are restored by the ROM code on wake up.
** are used by [[TF-A overview#BL32|secure services]] to store:
{{Warning | This feature is enabled in the ROM code but is not implemented in STM32 MPU Embedded Software}}
*** Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-A7 core 0 '''branch address''' that are used by the [[STM32MP15 ROM code overview|ROM]] code on wakeup from Standby mode.
 
*** Arm<sup>&reg;</sup> Cortex<sup>&reg;</sup>-M4 '''security perimeter''' that is restored by the [[STM32MP15 ROM code overview|ROM]] code before starting the Cortex<sup>&reg;</sup>-M4 on wakeup from Standby.
=== Cortex-M4 management feature ===
Two registers are used to control the Arm Cortex<sup>&reg;</sup>-M4 coprocessor from the Arm Cortex<sup>&reg;</sup>-A7:
* The [[#COPRO_RSC_TBL_ADDRESS|COPRO_RSC_TBL_ADDRESS]] register owns the [[Coprocessor resource table]] base address. This is read by the Linux Kernel to retrieve the resource table when the Cortex-M4 firmware is loaded by U-Boot or OP-TEE.
* The [[#CORTEX_M_STATE|CORTEX_M_STATE]] register reflects the Cortex-M4 state. This is written by U-Boot or OP-TEE when loading the firmware; it can be updated by the Cortex-M4 firmware at runtime and is read by the Linux Kernel to know the coprocessor state.


== Memory mapping ==
== Memory mapping ==
Line 48: Line 59:
{|  
{|  
! [[TAMP internal peripheral|TAMP]] register
! [[TAMP internal peripheral|TAMP]] register
! Security
! Security<sup>[[#Security|a]]</sup>
! [[STM32MP15 ROM code overview|ROM]] / software register name
! [[STM32 MPU ROM code overview|ROM]] / software register name
! Comment
! Comment
|-
|-
| TAMP_BKP31R
| TAMP_BKP31R
| Non-secure
| Non-secure
| rowspan="8" | M4_WAKEUP_AREA_HASH
| rowspan="8" | <span id="M4_WAKEUP_AREA_HASH">M4_WAKEUP_AREA_HASH</span>
| rowspan="8" | This register can be used to store a SHA-256 value computed on M4_WAKEUP_AREA_LENGTH bytes in [[RETRAM internal memory|RETRAM]] starting from M4_WAKEUP_AREA_START, before entering in low power Standby mode. This allows the [[STM32MP15 ROM code overview|ROM]] code to perform an integrity check on wakeup before starting the coprocessor.
| rowspan="8" | SHA-256 value, see [[#Cortex-M4 wake up feature|Cortex-M4 wake up feature]]
|-
|-
| TAMP_BKP30R
| TAMP_BKP30R
Line 80: Line 91:
| TAMP_BKP23R
| TAMP_BKP23R
| Non-secure
| Non-secure
| M4_WAKEUP_AREA_LENGTH
| <span id="M4_WAKEUP_AREA_LENGTH">M4_WAKEUP_AREA_LENGTH</span>
| Amount of bytes hashed in [[RETRAM internal memory|RETRAM]] to compute the integrity check value
| See [[#Cortex-M4 wake up feature|Cortex-M4 wake up feature]]
|-
|-
| TAMP_BKP22R
| TAMP_BKP22R
| Non-secure
| Non-secure
| M4_WAKEUP_AREA_START
| <span id="M4_WAKEUP_AREA_START">M4_WAKEUP_AREA_START</span>
| Start address in [[RETRAM internal memory|RETRAM]] from where the integrity check value has to be computed
| See [[#Cortex-M4 wake up feature|Cortex-M4 wake up feature]]
|-
|-
| TAMP_BKP21R
| TAMP_BKP21R
| Non-secure
| Non-secure
| BOOT_COUNTER
| <span id="BOOT_COUNTER">BOOT_COUNTER</span>
| Boot counter
| See [[#Boot counter feature | Boot counter feature]]
|-
|-
| TAMP_BKP20R
| TAMP_BKP20R
| Non-secure
| Non-secure
| BOOT_MODE<ref name="u-boot">{{CodeSource | U-Boot | arch/arm/mach-stm32mp/include/mach/stm32.h}}</ref>
| <span id="BOOT_MODE">BOOT_MODE</span>
| Boot mode context information
| See [[#Boot mode selection feature | Boot mode selection feature]]
|-
|-
| TAMP_BKP19R
| TAMP_BKP19R
| Non-secure
| Non-secure
|  
|  
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP18R
| TAMP_BKP18R
| Non-secure
| Non-secure
| CORTEX_M_STATE
| <span id="CORTEX_M_STATE">CORTEX_M_STATE</span>
| Cortex-M state (written by Cortex-M / read by Cortex-A)
| See [[#Cortex-M4 management feature|Cortex-M4 management feature]]
|-
|-
| TAMP_BKP17R
| TAMP_BKP17R
| Non-secure
| Non-secure
| COPRO_RSC_TBL_ADDRESS
| <span id="COPRO_RSC_TBL_ADDRESS">COPRO_RSC_TBL_ADDRESS</span>
| [[Coprocessor resource table]] base address
| See [[#Cortex-M4 management feature|Cortex-M4 management feature]]
|-
|-
| TAMP_BKP16R
| TAMP_BKP16R
| Non-secure
| Non-secure
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP15R
| TAMP_BKP15R
| Non-secure
| Non-secure
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP14R
| TAMP_BKP14R
| Non-secure
| Secure Write/ Non-secure Read
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP13R
| TAMP_BKP13R
| Non-secure
| Secure Write/ Non-secure Read
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP12R
| TAMP_BKP12R
| Non-secure
| Secure Write/ Non-secure Read
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP11R
| TAMP_BKP11R
| Non-secure
| Secure Write/ Non-secure Read
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP10R
| TAMP_BKP10R
| Non-secure
| Secure Write/ Non-secure Read
|
| <span id="FWU_INFO">FWU_INFO</span>
| (Reserved for future use)
| See [[#Firmware update info feature | Firmware update info feature]]
|-
|-
| TAMP_BKP9R
| TAMP_BKP9R
| Secure
| Secure
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP8R
| TAMP_BKP8R
| Secure
| Secure
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP7R
| TAMP_BKP7R
| Secure
| Secure
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP6R
| TAMP_BKP6R
| Secure
| Secure
|
|
| (Reserved for future use)
| (Free)
|-
|-
| TAMP_BKP5R
| TAMP_BKP5R
| Secure
| Secure
| BRANCH_ADDRESS<ref name="u-boot" />
| <span id="BRANCH_ADDRESS">BRANCH_ADDRESS</span>
| CPU0 or CPU1 branch address
| See [[#DDR and CPU wake up management feature | DDR and CPU wake up management feature]]
|-
|-
| TAMP_BKP4R
| TAMP_BKP4R
| Secure
| Secure
| MAGIC_NUMBER<ref name="u-boot" />
| <span id="MAGIC_NUMBER">MAGIC_NUMBER</span>
| CPU0 or CPU1 boot magic number
| See [[#DDR and CPU wake up management feature | DDR and CPU wake up management feature]]
|-
|-
| TAMP_BKP3R
| TAMP_BKP3R
| Secure
| Secure
| M4_SECURITY_PERIMETER_EXTI3
| <span id="M4_SECURITY_PERIMETER_EXTI3">M4_SECURITY_PERIMETER_EXTI3</span>
| Value of AEIC TZENR3
| See [[#Cortex-M4 wake up feature|Cortex-M4 wake up feature]]
|-
|-
| TAMP_BKP2R
| TAMP_BKP2R
| Secure
| Secure
| M4_SECURITY_PERIMETER_EXTI2
| <span id="M4_SECURITY_PERIMETER_EXTI2">M4_SECURITY_PERIMETER_EXTI2</span>
| Value of AEIC TZENR2
| See [[#Cortex-M4 wake up feature|Cortex-M4 wake up feature]]
|-
|-
| TAMP_BKP1R
| TAMP_BKP1R
| Secure
| Secure
| M4_SECURITY_PERIMETER_EXTI1
| <span id="M4_SECURITY_PERIMETER_EXTI1">M4_SECURITY_PERIMETER_EXTI1</span>
| Value of AEIC TZENR1
| See [[#Cortex-M4 wake up feature|Cortex-M4 wake up feature]]
|-
|-
| TAMP_BKP0R
| TAMP_BKP0R
| Secure
| Secure
| WAKEUP_SEC
| <span id="WAKEUP_SEC">WAKEUP_SEC</span>
| Wakeup parameters
| See [[#Cortex-M4 wake up feature|Cortex-M4 wake up feature]]
|}
|}
<span id="Security">a</span>: the security borders are configured by the Secure OS (look for {{Highlight|st,backup-zones}} in [[TAMP_device_tree_configuration#Common_TAMP_node_append|TAMP configuration]]), so the OP-TEE device tree has to be modified if a different border is needed.


== References ==
== References ==
Line 204: Line 216:
<noinclude>
<noinclude>
[[Category:STM32MP15 platform configuration|3]]
[[Category:STM32MP15 platform configuration|3]]
{{PublicationRequestId | 22116 | 2022-01-04 | TW review done in stm32mpuv3 }}
</noinclude>
</noinclude>

Revision as of 10:23, 18 April 2024

Applicable for STM32MP15x lines

This article explains which backup registers are used for system aspects in STM32 MPU Embedded Software distribution and so, which ones remain free for the application needs.


1. Article purpose[edit | edit source]

This article explains how the TAMP backup registers are used by STM32MPU Embedded Software on STM32MP15.

2. Overview[edit | edit source]

The STM32MP15 embeds 32 backup registers of 32 bits. A programmable border allows these backup registers to be split into a secure and a non-secure groupa.

3. Backup register usage[edit | edit source]

This paragraph explains the default usage of of backup registers by the ROM code and STM32MPU Embedded Software distribution. The subsequent chapter then shows the backup register mapping used to fulfill those needs.

Warning.png It is important to notice that the backup registers can be erased when a tamper detection occurs in TAMP internal peripheral
Info white.png Information
Backup register(s) might be used for another purpose by the application when the feature(s) listed below is/are not used by the said application

3.1. Boot counter feature[edit | edit source]

The BOOT_COUNTER is used by U-Boot to detect boot failures between its execution and before the complete Linux application initialization:

  • It is incremented by U-Boot
  • It is reset by the application

Hence if U-Boot reads a non-null value after a reset, this means that something went wrong at boot time. This information can be used to initiate entry into a fail safe mode.

Warning.png This feature is disabled by default, since TF-A BL2 firmware update feature takes care of a boot counter management

3.2. Boot mode selection feature[edit | edit source]

The BOOT_MODE register is used to propagate boot mode information from one component to the next boot stage, on cold boot or after a reset:

  • The ROM code executes a serial boot if BOOT_MODE[7:0] is equal to 0xFF, as stated in the ROM code boot device selection strategy. In this case, the backup register is reset by the ROM code before proceeding with the serial boot mode. Other values are ignored by the ROM code.
  • TF-A gets the selected boot device from the ROM code context in SYSRAM and writes it into BOOT_MODE[15:8] for U-Boot[1]. The boot interface type is written into BOOT_MODE[15:12], and the instance used is written into BOOT_MODE[11:8]. TF-A also writes other information in this register. The partition that was used to boot is written into BOOT_MODE[19:16], and the BL2 authentification status from ROM code into BOOT_MODE[23:20].
  • U-Boot uses the BOOT_MODE register to get TF-A and Linux kernel (as explained in the next bullet) information[2] in order to select the desired boot mode (among "NORMAL", "STM32PROG", ...[1]) and build the appropriate "chosen" node in the device tree. This device tree is given to the Linux kernel for its start up, as explained in the "Runtime configuration" paragraph in Documentation/devicetree/usage-model.rst .
  • The Linux kernel can force a reboot mode by writing to the BOOT_MODE register. This writing is done via the "reboot" Linux command, which is configured via the compatible "syscon-reboot-mode" in the device tree [2].

3.3. Firmware update info feature[edit | edit source]

The FWU_INFO is used by TF-A BL2 to detect boot failures between its execution and before the complete Linux application initialization during a Secure Firmware Update.

3.4. DDR and CPU wake up management feature[edit | edit source]

The MAGIC_NUMBER and BRANCH_ADDRESS registers allow control of the DDR initialization and the Arm® Cortex®-A7 CPU core's behavior on system transitions:

  • On cold boot, the ROM code sets the MAGIC_NUMBER register to 0x0. When the FSBL TF-A BL2 reads a value different from 0xCA7FACE0 (for example 0x0) in MAGIC_NUMBER, it performs a complete DDR initialization before jumping to the SSBL (U-Boot).
  • Before entering Standby with DDR in self-refresh low power mode, the PSCI framework writes the return address to which the Arm® Cortex®-A7 core 0 should branch to on wake up into the BRANCH_ADDRESS register, and sets the MAGIC_NUMBER register to 0xCA7FACE0.
  • On wakeup from Standby, when the FSBL reads the value 0xCA7FACE0 from the MAGIC_NUMBER register, it has to perform a partial DDR initialization to exit Self-Refresh, before branching the Arm® Cortex®-A7 core 0 non-secure execution back to the address given by the BRANCH_ADDRESS register.
  • On startup, the Linux® kernel starts to run on the Arm® Cortex®-A7 core 0, and uses the PSCI framework to write the address where the core 1 has to jump in BRANCH_ADDRESS register and to set MAGIC_NUMBER register to 0xCA7FACE1. These values are then interpreted by the ROM code, as explained in secondary core boot paragraph.

3.5. Cortex-M4 wake up feature[edit | edit source]

The ROM code can autonomously start the Arm Cortex®-M4 with a firmware kept in RETRAM after a Standby low power mode period:

  • On wake up from Standby low power mode, the M4_WAKEUP_AREA_HASH, M4_WAKEUP_AREA_LENGTH and M4_WAKEUP_AREA_START registers are used by the ROM code to perform an integrity check on the Arm Cortex®-M4 firmware stored in RETRAM. If successful, the ROM code starts the Cortex-M4 execution.
  • Before entering Standby mode, it is the application's responsibility to set the above registers; the application has to compute and store the SHA-256 hash to be used by the ROM code on wake up. The hash is computed starting from the address stored in M4_WAKEUP_AREA_START, for the length defined in M4_WAKEUP_AREA_LENGTH and is stored in M4_WAKEUP_AREA_HASH.
  • In addition to this branching mechanism, the Cortex-M4 coprocessor may need to access to some system resources that are secured (and so not accessible) by default. To achieve this, the RCC registers RCC_TZCR, EXTI_TZENR1, EXTI_TZENR2 and EXTI_TZENR3 respectively are saved into the WAKEUP_SEC, M4_SECURITY_PERIMETER_EXTI1, M4_SECURITY_PERIMETER_EXTI2, and M4_SECURITY_PERIMETER_EXTI3 registers by the application before entering Standby mode, and are restored by the ROM code on wake up.
Warning.png This feature is enabled in the ROM code but is not implemented in STM32 MPU Embedded Software

3.6. Cortex-M4 management feature[edit | edit source]

Two registers are used to control the Arm Cortex®-M4 coprocessor from the Arm Cortex®-A7:

  • The COPRO_RSC_TBL_ADDRESS register owns the Coprocessor resource table base address. This is read by the Linux Kernel to retrieve the resource table when the Cortex-M4 firmware is loaded by U-Boot or OP-TEE.
  • The CORTEX_M_STATE register reflects the Cortex-M4 state. This is written by U-Boot or OP-TEE when loading the firmware; it can be updated by the Cortex-M4 firmware at runtime and is read by the Linux Kernel to know the coprocessor state.

4. Memory mapping[edit | edit source]

The table below shows the backup register mapping used by STM32MPU Embedded Software.
The TAMP backup register base address is 0x5C00A100, corresponding to TAMP_BKP0R.

TAMP register Securitya ROM / software register name Comment
TAMP_BKP31R Non-secure M4_WAKEUP_AREA_HASH SHA-256 value, see Cortex-M4 wake up feature
TAMP_BKP30R Non-secure
TAMP_BKP29R Non-secure
TAMP_BKP28R Non-secure
TAMP_BKP27R Non-secure
TAMP_BKP26R Non-secure
TAMP_BKP25R Non-secure
TAMP_BKP24R Non-secure
TAMP_BKP23R Non-secure M4_WAKEUP_AREA_LENGTH See Cortex-M4 wake up feature
TAMP_BKP22R Non-secure M4_WAKEUP_AREA_START See Cortex-M4 wake up feature
TAMP_BKP21R Non-secure BOOT_COUNTER See Boot counter feature
TAMP_BKP20R Non-secure BOOT_MODE See Boot mode selection feature
TAMP_BKP19R Non-secure (Free)
TAMP_BKP18R Non-secure CORTEX_M_STATE See Cortex-M4 management feature
TAMP_BKP17R Non-secure COPRO_RSC_TBL_ADDRESS See Cortex-M4 management feature
TAMP_BKP16R Non-secure (Free)
TAMP_BKP15R Non-secure (Free)
TAMP_BKP14R Secure Write/ Non-secure Read (Free)
TAMP_BKP13R Secure Write/ Non-secure Read (Free)
TAMP_BKP12R Secure Write/ Non-secure Read (Free)
TAMP_BKP11R Secure Write/ Non-secure Read (Free)
TAMP_BKP10R Secure Write/ Non-secure Read FWU_INFO See Firmware update info feature
TAMP_BKP9R Secure (Free)
TAMP_BKP8R Secure (Free)
TAMP_BKP7R Secure (Free)
TAMP_BKP6R Secure (Free)
TAMP_BKP5R Secure BRANCH_ADDRESS See DDR and CPU wake up management feature
TAMP_BKP4R Secure MAGIC_NUMBER See DDR and CPU wake up management feature
TAMP_BKP3R Secure M4_SECURITY_PERIMETER_EXTI3 See Cortex-M4 wake up feature
TAMP_BKP2R Secure M4_SECURITY_PERIMETER_EXTI2 See Cortex-M4 wake up feature
TAMP_BKP1R Secure M4_SECURITY_PERIMETER_EXTI1 See Cortex-M4 wake up feature
TAMP_BKP0R Secure WAKEUP_SEC See Cortex-M4 wake up feature

a: the security borders are configured by the Secure OS (look for st,backup-zones in TAMP configuration), so the OP-TEE device tree has to be modified if a different border is needed.

5. References[edit | edit source]