Commit 4282d67a authored by Mathieu Choplain's avatar Mathieu Choplain Committed by Benjamin Cabé
Browse files

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: default avatarMathieu Choplain <mathieu.choplain@st.com>
parent 86c51359
Loading
Loading
Loading
Loading
+11 −11
Changes for soc/st/stm32/stm32h7x/soc_m4.c: 11 added lines, 11 removed lines.
Original line number Diff line number Diff line
@@ -37,19 +37,19 @@ void soc_early_init_hook(void)
	/* Enable hardware semaphore clock */
	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()) {
		/*
		 * Domain D2 is waiting for Cortex-M7 to perform
		 * 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) {
			;
		while (!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) {
			/* Wait for CM7 to lock the HSEM after system initialization */
		}
	}
}
+7 −3
Changes for soc/st/stm32/stm32h7x/soc_m7.c: 7 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -31,9 +31,13 @@ static int stm32h7_m4_wakeup(void)
	LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG);

	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,
		 * then Cortex-M7 takes HSEM so that CM4 can continue running.
		/**
		 * Cortex-M4 has been started by hardware.
		 * 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);
	} else if (IS_ENABLED(CONFIG_STM32H7_BOOT_M4_AT_INIT)) {