diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7b6b292b5c13d..c4b450089c967 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -144,6 +144,16 @@ config ARM_ON_EXIT_CPU_IDLE observed on some SoCs caused by a memory access following WFI/WFE instructions. +config ARCH_PM_S2RAM_RESUME + bool "Include PM S2RAM resume jump" + depends on ARCH_HAS_SUSPEND_TO_RAM && !PM_S2RAM + depends on CPU_CORTEX_M + help + This option enables suspend-to-RAM (S2RAM) resume intermediary support. + It is dedicated for the bootloader use case where the bootloader is the first stage + and its role (in S2RAM flow) is just to mediate in resuming the application from + the suspension. + rsource "core/Kconfig" rsource "core/Kconfig.vfp" diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index de4c99f4b67b8..bbe383910ffd5 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -41,6 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c) zephyr_library_sources_ifdef(CONFIG_PM_S2RAM pm_s2ram.c pm_s2ram.S) +zephyr_library_sources_ifdef(CONFIG_ARCH_PM_S2RAM_RESUME pm_s2ram_intermediary.S) zephyr_library_sources_ifdef(CONFIG_ARCH_CACHE cache.c) zephyr_library_sources_ifdef(CONFIG_SW_VECTOR_RELAY irq_relay.S) diff --git a/arch/arm/core/cortex_m/pm_s2ram_intermediary.S b/arch/arm/core/cortex_m/pm_s2ram_intermediary.S new file mode 100644 index 0000000000000..117a5b04dd1af --- /dev/null +++ b/arch/arm/core/cortex_m/pm_s2ram_intermediary.S @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARM Cortex-M suspend-to-RAM resume intermediary code (S2RAM) + */ + +#include +#include +#include + +GTEXT(pm_s2ram_mark_check_and_mediate) + +GTEXT(arch_pm_s2ram_resume) +SECTION_FUNC(TEXT, arch_pm_s2ram_resume) + /* + * Check if reset occurred after suspending to RAM. + * Store LR to ensure we can continue boot when we are not suspended + * to RAM. In addition to LR, R0 is pushed too, to ensure "SP mod 8 = 0", + * as stated by ARM rule 6.2.1.2 for AAPCS32. + */ + push {r0, lr} + bl pm_s2ram_mark_check_and_mediate + pop {r0, pc} diff --git a/arch/arm/core/cortex_m/reset.S b/arch/arm/core/cortex_m/reset.S index b09391aaf0b59..58606cf48e23c 100644 --- a/arch/arm/core/cortex_m/reset.S +++ b/arch/arm/core/cortex_m/reset.S @@ -100,7 +100,7 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) #endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */ -#if defined(CONFIG_PM_S2RAM) +#if defined(CONFIG_PM_S2RAM) || defined(CONFIG_ARCH_PM_S2RAM_RESUME) /* * Temporarily set MSP to interrupt stack so that arch_pm_s2ram_resume can * use stack for calling pm_s2ram_mark_check_and_clear. diff --git a/include/zephyr/arch/common/pm_s2ram.h b/include/zephyr/arch/common/pm_s2ram.h index 34c544c769b9b..b16186f894d83 100644 --- a/include/zephyr/arch/common/pm_s2ram.h +++ b/include/zephyr/arch/common/pm_s2ram.h @@ -81,6 +81,19 @@ void pm_s2ram_mark_set(void); * @retval false if marking is not found which indicates standard boot. */ bool pm_s2ram_mark_check_and_clear(void); + +/** + * @brief Check suspend-to-RAM marking and does mediation. + * + * Function does resume mediation if determines resuming after suspend-to-RAM + * or return so standard boot will be executed. + * + * Implementation is up to given application - usually a bootloader. The function is expected + * to do mediation needed for resuming the application from S2AM state, which usually means no + * return to caller. Usage of this API implementation shall be enabled using + * CONFIG_ARCH_PM_S2RAM_RESUME. + */ +void pm_s2ram_mark_check_and_mediate(void); /** * @} */