@@ -21,6 +21,7 @@ _ASM_FILE_PROLOGUE
2121GTEXT(z_arm_reset)
2222GTEXT(z_early_memset)
2323GDATA(z_interrupt_stacks)
24+ GDATA(z_main_stack)
2425#if defined(CONFIG_DEBUG_THREAD_INFO)
2526GDATA(z_sys_post_kernel)
2627#endif
@@ -29,7 +30,6 @@ GTEXT(soc_reset_hook)
2930#endif
3031#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT)
3132GTEXT(z_arm_init_arch_hw_at_boot)
32- GDATA(z_main_stack)
3333#endif
3434#if defined(CONFIG_PM_S2RAM)
3535GTEXT(arch_pm_s2ram_resume)
@@ -68,13 +68,6 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,z_arm_reset)
6868 */
6969SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start)
7070
71- #if defined(CONFIG_DEBUG_THREAD_INFO)
72- /* Clear z_sys_post_kernel flag for RTOS aware debuggers */
73- movs .n r0, #0
74- ldr r1, =z_sys_post_kernel
75- strb r0, [r1]
76- #endif /* CONFIG_DEBUG_THREAD_INFO */
77-
7871#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT)
7972 /* Reset CONTROL register */
8073 movs .n r0, #0
@@ -90,9 +83,56 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start)
9083#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */
9184
9285#if defined(CONFIG_PM_S2RAM)
86+ /*
87+ * Temporarily set MSP to interrupt stack so that arch_pm_s2ram_resume can
88+ * use stack for calling pm_s2ram_mark_check_and_clear.
89+ * This is safe because suspend never being called from an ISR ensures that
90+ * interrupt stack was not live during suspend.
91+ * Note:
92+ * if resuming from suspend, MSP is restored from cpu context
93+ * if not resuming, MSP will be set back to z_main_stack for proper init
94+ * And, apart from arch_pm_s2ram_resume being able to use the stack for
95+ * a short while, there is no change in behavior in either of the paths.
96+ */
97+ ldr r0, =z_interrupt_stacks + CONFIG_ISR_STACK_SIZE + MPU_GUARD_ALIGN_AND_SIZE
98+ msr msp, r0
99+
93100 bl arch_pm_s2ram_resume
94101#endif /* CONFIG_PM_S2RAM */
95102
103+ /*
104+ * MSP needs to be set to main stack for following scenarios:
105+ * - If CONFIG_PM_S2RAM is enabled, MSP is set to z_interrupt_stacks
106+ * for resume functions to make use of a stack. However,
107+ * if the device was not suspended and if resume functions return,
108+ * MSP needs to be set back to z_main_stack to ensure proper
109+ * initialization.
110+ * - If CONFIG_PM_S2RAM is not enabled but CONFIG_INIT_ARCH_HW_AT_BOOT is,
111+ * MSP needs to be set to z_main_stack for proper initialization in case
112+ * device was loaded through chain loading or a debugger, as the initial
113+ * value of MSP would be anything that the previous image loaded.
114+ * - If CONFIG_INIT_STACKS is enabled, we need to ensure MSP is not set
115+ * to z_interrupt_stacks, so we set it to z_main_stack.
116+ *
117+ * Since these scenarios cover most of the cases, we set MSP to
118+ * z_main_stack here.
119+ *
120+ */
121+ ldr r0, =z_main_stack + CONFIG_MAIN_STACK_SIZE
122+ msr msp, r0
123+
124+ /* Note: Make sure that variables like z_sys_post_kernel
125+ * are set after the call to arch_pm_s2ram_resume
126+ * to avoid any issues with suspend/resume path.
127+ * Refer issue #83660 for more details.
128+ */
129+ #if defined(CONFIG_DEBUG_THREAD_INFO)
130+ /* Clear z_sys_post_kernel flag for RTOS aware debuggers */
131+ movs .n r0, #0
132+ ldr r1, =z_sys_post_kernel
133+ strb r0, [r1]
134+ #endif /* CONFIG_DEBUG_THREAD_INFO */
135+
96136#if defined(CONFIG_SOC_RESET_HOOK)
97137 bl soc_reset_hook
98138#endif
@@ -105,8 +145,6 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start)
105145 str r0, [r1]
106146 dsb
107147#endif /* CONFIG_CPU_HAS_ARM_MPU */
108- ldr r0, =z_main_stack + CONFIG_MAIN_STACK_SIZE
109- msr msp, r0
110148
111149 /* Initialize core architecture registers and system blocks */
112150 bl z_arm_init_arch_hw_at_boot
0 commit comments