Thoughts: 1. When the SOC powers on, does only one core start, or do all cores start? 2. If only one core starts when the SOC powers on, where is the entry point for that core? 3. What is a cold boot? When is a warm boot used? In what scenarios would a warm boot be employed?
Basic Concepts
Please first understand the following four concepts:
-
cold boot
-
warm boot
-
Primary boot
-
Secondary boot
Additionally, there are two configurations:
-
If your reset address is programmable, it will be configured as
<span>PROGRAMMABLE_RESET_ADDRESS=1</span> -
If you start only one CPU during a cold boot, it will be configured as
<span>COLD_BOOT_SINGLE_CPU=1</span>
Boot Process
Assuming that the reset address is programmable and only one CPU starts during a cold boot, let’s explain our boot process:
(1) When the CPU powers on, the SOC sends a signal configuration to the ARM Core which changes RVBAR_EL3. Here, it generally points to the starting address of the bootrom. That is, when the CPU powers on, the PC of the primary core points to the address of RVBAR_EL3, and the machine starts up.
(2) When a secondary core needs to start, for example, it will follow the PSCI protocol, enter ATF, write bl31_warm_entrypoint into the SOC register, change the reset address (modify the value of RVBAR_EL3), and then the SOC’s PMIC powers on the secondary core, causing a cold reset on the secondary core, with the PC starting execution from RVBAR_EL3 (bl31_warm_entrypoint).
Summary: (For the example in this article: the reset address is programmable, and only one CPU starts during a cold boot):
-
Only the Primary Core runs immediately upon power on, starting from RVBAR_EL3, which is a cold boot.
-
When the secondary core starts, the reset value will be modified, affecting the value of RVBAR_EL3, and then powering on the secondary core, which still counts as a cold boot.
-
Generally, bl31_warm_entrypoint is set as the reset address, which is the starting address for the secondary core;
-
This example does not utilize warm boot.
Analysis of ATF (TF-A) Code

-
If the reset is programmable,
<span>PROGRAMMABLE_RESET_ADDRESS=1</span>, then<span>_warm_boot_mailbox = 0</span>, regardless of whether it’s a cold boot or warm boot, it will not go through<span>_warm_boot_mailbox</span>. -
If the reset is not programmable,
<span>PROGRAMMABLE_RESET_ADDRESS=0</span>, then<span>_warm_boot_mailbox = 1</span>, cold boot will not go through<span>_warm_boot_mailbox</span>, warm boot must go through<span>_warm_boot_mailbox</span>process.
.if _warm_boot_mailbox
/* -------------------------------------------------------------
* This code will be executed for both warm and cold resets.
* Now is the time to distinguish between the two.
* Query the platform entrypoint address and if it is not zero
* then it means it is a warm boot so jump to this address.
* -------------------------------------------------------------
*/
bl plat_get_my_entrypoint
cbz x0, do_cold_boot
br x0
-
If only one CPU starts during a cold boot,
<span>COLD_BOOT_SINGLE_CPU=1</span>, then<span>_secondary_cold_boot = 0</span>, regardless of whether it’s the primary or secondary core, neither needs to go through<span>_secondary_cold_boot</span>process. -
If multiple CPUs start during a cold boot,
<span>COLD_BOOT_SINGLE_CPU=0</span>, then<span>_secondary_cold_boot = 1</span>, the primary core will not go through<span>_secondary_cold_boot</span>, but the secondary core needs to go through<span>_secondary_cold_boot</span>process.
.if _secondary_cold_boot
/* -------------------------------------------------------------
* Check if this is a primary or secondary CPU cold boot.
* The primary CPU will set up the platform while the
* secondaries are placed in a platform-specific state until the
* primary CPU performs the necessary actions to bring them out
* of that state and allows entry into the OS.
* -------------------------------------------------------------
*/
bl plat_is_my_cpu_primary
cbnz w0, do_primary_cold_boot
/* This is a cold boot on a secondary CPU */
bl plat_secondary_cold_boot_setup
/* plat_secondary_cold_boot_setup() is not supposed to return */
bl el3_panic
do_primary_cold_boot:


Specific Scenarios Introduction
(1) Reboot command entered during serial interrupt or machine restart due to system panic: In some SOC vendor designs, it should be a code reboot. For example, in the Linux Kernel, entering the reboot command ultimately writes to some registers to control the PMIC (or PMU), directly powering off the CPU. Then, upon re-powering, the SOC will send signal configuration to the Core, at which point RVBAR_EL3 will again change to the value set by the ASIC.
(2) Suspend and Resume: For instance, in the HiSilicon platform within ATF, the address of bl31_warm_entrypoint is written to a register of the SOC PMIC in the ATF suspend function (upon power on, this register affects the RVBARADDR signal). At this point, when the system is in deep sleep, the Linux Kernel calls ATF, writing the address of bl31_warm_entrypoint into the relevant PMU/PMIC registers, which will affect the signal configuration and subsequently change the value of RVBAR_EL3 during the next reset. The system will then power off various modules (which modules to power off depends on the SOC design and logic), and finally power off the ARM Core, achieving deep sleep. During Resume, there are also some SOC hardware behaviors, and then the Core is powered on. Note that here the SOC does not resend the relevant signal configuration to the Core. So where does the Core execute from upon power on?
The PC still points to the address in RVBAR_EL3, which we modified during suspend, essentially being bl31_warm_entrypoint.
(3) RMR_EL3: Points 1-3 did not mention RMR_EL3. So what is RMR_EL3 for? This is an ARM feature, how to use it? It’s your own design, whatever you want. Writing bits in RMR_EL3 can trigger a warm reset. Generally, kernel dumps or some tools can actively trigger RMR_EL3 to perform certain tasks. I also saw a blog on CSDN about Qualcomm SOC’s boot process; in their normal boot process, a certain image jumps to another image by writing to RMR_EL3, triggering a warm reset, and the address of the other image happens to be the jump address for warm reset.
Follow Arm Select for more learning!