arch: arm: cortex_m: pm_s2ram: Add option for custom marking

s2ram procedure used RAM magic word for marking suspend-to-RAM. This
method may not work in some cases, e.g. when global reset does not
reset RAM content. In that case resuming from s2ram is detected when
global reset occurred.

RAM magic word method is the default but with
CONFIG_PM_S2RAM_CUSTOM_MARKING a custom implementation can be provided.

Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruściński 2024-02-12 11:56:20 +01:00 committed by Carles Cufí
commit 24082d582f
4 changed files with 67 additions and 25 deletions

View file

@ -14,12 +14,11 @@
#include <zephyr/arch/cpu.h>
#include <zephyr/arch/common/pm_s2ram.h>
#define MAGIC (0xDABBAD00)
_ASM_FILE_PROLOGUE
GTEXT(pm_s2ram_mark_set)
GTEXT(pm_s2ram_mark_check_and_clear)
GDATA(_cpu_context)
GDATA(marker)
SECTION_FUNC(TEXT, arch_pm_s2ram_suspend)
/*
@ -64,11 +63,9 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend)
str r2, [r1, #___cpu_context_t_control_OFFSET]
/*
* Set the marker to MAGIC value
* Mark entering suspend to RAM.
*/
ldr r1, =marker
ldr r2, =MAGIC
str r2, [r1]
bl pm_s2ram_mark_set
/*
* Call the system_off function passed as parameter. This should never
@ -82,35 +79,29 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend)
*/
/*
* Reset the marker
* Reset the marking of suspend to RAM, return is ignored.
*/
ldr r1, =marker
mov r2, #0x0
str r2, [r1]
push {r0}
bl pm_s2ram_mark_check_and_clear
pop {r0}
pop {r4-r12, lr}
bx lr
GTEXT(arch_pm_s2ram_resume)
SECTION_FUNC(TEXT, arch_pm_s2ram_resume)
/*
* Check if the marker is set
* Check if reset occurred after suspending to RAM.
*/
ldr r0, =marker
ldr r0, [r0]
ldr r1, =MAGIC
cmp r0, r1
push {lr}
bl pm_s2ram_mark_check_and_clear
cmp r0, #0x1
pop {lr}
beq resume
bx lr
resume:
/*
* Reset the marker
*/
ldr r0, =marker
mov r1, #0x0
str r1, [r0]
/*
* Restore the CPU context
*/

View file

@ -9,12 +9,33 @@
#include <zephyr/arch/common/pm_s2ram.h>
#define MAGIC (0xDABBAD00)
/**
* CPU context for S2RAM
*/
__noinit _cpu_context_t _cpu_context;
#ifndef CONFIG_PM_S2RAM_CUSTOM_MARKING
/**
* S2RAM Marker
*/
__noinit uint32_t marker;
static __noinit uint32_t marker;
void pm_s2ram_mark_set(void)
{
marker = MAGIC;
}
bool pm_s2ram_mark_check_and_clear(void)
{
if (marker == MAGIC) {
marker = 0;
return true;
}
return false;
}
#endif /* CONFIG_PM_S2RAM_CUSTOM_MARKING */

View file

@ -7,7 +7,6 @@
*
* @brief public S2RAM APIs.
* @defgroup pm_s2ram S2RAM APIs
* @ingroup subsys_pm
* @{
*/
@ -57,6 +56,30 @@ typedef int (*pm_s2ram_system_off_fn_t)(void);
*/
int arch_pm_s2ram_suspend(pm_s2ram_system_off_fn_t system_off);
/**
* @brief Mark that core is entering suspend-to-RAM state.
*
* Function is called when system state is stored to RAM, just before going to system
* off.
*
* Default implementation is setting a magic word in RAM. CONFIG_PM_S2RAM_CUSTOM_MARKING
* allows custom implementation.
*/
void pm_s2ram_mark_set(void);
/**
* @brief Check suspend-to-RAM marking and clear its state.
*
* Function is used to determine if resuming after suspend-to-RAM shall be performed
* or standard boot code shall be executed.
*
* Default implementation is checking a magic word in RAM. CONFIG_PM_S2RAM_CUSTOM_MARKING
* allows custom implementation.
*
* @retval true if marking is found which indicates resuming after suspend-to-RAM.
* @retval false if marking is not found which indicates standard boot.
*/
bool pm_s2ram_mark_check_and_clear(void);
/**
* @}
*/

View file

@ -37,6 +37,13 @@ config PM_S2RAM
help
This option enables suspend-to-RAM (S2RAM).
config PM_S2RAM_CUSTOM_MARKING
bool "Use custom marking functions"
depends on PM_S2RAM
help
By default a magic word in RAM is used to mark entering suspend-to-RAM. Enabling
this option allows custom implementation of functions which handles the marking.
config PM_NEED_ALL_DEVICES_IDLE
bool "System Low Power Mode Needs All Devices Idle"
depends on PM_DEVICE && !SMP