diff --git a/arch/avr/src/avr/avr_saveusercontext.S b/arch/avr/src/avr/avr_saveusercontext.S index 60fbe1b8c5d..fb37b2cd4ba 100644 --- a/arch/avr/src/avr/avr_saveusercontext.S +++ b/arch/avr/src/avr/avr_saveusercontext.S @@ -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 diff --git a/arch/avr/src/avr/excptmacros.h b/arch/avr/src/avr/excptmacros.h index 4ee5d211704..d0973e175c5 100644 --- a/arch/avr/src/avr/excptmacros.h +++ b/arch/avr/src/avr/excptmacros.h @@ -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