arch/avr: fix up_saveusercontext

The up_saveusercontext function leverages USER_SAVE macro,
which is ordinarily used as a first half of the context switch.
This macro is therefore unsuitable to be used standalone,
it pops return address from the stack and does not return.

This patch adds missing instructions to do what would otherwise
be done by the second half of the context switch.

Tested by compiling and verifying the disassembly - the function
no longer falls through to the next function in the program memory,
push/pop instructions are balanced and stack contents preserved

Signed-off-by: Kerogit <kr.git@kerogit.eu>
This commit is contained in:
Kerogit 2025-05-27 01:33:38 +02:00 • committed by Xiang Xiao
parent 2c43595dfd
commit fa7f81c34e
2 changed files with 27 additions and 0 deletions

View file

@ -68,5 +68,26 @@ up_saveusercontext:
USER_SAVE
/* Main purpose of USER_SAVE macro is to serve as a first half
* of a context switch. To be able to do that, it - among other
* things - pops return address from the stack. The other half
* of context switch procedure then reverses that and pushes
* (different) return address back to the stack and returns
*
* The same needs to be done here, albeit simplified (we are
* not restoring context, just need return address back on the stack
* to be able to return.)
*
* Return address is loaded to r18-r20 in USER_SAVE
*/
push r18
push r19
#if AVR_PC_SIZE > 16
push r20
#endif /* AVR_PC_SIZE */
ret
.endfunc
.end

View file

@ -346,6 +346,12 @@
/* Pop the return address from the stack (PC0 then PC1).
* R18:19 are Call-used
*
* NOTE: up_saveusercontext in avr_saveusercontext.S uses this macro
* and needs to reverse this by pushing the return address back
* to the stack. Contents of these two/three registers must not change
* throughout whole macro and all changes in registers used and/or
* instruction ordering need to be reflected in up_saveusercontext.
*/
#if AVR_PC_SIZE > 16