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:
parent
86c5135982
commit
4282d67ac2
2 changed files with 18 additions and 14 deletions
|
@ -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) {
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue