soc: st: stm32h7: synchronize cores during boot properly

On dual-core STM32H7, the Cortex-M4 core is supposed to wait until the
Cortex-M7 initializes the system before starting to execute. CM7 should
signal this by locking a specific HSEM, which CM4 should poll until locked.
However, the logic on the Cortex-M4 side was reading the "RLR" register of
HSEM, which *locks the semaphore on read* - in turn, this makes the CM4
start directly since it sees that the semaphore is locked (by itself).

Use proper LL API to read HSEM status - which will read the "R" register
instead - to make sure CM4 doesn't begin execution earlier than it should.

Suggested-by: hglassdyb
Signed-off-by: Mathieu Choplain <mathieu.choplain@st.com>
This commit is contained in:
Mathieu Choplain 2025-05-27 14:02:28 +02:00 committed by Benjamin Cabé
commit 4282d67ac2
2 changed files with 18 additions and 14 deletions

View file

@ -37,19 +37,19 @@ void soc_early_init_hook(void)
/* Enable hardware semaphore clock */ /* Enable hardware semaphore clock */
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_HSEM); LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_HSEM);
/* In case CM4 has not been forced boot by CM7, /**
* CM4 needs to wait until CM7 has setup clock configuration * Cortex-M7 is responsible for initializing the system.
*
* CM7 will start CM4 ("forced boot") at the end of system
* initialization if the core is not already running - in
* this scenario, we don't have to wait because the system
* is initialized. Otherwise, wait for CM7 to initialize the
* system before proceeding with the boot process. CM7 will
* acquire a specific HSEM to indicate that CM4 can proceed.
*/ */
if (!LL_RCC_IsCM4BootForced()) { if (!LL_RCC_IsCM4BootForced()) {
/* while (!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) {
* Domain D2 is waiting for Cortex-M7 to perform /* Wait for CM7 to lock the HSEM after system initialization */
* system initialization
* (system clock config, external memory configuration.. ).
* End of system initialization is reached when CM7 takes HSEM.
*/
while ((HSEM->RLR[CFG_HW_ENTRY_STOP_MODE_SEMID] & HSEM_R_LOCK)
!= HSEM_R_LOCK) {
;
} }
} }
} }

View file

@ -31,9 +31,13 @@ static int stm32h7_m4_wakeup(void)
LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG); LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG);
if (READ_BIT(SYSCFG->UR1, SYSCFG_UR1_BCM4)) { if (READ_BIT(SYSCFG->UR1, SYSCFG_UR1_BCM4)) {
/* Cortex-M4 is waiting for end of system initialization made by /**
* Cortex-M7. This initialization is now finished, * Cortex-M4 has been started by hardware.
* then Cortex-M7 takes HSEM so that CM4 can continue running. * Its `soc_early_init_hook()` will stall boot until
* a specific HSEM becomes locked, which indicates
* that Cortex-M7 has finished initializing the system.
* As system initialization is now complete, lock the
* HSEM to release CM4 and allow it to continue booting.
*/ */
LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID); LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID);
} else if (IS_ENABLED(CONFIG_STM32H7_BOOT_M4_AT_INIT)) { } else if (IS_ENABLED(CONFIG_STM32H7_BOOT_M4_AT_INIT)) {